#include "util.h"
#include "printf.h"
#include "string.h"
-
#include <stdarg.h>
#include "legicrf.h"
WriteTItag(c->arg[0],c->arg[1],c->arg[2]);
break;
case CMD_SIMULATE_TAG_125K:
- LED_A_ON();
SimulateTagLowFrequency(c->arg[0], c->arg[1], 1);
- LED_A_OFF();
break;
case CMD_LF_SIMULATE_BIDIR:
SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);
else if(*rit > *start)\r
--rit;\r
else\r
- *it ^= (*it ^= *rit, *rit ^= *it);\r
+ *it ^= ( (*it ^= *rit ), *rit ^= *it);\r
\r
if(*rit >= *start)\r
--rit;\r
if(rit != start)\r
- *rit ^= (*rit ^= *start, *start ^= *rit);\r
+ *rit ^= ( (*rit ^= *start), *start ^= *rit);\r
\r
quicksort(start, rit - 1);\r
quicksort(rit + 1, stop);\r
// Set up eavesdropping mode, frequency divisor which will drive the FPGA
// and analog mux selection.
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
RELAY_OFF();
// Set up simulator mode, frequency divisor which will drive the FPGA
// and analog mux selection.
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
RELAY_OFF();
if (!ReaderReceive(resp, resp_par)) return 0;
sak = resp[0];
- // Test if more parts of the uid are comming
+ // Test if more parts of the uid are coming
if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) {
// Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
// http://www.nxp.com/documents/application_note/AN10927.pdf
*/
void DoAcquisition125k_internal(int trigger_threshold,bool silent)
{
- uint8_t *dest = (uint8_t *)BigBuf;
- int n = sizeof(BigBuf);
- int i;
-
- memset(dest, 0, n);
- 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;
- LED_D_OFF();
- if (trigger_threshold != -1 && dest[i] < trigger_threshold)
- continue;
- else
- trigger_threshold = -1;
- if (++i >= n) break;
- }
- }
- if(!silent)
- {
- Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
- dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
-
- }
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int n = sizeof(BigBuf);
+ int i;
+
+ memset(dest, 0, n);
+ 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;
+ LED_D_OFF();
+ if (trigger_threshold != -1 && dest[i] < trigger_threshold)
+ continue;
+ else
+ trigger_threshold = -1;
+ if (++i >= n) break;
+ }
+ }
+ if(!silent)
+ {
+ Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
+
+ }
}
/**
* Perform sample aquisition.
*/
void DoAcquisition125k(int trigger_threshold)
{
- DoAcquisition125k_internal(trigger_threshold, false);
+ DoAcquisition125k_internal(trigger_threshold, false);
}
/**
**/
void LFSetupFPGAForADC(int divisor, bool lf_field)
{
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
- else if (divisor == 0)
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- else
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
-
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
-
- // Connect the A/D to the peak-detected low-frequency path.
- SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
- // Give it a bit of time for the resonant antenna to settle.
- SpinDelay(50);
- // Now set up the SSC to get the ADC samples that are now streaming at us.
- FpgaSetupSsc();
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
+ else if (divisor == 0)
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ else
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
+
+ // Connect the A/D to the peak-detected low-frequency path.
+ SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
+ // Give it a bit of time for the resonant antenna to settle.
+ SpinDelay(50);
+ // Now set up the SSC to get the ADC samples that are now streaming at us.
+ FpgaSetupSsc();
}
/**
* Initializes the FPGA, and acquires the samples.
**/
void AcquireRawAdcSamples125k(int divisor)
{
- LFSetupFPGAForADC(divisor, true);
- // Now call the acquisition routine
- DoAcquisition125k_internal(-1,false);
+ LFSetupFPGAForADC(divisor, true);
+ // Now call the acquisition routine
+ DoAcquisition125k_internal(-1,false);
}
/**
* Initializes the FPGA for snoop-mode, and acquires the samples.
void SnoopLFRawAdcSamples(int divisor, int trigger_threshold)
{
- LFSetupFPGAForADC(divisor, false);
- DoAcquisition125k(trigger_threshold);
+ LFSetupFPGAForADC(divisor, false);
+ DoAcquisition125k(trigger_threshold);
}
void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
{
- /* Make sure the tag is reset */
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelay(2500);
+ /* Make sure the tag is reset */
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelay(2500);
- 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
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- // Give it a bit of time for the resonant antenna to settle.
- SpinDelay(50);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ // Give it a bit of time for the resonant antenna to settle.
+ SpinDelay(50);
- // And a little more time for the tag to fully power up
- SpinDelay(2000);
+ // And a little more time for the tag to fully power up
+ SpinDelay(2000);
- // Now set up the SSC to get the ADC samples that are now streaming at us.
- FpgaSetupSsc();
+ // Now set up the SSC to get the ADC samples that are now streaming at us.
+ FpgaSetupSsc();
- // 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, divisor_used);
+ // 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, divisor_used);
- 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, divisor_used);
+ 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, divisor_used);
- 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
- DoAcquisition125k(-1);
+ // now do the read
+ DoAcquisition125k(-1);
}
/* blank r/w tag data stream
*/
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;
- int n = sizeof(BigBuf);
- // 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; i<n-1; i++) {
- // count cycles by looking for lo to hi zero crossings
- if ( (dest[i]<0) && (dest[i+1]>0) ) {
- 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;
+ int n = sizeof(BigBuf);
+ // 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; i<n-1; i++) {
+ // count cycles by looking for lo to hi zero crossings
+ if ( (dest[i]<0) && (dest[i+1]>0) ) {
+ 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<<i)) {
- // stop modulating antenna
- LOW(GPIO_SSC_DOUT);
- SpinDelayUs(1000);
- // modulate antenna
- HIGH(GPIO_SSC_DOUT);
- SpinDelayUs(1000);
- } else {
- // stop modulating antenna
- LOW(GPIO_SSC_DOUT);
- SpinDelayUs(300);
- // modulate antenna
- HIGH(GPIO_SSC_DOUT);
- SpinDelayUs(1700);
- }
- }
+ int i = 0;
+
+ // modulate 8 bits out to the antenna
+ for (i=0; i<8; i++)
+ {
+ if (b&(1<<i)) {
+ // stop modulating antenna
+ LOW(GPIO_SSC_DOUT);
+ SpinDelayUs(1000);
+ // modulate antenna
+ HIGH(GPIO_SSC_DOUT);
+ SpinDelayUs(1000);
+ } else {
+ // stop modulating antenna
+ LOW(GPIO_SSC_DOUT);
+ SpinDelayUs(300);
+ // modulate antenna
+ HIGH(GPIO_SSC_DOUT);
+ SpinDelayUs(1700);
+ }
+ }
}
void AcquireTiType(void)
{
- int i, j, n;
- // tag transmission is <20ms, sampling at 2M gives us 40K samples max
- // each sample is 1 bit stuffed into a uint32_t so we need 1250 uint32_t
+ int i, j, n;
+ // tag transmission is <20ms, sampling at 2M gives us 40K samples max
+ // each sample is 1 bit stuffed into a uint32_t so we need 1250 uint32_t
#define TIBUFLEN 1250
- // clear buffer
- memset(BigBuf,0,sizeof(BigBuf));
-
- // 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;
- 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;
- }
- }
- }
+ // clear buffer
+ memset(BigBuf,0,sizeof(BigBuf));
+
+ // 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;
+ 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
// 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 = (uint8_t *)BigBuf;
+ int i;
+ uint8_t *tab = (uint8_t *)BigBuf;
- 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(;;) {
- while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
- if(BUTTON_PRESS()) {
- DbpString("Stopped");
- return;
- }
- WDT_HIT();
- }
-
- if (ledcontrol)
- LED_D_ON();
-
- if(tab[i])
- OPEN_COIL();
- else
- SHORT_COIL();
-
- if (ledcontrol)
- LED_D_OFF();
-
- 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);
- }
- }
- }
+ i = 0;
+ for(;;) {
+ while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
+ if(BUTTON_PRESS()) {
+ DbpString("Stopped");
+ return;
+ }
+ WDT_HIT();
+ }
+
+ if (ledcontrol)
+ LED_D_ON();
+
+ if(tab[i])
+ OPEN_COIL();
+ else
+ SHORT_COIL();
+
+ if (ledcontrol)
+ LED_D_OFF();
+
+ 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
// compose fc/8 fc/10 waveform
static void fc(int c, int *n) {
- uint8_t *dest = (uint8_t *)BigBuf;
- int idx;
-
- // for when we want an fc8 pattern every 4 logical bits
- if(c==0) {
- dest[((*n)++)]=1;
- dest[((*n)++)]=1;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- }
- // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
- if(c==8) {
- for (idx=0; idx<6; idx++) {
- dest[((*n)++)]=1;
- dest[((*n)++)]=1;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- }
- }
-
- // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
- if(c==10) {
- for (idx=0; idx<5; idx++) {
- dest[((*n)++)]=1;
- dest[((*n)++)]=1;
- dest[((*n)++)]=1;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- }
- }
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int idx;
+
+ // for when we want an fc8 pattern every 4 logical bits
+ if(c==0) {
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ }
+ // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
+ if(c==8) {
+ for (idx=0; idx<6; idx++) {
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ }
+ }
+
+ // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
+ if(c==10) {
+ for (idx=0; idx<5; idx++) {
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ }
+ }
}
// 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.");
- 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.");
+ 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();
}
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
- uint8_t *dest = (uint8_t *)BigBuf;
+ uint8_t *dest = (uint8_t *)BigBuf;
- size_t size=0; //, found=0;
- uint32_t hi2=0, hi=0, lo=0;
+ size_t size=0; //, found=0;
+ uint32_t hi2=0, hi=0, lo=0;
- // Configure to go in 125Khz listen mode
- LFSetupFPGAForADC(95, true);
+ // 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();
- DoAcquisition125k_internal(-1,true);
- // FSK demodulator
+ DoAcquisition125k_internal(-1,true);
+ // FSK demodulator
size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo);
- WDT_HIT();
+ WDT_HIT();
if (size>0 && 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;
+ // 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 (((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();
- 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();
+ return;
+ }
+ // reset
+ hi2 = hi = lo = 0;
+ }
+ WDT_HIT();
+ }
+ DbpString("Stopped");
+ if (ledcontrol) LED_A_OFF();
}
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
{
- uint8_t *dest = (uint8_t *)BigBuf;
+ uint8_t *dest = (uint8_t *)BigBuf;
size_t size=0;
- int clk=0, invert=0, errCnt=0;
- uint64_t lo=0;
- // Configure to go in 125Khz listen mode
- LFSetupFPGAForADC(95, true);
+ int clk=0, invert=0, errCnt=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();
- DoAcquisition125k_internal(-1,true);
- size = sizeof(BigBuf);
- //Dbprintf("DEBUG: Buffer got");
+ DoAcquisition125k_internal(-1,true);
+ size = sizeof(BigBuf);
+ //Dbprintf("DEBUG: Buffer got");
//askdemod and manchester decode
errCnt = askmandemod(dest, &size, &clk, &invert);
- //Dbprintf("DEBUG: ASK Got");
- WDT_HIT();
+ //Dbprintf("DEBUG: ASK Got");
+ WDT_HIT();
- if (errCnt>=0){
+ if (errCnt>=0){
lo = Em410xDecode(dest,size);
- //Dbprintf("DEBUG: EM GOT");
- if (lo>0){
+ //Dbprintf("DEBUG: EM GOT");
+ if (lo>0){
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();
- 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();
+ }
+ if (findone){
+ if (ledcontrol) LED_A_OFF();
+ 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();
}
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
- uint8_t *dest = (uint8_t *)BigBuf;
- 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();
- DoAcquisition125k_internal(-1,true);
- //fskdemod and get start index
- WDT_HIT();
- idx = IOdemodFSK(dest,sizeof(BigBuf));
- 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();
- return;
- }
- code=code2=0;
- version=facilitycode=0;
- number=0;
- idx=0;
- }
- WDT_HIT();
- }
- DbpString("Stopped");
- if (ledcontrol) LED_A_OFF();
+ uint8_t *dest = (uint8_t *)BigBuf;
+ 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();
+ DoAcquisition125k_internal(-1,true);
+ //fskdemod and get start index
+ WDT_HIT();
+ idx = IOdemodFSK(dest,sizeof(BigBuf));
+ 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();
+ return;
+ }
+ code=code2=0;
+ version=facilitycode=0;
+ number=0;
+ idx=0;
+ }
+ WDT_HIT();
+ }
+ DbpString("Stopped");
+ if (ledcontrol) LED_A_OFF();
}
/*------------------------------
// 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);
+ //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);
}
// Read one card block in page 0
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
- uint8_t *dest = (uint8_t *)BigBuf;
- //int m=0, i=0; //enio adjustment 12/10/14
- uint32_t m=0, i=0;
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- m = sizeof(BigBuf);
- // 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!");
+ uint8_t *dest = (uint8_t *)BigBuf;
+ //int m=0, i=0; //enio adjustment 12/10/14
+ uint32_t m=0, i=0;
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ m = sizeof(BigBuf);
+ // 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!");
}
// Read card traceability data (page 1)
void T55xxReadTrace(void){
- uint8_t *dest = (uint8_t *)BigBuf;
- int m=0, i=0;
-
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- m = sizeof(BigBuf);
- // 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!");
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int m=0, i=0;
+
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ m = sizeof(BigBuf);
+ // 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!");
}
/*-------------- 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
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!");
}
#define max(x,y) ( x<y ? y:x)
int DemodPCF7931(uint8_t **outBlocks) {
- uint8_t BitStream[256];
- uint8_t Blocks[8][16];
- uint8_t *GraphBuffer = (uint8_t *)BigBuf;
- int GraphTraceLen = sizeof(BigBuf);
- int i, j, lastval, bitidx, half_switch;
- int clock = 64;
- int tolerance = clock / 8;
- int pmc, block_done;
- int lc, warnings = 0;
- int num_blocks = 0;
- int lmin=128, lmax=128;
- uint8_t dir;
-
- AcquireRawAdcSamples125k(0);
-
- 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;
+ uint8_t BitStream[256];
+ uint8_t Blocks[8][16];
+ uint8_t *GraphBuffer = (uint8_t *)BigBuf;
+ int GraphTraceLen = sizeof(BigBuf);
+ int i, j, lastval, bitidx, half_switch;
+ int clock = 64;
+ int tolerance = clock / 8;
+ int pmc, block_done;
+ int lc, warnings = 0;
+ int num_blocks = 0;
+ int lmin=128, lmax=128;
+ uint8_t dir;
+
+ AcquireRawAdcSamples125k(0);
+
+ 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<n; i++)
- Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
- tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
- if(!ident) {
- for(i=0; i<n; i++) {
- if(IsBlock0PCF7931(tmpBlocks[i])) {
- // Found block 0 ?
- if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
- // Found block 1!
- // \o/
- ident = 1;
- memcpy(Blocks[0], tmpBlocks[i], 16);
- Blocks[0][ALLOC] = 1;
- memcpy(Blocks[1], tmpBlocks[i+1], 16);
- Blocks[1][ALLOC] = 1;
- max_blocks = max((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
- // Debug print
- Dbprintf("(dbg) Max blocks: %d", max_blocks);
- num_blocks = 2;
- // Handle following blocks
- for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
- if(j==n) j=0;
- if(j==i) break;
- memcpy(Blocks[ind2], tmpBlocks[j], 16);
- Blocks[ind2][ALLOC] = 1;
- }
- break;
- }
- }
- }
- }
- else {
- for(i=0; i<n; i++) { // Look for identical block in known blocks
- if(memcmp(tmpBlocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { // Block is not full of 00
- for(j=0; j<max_blocks; j++) {
- if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
- // Found an identical block
- for(ind=i-1,ind2=j-1; ind >= 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<n; i++)
+ Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
+ tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
+ if(!ident) {
+ for(i=0; i<n; i++) {
+ if(IsBlock0PCF7931(tmpBlocks[i])) {
+ // Found block 0 ?
+ if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
+ // Found block 1!
+ // \o/
+ ident = 1;
+ memcpy(Blocks[0], tmpBlocks[i], 16);
+ Blocks[0][ALLOC] = 1;
+ memcpy(Blocks[1], tmpBlocks[i+1], 16);
+ Blocks[1][ALLOC] = 1;
+ max_blocks = max((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
+ // Debug print
+ Dbprintf("(dbg) Max blocks: %d", max_blocks);
+ num_blocks = 2;
+ // Handle following blocks
+ for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
+ if(j==n) j=0;
+ if(j==i) break;
+ memcpy(Blocks[ind2], tmpBlocks[j], 16);
+ Blocks[ind2][ALLOC] = 1;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else {
+ for(i=0; i<n; i++) { // Look for identical block in known blocks
+ if(memcmp(tmpBlocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { // Block is not full of 00
+ for(j=0; j<max_blocks; j++) {
+ if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
+ // Found an identical block
+ for(ind=i-1,ind2=j-1; ind >= 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<max_blocks; i++) {
- if(Blocks[i][ALLOC]==1)
- Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
- Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
- else
- Dbprintf("<missing block %d>", i);
- }
- Dbprintf("-----------------------------------------");
-
- return ;
+ Dbprintf("-----------------------------------------");
+ Dbprintf("Memory content:");
+ Dbprintf("-----------------------------------------");
+ for(i=0; i<max_blocks; i++) {
+ if(Blocks[i][ALLOC]==1)
+ Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
+ Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
+ else
+ Dbprintf("<missing block %d>", i);
+ }
+ Dbprintf("-----------------------------------------");
+
+ return ;
}
//====================================================================
//--------------------------------------------------------------------
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
}
//====================================================================
//--------------------------------------------------------------------
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
}
//====================================================================
//--------------------------------------------------------------------
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
}
//====================================================================
//====================================================================
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 = (uint8_t *)BigBuf;
- 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 = sizeof(BigBuf);
- // 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 = (uint8_t *)BigBuf;
+ 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 = sizeof(BigBuf);
+ // 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();
}
\r
#include "mifarecmd.h"\r
#include "apps.h"\r
+#include "util.h"\r
\r
//-----------------------------------------------------------------------------\r
// Select, Authenticate, Read a MIFARE tag. \r
\r
void MifareUReadBlock(uint8_t arg0,uint8_t *datain)\r
{\r
- // params\r
uint8_t blockNo = arg0;\r
- \r
- // variables\r
- byte_t isOK = 0;\r
- byte_t dataoutbuf[16];\r
- uint8_t uid[10];\r
+ byte_t dataout[16] = {0x00};\r
+ uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- // clear trace\r
- iso14a_clear_trace();\r
- iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
- \r
LED_A_ON();\r
LED_B_OFF();\r
LED_C_OFF();\r
\r
- while (true) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
- break;\r
+ iso14a_clear_trace();\r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+ \r
+ int len = iso14443a_select_card(uid, NULL, &cuid);\r
+ if(!len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
+ OnError(1);\r
+ return;\r
};\r
\r
- if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");\r
- break;\r
+ len = mifare_ultra_readblock(cuid, blockNo, dataout);\r
+ if(len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");\r
+ OnError(2);\r
+ return;\r
};\r
\r
- if(mifare_ultra_halt(cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
- break;\r
+ len = mifare_ultra_halt(cuid);\r
+ if(len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");\r
+ OnError(3);\r
+ return;\r
};\r
\r
- isOK = 1;\r
- break;\r
- }\r
- \r
- if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");\r
- \r
- LED_B_ON();\r
- cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);\r
- LED_B_OFF();\r
+ cmd_send(CMD_ACK,1,0,0,dataout,16);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
LEDsoff();\r
}\r
\r
-\r
-void MifareUReadCard(uint8_t arg0, uint8_t *datain)\r
+void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)\r
{\r
// params\r
uint8_t sectorNo = arg0;\r
- \r
- // variables\r
- byte_t isOK = 0;\r
- byte_t dataoutbuf[16 * 4];\r
- uint8_t uid[10];\r
+ int Pages = arg1;\r
+ int count_Pages = 0;\r
+ byte_t dataout[176] = {0x00};;\r
+ uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- // clear trace\r
- iso14a_clear_trace();\r
-// iso14a_set_tracing(false);\r
-\r
- iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
-\r
LED_A_ON();\r
LED_B_OFF();\r
LED_C_OFF();\r
\r
- while (true) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
- break;\r
- };\r
- for(int sec=0;sec<16;sec++){\r
- if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Read block %d error",sec);\r
- break;\r
- };\r
- }\r
- if(mifare_ultra_halt(cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
- break;\r
- };\r
+ if (MF_DBGLEVEL >= MF_DBG_ALL) \r
+ Dbprintf("Pages %d",Pages);\r
+ \r
+ iso14a_clear_trace();\r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
- isOK = 1;\r
- break;\r
- }\r
- \r
- if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");\r
+ int len = iso14443a_select_card(uid, NULL, &cuid);\r
+ \r
+ if (!len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Can't select card");\r
+ OnError(1);\r
+ return;\r
+ }\r
+ \r
+ for (int i = 0; i < Pages; i++){\r
+ \r
+ len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i);\r
+ \r
+ if (len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Read block %d error",i);\r
+ OnError(2);\r
+ return;\r
+ } else {\r
+ count_Pages++;\r
+ }\r
+ }\r
+ \r
+ len = mifare_ultra_halt(cuid);\r
+ if (len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Halt error");\r
+ OnError(3);\r
+ return;\r
+ }\r
+ \r
+ if (MF_DBGLEVEL >= MF_DBG_ALL) {\r
+ Dbprintf("Pages read %d", count_Pages);\r
+ }\r
\r
- LED_B_ON();\r
- cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);\r
- LED_B_OFF();\r
+ len = 16*4; //64 bytes\r
+ \r
+ // Read a UL-C\r
+ if (Pages == 44 && count_Pages > 16) \r
+ len = 176;\r
\r
- // Thats it...\r
+ cmd_send(CMD_ACK, 1, 0, 0, dataout, len); \r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
-\r
}\r
\r
\r
{\r
// params\r
uint8_t blockNo = arg0;\r
- byte_t blockdata[16];\r
+ byte_t blockdata[16] = {0x00};\r
\r
- memset(blockdata,'\0',16);\r
memcpy(blockdata, datain,16);\r
\r
// variables\r
byte_t isOK = 0;\r
- uint8_t uid[10];\r
+ uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- // clear trace\r
iso14a_clear_trace();\r
-\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
LED_A_ON();\r
\r
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
\r
- LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,0,0);\r
- LED_B_OFF();\r
-\r
-\r
- // Thats it...\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
-// iso14a_set_tracing(TRUE);\r
}\r
\r
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)\r
{\r
// params\r
uint8_t blockNo = arg0;\r
- byte_t blockdata[4];\r
+ byte_t blockdata[4] = {0x00};\r
\r
memcpy(blockdata, datain,4);\r
\r
// variables\r
byte_t isOK = 0;\r
- uint8_t uid[10];\r
+ uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- // clear trace\r
iso14a_clear_trace();\r
-\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
LED_A_ON();\r
\r
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
\r
- LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,0,0);\r
- LED_B_OFF();\r
-\r
- // Thats it...\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
return len;\r
}\r
\r
-// mifare commands\r
+// mifare classic commands\r
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested) \r
{\r
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);\r
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
- // variables
uint16_t len;
uint8_t bt[2];
-
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
}
if (len != 18) {
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: card timeout. len: %x", len);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Error: card timeout. len: %x", len);
return 2;
}
memcpy(bt, receivedAnswer + 16, 2);
AppendCrc14443a(receivedAnswer, 16);
if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd CRC response error.");
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd CRC response error.");
return 3;
}
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
- // variables
uint16_t len;
uint8_t par[3] = {0}; // enough for 18 parity bits
- uint8_t d_block[18];
+ uint8_t d_block[18] = {0x00};
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
return 1;
}
- memset(d_block,'\0',18);
memcpy(d_block, blockData, 16);
AppendCrc14443a(d_block, 16);
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
- // Receive the response
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
return 2;
}
-
return 0;
}
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
uint16_t len;
- uint8_t d_block[8];
+ uint8_t d_block[8] = {0x00};
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();\r
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_WRITEBLOCK
- memset(d_block,'\0',8);
d_block[0]= blockNo;
memcpy(d_block+1,blockData,4);
AppendCrc14443a(d_block, 6);
- //i know the data send here is correct
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
return 1;
}
\r return 0;
\r
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);\r
if (len != 0) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len); \r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("halt error. response len: %x", len); \r
return 1;\r
}\r
\r
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) {
- if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("halt error. response len: %x", len);
return 1;
}
-
return 0;
}
return 0;
}
+void memxor(uint8_t * dest, uint8_t * src, size_t len) {
+ for( ; len > 0; len--,dest++,src++)
+ *dest ^= *src;
+}
+
int strlen(const char *str)
{
int l = 0;
RAMFUNC void *memcpy(void *dest, const void *src, int len);
void *memset(void *dest, int c, int len);
RAMFUNC int memcmp(const void *av, const void *bv, int len);
+void memxor(uint8_t * dest, uint8_t * src, size_t len);
char *strncat(char *dest, const char *src, unsigned int n);
char *strcat(char *dest, const char *src);
void strreverse(char s[]);
#include "string.h"
#include "apps.h"
+
+
+void print_result(char *name, uint8_t *buf, size_t len) {
+ uint8_t *p = buf;
+
+ if ( len % 16 == 0 ) {
+ for(; p-buf < len; p += 16)
+ Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ name,
+ p-buf,
+ len,
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
+ );
+ }
+ else {
+ for(; p-buf < len; p += 8)
+ Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x", name, p-buf, len, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ }
+}
+
size_t nbytes(size_t nbits) {
return (nbits/8)+((nbits%8)>0);
}
return num;
}
+// RotateLeft - Ultralight, Desfire
+void rol(uint8_t *data, const size_t len){
+ uint8_t first = data[0];
+ for (size_t i = 0; i < len-1; i++) {
+ data[i] = data[i+1];
+ }
+ data[len-1] = first;
+}
+void lsl (uint8_t *data, size_t len) {
+ for (size_t n = 0; n < len - 1; n++) {
+ data[n] = (data[n] << 1) | (data[n+1] >> 7);
+ }
+ data[len - 1] <<= 1;
+}
+
+int32_t le24toh (uint8_t data[3])
+{
+ return (data[2] << 16) | (data[1] << 8) | data[0];
+}
+
void LEDsoff()
{
LED_A_OFF();
#define BUTTON_DOUBLE_CLICK -2
#define BUTTON_ERROR -99
+void print_result(char *name, uint8_t *buf, size_t len);
size_t nbytes(size_t nbits);
uint32_t SwapBits(uint32_t value, int nrbits);
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
uint64_t bytes_to_num(uint8_t* src, size_t len);
+void rol(uint8_t *data, const size_t len);
+void lsl (uint8_t *data, size_t len);
+int32_t le24toh (uint8_t data[3]);
void SpinDelay(int ms);
void SpinDelayUs(int us);
switch(c->cmd) {
case CMD_DEVICE_INFO: {
dont_ack = 1;
-// c->cmd = CMD_DEVICE_INFO;
arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM |
DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH;
if(common_area.flags.osimage_present) {
arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;
}
-// UsbSendPacket(packet, len);
cmd_send(CMD_DEVICE_INFO,arg0,1,2,0,0);
} break;
case CMD_FINISH_WRITE: {
uint32_t* flash_mem = (uint32_t*)(&_flash_start);
-// p = (volatile uint32_t *)&_flash_start;
for (size_t j=0; j<2; j++) {
for(i = 0+(64*j); i < 64+(64*j); i++) {
- //p[i+60] = c->d.asDwords[i];
flash_mem[i] = c->d.asDwords[i];
}
if( ((flash_address+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (flash_address < start_addr) ) {
/* Disallow write */
dont_ack = 1;
- // c->cmd = CMD_NACK;
- // UsbSendPacket(packet, len);
cmd_send(CMD_NACK,0,0,0,0,0);
} else {
uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE;
AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY |
MC_FLASH_COMMAND_PAGEN(page_n) |
AT91C_MC_FCMD_START_PROG;
- // arg0 = (address - ((uint32_t)flash_s));
}
// Wait until flashing of page finishes
while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY));
if(sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) {
dont_ack = 1;
- // c->cmd = CMD_NACK;
cmd_send(CMD_NACK,0,0,0,0,0);
- // UsbSendPacket(packet, len);
}
}
} break;
case CMD_HARDWARE_RESET: {
-// USB_D_PLUS_PULLUP_OFF();
usb_disable();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
} break;
} else {
start_addr = end_addr = 0;
dont_ack = 1;
-// c->cmd = CMD_NACK;
-// UsbSendPacket(packet, len);
cmd_send(CMD_NACK,0,0,0,0,0);
}
}
}
if(!dont_ack) {
-// c->cmd = CMD_ACK;
-// UsbSendPacket(packet, len);
cmd_send(CMD_ACK,arg0,0,0,0,0);
}
}
usb_enable();
for (volatile size_t i=0; i<0x100000; i++);
-// UsbStart();
for(;;) {
WDT_HIT();
if (usb_poll()) {
rx_len = usb_read(rx,sizeof(UsbCommand));
if (rx_len) {
-// DbpString("starting to flash");
UsbPacketReceived(rx,rx_len);
}
}
-// UsbPoll(TRUE);
-
if(!externally_entered && !BUTTON_PRESS()) {
/* Perform a reset to leave flash mode */
-// USB_D_PLUS_PULLUP_OFF();
usb_disable();
LED_B_ON();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
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;
}
/*
//this method is dependant on all highs and lows to be the same(or clipped) this creates issues[marshmellow] it also ignores the clock
int Cmdaskdemod(const char *Cmd)
{
- int i;
- int c, high = 0, low = 0;
+ int i;
+ int c, high = 0, low = 0;
- // TODO: complain if we do not give 2 arguments here !
- // (AL - this doesn't make sense! we're only using one argument!!!)
- sscanf(Cmd, "%i", &c);
+ // TODO: complain if we do not give 2 arguments here !
+ // (AL - this doesn't make sense! we're only using one argument!!!)
+ sscanf(Cmd, "%i", &c);
- /* Detect high and lows and clock */
+ /* Detect high and lows and clock */
// (AL - clock???)
- 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;
+ 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;
}
//by marshmellow
void printBitStream(uint8_t BitStream[], uint32_t bitLen)
{
- uint32_t i = 0;
- if (bitLen<16) {
- PrintAndLog("Too few bits found: %d",bitLen);
- return;
- }
- if (bitLen>512) bitLen=512;
- 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]);
- }
+ uint32_t i = 0;
+ if (bitLen<16) {
+ PrintAndLog("Too few bits found: %d",bitLen);
+ return;
+ }
+ if (bitLen>512) bitLen=512;
+ 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]);
+ }
return;
}
//by marshmellow
//print EM410x ID in multiple formats
void printEM410x(uint64_t id)
{
- if (id !=0){
- uint64_t iii=1;
- uint64_t id2lo=0; //id2hi=0,
- uint32_t ii=0;
- uint32_t i=0;
- for (ii=5; ii>0;ii--){
- for (i=0;i<8;i++){
+ if (id !=0){
+ uint64_t iii=1;
+ uint64_t id2lo=0; //id2hi=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); //id2hi,
- 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));
+ }
+ }
+ //output em id
+ PrintAndLog("EM TAG ID : %010llx", id);
+ PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi,
+ 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;
+ return;
}
//by marshmellow
//take binary from demod buffer and see if we can find an EM410x ID
int CmdEm410xDecode(const char *Cmd)
{
- uint64_t id=0;
+ uint64_t id=0;
// uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
// uint32_t i=0;
// i=getFromGraphBuf(BitStream);
id = Em410xDecode(DemodBuffer,DemodBufferLen);
- printEM410x(id);
- if (id>0) return 1;
- return 0;
+ printEM410x(id);
+ if (id>0) return 1;
+ return 0;
}
{
int invert=0;
int clk=0;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i", &clk, &invert);
- if (invert != 0 && invert != 1) {
- PrintAndLog("Invalid argument: %s", Cmd);
- return 0;
- }
+ if (invert != 0 && invert != 1) {
+ PrintAndLog("Invalid argument: %s", Cmd);
+ return 0;
+ }
size_t BitLen = getFromGraphBuf(BitStream);
- // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
- int errCnt=0;
- errCnt = askmandemod(BitStream, &BitLen,&clk,&invert);
+ // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
+ int errCnt=0;
+ errCnt = askmandemod(BitStream, &BitLen,&clk,&invert);
if (errCnt<0||BitLen<16){ //if fatal error (or -1)
// PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
- return 0;
+ return 0;
}
- PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
+ 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
+ //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);
printDemodBuff();
- uint64_t lo =0;
- lo = Em410xDecode(BitStream,BitLen);
- if (lo>0){
- //set GraphBuffer for clone or sim command
- PrintAndLog("EM410x pattern found: ");
- printEM410x(lo);
- return 1;
- }
- //if (BitLen>16) return 1;
- return 0;
+ uint64_t lo =0;
+ lo = Em410xDecode(BitStream,BitLen);
+ if (lo>0){
+ //set GraphBuffer for clone or sim command
+ PrintAndLog("EM410x pattern found: ");
+ printEM410x(lo);
+ return 1;
+ }
+ //if (BitLen>16) return 1;
+ return 0;
}
//by marshmellow
//stricktly take 10 and 01 and convert to 0 and 1
int Cmdmandecoderaw(const char *Cmd)
{
- int i =0;
- int errCnt=0;
+ int i =0;
+ int errCnt=0;
size_t size=0;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- int high=0,low=0;
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ int high=0,low=0;
for (;i<DemodBufferLen;++i){
if (DemodBuffer[i]>high) high=DemodBuffer[i];
else if(DemodBuffer[i]<low) low=DemodBuffer[i];
BitStream[i]=DemodBuffer[i];
- }
- if (high>1 || low <0 ){
- PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode");
- return 0;
- }
+ }
+ if (high>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>=20){
- PrintAndLog("Too many errors: %d",errCnt);
- return 0;
- }
- PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt);
+ if (errCnt>=20){
+ PrintAndLog("Too many errors: %d",errCnt);
+ return 0;
+ }
+ PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt);
printBitStream(BitStream, size);
- if (errCnt==0){
+ if (errCnt==0){
uint64_t id = 0;
id = Em410xDecode(BitStream, size);
if (id>0) setDemodBuf(BitStream, size);
printEM410x(id);
- }
- return 1;
+ }
+ return 1;
}
//by marshmellow
// width waves vs small width waves to help the decode positioning) or askbiphdemod
int CmdBiphaseDecodeRaw(const char *Cmd)
{
- int i = 0;
- int errCnt=0;
+ int i = 0;
+ int errCnt=0;
size_t size=0;
- int offset=0;
- int high=0, low=0;
+ int offset=0;
+ int high=0, low=0;
sscanf(Cmd, "%i", &offset);
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- //get graphbuffer & high and low
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ //get graphbuffer & high and low
for (;i<DemodBufferLen;++i){
if(DemodBuffer[i]>high)high=DemodBuffer[i];
else if(DemodBuffer[i]<low)low=DemodBuffer[i];
BitStream[i]=DemodBuffer[i];
- }
- if (high>1 || low <0){
- PrintAndLog("Error: please raw demod the wave first then decode");
- return 0;
- }
+ }
+ if (high>1 || low <0){
+ PrintAndLog("Error: please raw demod the wave first then decode");
+ return 0;
+ }
size=i;
errCnt=BiphaseRawDecode(BitStream, &size, offset);
- if (errCnt>=20){
- PrintAndLog("Too many errors attempting to decode: %d",errCnt);
- return 0;
- }
- PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt);
+ if (errCnt>=20){
+ PrintAndLog("Too many errors attempting to decode: %d",errCnt);
+ return 0;
+ }
+ PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt);
printBitStream(BitStream, size);
- PrintAndLog("\nif bitstream does not look right try offset=1");
- return 1;
+ PrintAndLog("\nif bitstream does not look right try offset=1");
+ return 1;
}
{
int invert=0;
int clk=0;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i", &clk, &invert);
- if (invert != 0 && invert != 1) {
- PrintAndLog("Invalid argument: %s", Cmd);
- return 0;
- }
+ if (invert != 0 && invert != 1) {
+ PrintAndLog("Invalid argument: %s", Cmd);
+ return 0;
+ }
size_t BitLen = getFromGraphBuf(BitStream);
- int errCnt=0;
+ int errCnt=0;
errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert);
if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
PrintAndLog("no data found");
- return 0;
+ return 0;
}
- PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
- //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
+ PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
+ //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
//move BitStream back to DemodBuffer
setDemodBuf(BitStream,BitLen);
//output
- if (errCnt>0){
- PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
- }
- PrintAndLog("ASK demoded bitstream:");
- // Now output the bitstream to the scrollback by line of 16 bits
- printBitStream(BitStream,BitLen);
-
- return 1;
+ if (errCnt>0){
+ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
+ }
+ PrintAndLog("ASK demoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ printBitStream(BitStream,BitLen);
+
+ return 1;
}
int CmdAutoCorr(const char *Cmd)
{
- 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;
- }
-
- 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;
- }
- GraphTraceLen = GraphTraceLen - window;
- memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
-
- RepaintGraphWindow();
- return 0;
+ 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;
+ }
+
+ 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;
+ }
+ GraphTraceLen = GraphTraceLen - window;
+ memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
+
+ RepaintGraphWindow();
+ return 0;
}
int CmdBitsamples(const char *Cmd)
{
- int cnt = 0;
- uint8_t got[12288];
-
- 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;
+ int cnt = 0;
+ uint8_t got[12288];
+
+ 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;
}
/*
*/
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 = GetClock(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);
+ 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 = GetClock(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);
// for (j = 0; j < (int)(clock/2); j++)
// GraphBuffer[(i * clock) + j] = bit ^ 1;
// for (j = (int)(clock/2); j < clock; j++)
// GraphBuffer[(i * clock) + j] = bit;
- }
+ }
- RepaintGraphWindow();
- return 0;
+ 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;
}
/* Print our clock rate */
// uses data from graphbuffer
int CmdDetectClockRate(const char *Cmd)
{
- GetClock("",0,0);
+ GetClock("",0,0);
//int clock = DetectASKClock(0);
//PrintAndLog("Auto-detected clock rate: %d", clock);
- return 0;
+ return 0;
}
//by marshmellow
//defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a))
int CmdFSKrawdemod(const char *Cmd)
{
- //raw fsk demod no manchester decoding no start bit finding just get binary from wave
- //set defaults
- int rfLen = 50;
- int invert=0;
- int fchigh=10;
- int fclow=8;
- //set options from parameters entered with the command
+ //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+ //set defaults
+ int rfLen = 50;
+ int invert=0;
+ int fchigh=10;
+ int fclow=8;
+ //set options from parameters entered with the command
sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
- if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
- //rfLen=param_get8(Cmd, 0); //if rfLen option only is used
- if (rfLen==1){
- invert=1; //if invert option only is used
- rfLen = 50;
- } else if(rfLen==0) rfLen=50;
+ if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
+ //rfLen=param_get8(Cmd, 0); //if rfLen option only is used
+ if (rfLen==1){
+ invert=1; //if invert option only is used
+ rfLen = 50;
+ } else if(rfLen==0) rfLen=50;
}
- PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
- if (size>0){
- PrintAndLog("FSK decoded bitstream:");
+ if (size>0){
+ PrintAndLog("FSK decoded bitstream:");
setDemodBuf(BitStream,size);
- // 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
- printBitStream(BitStream,size);
- } else{
- PrintAndLog("no FSK data found");
- }
- return 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
+ printBitStream(BitStream,size);
+ } else{
+ PrintAndLog("no FSK data found");
+ }
+ return 0;
}
//by marshmellow (based on existing demod + holiman's refactor)
//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;
+ //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};
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
- //get binary from fsk wave
+ //get binary from fsk wave
size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo);
- if (size<0){
- PrintAndLog("Error demoding fsk");
- return 0;
- }
- if (hi2==0 && hi==0 && lo==0) return 0;
- if (hi2 != 0){ //extra large HID tags
+ if (size<0){
+ PrintAndLog("Error demoding fsk");
+ return 0;
+ }
+ if (hi2==0 && hi==0 && lo==0) 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);
+ (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
setDemodBuf(BitStream,BitLen);
- return 1;
- }
- 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 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 & 15) << 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++;
- }
+ return 1;
+ }
+ 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 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 & 15) << 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==37){
- cardnum = (lo>>1)&0x7FFFF;
- fc = ((hi&0xF)<<12)|(lo>>20);
- }
- if(fmtLen==34){
- cardnum = (lo>>1)&0xFFFF;
- fc= ((hi&1)<<15)|(lo>>17);
- }
- if(fmtLen==35){
- cardnum = (lo>>1)&0xFFFFF;
- fc = ((hi&1)<<11)|(lo>>21);
- }
- }
- else { //if bit 38 is not set then 37 bit format is used
- fmtLen= 37;
- fc =0;
- cardnum=0;
- if(fmtLen==37){
- cardnum = (lo>>1)&0x7FFFF;
- fc = ((hi&0xF)<<12)|(lo>>20);
- }
+ fc =0;
+ cardnum=0;
+ if(fmtLen==26){
+ cardnum = (lo>>1)&0xFFFF;
+ fc = (lo>>17)&0xFF;
+ }
+ if(fmtLen==37){
+ cardnum = (lo>>1)&0x7FFFF;
+ fc = ((hi&0xF)<<12)|(lo>>20);
+ }
+ if(fmtLen==34){
+ cardnum = (lo>>1)&0xFFFF;
+ fc= ((hi&1)<<15)|(lo>>17);
+ }
+ if(fmtLen==35){
+ cardnum = (lo>>1)&0xFFFFF;
+ fc = ((hi&1)<<11)|(lo>>21);
+ }
+ }
+ else { //if bit 38 is not set then 37 bit format is used
+ fmtLen= 37;
+ fc =0;
+ cardnum=0;
+ if(fmtLen==37){
+ cardnum = (lo>>1)&0x7FFFF;
+ fc = ((hi&0xF)<<12)|(lo>>20);
+ }
}
PrintAndLog("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);
+ (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
+ (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
setDemodBuf(BitStream,BitLen);
- return 1;
- }
- return 0;
+ return 1;
+ }
+ return 0;
}
//by marshmellow
//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
+ //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) return 0;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ //something in graphbuffer
+ if (GraphTraceLen < 65) return 0;
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
- //get binary from fsk wave
- // PrintAndLog("DEBUG: got buff");
+ //get binary from fsk wave
+ // PrintAndLog("DEBUG: got buff");
idx = IOdemodFSK(BitStream,BitLen);
- if (idx<0){
- //PrintAndLog("Error demoding fsk");
- return 0;
- }
- // PrintAndLog("DEBUG: Got IOdemodFSK");
- if (idx==0){
- //PrintAndLog("IO Prox Data not found - FSK Data:");
- //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) 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]);
+ if (idx<0){
+ //PrintAndLog("Error demoding fsk");
+ return 0;
+ }
+ // PrintAndLog("DEBUG: Got IOdemodFSK");
+ if (idx==0){
+ //PrintAndLog("IO Prox Data not found - FSK Data:");
+ //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) 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]);
+ 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 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 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);
int i;
for (i=0;i<64;++i)
DemodBuffer[i]=BitStream[idx++];
DemodBufferLen=64;
- return 1;
+ 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; //if highlen > lowLen then highlen else 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);
+ 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];
bits[sizeof(bits)-1] = '\0';
- // 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;
+ // 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;
}
int CmdDetectNRZpskClockRate(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[40000];
-
- sscanf(Cmd, "%i %i", &requested, &offset);
-
- /* if no args send something */
- if (requested == 0) {
- requested = 8;
- }
- if (offset + requested > sizeof(got)) {
- PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
- return 0;
+ int i, j;
+ int requested = 0;
+ int offset = 0;
+ char string_buf[25];
+ char* string_ptr = string_buf;
+ uint8_t got[40000];
+
+ sscanf(Cmd, "%i %i", &requested, &offset);
+
+ /* if no args send something */
+ if (requested == 0) {
+ requested = 8;
+ }
+ if (offset + requested > sizeof(got)) {
+ PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
+ 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';
+ }
}
-
- 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;
+ return 0;
}
int CmdHide(const char *Cmd)
{
- HideGraphWindow();
- return 0;
+ HideGraphWindow();
+ return 0;
}
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;
}
int CmdSamples(const char *Cmd)
n = sizeof(got);
PrintAndLog("Reading %d samples from device memory\n", n);
- GetFromBigBuf(got,n,0);
- WaitForResponse(CMD_ACK,NULL);
+ GetFromBigBuf(got,n,0);
+ WaitForResponse(CMD_ACK,NULL);
for (int j = 0; j < n; j++) {
GraphBuffer[j] = ((int)got[j]) - 128;
- }
- GraphTraceLen = n;
- RepaintGraphWindow();
- return 0;
+ }
+ GraphTraceLen = n;
+ RepaintGraphWindow();
+ return 0;
}
int CmdTuneSamples(const char *Cmd)
GraphBuffer[i] = resp.d.asBytes[i] - 128;
}
- PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n");
- PrintAndLog("\n");
+ PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n");
+ PrintAndLog("\n");
GraphTraceLen = 256;
ShowGraphWindow();
int CmdLoad(const char *Cmd)
{
- FILE *f = fopen(Cmd, "r");
- if (!f) {
- PrintAndLog("couldn't open '%s'", Cmd);
- 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;
+ 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);
+
+ 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;
}
int CmdRtrim(const char *Cmd)
{
- int ds = atoi(Cmd);
+ int ds = atoi(Cmd);
- GraphTraceLen = ds;
+ GraphTraceLen = ds;
- RepaintGraphWindow();
- return 0;
+ RepaintGraphWindow();
+ return 0;
}
/*
*/
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 = GetClock(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 = GetClock(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;
-
- /* Get our clock */
- clock = GetClock(Cmd, 0, 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;
-
- /* Keep track of how we start our wave and if we changed or not this time */
- wave ^= bit ^ lastbit;
- lastbit = bit;
- }
-
- RepaintGraphWindow();
- return 0;
+ int i, j;
+ int clock;
+ int bit, lastbit, wave;
+
+ /* Get our clock */
+ clock = GetClock(Cmd, 0, 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;
+
+ /* Keep track of how we start our wave and if we changed or not this time */
+ wave ^= bit ^ lastbit;
+ lastbit = bit;
+ }
+
+ RepaintGraphWindow();
+ return 0;
}
int CmdNorm(const char *Cmd)
{
- 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];
- }
-
- if (max != min) {
- for (i = 0; i < GraphTraceLen; ++i) {
+ 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];
+ }
+
+ 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)
{
- FILE *f = fopen(Cmd, "w");
- if(!f) {
- PrintAndLog("couldn't open '%s'", Cmd);
- 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;
+ 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);
+
+
+ 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);
-
- for (int i = 0; i < GraphTraceLen; ++i) {
- if (GraphBuffer[i] >= threshold)
- GraphBuffer[i] = 1;
- else
- GraphBuffer[i] = -1;
- }
- RepaintGraphWindow();
- return 0;
+ 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;
}
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;
+ 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"},
+ {"help", CmdHelp, 1, "This help"},
+ {"amp", CmdAmp, 1, "Amplify peaks"},
+ {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
{"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"},
{"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"},
- {"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
- {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"},
- {"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"},
+ {"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
+ {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"},
+ {"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, "Detect ASK clock rate"},
- {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},
- {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"},
- {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"},
+ {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},
+ {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"},
+ {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"},
{"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
- {"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
+ {"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
- {"hide", CmdHide, 1, "Hide graph window"},
- {"hpf", CmdHpf, 1, "Remove DC offset from trace"},
- {"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},
- {"ltrim", CmdLtrim, 1, "<samples> -- Trim samples from left of trace"},
- {"rtrim", CmdRtrim, 1, "<location to end trace> -- 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 already in graph buffer"},
- {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"},
+ {"hide", CmdHide, 1, "Hide graph window"},
+ {"hpf", CmdHpf, 1, "Remove DC offset from trace"},
+ {"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},
+ {"ltrim", CmdLtrim, 1, "<samples> -- Trim samples from left of trace"},
+ {"rtrim", CmdRtrim, 1, "<location to end trace> -- 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 already in graph buffer"},
+ {"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)"},
+ {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
{"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"},
{"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
{"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"},
{"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"},
- {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"},
- {"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
- {"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
- {"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
+ {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"},
+ {"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
+ {"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
+ {"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
{"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
{"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"},
- {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"},
- {NULL, NULL, 0, NULL}
+ {"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;
}
// Rough guess that this is a command from the reader
// For iClass the command byte is not part of the CRC
ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
- }
- else {
+ } else {
// For other data.. CRC might not be applicable (UPDATE commands etc.)
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
}
}
}
}
-
}
char *crc = crcError ? "!crc" :" ";
if(!isResponse)
{
- if(iclass) annotateIclass(explanation,sizeof(explanation),frame,data_len);
- else annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
+ if(iclass)
+ annotateIclass(explanation,sizeof(explanation),frame,data_len);
+ else
+ annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
}
int num_lines = (data_len - 1)/16 + 1;
static int CmdHelp(const char *Cmd);
static void waitCmd(uint8_t iLen);
+// structure and database for uid -> tagtype lookups
+typedef struct {
+ uint8_t uid;
+ char* desc;
+} manufactureName;
+
+const manufactureName manufactureMapping[] = {
+ // ID, "Vendor Country"
+ { 0x01, "Motorola UK" },
+ { 0x02, "ST Microelectronics SA France" },
+ { 0x03, "Hitachi, Ltd Japan" },
+ { 0x04, "NXP Semiconductors Germany" },
+ { 0x05, "Infineon Technologies AG Germany" },
+ { 0x06, "Cylink USA" },
+ { 0x07, "Texas Instrument France" },
+ { 0x08, "Fujitsu Limited Japan" },
+ { 0x09, "Matsushita Electronics Corporation, Semiconductor Company Japan" },
+ { 0x0A, "NEC Japan" },
+ { 0x0B, "Oki Electric Industry Co. Ltd Japan" },
+ { 0x0C, "Toshiba Corp. Japan" },
+ { 0x0D, "Mitsubishi Electric Corp. Japan" },
+ { 0x0E, "Samsung Electronics Co. Ltd Korea" },
+ { 0x0F, "Hynix / Hyundai, Korea" },
+ { 0x10, "LG-Semiconductors Co. Ltd Korea" },
+ { 0x11, "Emosyn-EM Microelectronics USA" },
+ { 0x12, "INSIDE Technology France" },
+ { 0x13, "ORGA Kartensysteme GmbH Germany" },
+ { 0x14, "SHARP Corporation Japan" },
+ { 0x15, "ATMEL France" },
+ { 0x16, "EM Microelectronic-Marin SA Switzerland" },
+ { 0x17, "KSW Microtec GmbH Germany" },
+ { 0x18, "ZMD AG Germany" },
+ { 0x19, "XICOR, Inc. USA" },
+ { 0x1A, "Sony Corporation Japan Identifier Company Country" },
+ { 0x1B, "Malaysia Microelectronic Solutions Sdn. Bhd Malaysia" },
+ { 0x1C, "Emosyn USA" },
+ { 0x1D, "Shanghai Fudan Microelectronics Co. Ltd. P.R. China" },
+ { 0x1E, "Magellan Technology Pty Limited Australia" },
+ { 0x1F, "Melexis NV BO Switzerland" },
+ { 0x20, "Renesas Technology Corp. Japan" },
+ { 0x21, "TAGSYS France" },
+ { 0x22, "Transcore USA" },
+ { 0x23, "Shanghai belling corp., ltd. China" },
+ { 0x24, "Masktech Germany Gmbh Germany" },
+ { 0x25, "Innovision Research and Technology Plc UK" },
+ { 0x26, "Hitachi ULSI Systems Co., Ltd. Japan" },
+ { 0x27, "Cypak AB Sweden" },
+ { 0x28, "Ricoh Japan" },
+ { 0x29, "ASK France" },
+ { 0x2A, "Unicore Microsystems, LLC Russian Federation" },
+ { 0x2B, "Dallas Semiconductor/Maxim USA" },
+ { 0x2C, "Impinj, Inc. USA" },
+ { 0x2D, "RightPlug Alliance USA" },
+ { 0x2E, "Broadcom Corporation USA" },
+ { 0x2F, "MStar Semiconductor, Inc Taiwan, ROC" },
+ { 0x30, "BeeDar Technology Inc. USA" },
+ { 0x31, "RFIDsec Denmark" },
+ { 0x32, "Schweizer Electronic AG Germany" },
+ { 0x33, "AMIC Technology Corp Taiwan" },
+ { 0x34, "Mikron JSC Russia" },
+ { 0x35, "Fraunhofer Institute for Photonic Microsystems Germany" },
+ { 0x36, "IDS Microchip AG Switzerland" },
+ { 0x37, "Kovio USA" },
+ { 0x38, "HMT Microelectronic Ltd Switzerland Identifier Company Country" },
+ { 0x39, "Silicon Craft Technology Thailand" },
+ { 0x3A, "Advanced Film Device Inc. Japan" },
+ { 0x3B, "Nitecrest Ltd UK" },
+ { 0x3C, "Verayo Inc. USA" },
+ { 0x3D, "HID Global USA" },
+ { 0x3E, "Productivity Engineering Gmbh Germany" },
+ { 0x3F, "Austriamicrosystems AG (reserved) Austria" },
+ { 0x40, "Gemalto SA France" },
+ { 0x41, "Renesas Electronics Corporation Japan" },
+ { 0x42, "3Alogics Inc Korea" },
+ { 0x43, "Top TroniQ Asia Limited Hong Kong" },
+ { 0x44, "Gentag Inc (USA) USA" },
+ { 0x00, "no tag-info available" } // must be the last entry
+};
+
+
+// get a product description based on the UID
+// uid[8] tag uid
+// returns description of the best match
+char* getTagInfo(uint8_t uid) {
+
+ int i, best = -1;
+ int len = sizeof(manufactureMapping) / sizeof(manufactureName);
+
+ for ( i = 0; i < len; ++i ) {
+ if ( uid == manufactureMapping[i].uid) {
+ if (best == -1) {
+ best = i;
+ }
+ }
+ }
+
+ if (best>=0) return manufactureMapping[best].desc;
+
+ return manufactureMapping[i].desc;
+}
+
int CmdHF14AList(const char *Cmd)
{
PrintAndLog("Deprecated command, use 'hf list 14a' instead");
PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen));
PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
+ // Double & triple sized UID, can be mapped to a manufacturer.
+ // HACK: does this apply for Ultralight cards?
+ if ( card.uidlen > 4 ) {
+ PrintAndLog("MANUFACTURER : %s", getTagInfo(card.uid[0]));
+ }
+
switch (card.sak) {
case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break;
case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break;
default: ;
}
-
// try to request ATS even if tag claims not to support it
if (select_status == 2) {
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
card.ats_len = resp.arg[0]; // note: ats_len includes CRC Bytes
}
- // disconnect
- c.arg[0] = 0;
- c.arg[1] = 0;
- c.arg[2] = 0;
- SendCommand(&c);
-
-
if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
bool ta1 = 0, tb1 = 0, tc1 = 0;
int pos;
PrintAndLog("proprietary non iso14443-4 card found, RATS not supported");
}
+
+ // try to see if card responses to "chinese magic backdoor" commands.
+ c.cmd = CMD_MIFARE_CIDENT;
+ c.arg[0] = 0;
+ c.arg[1] = 0;
+ c.arg[2] = 0;
+ SendCommand(&c);
+ WaitForResponse(CMD_ACK,&resp);
+ uint8_t isOK = resp.arg[0] & 0xff;
+ PrintAndLog(" Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
+
+ // disconnect
+ c.cmd = CMD_READER_ISO_14443a;
+ c.arg[0] = 0;
+ c.arg[1] = 0;
+ c.arg[2] = 0;
+ SendCommand(&c);
+
return select_status;
}
uint8_t active=0;
uint8_t active_select=0;
uint16_t numbits=0;
+ uint16_t timeout=0;
+ uint8_t bTimeout=0;
char buf[5]="";
int i=0;
- uint8_t data[100];
+ uint8_t data[USB_CMD_DATA_SIZE];
unsigned int datalen=0, temp;
if (strlen(cmd)<2) {
- PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] <number of bits> <0A 0B 0C ... hex>");
+ PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] [-t] <number of bits> <0A 0B 0C ... hex>");
PrintAndLog(" -r do not read response");
PrintAndLog(" -c calculate and append CRC");
PrintAndLog(" -p leave the signal field ON after receive");
PrintAndLog(" -a active signal field ON without select");
PrintAndLog(" -s active signal field ON with select");
PrintAndLog(" -b number of bits to send. Useful for send partial byte");
+ PrintAndLog(" -t timeout");
return 0;
}
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
i-=2;
break;
+ case 't':
+ bTimeout=1;
+ sscanf(cmd+i+2,"%d",&temp);
+ timeout = temp & 0xFFFF;
+ i+=3;
+ while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
+ i+=2;
+ break;
default:
PrintAndLog("Invalid option");
return 0;
if (strlen(buf)>=2) {
sscanf(buf,"%x",&temp);
data[datalen]=(uint8_t)(temp & 0xff);
- datalen++;
*buf=0;
+ if (++datalen>sizeof(data)){
+ if (crc)
+ PrintAndLog("Buffer is full, we can't add CRC to your data");
+ break;
+ }
}
continue;
}
PrintAndLog("Invalid char on input");
return 0;
}
- if(crc && datalen>0)
+ if(crc && datalen>0 && datalen<sizeof(data)-2)
{
uint8_t first, second;
ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
if(active)
c.arg[0] |= ISO14A_NO_SELECT;
}
+ if(bTimeout){
+ #define MAX_TIMEOUT 624*105 // max timeout is 624 ms
+ c.arg[0] |= ISO14A_SET_TIMEOUT;
+ c.arg[2] = timeout * 105; // each bit is about 9.4 us
+ if(c.arg[2]>MAX_TIMEOUT) {
+ c.arg[2] = MAX_TIMEOUT;
+ PrintAndLog("Set timeout to 624 ms. The max we can wait for response");
+ }
+ }
if(power)
c.arg[0] |= ISO14A_NO_DISCONNECT;
if(datalen>0)
c.arg[0] |= ISO14A_RAW;
- c.arg[1] = datalen;
- c.arg[2] = numbits;
+ // Max buffer is USB_CMD_DATA_SIZE
+ c.arg[1] = (datalen & 0xFFFF) | (numbits << 16);
memcpy(c.d.asBytes,data,datalen);
SendCommand(&c);
UsbCommand resp;
char *hexout;
- if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
recv = resp.d.asBytes;
uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0];
PrintAndLog("received %i octets",iLen);
int CmdHF14ASim(const char *Cmd);
int CmdHF14ASnoop(const char *Cmd);
+char* getTagInfo(uint8_t uid);
#endif
#include "cmdhf14b.h"
#include "cmdmain.h"
-
static int CmdHelp(const char *Cmd);
int CmdHF14BDemod(const char *Cmd)
int CmdHF14BList(const char *Cmd)
{
- uint8_t got[960];
+ uint8_t got[TRACE_BUFFER_SIZE];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
int prev = -1;
for(;;) {
- if(i >= 900) {
- break;
- }
+
+ if(i >= TRACE_BUFFER_SIZE) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if(len > 100) {
break;
}
- if(i + len >= 900) {
+ if(i + len >= TRACE_BUFFER_SIZE) {
break;
}
bool isSrix4k = true;
char str[20];
- if (cmdp == 'h' || cmdp == 'H') {
+ if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
- PrintAndLog("");
- PrintAndLog(" sample: hf 14b write 1 127 11223344");
- PrintAndLog(" sample: hf 14b write 1 255 11223344");
- PrintAndLog(" sample: hf 14b write 2 15 11223344");
- PrintAndLog(" sample: hf 14b write 2 255 11223344");
+ PrintAndLog(" [1 = SRIX4K]");
+ PrintAndLog(" [2 = SRI512]");
+ PrintAndLog(" [BLOCK number depends on tag, special block == FF]");
+ PrintAndLog(" sample: hf 14b write 1 7F 11223344");
+ PrintAndLog(" : hf 14b write 1 FF 11223344");
+ PrintAndLog(" : hf 14b write 2 15 11223344");
+ PrintAndLog(" : hf 14b write 2 FF 11223344");
return 0;
}
- if ( param_getchar(Cmd, 0) == '2' )
+ if ( cmdp == '2' )
isSrix4k = false;
- blockno = param_get8(Cmd, 1);
+ //blockno = param_get8(Cmd, 1);
+
+ if ( param_gethex(Cmd,1, &blockno, 2) ) {
+ PrintAndLog("Block number must include 2 HEX symbols");
+ return 0;
+ }
if ( isSrix4k ){
if ( blockno > 0x7f && blockno != 0xff ){
}
if ( blockno == 0xff)
- PrintAndLog("Writing to special block %02X [ %s]", blockno, sprint_hex(data,4) );
+ PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
else
- PrintAndLog("Writing to block %02X [ %s]", blockno, sprint_hex(data,4) );
+ PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
sprintf(str, "-c -p 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
+
CmdHF14BCmdRaw(str);
return 0;
}
const productName uidmapping[] = {
+
// UID, #significant Bits, "Vendor(+Product)"
- { 0xE001000000000000LL, 16, "Motorola" },
- { 0xE002000000000000LL, 16, "ST Microelectronics" },
- { 0xE003000000000000LL, 16, "Hitachi" },
- { 0xE004000000000000LL, 16, "NXP(Philips)" },
+ { 0xE001000000000000LL, 16, "Motorola UK" },
+
+ // E0 02 xx
+ // 02 = ST Microelectronics
+ // XX = IC id (Chip ID Family)
+ { 0xE002000000000000LL, 16, "ST Microelectronics SA France" },
+ { 0xE002050000000000LL, 24, "ST Microelectronics; LRI64 [IC id = 05]"},
+ { 0xE002080000000000LL, 24, "ST Microelectronics; LRI2K [IC id = 08]"},
+ { 0xE0020A0000000000LL, 24, "ST Microelectronics; LRIS2K [IC id = 10]"},
+ { 0xE002440000000000LL, 24, "ST Microelectronics; LRIS64K [IC id = 68]"},
+
+ { 0xE003000000000000LL, 16, "Hitachi, Ltd Japan" },
+
+ // E0 04 xx
+ // 04 = Manufacturer code (Philips/NXP)
+ // XX = IC id (Chip ID Family)
+ //I-Code SLI SL2 ICS20 [IC id = 01]
+ //I-Code SLI-S [IC id = 02]
+ //I-Code SLI-L [IC id = 03]
+ //I-Code SLIX [IC id = 01 + bit36 set to 1 (starting from bit0 - different from normal SLI)]
+ //I-Code SLIX-S [IC id = 02 + bit36 set to 1]
+ //I-Code SLIX-L [IC id = 03 + bit36 set to 1]
+ { 0xE004000000000000LL, 16, "NXP Semiconductors Germany (Philips)" },
{ 0xE004010000000000LL, 24, "NXP(Philips); IC SL2 ICS20/ICS21(SLI) ICS2002/ICS2102(SLIX)" },
{ 0xE004020000000000LL, 24, "NXP(Philips); IC SL2 ICS53/ICS54(SLI-S) ICS5302/ICS5402(SLIX-S)" },
{ 0xE004030000000000LL, 24, "NXP(Philips); IC SL2 ICS50/ICS51(SLI-L) ICS5002/ICS5102(SLIX-L)" },
- { 0xE005000000000000LL, 16, "Infineon" },
- { 0xE005400000000000LL, 24, "Infineon; 56x32bit" },
- { 0xE006000000000000LL, 16, "Cylinc" },
- { 0xE007000000000000LL, 16, "Texas Instrument; " },
+
+ // E0 05 XX .. .. ..
+ // 05 = Manufacturer code (Infineon)
+ // XX = IC id (Chip ID Family)
+ { 0xE005000000000000LL, 16, "Infineon Technologies AG Germany" },
+ { 0xE005A10000000000LL, 24, "Infineon; SRF55V01P [IC id = 161] plain mode 1kBit"},
+ { 0xE005A80000000000LL, 24, "Infineon; SRF55V01P [IC id = 168] pilot series 1kBit"},
+ { 0xE005400000000000LL, 24, "Infineon; SRF55V02P [IC id = 64] plain mode 2kBit"},
+ { 0xE005000000000000LL, 24, "Infineon; SRF55V10P [IC id = 00] plain mode 10KBit"},
+ { 0xE005500000000000LL, 24, "Infineon; SRF55V02S [IC id = 80] secure mode 2kBit"},
+ { 0xE005100000000000LL, 24, "Infineon; SRF55V10S [IC id = 16] secure mode 10KBit"},
+ { 0xE0051E0000000000LL, 23, "Infineon; SLE66r01P [IC id = 3x = My-d Move or My-d move NFC]"},
+ { 0xE005200000000000LL, 21, "Infineon; SLE66r01P [IC id = 3x = My-d Move or My-d move NFC]"},
+
+ { 0xE006000000000000LL, 16, "Cylink USA" },
+
+
+ // E0 07 xx
+ // 07 = Texas Instruments
+ // XX = from bit 41 to bit 43 = product configuration - from bit 44 to bit 47 IC id (Chip ID Family)
+ //Tag IT RFIDType-I Plus, 2kBit, TI Inlay
+ //Tag-it HF-I Plus Inlay [IC id = 00] -> b'0000 000 2kBit
+ //Tag-it HF-I Plus Chip [IC id = 64] -> b'1000 000 2kBit
+ //Tag-it HF-I Standard Chip / Inlays [IC id = 96] -> b'1100 000 256Bit
+ //Tag-it HF-I Pro Chip / Inlays [IC id = 98] -> b'1100 010 256Bit, Password protection
+ { 0xE007000000000000LL, 16, "Texas Instrument France" },
{ 0xE007000000000000LL, 20, "Texas Instrument; Tag-it HF-I Plus Inlay; 64x32bit" },
{ 0xE007100000000000LL, 20, "Texas Instrument; Tag-it HF-I Plus Chip; 64x32bit" },
{ 0xE007800000000000LL, 23, "Texas Instrument; Tag-it HF-I Plus (RF-HDT-DVBB tag or Third Party Products)" },
{ 0xE007C00000000000LL, 23, "Texas Instrument; Tag-it HF-I Standard; 8x32bit" },
{ 0xE007C40000000000LL, 23, "Texas Instrument; Tag-it HF-I Pro; 8x23bit; password" },
- { 0xE008000000000000LL, 16, "Fujitsu" },
- { 0xE009000000000000LL, 16, "Matsushita" },
- { 0xE00A000000000000LL, 16, "NEC" },
- { 0xE00B000000000000LL, 16, "Oki Electric" },
- { 0xE00C000000000000LL, 16, "Toshiba" },
- { 0xE00D000000000000LL, 16, "Mitsubishi" },
- { 0xE00E000000000000LL, 16, "Samsung" },
- { 0xE00F000000000000LL, 16, "Hyundai" },
- { 0xE010000000000000LL, 16, "LG-Semiconductors" },
+
+ { 0xE008000000000000LL, 16, "Fujitsu Limited Japan" },
+ { 0xE009000000000000LL, 16, "Matsushita Electronics Corporation, Semiconductor Company Japan" },
+ { 0xE00A000000000000LL, 16, "NEC Japan" },
+ { 0xE00B000000000000LL, 16, "Oki Electric Industry Co. Ltd Japan" },
+ { 0xE00C000000000000LL, 16, "Toshiba Corp. Japan" },
+ { 0xE00D000000000000LL, 16, "Mitsubishi Electric Corp. Japan" },
+ { 0xE00E000000000000LL, 16, "Samsung Electronics Co. Ltd Korea" },
+ { 0xE00F000000000000LL, 16, "Hynix / Hyundai, Korea" },
+ { 0xE010000000000000LL, 16, "LG-Semiconductors Co. Ltd Korea" },
+ { 0xE011000000000000LL, 16, "Emosyn-EM Microelectronics USA" },
+
{ 0xE012000000000000LL, 16, "HID Corporation" },
- { 0xE016000000000000LL, 16, "EM-Marin SA (Skidata)" },
+ { 0xE012000000000000LL, 16, "INSIDE Technology France" },
+ { 0xE013000000000000LL, 16, "ORGA Kartensysteme GmbH Germany" },
+ { 0xE014000000000000LL, 16, "SHARP Corporation Japan" },
+ { 0xE015000000000000LL, 16, "ATMEL France" },
+
+ { 0xE016000000000000LL, 16, "EM Microelectronic-Marin SA Switzerland (Skidata)" },
{ 0xE016040000000000LL, 24, "EM-Marin SA (Skidata Keycard-eco); EM4034? no 'read', just 'readmulti'" },
{ 0xE0160c0000000000LL, 24, "EM-Marin SA; EM4035?" },
{ 0xE016100000000000LL, 24, "EM-Marin SA (Skidata); EM4135; 36x64bit start page 13" },
{ 0xE016940000000000LL, 24, "EM-Marin SA (Skidata); 51x64bit" },
+
+ { 0xE017000000000000LL, 16, "KSW Microtec GmbH Germany" },
+ { 0xE018000000000000LL, 16, "ZMD AG Germany" },
+ { 0xE019000000000000LL, 16, "XICOR, Inc. USA" },
+ { 0xE01A000000000000LL, 16, "Sony Corporation Japan Identifier Company Country" },
+ { 0xE01B000000000000LL, 16, "Malaysia Microelectronic Solutions Sdn. Bhd Malaysia" },
+ { 0xE01C000000000000LL, 16, "Emosyn USA" },
+ { 0xE01D000000000000LL, 16, "Shanghai Fudan Microelectronics Co. Ltd. P.R. China" },
+ { 0xE01E000000000000LL, 16, "Magellan Technology Pty Limited Australia" },
+ { 0xE01F000000000000LL, 16, "Melexis NV BO Switzerland" },
+ { 0xE020000000000000LL, 16, "Renesas Technology Corp. Japan" },
+ { 0xE021000000000000LL, 16, "TAGSYS France" },
+ { 0xE022000000000000LL, 16, "Transcore USA" },
+ { 0xE023000000000000LL, 16, "Shanghai belling corp., ltd. China" },
+ { 0xE024000000000000LL, 16, "Masktech Germany Gmbh Germany" },
+ { 0xE025000000000000LL, 16, "Innovision Research and Technology Plc UK" },
+ { 0xE026000000000000LL, 16, "Hitachi ULSI Systems Co., Ltd. Japan" },
+ { 0xE027000000000000LL, 16, "Cypak AB Sweden" },
+ { 0xE028000000000000LL, 16, "Ricoh Japan" },
+ { 0xE029000000000000LL, 16, "ASK France" },
+ { 0xE02A000000000000LL, 16, "Unicore Microsystems, LLC Russian Federation" },
+ { 0xE02B000000000000LL, 16, "Dallas Semiconductor/Maxim USA" },
+ { 0xE02C000000000000LL, 16, "Impinj, Inc. USA" },
+ { 0xE02D000000000000LL, 16, "RightPlug Alliance USA" },
+ { 0xE02E000000000000LL, 16, "Broadcom Corporation USA" },
+ { 0xE02F000000000000LL, 16, "MStar Semiconductor, Inc Taiwan, ROC" },
+ { 0xE030000000000000LL, 16, "BeeDar Technology Inc. USA" },
+ { 0xE031000000000000LL, 16, " RFIDsec Denmark" },
+ { 0xE032000000000000LL, 16, " Schweizer Electronic AG Germany" },
+ { 0xE033000000000000LL, 16, " AMIC Technology Corp Taiwan" },
+ { 0xE034000000000000LL, 16, "Mikron JSC Russia" },
+ { 0xE035000000000000LL, 16, "Fraunhofer Institute for Photonic Microsystems Germany" },
+ { 0xE036000000000000LL, 16, "IDS Microchip AG Switzerland" },
+ { 0xE037000000000000LL, 16, "Kovio USA" },
+ { 0xE038000000000000LL, 16, "HMT Microelectronic Ltd Switzerland Identifier Company Country" },
+ { 0xE039000000000000LL, 16, "Silicon Craft Technology Thailand" },
+ { 0xE03A000000000000LL, 16, "Advanced Film Device Inc. Japan" },
+ { 0xE03B000000000000LL, 16, "Nitecrest Ltd UK" },
+ { 0xE03C000000000000LL, 16, "Verayo Inc. USA" },
+ { 0xE03D000000000000LL, 16, "HID Global USA" },
+ { 0xE03E000000000000LL, 16, "Productivity Engineering Gmbh Germany" },
+ { 0xE03F000000000000LL, 16, "Austriamicrosystems AG (reserved) Austria" },
+ { 0xE040000000000000LL, 16, "Gemalto SA France" },
+ { 0xE041000000000000LL, 16, "Renesas Electronics Corporation Japan" },
+ { 0xE042000000000000LL, 16, "3Alogics Inc Korea" },
+ { 0xE043000000000000LL, 16, "Top TroniQ Asia Limited Hong Kong" },
+ { 0xE044000000000000LL, 16, "Gentag Inc (USA) USA" },
{ 0,0,"no tag-info available" } // must be the last entry
};
int CmdLegicLoad(const char *Cmd)
{
- FILE *f = fopen(Cmd, "r");
+ char filename[FILE_PATH_SIZE] = {0x00};
+ int len = 0;
+
+ if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
+ PrintAndLog("It loads datasamples from the file `filename`");
+ PrintAndLog("Usage: hf legic load <file name>");
+ PrintAndLog(" sample: hf legic load filename");
+ return 0;
+ }
+
+ len = strlen(Cmd);
+ if (len > FILE_PATH_SIZE) {
+ PrintAndLog("Filepath too long (was %s bytes), max allowed is %s ", len, FILE_PATH_SIZE);
+ return 0;
+ }
+ memcpy(filename, Cmd, len);
+
+ FILE *f = fopen(filename, "r");
if(!f) {
PrintAndLog("couldn't open '%s'", Cmd);
return -1;
int requested = 1024;
int offset = 0;
int delivered = 0;
- char filename[1024];
+ char filename[FILE_PATH_SIZE];
uint8_t got[1024];
sscanf(Cmd, " %s %i %i", filename, &requested, &offset);
if (isOK != 1) return 1;\r
\r
// execute original function from util nonce2key\r
- if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key))\r
- {\r
+ if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) {\r
isOK = 2;\r
PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt); \r
} else {\r
return 2;\r
}\r
}\r
+ \r
fclose(fin);\r
- // Read access rights to sectors\r
\r
PrintAndLog("|-----------------------------------------|");\r
PrintAndLog("|------ Reading sector access bits...-----|");\r
}\r
}\r
\r
- // Read blocks and print to file\r
- \r
PrintAndLog("|-----------------------------------------|");\r
PrintAndLog("|----- Dumping all blocks to file... -----|");\r
PrintAndLog("|-----------------------------------------|");\r
{\r
uint8_t sectorNo,blockNo;\r
uint8_t keyType = 0;\r
- uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r
- uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\r
+ uint8_t key[6] = {0xFF};\r
+ uint8_t bldata[16] = {0x00};\r
uint8_t keyA[40][6];\r
uint8_t keyB[40][6];\r
uint8_t numSectors;\r
return 0;\r
}\r
\r
- if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {\r
- PrintAndLog("Could not find file dumpdata.bin");\r
- return 1;\r
- }\r
if ((fkeys = fopen("dumpkeys.bin","rb")) == NULL) {\r
PrintAndLog("Could not find file dumpkeys.bin");\r
- fclose(fdump);\r
return 1;\r
}\r
\r
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
if (fread(keyA[sectorNo], 1, 6, fkeys) == 0) {\r
PrintAndLog("File reading error (dumpkeys.bin).");\r
- fclose(fdump);\r
- fclose(fkeys);\r
return 2;\r
}\r
}\r
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
if (fread(keyB[sectorNo], 1, 6, fkeys) == 0) {\r
PrintAndLog("File reading error (dumpkeys.bin).");\r
- fclose(fdump);\r
- fclose(fkeys);\r
return 2;\r
}\r
}\r
+\r
fclose(fkeys);\r
\r
+ if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {\r
+ PrintAndLog("Could not find file dumpdata.bin");\r
+ return 1;\r
+ } \r
PrintAndLog("Restoring dumpdata.bin to card");\r
\r
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
uint8_t trgKeyType = 0;\r
uint8_t SectorsCnt = 0;\r
uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
- uint8_t keyBlock[6*6];\r
+ uint8_t keyBlock[13*6];\r
uint64_t key64 = 0;\r
bool transferToEml = false;\r
\r
cmdp = param_getchar(Cmd, 0);\r
blockNo = param_get8(Cmd, 1);\r
ctmp = param_getchar(Cmd, 2);\r
+ \r
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
PrintAndLog("Key type must be A or B");\r
return 1;\r
}\r
- if (ctmp != 'A' && ctmp != 'a') keyType = 1;\r
+ \r
+ if (ctmp != 'A' && ctmp != 'a') \r
+ keyType = 1;\r
+ \r
if (param_gethex(Cmd, 3, key, 12)) {\r
PrintAndLog("Key must include 12 HEX symbols");\r
return 1;\r
PrintAndLog("Target key type must be A or B");\r
return 1;\r
}\r
- if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1;\r
+ if (ctmp != 'A' && ctmp != 'a') \r
+ trgKeyType = 1;\r
} else {\r
+ \r
switch (cmdp) {\r
case '0': SectorsCnt = 05; break;\r
case '1': SectorsCnt = 16; break;\r
num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 3 * 6));\r
num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 4 * 6));\r
num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));\r
+ num_to_bytes(0x4d3a99c351dd, 6, (uint8_t*)(keyBlock + 6 * 6));\r
+ num_to_bytes(0x1a982c7e459a, 6, (uint8_t*)(keyBlock + 7 * 6));\r
+ num_to_bytes(0xd3f7d3f7d3f7, 6, (uint8_t*)(keyBlock + 8 * 6));\r
+ num_to_bytes(0x714c5c886e97, 6, (uint8_t*)(keyBlock + 9 * 6));\r
+ num_to_bytes(0x587ee5f9350f, 6, (uint8_t*)(keyBlock + 10 * 6));\r
+ num_to_bytes(0xa0478cc39091, 6, (uint8_t*)(keyBlock + 11 * 6));\r
+ num_to_bytes(0x533cb6c723f6, 6, (uint8_t*)(keyBlock + 12 * 6));\r
+ num_to_bytes(0x8fd0a4f256e9, 6, (uint8_t*)(keyBlock + 13 * 6));\r
\r
PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);\r
for (i = 0; i < SectorsCnt; i++) {\r
}\r
}\r
\r
- \r
// nested sectors\r
iterations = 0;\r
PrintAndLog("nested...");\r
if(mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate)) {\r
PrintAndLog("Nested error.\n");\r
free(e_sector);\r
- return 2;\r
- }\r
+ return 2; }\r
else {\r
calibrate = false;\r
}\r
} \r
\r
FILE * f;\r
- char filename[256]={0};\r
+ char filename[FILE_PATH_SIZE]={0};\r
char buf[13];\r
uint8_t *keyBlock = NULL, *p;\r
uint8_t stKeyBlock = 20;\r
keycnt++;\r
} else {\r
// May be a dic file\r
- if ( param_getstr(Cmd, 2 + i,filename) > 255 ) {\r
+ if ( param_getstr(Cmd, 2 + i,filename) >= FILE_PATH_SIZE ) {\r
PrintAndLog("File name too long");\r
free(keyBlock);\r
return 2;\r
int CmdHF14AMfELoad(const char *Cmd)\r
{\r
FILE * f;\r
- char filename[20];\r
+ char filename[FILE_PATH_SIZE];\r
char *fnameptr = filename;\r
char buf[64];\r
uint8_t buf8[64];\r
- int i, len, blockNum;\r
+ int i, len, blockNum, numBlocks;\r
+ int nameParamNo = 1;\r
\r
memset(filename, 0, sizeof(filename));\r
memset(buf, 0, sizeof(buf));\r
\r
- if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {\r
+ char ctmp = param_getchar(Cmd, 0);\r
+ \r
+ if ( ctmp == 'h' || ctmp == 0x00) {\r
PrintAndLog("It loads emul dump from the file `filename.eml`");\r
- PrintAndLog("Usage: hf mf eload <file name w/o `.eml`>");\r
+ PrintAndLog("Usage: hf mf eload [card memory] <file name w/o `.eml`>");\r
+ PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+ PrintAndLog("");\r
PrintAndLog(" sample: hf mf eload filename");\r
+ PrintAndLog(" hf mf eload 4 filename");\r
return 0;\r
} \r
\r
- len = strlen(Cmd);\r
- if (len > 14) len = 14;\r
+ switch (ctmp) {\r
+ case '0' : numBlocks = 5*4; break;\r
+ case '1' : \r
+ case '\0': numBlocks = 16*4; break;\r
+ case '2' : numBlocks = 32*4; break;\r
+ case '4' : numBlocks = 256; break;\r
+ default: {\r
+ numBlocks = 16*4;\r
+ nameParamNo = 0;\r
+ }\r
+ }\r
+\r
+ len = param_getstr(Cmd,nameParamNo,filename);\r
+ \r
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
\r
- memcpy(filename, Cmd, len);\r
fnameptr += len;\r
\r
sprintf(fnameptr, ".eml"); \r
blockNum = 0;\r
while(!feof(f)){\r
memset(buf, 0, sizeof(buf));\r
+ \r
if (fgets(buf, sizeof(buf), f) == NULL) {\r
- if((blockNum == 16*4) || (blockNum == 32*4 + 8*16)) { // supports both old (1K) and new (4K) .eml files)\r
- break;\r
- }\r
+ \r
+ if (blockNum >= numBlocks) break;\r
+ \r
PrintAndLog("File reading error.");\r
fclose(f);\r
return 2;\r
}\r
+ \r
if (strlen(buf) < 32){\r
if(strlen(buf) && feof(f))\r
break;\r
fclose(f);\r
return 2;\r
}\r
+ \r
for (i = 0; i < 32; i += 2) {\r
sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);\r
}\r
}\r
blockNum++;\r
\r
- if (blockNum >= 32*4 + 8*16) break;\r
+ if (blockNum >= numBlocks) break;\r
}\r
fclose(f);\r
\r
- if ((blockNum != 16*4) && (blockNum != 32*4 + 8*16)) {\r
- PrintAndLog("File content error. There must be 64 or 256 blocks.");\r
+ if ((blockNum != numBlocks)) {\r
+ PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);\r
return 4;\r
}\r
PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename);\r
int CmdHF14AMfESave(const char *Cmd)\r
{\r
FILE * f;\r
- char filename[20];\r
+ char filename[FILE_PATH_SIZE];\r
char * fnameptr = filename;\r
uint8_t buf[64];\r
- int i, j, len;\r
+ int i, j, len, numBlocks;\r
+ int nameParamNo = 1;\r
\r
memset(filename, 0, sizeof(filename));\r
memset(buf, 0, sizeof(buf));\r
\r
- if (param_getchar(Cmd, 0) == 'h') {\r
+ char ctmp = param_getchar(Cmd, 0);\r
+ \r
+ if ( ctmp == 'h' || ctmp == 'H') {\r
PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");\r
- PrintAndLog("Usage: hf mf esave [file name w/o `.eml`]");\r
+ PrintAndLog(" Usage: hf mf esave [card memory] [file name w/o `.eml`]");\r
+ PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+ PrintAndLog("");\r
PrintAndLog(" sample: hf mf esave ");\r
- PrintAndLog(" hf mf esave filename");\r
+ PrintAndLog(" hf mf esave 4");\r
+ PrintAndLog(" hf mf esave 4 filename");\r
return 0;\r
} \r
\r
- len = strlen(Cmd);\r
- if (len > 14) len = 14;\r
+ switch (ctmp) {\r
+ case '0' : numBlocks = 5*4; break;\r
+ case '1' : \r
+ case '\0': numBlocks = 16*4; break;\r
+ case '2' : numBlocks = 32*4; break;\r
+ case '4' : numBlocks = 256; break;\r
+ default: {\r
+ numBlocks = 16*4;\r
+ nameParamNo = 0;\r
+ }\r
+ }\r
+\r
+ len = param_getstr(Cmd,nameParamNo,filename);\r
+ \r
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
\r
+ // user supplied filename?\r
if (len < 1) {\r
- // get filename\r
+ // get filename (UID from memory)\r
if (mfEmlGetMem(buf, 0, 1)) {\r
- PrintAndLog("Cant get block: %d", 0);\r
- return 1;\r
+ PrintAndLog("Can\'t get UID from block: %d", 0);\r
+ sprintf(filename, "dump.eml"); \r
}\r
for (j = 0; j < 7; j++, fnameptr += 2)\r
- sprintf(fnameptr, "%02x", buf[j]); \r
+ sprintf(fnameptr, "%02X", buf[j]); \r
} else {\r
- memcpy(filename, Cmd, len);\r
fnameptr += len;\r
}\r
\r
+ // add file extension\r
sprintf(fnameptr, ".eml"); \r
\r
// open file\r
f = fopen(filename, "w+");\r
\r
+ if ( !f ) {\r
+ PrintAndLog("Can't open file %s ", filename);\r
+ return 1;\r
+ }\r
+ \r
// put hex\r
- for (i = 0; i < 32*4 + 8*16; i++) {\r
+ for (i = 0; i < numBlocks; i++) {\r
if (mfEmlGetMem(buf, i, 1)) {\r
PrintAndLog("Cant get block: %d", i);\r
break;\r
}\r
fclose(f);\r
\r
- PrintAndLog("Saved to file: %s", filename);\r
+ PrintAndLog("Saved %d blocks to file: %s", numBlocks, filename);\r
\r
return 0;\r
}\r
int CmdHF14AMfEKeyPrn(const char *Cmd)\r
{\r
int i;\r
+ uint8_t numSectors;\r
uint8_t data[16];\r
uint64_t keyA, keyB;\r
\r
+ if (param_getchar(Cmd, 0) == 'h') {\r
+ PrintAndLog("It prints the keys loaded in the emulator memory");\r
+ PrintAndLog("Usage: hf mf ekeyprn [card memory]");\r
+ PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+ PrintAndLog("");\r
+ PrintAndLog(" sample: hf mf ekeyprn 1");\r
+ return 0;\r
+ } \r
+\r
+ char cmdp = param_getchar(Cmd, 0);\r
+ \r
+ switch (cmdp) {\r
+ case '0' : numSectors = 5; break;\r
+ case '1' : \r
+ case '\0': numSectors = 16; break;\r
+ case '2' : numSectors = 32; break;\r
+ case '4' : numSectors = 40; break;\r
+ default: numSectors = 16;\r
+ } \r
+ \r
PrintAndLog("|---|----------------|----------------|");\r
PrintAndLog("|sec|key A |key B |");\r
PrintAndLog("|---|----------------|----------------|");\r
- for (i = 0; i < 40; i++) {\r
+ for (i = 0; i < numSectors; i++) {\r
if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {\r
PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);\r
break;\r
int CmdHF14AMfCLoad(const char *Cmd)\r
{\r
FILE * f;\r
- char filename[20];\r
+ char filename[FILE_PATH_SIZE] = {0x00};\r
char * fnameptr = filename;\r
- char buf[64];\r
- uint8_t buf8[64];\r
+ char buf[64] = {0x00};\r
+ uint8_t buf8[64] = {0x00};\r
uint8_t fillFromEmulator = 0;\r
int i, len, blockNum, flags;\r
\r
- memset(filename, 0, sizeof(filename));\r
- memset(buf, 0, sizeof(buf));\r
+ // memset(filename, 0, sizeof(filename));\r
+ // memset(buf, 0, sizeof(buf));\r
\r
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {\r
PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`");\r
return 0;\r
} else {\r
len = strlen(Cmd);\r
- if (len > 14) len = 14;\r
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
\r
memcpy(filename, Cmd, len);\r
fnameptr += len;\r
}\r
fclose(f);\r
\r
- if (blockNum != 16 * 4){\r
+ if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){\r
PrintAndLog("File content error. There must be 64 blocks");\r
return 4;\r
}\r
int CmdHF14AMfCSave(const char *Cmd) {\r
\r
FILE * f;\r
- char filename[20];\r
+ char filename[FILE_PATH_SIZE] = {0x00};\r
char * fnameptr = filename;\r
uint8_t fillFromEmulator = 0;\r
- uint8_t buf[64];\r
+ uint8_t buf[64] = {0x00};\r
int i, j, len, flags;\r
\r
- memset(filename, 0, sizeof(filename));\r
- memset(buf, 0, sizeof(buf));\r
+ // memset(filename, 0, sizeof(filename));\r
+ // memset(buf, 0, sizeof(buf));\r
\r
if (param_getchar(Cmd, 0) == 'h') {\r
PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");\r
return 0;\r
} else {\r
len = strlen(Cmd);\r
- if (len > 14) len = 14;\r
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
\r
if (len < 1) {\r
// get filename\r
// open file\r
f = fopen(filename, "w+");\r
\r
+ if (f == NULL) {\r
+ PrintAndLog("File not found or locked.");\r
+ return 1;\r
+ }\r
+\r
// put hex\r
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;\r
for (i = 0; i < 16 * 4; i++) {\r
{"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},\r
{"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},\r
{"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"},\r
- {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block into magic Chinese card"},\r
- {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block from magic Chinese card"},\r
- {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector from magic Chinese card"},\r
+ {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"},\r
+ {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"},\r
+ {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},\r
{"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},\r
{"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},\r
{NULL, NULL, 0, NULL}\r
#include <string.h>
#include <limits.h>
#include "ui.h"
-//#include "proxusb.h"
#include "proxmark3.h"
#include "cmdparser.h"
+#include "cmddata.h"
#include "cmdhw.h"
#include "cmdmain.h"
#include "cmddata.h"
{"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},
{"setmux", CmdSetMux, 0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},
{"tune", CmdTune, 0, "Measure antenna tuning"},
- {"version", CmdVersion, 0, "Show version inforation about the connected Proxmark"},
+ {"version", CmdVersion, 0, "Show version information about the connected Proxmark"},
{NULL, NULL, 0, NULL}
};
int i;
/* convert to bitstream if necessary */
- for (i = 0; i < (int)(GraphTraceLen / 2); i++)
- {
- if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0)
- {
+ for (i = 0; i < (int)(GraphTraceLen / 2); i++){
+ if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) {
CmdBitstream(str);
break;
}
int CmdLFSim(const char *Cmd)
{
- int i;
+ int i,j;
static int gap;
sscanf(Cmd, "%i", &gap);
/* convert to bitstream if necessary */
ChkBitstream(Cmd);
- PrintAndLog("Sending data, please wait...");
- for (i = 0; i < GraphTraceLen; i += 48) {
+ 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}};
- int j;
- for (j = 0; j < 48; j++) {
+
+ for (j = 0; j < USB_CMD_DATA_SIZE; j++) {
c.d.asBytes[j] = GraphBuffer[i+j];
}
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL);
+ printf(".");
}
- PrintAndLog("Starting simulator...");
+ printf("\n");
+ PrintAndLog("Starting to simulate");
UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}};
SendCommand(&c);
return 0;
int CmdLFfind(const char *Cmd)
{
int ans=0;
- if (!offline){
+ char cmdp = param_getchar(Cmd, 0);
+
+ if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: lf search <0|1>");
+ PrintAndLog(" <use data from Graphbuffer>, if not set, try reading data from tag.");
+ PrintAndLog("");
+ PrintAndLog(" sample: lf search");
+ PrintAndLog(" : lf search 1");
+ return 0;
+ }
+
+ if (!offline || (cmdp != '1') ){
ans=CmdLFRead("");
- ans=CmdSamples("20000");
+ ans=CmdSamples("20000");
+ } else if (GraphTraceLen < 1000) {
+ PrintAndLog("Data in Graphbuffer was too small.");
+ return 0;
}
- if (GraphTraceLen<1000) return 0;
+
PrintAndLog("Checking for known tags:");
ans=Cmdaskmandemod("");
if (ans>0) return 1;
#include "cmddata.h"
#include "cmdlf.h"
#include "cmdlfem4x.h"
+char *global_em410xId;
static int CmdHelp(const char *Cmd);
parity[0] = parity[1] = parity[2] = parity[3] = 0;
header = rows = 0;
- /* manchester demodulate */
+ // manchester demodulate
bit = bit2idx = 0;
for (i = 0; i < (int)(GraphTraceLen / clock); i++)
{
/* Find out if we hit both high and low peaks */
for (j = 0; j < clock; j++)
{
- if (GraphBuffer[(i * clock) + j] == high)
+ if (GraphBuffer[(i * clock) + j] >= high)
hithigh = 1;
- else if (GraphBuffer[(i * clock) + j] == low)
+ else if (GraphBuffer[(i * clock) + j] <= low)
hitlow = 1;
/* it doesn't count if it's the first part of our read
PrintAndLog("EM410x Tag ID: %s", id);
PrintAndLog("Unique Tag ID: %s", id2);
+ global_em410xId = id;
+
/* Stop any loops */
return 1;
}
}
/* if we've already retested after flipping bits, return */
- if (retested++)
+ if (retested++){
+ PrintAndLog("Failed to decode");
return 0;
+ }
/* if this didn't work, try flipping bits */
for (i = 0; i < bit2idx; i++)
return 0;
}
+int CmdEM410xWatchnSpoof(const char *Cmd)
+{
+ CmdEM410xWatch(Cmd);
+ PrintAndLog("# Replaying : %s",global_em410xId);
+ CmdEM410xSim(global_em410xId);
+ return 0;
+}
+
/* Read the transmitted data of an EM4x50 tag
* Format:
*
int CmdReadWord(const char *Cmd)
{
- int Word = 16; //default to invalid word
+ int Word = -1; //default to invalid word
UsbCommand c;
sscanf(Cmd, "%d", &Word);
- if (Word > 15) {
+ if ( (Word > 15) | (Word < 0) ) {
PrintAndLog("Word must be between 0 and 15");
return 1;
}
int CmdReadWordPWD(const char *Cmd)
{
- int Word = 16; //default to invalid word
+ int Word = -1; //default to invalid word
int Password = 0xFFFFFFFF; //default to blank password
UsbCommand c;
sscanf(Cmd, "%d %x", &Word, &Password);
- if (Word > 15) {
+ if ( (Word > 15) | (Word < 0) ) {
PrintAndLog("Word must be between 0 and 15");
return 1;
}
return 1;
}
- PrintAndLog("Writting word %d with data %08X", Word, Data);
+ PrintAndLog("Writing word %d with data %08X", Word, Data);
c.cmd = CMD_EM4X_WRITE_WORD;
c.d.asBytes[0] = 0x0; //Normal mode
int CmdWriteWordPWD(const char *Cmd)
{
- int Word = 8; //default to invalid word
+ int Word = 16; //default to invalid word
int Data = 0xFFFFFFFF; //default to blank data
int Password = 0xFFFFFFFF; //default to blank password
UsbCommand c;
return 1;
}
- PrintAndLog("Writting word %d with data %08X and password %08X", Word, Data, Password);
+ PrintAndLog("Writing word %d with data %08X and password %08X", Word, Data, Password);
c.cmd = CMD_EM4X_WRITE_WORD;
c.d.asBytes[0] = 0x1; //Password mode
return 0;
}
-
-
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
{"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
{"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
+ {"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
{"em410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
{"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
{"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
int CmdEM410xRead(const char *Cmd);
int CmdEM410xSim(const char *Cmd);
int CmdEM410xWatch(const char *Cmd);
+int CmdEM410xWatchnSpoof(const char *Cmd);
int CmdEM410xWrite(const char *Cmd);
int CmdEM4x50Read(const char *Cmd);
int CmdReadWord(const char *Cmd);
int CmdLFHitagList(const char *Cmd)
{
- uint8_t got[3000];
+ uint8_t got[TRACE_BUFFER_SIZE];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
int i = 0;
int prev = -1;
+ int len = strlen(Cmd);
+
+ char filename[FILE_PATH_SIZE] = { 0x00 };
+ FILE* pf = NULL;
+
+ if (len > FILE_PATH_SIZE)
+ len = FILE_PATH_SIZE;
+ memcpy(filename, Cmd, len);
+
+ if (strlen(filename) > 0) {
+ if ((pf = fopen(filename,"wb")) == NULL) {
+ PrintAndLog("Error: Could not open file [%s]",filename);
+ return 1;
+ }
+ }
for (;;) {
- if(i >= 1900) {
- break;
- }
+
+ if(i >= TRACE_BUFFER_SIZE) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if (len > 100) {
break;
}
- if (i + len >= 1900) {
- break;
- }
+ if (i + len >= TRACE_BUFFER_SIZE) { break;}
uint8_t *frame = (got+i+9);
line);
-// if (pf) {
-// fprintf(pf," +%7d: %3d: %s %s\n",
-// (prev < 0 ? 0 : (timestamp - prev)),
-// bits,
-// (isResponse ? "TAG" : " "),
-// line);
-// }
+ if (pf) {
+ fprintf(pf," +%7d: %3d: %s %s\n",
+ (prev < 0 ? 0 : (timestamp - prev)),
+ bits,
+ (isResponse ? "TAG" : " "),
+ line);
+ }
prev = timestamp;
i += (len + 9);
}
+ if (pf) {
+ fclose(pf);
+ PrintAndLog("Recorded activity succesfully written to file: %s", filename);
+ }
return 0;
}
}
int CmdLFHitagSim(const char *Cmd) {
+
UsbCommand c = {CMD_SIMULATE_HITAG};
- char filename[256] = { 0x00 };
+ char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf;
bool tag_mem_supplied;
-
- param_getstr(Cmd,0,filename);
+ int len = strlen(Cmd);
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+ memcpy(filename, Cmd, len);
if (strlen(filename) > 0) {
if ((pf = fopen(filename,"rb+")) == NULL) {
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
- {"list", CmdLFHitagList, 1, "List Hitag trace history"},
+ {"list", CmdLFHitagList, 1, "<outfile> List Hitag trace history"},
{"reader", CmdLFHitagReader, 1, "Act like a Hitag Reader"},
- {"sim", CmdLFHitagSim, 1, "Simulate Hitag transponder"},
+ {"sim", CmdLFHitagSim, 1, "<infile> Simulate Hitag transponder"},
{"snoop", CmdLFHitagSnoop, 1, "Eavesdrop Hitag communication"},
{NULL, NULL, 0, NULL}
};
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
UsbCommand resp;
-
+
if (response == NULL)
response = &resp;
#include <stdint.h>
+//trace buffer size as defined in armsrc/apps.h TRACE_SIZE
+#define TRACE_BUFFER_SIZE 4096
+#define FILE_PATH_SIZE 1000
#define SAMPLE_BUFFER_SIZE 64
extern uint8_t* sample_buf;
while (true) {
rxlen = sizeof(UsbCommand) - (prx-prxcmd);
if (uart_receive(sp,prx,&rxlen)) {
-// printf("received [%zd] bytes\n",rxlen);
prx += rxlen;
if ((prx-prxcmd) >= sizeof(UsbCommand)) {
-// printf("received: ");
-// cmd_debug(rxcmd);
return;
}
}
/* write a bit to the graph */
void AppendGraph(int redraw, int clock, int bit)
{
- int i;
+ int i;
- for (i = 0; i < (int)(clock / 2); ++i)
- GraphBuffer[GraphTraceLen++] = bit ^ 1;
+ for (i = 0; i < (int)(clock / 2); ++i)
+ GraphBuffer[GraphTraceLen++] = bit ^ 1;
- for (i = (int)(clock / 2); i < clock; ++i)
- GraphBuffer[GraphTraceLen++] = bit;
+ for (i = (int)(clock / 2); i < clock; ++i)
+ GraphBuffer[GraphTraceLen++] = bit;
- if (redraw)
- RepaintGraphWindow();
+ if (redraw)
+ RepaintGraphWindow();
}
// clear out our graph window
int ClearGraph(int redraw)
{
- int gtl = GraphTraceLen;
- GraphTraceLen = 0;
+ int gtl = GraphTraceLen;
+ memset(GraphBuffer, 0x00, GraphTraceLen);
- if (redraw)
- RepaintGraphWindow();
+ GraphTraceLen = 0;
- return gtl;
+ if (redraw)
+ RepaintGraphWindow();
+
+ return gtl;
}
// DETECT CLOCK NOW IN LFDEMOD.C
void setGraphBuf(uint8_t *buff, size_t size)
{
- int i=0;
- ClearGraph(0);
- for (; i < size; ++i){
+ int i=0;
+ ClearGraph(0);
+ for (; i < size; ++i){
GraphBuffer[i]=buff[i]-128;
- }
- GraphTraceLen=size;
- RepaintGraphWindow();
- return;
+ }
+ GraphTraceLen=size;
+ RepaintGraphWindow();
+ return;
}
size_t getFromGraphBuf(uint8_t *buff)
{
- uint32_t i;
- for (i=0;i<GraphTraceLen;++i){
- if (GraphBuffer[i]>127) GraphBuffer[i]=127; //trim
- if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim
- buff[i]=(uint8_t)(GraphBuffer[i]+128);
- }
- return i;
+ uint32_t i;
+ for (i=0;i<GraphTraceLen;++i){
+ if (GraphBuffer[i]>127) GraphBuffer[i]=127; //trim
+ if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim
+ buff[i]=(uint8_t)(GraphBuffer[i]+128);
+ }
+ return i;
}
// Get or auto-detect clock rate
int GetClock(const char *str, int peak, int verbose)
{
- int clock;
- sscanf(str, "%i", &clock);
- if (!strcmp(str, ""))
- clock = 0;
+ int clock;
+ sscanf(str, "%i", &clock);
+ if (!strcmp(str, ""))
+ clock = 0;
// Auto-detect clock
- if (!clock)
- {
- uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
+ if (!clock)
+ {
+ uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
size_t size = getFromGraphBuf(grph);
- clock = DetectASKClock(grph,size,0);
+ clock = DetectASKClock(grph,size,0);
// Only print this message if we're not looping something
- if (!verbose){
- PrintAndLog("Auto-detected clock rate: %d", clock);
- }
- }
+ if (!verbose){
+ PrintAndLog("Auto-detected clock rate: %d", clock);
+ }
+ }
- return clock;
+ return clock;
}
int GetNRZpskClock(const char *str, int peak, int verbose)
*/
int bruteforceFile(const char *filename, uint16_t keytable[])
{
-
FILE *f = fopen(filename, "rb");
if(!f) {
prnlog("Failed to read from file '%s'", filename);
int readKeyFile(uint8_t key[8])
{
-
FILE *f;
int retval = 1;
f = fopen("iclass_key.bin", "rb");
fclose(f);
}
return retval;
-
}
CMD_ISO_15693_COMMAND_DONE = 0x0314,
CMD_ISO_15693_FIND_AFI = 0x0315,
CMD_ISO_15693_DEBUG = 0x0316,
+ CMD_LF_SNOOP_RAW_ADC_SAMPLES = 0x0317,
--// For Hitag2 transponders
CMD_SNOOP_HITAG = 0x0370,
CMD_READER_LEGIC_RF = 0x0388,
CMD_WRITER_LEGIC_RF = 0x0389,
CMD_EPA_PACE_COLLECT_NONCE = 0x038A,
+ --//CMD_EPA_ = 0x038B,
CMD_SNOOP_ICLASS = 0x0392,
CMD_SIMULATE_TAG_ICLASS = 0x0393,
CMD_READER_ICLASS = 0x0394,
+ CMD_READER_ICLASS_REPLAY = 0x0395,
+ CMD_ICLASS_ISO14443A_WRITE = 0x0397,
--// For measurements of the antenna tuning
CMD_MEASURE_ANTENNA_TUNING = 0x0400,
CMD_MIFARE_EML_MEMSET = 0x0602,
CMD_MIFARE_EML_MEMGET = 0x0603,
CMD_MIFARE_EML_CARDLOAD = 0x0604,
- CMD_MIFARE_EML_CSETBLOCK = 0x0605,
- CMD_MIFARE_EML_CGETBLOCK = 0x0606,
+
+ --// magic chinese card commands
+ CMD_MIFARE_CSETBLOCK = 0x0605,
+ CMD_MIFARE_CGETBLOCK = 0x0606,
+ CMD_MIFARE_CIDENT = 0x0607,
CMD_SIMULATE_MIFARE_CARD = 0x0610,
CMD_MIFARE_NESTED = 0x0612,
CMD_MIFARE_READBL = 0x0620,
+ CMD_MIFAREU_READBL = 0x0720,
+
CMD_MIFARE_READSC = 0x0621,
+ CMD_MIFAREU_READCARD = 0x0721,
+
CMD_MIFARE_WRITEBL = 0x0622,
+ CMD_MIFAREU_WRITEBL = 0x0722,
+ CMD_MIFAREU_WRITEBL_COMPAT = 0x0723,
+
CMD_MIFARE_CHKKEYS = 0x0623,
CMD_MIFARE_SNIFFER = 0x0630,
+ --//ultralightC
+ CMD_MIFAREUC_AUTH1 = 0x0724,
+ CMD_MIFAREUC_AUTH2 = 0x0725,
+ CMD_MIFAREUC_READCARD = 0x0726,
+
+ --// mifare desfire
+ CMD_MIFARE_DESFIRE_READBL = 0x0728,
+ CMD_MIFARE_DESFIRE_WRITEBL = 0x0729,
+ CMD_MIFARE_DESFIRE_AUTH1 = 0x072a,
+ CMD_MIFARE_DESFIRE_AUTH2 = 0x072b,
+ CMD_MIFARE_DES_READER = 0x072c,
+ CMD_MIFARE_DESFIRE_INFO = 0x072d,
+ CMD_MIFARE_DESFIRE = 0x072e,
+
CMD_UNKNOWN = 0xFFFF,
}
local data = self.data
local cmd = self.cmd
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
-
return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data);
end
--- /dev/null
+local _names = {
+ --[[
+ --]]
+ ["0400"]="BASH",
+ ["1600"]="BOOMER" ,
+ ["1800"]="CAMO",
+ ["3000"]="CHOPCHOP" ,
+ ["2000"]="CYNDER",
+ ["6400"]="JET-VAC",
+ ["6700"]="FLASHWING",
+ ["7000"]="TREE REX",
+ ["7100"]="LIGHTCORE SHROOMBOOM",
+ ["1C00"]="DARK SPYRO",
+ ["0600"]="DINORANG" ,
+ ["1200"]="DOUBLE TROUBLE" ,
+ ["1500"]="DRILLSERGEANT" ,
+ ["1400"]="DROBOT",
+ ["0900"]="LIGHTCORE ERUPTOR" ,
+ ["0B00"]="FLAMESLINGER" ,
+ ["1F00"]="GHOST ROASTER",
+ ["0E00"]="GILL GRUNT" ,
+ ["1D00"]="HEX",
+ ["0A00"]="IGNITOR",
+ ["0300"]="LIGHTNINGROD",
+ ["0700"]="LIGHTCORE PRISM BREAK",
+ ["1500"]="SLAMBAM",
+ ["0100"]="SONIC BOOM",
+ ["1000"]="SPYRO",
+ ["1A00"]="STEALTH ELF",
+ ["1B00"]="STUMP SMASH",
+ ["0800"]="SUNBURN",
+ ["0500"]="TERRAFIN",
+ ["1300"]="TRIGGER HAPPY",
+ ["1100"]="VOODOOD",
+ ["0200"]="WARNADO",
+ ["0D00"]="WHAM SHELL",
+ ["0000"]="WHIRLWIND",
+ ["1700"]="WRECKING BALL",
+ ["0C00"]="ZAP",
+ ["1900"]="ZOOK",
+ ["0300"]="DRAGON",
+ ["012D"]="ICE",
+ ["012E"]="PIRATE",
+ ["0130"]="PVPUNLOCK",
+ ["012F"]="UNDEAD",
+ ["0200"]="ANVIL" ,
+ ["CB00"]="CROSSED SWORDS",
+ ["CC00"]="HOURGLASS",
+ ["CA00"]="REGENERATION",
+ ["C900"]="SECRET STASH",
+ ["CD00"]="SHIELD",
+ ["CF00"]="SPARX",
+ ["CE00"]="SPEED BOOTS",
+ ["0194"]="LEGENDARY BASH",
+ ["0430"]="LEGENDARY CHOPCHOP",
+ ["01A0"]="LEGENDARY SPYRO",
+ ["01A3"]="LEGENDARY TRIGGER HAPPY",
+ ["0202"]="PET GILL GRUNT",
+ ["020E"]="PET STEALTH ELF",
+ ["01F9"]="PET TERRAFIN",
+ ["0207"]="PET TRIGGER HAPPY",
+}
+return _names
end
+local function save_TEXT(data,filename)
+ -- Open the output file
+ local outfile = io.open(filename, "wb")
+ if outfile == nil then
+ return oops(string.format("Could not write to file %s",tostring(filename)))
+ end
+
+ outfile:write(data)
+ io.close(outfile)
+ return filename
+end
+
local function save_BIN(data, filename)
-- Open the output file
convert_bin_to_html = convert_bin_to_html,
convert_eml_to_html = convert_eml_to_html,
convert_eml_to_bin = convert_eml_to_bin,
+ SaveAsBinary = save_BIN,
+ SaveAsText = save_TEXT,
}
return "UNKNOWN"
}
+ add("04,,,Mifare TNP3xxx Activision 1K,0f01,01");
add("04,,,Mifare Mini,0004,09");
add("04,,,Mifare Classic 1k/Mifare Plus(4 byte UID) 2K SL1,0004,08");
add("04,,,Mifare Plus (4 byte UID) 2K SL2,0004,10");
'200000000000',
'a00000000000',
'b00000000000',
+
+ --[[
+ Should be for Mifare TNP3xxx tags A KEY.
+ --]]
+ '4b0b20107ccb',
+
+ --[[
+ Kiev metro cards
+ --]]
+ '8fe644038790',
+ 'f14ee7cae863',
+ '632193be1c3c',
+ '569369c5a0e5',
+ '9de89e070277',
+ 'eff603e1efe9',
+ '644672bd4afe',
+
+ 'b5ff67cba951',
}
---
local ISO14443a_TYPES = {}
ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C"
+ISO14443a_TYPES[0x01] = "NXP MIFARE TNP3xxx Activision Game Appliance"
ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k"
ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k"
\r
return answer\r
end,\r
+ \r
+ ------------ FILE READING\r
+ ReadDumpFile = function (filename)\r
+ \r
+ if filename == nil then \r
+ return nil, 'Filename is empty'\r
+ end\r
+ if #filename == 0 then\r
+ return nil, 'Filename length is zero'\r
+ end\r
+\r
+ infile = io.open(filename, "rb")\r
+ if infile == nil then \r
+ return nil, string.format("Could not read file %s",filename)\r
+ end\r
+ local t = infile:read("*all")\r
+ len = string.len(t)\r
+ local _,hex = bin.unpack(("H%d"):format(len),t)\r
+ io.close(infile)\r
+ return hex\r
+ end,\r
+ \r
+ ------------ string split function\r
+ Split = function( inSplitPattern, outResults )\r
+ if not outResults then\r
+ outResults = {}\r
+ end\r
+ local start = 1\r
+ local splitStart, splitEnd = string.find( self, inSplitPattern, start )\r
+ while splitStart do\r
+ table.insert( outResults, string.sub( self, start, splitStart-1 ) )\r
+ start = splitEnd + 1\r
+ splitStart, splitEnd = string.find( self, inSplitPattern, start )\r
+ end\r
+ table.insert( outResults, string.sub( self, start ) )\r
+ return outResults\r
+ end,\r
+ \r
+ ------------ CRC-16 ccitt checksums\r
+ \r
+ -- Takes a hex string and calculates a crc16\r
+ Crc16 = function(s)\r
+ if s == nil then return nil end\r
+ if #s == 0 then return nil end\r
+ if type(s) == 'string' then\r
+ local utils = require('utils')\r
+ local asc = utils.ConvertHexToAscii(s)\r
+ local hash = core.crc16(asc)\r
+ return hash\r
+ end\r
+ return nil\r
+ end,\r
+\r
+ -- input parameter is a string\r
+ -- Swaps the endianess and returns a number, \r
+ -- IE: 'cd7a' -> '7acd' -> 0x7acd\r
+ SwapEndianness = function(s, len)\r
+ if s == nil then return nil end\r
+ if #s == 0 then return '' end\r
+ if type(s) ~= 'string' then return nil end\r
+ \r
+ local retval = 0\r
+ if len == 16 then\r
+ local t = s:sub(3,4)..s:sub(1,2)\r
+ retval = tonumber(t,16)\r
+ elseif len == 24 then\r
+ local t = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)\r
+ retval = tonumber(t,16)\r
+ elseif len == 32 then\r
+ local t = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)\r
+ retval = tonumber(t,16)\r
+ end\r
+ return retval\r
+ end,\r
+ \r
+ ------------ CONVERSIONS\r
+ \r
--\r
-- Converts DECIMAL to HEX\r
- ConvertDec2Hex = function(IN)\r
+ ConvertDecToHex = function(IN)\r
local B,K,OUT,I,D=16,"0123456789ABCDEF","",0\r
while IN>0 do\r
I=I+1\r
end,\r
---\r
-- Convert Byte array to string of hex\r
- ConvertBytes2String = function(bytes)\r
- s = {}\r
+ ConvertBytesToHex = function(bytes)\r
+ if #bytes == 0 then\r
+ return ''\r
+ end\r
+ local s={}\r
for i = 1, #(bytes) do\r
s[i] = string.format("%02X",bytes[i]) \r
end\r
return table.concat(s)\r
end, \r
+ -- Convert byte array to string with ascii\r
+ ConvertBytesToAscii = function(bytes)\r
+ if #bytes == 0 then\r
+ return ''\r
+ end\r
+ local s={}\r
+ for i = 1, #(bytes) do\r
+ s[i] = string.char(bytes[i]) \r
+ end\r
+ return table.concat(s) \r
+ end, \r
+ ConvertHexToBytes = function(s)\r
+ local t={}\r
+ if s == nil then return t end\r
+ if #s == 0 then return t end\r
+ for k in s:gmatch"(%x%x)" do\r
+ table.insert(t,tonumber(k,16))\r
+ end\r
+ return t\r
+ end,\r
+ ConvertAsciiToBytes = function(s)\r
+ local t={}\r
+ if s == nil then return t end\r
+ if #s == 0 then return t end\r
+ \r
+ for k in s:gmatch"(.)" do\r
+ table.insert(t, string.byte(k))\r
+ end\r
+ return t\r
+ end,\r
+ ConvertHexToAscii = function(s)\r
+ local t={}\r
+ if s == nil then return t end\r
+ if #s == 0 then return t end\r
+ for k in s:gmatch"(%x%x)" do\r
+ table.insert(t, string.char(tonumber(k,16)))\r
+ end\r
+ return table.concat(t) \r
+ end,\r
+ \r
+ -- function convertStringToBytes(str)\r
+ -- local bytes = {}\r
+ -- local strLength = string.len(str)\r
+ -- for i=1,strLength do\r
+ -- table.insert(bytes, string.byte(str, i))\r
+ -- end\r
+\r
+ -- return bytes\r
+-- end\r
+\r
+-- function convertBytesToString(bytes)\r
+ -- local bytesLength = table.getn(bytes)\r
+ -- local str = ""\r
+ -- for i=1,bytesLength do\r
+ -- str = str .. string.char(bytes[i])\r
+ -- end\r
+\r
+ -- return str\r
+-- end\r
+\r
+-- function convertHexStringToBytes(str)\r
+ -- local bytes = {}\r
+ -- local strLength = string.len(str)\r
+ -- for k=2,strLength,2 do\r
+ -- local hexString = "0x" .. string.sub(str, (k - 1), k)\r
+ -- table.insert(bytes, hex.to_dec(hexString))\r
+ -- end\r
+\r
+ -- return bytes\r
+-- end\r
+\r
+-- function convertBytesToHexString(bytes)\r
+ -- local str = ""\r
+ -- local bytesLength = table.getn(bytes)\r
+ -- for i=1,bytesLength do\r
+ -- local hexString = string.sub(hex.to_hex(bytes[i]), 3)\r
+ -- if string.len(hexString) == 1 then\r
+ -- hexString = "0" .. hexString\r
+ -- end\r
+ -- str = str .. hexString\r
+ -- end\r
+\r
+ -- return str\r
+-- end\r
+\r
}\r
return Utils
\ No newline at end of file
#include "util.h"
#include "nonce2key/nonce2key.h"
#include "../common/iso15693tools.h"
+#include <openssl/aes.h>
+#include "../common/crc16.h"
/**
* The following params expected:
* UsbCommand c
return 1;
}
+/*
+ Simple AES 128 cbc hook up to OpenSSL.
+ params: key, input
+*/
+static int l_aes(lua_State *L)
+{
+ //Check number of arguments
+ int i;
+ size_t size;
+ const char *p_key = luaL_checklstring(L, 1, &size);
+ if(size != 32) return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size);
+
+ const char *p_encTxt = luaL_checklstring(L, 2, &size);
+
+ unsigned char indata[AES_BLOCK_SIZE] = {0x00};
+ unsigned char outdata[AES_BLOCK_SIZE] = {0x00};
+ unsigned char aes_key[AES_BLOCK_SIZE] = {0x00};
+ unsigned char iv[AES_BLOCK_SIZE] = {0x00};
+
+ // convert key to bytearray
+ for (i = 0; i < 32; i += 2) {
+ sscanf(&p_encTxt[i], "%02x", (unsigned int *)&indata[i / 2]);
+ }
+
+ // convert input to bytearray
+ for (i = 0; i < 32; i += 2) {
+ sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]);
+ }
+
+ AES_KEY key;
+ AES_set_decrypt_key(aes_key, 128, &key);
+ AES_cbc_encrypt(indata, outdata, sizeof(indata), &key, iv, AES_DECRYPT);
+
+ //Push decrypted array as a string
+ lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
+ return 1;// return 1 to signal one return value
+}
+
+static int l_crc16(lua_State *L)
+{
+ size_t size;
+ const char *p_str = luaL_checklstring(L, 1, &size);
+
+ uint16_t retval = crc16_ccitt( (uint8_t*) p_str, size);
+ lua_pushinteger(L, (int) retval);
+ return 1;
+}
+
/**
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
* able to do "require('foobar')" if foobar.lua is within lualibs folder.
{"clearCommandBuffer", l_clearCommandBuffer},
{"console", l_CmdConsole},
{"iso15693_crc", l_iso15693_crc},
+ {"aes", l_aes},
+ {"crc16", l_crc16},
{NULL, NULL}
};
--- /dev/null
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local lib14a = require('read14a')
+local utils = require('utils')
+local md5 = require('md5')
+local dumplib = require('html_dumplib')
+local toyNames = require('default_toys')
+
+example =[[
+ 1. script run tnp3dump
+ 2. script run tnp3dump -n
+ 3. script run tnp3dump -k aabbccddeeff
+ 4. script run tnp3dump -k aabbccddeeff -n
+ 5. script run tnp3dump -o myfile
+ 6. script run tnp3dump -n -o myfile
+ 7. script run tnp3dump -k aabbccddeeff -n -o myfile
+]]
+author = "Iceman"
+usage = "script run tnp3dump -k <key> -n -o <filename>"
+desc =[[
+This script will try to dump the contents of a Mifare TNP3xxx card.
+It will need a valid KeyA in order to find the other keys and decode the card.
+Arguments:
+ -h : this help
+ -k <key> : Sector 0 Key A.
+ -n : Use the nested cmd to find all keys
+ -o : filename for the saved dumps
+]]
+
+local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = false -- the debug flag
+local numBlocks = 64
+local numSectors = 16
+---
+-- A debug printout-function
+function dbg(args)
+ if not DEBUG then
+ return
+ end
+
+ if type(args) == "table" then
+ local i = 1
+ while result[i] do
+ dbg(result[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
+
+local function readdumpkeys(infile)
+ t = infile:read("*all")
+ len = string.len(t)
+ local len,hex = bin.unpack(("H%d"):format(len),t)
+ return hex
+end
+
+local function waitCmd()
+ local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+ if response then
+ local count,cmd,arg0 = bin.unpack('LL',response)
+ if(arg0==1) then
+ local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
+ return data:sub(1,32)
+ else
+ return nil, "Couldn't read block.."
+ end
+ end
+ return nil, "No response from device"
+end
+
+local function computeCrc16(s)
+ local hash = core.crc16(utils.ConvertHexToAscii(s))
+ return hash
+end
+
+local function reverseCrcBytes(crc)
+ crc2 = crc:sub(3,4)..crc:sub(1,2)
+ return tonumber(crc2,16)
+end
+
+local function main(args)
+
+ print( string.rep('--',20) )
+ print( string.rep('--',20) )
+
+ local keyA
+ local cmd
+ local err
+ local useNested = false
+ local cmdReadBlockString = 'hf mf rdbl %d A %s'
+ local input = "dumpkeys.bin"
+ local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S");
+
+ -- Arguments for the script
+ for o, a in getopt.getopt(args, 'hk:no:') do
+ if o == "h" then return help() end
+ if o == "k" then keyA = a end
+ if o == "n" then useNested = true end
+ if o == "o" then outputTemplate = a end
+ end
+
+ -- validate input args.
+ keyA = keyA or '4b0b20107ccb'
+ if #(keyA) ~= 12 then
+ return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA))
+ end
+
+ -- Turn off Debug
+ local cmdSetDbgOff = "hf mf dbg 0"
+ core.console( cmdSetDbgOff)
+
+ result, err = lib14a.read1443a(false)
+ if not result then
+ return oops(err)
+ end
+
+ core.clearCommandBuffer()
+
+ if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
+ return oops('This is not a TNP3xxx tag. aborting.')
+ end
+
+ -- Show tag info
+ print((' Found tag : %s'):format(result.name))
+ print(('Using keyA : %s'):format(keyA))
+
+ --Trying to find the other keys
+ if useNested then
+ core.console( ('hf mf nested 1 0 A %s d'):format(keyA) )
+ end
+
+ core.clearCommandBuffer()
+
+ -- Loading keyfile
+ print('Loading dumpkeys.bin')
+ local hex, err = utils.ReadDumpFile(input)
+ if not hex then
+ return oops(err)
+ end
+
+ local akeys = hex:sub(0,12*16)
+
+ -- Read block 0
+ cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
+ err = core.SendCommand(cmd:getBytes())
+ if err then return oops(err) end
+ local block0, err = waitCmd()
+ if err then return oops(err) end
+
+ -- Read block 1
+ cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA}
+ err = core.SendCommand(cmd:getBytes())
+ if err then return oops(err) end
+ local block1, err = waitCmd()
+ if err then return oops(err) end
+
+ local key
+ local pos = 0
+ local blockNo
+ local blocks = {}
+
+ print('Reading card data')
+ core.clearCommandBuffer()
+
+ -- main loop
+ io.write('Decrypting blocks > ')
+ for blockNo = 0, numBlocks-1, 1 do
+
+ if core.ukbhit() then
+ print("aborted by user")
+ break
+ end
+
+ pos = (math.floor( blockNo / 4 ) * 12)+1
+ key = akeys:sub(pos, pos + 11 )
+ cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = key}
+ local err = core.SendCommand(cmd:getBytes())
+ if err then return oops(err) end
+ local blockdata, err = waitCmd()
+ if err then return oops(err) end
+
+ if blockNo%4 ~= 3 then
+ if blockNo < 8 then
+ -- Block 0-7 not encrypted
+ blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
+ else
+ local base = ('%s%s%02x%s'):format(block0, block1, blockNo, HASHCONSTANT)
+ local baseStr = utils.ConvertHexToAscii(base)
+ local md5hash = md5.sumhexa(baseStr)
+ local aestest = core.aes(md5hash, blockdata)
+
+ local hex = utils.ConvertAsciiToBytes(aestest)
+ hex = utils.ConvertBytesToHex(hex)
+
+ -- blocks with zero not encrypted.
+ if string.find(blockdata, '^0+$') then
+ blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
+ else
+ blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex)
+ io.write( blockNo..',')
+ end
+ end
+ else
+ -- Sectorblocks, not encrypted
+ blocks[blockNo+1] = ('%02d :: %s%s'):format(blockNo,key,blockdata:sub(13,32))
+ end
+ end
+ io.write('\n')
+
+ core.clearCommandBuffer()
+
+ -- Print results
+ local bindata = {}
+ local emldata = ''
+
+ for _,s in pairs(blocks) do
+ local slice = s:sub(8,#s)
+ local str = utils.ConvertBytesToAscii(
+ utils.ConvertHexToBytes(slice)
+ )
+ emldata = emldata..slice..'\n'
+ for c in (str):gmatch('.') do
+ bindata[#bindata+1] = c
+ end
+ end
+
+ -- Write dump to files
+ if not DEBUG then
+ local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
+ print(("Wrote a BIN dump to the file %s"):format(foo))
+ local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
+ print(("Wrote a EML dump to the file %s"):format(bar))
+ end
+
+ local uid = block0:sub(1,8)
+ local itemtype = block1:sub(1,4)
+ local cardid = block1:sub(9,24)
+
+ -- Show info
+ print( string.rep('--',20) )
+ print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
+ print( (' UID : 0x%s'):format(uid) )
+ print( (' CARDID : 0x%s'):format(cardid ) )
+ print( string.rep('--',20) )
+
+end
+main(args)
\ No newline at end of file
--- /dev/null
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local lib14a = require('read14a')
+local utils = require('utils')
+local md5 = require('md5')
+local toyNames = require('default_toys')
+
+example =[[
+ 1. script run tnp3sim
+ 2. script run tnp3sim -m
+ 3. script run tnp3sim -m -i myfile
+]]
+author = "Iceman"
+usage = "script run tnp3sim -h -m -i <filename>"
+desc =[[
+This script will try to load a binary datadump of a Mifare TNP3xxx card.
+It vill try to validate all checksums and view some information stored in the dump
+For an experimental mode, it tries to manipulate some data.
+At last it sends all data to the PM3 device memory where it can be used in the command "hf mf sim"
+
+Arguments:
+ -h : this help
+ -m : Maxed out items (experimental)
+ -i : filename for the datadump to read (bin)
+]]
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = true -- the debug flag
+---
+-- A debug printout-function
+function dbg(args)
+ if not DEBUG then
+ return
+ end
+
+ if type(args) == "table" then
+ local i = 1
+ while result[i] do
+ dbg(result[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
+
+
+local function writedumpfile(infile)
+ t = infile:read("*all")
+ len = string.len(t)
+ local len,hex = bin.unpack(("H%d"):format(len),t)
+ return hex
+end
+-- blocks with data
+-- there are two dataareas, in block 8 or block 36, ( 1==8 ,
+-- checksum type = 0, 1, 2, 3
+local function GetCheckSum(blocks, dataarea, chksumtype)
+
+ local crc
+ local area = 36
+ if dataarea == 1 then
+ area = 8
+ end
+
+ if chksumtype == 0 then
+ crc = blocks[1]:sub(29,32)
+ elseif chksumtype == 1 then
+ crc = blocks[area]:sub(29,32)
+ elseif chksumtype == 2 then
+ crc = blocks[area]:sub(25,28)
+ elseif chksumtype == 3 then
+ crc = blocks[area]:sub(21,24)
+ end
+ return utils.SwapEndianness(crc,16)
+end
+
+local function SetCheckSum(blocks, chksumtype)
+
+ if blocks == nil then return nil, 'Argument \"blocks\" nil' end
+ local newcrc
+ local area1 = 8
+ local area2 = 36
+
+ if chksumtype == 0 then
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,1,0))
+ blocks[1] = blocks[1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+ elseif chksumtype == 1 then
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,1,1))
+ blocks[area1] = blocks[area1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,2,1))
+ blocks[area2] = blocks[area2]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+ elseif chksumtype == 2 then
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,1,2))
+ blocks[area1] = blocks[area1]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(29,32)
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,2,2))
+ blocks[area2] = blocks[area2]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(29,32)
+ elseif chksumtype == 3 then
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,1,3))
+ blocks[area1] = blocks[area1]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(25,32)
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,2,3))
+ blocks[area2] = blocks[area2]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(25,32)
+ end
+end
+
+function CalcCheckSum(blocks, dataarea, chksumtype)
+ local area = 36
+ if dataarea == 1 then
+ area = 8
+ end
+
+ if chksumtype == 0 then
+ data = blocks[0]..blocks[1]:sub(1,28)
+ elseif chksumtype == 1 then
+ data = blocks[area]:sub(1,28)..'0500'
+ elseif chksumtype == 2 then
+ data = blocks[area+1]..blocks[area+2]..blocks[area+4]
+ elseif chksumtype == 3 then
+ data = blocks[area+5]..blocks[area+6]..blocks[area+8]..string.rep('00',0xe0)
+ end
+ return utils.Crc16(data)
+end
+
+local function ValidateCheckSums(blocks)
+
+ local isOk, crc, calc
+ -- Checksum Type 0
+ crc = GetCheckSum(blocks,1,0)
+ calc = CalcCheckSum(blocks, 1, 0)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 0 : %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 1 (DATAAREAHEADER 1)
+ crc = GetCheckSum(blocks,1,1)
+ calc = CalcCheckSum(blocks,1,1)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 1 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 1 (DATAAREAHEADER 2)
+ crc = GetCheckSum(blocks,2,1)
+ calc = CalcCheckSum(blocks,2,1)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 1 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 2 (DATAAREA 1)
+ crc = GetCheckSum(blocks,1,2)
+ calc = CalcCheckSum(blocks,1,2)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 2 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 2 (DATAAREA 2)
+ crc = GetCheckSum(blocks,2,2)
+ calc = CalcCheckSum(blocks,2,2)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 2 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 3 (DATAAREA 1)
+ crc = GetCheckSum(blocks,1,3)
+ calc = CalcCheckSum(blocks,1,3)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 3 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 3 (DATAAREA 2)
+ crc = GetCheckSum(blocks,2,3)
+ calc = CalcCheckSum(blocks,2,3)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+end
+
+
+local function LoadEmulator(blocks)
+ local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+ local cmd
+ local blockdata
+ for _,b in pairs(blocks) do
+
+ blockdata = b
+
+ if _%4 ~= 3 then
+ if (_ >= 8 and _<=21) or (_ >= 36 and _<=49) then
+ local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , HASHCONSTANT)
+ local baseStr = utils.ConvertHexToAscii(base)
+ local key = md5.sumhexa(baseStr)
+ local enc = core.aes(key, blockdata)
+ local hex = utils.ConvertAsciiToBytes(enc)
+ hex = utils.ConvertBytesToHex(hex)
+
+ blockdata = hex
+ io.write( _..',')
+ end
+ end
+
+ cmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 0, data = blockdata}
+ local err = core.SendCommand(cmd:getBytes())
+ if err then
+ return err
+ end
+ end
+ io.write('\n')
+end
+
+local function main(args)
+
+ print( string.rep('--',20) )
+ print( string.rep('--',20) )
+
+ local result, err, hex
+ local maxed = false
+ local inputTemplate = "dumpdata.bin"
+ local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M");
+
+ -- Arguments for the script
+ for o, a in getopt.getopt(args, 'hmi:o:') do
+ if o == "h" then return help() end
+ if o == "m" then maxed = true end
+ if o == "o" then outputTemplate = a end
+ if o == "i" then inputTemplate = a end
+ end
+
+ -- Turn off Debug
+ local cmdSetDbgOff = "hf mf dbg 0"
+ core.console( cmdSetDbgOff)
+
+ -- Look for tag present on reader,
+ result, err = lib14a.read1443a(false)
+ if not result then return oops(err) end
+
+ core.clearCommandBuffer()
+
+ if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
+ return oops('This is not a TNP3xxx tag. aborting.')
+ end
+
+ -- Show tag info
+ print((' Found tag : %s'):format(result.name))
+
+ -- Load dump.bin file
+ print( (' Load data from %s'):format(inputTemplate))
+ hex, err = utils.ReadDumpFile(inputTemplate)
+ if not hex then return oops(err) end
+
+ local blocks = {}
+ local blockindex = 0
+ for i = 1, #hex, 32 do
+ blocks[blockindex] = hex:sub(i,i+31)
+ blockindex = blockindex + 1
+ end
+
+ if DEBUG then
+ print('Validating checksums in the loaded datadump')
+ ValidateCheckSums(blocks)
+ end
+
+ --
+ print( string.rep('--',20) )
+ print(' Gathering info')
+ local uid = blocks[0]:sub(1,8)
+ local itemtype = blocks[1]:sub(1,4)
+ local cardid = blocks[1]:sub(9,24)
+
+ -- Show info
+ print( string.rep('--',20) )
+ print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
+ print( (' UID : 0x%s'):format(uid) )
+ print( (' CARDID : 0x%s'):format(cardid ) )
+ print( string.rep('--',20) )
+
+ -- lets do something.
+ --
+ local experience = blocks[8]:sub(1,6)
+ print(('Experience : %d'):format(utils.SwapEndianness(experience,24)))
+ local money = blocks[8]:sub(7,10)
+ print(('Money : %d'):format(utils.SwapEndianness(money,16)))
+ local fairy = blocks[9]:sub(1,8)
+ --FD0F = Left, FF0F = Right
+ local path = 'not choosen'
+ if fairy:sub(2,2) == 'D' then
+ path = 'Left'
+ elseif fairy:sub(2,2) == 'F' then
+ path = 'Right'
+ end
+ print(('Fairy : %d [Path: %s] '):format(utils.SwapEndianness(fairy,24),path))
+
+ local hat = blocks[9]:sub(8,11)
+ print(('Hat : %d'):format(utils.SwapEndianness(hat,16)))
+
+ --0x0D 0x29 0x0A 0x02 16-bit hero points value. Maximum 100.
+ local heropoints = blocks[13]:sub(20,23)
+ print(('Hero points : %d'):format(utils.SwapEndianness(heropoints,16)))
+
+ --0x10 0x2C 0x0C 0x04 32 bit flag value indicating heroic challenges completed.
+ local challenges = blocks[16]:sub(25,32)
+ print(('Finished hero challenges : %d'):format(utils.SwapEndianness(challenges,32)))
+
+ if maxed then
+ print('Lets try to max out some values')
+ -- max out money, experience
+ --print (blocks[8])
+ blocks[8] = 'FFFFFF'..'FFFF'..blocks[8]:sub(11,32)
+ blocks[36] = 'FFFFFF'..'FFFF'..blocks[36]:sub(11,32)
+ --print (blocks[8])
+
+ -- max out hero challenges
+ --print (blocks[16])
+ blocks[16] = blocks[16]:sub(1,24)..'FFFFFFFF'
+ blocks[44] = blocks[44]:sub(1,24)..'FFFFFFFF'
+ --print (blocks[16])
+
+ -- max out heropoints
+ --print (blocks[13])
+ blocks[13] = blocks[13]:sub(1,19)..'0064'..blocks[13]:sub(24,32)
+ blocks[41] = blocks[41]:sub(1,19)..'0064'..blocks[41]:sub(24,32)
+ --print (blocks[13])
+
+ -- Update Checksums
+ print('Updating all checksums')
+ SetCheckSum(blocks, 3)
+ SetCheckSum(blocks, 2)
+ SetCheckSum(blocks, 1)
+ SetCheckSum(blocks, 0)
+
+ print('Validating all checksums')
+ ValidateCheckSums(blocks)
+ end
+
+ --Load dumpdata to emulator memory
+ if DEBUG then
+ print('Sending dumpdata to emulator memory')
+ err = LoadEmulator(blocks)
+ if err then return oops(err) end
+ core.clearCommandBuffer()
+ print('The simulation is now prepared.\n --> run \"hf mf sim 5 '..uid..'\" <--')
+ end
+end
+main(args)
\ No newline at end of file
#ifndef _WIN32
#include <termios.h>
#include <sys/ioctl.h>
+
int ukbhit(void)
{
int cnt = 0;
#endif
// log files functions
-void AddLogLine(char *fileName, char *extData, char *c) {
+void AddLogLine(char *file, char *extData, char *c) {
FILE *fLog = NULL;
-
- fLog = fopen(fileName, "a");
+ char filename[FILE_PATH_SIZE] = {0x00};
+ int len = 0;
+
+ len = strlen(file);
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+ memcpy(filename, file, len);
+
+ fLog = fopen(filename, "a");
if (!fLog) {
- printf("Could not append log file %s", fileName);
+ printf("Could not append log file %s", filename);
return;
}
}
char * sprint_hex(const uint8_t * data, const size_t len) {
+
+ int maxLen = ( len > 1024/3) ? 1024/3 : len;
static char buf[1024];
char * tmp = buf;
size_t i;
- for (i=0; i < len && i < 1024/3; i++, tmp += 3)
+ for (i=0; i < maxLen; ++i, tmp += 3)
sprintf(tmp, "%02x ", data[i]);
return buf;
}
+char * sprint_bin(const uint8_t * data, const size_t len) {
+
+ int maxLen = ( len > 1024) ? 1024 : len;
+ static char buf[1024];
+ char * tmp = buf;
+ size_t i;
+
+ for (i=0; i < maxLen; ++i, ++tmp)
+ sprintf(tmp, "%u", data[i]);
+
+ return buf;
+}
+
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest)
{
while (len--) {
return num;
}
+//assumes little endian
+char * printBits(size_t const size, void const * const ptr)
+{
+ unsigned char *b = (unsigned char*) ptr;
+ unsigned char byte;
+ static char buf[1024];
+ char * tmp = buf;
+ int i, j;
+
+ for (i=size-1;i>=0;i--)
+ {
+ for (j=7;j>=0;j--)
+ {
+ byte = b[i] & (1<<j);
+ byte >>= j;
+ sprintf(tmp, "%u", byte);
+ tmp++;
+ }
+ }
+ return buf;
+}
+
// -------------------------------------------------------------------------
// string parameters lib
// -------------------------------------------------------------------------
return en - bg + 1;
}
+
+/*
+The following methods comes from Rfidler sourcecode.
+https://github.com/ApertureLabsLtd/RFIDler/blob/master/firmware/Pic32/RFIDler.X/src/
+*/
+
+// convert hex to sequence of 0/1 bit values
+// returns number of bits converted
+int hextobinarray(char *target, char *source)
+{
+ int length, i, count= 0;
+ char x;
+
+ length = strlen(source);
+ // process 4 bits (1 hex digit) at a time
+ while(length--)
+ {
+ x= *(source++);
+ // capitalize
+ if (x >= 'a' && x <= 'f')
+ x -= 32;
+ // convert to numeric value
+ if (x >= '0' && x <= '9')
+ x -= '0';
+ else if (x >= 'A' && x <= 'F')
+ x -= 'A' - 10;
+ else
+ return 0;
+ // output
+ for(i= 0 ; i < 4 ; ++i, ++count)
+ *(target++)= (x >> (3 - i)) & 1;
+ }
+
+ return count;
+}
+
+// convert hex to human readable binary string
+int hextobinstring(char *target, char *source)
+{
+ int length;
+
+ if(!(length= hextobinarray(target, source)))
+ return 0;
+ binarraytobinstring(target, target, length);
+ return length;
+}
+
+// convert binary array of 0x00/0x01 values to hex (safe to do in place as target will always be shorter than source)
+// return number of bits converted
+int binarraytohex(char *target, char *source, int length)
+{
+ unsigned char i, x;
+ int j = length;
+
+ if(j % 4)
+ return 0;
+
+ while(j)
+ {
+ for(i= x= 0 ; i < 4 ; ++i)
+ x += ( source[i] << (3 - i));
+ sprintf(target,"%X", x);
+ ++target;
+ source += 4;
+ j -= 4;
+ }
+ return length;
+}
+
+// convert binary array to human readable binary
+void binarraytobinstring(char *target, char *source, int length)
+{
+ int i;
+
+ for(i= 0 ; i < length ; ++i)
+ *(target++)= *(source++) + '0';
+ *target= '\0';
+}
+
+// return parity bit required to match type
+uint8_t GetParity( char *bits, uint8_t type, int length)
+{
+ int x;
+
+ for(x= 0 ; length > 0 ; --length)
+ x += bits[length - 1];
+ x %= 2;
+
+ return x ^ type;
+}
+
+// add HID parity to binary array: EVEN prefix for 1st half of ID, ODD suffix for 2nd half
+void wiegand_add_parity(char *target, char *source, char length)
+{
+ *(target++)= GetParity(source, EVEN, length / 2);
+ memcpy(target, source, length);
+ target += length;
+ *(target)= GetParity(source + length / 2, ODD, length / 2);
+}
#include <string.h>
#include <ctype.h>
#include <time.h>
+#include "data.h"
#ifndef MIN
# define MIN(a, b) (((a) < (b)) ? (a) : (b))
#ifndef MAX
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
+#define TRUE 1
+#define FALSE 0
+#define EVEN 0
+#define ODD 1
int ukbhit(void);
void print_hex(const uint8_t * data, const size_t len);
char * sprint_hex(const uint8_t * data, const size_t len);
+char * sprint_bin(const uint8_t * data, const size_t len);
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
uint64_t bytes_to_num(uint8_t* src, size_t len);
+char * printBits(size_t const size, void const * const ptr);
char param_getchar(const char *line, int paramnum);
uint8_t param_get8(const char *line, int paramnum);
int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
int param_getstr(const char *line, int paramnum, char * str);
+ int hextobinarray( char *target, char *source);
+ int hextobinstring( char *target, char *source);
+ int binarraytohex( char *target, char *source, int length);
+void binarraytobinstring(char *target, char *source, int length);
+uint8_t GetParity( char *string, uint8_t type, int length);
+void wiegand_add_parity(char *target, char *source, char length);
+
MOVE=ren
COPY=copy
PATHSEP=\\#
-FLASH_TOOL=winsrc\\prox.exe
+#FLASH_TOOL=winsrc\\prox.exe
+FLASH_TOOL=winsrc\\flash.exe
DETECTED_OS=Windows
endif
CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS) -Os
LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n
+
LIBS = -lgcc
THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(THUMBSRC))
#include "string.h"\r
#include "proxmark3.h"\r
\r
-//static UsbCommand txcmd;\r
-\r
bool cmd_receive(UsbCommand* cmd) {\r
\r
// Check if there is a usb packet available\r
#include "crc16.h"
+
unsigned short update_crc16( unsigned short crc, unsigned char c )
{
unsigned short i, v, tcrc = 0;
return ((crc >> 8) ^ tcrc)&0xffff;
}
+
+uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial) {
+
+ if (length == 0)
+ return (~remainder);
+
+ for (int byte = 0; byte < length; ++byte) {
+ remainder ^= (message[byte] << 8);
+ for (uint8_t bit = 8; bit > 0; --bit) {
+ if (remainder & 0x8000) {
+ remainder = (remainder << 1) ^ polynomial;
+ } else {
+ remainder = (remainder << 1);
+ }
+ }
+ }
+ return remainder;
+}
+
+uint16_t crc16_ccitt(uint8_t const *message, int length) {
+ return crc16(message, length, 0xffff, 0x1021);
+}
//-----------------------------------------------------------------------------
// CRC16
//-----------------------------------------------------------------------------
+#include <stdint.h>
#ifndef __CRC16_H
#define __CRC16_H
-
unsigned short update_crc16(unsigned short crc, unsigned char c);
-
+uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial);
+uint16_t crc16_ccitt(uint8_t const *message, int length);
#endif
--- /dev/null
+#include <stdint.h>
+#include <stddef.h>
+#include "crc32.h"
+
+#define htole32(x) (x)
+#define CRC32_PRESET 0xFFFFFFFF
+
+
+static void crc32_byte (uint32_t *crc, const uint8_t value);
+
+static void crc32_byte (uint32_t *crc, const uint8_t value) {
+ /* x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 */
+ const uint32_t poly = 0xEDB88320;
+
+ *crc ^= value;
+ for (int current_bit = 7; current_bit >= 0; current_bit--) {
+ int bit_out = (*crc) & 0x00000001;
+ *crc >>= 1;
+ if (bit_out)
+ *crc ^= poly;
+ }
+}
+
+void crc32 (const uint8_t *data, const size_t len, uint8_t *crc) {
+ uint32_t desfire_crc = CRC32_PRESET;
+ for (size_t i = 0; i < len; i++) {
+ crc32_byte (&desfire_crc, data[i]);
+ }
+
+ *((uint32_t *)(crc)) = htole32 (desfire_crc);
+}
+
+void crc32_append (uint8_t *data, const size_t len) {
+ crc32 (data, len, data + len);
+}
--- /dev/null
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+// CRC32
+//-----------------------------------------------------------------------------
+
+#ifndef __CRC32_H
+#define __CRC32_H
+
+void crc32 (const uint8_t *data, const size_t len, uint8_t *crc);
+void crc32_append (uint8_t *data, const size_t len);
+
+#endif
void usb_disable() {\r
// Disconnect the USB device\r
AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;\r
-// SpinDelay(100);\r
\r
// Clear all lingering interrupts\r
if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
\r
// Wait for a short while\r
for (volatile size_t i=0; i<0x100000; i++);\r
-// SpinDelay(100);\r
\r
// Reconnect USB reconnect\r
AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;\r
uint32_t packetSize, nbBytesRcv = 0;\r
uint32_t time_out = 0;\r
\r
- while (len)\r
- {\r
+ while (len) {\r
if (!usb_check()) break;\r
\r
if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
while(packetSize--)\r
data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];\r
pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);\r
- if (bank == AT91C_UDP_RX_DATA_BK0)\r
- {\r
+ if (bank == AT91C_UDP_RX_DATA_BK0) {\r
bank = AT91C_UDP_RX_DATA_BK1;\r
} else {\r
bank = AT91C_UDP_RX_DATA_BK0;\r
#define CMD_MIFARE_READBL 0x0620
#define CMD_MIFAREU_READBL 0x0720
+
#define CMD_MIFARE_READSC 0x0621
#define CMD_MIFAREU_READCARD 0x0721
+
#define CMD_MIFARE_WRITEBL 0x0622
#define CMD_MIFAREU_WRITEBL 0x0722
#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723