]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iso14443.c
More work on iclass
[proxmark3-svn] / armsrc / iso14443.c
index f50d7cb9737aa3127236710ddbf6cb1b0361b448..5e8eddd24dd5d9fa3314f2eb513606a45ca40c66 100644 (file)
@@ -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"
@@ -16,7 +22,7 @@
 #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
@@ -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;
 }
@@ -459,7 +466,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 +538,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 +599,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;
                     }
@@ -633,7 +640,7 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
     int samples = 0;
 
     // Clear out the state of the "UART" that receives from the tag.
-    memset(BigBuf, 0x44, 400);
+    memset(BigBuf, 0x00, 400);
     Demod.output = (uint8_t *)BigBuf;
     Demod.len = 0;
     Demod.state = DEMOD_UNSYNCD;
@@ -646,11 +653,11 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
     // Setup for the DMA.
     dmaBuf = (int8_t *)(BigBuf + 32);
     upTo = dmaBuf;
-    lastRxCounter = DMA_BUFFER_SIZE;
-    FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
+    lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
+    FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_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 +667,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) & (DEMOD_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 > DEMOD_DMA_BUFFER_SIZE) {
+                upTo -= DEMOD_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 = DEMOD_DMA_BUFFER_SIZE;
             }
             lastRxCounter -= 2;
             if(lastRxCounter <= 0) {
-                lastRxCounter += DMA_BUFFER_SIZE;
+                lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
             }
 
             samples += 2;
@@ -780,7 +787,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 +844,14 @@ 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);
-
-    CodeIso14443bAsReader(cmd1, sizeof(cmd1));
-    TransmitFor14443();
-//    LED_A_ON();
-    GetSamplesFor14443Demod(TRUE, 2000, FALSE);
-//    LED_A_OFF();
+    SendRawCommand14443B(sizeof(cmd1),1,1,cmd1);
 }
 
 //-----------------------------------------------------------------------------
@@ -874,16 +863,7 @@ 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)
-{
-     ReadSTMemoryIso14443(parameter,0x7F);
-}
-
-void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast)
+void ReadSTMemoryIso14443(uint32_t dwLast)
 {
     uint8_t i = 0x00;
 
@@ -967,8 +947,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++;
@@ -1022,14 +1002,14 @@ 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;
@@ -1066,16 +1046,12 @@ void SnoopIso14443(void)
     Uart.byteCntMax = 100;
     Uart.state = STATE_UNSYNCD;
 
-       // 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);
-       Dbprintf("  DMA: %i bytes", DMA_BUFFER_SIZE);
-
-       // Use a counter for blinking the LED
-       long ledCount=0;
-       long ledFlashAt=200000;
+    // 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);
+    Dbprintf("  DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
 
     // And put the FPGA in the appropriate mode
     // Signal field is off with the appropriate LED
@@ -1088,26 +1064,19 @@ void SnoopIso14443(void)
     // Setup for the DMA.
     FpgaSetupSsc();
     upTo = dmaBuf;
-    lastRxCounter = DMA_BUFFER_SIZE;
-    FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
+    lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
+    FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_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);
+                                (DEMOD_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);
+            if(behindBy > (DEMOD_DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not?
+                Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
                 goto done;
             }
         }
@@ -1117,18 +1086,17 @@ 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 > 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 = DMA_BUFFER_SIZE;
+            AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_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); \
@@ -1184,13 +1152,15 @@ void SnoopIso14443(void)
                        }
 
             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;
         }
-               WDT_HIT();
+       WDT_HIT();
 
         if(BUTTON_PRESS()) {
             DbpString("cancelled");
@@ -1199,12 +1169,67 @@ void SnoopIso14443(void)
     }
 
 done:
-       LED_D_OFF();
-    AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+       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[])
+{
+    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();
+    }
+}
+
Impressum, Datenschutz