]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iso15693.c
Legic Tag Simulator (#666)
[proxmark3-svn] / armsrc / iso15693.c
index 94040a85796a36eb38b7e5976b2339123845234f..ad6f5cfc0e6b684d2b186e498aab06f85642702b 100644 (file)
 #define AddCrc(data,datalen)  Iso15693AddCrc(data,datalen)
 #define sprintUID(target,uid)  Iso15693sprintUID(target,uid)
 
-int DEBUG=0;
+// approximate amplitude=sqrt(ci^2+cq^2) 
+#define AMPLITUDE(ci, cq) (MAX(ABS(ci), ABS(cq)) + (MIN(ABS(ci), ABS(cq))>>1))
+
+static int DEBUG = 0;
 
 
 // ---------------------------
@@ -303,13 +306,9 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
 
 // NOW READ RESPONSE
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
-       //spindelay(60);        // greg - experiment to get rid of some of the 0 byte/failed reads
        c = 0;
-       getNext = FALSE;
+       getNext = false;
        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;
@@ -319,22 +318,11 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
-                               int8_t r;
-
-                               if(b < 0) {
-                                       r = -b;
-                               } else {
-                                       r = b;
-                               }
-                               if(prev < 0) {
-                                       r -= prev;
-                               } else {
-                                       r += prev;
-                               }
+                               uint8_t r = AMPLITUDE(b, prev);
 
-                               dest[c++] = (uint8_t)r;
+                               dest[c++] = r;
 
-                               if(c >= 2000) {
+                               if(c >= 4000) {
                                        break;
                                }
                        } else {
@@ -352,12 +340,10 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
        int i, j;
        int max = 0, maxPos=0;
 
-       int skip = 4;
-
-       //      if(GraphTraceLen < 1000) return;        // THIS CHECKS FOR A BUFFER TO SMALL
+       int skip = 2;
 
        // First, correlate for SOF
-       for(i = 0; i < 100; i++) {
+       for(i = 0; i < 200; i++) {  // usually, SOF is found around i = 60
                int corr = 0;
                for(j = 0; j < arraylen(FrameSOF); j += skip) {
                        corr += FrameSOF[j]*dest[i+(j/skip)];
@@ -367,7 +353,7 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                        maxPos = i;
                }
        }
-       //      DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
+       if (DEBUG) Dbprintf("SOF at %d, correlation %d", maxPos, max/(arraylen(FrameSOF)/skip));
 
        int k = 0; // this will be our return value
 
@@ -381,10 +367,15 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                memset(outBuf, 0, sizeof(outBuf));
                uint8_t mask = 0x01;
                for(;;) {
-                       int corr0 = 0, corr1 = 0, corrEOF = 0;
+                       int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
                        for(j = 0; j < arraylen(Logic0); j += skip) {
                                corr0 += Logic0[j]*dest[i+(j/skip)];
                        }
+                       corr01 = corr00 = corr0;
+                       for(j = 0; j < arraylen(Logic0); j += skip) {
+                               corr00 += Logic0[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
+                               corr01 += Logic1[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
+                       }
                        for(j = 0; j < arraylen(Logic1); j += skip) {
                                corr1 += Logic1[j]*dest[i+(j/skip)];
                        }
@@ -392,11 +383,14 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                                corrEOF += FrameEOF[j]*dest[i+(j/skip)];
                        }
                        // Even things out by the length of the target waveform.
+                       corr00 *= 2;
+                       corr01 *= 2;
                        corr0 *= 4;
                        corr1 *= 4;
        
-                       if(corrEOF > corr1 && corrEOF > corr0) {
-       //                      DbpString("EOF at %d", i);
+                       if(corrEOF > corr1 && corrEOF > corr00 && corrEOF > corr01) {
+                               if (DEBUG) Dbprintf("EOF at %d, correlation %d (corr01: %d, corr00: %d, corr1: %d, corr0: %d)", 
+                                       i, corrEOF, corr01, corr00, corr1, corr0);
                                break;
                        } else if(corr1 > corr0) {
                                i += arraylen(Logic1)/skip;
@@ -409,7 +403,7 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                                k++;
                                mask = 0x01;
                        }
-                       if((i+(int)arraylen(FrameEOF)) >= 2000) {
+                       if((i+(int)arraylen(FrameEOF)/skip) >= 4000) {
                                DbpString("ran off end!");
                                break;
                        }
@@ -455,11 +449,8 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        //spindelay(60);        // greg - experiment to get rid of some of the 0 byte/failed reads
        c = 0;
-       getNext = FALSE;
+       getNext = false;
        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 = (int8_t)AT91C_BASE_SSC->SSC_RHR;
 
@@ -468,22 +459,11 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
-                               int8_t r;
+                               uint8_t r = AMPLITUDE(b, prev);
 
-                               if(b < 0) {
-                                       r = -b;
-                               } else {
-                                       r = b;
-                               }
-                               if(prev < 0) {
-                                       r -= prev;
-                               } else {
-                                       r += prev;
-                               }
-
-                               dest[c++] = (uint8_t)r;
+                               dest[c++] = r;
 
-                               if(c >= 20000) {
+                               if(c >= BIGBUF_SIZE) {
                                        break;
                                }
                        } else {
@@ -501,12 +481,10 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
        int i, j;
        int max = 0, maxPos=0;
 
-       int skip = 4;
-
-//     if(GraphTraceLen < 1000) return;        // THIS CHECKS FOR A BUFFER TO SMALL
+       int skip = 2;
 
        // First, correlate for SOF
-       for(i = 0; i < 19000; i++) {
+       for(i = 0; i < 38000; i++) {
                int corr = 0;
                for(j = 0; j < arraylen(FrameSOF); j += skip) {
                        corr += FrameSOF[j]*dest[i+(j/skip)];
@@ -516,7 +494,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                        maxPos = i;
                }
        }
-//     DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
+       if (DEBUG) Dbprintf("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
 
        int k = 0; // this will be our return value
 
@@ -530,10 +508,15 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                memset(outBuf, 0, sizeof(outBuf));
                uint8_t mask = 0x01;
                for(;;) {
-                       int corr0 = 0, corr1 = 0, corrEOF = 0;
+                       int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
                        for(j = 0; j < arraylen(Logic0); j += skip) {
                                corr0 += Logic0[j]*dest[i+(j/skip)];
                        }
+                       corr01 = corr00 = corr0;
+                       for(j = 0; j < arraylen(Logic0); j += skip) {
+                               corr00 += Logic0[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
+                               corr01 += Logic1[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
+                       }
                        for(j = 0; j < arraylen(Logic1); j += skip) {
                                corr1 += Logic1[j]*dest[i+(j/skip)];
                        }
@@ -541,11 +524,14 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                                corrEOF += FrameEOF[j]*dest[i+(j/skip)];
                        }
                        // Even things out by the length of the target waveform.
+                       corr00 *= 2;
+                       corr01 *= 2;
                        corr0 *= 4;
                        corr1 *= 4;
        
-                       if(corrEOF > corr1 && corrEOF > corr0) {
-       //                      DbpString("EOF at %d", i);
+                       if(corrEOF > corr1 && corrEOF > corr00 && corrEOF > corr01) {
+                               if (DEBUG) Dbprintf("EOF at %d, correlation %d (corr01: %d, corr00: %d, corr1: %d, corr0: %d)", 
+                                       i, corrEOF, corr01, corr00, corr1, corr0);
                                break;
                        } else if(corr1 > corr0) {
                                i += arraylen(Logic1)/skip;
@@ -558,7 +544,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                                k++;
                                mask = 0x01;
                        }
-                       if((i+(int)arraylen(FrameEOF)) >= 2000) {
+                       if((i+(int)arraylen(FrameEOF)/skip) >= BIGBUF_SIZE) {
                                DbpString("ran off end!");
                                break;
                        }
@@ -624,21 +610,14 @@ void AcquireRawAdcSamplesIso15693(void)
                                break;
                        }
                }
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-                       (void)r;
-               }
                WDT_HIT();
        }
 
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        c = 0;
-       getNext = FALSE;
+       getNext = false;
        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;
@@ -648,22 +627,11 @@ void AcquireRawAdcSamplesIso15693(void)
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
-                               int8_t r;
+                               uint8_t r = AMPLITUDE(b, prev);
 
-                               if(b < 0) {
-                                       r = -b;
-                               } else {
-                                       r = b;
-                               }
-                               if(prev < 0) {
-                                       r -= prev;
-                               } else {
-                                       r += prev;
-                               }
+                               dest[c++] = r;
 
-                               dest[c++] = (uint8_t)r;
-
-                               if(c >= 2000) {
+                               if(c >= 4000) {
                                        break;
                                }
                        } else {
@@ -699,11 +667,8 @@ void RecordRawAdcSamplesIso15693(void)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        c = 0;
-       getNext = FALSE;
+       getNext = false;
        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;
@@ -713,22 +678,11 @@ void RecordRawAdcSamplesIso15693(void)
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
-                               int8_t r;
-
-                               if(b < 0) {
-                                       r = -b;
-                               } else {
-                                       r = b;
-                               }
-                               if(prev < 0) {
-                                       r -= prev;
-                               } else {
-                                       r += prev;
-                               }
+                               uint8_t r = AMPLITUDE(b, prev);
 
-                               dest[c++] = (uint8_t)r;
+                               dest[c++] = r;
 
-                               if(c >= 7000) {
+                               if(c >= 14000) {
                                        break;
                                }
                        } else {
@@ -877,12 +831,12 @@ int SendDataTag(uint8_t *send, int sendlen, int init, int speed, uint8_t **recv)
        LED_C_OFF();
        LED_D_OFF();
        
+       if (init) Iso15693InitReader();
+
        int answerLen=0;
-       uint8_t *answer = BigBuf_get_addr() + 3660;
+       uint8_t *answer = BigBuf_get_addr() + 4000;
        if (recv != NULL) memset(answer, 0, 100);
 
-       if (init) Iso15693InitReader();
-       
        if (!speed) {
                // low speed (1 out of 256)
                CodeIso15693AsReader256(send, sendlen);
@@ -999,13 +953,9 @@ void ReaderIso15693(uint32_t parameter)
        LED_C_OFF();
        LED_D_OFF();
 
-       uint8_t *answer1 = BigBuf_get_addr() + 3660;
-       uint8_t *answer2 = BigBuf_get_addr() + 3760;
-       uint8_t *answer3 = BigBuf_get_addr() + 3860;
-
        int answerLen1 = 0;
        int answerLen2 = 0;
-       int answerLen3 = 0;
+       // int answerLen3 = 0;
        int i = 0;
        int samples = 0;
        int tsamples = 0;
@@ -1013,19 +963,21 @@ void ReaderIso15693(uint32_t parameter)
        int elapsed = 0;
        uint8_t TagUID[8] = {0x00};
 
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
+       uint8_t *answer1 = BigBuf_get_addr() + 4000;
+       uint8_t *answer2 = BigBuf_get_addr() + 4100;
+       // uint8_t *answer3 = BigBuf_get_addr() + 4200;
        // Blank arrays
-       memset(answer1, 0x00, 300);
-
-       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+       memset(answer1, 0x00, 200);
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        // Setup SSC
        FpgaSetupSsc();
 
        // Start from off (no field generated)
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       SpinDelay(200);
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       SpinDelay(200);
 
        // Give the tags time to energize
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
@@ -1071,21 +1023,21 @@ void ReaderIso15693(uint32_t parameter)
                        TagUID[3],TagUID[2],TagUID[1],TagUID[0]);
 
 
-       Dbprintf("%d octets read from SELECT request:", answerLen2);
-       DbdecodeIso15693Answer(answerLen2,answer2);
-       Dbhexdump(answerLen2,answer2,true);
+       // Dbprintf("%d octets read from SELECT request:", answerLen2);
+       // DbdecodeIso15693Answer(answerLen2,answer2);
+       // Dbhexdump(answerLen2,answer2,true);
 
-       Dbprintf("%d octets read from XXX request:", answerLen3);
-       DbdecodeIso15693Answer(answerLen3,answer3);
-       Dbhexdump(answerLen3,answer3,true);
+       // Dbprintf("%d octets read from XXX request:", answerLen3);
+       // DbdecodeIso15693Answer(answerLen3,answer3);
+       // Dbhexdump(answerLen3,answer3,true);
 
        // read all pages
        if (answerLen1>=12 && DEBUG) {
                i=0;                    
                while (i<32) {  // sanity check, assume max 32 pages
                        BuildReadBlockRequest(TagUID,i);
-             TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);  
-         answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed);
+                       TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);  
+                       answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed);
                        if (answerLen2>0) {
                                Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
                                DbdecodeIso15693Answer(answerLen2,answer2);
@@ -1111,24 +1063,22 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
        LED_C_OFF();
        LED_D_OFF();
 
-       uint8_t *buf = BigBuf_get_addr() + 3660;
-       
        int answerLen1 = 0;
        int samples = 0;
        int tsamples = 0;
        int wait = 0;
        int elapsed = 0;
 
-       memset(buf, 0x00, 100);
-
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
+       uint8_t *buf = BigBuf_get_addr() + 4000;
+       memset(buf, 0x00, 100);
+       
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-
        FpgaSetupSsc();
 
        // Start from off (no field generated)
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        SpinDelay(200);
 
        LED_A_OFF();
@@ -1225,7 +1175,7 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
 
        if (recv) { 
                LED_B_ON();
-    cmd_send(CMD_ACK,recvlen>48?48:recvlen,0,0,recvbuf,48);
+               cmd_send(CMD_ACK,recvlen>48?48:recvlen,0,0,recvbuf,48);
                LED_B_OFF();    
                
                if (DEBUG) {
Impressum, Datenschutz