]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/appmain.c
Merge pull request #130 from VERTCraig/StandAlone14a
[proxmark3-svn] / armsrc / appmain.c
index 3e670f0be9ef004f8cbf668074f14a7b2b479623..ddfe001c27dc97966eb27cf077a13eac52762e88 100644 (file)
  #include "LCD.h"
 #endif
 
  #include "LCD.h"
 #endif
 
+// Craig Young - 14a stand-alone code
+#ifdef WITH_ISO14443a_StandAlone
+ #include "iso14443a.h"
+#endif
+
 #define abs(x) ( ((x)<0) ? -(x) : (x) )
 
 //=============================================================================
 #define abs(x) ( ((x)<0) ? -(x) : (x) )
 
 //=============================================================================
@@ -250,55 +255,6 @@ void MeasureAntennaTuningHf(void)
 }
 
 
 }
 
 
-void SimulateTagHfListen(void)
-{
-       // ToDo: historically this used the free buffer, which was 2744 Bytes long. 
-       // There might be a better size to be defined:
-       #define HF_14B_SNOOP_BUFFER_SIZE 2744
-       uint8_t *dest = BigBuf_malloc(HF_14B_SNOOP_BUFFER_SIZE);
-       uint8_t v = 0;
-       int i;
-       int p = 0;
-
-       // We're using this mode just so that I can test it out; the simulated
-       // tag mode would work just as well and be simpler.
-       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);
-
-       // We need to listen to the high-frequency, peak-detected path.
-       SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-
-       FpgaSetupSsc();
-
-       i = 0;
-       for(;;) {
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                       AT91C_BASE_SSC->SSC_THR = 0xff;
-               }
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       uint8_t r = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-
-                       v <<= 1;
-                       if(r & 1) {
-                               v |= 1;
-                       }
-                       p++;
-
-                       if(p >= 8) {
-                               dest[i] = v;
-                               v = 0;
-                               p = 0;
-                               i++;
-
-                               if(i >= HF_14B_SNOOP_BUFFER_SIZE) {
-                                       break;
-                               }
-                       }
-               }
-       }
-       DbpString("simulate tag (now type bitsamples)");
-}
-
 void ReadMem(int addr)
 {
        const uint8_t *data = ((uint8_t *)addr);
 void ReadMem(int addr)
 {
        const uint8_t *data = ((uint8_t *)addr);
@@ -310,11 +266,11 @@ void ReadMem(int addr)
 /* osimage version information is linked in */
 extern struct version_information version_information;
 /* bootrom version information is pointed to from _bootphase1_version_pointer */
 /* osimage version information is linked in */
 extern struct version_information version_information;
 /* bootrom version information is pointed to from _bootphase1_version_pointer */
-extern char *_bootphase1_version_pointer, _flash_start, _flash_end;
+extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
 void SendVersion(void)
 {
 void SendVersion(void)
 {
-       char temp[512]; /* Limited data payload in USB packets */
-       DbpString("Prox/RFID mark3 RFID instrument");
+       char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
+       char VersionString[USB_CMD_DATA_SIZE] = { '\0' };
 
        /* Try to find the bootrom version information. Expect to find a pointer at
         * symbol _bootphase1_version_pointer, perform slight sanity checks on the
 
        /* Try to find the bootrom version information. Expect to find a pointer at
         * symbol _bootphase1_version_pointer, perform slight sanity checks on the
@@ -322,22 +278,28 @@ void SendVersion(void)
         */
        char *bootrom_version = *(char**)&_bootphase1_version_pointer;
        if( bootrom_version < &_flash_start || bootrom_version >= &_flash_end ) {
         */
        char *bootrom_version = *(char**)&_bootphase1_version_pointer;
        if( bootrom_version < &_flash_start || bootrom_version >= &_flash_end ) {
-               DbpString("bootrom version information appears invalid");
+               strcat(VersionString, "bootrom version information appears invalid\n");
        } else {
                FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
        } else {
                FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
-               DbpString(temp);
+               strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
        }
 
        FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
        }
 
        FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
-       DbpString(temp);
+       strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
+
+       FpgaGatherVersion(FPGA_BITSTREAM_LF, temp, sizeof(temp));
+       strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
+       FpgaGatherVersion(FPGA_BITSTREAM_HF, temp, sizeof(temp));
+       strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
 
 
-       FpgaGatherVersion(temp, sizeof(temp));
-       DbpString(temp);
-       // Send Chip ID
-       cmd_send(CMD_ACK,*(AT91C_DBGU_CIDR),0,0,NULL,0);
+       // Send Chip ID and used flash memory
+       uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start;
+       uint32_t compressed_data_section_size = common_area.arg1;
+       cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString));
 }
 
 #ifdef WITH_LF
 }
 
 #ifdef WITH_LF
