]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
ADD: well, starting with a luascript for reading calypso tags, made me remake the...
authoriceman1001 <iceman@iuse.se>
Sun, 20 Mar 2016 18:33:07 +0000 (19:33 +0100)
committericeman1001 <iceman@iuse.se>
Sun, 20 Mar 2016 18:33:07 +0000 (19:33 +0100)
I also made the SRi read functions better by combining them.   The demodulation / uart code should be the same as last summers changes.  The device side code can now be even smaller.

17 files changed:
armsrc/BigBuf.c
armsrc/appmain.c
armsrc/apps.h
armsrc/epa.c
armsrc/iso14443a.c
armsrc/iso14443b.c
armsrc/iso14443b.h
armsrc/iso15693.c
client/cmdhf14a.c
client/cmdhf14b.c
client/cmdhf14b.h
client/hid-flasher/usb_cmd.h
client/lualibs/commands.lua
client/lualibs/read14b.lua
include/common.h
include/mifare.h
include/usb_cmd.h

index 407133fdf60b5de431cfe05d6ab5dd523dfcf8a2..267921f4f299c7d034a059b7687c0d9c8bb565cb 100644 (file)
@@ -43,7 +43,6 @@ uint8_t *BigBuf_get_addr(void)
        return (uint8_t *)BigBuf;
 }
 
        return (uint8_t *)BigBuf;
 }
 
-
 // get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
 uint8_t *BigBuf_get_EM_addr(void)
 {
 // get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
 uint8_t *BigBuf_get_EM_addr(void)
 {
@@ -54,12 +53,12 @@ uint8_t *BigBuf_get_EM_addr(void)
        return emulator_memory;
 }
 
        return emulator_memory;
 }
 
-
 // clear ALL of BigBuf
 void BigBuf_Clear(void)
 {
        BigBuf_Clear_ext(true);
 }
 // clear ALL of BigBuf
 void BigBuf_Clear(void)
 {
        BigBuf_Clear_ext(true);
 }
+
 // clear ALL of BigBuf
 void BigBuf_Clear_ext(bool verbose)
 {
 // clear ALL of BigBuf
 void BigBuf_Clear_ext(bool verbose)
 {
@@ -86,7 +85,6 @@ uint8_t *BigBuf_malloc(uint16_t chunksize)
        }
 }
 
        }
 }
 
-
 // free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
 void BigBuf_free(void)
 {
 // free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
 void BigBuf_free(void)
 {
@@ -96,7 +94,6 @@ void BigBuf_free(void)
        // shouldn't this empty BigBuf also?
 }
 
        // shouldn't this empty BigBuf also?
 }
 
-
 // free allocated chunks EXCEPT the emulator memory
 void BigBuf_free_keep_EM(void)
 {
 // free allocated chunks EXCEPT the emulator memory
 void BigBuf_free_keep_EM(void)
 {
@@ -254,12 +251,10 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP
 // Emulator memory
 uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
        uint8_t* mem = BigBuf_get_EM_addr();
 // Emulator memory
 uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
        uint8_t* mem = BigBuf_get_EM_addr();
-       if(offset+length < CARD_MEMORY_SIZE)
-       {
+       if(offset+length < CARD_MEMORY_SIZE) {
                memcpy(mem+offset, data, length);
                return 0;
                memcpy(mem+offset, data, length);
                return 0;
-       }else
-       {
+       } else {
                Dbprintf("Error, trying to set memory outside of bounds! %d  > %d", (offset+length), CARD_MEMORY_SIZE);
                return 1;
        }
                Dbprintf("Error, trying to set memory outside of bounds! %d  > %d", (offset+length), CARD_MEMORY_SIZE);
                return 1;
        }
index 428d187ec8535590678a4bbe7137c84e221d108f..7654c9e37ff0be7a70a994887b9c93b7284ed56e 100644 (file)
@@ -1008,10 +1008,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_TEST_HITAGS_TRACES:// Tests every challenge within the given file
                        check_challenges((bool)c->arg[0],(byte_t*)c->d.asBytes);
                        break;
                case CMD_TEST_HITAGS_TRACES:// Tests every challenge within the given file
                        check_challenges((bool)c->arg[0],(byte_t*)c->d.asBytes);
                        break;
-               case CMD_READ_HITAG_S://Reader for only Hitag S tags, args = key or challenge
+               case CMD_READ_HITAG_S: //Reader for only Hitag S tags, args = key or challenge
                        ReadHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
                        break;
                        ReadHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
                        break;
-               case CMD_WR_HITAG_S://writer for Hitag tags args=data to write,page and key or challenge
+               case CMD_WR_HITAG_S: //writer for Hitag tags args=data to write,page and key or challenge
                        WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
                        break;
 #endif
                        WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
                        break;
 #endif
@@ -1059,11 +1059,8 @@ void UsbPacketReceived(uint8_t *packet, int len)
 #endif
 
 #ifdef WITH_ISO14443b
 #endif
 
 #ifdef WITH_ISO14443b
-               case CMD_READ_SRI512_TAG:
-                       ReadSTMemoryIso14443b(0x0F);
-                       break;
-               case CMD_READ_SRIX4K_TAG:
-                       ReadSTMemoryIso14443b(0x7F);
+               case CMD_READ_SRI_TAG:
+                       ReadSTMemoryIso14443b(c->arg[0]);
                        break;
                case CMD_SNOOP_ISO_14443B:
                        SnoopIso14443b();
                        break;
                case CMD_SNOOP_ISO_14443B:
                        SnoopIso14443b();
@@ -1072,7 +1069,8 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        SimulateIso14443bTag();
                        break;
                case CMD_ISO_14443B_COMMAND:
                        SimulateIso14443bTag();
                        break;
                case CMD_ISO_14443B_COMMAND:
-                       SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
+                       //SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
+                       SendRawCommand14443B_Ex(c);
                        break;
 #endif
 
                        break;
 #endif
 
@@ -1086,14 +1084,12 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_SIMULATE_TAG_ISO_14443a:
                        SimulateIso14443aTag(c->arg[0], c->arg[1], c->d.asBytes);  // ## Simulate iso14443a tag - pass tag type & UID
                        break;
                case CMD_SIMULATE_TAG_ISO_14443a:
                        SimulateIso14443aTag(c->arg[0], c->arg[1], c->d.asBytes);  // ## Simulate iso14443a tag - pass tag type & UID
                        break;
-                       
                case CMD_EPA_PACE_COLLECT_NONCE:
                        EPA_PACE_Collect_Nonce(c);
                        break;
                case CMD_EPA_PACE_REPLAY:
                        EPA_PACE_Replay(c);
                        break;
                case CMD_EPA_PACE_COLLECT_NONCE:
                        EPA_PACE_Collect_Nonce(c);
                        break;
                case CMD_EPA_PACE_REPLAY:
                        EPA_PACE_Replay(c);
                        break;
-                       
                case CMD_READER_MIFARE:
             ReaderMifare(c->arg[0], c->arg[1]);
                        break;
                case CMD_READER_MIFARE:
             ReaderMifare(c->arg[0], c->arg[1]);
                        break;
index 928ac4e56e576a1c4e76e7bdcde1899a1f76d31f..eed9f63af13ce63fdbeda2edb264b12a5abd4656 100644 (file)
@@ -28,7 +28,7 @@
 //#include "des.h"
 //#include "aes.h"
 #include "desfire.h"
 //#include "des.h"
 //#include "aes.h"
 #include "desfire.h"
-
+#include "iso14443b.h"
 
 extern const uint8_t OddByteParity[256];
 extern int rsamples;   // = 0;
 
 extern const uint8_t OddByteParity[256];
 extern int rsamples;   // = 0;
@@ -101,7 +101,7 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode
 /// iso14443.h
 void SimulateIso14443bTag(void);
 void AcquireRawAdcSamplesIso14443b(uint32_t parameter);
 /// iso14443.h
 void SimulateIso14443bTag(void);
 void AcquireRawAdcSamplesIso14443b(uint32_t parameter);
-void ReadSTMemoryIso14443b(uint32_t);
+void ReadSTMemoryIso14443b(uint8_t numofblocks);
 void RAMFUNC SnoopIso14443b(void);
 void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
 
 void RAMFUNC SnoopIso14443b(void);
 void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
 
index 3b4e341aa5d949f08b12b467e6ff2daee0bfed52..16d9001455dd7f58819c40aabb2a58611e61c140 100644 (file)
@@ -523,30 +523,31 @@ int EPA_Setup()
        uint8_t uid[10];
        uint8_t pps_response[3];
        uint8_t pps_response_par[1];
        uint8_t uid[10];
        uint8_t pps_response[3];
        uint8_t pps_response_par[1];
-       iso14a_card_select_t card_select_info;
+       iso14a_card_select_t card_a_info;
+       iso14b_card_select_t card_b_info;
 
        // first, look for type A cards
        // power up the field
        iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
        // select the card
 
        // first, look for type A cards
        // power up the field
        iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
        // select the card
-       return_code = iso14443a_select_card(uid, &card_select_info, NULL, true, 0);
+       return_code = iso14443a_select_card(uid, &card_a_info, NULL, true, 0);
        if (return_code == 1) {
        if (return_code == 1) {
-       // send the PPS request
-       ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
-       return_code = ReaderReceive(pps_response, pps_response_par);
-       if (return_code != 3 || pps_response[0] != 0xD0) {
-               return return_code == 0 ? 2 : return_code;
-       }
+               // send the PPS request
+               ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
+               return_code = ReaderReceive(pps_response, pps_response_par);
+               if (return_code != 3 || pps_response[0] != 0xD0) {
+                       return return_code == 0 ? 2 : return_code;
+               }
                Dbprintf("ISO 14443 Type A");
                iso_type = 'a';
                Dbprintf("ISO 14443 Type A");
                iso_type = 'a';
-       return 0;
+               return 0;
        }
 
        // if we're here, there is no type A card, so we look for type B
        // power up the field
        iso14443b_setup();
        // select the card
        }
 
        // if we're here, there is no type A card, so we look for type B
        // power up the field
        iso14443b_setup();
        // select the card
-       return_code = iso14443b_select_card();
+       return_code = iso14443b_select_card( &card_b_info );
        if (return_code == 1) {
                Dbprintf("ISO 14443 Type B");
                iso_type = 'b';
        if (return_code == 1) {
                Dbprintf("ISO 14443 Type B");
                iso_type = 'b';
index be16447cf8b4096013dca1d809b234c75a6920c7..29d70dfc6aed5005938a866d0e352c0b95e298e4 100644 (file)
@@ -17,6 +17,7 @@
 #include "cmd.h"
 #include "iso14443crc.h"
 #include "iso14443a.h"
 #include "cmd.h"
 #include "iso14443crc.h"
 #include "iso14443a.h"
+#include "iso14443b.h"
 #include "crapto1.h"
 #include "mifareutil.h"
 #include "BigBuf.h"
 #include "crapto1.h"
 #include "mifareutil.h"
 #include "BigBuf.h"
@@ -187,12 +188,6 @@ void AppendCrc14443a(uint8_t* data, int len)
        ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
 }
 
        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
 //=============================================================================
 //=============================================================================
 // ISO 14443 Type A - Miller decoder
 //=============================================================================
@@ -745,13 +740,12 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par
        ToSend[++ToSendMax] = SEC_F;
 
        // Convert from last byte pos to length
        ToSend[++ToSendMax] = SEC_F;
 
        // Convert from last byte pos to length
-       ToSendMax++;
+       ++ToSendMax;
 }
 
 static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len)
 {
        uint8_t par[MAX_PARITY_SIZE] = {0};
 }
 
 static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len)
 {
        uint8_t par[MAX_PARITY_SIZE] = {0};
-       
        GetParity(cmd, len, par);
        CodeIso14443aAsTagPar(cmd, len, par);
 }
        GetParity(cmd, len, par);
        CodeIso14443aAsTagPar(cmd, len, par);
 }
@@ -1427,7 +1421,7 @@ void PrepareDelayedTransfer(uint16_t delay)
        for (i = 0; i < delay; ++i)
                bitmask |= (0x01 << i);
 
        for (i = 0; i < delay; ++i)
                bitmask |= (0x01 << i);
 
-               ToSend[++ToSendMax] = 0x00;
+       ToSend[++ToSendMax] = 0x00;
 
        for (i = 0; i < ToSendMax; ++i) {
                        bits_to_shift = ToSend[i] & bitmask;
 
        for (i = 0; i < ToSendMax; ++i) {
                        bits_to_shift = ToSend[i] & bitmask;
@@ -2052,20 +2046,22 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
 
        // Signal field is on with the appropriate LED
        if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD
 
        // Signal field is on with the appropriate LED
        if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD
-               || fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) {
+               || fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN)
                LED_D_ON();
                LED_D_ON();
-       } else {
+       else
                LED_D_OFF();
                LED_D_OFF();
-       }
+
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode);
 
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode);
 
-       // Start the timer
-       StartCountSspClk();
-       
        DemodReset();
        UartReset();
        DemodReset();
        UartReset();
-       NextTransferTime = 2*DELAY_ARM2AIR_AS_READER;
+
        iso14a_set_timeout(10*106); // 10ms default
        iso14a_set_timeout(10*106); // 10ms default
+       
+       // Start the timer
+       StartCountSspClk();
+
+       NextTransferTime = 2*DELAY_ARM2AIR_AS_READER;
 }
 
 int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
 }
 
 int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
@@ -2119,13 +2115,14 @@ void ReaderIso14443a(UsbCommand *c)
        if (param & ISO14A_REQUEST_TRIGGER)
                iso14a_set_trigger(TRUE);
 
        if (param & ISO14A_REQUEST_TRIGGER)
                iso14a_set_trigger(TRUE);
 
-
        if (param & ISO14A_CONNECT) {
                iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
                if(!(param & ISO14A_NO_SELECT)) {
                        iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
                        arg0 = iso14443a_select_card(NULL,card,NULL, true, 0);
                        cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
        if (param & ISO14A_CONNECT) {
                iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
                if(!(param & ISO14A_NO_SELECT)) {
                        iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
                        arg0 = iso14443a_select_card(NULL,card,NULL, true, 0);
                        cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
+                       // if it fails,  the cmdhf14a.c client quites.. however this one still executes.
+                       if ( arg0 == 0 ) return;
                }
        }
 
                }
        }
 
