]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge branch 'master' of https://github.com/Proxmark/proxmark3
authoriceman1001 <iceman@iuse.se>
Tue, 24 Mar 2015 10:45:31 +0000 (11:45 +0100)
committericeman1001 <iceman@iuse.se>
Tue, 24 Mar 2015 10:45:31 +0000 (11:45 +0100)
Conflicts:
armsrc/lfops.c
client/cmddata.c
client/cmdlf.c
client/cmdlft55xx.c
client/cmdlft55xx.h
client/scripts/test_t55x7_bi.lua

30 files changed:
armsrc/BigBuf.c
armsrc/Makefile
armsrc/appmain.c
armsrc/apps.h
armsrc/iso14443a.c
armsrc/iso14443a.h
armsrc/lfops.c
armsrc/lfsampling.c
armsrc/lfsampling.h
armsrc/mifarecmd.c
armsrc/mifaredesfire.c
client/Makefile
client/cmddata.c
client/cmddata.h
client/cmdhf.c
client/cmdhf14a.c
client/cmdhfmfdes.c
client/cmdhfmfu.c
client/cmdhfmfu.h
client/cmdlf.c
client/cmdlfem4x.c
client/cmdlft55xx.c
client/cmdlft55xx.h
client/scripts/test_t55x7_bi.lua
client/scripts/test_t55x7_psk.lua
common/Makefile.common
common/lfdemod.c
common/lfdemod.h
common/protocols.h
include/mifare.h

index 703ade658da348db04f80b2824269a32c738cb55..2fb50a47ea2e4cee910a84c333f4f90d28153ece 100644 (file)
@@ -171,18 +171,19 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
        traceLen += iLen;
 
        // parity bytes
-       if (parity != NULL && iLen != 0) {
+       if (iLen != 0) {
+               if (parity != NULL) {
                memcpy(trace + traceLen, parity, num_paritybytes);
+               } else {
+                       memset(trace + traceLen, 0x00, num_paritybytes);
+               }
        }
        traceLen += num_paritybytes;
 
-       if(traceLen +4 < max_traceLen)
-       {       //If it hadn't been cleared, for whatever reason..
-               memset(trace+traceLen,0x44, 4);
-       }
-
        return TRUE;
 }
+
+
 int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag)
 {
        /**
@@ -224,6 +225,8 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP
 
        return TRUE;
 }
+
+
 // Emulator memory
 uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
        uint8_t* mem = BigBuf_get_EM_addr();
index 14ddbc056b2aad5b7d4499eff5004c11bec96ed6..1c03e5a3b17275124dcb3070e69c5a774d38ba1a 100644 (file)
@@ -18,7 +18,7 @@ SRC_LF = lfops.c hitag2.c lfsampling.c
 SRC_ISO15693 = iso15693.c iso15693tools.c
 SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
 SRC_ISO14443b = iso14443.c
-SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c 
+SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c desfire_key.c desfire_crypto.c mifaredesfire.c
 SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c 
 
 THUMBSRC = start.c \
index f6c979784a28a6b5c7e1df174d45ac6f09ffa740..4e12c94df55f3b1e54840a716316127d855e512c 100644 (file)
@@ -647,7 +647,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        setSamplingConfig((sample_config *) c->d.asBytes);
                        break;
                case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
-                       cmd_send(CMD_ACK,SampleLF(),0,0,0,0);
+                       cmd_send(CMD_ACK,SampleLF(c->arg[0]),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);
index 3fe8acaece373079feaf6286b97bcf65bc7e7ecc..ea298acb0ccf6dcdd73c46703192484d93c741dc 100644 (file)
 #include "../common/crc32.h"
 #include "BigBuf.h"
 #include "../include/hitag2.h"
+#include "../include/mifare.h"
+//#include <openssl/des.h>
+//#include <openssl/aes.h>
+//#include "des.h"
+//#include "aes.h"
+#include "desfire.h"
+
 
 extern const uint8_t OddByteParity[256];
 extern int rsamples;   // = 0;
@@ -170,7 +177,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand * c);
 void ReaderMifare(bool first_try);
 int32_t dist_nt(uint32_t nt1, uint32_t nt2);
 void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
-void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
+void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
 void MifareUC_Auth1(uint8_t arg0, uint8_t *datain);
 void MifareUC_Auth2(uint32_t arg0, uint8_t *datain);
 void MifareUReadCard(uint8_t arg0, int Pages, uint8_t *datain);
@@ -207,6 +214,17 @@ void       OnError(uint8_t reason);
 
 
 
+// desfire_crypto.h
+void   *mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, off_t offset, int communication_settings);
+void    *mifare_cryto_postprocess_data (desfiretag_t tag, void *data, ssize_t *nbytes, int communication_settings);
+void    mifare_cypher_single_block (desfirekey_t  key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size);
+void    mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation);
+size_t  key_block_size (const desfirekey_t  key);
+size_t  padded_data_length (const size_t nbytes, const size_t block_size);
+size_t  maced_data_length (const desfirekey_t  key, const size_t nbytes);
+size_t  enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int communication_settings);
+void    cmac_generate_subkeys (desfirekey_t key);
+void    cmac (const desfirekey_t  key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
 
 
 /// iso15693.h
index e7477789d287312fbf68ec4a417f4cbbfb7b01ee..9cd0cfdc9ceb8158a1cd5e5fe7238db5c58b3096 100644 (file)
@@ -213,6 +213,12 @@ void AppendCrc14443a(uint8_t* data, int len)
        ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
 }
 
+void AppendCrc14443b(uint8_t* data, int len)
+{
+       ComputeCrc14443(CRC_14443_B,data,len,data+len,data+len+1);
+}
+
+
 //=============================================================================
 // ISO 14443 Type A - Miller decoder
 //=============================================================================
@@ -232,13 +238,17 @@ void AppendCrc14443a(uint8_t* data, int len)
 static tUart Uart;
 
 // Lookup-Table to decide if 4 raw bits are a modulation.
-// We accept two or three consecutive "0" in any position with the rest "1"
+// We accept the following:
+// 0001  -   a 3 tick wide pause
+// 0011  -   a 2 tick wide pause, or a three tick wide pause shifted left
+// 0111  -   a 2 tick wide pause shifted left
+// 1001  -   a 2 tick wide pause shifted right
 const bool Mod_Miller_LUT[] = {
-       TRUE,  TRUE,  FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE,
-       TRUE,  TRUE,  FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE
+       FALSE,  TRUE, FALSE, TRUE,  FALSE, FALSE, FALSE, TRUE,
+       FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
 };
-#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x00F0) >> 4])
-#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x000F)])
+#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
+#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
 
 void UartReset()
 {
@@ -248,8 +258,6 @@ void UartReset()
        Uart.parityLen = 0;                                     // number of decoded parity bytes
        Uart.shiftReg = 0;                                      // shiftreg to hold decoded data bits
        Uart.parityBits = 0;                            // holds 8 parity bits
-       Uart.twoBits = 0x0000;                          // buffer for 2 Bits
-       Uart.highCnt = 0;
        Uart.startTime = 0;
        Uart.endTime = 0;
 }
@@ -258,6 +266,7 @@ void UartInit(uint8_t *data, uint8_t *parity)
 {
        Uart.output = data;
        Uart.parity = parity;
+       Uart.fourBits = 0x00000000;                     // clear the buffer for 4 Bits
        UartReset();
 }
 
@@ -265,40 +274,37 @@ void UartInit(uint8_t *data, uint8_t *parity)
 static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
 {
 
-       Uart.twoBits = (Uart.twoBits << 8) | bit;
+       Uart.fourBits = (Uart.fourBits << 8) | bit;
        
        if (Uart.state == STATE_UNSYNCD) {                                                                                      // not yet synced
        
-               if (Uart.highCnt < 2) {                                                                                                 // wait for a stable unmodulated signal
-                       if (Uart.twoBits == 0xffff) {
-                               Uart.highCnt++;
-                       } else {
-                               Uart.highCnt = 0;
-                       }
-               } else {        
-                       Uart.syncBit = 0xFFFF;                                                                                          // not set
-                                                                                                                                                               // we look for a ...1111111100x11111xxxxxx pattern (the start bit)
-                       if              ((Uart.twoBits & 0xDF00) == 0x1F00) Uart.syncBit = 8;           // mask is   11x11111 xxxxxxxx, 
-                                                                                                                                                               // check for 00x11111 xxxxxxxx
-                       else if ((Uart.twoBits & 0xEF80) == 0x8F80) Uart.syncBit = 7;           // both masks shifted right one bit, left padded with '1'
-                       else if ((Uart.twoBits & 0xF7C0) == 0xC7C0) Uart.syncBit = 6;           // ...
-                       else if ((Uart.twoBits & 0xFBE0) == 0xE3E0) Uart.syncBit = 5;
-                       else if ((Uart.twoBits & 0xFDF0) == 0xF1F0) Uart.syncBit = 4;
-                       else if ((Uart.twoBits & 0xFEF8) == 0xF8F8) Uart.syncBit = 3;
-                       else if ((Uart.twoBits & 0xFF7C) == 0xFC7C) Uart.syncBit = 2;
-                       else if ((Uart.twoBits & 0xFFBE) == 0xFE3E) Uart.syncBit = 1;
-                       if (Uart.syncBit != 0xFFFF) {                                                                           // found a sync bit
+               Uart.syncBit = 9999;                                                                                                    // not set
+               // The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from
+               // Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111)
+               // we therefore look for a ...xx11111111111100x11111xxxxxx... pattern 
+               // (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's)
+#define ISO14443A_STARTBIT_MASK                0x07FFEF80                                                                      // mask is    00000111 11111111 11101111 10000000
+#define ISO14443A_STARTBIT_PATTERN     0x07FF8F80                                                                      // pattern is 00000111 11111111 10001111 10000000
+               if              ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 0)) == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7;
+               else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 1)) == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6;
+               else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 2)) == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5;
+               else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 3)) == ISO14443A_STARTBIT_PATTERN >> 3) Uart.syncBit = 4;
+               else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 4)) == ISO14443A_STARTBIT_PATTERN >> 4) Uart.syncBit = 3;
+               else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 5)) == ISO14443A_STARTBIT_PATTERN >> 5) Uart.syncBit = 2;
+               else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 6)) == ISO14443A_STARTBIT_PATTERN >> 6) Uart.syncBit = 1;
+               else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 7)) == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0;
+
+               if (Uart.syncBit != 9999) {                                                                                             // found a sync bit
                                Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
                                Uart.startTime -= Uart.syncBit;
                                Uart.endTime = Uart.startTime;
                                Uart.state = STATE_START_OF_COMMUNICATION;
                        }
-               }
 
        } else {
 
-               if (IsMillerModulationNibble1(Uart.twoBits >> Uart.syncBit)) {                  
-                       if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) {          // Modulation in both halves - error
+               if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) {                 
+                       if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) {         // Modulation in both halves - error
                                UartReset();
                        } else {                                                                                                                        // Modulation in first half = Sequence Z = logic "0"
                                if (Uart.state == STATE_MILLER_X) {                                                             // error - must not follow after X
@@ -322,7 +328,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
                                }
                        }
                } else {
-                       if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) {          // Modulation second half = Sequence X = logic "1"
+                       if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) {         // Modulation second half = Sequence X = logic "1"
                                Uart.bitCount++;
                                Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100;                                   // add a 1 to the shiftreg
                                Uart.state = STATE_MILLER_X;
@@ -358,12 +364,10 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
                                                return TRUE;                                                                                    // we are finished with decoding the raw data sequence
                                        } else {
                                                UartReset();                                                                                    // Nothing received - start over
-                                               Uart.highCnt = 1;
                                        }
                                }
                                if (Uart.state == STATE_START_OF_COMMUNICATION) {                               // error - must not follow directly after SOC
                                        UartReset();
-                                       Uart.highCnt = 1;
                                } else {                                                                                                                // a logic "0"
                                        Uart.bitCount++;
                                        Uart.shiftReg = (Uart.shiftReg >> 1);                                           // add a 0 to the shiftreg
@@ -680,6 +684,9 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
 
                                        // And ready to receive another response.
                                        DemodReset();
+                                       // And reset the Miller decoder including itS (now outdated) input buffer
+                                       UartInit(receivedCmd, receivedCmdPar);
+
                                        LED_C_OFF();
                                } 
                                TagIsActive = (Demod.state != DEMOD_UNSYNCD);
@@ -1337,7 +1344,7 @@ void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8
                }
 
                // Only transmit parity bit if we transmitted a complete byte
-               if (j == 8) {
+               if (j == 8 && parity != NULL) {
                        // Get the parity bit
                        if (parity[i>>3] & (0x80 >> (i&0x0007))) {
                                // Sequence X
@@ -1631,6 +1638,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
        }
 }
 
+
 void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing)
 {
        CodeIso14443aBitsAsReaderPar(frame, bits, par);
@@ -1646,11 +1654,13 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t
        }
 }
 
+
 void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing)
 {
   ReaderTransmitBitsPar(frame, len*8, par, timing);
 }
 
+
 void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
 {
   // Generate parity and redirect
@@ -1659,6 +1669,7 @@ void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
   ReaderTransmitBitsPar(frame, len, par, timing);
 }
 
+
 void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
 {
   // Generate parity and redirect
@@ -1719,6 +1730,11 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                memset(uid_ptr,0,10);
        }
 
+       // check for proprietary anticollision:
+       if ((resp[0] & 0x1F) == 0) {
+               return 3;
+       }
+       
        // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
        // which case we need to make a cascade 2 request and select - this is a long UID
        // While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
@@ -1851,7 +1867,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
        DemodReset();
        UartReset();
        NextTransferTime = 2*DELAY_ARM2AIR_AS_READER;
-       iso14a_set_timeout(1050); // 10ms default
+       iso14a_set_timeout(50*106); // 10ms default
 }
 
 int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
@@ -1927,15 +1943,38 @@ void ReaderIso14443a(UsbCommand *c)
 
        if(param & ISO14A_RAW) {
                if(param & ISO14A_APPEND_CRC) {
+                       if(param & ISO14A_TOPAZMODE) {
+                               AppendCrc14443b(cmd,len);
+                       } else {
                        AppendCrc14443a(cmd,len);
+                       }
                        len += 2;
                        if (lenbits) lenbits += 16;
                }
-               if(lenbits>0) {
+               if(lenbits>0) {                         // want to send a specific number of bits (e.g. short commands)
+                       if(param & ISO14A_TOPAZMODE) {
+                               int bits_to_send = lenbits;
+                               uint16_t i = 0;
+                               ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL);             // first byte is always short (7bits) and no parity
+                               bits_to_send -= 7;
+                               while (bits_to_send > 0) {
+                                       ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 8), NULL, NULL);     // following bytes are 8 bit and no parity
+                                       bits_to_send -= 8;
+                               }
+                       } else {
                        GetParity(cmd, lenbits/8, par);
-                       ReaderTransmitBitsPar(cmd, lenbits, par, NULL);
+                               ReaderTransmitBitsPar(cmd, lenbits, par, NULL);                                                 // bytes are 8 bit with odd parity
+                       }
+               } else {                                        // want to send complete bytes only
+                       if(param & ISO14A_TOPAZMODE) {
+                               uint16_t i = 0;
+                               ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL);                                                // first byte: 7 bits, no paritiy
+                               while (i < len) {
+                                       ReaderTransmitBitsPar(&cmd[i++], 8, NULL, NULL);                                        // following bytes: 8 bits, no paritiy
+                               }
                } else {
-                       ReaderTransmit(cmd,len, NULL);
+                               ReaderTransmit(cmd,len, NULL);                                                                                  // 8 bits, odd parity
+                       }
                }
                arg0 = ReaderReceive(buf, par);
                cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
@@ -2302,6 +2341,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                } 
                if(cardSTATE == MFEMUL_NOFIELD) continue;
 
+               //Now, get data
+
                res = EmGetCmd(receivedCmd, &len, receivedCmd_par);
                if (res == 2) { //Field is off!
                        cardSTATE = MFEMUL_NOFIELD;
@@ -2805,7 +2846,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
                                        if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break;
 
                                        /* And ready to receive another command. */
-                                       UartReset();
+                                       UartInit(receivedCmd, receivedCmdPar);
                                        
                                        /* And also reset the demod code */
                                        DemodReset();
@@ -2822,6 +2863,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
 
                                        // And ready to receive another response.
                                        DemodReset();
+                                       // And reset the Miller decoder including its (now outdated) input buffer
+                                       UartInit(receivedCmd, receivedCmdPar);
                                }
                                TagIsActive = (Demod.state != DEMOD_UNSYNCD);
                        }
index be8775cef7d0f66e83f4514e830a3de1a60a1983..3344de4327a5a7d8fba8e2edb595547d54c39e64 100644 (file)
@@ -57,15 +57,14 @@ typedef struct {
                // DROP_FIRST_HALF,
                } state;
        uint16_t shiftReg;
-       uint16_t bitCount;
+       int16_t  bitCount;
        uint16_t len;
        uint16_t byteCntMax;
        uint16_t posCnt;
        uint16_t syncBit;
        uint8_t  parityBits;
        uint8_t  parityLen;
-       uint16_t highCnt;
-       uint16_t twoBits;
+       uint32_t fourBits;
        uint32_t startTime, endTime;
     uint8_t *output;
        uint8_t *parity;
index 7537d63fa60447cea122e02d26371d717ee6fe85..6eb89912606930f46e156075e7b19af5b818dcdf 100644 (file)
@@ -1085,11 +1085,11 @@ void T55xxWriteBit(int bit)
 // Write one card block in page 0, no lock
 void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
 {
-       uint32_t i = 0;
+    uint32_t i = 0;
 
-       // Set up FPGA, 125kHz
-       // Wait for config.. (192+8190xPOW)x8 == 67ms
-       LFSetupFPGAForADC(0, true);
+    // Set up FPGA, 125kHz
+    // Wait for config.. (192+8190xPOW)x8 == 67ms
+    LFSetupFPGAForADC(0, true);
 
     // Now start writting
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -1122,20 +1122,28 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 }
 