+#ifndef WITH_ISO14443a_StandAlone
 // samy's sniff and repeat routine
 void SamyRun()
 {
 // samy's sniff and repeat routine
 void SamyRun()
 {
@@ -484,7 +446,219 @@ void SamyRun()
        }
 }
 #endif
        }
 }
 #endif
+#endif
+#ifdef WITH_ISO14443a
+#ifdef WITH_ISO14443a_StandAlone
+void StandAloneMode14a()
+{
+       DbpString("Stand-alone mode! No PC necessary.");
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+
+       // 3 possible options? no just 1 for now
+#undef OPTS
+#define OPTS 2
+       // Oooh pretty -- notify user we're in elite samy mode now
+       LED(LED_RED,    200);
+       LED(LED_ORANGE, 200);
+       LED(LED_GREEN,  200);
+       LED(LED_ORANGE, 200);
+       LED(LED_RED,    200);
+       LED(LED_ORANGE, 200);
+       LED(LED_GREEN,  200);
+       LED(LED_ORANGE, 200);
+       LED(LED_RED,    200);
+
+       int selected = 0;
+       int playing = 0;
+       int cardRead[OPTS] = {0};
+       uint8_t readUID[10] = {0};
+       int uid_1st[OPTS]={0};
+       int uid_2nd[OPTS]={0};
+
+       LED(selected + 1, 0);
+
+       for (;;)
+       {
+               usb_poll();
+    WDT_HIT();
+
+               // Was our button held down or pressed?
+               int button_pressed = BUTTON_HELD(1000);
+
+               SpinDelay(300);
+
+               // Button was held for a second, begin recording
+               if (button_pressed > 0 && cardRead[selected] == 0)
+               {
+                       LEDsoff();
+                       LED(selected + 1, 0);
+                       LED(LED_RED2, 0);
+
+                       // record
+                       Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
+
+                       // wait for button to be released
+                       while(BUTTON_PRESS())
+                               WDT_HIT();
+                       /* need this delay to prevent catching some weird data */
+                       SpinDelay(500);
+                       /* Code for reading from 14a tag */
+                       uint8_t uid[10]  ={0};
+                       uint32_t cuid;
+                       iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
+
+                       for ( ; ; )
+                       {
+                               if (!iso14443a_select_card(uid, NULL, &cuid))
+                                       continue;
+                               else
+                               {
+                                       Dbprintf("Read UID:"); Dbhexdump(10,uid,0);
+                                       memcpy(readUID,uid,10*sizeof(uint8_t));
+                                       uint8_t *dst = (uint8_t *)&uid_1st[selected];
+                                       // Set UID byte order 
+                                       for (int i=0; i<4; i++)
+                                               dst[i] = uid[3-i];
+                                       dst = (uint8_t *)&uid_2nd[selected];
+                                       for (int i=0; i<4; i++)
+                                               dst[i] = uid[7-i];
+                                       break;
+                               }
+                       } 
+                       LEDsoff();
+                        LED(LED_GREEN,  200);
+                        LED(LED_ORANGE, 200);
+                        LED(LED_GREEN,  200);
+                        LED(LED_ORANGE, 200);
+                       
+                       LEDsoff();
+                       LED(selected + 1, 0);
+                       // Finished recording
+
+                       // If we were previously playing, set playing off
+                       // so next button push begins playing what we recorded
+                       playing = 0;
+                       
+                       cardRead[selected] = 1;
+       
+               }
+/* MF UID clone */
+               else if (button_pressed > 0 && cardRead[selected] == 1)
+               {
+                                       LEDsoff();
+                                       LED(selected + 1, 0);
+                                       LED(LED_ORANGE, 250);
+
+
+                                       // record
+                                       Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
 
 
+                                       // wait for button to be released
+                                       while(BUTTON_PRESS())
+                                               { 
+                                               // Delay cloning until card is in place
+                                               WDT_HIT();
+                                               }
+                                       Dbprintf("Starting clone. [Bank: %u]", selected);
+                                       // need this delay to prevent catching some weird data
+                                       SpinDelay(500);
+                                       // Begin clone function here:
+                                       /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
+                                                       UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
+                                               memcpy(c.d.asBytes, data, 16);
+                                               SendCommand(&c);
+
+                                       Block read is similar:
+                                               UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
+                                       We need to imitate that call with blockNo 0 to set a uid.
+
+                                       The get and set commands are handled in this file:
+                                               // Work with "magic Chinese" card
+                                       case CMD_MIFARE_CSETBLOCK:
+                                               MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                                               break;
+                                       case CMD_MIFARE_CGETBLOCK:
+                                               MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                                                                               // 
+                                               break;  
+
+                                               mfCSetUID provides example logic for UID set workflow:
+                                                       -Read block0 from card in field with MifareCGetBlock()
+                                                       -Configure new values without replacing reserved bytes
+                                                               memcpy(block0, uid, 4); // Copy UID bytes from byte array
+                                                               // Mifare UID BCC
+                                                               block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
+                                                               Bytes 5-7 are reserved SAK and ATQA for mifare classic
+                                               -Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
+                               */
+                               uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
+                               // arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo 
+                               MifareCGetBlock(0x1F, 1, 0, oldBlock0);
+                               Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
+                               memcpy(newBlock0,oldBlock0,16);
+                               // Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
+                               newBlock0[0] = uid_1st[selected]>>24;
+                               newBlock0[1] = 0xFF & (uid_1st[selected]>>16);
+                               newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
+                               newBlock0[3] = 0xFF & (uid_1st[selected]);
+                               newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
+                               // arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
+                               MifareCSetBlock(0, 0xFF,0, newBlock0);
+                               MifareCGetBlock(0x1F, 1, 0, testBlock0);
+                               if (memcmp(testBlock0,newBlock0,16)==0)
+                               {
+                                       DbpString("Cloned successfull!");
+                                       cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
+                               }
+                                       LEDsoff();
+                                       LED(selected + 1, 0);
+                                       // Finished recording
+
+                                       // If we were previously playing, set playing off
+                                       // so next button push begins playing what we recorded
+                                       playing = 0;
+                       
+               }
+               // Change where to record (or begin playing)
+               else if (button_pressed && cardRead[selected])
+               {
+                       // Next option if we were previously playing
+                       if (playing)
+                               selected = (selected + 1) % OPTS;
+                       playing = !playing;
+
+                       LEDsoff();
+                       LED(selected + 1, 0);
+
+                       // Begin transmitting
+                       if (playing)
+                       {
+                               LED(LED_GREEN, 0);
+                               DbpString("Playing");
+                   while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec
+                           Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected);
+                                       SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL);       
+                                       }
+                               //cardRead[selected] = 1; 
+                               Dbprintf("Done playing [Bank: %u]",selected);
+
+                               /* We pressed a button so ignore it here with a delay */
+                               SpinDelay(300);
+
+                               // when done, we're done playing, move to next option
+                               selected = (selected + 1) % OPTS;
+                               playing = !playing;
+                               LEDsoff();
+                               LED(selected + 1, 0);
+                       }
+                       else 
+                               while(BUTTON_PRESS())
+                                       WDT_HIT();
+               }
+       }
+}
+#endif
+#endif
 /*
 OBJECTIVE
 Listen and detect an external reader. Determine the best location
 /*
 OBJECTIVE
 Listen and detect an external reader. Determine the best location
@@ -648,7 +822,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        setSamplingConfig((sample_config *) c->d.asBytes);
                        break;
                case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
                        setSamplingConfig((sample_config *) c->d.asBytes);
                        break;
                case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
-                       cmd_send(CMD_ACK,SampleLF(),0,0,0,0);
+                       cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0);
                        break;
                case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
                        ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
                        break;
                case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
                        ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
@@ -711,6 +885,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
                case CMD_T55XX_WRITE_BLOCK:
                        T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
                        break;
                case CMD_T55XX_WRITE_BLOCK:
                        T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
+                       cmd_send(CMD_ACK,0,0,0,0,0);
                        break;
                case CMD_T55XX_READ_TRACE:
                        T55xxReadTrace();
                        break;
                case CMD_T55XX_READ_TRACE:
                        T55xxReadTrace();
@@ -725,6 +900,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_EM4X_WRITE_WORD:
                        EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
                        break;
                case CMD_EM4X_WRITE_WORD:
                        EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
                        break;
+               case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
+                       CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
+                        break;
 #endif
 
 #ifdef WITH_HITAG
 #endif
 
 #ifdef WITH_HITAG
@@ -738,7 +916,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
                        break;
 #endif
                        ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
                        break;
 #endif
-            
+
 #ifdef WITH_ISO15693
                case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
                        AcquireRawAdcSamplesIso15693();
 #ifdef WITH_ISO15693
                case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
                        AcquireRawAdcSamplesIso15693();
@@ -782,20 +960,17 @@ void UsbPacketReceived(uint8_t *packet, int len)
 #endif
 
 #ifdef WITH_ISO14443b
 #endif
 
 #ifdef WITH_ISO14443b
-               case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
-                       AcquireRawAdcSamplesIso14443(c->arg[0]);
-                       break;
                case CMD_READ_SRI512_TAG:
                case CMD_READ_SRI512_TAG:
-                       ReadSTMemoryIso14443(0x0F);
+                       ReadSTMemoryIso14443b(0x0F);
                        break;
                case CMD_READ_SRIX4K_TAG:
                        break;
                case CMD_READ_SRIX4K_TAG:
-                       ReadSTMemoryIso14443(0x7F);
+                       ReadSTMemoryIso14443b(0x7F);
                        break;
                        break;
-               case CMD_SNOOP_ISO_14443:
-                       SnoopIso14443();
+               case CMD_SNOOP_ISO_14443B:
+                       SnoopIso14443b();
                        break;
                        break;
-               case CMD_SIMULATE_TAG_ISO_14443:
-                       SimulateIso14443Tag();
+               case CMD_SIMULATE_TAG_ISO_14443B:
+                       SimulateIso14443bTag();
                        break;
                case CMD_ISO_14443B_COMMAND:
                        SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
                        break;
                case CMD_ISO_14443B_COMMAND:
                        SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
@@ -816,27 +991,27 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_EPA_PACE_COLLECT_NONCE:
                        EPA_PACE_Collect_Nonce(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:
                        
                case CMD_READER_MIFARE:
-            ReaderMifare(c->arg[0]);
+                       ReaderMifare(c->arg[0]);
                        break;
                case CMD_MIFARE_READBL:
                        MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFAREU_READBL:
                        break;
                case CMD_MIFARE_READBL:
                        MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFAREU_READBL:
-                       MifareUReadBlock(c->arg[0],c->d.asBytes);
+                       MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
                        break;
                        break;
-               case CMD_MIFAREUC_AUTH1:
-                       MifareUC_Auth1(c->arg[0],c->d.asBytes);
-                       break;
-               case CMD_MIFAREUC_AUTH2:
-                       MifareUC_Auth2(c->arg[0],c->d.asBytes);
+               case CMD_MIFAREUC_AUTH:
+                       MifareUC_Auth(c->arg[0],c->d.asBytes);
                        break;
                case CMD_MIFAREU_READCARD:
                        break;
                case CMD_MIFAREU_READCARD:
-                       MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
+                       MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                        break;
-               case CMD_MIFAREUC_READCARD:
-                       MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
+               case CMD_MIFAREUC_SETPWD: 
+                       MifareUSetPwd(c->arg[0], c->d.asBytes);
                        break;
                case CMD_MIFARE_READSC:
                        MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFARE_READSC:
                        MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
@@ -844,12 +1019,12 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_MIFARE_WRITEBL:
                        MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFARE_WRITEBL:
                        MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
-               case CMD_MIFAREU_WRITEBL_COMPAT:
-                       MifareUWriteBlock(c->arg[0], c->d.asBytes);
-                        break;
+               //case CMD_MIFAREU_WRITEBL_COMPAT:
+                       //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes);
+                       //break;
                case CMD_MIFAREU_WRITEBL:
                case CMD_MIFAREU_WRITEBL:
-                        MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
-                        break;
+                       MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
+                       break;
                case CMD_MIFARE_NESTED:
                        MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFARE_NESTED:
                        MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
@@ -914,10 +1089,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
 #endif
 
                        break;
 #endif
 
-               case CMD_SIMULATE_TAG_HF_LISTEN:
-                       SimulateTagHfListen();
-                       break;
-
                case CMD_BUFF_CLEAR:
                        BigBuf_Clear();
                        break;
                case CMD_BUFF_CLEAR:
                        BigBuf_Clear();
                        break;
@@ -1079,8 +1250,16 @@ void  __attribute__((noreturn)) AppMain(void)
                WDT_HIT();
 
 #ifdef WITH_LF
                WDT_HIT();
 
 #ifdef WITH_LF
+#ifndef WITH_ISO14443a_StandAlone
                if (BUTTON_HELD(1000) > 0)
                        SamyRun();
                if (BUTTON_HELD(1000) > 0)
                        SamyRun();
+#endif
+#endif
+#ifdef WITH_ISO14443a
+#ifdef WITH_ISO14443a_StandAlone
+               if (BUTTON_HELD(1000) > 0)
+                       StandAloneMode14a();
+#endif
 #endif
        }
 }
 #endif
        }
 }
Impressum, Datenschutz