index 72c71964ff79813b1449daebf1a251ffba7a6b84..9616cb301266853ec58b2da2c7e13f4497d7082c 100644 (file)
@@ -8,17 +8,12 @@
 // Routines to support ISO 14443B. This includes both the reader software and
 // the `fake tag' modes.
 //-----------------------------------------------------------------------------
 // Routines to support ISO 14443B. This includes both the reader software and
 // the `fake tag' modes.
 //-----------------------------------------------------------------------------
+#include "iso14443b.h"
 
 
-#include "proxmark3.h"
-#include "apps.h"
-#include "util.h"
-#include "string.h"
-#include "iso14443crc.h"
-#include "common.h"
 #define RECEIVE_SAMPLES_TIMEOUT 20000
 #define ISO14443B_DMA_BUFFER_SIZE 256
 
 #define RECEIVE_SAMPLES_TIMEOUT 20000
 #define ISO14443B_DMA_BUFFER_SIZE 256
 
-// PCB Block number for APDUs
+// the block number for the ISO14443-4 PCB  (used with APDUs)
 static uint8_t pcb_blocknum = 0;
 
 //=============================================================================
 static uint8_t pcb_blocknum = 0;
 
 //=============================================================================
@@ -100,7 +95,7 @@ static void DemodReset()
        Demod.bitCount = 0;
        Demod.thisBit = 0;
        Demod.shiftReg = 0;
        Demod.bitCount = 0;
        Demod.thisBit = 0;
        Demod.shiftReg = 0;
-       memset(Demod.output, 0x00, MAX_FRAME_SIZE);
+       //memset(Demod.output, 0x00, MAX_FRAME_SIZE);
 }
 
 
 }
 
 
@@ -111,6 +106,11 @@ static void DemodInit(uint8_t *data)
 }
 
 
 }
 
 
+void AppendCrc14443b(uint8_t* data, int len)
+{
+       ComputeCrc14443(CRC_14443_B,data,len,data+len,data+len+1);
+}
+
 //-----------------------------------------------------------------------------
 // Code up a string of octets at layer 2 (including CRC, we don't generate
 // that here) so that they can be transmitted to the reader. Doesn't transmit
 //-----------------------------------------------------------------------------
 // Code up a string of octets at layer 2 (including CRC, we don't generate
 // that here) so that they can be transmitted to the reader. Doesn't transmit
@@ -195,7 +195,7 @@ static void CodeIso14443bAsTag(const uint8_t *cmd, int len)
        }
 
        // Convert from last byte pos to length
        }
 
        // Convert from last byte pos to length
-       ToSendMax++;
+       ++ToSendMax;
 }
 
 
 }
 
 
@@ -372,13 +372,13 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len)
 void SimulateIso14443bTag(void)
 {
        // the only commands we understand is WUPB, AFI=0, Select All, N=1:
 void SimulateIso14443bTag(void)
 {
        // the only commands we understand is WUPB, AFI=0, Select All, N=1:
-       static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; // WUPB
+       static const uint8_t cmd1[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 }; // WUPB
        // ... and REQB, AFI=0, Normal Request, N=1:
        // ... and REQB, AFI=0, Normal Request, N=1:
-       static const uint8_t cmd2[] = { 0x05, 0x00, 0x00, 0x71, 0xFF }; // REQB
+       static const uint8_t cmd2[] = { ISO14443B_REQB, 0x00, 0x00, 0x71, 0xFF }; // REQB
        // ... and HLTB
        // ... and HLTB
-       static const uint8_t cmd3[] = { 0x50, 0xff, 0xff, 0xff, 0xff }; // HLTB
+       static const uint8_t cmd3[] = { ISO14443B_HALT, 0xff, 0xff, 0xff, 0xff }; // HLTB
        // ... and ATTRIB
        // ... and ATTRIB
-       static const uint8_t cmd4[] = { 0x1D, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // ATTRIB
+       static const uint8_t cmd4[] = { ISO14443B_ATTRIB, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // ATTRIB
 
        // ... and we always respond with ATQB, PUPI = 820de174, Application Data = 0x20381922,
        // supports only 106kBit/s in both directions, max frame size = 32Bytes,
 
        // ... and we always respond with ATQB, PUPI = 820de174, Application Data = 0x20381922,
        // supports only 106kBit/s in both directions, max frame size = 32Bytes,
@@ -389,8 +389,6 @@ void SimulateIso14443bTag(void)
        };
        // response to HLTB and ATTRIB
        static const uint8_t response2[] = {0x00, 0x78, 0xF0};
        };
        // response to HLTB and ATTRIB
        static const uint8_t response2[] = {0x00, 0x78, 0xF0};
-
-       //uint8_t parity[MAX_PARITY_SIZE] = {0x00};
                                
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
                                
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
@@ -435,7 +433,6 @@ void SimulateIso14443bTag(void)
                }
 
                if (tracing)
                }
 
                if (tracing)
-                       //LogTrace(receivedCmd, len, 0, 0, parity, TRUE);
                        LogTrace(receivedCmd, len, 0, 0, NULL, TRUE);   
                        
 
                        LogTrace(receivedCmd, len, 0, 0, NULL, TRUE);   
                        
 
@@ -454,6 +451,7 @@ void SimulateIso14443bTag(void)
                        respCodeLen = resp2CodeLen;
                } else {
                        Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
                        respCodeLen = resp2CodeLen;
                } else {
                        Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
+
                        // And print whether the CRC fails, just for good measure
                        uint8_t b1, b2;
                        if (len >= 3){ // if crc exists
                        // And print whether the CRC fails, just for good measure
                        uint8_t b1, b2;
                        if (len >= 3){ // if crc exists
@@ -475,9 +473,9 @@ void SimulateIso14443bTag(void)
                        //break;
                }
 
                        //break;
                }
 
-               cmdsRecvd++;
+               ++cmdsRecvd;
 
 
-               if(cmdsRecvd > 0x30) {
+               if(cmdsRecvd > 0xFF) {
                        DbpString("many commands later...");
                        break;
                }
                        DbpString("many commands later...");
                        break;
                }
@@ -493,26 +491,25 @@ void SimulateIso14443bTag(void)
 
                // Transmit the response.
                uint16_t i = 0;
 
                // Transmit the response.
                uint16_t i = 0;
+               volatile uint8_t b;
                for(;;) {
                        if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
                                uint8_t b = respCode[i];
 
                                AT91C_BASE_SSC->SSC_THR = b;
 
                for(;;) {
                        if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
                                uint8_t b = respCode[i];
 
                                AT91C_BASE_SSC->SSC_THR = b;
 
-                               i++;
-                               if(i > respCodeLen) {
+                               ++i;
+                               if(i > respCodeLen)
                                        break;
                                        break;
-                               }
+
                        }
                        if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
                        }
                        if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                               volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+                               b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
                                (void)b;
                        }
                }
                
                                (void)b;
                        }
                }
                
-               // trace the response:
                if (tracing)
                if (tracing)
-                       //LogTrace(resp, respLen, 0, 0, parity, FALSE);
                        LogTrace(resp, respLen, 0, 0, NULL, FALSE);
        }
 }
                        LogTrace(resp, respLen, 0, 0, NULL, FALSE);
        }
 }
@@ -604,6 +601,10 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq)
                } \
        }
 
                } \
        }
 
+//note: couldn't we just use MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2) from common.h - marshmellow
+#define CHECK_FOR_SUBCARRIER_duo() { \
+               v = MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2); \
+       }
 
        switch(Demod.state) {
                case DEMOD_UNSYNCD:
 
        switch(Demod.state) {
                case DEMOD_UNSYNCD:
@@ -758,10 +759,11 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
 
        // Allocate memory from BigBuf for some buffers
        // free all previous allocations first
 
        // Allocate memory from BigBuf for some buffers
        // free all previous allocations first
-       BigBuf_free();
+       ///BigBuf_free();
 
        // The response (tag -> reader) that we're receiving.
        // Set up the demodulator for tag -> reader responses.
 
        // The response (tag -> reader) that we're receiving.
        // Set up the demodulator for tag -> reader responses.
+       // this init, can take some time to execute,  memset
        DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
        
        // The DMA buffer, used to stream samples from the FPGA
        DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
        
        // The DMA buffer, used to stream samples from the FPGA
@@ -798,15 +800,15 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
 
                        samples += 2;
 
 
                        samples += 2;
 
-                       //
-                       gotFrame = Handle14443bSamplesDemod(ci , cq );
+                       // is this | 0x01 the error?   & 0xfe  in https://github.com/Proxmark/proxmark3/issues/103
+                       // can we double this?
+                       gotFrame = Handle14443bSamplesDemod(ci<<2 , cq<<2);
                        if ( gotFrame )
                                break;
                }
 
                        if ( gotFrame )
                                break;
                }
 
-               if(samples > n || gotFrame) {
+               if(samples > n || gotFrame)
                        break;
                        break;
-               }
        }
 
        //disable
        }
 
        //disable
@@ -824,9 +826,8 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
                );
        }
 
                );
        }
 
-       //Tracing
-       if (Demod.len > 0)
-               LogTrace(Demod.output, Demod.len, 0, 0, NULL, FALSE);
+        if (tracing > 0)
+               LogTrace(Demod.output, Demod.len, samples, samples, NULL, FALSE);
 }
 
 
 }
 
 
@@ -890,14 +891,14 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
        ToSendReset();
 
        // Establish initial reference level
        ToSendReset();
 
        // Establish initial reference level
-       for(i = 0; i < 40; i++)
+       for(i = 0; i < 40; ++i)
                ToSendStuffBit(1);
 
        // Send SOF
                ToSendStuffBit(1);
 
        // Send SOF
-       for(i = 0; i < 10; i++)
+       for(i = 0; i < 10; ++i)
                ToSendStuffBit(0);
 
                ToSendStuffBit(0);
 
-       for(i = 0; i < len; i++) {
+       for(i = 0; i < len; ++i) {
                // Stop bits/EGT
                ToSendStuffBit(1);
                ToSendStuffBit(1);
                // Stop bits/EGT
                ToSendStuffBit(1);
                ToSendStuffBit(1);
@@ -905,7 +906,7 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
                ToSendStuffBit(0);
                // Data bits
                b = cmd[i];
                ToSendStuffBit(0);
                // Data bits
                b = cmd[i];
-               for(j = 0; j < 8; j++) {
+               for(j = 0; j < 8; ++j) {
                        if(b & 1)
                                ToSendStuffBit(1);
                        else
                        if(b & 1)
                                ToSendStuffBit(1);
                        else
@@ -916,16 +917,16 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
        }
        // Send EOF
        ToSendStuffBit(1);
        }
        // Send EOF
        ToSendStuffBit(1);
-       for(i = 0; i < 10; i++)
+       for(i = 0; i < 10; ++i)
                ToSendStuffBit(0);
        
                ToSendStuffBit(0);
        
-       for(i = 0; i < 8; i++)
+       for(i = 0; i < 8; ++i)
                ToSendStuffBit(1);
 
 
        // And then a little more, to make sure that the last character makes
        // it out before we switch to rx mode.
                ToSendStuffBit(1);
 
 
        // And then a little more, to make sure that the last character makes
        // it out before we switch to rx mode.
-       for(i = 0; i < 24; i++)
+       for(i = 0; i < 24; ++i)
                ToSendStuffBit(1);
 
        // Convert from last character reference to length
                ToSendStuffBit(1);
 
        // Convert from last character reference to length
@@ -940,18 +941,18 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len)
 {
        CodeIso14443bAsReader(cmd, len);
        TransmitFor14443b();
 {
        CodeIso14443bAsReader(cmd, len);
        TransmitFor14443b();
-       if (tracing) {
-               //uint8_t parity[MAX_PARITY_SIZE];
-               //LogTrace(cmd,len, 0, 0, parity, TRUE);
-               LogTrace(cmd,len, 0, 0, NULL, TRUE);
-       }
+
+       if(trigger) LED_A_ON();
+       
+       if (tracing) LogTrace(cmd, len, 0, 0, NULL, TRUE);
 }
 
 /* Sends an APDU to the tag
  * TODO: check CRC and preamble
  */
 }
 
 /* Sends an APDU to the tag
  * TODO: check CRC and preamble
  */
-int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response)
+uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response)
 {
 {
+       uint8_t crc[2] = {0x00, 0x00};
        uint8_t message_frame[message_length + 4];
        // PCB
        message_frame[0] = 0x0A | pcb_blocknum;
        uint8_t message_frame[message_length + 4];
        // PCB
        message_frame[0] = 0x0A | pcb_blocknum;
@@ -969,7 +970,11 @@ int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *respo
        if(Demod.len < 3)
                return 0;
        
        if(Demod.len < 3)
                return 0;
        
-       // TODO: Check CRC
+       // VALIDATE CRC
+    ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]);
+       if ( crc[0] != Demod.output[Demod.len-2] || crc[1] != Demod.output[Demod.len-1] )
+               return 0;
+       
        // copy response contents
        if(response != NULL)
                memcpy(response, Demod.output, Demod.len);
        // copy response contents
        if(response != NULL)
                memcpy(response, Demod.output, Demod.len);
@@ -977,43 +982,120 @@ int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *respo
        return Demod.len;
 }
 
        return Demod.len;
 }
 
+/**
+* SRx Initialise.
+*/
+uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card )
+{
+       // INITIATE command: wake up the tag using the INITIATE
+       static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b };
+       // SELECT command (with space for CRC)
+       uint8_t select_srx[] = { ISO14443B_SELECT, 0x00, 0x00, 0x00};
+       // temp to calc crc.
+       uint8_t crc[2] = {0x00, 0x00};
+       
+       CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx));
+       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+
+       if (Demod.len == 0) return 2;
+
+       // Randomly generated Chip ID   
+       if (card) card->chipid = Demod.output[0];
+       
+       select_srx[1] = Demod.output[0];
+       
+       ComputeCrc14443(CRC_14443_B, select_srx, 2, &select_srx[2], &select_srx[3]);
+       CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx));
+       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+       
+       if (Demod.len != 3)     return 2;
+       
+       // Check the CRC of the answer:
+       ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2 , &crc[0], &crc[1]);
+       if(crc[0] != Demod.output[1] || crc[1] != Demod.output[2]) return 3;
+       
+       // Check response from the tag: should be the same UID as the command we just sent:
+       if (select_srx[1] != Demod.output[0]) return 1;
+
+       // First get the tag's UID:
+       select_srx[0] = ISO14443B_GET_UID;
+
+       ComputeCrc14443(CRC_14443_B, select_srx, 1 , &select_srx[1], &select_srx[2]);
+       CodeAndTransmit14443bAsReader(select_srx, 3); // Only first three bytes for this one
+       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+
+       if (Demod.len != 10) return 2;
+       
+       // The check the CRC of the answer
+       ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]);
+       if(crc[0] != Demod.output[8] || crc[1] != Demod.output[9]) return 3;
+
+       if (card) {
+               card->uidlen = 8;
+               memcpy(card->uid, Demod.output, 8);
+       }
+
+       return 0;
+}
 /* Perform the ISO 14443 B Card Selection procedure
  * Currently does NOT do any collision handling.
  * It expects 0-1 cards in the device's range.
  * TODO: Support multiple cards (perform anticollision)
  * TODO: Verify CRC checksums
  */
 /* Perform the ISO 14443 B Card Selection procedure
  * Currently does NOT do any collision handling.
  * It expects 0-1 cards in the device's range.
  * TODO: Support multiple cards (perform anticollision)
  * TODO: Verify CRC checksums
  */
