Merge pull request #2616 from jmichelp/fix14b
[RRG-proxmark3.git] / armsrc / appmain.c
blob96cf50d314b315b563487c2c2fe61142aac81e5d
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Jonathan Westhues, Mar 2006
3 // Copyright (C) Gerhard de Koning Gans, Sep 2007
4 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // See LICENSE.txt for the text of the license.
17 //-----------------------------------------------------------------------------
18 // The main application code. This is the first thing called after start.c
19 // executes.
20 //-----------------------------------------------------------------------------
21 #include "appmain.h"
23 #include "clocks.h"
24 #include "usb_cdc.h"
25 #include "proxmark3_arm.h"
26 #include "dbprint.h"
27 #include "pmflash.h"
28 #include "fpga.h"
29 #include "fpgaloader.h"
30 #include "string.h"
31 #include "printf.h"
32 #include "legicrf.h"
33 #include "BigBuf.h"
34 #include "iclass_cmd.h"
35 #include "hfops.h"
36 #include "iso14443a.h"
37 #include "iso14443b.h"
38 #include "iso15693.h"
39 #include "thinfilm.h"
40 #include "felica.h"
41 #include "hitag2.h"
42 #include "hitag2_crack.h"
43 #include "hitagS.h"
44 #include "em4x50.h"
45 #include "em4x70.h"
46 #include "iclass.h"
47 #include "legicrfsim.h"
48 //#include "cryptorfsim.h"
49 #include "epa.h"
50 #include "hfsnoop.h"
51 #include "lfops.h"
52 #include "lfsampling.h"
53 #include "lfzx.h"
54 #include "mifarecmd.h"
55 #include "mifaredesfire.h"
56 #include "mifaresim.h"
57 #include "pcf7931.h"
58 #include "Standalone/standalone.h"
59 #include "util.h"
60 #include "ticks.h"
61 #include "commonutil.h"
62 #include "crc16.h"
63 #include "protocols.h"
64 #include "mifareutil.h"
65 #include "sam_picopass.h"
66 #include "sam_seos.h"
67 #include "sam_mfc.h"
69 #ifdef WITH_LCD
70 #include "LCD_disabled.h"
71 #endif
73 #ifdef WITH_SMARTCARD
74 #include "i2c.h"
75 #endif
77 #ifdef WITH_FPC_USART
78 #include "usart.h"
79 #endif
81 #ifdef WITH_FLASH
82 #include "flashmem.h"
83 #include "spiffs.h"
84 #endif
86 int g_dbglevel = DBG_ERROR;
87 uint8_t g_trigger = 0;
88 bool g_hf_field_active = false;
89 extern uint32_t _stack_start[], _stack_end[];
90 common_area_t g_common_area __attribute__((section(".commonarea")));
91 static int button_status = BUTTON_NO_CLICK;
92 static bool allow_send_wtx = false;
93 uint16_t g_tearoff_delay_us = 0;
94 bool g_tearoff_enabled = false;
96 int tearoff_hook(void) {
97 if (g_tearoff_enabled) {
98 if (g_tearoff_delay_us == 0) {
99 Dbprintf(_RED_("No tear-off delay configured!"));
100 return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
102 SpinDelayUsPrecision(g_tearoff_delay_us);
103 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
104 g_tearoff_enabled = false;
105 Dbprintf(_YELLOW_("Tear-off triggered!"));
106 return PM3_ETEAROFF;
107 } else {
108 return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
112 void hf_field_off(void) {
113 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
114 LEDsoff();
115 g_hf_field_active = false;
118 void send_wtx(uint16_t wtx) {
119 if (allow_send_wtx) {
120 reply_ng(CMD_WTX, PM3_SUCCESS, (uint8_t *)&wtx, sizeof(wtx));
124 //-----------------------------------------------------------------------------
125 // Read an ADC channel and block till it completes, then return the result
126 // in ADC units (0 to 1023). Also a routine to sum up a number of samples and
127 // return that.
128 //-----------------------------------------------------------------------------
129 static uint16_t ReadAdc(uint8_t ch) {
131 // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value.
132 // AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant
133 // of RC = (0.91MOhm) * 12pF = 10.9us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged.
135 // The maths are:
136 // If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be
138 // v_cap = v_in * (1 - exp(-SHTIM/RC)) = v_in * (1 - exp(-40us/10.9us)) = v_in * 0,97 (i.e. an error of 3%)
140 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
141 AT91C_BASE_ADC->ADC_MR =
142 ADC_MODE_PRESCALE(63) // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
143 | ADC_MODE_STARTUP_TIME(1) // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us
144 | ADC_MODE_SAMPLE_HOLD_TIME(15); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us
146 AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch);
147 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
149 while (!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) {};
151 return (AT91C_BASE_ADC->ADC_CDR[ch] & 0x3FF);
154 // was static - merlok
155 uint16_t AvgAdc(uint8_t ch) {
156 return SumAdc(ch, 32) >> 5;
159 uint16_t SumAdc(uint8_t ch, uint8_t NbSamples) {
160 uint16_t a = 0;
161 for (uint8_t i = 0; i < NbSamples; i++)
162 a += ReadAdc(ch);
163 return (a + (NbSamples >> 1) - 1);
165 #ifdef WITH_LF
166 static void MeasureAntennaTuning(void) {
168 uint32_t peak = 0;
170 // in mVolt
171 struct p {
172 uint32_t v_lf134;
173 uint32_t v_lf125;
174 uint32_t v_lfconf;
175 uint32_t v_hf;
176 uint32_t peak_v;
177 uint32_t peak_f;
178 int divisor;
179 uint8_t results[256];
180 } PACKED payload;
182 // Need to clear all values to ensure non-random responses.
183 memset(&payload, 0, sizeof(payload));
184 // memset(payload.results, 0, sizeof(payload.results));
186 sample_config *sc = getSamplingConfig();
187 payload.divisor = sc->divisor;
189 LED_B_ON();
192 * Sweeps the useful LF range of the proxmark from
193 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
194 * read the voltage in the antenna, the result left
195 * in the buffer is a graph which should clearly show
196 * the resonating frequency of your LF antenna
197 * ( hopefully around 95 if it is tuned to 125kHz!)
200 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
201 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD);
202 SpinDelay(50);
204 for (uint8_t i = 255; i >= 19; i--) {
205 WDT_HIT();
206 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
207 SpinDelay(20);
208 uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14);
209 if (i == LF_DIVISOR_125)
210 payload.v_lf125 = adcval; // voltage at 125kHz
212 if (i == LF_DIVISOR_134)
213 payload.v_lf134 = adcval; // voltage at 134kHz
215 if (i == sc->divisor)
216 payload.v_lfconf = adcval; // voltage at `lf config --divisor`
218 payload.results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes
220 if (payload.results[i] > peak) {
221 payload.peak_v = adcval;
222 payload.peak_f = i;
223 peak = payload.results[i];
227 LED_A_ON();
228 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
229 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
230 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
231 SpinDelay(50);
233 payload.v_hf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
235 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
236 reply_ng(CMD_MEASURE_ANTENNA_TUNING, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload));
237 LEDsoff();
239 #endif
240 // Measure HF in milliVolt
241 static uint16_t MeasureAntennaTuningHfData(void) {
243 return (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
247 // Measure LF in milliVolt
248 static uint32_t MeasureAntennaTuningLfData(void) {
249 return (MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14;
252 void print_stack_usage(void) {
253 for (uint32_t *p = _stack_start; ; ++p) {
254 if (*p != 0xdeadbeef) {
255 Dbprintf(" Max stack usage......... %d / %d bytes", (uint32_t)_stack_end - (uint32_t)p, (uint32_t)_stack_end - (uint32_t)_stack_start);
256 break;
261 void ReadMem(int addr) {
262 const uint8_t *data = ((uint8_t *)addr);
264 Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
267 /* osimage version information is linked in, cf commonutil.h */
268 /* bootrom version information is pointed to from _bootphase1_version_pointer */
269 extern uint32_t _bootphase1_version_pointer[], _flash_start[], _flash_end[], __data_src_start__[];
270 #ifndef WITH_COMPRESSION
271 extern uint32_t _bootrom_end[], _bootrom_start[], __os_size__[];
272 #endif
273 static void SendVersion(void) {
274 char temp[PM3_CMD_DATA_SIZE - 12]; /* Limited data payload in USB packets */
275 char VersionString[PM3_CMD_DATA_SIZE - 12] = { '\0' };
277 /* Try to find the bootrom version information. Expect to find a pointer at
278 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
279 * pointer, then use it.
281 // dummy casting to avoid "dereferencing type-punned pointer breaking strict-aliasing rules" errors
282 uint32_t bootrom_version_ptr = (uint32_t)_bootphase1_version_pointer;
283 char *bootrom_version = *(char **)(bootrom_version_ptr);
285 strncat(VersionString, " [ "_YELLOW_("ARM")" ]\n", sizeof(VersionString) - strlen(VersionString) - 1);
287 if ((uint32_t)bootrom_version < (uint32_t)_flash_start || (uint32_t)bootrom_version >= (uint32_t)_flash_end) {
288 strcat(VersionString, "bootrom version information appears invalid\n");
289 } else {
290 FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version);
291 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
292 strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
296 FormatVersionInformation(temp, sizeof(temp), " os: ", &g_version_information);
297 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
298 strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
300 #if defined(__clang__)
301 strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
302 #elif defined(__GNUC__) || defined(__GNUG__)
303 strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
304 #endif
306 strncat(VersionString, "\n [ "_YELLOW_("FPGA")" ] \n ", sizeof(VersionString) - strlen(VersionString) - 1);
308 for (int i = 0; i < g_fpga_bitstream_num; i++) {
309 strncat(VersionString, g_fpga_version_information[i].versionString, sizeof(VersionString) - strlen(VersionString) - 1);
310 if (i < g_fpga_bitstream_num - 1) {
311 strncat(VersionString, "\n ", sizeof(VersionString) - strlen(VersionString) - 1);
314 #ifdef WITH_COMPRESSION
315 // Send Chip ID and used flash memory
316 uint32_t text_and_rodata_section_size = (uint32_t)__data_src_start__ - (uint32_t)_flash_start;
317 uint32_t compressed_data_section_size = g_common_area.arg1;
318 #endif
320 struct p {
321 uint32_t id;
322 uint32_t section_size;
323 uint32_t versionstr_len;
324 char versionstr[PM3_CMD_DATA_SIZE - 12];
325 } PACKED;
327 struct p payload;
328 payload.id = *(AT91C_DBGU_CIDR);
329 #ifndef WITH_COMPRESSION
330 payload.section_size = (uint32_t)_bootrom_end - (uint32_t)_bootrom_start + (uint32_t)__os_size__;
331 #else
332 payload.section_size = text_and_rodata_section_size + compressed_data_section_size;
333 #endif
334 payload.versionstr_len = strlen(VersionString) + 1;
335 memcpy(payload.versionstr, VersionString, payload.versionstr_len);
337 reply_ng(CMD_VERSION, PM3_SUCCESS, (uint8_t *)&payload, 12 + payload.versionstr_len);
340 static void TimingIntervalAcquisition(void) {
341 // trigger new acquisition by turning main oscillator off and on
342 mck_from_pll_to_slck();
343 mck_from_slck_to_pll();
344 // wait for MCFR and recompute RTMR scaler
345 StartTickCount();
348 static void print_debug_level(void) {
349 char dbglvlstr[20] = {0};
350 switch (g_dbglevel) {
351 case DBG_NONE:
352 sprintf(dbglvlstr, "off");
353 break;
354 case DBG_ERROR:
355 sprintf(dbglvlstr, "error");
356 break;
357 case DBG_INFO:
358 sprintf(dbglvlstr, "info");
359 break;
360 case DBG_DEBUG:
361 sprintf(dbglvlstr, "debug");
362 break;
363 case DBG_EXTENDED:
364 sprintf(dbglvlstr, "extended");
365 break;
367 Dbprintf(" Debug log level......... %d ( " _YELLOW_("%s")" )", g_dbglevel, dbglvlstr);
370 // measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
371 // Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the PacketCommandNG structure included.
372 static void printConnSpeed(uint32_t wait) {
373 DbpString(_CYAN_("Transfer Speed"));
374 Dbprintf(" Sending packets to client...");
376 uint8_t *test_data = BigBuf_get_addr();
377 uint32_t start_time = GetTickCount();
378 uint32_t delta_time = 0;
379 uint32_t bytes_transferred = 0;
381 LED_B_ON();
383 while (delta_time < wait) {
384 reply_ng(CMD_DOWNLOADED_BIGBUF, PM3_SUCCESS, test_data, PM3_CMD_DATA_SIZE);
385 bytes_transferred += PM3_CMD_DATA_SIZE;
386 delta_time = GetTickCountDelta(start_time);
388 LED_B_OFF();
390 Dbprintf(" Time elapsed................... %dms", delta_time);
391 Dbprintf(" Bytes transferred.............. %d", bytes_transferred);
392 if (delta_time) {
393 Dbprintf(" Transfer Speed PM3 -> Client... " _YELLOW_("%llu") " bytes/s", 1000 * (uint64_t)bytes_transferred / delta_time);
398 * Prints runtime information about the PM3.
400 static void SendStatus(uint32_t wait) {
401 BigBuf_print_status();
402 Fpga_print_status();
403 #ifdef WITH_FLASH
404 Flashmem_print_status();
405 #endif
406 #ifdef WITH_SMARTCARD
407 I2C_print_status();
408 #endif
409 #ifdef WITH_LF
410 printLFConfig(); // LF Sampling config
411 printT55xxConfig(); // LF T55XX Config
412 #endif
413 #ifdef WITH_ISO14443a
414 printHf14aConfig(); // HF 14a config
415 #endif
416 printConnSpeed(wait);
417 DbpString(_CYAN_("Various"));
419 print_stack_usage();
420 print_debug_level();
422 tosend_t *ts = get_tosend();
423 Dbprintf(" ToSendMax............... %d", ts->max);
424 Dbprintf(" ToSend BUFFERSIZE....... %d", TOSEND_BUFFER_SIZE);
425 while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
426 uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks
427 Dbprintf(" Slow clock.............. %d Hz", (16 * MAINCK) / mainf);
428 uint32_t delta_time = 0;
429 uint32_t start_time = GetTickCount();
430 #define SLCK_CHECK_MS 50
431 SpinDelay(SLCK_CHECK_MS);
432 delta_time = GetTickCountDelta(start_time);
433 if ((delta_time < SLCK_CHECK_MS - 1) || (delta_time > SLCK_CHECK_MS + 1)) {
434 // error > 2% with SLCK_CHECK_MS=50
435 Dbprintf(_RED_(" Slow Clock speed change detected, run `hw tia`"));
436 Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"),
437 (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS);
439 DbpString(_CYAN_("Installed StandAlone Mode"));
440 ModInfo();
442 #ifdef WITH_FLASH
443 Flashmem_print_info();
444 #endif
445 DbpString("");
446 reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0);
449 static void SendCapabilities(void) {
450 capabilities_t capabilities;
451 capabilities.version = CAPABILITIES_VERSION;
452 capabilities.via_fpc = g_reply_via_fpc;
453 capabilities.via_usb = g_reply_via_usb;
454 capabilities.bigbuf_size = BigBuf_get_size();
455 capabilities.baudrate = 0; // no real baudrate for USB-CDC
456 #ifdef WITH_FPC_USART
457 if (g_reply_via_fpc)
458 capabilities.baudrate = g_usart_baudrate;
459 #endif
461 #ifdef RDV4
462 capabilities.is_rdv4 = true;
463 #else
464 capabilities.is_rdv4 = false;
465 #endif
467 #ifdef WITH_FLASH
468 capabilities.compiled_with_flash = true;
469 capabilities.hw_available_flash = FlashInit();
470 #else
471 capabilities.compiled_with_flash = false;
472 capabilities.hw_available_flash = false;
473 #endif
474 #ifdef WITH_SMARTCARD
475 capabilities.compiled_with_smartcard = true;
476 uint8_t maj, min;
477 capabilities.hw_available_smartcard = I2C_get_version(&maj, &min) == PM3_SUCCESS;
478 #else
479 capabilities.compiled_with_smartcard = false;
480 capabilities.hw_available_smartcard = false;
481 #endif
482 #ifdef WITH_FPC_USART
483 capabilities.compiled_with_fpc_usart = true;
484 #else
485 capabilities.compiled_with_fpc_usart = false;
486 #endif
487 #ifdef WITH_FPC_USART_DEV
488 capabilities.compiled_with_fpc_usart_dev = true;
489 #else
490 capabilities.compiled_with_fpc_usart_dev = false;
491 #endif
492 #ifdef WITH_FPC_USART_HOST
493 capabilities.compiled_with_fpc_usart_host = true;
494 #else
495 capabilities.compiled_with_fpc_usart_host = false;
496 #endif
497 #ifdef WITH_LF
498 capabilities.compiled_with_lf = true;
499 #else
500 capabilities.compiled_with_lf = false;
501 #endif
502 #ifdef WITH_HITAG
503 capabilities.compiled_with_hitag = true;
504 #else
505 capabilities.compiled_with_hitag = false;
506 #endif
507 #ifdef WITH_EM4x50
508 capabilities.compiled_with_em4x50 = true;
509 #else
510 capabilities.compiled_with_em4x50 = false;
511 #endif
512 #ifdef WITH_EM4x70
513 capabilities.compiled_with_em4x70 = true;
514 #else
515 capabilities.compiled_with_em4x70 = false;
516 #endif
518 #ifdef WITH_HFSNIFF
519 capabilities.compiled_with_hfsniff = true;
520 #else
521 capabilities.compiled_with_hfsniff = false;
522 #endif
523 #ifdef WITH_HFPLOT
524 capabilities.compiled_with_hfplot = true;
525 #else
526 capabilities.compiled_with_hfplot = false;
527 #endif
528 #ifdef WITH_ISO14443a
529 capabilities.compiled_with_iso14443a = true;
530 #else
531 capabilities.compiled_with_iso14443a = false;
532 #endif
533 #ifdef WITH_ISO14443b
534 capabilities.compiled_with_iso14443b = true;
535 #else
536 capabilities.compiled_with_iso14443b = false;
537 #endif
538 #ifdef WITH_ISO15693
539 capabilities.compiled_with_iso15693 = true;
540 #else
541 capabilities.compiled_with_iso15693 = false;
542 #endif
543 #ifdef WITH_FELICA
544 capabilities.compiled_with_felica = true;
545 #else
546 capabilities.compiled_with_felica = false;
547 #endif
548 #ifdef WITH_LEGICRF
549 capabilities.compiled_with_legicrf = true;
550 #else
551 capabilities.compiled_with_legicrf = false;
552 #endif
553 #ifdef WITH_ICLASS
554 capabilities.compiled_with_iclass = true;
555 #else
556 capabilities.compiled_with_iclass = false;
557 #endif
558 #ifdef WITH_NFCBARCODE
559 capabilities.compiled_with_nfcbarcode = true;
560 #else
561 capabilities.compiled_with_nfcbarcode = false;
562 #endif
563 #ifdef WITH_LCD
564 capabilities.compiled_with_lcd = true;
565 #else
566 capabilities.compiled_with_lcd = false;
567 #endif
569 #ifdef WITH_ZX8211
570 capabilities.compiled_with_zx8211 = true;
571 #else
572 capabilities.compiled_with_zx8211 = false;
573 #endif
575 reply_ng(CMD_CAPABILITIES, PM3_SUCCESS, (uint8_t *)&capabilities, sizeof(capabilities));
578 // Show some leds in a pattern to identify StandAlone mod is running
579 void StandAloneMode(void) {
580 DbpString("");
581 DbpString("Stand-alone mode, no computer necessary");
582 SpinDown(50);
583 SpinDelay(50);
584 SpinUp(50);
585 SpinDelay(50);
586 SpinDown(50);
590 OBJECTIVE
591 Listen and detect an external reader. Determine the best location
592 for the antenna.
594 INSTRUCTIONS:
595 Inside the ListenReaderField() function, there is two mode.
596 By default, when you call the function, you will enter mode 1.
597 If you press the PM3 button one time, you will enter mode 2.
598 If you press the PM3 button a second time, you will exit the function.
600 DESCRIPTION OF MODE 1:
601 This mode just listens for an external reader field and lights up green
602 for HF and/or red for LF. This is the original mode of the detectreader
603 function.
605 DESCRIPTION OF MODE 2:
606 This mode will visually represent, using the LEDs, the actual strength of the
607 current compared to the maximum current detected. Basically, once you know
608 what kind of external reader is present, it will help you spot the best location to place
609 your antenna. You will probably not get some good results if there is a LF and a HF reader
610 at the same place! :-)
612 #define LIGHT_LEVELS 20
614 void ListenReaderField(uint8_t limit) {
615 #define LF_HF_BOTH 0
616 #define LF_ONLY 1
617 #define HF_ONLY 2
618 #define REPORT_CHANGE 1000 // report new values only if they have changed at least by REPORT_CHANGE mV
620 uint16_t lf_av = 0, lf_av_new, lf_baseline = 0, lf_max = 0;
621 uint16_t hf_av = 0, hf_av_new, hf_baseline = 0, hf_max = 0;
622 uint16_t mode = 1, display_val, display_max;
624 // switch off FPGA - we don't want to measure our own signal
625 // 20180315 - iceman, why load this before and then turn off?
626 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
627 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
629 LEDsoff();
631 if (limit == LF_ONLY || limit == LF_HF_BOTH) {
632 lf_av = lf_max = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15;
633 Dbprintf("LF 125/134kHz Baseline: %dmV", lf_av);
634 lf_baseline = lf_av;
637 if (limit == HF_ONLY || limit == LF_HF_BOTH) {
639 // iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader.
640 hf_av = hf_max = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
641 Dbprintf("HF 13.56MHz Baseline: %dmV", hf_av);
642 hf_baseline = hf_av;
645 for (;;) {
647 // Switch modes with button or Enter key
648 bool modeSwitched = BUTTON_PRESS();
649 if (modeSwitched == false && data_available()) {
650 // flush the buffer
651 PacketCommandNG rx;
652 receive_ng(&rx);
653 modeSwitched = true;
655 if (modeSwitched) {
656 SpinDelay(500);
657 switch (mode) {
658 case 1:
659 mode = 2;
660 DbpString("Signal Strength Mode");
661 break;
662 case 2:
663 default:
664 DbpString("Stopped");
665 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
666 LEDsoff();
667 return;
670 WDT_HIT();
672 if (limit == LF_ONLY || limit == LF_HF_BOTH) {
673 if (mode == 1) {
674 if (ABS(lf_av - lf_baseline) > REPORT_CHANGE)
675 LED_D_ON();
676 else
677 LED_D_OFF();
680 lf_av_new = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15;
681 // see if there's a significant change
682 if (ABS(lf_av - lf_av_new) > REPORT_CHANGE) {
683 Dbprintf("LF 125/134kHz Field Change: %5dmV", lf_av_new);
684 lf_av = lf_av_new;
685 if (lf_av > lf_max)
686 lf_max = lf_av;
690 if (limit == HF_ONLY || limit == LF_HF_BOTH) {
691 if (mode == 1) {
692 if (ABS(hf_av - hf_baseline) > REPORT_CHANGE)
693 LED_B_ON();
694 else
695 LED_B_OFF();
698 hf_av_new = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
699 // see if there's a significant change
700 if (ABS(hf_av - hf_av_new) > REPORT_CHANGE) {
701 Dbprintf("HF 13.56MHz Field Change: %5dmV", hf_av_new);
702 hf_av = hf_av_new;
703 if (hf_av > hf_max)
704 hf_max = hf_av;
708 if (mode == 2) {
709 if (limit == LF_ONLY) {
710 display_val = lf_av;
711 display_max = lf_max;
712 } else if (limit == HF_ONLY) {
713 display_val = hf_av;
714 display_max = hf_max;
715 } else { /* Pick one at random */
716 if ((hf_max - hf_baseline) > (lf_max - lf_baseline)) {
717 display_val = hf_av;
718 display_max = hf_max;
719 } else {
720 display_val = lf_av;
721 display_max = lf_max;
725 display_val = display_val * (4 * LIGHT_LEVELS) / MAX(1, display_max);
726 uint32_t duty_a = MIN(MAX(display_val, 0 * LIGHT_LEVELS), 1 * LIGHT_LEVELS) - 0 * LIGHT_LEVELS;
727 uint32_t duty_b = MIN(MAX(display_val, 1 * LIGHT_LEVELS), 2 * LIGHT_LEVELS) - 1 * LIGHT_LEVELS;
728 uint32_t duty_c = MIN(MAX(display_val, 2 * LIGHT_LEVELS), 3 * LIGHT_LEVELS) - 2 * LIGHT_LEVELS;
729 uint32_t duty_d = MIN(MAX(display_val, 3 * LIGHT_LEVELS), 4 * LIGHT_LEVELS) - 3 * LIGHT_LEVELS;
731 // LED A
732 if (duty_a == 0) {
733 LED_A_OFF();
734 } else if (duty_a == LIGHT_LEVELS) {
735 LED_A_ON();
736 } else {
737 LED_A_ON();
738 SpinDelay(duty_a);
739 LED_A_OFF();
740 SpinDelay(LIGHT_LEVELS - duty_a);
743 // LED B
744 if (duty_b == 0) {
745 LED_B_OFF();
746 } else if (duty_b == LIGHT_LEVELS) {
747 LED_B_ON();
748 } else {
749 LED_B_ON();
750 SpinDelay(duty_b);
751 LED_B_OFF();
752 SpinDelay(LIGHT_LEVELS - duty_b);
755 // LED C
756 if (duty_c == 0) {
757 LED_C_OFF();
758 } else if (duty_c == LIGHT_LEVELS) {
759 LED_C_ON();
760 } else {
761 LED_C_ON();
762 SpinDelay(duty_c);
763 LED_C_OFF();
764 SpinDelay(LIGHT_LEVELS - duty_c);
767 // LED D
768 if (duty_d == 0) {
769 LED_D_OFF();
770 } else if (duty_d == LIGHT_LEVELS) {
771 LED_D_ON();
772 } else {
773 LED_D_ON();
774 SpinDelay(duty_d);
775 LED_D_OFF();
776 SpinDelay(LIGHT_LEVELS - duty_d);
781 static void PacketReceived(PacketCommandNG *packet) {
783 if (packet->ng) {
784 Dbprintf("received NG frame with %d bytes payload, with command: 0x%04x", packet->length, cmd);
785 } else {
786 Dbprintf("received OLD frame of %d bytes, with command: 0x%04x and args: %d %d %d", packet->length, packet->cmd, packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]);
790 switch (packet->cmd) {
791 case CMD_BREAK_LOOP:
792 break;
793 case CMD_QUIT_SESSION: {
794 g_reply_via_fpc = false;
795 g_reply_via_usb = false;
796 break;
798 case CMD_SET_FPGAMODE: {
799 uint8_t mode = packet->data.asBytes[0];
800 if (mode >= FPGA_BITSTREAM_MIN && mode <= FPGA_BITSTREAM_MAX) {
801 FpgaDownloadAndGo(mode);
802 reply_ng(CMD_SET_FPGAMODE, PM3_SUCCESS, NULL, 0);
804 reply_ng(CMD_SET_FPGAMODE, PM3_EINVARG, NULL, 0);
805 break;
807 // emulator
808 case CMD_SET_DBGMODE: {
809 g_dbglevel = packet->data.asBytes[0];
810 if (packet->length == 1 || packet->data.asBytes[1] != 0)
811 print_debug_level();
812 reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0);
813 break;
815 case CMD_GET_DBGMODE: {
816 reply_ng(CMD_GET_DBGMODE, PM3_SUCCESS, (uint8_t *)&g_dbglevel, 1);
817 break;
819 case CMD_SET_TEAROFF: {
820 struct p {
821 uint16_t delay_us;
822 bool on;
823 bool off;
824 } PACKED;
825 struct p *payload = (struct p *)packet->data.asBytes;
826 if (payload->on && payload->off) {
827 reply_ng(CMD_SET_TEAROFF, PM3_EINVARG, NULL, 0);
830 if (payload->on) {
831 g_tearoff_enabled = true;
834 if (payload->off) {
835 g_tearoff_enabled = false;
838 if (payload->delay_us > 0) {
839 g_tearoff_delay_us = payload->delay_us;
841 reply_ng(CMD_SET_TEAROFF, PM3_SUCCESS, NULL, 0);
842 break;
844 // always available
845 case CMD_HF_DROPFIELD: {
846 hf_field_off();
847 break;
849 #ifdef WITH_LF
850 case CMD_LF_T55XX_SET_CONFIG: {
851 setT55xxConfig(packet->oldarg[0], (t55xx_configurations_t *) packet->data.asBytes);
852 break;
854 case CMD_LF_SAMPLING_PRINT_CONFIG: {
855 printLFConfig();
856 break;
858 case CMD_LF_SAMPLING_GET_CONFIG: {
859 sample_config *config = getSamplingConfig();
860 reply_ng(CMD_LF_SAMPLING_GET_CONFIG, PM3_SUCCESS, (uint8_t *)config, sizeof(sample_config));
861 break;
863 case CMD_LF_SAMPLING_SET_CONFIG: {
864 sample_config c;
865 memcpy(&c, packet->data.asBytes, sizeof(sample_config));
866 setSamplingConfig(&c);
867 break;
869 case CMD_LF_ACQ_RAW_ADC: {
870 lf_sample_payload_t *payload = (lf_sample_payload_t *)packet->data.asBytes;
871 if (payload->realtime) {
872 ReadLF_realtime(true);
873 } else {
874 uint32_t bits = SampleLF(payload->verbose, payload->samples, true);
875 reply_ng(CMD_LF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
877 break;
879 case CMD_LF_MOD_THEN_ACQ_RAW_ADC: {
880 struct p {
881 uint32_t delay;
882 uint16_t period_0;
883 uint16_t period_1;
884 uint8_t symbol_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
885 uint16_t period_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
886 uint32_t samples : 30;
887 bool keep : 1;
888 bool verbose : 1;
889 } PACKED;
890 struct p *payload = (struct p *)packet->data.asBytes;
891 uint8_t symbol_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
892 uint16_t period_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
893 memcpy(symbol_extra, payload->symbol_extra, sizeof(symbol_extra));
894 memcpy(period_extra, payload->period_extra, sizeof(period_extra));
895 ModThenAcquireRawAdcSamples125k(payload->delay, payload->period_0, payload->period_1, symbol_extra, period_extra, packet->data.asBytes + sizeof(struct p), payload->verbose, payload->keep, payload->samples, true);
896 break;
898 case CMD_LF_SNIFF_RAW_ADC: {
899 lf_sample_payload_t *payload = (lf_sample_payload_t *)packet->data.asBytes;
900 if (payload->realtime) {
901 ReadLF_realtime(false);
902 } else {
903 uint32_t bits = SniffLF(payload->verbose, payload->samples, true);
904 reply_ng(CMD_LF_SNIFF_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
906 break;
908 case CMD_LF_HID_WATCH: {
909 uint32_t high, low;
910 int res = lf_hid_watch(0, &high, &low, true);
911 reply_ng(CMD_LF_HID_WATCH, res, NULL, 0);
912 break;
914 case CMD_LF_HID_SIMULATE: {
915 lf_hidsim_t *payload = (lf_hidsim_t *)packet->data.asBytes;
916 CmdHIDsimTAG(payload->hi2, payload->hi, payload->lo, payload->longFMT, 1);
917 break;
919 case CMD_LF_FSK_SIMULATE: {
920 lf_fsksim_t *payload = (lf_fsksim_t *)packet->data.asBytes;
921 CmdFSKsimTAG(payload->fchigh, payload->fclow, payload->separator, payload->clock, packet->length - sizeof(lf_fsksim_t), payload->data, true);
922 break;
924 case CMD_LF_ASK_SIMULATE: {
925 lf_asksim_t *payload = (lf_asksim_t *)packet->data.asBytes;
926 CmdASKsimTAG(payload->encoding, payload->invert, payload->separator, payload->clock, packet->length - sizeof(lf_asksim_t), payload->data, true);
927 break;
929 case CMD_LF_PSK_SIMULATE: {
930 lf_psksim_t *payload = (lf_psksim_t *)packet->data.asBytes;
931 CmdPSKsimTAG(payload->carrier, payload->invert, payload->clock, packet->length - sizeof(lf_psksim_t), payload->data, true);
932 break;
934 case CMD_LF_NRZ_SIMULATE: {
935 lf_nrzsim_t *payload = (lf_nrzsim_t *)packet->data.asBytes;
936 CmdNRZsimTAG(payload->invert, payload->separator, payload->clock, packet->length - sizeof(lf_nrzsim_t), payload->data, true);
937 break;
939 case CMD_LF_HID_CLONE: {
940 lf_hidsim_t *payload = (lf_hidsim_t *)packet->data.asBytes;
941 CopyHIDtoT55x7(payload->hi2, payload->hi, payload->lo, payload->longFMT, payload->Q5, payload->EM, true);
942 break;
944 case CMD_LF_IO_WATCH: {
945 uint32_t high, low;
946 int res = lf_io_watch(0, &high, &low, true);
947 reply_ng(CMD_LF_IO_WATCH, res, NULL, 0);
948 break;
950 case CMD_LF_EM410X_WATCH: {
951 uint32_t high;
952 uint64_t low;
953 int res = lf_em410x_watch(0, &high, &low, true);
954 reply_ng(CMD_LF_EM410X_WATCH, res, NULL, 0);
955 break;
957 case CMD_LF_EM410X_CLONE: {
958 struct p {
959 bool Q5;
960 bool EM;
961 bool add_electra;
962 uint8_t clock;
963 uint32_t high;
964 uint32_t low;
965 } PACKED;
966 struct p *payload = (struct p *)packet->data.asBytes;
967 uint8_t card = payload->Q5 ? 0 : (payload->EM ? 2 : 1);
968 int res = copy_em410x_to_t55xx(card, payload->clock, payload->high, payload->low, payload->add_electra, true);
969 reply_ng(CMD_LF_EM410X_CLONE, res, NULL, 0);
970 break;
972 case CMD_LF_TI_READ: {
973 ReadTItag(true);
974 break;
976 case CMD_LF_TI_WRITE: {
977 struct p {
978 uint32_t high;
979 uint32_t low;
980 uint16_t crc;
981 } PACKED;
982 struct p *payload = (struct p *)packet->data.asBytes;
983 WriteTItag(payload->high, payload->low, packet->crc, true);
984 break;
986 case CMD_LF_SIMULATE: {
987 LED_A_ON();
988 struct p {
989 uint16_t len;
990 uint16_t gap;
991 } PACKED;
992 struct p *payload = (struct p *)packet->data.asBytes;
993 // length, start gap, led control
994 SimulateTagLowFrequency(payload->len, payload->gap, true);
995 reply_ng(CMD_LF_SIMULATE, PM3_EOPABORTED, NULL, 0);
996 LED_A_OFF();
997 break;
999 case CMD_LF_SIMULATE_BIDIR: {
1000 SimulateTagLowFrequencyBidir(packet->oldarg[0], packet->oldarg[1]);
1001 break;
1003 case CMD_LF_T55XX_READBL: {
1004 struct p {
1005 uint32_t password;
1006 uint8_t blockno;
1007 uint8_t page;
1008 bool pwdmode;
1009 uint8_t downlink_mode;
1010 } PACKED;
1011 struct p *payload = (struct p *) packet->data.asBytes;
1012 T55xxReadBlock(payload->page, payload->pwdmode, false, payload->blockno, payload->password, payload->downlink_mode, true);
1013 break;
1015 case CMD_LF_T55XX_WRITEBL: {
1016 // uses NG format
1017 T55xxWriteBlock(packet->data.asBytes, true);
1018 break;
1020 case CMD_LF_T55XX_DANGERRAW: {
1021 T55xxDangerousRawTest(packet->data.asBytes, true);
1022 break;
1024 case CMD_LF_T55XX_WAKEUP: {
1025 struct p {
1026 uint32_t password;
1027 uint8_t flags;
1028 } PACKED;
1029 struct p *payload = (struct p *) packet->data.asBytes;
1030 T55xxWakeUp(payload->password, payload->flags, true);
1031 break;
1033 case CMD_LF_T55XX_RESET_READ: {
1034 T55xxResetRead(packet->data.asBytes[0] & 0xff, true);
1035 break;
1037 case CMD_LF_T55XX_CHK_PWDS: {
1038 T55xx_ChkPwds(packet->data.asBytes[0] & 0xff, true);
1039 break;
1041 case CMD_LF_PCF7931_READ: {
1042 ReadPCF7931(true);
1043 break;
1045 case CMD_LF_PCF7931_WRITE: {
1046 WritePCF7931(
1047 packet->data.asBytes[0], packet->data.asBytes[1], packet->data.asBytes[2], packet->data.asBytes[3],
1048 packet->data.asBytes[4], packet->data.asBytes[5], packet->data.asBytes[6], packet->data.asBytes[9],
1049 packet->data.asBytes[7] - 128, packet->data.asBytes[8] - 128,
1050 packet->oldarg[0],
1051 packet->oldarg[1],
1052 packet->oldarg[2],
1053 true
1055 break;
1057 case CMD_LF_EM4X_LOGIN: {
1058 struct p {
1059 uint32_t password;
1060 } PACKED;
1061 struct p *payload = (struct p *) packet->data.asBytes;
1062 EM4xLogin(payload->password, true);
1063 break;
1065 case CMD_LF_EM4X_BF: {
1066 struct p {
1067 uint32_t start_pwd;
1068 uint32_t n;
1069 } PACKED;
1070 struct p *payload = (struct p *) packet->data.asBytes;
1071 EM4xBruteforce(payload->start_pwd, payload->n, true);
1072 break;
1074 case CMD_LF_EM4X_READWORD: {
1075 struct p {
1076 uint32_t password;
1077 uint8_t address;
1078 uint8_t usepwd;
1079 } PACKED;
1080 struct p *payload = (struct p *) packet->data.asBytes;
1081 EM4xReadWord(payload->address, payload->password, payload->usepwd, true);
1082 break;
1084 case CMD_LF_EM4X_WRITEWORD: {
1085 struct p {
1086 uint32_t password;
1087 uint32_t data;
1088 uint8_t address;
1089 uint8_t usepwd;
1090 } PACKED;
1091 struct p *payload = (struct p *) packet->data.asBytes;
1092 EM4xWriteWord(payload->address, payload->data, payload->password, payload->usepwd, true);
1093 break;
1095 case CMD_LF_EM4X_PROTECTWORD: {
1096 struct p {
1097 uint32_t password;
1098 uint32_t data;
1099 uint8_t usepwd;
1100 } PACKED;
1101 struct p *payload = (struct p *) packet->data.asBytes;
1102 EM4xProtectWord(payload->data, payload->password, payload->usepwd, true);
1103 break;
1105 case CMD_LF_AWID_WATCH: {
1106 uint32_t high, low;
1107 int res = lf_awid_watch(0, &high, &low, true);
1108 reply_ng(CMD_LF_AWID_WATCH, res, NULL, 0);
1109 break;
1111 case CMD_LF_VIKING_CLONE: {
1112 struct p {
1113 bool Q5;
1114 bool EM;
1115 uint8_t blocks[8];
1116 } PACKED;
1117 struct p *payload = (struct p *)packet->data.asBytes;
1118 CopyVikingtoT55xx(payload->blocks, payload->Q5, payload->EM, true);
1119 break;
1121 case CMD_LF_COTAG_READ: {
1122 struct p {
1123 uint8_t mode;
1124 } PACKED;
1125 struct p *payload = (struct p *)packet->data.asBytes;
1126 Cotag(payload->mode, true);
1127 break;
1129 #endif
1131 #ifdef WITH_HITAG
1132 case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type
1133 SniffHitag2(true);
1134 //hitag_sniff();
1135 reply_ng(CMD_LF_HITAG_SNIFF, PM3_SUCCESS, NULL, 0);
1136 break;
1138 case CMD_LF_HITAG_SIMULATE: { // Simulate Hitag tag, args = memory content
1139 SimulateHitag2(true);
1140 break;
1142 case CMD_LF_HITAG2_CRACK: {
1143 lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
1144 ht2_crack1(payload->NrAr);
1145 break;
1147 case CMD_LF_HITAG2_CRACK_2: {
1148 lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
1149 ht2_crack2(payload->NrAr);
1150 break;
1152 case CMD_LF_HITAG_READER: { // Reader for Hitag tags, args = type and function
1153 lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
1155 switch (payload->cmd) {
1156 case HT2F_UID_ONLY: {
1157 ht2_read_uid(NULL, true, true, false);
1158 break;
1160 default: {
1161 ReaderHitag(payload, true);
1162 break;
1165 break;
1167 case CMD_LF_HITAGS_SIMULATE: { // Simulate Hitag s tag, args = memory content
1168 hts_simulate((bool)packet->oldarg[0], packet->data.asBytes, true);
1169 break;
1171 case CMD_LF_HITAGS_TEST_TRACES: { // Tests every challenge within the given file
1172 hts_check_challenges(packet->data.asBytes, packet->length, true);
1173 break;
1175 case CMD_LF_HITAGS_READ: { // Reader for only Hitag S tags, args = key or challenge
1176 lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
1177 hts_read(payload, true);
1178 break;
1180 case CMD_LF_HITAGS_WRITE: {
1181 lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
1182 hts_write_page(payload, true);
1183 break;
1185 case CMD_LF_HITAGS_UID: {
1186 hts_read_uid(NULL, false, true);
1187 break;
1189 case CMD_LF_HITAG2_WRITE: {
1190 lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
1191 WriterHitag(payload, true);
1192 break;
1194 case CMD_LF_HITAG_ELOAD: {
1195 lf_hitag_t *payload = (lf_hitag_t *) packet->data.asBytes;
1196 uint8_t *mem = BigBuf_get_EM_addr();
1197 memcpy(mem, payload->data, payload->len);
1198 break;
1200 #endif
1202 #ifdef WITH_EM4x50
1203 case CMD_LF_EM4X50_INFO: {
1204 em4x50_info((const em4x50_data_t *)packet->data.asBytes, true);
1205 break;
1207 case CMD_LF_EM4X50_WRITE: {
1208 em4x50_write((const em4x50_data_t *)packet->data.asBytes, true);
1209 break;
1211 case CMD_LF_EM4X50_WRITEPWD: {
1212 em4x50_writepwd((const em4x50_data_t *)packet->data.asBytes, true);
1213 break;
1215 case CMD_LF_EM4X50_READ: {
1216 em4x50_read((const em4x50_data_t *)packet->data.asBytes, true);
1217 break;
1219 case CMD_LF_EM4X50_BRUTE: {
1220 em4x50_brute((const em4x50_data_t *)packet->data.asBytes, true);
1221 break;
1223 case CMD_LF_EM4X50_LOGIN: {
1224 em4x50_login((const uint32_t *)packet->data.asBytes, true);
1225 break;
1227 case CMD_LF_EM4X50_SIM: {
1228 //-----------------------------------------------------------------------------
1229 // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_LF) here although FPGA is not
1230 // involved in dealing with emulator memory. But if it is called later, it might
1231 // destroy the Emulator Memory.
1232 //-----------------------------------------------------------------------------
1233 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
1234 em4x50_sim((const uint32_t *)packet->data.asBytes, true);
1235 break;
1237 case CMD_LF_EM4X50_READER: {
1238 em4x50_reader(true);
1239 break;
1241 case CMD_LF_EM4X50_ESET: {
1242 //-----------------------------------------------------------------------------
1243 // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_LF) here although FPGA is not
1244 // involved in dealing with emulator memory. But if it is called later, it might
1245 // destroy the Emulator Memory.
1246 //-----------------------------------------------------------------------------
1247 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
1248 emlSet(packet->data.asBytes, packet->oldarg[0], packet->oldarg[1]);
1249 break;
1251 case CMD_LF_EM4X50_CHK: {
1252 //-----------------------------------------------------------------------------
1253 // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_LF) here although FPGA is not
1254 // involved in dealing with emulator memory. But if it is called later, it might
1255 // destroy the Emulator Memory.
1256 //-----------------------------------------------------------------------------
1257 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
1258 em4x50_chk((const char *)packet->data.asBytes, true);
1259 break;
1261 #endif
1263 #ifdef WITH_EM4x70
1264 case CMD_LF_EM4X70_INFO: {
1265 em4x70_info((em4x70_data_t *)packet->data.asBytes, true);
1266 break;
1268 case CMD_LF_EM4X70_WRITE: {
1269 em4x70_write((em4x70_data_t *)packet->data.asBytes, true);
1270 break;
1272 case CMD_LF_EM4X70_UNLOCK: {
1273 em4x70_unlock((em4x70_data_t *)packet->data.asBytes, true);
1274 break;
1276 case CMD_LF_EM4X70_AUTH: {
1277 em4x70_auth((em4x70_data_t *)packet->data.asBytes, true);
1278 break;
1280 case CMD_LF_EM4X70_SETPIN: {
1281 em4x70_write_pin((em4x70_data_t *)packet->data.asBytes, true);
1282 break;
1284 case CMD_LF_EM4X70_SETKEY: {
1285 em4x70_write_key((em4x70_data_t *)packet->data.asBytes, true);
1286 break;
1288 case CMD_LF_EM4X70_BRUTE: {
1289 em4x70_brute((em4x70_data_t *)packet->data.asBytes, true);
1290 break;
1292 #endif
1294 #ifdef WITH_ZX8211
1295 case CMD_LF_ZX_READ: {
1296 zx8211_read((zx8211_data_t *)packet->data.asBytes, true);
1297 break;
1299 case CMD_LF_ZX_WRITE: {
1300 zx8211_write((zx8211_data_t *)packet->data.asBytes, true);
1301 break;
1303 #endif
1305 #ifdef WITH_ISO15693
1306 case CMD_HF_ISO15693_ACQ_RAW_ADC: {
1307 AcquireRawAdcSamplesIso15693();
1308 break;
1310 case CMD_HF_ISO15693_SNIFF: {
1311 SniffIso15693(0, NULL, false);
1312 reply_ng(CMD_HF_ISO15693_SNIFF, PM3_SUCCESS, NULL, 0);
1313 break;
1315 case CMD_HF_ISO15693_COMMAND: {
1316 iso15_raw_cmd_t *payload = (iso15_raw_cmd_t *)packet->data.asBytes;
1317 SendRawCommand15693(payload);
1318 break;
1320 case CMD_HF_ISO15693_FINDAFI: {
1321 struct p {
1322 uint32_t flags;
1323 } PACKED;
1324 struct p *payload = (struct p *)packet->data.asBytes;
1325 BruteforceIso15693Afi(payload->flags);
1326 break;
1328 case CMD_HF_ISO15693_READER: {
1329 ReaderIso15693(NULL);
1330 break;
1332 case CMD_HF_ISO15693_EML_CLEAR: {
1333 //-----------------------------------------------------------------------------
1334 // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15) here although FPGA is not
1335 // involved in dealing with emulator memory. But if it is called later, it might
1336 // destroy the Emulator Memory.
1337 //-----------------------------------------------------------------------------
1338 EmlClearIso15693();
1339 break;
1341 case CMD_HF_ISO15693_EML_SETMEM: {
1342 //-----------------------------------------------------------------------------
1343 // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15) here although FPGA is not
1344 // involved in dealing with emulator memory. But if it is called later, it might
1345 // destroy the Emulator Memory.
1346 //-----------------------------------------------------------------------------
1347 FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15);
1348 struct p {
1349 uint32_t offset;
1350 uint16_t count;
1351 uint8_t data[];
1352 } PACKED;
1353 struct p *payload = (struct p *) packet->data.asBytes;
1354 emlSet(payload->data, payload->offset, payload->count);
1355 break;
1357 case CMD_HF_ISO15693_EML_GETMEM: {
1358 FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15);
1359 struct p {
1360 uint32_t offset;
1361 uint16_t length;
1362 } PACKED;
1363 struct p *payload = (struct p *) packet->data.asBytes;
1365 if (payload->length > PM3_CMD_DATA_SIZE) {
1366 reply_ng(CMD_HF_ISO15693_EML_GETMEM, PM3_EMALLOC, NULL, 0);
1367 return;
1370 uint8_t *buf = BigBuf_malloc(payload->length);
1371 emlGet(buf, payload->offset, payload->length);
1372 LED_B_ON();
1373 reply_ng(CMD_HF_ISO15693_EML_GETMEM, PM3_SUCCESS, buf, payload->length);
1374 LED_B_OFF();
1375 BigBuf_free_keep_EM();
1376 break;
1378 case CMD_HF_ISO15693_SIMULATE: {
1379 struct p {
1380 uint8_t uid[8];
1381 uint8_t block_size;
1382 } PACKED;
1383 struct p *payload = (struct p *) packet->data.asBytes;
1384 SimTagIso15693(payload->uid, payload->block_size);
1385 break;
1387 case CMD_HF_ISO15693_CSETUID: {
1388 struct p {
1389 uint8_t uid[8];
1390 } PACKED;
1391 struct p *payload = (struct p *) packet->data.asBytes;
1392 SetTag15693Uid(payload->uid);
1393 break;
1395 case CMD_HF_ISO15693_CSETUID_V2: {
1396 struct p {
1397 uint8_t uid[8];
1398 } PACKED;
1399 struct p *payload = (struct p *) packet->data.asBytes;
1400 SetTag15693Uid_v2(payload->uid);
1401 break;
1403 case CMD_HF_ISO15693_SLIX_DISABLE_EAS: {
1404 struct p {
1405 uint8_t pwd[4];
1406 bool usepwd;
1407 } PACKED;
1408 struct p *payload = (struct p *) packet->data.asBytes;
1409 DisableEAS_AFISlixIso15693(payload->pwd, payload->usepwd);
1410 break;
1412 case CMD_HF_ISO15693_SLIX_ENABLE_EAS: {
1413 struct p {
1414 uint8_t pwd[4];
1415 bool usepwd;
1416 } PACKED;
1417 struct p *payload = (struct p *) packet->data.asBytes;
1418 EnableEAS_AFISlixIso15693(payload->pwd, payload->usepwd);
1419 break;
1421 case CMD_HF_ISO15693_SLIX_WRITE_PWD: {
1422 struct p {
1423 uint8_t old_pwd[4];
1424 uint8_t new_pwd[4];
1425 uint8_t pwd_id;
1426 } PACKED;
1427 struct p *payload = (struct p *) packet->data.asBytes;
1428 WritePasswordSlixIso15693(payload->old_pwd, payload->new_pwd, payload->pwd_id);
1429 break;
1431 case CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY: {
1432 struct p {
1433 uint8_t pwd[4];
1434 } PACKED;
1435 struct p *payload = (struct p *) packet->data.asBytes;
1436 DisablePrivacySlixIso15693(payload->pwd);
1437 break;
1439 case CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY: {
1440 struct p {
1441 uint8_t pwd[4];
1442 } PACKED;
1443 struct p *payload = (struct p *)packet->data.asBytes;
1444 EnablePrivacySlixIso15693(payload->pwd);
1445 break;
1447 case CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI: {
1448 struct p {
1449 uint8_t pwd[4];
1450 } PACKED;
1451 struct p *payload = (struct p *)packet->data.asBytes;
1452 PassProtectAFISlixIso15693(payload->pwd);
1453 break;
1455 case CMD_HF_ISO15693_WRITE_AFI: {
1456 struct p {
1457 uint8_t pwd[4];
1458 bool use_pwd;
1459 uint8_t uid[8];
1460 bool use_uid;
1461 uint8_t afi;
1462 } PACKED;
1463 struct p *payload = (struct p *)packet->data.asBytes;
1464 WriteAFIIso15693(payload->pwd, payload->use_pwd, payload->uid, payload->use_uid, payload->afi);
1465 break;
1467 case CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS: {
1468 struct p {
1469 uint8_t pwd[4];
1470 } PACKED;
1471 struct p *payload = (struct p *)packet->data.asBytes;
1472 PassProtextEASSlixIso15693(payload->pwd);
1473 break;
1476 #endif
1478 #ifdef WITH_LEGICRF
1479 case CMD_HF_LEGIC_SIMULATE: {
1480 struct p {
1481 uint8_t tagtype;
1482 bool send_reply;
1483 } PACKED;
1484 struct p *payload = (struct p *) packet->data.asBytes;
1485 LegicRfSimulate(payload->tagtype, payload->send_reply);
1486 break;
1488 case CMD_HF_LEGIC_WRITER: {
1489 legic_packet_t *payload = (legic_packet_t *) packet->data.asBytes;
1490 LegicRfWriter(payload->offset, payload->len, payload->iv, payload->data);
1491 break;
1493 case CMD_HF_LEGIC_READER: {
1494 legic_packet_t *payload = (legic_packet_t *) packet->data.asBytes;
1495 LegicRfReader(payload->offset, payload->len, payload->iv);
1496 break;
1498 case CMD_HF_LEGIC_INFO: {
1499 LegicRfInfo();
1500 break;
1502 case CMD_HF_LEGIC_ESET: {
1503 //-----------------------------------------------------------------------------
1504 // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not
1505 // involved in dealing with emulator memory. But if it is called later, it might
1506 // destroy the Emulator Memory.
1507 //-----------------------------------------------------------------------------
1508 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1509 legic_packet_t *payload = (legic_packet_t *) packet->data.asBytes;
1510 emlSet(payload->data, payload->offset, payload->len);
1511 break;
1513 #endif
1515 #ifdef WITH_ISO14443b
1516 case CMD_HF_SRI_READ: {
1517 struct p {
1518 uint8_t blockno;
1519 } PACKED;
1520 struct p *payload = (struct p *) packet->data.asBytes;
1521 read_14b_st_block(payload->blockno);
1522 break;
1524 case CMD_HF_ISO14443B_SNIFF: {
1525 SniffIso14443b();
1526 reply_ng(CMD_HF_ISO14443B_SNIFF, PM3_SUCCESS, NULL, 0);
1527 break;
1529 case CMD_HF_ISO14443B_SIMULATE: {
1530 SimulateIso14443bTag(packet->data.asBytes);
1531 break;
1533 case CMD_HF_ISO14443B_COMMAND: {
1534 iso14b_raw_cmd_t *payload = (iso14b_raw_cmd_t *)packet->data.asBytes;
1535 SendRawCommand14443B(payload);
1536 break;
1538 case CMD_HF_CRYPTORF_SIM : {
1539 // simulate_crf_tag();
1540 break;
1542 #endif
1544 #ifdef WITH_FELICA
1545 case CMD_HF_FELICA_COMMAND: {
1546 felica_sendraw(packet);
1547 break;
1549 case CMD_HF_FELICALITE_SIMULATE: {
1550 struct p {
1551 uint8_t uid[8];
1552 } PACKED;
1553 struct p *payload = (struct p *) packet->data.asBytes;
1554 felica_sim_lite(payload->uid);
1555 break;
1557 case CMD_HF_FELICA_SNIFF: {
1558 struct p {
1559 uint32_t samples;
1560 uint32_t triggers;
1561 } PACKED;
1562 struct p *payload = (struct p *) packet->data.asBytes;
1563 felica_sniff(payload->samples, payload->triggers);
1564 break;
1566 case CMD_HF_FELICALITE_DUMP: {
1567 felica_dump_lite_s();
1568 break;
1570 #endif
1572 #ifdef WITH_GENERAL_HF
1573 case CMD_HF_ACQ_RAW_ADC: {
1574 uint32_t samplesCount = 0;
1575 memcpy(&samplesCount, packet->data.asBytes, 4);
1576 HfReadADC(samplesCount, true);
1577 break;
1579 case CMD_HF_TEXKOM_SIMULATE: {
1580 struct p {
1581 uint8_t data[8];
1582 uint8_t modulation;
1583 uint32_t timeout;
1584 } PACKED;
1585 struct p *payload = (struct p *) packet->data.asBytes;
1586 HfSimulateTkm(payload->data, payload->modulation, payload->timeout);
1587 break;
1590 #endif
1592 #ifdef WITH_ISO14443a
1593 case CMD_HF_ISO14443A_PRINT_CONFIG: {
1594 printHf14aConfig();
1595 break;
1597 case CMD_HF_ISO14443A_GET_CONFIG: {
1598 hf14a_config *hf14aconfig = getHf14aConfig();
1599 reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)hf14aconfig, sizeof(hf14a_config));
1600 break;
1602 case CMD_HF_ISO14443A_SET_CONFIG: {
1603 hf14a_config c;
1604 memcpy(&c, packet->data.asBytes, sizeof(hf14a_config));
1605 setHf14aConfig(&c);
1606 break;
1608 case CMD_HF_ISO14443A_SET_THRESHOLDS: {
1609 struct p {
1610 uint8_t threshold;
1611 uint8_t threshold_high;
1612 uint8_t legic_threshold;
1613 } PACKED;
1614 struct p *payload = (struct p *) packet->data.asBytes;
1615 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1616 FpgaSendCommand(FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, (payload->threshold & 0x3f) | ((payload->threshold_high & 0x3f) << 6));
1617 #ifdef WITH_LEGICRF
1618 LegicRfSetThreshold((uint32_t)payload->legic_threshold);
1619 #endif
1620 break;
1622 case CMD_HF_ISO14443A_SNIFF: {
1623 SniffIso14443a(packet->data.asBytes[0]);
1624 reply_ng(CMD_HF_ISO14443A_SNIFF, PM3_SUCCESS, NULL, 0);
1625 break;
1627 case CMD_HF_ISO14443A_READER: {
1628 ReaderIso14443a(packet);
1629 break;
1631 case CMD_HF_ISO14443A_SIMULATE: {
1632 struct p {
1633 uint8_t tagtype;
1634 uint16_t flags;
1635 uint8_t uid[10];
1636 uint8_t exitAfter;
1637 uint8_t rats[20];
1638 } PACKED;
1639 struct p *payload = (struct p *) packet->data.asBytes;
1640 SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid, payload->exitAfter, payload->rats); // ## Simulate iso14443a tag - pass tag type & UID
1641 break;
1643 case CMD_HF_ISO14443A_SIM_AID: {
1644 struct p {
1645 uint8_t tagtype;
1646 uint16_t flags;
1647 uint8_t uid[10];
1648 uint8_t rats[20];
1649 uint8_t aid[30];
1650 uint8_t response[100];
1651 uint8_t apdu[100];
1652 int aid_len;
1653 int respond_len;
1654 int apdu_len;
1655 bool enumerate;
1656 } PACKED;
1657 struct p *payload = (struct p *) packet->data.asBytes;
1658 SimulateIso14443aTagAID(payload->tagtype, payload->flags, payload->uid, payload->rats, payload->aid, payload->response, payload->apdu, payload->aid_len, payload->respond_len, payload->apdu_len, payload->enumerate); // ## Simulate iso14443a tag - pass tag type, UID, rats, aid, resp, apdu
1659 break;
1661 case CMD_HF_ISO14443A_ANTIFUZZ: {
1662 struct p {
1663 uint8_t flag;
1664 } PACKED;
1665 struct p *payload = (struct p *) packet->data.asBytes;
1666 iso14443a_antifuzz(payload->flag);
1667 break;
1669 // EPA related
1670 case CMD_HF_EPA_COLLECT_NONCE: {
1671 EPA_PACE_Collect_Nonce(packet);
1672 break;
1674 case CMD_HF_EPA_REPLAY: {
1675 EPA_PACE_Replay(packet);
1676 break;
1678 case CMD_HF_EPA_PACE_SIMULATE: {
1679 EPA_PACE_Simulate(packet);
1680 break;
1683 case CMD_HF_MIFARE_READER: {
1684 struct p {
1685 uint8_t first_run;
1686 uint8_t blockno;
1687 uint8_t key_type;
1688 } PACKED;
1689 struct p *payload = (struct p *) packet->data.asBytes;
1690 ReaderMifare(payload->first_run, payload->blockno, payload->key_type);
1691 break;
1693 case CMD_HF_MIFARE_READBL: {
1694 mf_readblock_t *payload = (mf_readblock_t *)packet->data.asBytes;
1695 uint8_t outbuf[16];
1696 int16_t retval = mifare_cmd_readblocks(MF_WAKE_WUPA, MIFARE_AUTH_KEYA + payload->keytype, payload->key, ISO14443A_CMD_READBLOCK, payload->blockno, 1, outbuf);
1697 reply_ng(CMD_HF_MIFARE_READBL, retval, outbuf, sizeof(outbuf));
1698 break;
1700 case CMD_HF_MIFARE_READBL_EX: {
1701 mf_readblock_ex_t *payload = (mf_readblock_ex_t *)packet->data.asBytes;
1702 uint8_t outbuf[16];
1703 int16_t retval = mifare_cmd_readblocks(payload->wakeup, payload->auth_cmd, payload->key, payload->read_cmd, payload->block_no, 1, outbuf);
1704 reply_ng(CMD_HF_MIFARE_READBL_EX, retval, outbuf, sizeof(outbuf));
1705 break;
1707 case CMD_HF_MIFAREU_READBL: {
1709 MifareUReadBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
1710 break;
1712 case CMD_HF_MIFAREUC_AUTH: {
1713 MifareUC_Auth(packet->oldarg[0], packet->data.asBytes);
1714 break;
1716 case CMD_HF_MIFAREULAES_AUTH: {
1717 struct p {
1718 bool turn_off_field;
1719 uint8_t keyno;
1720 uint8_t key[18];
1721 } PACKED;
1722 struct p *payload = (struct p *) packet->data.asBytes;
1723 MifareUL_AES_Auth(payload->turn_off_field, payload->keyno, payload->key);
1724 break;
1726 case CMD_HF_MIFAREU_READCARD: {
1727 MifareUReadCard(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes);
1728 break;
1730 case CMD_HF_MIFAREUC_SETPWD: {
1731 MifareUSetPwd(packet->oldarg[0], packet->data.asBytes);
1732 break;
1734 case CMD_HF_MIFARE_READSC: {
1735 MifareReadSector(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
1736 break;
1738 case CMD_HF_MIFARE_WRITEBL: {
1739 uint8_t block_no = packet->oldarg[0];
1740 uint8_t key_type = packet->oldarg[1];
1741 uint8_t *key = packet->data.asBytes;
1742 uint8_t *block_data = packet->data.asBytes + 10;
1744 int16_t retval = mifare_cmd_writeblocks(MF_WAKE_WUPA, MIFARE_AUTH_KEYA + (key_type & 0xF), key, ISO14443A_CMD_WRITEBLOCK, block_no, 1, block_data);
1746 // convert ng style retval to old status
1747 if (retval >= 0) {
1748 retval = 1;
1751 reply_mix(CMD_ACK, retval, 0, 0, 0, 0);
1752 break;
1754 case CMD_HF_MIFARE_WRITEBL_EX: {
1755 mf_writeblock_ex_t *payload = (mf_writeblock_ex_t *)packet->data.asBytes;
1756 int16_t retval = mifare_cmd_writeblocks(payload->wakeup, payload->auth_cmd, payload->key, payload->write_cmd, payload->block_no, 1, payload->block_data);
1757 reply_ng(CMD_HF_MIFARE_WRITEBL_EX, retval, NULL, 0);
1758 break;
1760 case CMD_HF_MIFARE_VALUE: {
1761 MifareValue(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes);
1762 break;
1764 case CMD_HF_MIFAREU_WRITEBL: {
1765 MifareUWriteBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
1766 break;
1768 case CMD_HF_MIFAREU_WRITEBL_COMPAT: {
1769 MifareUWriteBlockCompat(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
1770 break;
1772 case CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES: {
1773 MifareAcquireEncryptedNonces(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes);
1774 break;
1776 case CMD_HF_MIFARE_ACQ_STATIC_ENCRYPTED_NONCES: {
1777 MifareAcquireStaticEncryptedNonces(packet->oldarg[0], packet->data.asBytes, true);
1778 break;
1780 case CMD_HF_MIFARE_ACQ_NONCES: {
1781 MifareAcquireNonces(packet->oldarg[0], packet->oldarg[2]);
1782 break;
1784 case CMD_HF_MIFARE_NESTED: {
1785 struct p {
1786 uint8_t block;
1787 uint8_t keytype;
1788 uint8_t target_block;
1789 uint8_t target_keytype;
1790 bool calibrate;
1791 uint8_t key[6];
1792 } PACKED;
1793 struct p *payload = (struct p *) packet->data.asBytes;
1794 MifareNested(payload->block, payload->keytype, payload->target_block, payload->target_keytype, payload->calibrate, payload->key);
1795 break;
1797 case CMD_HF_MIFARE_STATIC_NESTED: {
1798 struct p {
1799 uint8_t block;
1800 uint8_t keytype;
1801 uint8_t target_block;
1802 uint8_t target_keytype;
1803 uint8_t key[6];
1804 } PACKED;
1805 struct p *payload = (struct p *) packet->data.asBytes;
1806 MifareStaticNested(payload->block, payload->keytype, payload->target_block, payload->target_keytype, payload->key);
1807 break;
1809 case CMD_HF_MIFARE_CHKKEYS: {
1810 MifareChkKeys(packet->data.asBytes, false);
1811 break;
1813 case CMD_HF_MIFARE_CHKKEYS_FAST: {
1814 MifareChkKeys_fast(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes);
1815 break;
1817 case CMD_HF_MIFARE_CHKKEYS_FILE: {
1818 struct p {
1819 uint8_t filename[32];
1820 } PACKED;
1821 struct p *payload = (struct p *) packet->data.asBytes;
1822 MifareChkKeys_file(payload->filename);
1823 break;
1825 case CMD_HF_MIFARE_SIMULATE: {
1826 struct p {
1827 uint16_t flags;
1828 uint8_t exitAfter;
1829 uint8_t uid[10];
1830 uint16_t atqa;
1831 uint8_t sak;
1832 } PACKED;
1833 struct p *payload = (struct p *) packet->data.asBytes;
1834 Mifare1ksim(payload->flags, payload->exitAfter, payload->uid, payload->atqa, payload->sak);
1835 break;
1837 case CMD_HF_MIFARE_EML_MEMCLR: {
1838 MifareEMemClr();
1839 reply_ng(CMD_HF_MIFARE_EML_MEMCLR, PM3_SUCCESS, NULL, 0);
1840 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1841 break;
1843 case CMD_HF_MIFARE_EML_MEMSET: {
1844 struct p {
1845 uint8_t blockno;
1846 uint8_t blockcnt;
1847 uint8_t blockwidth;
1848 uint8_t data[];
1849 } PACKED;
1850 struct p *payload = (struct p *) packet->data.asBytes;
1852 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1854 // backwards compat... default bytewidth
1855 if (payload->blockwidth == 0)
1856 payload->blockwidth = 16;
1858 emlSetMem_xt(payload->data, payload->blockno, payload->blockcnt, payload->blockwidth);
1859 break;
1861 case CMD_HF_MIFARE_EML_MEMGET: {
1862 struct p {
1863 uint8_t blockno;
1864 uint8_t blockcnt;
1865 } PACKED;
1866 struct p *payload = (struct p *) packet->data.asBytes;
1867 MifareEMemGet(payload->blockno, payload->blockcnt);
1868 break;
1870 case CMD_HF_MIFARE_EML_LOAD: {
1871 mfc_eload_t *payload = (mfc_eload_t *) packet->data.asBytes;
1872 MifareECardLoadExt(payload->sectorcnt, payload->keytype, payload->key);
1873 break;
1875 // Gen1a / 1b - "magic Chinese" card
1876 case CMD_HF_MIFARE_CSETBL: {
1877 MifareCSetBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
1878 break;
1880 case CMD_HF_MIFARE_CGETBL: {
1881 MifareCGetBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
1882 break;
1884 case CMD_HF_MIFARE_CIDENT: {
1885 struct p {
1886 uint8_t is_mfc;
1887 uint8_t keytype;
1888 uint8_t key[6];
1889 } PACKED;
1890 struct p *payload = (struct p *) packet->data.asBytes;
1891 MifareCIdent(payload->is_mfc, payload->keytype, payload->key);
1892 break;
1894 // Gen 3 magic cards
1895 case CMD_HF_MIFARE_GEN3UID: {
1896 MifareGen3UID(packet->oldarg[0], packet->data.asBytes);
1897 break;
1899 case CMD_HF_MIFARE_GEN3BLK: {
1900 MifareGen3Blk(packet->oldarg[0], packet->data.asBytes);
1901 break;
1903 case CMD_HF_MIFARE_GEN3FREEZ: {
1904 MifareGen3Freez();
1905 break;
1907 // Gen 4 GTU magic cards
1908 case CMD_HF_MIFARE_G4_RDBL: {
1909 struct p {
1910 uint8_t blockno;
1911 uint8_t pwd[4];
1912 uint8_t workFlags;
1913 } PACKED;
1914 struct p *payload = (struct p *) packet->data.asBytes;
1915 MifareG4ReadBlk(payload->blockno, payload->pwd, payload->workFlags);
1916 break;
1918 case CMD_HF_MIFARE_G4_WRBL: {
1919 struct p {
1920 uint8_t blockno;
1921 uint8_t pwd[4];
1922 uint8_t data[16]; // data to be written
1923 uint8_t workFlags;
1924 } PACKED;
1925 struct p *payload = (struct p *) packet->data.asBytes;
1926 MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data, payload->workFlags);
1927 break;
1929 case CMD_HF_MIFARE_G4_GDM_WRBL: {
1930 struct p {
1931 uint8_t blockno;
1932 uint8_t key[6];
1933 uint8_t data[16]; // data to be written
1934 } PACKED;
1935 struct p *payload = (struct p *) packet->data.asBytes;
1936 int16_t retval = mifare_cmd_writeblocks(MF_WAKE_WUPA, MIFARE_MAGIC_GDM_AUTH_KEY, payload->key, MIFARE_MAGIC_GDM_WRITEBLOCK, payload->blockno, 1, payload->data);
1937 reply_ng(CMD_HF_MIFARE_G4_GDM_WRBL, retval, NULL, 0);
1938 break;
1940 case CMD_HF_MIFARE_PERSONALIZE_UID: {
1941 struct p {
1942 uint8_t keytype;
1943 uint8_t pers_option;
1944 uint8_t key[6];
1945 } PACKED;
1946 struct p *payload = (struct p *) packet->data.asBytes;
1947 uint64_t authkey = bytes_to_num(payload->key, 6);
1948 MifarePersonalizeUID(payload->keytype, payload->pers_option, authkey);
1949 break;
1951 case CMD_HF_MIFARE_SETMOD: {
1952 MifareSetMod(packet->data.asBytes);
1953 break;
1955 //mifare desfire
1956 case CMD_HF_DESFIRE_READBL: {
1957 break;
1959 case CMD_HF_DESFIRE_WRITEBL: {
1960 break;
1962 case CMD_HF_DESFIRE_AUTH1: {
1963 MifareDES_Auth1(packet->data.asBytes);
1964 break;
1966 case CMD_HF_DESFIRE_AUTH2: {
1967 //MifareDES_Auth2(packet->oldarg[0],packet->data.asBytes);
1968 break;
1970 case CMD_HF_DESFIRE_READER: {
1971 //readermifaredes(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
1972 break;
1974 case CMD_HF_DESFIRE_INFO: {
1975 MifareDesfireGetInformation();
1976 break;
1978 case CMD_HF_DESFIRE_COMMAND: {
1979 MifareSendCommand(packet->data.asBytes);
1980 break;
1982 case CMD_HF_MIFARE_NACK_DETECT: {
1983 DetectNACKbug();
1984 break;
1986 case CMD_HF_MFU_OTP_TEAROFF: {
1987 MifareU_Otp_Tearoff(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
1988 break;
1990 case CMD_HF_MFU_COUNTER_TEAROFF: {
1991 struct p {
1992 uint8_t counter;
1993 uint32_t tearoff_time;
1994 uint8_t value[4];
1995 } PACKED;
1996 struct p *payload = (struct p *) packet->data.asBytes;
1997 MifareU_Counter_Tearoff(payload->counter, payload->tearoff_time, payload->value);
1998 break;
2000 case CMD_HF_MIFARE_STATIC_NONCE: {
2001 MifareHasStaticNonce();
2002 break;
2004 case CMD_HF_MIFARE_STATIC_ENCRYPTED_NONCE: {
2005 struct p {
2006 uint8_t block_no;
2007 uint8_t key_type;
2008 uint8_t key[6];
2009 uint8_t block_no_nested;
2010 uint8_t key_type_nested;
2011 uint8_t key_nested[6];
2012 uint8_t nr_nonces;
2013 uint8_t resets;
2014 uint8_t addread;
2015 uint8_t addauth;
2016 uint8_t incblk2;
2017 uint8_t corruptnrar;
2018 uint8_t corruptnrarparity;
2019 } PACKED;
2020 struct p *payload = (struct p *) packet->data.asBytes;
2022 MifareHasStaticEncryptedNonce(payload->block_no, payload->key_type, payload->key, payload->block_no_nested, payload->key_type_nested, payload->key_nested, payload->nr_nonces, payload->resets & 1, (payload->resets >> 1) & 1, payload->addread, payload->addauth, payload->incblk2, payload->corruptnrar, payload->corruptnrarparity);
2023 break;
2025 #endif
2027 #ifdef WITH_NFCBARCODE
2028 case CMD_HF_THINFILM_READ: {
2029 ReadThinFilm();
2030 break;
2032 case CMD_HF_THINFILM_SIMULATE: {
2033 SimulateThinFilm(packet->data.asBytes, packet->length);
2034 break;
2036 #endif
2038 #ifdef WITH_ICLASS
2039 // Makes use of ISO14443a FPGA Firmware
2040 case CMD_HF_ICLASS_SNIFF: {
2041 struct p {
2042 uint8_t jam_search_len;
2043 uint8_t jam_search_string[];
2044 } PACKED;
2045 struct p *payload = (struct p *) packet->data.asBytes;
2046 SniffIClass(payload->jam_search_len, payload->jam_search_string);
2047 reply_ng(CMD_HF_ICLASS_SNIFF, PM3_SUCCESS, NULL, 0);
2048 break;
2050 case CMD_HF_ICLASS_SIMULATE: {
2052 struct p {
2053 uint8_t reader[4];
2054 uint8_t mac[4];
2055 } PACKED;
2056 struct p *payload = (struct p *) packet->data.asBytes;
2059 SimulateIClass(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes);
2060 break;
2062 case CMD_HF_ICLASS_READER: {
2063 iclass_card_select_t *payload = (iclass_card_select_t *) packet->data.asBytes;
2064 ReaderIClass(payload->flags);
2065 break;
2067 case CMD_HF_ICLASS_EML_MEMSET: {
2068 //-----------------------------------------------------------------------------
2069 // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15) here although FPGA is not
2070 // involved in dealing with emulator memory. But if it is called later, it might
2071 // destroy the Emulator Memory.
2072 //-----------------------------------------------------------------------------
2073 FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15);
2074 struct p {
2075 uint16_t offset;
2076 uint16_t len;
2077 uint8_t data[];
2078 } PACKED;
2079 struct p *payload = (struct p *) packet->data.asBytes;
2080 emlSet(payload->data, payload->offset, payload->len);
2081 break;
2083 case CMD_HF_ICLASS_WRITEBL: {
2084 iClass_WriteBlock(packet->data.asBytes);
2085 break;
2087 case CMD_HF_ICLASS_READBL: {
2088 iClass_ReadBlock(packet->data.asBytes);
2089 break;
2091 case CMD_HF_ICLASS_CHKKEYS: {
2092 iClass_Authentication_fast((iclass_chk_t *)packet->data.asBytes);
2093 break;
2095 case CMD_HF_ICLASS_DUMP: {
2096 iClass_Dump(packet->data.asBytes);
2097 break;
2099 case CMD_HF_ICLASS_RESTORE: {
2100 iClass_Restore((iclass_restore_req_t *)packet->data.asBytes);
2101 break;
2103 case CMD_HF_ICLASS_RECOVER: {
2104 iClass_Recover((iclass_recover_req_t *)packet->data.asBytes);
2105 break;
2107 case CMD_HF_ICLASS_CREDIT_EPURSE: {
2108 iclass_credit_epurse((iclass_credit_epurse_t *)packet->data.asBytes);
2109 break;
2111 #endif
2113 #ifdef WITH_HFSNIFF
2114 case CMD_HF_SNIFF: {
2115 struct p {
2116 uint32_t samplesToSkip;
2117 uint32_t triggersToSkip;
2118 uint8_t skipMode;
2119 uint8_t skipRatio;
2120 } PACKED;
2121 struct p *payload = (struct p *) packet->data.asBytes;
2123 uint16_t len = 0;
2124 int res = HfSniff(payload->samplesToSkip, payload->triggersToSkip, &len, payload->skipMode, payload->skipRatio);
2126 struct {
2127 uint16_t len;
2128 } PACKED retval;
2129 retval.len = len;
2130 reply_ng(CMD_HF_SNIFF, res, (uint8_t *)&retval, sizeof(retval));
2131 break;
2133 #endif
2135 #ifdef WITH_HFPLOT
2136 case CMD_FPGAMEM_DOWNLOAD: {
2137 HfPlotDownload();
2138 break;
2140 #endif
2142 #ifdef WITH_SMARTCARD
2143 case CMD_SMART_ATR: {
2144 SmartCardAtr();
2145 break;
2147 case CMD_SMART_SETBAUD: {
2148 SmartCardSetBaud(packet->oldarg[0]);
2149 break;
2151 case CMD_SMART_SETCLOCK: {
2152 struct p {
2153 uint32_t new_clk;
2154 } PACKED;
2155 struct p *payload = (struct p *) packet->data.asBytes;
2156 SmartCardSetClock(payload->new_clk);
2157 break;
2159 case CMD_SMART_RAW: {
2160 SmartCardRaw((smart_card_raw_t *) packet->data.asBytes);
2161 break;
2163 case CMD_SMART_UPLOAD: {
2164 // upload file from client
2165 struct p {
2166 uint32_t idx;
2167 uint32_t bytes_in_packet;
2168 uint16_t crc;
2169 uint8_t data[400];
2170 } PACKED;
2171 struct p *payload = (struct p *) packet->data.asBytes;
2172 uint8_t *mem = BigBuf_get_addr();
2173 memcpy(mem + payload->idx, payload->data, payload->bytes_in_packet);
2175 uint8_t a = 0, b = 0;
2176 compute_crc(CRC_14443_A, mem + payload->idx, payload->bytes_in_packet, &a, &b);
2177 int res = PM3_SUCCESS;
2178 if (payload->crc != (a << 8 | b)) {
2179 DbpString("CRC Failed");
2180 res = PM3_ESOFT;
2182 reply_ng(CMD_SMART_UPLOAD, res, NULL, 0);
2183 break;
2185 case CMD_SMART_UPGRADE: {
2186 struct p {
2187 uint16_t fw_size;
2188 uint16_t crc;
2189 } PACKED;
2190 struct p *payload = (struct p *) packet->data.asBytes;
2192 uint8_t *fwdata = BigBuf_get_addr();
2193 uint8_t a = 0, b = 0;
2194 compute_crc(CRC_14443_A, fwdata, payload->fw_size, &a, &b);
2196 if (payload->crc != (a << 8 | b)) {
2197 Dbprintf("CRC Failed, 0x[%04x] != 0x[%02x%02x]", payload->crc, a, b);
2198 reply_ng(CMD_SMART_UPGRADE, PM3_ESOFT, NULL, 0);
2199 } else {
2200 SmartCardUpgrade(payload->fw_size);
2202 fwdata = NULL;
2203 break;
2206 case CMD_HF_SAM_PICOPASS: {
2207 sam_picopass_get_pacs();
2208 break;
2210 case CMD_HF_SAM_SEOS: {
2211 // sam_seos_get_pacs();
2212 break;
2215 case CMD_HF_SAM_MFC: {
2216 // sam_mfc_get_pacs();
2217 break;
2220 #endif
2222 #ifdef WITH_FPC_USART
2223 case CMD_USART_TX: {
2224 LED_B_ON();
2225 usart_writebuffer_sync(packet->data.asBytes, packet->length);
2226 reply_ng(CMD_USART_TX, PM3_SUCCESS, NULL, 0);
2227 LED_B_OFF();
2228 break;
2230 case CMD_USART_RX: {
2231 LED_B_ON();
2232 struct p {
2233 uint32_t waittime;
2234 } PACKED;
2235 struct p *payload = (struct p *) packet->data.asBytes;
2237 uint16_t available;
2238 uint16_t pre_available = 0;
2239 uint8_t *dest = BigBuf_malloc(USART_FIFOLEN);
2240 uint32_t wait = payload->waittime;
2242 StartTicks();
2244 uint32_t ti = GetTickCount();
2246 while (true) {
2247 WaitMS(50);
2248 available = usart_rxdata_available();
2249 if (available > pre_available) {
2250 // When receiving data, reset timer and shorten timeout
2251 ti = GetTickCount();
2252 wait = 50;
2253 pre_available = available;
2254 continue;
2256 // We stop either after waittime if no data or 50ms after last data received
2257 if (GetTickCountDelta(ti) > wait)
2258 break;
2260 if (available > 0) {
2261 uint16_t len = usart_read_ng(dest, available);
2262 reply_ng(CMD_USART_RX, PM3_SUCCESS, dest, len);
2263 } else {
2264 reply_ng(CMD_USART_RX, PM3_ENODATA, NULL, 0);
2267 StopTicks();
2268 BigBuf_free();
2269 LED_B_OFF();
2270 break;
2272 case CMD_USART_TXRX: {
2273 LED_B_ON();
2274 struct p {
2275 uint32_t waittime;
2276 uint8_t data[];
2277 } PACKED;
2278 struct p *payload = (struct p *) packet->data.asBytes;
2279 usart_writebuffer_sync(payload->data, packet->length - sizeof(payload));
2281 uint16_t available;
2282 uint16_t pre_available = 0;
2283 uint8_t *dest = BigBuf_malloc(USART_FIFOLEN);
2284 uint32_t wait = payload->waittime;
2286 StartTicks();
2288 uint32_t ti = GetTickCount();
2290 while (true) {
2291 WaitMS(50);
2292 available = usart_rxdata_available();
2293 if (available > pre_available) {
2294 // When receiving data, reset timer and shorten timeout
2295 ti = GetTickCount();
2296 wait = 50;
2297 pre_available = available;
2298 continue;
2300 // We stop either after waittime if no data or 50ms after last data received
2301 if (GetTickCountDelta(ti) > wait)
2302 break;
2305 if (available > 0) {
2306 uint16_t len = usart_read_ng(dest, available);
2307 reply_ng(CMD_USART_TXRX, PM3_SUCCESS, dest, len);
2308 } else {
2309 reply_ng(CMD_USART_TXRX, PM3_ENODATA, NULL, 0);
2312 StopTicks();
2313 BigBuf_free();
2314 LED_B_OFF();
2315 break;
2317 case CMD_USART_CONFIG: {
2318 struct p {
2319 uint32_t baudrate;
2320 uint8_t parity;
2321 } PACKED;
2322 struct p *payload = (struct p *) packet->data.asBytes;
2323 usart_init(payload->baudrate, payload->parity);
2324 reply_ng(CMD_USART_CONFIG, PM3_SUCCESS, NULL, 0);
2325 break;
2327 #endif
2328 case CMD_BUFF_CLEAR: {
2329 BigBuf_Clear();
2330 BigBuf_free();
2331 break;
2333 #ifdef WITH_LF
2334 case CMD_MEASURE_ANTENNA_TUNING: {
2335 MeasureAntennaTuning();
2336 break;
2338 #endif
2339 case CMD_MEASURE_ANTENNA_TUNING_HF: {
2340 if (packet->length != 1)
2341 reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_EINVARG, NULL, 0);
2343 switch (packet->data.asBytes[0]) {
2344 case 1: // MEASURE_ANTENNA_TUNING_HF_START
2345 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
2346 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
2347 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
2348 reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_SUCCESS, NULL, 0);
2349 break;
2350 case 2:
2351 if (button_status == BUTTON_SINGLE_CLICK) {
2352 reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_EOPABORTED, NULL, 0);
2354 uint16_t volt = MeasureAntennaTuningHfData();
2355 reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_SUCCESS, (uint8_t *)&volt, sizeof(volt));
2356 break;
2357 case 3:
2358 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
2359 reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_SUCCESS, NULL, 0);
2360 break;
2361 default:
2362 reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_EINVARG, NULL, 0);
2363 break;
2365 break;
2367 case CMD_MEASURE_ANTENNA_TUNING_LF: {
2368 if (packet->length != 2)
2369 reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EINVARG, NULL, 0);
2371 switch (packet->data.asBytes[0]) {
2372 case 1: // MEASURE_ANTENNA_TUNING_LF_START
2373 // Let the FPGA drive the low-frequency antenna around 125kHz
2374 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
2375 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD);
2376 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, packet->data.asBytes[1]);
2377 reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, NULL, 0);
2378 break;
2379 case 2:
2380 if (button_status == BUTTON_SINGLE_CLICK) {
2381 reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EOPABORTED, NULL, 0);
2384 uint32_t volt = MeasureAntennaTuningLfData();
2385 reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, (uint8_t *)&volt, sizeof(volt));
2386 break;
2387 case 3:
2388 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
2389 reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, NULL, 0);
2390 break;
2391 default:
2392 reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EINVARG, NULL, 0);
2393 break;
2395 break;
2397 case CMD_LISTEN_READER_FIELD: {
2398 if (packet->length != sizeof(uint8_t))
2399 break;
2400 ListenReaderField(packet->data.asBytes[0]);
2401 reply_ng(CMD_LISTEN_READER_FIELD, PM3_EOPABORTED, NULL, 0);
2402 break;
2404 case CMD_FPGA_MAJOR_MODE_OFF: { // ## FPGA Control
2405 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
2406 SpinDelay(200);
2407 LED_D_OFF(); // LED D indicates field ON or OFF
2408 break;
2410 case CMD_DOWNLOAD_BIGBUF: {
2411 LED_B_ON();
2412 uint8_t *mem = BigBuf_get_addr();
2413 uint32_t startidx = packet->oldarg[0];
2414 uint32_t numofbytes = packet->oldarg[1];
2416 // arg0 = startindex
2417 // arg1 = length bytes to transfer
2418 // arg2 = BigBuf tracelen
2419 //Dbprintf("transfer to client parameters: %" PRIu32 " | %" PRIu32 " | %" PRIu32, startidx, numofbytes, packet->oldarg[2]);
2421 for (size_t offset = 0; offset < numofbytes; offset += PM3_CMD_DATA_SIZE) {
2422 size_t len = MIN((numofbytes - offset), PM3_CMD_DATA_SIZE);
2423 int result = reply_old(CMD_DOWNLOADED_BIGBUF, offset, len, BigBuf_get_traceLen(), &mem[startidx + offset], len);
2424 if (result != PM3_SUCCESS)
2425 Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", offset, offset + len, len, result);
2427 // Trigger a finish downloading signal with an ACK frame
2428 // arg0 = status of download transfer
2429 reply_mix(CMD_ACK, 1, 0, BigBuf_get_traceLen(), NULL, 0);
2430 LED_B_OFF();
2431 break;
2433 #ifdef WITH_LF
2434 case CMD_LF_UPLOAD_SIM_SAMPLES: {
2435 // iceman; since changing fpga_bitstreams clears bigbuff, Its better to call it before.
2436 // to be able to use this one for uploading data to device
2437 // flag =
2438 // b0 0 skip
2439 // 1 clear bigbuff
2440 struct p {
2441 uint8_t flag;
2442 uint16_t offset;
2443 uint8_t data[PM3_CMD_DATA_SIZE - sizeof(uint8_t) - sizeof(uint16_t)];
2444 } PACKED;
2445 struct p *payload = (struct p *) packet->data.asBytes;
2447 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
2449 if ((payload->flag & 0x1) == 0x1) {
2450 BigBuf_Clear_ext(false);
2451 BigBuf_free();
2454 // offset should not be over buffer
2455 if (payload->offset >= BigBuf_get_size()) {
2456 reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_EOVFLOW, NULL, 0);
2457 break;
2459 // ensure len bytes copied won't go past end of bigbuf
2460 uint16_t len = MIN(BigBuf_get_size() - payload->offset, sizeof(payload->data));
2462 uint8_t *mem = BigBuf_get_addr();
2464 memcpy(mem + payload->offset, &payload->data, len);
2465 reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0);
2466 break;
2468 #endif
2469 case CMD_DOWNLOAD_EML_BIGBUF: {
2470 LED_B_ON();
2471 uint8_t *mem = BigBuf_get_EM_addr();
2472 uint32_t startidx = packet->oldarg[0];
2473 uint32_t numofbytes = packet->oldarg[1];
2475 // arg0 = startindex
2476 // arg1 = length bytes to transfer
2477 // arg2 = RFU
2479 for (size_t i = 0; i < numofbytes; i += PM3_CMD_DATA_SIZE) {
2480 size_t len = MIN((numofbytes - i), PM3_CMD_DATA_SIZE);
2481 int result = reply_old(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len);
2482 if (result != PM3_SUCCESS)
2483 Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result);
2485 // Trigger a finish downloading signal with an ACK frame
2486 reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
2487 LED_B_OFF();
2488 break;
2490 case CMD_READ_MEM: {
2491 if (packet->length != sizeof(uint32_t))
2492 break;
2493 ReadMem(packet->data.asDwords[0]);
2494 break;
2496 case CMD_READ_MEM_DOWNLOAD: {
2497 LED_B_ON();
2499 size_t offset = packet->oldarg[0];
2500 size_t count = packet->oldarg[1];
2501 uint32_t flags = packet->oldarg[2];
2503 bool isok = true;
2504 uint8_t *base = NULL;
2506 bool raw_address_mode = ((flags & READ_MEM_DOWNLOAD_FLAG_RAW) == READ_MEM_DOWNLOAD_FLAG_RAW);
2507 if (!raw_address_mode) {
2509 base = (uint8_t *) _flash_start;
2511 size_t flash_size = get_flash_size();
2513 // Boundary check the offset.
2514 if (offset > flash_size) {
2515 isok = false;
2516 Dbprintf("reading mcu flash failed :: | out of bounds, offset %u count %u", offset, count);
2519 // Clip the length if it goes past the end of the flash memory.
2520 count = MIN(count, flash_size - offset);
2522 } else {
2523 // Allow reading from any memory address and length in special 'raw' mode.
2524 base = NULL;
2525 // Boundary check against end of addressable space.
2526 if (offset > 0)
2527 count = MIN(count, -offset);
2530 if (isok) {
2531 for (size_t pos = 0; pos < count; pos += PM3_CMD_DATA_SIZE) {
2532 size_t len = MIN((count - pos), PM3_CMD_DATA_SIZE);
2533 isok = 0 == reply_old(CMD_READ_MEM_DOWNLOADED, pos, len, 0, &base[offset + pos], len);
2534 if (!isok) {
2535 Dbprintf("transfer to client failed :: | pos %u len %u", pos, len);
2536 break;
2541 reply_old(CMD_ACK, 1, 0, 0, 0, 0);
2542 LED_B_OFF();
2543 break;
2545 #ifdef WITH_FLASH
2546 case CMD_SPIFFS_TEST: {
2547 test_spiffs();
2548 break;
2550 case CMD_SPIFFS_CHECK: {
2551 rdv40_spiffs_check();
2552 break;
2554 case CMD_SPIFFS_MOUNT: {
2555 rdv40_spiffs_lazy_mount();
2556 break;
2558 case CMD_SPIFFS_UNMOUNT: {
2559 rdv40_spiffs_lazy_unmount();
2560 break;
2562 case CMD_SPIFFS_PRINT_TREE: {
2563 rdv40_spiffs_safe_print_tree();
2564 break;
2566 case CMD_SPIFFS_PRINT_FSINFO: {
2567 rdv40_spiffs_safe_print_fsinfo();
2568 break;
2570 case CMD_SPIFFS_DOWNLOAD: {
2571 LED_B_ON();
2572 uint8_t filename[32];
2573 uint8_t *pfilename = packet->data.asBytes;
2574 memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN);
2575 if (g_dbglevel >= DBG_DEBUG) Dbprintf("Filename received for spiffs dump : %s", filename);
2577 uint32_t size = packet->oldarg[1];
2579 uint8_t *buff = BigBuf_malloc(size);
2580 if (buff == NULL) {
2581 if (g_dbglevel >= DBG_DEBUG) Dbprintf("Could not allocate buffer");
2582 // Trigger a finish downloading signal with an PM3_EMALLOC
2583 reply_ng(CMD_SPIFFS_DOWNLOAD, PM3_EMALLOC, NULL, 0);
2584 } else {
2585 rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)buff, size, RDV40_SPIFFS_SAFETY_SAFE);
2586 // arg0 = filename
2587 // arg1 = size
2588 // arg2 = RFU
2590 for (size_t i = 0; i < size; i += PM3_CMD_DATA_SIZE) {
2591 size_t len = MIN((size - i), PM3_CMD_DATA_SIZE);
2592 int result = reply_old(CMD_SPIFFS_DOWNLOADED, i, len, 0, buff + i, len);
2593 if (result != PM3_SUCCESS)
2594 Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result);
2596 // Trigger a finish downloading signal with an ACK frame
2597 reply_ng(CMD_SPIFFS_DOWNLOAD, PM3_SUCCESS, NULL, 0);
2598 BigBuf_free();
2600 LED_B_OFF();
2601 break;
2603 case CMD_SPIFFS_STAT: {
2604 LED_B_ON();
2605 uint8_t filename[32];
2606 uint8_t *pfilename = packet->data.asBytes;
2607 memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN);
2608 if (g_dbglevel >= DBG_DEBUG) {
2609 Dbprintf("Filename received for spiffs STAT : %s", filename);
2612 int changed = rdv40_spiffs_lazy_mount();
2613 uint32_t size = size_in_spiffs((char *)filename);
2614 if (changed) {
2615 rdv40_spiffs_lazy_unmount();
2618 reply_ng(CMD_SPIFFS_STAT, PM3_SUCCESS, (uint8_t *)&size, sizeof(uint32_t));
2619 LED_B_OFF();
2620 break;
2622 case CMD_SPIFFS_REMOVE: {
2623 LED_B_ON();
2625 struct p {
2626 uint8_t len;
2627 uint8_t fn[32];
2628 } PACKED;
2629 struct p *payload = (struct p *) packet->data.asBytes;
2631 if (g_dbglevel >= DBG_DEBUG) {
2632 Dbprintf("Filename received for spiffs REMOVE : %s", payload->fn);
2635 rdv40_spiffs_remove((char *)payload->fn, RDV40_SPIFFS_SAFETY_SAFE);
2636 reply_ng(CMD_SPIFFS_REMOVE, PM3_SUCCESS, NULL, 0);
2637 LED_B_OFF();
2638 break;
2640 case CMD_SPIFFS_RENAME: {
2641 LED_B_ON();
2642 struct p {
2643 uint8_t slen;
2644 uint8_t src[32];
2645 uint8_t dlen;
2646 uint8_t dest[32];
2647 } PACKED;
2648 struct p *payload = (struct p *) packet->data.asBytes;
2650 if (g_dbglevel >= DBG_DEBUG) {
2651 Dbprintf("SPIFFS RENAME");
2652 Dbprintf("Source........ %s", payload->src);
2653 Dbprintf("Destination... %s", payload->dest);
2655 rdv40_spiffs_rename((char *)payload->src, (char *)payload->dest, RDV40_SPIFFS_SAFETY_SAFE);
2656 reply_ng(CMD_SPIFFS_RENAME, PM3_SUCCESS, NULL, 0);
2657 LED_B_OFF();
2658 break;
2660 case CMD_SPIFFS_COPY: {
2661 LED_B_ON();
2662 struct p {
2663 uint8_t slen;
2664 uint8_t src[32];
2665 uint8_t dlen;
2666 uint8_t dest[32];
2667 } PACKED;
2668 struct p *payload = (struct p *) packet->data.asBytes;
2670 if (g_dbglevel >= DBG_DEBUG) {
2671 Dbprintf("SPIFFS COPY");
2672 Dbprintf("Source........ %s", payload->src);
2673 Dbprintf("Destination... %s", payload->dest);
2675 rdv40_spiffs_copy((char *)payload->src, (char *)payload->dest, RDV40_SPIFFS_SAFETY_SAFE);
2676 reply_ng(CMD_SPIFFS_COPY, PM3_SUCCESS, NULL, 0);
2677 LED_B_OFF();
2678 break;
2680 case CMD_SPIFFS_WRITE: {
2681 LED_B_ON();
2683 flashmem_write_t *payload = (flashmem_write_t *)packet->data.asBytes;
2685 if (g_dbglevel >= DBG_DEBUG) {
2686 Dbprintf("SPIFFS WRITE, dest `%s` with APPEND set to: %c", payload->fn, payload->append ? 'Y' : 'N');
2689 if (payload->append) {
2690 rdv40_spiffs_append((char *) payload->fn, payload->data, payload->bytes_in_packet, RDV40_SPIFFS_SAFETY_SAFE);
2691 } else {
2692 rdv40_spiffs_write((char *) payload->fn, payload->data, payload->bytes_in_packet, RDV40_SPIFFS_SAFETY_SAFE);
2695 reply_ng(CMD_SPIFFS_WRITE, PM3_SUCCESS, NULL, 0);
2696 LED_B_OFF();
2697 break;
2699 case CMD_SPIFFS_WIPE: {
2700 LED_B_ON();
2701 rdv40_spiffs_safe_wipe();
2702 reply_ng(CMD_SPIFFS_WIPE, PM3_SUCCESS, NULL, 0);
2703 LED_B_OFF();
2704 break;
2706 case CMD_SPIFFS_ELOAD: {
2707 LED_B_ON();
2709 uint8_t *em = BigBuf_get_EM_addr();
2710 if (em == NULL) {
2711 reply_ng(CMD_SPIFFS_ELOAD, PM3_EMALLOC, NULL, 0);
2712 LED_B_OFF();
2713 break;
2716 char *fn = (char *)packet->data.asBytes;
2718 uint32_t size = size_in_spiffs(fn);
2719 if (size == 0) {
2720 reply_ng(CMD_SPIFFS_ELOAD, PM3_SUCCESS, NULL, 0);
2721 LED_B_OFF();
2722 break;
2725 rdv40_spiffs_read_as_filetype(fn, em, size, RDV40_SPIFFS_SAFETY_SAFE);
2726 reply_ng(CMD_SPIFFS_ELOAD, PM3_SUCCESS, NULL, 0);
2727 LED_B_OFF();
2728 break;
2730 case CMD_FLASHMEM_SET_SPIBAUDRATE: {
2731 if (packet->length != sizeof(uint32_t))
2732 break;
2733 FlashmemSetSpiBaudrate(packet->data.asDwords[0]);
2734 break;
2736 case CMD_FLASHMEM_WRITE: {
2737 LED_B_ON();
2739 flashmem_old_write_t *payload = (flashmem_old_write_t *)packet->data.asBytes;
2741 if (FlashInit() == false) {
2742 reply_ng(CMD_FLASHMEM_WRITE, PM3_EIO, NULL, 0);
2743 LED_B_OFF();
2744 break;
2747 if (payload->startidx == DEFAULT_T55XX_KEYS_OFFSET) {
2748 Flash_CheckBusy(BUSY_TIMEOUT);
2749 Flash_WriteEnable();
2750 Flash_Erase4k(3, 0xC);
2751 } else if (payload->startidx == DEFAULT_MF_KEYS_OFFSET) {
2752 Flash_CheckBusy(BUSY_TIMEOUT);
2753 Flash_WriteEnable();
2754 Flash_Erase4k(3, 0x8);
2755 Flash_CheckBusy(BUSY_TIMEOUT);
2756 Flash_WriteEnable();
2757 Flash_Erase4k(3, 0x9);
2758 Flash_CheckBusy(BUSY_TIMEOUT);
2759 Flash_WriteEnable();
2760 Flash_Erase4k(3, 0xA);
2761 } else if (payload->startidx == DEFAULT_ICLASS_KEYS_OFFSET) {
2762 Flash_CheckBusy(BUSY_TIMEOUT);
2763 Flash_WriteEnable();
2764 Flash_Erase4k(3, 0xB);
2765 } else if (payload->startidx == FLASH_MEM_SIGNATURE_OFFSET) {
2766 Flash_CheckBusy(BUSY_TIMEOUT);
2767 Flash_WriteEnable();
2768 Flash_Erase4k(3, 0xF);
2771 uint16_t res = Flash_Write(payload->startidx, payload->data, payload->len);
2773 reply_ng(CMD_FLASHMEM_WRITE, (res == payload->len) ? PM3_SUCCESS : PM3_ESOFT, NULL, 0);
2774 LED_B_OFF();
2775 break;
2777 case CMD_FLASHMEM_WIPE: {
2778 LED_B_ON();
2779 uint8_t page = packet->oldarg[0];
2780 uint8_t initialwipe = packet->oldarg[1];
2781 bool isok = false;
2782 if (initialwipe) {
2783 isok = Flash_WipeMemory();
2784 reply_mix(CMD_ACK, isok, 0, 0, 0, 0);
2785 LED_B_OFF();
2786 break;
2788 if (page < 3) {
2789 isok = Flash_WipeMemoryPage(page);
2790 // let spiffs check and update its info post flash erase
2791 rdv40_spiffs_check();
2794 reply_mix(CMD_ACK, isok, 0, 0, 0, 0);
2795 LED_B_OFF();
2796 break;
2798 case CMD_FLASHMEM_DOWNLOAD: {
2800 LED_B_ON();
2801 uint8_t *mem = BigBuf_malloc(PM3_CMD_DATA_SIZE);
2802 uint32_t startidx = packet->oldarg[0];
2803 uint32_t numofbytes = packet->oldarg[1];
2804 // arg0 = startindex
2805 // arg1 = length bytes to transfer
2806 // arg2 = RFU
2808 if (FlashInit() == false) {
2809 break;
2812 for (size_t i = 0; i < numofbytes; i += PM3_CMD_DATA_SIZE) {
2813 size_t len = MIN((numofbytes - i), PM3_CMD_DATA_SIZE);
2814 Flash_CheckBusy(BUSY_TIMEOUT);
2815 bool isok = Flash_ReadDataCont(startidx + i, mem, len);
2816 if (isok == false)
2817 Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len);
2819 isok = reply_old(CMD_FLASHMEM_DOWNLOADED, i, len, 0, mem, len);
2820 if (isok != 0)
2821 Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
2823 FlashStop();
2825 reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
2826 BigBuf_free();
2827 LED_B_OFF();
2828 break;
2830 case CMD_FLASHMEM_INFO: {
2832 LED_B_ON();
2833 rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t));
2835 bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET, info->signature, FLASH_MEM_SIGNATURE_LEN);
2837 if (FlashInit()) {
2838 Flash_UniqueID(info->flashid);
2839 FlashStop();
2841 reply_mix(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t));
2842 BigBuf_free();
2844 LED_B_OFF();
2845 break;
2847 #endif
2848 #ifdef WITH_LF
2849 case CMD_LF_SET_DIVISOR: {
2850 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
2851 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, packet->data.asBytes[0]);
2852 break;
2854 #endif
2855 case CMD_SET_ADC_MUX: {
2856 switch (packet->data.asBytes[0]) {
2857 case 0:
2858 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
2859 break;
2860 case 2:
2861 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
2862 break;
2863 #ifndef WITH_FPC_USART
2864 case 1:
2865 SetAdcMuxFor(GPIO_MUXSEL_LORAW);
2866 break;
2867 case 3:
2868 SetAdcMuxFor(GPIO_MUXSEL_HIRAW);
2869 break;
2870 #endif
2872 break;
2874 case CMD_VERSION: {
2875 SendVersion();
2876 break;
2878 case CMD_STATUS: {
2879 if (packet->length == 4)
2880 SendStatus(packet->data.asDwords[0]);
2881 else
2882 SendStatus(CONN_SPEED_TEST_MIN_TIME_DEFAULT);
2883 break;
2885 case CMD_TIA: {
2887 while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
2888 uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF;
2889 Dbprintf(" Slow clock old measured value:.........%d Hz", (16 * MAINCK) / mainf);
2890 TimingIntervalAcquisition();
2892 while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
2893 mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF;
2894 Dbprintf(""); // first message gets lost
2895 Dbprintf(" Slow clock new measured value:.........%d Hz", (16 * MAINCK) / mainf);
2896 reply_ng(CMD_TIA, PM3_SUCCESS, NULL, 0);
2897 break;
2899 case CMD_STANDALONE: {
2901 struct p {
2902 uint8_t arg;
2903 uint8_t mlen;
2904 uint8_t mode[10];
2905 } PACKED;
2907 struct p *payload = (struct p *) packet->data.asBytes;
2909 uint8_t *bb = BigBuf_get_EM_addr();
2910 if (payload->mlen == 0) {
2911 bb[0] = payload->arg;
2912 } else {
2913 memcpy(bb, payload->mode, payload->mlen);
2916 RunMod();
2917 break;
2919 case CMD_CAPABILITIES: {
2920 SendCapabilities();
2921 break;
2923 case CMD_PING: {
2924 reply_ng(CMD_PING, PM3_SUCCESS, packet->data.asBytes, packet->length);
2925 break;
2927 #ifdef WITH_LCD
2928 case CMD_LCD_RESET: {
2929 LCDReset();
2930 break;
2932 case CMD_LCD: {
2933 LCDSend(packet->oldarg[0]);
2934 break;
2936 #endif
2937 case CMD_FINISH_WRITE:
2938 case CMD_HARDWARE_RESET: {
2939 usb_disable();
2941 // (iceman) why this wait?
2942 SpinDelay(1000);
2943 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
2944 // We're going to reset, and the bootrom will take control.
2945 for (;;) {}
2946 break;
2948 case CMD_START_FLASH: {
2949 if (g_common_area.flags.bootrom_present) {
2950 g_common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
2952 usb_disable();
2953 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
2954 // We're going to flash, and the bootrom will take control.
2955 for (;;) {}
2956 break;
2958 case CMD_DEVICE_INFO: {
2959 uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
2960 if (g_common_area.flags.bootrom_present) {
2961 dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
2963 reply_old(CMD_DEVICE_INFO, dev_info, 0, 0, 0, 0);
2964 break;
2966 default: {
2967 Dbprintf("%s: 0x%04x", "unknown command:", packet->cmd);
2968 break;
2973 void __attribute__((noreturn)) AppMain(void) {
2975 SpinDelay(100);
2976 BigBuf_initialize();
2978 // Add stack canary
2979 for (uint32_t *p = _stack_start; p + 0x200 < _stack_end ; ++p) {
2980 *p = 0xdeadbeef;
2983 LEDsoff();
2985 // The FPGA gets its clock from us from PCK0 output, so set that up.
2986 AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
2987 AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;
2988 AT91C_BASE_PMC->PMC_SCER |= AT91C_PMC_PCK0;
2989 // PCK0 is PLL clock / 4 = 96MHz / 4 = 24MHz
2990 AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_4; // 4 for 24MHz pck0, 2 for 48 MHZ pck0
2991 AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0;
2993 // Reset SPI
2994 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
2995 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; // errata says it needs twice to be correctly set.
2997 // Reset SSC
2998 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
3000 // Configure MUX
3001 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
3003 // Load the FPGA image, which we have stored in our flash.
3004 // (the HF version by default)
3005 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
3007 StartTickCount();
3009 #ifdef WITH_LCD
3010 LCDInit();
3011 #endif
3013 #ifdef WITH_SMARTCARD
3014 I2C_init(false);
3015 #endif
3017 #ifdef WITH_FLASH
3018 if (FlashInit()) {
3019 uint64_t flash_uniqueID = 0;
3020 if (!Flash_CheckBusy(BUSY_TIMEOUT)) { // OK because firmware was built for devices with flash
3021 Flash_UniqueID((uint8_t *)(&flash_uniqueID));
3023 FlashStop();
3024 usb_update_serial(flash_uniqueID);
3026 #endif
3029 #ifdef WITH_FLASH
3030 // If flash is not present, BUSY_TIMEOUT kicks in, let's do it after USB
3031 loadT55xxConfig();
3034 // Enforce a spiffs check/garbage collection at boot so we are likely to never
3035 // fall under the 2 contigous free blocks availables
3036 // This is a time-consuming process on large flash.
3037 rdv40_spiffs_check();
3038 #endif
3040 #ifdef WITH_FPC_USART
3041 usart_init(USART_BAUD_RATE, USART_PARITY);
3042 #endif
3044 allow_send_wtx = true;
3046 // This is made as late as possible to ensure enumeration without timeout
3047 // against device such as http://www.hobbytronics.co.uk/usb-host-board-v2
3048 // In other words, keep the interval between usb_enable() and the main loop as short as possible.
3049 // (AT91F_CDC_Enumerate() will be called in the main loop)
3050 usb_disable();
3051 usb_enable();
3053 for (;;) {
3054 WDT_HIT();
3056 if (*_stack_start != 0xdeadbeef) {
3057 Dbprintf("DEBUG: increase stack size, currently " _YELLOW_("%d") " bytes", (uint32_t)_stack_end - (uint32_t)_stack_start);
3058 Dbprintf("Stack overflow detected");
3059 Dbprintf("--> Unplug your device now! <--");
3060 hf_field_off();
3061 while (1);
3064 // Check if there is a packet available
3065 PacketCommandNG rx;
3066 memset(&rx.data, 0, sizeof(rx.data));
3068 int ret = receive_ng(&rx);
3069 if (ret == PM3_SUCCESS) {
3070 PacketReceived(&rx);
3071 } else if (ret != PM3_ENODATA) {
3073 Dbprintf("Error in frame reception: %d %s", ret, (ret == PM3_EIO) ? "PM3_EIO" : "");
3074 // TODO if error, shall we resync ?
3077 // Press button for one second to enter a possible standalone mode
3078 button_status = BUTTON_HELD(1000);
3079 if (button_status == BUTTON_HOLD) {
3081 * So this is the trigger to execute a standalone mod. Generic entrypoint by following the standalone/standalone.h headerfile
3082 * All standalone mod "main loop" should be the RunMod() function.
3084 allow_send_wtx = false;
3085 RunMod();
3086 allow_send_wtx = true;