+void TurnReadLFOn(){
+    FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+    // Give it a bit of time for the resonant antenna to settle.
+    SpinDelayUs(8*150);
+}
+
+
 // Read one card block in page 0
 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
 {
     uint32_t i = 0;
     uint8_t *dest = BigBuf_get_addr();
     uint16_t bufferlength = BigBuf_max_traceLen();
-       if ( bufferlength > T55xx_SAMPLES_SIZE )
-               bufferlength = T55xx_SAMPLES_SIZE;
+    if ( bufferlength > T55xx_SAMPLES_SIZE )
+        bufferlength = T55xx_SAMPLES_SIZE;
 
-       memset(dest, 0x80, bufferlength);
-       
-       // Set up FPGA, 125kHz
-       // Wait for config.. (192+8190xPOW)x8 == 67ms
-       LFSetupFPGAForADC(0, true);
+    // Clear destination buffer before sending the command
+    memset(dest, 0x80, bufferlength);
+
+    // Set up FPGA, 125kHz
+    // Wait for config.. (192+8190xPOW)x8 == 67ms
+    LFSetupFPGAForADC(0, true);
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
     SpinDelayUs(START_GAP);
 
@@ -1154,40 +1162,40 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
         T55xxWriteBit(Block & i);
 
     // Turn field on to read the response
-       TurnReadLFOn();
-
+    TurnReadLFOn();
     // Now do the acquisition
     i = 0;
     for(;;) {
         if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
             AT91C_BASE_SSC->SSC_THR = 0x43;
-                       LED_D_ON();
+            LED_D_ON();
         }
         if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
             dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-                       ++i;
-                       LED_D_OFF();
-                       if (i >= bufferlength) break;
+            i++;
+            LED_D_OFF();
+            if (i >= bufferlength) break;
         }
     }
 
-       cmd_send(CMD_ACK,0,0,0,0,0);
+    cmd_send(CMD_ACK,0,0,0,0,0);    
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
     LED_D_OFF();
 }
 
 // Read card traceability data (page 1)
 void T55xxReadTrace(void){
-
-       uint32_t i = 0;
+    
+    uint32_t i = 0;
     uint8_t *dest = BigBuf_get_addr();
     uint16_t bufferlength = BigBuf_max_traceLen();
-       if ( bufferlength > T55xx_SAMPLES_SIZE )
-               bufferlength = T55xx_SAMPLES_SIZE;
+    if ( bufferlength > T55xx_SAMPLES_SIZE )
+        bufferlength= T55xx_SAMPLES_SIZE;
 
-       memset(dest, 0x80, bufferlength);  
-  
-       LFSetupFPGAForADC(0, true);
+    // Clear destination buffer before sending the command
+    memset(dest, 0x80, bufferlength);
+
+    LFSetupFPGAForADC(0, true);
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
     SpinDelayUs(START_GAP);
 
@@ -1196,24 +1204,25 @@ void T55xxReadTrace(void){
     T55xxWriteBit(1); //Page 1
 
     // Turn field on to read the response
-       TurnReadLFOn();
+    TurnReadLFOn();
 
     // Now do the acquisition
     for(;;) {
         if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
             AT91C_BASE_SSC->SSC_THR = 0x43;
-                       LED_D_ON();
+            LED_D_ON();
         }
         if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
             dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-                       ++i;
-                       LED_D_OFF();
-               
-                       if (i >= bufferlength) break;
+            i++;
+            LED_D_OFF();
+
+            if (i >= bufferlength) break;
                }
        }
   
        cmd_send(CMD_ACK,0,0,0,0,0);
+    cmd_send(CMD_ACK,0,0,0,0,0);
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
     LED_D_OFF();
 }
index 6094bd34878c3367133ce8f24ccb4be4ccaeade0..120c0801de6ccecc3e7e558e10c078e3b187c980 100644 (file)
@@ -224,21 +224,21 @@ uint32_t DoAcquisition_config( bool silent)
                                  ,silent);
 }
 
-uint32_t ReadLF(bool activeField)
+uint32_t ReadLF(bool activeField, bool silent)
 {
-       printConfig();
+       if (!silent) printConfig();
        LFSetupFPGAForADC(config.divisor, activeField);
        // Now call the acquisition routine
-       return DoAcquisition_config(false);
+       return DoAcquisition_config(silent);
 }
 
 /**
 * Initializes the FPGA for reader-mode (field on), and acquires the samples.
 * @return number of bits sampled
 **/
-uint32_t SampleLF()
+uint32_t SampleLF(bool printCfg)
 {
-       return ReadLF(true);
+       return ReadLF(true, printCfg);
 }
 /**
 * Initializes the FPGA for snoop-mode (field off), and acquires the samples.
@@ -247,5 +247,5 @@ uint32_t SampleLF()
 
 uint32_t SnoopLF()
 {
-       return ReadLF(false);
+       return ReadLF(false, true);
 }
index 9ab458f8129e8ce5f307ca40d240bb8939554aac..6c671ec8ca7a295b49a2d9200401a3ca69d49753 100644 (file)
@@ -5,7 +5,7 @@
 * Initializes the FPGA for reader-mode (field on), and acquires the samples.
 * @return number of bits sampled
 **/
-uint32_t SampleLF();
+uint32_t SampleLF(bool silent);
 
 /**
 * Initializes the FPGA for snoop-mode (field off), and acquires the samples.
index 94bc1c1c545d7a34d1576721427f9f669e282614..69b5b53c76843e41267cdbb3926367b6f694260e 100644 (file)
@@ -16,7 +16,8 @@
 #include "mifarecmd.h"\r
 #include "apps.h"\r
 #include "util.h"\r
-\r
+//#include "../client/loclass/des.h"\r
+#include "des.h"\r
 #include "crc.h"\r
 \r
 //-----------------------------------------------------------------------------\r
@@ -104,14 +105,14 @@ void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){
        if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
                        Dbprintf("Can't select card");\r
-               //OnError(0);\r
+               OnError(0);\r
                return;\r
        };\r
        \r
        if(mifare_ultra_auth1(cuid, dataoutbuf)){\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)        \r
                        Dbprintf("Authentication part1: Fail.");\r
-               //OnError(1);\r
+               OnError(1);\r
                return;\r
        }\r
 \r
@@ -138,7 +139,7 @@ void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){
        if(mifare_ultra_auth2(cuid, key, dataoutbuf)){\r
            if (MF_DBGLEVEL >= MF_DBG_ERROR) \r
                        Dbprintf("Authentication part2: Fail...");\r
-               //OnError(1);\r
+               OnError(1);\r
                return;                 \r
        }\r
        \r
@@ -151,13 +152,21 @@ void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){
        LEDsoff();\r
 }\r
 \r
-void MifareUReadBlock(uint8_t arg0,uint8_t *datain)\r
+void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)\r
 {\r
        uint8_t blockNo = arg0;\r
        byte_t dataout[16] = {0x00};\r
        uint8_t uid[10] = {0x00};\r
+       uint8_t key[8] = {0x00};\r
        uint32_t cuid;\r
-    \r
+    bool usePwd = false;\r
+       \r
+       usePwd = (arg1 == 1);\r
+       \r
+       // use password\r
+       if ( usePwd )\r
+               memcpy(key, datain, 8);\r
+       \r
        LED_A_ON();\r
        LED_B_OFF();\r
        LED_C_OFF();\r
@@ -167,22 +176,82 @@ void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
     \r
        int len = iso14443a_select_card(uid, NULL, &cuid);\r
        if(!len) {\r
-               if (MF_DBGLEVEL >= MF_DBG_ERROR)        Dbprintf("Can't select card");\r
-               //OnError(1);\r
+               if (MF_DBGLEVEL >= MF_DBG_ERROR)        Dbprintf("Can't select card (RC:%d)",len);\r
+               OnError(1);\r
                return;\r
                };\r
-        \r
+       \r
+        // authenticate here.\r
+       if ( usePwd ) {\r
+\r
+               uint8_t a[8] = { 0x01 };\r
+               uint8_t b[8] = { 0x00 };\r
+               uint8_t enc_b[8] = { 0x00 };\r
+               uint8_t ab[16] = { 0x00 };\r
+               \r
+               uint8_t transKey[8] = { 0x00 };\r
+               \r
+               uint16_t len;\r
+               uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
+               uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+       \r
+               len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);\r
+               if (len == 1) {\r
+                       if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+                               Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+                               OnError(1);\r
+                               return;\r
+               }\r
+               \r
+//             memcpy(dataout, receivedAnswer, 11);\r
+               \r
+               // tag nonce.\r
+               memcpy(enc_b,receivedAnswer+1,8);\r
+\r
+               // decrypt nonce.\r
+               des_dec(enc_b, b, key );\r
+\r
+               Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x", enc_b[0],enc_b[1],enc_b[2],enc_b[3],enc_b[4],enc_b[5],enc_b[6],enc_b[7] );\r
+\r
+               rol(b,8);\r
+               \r
+               memcpy(ab  ,a,8);\r
+               memcpy(ab+8,b,8);\r
+\r
+               Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] );\r
+               Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] );\r
+\r
+               // encrypt\r
+               des_enc(ab, ab, key);\r
+\r
+               Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] );\r
+               Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] );\r
+\r
+               len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, ab, receivedAnswer, receivedAnswerPar, NULL);\r
+               if (len == 1) {\r
+                       if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+                               Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+                       OnError(1);\r
+                       return;\r
+               }\r
+       \r
+               // \r
+               memcpy(transKey, receivedAnswer+1, 8);\r
+               Dbprintf("TRANSACTIONKEY: %02x %02x %02x %02x %02x %02x %02x %02x", transKey[0],transKey[1],transKey[2],transKey[3],\r
+               transKey[4],transKey[5],transKey[6],transKey[7] );\r
+       }\r
+               \r
        len = mifare_ultra_readblock(cuid, blockNo, dataout);\r
        if(len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)        Dbprintf("Read block error");\r
-               //OnError(2);\r
+               OnError(2);\r
                return;\r
                };\r
         \r
        len = mifare_ultra_halt(cuid);\r
        if(len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)        Dbprintf("Halt error");\r
-               //OnError(3);\r
+               OnError(3);\r
                return;\r
                };\r
                \r
@@ -261,8 +330,8 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
 void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)\r
 {\r
-  // params\r
-        uint8_t sectorNo = arg0;\r
+       // params\r
+       uint8_t sectorNo = arg0;\r
        int Pages = arg1;\r
        int count_Pages = 0;\r
        byte_t dataout[176] = {0x00};;\r
@@ -283,8 +352,8 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
        \r
        if (!len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
-                       Dbprintf("Can't select card");\r
-               //OnError(1);\r
+                       Dbprintf("Can't select card (RC:%d)",len);\r
+               OnError(1);\r
                return;\r
        }\r
        \r
@@ -295,7 +364,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
                if (len) {\r
                        if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
                                Dbprintf("Read block %d error",i);\r
-                       //OnError(2);\r
+                       OnError(2);\r
                        return;\r
                } else {\r
                        count_Pages++;\r
@@ -306,7 +375,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
        if (len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
                        Dbprintf("Halt error");\r
-               //OnError(3);\r
+               OnError(3);\r
                return;\r
        }\r
        \r
@@ -1143,14 +1212,14 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
        if(!len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)        \r
                        Dbprintf("Can't select card");\r
-               //OnError(1);\r
+               OnError(1);\r
                return;\r
        };\r
 \r
        if(mifare_desfire_des_auth1(cuid, dataout)){\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR)        \r
                        Dbprintf("Authentication part1: Fail.");\r
-               //OnError(4);\r
+               OnError(4);\r
                return;\r
        }\r
 \r
@@ -1173,7 +1242,7 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
        if( isOK) {\r
            if (MF_DBGLEVEL >= MF_DBG_EXTENDED) \r
                        Dbprintf("Authentication part2: Failed");  \r
-               //OnError(4);\r
+               OnError(4);\r
                return;\r
        }\r
 \r
index 5737615106c9a0cddd2d8a92d3763807c97d6b01..979e2f39cd2d04b2184d01a74a6f07938ca918dc 100644 (file)
@@ -1,5 +1,6 @@
 #include "mifaredesfire.h"
 #include "des.h"
+#include "BigBuf.h"
 
 #define MAX_APPLICATION_COUNT 28
 #define MAX_FILE_COUNT 16
@@ -23,7 +24,7 @@ bool InitDesfireCard(){
 
        iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
        
-       iso14a_set_tracing(TRUE);
+       set_tracing(TRUE);
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
        
        int len = iso14443a_select_card(NULL,card,NULL);
@@ -65,7 +66,7 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
        }
        
        if ( flags & CLEARTRACE ){
-               iso14a_clear_trace();
+               clear_trace();
        }
        
        if ( flags & INIT ){
@@ -109,8 +110,8 @@ void MifareDesfireGetInformation(){
                PCB == 0x0A because sending CID byte.
                CID == 0x00 first card?         
        */
-       iso14a_clear_trace();
-       iso14a_set_tracing(TRUE);
+       clear_trace();
+       set_tracing(TRUE);
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
 
        // card select - information
@@ -434,8 +435,8 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
        size_t wrappedLen = 0;
        uint8_t wCmd[USB_CMD_DATA_SIZE] = {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];
+    uint8_t par[MAX_PARITY_SIZE];
        
        wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
        
@@ -444,7 +445,7 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
        }
        ReaderTransmit( wCmd, wrappedLen, NULL);
 