-int iso14443b_select_card()
+uint8_t iso14443b_select_card(iso14b_card_select_t *card )
 {
        // WUPB command (including CRC)
        // Note: WUPB wakes up all tags, REQB doesn't wake up tags in HALT state
 {
        // WUPB command (including CRC)
        // Note: WUPB wakes up all tags, REQB doesn't wake up tags in HALT state
-       static const uint8_t wupb[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
+       static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 };
        // ATTRIB command (with space for CRC)
        // ATTRIB command (with space for CRC)
-       uint8_t attrib[] = { 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
+       uint8_t attrib[] = { ISO14443B_ATTRIB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
 
 
+       // temp to calc crc.
+       uint8_t crc[2] = {0x00, 0x00};
+       
        // first, wake up the tag
        CodeAndTransmit14443bAsReader(wupb, sizeof(wupb));
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
        // first, wake up the tag
        CodeAndTransmit14443bAsReader(wupb, sizeof(wupb));
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+       
        // ATQB too short?
        // ATQB too short?
-       if (Demod.len < 14)
-               return 2;
+       if (Demod.len < 14) return 2;
+       
+       // VALIDATE CRC
+    ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]);
+       if ( crc[0] != Demod.output[12] || crc[1] != Demod.output[13] )
+               return 3;
+       
+       if (card) {
+               card->uidlen = 4;
+               memcpy(card->uid, Demod.output+1, 4);
+               memcpy(card->atqb, Demod.output+5, 7);
+       }
 
 
-    // select the tag
     // copy the PUPI to ATTRIB
     memcpy(attrib + 1, Demod.output + 1, 4);
     // copy the PUPI to ATTRIB
     memcpy(attrib + 1, Demod.output + 1, 4);
-    /* copy the protocol info from ATQB (Protocol Info -> Protocol_Type) into
-    ATTRIB (Param 3) */
+       
+    // copy the protocol info from ATQB (Protocol Info -> Protocol_Type) into ATTRIB (Param 3)
     attrib[7] = Demod.output[10] & 0x0F;
     ComputeCrc14443(CRC_14443_B, attrib, 9, attrib + 9, attrib + 10);
     attrib[7] = Demod.output[10] & 0x0F;
     ComputeCrc14443(CRC_14443_B, attrib, 9, attrib + 9, attrib + 10);
+
     CodeAndTransmit14443bAsReader(attrib, sizeof(attrib));
     GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
     CodeAndTransmit14443bAsReader(attrib, sizeof(attrib));
     GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+
     // Answer to ATTRIB too short?
     // Answer to ATTRIB too short?
-    if(Demod.len < 3)
-               return 2;
+    if(Demod.len < 3) return 2;
+
+       // VALIDATE CRC
+    ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]);
+       if ( crc[0] != Demod.output[1] || crc[1] != Demod.output[2] ) 
+               return 3;
+       
+       // CID
+       if (card) card->cid = Demod.output[0];
        
        // reset PCB block number
        pcb_blocknum = 0;
        
        // reset PCB block number
        pcb_blocknum = 0;
-       return 1;
+       return 0;
 }
 
 // Set up ISO 14443 Type B communication (similar to iso14443a_setup)
 }
 
 // Set up ISO 14443 Type B communication (similar to iso14443a_setup)
@@ -1034,7 +1116,7 @@ void iso14443b_setup() {
        // Signal field is on with the appropriate LED
     LED_D_ON();
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
        // Signal field is on with the appropriate LED
     LED_D_ON();
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
-       SpinDelay(200);
+       SpinDelay(400);
 
        // Start the timer
        StartCountSspClk();
 
        // Start the timer
        StartCountSspClk();
@@ -1049,7 +1131,7 @@ void iso14443b_setup() {
 //
 // I tried to be systematic and check every answer of the tag, every CRC, etc...
 //-----------------------------------------------------------------------------
 //
 // I tried to be systematic and check every answer of the tag, every CRC, etc...
 //-----------------------------------------------------------------------------
-void ReadSTMemoryIso14443b(uint32_t dwLast)
+void ReadSTMemoryIso14443b(uint8_t numofblocks)
 {
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        clear_trace();
 {
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        clear_trace();
@@ -1070,10 +1152,10 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
        // Signal field is on with the appropriate LED
        LED_D_ON();
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
        // Signal field is on with the appropriate LED
        LED_D_ON();
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
-       SpinDelay(200);
+       SpinDelay(300);
 
        // First command: wake up the tag using the INITIATE command
 
        // First command: wake up the tag using the INITIATE command
-       uint8_t cmd1[] = {0x06, 0x00, 0x97, 0x5b};
+       uint8_t cmd1[] = {ISO14443B_INITIATE, 0x00, 0x97, 0x5b};
        CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
 
        CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
 
@@ -1088,7 +1170,7 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
 
        // There is a response, SELECT the uid
        DbpString("Now SELECT tag:");
 
        // There is a response, SELECT the uid
        DbpString("Now SELECT tag:");
-       cmd1[0] = 0x0E; // 0x0E is SELECT
+       cmd1[0] = ISO14443B_SELECT; // 0x0E is SELECT
        cmd1[1] = Demod.output[0];
        ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
        CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
        cmd1[1] = Demod.output[0];
        ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
        CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
@@ -1114,7 +1196,7 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
 
        // Tag is now selected,
        // First get the tag's UID:
 
        // Tag is now selected,
        // First get the tag's UID:
-       cmd1[0] = 0x0B;
+       cmd1[0] = ISO14443B_GET_UID;
        ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
        CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
        ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
        CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
@@ -1135,12 +1217,13 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
                        (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
 
        // Now loop to read all 16 blocks, address from 0 to last block
                        (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
 
        // Now loop to read all 16 blocks, address from 0 to last block
-       Dbprintf("Tag memory dump, block 0 to %d", dwLast);
+       Dbprintf("Tag memory dump, block 0 to %d", numofblocks);
        cmd1[0] = 0x08;
        i = 0x00;
        cmd1[0] = 0x08;
        i = 0x00;
-       dwLast++;
+       ++numofblocks;
+       
        for (;;) {
        for (;;) {
-                  if (i == dwLast) {
+               if (i == numofblocks) {
                        DbpString("System area block (0xff):");
                        i = 0xff;
                }
                        DbpString("System area block (0xff):");
                        i = 0xff;
                }
@@ -1148,9 +1231,10 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
                ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
                CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
                GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
                ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
                CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
                GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+               
                if (Demod.len != 6) { // Check if we got an answer from the tag
                if (Demod.len != 6) { // Check if we got an answer from the tag
-               DbpString("Expected 6 bytes from tag, got less...");
-               return;
+                       DbpString("Expected 6 bytes from tag, got less...");
+                       return;
                }
                // The check the CRC of the answer (use cmd1 as temporary variable):
                ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
                }
                // The check the CRC of the answer (use cmd1 as temporary variable):
                ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
@@ -1163,16 +1247,14 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
                Dbprintf("Address=%02x, Contents=%08x, CRC=%04x", i,
                                (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
                                (Demod.output[4]<<8)+Demod.output[5]);
                Dbprintf("Address=%02x, Contents=%08x, CRC=%04x", i,
                                (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
                                (Demod.output[4]<<8)+Demod.output[5]);
-               if (i == 0xff) {
-                       break;
-               }
-               i++;
+
+               if (i == 0xff) break;
+               ++i;
        }
        
        set_tracing(FALSE);
 }
 
        }
        
        set_tracing(FALSE);
 }
 
-
 //=============================================================================
 // Finally, the `sniffer' combines elements from both the reader and
 // simulated tag, to show both sides of the conversation.
 //=============================================================================
 // Finally, the `sniffer' combines elements from both the reader and
 // simulated tag, to show both sides of the conversation.
@@ -1236,7 +1318,6 @@ void RAMFUNC SnoopIso14443b(void)
        upTo = dmaBuf;
        lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
        FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
        upTo = dmaBuf;
        lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
        FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
-       //uint8_t parity[MAX_PARITY_SIZE] = {0x00};
 
        bool TagIsActive = FALSE;
        bool ReaderIsActive = FALSE;
 
        bool TagIsActive = FALSE;
        bool ReaderIsActive = FALSE;
@@ -1245,10 +1326,8 @@ void RAMFUNC SnoopIso14443b(void)
        for(;;) {
                int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
                                                                (ISO14443B_DMA_BUFFER_SIZE-1);
        for(;;) {
                int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
                                                                (ISO14443B_DMA_BUFFER_SIZE-1);
-               if(behindBy > maxBehindBy) {
-                       maxBehindBy = behindBy;
-               }
 
 
+               if(behindBy > maxBehindBy) maxBehindBy = behindBy;
                if(behindBy < 2) continue;
 
                ci = upTo[0];
                if(behindBy < 2) continue;
 
                ci = upTo[0];
@@ -1281,27 +1360,27 @@ void RAMFUNC SnoopIso14443b(void)
 
                if (!TagIsActive) {                                                     // no need to try decoding reader data if the tag is sending
                        if (Handle14443bUartBit(ci & 0x01)) {
 
                if (!TagIsActive) {                                                     // no need to try decoding reader data if the tag is sending
                        if (Handle14443bUartBit(ci & 0x01)) {
-                               if(triggered && tracing) {
-                                       //LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, TRUE);
+
+                               if(triggered && tracing)
                                        LogTrace(Uart.output, Uart.byteCnt, samples, samples, NULL, TRUE);
                                        LogTrace(Uart.output, Uart.byteCnt, samples, samples, NULL, TRUE);
-                               }
+
                                /* And ready to receive another command. */
                                UartReset();
                                /* And also reset the demod code, which might have been */
                                /* false-triggered by the commands from the reader. */
                                DemodReset();
                        }
                                /* And ready to receive another command. */
                                UartReset();
                                /* And also reset the demod code, which might have been */
                                /* false-triggered by the commands from the reader. */
                                DemodReset();
                        }
+                       
                        if (Handle14443bUartBit(cq & 0x01)) {
                        if (Handle14443bUartBit(cq & 0x01)) {
-                               if(triggered && tracing) {
-                                       //LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, TRUE);
+                               if(triggered && tracing)
                                        LogTrace(Uart.output, Uart.byteCnt, samples, samples, NULL, TRUE);
                                        LogTrace(Uart.output, Uart.byteCnt, samples, samples, NULL, TRUE);
-                               }
+
                                        /* And ready to receive another command. */
                                        UartReset();
                                        /* And also reset the demod code, which might have been */
                                        /* false-triggered by the commands from the reader. */
                                        DemodReset();
                                        /* And ready to receive another command. */
                                        UartReset();
                                        /* And also reset the demod code, which might have been */
                                        /* false-triggered by the commands from the reader. */
                                        DemodReset();
-                               }
+                       }
                        ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF);
                }
 
                        ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF);
                }
 
@@ -1311,7 +1390,6 @@ void RAMFUNC SnoopIso14443b(void)
 
                                //Use samples as a time measurement
                                if(tracing)
 
                                //Use samples as a time measurement
                                if(tracing)
-                                   //LogTrace(Demod.output, Demod.len, samples, samples, parity, FALSE);
                                        LogTrace(Demod.output, Demod.len, samples, samples, NULL, FALSE);
 
                                triggered = TRUE;
                                        LogTrace(Demod.output, Demod.len, samples, samples, NULL, FALSE);
 
                                triggered = TRUE;
@@ -1336,47 +1414,94 @@ void RAMFUNC SnoopIso14443b(void)
        set_tracing(FALSE);     
 }
 
        set_tracing(FALSE);     
 }
 
+void iso14b_set_trigger(bool enable) {
+       trigger = enable;
+}
 
 /*
  * Send raw command to tag ISO14443B
  * @Input
 
 /*
  * Send raw command to tag ISO14443B
  * @Input
- * datalen     len of buffer data
- * recv        bool when true wait for data from tag and send to client
- * powerfield  bool leave the field on when true
- * data        buffer with byte to send
+ * param   flags enum ISO14B_COMMAND.  (mifare.h)
+ * len     len of buffer data
+ * data    buffer with bytes to send
  *
  * @Output
  * none
  *
  */
  *
  * @Output
  * none
  *
  */
-void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, uint8_t data[])
+void SendRawCommand14443B_Ex(UsbCommand *c)
 {
 {
-       // param ISO_
-       // param ISO_CONNECT
-       // param ISO14A_NO_DISCONNECT
-       //if (param & ISO14A_NO_DISCONNECT)
-       // return;
-       iso14443b_setup();
+       iso14b_command_t param = c->arg[0];
+       size_t len = c->arg[1] & 0xffff;
+       uint8_t *cmd = c->d.asBytes;
+       uint8_t status = 0;
+       uint32_t sendlen = sizeof(iso14b_card_select_t);
+       uint8_t buf[USB_CMD_DATA_SIZE] = {0x00};
+
+       if (MF_DBGLEVEL > 3) Dbprintf("param, %04x", param );
        
        
-       if ( datalen == 0 && recv == 0 && powerfield == 0){
-               
-       } else {                
+       // turn on trigger (LED_A)
+       if (param & ISO14B_REQUEST_TRIGGER)
+               iso14b_set_trigger(TRUE);
+       
+       if (param & ISO14B_CONNECT) {
+               // Make sure that we start from off, since the tags are stateful;
+               // confusing things will happen if we don't reset them between reads.
+               LED_D_OFF();
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+               SpinDelay(200);
                clear_trace();
                clear_trace();
-               set_tracing(TRUE);
-               CodeAndTransmit14443bAsReader(data, datalen);
+               iso14443b_setup();
        }
        }
+       
+       set_tracing(TRUE);
 
 
-       if (recv) {
-               GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, FALSE);
-               uint16_t len = MIN(Demod.len, USB_CMD_DATA_SIZE);
-               cmd_send(CMD_ACK, len, 0, 0, Demod.output, len);
+       if ( param & ISO14B_SELECT_STD) {
+               iso14b_card_select_t *card = (iso14b_card_select_t*)buf;
+               status = iso14443b_select_card(card);   
+               cmd_send(CMD_ACK, status, sendlen, 0, buf, sendlen);
+               // 0: OK 2: attrib fail, 3:crc fail,
+               if ( status > 0 ) return;
+       } 
+       
+       if ( param & ISO14B_SELECT_SR) {
+               iso14b_card_select_t *card = (iso14b_card_select_t*)buf;
+               status = iso14443b_select_srx_card(card);
+               cmd_send(CMD_ACK, status, sendlen, 0, buf, sendlen);
+               // 0: OK 2: attrib fail, 3:crc fail,
+               if ( status > 0 ) return;
+       } 
+       
+       if (param & ISO14B_APDU) {
+               status = iso14443b_apdu(cmd, len, buf);
+               cmd_send(CMD_ACK, status, status, 0, buf, status);
        }
        
        }
        
-       if (!powerfield) {
+       if (param & ISO14B_RAW) {
+               if(param & ISO14B_APPEND_CRC) {
+                       AppendCrc14443b(cmd, len);
+                       len += 2;
+               }
+       
+               CodeAndTransmit14443bAsReader(cmd, len);
+               GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+               
+               sendlen = MIN(Demod.len, USB_CMD_DATA_SIZE);
+               status =  (Demod.len > 0) ? 0 : 1;
+               cmd_send(CMD_ACK, status, sendlen, 0, Demod.output, sendlen);
+       }
+       
+       // turn off trigger (LED_A)
+       if (param & ISO14B_REQUEST_TRIGGER)
+               iso14a_set_trigger(FALSE);
+
+       // turn off antenna et al
+       // we don't send a HALT command.
+       if ( param & ISO14B_DISCONNECT) {
+               if (MF_DBGLEVEL > 3) Dbprintf("disconnect");
                FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                FpgaDisableSscDma();
                set_tracing(FALSE);
                FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                FpgaDisableSscDma();
                set_tracing(FALSE);
-               LED_D_OFF();
+               LEDsoff();
        }
        }
-}
-
+}
\ No newline at end of file
index f90c54f3f65c9195e153945619e8fea01263a028..30d1ac343a26158472278170ca4543f5593f24a7 100644 (file)
@@ -7,15 +7,29 @@
 // at your option, any later version. See the LICENSE.txt file for the text of
 // the license.
 //-----------------------------------------------------------------------------
 // at your option, any later version. See the LICENSE.txt file for the text of
 // the license.
 //-----------------------------------------------------------------------------
-// Routines to support ISO 14443 type A.
+// Routines to support ISO 14443 type B.
 //-----------------------------------------------------------------------------
 
 #ifndef __ISO14443B_H
 #define __ISO14443B_H
 //-----------------------------------------------------------------------------
 
 #ifndef __ISO14443B_H
 #define __ISO14443B_H
+
+#include "proxmark3.h"
+#include "apps.h"
+#include "util.h"
+#include "string.h"
+#include "iso14443crc.h"
 #include "common.h"
 #include "common.h"
+#include "mifare.h"
+#include "protocols.h"
+#include "mifareutil.h"                // access to global variable: MF_DBGLEVEL
+
+extern void AppendCrc14443b(uint8_t *data, int len);
 
 
-int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response);
+uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response);
 void iso14443b_setup();
 void iso14443b_setup();
