From: Martin Holst Swende Date: Fri, 6 Feb 2015 07:41:02 +0000 (+0100) Subject: Merge branch 'master' into GenericTracing X-Git-Tag: v2.0.0-rc1~23^2~5 X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/7d5ebac99397fe7661760259377a4f222fdb92cb?hp=-c Merge branch 'master' into GenericTracing Conflicts: armsrc/iso14443.c armsrc/iso14443a.c client/cmdhf.c client/cmdhf14b.c --- 7d5ebac99397fe7661760259377a4f222fdb92cb diff --combined armsrc/appmain.c index bca31533,cb1b9f73..7c50a51e --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@@ -23,7 -23,7 +23,7 @@@ #include "legicrf.h" #include - + #include "lfsampling.h" #ifdef WITH_LCD #include "LCD.h" #endif @@@ -42,12 -42,6 +42,6 @@@ int ToSendMax static int ToSendBit; struct common_area common_area __attribute__((section(".commonarea"))); - void BufferClear(void) - { - memset(BigBuf,0,sizeof(BigBuf)); - Dbprintf("Buffer cleared (%i bytes)",sizeof(BigBuf)); - } - void ToSendReset(void) { ToSendMax = -1; @@@ -246,7 -240,10 +240,10 @@@ void MeasureAntennaTuningHf(void void SimulateTagHfListen(void) { - uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET; + // ToDo: historically this used the free buffer, which was 2744 Bytes long. + // There might be a better size to be defined: + #define HF_14B_SNOOP_BUFFER_SIZE 2744 + uint8_t *dest = BigBuf_malloc(HF_14B_SNOOP_BUFFER_SIZE); uint8_t v = 0; int i; int p = 0; @@@ -281,7 -278,7 +278,7 @@@ p = 0; i++; - if(i >= FREE_BUFFER_SIZE) { + if(i >= HF_14B_SNOOP_BUFFER_SIZE) { break; } } @@@ -629,16 -626,17 +626,17 @@@ void UsbPacketReceived(uint8_t *packet switch(c->cmd) { #ifdef WITH_LF + case CMD_SET_LF_SAMPLING_CONFIG: + setSamplingConfig((sample_config *) c->d.asBytes); + break; case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K: - AcquireRawAdcSamples125k(c->arg[0]); - cmd_send(CMD_ACK,0,0,0,0,0); + cmd_send(CMD_ACK,SampleLF(),0,0,0,0); break; case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K: ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes); break; case CMD_LF_SNOOP_RAW_ADC_SAMPLES: - SnoopLFRawAdcSamples(c->arg[0], c->arg[1]); - cmd_send(CMD_ACK,0,0,0,0,0); + cmd_send(CMD_ACK,SnoopLF(),0,0,0,0); break; case CMD_HID_DEMOD_FSK: CmdHIDdemodFSK(c->arg[0], 0, 0, 1); @@@ -801,9 -799,18 +799,18 @@@ case CMD_MIFAREU_READBL: MifareUReadBlock(c->arg[0],c->d.asBytes); break; + case CMD_MIFAREUC_AUTH1: + MifareUC_Auth1(c->arg[0],c->d.asBytes); + break; + case CMD_MIFAREUC_AUTH2: + MifareUC_Auth2(c->arg[0],c->d.asBytes); + break; case CMD_MIFAREU_READCARD: MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes); - break; + break; + case CMD_MIFAREUC_READCARD: + MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes); + break; case CMD_MIFARE_READSC: MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); break; @@@ -858,6 -865,7 +865,7 @@@ case CMD_MIFARE_SNIFFER: SniffMifare(c->arg[0]); break; + #endif #ifdef WITH_ICLASS @@@ -881,7 -889,7 +889,7 @@@ break; case CMD_BUFF_CLEAR: - BufferClear(); + BigBuf_Clear(); break; case CMD_MEASURE_ANTENNA_TUNING: @@@ -905,17 -913,18 +913,18 @@@ case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: LED_B_ON(); + uint8_t *BigBuf = BigBuf_get_addr(); for(size_t i=0; iarg[1]; i += USB_CMD_DATA_SIZE) { size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE); - cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len); + cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,traceLen,BigBuf+c->arg[0]+i,len); } // Trigger a finish downloading signal with an ACK frame - cmd_send(CMD_ACK,0,0,0,0,0); + cmd_send(CMD_ACK,1,0,traceLen,getSamplingConfig(),sizeof(sample_config)); LED_B_OFF(); break; case CMD_DOWNLOADED_SIM_SAMPLES_125K: { - uint8_t *b = (uint8_t *)BigBuf; + uint8_t *b = BigBuf_get_addr(); memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE); cmd_send(CMD_ACK,0,0,0,0,0); break; @@@ -986,7 -995,7 +995,7 @@@ void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); - + clear_trace(); if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { /* Initialize common area */ memset(&common_area, 0, sizeof(common_area)); diff --combined armsrc/iso14443.c index 1191c5bf,6a2e4d6a..92d05782 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@@ -19,11 -19,11 +19,11 @@@ //static void GetSamplesFor14443(int weTx, int n); -#define DEMOD_TRACE_SIZE 4096 +/*#define DEMOD_TRACE_SIZE 4096 #define READER_TAG_BUFFER_SIZE 2048 #define TAG_READER_BUFFER_SIZE 2048 #define DEMOD_DMA_BUFFER_SIZE 1024 - +*/ //============================================================================= // An ISO 14443 Type B tag. We listen for commands from the reader, using // a UART kind of thing that's implemented in software. When we get a @@@ -39,87 -39,87 +39,87 @@@ //----------------------------------------------------------------------------- static void CodeIso14443bAsTag(const uint8_t *cmd, int len) { -- int i; -- -- ToSendReset(); -- -- // Transmit a burst of ones, as the initial thing that lets the -- // reader get phase sync. This (TR1) must be > 80/fs, per spec, -- // but tag that I've tried (a Paypass) exceeds that by a fair bit, -- // so I will too. -- for(i = 0; i < 20; i++) { -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } -- -- // Send SOF. -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- } -- for(i = 0; i < 2; i++) { -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } -- -- for(i = 0; i < len; i++) { -- int j; -- uint8_t b = cmd[i]; -- -- // Start bit -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- -- // Data bits -- for(j = 0; j < 8; j++) { -- if(b & 1) { -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } else { -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- } -- b >>= 1; -- } -- -- // Stop bit -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } -- -- // Send SOF. -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- } -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } -- -- // Convert from last byte pos to length -- ToSendMax++; -- -- // Add a few more for slop -- ToSendMax += 2; ++ int i; ++ ++ ToSendReset(); ++ ++ // Transmit a burst of ones, as the initial thing that lets the ++ // reader get phase sync. This (TR1) must be > 80/fs, per spec, ++ // but tag that I've tried (a Paypass) exceeds that by a fair bit, ++ // so I will too. ++ for(i = 0; i < 20; i++) { ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } ++ ++ // Send SOF. ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ } ++ for(i = 0; i < 2; i++) { ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } ++ ++ for(i = 0; i < len; i++) { ++ int j; ++ uint8_t b = cmd[i]; ++ ++ // Start bit ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ++ // Data bits ++ for(j = 0; j < 8; j++) { ++ if(b & 1) { ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } else { ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ } ++ b >>= 1; ++ } ++ ++ // Stop bit ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } ++ ++ // Send SOF. ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ } ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } ++ ++ // Convert from last byte pos to length ++ ToSendMax++; ++ ++ // Add a few more for slop ++ ToSendMax += 2; } //----------------------------------------------------------------------------- @@@ -127,19 -127,19 +127,19 @@@ // variables. //----------------------------------------------------------------------------- static struct { -- enum { -- STATE_UNSYNCD, -- STATE_GOT_FALLING_EDGE_OF_SOF, -- STATE_AWAITING_START_BIT, -- STATE_RECEIVING_DATA, -- STATE_ERROR_WAIT -- } state; -- uint16_t shiftReg; -- int bitCnt; -- int byteCnt; -- int byteCntMax; -- int posCnt; -- uint8_t *output; ++ enum { ++ STATE_UNSYNCD, ++ STATE_GOT_FALLING_EDGE_OF_SOF, ++ STATE_AWAITING_START_BIT, ++ STATE_RECEIVING_DATA, ++ STATE_ERROR_WAIT ++ } state; ++ uint16_t shiftReg; ++ int bitCnt; ++ int byteCnt; ++ int byteCntMax; ++ int posCnt; ++ uint8_t *output; } Uart; /* Receive & handle a bit coming from the reader. @@@ -153,126 -153,126 +153,126 @@@ */ static int Handle14443UartBit(int bit) { -- switch(Uart.state) { - case STATE_UNSYNCD: - LED_A_OFF(); - if(!bit) { - // we went low, so this could be the beginning - // of an SOF - Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; - Uart.posCnt = 0; - Uart.bitCnt = 0; - } - break; - - case STATE_GOT_FALLING_EDGE_OF_SOF: - Uart.posCnt++; - if(Uart.posCnt == 2) { - if(bit) { - if(Uart.bitCnt >= 10) { - // we've seen enough consecutive - // zeros that it's a valid SOF - Uart.posCnt = 0; - Uart.byteCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; - LED_A_ON(); // Indicate we got a valid SOF - } else { - // didn't stay down long enough - // before going high, error - Uart.state = STATE_ERROR_WAIT; - } - } else { - // do nothing, keep waiting - } - Uart.bitCnt++; - } - if(Uart.posCnt >= 4) Uart.posCnt = 0; - if(Uart.bitCnt > 14) { - // Give up if we see too many zeros without - // a one, too. - Uart.state = STATE_ERROR_WAIT; - } - break; - - case STATE_AWAITING_START_BIT: - Uart.posCnt++; - if(bit) { - if(Uart.posCnt > 25) { - // stayed high for too long between - // characters, error - Uart.state = STATE_ERROR_WAIT; - } - } else { - // falling edge, this starts the data byte - Uart.posCnt = 0; - Uart.bitCnt = 0; - Uart.shiftReg = 0; - Uart.state = STATE_RECEIVING_DATA; - LED_A_ON(); // Indicate we're receiving - } - break; - - case STATE_RECEIVING_DATA: - Uart.posCnt++; - if(Uart.posCnt == 2) { - // time to sample a bit - Uart.shiftReg >>= 1; - if(bit) { - Uart.shiftReg |= 0x200; - } - Uart.bitCnt++; - } - if(Uart.posCnt >= 4) { - Uart.posCnt = 0; - } - if(Uart.bitCnt == 10) { - if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) - { - // this is a data byte, with correct - // start and stop bits - Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff; - Uart.byteCnt++; - - if(Uart.byteCnt >= Uart.byteCntMax) { - // Buffer overflowed, give up - Uart.posCnt = 0; - Uart.state = STATE_ERROR_WAIT; - } else { - // so get the next byte now - Uart.posCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; - } - } else if(Uart.shiftReg == 0x000) { - // this is an EOF byte - LED_A_OFF(); // Finished receiving - return TRUE; - } else { - // this is an error - Uart.posCnt = 0; - Uart.state = STATE_ERROR_WAIT; - } - } - break; - - case STATE_ERROR_WAIT: - // We're all screwed up, so wait a little while - // for whatever went wrong to finish, and then - // start over. - Uart.posCnt++; - if(Uart.posCnt > 10) { - Uart.state = STATE_UNSYNCD; - } - break; - - default: - Uart.state = STATE_UNSYNCD; - break; - } - - // This row make the error blew circular buffer in hf 14b snoop - //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error - - return FALSE; ++ switch(Uart.state) { + case STATE_UNSYNCD: - LED_A_OFF(); - if(!bit) { - // we went low, so this could be the beginning - // of an SOF - Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; - Uart.posCnt = 0; - Uart.bitCnt = 0; - } - break; - - case STATE_GOT_FALLING_EDGE_OF_SOF: - Uart.posCnt++; - if(Uart.posCnt == 2) { - if(bit) { - if(Uart.bitCnt >= 10) { - // we've seen enough consecutive - // zeros that it's a valid SOF - Uart.posCnt = 0; - Uart.byteCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; - LED_A_ON(); // Indicate we got a valid SOF - } else { - // didn't stay down long enough - // before going high, error - Uart.state = STATE_ERROR_WAIT; - } - } else { - // do nothing, keep waiting - } - Uart.bitCnt++; - } - if(Uart.posCnt >= 4) Uart.posCnt = 0; - if(Uart.bitCnt > 14) { - // Give up if we see too many zeros without - // a one, too. - Uart.state = STATE_ERROR_WAIT; - } - break; - - case STATE_AWAITING_START_BIT: - Uart.posCnt++; - if(bit) { - if(Uart.posCnt > 25) { - // stayed high for too long between - // characters, error - Uart.state = STATE_ERROR_WAIT; - } - } else { - // falling edge, this starts the data byte - Uart.posCnt = 0; - Uart.bitCnt = 0; - Uart.shiftReg = 0; - Uart.state = STATE_RECEIVING_DATA; - LED_A_ON(); // Indicate we're receiving - } - break; - - case STATE_RECEIVING_DATA: - Uart.posCnt++; - if(Uart.posCnt == 2) { - // time to sample a bit - Uart.shiftReg >>= 1; - if(bit) { - Uart.shiftReg |= 0x200; - } - Uart.bitCnt++; - } - if(Uart.posCnt >= 4) { - Uart.posCnt = 0; - } - if(Uart.bitCnt == 10) { - if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) - { - // this is a data byte, with correct - // start and stop bits - Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff; - Uart.byteCnt++; - - if(Uart.byteCnt >= Uart.byteCntMax) { - // Buffer overflowed, give up - Uart.posCnt = 0; - Uart.state = STATE_ERROR_WAIT; - } else { - // so get the next byte now - Uart.posCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; - } - } else if(Uart.shiftReg == 0x000) { - // this is an EOF byte - LED_A_OFF(); // Finished receiving - return TRUE; - } else { - // this is an error - Uart.posCnt = 0; - Uart.state = STATE_ERROR_WAIT; - } - } - break; - - case STATE_ERROR_WAIT: - // We're all screwed up, so wait a little while - // for whatever went wrong to finish, and then - // start over. - Uart.posCnt++; - if(Uart.posCnt > 10) { - Uart.state = STATE_UNSYNCD; - } - break; - - default: - Uart.state = STATE_UNSYNCD; - break; - } - - // This row make the error blew circular buffer in hf 14b snoop - //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error - - return FALSE; ++ LED_A_OFF(); ++ if(!bit) { ++ // we went low, so this could be the beginning ++ // of an SOF ++ Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; ++ Uart.posCnt = 0; ++ Uart.bitCnt = 0; ++ } ++ break; ++ ++ case STATE_GOT_FALLING_EDGE_OF_SOF: ++ Uart.posCnt++; ++ if(Uart.posCnt == 2) { ++ if(bit) { ++ if(Uart.bitCnt >= 10) { ++ // we've seen enough consecutive ++ // zeros that it's a valid SOF ++ Uart.posCnt = 0; ++ Uart.byteCnt = 0; ++ Uart.state = STATE_AWAITING_START_BIT; ++ LED_A_ON(); // Indicate we got a valid SOF ++ } else { ++ // didn't stay down long enough ++ // before going high, error ++ Uart.state = STATE_ERROR_WAIT; ++ } ++ } else { ++ // do nothing, keep waiting ++ } ++ Uart.bitCnt++; ++ } ++ if(Uart.posCnt >= 4) Uart.posCnt = 0; ++ if(Uart.bitCnt > 14) { ++ // Give up if we see too many zeros without ++ // a one, too. ++ Uart.state = STATE_ERROR_WAIT; ++ } ++ break; ++ ++ case STATE_AWAITING_START_BIT: ++ Uart.posCnt++; ++ if(bit) { ++ if(Uart.posCnt > 25) { ++ // stayed high for too long between ++ // characters, error ++ Uart.state = STATE_ERROR_WAIT; ++ } ++ } else { ++ // falling edge, this starts the data byte ++ Uart.posCnt = 0; ++ Uart.bitCnt = 0; ++ Uart.shiftReg = 0; ++ Uart.state = STATE_RECEIVING_DATA; ++ LED_A_ON(); // Indicate we're receiving ++ } ++ break; ++ ++ case STATE_RECEIVING_DATA: ++ Uart.posCnt++; ++ if(Uart.posCnt == 2) { ++ // time to sample a bit ++ Uart.shiftReg >>= 1; ++ if(bit) { ++ Uart.shiftReg |= 0x200; ++ } ++ Uart.bitCnt++; ++ } ++ if(Uart.posCnt >= 4) { ++ Uart.posCnt = 0; ++ } ++ if(Uart.bitCnt == 10) { ++ if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) ++ { ++ // this is a data byte, with correct ++ // start and stop bits ++ Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff; ++ Uart.byteCnt++; ++ ++ if(Uart.byteCnt >= Uart.byteCntMax) { ++ // Buffer overflowed, give up ++ Uart.posCnt = 0; ++ Uart.state = STATE_ERROR_WAIT; ++ } else { ++ // so get the next byte now ++ Uart.posCnt = 0; ++ Uart.state = STATE_AWAITING_START_BIT; ++ } ++ } else if(Uart.shiftReg == 0x000) { ++ // this is an EOF byte ++ LED_A_OFF(); // Finished receiving ++ return TRUE; ++ } else { ++ // this is an error ++ Uart.posCnt = 0; ++ Uart.state = STATE_ERROR_WAIT; ++ } ++ } ++ break; ++ ++ case STATE_ERROR_WAIT: ++ // We're all screwed up, so wait a little while ++ // for whatever went wrong to finish, and then ++ // start over. ++ Uart.posCnt++; ++ if(Uart.posCnt > 10) { ++ Uart.state = STATE_UNSYNCD; ++ } ++ break; ++ ++ default: ++ Uart.state = STATE_UNSYNCD; ++ break; ++ } ++ ++ // This row make the error blew circular buffer in hf 14b snoop ++ //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error ++ ++ return FALSE; } //----------------------------------------------------------------------------- @@@ -286,42 -286,42 +286,42 @@@ //----------------------------------------------------------------------------- static int GetIso14443CommandFromReader(uint8_t *received, int *len, int maxLen) { -- uint8_t mask; -- int i, bit; -- -- // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen -- // only, since we are receiving, not transmitting). -- // Signal field is off with the appropriate LED -- LED_D_OFF(); -- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION); -- -- -- // Now run a `software UART' on the stream of incoming samples. -- Uart.output = received; -- Uart.byteCntMax = maxLen; -- Uart.state = STATE_UNSYNCD; -- -- for(;;) { -- WDT_HIT(); -- -- if(BUTTON_PRESS()) return FALSE; -- -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- AT91C_BASE_SSC->SSC_THR = 0x00; -- } -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { -- uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; -- -- mask = 0x80; -- for(i = 0; i < 8; i++, mask >>= 1) { -- bit = (b & mask); -- if(Handle14443UartBit(bit)) { -- *len = Uart.byteCnt; -- return TRUE; -- } -- } -- } -- } ++ uint8_t mask; ++ int i, bit; ++ ++ // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen ++ // only, since we are receiving, not transmitting). ++ // Signal field is off with the appropriate LED ++ LED_D_OFF(); ++ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION); ++ ++ ++ // Now run a `software UART' on the stream of incoming samples. ++ Uart.output = received; ++ Uart.byteCntMax = maxLen; ++ Uart.state = STATE_UNSYNCD; ++ ++ for(;;) { ++ WDT_HIT(); ++ ++ if(BUTTON_PRESS()) return FALSE; ++ ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ AT91C_BASE_SSC->SSC_THR = 0x00; ++ } ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { ++ uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; ++ ++ mask = 0x80; ++ for(i = 0; i < 8; i++, mask >>= 1) { ++ bit = (b & mask); ++ if(Handle14443UartBit(bit)) { ++ *len = Uart.byteCnt; ++ return TRUE; ++ } ++ } ++ } ++ } } //----------------------------------------------------------------------------- @@@ -330,99 -330,99 +330,99 @@@ //----------------------------------------------------------------------------- void SimulateIso14443Tag(void) { -- static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; -- static const uint8_t response1[] = { -- 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22, -- 0x00, 0x21, 0x85, 0x5e, 0xd7 -- }; ++ static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; ++ static const uint8_t response1[] = { ++ 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22, ++ 0x00, 0x21, 0x85, 0x5e, 0xd7 ++ }; -- uint8_t *resp; -- int respLen; ++ uint8_t *resp; ++ int respLen; - uint8_t *resp1 = (((uint8_t *)BigBuf) + 800); - uint8_t *resp1 = BigBuf_get_addr() + 800; -- int resp1Len; ++ uint8_t *resp1 = BigBuf_get_addr() + 800; ++ int resp1Len; - uint8_t *receivedCmd = (uint8_t *)BigBuf; - uint8_t *receivedCmd = BigBuf_get_addr(); -- int len; ++ uint8_t *receivedCmd = BigBuf_get_addr(); ++ int len; -- int i; ++ int i; -- int cmdsRecvd = 0; ++ int cmdsRecvd = 0; -- FpgaDownloadAndGo(FPGA_BITSTREAM_HF); -- memset(receivedCmd, 0x44, 400); ++ FpgaDownloadAndGo(FPGA_BITSTREAM_HF); ++ memset(receivedCmd, 0x44, 400); -- CodeIso14443bAsTag(response1, sizeof(response1)); -- memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax; ++ CodeIso14443bAsTag(response1, sizeof(response1)); ++ memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax; -- // We need to listen to the high-frequency, peak-detected path. -- SetAdcMuxFor(GPIO_MUXSEL_HIPKD); -- FpgaSetupSsc(); ++ // We need to listen to the high-frequency, peak-detected path. ++ SetAdcMuxFor(GPIO_MUXSEL_HIPKD); ++ FpgaSetupSsc(); -- cmdsRecvd = 0; ++ cmdsRecvd = 0; -- for(;;) { -- uint8_t b1, b2; ++ for(;;) { ++ uint8_t b1, b2; -- if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) { ++ if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) { Dbprintf("button pressed, received %d commands", cmdsRecvd); break; -- } -- -- // Good, look at the command now. -- -- if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) { -- resp = resp1; respLen = resp1Len; -- } else { -- Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd); -- // And print whether the CRC fails, just for good measure -- ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2); -- if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) { -- // Not so good, try again. -- DbpString("+++CRC fail"); -- } else { -- DbpString("CRC passes"); -- } -- break; -- } -- -- memset(receivedCmd, 0x44, 32); -- -- cmdsRecvd++; -- -- if(cmdsRecvd > 0x30) { -- DbpString("many commands later..."); -- break; -- } -- -- if(respLen <= 0) continue; -- -- // Modulate BPSK -- // Signal field is off with the appropriate LED -- LED_D_OFF(); -- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK); -- AT91C_BASE_SSC->SSC_THR = 0xff; -- FpgaSetupSsc(); -- -- // Transmit the response. -- i = 0; -- for(;;) { -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- uint8_t b = resp[i]; -- -- AT91C_BASE_SSC->SSC_THR = b; -- -- i++; -- if(i > respLen) { -- break; -- } -- } -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { -- volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; -- (void)b; -- } -- } -- } ++ } ++ ++ // Good, look at the command now. ++ ++ if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) { ++ resp = resp1; respLen = resp1Len; ++ } else { ++ Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd); ++ // And print whether the CRC fails, just for good measure ++ ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2); ++ if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) { ++ // Not so good, try again. ++ DbpString("+++CRC fail"); ++ } else { ++ DbpString("CRC passes"); ++ } ++ break; ++ } ++ ++ memset(receivedCmd, 0x44, 32); ++ ++ cmdsRecvd++; ++ ++ if(cmdsRecvd > 0x30) { ++ DbpString("many commands later..."); ++ break; ++ } ++ ++ if(respLen <= 0) continue; ++ ++ // Modulate BPSK ++ // Signal field is off with the appropriate LED ++ LED_D_OFF(); ++ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK); ++ AT91C_BASE_SSC->SSC_THR = 0xff; ++ FpgaSetupSsc(); ++ ++ // Transmit the response. ++ i = 0; ++ for(;;) { ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ uint8_t b = resp[i]; ++ ++ AT91C_BASE_SSC->SSC_THR = b; ++ ++ i++; ++ if(i > respLen) { ++ break; ++ } ++ } ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { ++ volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; ++ (void)b; ++ } ++ } ++ } } //============================================================================= @@@ -433,25 -433,25 +433,25 @@@ //============================================================================= static struct { -- enum { -- DEMOD_UNSYNCD, -- DEMOD_PHASE_REF_TRAINING, -- DEMOD_AWAITING_FALLING_EDGE_OF_SOF, -- DEMOD_GOT_FALLING_EDGE_OF_SOF, -- DEMOD_AWAITING_START_BIT, -- DEMOD_RECEIVING_DATA, -- DEMOD_ERROR_WAIT -- } state; -- int bitCount; -- int posCount; -- int thisBit; -- int metric; -- int metricN; -- uint16_t shiftReg; -- uint8_t *output; -- int len; -- int sumI; -- int sumQ; ++ enum { ++ DEMOD_UNSYNCD, ++ DEMOD_PHASE_REF_TRAINING, ++ DEMOD_AWAITING_FALLING_EDGE_OF_SOF, ++ DEMOD_GOT_FALLING_EDGE_OF_SOF, ++ DEMOD_AWAITING_START_BIT, ++ DEMOD_RECEIVING_DATA, ++ DEMOD_ERROR_WAIT ++ } state; ++ int bitCount; ++ int posCount; ++ int thisBit; ++ int metric; ++ int metricN; ++ uint16_t shiftReg; ++ uint8_t *output; ++ int len; ++ int sumI; ++ int sumQ; } Demod; /* @@@ -467,251 -467,238 +467,266 @@@ */ static RAMFUNC int Handle14443SamplesDemod(int ci, int cq) { -- int v; ++ int v; -- // The soft decision on the bit uses an estimate of just the -- // quadrant of the reference angle, not the exact angle. ++ // The soft decision on the bit uses an estimate of just the ++ // quadrant of the reference angle, not the exact angle. #define MAKE_SOFT_DECISION() { \ -- if(Demod.sumI > 0) { \ -- v = ci; \ -- } else { \ -- v = -ci; \ -- } \ -- if(Demod.sumQ > 0) { \ -- v += cq; \ -- } else { \ -- v -= cq; \ -- } \ -- } -- -- switch(Demod.state) { -- case DEMOD_UNSYNCD: -- v = ci; -- if(v < 0) v = -v; -- if(cq > 0) { -- v += cq; -- } else { -- v -= cq; -- } -- if(v > 40) { -- Demod.posCount = 0; -- Demod.state = DEMOD_PHASE_REF_TRAINING; -- Demod.sumI = 0; -- Demod.sumQ = 0; -- } -- break; -- -- case DEMOD_PHASE_REF_TRAINING: -- if(Demod.posCount < 8) { -- Demod.sumI += ci; -- Demod.sumQ += cq; -- } else if(Demod.posCount > 100) { -- // error, waited too long -- Demod.state = DEMOD_UNSYNCD; -- } else { -- MAKE_SOFT_DECISION(); -- if(v < 0) { -- Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF; -- Demod.posCount = 0; -- } -- } -- Demod.posCount++; -- break; -- -- case DEMOD_AWAITING_FALLING_EDGE_OF_SOF: -- MAKE_SOFT_DECISION(); -- if(v < 0) { -- Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF; -- Demod.posCount = 0; -- } else { -- if(Demod.posCount > 100) { -- Demod.state = DEMOD_UNSYNCD; -- } -- } -- Demod.posCount++; -- break; -- -- case DEMOD_GOT_FALLING_EDGE_OF_SOF: -- MAKE_SOFT_DECISION(); -- if(v > 0) { -- if(Demod.posCount < 12) { -- Demod.state = DEMOD_UNSYNCD; -- } else { -- LED_C_ON(); // Got SOF -- Demod.state = DEMOD_AWAITING_START_BIT; -- Demod.posCount = 0; -- Demod.len = 0; -- Demod.metricN = 0; -- Demod.metric = 0; -- } -- } else { -- if(Demod.posCount > 100) { -- Demod.state = DEMOD_UNSYNCD; -- } -- } -- Demod.posCount++; -- break; -- -- case DEMOD_AWAITING_START_BIT: -- MAKE_SOFT_DECISION(); -- if(v > 0) { -- if(Demod.posCount > 10) { -- Demod.state = DEMOD_UNSYNCD; -- } -- } else { -- Demod.bitCount = 0; -- Demod.posCount = 1; -- Demod.thisBit = v; -- Demod.shiftReg = 0; -- Demod.state = DEMOD_RECEIVING_DATA; -- } -- break; -- -- case DEMOD_RECEIVING_DATA: -- MAKE_SOFT_DECISION(); -- if(Demod.posCount == 0) { -- Demod.thisBit = v; -- Demod.posCount = 1; -- } else { -- Demod.thisBit += v; -- -- if(Demod.thisBit > 0) { -- Demod.metric += Demod.thisBit; -- } else { -- Demod.metric -= Demod.thisBit; -- } -- (Demod.metricN)++; -- -- Demod.shiftReg >>= 1; -- if(Demod.thisBit > 0) { -- Demod.shiftReg |= 0x200; -- } -- -- Demod.bitCount++; -- if(Demod.bitCount == 10) { -- uint16_t s = Demod.shiftReg; -- if((s & 0x200) && !(s & 0x001)) { -- uint8_t b = (s >> 1); -- Demod.output[Demod.len] = b; -- Demod.len++; -- Demod.state = DEMOD_AWAITING_START_BIT; -- } else if(s == 0x000) { -- // This is EOF -- LED_C_OFF(); -- Demod.state = DEMOD_UNSYNCD; -- return TRUE; -- } else { -- Demod.state = DEMOD_UNSYNCD; -- } -- } -- Demod.posCount = 0; -- } -- break; -- -- default: -- Demod.state = DEMOD_UNSYNCD; -- break; -- } -- -- if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized... -- return FALSE; - } ++ if(Demod.sumI > 0) { \ ++ v = ci; \ ++ } else { \ ++ v = -ci; \ ++ } \ ++ if(Demod.sumQ > 0) { \ ++ v += cq; \ ++ } else { \ ++ v -= cq; \ ++ } \ ++ } + ++ switch(Demod.state) { ++ case DEMOD_UNSYNCD: ++ v = ci; ++ if(v < 0) v = -v; ++ if(cq > 0) { ++ v += cq; ++ } else { ++ v -= cq; ++ } ++ if(v > 40) { ++ Demod.posCount = 0; ++ Demod.state = DEMOD_PHASE_REF_TRAINING; ++ Demod.sumI = 0; ++ Demod.sumQ = 0; ++ } ++ break; ++ ++ case DEMOD_PHASE_REF_TRAINING: ++ if(Demod.posCount < 8) { ++ Demod.sumI += ci; ++ Demod.sumQ += cq; ++ } else if(Demod.posCount > 100) { ++ // error, waited too long ++ Demod.state = DEMOD_UNSYNCD; ++ } else { ++ MAKE_SOFT_DECISION(); ++ if(v < 0) { ++ Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF; ++ Demod.posCount = 0; ++ } ++ } ++ Demod.posCount++; ++ break; ++ ++ case DEMOD_AWAITING_FALLING_EDGE_OF_SOF: ++ MAKE_SOFT_DECISION(); ++ if(v < 0) { ++ Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF; ++ Demod.posCount = 0; ++ } else { ++ if(Demod.posCount > 100) { ++ Demod.state = DEMOD_UNSYNCD; ++ } ++ } ++ Demod.posCount++; ++ break; ++ ++ case DEMOD_GOT_FALLING_EDGE_OF_SOF: ++ MAKE_SOFT_DECISION(); ++ if(v > 0) { ++ if(Demod.posCount < 12) { ++ Demod.state = DEMOD_UNSYNCD; ++ } else { ++ LED_C_ON(); // Got SOF ++ Demod.state = DEMOD_AWAITING_START_BIT; ++ Demod.posCount = 0; ++ Demod.len = 0; ++ Demod.metricN = 0; ++ Demod.metric = 0; ++ } ++ } else { ++ if(Demod.posCount > 100) { ++ Demod.state = DEMOD_UNSYNCD; ++ } ++ } ++ Demod.posCount++; ++ break; ++ ++ case DEMOD_AWAITING_START_BIT: ++ MAKE_SOFT_DECISION(); ++ if(v > 0) { ++ if(Demod.posCount > 10) { ++ Demod.state = DEMOD_UNSYNCD; ++ } ++ } else { ++ Demod.bitCount = 0; ++ Demod.posCount = 1; ++ Demod.thisBit = v; ++ Demod.shiftReg = 0; ++ Demod.state = DEMOD_RECEIVING_DATA; ++ } ++ break; ++ ++ case DEMOD_RECEIVING_DATA: ++ MAKE_SOFT_DECISION(); ++ if(Demod.posCount == 0) { ++ Demod.thisBit = v; ++ Demod.posCount = 1; ++ } else { ++ Demod.thisBit += v; ++ ++ if(Demod.thisBit > 0) { ++ Demod.metric += Demod.thisBit; ++ } else { ++ Demod.metric -= Demod.thisBit; ++ } ++ (Demod.metricN)++; ++ ++ Demod.shiftReg >>= 1; ++ if(Demod.thisBit > 0) { ++ Demod.shiftReg |= 0x200; ++ } ++ ++ Demod.bitCount++; ++ if(Demod.bitCount == 10) { ++ uint16_t s = Demod.shiftReg; ++ if((s & 0x200) && !(s & 0x001)) { ++ uint8_t b = (s >> 1); ++ Demod.output[Demod.len] = b; ++ Demod.len++; ++ Demod.state = DEMOD_AWAITING_START_BIT; ++ } else if(s == 0x000) { ++ // This is EOF ++ LED_C_OFF(); ++ Demod.state = DEMOD_UNSYNCD; ++ return TRUE; ++ } else { ++ Demod.state = DEMOD_UNSYNCD; ++ } ++ } ++ Demod.posCount = 0; ++ } ++ break; ++ ++ default: ++ Demod.state = DEMOD_UNSYNCD; ++ break; ++ } ++ ++ if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized... ++ return FALSE; ++} +static void DemodReset() +{ + // Clear out the state of the "UART" that receives from the tag. - Demod.output = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; + Demod.len = 0; + Demod.state = DEMOD_UNSYNCD; + memset(Demod.output, 0x00, MAX_FRAME_SIZE); - ++} ++static void DemodInit(uint8_t *data) ++{ ++ Demod.output = data; ++ DemodReset(); +} + +static void UartReset() +{ - // And the UART that receives from the reader - Uart.output = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; + Uart.byteCntMax = MAX_FRAME_SIZE; + Uart.state = STATE_UNSYNCD; + Uart.byteCnt = 0; + Uart.bitCnt = 0; +} ++static void UartInit(uint8_t *data) ++{ ++ Uart.output = data; ++ UartReset(); + } /* - * Demodulate the samples we received from the tag + * Demodulate the samples we received from the tag, also log to tracebuffer * weTx: set to 'TRUE' if we behave like a reader * set to 'FALSE' if we behave like a snooper * quiet: set to 'TRUE' to disable debug output */ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) { -- int max = 0; -- int gotFrame = FALSE; - -//# define DMA_BUFFER_SIZE 8 - uint8_t *dmaBuf; -- -- int lastRxCounter; - uint8_t *upTo; -- -- int ci, cq; - - int samples = 0; - - // Clear out the state of the "UART" that receives from the tag. - uint8_t *BigBuf = BigBuf_get_addr(); - memset(BigBuf, 0x00, 400); - Demod.output = BigBuf; - Demod.len = 0; - Demod.state = DEMOD_UNSYNCD; - - // And the UART that receives from the reader - Uart.output = BigBuf + 1024; - Uart.byteCntMax = 100; - Uart.state = STATE_UNSYNCD; - - // Setup for the DMA. - dmaBuf = BigBuf + 32; - upTo = dmaBuf; - lastRxCounter = DEMOD_DMA_BUFFER_SIZE; - FpgaSetupSscDma(dmaBuf, DEMOD_DMA_BUFFER_SIZE); - - // Signal field is ON with the appropriate LED: - if (weTx) LED_D_ON(); else LED_D_OFF(); - // And put the FPGA in the appropriate mode - FpgaWriteConfWord( - FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | - (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); - - for(;;) { - int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR; - if(behindBy > max) max = behindBy; - - while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DEMOD_DMA_BUFFER_SIZE-1)) - > 2) - { - ci = upTo[0]; - cq = upTo[1]; - upTo += 2; - if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) { - upTo -= DEMOD_DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE; - } - lastRxCounter -= 2; - if(lastRxCounter <= 0) { - lastRxCounter += DEMOD_DMA_BUFFER_SIZE; - } - - samples += 2; - - Handle14443UartBit(1); - Handle14443UartBit(1); - - if(Handle14443SamplesDemod(ci, cq)) { - gotFrame = 1; - } - } - - if(samples > 2000) { - break; - } - } - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; - if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len); ++ int max = 0; ++ int gotFrame = FALSE; ++ int lastRxCounter, ci, cq, samples = 0; ++ ++ // Allocate memory from BigBuf for some buffers ++ // free all previous allocations first ++ BigBuf_free(); ++ ++ // The command (reader -> tag) that we're receiving. ++ uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); ++ ++ // The response (tag -> reader) that we're receiving. ++ uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE); ++ ++ // The DMA buffer, used to stream samples from the FPGA ++ uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + - int samples = 0; ++ // Set up the demodulator for tag -> reader responses. ++ DemodInit(receivedResponse); ++ // Set up the demodulator for the reader -> tag commands ++ UartInit(receivedCmd); + - DemodReset(); - UartReset(); ++ // Setup and start DMA. ++ FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE); + - // The DMA buffer, used to stream samples from the FPGA - int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; - int8_t *upTo= dmaBuf; ++ uint8_t *upTo= dmaBuf; + lastRxCounter = DMA_BUFFER_SIZE; - FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); + - // Signal field is ON with the appropriate LED: - if (weTx) LED_D_ON(); else LED_D_OFF(); - // And put the FPGA in the appropriate mode - FpgaWriteConfWord( - FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | - (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); ++ // Signal field is ON with the appropriate LED: ++ if (weTx) LED_D_ON(); else LED_D_OFF(); ++ // And put the FPGA in the appropriate mode ++ FpgaWriteConfWord( ++ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | ++ (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); + - for(;;) { - int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR; - if(behindBy > max) max = behindBy; ++ for(;;) { ++ int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR; ++ if(behindBy > max) max = behindBy; + + while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1)) - > 2) - { - ci = upTo[0]; - cq = upTo[1]; - upTo += 2; ++ > 2) ++ { ++ ci = upTo[0]; ++ cq = upTo[1]; ++ upTo += 2; + if(upTo - dmaBuf > DMA_BUFFER_SIZE) { + upTo -= DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; ++ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } - lastRxCounter -= 2; - if(lastRxCounter <= 0) { ++ } ++ lastRxCounter -= 2; ++ if(lastRxCounter <= 0) { + lastRxCounter += DMA_BUFFER_SIZE; - } ++ } + - samples += 2; ++ samples += 2; + - Handle14443UartBit(1); - Handle14443UartBit(1); ++ Handle14443UartBit(1); ++ Handle14443UartBit(1); + - if(Handle14443SamplesDemod(ci, cq)) { - gotFrame = 1; - } - } ++ if(Handle14443SamplesDemod(ci, cq)) { ++ gotFrame = 1; ++ } ++ } + - if(samples > 2000) { - break; - } - } - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; - if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len); ++ if(samples > 2000) { ++ break; ++ } ++ } ++ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; ++ if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len); + //Tracing + if (tracing && Demod.len > 0) { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(Demod.output , Demod.len, parity); + LogTrace(Demod.output,Demod.len, 0, 0, parity, FALSE); + } } //----------------------------------------------------------------------------- @@@ -721,29 -708,29 +736,29 @@@ //----------------------------------------------------------------------------- /*static void GetSamplesFor14443(int weTx, int n) { -- uint8_t *dest = (uint8_t *)BigBuf; -- int c; -- -- FpgaWriteConfWord( -- FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | -- (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); -- -- c = 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)) { -- int8_t b; -- b = (int8_t)AT91C_BASE_SSC->SSC_RHR; -- -- dest[c++] = (uint8_t)b; -- -- if(c >= n) { -- break; -- } -- } -- } ++ uint8_t *dest = (uint8_t *)BigBuf; ++ int c; ++ ++ FpgaWriteConfWord( ++ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | ++ (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); ++ ++ c = 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)) { ++ int8_t b; ++ b = (int8_t)AT91C_BASE_SSC->SSC_RHR; ++ ++ dest[c++] = (uint8_t)b; ++ ++ if(c >= n) { ++ break; ++ } ++ } ++ } }*/ //----------------------------------------------------------------------------- @@@ -751,49 -738,49 +766,49 @@@ //----------------------------------------------------------------------------- static void TransmitFor14443(void) { -- int c; ++ int c; -- FpgaSetupSsc(); ++ FpgaSetupSsc(); -- while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- AT91C_BASE_SSC->SSC_THR = 0xff; -- } ++ while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ AT91C_BASE_SSC->SSC_THR = 0xff; ++ } -- // Signal field is ON with the appropriate Red LED ++ // Signal field is ON with the appropriate Red LED LED_D_ON(); // Signal we are transmitting with the Green LED LED_B_ON(); FpgaWriteConfWord( -- FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); -- -- for(c = 0; c < 10;) { -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- AT91C_BASE_SSC->SSC_THR = 0xff; -- c++; -- } -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { -- volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; -- (void)r; -- } -- WDT_HIT(); -- } -- -- c = 0; -- for(;;) { -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- AT91C_BASE_SSC->SSC_THR = ToSend[c]; -- c++; -- if(c >= ToSendMax) { -- break; -- } -- } -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { -- volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; -- (void)r; -- } -- WDT_HIT(); -- } -- LED_B_OFF(); // Finished sending ++ FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); ++ ++ for(c = 0; c < 10;) { ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ AT91C_BASE_SSC->SSC_THR = 0xff; ++ c++; ++ } ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { ++ volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; ++ (void)r; ++ } ++ WDT_HIT(); ++ } ++ ++ c = 0; ++ for(;;) { ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ AT91C_BASE_SSC->SSC_THR = ToSend[c]; ++ c++; ++ if(c >= ToSendMax) { ++ break; ++ } ++ } ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { ++ volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; ++ (void)r; ++ } ++ WDT_HIT(); ++ } ++ LED_B_OFF(); // Finished sending } //----------------------------------------------------------------------------- @@@ -802,54 -789,54 +817,54 @@@ //----------------------------------------------------------------------------- static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { -- int i, j; -- uint8_t b; -- -- ToSendReset(); -- -- // Establish initial reference level -- for(i = 0; i < 40; i++) { -- ToSendStuffBit(1); -- } -- // Send SOF -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(0); -- } -- -- for(i = 0; i < len; i++) { -- // Stop bits/EGT -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- // Start bit -- ToSendStuffBit(0); -- // Data bits -- b = cmd[i]; -- for(j = 0; j < 8; j++) { -- if(b & 1) { -- ToSendStuffBit(1); -- } else { -- ToSendStuffBit(0); -- } -- b >>= 1; -- } -- } -- // Send EOF -- ToSendStuffBit(1); -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(0); -- } -- for(i = 0; i < 8; i++) { -- ToSendStuffBit(1); -- } -- -- // And then a little more, to make sure that the last character makes -- // it out before we switch to rx mode. -- for(i = 0; i < 24; i++) { -- ToSendStuffBit(1); -- } -- -- // Convert from last character reference to length -- ToSendMax++; ++ int i, j; ++ uint8_t b; ++ ++ ToSendReset(); ++ ++ // Establish initial reference level ++ for(i = 0; i < 40; i++) { ++ ToSendStuffBit(1); ++ } ++ // Send SOF ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(0); ++ } ++ ++ for(i = 0; i < len; i++) { ++ // Stop bits/EGT ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ // Start bit ++ ToSendStuffBit(0); ++ // Data bits ++ b = cmd[i]; ++ for(j = 0; j < 8; j++) { ++ if(b & 1) { ++ ToSendStuffBit(1); ++ } else { ++ ToSendStuffBit(0); ++ } ++ b >>= 1; ++ } ++ } ++ // Send EOF ++ ToSendStuffBit(1); ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(0); ++ } ++ for(i = 0; i < 8; i++) { ++ ToSendStuffBit(1); ++ } ++ ++ // And then a little more, to make sure that the last character makes ++ // it out before we switch to rx mode. ++ for(i = 0; i < 24; i++) { ++ ToSendStuffBit(1); ++ } ++ ++ // Convert from last character reference to length ++ ToSendMax++; } //----------------------------------------------------------------------------- @@@ -862,23 -849,9 +877,23 @@@ //----------------------------------------------------------------------------- void AcquireRawAdcSamplesIso14443(uint32_t parameter) { -- uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; ++ uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; -- SendRawCommand14443B(sizeof(cmd1),1,1,cmd1); ++ SendRawCommand14443B(sizeof(cmd1),1,1,cmd1); +} + +/** + Convenience function to encode, transmit and trace iso 14443b comms + **/ +static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) +{ + CodeIso14443bAsReader(cmd, len); + TransmitFor14443(); + if (tracing) { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(cmd, len, parity); + LogTrace(cmd,len, 0, 0, parity, TRUE); + } } //----------------------------------------------------------------------------- @@@ -892,129 -865,126 +907,129 @@@ //----------------------------------------------------------------------------- void ReadSTMemoryIso14443(uint32_t dwLast) { - uint8_t i = 0x00; - - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // Make sure that we start from off, since the tags are stateful; - // confusing things will happen if we don't reset them between reads. - LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); - - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); - - // Now give it time to spin up. - // Signal field is on with the appropriate LED - LED_D_ON(); - FpgaWriteConfWord( - FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); - SpinDelay(200); - - // First command: wake up the tag using the INITIATE command - uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); + clear_trace(); + set_tracing(TRUE); + - uint8_t i = 0x00; ++ uint8_t i = 0x00; + - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // Make sure that we start from off, since the tags are stateful; - // confusing things will happen if we don't reset them between reads. - LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); ++ FpgaDownloadAndGo(FPGA_BITSTREAM_HF); ++ // Make sure that we start from off, since the tags are stateful; ++ // confusing things will happen if we don't reset them between reads. ++ LED_D_OFF(); ++ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); ++ SpinDelay(200); + - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); ++ SetAdcMuxFor(GPIO_MUXSEL_HIPKD); ++ FpgaSetupSsc(); + - // Now give it time to spin up. - // Signal field is on with the appropriate LED - LED_D_ON(); - FpgaWriteConfWord( - FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); - SpinDelay(200); ++ // Now give it time to spin up. ++ // Signal field is on with the appropriate LED ++ LED_D_ON(); ++ FpgaWriteConfWord( ++ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); ++ SpinDelay(200); + - // First command: wake up the tag using the INITIATE command - uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; ++ // First command: wake up the tag using the INITIATE command ++ uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; + + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); // LED_A_ON(); -- GetSamplesFor14443Demod(TRUE, 2000,TRUE); ++ GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); -- if (Demod.len == 0) { ++ if (Demod.len == 0) { DbpString("No response from tag"); return; -- } else { ++ } else { Dbprintf("Randomly generated UID from tag (+ 2 byte CRC): %x %x %x", Demod.output[0], Demod.output[1],Demod.output[2]); -- } -- // There is a response, SELECT the uid -- DbpString("Now SELECT tag:"); -- cmd1[0] = 0x0E; // 0x0E is SELECT -- cmd1[1] = Demod.output[0]; -- ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); ++ } ++ // There is a response, SELECT the uid ++ DbpString("Now SELECT tag:"); ++ cmd1[0] = 0x0E; // 0x0E is SELECT ++ cmd1[1] = Demod.output[0]; ++ ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); + // LED_A_ON(); -- GetSamplesFor14443Demod(TRUE, 2000,TRUE); ++ GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); -- if (Demod.len != 3) { ++ if (Demod.len != 3) { Dbprintf("Expected 3 bytes from tag, got %d", Demod.len); return; -- } -- // Check the CRC of the answer: -- ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]); -- if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) { ++ } ++ // Check the CRC of the answer: ++ ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]); ++ if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) { DbpString("CRC Error reading select response."); return; -- } -- // Check response from the tag: should be the same UID as the command we just sent: -- if (cmd1[1] != Demod.output[0]) { ++ } ++ // Check response from the tag: should be the same UID as the command we just sent: ++ if (cmd1[1] != Demod.output[0]) { Dbprintf("Bad response to SELECT from Tag, aborting: %x %x", cmd1[1], Demod.output[0]); return; -- } -- // Tag is now selected, -- // First get the tag's UID: -- cmd1[0] = 0x0B; -- ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]); - CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one - TransmitFor14443(); ++ } ++ // Tag is now selected, ++ // First get the tag's UID: ++ cmd1[0] = 0x0B; ++ ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]); + CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one + // LED_A_ON(); -- GetSamplesFor14443Demod(TRUE, 2000,TRUE); ++ GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); -- if (Demod.len != 10) { ++ if (Demod.len != 10) { Dbprintf("Expected 10 bytes from tag, got %d", Demod.len); return; -- } -- // The check the CRC of the answer (use cmd1 as temporary variable): -- ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]); -- if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) { ++ } ++ // The check the CRC of the answer (use cmd1 as temporary variable): ++ ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]); ++ if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) { Dbprintf("CRC Error reading block! - Below: expected, got %x %x", (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]); // Do not return;, let's go on... (we should retry, maybe ?) -- } -- Dbprintf("Tag UID (64 bits): %08x %08x", ++ } ++ Dbprintf("Tag UID (64 bits): %08x %08x", (Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4], (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]); -- // Now loop to read all 16 blocks, address from 0 to last block -- Dbprintf("Tag memory dump, block 0 to %d",dwLast); -- cmd1[0] = 0x08; -- i = 0x00; -- dwLast++; -- for (;;) { -- if (i == dwLast) { -- DbpString("System area block (0xff):"); -- i = 0xff; -- } -- cmd1[1] = i; -- ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); ++ // Now loop to read all 16 blocks, address from 0 to last block ++ Dbprintf("Tag memory dump, block 0 to %d",dwLast); ++ cmd1[0] = 0x08; ++ i = 0x00; ++ dwLast++; ++ for (;;) { ++ if (i == dwLast) { ++ DbpString("System area block (0xff):"); ++ i = 0xff; ++ } ++ cmd1[1] = i; ++ ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); + // LED_A_ON(); -- GetSamplesFor14443Demod(TRUE, 2000,TRUE); ++ GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); -- if (Demod.len != 6) { // Check if we got an answer from the tag ++ if (Demod.len != 6) { // Check if we got an answer from the tag DbpString("Expected 6 bytes from tag, got less..."); return; -- } -- // The check the CRC of the answer (use cmd1 as temporary variable): -- ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]); -- if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) { ++ } ++ // The check the CRC of the answer (use cmd1 as temporary variable): ++ ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]); ++ if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) { Dbprintf("CRC Error reading block! - Below: expected, got %x %x", (cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5]); // Do not return;, let's go on... (we should retry, maybe ?) -- } -- // Now print out the memory location: -- Dbprintf("Address=%x, Contents=%x, CRC=%x", i, ++ } ++ // Now print out the memory location: ++ Dbprintf("Address=%x, Contents=%x, CRC=%x", i, (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], (Demod.output[4]<<8)+Demod.output[5]); -- if (i == 0xff) { ++ if (i == 0xff) { break; -- } -- i++; -- } ++ } ++ i++; ++ } } @@@ -1037,136 -1007,171 +1052,137 @@@ */ void RAMFUNC SnoopIso14443(void) { -- // We won't start recording the frames that we acquire until we trigger; -- // a good trigger condition to get started is probably when we see a -- // response from the tag. -- int triggered = TRUE; ++ // We won't start recording the frames that we acquire until we trigger; ++ // a good trigger condition to get started is probably when we see a ++ // response from the tag. ++ int triggered = TRUE; -- FpgaDownloadAndGo(FPGA_BITSTREAM_HF); ++ FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + BigBuf_free(); - // The command (reader -> tag) that we're working on receiving. - uint8_t *receivedCmd = BigBuf_malloc(READER_TAG_BUFFER_SIZE); - // The response (tag -> reader) that we're working on receiving. - uint8_t *receivedResponse = BigBuf_malloc(TAG_READER_BUFFER_SIZE); - - // As we receive stuff, we copy it from receivedCmd or receivedResponse - // into trace, along with its length and other annotations. - uint8_t *trace = BigBuf_get_addr(); - traceLen = 0; - - // The DMA buffer, used to stream samples from the FPGA. - uint8_t *dmaBuf = BigBuf_malloc(DEMOD_DMA_BUFFER_SIZE); - int lastRxCounter; - uint8_t *upTo; - int ci, cq; - int maxBehindBy = 0; - - // Count of samples received so far, so that we can include timing - // information in the trace buffer. - int samples = 0; - - // Initialize the trace buffer - memset(trace, 0x44, BigBuf_max_traceLen()); - - // Set up the demodulator for tag -> reader responses. - Demod.output = receivedResponse; - Demod.len = 0; - Demod.state = DEMOD_UNSYNCD; - - // And the reader -> tag commands - memset(&Uart, 0, sizeof(Uart)); - Uart.output = receivedCmd; - Uart.byteCntMax = 100; - Uart.state = STATE_UNSYNCD; - - // Print some debug information about the buffer sizes - Dbprintf("Snooping buffers initialized:"); - Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen()); - Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE); - Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE); - Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE); - - // And put the FPGA in the appropriate mode - // Signal field is off with the appropriate LED - LED_D_OFF(); - FpgaWriteConfWord( - FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | - FPGA_HF_READER_RX_XCORR_SNOOP); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - - // Setup for the DMA. - FpgaSetupSsc(); - upTo = dmaBuf; - lastRxCounter = DEMOD_DMA_BUFFER_SIZE; - FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE); - - LED_A_ON(); - - // And now we loop, receiving samples. - for(;;) { - int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & - (DEMOD_DMA_BUFFER_SIZE-1); - if(behindBy > maxBehindBy) { - maxBehindBy = behindBy; - if(behindBy > (9*DEMOD_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not? - Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); - goto done; - } - } - if(behindBy < 2) continue; - - ci = upTo[0]; - cq = upTo[1]; - upTo += 2; - lastRxCounter -= 2; - if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) { - upTo -= DEMOD_DMA_BUFFER_SIZE; - lastRxCounter += DEMOD_DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE; - } - - samples += 2; - -#define HANDLE_BIT_IF_BODY \ - if(triggered) { \ - trace[traceLen++] = ((samples >> 0) & 0xff); \ - trace[traceLen++] = ((samples >> 8) & 0xff); \ - trace[traceLen++] = ((samples >> 16) & 0xff); \ - trace[traceLen++] = ((samples >> 24) & 0xff); \ - trace[traceLen++] = 0; \ - trace[traceLen++] = 0; \ - trace[traceLen++] = 0; \ - trace[traceLen++] = 0; \ - trace[traceLen++] = Uart.byteCnt; \ - memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \ - traceLen += Uart.byteCnt; \ - if(traceLen > 1000) break; \ - } \ - /* And ready to receive another command. */ \ - memset(&Uart, 0, sizeof(Uart)); \ - Uart.output = receivedCmd; \ - Uart.byteCntMax = 100; \ - Uart.state = STATE_UNSYNCD; \ - /* And also reset the demod code, which might have been */ \ - /* false-triggered by the commands from the reader. */ \ - memset(&Demod, 0, sizeof(Demod)); \ - Demod.output = receivedResponse; \ - Demod.state = DEMOD_UNSYNCD; \ - - if(Handle14443UartBit(ci & 1)) { - HANDLE_BIT_IF_BODY - } - if(Handle14443UartBit(cq & 1)) { - HANDLE_BIT_IF_BODY - } - - if(Handle14443SamplesDemod(ci, cq)) { - // timestamp, as a count of samples - trace[traceLen++] = ((samples >> 0) & 0xff); - trace[traceLen++] = ((samples >> 8) & 0xff); - trace[traceLen++] = ((samples >> 16) & 0xff); - trace[traceLen++] = 0x80 | ((samples >> 24) & 0xff); - // correlation metric (~signal strength estimate) - if(Demod.metricN != 0) { - Demod.metric /= Demod.metricN; - } - trace[traceLen++] = ((Demod.metric >> 0) & 0xff); - trace[traceLen++] = ((Demod.metric >> 8) & 0xff); - trace[traceLen++] = ((Demod.metric >> 16) & 0xff); - trace[traceLen++] = ((Demod.metric >> 24) & 0xff); - // length - trace[traceLen++] = Demod.len; - memcpy(trace+traceLen, receivedResponse, Demod.len); - traceLen += Demod.len; - if(traceLen > BigBuf_max_traceLen()) { - DbpString("Reached trace limit"); - goto done; - } - triggered = TRUE; - LED_A_OFF(); - LED_B_ON(); + clear_trace(); + set_tracing(TRUE); + - // The DMA buffer, used to stream samples from the FPGA. - int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; - int lastRxCounter; - int8_t *upTo; - int ci, cq; - int maxBehindBy = 0; - - // Count of samples received so far, so that we can include timing - // information in the trace buffer. - int samples = 0; - - DemodReset(); - UartReset(); - - // Print some debug information about the buffer sizes - Dbprintf("Snooping buffers initialized:"); - Dbprintf(" Trace: %i bytes", TRACE_SIZE); ++ // The DMA buffer, used to stream samples from the FPGA ++ uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); ++ int lastRxCounter; ++ uint8_t *upTo; ++ int ci, cq; ++ int maxBehindBy = 0; ++ ++ // Count of samples received so far, so that we can include timing ++ // information in the trace buffer. ++ int samples = 0; + - // And ready to receive another response. - memset(&Demod, 0, sizeof(Demod)); - Demod.output = receivedResponse; - Demod.state = DEMOD_UNSYNCD; - } - WDT_HIT(); ++ DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); ++ UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); + - if(BUTTON_PRESS()) { - DbpString("cancelled"); - goto done; - } - } ++ // Print some debug information about the buffer sizes ++ Dbprintf("Snooping buffers initialized:"); ++ Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen()); + Dbprintf(" Reader -> tag: %i bytes", MAX_FRAME_SIZE); + Dbprintf(" tag -> Reader: %i bytes", MAX_FRAME_SIZE); + Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE); -done: + // Signal field is off with the appropriate LED + LED_D_OFF(); + + // And put the FPGA in the appropriate mode - FpgaWriteConfWord( - FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | - FPGA_HF_READER_RX_XCORR_SNOOP); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - - // Setup for the DMA. - FpgaSetupSsc(); - upTo = dmaBuf; ++ FpgaWriteConfWord( ++ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | ++ FPGA_HF_READER_RX_XCORR_SNOOP); ++ SetAdcMuxFor(GPIO_MUXSEL_HIPKD); ++ ++ // Setup for the DMA. ++ FpgaSetupSsc(); ++ upTo = dmaBuf; + lastRxCounter = DMA_BUFFER_SIZE; + FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); + uint8_t parity[MAX_PARITY_SIZE]; - LED_A_ON(); ++ LED_A_ON(); + - // And now we loop, receiving samples. - for(;;) { - int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & ++ // And now we loop, receiving samples. ++ for(;;) { ++ int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & + (DMA_BUFFER_SIZE-1); - if(behindBy > maxBehindBy) { - maxBehindBy = behindBy; - if(behindBy > (DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not? - Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); ++ if(behindBy > maxBehindBy) { ++ maxBehindBy = behindBy; ++ if(behindBy > (9*DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not? ++ Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); + break; - } - } - if(behindBy < 2) continue; - - ci = upTo[0]; - cq = upTo[1]; - upTo += 2; - lastRxCounter -= 2; ++ } ++ } ++ if(behindBy < 2) continue; ++ ++ ci = upTo[0]; ++ cq = upTo[1]; ++ upTo += 2; ++ lastRxCounter -= 2; + if(upTo - dmaBuf > DMA_BUFFER_SIZE) { + upTo -= DMA_BUFFER_SIZE; + lastRxCounter += DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; ++ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } ++ } + - samples += 2; ++ samples += 2; + + if(Handle14443UartBit(ci & 1)) { + if(triggered && tracing) { + GetParity(Uart.output, Uart.byteCnt, parity); + LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE); + } + if(Uart.byteCnt==0) Dbprintf("[1] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt); + + /* And ready to receive another command. */ + UartReset(); + /* And also reset the demod code, which might have been */ + /* false-triggered by the commands from the reader. */ + DemodReset(); + } - if(Handle14443UartBit(cq & 1)) { ++ if(Handle14443UartBit(cq & 1)) { + if(triggered && tracing) { + GetParity(Uart.output, Uart.byteCnt, parity); + LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE); + } + if(Uart.byteCnt==0) Dbprintf("[2] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt); + + /* And ready to receive another command. */ + UartReset(); + /* And also reset the demod code, which might have been */ + /* false-triggered by the commands from the reader. */ + DemodReset(); + } + - if(Handle14443SamplesDemod(ci, cq)) { ++ if(Handle14443SamplesDemod(ci, cq)) { + + //Use samples as a time measurement + if(tracing) + { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(Demod.output, Demod.len, parity); + LogTrace(Demod.output,Demod.len,samples, samples,parity,FALSE); + } - triggered = TRUE; - LED_A_OFF(); - LED_B_ON(); ++ triggered = TRUE; ++ LED_A_OFF(); ++ LED_B_ON(); + - // And ready to receive another response. ++ // And ready to receive another response. + DemodReset(); - } ++ } + WDT_HIT(); + + if(!tracing) { + DbpString("Reached trace limit"); + break; + } + - if(BUTTON_PRESS()) { - DbpString("cancelled"); ++ if(BUTTON_PRESS()) { ++ DbpString("cancelled"); + break; - } - } ++ } ++ } + FpgaDisableSscDma(); LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); @@@ -1194,41 -1199,41 +1210,41 @@@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, uint8_t data[]) { -- FpgaDownloadAndGo(FPGA_BITSTREAM_HF); -- if(!powerfield) -- { -- // Make sure that we start from off, since the tags are stateful; -- // confusing things will happen if we don't reset them between reads. -- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); -- LED_D_OFF(); -- SpinDelay(200); -- } -- -- if(!GETBIT(GPIO_LED_D)) -- { -- SetAdcMuxFor(GPIO_MUXSEL_HIPKD); -- FpgaSetupSsc(); -- -- // Now give it time to spin up. -- // Signal field is on with the appropriate LED -- LED_D_ON(); -- FpgaWriteConfWord( -- FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); -- SpinDelay(200); - } - - CodeIso14443bAsReader(data, datalen); - TransmitFor14443(); - if(recv) - { - uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE); - GetSamplesFor14443Demod(TRUE, 2000, TRUE); - cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen); - } - if(!powerfield) - { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); -- } ++ FpgaDownloadAndGo(FPGA_BITSTREAM_HF); ++ if(!powerfield) ++ { ++ // Make sure that we start from off, since the tags are stateful; ++ // confusing things will happen if we don't reset them between reads. ++ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); ++ LED_D_OFF(); ++ SpinDelay(200); ++ } ++ ++ if(!GETBIT(GPIO_LED_D)) ++ { ++ SetAdcMuxFor(GPIO_MUXSEL_HIPKD); ++ FpgaSetupSsc(); ++ ++ // Now give it time to spin up. ++ // Signal field is on with the appropriate LED ++ LED_D_ON(); ++ FpgaWriteConfWord( ++ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); ++ SpinDelay(200); ++ } + + CodeAndTransmit14443bAsReader(data, datalen); + - if(recv) - { - uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE); - GetSamplesFor14443Demod(TRUE, 2000, TRUE); - cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen); - } - if(!powerfield) - { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - } ++ if(recv) ++ { ++ uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE); ++ GetSamplesFor14443Demod(TRUE, 2000, TRUE); ++ cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen); ++ } ++ if(!powerfield) ++ { ++ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); ++ LED_D_OFF(); ++ } } diff --combined armsrc/iso14443a.c index 54c1db40,b73495a3..336250ed --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@@ -23,6 -23,7 +23,6 @@@ static uint32_t iso14a_timeout; int rsamples = 0; -int tracing = TRUE; uint8_t trigger = 0; // the block number for the ISO14443-4 PCB static uint8_t iso14_pcb_blocknum = 0; @@@ -145,7 -146,17 +145,8 @@@ void iso14a_set_trigger(bool enable) trigger = enable; } -void iso14a_clear_trace() { - uint8_t *trace = BigBuf_get_addr(); - uint16_t max_traceLen = BigBuf_max_traceLen(); - memset(trace, 0x44, max_traceLen); - traceLen = 0; -} -void iso14a_set_tracing(bool enable) { - tracing = enable; -} + void iso14a_set_timeout(uint32_t timeout) { iso14a_timeout = timeout; } @@@ -188,7 -199,63 +189,6 @@@ void AppendCrc14443a(uint8_t* data, in ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1); } -// The function LogTrace() is also used by the iClass implementation in iClass.c -bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) -{ - if (!tracing) return FALSE; - - uint8_t *trace = BigBuf_get_addr(); - uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity - uint16_t duration = timestamp_end - timestamp_start; - - // Return when trace is full - uint16_t max_traceLen = BigBuf_max_traceLen(); - if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) { - tracing = FALSE; // don't trace any more - return FALSE; - } - - // Traceformat: - // 32 bits timestamp (little endian) - // 16 bits duration (little endian) - // 16 bits data length (little endian, Highest Bit used as readerToTag flag) - // y Bytes data - // x Bytes parity (one byte per 8 bytes data) - - // timestamp (start) - trace[traceLen++] = ((timestamp_start >> 0) & 0xff); - trace[traceLen++] = ((timestamp_start >> 8) & 0xff); - trace[traceLen++] = ((timestamp_start >> 16) & 0xff); - trace[traceLen++] = ((timestamp_start >> 24) & 0xff); - - // duration - trace[traceLen++] = ((duration >> 0) & 0xff); - trace[traceLen++] = ((duration >> 8) & 0xff); - - // data length - trace[traceLen++] = ((iLen >> 0) & 0xff); - trace[traceLen++] = ((iLen >> 8) & 0xff); - - // readerToTag flag - if (!readerToTag) { - trace[traceLen - 1] |= 0x80; - } - - // data bytes - if (btBytes != NULL && iLen != 0) { - memcpy(trace + traceLen, btBytes, iLen); - } - traceLen += iLen; - - // parity bytes - if (parity != NULL && iLen != 0) { - memcpy(trace + traceLen, parity, num_paritybytes); - } - traceLen += num_paritybytes; - - return TRUE; -} -- //============================================================================= // ISO 14443 Type A - Miller decoder //============================================================================= @@@ -526,9 -593,6 +526,6 @@@ void RAMFUNC SnoopIso14443a(uint8_t par // bit 1 - trigger from first reader 7-bit request LEDsoff(); - // init trace buffer - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); // We won't start recording the frames that we acquire until we trigger; // a good trigger condition to get started is probably when we see a @@@ -536,22 -600,25 +533,25 @@@ // triggered == FALSE -- to wait first for card bool triggered = !(param & 0x03); + // Allocate memory from BigBuf for some buffers + // free all previous allocations first + BigBuf_free(); + // The command (reader -> tag) that we're receiving. - // The length of a received command will in most cases be no more than 18 bytes. - // So 32 should be enough! - uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; - uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET; + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); // The response (tag -> reader) that we're receiving. - uint8_t *receivedResponse = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; - uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET; - - // As we receive stuff, we copy it from receivedCmd or receivedResponse - // into trace, along with its length and other annotations. - //uint8_t *trace = (uint8_t *)BigBuf; + uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedResponsePar = BigBuf_malloc(MAX_PARITY_SIZE); // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET; + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + + // init trace buffer + iso14a_clear_trace(); + iso14a_set_tracing(TRUE); + uint8_t *data = dmaBuf; uint8_t previous_data = 0; int maxDataLen = 0; @@@ -591,7 -658,7 +591,7 @@@ // test for length of buffer if(dataLen > maxDataLen) { maxDataLen = dataLen; - if(dataLen > 400) { + if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("blew circular buffer! dataLen=%d", dataLen); break; } @@@ -820,7 -887,7 +820,7 @@@ int EmSendCmdPar(uint8_t *resp, uint16_ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity, uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity); - static uint8_t* free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); + static uint8_t* free_buffer_pointer; typedef struct { uint8_t* response; @@@ -830,10 -897,6 +830,6 @@@ uint32_t ProxToAirDuration; } tag_response_info_t; - void reset_free_buffer() { - free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); - } - bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) { // Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes // This will need the following byte array for a modulation sequence @@@ -845,7 -908,8 +841,8 @@@ // ----------- + // 166 bytes, since every bit that needs to be send costs us a byte // - + + // Prepare the tag modulation bits from the message CodeIso14443aAsTag(response_info->response,response_info->response_n); @@@ -866,15 -930,22 +863,22 @@@ return true; } + + // "precompile" responses. There are 7 predefined responses with a total of 28 bytes data to transmit. + // Coded responses need one byte per bit to transfer (data, parity, start, stop, correction) + // 28 * 8 data bits, 28 * 1 parity bits, 7 start bits, 7 stop bits, 7 correction bits + // -> need 273 bytes buffer + #define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 273 + bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { // Retrieve and store the current buffer index response_info->modulation = free_buffer_pointer; // Determine the maximum size we can use from our buffer - size_t max_buffer_size = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + FREE_BUFFER_SIZE) - free_buffer_pointer; + size_t max_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE; // Forward the prepare tag modulation function to the inner function - if (prepare_tag_modulation(response_info,max_buffer_size)) { + if (prepare_tag_modulation(response_info, max_buffer_size)) { // Update the free buffer offset free_buffer_pointer += ToSendMax; return true; @@@ -889,10 -960,6 +893,6 @@@ //----------------------------------------------------------------------------- void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) { - // Enable and clear the trace - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); - uint8_t sak; // The first response contains the ATQA (note: bytes are transmitted in reverse order). @@@ -936,10 -1003,11 +936,11 @@@ } // The second response contains the (mandatory) first 24 bits of the UID - uint8_t response2[5]; + uint8_t response2[5] = {0x00}; // Check if the uid uses the (optional) part - uint8_t response2a[5]; + uint8_t response2a[5] = {0x00}; + if (uid_2nd) { response2[0] = 0x88; num_to_bytes(uid_1st,3,response2+1); @@@ -960,12 -1028,12 +961,12 @@@ response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3]; // Prepare the mandatory SAK (for 4 and 7 byte UID) - uint8_t response3[3]; + uint8_t response3[3] = {0x00}; response3[0] = sak; ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]); // Prepare the optional second SAK (for 7 byte UID), drop the cascade bit - uint8_t response3a[3]; + uint8_t response3a[3] = {0x00}; response3a[0] = sak & 0xFB; ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); @@@ -1001,9 -1069,17 +1002,17 @@@ .modulation_n = 0 }; - // Reset the offset pointer of the free buffer - reset_free_buffer(); - + BigBuf_free_keep_EM(); + + // allocate buffers: + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); + free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE); + + // clear trace + iso14a_clear_trace(); + iso14a_set_tracing(TRUE); + // Prepare the responses of the anticollision phase // there will be not enough time to do this at the moment the reader sends it REQA for (size_t i=0; iSSC_THR = SEC_F; // send cycle - for(; i <= respLen; ) { + for(; i < respLen; ) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = resp[i++]; FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@@ -1661,8 -1734,8 +1667,8 @@@ int iso14443a_select_card(byte_t *uid_p uint8_t sel_all[] = { 0x93,0x20 }; uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0 - uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; - uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET; + uint8_t resp[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller + uint8_t resp_par[MAX_PARITY_SIZE]; byte_t uid_resp[4]; size_t uid_resp_len; @@@ -1954,9 -2027,12 +1960,12 @@@ void ReaderMifare(bool first_try uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; static uint8_t mf_nr_ar3; - uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); - uint8_t* receivedAnswerPar = (((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET); + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; + // free eventually allocated BigBuf memory. We want all for tracing. + BigBuf_free(); + iso14a_clear_trace(); iso14a_set_tracing(TRUE); @@@ -2166,10 -2242,10 +2175,10 @@@ void Mifare1ksim(uint8_t flags, uint8_ struct Crypto1State *pcs; pcs = &mpcs; uint32_t numReads = 0;//Counts numer of times reader read a block - uint8_t* receivedCmd = get_bigbufptr_recvcmdbuf(); - uint8_t* receivedCmd_par = receivedCmd + MAX_FRAME_SIZE; - uint8_t* response = get_bigbufptr_recvrespbuf(); - uint8_t* response_par = response + MAX_FRAME_SIZE; + uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE]; + uint8_t response[MAX_MIFARE_FRAME_SIZE]; + uint8_t response_par[MAX_MIFARE_PARITY_SIZE]; uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; @@@ -2186,6 -2262,8 +2195,8 @@@ uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0}; uint8_t ar_nr_collected = 0; + // free eventually allocated BigBuf memory but keep Emulator Memory + BigBuf_free_keep_EM(); // clear trace iso14a_clear_trace(); iso14a_set_tracing(TRUE); @@@ -2656,18 -2734,20 +2667,20 @@@ void RAMFUNC SniffMifare(uint8_t param // The command (reader -> tag) that we're receiving. // The length of a received command will in most cases be no more than 18 bytes. // So 32 should be enough! - uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); - uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET; + uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE]; // The response (tag -> reader) that we're receiving. - uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); - uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET; + uint8_t receivedResponse[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedResponsePar[MAX_MIFARE_PARITY_SIZE]; // As we receive stuff, we copy it from receivedCmd or receivedResponse // into trace, along with its length and other annotations. //uint8_t *trace = (uint8_t *)BigBuf; - // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET; + // free eventually allocated BigBuf memory + BigBuf_free(); + // allocate the DMA buffer, used to stream samples from the FPGA + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); uint8_t *data = dmaBuf; uint8_t previous_data = 0; int maxDataLen = 0; @@@ -2726,7 -2806,7 +2739,7 @@@ // test for length of buffer if(dataLen > maxDataLen) { // we are more behind than ever... maxDataLen = dataLen; - if(dataLen > 400) { + if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("blew circular buffer! dataLen=0x%x", dataLen); break; } diff --combined armsrc/util.c index 38f41750,674f1b91..4948fce8 --- a/armsrc/util.c +++ b/armsrc/util.c @@@ -12,10 -12,7 +12,9 @@@ #include "util.h" #include "string.h" #include "apps.h" ++#include "BigBuf.h" - uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET; - int traceLen = 0; +int tracing = TRUE; void print_result(char *name, uint8_t *buf, size_t len) { @@@ -430,85 -427,5 +429,91 @@@ uint32_t RAMFUNC GetCountSspClk() return tmp_count; } } +void iso14a_clear_trace() { + clear_trace(); +} + +void iso14a_set_tracing(bool enable) { + set_tracing(enable); +} + +void clear_trace() { - memset(trace, 0x44, TRACE_SIZE); ++ uint8_t *trace = BigBuf_get_addr(); ++ uint16_t max_traceLen = BigBuf_max_traceLen(); ++ memset(trace, 0x44, max_traceLen); + traceLen = 0; +} + +void set_tracing(bool enable) { + tracing = enable; +} + +/** + This is a function to store traces. All protocols can use this generic tracer-function. + The traces produced by calling this function can be fetched on the client-side + by 'hf list raw', alternatively 'hf list ' for protocol-specific + annotation of commands/responses. + +**/ +bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) +{ + if (!tracing) return FALSE; + ++ uint8_t *trace = BigBuf_get_addr(); ++ + uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity + uint16_t duration = timestamp_end - timestamp_start; + // Return when trace is full - if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= TRACE_SIZE) { ++ uint16_t max_traceLen = BigBuf_max_traceLen(); ++ ++ if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) { + tracing = FALSE; // don't trace any more + return FALSE; + } + // Traceformat: + // 32 bits timestamp (little endian) + // 16 bits duration (little endian) + // 16 bits data length (little endian, Highest Bit used as readerToTag flag) + // y Bytes data + // x Bytes parity (one byte per 8 bytes data) + + // timestamp (start) + trace[traceLen++] = ((timestamp_start >> 0) & 0xff); + trace[traceLen++] = ((timestamp_start >> 8) & 0xff); + trace[traceLen++] = ((timestamp_start >> 16) & 0xff); + trace[traceLen++] = ((timestamp_start >> 24) & 0xff); + + // duration + trace[traceLen++] = ((duration >> 0) & 0xff); + trace[traceLen++] = ((duration >> 8) & 0xff); + + // data length + trace[traceLen++] = ((iLen >> 0) & 0xff); + trace[traceLen++] = ((iLen >> 8) & 0xff); + + // readerToTag flag + if (!readerToTag) { + trace[traceLen - 1] |= 0x80; + } + + // data bytes + if (btBytes != NULL && iLen != 0) { + memcpy(trace + traceLen, btBytes, iLen); + } + traceLen += iLen; + + // parity bytes + if (parity != NULL && iLen != 0) { + memcpy(trace + traceLen, parity, num_paritybytes); + } + traceLen += num_paritybytes; + - if(traceLen +4 < TRACE_SIZE) ++ if(traceLen +4 < max_traceLen) + { //If it hadn't been cleared, for whatever reason.. + memset(trace+traceLen,0x44, 4); + } + + return TRUE; +} diff --combined armsrc/util.h index 141d74b9,bf5d0cc8..e0066302 --- a/armsrc/util.h +++ b/armsrc/util.h @@@ -13,7 -13,7 +13,7 @@@ #include #include - #include + #include "common.h" #define BYTEx(x, n) (((x) >> (n * 8)) & 0xff ) @@@ -43,15 -43,6 +43,15 @@@ void LEDsoff() int BUTTON_CLICKED(int ms); int BUTTON_HELD(int ms); void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information); +// @deprecated +void iso14a_clear_trace(); +// @deprecated +void iso14a_set_tracing(bool enable); +void clear_trace(); +void set_tracing(bool enable); + +// The function LogTrace() is also used by the iClass implementation in iclass.c and both iso14443a, iso14443b and mifare +bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); void StartTickCount(); uint32_t RAMFUNC GetTickCount(); diff --combined client/cmdhf.c index 0f31da4d,a55c41b2..07a4aa49 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@@ -22,6 -22,7 +22,7 @@@ #include "cmdhflegic.h" #include "cmdhficlass.h" #include "cmdhfmf.h" + #include "cmdhfmfu.h" static int CmdHelp(const char *Cmd); @@@ -31,8 -32,6 +32,6 @@@ int CmdHFTune(const char *Cmd SendCommand(&c); return 0; } - // for the time being. Need better Bigbuf handling. - #define TRACE_SIZE 3000 //The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501 /* @@@ -158,28 -157,9 +157,28 @@@ NXP/Philips CUSTOM COMMAND #define MIFARE_ULC_AUTH_1 0x1A #define MIFARE_ULC_AUTH_2 0xAF +/** +06 00 = INITIATE +0E xx = SELECT ID (xx = Chip-ID) +0B = Get UID +08 yy = Read Block (yy = block number) +09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written) +0C = Reset to Inventory +0F = Completion +0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate) +**/ + #define ISO14443B_REQB 0x05 #define ISO14443B_ATTRIB 0x1D #define ISO14443B_HALT 0x50 +#define ISO14443B_INITIATE 0x06 +#define ISO14443B_SELECT 0x0E +#define ISO14443B_GET_UID 0x0B +#define ISO14443B_READ_BLK 0x08 +#define ISO14443B_WRITE_BLK 0x09 +#define ISO14443B_RESET 0x0C +#define ISO14443B_COMPLETION 0x0F +#define ISO14443B_AUTHENTICATE 0x0A //First byte is 26 #define ISO15693_INVENTORY 0x01 @@@ -212,7 -192,7 +211,7 @@@ void annotateIso14443a(char *exp, size_ case ISO14443A_CMD_ANTICOLL_OR_SELECT:{ // 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor) // 93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK) - if(cmd[2] == 0x70) + if(cmd[1] == 0x70) { snprintf(exp,size,"SELECT_UID"); break; }else @@@ -240,8 -220,8 +239,8 @@@ case MIFARE_CMD_DEC: snprintf(exp,size,"DEC(%d)",cmd[1]); break; case MIFARE_CMD_RESTORE: snprintf(exp,size,"RESTORE(%d)",cmd[1]); break; case MIFARE_CMD_TRANSFER: snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break; - case MIFARE_AUTH_KEYA: snprintf(exp,size,"AUTH-A"); break; - case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B"); break; + case MIFARE_AUTH_KEYA: snprintf(exp,size,"AUTH-A(%d)",cmd[1]); break; + case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B(%d)",cmd[1]); break; case MIFARE_MAGICMODE: snprintf(exp,size,"MAGIC"); break; default: snprintf(exp,size,"?"); break; } @@@ -307,33 -287,13 +306,33 @@@ void annotateIso15693(char *exp, size_ } } } + +/** +06 00 = INITIATE +0E xx = SELECT ID (xx = Chip-ID) +0B = Get UID +08 yy = Read Block (yy = block number) +09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written) +0C = Reset to Inventory +0F = Completion +0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate) +**/ + void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) { switch(cmd[0]){ case ISO14443B_REQB : snprintf(exp,size,"REQB");break; case ISO14443B_ATTRIB : snprintf(exp,size,"ATTRIB");break; case ISO14443B_HALT : snprintf(exp,size,"HALT");break; - default: snprintf(exp,size ,"?");break; + case ISO14443B_INITIATE : snprintf(exp,size,"INITIATE");break; + case ISO14443B_SELECT : snprintf(exp,size,"SELECT(%d)",cmd[1]);break; + case ISO14443B_GET_UID : snprintf(exp,size,"GET UID");break; + case ISO14443B_READ_BLK : snprintf(exp,size,"READ_BLK(%d)", cmd[1]);break; + case ISO14443B_WRITE_BLK : snprintf(exp,size,"WRITE_BLK(%d)",cmd[1]);break; + case ISO14443B_RESET : snprintf(exp,size,"RESET");break; + case ISO14443B_COMPLETION : snprintf(exp,size,"COMPLETION");break; + case ISO14443B_AUTHENTICATE : snprintf(exp,size,"AUTHENTICATE");break; + default : snprintf(exp,size ,"?");break; } } @@@ -422,18 -382,18 +421,18 @@@ uint8_t iclass_CRC_check(bool isRespons } } - uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, bool showWaitCycles) + uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles) { bool isResponse; - uint16_t duration, data_len,parity_len; + uint16_t duration, data_len, parity_len; uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp; char explanation[30] = {0}; + if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen; + first_timestamp = *((uint32_t *)(trace)); timestamp = *((uint32_t *)(trace + tracepos)); - // Break and stick with current result if buffer was not completely full - if (timestamp == 0x44444444) return TRACE_SIZE; tracepos += 4; duration = *((uint16_t *)(trace + tracepos)); @@@ -449,21 -409,18 +448,21 @@@ } parity_len = (data_len-1)/8 + 1; - if (tracepos + data_len + parity_len >= TRACE_SIZE) { - return TRACE_SIZE; + if (tracepos + data_len + parity_len > traceLen) { + return traceLen; } - uint8_t *frame = trace + tracepos; tracepos += data_len; uint8_t *parityBytes = trace + tracepos; tracepos += parity_len; + //--- Draw the data column + //char line[16][110]; char line[16][110]; - for (int j = 0; j < data_len; j++) { + + for (int j = 0; j < data_len && j/16 < 16; j++) { + int oddparity = 0x01; int k; @@@ -472,17 -429,11 +471,17 @@@ } uint8_t parityBits = parityBytes[j>>3]; - if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) { - sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]); + snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]); + } else { - sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]); + snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]); + } + } + if(data_len == 0) + { + if(data_len == 0){ + sprintf(line[0],""); } } //--- Draw the CRC column @@@ -527,8 -478,8 +526,8 @@@ annotateIso14443b(explanation,sizeof(explanation),frame,data_len); } - int num_lines = (data_len - 1)/16 + 1; - for (int j = 0; j < num_lines; j++) { + int num_lines = MIN((data_len - 1)/16 + 1, 16); + for (int j = 0; j < num_lines ; j++) { if (j == 0) { PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s", (timestamp - first_timestamp), @@@ -545,6 -496,8 +544,8 @@@ } } + if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen; + bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000; if (showWaitCycles && !isResponse && next_isResponse) { @@@ -557,9 -510,11 +558,11 @@@ (next_timestamp - EndOfTransmissionTimestamp)); } } + return tracepos; } + int CmdHFList(const char *Cmd) { bool showWaitCycles = false; @@@ -599,12 -554,13 +602,13 @@@ if (errors) { PrintAndLog("List protocol data in trace buffer."); - PrintAndLog("Usage: hf list [14a|14b|iclass] [f]"); + PrintAndLog("Usage: hf list [f]"); + PrintAndLog(" f - show frame delay times as well"); + PrintAndLog("Supported values:"); + PrintAndLog(" raw - just show raw data without annotations"); PrintAndLog(" 14a - interpret data as iso14443a communications"); PrintAndLog(" 14b - interpret data as iso14443b communications"); PrintAndLog(" iclass - interpret data as iclass communications"); - PrintAndLog(" raw - just show raw data"); - PrintAndLog(" f - show frame delay times as well"); PrintAndLog(""); PrintAndLog("example: hf list 14a f"); PrintAndLog("example: hf list iclass"); @@@ -617,11 -573,28 +621,28 @@@ } - uint8_t trace[TRACE_SIZE]; + uint8_t *trace; uint16_t tracepos = 0; - GetFromBigBuf(trace, TRACE_SIZE, 0); - WaitForResponse(CMD_ACK, NULL); - PrintAndLog("Recorded Activity"); + trace = malloc(USB_CMD_DATA_SIZE); + + // Query for the size of the trace + UsbCommand response; + GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0); + WaitForResponse(CMD_ACK, &response); + uint16_t traceLen = response.arg[2]; + if (traceLen > USB_CMD_DATA_SIZE) { + uint8_t *p = realloc(trace, traceLen); + if (p == NULL) { + PrintAndLog("Cannot allocate memory for trace"); + free(trace); + return 2; + } + trace = p; + GetFromBigBuf(trace, traceLen, 0); + WaitForResponse(CMD_ACK, NULL); + } + + PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen); PrintAndLog(""); PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)"); @@@ -630,10 -603,12 +651,12 @@@ PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |"); PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|"); - while(tracepos < TRACE_SIZE) + while(tracepos < traceLen) { - tracepos = printTraceLine(tracepos, trace, protocol, showWaitCycles); + tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles); } + + free(trace); return 0; } @@@ -648,6 -623,7 +671,7 @@@ static command_t CommandTable[] {"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"}, {"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"}, {"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"}, + {"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"}, {"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"}, {"list", CmdHFList, 1, "List protocol data in trace buffer"}, {NULL, NULL, 0, NULL} diff --combined client/cmdhf14b.c index 3aaf45fa,cf865875..525ffcc6 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@@ -145,9 -145,97 +145,10 @@@ demodError int CmdHF14BList(const char *Cmd) { - uint8_t *got = malloc(USB_CMD_DATA_SIZE); - - // Query for the actual size of the trace - UsbCommand response; - GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0); - WaitForResponse(CMD_ACK, &response); - uint16_t traceLen = response.arg[2]; - if (traceLen > USB_CMD_DATA_SIZE) { - uint8_t *p = realloc(got, traceLen); - if (p == NULL) { - PrintAndLog("Cannot allocate memory for trace"); - free(got); - return 2; - } - got = p; - GetFromBigBuf(got, traceLen, 0); - WaitForResponse(CMD_ACK,NULL); - } - PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen); - PrintAndLog(" time :rssi: who bytes"); - PrintAndLog("---------+----+----+-----------"); - - int i = 0; - int prev = -1; - - for(;;) { - - if(i >= traceLen) { break; } - - bool isResponse; - int timestamp = *((uint32_t *)(got+i)); - if(timestamp & 0x80000000) { - timestamp &= 0x7fffffff; - isResponse = 1; - } else { - isResponse = 0; - } - int metric = *((uint32_t *)(got+i+4)); - - int len = got[i+8]; + PrintAndLog("Deprecated command, use 'hf list 14b' instead"); + - if(len > 100) { - break; - } - if(i + len >= traceLen) { - break; - } - - uint8_t *frame = (got+i+9); - - // Break and stick with current result if buffer was not completely full - if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break; - - char line[1000] = ""; - int j; - for(j = 0; j < len; j++) { - sprintf(line+(j*3), "%02x ", frame[j]); - } - - char *crc; - if(len > 2) { - uint8_t b1, b2; - ComputeCrc14443(CRC_14443_B, frame, len-2, &b1, &b2); - if(b1 != frame[len-2] || b2 != frame[len-1]) { - crc = "**FAIL CRC**"; - } else { - crc = ""; - } - } else { - crc = "(SHORT)"; - } - - char metricString[100]; - if(isResponse) { - sprintf(metricString, "%3d", metric); - } else { - strcpy(metricString, " "); - } - - PrintAndLog(" +%7d: %s: %s %s %s", - (prev < 0 ? 0 : timestamp - prev), - metricString, - (isResponse ? "TAG" : " "), line, crc); - - prev = timestamp; - i += (len + 9); - } - free(got); - return 0; + return 0; } - int CmdHF14BRead(const char *Cmd) { UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}}; @@@ -207,7 -295,7 +208,7 @@@ int CmdHF14BCmdRaw (const char *cmd) uint8_t power=0; char buf[5]=""; int i=0; - uint8_t data[100]; + uint8_t data[100] = {0x00}; unsigned int datalen=0, temp; char *hexout; @@@ -261,7 -349,7 +262,7 @@@ continue; } PrintAndLog("Invalid char on input"); - return 0; + return 1; } if (datalen == 0) { @@@ -375,7 -463,7 +376,7 @@@ int CmdHF14BWrite( const char *Cmd) else 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]); + sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]); CmdHF14BCmdRaw(str); return 0; @@@ -385,7 -473,7 +386,7 @@@ static command_t CommandTable[] { {"help", CmdHelp, 1, "This help"}, {"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"}, - {"list", CmdHF14BList, 0, "List ISO 14443 history"}, + {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"}, {"read", CmdHF14BRead, 0, "Read HF tag (ISO 14443)"}, {"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"}, {"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},