-       len = ReaderReceive(resp, resp_par);
+       len = ReaderReceive(resp, par);
        
        if( len == 0x00 ){
                if (MF_DBGLEVEL >= 4) {
index ae116dd63da957fb804fa8d7c7af11da871e0c3d..4fd41b46a170e821cec76275ef3b0aa76ae5774c 100644 (file)
@@ -94,6 +94,8 @@ CMDSRCS =     nonce2key/crapto1.c\
                        cmdhficlass.c \
                        cmdhfmf.c \
             cmdhfmfu.c \
+                       cmdhfmfdes.c \
+                       cmdhftopaz.c \
                        cmdhw.c \
                        cmdlf.c \
                        cmdlfio.c \
index c83cf087293faf83c1a035d666d781a51e28761a..7854fa51d743191c2c2c297810f9f927cc7b0161 100644 (file)
@@ -35,10 +35,10 @@ void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx)
 {
        if (buff == NULL) 
                return;
-       
+
        if ( size >= MAX_DEMOD_BUF_LEN)
                size = MAX_DEMOD_BUF_LEN;
-       
+
        size_t i = 0;
        for (; i < size; i++){
                DemodBuffer[i]=buff[startIdx++];
@@ -283,87 +283,103 @@ void printEM410x(uint32_t hi, uint64_t id)
       PrintAndLog("EM TAG ID    : %06x%016llx", hi, id);
     } else{
       //output 40 bit em id
-    PrintAndLog("EM TAG ID    : %010llx", id);
-    PrintAndLog("Unique TAG ID: %010llx",  id2lo);
-       
-       PrintAndLog("");
-       PrintAndLog("Possible de-scramble patterns");
-       PrintAndLog("HoneyWell IdentKey");
-    PrintAndLog("DEZ 8        : %08lld",id & 0xFFFFFF);
-    PrintAndLog("DEZ 10       : %010lld",id & 0xFFFFFFFF);
-    PrintAndLog("DEZ 5.5      : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
-    PrintAndLog("DEZ 3.5A     : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
-       PrintAndLog("DEZ 3.5B     : %03lld.%05lld",(id & 0xFF000000) >> 24,(id & 0xFFFF));
-       PrintAndLog("DEZ 3.5C     : %03lld.%05lld",(id & 0xFF0000) >> 16,(id & 0xFFFF));
-    PrintAndLog("DEZ 14/IK2   : %014lld",id);
-    PrintAndLog("DEZ 15/IK3   : %015lld",id2lo);
-       PrintAndLog("DEZ 20/ZK    : %02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld",
-                       (id2lo & 0xf000000000) >> 36,
-                       (id2lo & 0x0f00000000) >> 32,
-                       (id2lo & 0x00f0000000) >> 28,
-                       (id2lo & 0x000f000000) >> 24,
-                       (id2lo & 0x0000f00000) >> 20,
-                       (id2lo & 0x00000f0000) >> 16,
-                       (id2lo & 0x000000f000) >> 12,
-                       (id2lo & 0x0000000f00) >> 8,
-                       (id2lo & 0x00000000f0) >> 4,
-                       (id2lo & 0x000000000f)
-                       );
-    PrintAndLog("Other        : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));  
-       PrintAndLog("");                        
-       uint64_t paxton = (((id>>32) << 24) | (id & 0xffffff))  + 0x143e00;
-       PrintAndLog("Pattern Paxton  : %lld (hex %08llX)", paxton, paxton);     
-
-       uint32_t p1id = (id & 0xFFFFFF);
-       uint8_t arr[32] = {0x00};
-       int i =0; 
-       int j = 23;
-       for (; i < 24; ++i, --j ){
-               arr[i] = (p1id >> i) & 1;
-       }
-
-       uint32_t p1  = 0;       
+      PrintAndLog("EM TAG ID    : %010llx", id);
+      PrintAndLog("Unique TAG ID: %010llx",  id2lo);
+      PrintAndLog("");
+      PrintAndLog("Possible de-scramble patterns");
+      PrintAndLog("HoneyWell IdentKey");
+      PrintAndLog("DEZ 8        : %08lld",id & 0xFFFFFF);
+      PrintAndLog("DEZ 10       : %010lld",id & 0xFFFFFFFF);
+      PrintAndLog("DEZ 5.5      : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
+      PrintAndLog("DEZ 3.5A     : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
+      PrintAndLog("DEZ 3.5B     : %03lld.%05lld",(id & 0xFF000000) >> 24,(id & 0xFFFF));
+      PrintAndLog("DEZ 3.5C     : %03lld.%05lld",(id & 0xFF0000) >> 16,(id & 0xFFFF));
+      PrintAndLog("DEZ 14/IK2   : %014lld",id);
+      PrintAndLog("DEZ 15/IK3   : %015lld",id2lo);
+      PrintAndLog("Other        : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));  
+      PrintAndLog("DEZ 20/ZK    : %02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld",
+        (id2lo & 0xf000000000) >> 36,
+        (id2lo & 0x0f00000000) >> 32,
+        (id2lo & 0x00f0000000) >> 28,
+        (id2lo & 0x000f000000) >> 24,
+        (id2lo & 0x0000f00000) >> 20,
+        (id2lo & 0x00000f0000) >> 16,
+        (id2lo & 0x000000f000) >> 12,
+        (id2lo & 0x0000000f00) >> 8,
+        (id2lo & 0x00000000f0) >> 4,
+        (id2lo & 0x000000000f)
+      );
+
+      PrintAndLog("");                 
+      uint64_t paxton = (((id>>32) << 24) | (id & 0xffffff))  + 0x143e00;
+      PrintAndLog("Pattern Paxton  : %0d", paxton);    
+
+      uint32_t p1id = (id & 0xFFFFFF);
+      uint8_t arr[32] = {0x00};
+      int i =0; 
+      int j = 23;
+      for (; i < 24; ++i, --j  ){
+       arr[i] = (p1id >> i) & 1;
+      }
 
-       p1 |= arr[23] << 21;
-       p1 |= arr[22] << 23;
-       p1 |= arr[21] << 20;
-       p1 |= arr[20] << 22;
-       
-       p1 |= arr[19] << 18;
-       p1 |= arr[18] << 16;
-       p1 |= arr[17] << 19;
-       p1 |= arr[16] << 17;
-       
-       p1 |= arr[15] << 13;
-       p1 |= arr[14] << 15;
-       p1 |= arr[13] << 12;
-       p1 |= arr[12] << 14;    
-
-       p1 |= arr[11] << 6;
-       p1 |= arr[10] << 2;
-       p1 |= arr[9]  << 7;
-       p1 |= arr[8]  << 1;
-       
-       p1 |= arr[7]  << 0;
-       p1 |= arr[6]  << 8;
-       p1 |= arr[5]  << 11;
-       p1 |= arr[4]  << 3;     
-       
-       p1 |= arr[3]  << 10;
-       p1 |= arr[2]  << 4;
-       p1 |= arr[1]  << 5;
-       p1 |= arr[0]  << 9;     
-       PrintAndLog("Pattern 1       : %d (hex %X)", p1, p1);
-
-       uint16_t sebury1 = id & 0xFFFF;
-       uint8_t  sebury2 = (id >> 16) & 0x7F;
-       uint32_t sebury3 = id & 0x7FFFFF;
-       PrintAndLog("Pattern Sebury  : %010d %03d %d  (hex: %X %X %X)", sebury3, sebury2, sebury1, sebury3, sebury2, sebury1);
-       }
+      uint32_t p1  = 0;        
+
+      p1 |= arr[23] << 21;
+      p1 |= arr[22] << 23;
+      p1 |= arr[21] << 20;
+      p1 |= arr[20] << 22;
+       
+      p1 |= arr[19] << 18;
+      p1 |= arr[18] << 16;
+      p1 |= arr[17] << 19;
+      p1 |= arr[16] << 17;
+       
+      p1 |= arr[15] << 13;
+      p1 |= arr[14] << 15;
+      p1 |= arr[13] << 12;
+      p1 |= arr[12] << 14;     
+
+      p1 |= arr[11] << 6;
+      p1 |= arr[10] << 2;
+      p1 |= arr[9]  << 7;
+      p1 |= arr[8]  << 1;
+
+      p1 |= arr[7]  << 0;
+      p1 |= arr[6]  << 8;
+      p1 |= arr[5]  << 11;
+      p1 |= arr[4]  << 3;      
+
+      p1 |= arr[3]  << 10;
+      p1 |= arr[2]  << 4;
+      p1 |= arr[1]  << 5;
+      p1 |= arr[0]  << 9;      
+      PrintAndLog("Pattern 1       : 0x%X - %d", p1, p1);
+
+      uint16_t sebury1 = id & 0xFFFF;
+      uint8_t  sebury2 = (id >> 16) & 0x7F;
+      uint32_t sebury3 = id & 0x7FFFFF;
+      PrintAndLog("Pattern Sebury  : %d %d %d  (hex: %X %X %X)", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3);
+    }
   }
   return;
 }
 
+
+int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo)
+{
+  int ans = ASKmanDemod(Cmd, FALSE, FALSE);
+  if (!ans) return 0;
+
+  size_t idx=0;
+  if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, hi, lo)){
+    if (g_debugMode){
+      PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen);
+      printDemodBuff();
+    }
+    return 1;
+  }
+  return 0;    
+}
 //by marshmellow
 //takes 3 arguments - clock, invert and maxErr as integers
 //attempts to demodulate ask while decoding manchester
@@ -384,17 +400,9 @@ int CmdAskEM410xDemod(const char *Cmd)
     PrintAndLog("          : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors");
     return 0;
   }
-  int ans = ASKmanDemod(Cmd, FALSE, FALSE);
-  if (!ans) return 0;
-
-  uint64_t lo =0;
-  uint32_t hi =0;
-  size_t idx=0;
-  if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, &hi, &lo)){
-    if (g_debugMode){
-      PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen);
-      printDemodBuff();
-    }
+  uint32_t hi;
+  uint64_t lo;
+  if (AskEm410xDemod(Cmd, &hi, &lo)) {
     PrintAndLog("EM410x pattern found: ");
     printEM410x(hi, lo);
     return 1;
@@ -550,6 +558,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
                PrintAndLog("Usage:  data biphaserawdecode [offset] [invert] [maxErr]");
                PrintAndLog("     Converts 10 or 01 to 1 and 11 or 00 to 0");
                PrintAndLog("     --must have binary sequence in demodbuffer (run data askrawdemod first)");
+    PrintAndLog("     --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
                PrintAndLog("");
                PrintAndLog("     [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position");
                PrintAndLog("     [invert <0|1>], set to 1 to invert output");
@@ -712,6 +721,8 @@ int Cmdaskbiphdemod(const char *Cmd)
     PrintAndLog("     NOTE: <amplify> can be entered as first, second or last argument");
     PrintAndLog("     NOTE: any other arg must have previous args set to work");
     PrintAndLog("");
+    PrintAndLog("     NOTE: --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
+    PrintAndLog("");
     PrintAndLog("    sample: data rawdemod ab            = demod an ask/biph tag from GraphBuffer");
     PrintAndLog("          : data rawdemod ab a          = demod an ask/biph tag from GraphBuffer, amplified");
     PrintAndLog("          : data rawdemod ab 1 32       = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32");
@@ -741,7 +752,7 @@ int CmdG_Prox_II_Demod(const char *Cmd)
   if (ans < 0){
     if (g_debugMode) PrintAndLog("Error gProxII_Demod");
     return 0;
-    }
+  }
   //got a good demod
   uint32_t ByteStream[65] = {0x00};
   uint8_t xorKey=0;
@@ -846,7 +857,7 @@ int AutoCorrelate(int window, bool SaveGrph, bool verbose)
     } else if (sum > maxSum){
       maxSum=sum;
       lastMax = i;
-  }
+    }
   }
   if (Correlation==0){
     //try again with wider margin
@@ -862,8 +873,8 @@ int AutoCorrelate(int window, bool SaveGrph, bool verbose)
   if (verbose && Correlation > 0) PrintAndLog("Possible Correlation: %d samples",Correlation);
 
   if (SaveGrph){
-  GraphTraceLen = GraphTraceLen - window;
-  memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
+    GraphTraceLen = GraphTraceLen - window;
+    memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
     RepaintGraphWindow();  
   }
   return Correlation;
@@ -1171,7 +1182,7 @@ int FSKrawDemod(const char *Cmd, bool verbose)
     if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits  most tags will have full bit stream inside that sample size
     if (verbose) {
       PrintAndLog("FSK decoded bitstream:");
-    printBitStream(BitStream,size);
+      printBitStream(BitStream,size);
     }
 
     return 1;
@@ -1266,7 +1277,6 @@ int CmdFSKdemodHID(const char *Cmd)
       if(fmtLen==34){
         cardnum = (lo>>1)&0xFFFF;
         fc= ((hi&1)<<15)|(lo>>17);
-               // this could also be QUADRAKEY.  Uses 34bit HID. 
       }
       if(fmtLen==35){
         cardnum = (lo>>1)&0xFFFFF;
@@ -1413,21 +1423,19 @@ int CmdFSKdemodIO(const char *Cmd)
   uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
   uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
   uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
-
   uint8_t crc = bytebits_to_byte(BitStream+idx+54,8);
   uint16_t calccrc = 0;
+
   for (uint8_t i=1; i<6; ++i){
-       calccrc += bytebits_to_byte(BitStream+idx+9*i,8);
-       PrintAndLog("%d", calccrc);
+    calccrc += bytebits_to_byte(BitStream+idx+9*i,8);
+    //PrintAndLog("%d", calccrc);
   }
   calccrc &= 0xff;
   calccrc = 0xff - calccrc;
 
-  char *crcStr = (crc == calccrc) ? "ok": "!crc";
+  char *crcStr = (crc == calccrc) ? "crc ok": "!crc";
 
-  PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)  [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
-  
+  PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
   setDemodBuf(BitStream,64,idx);
   if (g_debugMode){
     PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64);
@@ -1947,25 +1955,22 @@ int NRZrawDemod(const char *Cmd, bool verbose)
   int errCnt=0;
   errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr);
   if (errCnt > maxErr){
-    if (g_debugMode==1 && verbose) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+    if (g_debugMode) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
     return 0;
   } 
   if (errCnt<0|| BitLen<16){  //throw away static - allow 1 and -1 (in case of threshold command first)
-    if (g_debugMode==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+    if (g_debugMode) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
     return 0;
   }
-  if (verbose) 
-       PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
+  if (verbose || g_debugMode) PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
   //prime demod buffer for output
   setDemodBuf(BitStream,BitLen,0);
 
-  if (errCnt>0 && verbose){
-    PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
-  }
-  if (verbose) {
-  PrintAndLog("NRZ demoded bitstream:");
-  // Now output the bitstream to the scrollback by line of 16 bits
-  printDemodBuff();
+  if (errCnt>0 && (verbose || g_debugMode)) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
+  if (verbose || g_debugMode) {
+    PrintAndLog("NRZ demoded bitstream:");
+    // Now output the bitstream to the scrollback by line of 16 bits
+    printDemodBuff();
   }
   return 1; 
 }
@@ -2066,7 +2071,7 @@ int CmdRawDemod(const char *Cmd)
                PrintAndLog("   <help> as 'h', prints the help for the specific modulation");   
                PrintAndLog("   <options> see specific modulation help for optional parameters");                               
                PrintAndLog("");
-               PrintAndLog("    sample: data rawdemod fs h         = print help for ask/raw demod");
+               PrintAndLog("    sample: data rawdemod fs h         = print help specific to fsk demod");
                PrintAndLog("          : data rawdemod fs           = demod GraphBuffer using: fsk - autodetect");
                PrintAndLog("          : data rawdemod ab           = demod GraphBuffer using: ask/biphase - autodetect");
                PrintAndLog("          : data rawdemod am           = demod GraphBuffer using: ask/manchester - autodetect");
@@ -2195,57 +2200,64 @@ uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
        return val;
 }
 
-int CmdSamples(const char *Cmd)
+int getSamples(const char *Cmd, bool silent)
 {
-       //If we get all but the last byte in bigbuf,
-       // we don't have to worry about remaining trash
-       // in the last byte in case the bits-per-sample
-       // does not line up on byte boundaries
-       uint8_t got[BIGBUF_SIZE-1] = { 0 };
+  //If we get all but the last byte in bigbuf,
+  // we don't have to worry about remaining trash
+  // in the last byte in case the bits-per-sample
+  // does not line up on byte boundaries
 
-       int n = strtol(Cmd, NULL, 0);
-       if (n == 0)
-               n = sizeof(got);
+  uint8_t got[BIGBUF_SIZE-1] = { 0 };
 
-       if (n > sizeof(got))
-               n = sizeof(got);
+  int n = strtol(Cmd, NULL, 0);
 
-       PrintAndLog("Reading %d bytes from device memory\n", n);
-       GetFromBigBuf(got,n,0);
-       PrintAndLog("Data fetched");
-       UsbCommand response;
-       WaitForResponse(CMD_ACK, &response);
-       uint8_t bits_per_sample = 8;
+  if (n == 0)
+    n = sizeof(got);
 
-       //Old devices without this feature would send 0 at arg[0]
-       if(response.arg[0] > 0)
-       {
-               sample_config *sc = (sample_config *) response.d.asBytes;
-               PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample
-                                       , sc->decimation);
-               bits_per_sample = sc->bits_per_sample;
-       }
-       if(bits_per_sample < 8)
-       {
-               PrintAndLog("Unpacking...");
-               BitstreamOut bout = { got, bits_per_sample * n,  0};
-               int j =0;
-               for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) {
-                       uint8_t sample = getByte(bits_per_sample, &bout);
-                       GraphBuffer[j] = ((int) sample )- 128;
-               }
-               GraphTraceLen = j;
-               PrintAndLog("Unpacked %d samples" , j );
-       }else
-       {
-               for (int j = 0; j < n; j++) {
-                       GraphBuffer[j] = ((int)got[j]) - 128;
-               }
-               GraphTraceLen = n;
-       }
+  if (n > sizeof(got))
+    n = sizeof(got);
 
-       RepaintGraphWindow();
-       return 0;
+  PrintAndLog("Reading %d bytes from device memory\n", n);
+  GetFromBigBuf(got,n,0);
+  PrintAndLog("Data fetched");
+  UsbCommand response;
+  WaitForResponse(CMD_ACK, &response);
+  uint8_t bits_per_sample = 8;
+
+  //Old devices without this feature would send 0 at arg[0]
+  if(response.arg[0] > 0)
+  {
+    sample_config *sc = (sample_config *) response.d.asBytes;
+    PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample
+          , sc->decimation);
+    bits_per_sample = sc->bits_per_sample;
+  }
+  if(bits_per_sample < 8)
+  {
+    PrintAndLog("Unpacking...");
+    BitstreamOut bout = { got, bits_per_sample * n,  0};
+    int j =0;
+    for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) {
+      uint8_t sample = getByte(bits_per_sample, &bout);
+      GraphBuffer[j] = ((int) sample )- 128;
+    }
+    GraphTraceLen = j;
+    PrintAndLog("Unpacked %d samples" , j );
+  }else
+  {
+    for (int j = 0; j < n; j++) {
+      GraphBuffer[j] = ((int)got[j]) - 128;
+    }
+    GraphTraceLen = n;
+  }
+
+  RepaintGraphWindow();
+  return 0;
+}
+
+int CmdSamples(const char *Cmd)
+{
+  return getSamples(Cmd, false);
 }
 
 int CmdTuneSamples(const char *Cmd)