-int iso14443b_select_card();
+uint8_t iso14443b_select_card(iso14b_card_select_t* card);
+uint8_t iso14443b_select_card_srx(iso14b_card_select_t* card);
+
+void SendRawCommand14443B_Ex(UsbCommand *c);
 
 #endif /* __ISO14443B_H */
 
 #endif /* __ISO14443B_H */
index 888f6aaf0709fdba641a79009bf3fa47291026b8..e65e7958e6598ec1410d028feb03dab689cb03c7 100644 (file)
@@ -317,21 +317,7 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
-                               int8_t r;
-
-                               r = ABS(b);
-                               
-                               // if(b < 0) {
-                                       // r = -b;
-                               // } else {
-                                       // r = b;
-                               // }
-                               // ABS(prev)
-                               if(prev < 0) {
-                                       r -= prev;
-                               } else {
-                                       r += prev;
-                               }
+                               int8_t r = ABS(b) + ABS(prev);
 
                                dest[c++] = (uint8_t)r;
 
 
                                dest[c++] = (uint8_t)r;
 
@@ -466,19 +452,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
-                               int8_t r;
-
-                               r = ABS(b);
-                               // if(b < 0) {
-                                       // r = -b;
-                               // } else {
-                                       // r = b;
-                               // }
-                               if(prev < 0) {
-                                       r -= prev;
-                               } else {
-                                       r += prev;
-                               }
+                               int8_t r = ABS(b) + ABS(prev);
 
                                dest[c++] = (uint8_t)r;
 
 
                                dest[c++] = (uint8_t)r;
 
@@ -647,18 +621,7 @@ void AcquireRawAdcSamplesIso15693(void)
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
-                               int8_t r;
-
-                               if(b < 0) {
-                                       r = -b;
-                               } else {
-                                       r = b;
-                               }
-                               if(prev < 0) {
-                                       r -= prev;
-                               } else {
-                                       r += prev;
-                               }
+                               int8_t r = ABS(b) + ABS(prev);
 
                                dest[c++] = (uint8_t)r;
 
 
                                dest[c++] = (uint8_t)r;
 
@@ -712,18 +675,7 @@ void RecordRawAdcSamplesIso15693(void)
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
                        // every other is Q. We just want power, so abs(I) + abs(Q) is
                        // close to what we want.
                        if(getNext) {
-                               int8_t r;
-
-                               if(b < 0) {
-                                       r = -b;
-                               } else {
-                                       r = b;
-                               }
-                               if(prev < 0) {
-                                       r -= prev;
-                               } else {
-                                       r += prev;
-                               }
+                               int8_t r = ABS(b) + ABS(prev);
 
                                dest[c++] = (uint8_t)r;
 
 
                                dest[c++] = (uint8_t)r;
 
index 33a4234c5fad3599b71657fed3aee9a813bba863..577ee574ec71e8151c63dcf78761373b03587932 100644 (file)
@@ -734,7 +734,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
        datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen;
                
     c.arg[1] = (datalen & 0xFFFF) | (uint32_t)(numbits << 16);
        datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen;
                
     c.arg[1] = (datalen & 0xFFFF) | (uint32_t)(numbits << 16);
-    memcpy(c.d.asBytes,data,datalen);
+    memcpy(c.d.asBytes, data, datalen);
 
        clearCommandBuffer();
     SendCommand(&c);
 
        clearCommandBuffer();
     SendCommand(&c);
@@ -749,26 +749,15 @@ int CmdHF14ACmdRaw(const char *cmd) {
 }
 
 static void waitCmd(uint8_t iSelect) {
 }
 
 static void waitCmd(uint8_t iSelect) {
-    uint8_t *recv;
     UsbCommand resp;
     UsbCommand resp;
-    char *hexout;
+    uint16_t len = 0;
 
 
-    if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
-        recv = resp.d.asBytes;
-        uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0];
-        PrintAndLog("received %i octets",iLen);
-        if(!iLen)
+    if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {        
+        len = iSelect ? (resp.arg[1] & 0xffff) : (resp.arg[0]  & 0xffff);
+        PrintAndLog("received %i octets", len);
+        if(!len)
             return;
             return;
-        hexout = (char *)malloc(iLen * 3 + 1);
-        if (hexout != NULL) {
-            for (int i = 0; i < iLen; i++) { // data in hex
-                sprintf(&hexout[i * 3], "%02X ", recv[i]);
-            }
-            PrintAndLog("%s", hexout);
-            free(hexout);
-        } else {
-            PrintAndLog("malloc failed your client has low memory?");
-        }
+               PrintAndLog("%s", sprint_hex(resp.d.asBytes, len) );
     } else {
         PrintAndLog("timeout while waiting for reply.");
     }
     } else {
         PrintAndLog("timeout while waiting for reply.");
     }
index 2e90bc4bca7ce92f5697ba6b91d19380ae01a65f..05572a3b7993f514a0c001a1ba500ccac7cc97b0 100644 (file)
 #include <stdlib.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <stdbool.h>
 #include <stdint.h>
-#include "iso14443crc.h"
-#include "proxmark3.h"
-#include "data.h"
-#include "graph.h"
-#include "util.h"
-#include "ui.h"
-#include "cmdparser.h"
 #include "cmdhf14b.h"
 #include "cmdhf14b.h"
-#include "cmdmain.h"
-#include "cmdhf14a.h"
-#include "tea.h"
-#include "cmdhf.h"
-#include "prng.h"
-#include "sha1.h"
 
 static int CmdHelp(const char *Cmd);
 
 
 static int CmdHelp(const char *Cmd);
 
-int CmdHF14BList(const char *Cmd) {
-       CmdHFList("14b");
+int usage_hf_14b_info(void){
+       PrintAndLog("Usage: hf 14b info [-h] [-s]");
+       PrintAndLog("       -h    this help");
+       PrintAndLog("       -s    silently");
        return 0;
 }
        return 0;
 }
-
-int CmdHF14BSim(const char *Cmd)
-{
-       UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443B};
-       clearCommandBuffer();
-       SendCommand(&c);
+int usage_hf_14b_reader(void){
+       PrintAndLog("Usage: hf 14b reader [-h] [-s]");
+       PrintAndLog("       -h    this help");
+       PrintAndLog("       -s    silently");
        return 0;
 }
        return 0;
 }
-
-int CmdHF14BSnoop(const char *Cmd)
-{
-       UsbCommand c = {CMD_SNOOP_ISO_14443B};
-       clearCommandBuffer();
-       SendCommand(&c);
-       return 0;
+int usage_hf_14b_raw(void){
+       PrintAndLog("Usage: hf 14b raw [-h] [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>");
+       PrintAndLog("       -h    this help");
+       PrintAndLog("       -r    do not read response");
+       PrintAndLog("       -c    calculate and append CRC");
+       PrintAndLog("       -p    leave the field on after receive");
+       PrintAndLog("       -s    active signal field ON with select");
+       PrintAndLog("       -ss   active signal field ON with select for SRx ST Microelectronics tags");
+       return 0;    
 }
 }
-
-/* New command to read the contents of a SRI512 tag
- * SRI512 tags are ISO14443-B modulated memory tags,
- * this command just dumps the contents of the memory
- */
-int CmdSri512Read(const char *Cmd)
-{
-       UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
-       clearCommandBuffer();
-       SendCommand(&c);
+int usage_hf_14b_snoop(void){
+       PrintAndLog("It get data from the field and saves it into command buffer.");
+       PrintAndLog("Buffer accessible from command 'hf list 14b'");
+       PrintAndLog("Usage: hf 14b snoop [-h]");
+       PrintAndLog("       -h    this help");
+       PrintAndLog("sample: hf 14b snoop");
+       return 0;    
+}
+int usage_hf_14b_sim(void){
+       PrintAndLog("Emulating ISO/IEC 14443 type B tag with 4 UID");
+       PrintAndLog("Usage: hf 14b sim [-h]");
+       PrintAndLog("       -h    this help");
+       PrintAndLog("sample: hf 14b sim");
+       return 0;    
+}
+int usage_hf_14b_read_srx(void){
+       PrintAndLog("Usage:  hf 14b read [h] <1|2>");
+       PrintAndLog("Options:");
+       PrintAndLog("       h        this help");
+       PrintAndLog("       <1|2>    1 = SRIX4K , 2 = SRI512");
+       PrintAndLog("sample: hf 14b read 1");
+       PrintAndLog("      : hf 14b read 2");
        return 0;
 }
        return 0;
 }
-
-/* New command to read the contents of a SRIX4K tag
- * SRIX4K tags are ISO14443-B modulated memory tags,
- * this command just dumps the contents of the memory/
- */
-int CmdSrix4kRead(const char *Cmd) {
-       UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
-       clearCommandBuffer();
-       SendCommand(&c);
+int usage_hf_14b_write_srx(void){
+       PrintAndLog("Usage:  hf 14b write <1|2> <BLOCK> <DATA>");
+       PrintAndLog("Options:");
+       PrintAndLog("       h        this help");
+       PrintAndLog("       <1|2>    1 = SRIX4K , 2 = SRI512");
+       PrintAndLog("       <block>  BLOCK number depends on tag, special block == FF");
+       PrintAndLog("       <data>   hex bytes of data to be written");
+       PrintAndLog("sample  : hf 14b write 1 7F 11223344");
+       PrintAndLog("        : hf 14b write 1 FF 11223344");
+       PrintAndLog("        : hf 14b write 2 15 11223344");
+       PrintAndLog("        : hf 14b write 2 FF 11223344");
        return 0;
 }
 
        return 0;
 }
 
-static int rawCloseEx(bool verbose){
-       UsbCommand resp;
-       UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}};
+static int rawClose(){
+       UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_DISCONNECT, 0, 0}};
        clearCommandBuffer();
        SendCommand(&c);
        clearCommandBuffer();
        SendCommand(&c);
-       if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
-               if ( verbose ) PrintAndLog("Command time-out");
-               return 0;
-       }
        return 1;
 }
        return 1;
 }
