X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/9ab7a6c75566a2d06e56a8a97173c6382a3c5b3d..08e8317c2168fbdc788afe7b19f4c918bf1e4a6f:/armsrc/iso14443.c diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index f50d7cb9..1191c5bf 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -1,9 +1,15 @@ //----------------------------------------------------------------------------- +// Jonathan Westhues, split Nov 2006 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- // Routines to support ISO 14443. This includes both the reader software and // the `fake tag' modes. At the moment only the Type B modulation is // supported. -// Jonathan Westhues, split Nov 2006 //----------------------------------------------------------------------------- + #include "proxmark3.h" #include "apps.h" #include "util.h" @@ -13,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 DMA_BUFFER_SIZE 1024 - +#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 @@ -148,7 +154,7 @@ static struct { static int Handle14443UartBit(int bit) { switch(Uart.state) { - case STATE_UNSYNCD: + case STATE_UNSYNCD: LED_A_OFF(); if(!bit) { // we went low, so this could be the beginning @@ -263,7 +269,8 @@ static int Handle14443UartBit(int bit) break; } - if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error + // 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,8 +293,7 @@ static int GetIso14443CommandFromReader(uint8_t *received, int *len, int maxLen) // 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); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION); // Now run a `software UART' on the stream of incoming samples. @@ -343,6 +349,7 @@ void SimulateIso14443Tag(void) int cmdsRecvd = 0; + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); memset(receivedCmd, 0x44, 400); CodeIso14443bAsTag(response1, sizeof(response1)); @@ -393,8 +400,7 @@ void SimulateIso14443Tag(void) // Modulate BPSK // Signal field is off with the appropriate LED LED_D_OFF(); - FpgaWriteConfWord( - FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK); AT91C_BASE_SSC->SSC_THR = 0xff; FpgaSetupSsc(); @@ -459,7 +465,7 @@ static struct { * false if we are still waiting for some more * */ -static int Handle14443SamplesDemod(int ci, int cq) +static RAMFUNC int Handle14443SamplesDemod(int ci, int cq) { int v; @@ -531,7 +537,7 @@ static int Handle14443SamplesDemod(int ci, int cq) if(Demod.posCount < 12) { Demod.state = DEMOD_UNSYNCD; } else { - LED_C_ON(); // Got SOF + LED_C_ON(); // Got SOF Demod.state = DEMOD_AWAITING_START_BIT; Demod.posCount = 0; Demod.len = 0; @@ -592,8 +598,8 @@ static int Handle14443SamplesDemod(int ci, int cq) } else if(s == 0x000) { // This is EOF LED_C_OFF(); - return TRUE; Demod.state = DEMOD_UNSYNCD; + return TRUE; } else { Demod.state = DEMOD_UNSYNCD; } @@ -611,8 +617,28 @@ static int Handle14443SamplesDemod(int ci, int cq) 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 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; +} + /* - * 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 @@ -622,35 +648,23 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) int max = 0; int gotFrame = FALSE; -//# define DMA_BUFFER_SIZE 8 - int8_t *dmaBuf; - int lastRxCounter; - int8_t *upTo; int ci, cq; int samples = 0; - // Clear out the state of the "UART" that receives from the tag. - memset(BigBuf, 0x44, 400); - Demod.output = (uint8_t *)BigBuf; - Demod.len = 0; - Demod.state = DEMOD_UNSYNCD; + DemodReset(); + UartReset(); - // And the UART that receives from the reader - Uart.output = (((uint8_t *)BigBuf) + 1024); - Uart.byteCntMax = 100; - Uart.state = STATE_UNSYNCD; - - // Setup for the DMA. - dmaBuf = (int8_t *)(BigBuf + 32); - upTo = dmaBuf; - lastRxCounter = DMA_BUFFER_SIZE; - FpgaSetupSscDma((uint8_t *)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; + 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(); + 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 | @@ -660,20 +674,20 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) 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)) + while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1)) > 2) { ci = upTo[0]; cq = upTo[1]; upTo += 2; - if(upTo - dmaBuf > DMA_BUFFER_SIZE) { - upTo -= DMA_BUFFER_SIZE; + if(upTo - dmaBuf > DMA_BUFFER_SIZE) { + upTo -= DMA_BUFFER_SIZE; AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; } lastRxCounter -= 2; if(lastRxCounter <= 0) { - lastRxCounter += DMA_BUFFER_SIZE; + lastRxCounter += DMA_BUFFER_SIZE; } samples += 2; @@ -692,6 +706,12 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) } 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); + } } //----------------------------------------------------------------------------- @@ -780,7 +800,7 @@ static void TransmitFor14443(void) // Code a layer 2 command (string of octets, including CRC) into ToSend[], // so that it is ready to transmit to the tag using TransmitFor14443(). //----------------------------------------------------------------------------- -void CodeIso14443bAsReader(const uint8_t *cmd, int len) +static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { int i, j; uint8_t b; @@ -837,32 +857,28 @@ void CodeIso14443bAsReader(const uint8_t *cmd, int len) // responses. // The command name is misleading, it actually decodes the reponse in HEX // into the output buffer (read the result using hexsamples, not hisamples) +// +// obsolete function only for test //----------------------------------------------------------------------------- void AcquireRawAdcSamplesIso14443(uint32_t parameter) { uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; - // 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); - - 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); + SendRawCommand14443B(sizeof(cmd1),1,1,cmd1); +} - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); -// LED_A_ON(); - GetSamplesFor14443Demod(TRUE, 2000, FALSE); -// LED_A_OFF(); +/** + 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); + } } //----------------------------------------------------------------------------- @@ -874,19 +890,14 @@ void AcquireRawAdcSamplesIso14443(uint32_t parameter) // // I tried to be systematic and check every answer of the tag, every CRC, etc... //----------------------------------------------------------------------------- -void ReadSRI512Iso14443(uint32_t parameter) -{ - ReadSTMemoryIso14443(parameter,0x0F); -} -void ReadSRIX4KIso14443(uint32_t parameter) +void ReadSTMemoryIso14443(uint32_t dwLast) { - ReadSTMemoryIso14443(parameter,0x7F); -} + clear_trace(); + set_tracing(TRUE); -void ReadSTMemoryIso14443(uint32_t parameter,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(); @@ -905,8 +916,8 @@ void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast) // First command: wake up the tag using the INITIATE command uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); + + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); // LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); @@ -923,8 +934,8 @@ void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast) 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(); + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); + // LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); @@ -947,8 +958,8 @@ void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast) // 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(); + CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one + // LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); @@ -967,8 +978,8 @@ void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast) (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 15 - DbpString("Tag memory dump, block 0 to 15"); + // 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++; @@ -979,8 +990,8 @@ void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast) } cmd1[1] = i; ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); + // LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); @@ -1022,27 +1033,22 @@ void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast) * 0-4095 : Demodulated samples receive (4096 bytes) - DEMOD_TRACE_SIZE * 4096-6143 : Last Received command, 2048 bytes (reader->tag) - READER_TAG_BUFFER_SIZE * 6144-8191 : Last Received command, 2048 bytes(tag->reader) - TAG_READER_BUFFER_SIZE - * 8192-9215 : DMA Buffer, 1024 bytes (samples) - DMA_BUFFER_SIZE + * 8192-9215 : DMA Buffer, 1024 bytes (samples) - DEMOD_DMA_BUFFER_SIZE */ -void SnoopIso14443(void) +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 = FALSE; + int triggered = TRUE; - // The command (reader -> tag) that we're working on receiving. - uint8_t *receivedCmd = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE; - // The response (tag -> reader) that we're working on receiving. - uint8_t *receivedResponse = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE; + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // 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; - int traceLen = 0; + clear_trace(); + set_tracing(TRUE); // The DMA buffer, used to stream samples from the FPGA. - int8_t *dmaBuf = (int8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE + TAG_READER_BUFFER_SIZE; + int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; int lastRxCounter; int8_t *upTo; int ci, cq; @@ -1052,34 +1058,20 @@ void SnoopIso14443(void) // information in the trace buffer. int samples = 0; - // Initialize the trace buffer - memset(trace, 0x44, DEMOD_TRACE_SIZE); - - // 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; + DemodReset(); + UartReset(); - // Print some debug information about the buffer sizes - Dbprintf("Snooping buffers initialized:"); - Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE); - Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE); - Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE); + // Print some debug information about the buffer sizes + Dbprintf("Snooping buffers initialized:"); + Dbprintf(" Trace: %i bytes", TRACE_SIZE); + Dbprintf(" Reader -> tag: %i bytes", MAX_FRAME_SIZE); + Dbprintf(" tag -> Reader: %i bytes", MAX_FRAME_SIZE); Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE); - // Use a counter for blinking the LED - long ledCount=0; - long ledFlashAt=200000; + // Signal field is off with the appropriate LED + LED_D_OFF(); - // And put the FPGA in the appropriate mode - // 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); @@ -1088,27 +1080,20 @@ void SnoopIso14443(void) // Setup for the DMA. FpgaSetupSsc(); upTo = dmaBuf; - lastRxCounter = DMA_BUFFER_SIZE; - FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); + lastRxCounter = DMA_BUFFER_SIZE; + FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); + uint8_t parity[MAX_PARITY_SIZE]; + LED_A_ON(); + // And now we loop, receiving samples. for(;;) { - // Blink the LED while Snooping - ledCount++; - if (ledCount == ledFlashAt) { - LED_D_ON(); - } - if (ledCount >= 2*ledFlashAt) { - LED_D_OFF(); - ledCount=0; - } - int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & - (DMA_BUFFER_SIZE-1); + (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=%x", behindBy); - goto done; + 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); + break; } } if(behindBy < 2) continue; @@ -1117,94 +1102,133 @@ void SnoopIso14443(void) cq = upTo[1]; upTo += 2; lastRxCounter -= 2; - if(upTo - dmaBuf > DMA_BUFFER_SIZE) { - upTo -= DMA_BUFFER_SIZE; - lastRxCounter += DMA_BUFFER_SIZE; + 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_RNCR = DMA_BUFFER_SIZE; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; } samples += 2; -#define HANDLE_BIT_IF_BODY \ - if(triggered) { \ - ledFlashAt=30000; \ - 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(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)) { - HANDLE_BIT_IF_BODY - } + 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)) { - // 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 > DEMOD_TRACE_SIZE) { - DbpString("Reached trace limit"); - goto done; - } + //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(); // And ready to receive another response. - memset(&Demod, 0, sizeof(Demod)); - Demod.output = receivedResponse; - Demod.state = DEMOD_UNSYNCD; + DemodReset(); } WDT_HIT(); + if(!tracing) { + DbpString("Reached trace limit"); + break; + } + if(BUTTON_PRESS()) { DbpString("cancelled"); - goto done; + break; } } - -done: - LED_D_OFF(); - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; + FpgaDisableSscDma(); + LED_A_OFF(); + LED_B_OFF(); + LED_C_OFF(); + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; DbpString("Snoop statistics:"); - Dbprintf(" Max behind by: %i", maxBehindBy); + Dbprintf(" Max behind by: %i", maxBehindBy); Dbprintf(" Uart State: %x", Uart.state); Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt); Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax); Dbprintf(" Trace length: %i", traceLen); } + +/* + * Send raw command to tag ISO14443B + * @Input + * datalen len of buffer data + * recv bool when true wait for data from tag and send to client + * powerfield bool leave the field on when true + * data buffer with byte to send + * + * @Output + * none + * + */ + +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); + } + + 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(); + } +} +