@@ -2741,60 +2753,52 @@ int CmdZerocrossings(const char *Cmd)
 
 static command_t CommandTable[] =
 {
-  {"help",          CmdHelp,            1, "This help"},
-  {"amp",           CmdAmp,             1, "Amplify peaks"},
+  {"help",            CmdHelp,            1, "This help"},
+  {"amp",             CmdAmp,             1, "Amplify peaks"},
   //{"askdemod",      Cmdaskdemod,        1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
-  {"askedgedetect", CmdAskEdgeDetect,   1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 25)"},
-  {"askem410xdemod",CmdAskEM410xDemod,  1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
-  {"askgproxiidemod",CmdG_Prox_II_Demod,1, "Demodulate a G Prox II tag from GraphBuffer"},
-  //{"askmandemod",   Cmdaskmandemod,     1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"},
-  //{"askrawdemod",   Cmdaskrawdemod,     1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"},
-  {"autocorr",      CmdAutoCorr,        1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
+  {"askedgedetect",   CmdAskEdgeDetect,   1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 25)"},
+  {"askem410xdemod",  CmdAskEM410xDemod,  1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
+  {"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
+  {"autocorr",        CmdAutoCorr,        1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
   {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
-  {"bitsamples",    CmdBitsamples,      0, "Get raw samples as bitstring"},
+  {"bitsamples",      CmdBitsamples,      0, "Get raw samples as bitstring"},
   //{"bitstream",     CmdBitstream,       1, "[clock rate] -- Convert waveform into a bitstream"},
-  {"buffclear",     CmdBuffClear,       1, "Clear sample buffer and graph window"},
-  {"dec",           CmdDec,             1, "Decimate samples"},
-  {"detectclock",   CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
+  {"buffclear",       CmdBuffClear,       1, "Clear sample buffer and graph window"},
+  {"dec",             CmdDec,             1, "Decimate samples"},
+  {"detectclock",     CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
   //{"fskdemod",      CmdFSKdemod,        1, "Demodulate graph window as a HID FSK"},
-  {"fskawiddemod",  CmdFSKdemodAWID,    1, "Demodulate an AWID FSK tag from GraphBuffer"},
+  {"fskawiddemod",    CmdFSKdemodAWID,    1, "Demodulate an AWID FSK tag from GraphBuffer"},
   //{"fskfcdetect",   CmdFSKfcDetect,     1, "Try to detect the Field Clock of an FSK wave"},
-  {"fskhiddemod",   CmdFSKdemodHID,     1, "Demodulate a HID FSK tag from GraphBuffer"},
-  {"fskiodemod",    CmdFSKdemodIO,      1, "Demodulate an IO Prox FSK tag from GraphBuffer"},
-  {"fskpyramiddemod",CmdFSKdemodPyramid,1, "Demodulate a Pyramid FSK tag from GraphBuffer"},
-  {"fskparadoxdemod",CmdFSKdemodParadox,1, "Demodulate a Paradox FSK tag from GraphBuffer"},
-  //{"fskrawdemod",   CmdFSKrawdemod,     1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to bin (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
-  {"getbitstream",  CmdGetBitStream,    1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
-  {"grid",          CmdGrid,            1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
-  {"hexsamples",    CmdHexsamples,      0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
-  {"hide",          CmdHide,            1, "Hide graph window"},
-  {"hpf",           CmdHpf,             1, "Remove DC offset from trace"},
-  {"load",          CmdLoad,            1, "<filename> -- Load trace (to graph window"},
-  {"ltrim",         CmdLtrim,           1, "<samples> -- Trim samples from left of trace"},
-  {"rtrim",         CmdRtrim,           1, "<location to end trace> -- Trim samples from right of trace"},
+  {"fskhiddemod",     CmdFSKdemodHID,     1, "Demodulate a HID FSK tag from GraphBuffer"},
+  {"fskiodemod",      CmdFSKdemodIO,      1, "Demodulate an IO Prox FSK tag from GraphBuffer"},
+  {"fskpyramiddemod", CmdFSKdemodPyramid, 1, "Demodulate a Pyramid FSK tag from GraphBuffer"},
+  {"fskparadoxdemod", CmdFSKdemodParadox, 1, "Demodulate a Paradox FSK tag from GraphBuffer"},
+  {"getbitstream",    CmdGetBitStream,    1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
+  {"grid",            CmdGrid,            1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
+  {"hexsamples",      CmdHexsamples,      0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
+  {"hide",            CmdHide,            1, "Hide graph window"},
+  {"hpf",             CmdHpf,             1, "Remove DC offset from trace"},
+  {"load",            CmdLoad,            1, "<filename> -- Load trace (to graph window"},
+  {"ltrim",           CmdLtrim,           1, "<samples> -- Trim samples from left of trace"},
+  {"rtrim",           CmdRtrim,           1, "<location to end trace> -- Trim samples from right of trace"},
   //{"mandemod",      CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"},
-  {"manrawdecode",  Cmdmandecoderaw,    1, "Manchester decode binary stream in DemodBuffer"},
-  {"manmod",        CmdManchesterMod,   1, "[clock rate] -- Manchester modulate a binary stream"},
-  {"norm",          CmdNorm,            1, "Normalize max/min to +/-128"},
-  //{"nrzdetectclock",CmdDetectNRZClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
-  //{"nrzrawdemod",   CmdNRZrawDemod,     1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate nrz tags and output binary (args optional)"},
-  {"plot",          CmdPlot,            1, "Show graph window (hit 'h' in window for keystroke help)"},
-  //{"pskdetectclock",CmdDetectPSKClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
-  {"printdemodbuffer",CmdPrintDemodBuff,1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"},
-  {"pskindalademod",CmdIndalaDecode,    1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"},
-  //{"psk1rawdemod",  CmdPSK1rawDemod,    1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk1 tags and output binary (args optional)"},
-  //{"psk2rawdemod",  CmdPSK2rawDemod,    1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk2 tags and output binary (args optional)"},
-  {"rawdemod",      CmdRawDemod,        1, "[modulation] ... <options> -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"},  
-  {"samples",       CmdSamples,         0, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"},
-  {"save",          CmdSave,            1, "<filename> -- Save trace (from graph window)"},
-  {"scale",         CmdScale,           1, "<int> -- Set cursor display scale"},
-  {"setdebugmode",  CmdSetDebugMode,    1, "<0|1> -- Turn on or off Debugging Mode for demods"},
-  {"shiftgraphzero",CmdGraphShiftZero,  1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
+  {"manrawdecode",    Cmdmandecoderaw,    1, "Manchester decode binary stream in DemodBuffer"},
+  {"manmod",          CmdManchesterMod,   1, "[clock rate] -- Manchester modulate a binary stream"},
+  {"norm",            CmdNorm,            1, "Normalize max/min to +/-128"},
+  {"plot",            CmdPlot,            1, "Show graph window (hit 'h' in window for keystroke help)"},
+  {"printdemodbuffer",CmdPrintDemodBuff,  1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"},
+  {"pskindalademod",  CmdIndalaDecode,    1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"},
+  {"rawdemod",        CmdRawDemod,        1, "[modulation] ... <options> -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"},  
+  {"samples",         CmdSamples,         0, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"},
+  {"save",            CmdSave,            1, "<filename> -- Save trace (from graph window)"},
+  {"scale",           CmdScale,           1, "<int> -- Set cursor display scale"},
+  {"setdebugmode",    CmdSetDebugMode,    1, "<0|1> -- Turn on or off Debugging Mode for demods"},
+  {"shiftgraphzero",  CmdGraphShiftZero,  1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
   //{"threshold",     CmdThreshold,       1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
-  {"dirthreshold",  CmdDirectionalThreshold,   1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
-  {"tune",          CmdTuneSamples,     0, "Get hw tune samples for graph window"},
-  {"undec",         CmdUndec,           1, "Un-decimate samples by 2"},
-  {"zerocrossings", CmdZerocrossings,   1, "Count time between zero-crossings"},
+  {"dirthreshold",    CmdDirectionalThreshold,   1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
+  {"tune",            CmdTuneSamples,     0, "Get hw tune samples for graph window"},
+  {"undec",           CmdUndec,           1, "Un-decimate samples by 2"},
+  {"zerocrossings",   CmdZerocrossings,   1, "Count time between zero-crossings"},
   {NULL, NULL, 0, NULL}
 };
 
index ea8af9a6bdbf9cc6088bf7139f9834844f9435f4..f1dd9c7b83a6d2a46c7ef94d2c5b7ba41a59a113 100644 (file)
@@ -64,12 +64,16 @@ int CmdThreshold(const char *Cmd);
 int CmdDirectionalThreshold(const char *Cmd);
 int CmdZerocrossings(const char *Cmd);
 int CmdIndalaDecode(const char *Cmd);
+int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo);
 int ASKbiphaseDemod(const char *Cmd, bool verbose);
 int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch);
 int ASKrawDemod(const char *Cmd, bool verbose);
 int FSKrawDemod(const char *Cmd, bool verbose);
 int PSKDemod(const char *Cmd, bool verbose);
 int NRZrawDemod(const char *Cmd, bool verbose);
+void printEM410x(uint32_t hi, uint64_t id);
+int getSamples(const char *Cmd, bool silent);
+
 
 #define MAX_DEMOD_BUF_LEN (1024*128)
 extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
index 22063bbbe566e22e139524ad98ba2cc817c9b641..eba70a663c4ba82e32fab303f6c207ab81051043 100644 (file)
@@ -23,6 +23,8 @@
 #include "cmdhficlass.h"
 #include "cmdhfmf.h"
 #include "cmdhfmfu.h"
+#include "cmdhfmfdes.h"
+#include "cmdhftopaz.h"
 #include "protocols.h"
 
 static int CmdHelp(const char *Cmd);
@@ -141,6 +143,26 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
        }
 }
 
+
+void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
+{
+       switch(cmd[0]) {
+               case TOPAZ_REQA                                         :snprintf(exp, size, "REQA");break;
+               case TOPAZ_WUPA                                         :snprintf(exp, size, "WUPA");break;
+               case TOPAZ_RID                                          :snprintf(exp, size, "RID");break;
+               case TOPAZ_RALL                                         :snprintf(exp, size, "RALL");break;
+               case TOPAZ_READ                                         :snprintf(exp, size, "READ");break;
+               case TOPAZ_WRITE_E                                      :snprintf(exp, size, "WRITE-E");break;
+               case TOPAZ_WRITE_NE                                     :snprintf(exp, size, "WRITE-NE");break;
+               case TOPAZ_RSEG                                         :snprintf(exp, size, "RSEG");break;
+               case TOPAZ_READ8                                        :snprintf(exp, size, "READ8");break;
+               case TOPAZ_WRITE_E8                                     :snprintf(exp, size, "WRITE-E8");break;
+               case TOPAZ_WRITE_NE8                            :snprintf(exp, size, "WRITE-NE8");break;
+               default:                            snprintf(exp,size,"?"); break;
+       }
+}
+
+
 /**
 06 00 = INITIATE
 0E xx = SELECT ID (xx = Chip-ID)
@@ -172,7 +194,34 @@ void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 }
 
 /**
- * @brief iso14443B_CRC_Ok Checks CRC in command or response
+ * @brief iso14443A_CRC_check Checks CRC in command or response
+ * @param isResponse
+ * @param data
+ * @param len
+ * @return  0 : CRC-command, CRC not ok
+ *          1 : CRC-command, CRC ok
+ *          2 : Not crc-command
+ */
+
+uint8_t iso14443A_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
+{
+       uint8_t b1,b2;
+
+       if(len <= 2) return 2;
+
+       if(isResponse & (len < 6)) return 2;
+       
+       ComputeCrc14443(CRC_14443_A, data, len-2, &b1, &b2);
+       if (b1 != data[len-2] || b2 != data[len-1]) {
+               return 0;
+       } else {
+               return 1;
+       }
+}
+
+
+/**
+ * @brief iso14443B_CRC_check Checks CRC in command or response
  * @param isResponse
  * @param data
  * @param len
@@ -190,8 +239,9 @@ uint8_t iso14443B_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
        ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
        if(b1 != data[len-2] || b2 != data[len-1]) {
          return 0;
-       }
+       } else {
        return 1;
+       }
 }
 
 /**
@@ -255,11 +305,66 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
        }
 }
 
-uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles)
+
+bool is_last_record(uint16_t tracepos, uint8_t *trace, uint16_t traceLen)
 {
-       bool isResponse;
-       uint16_t duration, data_len, parity_len;
+       return(tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) >= traceLen);
+}
+
+
+bool next_record_is_response(uint16_t tracepos, uint8_t *trace)
+{
+       uint16_t next_records_datalen = *((uint16_t *)(trace + tracepos + sizeof(uint32_t) + sizeof(uint16_t)));
+       
+       return(next_records_datalen & 0x8000);
+}
+
+
+bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t *tracepos, uint16_t traceLen, uint8_t *trace, uint8_t *frame, uint8_t *topaz_reader_command, uint16_t *data_len)
+{
+
+#define MAX_TOPAZ_READER_CMD_LEN       16
 
+       uint32_t last_timestamp = timestamp + *duration;
+
+       if ((*data_len != 1) || (frame[0] == TOPAZ_WUPA) || (frame[0] == TOPAZ_REQA)) return false;
+
+       memcpy(topaz_reader_command, frame, *data_len);
+
+       while (!is_last_record(*tracepos, trace, traceLen) && !next_record_is_response(*tracepos, trace)) {
+               uint32_t next_timestamp = *((uint32_t *)(trace + *tracepos));
+               *tracepos += sizeof(uint32_t);
+               uint16_t next_duration = *((uint16_t *)(trace + *tracepos));
+               *tracepos += sizeof(uint16_t);
+               uint16_t next_data_len = *((uint16_t *)(trace + *tracepos)) & 0x7FFF;
+               *tracepos += sizeof(uint16_t);
+               uint8_t *next_frame = (trace + *tracepos);
+               *tracepos += next_data_len;
+               if ((next_data_len == 1) && (*data_len + next_data_len <= MAX_TOPAZ_READER_CMD_LEN)) {
+                       memcpy(topaz_reader_command + *data_len, next_frame, next_data_len);
+                       *data_len += next_data_len;
+                       last_timestamp = next_timestamp + next_duration;
+               } else {
+                       // rewind and exit
+                       *tracepos = *tracepos - next_data_len - sizeof(uint16_t) - sizeof(uint16_t) - sizeof(uint32_t);
+                       break;
+               }
+               uint16_t next_parity_len = (next_data_len-1)/8 + 1;
+               *tracepos += next_parity_len;
+       }
+
+       *duration = last_timestamp - timestamp;
+       
+       return true;
+}
+
+
+uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes)
+{
+       bool isResponse;
+       uint16_t data_len, parity_len;
+       uint32_t duration;
+       uint8_t topaz_reader_command[9];
        uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
        char explanation[30] = {0};
 
@@ -290,29 +395,31 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
        uint8_t *parityBytes = trace + tracepos;
        tracepos += parity_len;
 
+       if (protocol == TOPAZ && !isResponse) {
+               // topaz reader commands come in 1 or 9 separate frames with 7 or 8 Bits each.
+               // merge them:
+               if (merge_topaz_reader_frames(timestamp, &duration, &tracepos, traceLen, trace, frame, topaz_reader_command, &data_len)) {
+                       frame = topaz_reader_command;
+               }
+       }
+       
        //Check the CRC status
        uint8_t crcStatus = 2;
 
        if (data_len > 2) {
-               uint8_t b1, b2;
-               if(protocol == ICLASS)
-               {
+               switch (protocol) {
+                       case ICLASS:
                        crcStatus = iclass_CRC_check(isResponse, frame, data_len);
-
-               }else if (protocol == ISO_14443B)
-               {
+                               break;
+                       case ISO_14443B:
+                       case TOPAZ:
                        crcStatus = iso14443B_CRC_check(isResponse, frame, data_len);
-               }
-               else if (protocol == ISO_14443A){//Iso 14443a
-
-                       ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
-
-                       if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
-                               if(!(isResponse & (data_len < 6)))
-                               {
-                                               crcStatus = 0;
-                               }
-                       }
+                               break;
+                       case ISO_14443A:
+                               crcStatus = iso14443A_CRC_check(isResponse, frame, data_len);
+                               break;
+                       default: 
+                               break;
                }
        }
        //0 CRC-command, CRC not ok
@@ -334,19 +441,22 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
                uint8_t parityBits = parityBytes[j>>3];
                if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
                        snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
-
                } else {
                        snprintf(line[j/16]+(( j % 16) * 4),110, "%02x  ", frame[j]);
                }
 
        }
-       if(crcStatus == 1)
+
+       if (markCRCBytes) {
+               if(crcStatus == 0 || crcStatus == 1)
        {//CRC-command
-               char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4)-1;
+                       char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4);
                (*pos1) = '[';
-               char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4)-2;
-               (*pos2) = ']';
+                       char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4);
+                       sprintf(pos2, "%c", ']');
+               }
        }
+
        if(data_len == 0)
        {
                if(data_len == 0){
@@ -361,18 +471,19 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
 
        if(!isResponse)
        {
-               if(protocol == ICLASS)
-                       annotateIclass(explanation,sizeof(explanation),frame,data_len);
-               else if (protocol == ISO_14443A)
-                       annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
-               else if(protocol == ISO_14443B)
-                       annotateIso14443b(explanation,sizeof(explanation),frame,data_len);
+               switch(protocol) {
+                       case ICLASS:            annotateIclass(explanation,sizeof(explanation),frame,data_len); break;
+                       case ISO_14443A:        annotateIso14443a(explanation,sizeof(explanation),frame,data_len); break;
+                       case ISO_14443B:        annotateIso14443b(explanation,sizeof(explanation),frame,data_len); break;
+                       case TOPAZ:                     annotateTopaz(explanation,sizeof(explanation),frame,data_len); break;
+                       default:                        break;
+               }
        }
 
        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",
+                       PrintAndLog(" %10d | %10d | %s |%-64s | %s| %s",
                                (timestamp - first_timestamp),
                                (EndOfTransmissionTimestamp - first_timestamp),
                                (isResponse ? "Tag" : "Rdr"),
@@ -387,20 +498,16 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
                }
        }
 
-       if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
+       if (is_last_record(tracepos, trace, traceLen)) return traceLen;
        
-       bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
-
-       if (showWaitCycles && !isResponse && next_isResponse) {
+       if (showWaitCycles && !isResponse && next_record_is_response(tracepos, trace)) {
                uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
-               if (next_timestamp != 0x44444444) {
                        PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
                                (EndOfTransmissionTimestamp - first_timestamp),
                                (next_timestamp - first_timestamp),
                                "   ",
                                (next_timestamp - EndOfTransmissionTimestamp));
                }
-       }
 
        return tracepos;
 }
@@ -409,34 +516,35 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
 int CmdHFList(const char *Cmd)
 {
        bool showWaitCycles = false;
+       bool markCRCBytes = false;
        char type[40] = {0};
        int tlen = param_getstr(Cmd,0,type);
-       char param = param_getchar(Cmd, 1);
+       char param1 = param_getchar(Cmd, 1);
+       char param2 = param_getchar(Cmd, 2);
        bool errors = false;
        uint8_t protocol = 0;
        //Validate params
-       if(tlen == 0)
-       {
+
+       if(tlen == 0) {
                errors = true;
        }
-       if(param == 'h' || (param !=0 && param != 'f'))
-       {
+
+       if(param1 == 'h'
+                       || (param1 != 0 && param1 != 'f' && param1 != 'c')
+                       || (param2 != 0 && param2 != 'f' && param2 != 'c')) {
                errors = true;
        }
-       if(!errors)
-       {
-               if(strcmp(type, "iclass") == 0)
-               {
+
+       if(!errors) {
+               if(strcmp(type, "iclass") == 0) {
                        protocol = ICLASS;
-               }else if(strcmp(type, "14a") == 0)
-               {
+               } else if(strcmp(type, "14a") == 0) {
                        protocol = ISO_14443A;
-               }
-               else if(strcmp(type, "14b") == 0)
-               {
+               } else if(strcmp(type, "14b") == 0)     {
                        protocol = ISO_14443B;
-               }else if(strcmp(type,"raw")== 0)
-               {
+               } else if(strcmp(type,"topaz")== 0) {
+                       protocol = TOPAZ;
+               } else if(strcmp(type,"raw")== 0) {
                        protocol = -1;//No crc, no annotations
                }else{
                        errors = true;
@@ -445,13 +553,15 @@ int CmdHFList(const char *Cmd)
 
        if (errors) {
                PrintAndLog("List protocol data in trace buffer.");
-               PrintAndLog("Usage:  hf list <protocol> [f]");
+               PrintAndLog("Usage:  hf list <protocol> [f][c]");
                PrintAndLog("    f      - show frame delay times as well");
+               PrintAndLog("    c      - mark CRC bytes");
                PrintAndLog("Supported <protocol> 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("    topaz  - interpret data as topaz communications");
                PrintAndLog("");
                PrintAndLog("example: hf list 14a f");
                PrintAndLog("example: hf list iclass");
@@ -459,10 +569,13 @@ int CmdHFList(const char *Cmd)
        }
 
 
-       if (param == 'f') {
+       if (param1 == 'f' || param2 == 'f') {
                showWaitCycles = true;
        }
 
+       if (param1 == 'c' || param2 == 'c') {
+               markCRCBytes = true;
+       }
 
        uint8_t *trace;
        uint16_t tracepos = 0;
@@ -496,7 +609,7 @@ int CmdHFList(const char *Cmd)
 
        while(tracepos < traceLen)
        {
-               tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles);
+               tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles, markCRCBytes);
        }
 
        free(trace);
@@ -514,9 +627,11 @@ 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"},
+  {"mfu",                      CmdHFMFUltra,   1, "{ MIFARE Ultralight RFIDs... }"},
+  {"mfdes",                    CmdHFMFDes,             1, "{ MIFARE Desfire RFIDs... }"},
+  {"topaz",                    CmdHFTopaz,             1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
+  {"tune",                     CmdHFTune,      0, "Continuously measure HF antenna tuning"},
+  {"list",                     CmdHFList,      1, "List protocol data in trace buffer"},
        {NULL, NULL, 0, NULL}
 };
 
index bce7f4d6cba5f9abfffb613e63ba008e9a2d81ea..6fc4d2a06ba13906f35d248bfbe19df66444f87a 100644 (file)
@@ -140,7 +140,7 @@ int CmdHF14AReader(const char *Cmd)
        iso14a_card_select_t card;
        memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
 
-       uint64_t select_status = resp.arg[0];           // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
+       uint64_t select_status = resp.arg[0];           // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
        
        if(select_status == 0) {
                PrintAndLog("iso14443a card select failed");
@@ -152,6 +152,18 @@ int CmdHF14AReader(const char *Cmd)
                return 0;
        }
 
+       if(select_status == 3) {
+               PrintAndLog("Card doesn't support standard iso14443-3 anticollision");
+       PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
+               // disconnect
+               c.arg[0] = 0;
+               c.arg[1] = 0;
+               c.arg[2] = 0;
+               SendCommand(&c);
+               return 0;
+       }
+
+
        PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
        PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen));
        PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
@@ -497,16 +509,18 @@ int CmdHF14ASnoop(const char *Cmd) {
   return 0;
 }
 
+
 int CmdHF14ACmdRaw(const char *cmd) {
     UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
-    uint8_t reply=1;
-    uint8_t crc=0;
-    uint8_t power=0;
-    uint8_t active=0;
-    uint8_t active_select=0;
+    bool reply=1;
+    bool crc = FALSE;
+    bool power = FALSE;
+    bool active = FALSE;
+    bool active_select = FALSE;
     uint16_t numbits=0;
+       bool bTimeout = FALSE;
        uint32_t timeout=0;
-       uint8_t bTimeout=0;
+       bool topazmode = FALSE;
     char buf[5]="";
     int i=0;
     uint8_t data[USB_CMD_DATA_SIZE];
@@ -522,9 +536,11 @@ int CmdHF14ACmdRaw(const char *cmd) {
         PrintAndLog("       -s    active signal field ON with select");
         PrintAndLog("       -b    number of bits to send. Useful for send partial byte");
                PrintAndLog("       -t    timeout in ms");
+               PrintAndLog("       -T    use Topaz protocol to send command");
         return 0;
     }
 
+
     // strip
     while (*cmd==' ' || *cmd=='\t') cmd++;
 
@@ -533,19 +549,19 @@ int CmdHF14ACmdRaw(const char *cmd) {
         if (cmd[i]=='-') {
             switch (cmd[i+1]) {
                 case 'r': 
-                    reply=0;
+                    reply = FALSE;
                     break;
                 case 'c':
-                    crc=1;
+                    crc = TRUE;
                     break;
                 case 'p':
-                    power=1;
+                    power = TRUE;
                     break;
                 case 'a':
-                    active=1;
+                    active = TRUE;
                     break;
                 case 's':
-                    active_select=1;
+                    active_select = TRUE;
                     break;
                 case 'b': 
                     sscanf(cmd+i+2,"%d",&temp);
@@ -555,13 +571,16 @@ int CmdHF14ACmdRaw(const char *cmd) {
                     i-=2;
                     break;
                                case 't':
-                                       bTimeout=1;
+                                       bTimeout = TRUE;
                                        sscanf(cmd+i+2,"%d",&temp);
                                        timeout = temp;
                                        i+=3;
                                        while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
                                        i-=2;
                                        break;
+                case 'T':
+                                       topazmode = TRUE;
+                                       break;
                 default:
                     PrintAndLog("Invalid option");
                     return 0;
@@ -591,10 +610,15 @@ int CmdHF14ACmdRaw(const char *cmd) {
         PrintAndLog("Invalid char on input");
         return 0;
     }
+
     if(crc && datalen>0 && datalen<sizeof(data)-2)
     {
         uint8_t first, second;
+               if (topazmode) {
+                       ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
+               } else {
         ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
+               }
         data[datalen++] = first;
         data[datalen++] = second;
     }
@@ -607,7 +631,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
     }
 
        if(bTimeout){
-           #define MAX_TIMEOUT 40542464        // (2^32-1) * (8*16) / 13560000Hz * 1000ms/s = 
+           #define MAX_TIMEOUT 40542464        // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
         c.arg[0] |= ISO14A_SET_TIMEOUT;
         if(timeout > MAX_TIMEOUT) {
             timeout = MAX_TIMEOUT;
@@ -615,11 +639,16 @@ int CmdHF14ACmdRaw(const char *cmd) {
         }
                c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
        }
+
     if(power)
         c.arg[0] |= ISO14A_NO_DISCONNECT;
+
     if(datalen>0)
         c.arg[0] |= ISO14A_RAW;
 
+       if(topazmode)
+               c.arg[0] |= ISO14A_TOPAZMODE;
+               
        // Max buffer is USB_CMD_DATA_SIZE
     c.arg[1] = (datalen & 0xFFFF) | (numbits << 16);
     memcpy(c.d.asBytes,data,datalen);
@@ -635,6 +664,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
     return 0;
 }
 
+
 static void waitCmd(uint8_t iSelect)
 {
     uint8_t *recv;
index 75aaa084685a7ced8ea410a6c69d57d86dcc642c..c3cdde2c944e7b4f2baabc35f01f49765552fac3 100644 (file)
@@ -12,7 +12,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include <openssl/des.h>
+//#include <openssl/des.h>
+#include "loclass/des.h"
 #include "cmdmain.h"
 #include "proxmark3.h"
 #include "../include/common.h"
@@ -236,7 +237,7 @@ char * GetCardSizeStr( uint8_t fsize ){
        uint16_t lsize = 1 << (fsize >>1);
        
        // is  LSB set?
-       if (  fsize & (1 << 0 ) )
+       if (  fsize & 1 )
                sprintf(retStr, "0x%02X (%d - %d bytes)",fsize, usize, lsize);
        else 
                sprintf(retStr, "0x%02X (%d bytes)", fsize, lsize);             
@@ -251,7 +252,7 @@ char * GetProtocolStr(uint8_t id){
        if ( id == 0x05)
                sprintf(retStr,"0x%02X (ISO 14443-3, 14443-4)", id);
        else
-               sprintf(retStr,"0x%02X", id);   
+               sprintf(retStr,"0x%02X (Unknown)", id); 
        return buf;
 }
 
index 75080f2513852972d8b55776709644c65d9b6ca6..f85c160a59c419df9146e1ffb0d6b141352906c3 100644 (file)
@@ -7,7 +7,6 @@
 //-----------------------------------------------------------------------------
 // High frequency MIFARE ULTRALIGHT (C) commands
 //-----------------------------------------------------------------------------
-//#include <openssl/des.h>
 #include "loclass/des.h"
 #include "cmdhfmfu.h"
 #include "cmdhfmf.h"
@@ -391,7 +390,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
        //Change key to user defined one
        if (cmdp == 'k' || cmdp == 'K'){
                keyNo = param_get8(Cmd, 1);
-               if(keyNo >= 4) errors = true;
+               if(keyNo > 4) errors = true;
        }
 
        if (cmdp == 'h' || cmdp == 'H') {
@@ -430,7 +429,6 @@ int CmdHF14AMfucAuth(const char *Cmd){
                uint8_t * data= resp.d.asBytes;
 
                if (isOK){
-                       PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
                        memcpy(enc_random_b,data+1,8);
                } else {
                        PrintAndLog("Auth failed");
@@ -440,10 +438,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
                PrintAndLog("Command execute timeout");
                return 1;
        }
-
        uint8_t iv[8]           = { 0 };
-       // Do we need random ? Right now we use all ones, is that random enough ?
-//    DES_random_key(&RndA);
 
        PrintAndLog("     RndA  :%s",sprint_hex(random_a, 8));
        PrintAndLog("     e_RndB:%s",sprint_hex(enc_random_b, 8));
@@ -490,6 +485,23 @@ int CmdHF14AMfucAuth(const char *Cmd){
 
                if (isOK){
                        PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
+                       
+                       uint8_t foo[8] = { 0 };
+                       uint8_t bar[8] = { 0 };
+                       memcpy(foo, data2+1, 8);
+                       des3_set2key_enc(&ctx, key);
+
+                       des3_crypt_cbc(&ctx    // des3_context *ctx
+                               , DES_DECRYPT      // int mode
+                               , 8      // size_t length
+                               , enc_random_b     // unsigned char iv[8]
+                               , foo           // const unsigned char *input
+                               , bar   // unsigned char *output
+                       );
+
+                       PrintAndLog("BAR:%s",sprint_hex(bar, 8));
+
+                       
                } else {
                        return 2;
                }
index c4bc03415c7bb8a8a7467a055d58495d32d614f8..ccb53ad0e99f793c92d957883e6eb61067f07e2e 100644 (file)
@@ -1,6 +1,9 @@
 #include "cmdhfmf.h"
 #include "cmdhf14a.h"
 
+#ifndef CMDHFMFU_H__
+#define CMDHFMFU_H__
+
 //standard ultralight
 int CmdHF14AMfUWrBl(const char *Cmd);
 int CmdHF14AMfURdBl(const char *Cmd);
@@ -14,6 +17,6 @@ int CmdHF14AMfucAuth(const char *Cmd);
 int CmdHF14AMfUDump(const char *Cmd);
 void rol (uint8_t *data, const size_t len);
 
-
 int CmdHFMFUltra(const char *Cmd);
 int CmdHF14AMfUInfo(const char *Cmd);
+#endif
index 46927f74a153ccf1dadb9ab86e3e6ece3d33fe88..30c8bb229fa98b6ffe86f73cac00bfcce24b58f3 100644 (file)
@@ -362,6 +362,7 @@ int usage_lf_read()
        PrintAndLog("Usage: lf read");
        PrintAndLog("Options:        ");
        PrintAndLog("       h            This help");
+       PrintAndLog("       s            silent run no printout");
        PrintAndLog("This function takes no arguments. ");
        PrintAndLog("Use 'lf config' to set parameters.");
        return 0;
@@ -481,13 +482,15 @@ int CmdLFSetConfig(const char *Cmd)
 int CmdLFRead(const char *Cmd)
 {
 
-       uint8_t cmdp =0;
-       if(param_getchar(Cmd, cmdp) == 'h')
+       uint8_t cmdp = 0;
+       bool arg1 = false;
+       if (param_getchar(Cmd, cmdp) == 'h')
        {
                return usage_lf_read();
        }
+       if (param_getchar(Cmd, cmdp) == 's') arg1 = true; //suppress print
        //And ship it to device
-       UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
+       UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
        SendCommand(&c);
        //WaitForResponse(CMD_ACK,NULL);        
        if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
@@ -1041,57 +1044,61 @@ int CmdLFfind(const char *Cmd)
     return 0;
   }
   if (cmdp == 'u' || cmdp == 'U') testRaw = 'u';
-  
+
   PrintAndLog("NOTE: some demods output possible binary\n  if it finds something that looks like a tag");
   PrintAndLog("False Positives ARE possible\n");  
   PrintAndLog("\nChecking for known tags:\n");
-  
+
   ans=CmdFSKdemodIO("");
   
   if (ans>0) {
     PrintAndLog("\nValid IO Prox ID Found!");
     return 1;
   }
-  
+
   ans=CmdFSKdemodPyramid("");
   if (ans>0) {
     PrintAndLog("\nValid Pyramid ID Found!");
     return 1;
   }
-  
+
   ans=CmdFSKdemodParadox("");
   if (ans>0) {
     PrintAndLog("\nValid Paradox ID Found!");
     return 1;
   }
-  
+
   ans=CmdFSKdemodAWID("");
   if (ans>0) {
     PrintAndLog("\nValid AWID ID Found!");
     return 1;
   }
-  
+
   ans=CmdFSKdemodHID("");
   if (ans>0) {
     PrintAndLog("\nValid HID Prox ID Found!");
     return 1;
   }
+
   //add psk and indala
   ans=CmdIndalaDecode("");
   if (ans>0) {
     PrintAndLog("\nValid Indala ID Found!");
     return 1;
   }
+
   ans=CmdAskEM410xDemod("");
   if (ans>0) {
     PrintAndLog("\nValid EM410x ID Found!");
     return 1;
   }
+
   ans=CmdG_Prox_II_Demod("");
   if (ans>0) {
     PrintAndLog("\nValid G Prox II ID Found!");
     return 1;
   }
+
   PrintAndLog("\nNo Known Tags Found!\n");
   if (testRaw=='u' || testRaw=='U'){
     //test unknown tag formats (raw mode)
@@ -1170,7 +1177,7 @@ static command_t CommandTable[] =
   {"flexdemod",   CmdFlexdemod,       1, "Demodulate samples for FlexPass"},
   {"indalademod", CmdIndalaDemod,     1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
   {"indalaclone", CmdIndalaClone,     0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
-  {"read",        CmdLFRead,          0, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
+  {"read",        CmdLFRead,          0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
   {"search",      CmdLFfind,          1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"},
   {"sim",         CmdLFSim,           0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
   {"simask",      CmdLFaskSim,        0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"},
index f6671bcdb27586eb376e147d9df30ed27cdaf17a..b915aa5aac5f62f63e7d35a70f6bd23a61cf78cd 100644 (file)
@@ -43,163 +43,24 @@ int CmdEMdemodASK(const char *Cmd)
  */
 int CmdEM410xRead(const char *Cmd)
 {
-  int i, j, clock, header, rows, bit, hithigh, hitlow, first, bit2idx, high, low;
-  int parity[4];
-  char id[11] = {0x00};
-  char id2[11] = {0x00};
-  int retested = 0;
-  uint8_t BitStream[MAX_GRAPH_TRACE_LEN];
-  high = low = 0;
-
-  /* Detect high and lows and clock */
-  for (i = 0; i < GraphTraceLen; i++)
-  {
-    if (GraphBuffer[i] > high)
-      high = GraphBuffer[i];
-    else if (GraphBuffer[i] < low)
-      low = GraphBuffer[i];
-  }
-
-  /* get clock */
-  clock = GetAskClock(Cmd, false, false);
-
-  /* parity for our 4 columns */
-  parity[0] = parity[1] = parity[2] = parity[3] = 0;
-  header = rows = 0;
-
-  // manchester demodulate
-  bit = bit2idx = 0;
-  for (i = 0; i < (int)(GraphTraceLen / clock); i++)
-  {
-    hithigh = 0;
-    hitlow = 0;
-    first = 1;
-
-    /* Find out if we hit both high and low peaks */
-    for (j = 0; j < clock; j++)
-    {
-      if (GraphBuffer[(i * clock) + j] >= high)
-        hithigh = 1;
-      else if (GraphBuffer[(i * clock) + j] <= low)
-        hitlow = 1;
-
-      /* it doesn't count if it's the first part of our read
-       because it's really just trailing from the last sequence */
-      if (first && (hithigh || hitlow))
-        hithigh = hitlow = 0;
-      else
-        first = 0;
-
-      if (hithigh && hitlow)
-        break;
-    }
-
-    /* If we didn't hit both high and low peaks, we had a bit transition */
-    if (!hithigh || !hitlow)
-      bit ^= 1;
-
-    BitStream[bit2idx++] = bit;
-  }
-
-retest:
-  /* We go till 5 before the graph ends because we'll get that far below */
-  for (i = 1; i < bit2idx - 5; i++)
-  {
-    /* Step 2: We have our header but need our tag ID */
-    if (header == 9 && rows < 10)
-    {
-      /* Confirm parity is correct */
-      if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4])
-      {
-        /* Read another byte! */
-        sprintf(id+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3]));
-        sprintf(id2+rows, "%x", (8 * BitStream[i+3]) + (4 * BitStream[i+2]) + (2 * BitStream[i+1]) + (1 * BitStream[i]));
-        rows++;
-
-        /* Keep parity info */
-        parity[0] ^= BitStream[i];
-        parity[1] ^= BitStream[i+1];
-        parity[2] ^= BitStream[i+2];
-        parity[3] ^= BitStream[i+3];
-
-        /* Move 4 bits ahead */
-        i += 4;
-      }
-
-      /* Damn, something wrong! reset */
-      else
-      {
-        PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i);
-
-        /* Start back rows * 5 + 9 header bits, -1 to not start at same place */
-        i -= 9 + (5 * rows) - 5;
-
-        rows = header = 0;
-      }
-    }
-
-    /* Step 3: Got our 40 bits! confirm column parity */
-    else if (rows == 10)
-    {
-      /* We need to make sure our 4 bits of parity are correct and we have a stop bit */
-      if (BitStream[i] == parity[0] && BitStream[i+1] == parity[1] &&
-        BitStream[i+2] == parity[2] && BitStream[i+3] == parity[3] &&
-        BitStream[i+4] == 0)
-      {
-        /* Sweet! */
-        PrintAndLog("EM410x Tag ID: %s", id);
-        PrintAndLog("Unique Tag ID: %s", id2);
-
-               global_em410xId = id;
-               
-        /* Stop any loops */
-        return 1;
-      }
-
-      /* Crap! Incorrect parity or no stop bit, start all over */
-      else
-      {
-        rows = header = 0;
-
-        /* Go back 59 bits (9 header bits + 10 rows at 4+1 parity) */
-        i -= 59;
-      }
-    }
-
-    /* Step 1: get our header */
-    else if (header < 9)
-    {
-      /* Need 9 consecutive 1's */
-      if (BitStream[i] == 1)
-        header++;
-
-      /* We don't have a header, not enough consecutive 1 bits */
-      else
-        header = 0;
-    }
-  }
-
-  /* if we've already retested after flipping bits, return */
-       if (retested++){
-               PrintAndLog("Failed to decode");
+  uint32_t hi=0;
+  uint64_t lo=0;
+
+  if(!AskEm410xDemod("", &hi, &lo)) return 0;
+  PrintAndLog("EM410x pattern found: ");
+  printEM410x(hi, lo);
+  if (hi){
+    PrintAndLog ("EM410x XL pattern found");
     return 0;
-       }
-
-  /* if this didn't work, try flipping bits */
-  for (i = 0; i < bit2idx; i++)
-    BitStream[i] ^= 1;
-
-  goto retest;
+  }
+  char id[12] = {0x00};
+  sprintf(id, "%010llx",lo);
+  
+  global_em410xId = id;
+  return 1;
 }
 
-/* emulate an EM410X tag
- * Format:
- *   1111 1111 1           <-- standard non-repeatable header
- *   XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID
- *   ....
- *   CCCC                  <-- each bit here is parity for the 10 bits above in corresponding column
- *   0                     <-- stop bit, end of tag
- */
+// emulate an EM410X tag
 int CmdEM410xSim(const char *Cmd)
 {
        int i, n, j, binary[4], parity[4];
@@ -282,28 +143,25 @@ int CmdEM410xSim(const char *Cmd)
 */
 int CmdEM410xWatch(const char *Cmd)
 {
-       char cmdp = param_getchar(Cmd, 0);
-       int read_h = (cmdp == 'h');
        do {
                if (ukbhit()) {
                        printf("\naborted via keyboard!\n");
                        break;
                }
                
-               CmdLFRead(read_h ? "h" : "");
-               CmdSamples("6000");             
-       } while (
-               !CmdEM410xRead("") 
-       );
+               CmdLFRead("s");
+               getSamples("8192",true); //capture enough to get 2 full messages                
+       } while (!CmdEM410xRead(""));
+
        return 0;
 }
 
 int CmdEM410xWatchnSpoof(const char *Cmd)
 {
        CmdEM410xWatch(Cmd);
-    PrintAndLog("# Replaying : %s",global_em410xId);
-    CmdEM410xSim(global_em410xId);
-  return 0;
+       PrintAndLog("# Replaying captured ID: %s",global_em410xId);
+       CmdLFaskSim("");
+       return 0;
 }
 
 /* Read the transmitted data of an EM4x50 tag
index 61758bde01e576c632dafcce0fe9c23f3af8e9a6..da3ee1a9f04b3f4612d69e30946a341665e9f84c 100644 (file)
@@ -33,11 +33,12 @@ t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offse
 \r
 int usage_t55xx_config(){\r
        PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>]");\r
-       PrintAndLog("Options:");\r
-       PrintAndLog("       h                                  This help");\r
-       PrintAndLog("       d <FSK|ASK|PSK1|PSK2|PSK3|NRZ|BI>  Set demodulation");\r
-       PrintAndLog("       i [1]                              Inverse data signal, defaults to normal");\r
-       PrintAndLog("       o [offset]                         Set offset where data should start decode in bitstream");\r
+       PrintAndLog("Options:        ");\r
+       PrintAndLog("       h                        This help");\r
+       PrintAndLog("       b <8|16|32|40|50|64|100|128>     Set bitrate");\r
+       PrintAndLog("       d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NZ|BI|BIa>  Set demodulation FSK / ASK / PSK / NZ / Biphase / Biphase A");\r
+       PrintAndLog("       i [1]                            Invert data signal, defaults to normal");\r
+       PrintAndLog("       o [offset]                       Set offset, where data should start decode in bitstream");\r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
        PrintAndLog("      lf t55xx config d FSK          - FSK demodulation");\r
@@ -100,8 +101,7 @@ int usage_t55xx_dump(){
        return 0;\r
 }\r
 int usage_t55xx_detect(){\r
-       PrintAndLog("Usage:  lf t55xx detect [1]");\r
-       PrintAndLog("     [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
+       PrintAndLog("Usage:  lf t55xx detect");\r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
        PrintAndLog("      lf t55xx detect");\r
@@ -119,7 +119,8 @@ int CmdT55xxSetConfig(const char *Cmd) {
        uint8_t cmdp = 0;\r
        char modulation[5] = {0x00};\r
        char tmp = 0x00;\r
-       \r
+       uint8_t bitRate = 0;\r
+       uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};\r
        while(param_getchar(Cmd, cmdp) != 0x00 && !errors)\r
        {\r
                tmp = param_getchar(Cmd, cmdp);\r
@@ -128,12 +129,34 @@ int CmdT55xxSetConfig(const char *Cmd) {
                case 'h':\r
                case 'H':\r
                        return usage_t55xx_config();\r
+               case 'b':\r
+                       errors |= param_getdec(Cmd, cmdp+1, &bitRate);\r
+                       if ( !errors){\r
+                               uint8_t i = 0;\r
+                               for (; i < 9; i++){\r
+                                       if (rates[i]==bitRate) {\r
+                                               config.bitrate = i;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               if (i==9) errors = TRUE;\r
+                       }\r
+                       cmdp+=2;\r
+                       break;\r
                case 'd':\r
                        param_getstr(Cmd, cmdp+1, modulation);\r
                        cmdp += 2;\r
-                       \r
+\r
                        if ( strcmp(modulation, "FSK" ) == 0)\r
                                config.modulation = DEMOD_FSK;\r
+                       else if ( strcmp(modulation, "FSK1" ) == 0)\r
+                               config.modulation = DEMOD_FSK1;\r
+                       else if ( strcmp(modulation, "FSK1a" ) == 0)\r
+                               config.modulation = DEMOD_FSK1a;\r
+                       else if ( strcmp(modulation, "FSK2" ) == 0)\r
+                               config.modulation = DEMOD_FSK2;\r
+                       else if ( strcmp(modulation, "FSK2a" ) == 0)\r
+                               config.modulation = DEMOD_FSK2a;\r
                        else if ( strcmp(modulation, "ASK" ) == 0)\r
                                config.modulation = DEMOD_ASK;\r
                        else if ( strcmp(modulation, "NRZ" ) == 0)\r
@@ -143,7 +166,9 @@ int CmdT55xxSetConfig(const char *Cmd) {
                        else if ( strcmp(modulation, "PSK2" ) == 0)\r
                                config.modulation = DEMOD_PSK2;\r
                        else if ( strcmp(modulation, "PSK3" ) == 0)\r
-                               config.modulation = DEMOD_PSK3;                 \r
+                               config.modulation = DEMOD_PSK3;\r
+                       else if ( strcmp(modulation, "BIa" ) == 0)\r
+                               config.modulation = DEMOD_BIa;\r
                        else if ( strcmp(modulation, "BI" ) == 0)\r
                                config.modulation = DEMOD_BI;\r
                        else {\r
@@ -156,10 +181,10 @@ int CmdT55xxSetConfig(const char *Cmd) {
                        cmdp+=2;\r
                        break;\r
                case 'o':\r
-                       errors |= param_getdec(Cmd, cmdp+1,&offset);\r
+                       errors |= param_getdec(Cmd, cmdp+1, &offset);\r
                        if ( !errors )\r
                                config.offset = offset;\r
-                       cmdp += 2;\r
+                       cmdp+=2;\r
                        break;\r
                default:\r
                        PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
@@ -176,9 +201,9 @@ int CmdT55xxSetConfig(const char *Cmd) {
        //Validations\r
        if (errors)\r
                return usage_t55xx_config();\r
-       \r
-       config.block0 = 0;\r
-       printConfiguration( config );\r
+\r
+       config.block0 = 0;\r
+       printConfiguration ( config );\r
        return 0;\r
 }\r
 \r
@@ -220,94 +245,148 @@ int CmdT55xxReadBlock(const char *Cmd) {
        GetFromBigBuf(got,sizeof(got),0);\r
        WaitForResponse(CMD_ACK,NULL);\r
        setGraphBuf(got, 12000);\r
-\r
-       DecodeT55xxBlock();\r
-       printT55xxBlock("");\r
+       DemodBufferLen=0;\r
+       if (!DecodeT55xxBlock()) return 3;\r
+       char blk[10]={0};\r
+       sprintf(blk,"%d", block);\r
+       printT55xxBlock(blk);\r
        return 0;\r
 }\r
 \r
-void DecodeT55xxBlock(){\r
+bool DecodeT55xxBlock(){\r
        \r
        char buf[8] = {0x00};\r
        char *cmdStr = buf;\r
+       int ans = 0;\r
+       uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};\r
 \r
        DemodBufferLen = 0x00;\r
-       \r
+\r
        switch( config.modulation ){\r
                case DEMOD_FSK:\r
-                       sprintf(cmdStr,"0 %d", config.inverted );\r
-                       FSKrawDemod(cmdStr, FALSE);\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d %d", bitRate[config.bitrate], config.inverted );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_FSK1:\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d 1 8 5", bitRate[config.bitrate] );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_FSK1a:\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d 0 8 5", bitRate[config.bitrate] );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_FSK2:\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d 0 10 8", bitRate[config.bitrate] );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_FSK2a:\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d 1 10 8", bitRate[config.bitrate] );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
                        break;\r
                case DEMOD_ASK:\r
-                       sprintf(cmdStr,"0 %d 1", config.inverted );\r
-                       ASKmanDemod(cmdStr, FALSE, FALSE);\r
+                       sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );\r
+                       ans = ASKmanDemod(cmdStr, FALSE, FALSE);\r
                        break;\r
                case DEMOD_PSK1:\r
-                       sprintf(cmdStr,"0 %d 1", config.inverted );\r
-                       PSKDemod(cmdStr, FALSE);\r
+                       sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );\r
+                       ans = PSKDemod(cmdStr, FALSE);\r
                        break;\r
                case DEMOD_PSK2:\r
-                       sprintf(cmdStr,"0 %d 1", config.inverted );\r
-                       PSKDemod(cmdStr, FALSE);\r
+                       sprintf(cmdStr,"%d 1", bitRate[config.bitrate] );\r
+                       ans = PSKDemod(cmdStr, FALSE);\r
                        psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
                        break;\r
                case DEMOD_PSK3:\r
-                       sprintf(cmdStr,"0 %d 1", config.inverted );\r
-                       PSKDemod(cmdStr, FALSE);\r
+                       sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );\r
+                       ans = PSKDemod(cmdStr, FALSE);\r
                        psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
                        break;\r
                case DEMOD_NRZ:\r
-                       sprintf(cmdStr,"0 %d 1", config.inverted );\r
-                       NRZrawDemod(cmdStr, FALSE);\r
+                       sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );\r
+                       ans = NRZrawDemod(cmdStr, FALSE);\r
                        break;\r
                case DEMOD_BI:\r
-                       sprintf(cmdStr,"0 0 %d 1", config.inverted );\r
-                       ASKbiphaseDemod(cmdStr, FALSE);\r
+                       sprintf(cmdStr,"0 %d 0 1", bitRate[config.bitrate] );\r
+                       ans = ASKbiphaseDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_BIa:\r
+                       sprintf(cmdStr,"0 %d 1 1", bitRate[config.bitrate] );\r
+                       ans = ASKbiphaseDemod(cmdStr, FALSE);\r
                        break;\r
                default:\r
-               return;\r
+                       return FALSE;\r
        }\r
+       return (bool) ans;\r
 }\r
 \r
 int CmdT55xxDetect(const char *Cmd){\r
 \r
        char cmdp = param_getchar(Cmd, 0);\r
-       \r
-       if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') \r
+       if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')\r
                return usage_t55xx_detect();\r
-\r
+       \r
        if (strlen(Cmd)==0)\r
                AquireData( CONFIGURATION_BLOCK );\r
-       \r
+\r
        if ( !tryDetectModulation() )\r
                PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");\r
 \r
        return 0;\r
 }\r
 \r
+// detect configuration?\r
 bool tryDetectModulation(){\r
-       \r
+       char cmdStr[8] = {0};\r
        uint8_t hits = 0;\r
        t55xx_conf_block_t tests[15];\r
        \r
        if (GetFskClock("", FALSE, FALSE)){ \r
+               uint8_t fc1 = 0, fc2 = 0, clk=0;\r
+               fskClocks(&fc1, &fc2, &clk, FALSE);\r
+               sprintf(cmdStr,"%d", clk/2);\r
+               CmdLtrim(cmdStr);\r
                if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset)){\r
                        tests[hits].modulation = DEMOD_FSK;\r
+                       if (fc1==8 && fc2 == 5)\r
+                               tests[hits].modulation = DEMOD_FSK1a;\r
+                       else if (fc1==10 && fc2 == 8)\r
+                               tests[hits].modulation = DEMOD_FSK2;\r
+\r
                        tests[hits].inverted = FALSE;\r
-                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);                     \r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
                        ++hits;\r
                }\r
                if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset)) {\r
                        tests[hits].modulation = DEMOD_FSK;\r
+                       if (fc1==8 && fc2 == 5)\r
+                               tests[hits].modulation = DEMOD_FSK1;\r
+                       else if (fc1==10 && fc2 == 8)\r
+                               tests[hits].modulation = DEMOD_FSK2a;\r
+\r
                        tests[hits].inverted = TRUE;\r
-                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);                     \r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
                        ++hits;\r
-                       }\r
-    } else {\r
+               }\r
+       } else {\r
                if ( ASKmanDemod("0 0 1", FALSE, FALSE) && test(DEMOD_ASK, &tests[hits].offset)) {\r
                        tests[hits].modulation = DEMOD_ASK;\r
                        tests[hits].inverted = FALSE;\r
-                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);                     \r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
                        ++hits;\r
                        }\r
 \r
@@ -335,14 +414,14 @@ bool tryDetectModulation(){
                if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) {\r
                        tests[hits].modulation = DEMOD_PSK1;\r
                        tests[hits].inverted = FALSE;\r
-                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);                     \r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
                        ++hits;\r
                }\r
                \r
                if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) {\r
                        tests[hits].modulation = DEMOD_PSK1;\r
                        tests[hits].inverted = TRUE;\r
-                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);                     \r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
                        ++hits;\r
                }\r
 \r
@@ -352,20 +431,10 @@ bool tryDetectModulation(){
                        if (test(DEMOD_PSK2, &tests[hits].offset)){\r
                                tests[hits].modulation = DEMOD_PSK2;\r
                                tests[hits].inverted = FALSE;\r
-                               tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);                             \r
-                               ++hits;\r
-                       }\r
-               }\r
-               // PSK2 - needs a call to psk1TOpsk2.\r
-               if ( PSKDemod("0 1 1", FALSE)) {\r
-                       psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
-                       if (test(DEMOD_PSK2, &tests[hits].offset)){\r
-                               tests[hits].modulation = DEMOD_PSK2;\r
-                               tests[hits].inverted = TRUE;\r
-                               tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);                             \r
+                               tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
                                ++hits;\r
                        }\r
-               }\r
+               } // inverse waves does not affect this demod\r
 \r
                // PSK3 - needs a call to psk1TOpsk2.\r
                if ( PSKDemod("0 0 1", FALSE)) {\r
@@ -373,43 +442,29 @@ bool tryDetectModulation(){
                        if (test(DEMOD_PSK3, &tests[hits].offset)){\r
                                tests[hits].modulation = DEMOD_PSK3;\r
                                tests[hits].inverted = FALSE;\r
-                               tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);                             \r
-                               ++hits;\r
-                       }\r
-               }\r
-               // PSK3 - needs a call to psk1TOpsk2.\r
-               if ( PSKDemod("0 1 1", FALSE)) {\r
-                       psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
-                       if (test(DEMOD_PSK3, &tests[hits].offset)){\r
-                               tests[hits].modulation = DEMOD_PSK3;\r
-                               tests[hits].inverted = TRUE;\r
                                tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
                                ++hits;\r
                        }\r
-               }\r
-               \r
+               } // inverse waves does not affect this demod\r
+       \r
                if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset) ) {\r
                        tests[hits].modulation = DEMOD_BI;\r
                        tests[hits].inverted = FALSE;\r
                        tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
                        ++hits;\r
                }\r
-               if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BI, &tests[hits].offset) ) {\r
-                       tests[hits].modulation = DEMOD_BI;\r
+               if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset) ) {\r
+                       tests[hits].modulation = DEMOD_BIa;\r
                        tests[hits].inverted = TRUE;\r
                        tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
                        ++hits;\r
                }\r
        }               \r
-\r
        if ( hits == 1) {\r
                config.modulation = tests[0].modulation;\r
                config.inverted = tests[0].inverted;\r
                config.offset = tests[0].offset;\r
-               \r
-               DecodeT55xxBlock();\r
-               if (DemodBufferLen > config.offset + 32) \r
-                       config.block0 = PackBits(config.offset, 32, DemodBuffer);\r
+               config.block0 = tests[0].block0;\r
                printConfiguration( config );\r
                return TRUE;\r
        }\r
@@ -430,22 +485,112 @@ bool testModulation(uint8_t mode, uint8_t modread){
                        if (modread > 3 && modread < 8) return TRUE;\r
                        break;\r
                case DEMOD_ASK:\r
-                       if (modread == 8) return TRUE;\r
+                       if (modread == DEMOD_ASK) return TRUE;\r
                        break;\r
                case DEMOD_PSK1:\r
-                       if (modread == 1) return TRUE;\r
+                       if (modread == DEMOD_PSK1) return TRUE;\r
                        break;\r
                case DEMOD_PSK2:\r
-                       if (modread == 2) return TRUE;\r
+                       if (modread == DEMOD_PSK2) return TRUE;\r
                        break;\r
                case DEMOD_PSK3:\r
-                       if (modread == 3) return TRUE;\r
+                       if (modread == DEMOD_PSK3) return TRUE;\r
                        break;\r
                case DEMOD_NRZ:\r
-                       if (!modread) return TRUE;\r
+                       if (modread == DEMOD_NRZ) return TRUE;\r
                        break;\r
                case DEMOD_BI:\r
-                       if (modread == 16) return TRUE;\r
+                       if (modread == DEMOD_BI) return TRUE;\r
+                       break;\r
+               case DEMOD_BIa:\r
+                       if (modread == DEMOD_BIa) return TRUE;\r
+                       break;          \r
+               default:\r
+                       return FALSE;\r
+       }\r
+       return FALSE;\r
+}\r
+\r
+bool testBitRate(uint8_t readRate, uint8_t mod){\r
+       uint8_t expected[8] = {8, 16, 32, 40, 50, 64, 100, 128};\r
+       uint8_t detRate = 0;\r
+       switch( mod ){\r
+               case DEMOD_FSK:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_FSK1:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_FSK1a:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_FSK2:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_FSK2a:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_ASK:\r
+                       detRate = GetAskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_PSK1:\r
+                       detRate = GetPskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_PSK2:\r
+                       detRate = GetPskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_PSK3:\r
+                       detRate = GetPskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_NRZ:\r
+                       detRate = GetNrzClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_BI:\r
+                       detRate = GetAskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
                        break;\r
                default:\r
                        return FALSE;\r
@@ -456,21 +601,19 @@ bool testModulation(uint8_t mode, uint8_t modread){
 bool test(uint8_t mode, uint8_t *offset){\r
 \r
        if ( !DemodBufferLen) return FALSE;\r
-       \r
        uint8_t si = 0;\r
-       for (uint8_t idx = 0; idx < 64; ++idx){\r
+       for (uint8_t idx = 0; idx < 64; idx++){\r
                si = idx;\r
                if ( PackBits(si, 32, DemodBuffer) == 0x00 ) continue;\r
 \r
                uint8_t safer    = PackBits(si, 4, DemodBuffer); si += 4;           //master key\r
                uint8_t resv     = PackBits(si, 4, DemodBuffer); si += 4;     //was 7 & +=7+3 //should be only 4 bits if extended mode\r
-\r
                // 2nibble must be zeroed.\r
                // moved test to here, since this gets most faults first.\r
                if ( resv > 0x00) continue;\r
 \r
-               uint8_t xtRate   = PackBits(si, 3, DemodBuffer); si += 3+3;   //new\r
-               //uint8_t bitRate  = PackBits(si, 3, DemodBuffer); si += 3;   //new  could check bit rate\r
+               uint8_t xtRate   = PackBits(si, 3, DemodBuffer); si += 3;   //new\r
+               uint8_t bitRate  = PackBits(si, 3, DemodBuffer); si += 3;   //new  could check bit rate\r
                uint8_t extend   = PackBits(si, 1, DemodBuffer); si += 1;     //bit 15 extended mode\r
                uint8_t modread  = PackBits(si, 5, DemodBuffer); si += 5+2+1; //new\r
                //uint8_t pskcr   = PackBits(si, 2, DemodBuffer); si += 2+1;  //new  could check psk cr\r
@@ -483,33 +626,33 @@ bool test(uint8_t mode, uint8_t *offset){
                if (!extMode){\r
                        if (nml01 || nml02 || xtRate) continue;\r
                }\r
-\r
                //test modulation\r
                if (!testModulation(mode, modread)) continue;\r
-               \r
+\r
                *offset = idx;\r
+               if (!testBitRate(bitRate, mode)) continue;\r
                return TRUE;\r
        }\r
        return FALSE;\r
 }\r
 \r
 void printT55xxBlock(const char *demodStr){\r
-\r
+       \r
        uint8_t i = config.offset;\r
-       uint8_t endpos = 32 + i;        \r
+       uint8_t endpos = 32 + i;\r
        uint32_t blockData = 0;\r
        uint8_t bits[64] = {0x00};\r
 \r
        if ( !DemodBufferLen) return;\r
-       \r
+\r
        if ( endpos > DemodBufferLen){\r
                PrintAndLog("The configured offset %d is too big. Possible offset: %d)", i, DemodBufferLen-32);\r
                return;\r
        }\r
 \r
-    for (; i < endpos; ++i)\r
-               bits[i - config.offset] = DemodBuffer[i];\r
-       \r
+       for (; i < endpos; ++i)\r
+               bits[i - config.offset]=DemodBuffer[i];\r
+\r
        blockData = PackBits(0, 32, bits);\r
        PrintAndLog("0x%08X  %s [%s]", blockData, sprint_bin(bits,32), demodStr);\r
 }\r
@@ -527,11 +670,7 @@ int special(const char *Cmd) {
                        bits[i]=DemodBuffer[j+i];\r
        \r
                blockData = PackBits(0, 32, bits);\r
-\r
-               //char indicate[4] = {0x00};\r
-               // if ( (blockData >> 24) == 0xE0 )\r
-                       // sprintf(indicate,"<--");\r
-               //PrintAndLog("[%02d] 0x%08X  %s %s",j , blockData, sprint_bin(bits,32), indicate);     \r
+               \r
                PrintAndLog("[%02d] 0x%08X  %s",j , blockData, sprint_bin(bits,32));    \r
        }\r
        return 0;\r
@@ -539,6 +678,7 @@ int special(const char *Cmd) {
 \r
 void printConfiguration( t55xx_conf_block_t b){\r
        PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );\r
+       PrintAndLog("Bit Rate   : %s", GetBitRateStr(b.bitrate) );\r
        PrintAndLog("Inverted   : %s", (b.inverted) ? "Yes" : "No" );\r
        PrintAndLog("Offset     : %d", b.offset);\r
        PrintAndLog("Block0     : 0x%08X", b.block0);\r
@@ -572,7 +712,7 @@ int CmdT55xxWriteBlock(const char *Cmd)
        UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};\r
        c.d.asBytes[0] = 0x0; \r
 \r
-       PrintAndLog("Writing to block: %d  data: 0x%08X", block, data);\r
+       PrintAndLog("Writing to block: %d  data  : 0x%08X", block, data);\r
 \r
        //Password mode\r
        if (res == 3) {\r
@@ -594,9 +734,9 @@ int CmdT55xxReadTrace(const char *Cmd)
        if (strlen(Cmd)==0)\r
                AquireData( TRACE_BLOCK );\r
        \r
-       DecodeT55xxBlock();\r
+       if (!DecodeT55xxBlock()) return 1;\r
 \r
-       if (!DemodBufferLen) return 1;\r
+       if ( !DemodBufferLen) return 1;\r
        \r
        RepaintGraphWindow();\r
        uint8_t repeat = 0;\r
@@ -635,8 +775,8 @@ int CmdT55xxReadTrace(const char *Cmd)
        PrintAndLog("     Block 0  : 0x%08X  %s", bl0, sprint_bin(DemodBuffer+config.offset+repeat,32) );\r
        PrintAndLog("     Block 1  : 0x%08X  %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );\r
        PrintAndLog("-------------------------------------------------------------");\r
-       \r
-       if ( acl != 0xE0 ) \r
+\r
+       if ( acl != 0xE0 )\r
                PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");\r
        /*\r
        TRACE - BLOCK O\r
@@ -666,16 +806,16 @@ int CmdT55xxInfo(const char *Cmd){
        */\r
        char cmdp = param_getchar(Cmd, 0);\r
 \r
-       if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') \r
+       if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')\r
                return usage_t55xx_info();\r
        \r
        if (strlen(Cmd)==0)\r
                AquireData( CONFIGURATION_BLOCK );\r
        \r
-       DecodeT55xxBlock();\r
+       if (!DecodeT55xxBlock()) return 1;\r
+\r
+       if ( !DemodBufferLen) return 1;\r
 \r
-       if (!DemodBufferLen) return 1;\r
-       \r
        uint8_t si = config.offset;\r
        uint32_t bl0      = PackBits(si, 32, DemodBuffer);\r
        \r
@@ -715,6 +855,7 @@ int CmdT55xxInfo(const char *Cmd){
        PrintAndLog(" Raw Data - Page 0");\r
        PrintAndLog("     Block 0  : 0x%08X  %s", bl0, sprint_bin(DemodBuffer+config.offset,32) );\r
        PrintAndLog("-------------------------------------------------------------");\r
+       \r
        return 0;\r
 }\r
 \r
@@ -819,7 +960,7 @@ char * GetBitRateStr(uint32_t id){
 }\r
 \r
 char * GetSaferStr(uint32_t id){\r
-       static char buf[40];\r
+       static char buf[40];\r
        char *retStr = buf;\r
        \r
        sprintf(retStr,"%d",id);\r
@@ -833,7 +974,7 @@ char * GetSaferStr(uint32_t id){
        return buf;\r
 }\r
 char * GetModulationStr( uint32_t id){\r
-       static char buf[40];\r
+       static char buf[40];\r
        char *retStr = buf;\r
        \r
        switch (id){\r
@@ -867,6 +1008,9 @@ char * GetModulationStr( uint32_t id){
                case 16:\r
                        sprintf(retStr,"%d - Biphase",id);\r
                        break;\r
+               case 0x18:\r
+                       sprintf(retStr,"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id);\r
+                       break;\r
                case 17:\r
                        sprintf(retStr,"%d - Reserved",id);\r
                        break;\r
@@ -889,13 +1033,25 @@ char * GetModelStrFromCID(uint32_t cid){
 \r
 char * GetSelectedModulationStr( uint8_t id){\r
 \r
-       static char buf[16];\r
+       static char buf[16];\r
        char *retStr = buf;\r
-       \r
+\r
        switch (id){\r
                case DEMOD_FSK:\r
                        sprintf(retStr,"FSK");\r
                        break;\r
+               case DEMOD_FSK1:\r
+                       sprintf(retStr,"FSK1");\r
+                       break;\r
+               case DEMOD_FSK1a:\r
+                       sprintf(retStr,"FSK1a");\r
+                       break;\r
+               case DEMOD_FSK2:\r
+                       sprintf(retStr,"FSK2");\r
+                       break;\r
+               case DEMOD_FSK2a:\r
+                       sprintf(retStr,"FSK2a");\r
+                       break;\r
                case DEMOD_ASK:         \r
                        sprintf(retStr,"ASK");\r
                        break;\r
@@ -910,10 +1066,13 @@ char * GetSelectedModulationStr( uint8_t id){
                        break;\r
                case DEMOD_PSK3:\r
                        sprintf(retStr,"PSK3");\r
-                       break;                  \r
+                       break;\r
                case DEMOD_BI:\r
                        sprintf(retStr,"BIPHASE");\r
                        break;\r
+               case DEMOD_BIa:\r
+                       sprintf(retStr,"BIPHASEa - (CDP)");\r
+                       break;\r
                default:\r
                        sprintf(retStr,"(Unknown)");\r
                        break;\r
@@ -928,17 +1087,17 @@ uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
 \r
        if (len > 32) return 0;\r
 \r
-       uint32_t tmp = 0;\r
+       uint32_t tmp = 0;\r
        for (; j >= 0; --j, ++i)\r
                tmp     |= bits[i] << j;\r
-       \r
+\r
        return tmp;\r
 }\r
 \r
 static command_t CommandTable[] =\r
 {\r
   {"help",   CmdHelp,           1, "This help"},\r
-  {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset)"},\r
+  {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
   {"detect", CmdT55xxDetect,    0, "[1] Try detecting the tag modulation from reading the configuration block."},\r
   {"read",   CmdT55xxReadBlock, 0, "<block> [password] -- Read T55xx block data (page 0) [optional password]"},\r
   {"write",  CmdT55xxWriteBlock,0, "<block> <data> [password] -- Write T55xx block data (page 0) [optional password]"},\r
index 5a9af6a7f6cd5df19472d4db56263ad3204aef46..a64b1edab6cb27bba05d33c38c83039d33929f60 100644 (file)
@@ -16,13 +16,28 @@ typedef struct {
                DEMOD_PSK1 = 0x01,\r
                DEMOD_PSK2 = 0x02,\r
                DEMOD_PSK3 = 0x03,\r
-               DEMOD_FSK  = 0x04,     \r
+               DEMOD_FSK1  = 0x04,     \r
+               DEMOD_FSK1a = 0x05,     \r
+               DEMOD_FSK2  = 0x06,     \r
+               DEMOD_FSK2a = 0x07, \r
+               DEMOD_FSK   = 0xF0, //generic FSK (auto detect FCs)    \r
                DEMOD_ASK  = 0x08,\r
-               DEMOD_BI   = 0x16,\r
+               DEMOD_BI   = 0x10,\r
+               DEMOD_BIa  = 0x18,              \r
        }  modulation;\r
        bool inverted;\r
        uint8_t offset;\r
        uint32_t block0;\r
+       enum {\r
+               RF_8 = 0x00,\r
+               RF_16 = 0x01,\r
+               RF_32 = 0x02,\r
+               RF_40 = 0x03,\r
+               RF_50 = 0x04,\r
+               RF_64 = 0x05,\r
+               RF_100 = 0x06,\r
+               RF_128 = 0x07,\r
+       } bitrate;\r
 } t55xx_conf_block_t;\r
 \r
 int CmdLFT55XX(const char *Cmd);\r
@@ -42,9 +57,10 @@ uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bitstream);
 void printT55xxBlock(const char *demodStr);\r
 void printConfiguration( t55xx_conf_block_t b);\r
 \r
-void DecodeT55xxBlock();\r
+bool DecodeT55xxBlock();\r
 bool tryDetectModulation();\r
 bool test(uint8_t mode, uint8_t *offset);\r
 int special(const char *Cmd);\r
 int AquireData( uint8_t block );\r
+\r
 #endif\r
index 91445d43ecaee998667157ed80d41e36c37ef710..4f61cf7884866c79ec61df24cd4d869dfb899547 100644 (file)
@@ -129,4 +129,4 @@ local function main(args)
        test()
        print( string.rep('--',20) )
 end
-main(args)
\ No newline at end of file
+main(args)
index eb3da35106ba30afa714117461ce3f5b5eacad23..cbd78e873599270194f1b407e5c6cbf525fd5966 100644 (file)
@@ -168,4 +168,4 @@ main(args)
 
     -- XXXXX0XX = PSK RF/2
     -- XXXXX4XX = PSK RF/4
-    -- XXXXX8XX = PSK RF/8
\ No newline at end of file
+    -- XXXXX8XX = PSK RF/8
index 445ede1f779b3353dc4a8c1559c46b43ef92375d..7e264d286a8a5a61186834f75ae0c22fd0f313ca 100644 (file)
@@ -71,8 +71,6 @@ LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n
 
 LIBS = -lgcc
 
-LIBS = -lgcc 
-
 THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(THUMBSRC))
 ARMOBJ   = $(ARMSRC:%.c=$(OBJDIR)/%.o)
 ASMOBJ   = $(patsubst %.s,$(OBJDIR)/%.o,$(ASMSRC))
index 5b90f1c4a2eef6d20942c5e685085a9132e7c348..3305c8b0c53e84adb4cdd992c28c3a51fac531b2 100644 (file)
@@ -75,51 +75,6 @@ uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_
   return 0;
 }
 
-
-//by marshmellow
-//takes 1s and 0s and searches for EM410x format - output EM ID
-uint64_t Em410xDecodeOld(uint8_t *BitStream, size_t *size, size_t *startIdx)
-{
-  //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
-  //  otherwise could be a void with no arguments
-  //set defaults
-  uint64_t lo=0;
-  uint32_t i = 0;
-  if (BitStream[1]>1){  //allow only 1s and 0s
-    // PrintAndLog("no data found");
-    return 0;
-  }
-  // 111111111 bit pattern represent start of frame
-  uint8_t preamble[] = {1,1,1,1,1,1,1,1,1};
-  uint32_t idx = 0;
-  uint32_t parityBits = 0;
-  uint8_t errChk = 0;
-  *startIdx = 0;
-  for (uint8_t extraBitChk=0; extraBitChk<5; extraBitChk++){
-    errChk = preambleSearch(BitStream+extraBitChk+*startIdx, preamble, sizeof(preamble), size, startIdx);
-    if (errChk == 0) return 0;
-    idx = *startIdx + 9;
-    for (i=0; i<10;i++){ //loop through 10 sets of 5 bits (50-10p = 40 bits)
-      parityBits = bytebits_to_byte(BitStream+(i*5)+idx,5);
-      //check even parity
-      if (parityTest(parityBits, 5, 0) == 0){
-        //parity failed try next bit (in the case of 1111111111) but last 9 = preamble
-        startIdx++;
-        errChk = 0;
-        break;
-      }
-      //set uint64 with ID from BitStream
-      for (uint8_t ii=0; ii<4; ii++){
-        lo = (lo << 1LL) | (BitStream[(i*5)+ii+idx]);
-      }
-    }
-    if (errChk != 0) return lo;
-    //skip last 5 bit parity test for simplicity.
-    // *size = 64;
-  }
-  return 0;
-}
-
 //by marshmellow
 //takes 1s and 0s and searches for EM410x format - output EM ID
 uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo)
@@ -144,6 +99,7 @@ uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_
     if (errChk == 0) return 0;
        if (*size<64) return 0;
     if (*size>64) FmtLen = 22;
+    if (*size<64) return 0;
     idx = *startIdx + 9;
     for (i=0; i<FmtLen; i++){ //loop through 10 or 22 sets of 5 bits (50-10p = 40 bits or 88 bits)
       parityBits = bytebits_to_byte(BitStream+(i*5)+idx,5);
@@ -309,16 +265,12 @@ int ManchesterEncode(uint8_t *BitStream, size_t size)
 //run through 2 times and take least errCnt
 int manrawdecode(uint8_t * BitStream, size_t *size)
 {
-       uint16_t bitnum=0;
-       uint16_t MaxBits = 500;
-       uint16_t errCnt = 0;
-       size_t i=1;
-       uint16_t bestErr = 1000;
-       uint16_t bestRun = 0;
-       size_t ii=1;
+       uint16_t bitnum=0, MaxBits = 512, errCnt = 0;
+       size_t i, ii;
+       uint16_t bestErr = 1000, bestRun = 0;
        if (size == 0) return -1;
-       for (ii=1;ii<3;++ii){
-               i=1;
+       for (ii=0;ii<2;++ii){
+               i=0;
                for (i=i+ii;i<*size-2;i+=2){
                        if(BitStream[i]==1 && (BitStream[i+1]==0)){
                        } else if((BitStream[i]==0)&& BitStream[i+1]==1){
@@ -336,7 +288,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
        errCnt=bestErr;
        if (errCnt<20){
                ii=bestRun;
-               i=1;
+               i=0;
                for (i=i+ii; i < *size-2; i+=2){
                        if(BitStream[i] == 1 && (BitStream[i+1] == 0)){
                                BitStream[bitnum++]=0;
@@ -356,6 +308,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
 //by marshmellow
 //take 01 or 10 = 1 and 11 or 00 = 0
 //check for phase errors - should never have 111 or 000 should be 01001011 or 10110100 for 1010
+//decodes biphase or if inverted it is AKA conditional dephase encoding AKA differential manchester encoding
 int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
 {
        uint16_t bitnum=0;
@@ -373,7 +326,7 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
        if (!offsetA && offsetB) offset++;
        for (i=offset; i<*size-3; i+=2){
                //check for phase error
-               if (i<*size-3 && BitStream[i+1]==BitStream[i+2]) {
+               if (BitStream[i+1]==BitStream[i+2]) {
                        BitStream[bitnum++]=77;
                        errCnt++;
                }
@@ -413,6 +366,56 @@ void askAmp(uint8_t *BitStream, size_t size)
        return;
 }
 
+int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int high, int low)
+{
+       size_t bitCnt=0, smplCnt=0, errCnt=0;
+       uint8_t waveHigh = 0;
+       //PrintAndLog("clk: %d", clk);
+       for (size_t i=0; i < *size; i++){
+               if (BinStream[i] >= high && waveHigh){
+                       smplCnt++;
+               } else if (BinStream[i] <= low && !waveHigh){
+                       smplCnt++;
+               } else { //transition
+                       if ((BinStream[i] >= high && !waveHigh) || (BinStream[i] <= low && waveHigh)){
+                               if (smplCnt > clk-(clk/4)-1) { //full clock
+                                       if (smplCnt > clk + (clk/4)+1) { //too many samples
+                                               errCnt++;
+                                               BinStream[bitCnt++]=77;
+                                       } else if (waveHigh) {
+                                               BinStream[bitCnt++] = invert;
+                                               BinStream[bitCnt++] = invert;
+                                       } else if (!waveHigh) {
+                                               BinStream[bitCnt++] = invert ^ 1;
+                                               BinStream[bitCnt++] = invert ^ 1;
+                                       }
+                                       waveHigh ^= 1;  
+                                       smplCnt = 0;
+                               } else if (smplCnt > (clk/2) - (clk/4)-1) {
+                                       if (waveHigh) {
+                                               BinStream[bitCnt++] = invert;
+                                       } else if (!waveHigh) {
+                                               BinStream[bitCnt++] = invert ^ 1;
+                                       }
+                                       waveHigh ^= 1;  
+                                       smplCnt = 0;
+                               } else if (!bitCnt) {
+                                       //first bit
+                                       waveHigh = (BinStream[i] >= high);
+                                       smplCnt = 1;
+                               } else {
+                                       smplCnt++;
+                                       //transition bit oops
+                               }
+                       } else { //haven't hit new high or new low yet
+                               smplCnt++;
+                       }
+               }
+       }
+       *size = bitCnt;
+       return errCnt;
+}
+
 //by marshmellow
 //takes 3 arguments - clock, invert and maxErr as integers
 //attempts to demodulate ask only
@@ -424,15 +427,22 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max
        if (*clk==0) return -1;
        if (start<0) return -1;
        if (*invert != 0 && *invert != 1) *invert =0;
+       if (amp==1) askAmp(BinStream, *size);
+
        uint32_t initLoopMax = 200;
        if (initLoopMax > *size) initLoopMax=*size;
        // Detect high and lows
-       //25% fuzz in case highs and lows aren't clipped [marshmellow]
+       //25% clip in case highs and lows aren't clipped [marshmellow]
+       uint8_t clip = 75;
        int high, low, ans;
-       if (amp==1) askAmp(BinStream, *size);
-       ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75);
+       ans = getHiLo(BinStream, initLoopMax, &high, &low, clip, clip);
        if (ans<1) return -1; //just noise
 
+       if (DetectCleanAskWave(BinStream, *size, high, low)) {
+               //PrintAndLog("Clean");
+               return cleanAskRawDemod(BinStream, size, *clk, *invert, high, low);
+       }
+
        //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
        int lastBit = 0;  //set first clock check
        uint32_t bitnum = 0;     //output counter
@@ -444,12 +454,13 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max
        uint32_t gLen = *size;
        if (gLen > 500) gLen=500;
        //if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance
-       if (!maxErr) gLen=*clk*2; 
+       if (!maxErr) gLen = *clk * 2; 
        uint8_t errCnt =0;
        uint32_t bestStart = *size;
        uint32_t bestErrCnt = maxErr; //(*size/1000);
        uint8_t midBit=0;
        uint16_t MaxBits=1000;
+
        //PrintAndLog("DEBUG - lastbit - %d",lastBit);
        //loop to find first wave that works
        for (iii=start; iii < gLen; ++iii){
@@ -620,7 +631,9 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow
                                //do nothing with extra garbage
                        } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves
                                dest[numBits]=1;
-                       } else {                                                        //9+ = 10 waves
+                       } else if ((idx-last_transition) > (fchigh+1) && !numBits) { //12 + and first bit = garbage 
+                               //do nothing with beginning garbage
+                       } else {                                         //9+ = 10 waves
                                dest[numBits]=0;
                        }
                        last_transition = idx;
@@ -644,18 +657,31 @@ size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxCons
        uint32_t idx=0;
        size_t numBits=0;
        uint32_t n=1;
-
+       float lowWaves = (((float)(rfLen))/((float)fclow));
+       float highWaves = (((float)(rfLen))/((float)fchigh));
        for( idx=1; idx < size; idx++) {
 
                if (dest[idx]==lastval) {
                        n++;
                        continue;
                }
+               n++;
                //if lastval was 1, we have a 1->0 crossing
-               if ( dest[idx-1]==1 ) {
-                       n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow));
-               } else {// 0->1 crossing
-                       n=myround2((float)(n+1)/((float)(rfLen-1)/(float)fchigh));  //-1 for fudge factor
+               if (dest[idx-1]==1) {
+                       if (!numBits && n < (uint8_t)lowWaves) {
+                               n=0;
+                               lastval = dest[idx];
+                               continue;
+                       }
+                       n=myround2(((float)n)/lowWaves);
+               } else {// 0->1 crossing 
+                       //test first bitsample too small
+                       if (!numBits && n < (uint8_t)highWaves) {
+                               n=0;
+                               lastval = dest[idx];
+                               continue;
+                       }
+                       n = myround2(((float)n)/highWaves);  //-1 for fudge factor
                }
                if (n == 0) n = 1;
 
@@ -671,6 +697,17 @@ size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxCons
                n=0;
                lastval=dest[idx];
        }//end for
+
+       // if valid extra bits at the end were all the same frequency - add them in
+       if (n > lowWaves && n > highWaves) {
+               if (dest[idx-2]==1) {
+                       n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow));
+               } else {
+                       n=myround2((float)(n+1)/((float)(rfLen-1)/(float)fchigh));  //-1 for fudge factor                       
+               }
+               memset(dest, dest[idx-1]^invert , n);
+               numBits += n;
+       }
        return numBits;
 }
 //by marshmellow  (from holiman's base)
@@ -857,20 +894,70 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size)
 
 uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low)
 {
-       uint8_t allPeaks=1;
+       uint16_t allPeaks=1;
        uint16_t cntPeaks=0;
-       for (size_t i=20; i<255; i++){
+       size_t loopEnd = 572;
+       if (loopEnd > size) loopEnd = size;
+       for (size_t i=60; i<loopEnd; i++){
                if (dest[i]>low && dest[i]<high) 
                        allPeaks=0;
                else
                        cntPeaks++;
        }
-       if (allPeaks==0){
-               if (cntPeaks>190) return 1;
+       if (allPeaks == 0){
+               if (cntPeaks > 300) return 1;
        }
        return allPeaks;
 }
 
+int DetectStrongAskClock(uint8_t dest[], size_t size)
+{
+       int clk[]={0,8,16,32,40,50,64,100,128,256};
+  size_t idx = 40;
+       uint8_t high=0;
+       size_t cnt = 0;
+       size_t highCnt = 0;
+       size_t highCnt2 = 0;
+       for (;idx < size; idx++){
+               if (dest[idx]>128) {
+                       if (!high){
+                               high=1;
+                               if (cnt > highCnt){
+                                       if (highCnt != 0) highCnt2 = highCnt;
+                                       highCnt = cnt;
+                               } else if (cnt > highCnt2) {
+                                       highCnt2 = cnt;
+                               }
+                               cnt=1;
+                       } else {
+                               cnt++;
+                       }
+               } else if (dest[idx] <= 128){
+                       if (high) {
+                               high=0;
+                               if (cnt > highCnt) {
+                                       if (highCnt != 0) highCnt2 = highCnt;
+                                       highCnt = cnt;
+                               } else if (cnt > highCnt2) {
+                                       highCnt2 = cnt;
+                               }
+                               cnt=1;
+                       } else {
+                               cnt++;
+                       }
+               }
+       }
+       uint8_t tol;
+       for (idx=8; idx>0; idx--){
+               tol = clk[idx]/8;
+               if (clk[idx] >= highCnt - tol && clk[idx] <= highCnt + tol)
+                       return clk[idx];
+               if (clk[idx] >= highCnt2 - tol && clk[idx] <= highCnt2 + tol)
+                       return clk[idx];
+       }
+       return -1;
+}
+
 // by marshmellow
 // not perfect especially with lower clocks or VERY good antennas (heavy wave clipping)
 // maybe somehow adjust peak trimming value based on samples to fix?
@@ -893,24 +980,14 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
   
   //test for large clean peaks
   if (DetectCleanAskWave(dest, size, peak, low)==1){
-         uint16_t fcTest=0;
-         uint8_t mostFC=0;
-         fcTest=countFC(dest, size, &mostFC);
-         uint8_t fc1 = fcTest >> 8;
-         uint8_t fc2 = fcTest & 0xFF;
-
-         for (i=0; i<8; i++){
-               if (clk[i] == fc1) {
-                       *clock=fc1;
-                       return 0;
-               }
-               if (clk[i] == fc2) {
-                       *clock=fc2;
+       int ans = DetectStrongAskClock(dest, size);
+         for (i=7; i>0; i--){
+               if (clk[i] == ans) {
+                       *clock=ans;
                        return 0;
                }
          }
   }
-  
   int ii;
   int clkCnt;
   int tol = 0;
@@ -924,6 +1001,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
     }else{
       tol=0;
     }
+       if (!maxErr) loopCnt=clk[clkCnt]*2;
     bestErr[clkCnt]=1000;
     //try lining up the peaks by moving starting point (try first 256)
     for (ii=0; ii < loopCnt; ii++){
@@ -1243,11 +1321,10 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
   *clk = DetectNRZClock(dest, *size, *clk);
   if (*clk==0) return -2;
   uint32_t i;
-  int high, low, ans;
-  ans = getHiLo(dest, 1260, &high, &low, 75, 75); //25% fuzz on high 25% fuzz on low
-  if (ans<1) return -2; //just noise
-  uint32_t gLen = 256;
+  uint32_t gLen = 4096;
   if (gLen>*size) gLen = *size;
+  int high, low;
+  if (getHiLo(dest, gLen, &high, &low, 75, 75) < 1) return -3; //25% fuzz on high 25% fuzz on low
   int lastBit = 0;  //set first clock check
   uint32_t bitnum = 0;     //output counter
   uint8_t tol = 1;  //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
@@ -1257,6 +1334,8 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
   uint32_t bestErrCnt = maxErr+1;
   uint32_t bestPeakCnt = 0;
   uint32_t bestPeakStart=0;
+  uint8_t bestFirstPeakHigh=0;
+  uint8_t firstPeakHigh=0;
   uint8_t curBit=0;
   uint8_t bitHigh=0;
   uint8_t errBitHigh=0;
@@ -1266,6 +1345,8 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
   //loop to find first wave that works - align to clock
   for (iii=0; iii < gLen; ++iii){
     if ((dest[iii]>=high) || (dest[iii]<=low)){
+      if (dest[iii]>=high) firstPeakHigh=1;
+      else firstPeakHigh=0;
       lastBit=iii-*clk;
       peakCnt=0;
       errCnt=0;
@@ -1316,6 +1397,7 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
         //possible good read
         if (errCnt == 0){
           //bestStart = iii;
+          bestFirstPeakHigh=firstPeakHigh;
           bestErrCnt = errCnt;
           bestPeakCnt = peakCnt;
           bestPeakStart = iii;
@@ -1326,6 +1408,7 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
           //bestStart = iii;
         }
         if (peakCnt > bestPeakCnt){
+          bestFirstPeakHigh=firstPeakHigh;
           bestPeakCnt=peakCnt;
           bestPeakStart=iii;
         } 
@@ -1338,6 +1421,8 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
     iii=bestPeakStart;
     lastBit=bestPeakStart-*clk;
     bitnum=0;
+    memset(dest, bestFirstPeakHigh^1, bestPeakStart / *clk);
+    bitnum += (bestPeakStart / *clk);
     for (i = iii; i < *size; ++i) {
       //if we found a high bar and we are at a clock bit
       if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
@@ -1387,12 +1472,12 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
     *size=bitnum;
   } else{
     *size=bitnum;
-    return -1;
+    return bestErrCnt;
   }
 
   if (bitnum>16){
     *size=bitnum;
-  } else return -1;
+  } else return -5;
   return errCnt;
 }
 
@@ -1690,7 +1775,7 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
   errCnt=0;
   size_t numBits=0;
   //set skipped bits
-  memset(dest+numBits,curPhase^1,firstFullWave / *clock);
+  memset(dest,curPhase^1,firstFullWave / *clock);
   numBits += (firstFullWave / *clock);
   dest[numBits++] = curPhase; //set first read bit
   for (i = firstFullWave+fullWaveLen-1; i < *size-3; i++){
index 8e10a7dfed6c18e05ac6eb3835c9f81d5ae5fd5e..46e2bdd574d040268b2c4950a7d53e108ceca813 100644 (file)
@@ -16,6 +16,7 @@
 #include <stdint.h>
 
 int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr);
+uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low);
 int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr);
 uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
 //uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx);
@@ -47,5 +48,6 @@ uint8_t justNoise(uint8_t *BitStream, size_t size);
 uint8_t countPSK_FC(uint8_t *BitStream, size_t size);
 int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
 int DetectPSKClock(uint8_t dest[], size_t size, int clock);
+void askAmp(uint8_t *BitStream, size_t size);
 
 #endif
index 01b738c2b6076ec1fed19d7d47dd2b2033683442..3cdf79f92a87b9616ba991491db8ad303cf03bb2 100644 (file)
@@ -168,9 +168,25 @@ NXP/Philips CUSTOM COMMANDS
 #define ISO15693_READ_MULTI_SECSTATUS 0x2C
 
 
+// Topaz command set:
+#define        TOPAZ_REQA                                              0x26    // Request
+#define        TOPAZ_WUPA                                              0x52    // WakeUp
+#define        TOPAZ_RID                                               0x78    // Read ID
+#define        TOPAZ_RALL                                              0x00    // Read All (all bytes)
+#define        TOPAZ_READ                                              0x01    // Read (a single byte)
+#define        TOPAZ_WRITE_E                                   0x53    // Write-with-erase (a single byte)
+#define        TOPAZ_WRITE_NE                                  0x1a    // Write-no-erase (a single byte)
+// additional commands for Dynamic Memory Model
+#define TOPAZ_RSEG                                             0x10    // Read segment
+#define TOPAZ_READ8                                            0x02    // Read (eight bytes)
+#define TOPAZ_WRITE_E8                                 0x54    // Write-with-erase (eight bytes)
+#define TOPAZ_WRITE_NE8                                        0x1B    // Write-no-erase (eight bytes)
+
+
 #define ISO_14443A 0
 #define ICLASS     1
 #define ISO_14443B 2
+#define TOPAZ          3
 
 //-- Picopass fuses
 #define FUSE_FPERS   0x80
index 403132ac8a8294c75598050632503a2109a93083..89ff758e20727266698385204dc05e2f5b60c0e7 100644 (file)
@@ -26,14 +26,15 @@ typedef struct {
 } __attribute__((__packed__)) iso14a_card_select_t;
 
 typedef enum ISO14A_COMMAND {
-       ISO14A_CONNECT = 1,
-       ISO14A_NO_DISCONNECT = 2,
-       ISO14A_APDU = 4,
-       ISO14A_RAW = 8,
-       ISO14A_REQUEST_TRIGGER = 0x10,
-       ISO14A_APPEND_CRC = 0x20,
-       ISO14A_SET_TIMEOUT = 0x40,
-       ISO14A_NO_SELECT = 0x80
+       ISO14A_CONNECT =                        (1 << 0),
+       ISO14A_NO_DISCONNECT =          (1 << 1),
+       ISO14A_APDU =                           (1 << 2),
+       ISO14A_RAW =                            (1 << 3),
+       ISO14A_REQUEST_TRIGGER =        (1 << 4),
+       ISO14A_APPEND_CRC =                     (1 << 5),
+       ISO14A_SET_TIMEOUT =            (1 << 6),
+       ISO14A_NO_SELECT =                      (1 << 7),
+       ISO14A_TOPAZMODE =                      (1 << 8)
 } iso14a_command_t;
 
 #endif // _MIFARE_H_
Impressum, Datenschutz