-static int rawClose() {
-       return rawCloseEx(false);
-}
 
 
-int HF14BCmdRaw(bool reply, bool *crc, bool power, uint8_t *data, uint8_t *datalen, bool verbose){
-               
-       if(*crc) {
-               ComputeCrc14443(CRC_14443_B, data, *datalen, data+*datalen, data+*datalen+1);
-               *datalen += 2;
-       }
+int CmdHF14BList(const char *Cmd) {
+       CmdHFList("14b");
+       return 0;
+}
 
 
-       UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv,power
-       c.arg[0] = *datalen;
-       c.arg[1] = reply;
-       c.arg[2] = power;
-       memcpy(c.d.asBytes, data, *datalen);
+int CmdHF14BSim(const char *Cmd) {
+       char cmdp = param_getchar(Cmd, 0);
+       if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_sim();
+       
+       UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443B, {0, 0, 0}};
        clearCommandBuffer();
        SendCommand(&c);
        clearCommandBuffer();
        SendCommand(&c);
+       return 0;
+}
 
 
-       if (!reply) return 1; 
-
-       UsbCommand resp;
-       if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
-               if (verbose) PrintAndLog("timeout while waiting for reply.");
-               return 0;
-       }
-
-       *datalen = resp.arg[0];
-       if (verbose) PrintAndLog("received %u octets", *datalen);
-       if(*datalen<3) return 0;
-
-       memcpy(data, resp.d.asBytes, *datalen);
+int CmdHF14BSnoop(const char *Cmd) {
        
        
-       uint8_t first = 0, second = 0;
-       ComputeCrc14443(CRC_14443_B, data, *datalen-2, &first, &second);
-       *crc = ( data[*datalen-2] == first && data[*datalen-1] == second);
-
-       if (verbose)
-               PrintAndLog("[LEN %u] %s[%02X %02X] %s",
-                               *datalen,
-                               sprint_hex(data, *datalen-2),
-                               data[*datalen-2],
-                               data[*datalen-1],
-                               (*crc)?"OK":"FAIL"
-                               );
+       char cmdp = param_getchar(Cmd, 0);
+       if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_snoop();
        
        
-       return 1;
+       UsbCommand c = {CMD_SNOOP_ISO_14443B, {0, 0, 0}};
+       clearCommandBuffer();
+       SendCommand(&c);
+       return 0;
 }
 
 int CmdHF14BCmdRaw (const char *Cmd) {
 }
 
 int CmdHF14BCmdRaw (const char *Cmd) {
-    bool reply = true;
-    bool crc = false;
-       bool power = false;
-       bool select = false;
-       bool SRx = false;
-    char buf[5]="";
-    uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
-    uint8_t datalen = 0;
-    unsigned int temp;
-    int i = 0;
-    if (strlen(Cmd)<3) {
-               PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>");
-        PrintAndLog("       -r    do not read response");
-        PrintAndLog("       -c    calculate and append CRC");
-        PrintAndLog("       -p    leave the field on after receive");
-               PrintAndLog("       -s    active signal field ON with select");
-               PrintAndLog("       -ss   active signal field ON with select for SRx ST Microelectronics tags");
-        return 0;    
-    }
+       bool reply = TRUE;
+       bool power = FALSE;
+       bool select = FALSE;
+       char buf[5]="";
+
+       int i = 0;
+       uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
+       uint16_t datalen = 0;
+       uint32_t flags = 0;
+       uint32_t temp = 0;
+       
+       if (strlen(Cmd)<3) return usage_hf_14b_raw();
 
     // strip
 
     // strip
-    while (*Cmd==' ' || *Cmd=='\t') Cmd++;
+    while (*Cmd==' ' || *Cmd=='\t') ++Cmd;
     
     while (Cmd[i]!='\0') {
     
     while (Cmd[i]!='\0') {
-        if (Cmd[i]==' ' || Cmd[i]=='\t') { i++; continue; }
+        if (Cmd[i]==' ' || Cmd[i]=='\t') { ++i; continue; }
         if (Cmd[i]=='-') {
             switch (Cmd[i+1]) {
         if (Cmd[i]=='-') {
             switch (Cmd[i+1]) {
+                               case 'H':
+                               case 'h':
+                                       return usage_hf_14b_raw();
                 case 'r': 
                 case 'R': 
                 case 'r': 
                 case 'R': 
-                    reply = false;
+                    reply = FALSE;
                     break;
                 case 'c':
                 case 'C':                
                     break;
                 case 'c':
                 case 'C':                
-                    crc = true;
+                    flags |= ISO14B_APPEND_CRC;
                     break;
                 case 'p': 
                 case 'P': 
                     break;
                 case 'p': 
                 case 'P': 
-                                       power = true;
+                                       power = TRUE;
                     break;
                                case 's':
                                case 'S':
                     break;
                                case 's':
                                case 'S':
-                                       select = true;
+                                       flags |= ISO14B_CONNECT;
+                                       select = TRUE;
                                        if (Cmd[i+2]=='s' || Cmd[i+2]=='S') {
                                        if (Cmd[i+2]=='s' || Cmd[i+2]=='S') {
-                                               SRx = true;
-                                               i++;
+                                               flags |= ISO14B_SELECT_SR;
+                                               ++i;
+                                       } else {
+                                               flags |= ISO14B_SELECT_STD;
                                        }
                                        break;
                 default:
                                        }
                                        break;
                 default:
-                    PrintAndLog("Invalid option");
-                    return 0;
+                    return usage_hf_14b_raw();
             }
             i+=2;
             continue;
             }
             i+=2;
             continue;
@@ -197,7 +171,7 @@ int CmdHF14BCmdRaw (const char *Cmd) {
             
             if (strlen(buf)>=2) {
                 sscanf(buf,"%x",&temp);
             
             if (strlen(buf)>=2) {
                 sscanf(buf,"%x",&temp);
-                data[datalen++]=(uint8_t)(temp & 0xff);
+                data[datalen++] = (uint8_t)(temp & 0xff);
                 *buf=0;
                                memset(buf, 0x00, sizeof(buf));
             }
                 *buf=0;
                                memset(buf, 0x00, sizeof(buf));
             }
@@ -206,74 +180,40 @@ int CmdHF14BCmdRaw (const char *Cmd) {
         PrintAndLog("Invalid char on input");
                return 0;
     }
         PrintAndLog("Invalid char on input");
                return 0;
     }
-    if (datalen == 0)
-    {
-      PrintAndLog("Missing data input");
-      return 0;
-    }
-
-       if (select){ //auto select 14b tag
-               uint8_t cmd2[16];
-               bool crc2 = true;
-               uint8_t cmdLen;
-
-               if (SRx) {
-                       // REQ SRx
-                       cmdLen = 2;
-                       cmd2[0] = 0x06;
-                       cmd2[1] = 0x00;
-               } else {
-                       // REQB
-                       cmdLen = 3;
-                       cmd2[0] = 0x05;
-                       cmd2[1] = 0x00;
-                       cmd2[2] = 0x08;
-               }
-               
-               // REQB
-               if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose();
-                                                                         
-               PrintAndLog("REQB   : %s", sprint_hex(cmd2, cmdLen));
-               
-               if ( SRx && (cmdLen != 3 || !crc2) ) return rawClose();
-               else if (cmd2[0] != 0x50 || cmdLen != 14 || !crc2) return rawClose();
-               
-               uint8_t chipID = 0;
-               if (SRx) {
-                       // select
-                       chipID = cmd2[0];
-                       cmd2[0] = 0x0E;
-                       cmd2[1] = chipID;
-                       cmdLen = 2;
-               } else {
-                       // attrib
-                       cmd2[0] = 0x1D; 
-                       // UID from cmd2[1 - 4]
-                       cmd2[5] = 0x00;
-                       cmd2[6] = 0x08;
-                       cmd2[7] = 0x01;
-                       cmd2[8] = 0x00;
-                       cmdLen = 9;
-               }
-               // wait         
-               
-               // attrib
-               if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose();
-               PrintAndLog("ATTRIB : %s", sprint_hex(cmd2, cmdLen));
-               
-               if (cmdLen != 3 || !crc2) return rawClose();            
-               if (SRx && cmd2[0] != chipID) return rawClose();
        
        
-       }
-       return HF14BCmdRaw(reply, &crc, power, data, &datalen, true);
+       if(!power)
+        flags |= ISO14B_DISCONNECT;
+
+    if(datalen>0)
+        flags |= ISO14B_RAW;
+
+       // Max buffer is USB_CMD_DATA_SIZE
+       datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen;
+
+       UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}}; 
+       memcpy(c.d.asBytes, data, datalen);
+       clearCommandBuffer();
+       SendCommand(&c);
+
+       if (!reply) return 1; 
+
+       bool success = TRUE;
+       // get back iso14b_card_select_t, don't print it.
+       if(select) 
+               success = waitCmd(FALSE);
+
+       // get back response from the raw bytes you sent.
+       if(success && datalen>0) waitCmd(TRUE);
+
+    return 1;
 }
 
 // print full atqb info
 }
 
 // print full atqb info
-static void print_atqb_resp(uint8_t *data){
+static void print_atqb_resp(uint8_t *data, uint8_t cid){
        //PrintAndLog ("           UID: %s", sprint_hex(data+1,4));
        //PrintAndLog ("           UID: %s", sprint_hex(data+1,4));
-       PrintAndLog ("      App Data: %s", sprint_hex(data+5,4));
-       PrintAndLog ("      Protocol: %s", sprint_hex(data+9,3));
-       uint8_t BitRate = data[9];
+       PrintAndLog ("      App Data: %s", sprint_hex(data,4));
+       PrintAndLog ("      Protocol: %s", sprint_hex(data+4,3));
+       uint8_t BitRate = data[4];
        if (!BitRate) PrintAndLog ("      Bit Rate: 106 kbit/s only PICC <-> PCD");
        if (BitRate & 0x10)     PrintAndLog ("      Bit Rate: 212 kbit/s PICC -> PCD supported");
        if (BitRate & 0x20)     PrintAndLog ("      Bit Rate: 424 kbit/s PICC -> PCD supported"); 
        if (!BitRate) PrintAndLog ("      Bit Rate: 106 kbit/s only PICC <-> PCD");
        if (BitRate & 0x10)     PrintAndLog ("      Bit Rate: 212 kbit/s PICC -> PCD supported");
        if (BitRate & 0x20)     PrintAndLog ("      Bit Rate: 424 kbit/s PICC -> PCD supported"); 
@@ -283,7 +223,7 @@ static void print_atqb_resp(uint8_t *data){
        if (BitRate & 0x04)     PrintAndLog ("      Bit Rate: 847 kbit/s PICC <- PCD supported"); 
        if (BitRate & 0x80)     PrintAndLog ("                Same bit rate <-> required");
 
        if (BitRate & 0x04)     PrintAndLog ("      Bit Rate: 847 kbit/s PICC <- PCD supported"); 
        if (BitRate & 0x80)     PrintAndLog ("                Same bit rate <-> required");
 
-       uint16_t maxFrame = data[10]>>4;
+       uint16_t maxFrame = data[5]>>4;
        if (maxFrame < 5)               maxFrame = 8 * maxFrame + 16;
        else if (maxFrame == 5) maxFrame = 64;
        else if (maxFrame == 6) maxFrame = 96;
        if (maxFrame < 5)               maxFrame = 8 * maxFrame + 16;
        else if (maxFrame == 5) maxFrame = 64;
        else if (maxFrame == 6) maxFrame = 96;
@@ -293,14 +233,15 @@ static void print_atqb_resp(uint8_t *data){
 
        PrintAndLog ("Max Frame Size: %u%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
 
 
        PrintAndLog ("Max Frame Size: %u%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
 
-       uint8_t protocolT = data[10] & 0xF;
+       uint8_t protocolT = data[5] & 0xF;
        PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
        PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
-       PrintAndLog ("Frame Wait Int: %u", data[11]>>4);
-       PrintAndLog (" App Data Code: Application is %s",(data[11]&4) ? "Standard" : "Proprietary");
-       PrintAndLog (" Frame Options: NAD is %ssupported",(data[11]&2) ? "" : "not ");
-       PrintAndLog (" Frame Options: CID is %ssupported",(data[11]&1) ? "" : "not ");
-       PrintAndLog ("Max Buf Length: %u (MBLI) %s",data[14]>>4, (data[14] & 0xF0) ? "" : "not supported");
-
+       PrintAndLog ("Frame Wait Int: %u", data[6]>>4);
+       PrintAndLog (" App Data Code: Application is %s",(data[6]&4) ? "Standard" : "Proprietary");
+       PrintAndLog (" Frame Options: NAD is %ssupported",(data[6]&2) ? "" : "not ");
+       PrintAndLog (" Frame Options: CID is %ssupported",(data[6]&1) ? "" : "not ");
+       PrintAndLog ("Tag :");
+       PrintAndLog ("  Max Buf Length: %u (MBLI) %s",cid>>4, (cid & 0xF0) ? "" : "not supported");
+       PrintAndLog ("  Cid : %u", cid & 0x0f);
        return;
 }
 
        return;
 }
 
@@ -323,303 +264,347 @@ char *get_ST_Chip_Model(uint8_t data){
        return retStr;
 }
 
        return retStr;
 }
 
+// REMAKE:
 int print_ST_Lock_info(uint8_t model){
 int print_ST_Lock_info(uint8_t model){
-       //assume connection open and tag selected...
-       uint8_t data[16] = {0x00};
-       uint8_t datalen = 2;
-       bool crc = true;
-       uint8_t resplen;
-       uint8_t blk1;
-       data[0] = 0x08;
-
-       if (model == 0x2) { //SR176 has special command:
-               data[1] = 0xf;
-               resplen = 4;                    
-       } else {
-               data[1] = 0xff;
-               resplen = 6;
-       }
 
 
-       //std read cmd
-       if (HF14BCmdRaw(true, &crc, true, data, &datalen, false)==0) return rawClose();
-
-       if (datalen != resplen || !crc) return rawClose();
-
-       PrintAndLog("Chip Write Protection Bits:");
-       // now interpret the data
-       switch (model){
-               case 0x0: //fall through (SRIX4K special)
-               case 0x3: //fall through (SRIx4K)
-               case 0x7: //             (SRI4K)
-                       //only need data[3]
-                       blk1 = 9;
-                       PrintAndLog("   raw: %s", sprint_bin(data+3, 1));
-                       PrintAndLog(" 07/08:%slocked", (data[3] & 1) ? " not " : " " );
-                       for (uint8_t i = 1; i<8; i++){
-                               PrintAndLog("    %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " );
-                               blk1++;
-                       }
-                       break;
-               case 0x4: //fall through (SRIX512)
-               case 0x6: //fall through (SRI512)
-               case 0xC: //             (SRT512)
-                       //need data[2] and data[3]
-                       blk1 = 0;
-                       PrintAndLog("   raw: %s", sprint_bin(data+2, 2));
-                       for (uint8_t b=2; b<4; b++){
-                               for (uint8_t i=0; i<8; i++){
-                                       PrintAndLog("    %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " );
-                                       blk1++;
-                               }
-                       }
-                       break;
-               case 0x2: //             (SR176)
-                       //need data[2]
-                       blk1 = 0;
-                       PrintAndLog("   raw: %s", sprint_bin(data+2, 1));
-                       for (uint8_t i = 0; i<8; i++){
-                               PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " );
-                               blk1+=2;
-                       }
-                       break;
-               default:
-                       return rawClose();
-       }
+       // PrintAndLog("Chip Write Protection Bits:");
+       // // now interpret the data
+       // switch (model){
+               // case 0x0: //fall through (SRIX4K special)
+               // case 0x3: //fall through (SRIx4K)
+               // case 0x7: //             (SRI4K)
+                       // //only need data[3]
+                       // blk1 = 9;
+                       // PrintAndLog("   raw: %s", sprint_bin(data+3, 1));
+                       // PrintAndLog(" 07/08:%slocked", (data[3] & 1) ? " not " : " " );
+                       // for (uint8_t i = 1; i<8; i++){
+                               // PrintAndLog("    %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " );
+                               // blk1++;
+                       // }
+                       // break;
+               // case 0x4: //fall through (SRIX512)
+               // case 0x6: //fall through (SRI512)
+               // case 0xC: //             (SRT512)
+                       // //need data[2] and data[3]
+                       // blk1 = 0;
+                       // PrintAndLog("   raw: %s", sprint_bin(data+2, 2));
+                       // for (uint8_t b=2; b<4; b++){
+                               // for (uint8_t i=0; i<8; i++){
+                                       // PrintAndLog("    %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " );
+                                       // blk1++;
+                               // }
+                       // }
+                       // break;
+               // case 0x2: //             (SR176)
+                       // //need data[2]
+                       // blk1 = 0;
+                       // PrintAndLog("   raw: %s", sprint_bin(data+2, 1));
+                       // for (uint8_t i = 0; i<8; i++){
+                               // PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " );
+                               // blk1+=2;
+                       // }
+                       // break;
+               // default:
+                       // return rawClose();
+       // }
        return 1;
 }
 
 // print UID info from SRx chips (ST Microelectronics)
        return 1;
 }
 
 // print UID info from SRx chips (ST Microelectronics)
-static void print_st_general_info(uint8_t *data){
+static void print_st_general_info(uint8_t *data, uint8_t len){
        //uid = first 8 bytes in data
        //uid = first 8 bytes in data
-       PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8),8));
+       PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8), len));
        PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
        PrintAndLog("Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
        return;
 }
 
        PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
        PrintAndLog("Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
        return;
 }
 
