From: pwpiwi Date: Sun, 5 Apr 2015 17:32:12 +0000 (+0200) Subject: Merge branch 'master' into topaz X-Git-Tag: v2.3.0~20^2~5 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/6306ff4bacd74eff46d44f4b62240277ecb4c670?hp=c5847ae8af8d567da6cb905bd59c886e3d0c040b Merge branch 'master' into topaz Conflicts: armsrc/Makefile client/Makefile --- diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..5f3f84ef --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,28 @@ +# Change Log +All notable changes to this project will be documented in this file. +This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... + +## [Unreleased][unreleased] +### Changed +- Iclass read, `hf iclass read` now also reads tag config and prints configuration. (holiman) + +### Fixed +- Fixed issue #19, problems with LF T55xx commands (marshmellow) + +### Added +- Added changelog + +## [2.0.0] - 2015-03-25 +### Changed +- LF sim operations now abort when new commands arrive over the USB - not required to push the device button anymore. + +### Fixed +- Mifare simulation, `hf mf sim` (was broken a long time) (pwpiwi) +- Major improvements in LF area and data operations. (marshmellow, iceman1001) +- Issues regarding LF simulation (pwpiwi) + +### Added +- iClass functionality: full simulation of iclass tags, so tags can be simulated with data (not only CSN). Not yet support for write/update, but readers don't seem to enforce update. (holiman). +- iClass decryption. Proxmark can now decrypt data on an iclass tag, but requires you to have the HID decryption key locally on your computer, as this is not bundled with the sourcecode. + + diff --git a/Makefile b/Makefile index 101212b4..b558da2d 100644 --- a/Makefile +++ b/Makefile @@ -23,8 +23,8 @@ help: @echo + all - Make bootrom, armsrc and the OS-specific host directory @echo + client - Make only the OS-specific host directory @echo + flash-bootrom - Make bootrom and flash it - @echo + flash-os - Make armsrc and flash os - @echo + flash-fpga - Make armsrc and flash fpga + @echo + flash-os - Make armsrc and flash os (includes fpga) + @echo + flash-fpga - (Deprecated:) Make armsrc and flash fpga @echo + flash-both - Make armsrc and flash os and fpga image @echo + flash-all - Make bootrom and armsrc and flash bootrom, os and fpga image @echo + clean - Clean in bootrom, armsrc and the OS-specific host directory @@ -37,13 +37,13 @@ flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL) flash-os: armsrc/obj/osimage.elf $(FLASH_TOOL) $(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<) -flash-fpga: armsrc/obj/fpgaimage.elf $(FLASH_TOOL) - $(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<) +#flash-fpga: armsrc/obj/fpgaimage.elf $(FLASH_TOOL) +# $(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<) -flash-both: armsrc/obj/osimage.elf armsrc/obj/fpgaimage.elf $(FLASH_TOOL) +flash-both: armsrc/obj/osimage.elf $(FLASH_TOOL) $(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$(filter-out $(FLASH_TOOL),$^)) -flash-all: bootrom/obj/bootrom.elf armsrc/obj/osimage.elf armsrc/obj/fpgaimage.elf $(FLASH_TOOL) +flash-all: bootrom/obj/bootrom.elf armsrc/obj/osimage.elf $(FLASH_TOOL) $(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$(filter-out $(FLASH_TOOL),$^)) newtarbin: diff --git a/armsrc/Makefile b/armsrc/Makefile index 03541d61..899b0307 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -10,7 +10,7 @@ APP_INCLUDES = apps.h #remove one of the following defines and comment out the relevant line #in the next section to remove that particular feature from compilation -APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -fno-strict-aliasing -O2 +APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -fno-strict-aliasing -ffunction-sections -fdata-sections #-DWITH_LCD #SRC_LCD = fonts.c LCD.c @@ -51,7 +51,8 @@ APP_CFLAGS += -I. # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC include ../common/Makefile.common -OBJS = $(OBJDIR)/osimage.s19 $(OBJDIR)/fpgaimage.s19 +OBJS = $(OBJDIR)/osimage.s19 +#$(OBJDIR)/fpgaimage.s19 all: $(OBJS) @@ -64,11 +65,11 @@ $(OBJDIR)/fpga_hf.o: fpga_hf.bit $(OBJDIR)/fullimage.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_lf.o $(OBJDIR)/fpga_hf.o $(THUMBOBJ) $(ARMOBJ) $(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) -$(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fullimage.elf - $(OBJCOPY) -F elf32-littlearm --only-section .fpgaimage $^ $@ +#$(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fullimage.elf +# $(OBJCOPY) -F elf32-littlearm --only-section .fpgaimage $^ $@ $(OBJDIR)/osimage.elf: $(OBJDIR)/fullimage.elf - $(OBJCOPY) -F elf32-littlearm --remove-section .fpgaimage $^ $@ + $(OBJCOPY) -F elf32-littlearm $^ $@ tarbin: $(OBJS) $(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 3e670f0b..6e0b58b3 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -648,7 +648,7 @@ void UsbPacketReceived(uint8_t *packet, int len) setSamplingConfig((sample_config *) c->d.asBytes); break; case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K: - cmd_send(CMD_ACK,SampleLF(),0,0,0,0); + cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0); break; case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K: ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 260e6a60..7b4daa36 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1627,7 +1627,10 @@ uint8_t handshakeIclassTag(uint8_t *card_data) static uint8_t act_all[] = { 0x0a }; static uint8_t identify[] = { 0x0c }; static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static uint8_t readcheck_cc[]= { 0x88, 0x02 }; + + + static uint8_t readcheck_cc[]= { 0x88, 0x02,}; + uint8_t resp[ICLASS_BUFFER_SIZE]; uint8_t read_status = 0; @@ -1662,28 +1665,33 @@ uint8_t handshakeIclassTag(uint8_t *card_data) if(ReaderReceiveIClass(resp) == 8) { //Save CC (e-purse) in response data memcpy(card_data+8,resp,8); - - //Got both - read_status = 2; + read_status++; } return read_status; } + // Reader iClass Anticollission void ReaderIClass(uint8_t arg0) { - uint8_t card_data[24]={0}; + uint8_t card_data[6 * 8]={0xFF}; uint8_t last_csn[8]={0}; + //Read conf block CRC(0x01) => 0xfa 0x22 + uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x01, 0xfa, 0x22}; + //Read conf block CRC(0x05) => 0xde 0x64 + uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x05, 0xde, 0x64}; + + int read_status= 0; + uint8_t result_status = 0; bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE; - bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC; + set_tracing(TRUE); setupIclassReader(); - size_t datasize = 0; - while(!BUTTON_PRESS()) + while(!BUTTON_PRESS()) { if(!tracing) { @@ -1695,15 +1703,40 @@ void ReaderIClass(uint8_t arg0) { read_status = handshakeIclassTag(card_data); if(read_status == 0) continue; - if(read_status == 1) datasize = 8; - if(read_status == 2) datasize = 16; + if(read_status == 1) result_status = FLAG_ICLASS_READER_CSN; + if(read_status == 2) result_status = FLAG_ICLASS_READER_CSN|FLAG_ICLASS_READER_CC; + + // handshakeIclass returns CSN|CC, but the actual block + // layout is CSN|CONFIG|CC, so here we reorder the data, + // moving CC forward 8 bytes + memcpy(card_data+16,card_data+8, 8); + //Read block 1, config + if(arg0 & FLAG_ICLASS_READER_CONF) + { + if(sendCmdGetResponseWithRetries(readConf, sizeof(readConf),card_data+8, 10, 10)) + { + Dbprintf("Failed to dump config block"); + }else + { + result_status |= FLAG_ICLASS_READER_CONF; + } + } - //Todo, read the public blocks 1,5 aswell: - // - // 0 : CSN (we already have) + //Read block 5, AA + if(arg0 & FLAG_ICLASS_READER_AA){ + if(sendCmdGetResponseWithRetries(readAA, sizeof(readAA),card_data+(8*4), 10, 10)) + { +// Dbprintf("Failed to dump AA block"); + }else + { + result_status |= FLAG_ICLASS_READER_AA; + } + } + + // 0 : CSN // 1 : Configuration - // 2 : e-purse (we already have) - // (3,4 write-only) + // 2 : e-purse + // (3,4 write-only, kc and kd) // 5 Application issuer area // //Then we can 'ship' back the 8 * 5 bytes of data, @@ -1713,10 +1746,10 @@ void ReaderIClass(uint8_t arg0) { //Send back to client, but don't bother if we already sent this if(memcmp(last_csn, card_data, 8) != 0) { - - if(!get_cc || (get_cc && read_status == 2)) + // If caller requires that we get CC, continue until we got it + if( (arg0 & read_status & FLAG_ICLASS_READER_CC) || !(arg0 & FLAG_ICLASS_READER_CC)) { - cmd_send(CMD_ACK,read_status,0,0,card_data,datasize); + cmd_send(CMD_ACK,result_status,0,0,card_data,sizeof(card_data)); if(abort_after_read) { LED_A_OFF(); return; @@ -1724,7 +1757,7 @@ void ReaderIClass(uint8_t arg0) { //Save that we already sent this.... memcpy(last_csn, card_data, 8); } - //If 'get_cc' was specified and we didn't get a CC, we'll just keep trying... + } LED_B_OFF(); } diff --git a/armsrc/ldscript b/armsrc/ldscript index d0be3b6a..840b8196 100644 --- a/armsrc/ldscript +++ b/armsrc/ldscript @@ -11,8 +11,7 @@ INCLUDE ../common/ldscript.common PHDRS { - fpgaimage PT_LOAD FLAGS(4); - text PT_LOAD; + text PT_LOAD FLAGS(5); data PT_LOAD; bss PT_LOAD; } @@ -20,11 +19,6 @@ PHDRS ENTRY(Vector) SECTIONS { - .fpgaimage : { - *(fpga_lf_bit.data) - *(fpga_hf_bit.data) - } >fpgaimage :fpgaimage - .start : { *(.startos) } >osimage :text @@ -40,6 +34,8 @@ SECTIONS .rodata : { *(.rodata) *(.rodata.*) + *(fpga_lf_bit.data) + *(fpga_hf_bit.data) KEEP(*(.version_information)) } >osimage :text diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 16c42855..e5a40b2e 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -29,11 +29,11 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - int divisor_used = 95; // 125 KHz - // see if 'h' was specified + int divisor_used = 95; // 125 KHz + // see if 'h' was specified - if (command[strlen((char *) command) - 1] == 'h') - divisor_used = 88; // 134.8 KHz + if (command[strlen((char *) command) - 1] == 'h') + divisor_used = 88; // 134.8 KHz sample_config sc = { 0,0,1, divisor_used, 0}; setSamplingConfig(&sc); @@ -48,28 +48,28 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, // And a little more time for the tag to fully power up SpinDelay(2000); - // now modulate the reader field - while(*command != '\0' && *command != ' ') { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); + // now modulate the reader field + while(*command != '\0' && *command != ' ') { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - LED_D_ON(); - if(*(command++) == '0') - SpinDelayUs(period_0); - else - SpinDelayUs(period_1); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + if(*(command++) == '0') + SpinDelayUs(period_0); + else + SpinDelayUs(period_1); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // now do the read + // now do the read DoAcquisition_config(false); } @@ -86,228 +86,228 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, */ void ReadTItag(void) { - // some hardcoded initial params - // when we read a TI tag we sample the zerocross line at 2Mhz - // TI tags modulate a 1 as 16 cycles of 123.2Khz - // TI tags modulate a 0 as 16 cycles of 134.2Khz + // some hardcoded initial params + // when we read a TI tag we sample the zerocross line at 2Mhz + // TI tags modulate a 1 as 16 cycles of 123.2Khz + // TI tags modulate a 0 as 16 cycles of 134.2Khz #define FSAMPLE 2000000 #define FREQLO 123200 #define FREQHI 134200 - signed char *dest = (signed char *)BigBuf_get_addr(); - uint16_t n = BigBuf_max_traceLen(); - // 128 bit shift register [shift3:shift2:shift1:shift0] - uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; - - int i, cycles=0, samples=0; - // how many sample points fit in 16 cycles of each frequency - uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; - // when to tell if we're close enough to one freq or another - uint32_t threshold = (sampleslo - sampleshi + 1)>>1; - - // TI tags charge at 134.2Khz - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - - // get TI tag data into the buffer - AcquireTiType(); - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - - for (i=0; i0) ) { - cycles++; - // after 16 cycles, measure the frequency - if (cycles>15) { - cycles=0; - samples=i-samples; // number of samples in these 16 cycles - - // TI bits are coming to us lsb first so shift them - // right through our 128 bit right shift register - shift0 = (shift0>>1) | (shift1 << 31); - shift1 = (shift1>>1) | (shift2 << 31); - shift2 = (shift2>>1) | (shift3 << 31); - shift3 >>= 1; - - // check if the cycles fall close to the number - // expected for either the low or high frequency - if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { - // low frequency represents a 1 - shift3 |= (1<<31); - } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { - // high frequency represents a 0 - } else { - // probably detected a gay waveform or noise - // use this as gaydar or discard shift register and start again - shift3 = shift2 = shift1 = shift0 = 0; - } - samples = i; - - // for each bit we receive, test if we've detected a valid tag - - // if we see 17 zeroes followed by 6 ones, we might have a tag - // remember the bits are backwards - if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { - // if start and end bytes match, we have a tag so break out of the loop - if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { - cycles = 0xF0B; //use this as a flag (ugly but whatever) - break; - } - } - } - } - } - - // if flag is set we have a tag - if (cycles!=0xF0B) { - DbpString("Info: No valid tag detected."); - } else { - // put 64 bit data into shift1 and shift0 - shift0 = (shift0>>24) | (shift1 << 8); - shift1 = (shift1>>24) | (shift2 << 8); - - // align 16 bit crc into lower half of shift2 - shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; - - // if r/w tag, check ident match + signed char *dest = (signed char *)BigBuf_get_addr(); + uint16_t n = BigBuf_max_traceLen(); + // 128 bit shift register [shift3:shift2:shift1:shift0] + uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; + + int i, cycles=0, samples=0; + // how many sample points fit in 16 cycles of each frequency + uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; + // when to tell if we're close enough to one freq or another + uint32_t threshold = (sampleslo - sampleshi + 1)>>1; + + // TI tags charge at 134.2Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + + // get TI tag data into the buffer + AcquireTiType(); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + + for (i=0; i0) ) { + cycles++; + // after 16 cycles, measure the frequency + if (cycles>15) { + cycles=0; + samples=i-samples; // number of samples in these 16 cycles + + // TI bits are coming to us lsb first so shift them + // right through our 128 bit right shift register + shift0 = (shift0>>1) | (shift1 << 31); + shift1 = (shift1>>1) | (shift2 << 31); + shift2 = (shift2>>1) | (shift3 << 31); + shift3 >>= 1; + + // check if the cycles fall close to the number + // expected for either the low or high frequency + if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { + // low frequency represents a 1 + shift3 |= (1<<31); + } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { + // high frequency represents a 0 + } else { + // probably detected a gay waveform or noise + // use this as gaydar or discard shift register and start again + shift3 = shift2 = shift1 = shift0 = 0; + } + samples = i; + + // for each bit we receive, test if we've detected a valid tag + + // if we see 17 zeroes followed by 6 ones, we might have a tag + // remember the bits are backwards + if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { + // if start and end bytes match, we have a tag so break out of the loop + if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { + cycles = 0xF0B; //use this as a flag (ugly but whatever) + break; + } + } + } + } + } + + // if flag is set we have a tag + if (cycles!=0xF0B) { + DbpString("Info: No valid tag detected."); + } else { + // put 64 bit data into shift1 and shift0 + shift0 = (shift0>>24) | (shift1 << 8); + shift1 = (shift1>>24) | (shift2 << 8); + + // align 16 bit crc into lower half of shift2 + shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; + + // if r/w tag, check ident match if (shift3 & (1<<15) ) { - DbpString("Info: TI tag is rewriteable"); - // only 15 bits compare, last bit of ident is not valid + DbpString("Info: TI tag is rewriteable"); + // only 15 bits compare, last bit of ident is not valid if (((shift3 >> 16) ^ shift0) & 0x7fff ) { - DbpString("Error: Ident mismatch!"); - } else { - DbpString("Info: TI tag ident is valid"); - } - } else { - DbpString("Info: TI tag is readonly"); - } - - // WARNING the order of the bytes in which we calc crc below needs checking - // i'm 99% sure the crc algorithm is correct, but it may need to eat the - // bytes in reverse or something - // calculate CRC - uint32_t crc=0; - - crc = update_crc16(crc, (shift0)&0xff); - crc = update_crc16(crc, (shift0>>8)&0xff); - crc = update_crc16(crc, (shift0>>16)&0xff); - crc = update_crc16(crc, (shift0>>24)&0xff); - crc = update_crc16(crc, (shift1)&0xff); - crc = update_crc16(crc, (shift1>>8)&0xff); - crc = update_crc16(crc, (shift1>>16)&0xff); - crc = update_crc16(crc, (shift1>>24)&0xff); - - Dbprintf("Info: Tag data: %x%08x, crc=%x", - (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); - if (crc != (shift2&0xffff)) { - Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); - } else { - DbpString("Info: CRC is good"); - } - } + DbpString("Error: Ident mismatch!"); + } else { + DbpString("Info: TI tag ident is valid"); + } + } else { + DbpString("Info: TI tag is readonly"); + } + + // WARNING the order of the bytes in which we calc crc below needs checking + // i'm 99% sure the crc algorithm is correct, but it may need to eat the + // bytes in reverse or something + // calculate CRC + uint32_t crc=0; + + crc = update_crc16(crc, (shift0)&0xff); + crc = update_crc16(crc, (shift0>>8)&0xff); + crc = update_crc16(crc, (shift0>>16)&0xff); + crc = update_crc16(crc, (shift0>>24)&0xff); + crc = update_crc16(crc, (shift1)&0xff); + crc = update_crc16(crc, (shift1>>8)&0xff); + crc = update_crc16(crc, (shift1>>16)&0xff); + crc = update_crc16(crc, (shift1>>24)&0xff); + + Dbprintf("Info: Tag data: %x%08x, crc=%x", + (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); + if (crc != (shift2&0xffff)) { + Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); + } else { + DbpString("Info: CRC is good"); + } + } } void WriteTIbyte(uint8_t b) { - int i = 0; - - // modulate 8 bits out to the antenna - for (i=0; i<8; i++) - { - if (b&(1<PIO_PDR = GPIO_SSC_DIN; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; - - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; - - // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long - // 48/2 = 24 MHz clock must be divided by 12 - AT91C_BASE_SSC->SSC_CMR = 12; - - AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; - AT91C_BASE_SSC->SSC_TCMR = 0; - AT91C_BASE_SSC->SSC_TFMR = 0; - - LED_D_ON(); - - // modulate antenna - HIGH(GPIO_SSC_DOUT); - - // Charge TI tag for 50ms. - SpinDelay(50); - - // stop modulating antenna and listen - LOW(GPIO_SSC_DOUT); - - LED_D_OFF(); - - i = 0; - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer - i++; if(i >= TIBUFLEN) break; - } - WDT_HIT(); - } - - // return stolen pin to SSP - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; - - char *dest = (char *)BigBuf_get_addr(); - n = TIBUFLEN*32; - // unpack buffer - for (i=TIBUFLEN-1; i>=0; i--) { - for (j=0; j<32; j++) { - if(BigBuf[i] & (1 << j)) { - dest[--n] = 1; - } else { - dest[--n] = -1; - } - } - } + memset(BigBuf,0,BigBuf_max_traceLen()/sizeof(uint32_t)); + + // Set up the synchronous serial port + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; + + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; + + // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long + // 48/2 = 24 MHz clock must be divided by 12 + AT91C_BASE_SSC->SSC_CMR = 12; + + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; + AT91C_BASE_SSC->SSC_TCMR = 0; + AT91C_BASE_SSC->SSC_TFMR = 0; + + LED_D_ON(); + + // modulate antenna + HIGH(GPIO_SSC_DOUT); + + // Charge TI tag for 50ms. + SpinDelay(50); + + // stop modulating antenna and listen + LOW(GPIO_SSC_DOUT); + + LED_D_OFF(); + + i = 0; + for(;;) { + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + i++; if(i >= TIBUFLEN) break; + } + WDT_HIT(); + } + + // return stolen pin to SSP + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + + char *dest = (char *)BigBuf_get_addr(); + n = TIBUFLEN*32; + // unpack buffer + for (i=TIBUFLEN-1; i>=0; i--) { + for (j=0; j<32; j++) { + if(BigBuf[i] & (1 << j)) { + dest[--n] = 1; + } else { + dest[--n] = -1; + } + } + } } // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc @@ -315,128 +315,128 @@ void AcquireTiType(void) // if not provided a valid crc will be computed from the data and written. void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if(crc == 0) { - crc = update_crc16(crc, (idlo)&0xff); - crc = update_crc16(crc, (idlo>>8)&0xff); - crc = update_crc16(crc, (idlo>>16)&0xff); - crc = update_crc16(crc, (idlo>>24)&0xff); - crc = update_crc16(crc, (idhi)&0xff); - crc = update_crc16(crc, (idhi>>8)&0xff); - crc = update_crc16(crc, (idhi>>16)&0xff); - crc = update_crc16(crc, (idhi>>24)&0xff); - } - Dbprintf("Writing to tag: %x%08x, crc=%x", - (unsigned int) idhi, (unsigned int) idlo, crc); - - // TI tags charge at 134.2Khz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - LED_A_ON(); - - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - - // writing algorithm: - // a high bit consists of a field off for 1ms and field on for 1ms - // a low bit consists of a field off for 0.3ms and field on for 1.7ms - // initiate a charge time of 50ms (field on) then immediately start writing bits - // start by writing 0xBB (keyword) and 0xEB (password) - // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) - // finally end with 0x0300 (write frame) - // all data is sent lsb firts - // finish with 15ms programming time - - // modulate antenna - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // charge time - - WriteTIbyte(0xbb); // keyword - WriteTIbyte(0xeb); // password - WriteTIbyte( (idlo )&0xff ); - WriteTIbyte( (idlo>>8 )&0xff ); - WriteTIbyte( (idlo>>16)&0xff ); - WriteTIbyte( (idlo>>24)&0xff ); - WriteTIbyte( (idhi )&0xff ); - WriteTIbyte( (idhi>>8 )&0xff ); - WriteTIbyte( (idhi>>16)&0xff ); - WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo - WriteTIbyte( (crc )&0xff ); // crc lo - WriteTIbyte( (crc>>8 )&0xff ); // crc hi - WriteTIbyte(0x00); // write frame lo - WriteTIbyte(0x03); // write frame hi - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // programming time - - LED_A_OFF(); - - // get TI tag data into the buffer - AcquireTiType(); - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Now use tiread to check"); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if(crc == 0) { + crc = update_crc16(crc, (idlo)&0xff); + crc = update_crc16(crc, (idlo>>8)&0xff); + crc = update_crc16(crc, (idlo>>16)&0xff); + crc = update_crc16(crc, (idlo>>24)&0xff); + crc = update_crc16(crc, (idhi)&0xff); + crc = update_crc16(crc, (idhi>>8)&0xff); + crc = update_crc16(crc, (idhi>>16)&0xff); + crc = update_crc16(crc, (idhi>>24)&0xff); + } + Dbprintf("Writing to tag: %x%08x, crc=%x", + (unsigned int) idhi, (unsigned int) idlo, crc); + + // TI tags charge at 134.2Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + LED_A_ON(); + + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + + // writing algorithm: + // a high bit consists of a field off for 1ms and field on for 1ms + // a low bit consists of a field off for 0.3ms and field on for 1.7ms + // initiate a charge time of 50ms (field on) then immediately start writing bits + // start by writing 0xBB (keyword) and 0xEB (password) + // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) + // finally end with 0x0300 (write frame) + // all data is sent lsb firts + // finish with 15ms programming time + + // modulate antenna + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // charge time + + WriteTIbyte(0xbb); // keyword + WriteTIbyte(0xeb); // password + WriteTIbyte( (idlo )&0xff ); + WriteTIbyte( (idlo>>8 )&0xff ); + WriteTIbyte( (idlo>>16)&0xff ); + WriteTIbyte( (idlo>>24)&0xff ); + WriteTIbyte( (idhi )&0xff ); + WriteTIbyte( (idhi>>8 )&0xff ); + WriteTIbyte( (idhi>>16)&0xff ); + WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo + WriteTIbyte( (crc )&0xff ); // crc lo + WriteTIbyte( (crc>>8 )&0xff ); // crc hi + WriteTIbyte(0x00); // write frame lo + WriteTIbyte(0x03); // write frame hi + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // programming time + + LED_A_OFF(); + + // get TI tag data into the buffer + AcquireTiType(); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Now use tiread to check"); } void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { - int i; - uint8_t *tab = BigBuf_get_addr(); + int i; + uint8_t *tab = BigBuf_get_addr(); - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; #define SHORT_COIL() LOW(GPIO_SSC_DOUT) #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) - i = 0; - for(;;) { - //wait until SSC_CLK goes HIGH - while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + i = 0; + for(;;) { + //wait until SSC_CLK goes HIGH + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { if(BUTTON_PRESS() || usb_poll()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } - if (ledcontrol) - LED_D_ON(); - - if(tab[i]) - OPEN_COIL(); - else - SHORT_COIL(); - - if (ledcontrol) - LED_D_OFF(); - //wait until SSC_CLK goes LOW - while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } - - i++; - if(i == period) { - - i = 0; - if (gap) { - SHORT_COIL(); - SpinDelayUs(gap); - } - } - } + DbpString("Stopped"); + return; + } + WDT_HIT(); + } + if (ledcontrol) + LED_D_ON(); + + if(tab[i]) + OPEN_COIL(); + else + SHORT_COIL(); + + if (ledcontrol) + LED_D_OFF(); + //wait until SSC_CLK goes LOW + while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } + + i++; + if(i == period) { + + i = 0; + if (gap) { + SHORT_COIL(); + SpinDelayUs(gap); + } + } + } } #define DEBUG_FRAME_CONTENTS 1 @@ -447,136 +447,136 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) // compose fc/8 fc/10 waveform (FSK2) static void fc(int c, int *n) { - uint8_t *dest = BigBuf_get_addr(); - int idx; - - // for when we want an fc8 pattern every 4 logical bits - if(c==0) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - - // an fc/8 encoded bit is a bit pattern of 11110000 x6 = 48 samples - if(c==8) { - for (idx=0; idx<6; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } - - // an fc/10 encoded bit is a bit pattern of 1111100000 x5 = 50 samples - if(c==10) { - for (idx=0; idx<5; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + uint8_t *dest = BigBuf_get_addr(); + int idx; + + // for when we want an fc8 pattern every 4 logical bits + if(c==0) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + + // an fc/8 encoded bit is a bit pattern of 11110000 x6 = 48 samples + if(c==8) { + for (idx=0; idx<6; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } + + // an fc/10 encoded bit is a bit pattern of 1111100000 x5 = 50 samples + if(c==10) { + for (idx=0; idx<5; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } } // compose fc/X fc/Y waveform (FSKx) static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { - uint8_t *dest = BigBuf_get_addr(); - uint8_t halfFC = fc/2; - uint8_t wavesPerClock = clock/fc; - uint8_t mod = clock % fc; //modifier - uint8_t modAdj = fc/mod; //how often to apply modifier - bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk=TRUE; - // loop through clock - step field clock - for (uint8_t idx=0; idx < wavesPerClock; idx++){ - // put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave) - memset(dest+(*n), 0, fc-halfFC); //in case of odd number use extra here - memset(dest+(*n)+(fc-halfFC), 1, halfFC); - *n += fc; - } - if (mod>0) (*modCnt)++; - if ((mod>0) && modAdjOk){ //fsk2 - if ((*modCnt % modAdj) == 0){ //if 4th 8 length wave in a rf/50 add extra 8 length wave - memset(dest+(*n), 0, fc-halfFC); - memset(dest+(*n)+(fc-halfFC), 1, halfFC); - *n += fc; - } - } - if (mod>0 && !modAdjOk){ //fsk1 - memset(dest+(*n), 0, mod-(mod/2)); - memset(dest+(*n)+(mod-(mod/2)), 1, mod/2); - *n += mod; - } + uint8_t *dest = BigBuf_get_addr(); + uint8_t halfFC = fc/2; + uint8_t wavesPerClock = clock/fc; + uint8_t mod = clock % fc; //modifier + uint8_t modAdj = fc/mod; //how often to apply modifier + bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk=TRUE; + // loop through clock - step field clock + for (uint8_t idx=0; idx < wavesPerClock; idx++){ + // put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave) + memset(dest+(*n), 0, fc-halfFC); //in case of odd number use extra here + memset(dest+(*n)+(fc-halfFC), 1, halfFC); + *n += fc; + } + if (mod>0) (*modCnt)++; + if ((mod>0) && modAdjOk){ //fsk2 + if ((*modCnt % modAdj) == 0){ //if 4th 8 length wave in a rf/50 add extra 8 length wave + memset(dest+(*n), 0, fc-halfFC); + memset(dest+(*n)+(fc-halfFC), 1, halfFC); + *n += fc; + } + } + if (mod>0 && !modAdjOk){ //fsk1 + memset(dest+(*n), 0, mod-(mod/2)); + memset(dest+(*n)+(mod-(mod/2)), 1, mod/2); + *n += mod; + } } // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed void CmdHIDsimTAG(int hi, int lo, int ledcontrol) { - int n=0, i=0; - /* - HID tag bitstream format - The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits - A 1 bit is represented as 6 fc8 and 5 fc10 patterns - A 0 bit is represented as 5 fc10 and 6 fc8 patterns - A fc8 is inserted before every 4 bits - A special start of frame pattern is used consisting a0b0 where a and b are neither 0 - nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) - */ - - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits. - USE lf simfsk for larger tags"); - return; - } - fc(0,&n); - // special start of frame marker containing invalid bit sequences - fc(8, &n); fc(8, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 - fc(10, &n); fc(10, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 - - WDT_HIT(); - // manchester encode bits 43 to 32 - for (i=11; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((hi>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } - - WDT_HIT(); - // manchester encode bits 31 to 0 - for (i=31; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((lo>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } - - if (ledcontrol) - LED_A_ON(); - SimulateTagLowFrequency(n, 0, ledcontrol); - - if (ledcontrol) - LED_A_OFF(); + int n=0, i=0; + /* + HID tag bitstream format + The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits + A 1 bit is represented as 6 fc8 and 5 fc10 patterns + A 0 bit is represented as 5 fc10 and 6 fc8 patterns + A fc8 is inserted before every 4 bits + A special start of frame pattern is used consisting a0b0 where a and b are neither 0 + nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) + */ + + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits. - USE lf simfsk for larger tags"); + return; + } + fc(0,&n); + // special start of frame marker containing invalid bit sequences + fc(8, &n); fc(8, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 + fc(10, &n); fc(10, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 + + WDT_HIT(); + // manchester encode bits 43 to 32 + for (i=11; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((hi>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } + + WDT_HIT(); + // manchester encode bits 31 to 0 + for (i=31; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((lo>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } + + if (ledcontrol) + LED_A_ON(); + SimulateTagLowFrequency(n, 0, ledcontrol); + + if (ledcontrol) + LED_A_OFF(); } // prepare a waveform pattern in the buffer based on the ID given then @@ -584,352 +584,385 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol) // arg1 contains fcHigh and fcLow, arg2 contains invert and clock void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) { - int ledcontrol=1; - int n=0, i=0; - uint8_t fcHigh = arg1 >> 8; - uint8_t fcLow = arg1 & 0xFF; - uint16_t modCnt = 0; - uint8_t clk = arg2 & 0xFF; - uint8_t invert = (arg2 >> 8) & 1; - - for (i=0; i> 8; + uint8_t fcLow = arg1 & 0xFF; + uint16_t modCnt = 0; + uint8_t clk = arg2 & 0xFF; + uint8_t invert = (arg2 >> 8) & 1; + + for (i=0; i> 8) & 0xFF; - uint8_t manchester = arg1 & 1; - uint8_t separator = arg2 & 1; - uint8_t invert = (arg2 >> 8) & 1; - for (i=0; i> 8) & 0xFF; + uint8_t encoding = arg1 & 1; + uint8_t separator = arg2 & 1; + uint8_t invert = (arg2 >> 8) & 1; + + if (encoding==2){ //biphase + uint8_t phase=0; + for (i=0; i> 8; - uint8_t carrier = arg1 & 0xFF; - uint8_t invert = arg2 & 0xFF; - uint8_t curPhase = 0; - for (i=0; i> 8; + uint8_t carrier = arg1 & 0xFF; + uint8_t invert = arg2 & 0xFF; + uint8_t curPhase = 0; + for (i=0; i0 && lo>0){ - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - if (hi2 != 0){ //extra large HID tags - Dbprintf("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 - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd - uint8_t bitlen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; + + if (idx>0 && lo>0 && (size==96 || size==192)){ + // go over previously decoded manchester data and decode into usable tag ID + if (hi2 != 0){ //extra large HID tags 88/192 bits + Dbprintf("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + }else { //standard HID tags 44/96 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t bitlen = 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; + 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++; - } + idx3++; + } bitlen = idx3+19; - fc =0; - cardnum=0; + fc =0; + cardnum=0; if(bitlen == 26){ - cardnum = (lo>>1)&0xFFFF; - fc = (lo>>17)&0xFF; - } + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } if(bitlen == 37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } if(bitlen == 34){ - cardnum = (lo>>1)&0xFFFF; - fc= ((hi&1)<<15)|(lo>>17); - } + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } if(bitlen == 35){ - cardnum = (lo>>1)&0xFFFFF; - fc = ((hi&1)<<11)|(lo>>21); - } - } - else { //if bit 38 is not set then 37 bit format is used - bitlen= 37; - fc =0; - cardnum=0; - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - } - //Dbprintf("TAG ID: %x%08x (%d)", - // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - Dbprintf("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) bitlen, (unsigned int) fc, (unsigned int) cardnum); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - *high = hi; - *low = lo; - return; - } - // reset - hi2 = hi = lo = 0; - } - WDT_HIT(); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc =0; + cardnum=0; + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + //Dbprintf("TAG ID: %x%08x (%d)", + // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + Dbprintf("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) bitlen, (unsigned int) fc, (unsigned int) cardnum); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + *high = hi; + *low = lo; + return; + } + // reset + } + hi2 = hi = lo = idx = 0; + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = BigBuf_get_addr(); + uint8_t *dest = BigBuf_get_addr(); size_t size=0, idx=0; - int clk=0, invert=0, errCnt=0, maxErr=20; - uint64_t lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + int clk=0, invert=0, errCnt=0, maxErr=20; + uint32_t hi=0; + uint64_t lo=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); DoAcquisition_default(-1,true); size = BigBuf_max_traceLen(); - //Dbprintf("DEBUG: Buffer got"); //askdemod and manchester decode + if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format errCnt = askmandemod(dest, &size, &clk, &invert, maxErr); - //Dbprintf("DEBUG: ASK Got"); - WDT_HIT(); - - if (errCnt>=0){ - lo = Em410xDecode(dest, &size, &idx); - //Dbprintf("DEBUG: EM GOT"); - if (lo>0){ + WDT_HIT(); + + if (errCnt<0) continue; + + errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo); + if (errCnt){ + if (size>64){ + Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)", + hi, + (uint32_t)(lo>>32), + (uint32_t)lo, + (uint32_t)(lo&0xFFFF), + (uint32_t)((lo>>16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); + } else { Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)", - (uint32_t)(lo>>32), - (uint32_t)lo, - (uint32_t)(lo&0xFFFF), - (uint32_t)((lo>>16LL) & 0xFF), - (uint32_t)(lo & 0xFFFFFF)); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - *high=lo>>32; - *low=lo & 0xFFFFFFFF; - return; - } - } else{ - //Dbprintf("DEBUG: No Tag"); - } - WDT_HIT(); - lo = 0; - clk=0; - invert=0; - errCnt=0; - size=0; - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + (uint32_t)(lo>>32), + (uint32_t)lo, + (uint32_t)(lo&0xFFFF), + (uint32_t)((lo>>16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); + } + + if (findone){ + if (ledcontrol) LED_A_OFF(); + *high=lo>>32; + *low=lo & 0xFFFFFFFF; + return; + } + } + WDT_HIT(); + hi = lo = size = idx = 0; + clk = invert = errCnt = 0; + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = BigBuf_get_addr(); - int idx=0; - uint32_t code=0, code2=0; - uint8_t version=0; - uint8_t facilitycode=0; - uint16_t number=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); - - while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + uint8_t *dest = BigBuf_get_addr(); + int idx=0; + uint32_t code=0, code2=0; + uint8_t version=0; + uint8_t facilitycode=0; + uint16_t number=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); + + while(!BUTTON_PRESS()) { + WDT_HIT(); + if (ledcontrol) LED_A_ON(); DoAcquisition_default(-1,true); //fskdemod and get start index - WDT_HIT(); - idx = IOdemodFSK(dest, BigBuf_max_traceLen()); - if (idx>0){ - //valid tag found - - //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 - //Handle the data - if(findone){ //only print binary if we are doing one - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); - Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); - } - code = bytebits_to_byte(dest+idx,32); - code2 = bytebits_to_byte(dest+idx+32,32); - version = bytebits_to_byte(dest+idx+27,8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18,8) ; - number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 - - Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - // if we're only looking for one tag - if (findone){ - if (ledcontrol) LED_A_OFF(); - //LED_A_OFF(); - *high=code; - *low=code2; - return; - } - code=code2=0; - version=facilitycode=0; - number=0; - idx=0; - } - WDT_HIT(); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + WDT_HIT(); + idx = IOdemodFSK(dest, BigBuf_max_traceLen()); + if (idx<0) continue; + //valid tag found + + //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 + //Handle the data + if(findone){ //only print binary if we are doing one + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); + Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); + } + code = bytebits_to_byte(dest+idx,32); + code2 = bytebits_to_byte(dest+idx+32,32); + version = bytebits_to_byte(dest+idx+27,8); //14,4 + facilitycode = bytebits_to_byte(dest+idx+18,8); + number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 + + Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + // if we're only looking for one tag + if (findone){ + if (ledcontrol) LED_A_OFF(); + //LED_A_OFF(); + *high=code; + *low=code2; + return; + } + code=code2=0; + version=facilitycode=0; + number=0; + idx=0; + + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } /*------------------------------ @@ -991,329 +1024,312 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) * To compensate antenna falling times shorten the write times * and enlarge the gap ones. */ -#define START_GAP 250 -#define WRITE_GAP 160 -#define WRITE_0 144 // 192 -#define WRITE_1 400 // 432 for T55x7; 448 for E5550 +#define START_GAP 50*8 // 10 - 50fc 250 +#define WRITE_GAP 20*8 // - 30fc 160 +#define WRITE_0 24*8 // 16 - 63fc 54fc 144 +#define WRITE_1 54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550 //400 + +#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..) // Write one bit to card void T55xxWriteBit(int bit) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - if (bit == 0) - SpinDelayUs(WRITE_0); - else - SpinDelayUs(WRITE_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(WRITE_GAP); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + if (bit == 0) + SpinDelayUs(WRITE_0); + else + SpinDelayUs(WRITE_1); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(WRITE_GAP); } // Write one card block in page 0, no lock void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - //unsigned int i; //enio adjustment 12/10/14 - uint32_t i; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); - - // Data - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Data & i); - - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); - - // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + uint32_t i = 0; + + // Set up FPGA, 125kHz + // Wait for config.. (192+8190xPOW)x8 == 67ms + LFSetupFPGAForADC(0, true); + + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + + // Data + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Data & i); + + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); + + // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } +void TurnReadLFOn(){ + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelayUs(8*150); +} + + // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint8_t *dest = BigBuf_get_addr(); - //int m=0, i=0; //enio adjustment 12/10/14 - uint32_t m=0, i=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = BigBuf_max_traceLen(); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); - - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; - i++; - if (i >= m) break; - } - } - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + uint32_t i = 0; + uint8_t *dest = BigBuf_get_addr(); + uint16_t bufferlength = BigBuf_max_traceLen(); + if ( bufferlength > T55xx_SAMPLES_SIZE ) + bufferlength = T55xx_SAMPLES_SIZE; + + // Clear destination buffer before sending the command + memset(dest, 0x80, bufferlength); + + // Set up FPGA, 125kHz + // Wait for config.. (192+8190xPOW)x8 == 67ms + LFSetupFPGAForADC(0, true); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); + + // Turn field on to read the response + TurnReadLFOn(); + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + LED_D_OFF(); + if (i >= bufferlength) break; + } + } + + cmd_send(CMD_ACK,0,0,0,0,0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - uint8_t *dest = BigBuf_get_addr(); - int m=0, i=0; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = BigBuf_max_traceLen(); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(1); //Page 1 - - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + + uint32_t i = 0; + uint8_t *dest = BigBuf_get_addr(); + uint16_t bufferlength = BigBuf_max_traceLen(); + if ( bufferlength > T55xx_SAMPLES_SIZE ) + bufferlength= T55xx_SAMPLES_SIZE; + + // Clear destination buffer before sending the command + memset(dest, 0x80, bufferlength); + + LFSetupFPGAForADC(0, true); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(1); //Page 1 + + // Turn field on to read the response + TurnReadLFOn(); + + // Now do the acquisition + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + LED_D_OFF(); + + if (i >= bufferlength) break; + } + } + + cmd_send(CMD_ACK,0,0,0,0,0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } /*-------------- Cloning routines -----------*/ // Copy HID id to card and setup block 0 config void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format - int last_block = 0; - - if (longFMT){ - // Ensure no more than 84 bits supplied - if (hi2>0xFFFFF) { - DbpString("Tags can only have 84 bits."); - return; - } - // Build the 6 data blocks for supplied 84bit ID - last_block = 6; - data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) - for (int i=0;i<4;i++) { - if (hi2 & (1<<(19-i))) - data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((3-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (hi2 & (1<<(15-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data3 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(31-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data4 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(15-i))) - data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data4 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data5 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data5 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data6 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data6 |= (1<<((15-i)*2)); // 0 -> 01 - } - } - else { - // Ensure no more than 44 bits supplied - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - - // Build the 3 data blocks for supplied 44bit ID - last_block = 3; - - data1 = 0x1D000000; // load preamble - - for (int i=0;i<12;i++) { - if (hi & (1<<(11-i))) - data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((11-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data3 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - } - - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); - T55xxWriteBlock(data3,3,0,0); - - if (longFMT) { // if long format there are 6 blocks - T55xxWriteBlock(data4,4,0,0); - T55xxWriteBlock(data5,5,0,0); - T55xxWriteBlock(data6,6,0,0); - } - - // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) - T55xxWriteBlock(T55x7_BITRATE_RF_50 | - T55x7_MODULATION_FSK2a | - last_block << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - - LED_D_OFF(); - - DbpString("DONE!"); + int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format + int last_block = 0; + + if (longFMT){ + // Ensure no more than 84 bits supplied + if (hi2>0xFFFFF) { + DbpString("Tags can only have 84 bits."); + return; + } + // Build the 6 data blocks for supplied 84bit ID + last_block = 6; + data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) + for (int i=0;i<4;i++) { + if (hi2 & (1<<(19-i))) + data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((3-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (hi2 & (1<<(15-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data3 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(31-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data4 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(15-i))) + data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data4 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data5 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data5 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data6 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data6 |= (1<<((15-i)*2)); // 0 -> 01 + } + } + else { + // Ensure no more than 44 bits supplied + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + + // Build the 3 data blocks for supplied 44bit ID + last_block = 3; + + data1 = 0x1D000000; // load preamble + + for (int i=0;i<12;i++) { + if (hi & (1<<(11-i))) + data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((11-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data3 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } + } + + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); + T55xxWriteBlock(data3,3,0,0); + + if (longFMT) { // if long format there are 6 blocks + T55xxWriteBlock(data4,4,0,0); + T55xxWriteBlock(data5,5,0,0); + T55xxWriteBlock(data6,6,0,0); + } + + // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) + T55xxWriteBlock(T55x7_BITRATE_RF_50 | + T55x7_MODULATION_FSK2a | + last_block << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + + LED_D_OFF(); + + DbpString("DONE!"); } void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0; //up to six blocks for long format + int data1=0, data2=0; //up to six blocks for long format - data1 = hi; // load preamble - data2 = lo; + data1 = hi; // load preamble + data2 = lo; - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); - //Config Block - T55xxWriteBlock(0x00147040,0,0,0); - LED_D_OFF(); + //Config Block + T55xxWriteBlock(0x00147040,0,0,0); + LED_D_OFF(); - DbpString("DONE!"); + DbpString("DONE!"); } // Define 9bit header for EM410x tags @@ -1322,151 +1338,151 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { - int i, id_bit; - uint64_t id = EM410X_HEADER; - uint64_t rev_id = 0; // reversed ID - int c_parity[4]; // column parity - int r_parity = 0; // row parity - uint32_t clock = 0; - - // Reverse ID bits given as parameter (for simpler operations) - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - if (i < 32) { - rev_id = (rev_id << 1) | (id_lo & 1); - id_lo >>= 1; - } else { - rev_id = (rev_id << 1) | (id_hi & 1); - id_hi >>= 1; - } - } - - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - id_bit = rev_id & 1; - - if (i % 4 == 0) { - // Don't write row parity bit at start of parsing - if (i) - id = (id << 1) | r_parity; - // Start counting parity for new row - r_parity = id_bit; - } else { - // Count row parity - r_parity ^= id_bit; - } - - // First elements in column? - if (i < 4) - // Fill out first elements - c_parity[i] = id_bit; - else - // Count column parity - c_parity[i % 4] ^= id_bit; - - // Insert ID bit - id = (id << 1) | id_bit; - rev_id >>= 1; - } - - // Insert parity bit of last row - id = (id << 1) | r_parity; - - // Fill out column parity at the end of tag - for (i = 0; i < 4; ++i) - id = (id << 1) | c_parity[i]; - - // Add stop bit - id <<= 1; - - Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); - LED_D_ON(); - - // Write EM410x ID - T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); - T55xxWriteBlock((uint32_t)id, 2, 0, 0); - - // Config for EM410x (RF/64, Manchester, Maxblock=2) - if (card) { - // Clock rate is stored in bits 8-15 of the card value - clock = (card & 0xFF00) >> 8; - Dbprintf("Clock rate: %d", clock); - switch (clock) - { - case 32: - clock = T55x7_BITRATE_RF_32; - break; - case 16: - clock = T55x7_BITRATE_RF_16; - break; - case 0: - // A value of 0 is assumed to be 64 for backwards-compatibility - // Fall through... - case 64: - clock = T55x7_BITRATE_RF_64; - break; - default: - Dbprintf("Invalid clock rate: %d", clock); - return; - } - - // Writing configuration for T55x7 tag - T55xxWriteBlock(clock | - T55x7_MODULATION_MANCHESTER | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - } - else - // Writing configuration for T5555(Q5) tag - T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | - T5555_MODULATION_MANCHESTER | - 2 << T5555_MAXBLOCK_SHIFT, - 0, 0, 0); - - LED_D_OFF(); - Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", - (uint32_t)(id >> 32), (uint32_t)id); + int i, id_bit; + uint64_t id = EM410X_HEADER; + uint64_t rev_id = 0; // reversed ID + int c_parity[4]; // column parity + int r_parity = 0; // row parity + uint32_t clock = 0; + + // Reverse ID bits given as parameter (for simpler operations) + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + if (i < 32) { + rev_id = (rev_id << 1) | (id_lo & 1); + id_lo >>= 1; + } else { + rev_id = (rev_id << 1) | (id_hi & 1); + id_hi >>= 1; + } + } + + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + id_bit = rev_id & 1; + + if (i % 4 == 0) { + // Don't write row parity bit at start of parsing + if (i) + id = (id << 1) | r_parity; + // Start counting parity for new row + r_parity = id_bit; + } else { + // Count row parity + r_parity ^= id_bit; + } + + // First elements in column? + if (i < 4) + // Fill out first elements + c_parity[i] = id_bit; + else + // Count column parity + c_parity[i % 4] ^= id_bit; + + // Insert ID bit + id = (id << 1) | id_bit; + rev_id >>= 1; + } + + // Insert parity bit of last row + id = (id << 1) | r_parity; + + // Fill out column parity at the end of tag + for (i = 0; i < 4; ++i) + id = (id << 1) | c_parity[i]; + + // Add stop bit + id <<= 1; + + Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); + LED_D_ON(); + + // Write EM410x ID + T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); + T55xxWriteBlock((uint32_t)id, 2, 0, 0); + + // Config for EM410x (RF/64, Manchester, Maxblock=2) + if (card) { + // Clock rate is stored in bits 8-15 of the card value + clock = (card & 0xFF00) >> 8; + Dbprintf("Clock rate: %d", clock); + switch (clock) + { + case 32: + clock = T55x7_BITRATE_RF_32; + break; + case 16: + clock = T55x7_BITRATE_RF_16; + break; + case 0: + // A value of 0 is assumed to be 64 for backwards-compatibility + // Fall through... + case 64: + clock = T55x7_BITRATE_RF_64; + break; + default: + Dbprintf("Invalid clock rate: %d", clock); + return; + } + + // Writing configuration for T55x7 tag + T55xxWriteBlock(clock | + T55x7_MODULATION_MANCHESTER | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + } + else + // Writing configuration for T5555(Q5) tag + T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | + T5555_MODULATION_MANCHESTER | + 2 << T5555_MAXBLOCK_SHIFT, + 0, 0, 0); + + LED_D_OFF(); + Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", + (uint32_t)(id >> 32), (uint32_t)id); } // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(int hi, int lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the block 0 for Indala64 format - T55xxWriteBlock(hi,1,0,0); - T55xxWriteBlock(lo,2,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); + //Program the 2 data blocks for supplied 64bit UID + // and the block 0 for Indala64 format + T55xxWriteBlock(hi,1,0,0); + T55xxWriteBlock(lo,2,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); - DbpString("DONE!"); + DbpString("DONE!"); } void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) { - //Program the 7 data blocks for supplied 224bit UID - // and the block 0 for Indala224 format - T55xxWriteBlock(uid1,1,0,0); - T55xxWriteBlock(uid2,2,0,0); - T55xxWriteBlock(uid3,3,0,0); - T55xxWriteBlock(uid4,4,0,0); - T55xxWriteBlock(uid5,5,0,0); - T55xxWriteBlock(uid6,6,0,0); - T55xxWriteBlock(uid7,7,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 7 << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); - - DbpString("DONE!"); + //Program the 7 data blocks for supplied 224bit UID + // and the block 0 for Indala224 format + T55xxWriteBlock(uid1,1,0,0); + T55xxWriteBlock(uid2,2,0,0); + T55xxWriteBlock(uid3,3,0,0); + T55xxWriteBlock(uid4,4,0,0); + T55xxWriteBlock(uid5,5,0,0); + T55xxWriteBlock(uid6,6,0,0); + T55xxWriteBlock(uid7,7,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 7 << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); + + DbpString("DONE!"); } @@ -1475,263 +1491,263 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int #define max(x,y) ( x GraphBuffer[0]) { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) - break; - i++; - } - dir = 0; - } - else { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) - break; - i++; - } - dir = 1; - } - - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; - - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) - { - lc = i - lastval; - lastval = i; - - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - BitStream[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - BitStream[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } - - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ - 64*BitStream[j*8+6]+ - 32*BitStream[j*8+5]+ - 16*BitStream[j*8+4]+ - 8*BitStream[j*8+3]+ - 4*BitStream[j*8+2]+ - 2*BitStream[j*8+1]+ - BitStream[j*8]; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - { - if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; - else dir = 1; - } - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, Blocks, 16*num_blocks); - return num_blocks; + lmin = 64; + lmax = 192; + + i = 2; + + /* Find first local max/min */ + if(GraphBuffer[1] > GraphBuffer[0]) { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) + break; + i++; + } + dir = 0; + } + else { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) + break; + i++; + } + dir = 1; + } + + lastval = i++; + half_switch = 0; + pmc = 0; + block_done = 0; + + for (bitidx = 0; i < GraphTraceLen; i++) + { + if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) + { + lc = i - lastval; + lastval = i; + + // Switch depending on lc length: + // Tolerance is 1/8 of clock rate (arbitrary) + if (abs(lc-clock/4) < tolerance) { + // 16T0 + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33+16)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else { + pmc = i; + } + } else if (abs(lc-clock/2) < tolerance) { + // 32TO + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else if(half_switch == 1) { + BitStream[bitidx++] = 0; + half_switch = 0; + } + else + half_switch++; + } else if (abs(lc-clock) < tolerance) { + // 64TO + BitStream[bitidx++] = 1; + } else { + // Error + warnings++; + if (warnings > 10) + { + Dbprintf("Error: too many detection errors, aborting."); + return 0; + } + } + + if(block_done == 1) { + if(bitidx == 128) { + for(j=0; j<16; j++) { + Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ + 64*BitStream[j*8+6]+ + 32*BitStream[j*8+5]+ + 16*BitStream[j*8+4]+ + 8*BitStream[j*8+3]+ + 4*BitStream[j*8+2]+ + 2*BitStream[j*8+1]+ + BitStream[j*8]; + } + num_blocks++; + } + bitidx = 0; + block_done = 0; + half_switch = 0; + } + if(i < GraphTraceLen) + { + if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; + else dir = 1; + } + } + if(bitidx==255) + bitidx=0; + warnings = 0; + if(num_blocks == 4) break; + } + memcpy(outBlocks, Blocks, 16*num_blocks); + return num_blocks; } int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; + // Assume RFU means 0 :) + if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled + return 1; + if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? + return 1; + return 0; } int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; + // Assume RFU means 0 :) + if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) + if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) + return 1; - return 0; + return 0; } #define ALLOC 16 void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; - - memset(Blocks, 0, 8*17*sizeof(uint8_t)); - - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } - - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } - } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); + uint8_t Blocks[8][17]; + uint8_t tmpBlocks[4][16]; + int i, j, ind, ind2, n; + int num_blocks = 0; + int max_blocks = 8; + int ident = 0; + int error = 0; + int tries = 0; + + memset(Blocks, 0, 8*17*sizeof(uint8_t)); + + do { + memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); + n = DemodPCF7931((uint8_t**)tmpBlocks); + if(!n) + error++; + if(error==10 && num_blocks == 0) { + Dbprintf("Error, no tag or bad tag"); + return; + } + else if (tries==20 || error==10) { + Dbprintf("Error reading the tag"); + Dbprintf("Here is the partial content"); + goto end; + } + + for(i=0; i= 0; ind--,ind2--) { + if(ind2 < 0) + ind2 = max_blocks; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { + if(ind2 > max_blocks) + ind2 = 0; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + } + } + } + } + } + tries++; + if (BUTTON_PRESS()) return; + } while (num_blocks != max_blocks); end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); - } - Dbprintf("-----------------------------------------"); - - return ; + Dbprintf("-----------------------------------------"); + Dbprintf("Memory content:"); + Dbprintf("-----------------------------------------"); + for(i=0; i", i); + } + Dbprintf("-----------------------------------------"); + + return ; } @@ -1755,20 +1771,20 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer //==================================================================== //-------------------------------------------------------------------- uint8_t Prepare_Cmd( uint8_t cmd ) { - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- - *forward_ptr++ = 0; //start bit - *forward_ptr++ = 0; //second pause for 4050 code + *forward_ptr++ = 0; //start bit + *forward_ptr++ = 0; //second pause for 4050 code - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; - return 6; //return number of emited bits + return 6; //return number of emited bits } //==================================================================== @@ -1778,21 +1794,21 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { //-------------------------------------------------------------------- uint8_t Prepare_Addr( uint8_t addr ) { - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- - register uint8_t line_parity; + register uint8_t line_parity; - uint8_t i; - line_parity = 0; - for(i=0;i<6;i++) { - *forward_ptr++ = addr; - line_parity ^= addr; - addr >>= 1; - } + uint8_t i; + line_parity = 0; + for(i=0;i<6;i++) { + *forward_ptr++ = addr; + line_parity ^= addr; + addr >>= 1; + } - *forward_ptr++ = (line_parity & 1); + *forward_ptr++ = (line_parity & 1); - return 7; //return number of emited bits + return 7; //return number of emited bits } //==================================================================== @@ -1802,36 +1818,36 @@ uint8_t Prepare_Addr( uint8_t addr ) { //-------------------------------------------------------------------- uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - //-------------------------------------------------------------------- - - register uint8_t line_parity; - register uint8_t column_parity; - register uint8_t i, j; - register uint16_t data; - - data = data_low; - column_parity = 0; - - for(i=0; i<4; i++) { - line_parity = 0; - for(j=0; j<8; j++) { - line_parity ^= data; - column_parity ^= (data & 1) << j; - *forward_ptr++ = data; - data >>= 1; - } - *forward_ptr++ = line_parity; - if(i == 1) - data = data_hi; - } - - for(j=0; j<8; j++) { - *forward_ptr++ = column_parity; - column_parity >>= 1; - } - *forward_ptr = 0; - - return 45; //return number of emited bits + //-------------------------------------------------------------------- + + register uint8_t line_parity; + register uint8_t column_parity; + register uint8_t i, j; + register uint16_t data; + + data = data_low; + column_parity = 0; + + for(i=0; i<4; i++) { + line_parity = 0; + for(j=0; j<8; j++) { + line_parity ^= data; + column_parity ^= (data & 1) << j; + *forward_ptr++ = data; + data >>= 1; + } + *forward_ptr++ = line_parity; + if(i == 1) + data = data_hi; + } + + for(j=0; j<8; j++) { + *forward_ptr++ = column_parity; + column_parity >>= 1; + } + *forward_ptr = 0; + + return 45; //return number of emited bits } //==================================================================== @@ -1841,114 +1857,114 @@ uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { //==================================================================== void SendForward(uint8_t fwd_bit_count) { - fwd_write_ptr = forwardLink_data; - fwd_bit_sz = fwd_bit_count; - - LED_D_ON(); - - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // force 1st mod pulse (start gap must be longer for 4305) - fwd_bit_sz--; //prepare next bit modulation - fwd_write_ptr++; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(16*8); //16 cycles on (8us each) - - // now start writting - while(fwd_bit_sz-- > 0) { //prepare next bit modulation - if(((*fwd_write_ptr++) & 1) == 1) - SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) - else { - //These timings work for 4469/4269/4305 (with the 55*8 above) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(23*8); //16-4 cycles off (8us each) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(9*8); //16 cycles on (8us each) - } - } + fwd_write_ptr = forwardLink_data; + fwd_bit_sz = fwd_bit_count; + + LED_D_ON(); + + //Field on + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // force 1st mod pulse (start gap must be longer for 4305) + fwd_bit_sz--; //prepare next bit modulation + fwd_write_ptr++; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(16*8); //16 cycles on (8us each) + + // now start writting + while(fwd_bit_sz-- > 0) { //prepare next bit modulation + if(((*fwd_write_ptr++) & 1) == 1) + SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) + else { + //These timings work for 4469/4269/4305 (with the 55*8 above) + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(23*8); //16-4 cycles off (8us each) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(9*8); //16 cycles on (8us each) + } + } } void EM4xLogin(uint32_t Password) { - uint8_t fwd_bit_count; + uint8_t fwd_bit_count; - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); - fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); + fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); - SendForward(fwd_bit_count); + SendForward(fwd_bit_count); - //Wait for command to complete - SpinDelay(20); + //Wait for command to complete + SpinDelay(20); } void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - uint8_t fwd_bit_count; - uint8_t *dest = BigBuf_get_addr(); - int m=0, i=0; - - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); - fwd_bit_count += Prepare_Addr( Address ); - - m = BigBuf_max_traceLen(); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - SendForward(fwd_bit_count); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + uint8_t fwd_bit_count; + uint8_t *dest = BigBuf_get_addr(); + int m=0, i=0; + + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); + fwd_bit_count += Prepare_Addr( Address ); + + m = BigBuf_max_traceLen(); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + SendForward(fwd_bit_count); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - uint8_t fwd_bit_count; + uint8_t fwd_bit_count; - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); - fwd_bit_count += Prepare_Addr( Address ); - fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); + fwd_bit_count += Prepare_Addr( Address ); + fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); - SendForward(fwd_bit_count); + SendForward(fwd_bit_count); - //Wait for write to complete - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + //Wait for write to complete + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 6094bd34..120c0801 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -224,21 +224,21 @@ uint32_t DoAcquisition_config( bool silent) ,silent); } -uint32_t ReadLF(bool activeField) +uint32_t ReadLF(bool activeField, bool silent) { - printConfig(); + if (!silent) printConfig(); LFSetupFPGAForADC(config.divisor, activeField); // Now call the acquisition routine - return DoAcquisition_config(false); + return DoAcquisition_config(silent); } /** * Initializes the FPGA for reader-mode (field on), and acquires the samples. * @return number of bits sampled **/ -uint32_t SampleLF() +uint32_t SampleLF(bool printCfg) { - return ReadLF(true); + return ReadLF(true, printCfg); } /** * Initializes the FPGA for snoop-mode (field off), and acquires the samples. @@ -247,5 +247,5 @@ uint32_t SampleLF() uint32_t SnoopLF() { - return ReadLF(false); + return ReadLF(false, true); } diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index 9ab458f8..6c671ec8 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -5,7 +5,7 @@ * Initializes the FPGA for reader-mode (field on), and acquires the samples. * @return number of bits sampled **/ -uint32_t SampleLF(); +uint32_t SampleLF(bool silent); /** * Initializes the FPGA for snoop-mode (field off), and acquires the samples. diff --git a/client/Makefile b/client/Makefile index 2e1c2092..48cbdfaa 100644 --- a/client/Makefile +++ b/client/Makefile @@ -66,6 +66,7 @@ CMDSRCS = nonce2key/crapto1.c\ loclass/elite_crack.c\ loclass/fileutils.c\ mifarehost.c\ + crc.c \ crc16.c \ iso14443crc.c \ iso15693tools.c \ @@ -100,8 +101,7 @@ CMDSRCS = nonce2key/crapto1.c\ cmdscript.c\ pm3_bitlib.c\ aes.c\ - protocols.c\ - + protocols.c COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) diff --git a/client/cmddata.c b/client/cmddata.c index 95c7dc87..55959984 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -22,6 +22,7 @@ #include "cmddata.h" #include "lfdemod.h" #include "usb_cmd.h" +#include "crc.h" uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; uint8_t g_debugMode; @@ -32,6 +33,12 @@ static int CmdHelp(const char *Cmd); //by marshmellow void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx) { + if (buff == NULL) + return; + + if ( size >= MAX_DEMOD_BUF_LEN) + size = MAX_DEMOD_BUF_LEN; + size_t i = 0; for (; i < size; i++){ DemodBuffer[i]=buff[startIdx++]; @@ -42,10 +49,10 @@ void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx) int CmdSetDebugMode(const char *Cmd) { - int demod=0; - sscanf(Cmd, "%i", &demod); - g_debugMode=(uint8_t)demod; - return 1; + int demod=0; + sscanf(Cmd, "%i", &demod); + g_debugMode=(uint8_t)demod; + return 1; } //by marshmellow @@ -58,87 +65,88 @@ void printDemodBuff(void) return; } if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty - + // ensure equally divided by 16 bitLen &= 0xfff0; - + for (i = 0; i <= (bitLen-16); i+=16) { PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - DemodBuffer[i], - DemodBuffer[i+1], - DemodBuffer[i+2], - DemodBuffer[i+3], - DemodBuffer[i+4], - DemodBuffer[i+5], - DemodBuffer[i+6], - DemodBuffer[i+7], - DemodBuffer[i+8], - DemodBuffer[i+9], - DemodBuffer[i+10], - DemodBuffer[i+11], - DemodBuffer[i+12], - DemodBuffer[i+13], - DemodBuffer[i+14], - DemodBuffer[i+15]); + DemodBuffer[i], + DemodBuffer[i+1], + DemodBuffer[i+2], + DemodBuffer[i+3], + DemodBuffer[i+4], + DemodBuffer[i+5], + DemodBuffer[i+6], + DemodBuffer[i+7], + DemodBuffer[i+8], + DemodBuffer[i+9], + DemodBuffer[i+10], + DemodBuffer[i+11], + DemodBuffer[i+12], + DemodBuffer[i+13], + DemodBuffer[i+14], + DemodBuffer[i+15] + ); } return; } int CmdPrintDemodBuff(const char *Cmd) { - char hex; - char printBuff[512]={0x00}; - uint8_t numBits = DemodBufferLen & 0xFFF0; - sscanf(Cmd, "%c", &hex); - if (hex == 'h'){ - PrintAndLog("Usage: data printdemodbuffer [x]"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" x output in hex (omit for binary output)"); - return 0; - } - if (hex == 'x'){ - numBits = binarraytohex(printBuff, (char *)DemodBuffer, numBits); - if (numBits==0) return 0; - PrintAndLog("DemodBuffer: %s",printBuff); - } else { - printDemodBuff(); - } - return 1; + char hex; + char printBuff[512]={0x00}; + uint8_t numBits = DemodBufferLen & 0xFFF0; + sscanf(Cmd, "%c", &hex); + if (hex == 'h'){ + PrintAndLog("Usage: data printdemodbuffer [x]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" x output in hex (omit for binary output)"); + return 0; + } + if (hex == 'x'){ + numBits = binarraytohex(printBuff, (char *)DemodBuffer, numBits); + if (numBits==0) return 0; + PrintAndLog("DemodBuffer: %s",printBuff); + } else { + printDemodBuff(); + } + return 1; } int CmdAmp(const char *Cmd) { - int i, rising, falling; - int max = INT_MIN, min = INT_MAX; - - for (i = 10; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] > max) - max = GraphBuffer[i]; - if (GraphBuffer[i] < min) - min = GraphBuffer[i]; - } - - if (max != min) { - rising = falling= 0; - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i + 1] < GraphBuffer[i]) { - if (rising) { - GraphBuffer[i] = max; - rising = 0; - } - falling = 1; - } - if (GraphBuffer[i + 1] > GraphBuffer[i]) { - if (falling) { - GraphBuffer[i] = min; - falling = 0; - } - rising= 1; - } - } - } - RepaintGraphWindow(); - return 0; + int i, rising, falling; + int max = INT_MIN, min = INT_MAX; + + for (i = 10; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] > max) + max = GraphBuffer[i]; + if (GraphBuffer[i] < min) + min = GraphBuffer[i]; + } + + if (max != min) { + rising = falling= 0; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i + 1] < GraphBuffer[i]) { + if (rising) { + GraphBuffer[i] = max; + rising = 0; + } + falling = 1; + } + if (GraphBuffer[i + 1] > GraphBuffer[i]) { + if (falling) { + GraphBuffer[i] = min; + falling = 0; + } + rising= 1; + } + } + } + RepaintGraphWindow(); + return 0; } /* @@ -157,68 +165,68 @@ int CmdAmp(const char *Cmd) //this function strictly converts highs and lows to 1s and 0s for each sample in the graphbuffer int Cmdaskdemod(const char *Cmd) { - int i; - int c, high = 0, low = 0; - - sscanf(Cmd, "%i", &c); - - /* Detect high and lows */ - for (i = 0; i < GraphTraceLen; ++i) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } - high=abs(high*.75); - low=abs(low*.75); - if (c != 0 && c != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - //prime loop - if (GraphBuffer[0] > 0) { - GraphBuffer[0] = 1-c; - } else { - GraphBuffer[0] = c; - } - for (i = 1; i < GraphTraceLen; ++i) { - /* Transitions are detected at each peak - * Transitions are either: - * - we're low: transition if we hit a high - * - we're high: transition if we hit a low - * (we need to do it this way because some tags keep high or - * low for long periods, others just reach the peak and go - * down) - */ - //[marhsmellow] change == to >= for high and <= for low for fuzz - if ((GraphBuffer[i] >= high) && (GraphBuffer[i - 1] == c)) { - GraphBuffer[i] = 1 - c; - } else if ((GraphBuffer[i] <= low) && (GraphBuffer[i - 1] == (1 - c))){ - GraphBuffer[i] = c; - } else { - /* No transition */ - GraphBuffer[i] = GraphBuffer[i - 1]; - } - } - RepaintGraphWindow(); - return 0; + int i; + int c, high = 0, low = 0; + + sscanf(Cmd, "%i", &c); + + /* Detect high and lows */ + for (i = 0; i < GraphTraceLen; ++i) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } + high=abs(high*.75); + low=abs(low*.75); + if (c != 0 && c != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + //prime loop + if (GraphBuffer[0] > 0) { + GraphBuffer[0] = 1-c; + } else { + GraphBuffer[0] = c; + } + for (i = 1; i < GraphTraceLen; ++i) { + /* Transitions are detected at each peak + * Transitions are either: + * - we're low: transition if we hit a high + * - we're high: transition if we hit a low + * (we need to do it this way because some tags keep high or + * low for long periods, others just reach the peak and go + * down) + */ + //[marhsmellow] change == to >= for high and <= for low for fuzz + if ((GraphBuffer[i] >= high) && (GraphBuffer[i - 1] == c)) { + GraphBuffer[i] = 1 - c; + } else if ((GraphBuffer[i] <= low) && (GraphBuffer[i - 1] == (1 - c))){ + GraphBuffer[i] = c; + } else { + /* No transition */ + GraphBuffer[i] = GraphBuffer[i - 1]; + } + } + RepaintGraphWindow(); + return 0; } //this function strictly converts >1 to 1 and <1 to 0 for each sample in the graphbuffer int CmdGetBitStream(const char *Cmd) { - int i; - CmdHpf(Cmd); - for (i = 0; i < GraphTraceLen; i++) { - if (GraphBuffer[i] >= 1) { - GraphBuffer[i] = 1; - } else { - GraphBuffer[i] = 0; - } - } - RepaintGraphWindow(); - return 0; + int i; + CmdHpf(Cmd); + for (i = 0; i < GraphTraceLen; i++) { + if (GraphBuffer[i] >= 1) { + GraphBuffer[i] = 1; + } else { + GraphBuffer[i] = 0; + } + } + RepaintGraphWindow(); + return 0; } @@ -232,181 +240,230 @@ void printBitStream(uint8_t BitStream[], uint32_t bitLen) } if (bitLen>512) bitLen=512; - // ensure equally divided by 16 + // ensure equally divided by 16 bitLen &= 0xfff0; for (i = 0; i <= (bitLen-16); i+=16) { PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15]); + BitStream[i], + BitStream[i+1], + BitStream[i+2], + BitStream[i+3], + BitStream[i+4], + BitStream[i+5], + BitStream[i+6], + BitStream[i+7], + BitStream[i+8], + BitStream[i+9], + BitStream[i+10], + BitStream[i+11], + BitStream[i+12], + BitStream[i+13], + BitStream[i+14], + BitStream[i+15] + ); } return; } //by marshmellow //print 64 bit EM410x ID in multiple formats -void printEM410x(uint64_t id) -{ - if (id !=0){ - uint64_t iii=1; - uint64_t id2lo=0; - uint32_t ii=0; - uint32_t i=0; - for (ii=5; ii>0;ii--){ - for (i=0;i<8;i++){ - id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8))); - } - } - //output em id - PrintAndLog("EM TAG ID : %010llx", id); - PrintAndLog("Unique TAG ID: %010llx", id2lo); - PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); - PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); - PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); - PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF)); - PrintAndLog("DEZ 14/IK2 : %014lld",id); - PrintAndLog("DEZ 15/IK3 : %015lld",id2lo); - PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF)); - } - return; +void printEM410x(uint32_t hi, uint64_t id) +{ + if (id || hi){ + uint64_t iii=1; + uint64_t id2lo=0; + uint32_t ii=0; + uint32_t i=0; + for (ii=5; ii>0;ii--){ + for (i=0;i<8;i++){ + id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8))); + } + } + if (hi){ + //output 88 bit em id + PrintAndLog("\nEM TAG ID : %06x%016llx", hi, id); + } else{ + //output 40 bit em id + PrintAndLog("\nEM TAG ID : %010llx", id); + PrintAndLog("Unique TAG ID : %010llx", id2lo); + PrintAndLog("\nPossible de-scramble patterns"); + PrintAndLog("HoneyWell IdentKey {"); + PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); + PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFFFF); + PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); + PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF)); + PrintAndLog("DEZ 3.5B : %03lld.%05lld",(id & 0xFF000000) >> 24,(id & 0xFFFF)); + PrintAndLog("DEZ 3.5C : %03lld.%05lld",(id & 0xFF0000) >> 16,(id & 0xFFFF)); + PrintAndLog("DEZ 14/IK2 : %014lld",id); + PrintAndLog("DEZ 15/IK3 : %015lld",id2lo); + PrintAndLog("DEZ 20/ZK : %02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld", + (id2lo & 0xf000000000) >> 36, + (id2lo & 0x0f00000000) >> 32, + (id2lo & 0x00f0000000) >> 28, + (id2lo & 0x000f000000) >> 24, + (id2lo & 0x0000f00000) >> 20, + (id2lo & 0x00000f0000) >> 16, + (id2lo & 0x000000f000) >> 12, + (id2lo & 0x0000000f00) >> 8, + (id2lo & 0x00000000f0) >> 4, + (id2lo & 0x000000000f) + ); + uint64_t paxton = (((id>>32) << 24) | (id & 0xffffff)) + 0x143e00; + PrintAndLog("}\nOther : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF)); + PrintAndLog("Pattern Paxton : %0d", paxton); + + uint32_t p1id = (id & 0xFFFFFF); + uint8_t arr[32] = {0x00}; + int i =0; + int j = 23; + for (; i < 24; ++i, --j ){ + arr[i] = (p1id >> i) & 1; + } + + uint32_t p1 = 0; + + p1 |= arr[23] << 21; + p1 |= arr[22] << 23; + p1 |= arr[21] << 20; + p1 |= arr[20] << 22; + + p1 |= arr[19] << 18; + p1 |= arr[18] << 16; + p1 |= arr[17] << 19; + p1 |= arr[16] << 17; + + p1 |= arr[15] << 13; + p1 |= arr[14] << 15; + p1 |= arr[13] << 12; + p1 |= arr[12] << 14; + + p1 |= arr[11] << 6; + p1 |= arr[10] << 2; + p1 |= arr[9] << 7; + p1 |= arr[8] << 1; + + p1 |= arr[7] << 0; + p1 |= arr[6] << 8; + p1 |= arr[5] << 11; + p1 |= arr[4] << 3; + + p1 |= arr[3] << 10; + p1 |= arr[2] << 4; + p1 |= arr[1] << 5; + p1 |= arr[0] << 9; + PrintAndLog("Pattern 1 : 0x%X - %d", p1, p1); + + uint16_t sebury1 = id & 0xFFFF; + uint8_t sebury2 = (id >> 16) & 0x7F; + uint32_t sebury3 = id & 0x7FFFFF; + PrintAndLog("Pattern Sebury : %d %d %d (hex: %X %X %X)", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3); + } + } + return; } + +int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo) +{ + int ans = ASKmanDemod(Cmd, FALSE, FALSE); + if (!ans) return 0; + + size_t idx=0; + if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, hi, lo)){ + if (g_debugMode){ + PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen); + printDemodBuff(); + } + return 1; + } + return 0; +} //by marshmellow //takes 3 arguments - clock, invert and maxErr as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands int CmdAskEM410xDemod(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 askem410xdemod [clock] <0|1> [maxError]"); - PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); - PrintAndLog(" , 1 for invert output"); - PrintAndLog(" [set maximum allowed errors], default = 100."); - PrintAndLog(""); - PrintAndLog(" sample: data askem410xdemod = demod an EM410x Tag ID from GraphBuffer"); - PrintAndLog(" : data askem410xdemod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32"); - PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data"); - PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors"); - - return 0; - } - - - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - size_t BitLen = getFromGraphBuf(BitStream); - - if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); - if (BitLen==0) return 0; - int errCnt=0; - errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr); - if (errCnt<0||BitLen<16){ //if fatal error (or -1) - if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); - return 0; - } - PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); - - //output - if (errCnt>0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - } - //PrintAndLog("ASK/Manchester decoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - setDemodBuf(BitStream,BitLen,0); - //printDemodBuff(); - uint64_t lo =0; - size_t idx=0; - lo = Em410xDecode(BitStream, &BitLen, &idx); - if (lo>0){ - //set GraphBuffer for clone or sim command - setDemodBuf(BitStream, BitLen, idx); - if (g_debugMode){ - PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); - printDemodBuff(); - } - PrintAndLog("EM410x pattern found: "); - if (BitLen > 64) PrintAndLog("\nWarning! Length not what is expected - Length: %d bits\n",BitLen); - printEM410x(lo); - return 1; - } - return 0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data askem410xdemod [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data askem410xdemod = demod an EM410x Tag ID from GraphBuffer"); + PrintAndLog(" : data askem410xdemod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data"); + PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors"); + return 0; + } + uint32_t hi = 0; + uint64_t lo = 0; + if (AskEm410xDemod(Cmd, &hi, &lo)) { + PrintAndLog("EM410x pattern found: "); + printEM410x(hi, lo); + return 1; + } + return 0; } int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch) { - int invert=0; - int clk=0; - int maxErr=100; - - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - if (clk==1){ - invert=1; - clk=0; - } - size_t BitLen = getFromGraphBuf(BitStream); - if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); - if (BitLen==0) return 0; - int errCnt=0; - errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr); - if (errCnt<0||BitLen<16){ //if fatal error (or -1) - if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); - return 0; - } - if (verbose) PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); - - //output - if (errCnt>0){ - if (verbose) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - } - if (verbose) PrintAndLog("ASK/Manchester decoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - setDemodBuf(BitStream,BitLen,0); - if (verbose) printDemodBuff(); - uint64_t lo =0; - size_t idx=0; - if (emSearch){ - lo = Em410xDecode(BitStream, &BitLen, &idx); - if (lo>0){ - //set GraphBuffer for clone or sim command - setDemodBuf(BitStream, BitLen, idx); - if (g_debugMode){ - PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); - printDemodBuff(); - } - if (verbose) PrintAndLog("EM410x pattern found: "); - if (verbose) printEM410x(lo); - return 1; - } - } - return 1; + int invert=0; + int clk=0; + int maxErr=100; + //param_getdec(Cmd, 0, &clk); + //param_getdec(Cmd, 1, &invert); + //maxErr = param_get32ex(Cmd, 2, 0xFFFFFFFF, 10); + //if (maxErr == 0xFFFFFFFF) maxErr=100; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + if (clk==1){ + invert=1; + clk=0; + } + size_t BitLen = getFromGraphBuf(BitStream); + if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr); + if (errCnt<0||BitLen<16){ //if fatal error (or -1) + if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); + return 0; + } + if (verbose || g_debugMode) PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); + + //output + if (errCnt>0){ + if (verbose || g_debugMode) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + if (verbose || g_debugMode) PrintAndLog("ASK/Manchester decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + setDemodBuf(BitStream,BitLen,0); + if (verbose || g_debugMode) printDemodBuff(); + uint64_t lo =0; + uint32_t hi =0; + size_t idx=0; + if (emSearch){ + if (Em410xDecode(BitStream, &BitLen, &idx, &hi, &lo)){ + //set GraphBuffer for clone or sim command + setDemodBuf(BitStream, BitLen, idx); + if (g_debugMode){ + PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); + printDemodBuff(); + } + if (verbose) PrintAndLog("EM410x pattern found: "); + if (verbose) printEM410x(hi, lo); + return 1; + } + } + return 1; } //by marshmellow @@ -415,21 +472,21 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch) //prints binary found and saves in graphbuffer for further commands int Cmdaskmandemod(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data rawdemod am [clock] <0|1> [maxError]"); - PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); - PrintAndLog(" , 1 for invert output"); - PrintAndLog(" [set maximum allowed errors], default = 100."); - PrintAndLog(""); - PrintAndLog(" sample: data rawdemod am = demod an ask/manchester tag from GraphBuffer"); - PrintAndLog(" : data rawdemod am 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); - PrintAndLog(" : data rawdemod am 32 1 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLog(" : data rawdemod am 1 = demod an ask/manchester tag from GraphBuffer while inverting data"); - PrintAndLog(" : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); - return 0; - } - return ASKmanDemod(Cmd, TRUE, TRUE); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod am [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data rawdemod am = demod an ask/manchester tag from GraphBuffer"); + PrintAndLog(" : data rawdemod am 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data rawdemod am 32 1 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data rawdemod am 1 = demod an ask/manchester tag from GraphBuffer while inverting data"); + PrintAndLog(" : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + return 0; + } + return ASKmanDemod(Cmd, TRUE, TRUE); } //by marshmellow @@ -437,51 +494,51 @@ int Cmdaskmandemod(const char *Cmd) //stricktly take 10 and 01 and convert to 0 and 1 int Cmdmandecoderaw(const char *Cmd) { - int i =0; - int errCnt=0; - size_t size=0; - size_t maxErr = 20; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data manrawdecode"); - PrintAndLog(" Takes 10 and 01 and converts to 0 and 1 respectively"); - PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); - PrintAndLog(""); - PrintAndLog(" sample: data manrawdecode = decode manchester bitstream from the demodbuffer"); - return 0; - } - if (DemodBufferLen==0) return 0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - int high=0,low=0; - for (;ihigh) high=DemodBuffer[i]; - else if(DemodBuffer[i]1 || low <0 ){ - PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); - return 0; - } - size=i; - errCnt=manrawdecode(BitStream, &size); - if (errCnt>=maxErr){ - PrintAndLog("Too many errors: %d",errCnt); - return 0; - } - PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); - printBitStream(BitStream, size); - if (errCnt==0){ - uint64_t id = 0; - size_t idx=0; - id = Em410xDecode(BitStream, &size, &idx); - if (id>0){ - //need to adjust to set bitstream back to manchester encoded data - //setDemodBuf(BitStream, size, idx); - - printEM410x(id); - } - } - return 1; + int i =0; + int errCnt=0; + size_t size=0; + size_t maxErr = 20; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data manrawdecode"); + PrintAndLog(" Takes 10 and 01 and converts to 0 and 1 respectively"); + PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(""); + PrintAndLog(" sample: data manrawdecode = decode manchester bitstream from the demodbuffer"); + return 0; + } + if (DemodBufferLen==0) return 0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + int high=0,low=0; + for (;ihigh) high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0 ){ + PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); + return 0; + } + size=i; + errCnt=manrawdecode(BitStream, &size); + if (errCnt>=maxErr){ + PrintAndLog("Too many errors: %d",errCnt); + return 0; + } + PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); + printBitStream(BitStream, size); + if (errCnt==0){ + uint64_t id = 0; + uint32_t hi = 0; + size_t idx=0; + if (Em410xDecode(BitStream, &size, &idx, &hi, &id)){ + //need to adjust to set bitstream back to manchester encoded data + //setDemodBuf(BitStream, size, idx); + + printEM410x(hi, id); + } + } + return 1; } //by marshmellow @@ -496,120 +553,188 @@ int Cmdmandecoderaw(const char *Cmd) // width waves vs small width waves to help the decode positioning) or askbiphdemod int CmdBiphaseDecodeRaw(const char *Cmd) { - int i = 0; - int errCnt=0; size_t size=0; - int offset=0; - int invert=0; - int high=0, low=0; + int offset=0, invert=0, maxErr=20, errCnt=0; char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data biphaserawdecode [offset] "); - PrintAndLog(" Converts 10 or 01 to 0 and 11 or 00 to 1"); + PrintAndLog("Usage: data biphaserawdecode [offset] [invert] [maxErr]"); + PrintAndLog(" Converts 10 or 01 to 1 and 11 or 00 to 0"); PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(" --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester"); PrintAndLog(""); PrintAndLog(" [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position"); PrintAndLog(" [invert <0|1>], set to 1 to invert output"); + PrintAndLog(" [maxErr int], set max errors tolerated - default=20"); PrintAndLog(""); PrintAndLog(" sample: data biphaserawdecode = decode biphase bitstream from the demodbuffer"); PrintAndLog(" sample: data biphaserawdecode 1 1 = decode biphase bitstream from the demodbuffer, set offset, and invert output"); return 0; } - sscanf(Cmd, "%i %i", &offset, &invert); - if (DemodBufferLen==0) return 0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - //get graphbuffer & high and low - for (;ihigh)high=DemodBuffer[i]; - else if(DemodBuffer[i]1 || low <0){ - PrintAndLog("Error: please raw demod the wave first then decode"); + sscanf(Cmd, "%i %i %i", &offset, &invert, &maxErr); + if (DemodBufferLen==0){ + PrintAndLog("DemodBuffer Empty - run 'data rawdemod ar' first"); return 0; } - size=i; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + memcpy(BitStream, DemodBuffer, DemodBufferLen); + size = DemodBufferLen; errCnt=BiphaseRawDecode(BitStream, &size, offset, invert); - if (errCnt>=20){ + if (errCnt<0){ + PrintAndLog("Error during decode:%d", errCnt); + return 0; + } + if (errCnt>maxErr){ PrintAndLog("Too many errors attempting to decode: %d",errCnt); return 0; } - PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); + + if (errCnt>0){ + PrintAndLog("# Errors found during Demod (shown as 77 in bit stream): %d",errCnt); + } + PrintAndLog("Biphase Decoded using offset: %d - # invert:%d - data:",offset,invert); printBitStream(BitStream, size); - PrintAndLog("\nif bitstream does not look right try offset=1"); - if (offset == 1) setDemodBuf(DemodBuffer,DemodBufferLen-1,1); //remove first bit from raw demod + + if (offset) setDemodBuf(DemodBuffer,DemodBufferLen-offset, offset); //remove first bit from raw demod return 1; } // set demod buffer back to raw after biphase demod -void setBiphaseDemodBuf(uint8_t *BitStream, size_t size) -{ - uint8_t rawStream[512]={0x00}; - size_t i=0; - uint8_t curPhase=0; - if (size > 256) { - PrintAndLog("ERROR - Biphase Demod Buffer overrun"); - return; - } - for (size_t idx=0; idx 256) { + PrintAndLog("ERROR - Biphase Demod Buffer overrun"); + return; + } + for (size_t idx=0; idx0 && verbose){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d", errCnt); - } - if (verbose){ - PrintAndLog("ASK demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printBitStream(BitStream,BitLen); - } - return 1; + int invert=0; + int clk=0; + int maxErr=100; + uint8_t askAmp = 0; + char amp = param_getchar(Cmd, 0); + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &); + if (invert != 0 && invert != 1) { + if (verbose || g_debugMode) PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + if (clk==1){ + invert=1; + clk=0; + } + if (amp == 'a' || amp == 'A') askAmp=1; + size_t BitLen = getFromGraphBuf(BitStream); + if (BitLen==0) return 0; + int errCnt=0; + errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp); + if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + if (verbose || g_debugMode) PrintAndLog("no data found"); + if (g_debugMode) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert); + return 0; + } + if (verbose || g_debugMode) PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); + + //move BitStream back to DemodBuffer + setDemodBuf(BitStream,BitLen,0); + + //output + if (errCnt>0 && (verbose || g_debugMode)){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d", errCnt); + } + if (verbose || g_debugMode){ + PrintAndLog("ASK demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printBitStream(BitStream,BitLen); + } + return 1; +} + +//by marshmellow +// - ASK Demod then Biphase decode GraphBuffer samples +int ASKbiphaseDemod(const char *Cmd, bool verbose) +{ + //ask raw demod GraphBuffer first + int offset=0, clk=0, invert=0, maxErr=0, ans=0; + ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr); + if (ans>0) + ans = ASKrawDemod(Cmd+1, FALSE); + else + ans = ASKrawDemod(Cmd, FALSE); + if (!ans) { + if (g_debugMode || verbose) PrintAndLog("Error AskrawDemod: %d", ans); + return 0; + } + + //attempt to Biphase decode DemodBuffer + size_t size = DemodBufferLen; + uint8_t BitStream[MAX_DEMOD_BUF_LEN]; + memcpy(BitStream, DemodBuffer, DemodBufferLen); + + int errCnt = BiphaseRawDecode(BitStream, &size, offset, invert); + if (errCnt < 0){ + if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode: %d", errCnt); + return 0; + } + if (errCnt > maxErr) { + if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode too many errors: %d", errCnt); + return 0; + } + //success set DemodBuffer and return + setDemodBuf(BitStream, size, 0); + if (g_debugMode || verbose){ + PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); + printDemodBuff(); + } + return 1; +} +//by marshmellow - see ASKbiphaseDemod +int Cmdaskbiphdemod(const char *Cmd) +{ + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod ab [offset] [clock] [maxError] "); + PrintAndLog(" [offset], offset to begin biphase, default=0"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); + PrintAndLog(" , 1 to invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100"); + PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); + PrintAndLog(" NOTE: can be entered as second or third argument"); + PrintAndLog(" NOTE: can be entered as first, second or last argument"); + PrintAndLog(" NOTE: any other arg must have previous args set to work"); + PrintAndLog(""); + PrintAndLog(" NOTE: --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester"); + PrintAndLog(""); + PrintAndLog(" sample: data rawdemod ab = demod an ask/biph tag from GraphBuffer"); + PrintAndLog(" : data rawdemod ab a = demod an ask/biph tag from GraphBuffer, amplified"); + PrintAndLog(" : data rawdemod ab 1 32 = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32"); + PrintAndLog(" : data rawdemod ab 0 32 1 = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data rawdemod ab 0 1 = demod an ask/biph tag from GraphBuffer while inverting data"); + PrintAndLog(" : data rawdemod ab 0 64 1 0 = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLog(" : data rawdemod ab 0 64 1 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); + return 0; + } + return ASKbiphaseDemod(Cmd, TRUE); } //by marshmellow @@ -619,168 +744,194 @@ int ASKrawDemod(const char *Cmd, bool verbose) //if successful it will push askraw data back to demod buffer ready for emulation int CmdG_Prox_II_Demod(const char *Cmd) { - int ans = ASKrawDemod(Cmd, FALSE); - if (ans <= 0) { - if (g_debugMode) PrintAndLog("Error AskrawDemod: %d",ans); - return ans; - } - size_t size = DemodBufferLen; - ans = BiphaseRawDecode(DemodBuffer, &size, 0, 0); - if (ans !=0) { - if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d",ans); - return ans; - } - //call lfdemod.c demod for gProxII - ans = gProxII_Demod(DemodBuffer, &size); - if (ans < 0){ - if (g_debugMode) PrintAndLog("Error gProxII_Demod 1st Try: %d",ans); - //try biphase again - ans = BiphaseRawDecode(DemodBuffer, &size, 1, 0); - if (ans != 0) { - if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d",ans); - return ans; - } - ans = gProxII_Demod(DemodBuffer, &size); - if (ans < 0) { - if (g_debugMode) PrintAndLog("Error gProxII_Demod 1st Try: %d",ans); - return ans; - } - } - //got a good demod - uint32_t ByteStream[65] = {0x00}; - uint8_t xorKey=0; - uint8_t keyCnt=0; - uint8_t bitCnt=0; - uint8_t ByteCnt=0; - size_t startIdx = ans + 6; //start after preamble - for (size_t idx = 0; idx>2; - uint32_t FC = 0; - uint32_t Card = 0; - uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans,32); - uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32); - uint32_t raw3 = bytebits_to_byte(DemodBuffer+ans+64, 32); - - if (fmtLen==36){ - FC = ((ByteStream[3] & 0x7F)<<7) | (ByteStream[4]>>1); - Card = ((ByteStream[4]&1)<<19) | (ByteStream[5]<<11) | (ByteStream[6]<<3) | (ByteStream[7]>>5); - PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card); - } else if(fmtLen==26){ - FC = ((ByteStream[3] & 0x7F)<<1) | (ByteStream[4]>>7); - Card = ((ByteStream[4]&0x7F)<<9) | (ByteStream[5]<<1) | (ByteStream[6]>>7); - PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card); - } else { - PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",fmtLen); - } - PrintAndLog("Raw: %08x%08x%08x", raw1,raw2,raw3); - setBiphaseDemodBuf(DemodBuffer+ans, 96); - return 1; + if (!ASKbiphaseDemod(Cmd, FALSE)){ + if (g_debugMode) PrintAndLog("ASKbiphaseDemod failed 1st try"); + return 0; + } + size_t size = DemodBufferLen; + //call lfdemod.c demod for gProxII + int ans = gProxII_Demod(DemodBuffer, &size); + if (ans < 0){ + if (g_debugMode) PrintAndLog("Error gProxII_Demod"); + return 0; + } + //got a good demod + uint32_t ByteStream[65] = {0x00}; + uint8_t xorKey=0; + uint8_t keyCnt=0; + uint8_t bitCnt=0; + uint8_t ByteCnt=0; + size_t startIdx = ans + 6; //start after preamble + for (size_t idx = 0; idx>2; + uint32_t FC = 0; + uint32_t Card = 0; + uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans,32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32); + uint32_t raw3 = bytebits_to_byte(DemodBuffer+ans+64, 32); + + if (fmtLen==36){ + FC = ((ByteStream[3] & 0x7F)<<7) | (ByteStream[4]>>1); + Card = ((ByteStream[4]&1)<<19) | (ByteStream[5]<<11) | (ByteStream[6]<<3) | (ByteStream[7]>>5); + PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card); + } else if(fmtLen==26){ + FC = ((ByteStream[3] & 0x7F)<<1) | (ByteStream[4]>>7); + Card = ((ByteStream[4]&0x7F)<<9) | (ByteStream[5]<<1) | (ByteStream[6]>>7); + PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card); + } else { + PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",fmtLen); + } + PrintAndLog("Raw: %08x%08x%08x", raw1,raw2,raw3); + setDemodBuf(DemodBuffer+ans, 96, 0); + return 1; } //by marshmellow - see ASKrawDemod int Cmdaskrawdemod(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data rawdemod ar [clock] [maxError] [amplify]"); - PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); - PrintAndLog(" , 1 to invert output"); - PrintAndLog(" [set maximum allowed errors], default = 100"); - PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); - PrintAndLog(""); - PrintAndLog(" sample: data rawdemod ar = demod an ask tag from GraphBuffer"); - PrintAndLog(" : data rawdemod ar a = demod an ask tag from GraphBuffer, amplified"); - PrintAndLog(" : data rawdemod ar 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); - PrintAndLog(" : data rawdemod ar 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLog(" : data rawdemod ar 1 = demod an ask tag from GraphBuffer while inverting data"); - PrintAndLog(" : data rawdemod ar 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); - PrintAndLog(" : data rawdemod ar 64 1 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); - return 0; - } - return ASKrawDemod(Cmd, TRUE); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod ar [clock] [maxError] [amplify]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); + PrintAndLog(" , 1 to invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100"); + PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); + PrintAndLog(""); + PrintAndLog(" sample: data rawdemod ar = demod an ask tag from GraphBuffer"); + PrintAndLog(" : data rawdemod ar a = demod an ask tag from GraphBuffer, amplified"); + PrintAndLog(" : data rawdemod ar 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data rawdemod ar 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data rawdemod ar 1 = demod an ask tag from GraphBuffer while inverting data"); + PrintAndLog(" : data rawdemod ar 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLog(" : data rawdemod ar 64 1 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); + return 0; + } + return ASKrawDemod(Cmd, TRUE); } -int CmdAutoCorr(const char *Cmd) +int AutoCorrelate(int window, bool SaveGrph, bool verbose) { - static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; - - int window = atoi(Cmd); - - if (window == 0) { - PrintAndLog("needs a window"); - return 0; - } - if (window >= GraphTraceLen) { - PrintAndLog("window must be smaller than trace (%d samples)", - GraphTraceLen); - return 0; - } + static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; + size_t Correlation = 0; + int maxSum = 0; + int lastMax = 0; + if (verbose) PrintAndLog("performing %d correlations", GraphTraceLen - window); + for (int i = 0; i < GraphTraceLen - window; ++i) { + int sum = 0; + for (int j = 0; j < window; ++j) { + sum += (GraphBuffer[j]*GraphBuffer[i + j]) / 256; + } + CorrelBuffer[i] = sum; + if (sum >= maxSum-100 && sum <= maxSum+100){ + //another max + Correlation = i-lastMax; + lastMax = i; + if (sum > maxSum) maxSum = sum; + } else if (sum > maxSum){ + maxSum=sum; + lastMax = i; + } + } + if (Correlation==0){ + //try again with wider margin + for (int i = 0; i < GraphTraceLen - window; i++){ + if (CorrelBuffer[i] >= maxSum-(maxSum*0.05) && CorrelBuffer[i] <= maxSum+(maxSum*0.05)){ + //another max + Correlation = i-lastMax; + lastMax = i; + //if (CorrelBuffer[i] > maxSum) maxSum = sum; + } + } + } + if (verbose && Correlation > 0) PrintAndLog("Possible Correlation: %d samples",Correlation); - PrintAndLog("performing %d correlations", GraphTraceLen - window); + if (SaveGrph){ + GraphTraceLen = GraphTraceLen - window; + memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int)); + RepaintGraphWindow(); + } + return Correlation; +} - for (int i = 0; i < GraphTraceLen - window; ++i) { - int sum = 0; - for (int j = 0; j < window; ++j) { - sum += (GraphBuffer[j]*GraphBuffer[i + j]) / 256; - } - CorrelBuffer[i] = sum; - } - GraphTraceLen = GraphTraceLen - window; - memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int)); +int usage_data_autocorr(void) +{ + //print help + PrintAndLog("Usage: data autocorr [window] [g]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" [window] window length for correlation - default = 4000"); + PrintAndLog(" g save back to GraphBuffer (overwrite)"); + return 0; +} - RepaintGraphWindow(); - return 0; +int CmdAutoCorr(const char *Cmd) +{ + char cmdp = param_getchar(Cmd, 0); + if (cmdp == 'h' || cmdp == 'H') + return usage_data_autocorr(); + int window = 4000; //set default + char grph=0; + bool updateGrph = FALSE; + sscanf(Cmd, "%i %c", &window, &grph); + + if (window >= GraphTraceLen) { + PrintAndLog("window must be smaller than trace (%d samples)", + GraphTraceLen); + return 0; + } + if (grph == 'g') updateGrph=TRUE; + return AutoCorrelate(window, updateGrph, TRUE); } int CmdBitsamples(const char *Cmd) { - int cnt = 0; - uint8_t got[12288]; + int cnt = 0; + uint8_t got[12288]; - GetFromBigBuf(got,sizeof(got),0); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(got,sizeof(got),0); + WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < sizeof(got); j++) { - for (int k = 0; k < 8; k++) { - if(got[j] & (1 << (7 - k))) { - GraphBuffer[cnt++] = 1; - } else { - GraphBuffer[cnt++] = 0; - } - } - } - GraphTraceLen = cnt; - RepaintGraphWindow(); - return 0; + for (int j = 0; j < sizeof(got); j++) { + for (int k = 0; k < 8; k++) { + if(got[j] & (1 << (7 - k))) { + GraphBuffer[cnt++] = 1; + } else { + GraphBuffer[cnt++] = 0; + } + } + } + GraphTraceLen = cnt; + RepaintGraphWindow(); + return 0; } /* @@ -788,78 +939,78 @@ int CmdBitsamples(const char *Cmd) */ int CmdBitstream(const char *Cmd) { - int i, j; - int bit; - int gtl; - int clock; - int low = 0; - int high = 0; - int hithigh, hitlow, first; - - /* Detect high and lows and clock */ - for (i = 0; i < GraphTraceLen; ++i) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } - - /* Get our clock */ - clock = GetAskClock(Cmd, high, 1); - gtl = ClearGraph(0); - - bit = 0; - for (i = 0; i < (int)(gtl / clock); ++i) - { - hithigh = 0; - hitlow = 0; - first = 1; - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; ++j) - { - if (GraphBuffer[(i * clock) + j] == high) - hithigh = 1; - else if (GraphBuffer[(i * clock) + j] == low) - hitlow = 1; - /* it doesn't count if it's the first part of our read - because it's really just trailing from the last sequence */ - if (first && (hithigh || hitlow)) - hithigh = hitlow = 0; - else - first = 0; - - if (hithigh && hitlow) - break; - } - - /* If we didn't hit both high and low peaks, we had a bit transition */ - if (!hithigh || !hitlow) - bit ^= 1; - - AppendGraph(0, clock, bit); - } - - RepaintGraphWindow(); - return 0; + int i, j; + int bit; + int gtl; + int clock; + int low = 0; + int high = 0; + int hithigh, hitlow, first; + + /* Detect high and lows and clock */ + for (i = 0; i < GraphTraceLen; ++i) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } + + /* Get our clock */ + clock = GetAskClock(Cmd, high, 1); + gtl = ClearGraph(0); + + bit = 0; + for (i = 0; i < (int)(gtl / clock); ++i) + { + hithigh = 0; + hitlow = 0; + first = 1; + /* Find out if we hit both high and low peaks */ + for (j = 0; j < clock; ++j) + { + if (GraphBuffer[(i * clock) + j] == high) + hithigh = 1; + else if (GraphBuffer[(i * clock) + j] == low) + hitlow = 1; + /* it doesn't count if it's the first part of our read + because it's really just trailing from the last sequence */ + if (first && (hithigh || hitlow)) + hithigh = hitlow = 0; + else + first = 0; + + if (hithigh && hitlow) + break; + } + + /* If we didn't hit both high and low peaks, we had a bit transition */ + if (!hithigh || !hitlow) + bit ^= 1; + + AppendGraph(0, clock, bit); + } + + RepaintGraphWindow(); + return 0; } int CmdBuffClear(const char *Cmd) { - UsbCommand c = {CMD_BUFF_CLEAR}; - SendCommand(&c); - ClearGraph(true); - return 0; + UsbCommand c = {CMD_BUFF_CLEAR}; + SendCommand(&c); + ClearGraph(true); + return 0; } int CmdDec(const char *Cmd) { - for (int i = 0; i < (GraphTraceLen / 2); ++i) - GraphBuffer[i] = GraphBuffer[i * 2]; - GraphTraceLen /= 2; - PrintAndLog("decimated by 2"); - RepaintGraphWindow(); - return 0; + for (int i = 0; i < (GraphTraceLen / 2); ++i) + GraphBuffer[i] = GraphBuffer[i * 2]; + GraphTraceLen /= 2; + PrintAndLog("decimated by 2"); + RepaintGraphWindow(); + return 0; } /** * Undecimate - I'd call it 'interpolate', but we'll save that @@ -904,20 +1055,20 @@ int CmdUndec(const char *Cmd) 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; i127) - shiftedVal=127; - else if (shiftedVal<-127) - shiftedVal=-127; - GraphBuffer[i]= shiftedVal; - } - CmdNorm(""); - return 0; + int shift=0; + //set options from parameters entered with the command + sscanf(Cmd, "%i", &shift); + int shiftedVal=0; + for(int i = 0; i127) + shiftedVal=127; + else if (shiftedVal<-127) + shiftedVal=-127; + GraphBuffer[i]= shiftedVal; + } + CmdNorm(""); + return 0; } //by marshmellow @@ -926,27 +1077,27 @@ int CmdGraphShiftZero(const char *Cmd) //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=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; + int thresLen = 25; + sscanf(Cmd, "%i", &thresLen); + int shift = 127; + int shiftedVal=0; + for(int i = 1; i=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 */ @@ -986,61 +1137,60 @@ int CmdDetectClockRate(const char *Cmd) //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; + //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; + 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; + } + } + //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 @@ -1049,24 +1199,24 @@ int FSKrawDemod(const char *Cmd, bool verbose) //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] [fchigh] [fclow]"); - PrintAndLog(" [set clock as integer] optional, omit for autodetect."); - PrintAndLog(" , 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); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod fs [clock] [fchigh] [fclow]"); + PrintAndLog(" [set clock as integer] optional, omit for autodetect."); + PrintAndLog(" , 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) @@ -1074,85 +1224,85 @@ int CmdFSKrawdemod(const char *Cmd) //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; + //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 @@ -1160,48 +1310,48 @@ int CmdFSKdemodHID(const char *Cmd) //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; + //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 @@ -1209,78 +1359,90 @@ 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) { - 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 - PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - setDemodBuf(BitStream,64,idx); - if (g_debugMode){ - PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64); - printDemodBuff(); - } - return 1; + //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; } //by marshmellow @@ -1289,100 +1451,100 @@ int CmdFSKdemodIO(const char *Cmd) int CmdFSKdemodAWID(const char *Cmd) { - //int verbose=1; - //sscanf(Cmd, "%i", &verbose); - - //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; - - //get binary from fsk wave - int idx = AWIDdemodFSK(BitStream, &size); - if (idx<=0){ - if (g_debugMode==1){ - if (idx == -1) - PrintAndLog("DEBUG: Error - not enough samples"); - else if (idx == -2) - PrintAndLog("DEBUG: Error - only noise found"); - else if (idx == -3) - PrintAndLog("DEBUG: Error - problem during FSK demod"); - else if (idx == -4) - PrintAndLog("DEBUG: Error - AWID preamble not found"); - else if (idx == -5) - PrintAndLog("DEBUG: Error - Size not correct: %d", size); - else - PrintAndLog("DEBUG: Error %d",idx); - } - return 0; - } - - // Index map - // 0 10 20 30 40 50 60 - // | | | | | | | - // 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 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 - // f = facility code, c = card number - // w = wiegand parity - // (26 bit format shown) + //int verbose=1; + //sscanf(Cmd, "%i", &verbose); + + //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; + + //get binary from fsk wave + int idx = AWIDdemodFSK(BitStream, &size); + if (idx<=0){ + if (g_debugMode==1){ + if (idx == -1) + PrintAndLog("DEBUG: Error - not enough samples"); + else if (idx == -2) + PrintAndLog("DEBUG: Error - only noise found"); + else if (idx == -3) + PrintAndLog("DEBUG: Error - problem during FSK demod"); + else if (idx == -4) + PrintAndLog("DEBUG: Error - AWID preamble not found"); + else if (idx == -5) + PrintAndLog("DEBUG: Error - Size not correct: %d", size); + else + PrintAndLog("DEBUG: Error %d",idx); + } + return 0; + } + + // Index map + // 0 10 20 30 40 50 60 + // | | | | | | | + // 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 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 + // f = facility code, c = card number + // w = wiegand parity + // (26 bit format shown) - //get raw ID before removing parities - 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); - setDemodBuf(BitStream,96,idx); - - size = removeParity(BitStream, idx+8, 4, 1, 88); - if (size != 66){ - if (g_debugMode==1) PrintAndLog("DEBUG: Error - at parity check-tag size does not match AWID format"); - return 0; - } - // ok valid card found! - - // Index map - // 0 10 20 30 40 50 60 - // | | | | | | | - // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456 - // ----------------------------------------------------------------------------- - // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000 - // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - // |26 bit| |-117--| |-----142------| - // b = format bit len, o = odd parity of last 3 bits - // f = facility code, c = card number - // w = wiegand parity - // (26 bit format shown) - - uint32_t fc = 0; - uint32_t cardnum = 0; - uint32_t code1 = 0; - uint32_t code2 = 0; - uint8_t fmtLen = bytebits_to_byte(BitStream,8); - if (fmtLen==26){ - fc = bytebits_to_byte(BitStream+9, 8); - cardnum = bytebits_to_byte(BitStream+17, 16); - code1 = bytebits_to_byte(BitStream+8,fmtLen); - PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); - } else { - cardnum = bytebits_to_byte(BitStream+8+(fmtLen-17), 16); - if (fmtLen>32){ - code1 = bytebits_to_byte(BitStream+8,fmtLen-32); - code2 = bytebits_to_byte(BitStream+8+(fmtLen-32),32); - PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); - } else{ - code1 = bytebits_to_byte(BitStream+8,fmtLen); - PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); - } - } - if (g_debugMode){ - PrintAndLog("DEBUG: idx: %d, Len: %d Printing Demod Buffer:", idx, 96); - printDemodBuff(); - } - //todo - convert hi2, hi, lo to demodbuffer for future sim/clone commands - return 1; + //get raw ID before removing parities + 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); + setDemodBuf(BitStream,96,idx); + + size = removeParity(BitStream, idx+8, 4, 1, 88); + if (size != 66){ + if (g_debugMode==1) PrintAndLog("DEBUG: Error - at parity check-tag size does not match AWID format"); + return 0; + } + // ok valid card found! + + // Index map + // 0 10 20 30 40 50 60 + // | | | | | | | + // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456 + // ----------------------------------------------------------------------------- + // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000 + // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + // |26 bit| |-117--| |-----142------| + // b = format bit len, o = odd parity of last 3 bits + // f = facility code, c = card number + // w = wiegand parity + // (26 bit format shown) + + uint32_t fc = 0; + uint32_t cardnum = 0; + uint32_t code1 = 0; + uint32_t code2 = 0; + uint8_t fmtLen = bytebits_to_byte(BitStream,8); + if (fmtLen==26){ + fc = bytebits_to_byte(BitStream+9, 8); + cardnum = bytebits_to_byte(BitStream+17, 16); + code1 = bytebits_to_byte(BitStream+8,fmtLen); + PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); + } else { + cardnum = bytebits_to_byte(BitStream+8+(fmtLen-17), 16); + if (fmtLen>32){ + code1 = bytebits_to_byte(BitStream+8,fmtLen-32); + code2 = bytebits_to_byte(BitStream+8+(fmtLen-32),32); + PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); + } else{ + code1 = bytebits_to_byte(BitStream+8,fmtLen); + PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); + } + } + if (g_debugMode){ + PrintAndLog("DEBUG: idx: %d, Len: %d Printing Demod Buffer:", idx, 96); + printDemodBuff(); + } + //todo - convert hi2, hi, lo to demodbuffer for future sim/clone commands + return 1; } //by marshmellow @@ -1390,281 +1552,302 @@ int CmdFSKdemodAWID(const char *Cmd) //print full Farpointe Data/Pyramid Prox ID and some bit format details if found int CmdFSKdemodPyramid(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; - - //get binary from fsk wave - int idx = PyramiddemodFSK(BitStream, &size); - if (idx < 0){ - if (g_debugMode==1){ - if (idx == -5) - PrintAndLog("DEBUG: Error - not enough samples"); - else if (idx == -1) - PrintAndLog("DEBUG: Error - only noise found"); - else if (idx == -2) - PrintAndLog("DEBUG: Error - problem during FSK demod"); - else if (idx == -3) - PrintAndLog("DEBUG: Error - Size not correct: %d", size); - else if (idx == -4) - PrintAndLog("DEBUG: Error - Pyramid preamble not found"); - else - PrintAndLog("DEBUG: Error - idx: %d",idx); - } - return 0; - } - // Index map - // 0 10 20 30 40 50 60 - // | | | | | | | - // 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 - // ----------------------------------------------------------------------------- - // 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 - // premable xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o - - // 64 70 80 90 100 110 120 - // | | | | | | | - // 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 - // ----------------------------------------------------------------------------- - // 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0 - // xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o - // |---115---||---------71---------| - // s = format start bit, o = odd parity of last 7 bits - // f = facility code, c = card number - // w = wiegand parity, x = extra space for other formats - // p = unknown checksum - // (26 bit format shown) - - //get raw ID before removing parities - uint32_t rawLo = bytebits_to_byte(BitStream+idx+96,32); - uint32_t rawHi = bytebits_to_byte(BitStream+idx+64,32); - uint32_t rawHi2 = bytebits_to_byte(BitStream+idx+32,32); - uint32_t rawHi3 = bytebits_to_byte(BitStream+idx,32); - setDemodBuf(BitStream,128,idx); - - size = removeParity(BitStream, idx+8, 8, 1, 120); - if (size != 105){ - if (g_debugMode==1) PrintAndLog("DEBUG: Error at parity check-tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3); - return 0; - } - - // ok valid card found! - - // Index map - // 0 10 20 30 40 50 60 70 - // | | | | | | | | - // 01234567890123456789012345678901234567890123456789012345678901234567890 - // ----------------------------------------------------------------------- - // 00000000000000000000000000000000000000000000000000000000000000000000000 - // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - - // 71 80 90 100 - // | | | | - // 1 2 34567890 1234567890123456 7 8901234 - // --------------------------------------- - // 1 1 01110011 0000000001000110 0 1001010 - // s w ffffffff cccccccccccccccc w ppppppp - // |--115-| |------71------| - // s = format start bit, o = odd parity of last 7 bits - // f = facility code, c = card number - // w = wiegand parity, x = extra space for other formats - // p = unknown checksum - // (26 bit format shown) - - //find start bit to get fmtLen - int j; - for (j=0; j32){ - //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32); - //code2 = bytebits_to_byte(BitStream+(size-32),32); - PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); - } else{ - //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen); - PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); - } - } - if (g_debugMode){ - PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128); - printDemodBuff(); - } - return 1; + //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; + + //get binary from fsk wave + int idx = PyramiddemodFSK(BitStream, &size); + if (idx < 0){ + if (g_debugMode==1){ + if (idx == -5) + PrintAndLog("DEBUG: Error - not enough samples"); + else if (idx == -1) + PrintAndLog("DEBUG: Error - only noise found"); + else if (idx == -2) + PrintAndLog("DEBUG: Error - problem during FSK demod"); + else if (idx == -3) + PrintAndLog("DEBUG: Error - Size not correct: %d", size); + else if (idx == -4) + PrintAndLog("DEBUG: Error - Pyramid preamble not found"); + else + PrintAndLog("DEBUG: Error - idx: %d",idx); + } + return 0; + } + // Index map + // 0 10 20 30 40 50 60 + // | | | | | | | + // 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 + // ----------------------------------------------------------------------------- + // 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 + // premable xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o + + // 64 70 80 90 100 110 120 + // | | | | | | | + // 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 + // ----------------------------------------------------------------------------- + // 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0 + // xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o + // |---115---||---------71---------| + // s = format start bit, o = odd parity of last 7 bits + // f = facility code, c = card number + // w = wiegand parity, x = extra space for other formats + // p = unknown checksum + // (26 bit format shown) + + //get bytes for checksum calc + uint8_t checksum = bytebits_to_byte(BitStream + idx + 120, 8); + uint8_t csBuff[14] = {0x00}; + for (uint8_t i = 0; i < 13; i++){ + csBuff[i] = bytebits_to_byte(BitStream + idx + 16 + (i*8), 8); + } + //check checksum calc + //checksum calc thanks to ICEMAN!! + uint32_t checkCS = CRC8Maxim(csBuff,13); + + //get raw ID before removing parities + uint32_t rawLo = bytebits_to_byte(BitStream+idx+96,32); + uint32_t rawHi = bytebits_to_byte(BitStream+idx+64,32); + uint32_t rawHi2 = bytebits_to_byte(BitStream+idx+32,32); + uint32_t rawHi3 = bytebits_to_byte(BitStream+idx,32); + setDemodBuf(BitStream,128,idx); + + size = removeParity(BitStream, idx+8, 8, 1, 120); + if (size != 105){ + if (g_debugMode==1) + PrintAndLog("DEBUG: Error at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3); + return 0; + } + + // ok valid card found! + + // Index map + // 0 10 20 30 40 50 60 70 + // | | | | | | | | + // 01234567890123456789012345678901234567890123456789012345678901234567890 + // ----------------------------------------------------------------------- + // 00000000000000000000000000000000000000000000000000000000000000000000000 + // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + // 71 80 90 100 + // | | | | + // 1 2 34567890 1234567890123456 7 8901234 + // --------------------------------------- + // 1 1 01110011 0000000001000110 0 1001010 + // s w ffffffff cccccccccccccccc w ppppppp + // |--115-| |------71------| + // s = format start bit, o = odd parity of last 7 bits + // f = facility code, c = card number + // w = wiegand parity, x = extra space for other formats + // p = unknown checksum + // (26 bit format shown) + + //find start bit to get fmtLen + int j; + for (j=0; j32){ + //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32); + //code2 = bytebits_to_byte(BitStream+(size-32),32); + PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); + } else{ + //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen); + PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); + } + } + if (checksum == checkCS) + PrintAndLog("Checksum %02x passed", checksum); + else + PrintAndLog("Checksum %02x failed - should have been %02x", checksum, checkCS); + + if (g_debugMode){ + PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128); + printDemodBuff(); + } + return 1; } int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating { - static const int LowTone[] = { - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1 - }; - static const int HighTone[] = { - 1, 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, -1, - }; - - int lowLen = sizeof (LowTone) / sizeof (int); - int highLen = sizeof (HighTone) / sizeof (int); - int convLen = (highLen > lowLen) ? highLen : lowLen; - uint32_t hi = 0, lo = 0; - - int i, j; - int minMark = 0, maxMark = 0; - - for (i = 0; i < GraphTraceLen - convLen; ++i) { - int lowSum = 0, highSum = 0; - - for (j = 0; j < lowLen; ++j) { - lowSum += LowTone[j]*GraphBuffer[i+j]; - } - for (j = 0; j < highLen; ++j) { - highSum += HighTone[j] * GraphBuffer[i + j]; - } - lowSum = abs(100 * lowSum / lowLen); - highSum = abs(100 * highSum / highLen); - GraphBuffer[i] = (highSum << 16) | lowSum; - } - - for(i = 0; i < GraphTraceLen - convLen - 16; ++i) { - int lowTot = 0, highTot = 0; - // 10 and 8 are f_s divided by f_l and f_h, rounded - for (j = 0; j < 10; ++j) { - lowTot += (GraphBuffer[i+j] & 0xffff); - } - for (j = 0; j < 8; j++) { - highTot += (GraphBuffer[i + j] >> 16); - } - GraphBuffer[i] = lowTot - highTot; - if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i]; - if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i]; - } - - GraphTraceLen -= (convLen + 16); - RepaintGraphWindow(); - - // Find bit-sync (3 lo followed by 3 high) (HID ONLY) - int max = 0, maxPos = 0; - for (i = 0; i < 6000; ++i) { - int dec = 0; - for (j = 0; j < 3 * lowLen; ++j) { - dec -= GraphBuffer[i + j]; - } - for (; j < 3 * (lowLen + highLen ); ++j) { - dec += GraphBuffer[i + j]; - } - if (dec > max) { - max = dec; - maxPos = i; - } - } - - // place start of bit sync marker in graph - GraphBuffer[maxPos] = maxMark; - GraphBuffer[maxPos + 1] = minMark; - - maxPos += j; - - // place end of bit sync marker in graph - GraphBuffer[maxPos] = maxMark; - GraphBuffer[maxPos+1] = minMark; - - PrintAndLog("actual data bits start at sample %d", maxPos); - PrintAndLog("length %d/%d", highLen, lowLen); - - uint8_t bits[46] = {0x00}; - - // find bit pairs and manchester decode them - for (i = 0; i < arraylen(bits) - 1; ++i) { - int dec = 0; - for (j = 0; j < lowLen; ++j) { - dec -= GraphBuffer[maxPos + j]; - } - for (; j < lowLen + highLen; ++j) { - dec += GraphBuffer[maxPos + j]; - } - maxPos += j; - // place inter bit marker in graph - GraphBuffer[maxPos] = maxMark; - GraphBuffer[maxPos + 1] = minMark; - - // hi and lo form a 64 bit pair - hi = (hi << 1) | (lo >> 31); - lo = (lo << 1); - // store decoded bit as binary (in hi/lo) and text (in bits[]) - if(dec < 0) { - bits[i] = '1'; - lo |= 1; - } else { - bits[i] = '0'; - } - } - PrintAndLog("bits: '%s'", bits); - PrintAndLog("hex: %08x %08x", hi, lo); - return 0; + static const int LowTone[] = { + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1 + }; + static const int HighTone[] = { + 1, 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, -1, + }; + + int lowLen = sizeof (LowTone) / sizeof (int); + int highLen = sizeof (HighTone) / sizeof (int); + int convLen = (highLen > lowLen) ? highLen : lowLen; + uint32_t hi = 0, lo = 0; + + int i, j; + int minMark = 0, maxMark = 0; + + for (i = 0; i < GraphTraceLen - convLen; ++i) { + int lowSum = 0, highSum = 0; + + for (j = 0; j < lowLen; ++j) { + lowSum += LowTone[j]*GraphBuffer[i+j]; + } + for (j = 0; j < highLen; ++j) { + highSum += HighTone[j] * GraphBuffer[i + j]; + } + lowSum = abs(100 * lowSum / lowLen); + highSum = abs(100 * highSum / highLen); + GraphBuffer[i] = (highSum << 16) | lowSum; + } + + for(i = 0; i < GraphTraceLen - convLen - 16; ++i) { + int lowTot = 0, highTot = 0; + // 10 and 8 are f_s divided by f_l and f_h, rounded + for (j = 0; j < 10; ++j) { + lowTot += (GraphBuffer[i+j] & 0xffff); + } + for (j = 0; j < 8; j++) { + highTot += (GraphBuffer[i + j] >> 16); + } + GraphBuffer[i] = lowTot - highTot; + if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i]; + if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i]; + } + + GraphTraceLen -= (convLen + 16); + RepaintGraphWindow(); + + // Find bit-sync (3 lo followed by 3 high) (HID ONLY) + int max = 0, maxPos = 0; + for (i = 0; i < 6000; ++i) { + int dec = 0; + for (j = 0; j < 3 * lowLen; ++j) { + dec -= GraphBuffer[i + j]; + } + for (; j < 3 * (lowLen + highLen ); ++j) { + dec += GraphBuffer[i + j]; + } + if (dec > max) { + max = dec; + maxPos = i; + } + } + + // place start of bit sync marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos + 1] = minMark; + + maxPos += j; + + // place end of bit sync marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos+1] = minMark; + + PrintAndLog("actual data bits start at sample %d", maxPos); + PrintAndLog("length %d/%d", highLen, lowLen); + + uint8_t bits[46] = {0x00}; + + // find bit pairs and manchester decode them + for (i = 0; i < arraylen(bits) - 1; ++i) { + int dec = 0; + for (j = 0; j < lowLen; ++j) { + dec -= GraphBuffer[maxPos + j]; + } + for (; j < lowLen + highLen; ++j) { + dec += GraphBuffer[maxPos + j]; + } + maxPos += j; + // place inter bit marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos + 1] = minMark; + + // hi and lo form a 64 bit pair + hi = (hi << 1) | (lo >> 31); + lo = (lo << 1); + // store decoded bit as binary (in hi/lo) and text (in bits[]) + if(dec < 0) { + bits[i] = '1'; + lo |= 1; + } else { + bits[i] = '0'; + } + } + PrintAndLog("bits: '%s'", bits); + PrintAndLog("hex: %08x %08x", hi, lo); + return 0; } //by marshmellow //attempt to psk1 demod graph buffer int PSKDemod(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) { - if (verbose) PrintAndLog("Invalid argument: %s", Cmd); - return -1; - } - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t BitLen = getFromGraphBuf(BitStream); - if (BitLen==0) return -1; - uint8_t carrier=countPSK_FC(BitStream, BitLen); - if (carrier!=2 && carrier!=4 && carrier!=8){ - //invalid carrier - return -1; - } - int errCnt=0; - errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert); - if (errCnt > maxErr){ - if (g_debugMode==1 && verbose) 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 && verbose) 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; + 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) { + if (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 -1; + uint8_t carrier=countFC(BitStream, BitLen, 0); + if (carrier!=2 && carrier!=4 && carrier!=8){ + //invalid carrier + return 0; + } + int errCnt=0; + errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert); + if (errCnt > maxErr){ + if (g_debugMode==1 && 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==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return 0; + } + if (verbose){ + PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + } + //prime demod buffer for output + setDemodBuf(BitStream,BitLen,0); + return 1; } // Indala 26 bit decode @@ -1679,7 +1862,7 @@ int CmdIndalaDecode(const char *Cmd) ans = PSKDemod("32", 0); } - if (ans < 0){ + if (!ans){ if (g_debugMode==1) PrintAndLog("Error1: %d",ans); return 0; @@ -1694,7 +1877,7 @@ int CmdIndalaDecode(const char *Cmd) char showbits[251]={0x00}; if (invert) if (g_debugMode==1) - PrintAndLog("Had to invert bits"); + PrintAndLog("Had to invert bits"); //convert UID to HEX uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; @@ -1755,63 +1938,61 @@ int CmdIndalaDecode(const char *Cmd) 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, maxErr); - if (errCnt > maxErr){ - if (g_debugMode==1 && 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==1 && verbose) 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 && verbose){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - } - if (verbose) { - PrintAndLog("NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - } - return 1; + 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, maxErr); + 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 77 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) > 10 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data rawdemod nr [clock] <0|1> [maxError]"); - PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); - PrintAndLog(" , 1 for invert output"); - PrintAndLog(" [set maximum allowed errors], default = 100."); - PrintAndLog(""); - PrintAndLog(" sample: data rawdemod nr = demod a nrz/direct tag from GraphBuffer"); - PrintAndLog(" : data rawdemod nr 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32"); - PrintAndLog(" : data rawdemod nr 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLog(" : data rawdemod nr 1 = demod a nrz/direct tag from GraphBuffer while inverting data"); - PrintAndLog(" : data rawdemod nr 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; - } - return NRZrawDemod(Cmd, TRUE); + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod nr [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data rawdemod nr = demod a nrz/direct tag from GraphBuffer"); + PrintAndLog(" : data rawdemod nr 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data rawdemod nr 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data rawdemod nr 1 = demod a nrz/direct tag from GraphBuffer while inverting data"); + PrintAndLog(" : data rawdemod nr 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; + } + return NRZrawDemod(Cmd, TRUE); } // by marshmellow @@ -1820,74 +2001,63 @@ int CmdNRZrawDemod(const char *Cmd) // 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 rawdemod p1 [clock] <0|1> [maxError]"); - PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); - PrintAndLog(" , 1 for invert output"); - PrintAndLog(" [set maximum allowed errors], default = 100."); - PrintAndLog(""); - PrintAndLog(" sample: data rawdemod p1 = demod a psk1 tag from GraphBuffer"); - PrintAndLog(" : data rawdemod p1 32 = demod a psk1 tag from GraphBuffer using a clock of RF/32"); - PrintAndLog(" : data rawdemod p1 32 1 = demod a psk1 tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLog(" : data rawdemod p1 1 = demod a psk1 tag from GraphBuffer while inverting data"); - PrintAndLog(" : data rawdemod p1 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, TRUE); - //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); - } - PrintAndLog("PSK demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - return 1; + int ans; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod p1 [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data rawdemod p1 = demod a psk1 tag from GraphBuffer"); + PrintAndLog(" : data rawdemod p1 32 = demod a psk1 tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data rawdemod p1 32 1 = demod a psk1 tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data rawdemod p1 1 = demod a psk1 tag from GraphBuffer while inverting data"); + PrintAndLog(" : data rawdemod p1 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + return 0; + } + ans = PSKDemod(Cmd, TRUE); + //output + if (!ans){ + if (g_debugMode) PrintAndLog("Error demoding: %d",ans); + return 0; + } + + 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 cmdpsk1rawdemod 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 rawdemod p2 [clock] <0|1> [maxError]"); - PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); - PrintAndLog(" , 1 for invert output"); - PrintAndLog(" [set maximum allowed errors], default = 100."); - PrintAndLog(""); - PrintAndLog(" sample: data rawdemod p2 = demod a psk2 tag from GraphBuffer, autodetect clock"); - PrintAndLog(" : data rawdemod p2 32 = demod a psk2 tag from GraphBuffer using a clock of RF/32"); - PrintAndLog(" : data rawdemod p2 32 1 = demod a psk2 tag from GraphBuffer using a clock of RF/32 and inverting output"); - PrintAndLog(" : data rawdemod p2 1 = demod a psk2 tag from GraphBuffer, autodetect clock and invert output"); - PrintAndLog(" : data rawdemod p2 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, TRUE); - 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; + int ans=0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod p2 [clock] <0|1> [maxError]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); + PrintAndLog(" , 1 for invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100."); + PrintAndLog(""); + PrintAndLog(" sample: data rawdemod p2 = demod a psk2 tag from GraphBuffer, autodetect clock"); + PrintAndLog(" : data rawdemod p2 32 = demod a psk2 tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data rawdemod p2 32 1 = demod a psk2 tag from GraphBuffer using a clock of RF/32 and inverting output"); + PrintAndLog(" : data rawdemod p2 1 = demod a psk2 tag from GraphBuffer, autodetect clock and invert output"); + PrintAndLog(" : data rawdemod p2 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors"); + return 0; + } + 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 @@ -1897,12 +2067,14 @@ int CmdRawDemod(const char *Cmd) if (strlen(Cmd) > 14 || cmdp == 'h' || cmdp == 'H' || strlen(Cmd)<2) { PrintAndLog("Usage: data rawdemod [modulation] |"); - PrintAndLog(" [modulation] as 2 char, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2"); + PrintAndLog(" [modulation] as 2 char, 'ab' for ask/biphase, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, ..."); + PrintAndLog(" 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2"); PrintAndLog(" as 'h', prints the help for the specific modulation"); PrintAndLog(" see specific modulation help for optional parameters"); PrintAndLog(""); - PrintAndLog(" sample: data rawdemod fs h = print help for ask/raw demod"); + PrintAndLog(" sample: data rawdemod fs h = print help specific to fsk demod"); PrintAndLog(" : data rawdemod fs = demod GraphBuffer using: fsk - autodetect"); + PrintAndLog(" : data rawdemod ab = demod GraphBuffer using: ask/biphase - autodetect"); PrintAndLog(" : data rawdemod am = demod GraphBuffer using: ask/manchester - autodetect"); PrintAndLog(" : data rawdemod ar = demod GraphBuffer using: ask/raw - autodetect"); PrintAndLog(" : data rawdemod nr = demod GraphBuffer using: nrz/direct - autodetect"); @@ -1913,17 +2085,19 @@ int CmdRawDemod(const char *Cmd) char cmdp2 = Cmd[1]; int ans = 0; if (cmdp == 'f' && cmdp2 == 's'){ - ans = CmdFSKrawdemod(Cmd+3); + ans = CmdFSKrawdemod(Cmd+2); + } else if(cmdp == 'a' && cmdp2 == 'b'){ + ans = Cmdaskbiphdemod(Cmd+2); } else if(cmdp == 'a' && cmdp2 == 'm'){ - ans = Cmdaskmandemod(Cmd+3); + ans = Cmdaskmandemod(Cmd+2); } else if(cmdp == 'a' && cmdp2 == 'r'){ - ans = Cmdaskrawdemod(Cmd+3); + ans = Cmdaskrawdemod(Cmd+2); } else if(cmdp == 'n' && cmdp2 == 'r'){ - ans = CmdNRZrawDemod(Cmd+3); + ans = CmdNRZrawDemod(Cmd+2); } else if(cmdp == 'p' && cmdp2 == '1'){ - ans = CmdPSK1rawDemod(Cmd+3); + ans = CmdPSK1rawDemod(Cmd+2); } else if(cmdp == 'p' && cmdp2 == '2'){ - ans = CmdPSK2rawDemod(Cmd+3); + ans = CmdPSK2rawDemod(Cmd+2); } else { PrintAndLog("unknown modulation entered - see help ('h') for parameter structure"); } @@ -1932,76 +2106,76 @@ int CmdRawDemod(const char *Cmd) int CmdGrid(const char *Cmd) { - sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); - PlotGridXdefault= PlotGridX; - PlotGridYdefault= PlotGridY; - RepaintGraphWindow(); - return 0; + 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, + > %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; + 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, + > %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; } int CmdHide(const char *Cmd) { - HideGraphWindow(); - return 0; + HideGraphWindow(); + return 0; } //zero mean GraphBuffer int CmdHpf(const char *Cmd) { - int i; - int accum = 0; + int i; + int accum = 0; - for (i = 10; i < GraphTraceLen; ++i) - accum += GraphBuffer[i]; - accum /= (GraphTraceLen - 10); - for (i = 0; i < GraphTraceLen; ++i) - GraphBuffer[i] -= accum; + for (i = 10; i < GraphTraceLen; ++i) + accum += GraphBuffer[i]; + accum /= (GraphTraceLen - 10); + for (i = 0; i < GraphTraceLen; ++i) + GraphBuffer[i] -= accum; - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } typedef struct { uint8_t * buffer; @@ -2027,15 +2201,17 @@ uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b) return val; } -int CmdSamples(const char *Cmd) +int getSamples(const char *Cmd, bool silent) { //If we get all but the last byte in bigbuf, // we don't have to worry about remaining trash // in the last byte in case the bits-per-sample // does not line up on byte boundaries + uint8_t got[BIGBUF_SIZE-1] = { 0 }; int n = strtol(Cmd, NULL, 0); + if (n == 0) n = sizeof(got); @@ -2054,7 +2230,7 @@ int CmdSamples(const char *Cmd) { sample_config *sc = (sample_config *) response.d.asBytes; PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample - , sc->decimation); + , sc->decimation); bits_per_sample = sc->bits_per_sample; } if(bits_per_sample < 8) @@ -2080,6 +2256,11 @@ int CmdSamples(const char *Cmd) return 0; } +int CmdSamples(const char *Cmd) +{ + return getSamples(Cmd, false); +} + int CmdTuneSamples(const char *Cmd) { int timeout = 0; @@ -2142,52 +2323,52 @@ int CmdTuneSamples(const char *Cmd) int CmdLoad(const char *Cmd) { - char filename[FILE_PATH_SIZE] = {0x00}; - int len = 0; + char filename[FILE_PATH_SIZE] = {0x00}; + int len = 0; - len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); + len = strlen(Cmd); + if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; + memcpy(filename, Cmd, len); - FILE *f = fopen(filename, "r"); - if (!f) { - PrintAndLog("couldn't open '%s'", filename); - return 0; - } - - GraphTraceLen = 0; - char line[80]; - while (fgets(line, sizeof (line), f)) { - GraphBuffer[GraphTraceLen] = atoi(line); - GraphTraceLen++; - } - fclose(f); - PrintAndLog("loaded %d samples", GraphTraceLen); - RepaintGraphWindow(); - return 0; + FILE *f = fopen(filename, "r"); + if (!f) { + PrintAndLog("couldn't open '%s'", filename); + return 0; + } + + GraphTraceLen = 0; + char line[80]; + while (fgets(line, sizeof (line), f)) { + GraphBuffer[GraphTraceLen] = atoi(line); + GraphTraceLen++; + } + fclose(f); + PrintAndLog("loaded %d samples", GraphTraceLen); + RepaintGraphWindow(); + return 0; } int CmdLtrim(const char *Cmd) { - int ds = atoi(Cmd); + int ds = atoi(Cmd); - for (int i = ds; i < GraphTraceLen; ++i) - GraphBuffer[i-ds] = GraphBuffer[i]; - GraphTraceLen -= ds; + for (int i = ds; i < GraphTraceLen; ++i) + GraphBuffer[i-ds] = GraphBuffer[i]; + GraphTraceLen -= ds; - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } // trim graph to input argument length int CmdRtrim(const char *Cmd) { - int ds = atoi(Cmd); + int ds = atoi(Cmd); - GraphTraceLen = ds; + GraphTraceLen = ds; - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } /* @@ -2205,439 +2386,431 @@ int CmdRtrim(const char *Cmd) */ int CmdManchesterDemod(const char *Cmd) { - int i, j, invert= 0; - int bit; - int clock; - int lastval = 0; - int low = 0; - int high = 0; - int hithigh, hitlow, first; - int lc = 0; - int bitidx = 0; - int bit2idx = 0; - int warnings = 0; - - /* check if we're inverting output */ - if (*Cmd == 'i') - { - PrintAndLog("Inverting output"); - invert = 1; - ++Cmd; - do - ++Cmd; - while(*Cmd == ' '); // in case a 2nd argument was given - } - - /* Holds the decoded bitstream: each clock period contains 2 bits */ - /* later simplified to 1 bit after manchester decoding. */ - /* Add 10 bits to allow for noisy / uncertain traces without aborting */ - /* int BitStream[GraphTraceLen*2/clock+10]; */ - - /* But it does not work if compiling on WIndows: therefore we just allocate a */ - /* large array */ - uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0}; - - /* Detect high and lows */ - for (i = 0; i < GraphTraceLen; i++) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } - - /* Get our clock */ - clock = GetAskClock(Cmd, high, 1); - - int tolerance = clock/4; - - /* Detect first transition */ - /* Lo-Hi (arbitrary) */ - /* skip to the first high */ - for (i= 0; i < GraphTraceLen; i++) - if (GraphBuffer[i] == high) - break; - /* now look for the first low */ - for (; i < GraphTraceLen; i++) - { - if (GraphBuffer[i] == low) - { - lastval = i; - break; - } - } - - /* If we're not working with 1/0s, demod based off clock */ - if (high != 1) - { - bit = 0; /* We assume the 1st bit is zero, it may not be - * the case: this routine (I think) has an init problem. - * Ed. - */ - for (; i < (int)(GraphTraceLen / clock); i++) - { - hithigh = 0; - hitlow = 0; - first = 1; - - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; j++) - { - if (GraphBuffer[(i * clock) + j] == high) - hithigh = 1; - else if (GraphBuffer[(i * clock) + j] == low) - hitlow = 1; - - /* it doesn't count if it's the first part of our read - because it's really just trailing from the last sequence */ - if (first && (hithigh || hitlow)) - hithigh = hitlow = 0; - else - first = 0; - - if (hithigh && hitlow) - break; - } - - /* If we didn't hit both high and low peaks, we had a bit transition */ - if (!hithigh || !hitlow) - bit ^= 1; - - BitStream[bit2idx++] = bit ^ invert; - } - } - - /* standard 1/0 bitstream */ - else - { - - /* Then detect duration between 2 successive transitions */ - for (bitidx = 1; i < GraphTraceLen; i++) - { - if (GraphBuffer[i-1] != GraphBuffer[i]) - { - lc = i-lastval; - lastval = i; - - // Error check: if bitidx becomes too large, we do not - // have a Manchester encoded bitstream or the clock is really - // wrong! - if (bitidx > (GraphTraceLen*2/clock+8) ) { - PrintAndLog("Error: the clock you gave is probably wrong, aborting."); - return 0; - } - // Then switch depending on lc length: - // Tolerance is 1/4 of clock rate (arbitrary) - if (abs(lc-clock/2) < tolerance) { - // Short pulse : either "1" or "0" - BitStream[bitidx++]=GraphBuffer[i-1]; - } else if (abs(lc-clock) < tolerance) { - // Long pulse: either "11" or "00" - BitStream[bitidx++]=GraphBuffer[i-1]; - BitStream[bitidx++]=GraphBuffer[i-1]; - } else { - // Error - warnings++; - PrintAndLog("Warning: Manchester decode error for pulse width detection."); - PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); - - if (warnings > 10) - { - PrintAndLog("Error: too many detection errors, aborting."); - return 0; - } - } - } - } - - // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream - // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful - // to stop output at the final bitidx2 value, not bitidx - for (i = 0; i < bitidx; i += 2) { - if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) { - BitStream[bit2idx++] = 1 ^ invert; - } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { - BitStream[bit2idx++] = 0 ^ invert; - } else { - // We cannot end up in this state, this means we are unsynchronized, - // move up 1 bit: - i++; - warnings++; - PrintAndLog("Unsynchronized, resync..."); - PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); - - if (warnings > 10) - { - PrintAndLog("Error: too many decode errors, aborting."); - return 0; - } - } - } - } - - PrintAndLog("Manchester decoded bitstream"); - // Now output the bitstream to the scrollback by line of 16 bits - for (i = 0; i < (bit2idx-16); i+=16) { - PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15]); - } - return 0; + int i, j, invert= 0; + int bit; + int clock; + int lastval = 0; + int low = 0; + int high = 0; + int hithigh, hitlow, first; + int lc = 0; + int bitidx = 0; + int bit2idx = 0; + int warnings = 0; + + /* check if we're inverting output */ + if (*Cmd == 'i') + { + PrintAndLog("Inverting output"); + invert = 1; + ++Cmd; + do + ++Cmd; + while(*Cmd == ' '); // in case a 2nd argument was given + } + + /* Holds the decoded bitstream: each clock period contains 2 bits */ + /* later simplified to 1 bit after manchester decoding. */ + /* Add 10 bits to allow for noisy / uncertain traces without aborting */ + /* int BitStream[GraphTraceLen*2/clock+10]; */ + + /* But it does not work if compiling on WIndows: therefore we just allocate a */ + /* large array */ + uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0}; + + /* Detect high and lows */ + for (i = 0; i < GraphTraceLen; i++) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } + + /* Get our clock */ + clock = GetAskClock(Cmd, high, 1); + + int tolerance = clock/4; + + /* Detect first transition */ + /* Lo-Hi (arbitrary) */ + /* skip to the first high */ + for (i= 0; i < GraphTraceLen; i++) + if (GraphBuffer[i] == high) + break; + /* now look for the first low */ + for (; i < GraphTraceLen; i++) + { + if (GraphBuffer[i] == low) + { + lastval = i; + break; + } + } + + /* If we're not working with 1/0s, demod based off clock */ + if (high != 1) + { + bit = 0; /* We assume the 1st bit is zero, it may not be + * the case: this routine (I think) has an init problem. + * Ed. + */ + for (; i < (int)(GraphTraceLen / clock); i++) + { + hithigh = 0; + hitlow = 0; + first = 1; + + /* Find out if we hit both high and low peaks */ + for (j = 0; j < clock; j++) + { + if (GraphBuffer[(i * clock) + j] == high) + hithigh = 1; + else if (GraphBuffer[(i * clock) + j] == low) + hitlow = 1; + + /* it doesn't count if it's the first part of our read + because it's really just trailing from the last sequence */ + if (first && (hithigh || hitlow)) + hithigh = hitlow = 0; + else + first = 0; + + if (hithigh && hitlow) + break; + } + + /* If we didn't hit both high and low peaks, we had a bit transition */ + if (!hithigh || !hitlow) + bit ^= 1; + + BitStream[bit2idx++] = bit ^ invert; + } + } + + /* standard 1/0 bitstream */ + else + { + + /* Then detect duration between 2 successive transitions */ + for (bitidx = 1; i < GraphTraceLen; i++) + { + if (GraphBuffer[i-1] != GraphBuffer[i]) + { + lc = i-lastval; + lastval = i; + + // Error check: if bitidx becomes too large, we do not + // have a Manchester encoded bitstream or the clock is really + // wrong! + if (bitidx > (GraphTraceLen*2/clock+8) ) { + PrintAndLog("Error: the clock you gave is probably wrong, aborting."); + return 0; + } + // Then switch depending on lc length: + // Tolerance is 1/4 of clock rate (arbitrary) + if (abs(lc-clock/2) < tolerance) { + // Short pulse : either "1" or "0" + BitStream[bitidx++]=GraphBuffer[i-1]; + } else if (abs(lc-clock) < tolerance) { + // Long pulse: either "11" or "00" + BitStream[bitidx++]=GraphBuffer[i-1]; + BitStream[bitidx++]=GraphBuffer[i-1]; + } else { + // Error + warnings++; + PrintAndLog("Warning: Manchester decode error for pulse width detection."); + PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); + + if (warnings > 10) + { + PrintAndLog("Error: too many detection errors, aborting."); + return 0; + } + } + } + } + + // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream + // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful + // to stop output at the final bitidx2 value, not bitidx + for (i = 0; i < bitidx; i += 2) { + if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) { + BitStream[bit2idx++] = 1 ^ invert; + } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { + BitStream[bit2idx++] = 0 ^ invert; + } else { + // We cannot end up in this state, this means we are unsynchronized, + // move up 1 bit: + i++; + warnings++; + PrintAndLog("Unsynchronized, resync..."); + PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); + + if (warnings > 10) + { + PrintAndLog("Error: too many decode errors, aborting."); + return 0; + } + } + } + } + + PrintAndLog("Manchester decoded bitstream"); + // Now output the bitstream to the scrollback by line of 16 bits + for (i = 0; i < (bit2idx-16); i+=16) { + PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", + BitStream[i], + BitStream[i+1], + BitStream[i+2], + BitStream[i+3], + BitStream[i+4], + BitStream[i+5], + BitStream[i+6], + BitStream[i+7], + BitStream[i+8], + BitStream[i+9], + BitStream[i+10], + BitStream[i+11], + BitStream[i+12], + BitStream[i+13], + BitStream[i+14], + BitStream[i+15]); + } + return 0; } /* Modulate our data into manchester */ int CmdManchesterMod(const char *Cmd) { - int i, j; - int clock; - int bit, lastbit, wave; + int i, j; + int clock; + int bit, lastbit, wave; - /* Get our clock */ - clock = GetAskClock(Cmd, 0, 1); + /* Get our clock */ + clock = GetAskClock(Cmd, 0, 1); - wave = 0; - lastbit = 1; - for (i = 0; i < (int)(GraphTraceLen / clock); i++) - { - bit = GraphBuffer[i * clock] ^ 1; + wave = 0; + lastbit = 1; + for (i = 0; i < (int)(GraphTraceLen / clock); i++) + { + bit = GraphBuffer[i * clock] ^ 1; - for (j = 0; j < (int)(clock/2); j++) - GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave; - for (j = (int)(clock/2); j < clock; j++) - GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1; + for (j = 0; j < (int)(clock/2); j++) + GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave; + for (j = (int)(clock/2); j < clock; j++) + GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1; - /* Keep track of how we start our wave and if we changed or not this time */ - wave ^= bit ^ lastbit; - lastbit = bit; - } + /* Keep track of how we start our wave and if we changed or not this time */ + wave ^= bit ^ lastbit; + lastbit = bit; + } - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdNorm(const char *Cmd) { - int i; - int max = INT_MIN, min = INT_MAX; + int i; + int max = INT_MIN, min = INT_MAX; - for (i = 10; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] > max) - max = GraphBuffer[i]; - if (GraphBuffer[i] < min) - min = GraphBuffer[i]; - } + for (i = 10; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] > max) + max = GraphBuffer[i]; + if (GraphBuffer[i] < min) + min = GraphBuffer[i]; + } - if (max != min) { - for (i = 0; i < GraphTraceLen; ++i) { + if (max != min) { + for (i = 0; i < GraphTraceLen; ++i) { GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 / - (max - min); + (max - min); //marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work - } - } - RepaintGraphWindow(); - return 0; + } + } + RepaintGraphWindow(); + return 0; } int CmdPlot(const char *Cmd) { - ShowGraphWindow(); - return 0; + ShowGraphWindow(); + return 0; } int CmdSave(const char *Cmd) { - char filename[FILE_PATH_SIZE] = {0x00}; - int len = 0; + char filename[FILE_PATH_SIZE] = {0x00}; + int len = 0; - len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); - + len = strlen(Cmd); + if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; + memcpy(filename, Cmd, len); + - FILE *f = fopen(filename, "w"); - if(!f) { - PrintAndLog("couldn't open '%s'", filename); - return 0; - } - int i; - for (i = 0; i < GraphTraceLen; i++) { - fprintf(f, "%d\n", GraphBuffer[i]); - } - fclose(f); - PrintAndLog("saved to '%s'", Cmd); - return 0; + FILE *f = fopen(filename, "w"); + if(!f) { + PrintAndLog("couldn't open '%s'", filename); + return 0; + } + int i; + for (i = 0; i < GraphTraceLen; i++) { + fprintf(f, "%d\n", GraphBuffer[i]); + } + fclose(f); + PrintAndLog("saved to '%s'", Cmd); + return 0; } int CmdScale(const char *Cmd) { - CursorScaleFactor = atoi(Cmd); - if (CursorScaleFactor == 0) { - PrintAndLog("bad, can't have zero scale"); - CursorScaleFactor = 1; - } - RepaintGraphWindow(); - return 0; + CursorScaleFactor = atoi(Cmd); + if (CursorScaleFactor == 0) { + PrintAndLog("bad, can't have zero scale"); + CursorScaleFactor = 1; + } + RepaintGraphWindow(); + return 0; } int CmdThreshold(const char *Cmd) { - int threshold = atoi(Cmd); + int threshold = atoi(Cmd); - for (int i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] >= threshold) - GraphBuffer[i] = 1; - else - GraphBuffer[i] = -1; - } - RepaintGraphWindow(); - return 0; + for (int i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] >= threshold) + GraphBuffer[i] = 1; + else + GraphBuffer[i] = -1; + } + RepaintGraphWindow(); + return 0; } int CmdDirectionalThreshold(const char *Cmd) { - int8_t upThres = param_get8(Cmd, 0); - int8_t downThres = param_get8(Cmd, 1); - - printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres); - - int lastValue = GraphBuffer[0]; - GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in. - - for (int i = 1; i < GraphTraceLen; ++i) { - // Apply first threshold to samples heading up - if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue) - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = 1; - } - // Apply second threshold to samples heading down - else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue) - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = -1; - } - else - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = GraphBuffer[i-1]; - - } - } - GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample. - RepaintGraphWindow(); - return 0; + int8_t upThres = param_get8(Cmd, 0); + int8_t downThres = param_get8(Cmd, 1); + + printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres); + + int lastValue = GraphBuffer[0]; + GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in. + + for (int i = 1; i < GraphTraceLen; ++i) { + // Apply first threshold to samples heading up + if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue) + { + lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. + GraphBuffer[i] = 1; + } + // Apply second threshold to samples heading down + else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue) + { + lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. + GraphBuffer[i] = -1; + } + else + { + lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. + GraphBuffer[i] = GraphBuffer[i-1]; + + } + } + GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample. + RepaintGraphWindow(); + return 0; } int CmdZerocrossings(const char *Cmd) { - // Zero-crossings aren't meaningful unless the signal is zero-mean. - CmdHpf(""); - - int sign = 1; - int zc = 0; - int lastZc = 0; - - for (int i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] * sign >= 0) { - // No change in sign, reproduce the previous sample count. - zc++; - GraphBuffer[i] = lastZc; - } else { - // Change in sign, reset the sample count. - sign = -sign; - GraphBuffer[i] = lastZc; - if (sign > 0) { - lastZc = zc; - zc = 0; - } - } - } - - RepaintGraphWindow(); - return 0; + // Zero-crossings aren't meaningful unless the signal is zero-mean. + CmdHpf(""); + + int sign = 1; + int zc = 0; + int lastZc = 0; + + for (int i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] * sign >= 0) { + // No change in sign, reproduce the previous sample count. + zc++; + GraphBuffer[i] = lastZc; + } else { + // Change in sign, reset the sample count. + sign = -sign; + GraphBuffer[i] = lastZc; + if (sign > 0) { + lastZc = zc; + zc = 0; + } + } + } + + RepaintGraphWindow(); + return 0; } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"amp", CmdAmp, 1, "Amplify peaks"}, - //{"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, - {"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 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"}, - //{"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"}, - //{"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"}, - {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, - {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"}, - {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, - //{"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, - {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, - {"dec", CmdDec, 1, "Decimate samples"}, - {"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"}, - //{"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, - {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK 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"}, - {"fskpyramiddemod",CmdFSKdemodPyramid,1, "Demodulate a Pyramid FSK tag from GraphBuffer"}, - {"fskparadoxdemod",CmdFSKdemodParadox,1, "Demodulate a Paradox FSK tag from GraphBuffer"}, - //{"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to bin (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"}, - {"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"}, - {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, - {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, - {"hide", CmdHide, 1, "Hide graph window"}, - {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, - {"load", CmdLoad, 1, " -- Load trace (to graph window"}, - {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, - {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, - //{"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, - {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream in DemodBuffer"}, - {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, - {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, - //{"nrzdetectclock",CmdDetectNRZClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, - //{"nrzrawdemod", CmdNRZrawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate nrz tags and output binary (args optional)"}, - {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, - //{"pskdetectclock",CmdDetectPSKClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, - {"printdemodbuffer",CmdPrintDemodBuff,1, "[x] -- 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)"}, - //{"psk1rawdemod", CmdPSK1rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk1 tags and output binary (args optional)"}, - //{"psk2rawdemod", CmdPSK2rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk2 tags and output binary (args optional)"}, - {"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"}, - {"shiftgraphzero",CmdGraphShiftZero, 1, " -- Shift 0 for Graphed wave + or - shift value"}, - //{"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, - {"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"}, - {"undec", CmdUndec, 1, "Un-decimate samples by 2"}, - {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"amp", CmdAmp, 1, "Amplify peaks"}, + //{"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, + {"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 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"}, + {"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"}, + {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"}, + {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, + //{"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, + {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, + {"dec", CmdDec, 1, "Decimate samples"}, + {"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"}, + //{"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, + {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK 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"}, + {"fskpyramiddemod", CmdFSKdemodPyramid, 1, "Demodulate a Pyramid FSK tag from GraphBuffer"}, + {"fskparadoxdemod", CmdFSKdemodParadox, 1, "Demodulate a Paradox FSK tag from GraphBuffer"}, + {"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"}, + {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, + {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, + {"hide", CmdHide, 1, "Hide graph window"}, + {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, + {"load", CmdLoad, 1, " -- Load trace (to graph window"}, + {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, + {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, + //{"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, + {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream in DemodBuffer"}, + {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, + {"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] -- 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)"}, + {"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"}, + {"shiftgraphzero", CmdGraphShiftZero, 1, " -- Shift 0 for Graphed wave + or - shift value"}, + //{"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, + {"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"}, + {"undec", CmdUndec, 1, "Un-decimate samples by 2"}, + {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, + {NULL, NULL, 0, NULL} }; int CmdData(const char *Cmd) { - CmdsParse(CommandTable, Cmd); - return 0; + CmdsParse(CommandTable, Cmd); + return 0; } int CmdHelp(const char *Cmd) { - CmdsHelp(CommandTable); - return 0; + CmdsHelp(CommandTable); + return 0; } diff --git a/client/cmddata.h b/client/cmddata.h index 6866bcb1..f6b4b950 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -23,6 +23,7 @@ int CmdAskEM410xDemod(const char *Cmd); int CmdG_Prox_II_Demod(const char *Cmd); int Cmdaskrawdemod(const char *Cmd); int Cmdaskmandemod(const char *Cmd); +int AutoCorrelate(int window, bool SaveGrph, bool verbose); int CmdAutoCorr(const char *Cmd); int CmdBiphaseDecodeRaw(const char *Cmd); int CmdBitsamples(const char *Cmd); @@ -62,11 +63,16 @@ int CmdThreshold(const char *Cmd); int CmdDirectionalThreshold(const char *Cmd); int CmdZerocrossings(const char *Cmd); int CmdIndalaDecode(const char *Cmd); +int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo); +int ASKbiphaseDemod(const char *Cmd, bool verbose); int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch); int ASKrawDemod(const char *Cmd, bool verbose); int FSKrawDemod(const char *Cmd, bool verbose); int PSKDemod(const char *Cmd, bool verbose); int NRZrawDemod(const char *Cmd, bool verbose); +void printEM410x(uint32_t hi, uint64_t id); +int getSamples(const char *Cmd, bool silent); + #define MAX_DEMOD_BUF_LEN (1024*128) extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 31f7ba97..44b074b3 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -30,6 +30,7 @@ #include "loclass/elite_crack.h" #include "loclass/fileutils.h" #include "protocols.h" +#include "usb_cmd.h" static int CmdHelp(const char *Cmd); @@ -166,29 +167,25 @@ int CmdHFiClassSim(const char *Cmd) int CmdHFiClassReader(const char *Cmd) { - UsbCommand c = {CMD_READER_ICLASS, {0}}; + UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN| + FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_AA}}; SendCommand(&c); UsbCommand resp; while(!ukbhit()){ if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) { - uint8_t isOK = resp.arg[0] & 0xff; + uint8_t readStatus = resp.arg[0] & 0xff; uint8_t * data = resp.d.asBytes; - PrintAndLog("isOk:%02x", isOK); - if( isOK == 0){ + PrintAndLog("Readstatus:%02x", readStatus); + if( readStatus == 0){ //Aborted PrintAndLog("Quitting..."); return 0; } - if(isOK > 0) - { - PrintAndLog("CSN: %s",sprint_hex(data,8)); - } - if(isOK >= 1) - { - PrintAndLog("CC: %s",sprint_hex(data+8,8)); - }else{ - PrintAndLog("No CC obtained"); + if( readStatus & FLAG_ICLASS_READER_CSN) PrintAndLog("CSN: %s",sprint_hex(data,8)); + if( readStatus & FLAG_ICLASS_READER_CC) PrintAndLog("CC: %s",sprint_hex(data+16,8)); + if( readStatus & FLAG_ICLASS_READER_CONF){ + printIclassDumpInfo(data); } } else { PrintAndLog("Command execute timeout"); @@ -269,7 +266,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) uint8_t key_sel_p[8] = { 0 }; UsbCommand c = {CMD_READER_ICLASS, {0}}; - c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC; + c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_CC; SendCommand(&c); @@ -284,7 +281,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) uint8_t * data = resp.d.asBytes; memcpy(CSN,data,8); - memcpy(CCNR,data+8,8); + memcpy(CCNR,data+16,8); PrintAndLog("isOk:%02x", isOK); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index c16b9674..468243fc 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1539,7 +1539,7 @@ int CmdHF14AMfCLoad(const char *Cmd) char buf[64] = {0x00}; uint8_t buf8[64] = {0x00}; uint8_t fillFromEmulator = 0; - int i, len, blockNum, flags; + int i, len, blockNum, flags=0; if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) { PrintAndLog("It loads magic Chinese card from the file `filename.eml`"); diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index e76b3fb5..4e515f78 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -320,7 +320,7 @@ int CmdHFTopazReader(const char *Cmd) for (uint16_t j = 0; j < 8; j++) { sprintf(&line[3*j], "%02x ", topaz_tag.data_blocks[i][j] /*rall_response[2 + 8*i + j]*/); } - PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", i, i*8, line, topaz_block_is_locked(i, &topaz_tag.data_blocks[0x0d][0]) ? "yes" : "no"); + PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", i, i*8, line, topaz_block_is_locked(i, &topaz_tag.data_blocks[0x0e][0]) ? "yes" : "no"); } PrintAndLog(""); diff --git a/client/cmdlf.c b/client/cmdlf.c index 79d6787b..54f396fd 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -35,326 +35,326 @@ static int CmdHelp(const char *Cmd); /* send a command before reading */ int CmdLFCommandRead(const char *Cmd) { - static char dummy[3]; + static char dummy[3]; - dummy[0]= ' '; + dummy[0]= ' '; - UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; - sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); - // in case they specified 'h' - strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); - SendCommand(&c); - return 0; + UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; + sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); + // in case they specified 'h' + strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); + SendCommand(&c); + return 0; } int CmdFlexdemod(const char *Cmd) { - int i; - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] < 0) { - GraphBuffer[i] = -1; - } else { - GraphBuffer[i] = 1; - } - } + int i; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] < 0) { + GraphBuffer[i] = -1; + } else { + GraphBuffer[i] = 1; + } + } #define LONG_WAIT 100 - int start; - for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { - int first = GraphBuffer[start]; - for (i = start; i < start + LONG_WAIT; i++) { - if (GraphBuffer[i] != first) { - break; - } - } - if (i == (start + LONG_WAIT)) { - break; - } - } - if (start == GraphTraceLen - LONG_WAIT) { - PrintAndLog("nothing to wait for"); - return 0; - } - - GraphBuffer[start] = 2; - GraphBuffer[start+1] = -2; + int start; + for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { + int first = GraphBuffer[start]; + for (i = start; i < start + LONG_WAIT; i++) { + if (GraphBuffer[i] != first) { + break; + } + } + if (i == (start + LONG_WAIT)) { + break; + } + } + if (start == GraphTraceLen - LONG_WAIT) { + PrintAndLog("nothing to wait for"); + return 0; + } + + GraphBuffer[start] = 2; + GraphBuffer[start+1] = -2; uint8_t bits[64] = {0x00}; int bit, sum; - i = start; - for (bit = 0; bit < 64; bit++) { + i = start; + for (bit = 0; bit < 64; bit++) { sum = 0; for (int j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } + sum += GraphBuffer[i++]; + } bits[bit] = (sum > 0) ? 1 : 0; - PrintAndLog("bit %d sum %d", bit, sum); - } - - for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - if (sum > 0 && bits[bit] != 1) { - PrintAndLog("oops1 at %d", bit); - } - if (sum < 0 && bits[bit] != 0) { - PrintAndLog("oops2 at %d", bit); - } - } + PrintAndLog("bit %d sum %d", bit, sum); + } + + for (bit = 0; bit < 64; bit++) { + int j; + int sum = 0; + for (j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } + if (sum > 0 && bits[bit] != 1) { + PrintAndLog("oops1 at %d", bit); + } + if (sum < 0 && bits[bit] != 0) { + PrintAndLog("oops2 at %d", bit); + } + } // HACK writing back to graphbuffer. - GraphTraceLen = 32*64; - i = 0; - int phase = 0; - for (bit = 0; bit < 64; bit++) { + GraphTraceLen = 32*64; + i = 0; + int phase = 0; + for (bit = 0; bit < 64; bit++) { phase = (bits[bit] == 0) ? 0 : 1; - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } - - RepaintGraphWindow(); - return 0; + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } + + RepaintGraphWindow(); + return 0; } - + int CmdIndalaDemod(const char *Cmd) { - // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID + // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID - int state = -1; - int count = 0; - int i, j; + int state = -1; + int count = 0; + int i, j; - // worst case with GraphTraceLen=64000 is < 4096 - // under normal conditions it's < 2048 + // worst case with GraphTraceLen=64000 is < 4096 + // under normal conditions it's < 2048 - uint8_t rawbits[4096]; - int rawbit = 0; - int worst = 0, worstPos = 0; + uint8_t rawbits[4096]; + int rawbit = 0; + int worst = 0, worstPos = 0; // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32); - for (i = 0; i < GraphTraceLen-1; i += 2) { - count += 1; - if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { - if (state == 0) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 0; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 1; - count = 0; - } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { - if (state == 1) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 1; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 0; - count = 0; - } - } - - if (rawbit>0){ - PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); - PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); + for (i = 0; i < GraphTraceLen-1; i += 2) { + count += 1; + if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { + if (state == 0) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 0; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 1; + count = 0; + } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { + if (state == 1) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 1; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 0; + count = 0; + } + } + + if (rawbit>0){ + PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); + PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); } else { return 0; } - // Finding the start of a UID - int uidlen, long_wait; - if (strcmp(Cmd, "224") == 0) { - uidlen = 224; - long_wait = 30; - } else { - uidlen = 64; - long_wait = 29; - } - - int start; - int first = 0; - for (start = 0; start <= rawbit - uidlen; start++) { - first = rawbits[start]; - for (i = start; i < start + long_wait; i++) { - if (rawbits[i] != first) { - break; - } - } - if (i == (start + long_wait)) { - break; - } - } - - if (start == rawbit - uidlen + 1) { - PrintAndLog("nothing to wait for"); - return 0; - } - - // Inverting signal if needed - if (first == 1) { - for (i = start; i < rawbit; i++) { - rawbits[i] = !rawbits[i]; - } - } - - // Dumping UID + // Finding the start of a UID + int uidlen, long_wait; + if (strcmp(Cmd, "224") == 0) { + uidlen = 224; + long_wait = 30; + } else { + uidlen = 64; + long_wait = 29; + } + + int start; + int first = 0; + for (start = 0; start <= rawbit - uidlen; start++) { + first = rawbits[start]; + for (i = start; i < start + long_wait; i++) { + if (rawbits[i] != first) { + break; + } + } + if (i == (start + long_wait)) { + break; + } + } + + if (start == rawbit - uidlen + 1) { + PrintAndLog("nothing to wait for"); + return 0; + } + + // Inverting signal if needed + if (first == 1) { + for (i = start; i < rawbit; i++) { + rawbits[i] = !rawbits[i]; + } + } + + // Dumping UID uint8_t bits[224] = {0x00}; char showbits[225] = {0x00}; - int bit; - i = start; - int times = 0; + int bit; + i = start; + int times = 0; + + if (uidlen > rawbit) { + PrintAndLog("Warning: not enough raw bits to get a full UID"); + for (bit = 0; bit < rawbit; bit++) { + bits[bit] = rawbits[i++]; + // As we cannot know the parity, let's use "." and "/" + showbits[bit] = '.' + bits[bit]; + } + showbits[bit+1]='\0'; + PrintAndLog("Partial UID=%s", showbits); + return 0; + } else { + for (bit = 0; bit < uidlen; bit++) { + bits[bit] = rawbits[i++]; + showbits[bit] = '0' + bits[bit]; + } + times = 1; + } - if (uidlen > rawbit) { - PrintAndLog("Warning: not enough raw bits to get a full UID"); - for (bit = 0; bit < rawbit; bit++) { - bits[bit] = rawbits[i++]; - // As we cannot know the parity, let's use "." and "/" - showbits[bit] = '.' + bits[bit]; - } - showbits[bit+1]='\0'; - PrintAndLog("Partial UID=%s", showbits); - return 0; - } else { - for (bit = 0; bit < uidlen; bit++) { - bits[bit] = rawbits[i++]; - showbits[bit] = '0' + bits[bit]; - } - times = 1; - } - - //convert UID to HEX - uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; - int idx; + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; uid1 = uid2 = 0; - if (uidlen==64){ - for( idx=0; idx<64; idx++) { - if (showbits[idx] == '0') { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|0; - } else { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|1; - } - } - PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); - } - else { + if (uidlen==64){ + for( idx=0; idx<64; idx++) { + if (showbits[idx] == '0') { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|0; + } else { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|1; + } + } + PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { uid3 = uid4 = uid5 = uid6 = uid7 = 0; - for( idx=0; idx<224; 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); + for( idx=0; idx<224; 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 (showbits[idx] == '0') uid7 = (uid7<<1) | 0; else uid7 = (uid7<<1) | 1; - } - PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); - } + } + PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } - // Checking UID against next occurrences - int failed = 0; + // Checking UID against next occurrences + int failed = 0; for (; i + uidlen <= rawbit;) { failed = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] != rawbits[i++]) { - failed = 1; - break; - } - } - if (failed == 1) { - break; - } - times += 1; - } - - PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); - - // Remodulating for tag cloning + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] != rawbits[i++]) { + failed = 1; + break; + } + } + if (failed == 1) { + break; + } + times += 1; + } + + PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); + + // Remodulating for tag cloning // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod) // since this changes graphbuffer data. - GraphTraceLen = 32*uidlen; - i = 0; - int phase = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] == 0) { - phase = 0; - } else { - phase = 1; - } - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } - - RepaintGraphWindow(); - return 1; + GraphTraceLen = 32*uidlen; + i = 0; + int phase = 0; + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] == 0) { + phase = 0; + } else { + phase = 1; + } + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } + + RepaintGraphWindow(); + return 1; } int CmdIndalaClone(const char *Cmd) { - UsbCommand c; + UsbCommand c; unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7; uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0; - int n = 0, i = 0; - - if (strchr(Cmd,'l') != 0) { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (uid3 >> 28); - uid3 = (uid3 << 4) | (uid4 >> 28); - uid4 = (uid4 << 4) | (uid5 >> 28); - uid5 = (uid5 << 4) | (uid6 >> 28); - uid6 = (uid6 << 4) | (uid7 >> 28); - uid7 = (uid7 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); - c.cmd = CMD_INDALA_CLONE_TAG_L; - c.d.asDwords[0] = uid1; - c.d.asDwords[1] = uid2; - c.d.asDwords[2] = uid3; - c.d.asDwords[3] = uid4; - c.d.asDwords[4] = uid5; - c.d.asDwords[5] = uid6; - c.d.asDwords[6] = uid7; + int n = 0, i = 0; + + if (strchr(Cmd,'l') != 0) { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (uid3 >> 28); + uid3 = (uid3 << 4) | (uid4 >> 28); + uid4 = (uid4 << 4) | (uid5 >> 28); + uid5 = (uid5 << 4) | (uid6 >> 28); + uid6 = (uid6 << 4) | (uid7 >> 28); + uid7 = (uid7 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); + c.cmd = CMD_INDALA_CLONE_TAG_L; + c.d.asDwords[0] = uid1; + c.d.asDwords[1] = uid2; + c.d.asDwords[2] = uid3; + c.d.asDwords[3] = uid4; + c.d.asDwords[4] = uid5; + c.d.asDwords[5] = uid6; + c.d.asDwords[6] = uid7; } else { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); - c.cmd = CMD_INDALA_CLONE_TAG; - c.arg[0] = uid1; - c.arg[1] = uid2; - } - - SendCommand(&c); - return 0; + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); + c.cmd = CMD_INDALA_CLONE_TAG; + c.arg[0] = uid1; + c.arg[1] = uid2; + } + + SendCommand(&c); + return 0; } int usage_lf_read() @@ -362,6 +362,7 @@ int usage_lf_read() PrintAndLog("Usage: lf read"); PrintAndLog("Options: "); PrintAndLog(" h This help"); + PrintAndLog(" s silent run no printout"); PrintAndLog("This function takes no arguments. "); PrintAndLog("Use 'lf config' to set parameters."); return 0; @@ -481,13 +482,15 @@ int CmdLFSetConfig(const char *Cmd) int CmdLFRead(const char *Cmd) { - uint8_t cmdp =0; - if(param_getchar(Cmd, cmdp) == 'h') + uint8_t cmdp = 0; + bool arg1 = false; + if (param_getchar(Cmd, cmdp) == 'h') { return usage_lf_read(); } + if (param_getchar(Cmd, cmdp) == 's') arg1 = true; //suppress print //And ship it to device - UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; + UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}}; SendCommand(&c); WaitForResponse(CMD_ACK,NULL); return 0; @@ -509,638 +512,659 @@ int CmdLFSnoop(const char *Cmd) static void ChkBitstream(const char *str) { - int i; + int i; - /* convert to bitstream if necessary */ + /* convert to bitstream if necessary */ for (i = 0; i < (int)(GraphTraceLen / 2); i++){ if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) { - CmdGetBitStream(""); - break; - } - } + CmdGetBitStream(""); + break; + } + } } //appears to attempt to simulate manchester int CmdLFSim(const char *Cmd) { - int i,j; - static int gap; + int i,j; + static int gap; - sscanf(Cmd, "%i", &gap); + sscanf(Cmd, "%i", &gap); - /* convert to bitstream if necessary */ + /* convert to bitstream if necessary */ - ChkBitstream(Cmd); + ChkBitstream(Cmd); - //can send 512 bits at a time (1 byte sent per bit...) - printf("Sending [%d bytes]", GraphTraceLen); - for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) { - UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; + //can send 512 bits at a time (1 byte sent per bit...) + printf("Sending [%d bytes]", GraphTraceLen); + for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) { + UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; - for (j = 0; j < USB_CMD_DATA_SIZE; j++) { - c.d.asBytes[j] = GraphBuffer[i+j]; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - printf("."); - } + for (j = 0; j < USB_CMD_DATA_SIZE; j++) { + c.d.asBytes[j] = GraphBuffer[i+j]; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + printf("."); + } - printf("\n"); - PrintAndLog("Starting to simulate"); - UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; - SendCommand(&c); - return 0; + printf("\n"); + PrintAndLog("Starting to simulate"); + UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; + SendCommand(&c); + return 0; } int usage_lf_simfsk(void) { - //print help - PrintAndLog("Usage: lf simfsk [c ] [i] [H ] [L ] [d ]"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); - PrintAndLog(" i invert data"); - PrintAndLog(" H Manually set the larger Field Clock"); - PrintAndLog(" L Manually set the smaller Field Clock"); - //PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap"); - PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); - PrintAndLog("\n NOTE: if you set one clock manually set them all manually"); - return 0; + //print help + PrintAndLog("Usage: lf simfsk [c ] [i] [H ] [L ] [d ]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); + PrintAndLog(" i invert data"); + PrintAndLog(" H Manually set the larger Field Clock"); + PrintAndLog(" L Manually set the smaller Field Clock"); + //PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap"); + PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); + PrintAndLog("\n NOTE: if you set one clock manually set them all manually"); + return 0; } int usage_lf_simask(void) { - //print help - PrintAndLog("Usage: lf simask [c ] [i] [m|r] [s] [d ]"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); - PrintAndLog(" i invert data"); - PrintAndLog(" m sim ask/manchester"); - PrintAndLog(" r sim ask/raw"); - PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap"); - PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); - return 0; + //print help + PrintAndLog("Usage: lf simask [c ] [i] [b|m|r] [s] [d ]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); + PrintAndLog(" i invert data"); + PrintAndLog(" b sim ask/biphase"); + PrintAndLog(" m sim ask/manchester - Default"); + PrintAndLog(" r sim ask/raw"); + PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap"); + PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); + return 0; } int usage_lf_simpsk(void) { - //print help - PrintAndLog("Usage: lf simpsk [1|2|3] [c ] [i] [r ] [d ]"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); - PrintAndLog(" i invert data"); - PrintAndLog(" 1 set PSK1 (default)"); - PrintAndLog(" 2 set PSK2"); - PrintAndLog(" 3 set PSK3"); - PrintAndLog(" r 2|4|8 are valid carriers: default = 2"); - PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); - return 0; + //print help + PrintAndLog("Usage: lf simpsk [1|2|3] [c ] [i] [r ] [d ]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); + PrintAndLog(" i invert data"); + PrintAndLog(" 1 set PSK1 (default)"); + PrintAndLog(" 2 set PSK2"); + PrintAndLog(" 3 set PSK3"); + PrintAndLog(" r 2|4|8 are valid carriers: default = 2"); + PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); + return 0; } // by marshmellow - sim ask data given clock, fcHigh, fcLow, invert // - allow pull data from DemodBuffer int CmdLFfskSim(const char *Cmd) { - //might be able to autodetect FC and clock from Graphbuffer if using demod buffer - //will need FChigh, FClow, Clock, and bitstream - uint8_t fcHigh=0, fcLow=0, clk=0; - uint8_t invert=0; - bool errors = FALSE; - char hexData[32] = {0x00}; // store entered hex data - uint8_t data[255] = {0x00}; - int dataLen = 0; - uint8_t cmdp = 0; - while(param_getchar(Cmd, cmdp) != 0x00) - { - switch(param_getchar(Cmd, cmdp)) - { - case 'h': - return usage_lf_simfsk(); - case 'i': - invert = 1; - cmdp++; - break; - case 'c': - errors |= param_getdec(Cmd,cmdp+1,&clk); - cmdp+=2; - break; - case 'H': - errors |= param_getdec(Cmd,cmdp+1,&fcHigh); - cmdp+=2; - break; - case 'L': - errors |= param_getdec(Cmd,cmdp+1,&fcLow); - cmdp+=2; - break; - //case 's': - // separator=1; - // cmdp++; - // break; - case 'd': - dataLen = param_getstr(Cmd, cmdp+1, hexData); - if (dataLen==0) { - errors=TRUE; - } else { - dataLen = hextobinarray((char *)data, hexData); - } - if (dataLen==0) errors=TRUE; - if (errors) PrintAndLog ("Error getting hex data"); - cmdp+=2; - break; - default: - PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = TRUE; - break; - } - if(errors) break; - } - if(cmdp == 0 && DemodBufferLen == 0) - { - errors = TRUE;// No args - } - - //Validations - if(errors) - { - return usage_lf_simfsk(); - } - - if (dataLen == 0){ //using DemodBuffer - if (clk==0 || fcHigh==0 || fcLow==0){ //manual settings must set them all - uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0); - if (ans==0){ - if (!fcHigh) fcHigh=10; - if (!fcLow) fcLow=8; - if (!clk) clk=50; - } - } - } else { - setDemodBuf(data, dataLen, 0); - } - if (clk == 0) clk = 50; - if (fcHigh == 0) fcHigh = 10; - if (fcLow == 0) fcLow = 8; - - uint16_t arg1, arg2; - arg1 = fcHigh << 8 | fcLow; - arg2 = invert << 8 | clk; - size_t size = DemodBufferLen; - if (size > USB_CMD_DATA_SIZE) { - PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE); - size = USB_CMD_DATA_SIZE; - } - UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}}; - - memcpy(c.d.asBytes, DemodBuffer, size); - SendCommand(&c); - return 0; + //might be able to autodetect FC and clock from Graphbuffer if using demod buffer + //will need FChigh, FClow, Clock, and bitstream + uint8_t fcHigh=0, fcLow=0, clk=0; + uint8_t invert=0; + bool errors = FALSE; + char hexData[32] = {0x00}; // store entered hex data + uint8_t data[255] = {0x00}; + int dataLen = 0; + uint8_t cmdp = 0; + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + return usage_lf_simfsk(); + case 'i': + invert = 1; + cmdp++; + break; + case 'c': + errors |= param_getdec(Cmd,cmdp+1,&clk); + cmdp+=2; + break; + case 'H': + errors |= param_getdec(Cmd,cmdp+1,&fcHigh); + cmdp+=2; + break; + case 'L': + errors |= param_getdec(Cmd,cmdp+1,&fcLow); + cmdp+=2; + break; + //case 's': + // separator=1; + // cmdp++; + // break; + case 'd': + dataLen = param_getstr(Cmd, cmdp+1, hexData); + if (dataLen==0) { + errors=TRUE; + } else { + dataLen = hextobinarray((char *)data, hexData); + } + if (dataLen==0) errors=TRUE; + if (errors) PrintAndLog ("Error getting hex data"); + cmdp+=2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = TRUE; + break; + } + if(errors) break; + } + if(cmdp == 0 && DemodBufferLen == 0) + { + errors = TRUE;// No args + } + + //Validations + if(errors) + { + return usage_lf_simfsk(); + } + + if (dataLen == 0){ //using DemodBuffer + if (clk==0 || fcHigh==0 || fcLow==0){ //manual settings must set them all + uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0); + if (ans==0){ + if (!fcHigh) fcHigh=10; + if (!fcLow) fcLow=8; + if (!clk) clk=50; + } + } + } else { + setDemodBuf(data, dataLen, 0); + } + if (clk == 0) clk = 50; + if (fcHigh == 0) fcHigh = 10; + if (fcLow == 0) fcLow = 8; + + uint16_t arg1, arg2; + arg1 = fcHigh << 8 | fcLow; + arg2 = invert << 8 | clk; + size_t size = DemodBufferLen; + if (size > USB_CMD_DATA_SIZE) { + PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE); + size = USB_CMD_DATA_SIZE; + } + UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}}; + + memcpy(c.d.asBytes, DemodBuffer, size); + SendCommand(&c); + return 0; } // by marshmellow - sim ask data given clock, invert, manchester or raw, separator // - allow pull data from DemodBuffer int CmdLFaskSim(const char *Cmd) { - //autodetect clock from Graphbuffer if using demod buffer - //will need clock, invert, manchester/raw as m or r, separator as s, and bitstream - uint8_t manchester = 1, separator = 0; - //char cmdp = Cmd[0], par3='m', par4=0; - uint8_t clk=0, invert=0; - bool errors = FALSE; - char hexData[32] = {0x00}; - uint8_t data[255]= {0x00}; // store entered hex data - int dataLen = 0; - uint8_t cmdp = 0; - while(param_getchar(Cmd, cmdp) != 0x00) - { - switch(param_getchar(Cmd, cmdp)) - { - case 'h': - return usage_lf_simask(); - case 'i': - invert = 1; - cmdp++; - break; - case 'c': - errors |= param_getdec(Cmd,cmdp+1,&clk); - cmdp+=2; - break; - case 'm': - manchester=1; - cmdp++; - break; - case 'r': - manchester=0; - cmdp++; - break; - case 's': - separator=1; - cmdp++; - break; - case 'd': - dataLen = param_getstr(Cmd, cmdp+1, hexData); - if (dataLen==0) { - errors=TRUE; - } else { - dataLen = hextobinarray((char *)data, hexData); - } - if (dataLen==0) errors=TRUE; - if (errors) PrintAndLog ("Error getting hex data, datalen: %d",dataLen); - cmdp+=2; - break; - default: - PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = TRUE; - break; - } - if(errors) break; - } - if(cmdp == 0 && DemodBufferLen == 0) - { - errors = TRUE;// No args - } - - //Validations - if(errors) - { - return usage_lf_simask(); - } - if (dataLen == 0){ //using DemodBuffer - if (clk == 0) clk = GetAskClock("0", false, false); - } else { - setDemodBuf(data, dataLen, 0); - } - if (clk == 0) clk = 64; - if (manchester == 0) clk = clk/2; //askraw needs to double the clock speed - uint16_t arg1, arg2; - size_t size=DemodBufferLen; - arg1 = clk << 8 | manchester; - arg2 = invert << 8 | separator; - if (size > USB_CMD_DATA_SIZE) { - PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE); - size = USB_CMD_DATA_SIZE; - } - UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; - PrintAndLog("preparing to sim ask data: %d bits", size); - memcpy(c.d.asBytes, DemodBuffer, size); - SendCommand(&c); - return 0; + //autodetect clock from Graphbuffer if using demod buffer + //will need clock, invert, manchester/raw as m or r, separator as s, and bitstream + uint8_t encoding = 1, separator = 0; + //char cmdp = Cmd[0], par3='m', par4=0; + uint8_t clk=0, invert=0; + bool errors = FALSE; + char hexData[32] = {0x00}; + uint8_t data[255]= {0x00}; // store entered hex data + int dataLen = 0; + uint8_t cmdp = 0; + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + return usage_lf_simask(); + case 'i': + invert = 1; + cmdp++; + break; + case 'c': + errors |= param_getdec(Cmd,cmdp+1,&clk); + cmdp+=2; + break; + case 'b': + encoding=2; //biphase + cmdp++; + break; + case 'm': + encoding=1; + cmdp++; + break; + case 'r': + encoding=0; + cmdp++; + break; + case 's': + separator=1; + cmdp++; + break; + case 'd': + dataLen = param_getstr(Cmd, cmdp+1, hexData); + if (dataLen==0) { + errors=TRUE; + } else { + dataLen = hextobinarray((char *)data, hexData); + } + if (dataLen==0) errors=TRUE; + if (errors) PrintAndLog ("Error getting hex data, datalen: %d",dataLen); + cmdp+=2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = TRUE; + break; + } + if(errors) break; + } + if(cmdp == 0 && DemodBufferLen == 0) + { + errors = TRUE;// No args + } + + //Validations + if(errors) + { + return usage_lf_simask(); + } + if (dataLen == 0){ //using DemodBuffer + if (clk == 0) clk = GetAskClock("0", false, false); + } else { + setDemodBuf(data, dataLen, 0); + } + if (clk == 0) clk = 64; + if (encoding == 0) clk = clk/2; //askraw needs to double the clock speed + uint16_t arg1, arg2; + size_t size=DemodBufferLen; + arg1 = clk << 8 | encoding; + arg2 = invert << 8 | separator; + if (size > USB_CMD_DATA_SIZE) { + PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE); + size = USB_CMD_DATA_SIZE; + } + UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; + PrintAndLog("preparing to sim ask data: %d bits", size); + memcpy(c.d.asBytes, DemodBuffer, size); + SendCommand(&c); + return 0; } // by marshmellow - sim psk data given carrier, clock, invert // - allow pull data from DemodBuffer or parameters int CmdLFpskSim(const char *Cmd) { - //might be able to autodetect FC and clock from Graphbuffer if using demod buffer - //will need carrier, Clock, and bitstream - uint8_t carrier=0, clk=0; - uint8_t invert=0; - bool errors = FALSE; - char hexData[32] = {0x00}; // store entered hex data - uint8_t data[255] = {0x00}; - int dataLen = 0; - uint8_t cmdp = 0; - uint8_t pskType = 1; - while(param_getchar(Cmd, cmdp) != 0x00) - { - switch(param_getchar(Cmd, cmdp)) - { - case 'h': - return usage_lf_simpsk(); - case 'i': - invert = 1; - cmdp++; - break; - case 'c': - errors |= param_getdec(Cmd,cmdp+1,&clk); - cmdp+=2; - break; - case 'r': - errors |= param_getdec(Cmd,cmdp+1,&carrier); - cmdp+=2; - break; - case '1': - pskType=1; - cmdp++; - break; - case '2': - pskType=2; - cmdp++; - break; - case '3': - pskType=3; - cmdp++; - break; - case 'd': - dataLen = param_getstr(Cmd, cmdp+1, hexData); - if (dataLen==0) { - errors=TRUE; - } else { - dataLen = hextobinarray((char *)data, hexData); - } - if (dataLen==0) errors=TRUE; - if (errors) PrintAndLog ("Error getting hex data"); - cmdp+=2; - break; - default: - PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = TRUE; - break; - } - if (errors) break; - } - if (cmdp == 0 && DemodBufferLen == 0) - { - errors = TRUE;// No args - } - - //Validations - if (errors) - { - return usage_lf_simpsk(); - } - if (dataLen == 0){ //using DemodBuffer - PrintAndLog("Getting Clocks"); - if (clk==0) clk = GetPskClock("", FALSE, FALSE); - PrintAndLog("clk: %d",clk); - if (!carrier) carrier = GetPskCarrier("", FALSE, FALSE); - PrintAndLog("carrier: %d", carrier); - } else { - setDemodBuf(data, dataLen, 0); - } - - if (clk <= 0) clk = 32; - if (carrier == 0) carrier = 2; - if (pskType != 1){ - if (pskType == 2){ - //need to convert psk2 to psk1 data before sim - psk2TOpsk1(DemodBuffer, DemodBufferLen); - } else { - PrintAndLog("Sorry, PSK3 not yet available"); - } - } - uint16_t arg1, arg2; - arg1 = clk << 8 | carrier; - arg2 = invert; - size_t size=DemodBufferLen; - if (size > USB_CMD_DATA_SIZE) { - PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE); - size=USB_CMD_DATA_SIZE; - } - UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}}; - PrintAndLog("DEBUG: Sending DemodBuffer Length: %d", size); - memcpy(c.d.asBytes, DemodBuffer, size); - SendCommand(&c); - - return 0; + //might be able to autodetect FC and clock from Graphbuffer if using demod buffer + //will need carrier, Clock, and bitstream + uint8_t carrier=0, clk=0; + uint8_t invert=0; + bool errors = FALSE; + char hexData[32] = {0x00}; // store entered hex data + uint8_t data[255] = {0x00}; + int dataLen = 0; + uint8_t cmdp = 0; + uint8_t pskType = 1; + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + return usage_lf_simpsk(); + case 'i': + invert = 1; + cmdp++; + break; + case 'c': + errors |= param_getdec(Cmd,cmdp+1,&clk); + cmdp+=2; + break; + case 'r': + errors |= param_getdec(Cmd,cmdp+1,&carrier); + cmdp+=2; + break; + case '1': + pskType=1; + cmdp++; + break; + case '2': + pskType=2; + cmdp++; + break; + case '3': + pskType=3; + cmdp++; + break; + case 'd': + dataLen = param_getstr(Cmd, cmdp+1, hexData); + if (dataLen==0) { + errors=TRUE; + } else { + dataLen = hextobinarray((char *)data, hexData); + } + if (dataLen==0) errors=TRUE; + if (errors) PrintAndLog ("Error getting hex data"); + cmdp+=2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = TRUE; + break; + } + if (errors) break; + } + if (cmdp == 0 && DemodBufferLen == 0) + { + errors = TRUE;// No args + } + + //Validations + if (errors) + { + return usage_lf_simpsk(); + } + if (dataLen == 0){ //using DemodBuffer + PrintAndLog("Getting Clocks"); + if (clk==0) clk = GetPskClock("", FALSE, FALSE); + PrintAndLog("clk: %d",clk); + if (!carrier) carrier = GetPskCarrier("", FALSE, FALSE); + PrintAndLog("carrier: %d", carrier); + } else { + setDemodBuf(data, dataLen, 0); + } + + if (clk <= 0) clk = 32; + if (carrier == 0) carrier = 2; + if (pskType != 1){ + if (pskType == 2){ + //need to convert psk2 to psk1 data before sim + psk2TOpsk1(DemodBuffer, DemodBufferLen); + } else { + PrintAndLog("Sorry, PSK3 not yet available"); + } + } + uint16_t arg1, arg2; + arg1 = clk << 8 | carrier; + arg2 = invert; + size_t size=DemodBufferLen; + if (size > USB_CMD_DATA_SIZE) { + PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE); + size=USB_CMD_DATA_SIZE; + } + UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}}; + PrintAndLog("DEBUG: Sending DemodBuffer Length: %d", size); + memcpy(c.d.asBytes, DemodBuffer, size); + SendCommand(&c); + + return 0; } int CmdLFSimBidir(const char *Cmd) { - // Set ADC to twice the carrier for a slight supersampling - // HACK: not implemented in ARMSRC. - PrintAndLog("Not implemented yet."); - UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; - SendCommand(&c); - return 0; + // Set ADC to twice the carrier for a slight supersampling + // HACK: not implemented in ARMSRC. + PrintAndLog("Not implemented yet."); + UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; + SendCommand(&c); + return 0; } /* simulate an LF Manchester encoded tag with specified bitstream, clock rate and inter-id gap */ /* int CmdLFSimManchester(const char *Cmd) { - static int clock, gap; - static char data[1024], gapstring[8]; + static int clock, gap; + static char data[1024], gapstring[8]; - sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); + sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); - ClearGraph(0); + ClearGraph(0); - for (int i = 0; i < strlen(data) ; ++i) - AppendGraph(0, clock, data[i]- '0'); + for (int i = 0; i < strlen(data) ; ++i) + AppendGraph(0, clock, data[i]- '0'); - CmdManchesterMod(""); + CmdManchesterMod(""); - RepaintGraphWindow(); + RepaintGraphWindow(); - sprintf(&gapstring[0], "%i", gap); - CmdLFSim(gapstring); - return 0; + sprintf(&gapstring[0], "%i", gap); + CmdLFSim(gapstring); + return 0; } */ int CmdVchDemod(const char *Cmd) { - // Is this the entire sync pattern, or does this also include some - // data bits that happen to be the same everywhere? That would be - // lovely to know. - static const int SyncPattern[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }; - - // So first, we correlate for the sync pattern, and mark that. - int bestCorrel = 0, bestPos = 0; - int i; - // It does us no good to find the sync pattern, with fewer than - // 2048 samples after it... - for (i = 0; i < (GraphTraceLen-2048); i++) { - int sum = 0; - int j; - for (j = 0; j < arraylen(SyncPattern); j++) { - sum += GraphBuffer[i+j]*SyncPattern[j]; - } - if (sum > bestCorrel) { - bestCorrel = sum; - bestPos = i; - } - } - PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); - - char bits[257]; - bits[256] = '\0'; - - int worst = INT_MAX; - int worstPos = 0; - - for (i = 0; i < 2048; i += 8) { - int sum = 0; - int j; - for (j = 0; j < 8; j++) { - sum += GraphBuffer[bestPos+i+j]; - } - if (sum < 0) { - bits[i/8] = '.'; - } else { - bits[i/8] = '1'; - } - if(abs(sum) < worst) { - worst = abs(sum); - worstPos = i; - } - } - PrintAndLog("bits:"); - PrintAndLog("%s", bits); - PrintAndLog("worst metric: %d at pos %d", worst, worstPos); - - if (strcmp(Cmd, "clone")==0) { - GraphTraceLen = 0; - char *s; - for(s = bits; *s; s++) { - int j; - for(j = 0; j < 16; j++) { - GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; - } - } - RepaintGraphWindow(); - } - return 0; + // Is this the entire sync pattern, or does this also include some + // data bits that happen to be the same everywhere? That would be + // lovely to know. + static const int SyncPattern[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + + // So first, we correlate for the sync pattern, and mark that. + int bestCorrel = 0, bestPos = 0; + int i; + // It does us no good to find the sync pattern, with fewer than + // 2048 samples after it... + for (i = 0; i < (GraphTraceLen-2048); i++) { + int sum = 0; + int j; + for (j = 0; j < arraylen(SyncPattern); j++) { + sum += GraphBuffer[i+j]*SyncPattern[j]; + } + if (sum > bestCorrel) { + bestCorrel = sum; + bestPos = i; + } + } + PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); + + char bits[257]; + bits[256] = '\0'; + + int worst = INT_MAX; + int worstPos = 0; + + for (i = 0; i < 2048; i += 8) { + int sum = 0; + int j; + for (j = 0; j < 8; j++) { + sum += GraphBuffer[bestPos+i+j]; + } + if (sum < 0) { + bits[i/8] = '.'; + } else { + bits[i/8] = '1'; + } + if(abs(sum) < worst) { + worst = abs(sum); + worstPos = i; + } + } + PrintAndLog("bits:"); + PrintAndLog("%s", bits); + PrintAndLog("worst metric: %d at pos %d", worst, worstPos); + + if (strcmp(Cmd, "clone")==0) { + GraphTraceLen = 0; + char *s; + for(s = bits; *s; s++) { + int j; + for(j = 0; j < 16; j++) { + GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; + } + } + RepaintGraphWindow(); + } + return 0; } //by marshmellow int CmdLFfind(const char *Cmd) { - int ans=0; - char cmdp = param_getchar(Cmd, 0); - char testRaw = param_getchar(Cmd, 1); - if (strlen(Cmd) > 2 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf search <0|1> [u]"); - PrintAndLog(" , if not set, try reading data from tag."); - PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags."); - PrintAndLog(""); - PrintAndLog(" sample: lf search = try reading data from tag & search for known tags"); - PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags"); - PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags"); - PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); - - return 0; - } - - if (!offline && (cmdp != '1')){ - ans=CmdLFRead(""); - ans=CmdSamples("20000"); - } else if (GraphTraceLen < 1000) { - PrintAndLog("Data in Graphbuffer was too small."); - return 0; - } - if (cmdp == 'u' || cmdp == 'U') testRaw = 'u'; - PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); - PrintAndLog("False Positives ARE possible\n"); - PrintAndLog("\nChecking for known tags:\n"); - ans=CmdFSKdemodIO(""); - if (ans>0) { - PrintAndLog("\nValid IO Prox ID Found!"); - return 1; - } - ans=CmdFSKdemodPyramid(""); - if (ans>0) { - PrintAndLog("\nValid Pyramid ID Found!"); - return 1; - } - ans=CmdFSKdemodParadox(""); - if (ans>0) { - PrintAndLog("\nValid Paradox ID Found!"); - return 1; - } - ans=CmdFSKdemodAWID(""); - if (ans>0) { - PrintAndLog("\nValid AWID ID Found!"); - return 1; - } - ans=CmdFSKdemodHID(""); - if (ans>0) { - PrintAndLog("\nValid HID Prox ID Found!"); - return 1; - } - //add psk and indala - ans=CmdIndalaDecode(""); - if (ans>0) { - PrintAndLog("\nValid Indala ID Found!"); - return 1; - } - ans=CmdAskEM410xDemod(""); - if (ans>0) { - PrintAndLog("\nValid EM410x ID Found!"); - return 1; - } - ans=CmdG_Prox_II_Demod(""); - if (ans>0) { - PrintAndLog("\nValid G Prox II ID Found!"); - return 1; - } - PrintAndLog("\nNo Known Tags Found!\n"); - if (testRaw=='u' || testRaw=='U'){ - //test unknown tag formats (raw mode) - PrintAndLog("\nChecking for Unknown tags:\n"); - ans=CmdDetectClockRate("f"); - if (ans != 0){ //fsk - ans=CmdFSKrawdemod(""); - if (ans>0) { - PrintAndLog("\nUnknown FSK Modulated Tag Found!"); - return 1; - } - } - ans=Cmdaskmandemod(""); - if (ans>0) { - PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!"); - return 1; - } - ans=CmdPSK1rawDemod(""); - if (ans>0) { - PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data psk2rawdemod'"); - PrintAndLog("\nCould also be PSK3 - [currently not supported]"); - PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod"); - return 1; - } - PrintAndLog("\nNo Data Found!\n"); - } - return 0; + int ans=0; + char cmdp = param_getchar(Cmd, 0); + char testRaw = param_getchar(Cmd, 1); + if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: lf search <0|1> [u]"); + PrintAndLog(" , if not set, try reading data from tag."); + PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags."); + PrintAndLog(""); + PrintAndLog(" sample: lf search = try reading data from tag & search for known tags"); + PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags"); + PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags"); + PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); + + return 0; + } + + if (!offline && (cmdp != '1')){ + ans=CmdLFRead(""); + ans=CmdSamples("20000"); + } else if (GraphTraceLen < 1000) { + PrintAndLog("Data in Graphbuffer was too small."); + return 0; + } + if (cmdp == 'u' || cmdp == 'U') testRaw = 'u'; + + PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); + PrintAndLog("False Positives ARE possible\n"); + PrintAndLog("\nChecking for known tags:\n"); + + ans=CmdFSKdemodIO(""); + if (ans>0) { + PrintAndLog("\nValid IO Prox ID Found!"); + return 1; + } + + ans=CmdFSKdemodPyramid(""); + if (ans>0) { + PrintAndLog("\nValid Pyramid ID Found!"); + return 1; + } + + ans=CmdFSKdemodParadox(""); + if (ans>0) { + PrintAndLog("\nValid Paradox ID Found!"); + return 1; + } + + ans=CmdFSKdemodAWID(""); + if (ans>0) { + PrintAndLog("\nValid AWID ID Found!"); + return 1; + } + + ans=CmdFSKdemodHID(""); + if (ans>0) { + PrintAndLog("\nValid HID Prox ID Found!"); + return 1; + } + + //add psk and indala + ans=CmdIndalaDecode(""); + if (ans>0) { + PrintAndLog("\nValid Indala ID Found!"); + return 1; + } + + ans=CmdAskEM410xDemod(""); + if (ans>0) { + PrintAndLog("\nValid EM410x ID Found!"); + return 1; + } + + ans=CmdG_Prox_II_Demod(""); + if (ans>0) { + PrintAndLog("\nValid G Prox II ID Found!"); + return 1; + } + + PrintAndLog("\nNo Known Tags Found!\n"); + if (testRaw=='u' || testRaw=='U'){ + //test unknown tag formats (raw mode) + PrintAndLog("\nChecking for Unknown tags:\n"); + ans=AutoCorrelate(4000, FALSE, FALSE); + if (ans > 0) PrintAndLog("Possible Auto Correlation of %d repeating samples",ans); + ans=GetFskClock("",FALSE,FALSE); //CmdDetectClockRate("F"); // + if (ans != 0){ //fsk + ans=FSKrawDemod("",FALSE); + if (ans>0) { + PrintAndLog("\nUnknown FSK Modulated Tag Found!"); + printDemodBuff(); + return 1; + } + } + ans=ASKmanDemod("",FALSE,FALSE); + if (ans>0) { + PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!"); + PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'"); + printDemodBuff(); + return 1; + } + ans=CmdPSK1rawDemod(""); + if (ans>0) { + PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'"); + PrintAndLog("\nCould also be PSK3 - [currently not supported]"); + PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod"); + printDemodBuff(); + return 1; + } + PrintAndLog("\nNo Data Found!\n"); + } + return 0; } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, - {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, - {"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"}, - {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, - {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, - {"io", CmdLFIO, 1, "{ ioProx tags... }"}, - {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, - {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, - {"read", CmdLFRead, 0, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, - {"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"}, - {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, - {"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d ] -- Simulate LF ASK tag from demodbuffer or input"}, - {"simfsk", CmdLFfskSim, 0, "[c ] [i] [H ] [L ] [d ] -- Simulate LF FSK tag from demodbuffer or input"}, - {"simpsk", CmdLFpskSim, 0, "[1|2|3] [c ] [i] [r ] [d ] -- Simulate LF PSK tag from demodbuffer or input"}, - {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, - //{"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, - {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, - {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, - {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, - {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, - {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, - {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, + {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, + {"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"}, + {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, + {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, + {"io", CmdLFIO, 1, "{ ioProx tags... }"}, + {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, + {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, + {"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, + {"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"}, + {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, + {"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d ] -- Simulate LF ASK tag from demodbuffer or input"}, + {"simfsk", CmdLFfskSim, 0, "[c ] [i] [H ] [L ] [d ] -- Simulate LF FSK tag from demodbuffer or input"}, + {"simpsk", CmdLFpskSim, 0, "[1|2|3] [c ] [i] [r ] [d ] -- Simulate LF PSK tag from demodbuffer or input"}, + {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, + //{"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, + {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, + {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, + {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, + {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, + {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, + {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, + {NULL, NULL, 0, NULL} }; int CmdLF(const char *Cmd) { - CmdsParse(CommandTable, Cmd); - return 0; + CmdsParse(CommandTable, Cmd); + return 0; } int CmdHelp(const char *Cmd) { - CmdsHelp(CommandTable); - return 0; + CmdsHelp(CommandTable); + return 0; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index f6671bcd..b915aa5a 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -43,163 +43,24 @@ int CmdEMdemodASK(const char *Cmd) */ int CmdEM410xRead(const char *Cmd) { - int i, j, clock, header, rows, bit, hithigh, hitlow, first, bit2idx, high, low; - int parity[4]; - char id[11] = {0x00}; - char id2[11] = {0x00}; - int retested = 0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]; - high = low = 0; - - /* Detect high and lows and clock */ - for (i = 0; i < GraphTraceLen; i++) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } - - /* get clock */ - clock = GetAskClock(Cmd, false, false); - - /* parity for our 4 columns */ - parity[0] = parity[1] = parity[2] = parity[3] = 0; - header = rows = 0; - - // manchester demodulate - bit = bit2idx = 0; - for (i = 0; i < (int)(GraphTraceLen / clock); i++) - { - hithigh = 0; - hitlow = 0; - first = 1; - - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; j++) - { - if (GraphBuffer[(i * clock) + j] >= high) - hithigh = 1; - else if (GraphBuffer[(i * clock) + j] <= low) - hitlow = 1; - - /* it doesn't count if it's the first part of our read - because it's really just trailing from the last sequence */ - if (first && (hithigh || hitlow)) - hithigh = hitlow = 0; - else - first = 0; - - if (hithigh && hitlow) - break; - } - - /* If we didn't hit both high and low peaks, we had a bit transition */ - if (!hithigh || !hitlow) - bit ^= 1; - - BitStream[bit2idx++] = bit; - } - -retest: - /* We go till 5 before the graph ends because we'll get that far below */ - for (i = 1; i < bit2idx - 5; i++) - { - /* Step 2: We have our header but need our tag ID */ - if (header == 9 && rows < 10) - { - /* Confirm parity is correct */ - if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4]) - { - /* Read another byte! */ - sprintf(id+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3])); - sprintf(id2+rows, "%x", (8 * BitStream[i+3]) + (4 * BitStream[i+2]) + (2 * BitStream[i+1]) + (1 * BitStream[i])); - rows++; - - /* Keep parity info */ - parity[0] ^= BitStream[i]; - parity[1] ^= BitStream[i+1]; - parity[2] ^= BitStream[i+2]; - parity[3] ^= BitStream[i+3]; - - /* Move 4 bits ahead */ - i += 4; - } - - /* Damn, something wrong! reset */ - else - { - PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i); - - /* Start back rows * 5 + 9 header bits, -1 to not start at same place */ - i -= 9 + (5 * rows) - 5; - - rows = header = 0; - } - } - - /* Step 3: Got our 40 bits! confirm column parity */ - else if (rows == 10) - { - /* We need to make sure our 4 bits of parity are correct and we have a stop bit */ - if (BitStream[i] == parity[0] && BitStream[i+1] == parity[1] && - BitStream[i+2] == parity[2] && BitStream[i+3] == parity[3] && - BitStream[i+4] == 0) - { - /* Sweet! */ - PrintAndLog("EM410x Tag ID: %s", id); - PrintAndLog("Unique Tag ID: %s", id2); - - global_em410xId = id; - - /* Stop any loops */ - return 1; - } - - /* Crap! Incorrect parity or no stop bit, start all over */ - else - { - rows = header = 0; - - /* Go back 59 bits (9 header bits + 10 rows at 4+1 parity) */ - i -= 59; - } - } - - /* Step 1: get our header */ - else if (header < 9) - { - /* Need 9 consecutive 1's */ - if (BitStream[i] == 1) - header++; - - /* We don't have a header, not enough consecutive 1 bits */ - else - header = 0; - } - } - - /* if we've already retested after flipping bits, return */ - if (retested++){ - PrintAndLog("Failed to decode"); + uint32_t hi=0; + uint64_t lo=0; + + if(!AskEm410xDemod("", &hi, &lo)) return 0; + PrintAndLog("EM410x pattern found: "); + printEM410x(hi, lo); + if (hi){ + PrintAndLog ("EM410x XL pattern found"); return 0; - } - - /* if this didn't work, try flipping bits */ - for (i = 0; i < bit2idx; i++) - BitStream[i] ^= 1; - - goto retest; + } + char id[12] = {0x00}; + sprintf(id, "%010llx",lo); + + global_em410xId = id; + return 1; } -/* emulate an EM410X tag - * Format: - * 1111 1111 1 <-- standard non-repeatable header - * XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID - * .... - * CCCC <-- each bit here is parity for the 10 bits above in corresponding column - * 0 <-- stop bit, end of tag - */ +// emulate an EM410X tag int CmdEM410xSim(const char *Cmd) { int i, n, j, binary[4], parity[4]; @@ -282,28 +143,25 @@ int CmdEM410xSim(const char *Cmd) */ int CmdEM410xWatch(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - int read_h = (cmdp == 'h'); do { if (ukbhit()) { printf("\naborted via keyboard!\n"); break; } - CmdLFRead(read_h ? "h" : ""); - CmdSamples("6000"); - } while ( - !CmdEM410xRead("") - ); + CmdLFRead("s"); + getSamples("8192",true); //capture enough to get 2 full messages + } while (!CmdEM410xRead("")); + return 0; } int CmdEM410xWatchnSpoof(const char *Cmd) { CmdEM410xWatch(Cmd); - PrintAndLog("# Replaying : %s",global_em410xId); - CmdEM410xSim(global_em410xId); - return 0; + PrintAndLog("# Replaying captured ID: %s",global_em410xId); + CmdLFaskSim(""); + return 0; } /* Read the transmitted data of an EM4x50 tag diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index a719c7ad..b6b29c05 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -13,128 +13,1098 @@ #include "proxmark3.h" #include "ui.h" #include "graph.h" +#include "cmdmain.h" #include "cmdparser.h" #include "cmddata.h" #include "cmdlf.h" #include "cmdlft55xx.h" +#include "util.h" +#include "data.h" +#include "lfdemod.h" +#include "../common/crc.h" +#include "../common/iso14443crc.h" +#include "cmdhf14a.h" + +#define CONFIGURATION_BLOCK 0x00 +#define TRACE_BLOCK 0x01 + +// Default configuration +t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00}; + +int usage_t55xx_config(){ + PrintAndLog("Usage: lf t55xx config [d ] [i 1] [o ]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" b <8|16|32|40|50|64|100|128> Set bitrate"); + PrintAndLog(" d Set demodulation FSK / ASK / PSK / NZ / Biphase / Biphase A"); + PrintAndLog(" i [1] Invert data signal, defaults to normal"); + PrintAndLog(" o [offset] Set offset, where data should start decode in bitstream"); + PrintAndLog(""); + PrintAndLog("Examples:"); + PrintAndLog(" lf t55xx config d FSK - FSK demodulation"); + PrintAndLog(" lf t55xx config d FSK i 1 - FSK demodulation, inverse data"); + PrintAndLog(" lf t55xx config d FSK i 1 o 3 - FSK demodulation, inverse data, offset=3,start from position 3 to decode data"); + PrintAndLog(""); + return 0; +} +int usage_t55xx_read(){ + PrintAndLog("Usage: lf t55xx read "); + PrintAndLog(" , block number to read. Between 0-7"); + PrintAndLog(" , OPTIONAL password (8 hex characters)"); + PrintAndLog(""); + PrintAndLog("Examples:"); + PrintAndLog(" lf t55xx read 0 - read data from block 0"); + PrintAndLog(" lf t55xx read 0 feedbeef - read data from block 0 password feedbeef"); + PrintAndLog(""); + return 0; +} +int usage_t55xx_write(){ + PrintAndLog("Usage: lf t55xx wr [password]"); + PrintAndLog(" , block number to read. Between 0-7"); + PrintAndLog(" , 4 bytes of data to write (8 hex characters)"); + PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)"); + PrintAndLog(""); + PrintAndLog("Examples:"); + PrintAndLog(" lf t55xx wd 3 11223344 - write 11223344 to block 3"); + PrintAndLog(" lf t55xx wd 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef"); + PrintAndLog(""); + return 0; +} +int usage_t55xx_trace() { + PrintAndLog("Usage: lf t55xx trace [1]"); + PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); + PrintAndLog(""); + PrintAndLog("Examples:"); + PrintAndLog(" lf t55xx trace"); + PrintAndLog(" lf t55xx trace 1"); + PrintAndLog(""); + return 0; +} +int usage_t55xx_info() { + PrintAndLog("Usage: lf t55xx info [1]"); + PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); + PrintAndLog(""); + PrintAndLog("Examples:"); + PrintAndLog(" lf t55xx info"); + PrintAndLog(" lf t55xx info 1"); + PrintAndLog(""); + return 0; +} +int usage_t55xx_dump(){ + PrintAndLog("Usage: lf t55xx dump "); + PrintAndLog(" , OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLog(""); + PrintAndLog("Examples:"); + PrintAndLog(" lf t55xx dump"); + PrintAndLog(" lf t55xx dump feedbeef"); + PrintAndLog(""); + return 0; +} +int usage_t55xx_detect(){ + PrintAndLog("Usage: lf t55xx detect"); + PrintAndLog(""); + PrintAndLog("Examples:"); + PrintAndLog(" lf t55xx detect"); + PrintAndLog(" lf t55xx detect 1"); + PrintAndLog(""); + return 0; +} static int CmdHelp(const char *Cmd); +int CmdT55xxSetConfig(const char *Cmd) { -int CmdReadBlk(const char *Cmd) -{ - int Block = 8; //default to invalid block - UsbCommand c; + uint8_t offset = 0; + bool errors = FALSE; + uint8_t cmdp = 0; + char modulation[5] = {0x00}; + char tmp = 0x00; + uint8_t bitRate = 0; + uint8_t rates[9] = {8,16,32,40,50,64,100,128,0}; + while(param_getchar(Cmd, cmdp) != 0x00 && !errors) + { + tmp = param_getchar(Cmd, cmdp); + switch(tmp) + { + case 'h': + case 'H': + return usage_t55xx_config(); + case 'b': + errors |= param_getdec(Cmd, cmdp+1, &bitRate); + if ( !errors){ + uint8_t i = 0; + for (; i < 9; i++){ + if (rates[i]==bitRate) { + config.bitrate = i; + break; + } + } + if (i==9) errors = TRUE; + } + cmdp+=2; + break; + case 'd': + param_getstr(Cmd, cmdp+1, modulation); + cmdp += 2; - sscanf(Cmd, "%d", &Block); + if ( strcmp(modulation, "FSK" ) == 0) + config.modulation = DEMOD_FSK; + else if ( strcmp(modulation, "FSK1" ) == 0) + config.modulation = DEMOD_FSK1; + else if ( strcmp(modulation, "FSK1a" ) == 0) + config.modulation = DEMOD_FSK1a; + else if ( strcmp(modulation, "FSK2" ) == 0) + config.modulation = DEMOD_FSK2; + else if ( strcmp(modulation, "FSK2a" ) == 0) + config.modulation = DEMOD_FSK2a; + else if ( strcmp(modulation, "ASK" ) == 0) + config.modulation = DEMOD_ASK; + else if ( strcmp(modulation, "NRZ" ) == 0) + config.modulation = DEMOD_NRZ; + else if ( strcmp(modulation, "PSK1" ) == 0) + config.modulation = DEMOD_PSK1; + else if ( strcmp(modulation, "PSK2" ) == 0) + config.modulation = DEMOD_PSK2; + else if ( strcmp(modulation, "PSK3" ) == 0) + config.modulation = DEMOD_PSK3; + else if ( strcmp(modulation, "BIa" ) == 0) + config.modulation = DEMOD_BIa; + else if ( strcmp(modulation, "BI" ) == 0) + config.modulation = DEMOD_BI; + else { + PrintAndLog("Unknown modulation '%s'", modulation); + errors = TRUE; + } + break; + case 'i': + config.inverted = param_getchar(Cmd,cmdp+1) == '1'; + cmdp+=2; + break; + case 'o': + errors |= param_getdec(Cmd, cmdp+1, &offset); + if ( !errors ) + config.offset = offset; + cmdp+=2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = TRUE; + break; + } + } - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } + // No args + if (cmdp == 0) { + printConfiguration( config ); + return 0; + } + //Validations + if (errors) + return usage_t55xx_config(); - PrintAndLog("Reading block %d", Block); + config.block0 = 0; + printConfiguration ( config ); + return 0; +} - c.cmd = CMD_T55XX_READ_BLOCK; - c.d.asBytes[0] = 0x0; //Normal mode - c.arg[0] = 0; - c.arg[1] = Block; - c.arg[2] = 0; - SendCommand(&c); - return 0; +int CmdT55xxReadBlock(const char *Cmd) { + int block = -1; + int password = 0xFFFFFFFF; //default to blank Block 7 + + char cmdp = param_getchar(Cmd, 0); + if (cmdp == 'h' || cmdp == 'H') + return usage_t55xx_read(); + + int res = sscanf(Cmd, "%d %x", &block, &password); + + if ( res < 1 || res > 2 ) + return usage_t55xx_read(); + + + if ((block < 0) | (block > 7)) { + PrintAndLog("Block must be between 0 and 7"); + return 1; + } + + UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}}; + c.d.asBytes[0] = 0x0; + + //Password mode + if ( res == 2 ) { + c.arg[2] = password; + c.d.asBytes[0] = 0x1; + } + + SendCommand(&c); + if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) { + PrintAndLog("command execution time out"); + return 2; + } + + uint8_t got[12000]; + GetFromBigBuf(got,sizeof(got),0); + WaitForResponse(CMD_ACK,NULL); + setGraphBuf(got, 12000); + DemodBufferLen=0; + if (!DecodeT55xxBlock()) return 3; + char blk[10]={0}; + sprintf(blk,"%d", block); + printT55xxBlock(blk); + return 0; } -int CmdReadBlkPWD(const char *Cmd) -{ - int Block = 8; //default to invalid block - int Password = 0xFFFFFFFF; //default to blank Block 7 - UsbCommand c; +bool DecodeT55xxBlock(){ + + char buf[8] = {0x00}; + char *cmdStr = buf; + int ans = 0; + uint8_t bitRate[8] = {8,16,32,40,50,64,100,128}; - sscanf(Cmd, "%d %x", &Block, &Password); + DemodBufferLen = 0x00; - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } + switch( config.modulation ){ + case DEMOD_FSK: + //CmdLtrim("26"); + sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); + CmdLtrim(cmdStr); + sprintf(cmdStr,"%d %d", bitRate[config.bitrate], config.inverted ); + ans = FSKrawDemod(cmdStr, FALSE); + break; + case DEMOD_FSK1: + //CmdLtrim("26"); + sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); + CmdLtrim(cmdStr); + sprintf(cmdStr,"%d 1 8 5", bitRate[config.bitrate] ); + ans = FSKrawDemod(cmdStr, FALSE); + break; + case DEMOD_FSK1a: + //CmdLtrim("26"); + sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); + CmdLtrim(cmdStr); + sprintf(cmdStr,"%d 0 8 5", bitRate[config.bitrate] ); + ans = FSKrawDemod(cmdStr, FALSE); + break; + case DEMOD_FSK2: + //CmdLtrim("26"); + sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); + CmdLtrim(cmdStr); + sprintf(cmdStr,"%d 0 10 8", bitRate[config.bitrate] ); + ans = FSKrawDemod(cmdStr, FALSE); + break; + case DEMOD_FSK2a: + //CmdLtrim("26"); + sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); + CmdLtrim(cmdStr); + sprintf(cmdStr,"%d 1 10 8", bitRate[config.bitrate] ); + ans = FSKrawDemod(cmdStr, FALSE); + break; + case DEMOD_ASK: + sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted ); + ans = ASKmanDemod(cmdStr, FALSE, FALSE); + break; + case DEMOD_PSK1: + sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted ); + ans = PSKDemod(cmdStr, FALSE); + break; + case DEMOD_PSK2: + sprintf(cmdStr,"%d 1", bitRate[config.bitrate] ); + ans = PSKDemod(cmdStr, FALSE); + psk1TOpsk2(DemodBuffer, DemodBufferLen); + break; + case DEMOD_PSK3: + sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted ); + ans = PSKDemod(cmdStr, FALSE); + psk1TOpsk2(DemodBuffer, DemodBufferLen); + break; + case DEMOD_NRZ: + sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted ); + ans = NRZrawDemod(cmdStr, FALSE); + break; + case DEMOD_BI: + sprintf(cmdStr,"0 %d 0 1", bitRate[config.bitrate] ); + ans = ASKbiphaseDemod(cmdStr, FALSE); + break; + case DEMOD_BIa: + sprintf(cmdStr,"0 %d 1 1", bitRate[config.bitrate] ); + ans = ASKbiphaseDemod(cmdStr, FALSE); + break; + default: + return FALSE; + } + return (bool) ans; +} - PrintAndLog("Reading block %d with password %08X", Block, Password); +int CmdT55xxDetect(const char *Cmd){ - c.cmd = CMD_T55XX_READ_BLOCK; - c.d.asBytes[0] = 0x1; //Password mode - c.arg[0] = 0; - c.arg[1] = Block; - c.arg[2] = Password; - SendCommand(&c); - return 0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') + return usage_t55xx_detect(); + + if (strlen(Cmd)==0) + AquireData( CONFIGURATION_BLOCK ); + + if ( !tryDetectModulation() ) + PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); + + return 0; } -int CmdWriteBlk(const char *Cmd) -{ - int Block = 8; //default to invalid block - int Data = 0xFFFFFFFF; //default to blank Block - UsbCommand c; +// detect configuration? +bool tryDetectModulation(){ + char cmdStr[8] = {0}; + uint8_t hits = 0; + t55xx_conf_block_t tests[15]; + + if (GetFskClock("", FALSE, FALSE)){ + uint8_t fc1 = 0, fc2 = 0, clk=0; + fskClocks(&fc1, &fc2, &clk, FALSE); + sprintf(cmdStr,"%d", clk/2); + CmdLtrim(cmdStr); + if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset)){ + tests[hits].modulation = DEMOD_FSK; + if (fc1==8 && fc2 == 5) + tests[hits].modulation = DEMOD_FSK1a; + else if (fc1==10 && fc2 == 8) + tests[hits].modulation = DEMOD_FSK2; - sscanf(Cmd, "%x %d", &Data, &Block); + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset)) { + tests[hits].modulation = DEMOD_FSK; + if (fc1==8 && fc2 == 5) + tests[hits].modulation = DEMOD_FSK1; + else if (fc1==10 && fc2 == 8) + tests[hits].modulation = DEMOD_FSK2a; - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } + tests[hits].inverted = TRUE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + } else { + if ( ASKmanDemod("0 0 1", FALSE, FALSE) && test(DEMOD_ASK, &tests[hits].offset)) { + tests[hits].modulation = DEMOD_ASK; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } - PrintAndLog("Writting block %d with data %08X", Block, Data); + if ( ASKmanDemod("0 1 1", FALSE, FALSE) && test(DEMOD_ASK, &tests[hits].offset)) { + tests[hits].modulation = DEMOD_ASK; + tests[hits].inverted = TRUE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + + if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset)) { + tests[hits].modulation = DEMOD_NRZ; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } - c.cmd = CMD_T55XX_WRITE_BLOCK; - c.d.asBytes[0] = 0x0; //Normal mode - c.arg[0] = Data; - c.arg[1] = Block; - c.arg[2] = 0; - SendCommand(&c); - return 0; + if ( NRZrawDemod("0 1 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset)) { + tests[hits].modulation = DEMOD_NRZ; + tests[hits].inverted = TRUE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + + if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) { + tests[hits].modulation = DEMOD_PSK1; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + + if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) { + tests[hits].modulation = DEMOD_PSK1; + tests[hits].inverted = TRUE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + + // PSK2 - needs a call to psk1TOpsk2. + if ( PSKDemod("0 0 1", FALSE)) { + psk1TOpsk2(DemodBuffer, DemodBufferLen); + if (test(DEMOD_PSK2, &tests[hits].offset)){ + tests[hits].modulation = DEMOD_PSK2; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + } // inverse waves does not affect this demod + + // PSK3 - needs a call to psk1TOpsk2. + if ( PSKDemod("0 0 1", FALSE)) { + psk1TOpsk2(DemodBuffer, DemodBufferLen); + if (test(DEMOD_PSK3, &tests[hits].offset)){ + tests[hits].modulation = DEMOD_PSK3; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + } // inverse waves does not affect this demod + + if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset) ) { + tests[hits].modulation = DEMOD_BI; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset) ) { + tests[hits].modulation = DEMOD_BIa; + tests[hits].inverted = TRUE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + } + if ( hits == 1) { + config.modulation = tests[0].modulation; + config.inverted = tests[0].inverted; + config.offset = tests[0].offset; + config.block0 = tests[0].block0; + printConfiguration( config ); + return TRUE; + } + + if ( hits > 1) { + PrintAndLog("Found [%d] possible matches for modulation.",hits); + for(int i=0; i 3 && modread < 8) return TRUE; + break; + case DEMOD_ASK: + if (modread == DEMOD_ASK) return TRUE; + break; + case DEMOD_PSK1: + if (modread == DEMOD_PSK1) return TRUE; + break; + case DEMOD_PSK2: + if (modread == DEMOD_PSK2) return TRUE; + break; + case DEMOD_PSK3: + if (modread == DEMOD_PSK3) return TRUE; + break; + case DEMOD_NRZ: + if (modread == DEMOD_NRZ) return TRUE; + break; + case DEMOD_BI: + if (modread == DEMOD_BI) return TRUE; + break; + case DEMOD_BIa: + if (modread == DEMOD_BIa) return TRUE; + break; + default: + return FALSE; + } + return FALSE; +} + +bool testBitRate(uint8_t readRate, uint8_t mod){ + uint8_t expected[8] = {8, 16, 32, 40, 50, 64, 100, 128}; + uint8_t detRate = 0; + switch( mod ){ + case DEMOD_FSK: + detRate = GetFskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_FSK1: + detRate = GetFskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_FSK1a: + detRate = GetFskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_FSK2: + detRate = GetFskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_FSK2a: + detRate = GetFskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_ASK: + detRate = GetAskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_PSK1: + detRate = GetPskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_PSK2: + detRate = GetPskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_PSK3: + detRate = GetPskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_NRZ: + detRate = GetNrzClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + case DEMOD_BI: + detRate = GetAskClock("",FALSE, FALSE); + if (expected[readRate] == detRate) { + config.bitrate = readRate; + return TRUE; + } + break; + default: + return FALSE; + } + return FALSE; +} + +bool test(uint8_t mode, uint8_t *offset){ + + if ( !DemodBufferLen) return FALSE; + uint8_t si = 0; + for (uint8_t idx = 0; idx < 64; idx++){ + si = idx; + if ( PackBits(si, 32, DemodBuffer) == 0x00 ) continue; + + uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key + uint8_t resv = PackBits(si, 4, DemodBuffer); si += 4; //was 7 & +=7+3 //should be only 4 bits if extended mode + // 2nibble must be zeroed. + // moved test to here, since this gets most faults first. + if ( resv > 0x00) continue; + + uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //new + uint8_t bitRate = PackBits(si, 3, DemodBuffer); si += 3; //new could check bit rate + uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode + uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1; //new + //uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //new could check psk cr + uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24 , 30, 31 could be tested for 0 if not extended mode + uint8_t nml02 = PackBits(si, 2, DemodBuffer); si += 2; + + //if extended mode + bool extMode =( (safer == 0x6 || safer == 0x9) && extend) ? TRUE : FALSE; + + if (!extMode){ + if (nml01 || nml02 || xtRate) continue; + } + //test modulation + if (!testModulation(mode, modread)) continue; + + *offset = idx; + if (!testBitRate(bitRate, mode)) continue; + return TRUE; + } + return FALSE; +} + +void printT55xxBlock(const char *demodStr){ + + uint8_t i = config.offset; + uint8_t endpos = 32 + i; + uint32_t blockData = 0; + uint8_t bits[64] = {0x00}; + + if ( !DemodBufferLen) return; + + if ( endpos > DemodBufferLen){ + PrintAndLog("The configured offset %d is too big. Possible offset: %d)", i, DemodBufferLen-32); + return; + } + + for (; i < endpos; ++i) + bits[i - config.offset]=DemodBuffer[i]; + + blockData = PackBits(0, 32, bits); + PrintAndLog("0x%08X %s [%s]", blockData, sprint_bin(bits,32), demodStr); } -int CmdWriteBlkPWD(const char *Cmd) +int special(const char *Cmd) { + uint32_t blockData = 0; + uint8_t bits[32] = {0x00}; + + PrintAndLog("[OFFSET] [DATA] [BINARY]"); + PrintAndLog("----------------------------------------------------"); + int i,j = 0; + for (; j < 64; ++j){ + + for (i = 0; i < 32; ++i) + bits[i]=DemodBuffer[j+i]; + + blockData = PackBits(0, 32, bits); + + PrintAndLog("[%02d] 0x%08X %s",j , blockData, sprint_bin(bits,32)); + } + return 0; +} + +void printConfiguration( t55xx_conf_block_t b){ + PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) ); + PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) ); + PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" ); + PrintAndLog("Offset : %d", b.offset); + PrintAndLog("Block0 : 0x%08X", b.block0); + PrintAndLog(""); +} + +int CmdT55xxWriteBlock(const char *Cmd) { - int Block = 8; //default to invalid block - int Data = 0xFFFFFFFF; //default to blank Block - int Password = 0xFFFFFFFF; //default to blank Block 7 - UsbCommand c; - - sscanf(Cmd, "%x %d %x", &Data, &Block, &Password); - - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } - - PrintAndLog("Writting block %d with data %08X and password %08X", Block, Data, Password); - - c.cmd = CMD_T55XX_WRITE_BLOCK; - c.d.asBytes[0] = 0x1; //Password mode - c.arg[0] = Data; - c.arg[1] = Block; - c.arg[2] = Password; - SendCommand(&c); - return 0; + int block = 8; //default to invalid block + int data = 0xFFFFFFFF; //default to blank Block + int password = 0xFFFFFFFF; //default to blank Block 7 + + char cmdp = param_getchar(Cmd, 0); + if (cmdp == 'h' || cmdp == 'H') { + usage_t55xx_write(); + return 0; + } + + int res = sscanf(Cmd, "%d %x %x",&block, &data, &password); + + if ( res < 2 || res > 3) { + usage_t55xx_write(); + return 1; + } + + if (block > 7) { + PrintAndLog("Block number must be between 0 and 7"); + return 1; + } + + UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}}; + c.d.asBytes[0] = 0x0; + + PrintAndLog("Writing to block: %d data : 0x%08X", block, data); + + //Password mode + if (res == 3) { + c.arg[2] = password; + c.d.asBytes[0] = 0x1; + PrintAndLog("pwd : 0x%08X", password); + } + SendCommand(&c); + return 0; } -int CmdReadTrace(const char *Cmd) +int CmdT55xxReadTrace(const char *Cmd) { + char cmdp = param_getchar(Cmd, 0); + + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') + return usage_t55xx_trace(); - PrintAndLog("Reading traceability data"); + if (strlen(Cmd)==0) + AquireData( TRACE_BLOCK ); + + if (!DecodeT55xxBlock()) return 1; - UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}}; - SendCommand(&c); + if ( !DemodBufferLen) return 1; + + RepaintGraphWindow(); + uint8_t repeat = 0; + if (config.offset > 5) + repeat = 32; + uint8_t si = config.offset+repeat; + uint32_t bl0 = PackBits(si, 32, DemodBuffer); + uint32_t bl1 = PackBits(si+32, 32, DemodBuffer); + + uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8; + uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8; + uint32_t cid = PackBits(si, 5, DemodBuffer); si += 5; + uint32_t icr = PackBits(si, 3, DemodBuffer); si += 3; + uint32_t year = PackBits(si, 4, DemodBuffer); si += 4; + uint32_t quarter = PackBits(si, 2, DemodBuffer); si += 2; + uint32_t lotid = PackBits(si, 14, DemodBuffer); si += 14; + uint32_t wafer = PackBits(si, 5, DemodBuffer); si += 5; + uint32_t dw = PackBits(si, 15, DemodBuffer); + + PrintAndLog(""); + PrintAndLog("-- T55xx Trace Information ----------------------------------"); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", acl, acl); + PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d) - %s", mfc, mfc, getTagInfo(mfc)); + PrintAndLog(" CID : 0x%02X (%d) - %s", cid, cid, GetModelStrFromCID(cid)); + PrintAndLog(" ICR IC Revision : %d",icr ); + PrintAndLog(" Manufactured"); + PrintAndLog(" Year/Quarter : 20?%d/%d",year, quarter); + PrintAndLog(" Lot ID : %d", lotid ); + PrintAndLog(" Wafer number : %d", wafer); + PrintAndLog(" Die Number : %d", dw); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" Raw Data - Page 1"); + PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(DemodBuffer+config.offset+repeat,32) ); + PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) ); + PrintAndLog("-------------------------------------------------------------"); + + if ( acl != 0xE0 ) + PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. "); + /* + TRACE - BLOCK O + Bits Definition HEX + 1-8 ACL Allocation class (ISO/IEC 15963-1) 0xE0 + 9-16 MFC Manufacturer ID (ISO/IEC 7816-6) 0x15 Atmel Corporation + 17-21 CID 0x1 = Atmel ATA5577M1 0x2 = Atmel ATA5577M2 + 22-24 ICR IC revision + 25-28 YEAR (BCD encoded) 9 (= 2009) + 29-30 QUARTER 1,2,3,4 + 31-32 LOT ID + + TRACE - BLOCK 1 + 1-12 LOT ID + 13-17 Wafer number + 18-32 DW, die number sequential + */ + return 0; } +int CmdT55xxInfo(const char *Cmd){ + /* + Page 0 Block 0 Configuration data. + Normal mode + Extended mode + */ + char cmdp = param_getchar(Cmd, 0); + + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') + return usage_t55xx_info(); + + if (strlen(Cmd)==0) + AquireData( CONFIGURATION_BLOCK ); + + if (!DecodeT55xxBlock()) return 1; + + if ( !DemodBufferLen) return 1; + + uint8_t si = config.offset; + uint32_t bl0 = PackBits(si, 32, DemodBuffer); + + uint32_t safer = PackBits(si, 4, DemodBuffer); si += 4; + uint32_t resv = PackBits(si, 7, DemodBuffer); si += 7; + uint32_t dbr = PackBits(si, 3, DemodBuffer); si += 3; + uint32_t extend = PackBits(si, 1, DemodBuffer); si += 1; + uint32_t datamod = PackBits(si, 5, DemodBuffer); si += 5; + uint32_t pskcf = PackBits(si, 2, DemodBuffer); si += 2; + uint32_t aor = PackBits(si, 1, DemodBuffer); si += 1; + uint32_t otp = PackBits(si, 1, DemodBuffer); si += 1; + uint32_t maxblk = PackBits(si, 3, DemodBuffer); si += 3; + uint32_t pwd = PackBits(si, 1, DemodBuffer); si += 1; + uint32_t sst = PackBits(si, 1, DemodBuffer); si += 1; + uint32_t fw = PackBits(si, 1, DemodBuffer); si += 1; + uint32_t inv = PackBits(si, 1, DemodBuffer); si += 1; + uint32_t por = PackBits(si, 1, DemodBuffer); si += 1; + + PrintAndLog(""); + PrintAndLog("-- T55xx Configuration & Tag Information --------------------"); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" Safer key : %s", GetSaferStr(safer)); + PrintAndLog(" reserved : %d", resv); + PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr)); + PrintAndLog(" eXtended mode : %s", (extend) ? "Yes - Warning":"No"); + PrintAndLog(" Modulation : %s", GetModulationStr(datamod)); + PrintAndLog(" PSK clock frequency : %d", pskcf); + PrintAndLog(" AOR - Answer on Request : %s", (aor) ? "Yes":"No"); + PrintAndLog(" OTP - One Time Pad : %s", (otp) ? "Yes - Warning":"No" ); + PrintAndLog(" Max block : %d", maxblk); + PrintAndLog(" Password mode : %s", (pwd) ? "Yes":"No"); + PrintAndLog(" Sequence Start Terminator : %s", (sst) ? "Yes":"No"); + PrintAndLog(" Fast Write : %s", (fw) ? "Yes":"No"); + PrintAndLog(" Inverse data : %s", (inv) ? "Yes":"No"); + PrintAndLog(" POR-Delay : %s", (por) ? "Yes":"No"); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" Raw Data - Page 0"); + PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(DemodBuffer+config.offset,32) ); + PrintAndLog("-------------------------------------------------------------"); + + return 0; +} + +int CmdT55xxDump(const char *Cmd){ + + char s[20] = {0x00}; + uint8_t pwd[4] = {0x00}; + + char cmdp = param_getchar(Cmd, 0); + if ( cmdp == 'h' || cmdp == 'H') { + usage_t55xx_dump(); + return 0; + } + + bool hasPwd = ( strlen(Cmd) > 0); + if ( hasPwd ){ + if (param_gethex(Cmd, 0, pwd, 8)) { + PrintAndLog("password must include 8 HEX symbols"); + return 1; + } + } + + for ( int i = 0; i <8; ++i){ + memset(s,0,sizeof(s)); + if ( hasPwd ) { + sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]); + } else { + sprintf(s,"%d", i); + } + CmdT55xxReadBlock(s); + } + return 0; +} + +int AquireData( uint8_t block ){ + + UsbCommand c; + + if ( block == CONFIGURATION_BLOCK ) + c.cmd = CMD_T55XX_READ_BLOCK; + else if (block == TRACE_BLOCK ) + c.cmd = CMD_T55XX_READ_TRACE; + + c.arg[0] = 0x00; + c.arg[1] = 0x00; + c.arg[2] = 0x00; + c.d.asBytes[0] = 0x0; + + //Password mode + // if ( res == 2 ) { + // c.arg[2] = password; + // c.d.asBytes[0] = 0x1; + // } + + SendCommand(&c); + if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) { + PrintAndLog("command execution time out"); + return 1; + } + + uint8_t got[12000]; + GetFromBigBuf(got,sizeof(got),0); + WaitForResponse(CMD_ACK,NULL); + setGraphBuf(got, 12000); + return 0; +} + +char * GetBitRateStr(uint32_t id){ + static char buf[40]; + char *retStr = buf; + switch (id){ + case 0: + snprintf(retStr,sizeof(buf),"%d - RF/8",id); + break; + case 1: + snprintf(retStr,sizeof(buf),"%d - RF/16",id); + break; + case 2: + snprintf(retStr,sizeof(buf),"%d - RF/32",id); + break; + case 3: + snprintf(retStr,sizeof(buf),"%d - RF/40",id); + break; + case 4: + snprintf(retStr,sizeof(buf),"%d - RF/50",id); + break; + case 5: + snprintf(retStr,sizeof(buf),"%d - RF/64",id); + break; + case 6: + snprintf(retStr,sizeof(buf),"%d - RF/100",id); + break; + case 7: + snprintf(retStr,sizeof(buf),"%d - RF/128",id); + break; + default: + snprintf(retStr,sizeof(buf),"%d - (Unknown)",id); + break; + } + + return buf; +} + + +char * GetSaferStr(uint32_t id){ + static char buf[40]; + char *retStr = buf; + + snprintf(retStr,sizeof(buf),"%d",id); + if (id == 6) { + snprintf(retStr,sizeof(buf),"%d - passwd",id); + } + if (id == 9 ){ + snprintf(retStr,sizeof(buf),"%d - testmode",id); + } + + return buf; +} + +char * GetModulationStr( uint32_t id){ + static char buf[40]; + char *retStr = buf; + + switch (id){ + case 0: + snprintf(retStr,sizeof(buf),"%d - DIRECT (ASK/NRZ)",id); + break; + case 1: + snprintf(retStr,sizeof(buf),"%d - PSK 1 phase change when input changes",id); + break; + case 2: + snprintf(retStr,sizeof(buf),"%d - PSK 2 phase change on bitclk if input high",id); + break; + case 3: + snprintf(retStr,sizeof(buf),"%d - PSK 3 phase change on rising edge of input",id); + break; + case 4: + snprintf(retStr,sizeof(buf),"%d - FSK 1 RF/8 RF/5",id); + break; + case 5: + snprintf(retStr,sizeof(buf),"%d - FSK 2 RF/8 RF/10",id); + break; + case 6: + snprintf(retStr,sizeof(buf),"%d - FSK 1a RF/5 RF/8",id); + break; + case 7: + snprintf(retStr,sizeof(buf),"%d - FSK 2a RF/10 RF/8",id); + break; + case 8: + snprintf(retStr,sizeof(buf),"%d - Manschester",id); + break; + case 16: + snprintf(retStr,sizeof(buf),"%d - Biphase",id); + break; + case 0x18: + snprintf(retStr,sizeof(buf),"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id); + break; + case 17: + snprintf(retStr,sizeof(buf),"%d - Reserved",id); + break; + default: + snprintf(retStr,sizeof(buf),"0x%02X (Unknown)",id); + break; + } + return buf; +} + +char * GetModelStrFromCID(uint32_t cid){ + + static char buf[10]; + char *retStr = buf; + + if (cid == 1) sprintf(retStr,"ATA5577M1"); + if (cid == 2) sprintf(retStr,"ATA5577M2"); + return buf; +} + +char * GetSelectedModulationStr( uint8_t id){ + + static char buf[20]; + char *retStr = buf; + + switch (id){ + case DEMOD_FSK: + snprintf(retStr,sizeof(buf),"FSK"); + break; + case DEMOD_FSK1: + snprintf(retStr,sizeof(buf),"FSK1"); + break; + case DEMOD_FSK1a: + snprintf(retStr,sizeof(buf),"FSK1a"); + break; + case DEMOD_FSK2: + snprintf(retStr,sizeof(buf),"FSK2"); + break; + case DEMOD_FSK2a: + snprintf(retStr,sizeof(buf),"FSK2a"); + break; + case DEMOD_ASK: + snprintf(retStr,sizeof(buf),"ASK"); + break; + case DEMOD_NRZ: + snprintf(retStr,sizeof(buf),"DIRECT/NRZ"); + break; + case DEMOD_PSK1: + snprintf(retStr,sizeof(buf),"PSK1"); + break; + case DEMOD_PSK2: + snprintf(retStr,sizeof(buf),"PSK2"); + break; + case DEMOD_PSK3: + snprintf(retStr,sizeof(buf),"PSK3"); + break; + case DEMOD_BI: + snprintf(retStr,sizeof(buf),"BIPHASE"); + break; + case DEMOD_BIa: + snprintf(retStr,sizeof(buf),"BIPHASEa - (CDP)"); + break; + default: + snprintf(retStr,sizeof(buf),"(Unknown)"); + break; + } + return buf; +} + +uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){ + + int i = start; + int j = len-1; + + if (len > 32) return 0; + + uint32_t tmp = 0; + for (; j >= 0; --j, ++i) + tmp |= bits[i] << j; + + return tmp; +} + static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"readblock", CmdReadBlk, 1, " -- Read T55xx block data (page 0)"}, - {"readblockPWD", CmdReadBlkPWD, 1, " -- Read T55xx block data in password mode(page 0)"}, - {"writeblock", CmdWriteBlk, 1, " -- Write T55xx block data (page 0)"}, - {"writeblockPWD", CmdWriteBlkPWD, 1, " -- Write T55xx block data in password mode(page 0)"}, - {"readtrace", CmdReadTrace, 1, "Read T55xx traceability data (page 1)"}, + {"help", CmdHelp, 1, "This help"}, + {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, + {"detect", CmdT55xxDetect, 0, "[1] Try detecting the tag modulation from reading the configuration block."}, + {"read", CmdT55xxReadBlock, 0, " [password] -- Read T55xx block data (page 0) [optional password]"}, + {"write", CmdT55xxWriteBlock,0, " [password] -- Write T55xx block data (page 0) [optional password]"}, + {"trace", CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"}, + {"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"}, + {"dump", CmdT55xxDump, 0, "[password] Dump T55xx card block 0-7. [optional password]"}, + {"special", special, 0, "Show block changes with 64 different offsets"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 25503e87..a64b1eda 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -10,12 +10,57 @@ #ifndef CMDLFT55XX_H__ #define CMDLFT55XX_H__ +typedef struct { + enum { + DEMOD_NRZ = 0x00, + DEMOD_PSK1 = 0x01, + DEMOD_PSK2 = 0x02, + DEMOD_PSK3 = 0x03, + DEMOD_FSK1 = 0x04, + DEMOD_FSK1a = 0x05, + DEMOD_FSK2 = 0x06, + DEMOD_FSK2a = 0x07, + DEMOD_FSK = 0xF0, //generic FSK (auto detect FCs) + DEMOD_ASK = 0x08, + DEMOD_BI = 0x10, + DEMOD_BIa = 0x18, + } modulation; + bool inverted; + uint8_t offset; + uint32_t block0; + enum { + RF_8 = 0x00, + RF_16 = 0x01, + RF_32 = 0x02, + RF_40 = 0x03, + RF_50 = 0x04, + RF_64 = 0x05, + RF_100 = 0x06, + RF_128 = 0x07, + } bitrate; +} t55xx_conf_block_t; + int CmdLFT55XX(const char *Cmd); +int CmdT55xxSetConfig(const char *Cmd); +int CmdT55xxReadBlock(const char *Cmd); +int CmdT55xxWriteBlock(const char *Cmd); +int CmdT55xxReadTrace(const char *Cmd); +int CmdT55xxInfo(const char *Cmd); +int CmdT55xxDetect(const char *Cmd); + +char * GetBitRateStr(uint32_t id); +char * GetSaferStr(uint32_t id); +char * GetModulationStr( uint32_t id); +char * GetModelStrFromCID(uint32_t cid); +char * GetSelectedModulationStr( uint8_t id); +uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bitstream); +void printT55xxBlock(const char *demodStr); +void printConfiguration( t55xx_conf_block_t b); -int CmdReadBlk(const char *Cmd); -int CmdReadBlkPWD(const char *Cmd); -int CmdWriteBlk(const char *Cmd); -int CmdWriteBLkPWD(const char *Cmd); -int CmdReadTrace(const char *Cmd); +bool DecodeT55xxBlock(); +bool tryDetectModulation(); +bool test(uint8_t mode, uint8_t *offset); +int special(const char *Cmd); +int AquireData( uint8_t block ); #endif diff --git a/client/graph.c b/client/graph.c index 190dfe8f..f4acc579 100644 --- a/client/graph.c +++ b/client/graph.c @@ -146,7 +146,7 @@ uint8_t GetPskCarrier(const char str[], bool printAns, bool verbose) } //uint8_t countPSK_FC(uint8_t *BitStream, size_t size) - carrier = countPSK_FC(grph,size); + carrier = countFC(grph,size,0); // Only print this message if we're not looping something if (printAns){ PrintAndLog("Auto-detected PSK carrier rate: %d", carrier); @@ -232,8 +232,7 @@ uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose) 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); + uint16_t ans = countFC(BitStream, size, 1); if (ans==0) { if (verbose) PrintAndLog("DEBUG: No data found"); return 0; diff --git a/client/scripts/test_t55x7_ask.lua b/client/scripts/test_t55x7_ask.lua new file mode 100644 index 00000000..569d4260 --- /dev/null +++ b/client/scripts/test_t55x7_ask.lua @@ -0,0 +1,139 @@ +local cmds = require('commands') +local getopt = require('getopt') +local bin = require('bin') +local utils = require('utils') + +local format=string.format +local floor=math.floor + +example =[[ + 1. script run test_t55x7_ask +]] +author = "Iceman" +usage = "script run test_t55x7_ask" +desc =[[ +This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100 +The outlined procedure is as following: + +--ASK + 00 00 80 40 +-- max 2 +-- manchester +-- bit rate + +"lf t55xx write 0 00008040" +"lf t55xx detect" +"lf t55xx info" + +Loop: + change the configuretion block 0 with: + -xx 00 xxxx = RF/8 + -xx 04 xxxx = RF/16 + -xx 08 xxxx = RF/32 + -xx 0C xxxx = RF/40 + -xx 10 xxxx = RF/50 + -xx 14 xxxx = RF/64 + -xx 18 xxxx = RF/100 + -xx 1C xxxx = RF/128 + + +testsuit for the ASK/MANCHESTER demod + +Arguments: + -h : this help +]] + +local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds +local DEBUG = true -- the debug flag + +--BLOCK 0 = 00008040 ASK / MAN +local config1 = '00' +local config2 = '8040' + +local procedurecmds = { + [1] = '%s%02X%s', + [2] = 'lf t55xx detect', + [3] = 'lf t55xx info', +} +--- +-- A debug printout-function +function dbg(args) + if not DEBUG then + return + end + + if type(args) == "table" then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +function oops(err) + print("ERROR: ",err) +end +--- +-- Usage help +function help() + print(desc) + print("Example usage") + print(example) +end +-- +-- Exit message +function ExitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end + +function test() + local y + for y = 0x0, 0x1d, 0x4 do + for _ = 1, #procedurecmds do + local pcmd = procedurecmds[_] + + if #pcmd == 0 then + + elseif _ == 1 then + + local config = pcmd:format(config1, y, config2) + dbg(('lf t55xx write 0 %s'):format(config)) + config = tonumber(config,16) + + local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config} + local err = core.SendCommand(writecmd:getBytes()) + if err then return oops(err) end + local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) + + else + dbg(pcmd) + core.console( pcmd ) + end + end + core.clearCommandBuffer() + end + print( string.rep('--',20) ) +end + +local function main(args) + + print( string.rep('--',20) ) + print( string.rep('--',20) ) + + -- Arguments for the script + for o, arg in getopt.getopt(args, 'h') do + if o == "h" then return help() end + end + + core.clearCommandBuffer() + test() + print( string.rep('--',20) ) +end +main(args) \ No newline at end of file diff --git a/client/scripts/test_t55x7_bi.lua b/client/scripts/test_t55x7_bi.lua new file mode 100644 index 00000000..a1793ba6 --- /dev/null +++ b/client/scripts/test_t55x7_bi.lua @@ -0,0 +1,133 @@ +local cmds = require('commands') +local getopt = require('getopt') +local bin = require('bin') +local utils = require('utils') + +example =[[ + 1. script run test_t55x7_bi +]] +author = "Iceman" +usage = "script run test_t55x7_bi" +desc =[[ +This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00010040 +The outlined procedure is as following: + +--BIPHASE 00010040 +-- + +"lf t55xx write 0 00010040" +"lf t55xx detect" +"lf t55xx info" + +Loop: + change the configuretion block 0 with: + -xx01xxxx = RF/8 + -xx05xxxx = RF/16 + -xx09xxxx = RF/32 + -xx0Dxxxx = RF/40 + -xx11xxxx = RF/50 + -xx15xxxx = RF/64 + -xx19xxxx = RF/100 + -xx1Dxxxx = RF/128 + + +testsuit for the BIPHASE demod + +Arguments: + -h : this help +]] + +local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds +local DEBUG = true -- the debug flag + +--BLOCK 0 = 00010040 BIPHASE +local config1 = '00' +local config2 = '0040' + +local procedurecmds = { + [1] = '%s%02X%s', + [2] = 'lf t55xx detect', + [3] = 'lf t55xx info', +} +--- +-- A debug printout-function +function dbg(args) + if not DEBUG then + return + end + + if type(args) == "table" then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +function oops(err) + print("ERROR: ",err) +end +--- +-- Usage help +function help() + print(desc) + print("Example usage") + print(example) +end +-- +-- Exit message +function ExitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end + +function test() + local y + for y = 1, 0x1D, 4 do + for _ = 1, #procedurecmds do + local pcmd = procedurecmds[_] + + if #pcmd == 0 then + + elseif _ == 1 then + + local config = pcmd:format(config1, y, config2) + dbg(('lf t55xx wr 0 %s'):format(config)) + + config = tonumber(config,16) + local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config} + local err = core.SendCommand(writecmd:getBytes()) + if err then return oops(err) end + local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) + else + dbg(pcmd) + core.console( pcmd ) + end + end + core.clearCommandBuffer() + end + print( string.rep('--',20) ) + +end + +local function main(args) + + print( string.rep('--',20) ) + print( string.rep('--',20) ) + + -- Arguments for the script + for o, arg in getopt.getopt(args, 'h') do + if o == "h" then return help() end + end + + core.clearCommandBuffer() + test() + print( string.rep('--',20) ) +end +main(args) diff --git a/client/scripts/test_t55x7_fsk.lua b/client/scripts/test_t55x7_fsk.lua new file mode 100644 index 00000000..f42dd147 --- /dev/null +++ b/client/scripts/test_t55x7_fsk.lua @@ -0,0 +1,139 @@ +local cmds = require('commands') +local getopt = require('getopt') +local bin = require('bin') +local utils = require('utils') + +example =[[ + 1. script run test_t55x7_fsk +]] +author = "Iceman" +usage = "script run test_t55x7_fsk" +desc =[[ +This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100 +The outlined procedure is as following: + +--ASK + 00 00 80 40 +-- max 2 blocks +-- FSK1 +-- bit rate + +"lf t55xx write 0 00007040" +"lf t55xx detect" +"lf t55xx info" + +Loop: + change the configuretion block 0 with: + -xx 00 xxxx = RF/8 + -xx 04 xxxx = RF/16 + -xx 08 xxxx = RF/32 + -xx 0C xxxx = RF/40 + -xx 10 xxxx = RF/50 + -xx 14 xxxx = RF/64 + -xx 18 xxxx = RF/100 + -xx 1C xxxx = RF/128 + + +testsuit for the ASK/MANCHESTER demod + +Arguments: + -h : this help +]] + +local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds +local DEBUG = true -- the debug flag + +--BLOCK 0 = 00008040 FSK +local config1 = '00' +local config2 = '040' + +local procedurecmds = { + [1] = '%s%02X%X%s', + [2] = 'lf t55xx detect', + [3] = 'lf t55xx info', +} +--- +-- A debug printout-function +function dbg(args) + if not DEBUG then + return + end + + if type(args) == "table" then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +function oops(err) + print("ERROR: ",err) +end +--- +-- Usage help +function help() + print(desc) + print("Example usage") + print(example) +end +-- +-- Exit message +function ExitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end + +function test(modulation) + local y + for y = 0x0, 0x1d, 0x4 do + for _ = 1, #procedurecmds do + local pcmd = procedurecmds[_] + + if #pcmd == 0 then + + elseif _ == 1 then + + local config = pcmd:format(config1, y, modulation, config2) + dbg(('lf t55xx write 0 %s'):format(config)) + + config = tonumber(config,16) + local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config} + local err = core.SendCommand(writecmd:getBytes()) + if err then return oops(err) end + local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) + + else + dbg(pcmd) + core.console( pcmd ) + end + end + core.clearCommandBuffer() + end + print( string.rep('--',20) ) +end + +local function main(args) + + print( string.rep('--',20) ) + print( string.rep('--',20) ) + + -- Arguments for the script + for o, arg in getopt.getopt(args, 'h') do + if o == "h" then return help() end + end + + core.clearCommandBuffer() + test(4) + test(5) + test(6) + test(7) + print( string.rep('--',20) ) +end +main(args) \ No newline at end of file diff --git a/client/scripts/test_t55x7_psk.lua b/client/scripts/test_t55x7_psk.lua index 1b964094..cbd78e87 100644 --- a/client/scripts/test_t55x7_psk.lua +++ b/client/scripts/test_t55x7_psk.lua @@ -2,15 +2,14 @@ local cmds = require('commands') local getopt = require('getopt') local bin = require('bin') local utils = require('utils') -local dumplib = require('html_dumplib') example =[[ - 1. script run tracetest - 2. script run tracetest -o + 1. script run test_t55x7_psk + 2. script run test_t55x7_psk -o ]] author = "Iceman" -usage = "script run test_t55x7_psk -o " +usage = "script run test_t55x7_psk" desc =[[ This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040 The outlined procedure is as following: @@ -39,26 +38,35 @@ In all 12 individual test for the PSK demod Arguments: -h : this help - -o : logfile name ]] local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds local DEBUG = true -- the debug flag ---BLOCK 0 = 00088040 -local config1 = '0008' -local config2 = '40' +-- local procedurecmds = { + -- [1] = '%s%s%s%s', + -- [2] = 'lf read', + -- --[3] = '', + -- [3] = 'data samples', + -- [4] = 'data pskdetectclock', + -- [5] = 'data psknrzrawdemod', + -- [6] = 'data pskindalademod', +-- } + +-- --BLOCK 0 = 00 08 80 40 PSK + -- ----------- + -- 08------- bitrate + -- 8----- modulation PSK1 + -- 0---- PSK ClockRate + -- 40 max 2 blocks + local procedurecmds = { - [1] = '%s%s%s%s', - [2] = 'lf read', + [1] = '00%02X%X%X40', + [2] = 'lf t55xx detect', --[3] = '', - [3] = 'data samples', - [4] = 'data pskdetectclock', - [5] = 'data psknrzrawdemod', - [6] = 'data pskindalademod', + [3] = 'lf t55xx info', } - --- -- A debug printout-function function dbg(args) @@ -97,45 +105,39 @@ function ExitMsg(msg) print() end -function pskTest(modulation) - local y - for y = 0, 8, 4 do - for _ = 1, #procedurecmds do - local cmd = procedurecmds[_] - - if #cmd == 0 then - - elseif _ == 1 then - - dbg("Writing to T55x7 TAG") - - local configdata = cmd:format( config1, modulation , y, config2) +function test(modulation) + local bitrate + local clockrate + for bitrate = 0x0, 0x1d, 0x4 do + + for clockrate = 0,8,4 do + + for _ = 1, #procedurecmds do + local cmd = procedurecmds[_] - dbg( configdata) + if #cmd == 0 then - local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = configdata ,arg2 = 0, arg3 = 0} - local err = core.SendCommand(writecommand:getBytes()) - if err then return oops(err) end - local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) - - if response then - local count,cmd,arg0 = bin.unpack('LL',response) - if(arg0==1) then - dbg("Writing success") - else - return nil, "Couldn't read block.." - end + elseif _ == 1 then + + dbg("Writing to T55x7 TAG") + + local config = cmd:format(bitrate, modulation, clockrate) + dbg(('lf t55xx write 0 %s'):format(config)) + + config = tonumber(config,16) + local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config ,arg2 = 0, arg3 = 0} + local err = core.SendCommand(writecommand:getBytes()) + if err then return oops(err) end + local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) + else + dbg(cmd) + core.console( cmd ) end - - else - dbg(cmd) - core.console( cmd ) end + core.clearCommandBuffer() end - core.clearCommandBuffer() end print( string.rep('--',20) ) - end local function main(args) @@ -143,20 +145,16 @@ local function main(args) print( string.rep('--',20) ) print( string.rep('--',20) ) - local outputTemplate = os.date("testpsk_%Y-%m-%d_%H%M%S") - -- Arguments for the script - for o, arg in getopt.getopt(args, 'ho:') do + for o, arg in getopt.getopt(args, 'h') do if o == "h" then return help() end - if o == "o" then outputTemplate = arg end end core.clearCommandBuffer() - pskTest(1) - pskTest(2) - pskTest(3) - pskTest(8) + test(1) -- PSK1 + --test(2) -- PSK2 + --test(3) -- PSK3 print( string.rep('--',20) ) end @@ -170,4 +168,4 @@ main(args) -- XXXXX0XX = PSK RF/2 -- XXXXX4XX = PSK RF/4 - -- XXXXX8XX = PSK RF/8 \ No newline at end of file + -- XXXXX8XX = PSK RF/8 diff --git a/client/scripts/tracetest.lua b/client/scripts/tracetest.lua index e4a9215c..ae4055ae 100644 --- a/client/scripts/tracetest.lua +++ b/client/scripts/tracetest.lua @@ -6,19 +6,20 @@ local dumplib = require('html_dumplib') example =[[ 1. script run tracetest - 2. script run tracetest -o - ]] author = "Iceman" -usage = "script run tracetest -o " +usage = "script run tracetest" desc =[[ This script will load several traces files in ../traces/ folder and do "data load" -"lf search" +"lf search 1 u" + +The following tracefiles will be loaded: + em*.pm3 + m*.pm3 Arguments: -h : this help - -o : logfile name ]] local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds @@ -71,14 +72,14 @@ local function main(args) local tracesEM = "find '../traces/' -iname 'em*.pm3' -type f" local tracesMOD = "find '../traces/' -iname 'm*.pm3' -type f" + local write2File = false local outputTemplate = os.date("testtest_%Y-%m-%d_%H%M%S") -- Arguments for the script - for o, arg in getopt.getopt(args, 'ho:') do + for o, arg in getopt.getopt(args, 'h') do if o == "h" then return help() end - if o == "o" then outputTemplate = arg end end - + core.clearCommandBuffer() local files = {} @@ -97,7 +98,7 @@ local function main(args) end p.close(); - local cmdLFSEARCH = "lf search 1" + local cmdLFSEARCH = "lf search 1 u" -- main loop io.write('Starting to test traces > ') @@ -119,13 +120,6 @@ local function main(args) end io.write('\n') - -- Write dump to files - if not DEBUG then - local bar = dumplib.SaveAsText(emldata, outputTemplate..'.txt') - print(("Wrote output to: %s"):format(bar)) - end - - -- Show info print( string.rep('--',20) ) end diff --git a/common/crc.c b/common/crc.c index 90d57afa..0c73474f 100644 --- a/common/crc.c +++ b/common/crc.c @@ -5,8 +5,9 @@ //----------------------------------------------------------------------------- // Generic CRC calculation code. //----------------------------------------------------------------------------- - #include "crc.h" +#include +#include void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor) { @@ -40,3 +41,16 @@ uint32_t crc_finish(crc_t *crc) { return ( crc->state ^ crc->final_xor ) & crc->mask; } + +//credits to iceman +uint32_t CRC8Maxim(uint8_t *buff, size_t size) +{ + crc_t crc; + crc_init(&crc, 9, 0x8c, 0x00, 0x00); + crc_clear(&crc); + + for (size_t i=0; i < size; ++i){ + crc_update(&crc, buff[i], 8); + } + return crc_finish(&crc); +} diff --git a/common/crc.h b/common/crc.h new file mode 100644 index 00000000..adbfb237 --- /dev/null +++ b/common/crc.h @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Generic CRC calculation code. +//----------------------------------------------------------------------------- + +#ifndef __CRC_H +#define __CRC_H + +#include +#include + +typedef struct crc { + uint32_t state; + int order; + uint32_t polynom; + uint32_t initial_value; + uint32_t final_xor; + uint32_t mask; +} crc_t; + +/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32 + * polynom is the CRC polynom. initial_value is the initial value of a clean state. + * final_xor is XORed onto the state before returning it from crc_result(). */ +extern void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor); + +/* Update the crc state. data is the data of length data_width bits (only the the + * data_width lower-most bits are used). + */ +extern void crc_update(crc_t *crc, uint32_t data, int data_width); + +/* Clean the crc state, e.g. reset it to initial_value */ +extern void crc_clear(crc_t *crc); + +/* Get the result of the crc calculation */ +extern uint32_t crc_finish(crc_t *crc); + +// Calculate CRC-8/Maxim checksum +uint32_t CRC8Maxim(uint8_t *buff, size_t size ); +/* Static initialization of a crc structure */ +#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \ + .state = ((_initial_value) & ((1L<<(_order))-1)), \ + .order = (_order), \ + .polynom = (_polynom), \ + .initial_value = (_initial_value), \ + .final_xor = (_final_xor), \ + .mask = ((1L<<(_order))-1) } + +#endif /* __CRC_H */ diff --git a/common/ldscript.common b/common/ldscript.common index f1b63550..ea57ec24 100644 --- a/common/ldscript.common +++ b/common/ldscript.common @@ -1,6 +1,7 @@ /* ----------------------------------------------------------------------------- - This code is licensed to you under the terms of the GNU GPL, version 2 or, + This code is licensed to you under the ter +ms of the GNU GPL, version 2 or, at your option, any later version. See the LICENSE.txt file for the text of the license. ----------------------------------------------------------------------------- @@ -13,8 +14,7 @@ MEMORY { bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */ bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */ - fpgaimage : ORIGIN = 0x00102000, LENGTH = 96k - 0x2000 /* Place where the FPGA image will end up */ - osimage : ORIGIN = 0x00118000, LENGTH = 256K - 96k /* Place where the main OS will end up */ + osimage : ORIGIN = 0x00102000, LENGTH = 256K - 0x2000 /* Place where the main OS will end up */ ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */ commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */ } diff --git a/common/lfdemod.c b/common/lfdemod.c index a42566ad..ffa807fe 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -11,8 +11,6 @@ #include #include #include "lfdemod.h" - - uint8_t justNoise(uint8_t *BitStream, size_t size) { static const uint8_t THRESHOLD = 123; @@ -31,13 +29,13 @@ int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi *high=0; *low=255; // get high and low thresholds - for (int i=0; i < size; i++){ + for (size_t i=0; i < size; i++){ if (BitStream[i] > *high) *high = BitStream[i]; if (BitStream[i] < *low) *low = BitStream[i]; } if (*high < 123) return -1; // just noise - *high = (int)(((*high-128)*(((float)fuzzHi)/100))+128); - *low = (int)(((*low-128)*(((float)fuzzLo)/100))+128); + *high = ((*high-128)*fuzzHi + 12800)/100; + *low = ((*low-128)*fuzzLo + 12800)/100; return 1; } @@ -55,69 +53,65 @@ uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType) } //by marshmellow -//search for given preamble in given BitStream and return startIndex and length +//search for given preamble in given BitStream and return success=1 or fail=0 and startIndex and length uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx) { - uint8_t foundCnt=0; - for (int idx=0; idx < *size - pLen; idx++){ - if (memcmp(BitStream+idx, preamble, pLen) == 0){ - //first index found - foundCnt++; - if (foundCnt == 1){ - *startIdx = idx; - } - if (foundCnt == 2){ - *size = idx - *startIdx; - return 1; - } - } - } - return 0; + uint8_t foundCnt=0; + for (int idx=0; idx < *size - pLen; idx++){ + if (memcmp(BitStream+idx, preamble, pLen) == 0){ + //first index found + foundCnt++; + if (foundCnt == 1){ + *startIdx = idx; + } + if (foundCnt == 2){ + *size = idx - *startIdx; + return 1; + } + } + } + return 0; } - //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID -uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx) +uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo) { - //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future - // otherwise could be a void with no arguments - //set defaults - uint64_t lo=0; - uint32_t i = 0; - if (BitStream[1]>1){ //allow only 1s and 0s - // PrintAndLog("no data found"); - return 0; - } - // 111111111 bit pattern represent start of frame - uint8_t preamble[] = {1,1,1,1,1,1,1,1,1}; - uint32_t idx = 0; - uint32_t parityBits = 0; - uint8_t errChk = 0; - *startIdx = 0; - for (uint8_t extraBitChk=0; extraBitChk<5; extraBitChk++){ - errChk = preambleSearch(BitStream+extraBitChk+*startIdx, preamble, sizeof(preamble), size, startIdx); - if (errChk == 0) return 0; - idx = *startIdx + 9; - for (i=0; i<10;i++){ //loop through 10 sets of 5 bits (50-10p = 40 bits) - parityBits = bytebits_to_byte(BitStream+(i*5)+idx,5); - //check even parity - if (parityTest(parityBits, 5, 0) == 0){ - //parity failed try next bit (in the case of 1111111111) but last 9 = preamble - startIdx++; - errChk = 0; - break; - } - //set uint64 with ID from BitStream - for (uint8_t ii=0; ii<4; ii++){ - lo = (lo << 1LL) | (BitStream[(i*5)+ii+idx]); - } - } - if (errChk != 0) return lo; - //skip last 5 bit parity test for simplicity. - // *size = 64; - } - return 0; + //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future + // otherwise could be a void with no arguments + //set defaults + uint32_t i = 0; + if (BitStream[1]>1){ //allow only 1s and 0s + // PrintAndLog("no data found"); + return 0; + } + // 111111111 bit pattern represent start of frame + // include 0 in front to help get start pos + uint8_t preamble[] = {0,1,1,1,1,1,1,1,1,1}; + uint32_t idx = 0; + uint32_t parityBits = 0; + uint8_t errChk = 0; + uint8_t FmtLen = 10; + *startIdx = 0; + errChk = preambleSearch(BitStream, preamble, sizeof(preamble), size, startIdx); + if (errChk == 0 || *size < 64) return 0; + if (*size > 64) FmtLen = 22; + *startIdx += 1; //get rid of 0 from preamble + idx = *startIdx + 9; + for (i=0; i> 63); + *lo = (*lo << 1) | (BitStream[(i*5)+ii+idx]); + } + } + if (errChk != 0) return 1; + //skip last 5 bit parity test for simplicity. + // *size = 64 | 128; + return 0; } //by marshmellow @@ -126,116 +120,89 @@ uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx) //prints binary found and saves in graphbuffer for further commands int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr) { - int i; - //int clk2=*clk; + size_t i; int start = DetectASKClock(BinStream, *size, clk, 20); //clock default - if (*clk==0) return -3; - if (start < 0) return -3; - // if autodetected too low then adjust //MAY NEED ADJUSTMENT - //if (clk2==0 && *clk<8) *clk =64; - //if (clk2==0 && *clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert=0; - uint32_t initLoopMax = 200; - if (initLoopMax > *size) initLoopMax=*size; + if (*clk==0 || start < 0) return -3; + if (*invert != 1) *invert=0; + uint8_t initLoopMax = 255; + if (initLoopMax > *size) initLoopMax = *size; // Detect high and lows // 25% fuzz in case highs and lows aren't clipped [marshmellow] - int high, low, ans; - ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75); - if (ans<1) return -2; //just noise + int high, low; + if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1) return -2; //just noise // PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - int tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave - if (*clk<=32) tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely - int iii = 0; - uint32_t gLen = *size; - if (gLen > 3000) gLen=3000; - uint8_t errCnt =0; - uint16_t MaxBits = 500; - uint32_t bestStart = *size; - int bestErrCnt = maxErr+1; + uint16_t bitnum = 0; //output counter + uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave + if (*clk <= 32) tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely + size_t iii = 0; + //if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance + if (!maxErr) initLoopMax = *clk * 2; + uint16_t errCnt = 0, MaxBits = 512; + uint16_t bestStart = start; + uint16_t bestErrCnt = 0; // PrintAndLog("DEBUG - lastbit - %d",lastBit); - // loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii] >= high) || (BinStream[iii] <= low)){ - lastBit=iii-*clk; - errCnt=0; + // if best start position not already found by detect clock then + if (start <= 0 || start > initLoopMax){ + bestErrCnt = maxErr+1; + // loop to find first wave that works + for (iii=0; iii < initLoopMax; ++iii){ + // if no peak skip + if (BinStream[iii] < high && BinStream[iii] > low) continue; + + lastBit = iii - *clk; // loop through to see if this start location works for (i = iii; i < *size; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){ - lastBit+=*clk; - } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - //debug - //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); - - errCnt++; - lastBit+=*clk;//skip over until hit too many errors - if (errCnt>(maxErr)) break; //allow 1 error for every 1000 samples else start over - } + if ((i-lastBit) > (*clk-tol) && (BinStream[i] >= high || BinStream[i] <= low)) { + lastBit += *clk; + } else if ((i-lastBit) > (*clk+tol)) { + errCnt++; + lastBit += *clk; } - if ((i-iii) >(MaxBits * *clk)) break; //got plenty of bits + if ((i-iii) > (MaxBits * *clk) || errCnt > maxErr) break; //got plenty of bits or too many errors } //we got more than 64 good bits and not all errors if ((((i-iii)/ *clk) > (64)) && (errCnt<=maxErr)) { //possible good read - if (errCnt==0){ - bestStart=iii; - bestErrCnt=errCnt; - break; //great read - finish - } - if (errCnt= high) && ((i-lastBit) > (*clk-tol))){ - lastBit += *clk; - BinStream[bitnum] = *invert; - bitnum++; - } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BinStream[bitnum] = 1-*invert; - bitnum++; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - //debug - //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); - if (bitnum > 0){ - BinStream[bitnum]=77; - bitnum++; - } - - lastBit+=*clk;//skip over error - } - } - if (bitnum >=MaxBits) break; - } - *size=bitnum; - } else{ - *invert=bestStart; - *clk=iii; + if (bestErrCnt > maxErr){ + *invert = bestStart; + *clk = iii; return -1; + } + //best run is good enough set to best run and set overwrite BinStream + lastBit = bestStart - *clk; + errCnt = 0; + for (i = bestStart; i < *size; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){ + //high found and we are expecting a bar + lastBit += *clk; + BinStream[bitnum++] = *invert; + } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){ + //low found and we are expecting a bar + lastBit += *clk; + BinStream[bitnum++] = *invert ^ 1; + } else if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); + if (bitnum > 0) { + BinStream[bitnum++] = 77; + errCnt++; + } + lastBit += *clk;//skip over error + } + if (bitnum >= MaxBits) break; } + *size = bitnum; return bestErrCnt; } @@ -260,61 +227,62 @@ int ManchesterEncode(uint8_t *BitStream, size_t size) //run through 2 times and take least errCnt int manrawdecode(uint8_t * BitStream, size_t *size) { - uint16_t bitnum=0; - uint16_t MaxBits = 500; - uint16_t errCnt = 0; - size_t i=1; - uint16_t bestErr = 1000; - uint16_t bestRun = 0; - size_t ii=1; + uint16_t bitnum=0, MaxBits = 512, errCnt = 0; + size_t i, ii; + uint16_t bestErr = 1000, bestRun = 0; if (size == 0) return -1; - for (ii=1;ii<3;++ii){ - i=1; - for (i=i+ii;i<*size-2;i+=2){ - if(BitStream[i]==1 && (BitStream[i+1]==0)){ - } else if((BitStream[i]==0)&& BitStream[i+1]==1){ - } else { + for (ii=0;ii<2;++ii){ + for (i=ii; i<*size-2; i+=2) + if (BitStream[i]==BitStream[i+1]) errCnt++; - } - if(bitnum>MaxBits) break; - } + if (bestErr>errCnt){ bestErr=errCnt; bestRun=ii; } errCnt=0; } - errCnt=bestErr; - if (errCnt<20){ - ii=bestRun; - i=1; - for (i=i+ii; i < *size-2; i+=2){ + if (bestErr<20){ + for (i=bestRun; i < *size-2; i+=2){ if(BitStream[i] == 1 && (BitStream[i+1] == 0)){ BitStream[bitnum++]=0; } else if((BitStream[i] == 0) && BitStream[i+1] == 1){ BitStream[bitnum++]=1; } else { BitStream[bitnum++]=77; - //errCnt++; } if(bitnum>MaxBits) break; } *size=bitnum; } - return errCnt; + return bestErr; } //by marshmellow -//take 01 or 10 = 0 and 11 or 00 = 1 +//take 01 or 10 = 1 and 11 or 00 = 0 +//check for phase errors - should never have 111 or 000 should be 01001011 or 10110100 for 1010 +//decodes biphase or if inverted it is AKA conditional dephase encoding AKA differential manchester encoding int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) { - uint16_t bitnum=0; - uint32_t errCnt =0; - uint32_t i; - uint16_t MaxBits=500; - i=offset; - if (size == 0) return -1; - for (;i<*size-2; i+=2){ + uint16_t bitnum = 0; + uint16_t errCnt = 0; + size_t i = offset; + uint16_t MaxBits=512; + //if not enough samples - error + if (*size < 51) return -1; + //check for phase change faults - skip one sample if faulty + uint8_t offsetA = 1, offsetB = 1; + for (; i<48; i+=2){ + if (BitStream[i+1]==BitStream[i+2]) offsetA=0; + if (BitStream[i+2]==BitStream[i+3]) offsetB=0; + } + if (!offsetA && offsetB) offset++; + for (i=offset; i<*size-3; i+=2){ + //check for phase error + if (BitStream[i+1]==BitStream[i+2]) { + BitStream[bitnum++]=77; + errCnt++; + } if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){ BitStream[bitnum++]=1^invert; } else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){ @@ -334,7 +302,7 @@ void askAmp(uint8_t *BitStream, size_t size) { int shift = 127; int shiftedVal=0; - for(int i = 1; i=30) //large jump up shift=127; else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down @@ -351,154 +319,170 @@ void askAmp(uint8_t *BitStream, size_t size) return; } +// demodulates strong heavily clipped samples +int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int high, int low) +{ + size_t bitCnt=0, smplCnt=0, errCnt=0; + uint8_t waveHigh = 0; + //PrintAndLog("clk: %d", clk); + for (size_t i=0; i < *size; i++){ + if (BinStream[i] >= high && waveHigh){ + smplCnt++; + } else if (BinStream[i] <= low && !waveHigh){ + smplCnt++; + } else { //transition + if ((BinStream[i] >= high && !waveHigh) || (BinStream[i] <= low && waveHigh)){ + if (smplCnt > clk-(clk/4)-1) { //full clock + if (smplCnt > clk + (clk/4)+1) { //too many samples + errCnt++; + BinStream[bitCnt++]=77; + } else if (waveHigh) { + BinStream[bitCnt++] = invert; + BinStream[bitCnt++] = invert; + } else if (!waveHigh) { + BinStream[bitCnt++] = invert ^ 1; + BinStream[bitCnt++] = invert ^ 1; + } + waveHigh ^= 1; + smplCnt = 0; + } else if (smplCnt > (clk/2) - (clk/4)-1) { + if (waveHigh) { + BinStream[bitCnt++] = invert; + } else if (!waveHigh) { + BinStream[bitCnt++] = invert ^ 1; + } + waveHigh ^= 1; + smplCnt = 0; + } else if (!bitCnt) { + //first bit + waveHigh = (BinStream[i] >= high); + smplCnt = 1; + } else { + smplCnt++; + //transition bit oops + } + } else { //haven't hit new high or new low yet + smplCnt++; + } + } + } + *size = bitCnt; + return errCnt; +} + //by marshmellow //takes 3 arguments - clock, invert and maxErr as integers //attempts to demodulate ask only int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp) { - uint32_t i; if (*size==0) return -1; int start = DetectASKClock(BinStream, *size, clk, 20); //clock default - if (*clk==0) return -1; - if (start<0) return -1; - if (*invert != 0 && *invert != 1) *invert =0; - uint32_t initLoopMax = 200; - if (initLoopMax > *size) initLoopMax=*size; - // Detect high and lows - //25% fuzz in case highs and lows aren't clipped [marshmellow] - int high, low, ans; + if (*clk==0 || start < 0) return -1; + if (*invert != 1) *invert = 0; if (amp==1) askAmp(BinStream, *size); - ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75); - if (ans<1) return -1; //just noise - - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock - // if they fall + or - this value + clock from last valid wave - if (*clk == 32) tol=0; //clock tolerance may not be needed anymore currently set to - // + or - 1 but could be increased for poor waves or removed entirely - uint32_t iii = 0; - uint32_t gLen = *size; - if (gLen > 500) gLen=500; - uint8_t errCnt =0; - uint32_t bestStart = *size; - uint32_t bestErrCnt = maxErr; //(*size/1000); - uint8_t midBit=0; - uint16_t MaxBits=1000; - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=start; iii < gLen; ++iii){ - if ((BinStream[iii]>=high) || (BinStream[iii]<=low)){ - lastBit=iii-*clk; - errCnt=0; - //loop through to see if this start location works - for (i = iii; i < *size; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - midBit=0; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - midBit=0; - } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - } else if ((BinStream[i]>=high) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - } else if ((i-lastBit)>((*clk/2)+tol) && (midBit==0)){ - //no mid bar found - midBit=1; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ + uint8_t initLoopMax = 255; + if (initLoopMax > *size) initLoopMax=*size; + // Detect high and lows + //25% clip in case highs and lows aren't clipped [marshmellow] + int high, low; + if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1) + return -1; //just noise + + // if clean clipped waves detected run alternate demod + if (DetectCleanAskWave(BinStream, *size, high, low)) + return cleanAskRawDemod(BinStream, size, *clk, *invert, high, low); + + int lastBit = 0; //set first clock check - can go negative + size_t i, iii = 0; + size_t errCnt = 0, bitnum = 0; //output counter + uint8_t midBit = 0; + size_t bestStart = start, bestErrCnt = 0; //(*size/1000); + size_t MaxBits = 1024; + + //if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance + if (!maxErr) initLoopMax = *clk * 2; + //if best start not already found by detectclock + if (start <= 0 || start > initLoopMax){ + bestErrCnt = maxErr+1; + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < initLoopMax; ++iii){ + if ((BinStream[iii] >= high) || (BinStream[iii] <= low)){ + lastBit = iii - *clk; + //loop through to see if this start location works + for (i = iii; i < *size; ++i) { + if (i-lastBit > *clk && (BinStream[i] >= high || BinStream[i] <= low)){ + lastBit += *clk; + midBit = 0; + } else if (i-lastBit > (*clk/2) && midBit == 0) { + midBit = 1; + } else if ((i-lastBit) > *clk) { //should have hit a high or low based on clock!! - //debug //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); - errCnt++; - lastBit+=*clk;//skip over until hit too many errors - if (errCnt > maxErr){ - //errCnt=0; + lastBit += *clk;//skip over until hit too many errors + if (errCnt > maxErr) break; - } } + if ((i-iii)>(MaxBits * *clk)) break; //got enough bits } - if ((i-iii)>(MaxBits * *clk)) break; //got enough bits - } - //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64)) && (errCnt<=maxErr)) { - //possible good read - if (errCnt==0){ - bestStart=iii; - bestErrCnt=errCnt; - break; //great read - finish - } - if (errCnt 64) && (errCnt<=maxErr)) { + //possible good read + if (errCnt==0){ + bestStart=iii; + bestErrCnt=errCnt; + break; //great read - finish + } + if (errCnt= high) && ((i-lastBit) > (*clk-tol))){ - lastBit += *clk; - BinStream[bitnum] = *invert; - bitnum++; - midBit=0; - } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BinStream[bitnum] = 1 - *invert; - bitnum++; - midBit=0; - } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BinStream[bitnum] = 1 - *invert; - bitnum++; - } else if ((BinStream[i]>=high) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BinStream[bitnum] = *invert; - bitnum++; - } else if ((i-lastBit)>((*clk/2)+tol) && (midBit==0)){ - //no mid bar found - midBit=1; - if (bitnum!=0) BinStream[bitnum] = BinStream[bitnum-1]; - bitnum++; - + if (bestErrCnt > maxErr){ + *invert = bestStart; + *clk = iii; + return -1; + } + //best run is good enough - set to best run and overwrite BinStream + lastBit = bestStart - *clk - 1; + errCnt = 0; + + for (i = bestStart; i < *size; ++i) { + if (i - lastBit > *clk){ + if (BinStream[i] >= high) { + BinStream[bitnum++] = *invert; + } else if (BinStream[i] <= low) { + BinStream[bitnum++] = *invert ^ 1; } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - //debug - //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); - if (bitnum > 0){ - BinStream[bitnum]=77; - bitnum++; - } - lastBit+=*clk;//skip over error - } + if (bitnum > 0) { + BinStream[bitnum++]=77; + errCnt++; + } } - if (bitnum >= MaxBits) break; + midBit = 0; + lastBit += *clk; + } else if (i-lastBit > (*clk/2) && midBit == 0){ + if (BinStream[i] >= high) { + BinStream[bitnum++] = *invert; + } else if (BinStream[i] <= low) { + BinStream[bitnum++] = *invert ^ 1; + } else { + + BinStream[bitnum] = BinStream[bitnum-1]; + bitnum++; + } + midBit = 1; } - *size=bitnum; - } else{ - *invert=bestStart; - *clk=iii; - return -1; + if (bitnum >= MaxBits) break; } - return bestErrCnt; + *size = bitnum; + return errCnt; } // demod gProxIIDemod @@ -525,8 +509,8 @@ int gProxII_Demod(uint8_t BitStream[], size_t *size) //translate wave to 11111100000 (1 for each short wave 0 for each long wave) size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow) { - uint32_t last_transition = 0; - uint32_t idx = 1; + size_t last_transition = 0; + size_t idx = 1; //uint32_t maxVal=0; if (fchigh==0) fchigh=10; if (fclow==0) fclow=8; @@ -555,58 +539,64 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise //do nothing with extra garbage } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves - dest[numBits]=1; - } else { //9+ = 10 waves - dest[numBits]=0; + dest[numBits++]=1; + } else if ((idx-last_transition) > (fchigh+1) && !numBits) { //12 + and first bit = garbage + //do nothing with beginning garbage + } else { //9+ = 10 waves + dest[numBits++]=0; } last_transition = idx; - numBits++; } } return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 } -uint32_t myround2(float f) -{ - if (f >= 2000) return 2000;//something bad happened - return (uint32_t) (f + (float)0.5); -} - //translate 11111100000 to 10 -size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, - uint8_t invert, uint8_t fchigh, uint8_t fclow) +size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, + uint8_t invert, uint8_t fchigh, uint8_t fclow) { uint8_t lastval=dest[0]; - uint32_t idx=0; + size_t idx=0; size_t numBits=0; uint32_t n=1; - for( idx=1; idx < size; idx++) { - - if (dest[idx]==lastval) { - n++; - continue; - } + n++; + if (dest[idx]==lastval) continue; + //if lastval was 1, we have a 1->0 crossing - if ( dest[idx-1]==1 ) { - n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); - } else {// 0->1 crossing - n=myround2((float)(n+1)/((float)(rfLen-1)/(float)fchigh)); //-1 for fudge factor + if (dest[idx-1]==1) { + if (!numBits && n < rfLen/fclow) { + n=0; + lastval = dest[idx]; + continue; + } + n = (n * fclow + rfLen/2) / rfLen; + } else {// 0->1 crossing + //test first bitsample too small + if (!numBits && n < rfLen/fchigh) { + n=0; + lastval = dest[idx]; + continue; + } + n = (n * fchigh + rfLen/2) / rfLen; } if (n == 0) n = 1; - if(n < maxConsequtiveBits) //Consecutive - { - if(invert==0){ //invert bits - memset(dest+numBits, dest[idx-1] , n); - }else{ - memset(dest+numBits, dest[idx-1]^1 , n); - } - numBits += n; - } + memset(dest+numBits, dest[idx-1]^invert , n); + numBits += n; n=0; lastval=dest[idx]; }//end for + // if valid extra bits at the end were all the same frequency - add them in + if (n > rfLen/fchigh) { + if (dest[idx-2]==1) { + n = (n * fclow + rfLen/2) / rfLen; + } else { + n = (n * fchigh + rfLen/2) / rfLen; + } + memset(dest+numBits, dest[idx-1]^invert , n); + numBits += n; + } return numBits; } //by marshmellow (from holiman's base) @@ -615,40 +605,40 @@ int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t { // FSK demodulator size = fsk_wave_demod(dest, size, fchigh, fclow); - size = aggregate_bits(dest, size, rfLen, 192, invert, fchigh, fclow); + size = aggregate_bits(dest, size, rfLen, invert, fchigh, fclow); return size; } // loop to get raw HID waveform then FSK demodulate the TAG ID from it int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) { - if (justNoise(dest, *size)) return -1; - - size_t numStart=0, size2=*size, startIdx=0; - // FSK demodulator - *size = fskdemod(dest, size2,50,1,10,8); //fsk2a - if (*size < 96) return -2; - // 00011101 bit pattern represent start of frame, 01 pattern represents a 0 and 10 represents a 1 - uint8_t preamble[] = {0,0,0,1,1,1,0,1}; - // find bitstring in array - uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx); - if (errChk == 0) return -3; //preamble not found - - numStart = startIdx + sizeof(preamble); - // final loop, go over previously decoded FSK data and manchester decode into usable tag ID - for (size_t idx = numStart; (idx-numStart) < *size - sizeof(preamble); idx+=2){ - if (dest[idx] == dest[idx+1]){ - return -4; //not manchester data - } - *hi2 = (*hi2<<1)|(*hi>>31); - *hi = (*hi<<1)|(*lo>>31); - //Then, shift in a 0 or one into low - if (dest[idx] && !dest[idx+1]) // 1 0 - *lo=(*lo<<1)|1; - else // 0 1 - *lo=(*lo<<1)|0; - } - return (int)startIdx; + if (justNoise(dest, *size)) return -1; + + size_t numStart=0, size2=*size, startIdx=0; + // FSK demodulator + *size = fskdemod(dest, size2,50,1,10,8); //fsk2a + if (*size < 96*2) return -2; + // 00011101 bit pattern represent start of frame, 01 pattern represents a 0 and 10 represents a 1 + uint8_t preamble[] = {0,0,0,1,1,1,0,1}; + // find bitstring in array + uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx); + if (errChk == 0) return -3; //preamble not found + + numStart = startIdx + sizeof(preamble); + // final loop, go over previously decoded FSK data and manchester decode into usable tag ID + for (size_t idx = numStart; (idx-numStart) < *size - sizeof(preamble); idx+=2){ + if (dest[idx] == dest[idx+1]){ + return -4; //not manchester data + } + *hi2 = (*hi2<<1)|(*hi>>31); + *hi = (*hi<<1)|(*lo>>31); + //Then, shift in a 0 or one into low + if (dest[idx] && !dest[idx+1]) // 1 0 + *lo=(*lo<<1)|1; + else // 0 1 + *lo=(*lo<<1)|0; + } + return (int)startIdx; } // loop to get raw paradox waveform then FSK demodulate the TAG ID from it @@ -793,116 +783,161 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size) uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low) { - uint8_t allPeaks=1; + uint16_t allPeaks=1; uint16_t cntPeaks=0; - for (size_t i=20; i<255; i++){ + size_t loopEnd = 572; + if (loopEnd > size) loopEnd = size; + for (size_t i=60; ilow && dest[i]190) return 1; + if (allPeaks == 0){ + if (cntPeaks > 300) return 1; } return allPeaks; } +// by marshmellow +// to help detect clocks on heavily clipped samples +// based on counts between zero crossings +int DetectStrongAskClock(uint8_t dest[], size_t size) +{ + int clk[]={0,8,16,32,40,50,64,100,128}; + size_t idx = 40; + uint8_t high=0; + size_t cnt = 0; + size_t highCnt = 0; + size_t highCnt2 = 0; + for (;idx < size; idx++){ + if (dest[idx]>128) { + if (!high){ + high=1; + if (cnt > highCnt){ + if (highCnt != 0) highCnt2 = highCnt; + highCnt = cnt; + } else if (cnt > highCnt2) { + highCnt2 = cnt; + } + cnt=1; + } else { + cnt++; + } + } else if (dest[idx] <= 128){ + if (high) { + high=0; + if (cnt > highCnt) { + if (highCnt != 0) highCnt2 = highCnt; + highCnt = cnt; + } else if (cnt > highCnt2) { + highCnt2 = cnt; + } + cnt=1; + } else { + cnt++; + } + } + } + uint8_t tol; + for (idx=8; idx>0; idx--){ + tol = clk[idx]/8; + if (clk[idx] >= highCnt - tol && clk[idx] <= highCnt + tol) + return clk[idx]; + if (clk[idx] >= highCnt2 - tol && clk[idx] <= highCnt2 + tol) + return clk[idx]; + } + return -1; +} + // by marshmellow // not perfect especially with lower clocks or VERY good antennas (heavy wave clipping) // maybe somehow adjust peak trimming value based on samples to fix? // return start index of best starting position for that clock and return clock (by reference) int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) { - int i=0; - int clk[]={8,16,32,40,50,64,100,128,256}; - int loopCnt = 256; //don't need to loop through entire array... - if (size == 0) return -1; - if (size> 8; - uint8_t fc2 = fcTest & 0xFF; - - for (i=0; i<8; i++){ - if (clk[i] == fc1) { - *clock=fc1; - return 0; - } - if (clk[i] == fc2) { - *clock=fc2; - return 0; - } - } - } - - int ii; - int clkCnt; - int tol = 0; - int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000}; - int bestStart[]={0,0,0,0,0,0,0,0,0}; - int errCnt=0; - //test each valid clock from smallest to greatest to see which lines up - for(clkCnt=0; clkCnt < 8; clkCnt++){ - if (clk[clkCnt] == 32){ - tol=1; - }else{ - tol=0; - } - bestErr[clkCnt]=1000; - //try lining up the peaks by moving starting point (try first 256) - for (ii=0; ii < loopCnt; ii++){ - if ((dest[ii] >= peak) || (dest[ii] <= low)){ - errCnt=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)((size-ii-tol)/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt++; - } - } - //if we found no errors then we can stop here - // this is correct one - return this clock - //PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i); - if(errCnt==0 && clkCnt<6) { - *clock = clk[clkCnt]; - return ii; - } - //if we found errors see if it is lowest so far and save it as best run - if(errCntmaxErr) return -1; - *clock=clk[best]; - return bestStart[best]; + size_t i=0; + uint8_t clk[]={8,16,32,40,50,64,100,128,255}; + uint8_t loopCnt = 255; //don't need to loop through entire array... + if (size <= loopCnt) return -1; //not enough samples + //if we already have a valid clock quit + + for (;i<8;++i) + if (clk[i] == *clock) return 0; + + //get high and low peak + int peak, low; + if (getHiLo(dest, loopCnt, &peak, &low, 75, 75) < 1) return -1; + + //test for large clean peaks + if (DetectCleanAskWave(dest, size, peak, low)==1){ + int ans = DetectStrongAskClock(dest, size); + for (i=7; i>0; i--){ + if (clk[i] == ans) { + *clock = ans; + return 0; + } + } + } + uint8_t ii; + uint8_t clkCnt, tol = 0; + uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000}; + uint8_t bestStart[]={0,0,0,0,0,0,0,0,0}; + size_t errCnt = 0; + size_t arrLoc, loopEnd; + //test each valid clock from smallest to greatest to see which lines up + for(clkCnt=0; clkCnt < 8; clkCnt++){ + if (clk[clkCnt] == 32){ + tol=1; + }else{ + tol=0; + } + if (!maxErr) loopCnt=clk[clkCnt]*2; + bestErr[clkCnt]=1000; + //try lining up the peaks by moving starting point (try first 256) + for (ii=0; ii < loopCnt; ii++){ + if (dest[ii] < peak && dest[ii] > low) continue; + + errCnt=0; + // now that we have the first one lined up test rest of wave array + loopEnd = ((size-ii-tol) / clk[clkCnt]) - 1; + for (i=0; i < loopEnd; ++i){ + arrLoc = ii + (i * clk[clkCnt]); + if (dest[arrLoc] >= peak || dest[arrLoc] <= low){ + }else if (dest[arrLoc-tol] >= peak || dest[arrLoc-tol] <= low){ + }else if (dest[arrLoc+tol] >= peak || dest[arrLoc+tol] <= low){ + }else{ //error no peak detected + errCnt++; + } + } + //if we found no errors then we can stop here + // this is correct one - return this clock + //PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i); + if(errCnt==0 && clkCnt<6) { + *clock = clk[clkCnt]; + return ii; + } + //if we found errors see if it is lowest so far and save it as best run + if(errCnt maxErr) return -1; + *clock = clk[best]; + return bestStart[best]; } //by marshmellow @@ -910,165 +945,166 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) // a phase shift is determined by measuring the sample length of each wave int DetectPSKClock(uint8_t dest[], size_t size, int clock) { - uint8_t clk[]={255,16,32,40,50,64,100,128,255}; //255 is not a valid clock - uint16_t loopCnt = 4096; //don't need to loop through entire array... - if (size == 0) return 0; - if (size= dest[i+2]){ - if (waveStart == 0) { - waveStart = i+1; - //PrintAndLog("DEBUG: waveStart: %d",waveStart); - } else { - waveEnd = i+1; - //PrintAndLog("DEBUG: waveEnd: %d",waveEnd); - waveLenCnt = waveEnd-waveStart; - if (waveLenCnt > fc){ - firstFullWave = waveStart; - fullWaveLen=waveLenCnt; - break; - } - waveStart=0; - } - } - } - //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen); - - //test each valid clock from greatest to smallest to see which lines up - for(clkCnt=7; clkCnt >= 1 ; clkCnt--){ - lastClkBit = firstFullWave; //set end of wave as clock align - waveStart = 0; - errCnt=0; - peakcnt=0; - //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d",clk[clkCnt],lastClkBit); - - for (i = firstFullWave+fullWaveLen-1; i < loopCnt-2; i++){ - //top edge of wave = start of new wave - if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){ - if (waveStart == 0) { - waveStart = i+1; - waveLenCnt=0; - } else { //waveEnd - waveEnd = i+1; - waveLenCnt = waveEnd-waveStart; - if (waveLenCnt > fc){ - //if this wave is a phase shift - //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, ii: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,ii+1,fc); - if (i+1 >= lastClkBit + clk[clkCnt] - tol){ //should be a clock bit - peakcnt++; - lastClkBit+=clk[clkCnt]; - } else if (i lastClkBit + clk[clkCnt] + tol + fc){ - lastClkBit+=clk[clkCnt]; //no phase shift but clock bit - } - waveStart=i+1; - } - } - } - if (errCnt == 0){ - return clk[clkCnt]; - } - if (errCnt <= bestErr[clkCnt]) bestErr[clkCnt]=errCnt; - if (peakcnt > peaksdet[clkCnt]) peaksdet[clkCnt]=peakcnt; - } - //all tested with errors - //return the highest clk with the most peaks found - uint8_t best=7; - for (i=7; i>=1; i--){ - if (peaksdet[i] > peaksdet[best]) { - best = i; - } - //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]); - } - return clk[best]; + uint8_t clk[]={255,16,32,40,50,64,100,128,255}; //255 is not a valid clock + uint16_t loopCnt = 4096; //don't need to loop through entire array... + if (size == 0) return 0; + if (size= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + //PrintAndLog("DEBUG: waveStart: %d",waveStart); + } else { + waveEnd = i+1; + //PrintAndLog("DEBUG: waveEnd: %d",waveEnd); + waveLenCnt = waveEnd-waveStart; + if (waveLenCnt > fc){ + firstFullWave = waveStart; + fullWaveLen=waveLenCnt; + break; + } + waveStart=0; + } + } + } + //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen); + + //test each valid clock from greatest to smallest to see which lines up + for(clkCnt=7; clkCnt >= 1 ; clkCnt--){ + lastClkBit = firstFullWave; //set end of wave as clock align + waveStart = 0; + errCnt=0; + peakcnt=0; + //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d",clk[clkCnt],lastClkBit); + + for (i = firstFullWave+fullWaveLen-1; i < loopCnt-2; i++){ + //top edge of wave = start of new wave + if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + waveLenCnt=0; + } else { //waveEnd + waveEnd = i+1; + waveLenCnt = waveEnd-waveStart; + if (waveLenCnt > fc){ + //if this wave is a phase shift + //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, ii: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,ii+1,fc); + if (i+1 >= lastClkBit + clk[clkCnt] - tol){ //should be a clock bit + peakcnt++; + lastClkBit+=clk[clkCnt]; + } else if (i lastClkBit + clk[clkCnt] + tol + fc){ + lastClkBit+=clk[clkCnt]; //no phase shift but clock bit + } + waveStart=i+1; + } + } + } + if (errCnt == 0){ + return clk[clkCnt]; + } + if (errCnt <= bestErr[clkCnt]) bestErr[clkCnt]=errCnt; + if (peakcnt > peaksdet[clkCnt]) peaksdet[clkCnt]=peakcnt; + } + //all tested with errors + //return the highest clk with the most peaks found + uint8_t best=7; + for (i=7; i>=1; i--){ + if (peaksdet[i] > peaksdet[best]) { + best = i; + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]); + } + return clk[best]; } //by marshmellow //detect nrz clock by reading #peaks vs no peaks(or errors) int DetectNRZClock(uint8_t dest[], size_t size, int clock) { - int i=0; - int clk[]={8,16,32,40,50,64,100,128,256}; - int loopCnt = 4096; //don't need to loop through entire array... - if (size == 0) return 0; - if (size= peak || dest[i] <= low){ - peakcnt++; - } else { - if (peakcnt>0 && maxPeak < peakcnt){ - maxPeak = peakcnt; - } - peakcnt=0; - } - } - peakcnt=0; - //test each valid clock from smallest to greatest to see which lines up - for(clkCnt=0; clkCnt < 8; ++clkCnt){ - //ignore clocks smaller than largest peak - if (clk[clkCnt]= peak) || (dest[ii] <= low)){ - peakcnt=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i < ((int)((size-ii-tol)/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - peakcnt++; - } - } - if(peakcnt>peaksdet[clkCnt]) { - peaksdet[clkCnt]=peakcnt; - } - } - } - } - int iii=7; - int best=0; - for (iii=7; iii > 0; iii--){ - if (peaksdet[iii] > peaksdet[best]){ - best = iii; - } - //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]); - } - return clk[best]; + size_t i=0; + uint8_t clk[]={8,16,32,40,50,64,100,128,255}; + size_t loopCnt = 4096; //don't need to loop through entire array... + if (size == 0) return 0; + if (size= peak || dest[i] <= low){ + peakcnt++; + } else { + if (peakcnt>0 && maxPeak < peakcnt){ + maxPeak = peakcnt; + } + peakcnt=0; + } + } + peakcnt=0; + //test each valid clock from smallest to greatest to see which lines up + for(clkCnt=0; clkCnt < 8; ++clkCnt){ + //ignore clocks smaller than largest peak + if (clk[clkCnt]= peak) || (dest[ii] <= low)){ + peakcnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i < ((int)((size-ii-tol)/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + peakcnt++; + } + } + if(peakcnt>peaksdet[clkCnt]) { + peaksdet[clkCnt]=peakcnt; + } + } + } + } + int iii=7; + uint8_t best=0; + for (iii=7; iii > 0; iii--){ + if (peaksdet[iii] > peaksdet[best]){ + best = iii; + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]); + } + return clk[best]; } // by marshmellow @@ -1079,7 +1115,9 @@ void psk1TOpsk2(uint8_t *BitStream, size_t size) size_t i=1; uint8_t lastBit=BitStream[0]; for (; i*size) gLen = *size; - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - uint8_t tol = 1; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave - uint32_t iii = 0; - uint16_t errCnt =0; - uint16_t MaxBits = 1000; - uint32_t bestErrCnt = maxErr+1; - uint32_t bestPeakCnt = 0; - uint32_t bestPeakStart=0; - uint8_t curBit=0; - uint8_t bitHigh=0; - uint8_t errBitHigh=0; - uint16_t peakCnt=0; - uint8_t ignoreWindow=4; - uint8_t ignoreCnt=ignoreWindow; //in case of noice near peak - //loop to find first wave that works - align to clock - for (iii=0; iii < gLen; ++iii){ - if ((dest[iii]>=high) || (dest[iii]<=low)){ - lastBit=iii-*clk; - peakCnt=0; - errCnt=0; - bitnum=0; - //loop through to see if this start location works - for (i = iii; i < *size; ++i) { - //if we found a high bar and we are at a clock bit - if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - bitnum++; - peakCnt++; - errBitHigh=0; - ignoreCnt=ignoreWindow; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - bitnum++; - peakCnt++; - errBitHigh=0; - ignoreCnt=ignoreWindow; - //else if no bars found - }else if(dest[i] < high && dest[i] > low) { - if (ignoreCnt==0){ - bitHigh=0; - if (errBitHigh==1){ - errCnt++; - } - errBitHigh=0; - } else { - ignoreCnt--; - } - //if we are past a clock point - if (i >= lastBit+*clk+tol){ //clock val - lastBit+=*clk; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ - //error bar found no clock... - errBitHigh=1; - } - if (bitnum>=MaxBits) break; - } - //we got more than 64 good bits and not all errors - if (bitnum > (64) && (errCnt <= (maxErr))) { - //possible good read - if (errCnt == 0){ - //bestStart = iii; - bestErrCnt = errCnt; - bestPeakCnt = peakCnt; - bestPeakStart = iii; - break; //great read - finish - } - if (errCnt < bestErrCnt){ //set this as new best run - bestErrCnt = errCnt; - //bestStart = iii; - } - if (peakCnt > bestPeakCnt){ - bestPeakCnt=peakCnt; - bestPeakStart=iii; - } - } - } - } - //PrintAndLog("DEBUG: bestErrCnt: %d, maxErr: %d, bestStart: %d, bestPeakCnt: %d, bestPeakStart: %d",bestErrCnt,maxErr,bestStart,bestPeakCnt,bestPeakStart); - if (bestErrCnt <= maxErr){ - //best run is good enough set to best run and set overwrite BinStream - iii=bestPeakStart; - lastBit=bestPeakStart-*clk; - bitnum=0; - for (i = iii; i < *size; ++i) { - //if we found a high bar and we are at a clock bit - if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=1-*invert; - dest[bitnum]=curBit; - bitnum++; - errBitHigh=0; - ignoreCnt=ignoreWindow; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=*invert; - dest[bitnum]=curBit; - bitnum++; - errBitHigh=0; - ignoreCnt=ignoreWindow; - //else if no bars found - }else if(dest[i]low) { - if (ignoreCnt==0){ - bitHigh=0; - //if peak is done was it an error peak? - if (errBitHigh==1){ - dest[bitnum]=77; - bitnum++; - errCnt++; - } - errBitHigh=0; - } else { - ignoreCnt--; - } - //if we are past a clock point - if (i>=lastBit+*clk+tol){ //clock val - lastBit+=*clk; - dest[bitnum]=curBit; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ - //error bar found no clock... - errBitHigh=1; - } - if (bitnum >= MaxBits) break; - } - *size=bitnum; - } else{ - *size=bitnum; - return -1; - } - - if (bitnum>16){ - *size=bitnum; - } else return -1; - return errCnt; + if (justNoise(dest, *size)) return -1; + *clk = DetectNRZClock(dest, *size, *clk); + if (*clk==0) return -2; + size_t i, gLen = 4096; + if (gLen>*size) gLen = *size; + int high, low; + if (getHiLo(dest, gLen, &high, &low, 75, 75) < 1) return -3; //25% fuzz on high 25% fuzz on low + int lastBit = 0; //set first clock check + size_t iii = 0, bitnum = 0; //bitnum counter + uint16_t errCnt = 0, MaxBits = 1000; + size_t bestErrCnt = maxErr+1; + size_t bestPeakCnt = 0, bestPeakStart = 0; + uint8_t bestFirstPeakHigh=0, firstPeakHigh=0, curBit=0, bitHigh=0, errBitHigh=0; + uint8_t tol = 1; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave + uint16_t peakCnt=0; + uint8_t ignoreWindow=4; + uint8_t ignoreCnt=ignoreWindow; //in case of noise near peak + //loop to find first wave that works - align to clock + for (iii=0; iii < gLen; ++iii){ + if ((dest[iii]>=high) || (dest[iii]<=low)){ + if (dest[iii]>=high) firstPeakHigh=1; + else firstPeakHigh=0; + lastBit=iii-*clk; + peakCnt=0; + errCnt=0; + //loop through to see if this start location works + for (i = iii; i < *size; ++i) { + // if we are at a clock bit + if ((i >= lastBit + *clk - tol) && (i <= lastBit + *clk + tol)) { + //test high/low + if (dest[i] >= high || dest[i] <= low) { + bitHigh = 1; + peakCnt++; + errBitHigh = 0; + ignoreCnt = ignoreWindow; + lastBit += *clk; + } else if (i == lastBit + *clk + tol) { + lastBit += *clk; + } + //else if no bars found + } else if (dest[i] < high && dest[i] > low){ + if (ignoreCnt==0){ + bitHigh=0; + if (errBitHigh==1) errCnt++; + errBitHigh=0; + } else { + ignoreCnt--; + } + } else if ((dest[i]>=high || dest[i]<=low) && (bitHigh==0)) { + //error bar found no clock... + errBitHigh=1; + } + if (((i-iii) / *clk)>=MaxBits) break; + } + //we got more than 64 good bits and not all errors + if (((i-iii) / *clk) > 64 && (errCnt <= (maxErr))) { + //possible good read + if (!errCnt || peakCnt > bestPeakCnt){ + bestFirstPeakHigh=firstPeakHigh; + bestErrCnt = errCnt; + bestPeakCnt = peakCnt; + bestPeakStart = iii; + if (!errCnt) break; //great read - finish + } + } + } + } + //PrintAndLog("DEBUG: bestErrCnt: %d, maxErr: %d, bestStart: %d, bestPeakCnt: %d, bestPeakStart: %d",bestErrCnt,maxErr,bestStart,bestPeakCnt,bestPeakStart); + if (bestErrCnt > maxErr) return bestErrCnt; + + //best run is good enough set to best run and set overwrite BinStream + lastBit = bestPeakStart - *clk; + memset(dest, bestFirstPeakHigh^1, bestPeakStart / *clk); + bitnum += (bestPeakStart / *clk); + for (i = bestPeakStart; i < *size; ++i) { + // if expecting a clock bit + if ((i >= lastBit + *clk - tol) && (i <= lastBit + *clk + tol)) { + // test high/low + if (dest[i] >= high || dest[i] <= low) { + peakCnt++; + bitHigh = 1; + errBitHigh = 0; + ignoreCnt = ignoreWindow; + curBit = *invert; + if (dest[i] >= high) curBit ^= 1; + dest[bitnum++] = curBit; + lastBit += *clk; + //else no bars found in clock area + } else if (i == lastBit + *clk + tol) { + dest[bitnum++] = curBit; + lastBit += *clk; + } + //else if no bars found + } else if (dest[i] < high && dest[i] > low){ + if (ignoreCnt == 0){ + bitHigh = 0; + if (errBitHigh == 1){ + dest[bitnum++] = 77; + errCnt++; + } + errBitHigh=0; + } else { + ignoreCnt--; + } + } else if ((dest[i] >= high || dest[i] <= low) && (bitHigh == 0)) { + //error bar found no clock... + errBitHigh=1; + } + if (bitnum >= MaxBits) break; + } + *size = bitnum; + return bestErrCnt; } //by marshmellow //detects the bit clock for FSK given the high and low Field Clocks uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow) { - uint8_t clk[] = {8,16,32,40,50,64,100,128,0}; - uint16_t rfLens[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t rfCnts[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t rfLensFnd = 0; - uint8_t lastFCcnt=0; - uint32_t fcCounter = 0; - uint16_t rfCounter = 0; - uint8_t firstBitFnd = 0; - size_t i; - if (size == 0) return 0; - - uint8_t fcTol = (uint8_t)(0.5+(float)(fcHigh-fcLow)/2); - rfLensFnd=0; - fcCounter=0; - rfCounter=0; - firstBitFnd=0; - //PrintAndLog("DEBUG: fcTol: %d",fcTol); - // prime i to first up transition - for (i = 1; i < size-1; i++) - if (BitStream[i] > BitStream[i-1] && BitStream[i]>=BitStream[i+1]) - break; - - for (; i < size-1; i++){ - if (BitStream[i] > BitStream[i-1] && BitStream[i]>=BitStream[i+1]){ - // new peak - fcCounter++; - rfCounter++; - // if we got less than the small fc + tolerance then set it to the small fc - if (fcCounter < fcLow+fcTol) - fcCounter = fcLow; - else //set it to the large fc - fcCounter = fcHigh; - - //look for bit clock (rf/xx) - if ((fcCounterlastFCcnt)){ - //not the same size as the last wave - start of new bit sequence - - if (firstBitFnd>1){ //skip first wave change - probably not a complete bit - for (int ii=0; ii<15; ii++){ - if (rfLens[ii]==rfCounter){ - rfCnts[ii]++; - rfCounter=0; - break; - } - } - if (rfCounter>0 && rfLensFnd<15){ - //PrintAndLog("DEBUG: rfCntr %d, fcCntr %d",rfCounter,fcCounter); - rfCnts[rfLensFnd]++; - rfLens[rfLensFnd++]=rfCounter; - } - } else { - firstBitFnd++; - } - rfCounter=0; - lastFCcnt=fcCounter; - } - fcCounter=0; - } else { - // count sample - fcCounter++; - rfCounter++; - } - } - uint8_t rfHighest=15, rfHighest2=15, rfHighest3=15; - - for (i=0; i<15; i++){ - //PrintAndLog("DEBUG: RF %d, cnts %d",rfLens[i], rfCnts[i]); - //get highest 2 RF values (might need to get more values to compare or compare all?) - if (rfCnts[i]>rfCnts[rfHighest]){ - rfHighest3=rfHighest2; - rfHighest2=rfHighest; - rfHighest=i; - } else if(rfCnts[i]>rfCnts[rfHighest2]){ - rfHighest3=rfHighest2; - rfHighest2=i; - } else if(rfCnts[i]>rfCnts[rfHighest3]){ - rfHighest3=i; - } - } - // set allowed clock remainder tolerance to be 1 large field clock length+1 - // we could have mistakenly made a 9 a 10 instead of an 8 or visa versa so rfLens could be 1 FC off - uint8_t tol1 = fcHigh+1; - - //PrintAndLog("DEBUG: hightest: 1 %d, 2 %d, 3 %d",rfLens[rfHighest],rfLens[rfHighest2],rfLens[rfHighest3]); - - // loop to find the highest clock that has a remainder less than the tolerance - // compare samples counted divided by - int ii=7; - for (; ii>=0; ii--){ - if (rfLens[rfHighest] % clk[ii] < tol1 || rfLens[rfHighest] % clk[ii] > clk[ii]-tol1){ - if (rfLens[rfHighest2] % clk[ii] < tol1 || rfLens[rfHighest2] % clk[ii] > clk[ii]-tol1){ - if (rfLens[rfHighest3] % clk[ii] < tol1 || rfLens[rfHighest3] % clk[ii] > clk[ii]-tol1){ - break; - } - } - } - } - - if (ii<0) return 0; // oops we went too far - - return clk[ii]; + uint8_t clk[] = {8,16,32,40,50,64,100,128,0}; + uint16_t rfLens[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t rfCnts[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t rfLensFnd = 0; + uint8_t lastFCcnt = 0; + uint16_t fcCounter = 0; + uint16_t rfCounter = 0; + uint8_t firstBitFnd = 0; + size_t i; + if (size == 0) return 0; + + uint8_t fcTol = (uint8_t)(0.5+(float)(fcHigh-fcLow)/2); + rfLensFnd=0; + fcCounter=0; + rfCounter=0; + firstBitFnd=0; + //PrintAndLog("DEBUG: fcTol: %d",fcTol); + // prime i to first up transition + for (i = 1; i < size-1; i++) + if (BitStream[i] > BitStream[i-1] && BitStream[i]>=BitStream[i+1]) + break; + + for (; i < size-1; i++){ + fcCounter++; + rfCounter++; + + if (BitStream[i] <= BitStream[i-1] || BitStream[i] < BitStream[i+1]) + continue; + // else new peak + // if we got less than the small fc + tolerance then set it to the small fc + if (fcCounter < fcLow+fcTol) + fcCounter = fcLow; + else //set it to the large fc + fcCounter = fcHigh; + + //look for bit clock (rf/xx) + if ((fcCounter < lastFCcnt || fcCounter > lastFCcnt)){ + //not the same size as the last wave - start of new bit sequence + if (firstBitFnd > 1){ //skip first wave change - probably not a complete bit + for (int ii=0; ii<15; ii++){ + if (rfLens[ii] == rfCounter){ + rfCnts[ii]++; + rfCounter = 0; + break; + } + } + if (rfCounter > 0 && rfLensFnd < 15){ + //PrintAndLog("DEBUG: rfCntr %d, fcCntr %d",rfCounter,fcCounter); + rfCnts[rfLensFnd]++; + rfLens[rfLensFnd++] = rfCounter; + } + } else { + firstBitFnd++; + } + rfCounter=0; + lastFCcnt=fcCounter; + } + fcCounter=0; + } + uint8_t rfHighest=15, rfHighest2=15, rfHighest3=15; + + for (i=0; i<15; i++){ + //PrintAndLog("DEBUG: RF %d, cnts %d",rfLens[i], rfCnts[i]); + //get highest 2 RF values (might need to get more values to compare or compare all?) + if (rfCnts[i]>rfCnts[rfHighest]){ + rfHighest3=rfHighest2; + rfHighest2=rfHighest; + rfHighest=i; + } else if(rfCnts[i]>rfCnts[rfHighest2]){ + rfHighest3=rfHighest2; + rfHighest2=i; + } else if(rfCnts[i]>rfCnts[rfHighest3]){ + rfHighest3=i; + } + } + // set allowed clock remainder tolerance to be 1 large field clock length+1 + // we could have mistakenly made a 9 a 10 instead of an 8 or visa versa so rfLens could be 1 FC off + uint8_t tol1 = fcHigh+1; + + //PrintAndLog("DEBUG: hightest: 1 %d, 2 %d, 3 %d",rfLens[rfHighest],rfLens[rfHighest2],rfLens[rfHighest3]); + + // loop to find the highest clock that has a remainder less than the tolerance + // compare samples counted divided by + int ii=7; + for (; ii>=0; ii--){ + if (rfLens[rfHighest] % clk[ii] < tol1 || rfLens[rfHighest] % clk[ii] > clk[ii]-tol1){ + if (rfLens[rfHighest2] % clk[ii] < tol1 || rfLens[rfHighest2] % clk[ii] > clk[ii]-tol1){ + if (rfLens[rfHighest3] % clk[ii] < tol1 || rfLens[rfHighest3] % clk[ii] > clk[ii]-tol1){ + break; + } + } + } + } + + if (ii<0) return 0; // oops we went too far + + return clk[ii]; } //by marshmellow //countFC is to detect the field clock lengths. //counts and returns the 2 most common wave lengths //mainly used for FSK field clock detection -uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t *mostFC) +uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) { - uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0}; - uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0}; - uint8_t fcLensFnd = 0; - uint8_t lastFCcnt=0; - uint32_t fcCounter = 0; - size_t i; - if (size == 0) return 0; - - // prime i to first up transition - for (i = 1; i < size-1; i++) - if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]) - break; - - for (; i < size-1; i++){ - if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){ - // new up transition - fcCounter++; - - //if we had 5 and now have 9 then go back to 8 (for when we get a fc 9 instead of an 8) - if (lastFCcnt==5 && fcCounter==9) fcCounter--; - //if odd and not rc/5 add one (for when we get a fc 9 instead of 10) - if ((fcCounter==9 && fcCounter & 1) || fcCounter==4) fcCounter++; - - // save last field clock count (fc/xx) - // find which fcLens to save it to: - for (int ii=0; ii<10; ii++){ - if (fcLens[ii]==fcCounter){ - fcCnts[ii]++; - fcCounter=0; - break; - } - } - if (fcCounter>0 && fcLensFnd<10){ - //add new fc length - fcCnts[fcLensFnd]++; - fcLens[fcLensFnd++]=fcCounter; - } - fcCounter=0; - } else { - // count sample - fcCounter++; - } - } - - uint8_t best1=9, best2=9, best3=9; - uint16_t maxCnt1=0; - // go through fclens and find which ones are bigest 2 - for (i=0; i<10; i++){ - // PrintAndLog("DEBUG: FC %d, Cnt %d, Errs %d",fcLens[i],fcCnts[i],errCnt); - // get the 3 best FC values - if (fcCnts[i]>maxCnt1) { - best3=best2; - best2=best1; - maxCnt1=fcCnts[i]; - best1=i; - } else if(fcCnts[i]>fcCnts[best2]){ - best3=best2; - best2=i; - } else if(fcCnts[i]>fcCnts[best3]){ - best3=i; - } - } - uint8_t fcH=0, fcL=0; - if (fcLens[best1]>fcLens[best2]){ - fcH=fcLens[best1]; - fcL=fcLens[best2]; - } else{ - fcH=fcLens[best2]; - fcL=fcLens[best1]; - } - - *mostFC=fcLens[best1]; - // TODO: take top 3 answers and compare to known Field clocks to get top 2 - - uint16_t fcs = (((uint16_t)fcH)<<8) | fcL; - // PrintAndLog("DEBUG: Best %d best2 %d best3 %d",fcLens[best1],fcLens[best2],fcLens[best3]); - - return fcs; -} + uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0}; + uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0}; + uint8_t fcLensFnd = 0; + uint8_t lastFCcnt=0; + uint8_t fcCounter = 0; + size_t i; + if (size == 0) return 0; + + // prime i to first up transition + for (i = 1; i < size-1; i++) + if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]) + break; -//by marshmellow -//countPSK_FC is to detect the psk carrier clock length. -//counts and returns the 1 most common wave length -uint8_t countPSK_FC(uint8_t *BitStream, size_t size) -{ - uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0}; - uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0}; - uint8_t fcLensFnd = 0; - uint32_t fcCounter = 0; - size_t i; - if (size == 0) return 0; - - // prime i to first up transition - for (i = 1; i < size-1; i++) - if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]) - break; - - for (; i < size-1; i++){ - if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){ - // new up transition - fcCounter++; - - // save last field clock count (fc/xx) - // find which fcLens to save it to: - for (int ii=0; ii<10; ii++){ - if (fcLens[ii]==fcCounter){ - fcCnts[ii]++; - fcCounter=0; - break; - } - } - if (fcCounter>0 && fcLensFnd<10){ - //add new fc length - fcCnts[fcLensFnd]++; - fcLens[fcLensFnd++]=fcCounter; - } - fcCounter=0; - } else { - // count sample - fcCounter++; - } - } - - uint8_t best1=9; - uint16_t maxCnt1=0; - // go through fclens and find which ones are bigest - for (i=0; i<10; i++){ - //PrintAndLog("DEBUG: FC %d, Cnt %d",fcLens[i],fcCnts[i]); - // get the best FC value - if (fcCnts[i]>maxCnt1) { - maxCnt1=fcCnts[i]; - best1=i; - } - } - return fcLens[best1]; + for (; i < size-1; i++){ + if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){ + // new up transition + fcCounter++; + if (fskAdj){ + //if we had 5 and now have 9 then go back to 8 (for when we get a fc 9 instead of an 8) + if (lastFCcnt==5 && fcCounter==9) fcCounter--; + //if fc=9 or 4 add one (for when we get a fc 9 instead of 10 or a 4 instead of a 5) + if ((fcCounter==9) || fcCounter==4) fcCounter++; + // save last field clock count (fc/xx) + lastFCcnt = fcCounter; + } + // find which fcLens to save it to: + for (int ii=0; ii<10; ii++){ + if (fcLens[ii]==fcCounter){ + fcCnts[ii]++; + fcCounter=0; + break; + } + } + if (fcCounter>0 && fcLensFnd<10){ + //add new fc length + fcCnts[fcLensFnd]++; + fcLens[fcLensFnd++]=fcCounter; + } + fcCounter=0; + } else { + // count sample + fcCounter++; + } + } + + uint8_t best1=9, best2=9, best3=9; + uint16_t maxCnt1=0; + // go through fclens and find which ones are bigest 2 + for (i=0; i<10; i++){ + // PrintAndLog("DEBUG: FC %d, Cnt %d, Errs %d",fcLens[i],fcCnts[i],errCnt); + // get the 3 best FC values + if (fcCnts[i]>maxCnt1) { + best3=best2; + best2=best1; + maxCnt1=fcCnts[i]; + best1=i; + } else if(fcCnts[i]>fcCnts[best2]){ + best3=best2; + best2=i; + } else if(fcCnts[i]>fcCnts[best3]){ + best3=i; + } + } + uint8_t fcH=0, fcL=0; + if (fcLens[best1]>fcLens[best2]){ + fcH=fcLens[best1]; + fcL=fcLens[best2]; + } else{ + fcH=fcLens[best2]; + fcL=fcLens[best1]; + } + + // TODO: take top 3 answers and compare to known Field clocks to get top 2 + + uint16_t fcs = (((uint16_t)fcH)<<8) | fcL; + // PrintAndLog("DEBUG: Best %d best2 %d best3 %d",fcLens[best1],fcLens[best2],fcLens[best3]); + if (fskAdj) return fcs; + return fcLens[best1]; } //by marshmellow - demodulate PSK1 wave //uses wave lengths (# Samples) int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert) { - uint16_t loopCnt = 4096; //don't need to loop through entire array... - if (size == 0) return -1; - if (*size= dest[i+2]){ - if (waveStart == 0) { - waveStart = i+1; - avgWaveVal=dest[i+1]; - //PrintAndLog("DEBUG: waveStart: %d",waveStart); - } else { - waveEnd = i+1; - //PrintAndLog("DEBUG: waveEnd: %d",waveEnd); - waveLenCnt = waveEnd-waveStart; - lastAvgWaveVal = avgWaveVal/waveLenCnt; - if (waveLenCnt > fc){ - firstFullWave = waveStart; - fullWaveLen=waveLenCnt; - //if average wave value is > graph 0 then it is an up wave or a 1 - if (lastAvgWaveVal > 128) curPhase^=1; - break; - } - waveStart=0; - avgWaveVal=0; - } - } - avgWaveVal+=dest[i+1]; - } - //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen); - lastClkBit = firstFullWave; //set start of wave as clock align - waveStart = 0; - errCnt=0; - size_t numBits=0; - //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d", *clock, lastClkBit); - - for (i = firstFullWave+fullWaveLen-1; i < *size-3; i++){ - //top edge of wave = start of new wave - if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]){ - if (waveStart == 0) { - waveStart = i+1; - waveLenCnt=0; - avgWaveVal = dest[i+1]; - } else { //waveEnd - waveEnd = i+1; - waveLenCnt = waveEnd-waveStart; - lastAvgWaveVal = avgWaveVal/waveLenCnt; - if (waveLenCnt > fc){ - //PrintAndLog("DEBUG: avgWaveVal: %d, waveSum: %d",lastAvgWaveVal,avgWaveVal); - //if this wave is a phase shift - //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+*clock-tol,i+1,fc); - if (i+1 >= lastClkBit + *clock - tol){ //should be a clock bit - curPhase^=1; - dest[numBits] = curPhase; - numBits++; - lastClkBit += *clock; - } else if (i lastClkBit + *clock + tol + fc){ - lastClkBit += *clock; //no phase shift but clock bit - dest[numBits] = curPhase; - numBits++; - } - avgWaveVal=0; - waveStart=i+1; - } - } - avgWaveVal+=dest[i+1]; - } - *size = numBits; - return errCnt; + if (size == 0) return -1; + uint16_t loopCnt = 4096; //don't need to loop through entire array... + if (*size= dest[i+2]){ + waveEnd = i+1; + //PrintAndLog("DEBUG: waveEnd: %d",waveEnd); + waveLenCnt = waveEnd-waveStart; + if (waveLenCnt > fc && waveStart > fc){ //not first peak and is a large wave + lastAvgWaveVal = avgWaveVal/(waveLenCnt); + firstFullWave = waveStart; + fullWaveLen=waveLenCnt; + //if average wave value is > graph 0 then it is an up wave or a 1 + if (lastAvgWaveVal > 123) curPhase ^= 1; //fudge graph 0 a little 123 vs 128 + break; + } + waveStart = i+1; + avgWaveVal = 0; + } + avgWaveVal += dest[i+2]; + } + //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen); + lastClkBit = firstFullWave; //set start of wave as clock align + //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d", *clock, lastClkBit); + waveStart = 0; + size_t numBits=0; + //set skipped bits + memset(dest, curPhase^1, firstFullWave / *clock); + numBits += (firstFullWave / *clock); + dest[numBits++] = curPhase; //set first read bit + for (i = firstFullWave + fullWaveLen - 1; i < *size-3; i++){ + //top edge of wave = start of new wave + if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]){ + if (waveStart == 0) { + waveStart = i+1; + waveLenCnt = 0; + avgWaveVal = dest[i+1]; + } else { //waveEnd + waveEnd = i+1; + waveLenCnt = waveEnd-waveStart; + lastAvgWaveVal = avgWaveVal/waveLenCnt; + if (waveLenCnt > fc){ + //PrintAndLog("DEBUG: avgWaveVal: %d, waveSum: %d",lastAvgWaveVal,avgWaveVal); + //this wave is a phase shift + //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+*clock-tol,i+1,fc); + if (i+1 >= lastClkBit + *clock - tol){ //should be a clock bit + curPhase ^= 1; + dest[numBits++] = curPhase; + lastClkBit += *clock; + } else if (i < lastClkBit+10+fc){ + //noise after a phase shift - ignore + } else { //phase shift before supposed to based on clock + errCnt++; + dest[numBits++] = 77; + } + } else if (i+1 > lastClkBit + *clock + tol + fc){ + lastClkBit += *clock; //no phase shift but clock bit + dest[numBits++] = curPhase; + } + avgWaveVal = 0; + waveStart = i+1; + } + } + avgWaveVal += dest[i+1]; + } + *size = numBits; + return errCnt; } diff --git a/common/lfdemod.h b/common/lfdemod.h index 23525a48..15121cbf 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -16,8 +16,9 @@ #include int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr); +uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low); int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr); -uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx); +uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo); int ManchesterEncode(uint8_t *BitStream, size_t size); int manrawdecode(uint8_t *BitStream, size_t *size); int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert); @@ -32,18 +33,15 @@ void psk1TOpsk2(uint8_t *BitStream, size_t size); void psk2TOpsk1(uint8_t *BitStream, size_t size); int DetectNRZClock(uint8_t dest[], size_t size, int clock); int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert); -void pskCleanWave(uint8_t *bitStream, size_t size); int PyramiddemodFSK(uint8_t *dest, size_t *size); int AWIDdemodFSK(uint8_t *dest, size_t *size); size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen); -uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t *mostFC); +uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj); uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow); int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx); uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType); -uint8_t justNoise(uint8_t *BitStream, size_t size); -uint8_t countPSK_FC(uint8_t *BitStream, size_t size); int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert); int DetectPSKClock(uint8_t dest[], size_t size, int clock); diff --git a/include/crc.h b/include/crc.h deleted file mode 100644 index 8e68f3b3..00000000 --- a/include/crc.h +++ /dev/null @@ -1,48 +0,0 @@ -//----------------------------------------------------------------------------- -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Generic CRC calculation code. -//----------------------------------------------------------------------------- - -#ifndef __CRC_H -#define __CRC_H - -#include - -typedef struct crc { - uint32_t state; - int order; - uint32_t polynom; - uint32_t initial_value; - uint32_t final_xor; - uint32_t mask; -} crc_t; - -/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32 - * polynom is the CRC polynom. initial_value is the initial value of a clean state. - * final_xor is XORed onto the state before returning it from crc_result(). */ -extern void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor); - -/* Update the crc state. data is the data of length data_width bits (only the the - * data_width lower-most bits are used). - */ -extern void crc_update(crc_t *crc, uint32_t data, int data_width); - -/* Clean the crc state, e.g. reset it to initial_value */ -extern void crc_clear(crc_t *crc); - -/* Get the result of the crc calculation */ -extern uint32_t crc_finish(crc_t *crc); - -/* Static initialization of a crc structure */ -#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \ - .state = ((_initial_value) & ((1L<<(_order))-1)), \ - .order = (_order), \ - .polynom = (_polynom), \ - .initial_value = (_initial_value), \ - .final_xor = (_final_xor), \ - .mask = ((1L<<(_order))-1) } - -#endif /* __CRC_H */ diff --git a/include/usb_cmd.h b/include/usb_cmd.h index aab631da..62c3d949 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -199,7 +199,11 @@ typedef struct{ //Iclass reader flags #define FLAG_ICLASS_READER_ONLY_ONCE 0x01 -#define FLAG_ICLASS_READER_GET_CC 0x02 +#define FLAG_ICLASS_READER_CC 0x02 +#define FLAG_ICLASS_READER_CSN 0x04 +#define FLAG_ICLASS_READER_CONF 0x08 +#define FLAG_ICLASS_READER_AA 0x10 + // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: