]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
ADD: 'lf cotag read' - COTAG can be read now.
authoriceman1001 <iceman@iuse.se>
Thu, 2 Feb 2017 14:32:21 +0000 (15:32 +0100)
committericeman1001 <iceman@iuse.se>
Thu, 2 Feb 2017 14:32:21 +0000 (15:32 +0100)
armsrc/appmain.c
armsrc/apps.h
armsrc/lfops.c
armsrc/lfsampling.c
armsrc/lfsampling.h
client/cmdhw.c
client/cmdlfcotag.c
client/cmdlfcotag.h
common/lfdemod.c

index e457f438b3bd716d364ff0554e4e44b6a1cfb667..3db56845df0ba73ff5346db3cc0fad611a9bcb73 100644 (file)
@@ -1017,7 +1017,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        CopyVikingtoT55xx(c->arg[0], c->arg[1], c->arg[2]);
             break;
                case CMD_COTAG:
-                       Cotag();
+                       Cotag(c->arg[0]);
                        break;
 #endif
 
index 6ea9d5ead4b4db527d4750827fceebe59abddab8..90e4da993a664a608ff9933ca068e57e624cbd39 100644 (file)
@@ -98,7 +98,7 @@ void T55xxWakeUp(uint32_t Pwd);
 void TurnReadLFOn(uint32_t delay);
 void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
 void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
-void Cotag();
+void Cotag(uint32_t arg0);
 
 /// iso14443b.h
 void SimulateIso14443bTag(uint32_t pupi);
index 1c11ad09cd0b08a0ed31d7403e6e72129723cf57..3c69770e3bd69dcf39e2550bf98d3f381865274c 100644 (file)
@@ -799,7 +799,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
                WDT_HIT();
                if (ledcontrol) LED_A_ON();
 
-               DoAcquisition_default(-1,true);
+               DoAcquisition_default(0, true);
                // FSK demodulator
                size = 50*128*2; //big enough to catch 2 sequences of largest format
                idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
@@ -1740,18 +1740,36 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode
        LED_D_OFF();
 }
 
-void Cotag() {
+/*
+Reading a COTAG.
+
+COTAG needs the reader to send a startsequence and the card has an extreme slow datarate.
+because of this, we can "sample" the data signal but we interpreate it to Manchester direct.
+
+READER START SEQUENCE:
+burst 800 us,    gap   2.2 msecs
+burst 3.6 msecs  gap   2.2 msecs
+burst 800 us     gap   2.2 msecs
+pulse 3.6 msecs
+
+This triggers a COTAG tag to response
+*/
+void Cotag(uint32_t arg0) {
 
 #define OFF    { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2035); }
-//#define WAIT2200     { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2200); }
-#define ON(x)      { FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 89); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); }
-       LED_A_ON();
+#define ON(x)   { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); }
+
+       uint8_t rawsignal = arg0 & 0xF;
+
+       LED_A_ON();     
+
+       // Switching to LF image on FPGA. This might empty BigBuff
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        
        //clear buffer now so it does not interfere with timing later
        BigBuf_Clear_ext(false);
-
-       // Set up FPGA, 132kHz to power up the tag
-       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+       
+       // Set up FPGA, 132kHz to power up the tag      
        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 89);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
 
@@ -1761,27 +1779,20 @@ void Cotag() {
        // Now set up the SSC to get the ADC samples that are now streaming at us.
        FpgaSetupSsc();
 
-       // start a 1.5ticks is 1us
+       // start clock - 1.5ticks is 1us
        StartTicks();
        
-       //send start pulse
+       //send COTAG start pulse
        ON(740)  OFF
        ON(3330) OFF
        ON(740)  OFF
        ON(1000)
 
-/*
-       ON(800)  OFF
-       ON(3600) OFF
-       ON(800)  OFF
-       ON(1000)
-
-burst 800 us,    gap   2.2 msecs
-burst 3.6 msecs  gap   2.2 msecs
-burst 800 us     gap   2.2 msecs
-pulse 3.6 msecs
-*/
-       DoAcquisition_config(FALSE);    
+       switch(rawsignal) {
+               case 0: doCotagAcquisition(50000); break;
+               case 1: doCotagAcquisitionManchester(); break;
+               case 2: DoAcquisition_config(TRUE); break;
+       }
        
        // Turn the field off
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
index 0fcaf3ce5a529d61b648c73c16a491af1bd6d9a0..841bfab86313f15343befefa4bf8d6b887e5fa99 100644 (file)
@@ -20,7 +20,7 @@ sample_config config = { 1, 8, 1, 95, 0 } ;
 
 void printConfig() {
        Dbprintf("LF Sampling config: ");
-       Dbprintf("  [q] divisor:           %d ", config.divisor);
+       Dbprintf("  [q] divisor:           %d (%d KHz)", config.divisor, 12000 / (config.divisor+1));
        Dbprintf("  [b] bps:               %d ", config.bits_per_sample);
        Dbprintf("  [d] decimation:        %d ", config.decimation);
        Dbprintf("  [a] averaging:         %s ", (config.averaging) ? "Yes" : "No");
@@ -140,7 +140,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
        while(!BUTTON_PRESS() && !usb_poll_validate_length() ) {
                WDT_HIT();
                if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
-                       AT91C_BASE_SSC->SSC_THR = 0x00; //0x43;
+                       AT91C_BASE_SSC->SSC_THR = 0x43;
                        LED_D_ON();
                }
                if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
@@ -310,4 +310,122 @@ void doT55x7Acquisition(size_t sample_size) {
                }
        }
 }
-                       
\ No newline at end of file
+/**
+* acquisition of Cotag LF signal. Similart to other LF,  since the Cotag has such long datarate RF/384
+* and is Manchester?,  we directly gather the manchester data into bigbuff
+**/
+
+#define COTAG_T1 384
+#define COTAG_T2 (COTAG_T1>>1)
+#define COTAG_ONE_THRESHOLD 128+30
+#define COTAG_ZERO_THRESHOLD 128-30
+void doCotagAcquisition(size_t sample_size) {
+
+       uint8_t *dest = BigBuf_get_addr();
+       uint16_t bufsize = BigBuf_max_traceLen();
+       
+       if ( bufsize > sample_size )
+               bufsize = sample_size;
+
+       dest[0] = 0;    
+       uint8_t sample = 0, firsthigh = 0, firstlow = 0; 
+       uint16_t i = 0;
+
+       while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) ) {
+               WDT_HIT();              
+               if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
+                       AT91C_BASE_SSC->SSC_THR = 0x43;
+                       LED_D_ON();
+               }
+               
+               if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
+                       sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;      
+                       LED_D_OFF();
+               
+                       // find first peak
+                       if ( !firsthigh ) {
+                               if (sample < COTAG_ONE_THRESHOLD) 
+                                       continue;
+                               firsthigh = 1;
+                       }
+                       if ( !firstlow ){
+                               if (sample > COTAG_ZERO_THRESHOLD )
+                                       continue;
+                               firstlow = 1;
+                       }
+
+                       ++i;                    
+       
+                       if ( sample > COTAG_ONE_THRESHOLD)
+                               dest[i] = 255;
+                       else if ( sample < COTAG_ZERO_THRESHOLD) 
+                               dest[i] = 0;
+                       else 
+                               dest[i] = dest[i-1];                    
+               }
+       }
+}
+
+uint32_t doCotagAcquisitionManchester() {
+
+       uint8_t *dest = BigBuf_get_addr();
+       uint16_t bufsize = BigBuf_max_traceLen();
+       
+       if ( bufsize > 320 )
+               bufsize = 320;
+
+       dest[0] = 0;    
+       uint8_t sample = 0, firsthigh = 0, firstlow = 0; 
+       uint16_t sample_counter = 0, period = 0;
+       uint8_t curr = 0, prev = 0;
+
+       while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) ) {
+               WDT_HIT();              
+               if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
+                       AT91C_BASE_SSC->SSC_THR = 0x43;
+                       LED_D_ON();
+               }
+               
+               if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
+                       sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;      
+                       LED_D_OFF();
+               
+                       // find first peak
+                       if ( !firsthigh ) {
+                               if (sample < COTAG_ONE_THRESHOLD) 
+                                       continue;
+                               firsthigh = 1;
+                       }
+                       
+                       if ( !firstlow ){
+                               if (sample > COTAG_ZERO_THRESHOLD )
+                                       continue;
+                               firstlow = 1;
+                       }
+                                               
+                       // set sample 255, 0,  or previous                      
+                       if ( sample > COTAG_ONE_THRESHOLD){
+                               prev = curr;
+                               curr = 1;
+                       }
+                       else if ( sample < COTAG_ZERO_THRESHOLD) {
+                               prev = curr;
+                               curr = 0;
+                       }
+                       else {
+                               curr = prev;
+                       }                       
+
+                       // full T1 periods, 
+                       if ( period > 0 ) {
+                               --period;
+                               continue;
+                       }
+                                               
+                       dest[sample_counter] = curr;
+                       ++sample_counter;
+                       period = COTAG_T1;
+               }
+       }
+       return sample_counter;
+}
\ No newline at end of file
index b37b786eb6962b40dccd783cbaf956ec02cefa30..a31e2dc5bba8c7fe3129bd5617108f6017ae3f45 100644 (file)
 typedef struct BitstreamOut BitstreamOut;
 
 /**
-* acquisition of T55x7 LF signal. Similart to other LF, but adjusted with @marshmellows thresholds
+* acquisition of Cotag LF signal. Similar to other LF,  since the Cotag has such long datarate RF/384
+* and is Manchester?,  we directly gather the manchester data into bigbuff
+**/
+void doCotagAcquisition(size_t sample_size);
+uint32_t doCotagAcquisitionManchester(void);
+
+/**
+* acquisition of T55x7 LF signal. Similar to other LF, but adjusted with @marshmellows thresholds
 * the data is collected in BigBuf.
 **/
 void doT55x7Acquisition(size_t sample_size);
index 4dae7a32132e040a7b04a0b7ccc2945f0783282c..537e6335a1f78709a681603333581a4f22ce2c9d 100644 (file)
@@ -222,10 +222,11 @@ int CmdSetDivisor(const char *Cmd)
                PrintAndLog("divisor must be between 19 and 255");
                return 1;
        } 
-       
+       // 12 000 000 (12Mhz)
+       // 
        clearCommandBuffer();
        SendCommand(&c);
-       PrintAndLog("Divisor set, expected freq=%dHz", 12000000 / (c.arg[0]+1));
+       PrintAndLog("Divisor set, expected %.1f KHz", ((double)12000 / (c.arg[0]+1)) );
        return 0;
 }
 
index 5e3f28b66cda5f0e88c1bebae6d32d5d5116f46b..8b71a0318368e771ee44ca0c643ee470439a7354 100644 (file)
  
 static int CmdHelp(const char *Cmd);
 
-int CmdCOTAGRead(const char *Cmd) {
-
-//     if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read();
+int usage_lf_cotag_read(void){
+       PrintAndLog("Usage: lf COTAG read [h] <signaldata>");
+       PrintAndLog("Options:");
+       PrintAndLog("      h          : This help");
+       PrintAndLog("      <0|1|2>    : 0 - HIGH/LOW signal; maxlength bigbuff");
+       PrintAndLog("                 : 1 - translation of HI/LO into bytes with manchester 0,1");
+       PrintAndLog("                 : 2 - raw signal; maxlength bigbuff");
+       PrintAndLog("");
+       PrintAndLog("Sample:");
+       PrintAndLog("        lf cotag read 0");
+       PrintAndLog("        lf cotag read 1");
+       return 0;
+}
+int CmdCOTAGDemod(const char *Cmd) {
+       return 0;
+}
 
-       CmdLFSetConfig("q 89");
+// When reading a COTAG.
+// 0 = HIGH/LOW signal - maxlength bigbuff
+// 1 = translation for HI/LO into bytes with manchester 0,1 - length 300
+// 2 = raw signal -  maxlength bigbuff         
+int CmdCOTAGRead(const char *Cmd) {
+       
+       if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read();
+       
+       uint8_t bits[320] = {0};
+       uint32_t rawsignal = 0;
+       sscanf(Cmd, "%u", &rawsignal);
  
-       UsbCommand c = {CMD_COTAG, {0, 0, 0}};
+       UsbCommand c = {CMD_COTAG, {rawsignal, 0, 0}};
        clearCommandBuffer();
        SendCommand(&c);
-       if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500) ) {
+       if ( !WaitForResponseTimeout(CMD_ACK, NULL, 7000) ) {
                PrintAndLog("command execution time out");
-               return 1;
+               return 1;       
        }
-       getSamples("", true);
+       
+       switch ( rawsignal ){
+               case 0: 
+               case 2: {
+                       CmdPlot("");
+                       CmdGrid("384");
+                       getSamples("", true); break;
+               }
+               case 1: {
+                       GetFromBigBuf(bits, sizeof(bits), 0);
+                       UsbCommand response;
+                       if ( !WaitForResponseTimeout(CMD_ACK, &response, 500) ) {
+                                       PrintAndLog("timeout while waiting for reply.");
+                                       return 1;
+                       }
+                       
+                       size_t size = sizeof(bits);
+                       int err = manrawdecode(bits, &size, 1);
+                       if (err){
+                               PrintAndLog("DEBUG: Error - COTAG too many errors: %d", err);
+                               return 0;
+                       }
+                       PrintAndLog("%s", sprint_bin(bits, size));
+                       setDemodBuf(bits, sizeof(bits), 0);
+                       
+                       // CmdCOTAGDemod();
+                       break;
+               }
+       }       
        return 0;
 }
 
 static command_t CommandTable[] = {
        {"help",      CmdHelp,         1, "This help"},
-       {"read",      CmdCOTAGRead,     0, "Attempt to read and extract tag data"},
+       {"demod",     CmdCOTAGDemod,   1, "Tries to decode a COTAG signal"},
+       {"read",      CmdCOTAGRead,    0, "Attempt to read and extract tag data"},
        {NULL, NULL, 0, NULL}
 };
 
index 37009a0b308fd033c07ee18d73c677cd08d0eee9..ab808b4015abb292b6103459674ffbb0388c7644 100644 (file)
@@ -21,5 +21,7 @@
 
 int CmdLFCOTAG(const char *Cmd);
 int CmdCOTAGRead(const char *Cmd);
+int CmdCOTAGDemod(const char *Cmd);
 
+int usage_lf_cotag_read(void);
 #endif
index 49c5877e0d36c45a0fb7c026c9cf341f44a27906..910b2af4e65a1b2809819ff8d68d1db34bc6d7c2 100644 (file)
@@ -350,9 +350,9 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr
 //take 10 and 01 and manchester decode
 //run through 2 times and take least errCnt
 int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert){
-       uint16_t bitnum = 0, MaxBits = 512, errCnt = 0;
+       int errCnt = 0, bestErr = 1000;
+       uint16_t bitnum = 0, MaxBits = 512, bestRun = 0;
        size_t i, k;
-       uint16_t bestErr = 1000, bestRun = 0;
        if (*size < 16) return -1;
        //find correct start position [alignment]
        for (k=0; k < 2; ++k){
Impressum, Datenschutz