-// 14b get and print UID only (general info)
-int HF14BStdReader(uint8_t *data, uint8_t *datalen, bool verbose){
-       //05 00 00 = find one tag in field
-       //1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
-       //a3 = ?  (resp 03 [e2 c2])
-       //02 = ?  (resp 02 [6a d3])
-       // 022b (resp 02 67 00 [29  5b])
-       // 0200a40400 (resp 02 67 00 [29 5b])
-       // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
-       // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
-       // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
-       // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
-       // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
-       // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
-       // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
-       //03 = ?  (resp 03 [e3 c2])
-       //c2 = ?  (resp c2 [66 15])
-       //b2 = ?  (resp a3 [e9 67])             
-       //a2 = ?  (resp 02 [6a d3])
-       bool crc = true;
-       *datalen = 3;
-       //std read cmd
-       data[0] = 0x05;
-       data[1] = 0x00;
-       data[2] = 0x08;
-
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawCloseEx(verbose);
-
-       if (data[0] != 0x50 || *datalen != 14 || !crc) return rawCloseEx(verbose);
-
-       PrintAndLog ("\n14443-3b tag found:");
-       PrintAndLog ("           UID: %s", sprint_hex(data+1,4));
-
-       uint8_t cmd2[16];
-       uint8_t cmdLen = 3;
-       bool crc2 = true;
-
-       cmd2[0] = 0x1D; 
-       // UID from data[1 - 4]
-       cmd2[1] = data[1];
-       cmd2[2] = data[2];
-       cmd2[3] = data[3];
-       cmd2[4] = data[4];
-       cmd2[5] = 0x00;
-       cmd2[6] = 0x08;
-       cmd2[7] = 0x01;
-       cmd2[8] = 0x00;
-       cmdLen = 9;
-
-       // attrib
-       if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) rawCloseEx(verbose);
-
-       if (cmdLen != 3 || !crc2) return rawCloseEx(verbose);
-       // add attrib responce to data
-       data[14] = cmd2[0];
-       rawCloseEx(verbose);
-       return 1;
-}
+//05 00 00 = find one tag in field
+//1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
+//a3 = ?  (resp 03 [e2 c2])
+//02 = ?  (resp 02 [6a d3])
+// 022b (resp 02 67 00 [29  5b])
+// 0200a40400 (resp 02 67 00 [29 5b])
+// 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
+// 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
+// 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
+// 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
+// 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
+// 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
+// 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
+//03 = ?  (resp 03 [e3 c2])
+//c2 = ?  (resp c2 [66 15])
+//b2 = ?  (resp a3 [e9 67])            
+//a2 = ?  (resp 02 [6a d3])
 
 // 14b get and print Full Info (as much as we know)
 
 // 14b get and print Full Info (as much as we know)
-int HF14BStdInfo(uint8_t *data, uint8_t *datalen, bool verbose){
-       if (!HF14BStdReader(data,datalen, verbose)) return 0;
-
+bool HF14B_Std_Info(bool verbose){
        //add more info here
        //add more info here
-       print_atqb_resp(data);
-       return 1;
+       return FALSE;
 }
 
 }
 
-// SRx get and print general info about SRx chip from UID
-int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen, bool closeCon, bool verbose){
-       bool crc = true;
-       *datalen = 2;
-       //wake cmd
-       data[0] = 0x06;
-       data[1] = 0x00;
-
-       //leave power on
-       // verbose on for now for testing - turn off when functional
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawCloseEx(verbose);
+// SRx get and print full info (needs more info...)
+bool HF14B_ST_Info(bool verbose){
+       
+       UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
+       clearCommandBuffer();
+       SendCommand(&c);
+       UsbCommand resp;
 
 
-       if (*datalen != 3 || !crc) return rawClose();
+       if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
+               if (verbose) PrintAndLog("timeout while waiting for reply.");
+               return FALSE;
+    }
 
 
-       uint8_t chipID = data[0];
-       // select
-       data[0] = 0x0E;
-       data[1] = chipID;
-       *datalen = 2;
+       iso14b_card_select_t card;
+       memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
+       
+       uint64_t status = resp.arg[0];  
+       if ( status > 0 ) { 
+               rawClose();
+               return FALSE;
+       }
 
 
-       //leave power on
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawCloseEx(verbose);
+       //add locking bit information here. uint8_t data[16] = {0x00};
+       // uint8_t datalen = 2;
+       // uint8_t resplen;
+       // uint8_t      blk1;
+       // data[0] = 0x08;
+
+       //
+       // if (model == 0x2) { //SR176 has special command:
+               // data[1] = 0xf;
+               // resplen = 4;                 
+       // } else {
+               // data[1] = 0xff;
+               // resplen = 6;
+       // }
+
+       // //std read cmd
+       // if (HF14BCmdRaw(true, true, data, &datalen, false)==0) 
+               // return rawClose();
+       
+       // if (datalen != resplen || !crc) return rawClose();
+       //print_ST_Lock_info(data[5]>>2);
+       rawClose();
+       return TRUE;
+}
 
 
-       if (*datalen != 3 || !crc || data[0] != chipID) return rawCloseEx(verbose);
+// get and print all info known about any known 14b tag
+bool HF14BInfo(bool verbose){
 
 
-       // get uid
-       data[0] = 0x0B;
-       *datalen = 1;
+       // try std 14b (atqb)
+       if (HF14B_Std_Info(verbose)) return TRUE;
 
 
-       //leave power on
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawCloseEx(verbose);
+       // try st 14b
+       if (HF14B_ST_Info(verbose)) return TRUE;
 
 
-       if (*datalen != 10 || !crc) return rawCloseEx(verbose);
+       // try unknown 14b read commands (to be identified later)
+       //   could be read of calypso, CEPAS, moneo, or pico pass.
 
 
-       //power off ?
-       if (closeCon) rawCloseEx(verbose);
+       if (verbose) PrintAndLog("no 14443B tag found");
+       return FALSE;
+}
 
 
-       if (verbose ) {
-               PrintAndLog("\n14443-3b ST tag found:");
-               print_st_general_info(data);
-       }
-       return 1;
+// menu command to get and print all info known about any known 14b tag
+int CmdHF14Binfo(const char *Cmd){
+       char cmdp = param_getchar(Cmd, 0);
+       if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_info();
+       
+       bool verbose = !((cmdp == 's') || (cmdp == 'S'));
+       return HF14BInfo(verbose);
 }
 
 }
 
-// SRx get and print full info (needs more info...)
-int HF14B_ST_Info(uint8_t *data, uint8_t *datalen, bool verbose){
-       if (!HF14B_ST_Reader(data, datalen, false, verbose)) return 0;
+bool HF14B_ST_Reader(bool verbose){
+
+       bool isSuccess = FALSE;
+
+       // SRx get and print general info about SRx chip from UID
+       UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
+       clearCommandBuffer();
+       SendCommand(&c);
+       UsbCommand resp;
        
        
-       //add locking bit information here.
-       if (print_ST_Lock_info(data[5]>>2)) 
-               rawCloseEx(verbose);
+       if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
+               if (verbose) PrintAndLog("timeout while waiting for reply.");
+               return FALSE;
+    }
 
 
-       return 1;
-}
+       
+       iso14b_card_select_t card;
+       memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
 
 
-// test for other 14b type tags (mimic another reader - don't have tags to identify)
-int HF14B_Other_Reader(uint8_t *data, uint8_t *datalen, bool verbose){
-       bool crc = true;
-       *datalen = 4;
-       //std read cmd
-       data[0] = 0x00;
-       data[1] = 0x0b;
-       data[2] = 0x3f;
-       data[3] = 0x80;
-
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)!=0) {
-               if (*datalen > 2 || !crc) {
-                       PrintAndLog ("\n14443-3b tag found:");
-                       PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:");
-                       PrintAndLog ("%s",sprint_hex(data,*datalen));
-                       rawCloseEx(verbose);
-                       return 1;
-               }
-       }
+       uint64_t status = resp.arg[0];
 
 
-       crc = false;
-       *datalen = 1;
-       data[0] = 0x0a;
-
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)!=0) {
-               if (*datalen > 0) {
-                       PrintAndLog ("\n14443-3b tag found:");
-                       PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
-                       PrintAndLog ("%s",sprint_hex(data,*datalen));
-                       rawCloseEx(verbose);
-                       return 1;
-               }
+       switch( status ){
+               case 0: 
+                       print_st_general_info(card.uid, card.uidlen);
+                       isSuccess = TRUE;
+                       break;
+               case 1:
+                       if (verbose) PrintAndLog("iso14443-3 random chip id fail");
+                       break;
+               case 2:
+                       if (verbose) PrintAndLog("iso14443-3 ATTRIB fail");
+                       break;
+               case 3: 
+                       if (verbose) PrintAndLog("iso14443-3 CRC fail");
+                       break;
+               default:
+                       if (verbose) PrintAndLog("iso14443b card select SRx failed");
+                       break;
        }
        
        }
        
-       crc = false;
-       *datalen = 1;
-       data[0] = 0x0c;
-
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)!=0) {
-               if (*datalen > 0) {
-                       PrintAndLog ("\n14443-3b tag found:");
-                       PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
-                       PrintAndLog ("%s",sprint_hex(data,*datalen));
-                       rawCloseEx(verbose);
-                       return 1;
-               }
-       }
-       rawCloseEx(verbose);
-       return 0;
+       rawClose();
+       return isSuccess;               
 }
 
 }
 
-// get and print all info known about any known 14b tag
-int HF14BInfo(bool verbose){
-       uint8_t data[USB_CMD_DATA_SIZE];
-       uint8_t datalen = 5;
+bool HF14B_Std_Reader(bool verbose){
 
 
-       // try std 14b (atqb)
-       if (HF14BStdInfo(data, &datalen, verbose)) return 1;
+       bool isSuccess = FALSE;
 
 
-       // try st 14b
-       if (HF14B_ST_Info(data, &datalen, verbose)) return 1;
+       // 14b get and print UID only (general info) 
+       UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0}};
+       clearCommandBuffer();
+       SendCommand(&c);
+       UsbCommand resp;
+       
+       if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
+               if (verbose) PrintAndLog("timeout while waiting for reply.");
+               return FALSE;
+    }
+       
+       iso14b_card_select_t card;
+       memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
+       
+       uint64_t status = resp.arg[0];  
+       
+       switch( status ){
+               case 0: 
+                       PrintAndLog(" UID    : %s", sprint_hex(card.uid, card.uidlen));
+                       PrintAndLog(" ATQB   : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
+                       PrintAndLog(" CHIPID : %02X", card.chipid);
+                       print_atqb_resp(card.atqb, card.cid);
+                       isSuccess = TRUE;
+                       break;
+               case 2:
+                       if (verbose) PrintAndLog("iso14443-3 ATTRIB fail");
+                       break;
+               case 3: 
+                       if (verbose) PrintAndLog("iso14443-3 CRC fail");
+                       break;
+               default:
+                       if (verbose) PrintAndLog("iso14443b card select failed");
+                       break;
+       }
+       
+       rawClose();
+       return isSuccess;       
+}
 
 
-       // try unknown 14b read commands (to be identified later)
-       //   could be read of calypso, CEPAS, moneo, or pico pass.
-       if (HF14B_Other_Reader(data, &datalen, verbose)) return 1;
+// test for other 14b type tags (mimic another reader - don't have tags to identify)
+bool HF14B_Other_Reader(){
 
 
-       if (verbose) PrintAndLog("no 14443B tag found");
-       return 0;
-}
+       // uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
+       // uint8_t datalen = 4;
 
 
-// menu command to get and print all info known about any known 14b tag
-int CmdHF14Binfo(const char *Cmd){
-       return HF14BInfo(true);
+       // // 14b get and print UID only (general info) 
+       // uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC;
+       
+       // UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}}; 
+       // memcpy(c.d.asBytes, data, datalen);
+
+       // clearCommandBuffer();
+       // SendCommand(&c);
+       // UsbCommand resp;
+       // WaitForResponse(CMD_ACK,&resp);
+       
+       // if (datalen > 2 ) {
+               // printandlog ("\n14443-3b tag found:");
+               // printandlog ("unknown tag type answered to a 0x000b3f80 command ans:");
+               // //printandlog ("%s", sprint_hex(data, datalen));
+               // rawclose();
+               // return true;
+       // }
+
+       // c.arg1 = 1;
+       // c.d.asBytes[0] = ISO14443B_AUTHENTICATE;
+       // clearCommandBuffer();
+       // SendCommand(&c);
+       // UsbCommand resp;
+       // WaitForResponse(CMD_ACK, &resp);
+       
+       // if (datalen > 0) {
+               // PrintAndLog ("\n14443-3b tag found:");
+               // PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
+               // // PrintAndLog ("%s", sprint_hex(data, datalen));
+               // rawClose();
+               // return TRUE;
+       // }
+
+       // c.arg1 = 1;
+       // c.d.asBytes[0] = ISO14443B_RESET;
+       // clearCommandBuffer();
+       // SendCommand(&c);
+       // UsbCommand resp;
+       // WaitForResponse(CMD_ACK, &resp);
+
+       // if (datalen > 0) {
+               // PrintAndLog ("\n14443-3b tag found:");
+               // PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
+               // PrintAndLog ("%s", sprint_hex(data, datalen));
+               // rawClose();
+               // return TRUE;
+       // }
+       
+       // rawClose();
+       return FALSE;
 }
 
 // get and print general info about all known 14b chips
 }
 
 // get and print general info about all known 14b chips
-int HF14BReader(bool verbose){
-       uint8_t data[USB_CMD_DATA_SIZE];
-       uint8_t datalen = 5;
+bool HF14BReader(bool verbose){
        
        // try std 14b (atqb)
        
        // try std 14b (atqb)
-       if (HF14BStdReader(data, &datalen, verbose)) return 1;
+       if (HF14B_Std_Reader(verbose)) return TRUE;
 
 
-       // try st 14b
-       if (HF14B_ST_Reader(data, &datalen, true, verbose)) return 1;
+       // try ST Microelectronics 14b
+       if (HF14B_ST_Reader(verbose)) return TRUE;
 
        // try unknown 14b read commands (to be identified later)
        //   could be read of calypso, CEPAS, moneo, or pico pass.
 
        // try unknown 14b read commands (to be identified later)
        //   could be read of calypso, CEPAS, moneo, or pico pass.
-       if (HF14B_Other_Reader(data, &datalen, verbose)) return 1;
+       if (HF14B_Other_Reader()) return TRUE;
 
        if (verbose) PrintAndLog("no 14443B tag found");
 
        if (verbose) PrintAndLog("no 14443B tag found");
-       return 0;
+       return FALSE;
 }
 
 // menu command to get and print general info about all known 14b chips
 int CmdHF14BReader(const char *Cmd){
 }
 
 // menu command to get and print general info about all known 14b chips
 int CmdHF14BReader(const char *Cmd){
-       return HF14BReader(true);
+       char cmdp = param_getchar(Cmd, 0);
+       if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_reader();
+       
+       bool verbose = !((cmdp == 's') || (cmdp == 'S'));
+       return HF14BReader(verbose);
 }
 
 }
 
-int CmdSriWrite( const char *Cmd){
+/* New command to read the contents of a SRI512|SRIX4K tag
+ * SRI* tags are ISO14443-B modulated memory tags,
+ * this command just dumps the contents of the memory/
+ */
+int CmdHF14BReadSri(const char *Cmd){
+       char cmdp = param_getchar(Cmd, 0);
+       if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_hf_14b_read_srx();
+
+       uint8_t tagtype = param_get8(Cmd, 0);
+       uint8_t blocks = (tagtype == 1) ? 0x7F : 0x0F;
+       
+       UsbCommand c = {CMD_READ_SRI_TAG, {blocks, 0, 0}};
+       clearCommandBuffer();
+       SendCommand(&c);
+       return 0;
+}
+// New command to write a SRI512/SRIX4K tag.
+int CmdHF14BWriteSri(const char *Cmd){
 /*
  * For SRIX4K  blocks 00 - 7F
  * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
 /*
  * For SRIX4K  blocks 00 - 7F
  * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
@@ -634,26 +619,17 @@ int CmdSriWrite( const char *Cmd){
        uint8_t blockno = -1;
        uint8_t data[4] = {0x00};
        bool isSrix4k = true;
        uint8_t blockno = -1;
        uint8_t data[4] = {0x00};
        bool isSrix4k = true;
-       char str[20];   
-
-       if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
-               PrintAndLog("Usage:  hf 14b write <1|2> <BLOCK> <DATA>");
-               PrintAndLog("    [1 = SRIX4K]");
-               PrintAndLog("    [2 = SRI512]");
-               PrintAndLog("    [BLOCK number depends on tag, special block == FF]");
-               PrintAndLog("     sample: hf 14b write 1 7F 11223344");
-               PrintAndLog("           : hf 14b write 1 FF 11223344");
-               PrintAndLog("           : hf 14b write 2 15 11223344");
-               PrintAndLog("           : hf 14b write 2 FF 11223344");
-               return 0;
-       }
+       char str[30];   
+       memset(str, 0x00, sizeof(str));
+
+       if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_hf_14b_write_srx();
 
        if ( cmdp == '2' )
                isSrix4k = false;
        
        //blockno = param_get8(Cmd, 1);
        
 
        if ( cmdp == '2' )
                isSrix4k = false;
        
        //blockno = param_get8(Cmd, 1);
        
-       if ( param_gethex(Cmd,1, &blockno, 2) ) {
+       if ( param_gethex(Cmd, 1, &blockno, 2) ) {
                PrintAndLog("Block number must include 2 HEX symbols");
                return 0;
        }
                PrintAndLog("Block number must include 2 HEX symbols");
                return 0;
        }
@@ -675,13 +651,21 @@ int CmdSriWrite( const char *Cmd){
                return 0;
        }
  
                return 0;
        }
  
-       if ( blockno == 0xff)
-               PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno,  sprint_hex(data,4) );
-       else
-               PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno,  sprint_hex(data,4) );
-       sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
-
+       if ( blockno == 0xff) {
+               PrintAndLog("[%s] Write special block %02X [ %s ]",
+                       (isSrix4k) ? "SRIX4K":"SRI512",
+                       blockno,
+                       sprint_hex(data,4)
+               );
+       } else {
+               PrintAndLog("[%s] Write block %02X [ %s ]",
+                       (isSrix4k) ? "SRIX4K":"SRI512",
+                       blockno, 
+                       sprint_hex(data,4)
+               );
+       }
+       
+       sprintf(str, "-ss -c %02x %02x %02x%02x%02x%02x", ISO14443B_WRITE_BLK, blockno, data[0], data[1], data[2], data[3]);
        CmdHF14BCmdRaw(str);
        return 0;
 }
        CmdHF14BCmdRaw(str);
        return 0;
 }
@@ -821,19 +805,55 @@ int CmdteaSelfTest(const char *Cmd){
        return 0;
 }
 
        return 0;
 }
 
+bool waitCmd(bool verbose) {
+
+       bool crc = FALSE;
+       uint8_t b1 = 0, b2 = 0;
+       uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
+       uint8_t status = 0;
+       uint16_t len = 0;       
+    UsbCommand resp;
+
+    if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
+
+               status = (resp.arg[0] & 0xFFFF);
+               if ( status > 0 ) return FALSE;
+               
+               len = (resp.arg[1] & 0xFFFF);
+               memcpy(data, resp.d.asBytes, len);
+               
+               if (verbose) {
+                       
+                       ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
+                       crc = ( data[len-2] == b1 && data[len-1] == b2);
+                       
+                       PrintAndLog("[LEN %u] %s[%02X %02X] %s",
+                               len,
+                               sprint_hex(data, len-2),
+                               data[len-2],
+                               data[len-1],
+                               (crc) ? "OK" : "FAIL"
+                       );
+               }       
+               return TRUE;
+    } else {
+        PrintAndLog("timeout while waiting for reply.");
+               return FALSE;
+    }
+}
+
 static command_t CommandTable[] = {
        {"help",        CmdHelp,        1, "This help"},
        {"info",        CmdHF14Binfo,   0, "Find and print details about a 14443B tag"},
        {"list",        CmdHF14BList,   0, "[Deprecated] List ISO 14443B history"},
 static command_t CommandTable[] = {
        {"help",        CmdHelp,        1, "This help"},
        {"info",        CmdHF14Binfo,   0, "Find and print details about a 14443B tag"},
        {"list",        CmdHF14BList,   0, "[Deprecated] List ISO 14443B history"},
+       {"raw",         CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
        {"reader",      CmdHF14BReader, 0, "Act as a 14443B reader to identify a tag"},
        {"sim",         CmdHF14BSim,    0, "Fake ISO 14443B tag"},
        {"snoop",       CmdHF14BSnoop,  0, "Eavesdrop ISO 14443B"},
        {"reader",      CmdHF14BReader, 0, "Act as a 14443B reader to identify a tag"},
        {"sim",         CmdHF14BSim,    0, "Fake ISO 14443B tag"},
        {"snoop",       CmdHF14BSnoop,  0, "Eavesdrop ISO 14443B"},
-       {"sri512read",  CmdSri512Read,  0, "Read contents of a SRI512 tag"},
-       {"srix4kread",  CmdSrix4kRead,  0, "Read contents of a SRIX4K tag"},
-       {"sriwrite",    CmdSriWrite,    0, "Write data to a SRI512 | SRIX4K tag"},
-       {"raw",         CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
+       {"sriread",             CmdHF14BReadSri,  0, "Read contents of a SRI512 | SRIX4K tag"},
+       {"sriwrite",    CmdHF14BWriteSri, 0, "Write data to a SRI512 | SRIX4K tag"},
        //{"valid",     srix4kValid,    1, "srix4k checksum test"},
        //{"valid",     srix4kValid,    1, "srix4k checksum test"},
-       {"valid",       CmdteaSelfTest, 1, "tea test"},
+       //{"valid",     CmdteaSelfTest, 1, "tea test"},
        {NULL, NULL, 0, NULL}
 };
 
        {NULL, NULL, 0, NULL}
 };
 
index a45b74341ced2cd82a733472f7abd4939fc29744..873e2d511c9b980cfe72af86de44816f2547b324 100644 (file)
 #ifndef CMDHF14B_H__
 #define CMDHF14B_H__
 
 #ifndef CMDHF14B_H__
 #define CMDHF14B_H__
 
+#include "iso14443crc.h"
+#include "proxmark3.h"
+#include "data.h"
+#include "graph.h"
+#include "util.h"
+#include "ui.h"
+#include "cmdparser.h"
+#include "cmdmain.h"
+#include "cmdhf14a.h"
+#include "tea.h"
+#include "cmdhf.h"
+#include "prng.h"
+#include "sha1.h"
+#include "mifare.h"            // structs/enum for ISO14B
+#include "protocols.h" // definitions of ISO14B protocol
+
+
+int usage_hf_14b_info(void);
+int usage_hf_14b_reader(void);
+int usage_hf_14b_raw(void);
+int usage_hf_14b_snoop(void);
+int usage_hf_14b_sim(void);
+int usage_hf_14b_read_srx(void);
+int usage_hf_14b_write_srx(void);
+
 int CmdHF14B(const char *Cmd);
 int CmdHF14BList(const char *Cmd);
 int CmdHF14BInfo(const char *Cmd);
 int CmdHF14BSim(const char *Cmd);
 int CmdHF14BSnoop(const char *Cmd);
 int CmdHF14B(const char *Cmd);
 int CmdHF14BList(const char *Cmd);
 int CmdHF14BInfo(const char *Cmd);
 int CmdHF14BSim(const char *Cmd);
 int CmdHF14BSnoop(const char *Cmd);
-int CmdSri512Read(const char *Cmd);
-int CmdSrix4kRead(const char *Cmd);
 int CmdHF14BWrite( const char *cmd);
 int CmdHF14BWrite( const char *cmd);
-int HF14BInfo(bool verbose);
+int CmdHF14BReader(const char *Cmd);
+
+bool HF14BInfo(bool verbose);
+bool HF14BReader(bool verbose);
+int CmdHF14BCmdRaw (const char *Cmd);
+
+// SRi  ST Microelectronics read/write 
+int CmdHF14BReadSri(const char *Cmd);
+int CmdHF14BWriteSri(const char *Cmd);
 
 
+bool waitCmd(bool verbose);
 #endif
 #endif
index 983842a503c41ff77cc8f60024dd18460ef22b5c..da36bbc8fd3c07e9feca8989a5ab1f15c58a04d1 100644 (file)
@@ -101,8 +101,7 @@ typedef struct {
 
 // For the 13.56 MHz tags
 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693                             0x0300
 
 // For the 13.56 MHz tags
 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693                             0x0300
-#define CMD_READ_SRI512_TAG                                               0x0303
-#define CMD_READ_SRIX4K_TAG                                               0x0304
+#define CMD_READ_SRI_TAG                                                         0x0303
 #define CMD_ISO_14443B_COMMAND                                            0x0305
 #define CMD_READER_ISO_15693                                              0x0310
 #define CMD_SIMTAG_ISO_15693                                              0x0311
 #define CMD_ISO_14443B_COMMAND                                            0x0305
 #define CMD_READER_ISO_15693                                              0x0310
 #define CMD_SIMTAG_ISO_15693                                              0x0311
index c9488e312e4bef4bc303950e070b99d8cf49f5c3..afdba7e701a03d14e4fcc2a87452cf5ee3f079c9 100644 (file)
@@ -67,8 +67,7 @@ local _commands = {
 
        --// For the 13.56 MHz tags
        CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 =                              0x0300,
 
        --// For the 13.56 MHz tags
        CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 =                              0x0300,
-       CMD_READ_SRI512_TAG =                                                0x0303,
-       CMD_READ_SRIX4K_TAG =                                                0x0304,
+       CMD_READ_SRI_TAG =                                                   0x0303,
        CMD_ISO_14443B_COMMAND =                                                                                         0x0305,
        CMD_READER_ISO_15693 =                                               0x0310,
        CMD_SIMTAG_ISO_15693 =                                               0x0311,
        CMD_ISO_14443B_COMMAND =                                                                                         0x0305,
        CMD_READER_ISO_15693 =                                               0x0310,
        CMD_SIMTAG_ISO_15693 =                                               0x0311,
@@ -238,6 +237,6 @@ function Command:getBytes()
        local data  = self.data
        local cmd = self.cmd 
        local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
        local data  = self.data
        local cmd = self.cmd 
        local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
-       return bin.pack("LLLLH",cmd, arg1, arg2, arg3, data);
+       return bin.pack("LLLLH", cmd, arg1, arg2, arg3, data);
 end
 return _commands
 end
 return _commands
index 49e3d0e7fe92c222c9c6f72b1dd45c0ded0415a8..70d4f97848751d3b34243df5eea68ad226e9c654 100644 (file)
@@ -1,4 +1,3 @@
-
 --[[
        This is a library to read 14443b tags. It can be used something like this
 
 --[[
        This is a library to read 14443b tags. It can be used something like this
 
 -- Loads the commands-library
 local cmds = require('commands')
 local utils = require('utils')
 -- Loads the commands-library
 local cmds = require('commands')
 local utils = require('utils')
-local TIMEOUT = 10000 -- Shouldn't take longer than 2 seconds
+local TIMEOUT = 4000
+local ISO14B_COMMAND = {
+       ISO14B_CONNECT = 1,
+       ISO14B_DISCONNECT = 2,
+       ISO14B_APDU = 4,
+       ISO14B_RAW = 8,
+       ISO14B_REQUEST_TRIGGER = 0x10,
+       ISO14B_APPEND_CRC = 0x20,
+       ISO14B_SELECT_STD = 0x40,
+       ISO14B_SELECT_SR = 0x80,
+}
 
 
-local function parse1443b_reqb(data)
+local function parse1443b(data)
        --[[
        --[[
-       --]]
-       local pcb = data:sub(1,2)
-       local uid = data:sub(3,10)
-       local pps = data:sub(11,18)
-       local ats = data:sub(19,24)
-       local crc = data:sub(25,29)
-       return { pcb = pcb, uid = uid, pps = pps, ats = ats, crc = crc, cid = '' }
-end
+       
+       Based on this struct : 
+       
+       typedef struct {
+               byte_t uid[10];
+               byte_t uidlen;
+               byte_t atqb[7];
+               byte_t chipid;
+               byte_t cid;
+       } __attribute__((__packed__)) iso14b_card_select_t;
 
 
-local function parse1443b_attrib(data)
-       --[[
        --]]
        --]]
-       local attrib = data:sub(1,2)
-       local crc = data:sub(3,7)
-       return { attrib = attrib, crc = crc }
+       
+       local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data)
+       uid = uid:sub(1,2*uidlen)
+       return { uid = uid, uidlen = uidlen, atqb = atqb, chipid = chipid, cid = cid }
 end
 
 end
 
-
 --- Sends a USBpacket to the device
 -- @param command - the usb packet to send
 --- Sends a USBpacket to the device
 -- @param command - the usb packet to send
--- @param readresponse - if set to true, we read the device answer packet 
+-- @param ignoreresponse - if set to true, we don't read the device answer packet 
 --             which is usually recipe for fail. If not sent, the host will wait 2s for a 
 --             response of type CMD_ACK
 -- @return     packet,nil if successfull
 --                     nil, errormessage if unsuccessfull
 --             which is usually recipe for fail. If not sent, the host will wait 2s for a 
 --             response of type CMD_ACK
 -- @return     packet,nil if successfull
 --                     nil, errormessage if unsuccessfull
-local function sendToDevice(cmd, readresponse)
-       core.clearCommandBuffer()
+local function sendToDevice(cmd, ignoreresponse)
+       --core.clearCommandBuffer()
+       local bytes = cmd:getBytes()
+       local count,c,arg0,arg1,arg2 = bin.unpack('LLLL',bytes)
        local err = core.SendCommand(cmd:getBytes())
        if err then
        local err = core.SendCommand(cmd:getBytes())
        if err then
-               print(err)
+               print('ERROR',err)
                return nil, err
        end
                return nil, err
        end
-       if readresponse == 0 then return '',nil end
+       if ignoreresponse then return nil,nil end
+       
        local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
        local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
-       if response == nil then return nil, nil end
        return response,nil
 end
 --- Picks out and displays the data read from a tag
        return response,nil
 end
 --- Picks out and displays the data read from a tag
@@ -63,133 +74,63 @@ end
 -- @param usbpacket the data received from the device
 local function showData(usbpacket)
        local response = Command.parse(usbpacket)
 -- @param usbpacket the data received from the device
 local function showData(usbpacket)
        local response = Command.parse(usbpacket)
-       local len = tonumber(response.arg1) * 2
+       local len = response.arg2 * 2
        local data = string.sub(response.data, 0, len);
        print("<< ",data)
 end
 
        local data = string.sub(response.data, 0, len);
        print("<< ",data)
 end
 
----
--- Sends a usbpackage ,  "hf 14b raw" and the 14bCrc is added to the rawdata before sending
-local function sendRaw(rawdata, readresponse, addcrc)
-       -- add crc first
-       local rawdata_crc = rawdata
-       if ( addcrc == 1) then 
-               rawdata_crc = utils.Crc14b(rawdata)     
-       end
-       print(">> ", rawdata_crc)
-       
-       local command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, 
-                                                               arg1 = #rawdata_crc/2,  -- LEN of data, which is half the length of the ASCII-string rawdata
-                                                               arg2 = readresponse,    -- read response
-                                                               arg3 = 1,                               -- leave power on
-                                                               data = rawdata_crc}             -- raw data bytes 
-       return sendToDevice(command, readresponse) 
-end
 
 -- This function does a connect and retrieves some info
 -- @return if successfull: an table containing card info
 -- @return if unsuccessfull : nil, error
 
 -- This function does a connect and retrieves some info
 -- @return if successfull: an table containing card info
 -- @return if unsuccessfull : nil, error
+local function read14443b(disconnect)
 
 
--- void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, uint8_t data[])
-local function select1443b()
+       local command, result, info, err, data
 
 
-       local result, infoReqb, infoAttrib, infoPong, err, resp, len, data
-       local goodReqbResponse = false
-       --REQB
-       local p = 20
-       while p > 0 do
-               -- 05 00 08
-               -- 05
-               --   command (REQB/WUPB)
-               -- 00
-               --   AFI application family identifier  ( 00 == all sorts)
-               -- 08  (ie WUPB)
-               --   bit 0-1-2   | N slots  ( 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 == 16)
-               --   bit 3               | (1== WUPB, 0 == REQB)  
-               --   bit 4-5-6-7 | AFI application family identifier
-               local result, err = sendRaw('050008', 1, 1)
-               if result then
-                       resp = Command.parse( result )
-                       len = tonumber(resp.arg1) * 2
-                       local data = string.sub(resp.data, 0, len)
-                       if ( resp.arg1 == 14 ) then
-                               --print ('DATA ::', data)
-                               infoReqb, err = parse1443b_reqb(data)
-                               --print(infoReqb.pcb, infoReqb.uid, infoReqb.pps, infoReqb.ats, infoReqb.crc)
-                               goodReqbResponse = true
-                               break -- break while loop. REQB got a good response
-                       end
-               end
-               
-               -- send some strange 0A/0C
-               -- if ( p < 3) then
-                       -- sendRaw('0A', 0, 0)
-                       -- sendRaw('0C', 0, 0)
-               -- end
-               
-               p = p - 1
-               print('retrying')
+       local flags = ISO14B_COMMAND.ISO14B_CONNECT + 
+                                 ISO14B_COMMAND.ISO14B_SELECT_STD
+       
+       if disconnect then
+               print('DISCONNECT')
+               flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT
        end
 
        end
 
-       if goodReqbResponse == false then 
-               err = "No response from card"
-               print(err) 
-               return nil, err 
-       end
-       --SLOT MARKER
-       -- result, err = sendRaw('05', 1, 1)
-       -- if result then
-               -- showData(result)
-               -- resp = Command.parse( result )
-               -- if arg1 == 0 then 
-                       -- return nil, "iso14443b card - SLOT MARKER failed"
-               -- end
-               -- len = tonumber(resp.arg1) * 2
-               -- data = string.sub(resp.data, 0, len)
-               -- infoAttrib, err = parse1443b_attrib(data)
-               -- print( infoAttrib.attrib, infoAttrib.crc)            
-       -- else
-               -- err ="No response from card"
-               -- print(err) 
-               -- return nil, err
-       -- end
-       
-       --ATTRIB
-       local cid = '00'
-       result, err = sendRaw('1D'..infoReqb.uid..'000801'..cid, 1, 1)
+       command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
+       local result,err = sendToDevice(command, false) 
        if result then
        if result then
-               showData(result)
-               resp = Command.parse( result )
-               if resp.arg1 == 0 then 
-                       return nil, "iso14443b card - ATTRIB failed"
+               local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
+               if arg0 == 0 then 
+                       data = string.sub(result, count)
+                       info, err = parse1443b(data)
+               else
+                       err = "iso14443b card select failed"
                end
                end
-               len = tonumber(resp.arg1) * 2
-               data = string.sub(resp.data, 0, len)
-               infoAttrib, err = parse1443b_attrib(data)
-               infoReqb.cid = infoAttrib.attrib:sub(2,2)
-       else
-               err ="No response from card"
-               print(err) 
-               return nil, err
-       end
-       
-       --PING / PONG - Custom Anticollison for Navigo.
-       local ping = ('BA00')
-       result, err = sendRaw(ping, 1, 1)
-       if result then
-               resp = Command.parse( result )
-               if arg1 == 0 then 
-                       return nil, "iso14443b card - PING/PONG failed"
-               end             
-               showData(result)
        else
                err = "No response from card"
        else
                err = "No response from card"
+       end
+
+       if err then 
                print(err) 
                return nil, err
        end
                print(err) 
                return nil, err
        end
-
-       return infoReqb
+       return info
 end
 end
+--PING / PONG - Custom Anticollison for Navigo.
+-- AA / BB ?!?
+-- local ping = ('BA00')
+-- result, err = sendRaw(ping, 1, 1)
+-- if result then
+       -- resp = Command.parse( result )
+       -- if arg1 == 0 then 
+               -- return nil, "iso14443b card - PING/PONG failed"
+       -- end          
+       -- showData(result)
+-- else
+       -- err = "No response from card"
+       -- print(err) 
+       -- return nil, err
+-- end
+
 
 ---
 -- Waits for a mifare card to be placed within the vicinity of the reader. 
 
 ---
 -- Waits for a mifare card to be placed within the vicinity of the reader. 
@@ -198,42 +139,20 @@ end
 local function waitFor14443b()
        print("Waiting for card... press any key to quit")
        while not core.ukbhit() do
 local function waitFor14443b()
        print("Waiting for card... press any key to quit")
        while not core.ukbhit() do
-               res, err = select1443b()
+               res, err = read14443b(false)
                if res then return res end
                if res then return res end
-               if res == nil then return nil, err end
                -- err means that there was no response from card
        end
        return nil, "Aborted by user"
 end
 
                -- err means that there was no response from card
        end
        return nil, "Aborted by user"
 end
 
-local function disconnect(uid)
-
-       local halt = ('50'..uid) -- 50 UID0 UID1 UID2 UID3 CRC1 CRC2
-       result, err = sendRaw(halt, 1, 1)
-       if result then
-               resp = Command.parse( result )
-               showData(result)  -- expected answer is 00 CRC1 CRC2
-       else
-               err = "No response from card"
-               print(err) 
-               return nil, err
-       end
-
-       -- shutdown raw command / pm3 device.
-       local command = Command:new{ cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = 0, arg2 = 0, arg3 = 0 }
-       -- We can ignore the response here, no ACK is returned for this command
-       -- Check /armsrc/iso14443b.c, SendRawCommand14443B() for details
-       return sendToDevice(command, 0) 
-end
-
 local library = {
 local library = {
-       select1443b = select1443b,
-       select  = select1443b,
+       parse1443b  = parse1443b,
+       read1443b       = read14443b,
        waitFor14443b = waitFor14443b,
        sendToDevice = sendToDevice,
        waitFor14443b = waitFor14443b,
        sendToDevice = sendToDevice,
-       disconnect = disconnect,
-       sendRaw = sendRaw,
        showData = showData,
        showData = showData,
+       ISO14B_COMMAND = ISO14B_COMMAND,
 }
 
 return library
\ No newline at end of file
 }
 
 return library
\ No newline at end of file
index 70188ca93dc45d296b40cc8df37479745812d5ff..3d063351059e81d8f9ccbe5c3ab23239c210a20f 100644 (file)
@@ -31,5 +31,4 @@ typedef unsigned char byte_t;
 #endif
 
 #define RAMFUNC __attribute((long_call, section(".ramfunc")))
 #endif
 
 #define RAMFUNC __attribute((long_call, section(".ramfunc")))
-
 #endif
 #endif
index ad86886dbc0b69afc29ce453b08ec94be5cd23fb..f6626328217d75f3ee20a2f7a6bd24d61881be80 100644 (file)
@@ -37,4 +37,29 @@ typedef enum ISO14A_COMMAND {
        ISO14A_TOPAZMODE =                      (1 << 8)
 } iso14a_command_t;
 
        ISO14A_TOPAZMODE =                      (1 << 8)
 } iso14a_command_t;
 
+
+//-----------------------------------------------------------------------------
+// ISO 14443B
+//-----------------------------------------------------------------------------
+typedef struct {
+       byte_t uid[10];
+       byte_t uidlen;
+       byte_t atqb[7];
+       byte_t chipid;
+       byte_t cid;
+} __attribute__((__packed__)) iso14b_card_select_t;
+
+
+typedef enum ISO14B_COMMAND {
+       ISO14B_CONNECT =                        (1 << 0),
+       ISO14B_DISCONNECT =                     (1 << 1),
+       ISO14B_APDU =                           (1 << 2),
+       ISO14B_RAW =                            (1 << 3),
+       ISO14B_REQUEST_TRIGGER =        (1 << 4),
+       ISO14B_APPEND_CRC =                     (1 << 5),
+       ISO14B_SELECT_STD =                     (1 << 6),
+       ISO14B_SELECT_SR =                      (1 << 7)
+} iso14b_command_t;
+
+
 #endif // _MIFARE_H_
 #endif // _MIFARE_H_
index 8d6dd9524124922d768e9767adc77ec1c1f66dc6..2fd00ad93e58366a4065698fcbca83b3bd200504 100644 (file)
@@ -109,8 +109,7 @@ typedef struct{
 
 // For the 13.56 MHz tags
 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693                             0x0300
 
 // For the 13.56 MHz tags
 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693                             0x0300
-#define CMD_READ_SRI512_TAG                                               0x0303
-#define CMD_READ_SRIX4K_TAG                                               0x0304
+#define CMD_READ_SRI_TAG                                                  0x0303
 #define CMD_ISO_14443B_COMMAND                                            0x0305
 #define CMD_READER_ISO_15693                                              0x0310
 #define CMD_SIMTAG_ISO_15693                                              0x0311
 #define CMD_ISO_14443B_COMMAND                                            0x0305
 #define CMD_READER_ISO_15693                                              0x0310
 #define CMD_SIMTAG_ISO_15693                                              0x0311
Impressum, Datenschutz