Add 'hf 15 csetuid' command to set UID on ISO15693 Magic tags (#842)
[proxmark3-svn] / armsrc / appmain.c
CommitLineData
15c4dc5a 1//-----------------------------------------------------------------------------
15c4dc5a 2// Jonathan Westhues, Mar 2006
3// Edits by Gerhard de Koning Gans, Sep 2007 (##)
bd20f8f4 4//
5// This code is licensed to you under the terms of the GNU GPL, version 2 or,
6// at your option, any later version. See the LICENSE.txt file for the text of
7// the license.
8//-----------------------------------------------------------------------------
9// The main application code. This is the first thing called after start.c
10// executes.
15c4dc5a 11//-----------------------------------------------------------------------------
12
b8e461ff 13#include <stdarg.h>
14
902cb3c0 15#include "usb_cdc.h"
16#include "cmd.h"
e30c654b 17#include "proxmark3.h"
15c4dc5a 18#include "apps.h"
472345da 19#include "fpga.h"
f7e3ed82 20#include "util.h"
9ab7a6c7 21#include "printf.h"
22#include "string.h"
15c4dc5a 23#include "legicrf.h"
1b902aa0 24#include "legicrfsim.h"
b8e461ff 25#include "hitag2.h"
26#include "hitagS.h"
5ea2a248 27#include "iso14443b.h"
d9de20fa 28#include "iso15693.h"
31abe49f 29#include "lfsampling.h"
3000dc4e 30#include "BigBuf.h"
c89274cc 31#include "mifareutil.h"
a8561e35 32#include "mifaresim.h"
d10e08ae 33#include "pcf7931.h"
050aa18b 34#include "i2c.h"
fc52fbd4 35#include "hfsnoop.h"
36#include "fpgaloader.h"
15c4dc5a 37#ifdef WITH_LCD
902cb3c0 38 #include "LCD.h"
15c4dc5a 39#endif
43591e64 40
a9104f7e 41static uint32_t hw_capabilities;
15c4dc5a 42
e46fe044 43// Craig Young - 14a stand-alone code
854fdf15 44#ifdef WITH_ISO14443a
e46fe044
CY
45 #include "iso14443a.h"
46#endif
47
15c4dc5a 48//=============================================================================
49// A buffer where we can queue things up to be sent through the FPGA, for
50// any purpose (fake tag, as reader, whatever). We go MSB first, since that
51// is the order in which they go out on the wire.
52//=============================================================================
53
6a1f2d82 54#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
55uint8_t ToSend[TOSEND_BUFFER_SIZE];
15c4dc5a 56int ToSendMax;
57static int ToSendBit;
58struct common_area common_area __attribute__((section(".commonarea")));
59
15c4dc5a 60void ToSendReset(void)
61{
62 ToSendMax = -1;
63 ToSendBit = 8;
64}
65
66void ToSendStuffBit(int b)
67{
68 if(ToSendBit >= 8) {
69 ToSendMax++;
70 ToSend[ToSendMax] = 0;
71 ToSendBit = 0;
72 }
73
74 if(b) {
75 ToSend[ToSendMax] |= (1 << (7 - ToSendBit));
76 }
77
78 ToSendBit++;
79
6a1f2d82 80 if(ToSendMax >= sizeof(ToSend)) {
15c4dc5a 81 ToSendBit = 0;
82 DbpString("ToSendStuffBit overflowed!");
83 }
84}
85
86//=============================================================================
87// Debug print functions, to go out over USB, to the usual PC-side client.
88//=============================================================================
89
90void DbpString(char *str)
91{
9440213d 92 byte_t len = strlen(str);
93 cmd_send(CMD_DEBUG_PRINT_STRING,len,0,0,(byte_t*)str,len);
15c4dc5a 94}
95
96#if 0
97void DbpIntegers(int x1, int x2, int x3)
98{
902cb3c0 99 cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0);
15c4dc5a 100}
101#endif
102
103void Dbprintf(const char *fmt, ...) {
104// should probably limit size here; oh well, let's just use a big buffer
105 char output_string[128];
106 va_list ap;
107
108 va_start(ap, fmt);
109 kvsprintf(fmt, output_string, 10, ap);
110 va_end(ap);
e30c654b 111
15c4dc5a 112 DbpString(output_string);
113}
114
9455b51c 115// prints HEX & ASCII
d19929cb 116void Dbhexdump(int len, uint8_t *d, bool bAsci) {
9455b51c 117 int l=0,i;
118 char ascii[9];
d19929cb 119
9455b51c 120 while (len>0) {
121 if (len>8) l=8;
122 else l=len;
123
124 memcpy(ascii,d,l);
d19929cb 125 ascii[l]=0;
9455b51c 126
127 // filter safe ascii
d19929cb 128 for (i=0;i<l;i++)
9455b51c 129 if (ascii[i]<32 || ascii[i]>126) ascii[i]='.';
d19929cb 130
131 if (bAsci) {
132 Dbprintf("%-8s %*D",ascii,l,d," ");
133 } else {
134 Dbprintf("%*D",l,d," ");
135 }
136
9455b51c 137 len-=8;
138 d+=8;
139 }
140}
141
15c4dc5a 142//-----------------------------------------------------------------------------
143// Read an ADC channel and block till it completes, then return the result
144// in ADC units (0 to 1023). Also a routine to average 32 samples and
145// return that.
146//-----------------------------------------------------------------------------
147static int ReadAdc(int ch)
2d51da38 148{
3b692427 149 // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value.
050aa18b 150 // AMPL_HI is a high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant
9b32625c 151 // 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.
3b692427 152 //
153 // The maths are:
154 // 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
155 //
9b32625c 156 // 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%)
15c4dc5a 157
2d51da38
I
158 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
159 AT91C_BASE_ADC->ADC_MR =
9b32625c 160 ADC_MODE_PRESCALE(63) | // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
161 ADC_MODE_STARTUP_TIME(1) | // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us
162 ADC_MODE_SAMPLE_HOLD_TIME(15); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us
3b692427 163
2d51da38
I
164 AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch);
165 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
15c4dc5a 166
2d51da38
I
167 while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) {};
168
050aa18b 169 return AT91C_BASE_ADC->ADC_CDR[ch] & 0x3ff;
15c4dc5a 170}
171
9ca155ba 172int AvgAdc(int ch) // was static - merlok
15c4dc5a 173{
174 int i;
175 int a = 0;
176
177 for(i = 0; i < 32; i++) {
178 a += ReadAdc(ch);
179 }
180
181 return (a + 15) >> 5;
182}
183
050aa18b 184static int AvgAdc_Voltage_HF(void)
185{
186 int AvgAdc_Voltage_Low, AvgAdc_Voltage_High;
187
188 AvgAdc_Voltage_Low= (MAX_ADC_HF_VOLTAGE_LOW * AvgAdc(ADC_CHAN_HF_LOW)) >> 10;
189 // if voltage range is about to be exceeded, use high voltage ADC channel if available (RDV40 only)
190 if (AvgAdc_Voltage_Low > MAX_ADC_HF_VOLTAGE_LOW - 300) {
191 AvgAdc_Voltage_High = (MAX_ADC_HF_VOLTAGE_HIGH * AvgAdc(ADC_CHAN_HF_HIGH)) >> 10;
192 if (AvgAdc_Voltage_High >= AvgAdc_Voltage_Low) {
193 return AvgAdc_Voltage_High;
194 }
195 }
196 return AvgAdc_Voltage_Low;
197}
198
199static int AvgAdc_Voltage_LF(void)
200{
201 return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10;
202}
203
fdcfbdcc 204void MeasureAntennaTuningLfOnly(int *vLf125, int *vLf134, int *peakf, int *peakv, uint8_t LF_Results[])
15c4dc5a 205{
9b32625c 206 int i, adcval = 0, peak = 0;
15c4dc5a 207
208/*
209 * Sweeps the useful LF range of the proxmark from
210 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
211 * read the voltage in the antenna, the result left
212 * in the buffer is a graph which should clearly show
213 * the resonating frequency of your LF antenna
214 * ( hopefully around 95 if it is tuned to 125kHz!)
215 */
fdcfbdcc
RAB
216
217 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
b014c96d 218 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
2d51da38
I
219 SpinDelay(50);
220
2bdd68c3 221 for (i=255; i>=19; i--) {
fdcfbdcc 222 WDT_HIT();
15c4dc5a 223 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
224 SpinDelay(20);
050aa18b 225 adcval = AvgAdc_Voltage_LF();
fdcfbdcc
RAB
226 if (i==95) *vLf125 = adcval; // voltage at 125Khz
227 if (i==89) *vLf134 = adcval; // voltage at 134Khz
15c4dc5a 228
2d51da38 229 LF_Results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes
2bdd68c3 230 if(LF_Results[i] > peak) {
fdcfbdcc 231 *peakv = adcval;
2bdd68c3 232 peak = LF_Results[i];
fdcfbdcc 233 *peakf = i;
9f693930 234 //ptr = i;
15c4dc5a 235 }
236 }
237
2bdd68c3 238 for (i=18; i >= 0; i--) LF_Results[i] = 0;
fdcfbdcc
RAB
239
240 return;
241}
242
243void MeasureAntennaTuningHfOnly(int *vHf)
244{
15c4dc5a 245 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
fdcfbdcc
RAB
246 LED_A_ON();
247 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
5ea2a248 248 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
15c4dc5a 249 SpinDelay(20);
050aa18b 250 *vHf = AvgAdc_Voltage_HF();
fdcfbdcc 251 LED_A_OFF();
fdcfbdcc
RAB
252 return;
253}
254
255void MeasureAntennaTuning(int mode)
256{
257 uint8_t LF_Results[256] = {0};
258 int peakv = 0, peakf = 0;
259 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
260
261 LED_B_ON();
262
263 if (((mode & FLAG_TUNE_ALL) == FLAG_TUNE_ALL) && (FpgaGetCurrent() == FPGA_BITSTREAM_HF)) {
264 // Reverse "standard" order if HF already loaded, to avoid unnecessary swap.
265 MeasureAntennaTuningHfOnly(&vHf);
266 MeasureAntennaTuningLfOnly(&vLf125, &vLf134, &peakf, &peakv, LF_Results);
267 } else {
268 if (mode & FLAG_TUNE_LF) {
269 MeasureAntennaTuningLfOnly(&vLf125, &vLf134, &peakf, &peakv, LF_Results);
270 }
271 if (mode & FLAG_TUNE_HF) {
272 MeasureAntennaTuningHfOnly(&vHf);
273 }
274 }
15c4dc5a 275
d040cb90 276 cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125>>1 | (vLf134>>1<<16), vHf, peakf | (peakv>>1<<16), LF_Results, 256);
d19929cb 277 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
2bdd68c3 278 LED_B_OFF();
279 return;
15c4dc5a 280}
281
282void MeasureAntennaTuningHf(void)
283{
284 int vHf = 0; // in mV
285
286 DbpString("Measuring HF antenna, press button to exit");
287
3b692427 288 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
289 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
5ea2a248 290 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
3b692427 291
15c4dc5a 292 for (;;) {
050aa18b 293 SpinDelay(500);
294 vHf = AvgAdc_Voltage_HF();
e30c654b 295
15c4dc5a 296 Dbprintf("%d mV",vHf);
297 if (BUTTON_PRESS()) break;
298 }
299 DbpString("cancelled");
3b692427 300
301 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
302
15c4dc5a 303}
304
305
15c4dc5a 306void ReadMem(int addr)
307{
f7e3ed82 308 const uint8_t *data = ((uint8_t *)addr);
15c4dc5a 309
310 Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x",
311 addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
312}
313
314/* osimage version information is linked in */
315extern struct version_information version_information;
316/* bootrom version information is pointed to from _bootphase1_version_pointer */
0fa01ec7 317extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
472345da 318
050aa18b 319
a9104f7e 320void set_hw_capabilities(void)
321{
322 if (I2C_is_available()) {
323 hw_capabilities |= HAS_SMARTCARD_SLOT;
324 }
325
326 if (false) { // TODO: implement a test
327 hw_capabilities |= HAS_EXTRA_FLASH_MEM;
328 }
329}
330
331
15c4dc5a 332void SendVersion(void)
333{
a9104f7e 334 set_hw_capabilities();
335
8e074056 336 char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
337 char VersionString[USB_CMD_DATA_SIZE] = { '\0' };
e30c654b 338
339 /* Try to find the bootrom version information. Expect to find a pointer at
15c4dc5a 340 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
341 * pointer, then use it.
342 */
343 char *bootrom_version = *(char**)&_bootphase1_version_pointer;
344 if( bootrom_version < &_flash_start || bootrom_version >= &_flash_end ) {
8e074056 345 strcat(VersionString, "bootrom version information appears invalid\n");
15c4dc5a 346 } else {
347 FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
8e074056 348 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
15c4dc5a 349 }
e30c654b 350
15c4dc5a 351 FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
8e074056 352 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
e30c654b 353
472345da 354 for (int i = 0; i < fpga_bitstream_num; i++) {
355 strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1);
050aa18b 356 strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
472345da 357 }
050aa18b 358
359 // test availability of SmartCard slot
360 if (I2C_is_available()) {
361 strncat(VersionString, "SmartCard Slot: available\n", sizeof(VersionString) - strlen(VersionString) - 1);
362 } else {
363 strncat(VersionString, "SmartCard Slot: not available\n", sizeof(VersionString) - strlen(VersionString) - 1);
364 }
365
e6153040 366 // Send Chip ID and used flash memory
0fa01ec7 367 uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start;
368 uint32_t compressed_data_section_size = common_area.arg1;
a9104f7e 369 cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, hw_capabilities, VersionString, strlen(VersionString));
15c4dc5a 370}
371
bfb01844 372// measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
373// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included.
67b7d6fa 374void printUSBSpeed(void)
bfb01844 375{
376 Dbprintf("USB Speed:");
67b7d6fa 377 Dbprintf(" Sending USB packets to client...");
bfb01844 378
67b7d6fa 379 #define USB_SPEED_TEST_MIN_TIME 1500 // in milliseconds
bfb01844 380 uint8_t *test_data = BigBuf_get_addr();
67b7d6fa 381 uint32_t end_time;
bfb01844 382
67b7d6fa 383 uint32_t start_time = end_time = GetTickCount();
384 uint32_t bytes_transferred = 0;
385
bfb01844 386 LED_B_ON();
67b7d6fa 387 while(end_time < start_time + USB_SPEED_TEST_MIN_TIME) {
388 cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 0, USB_CMD_DATA_SIZE, 0, test_data, USB_CMD_DATA_SIZE);
389 end_time = GetTickCount();
390 bytes_transferred += USB_CMD_DATA_SIZE;
bfb01844 391 }
392 LED_B_OFF();
393
67b7d6fa 394 Dbprintf(" Time elapsed: %dms", end_time - start_time);
395 Dbprintf(" Bytes transferred: %d", bytes_transferred);
396 Dbprintf(" USB Transfer Speed PM3 -> Client = %d Bytes/s",
397 1000 * bytes_transferred / (end_time - start_time));
bfb01844 398
399}
400
c89274cc
CY
401/**
402 * Prints runtime information about the PM3.
403**/
67b7d6fa 404void SendStatus(void)
c89274cc
CY
405{
406 BigBuf_print_status();
407 Fpga_print_status();
43591e64 408#ifdef WITH_SMARTCARD
409 I2C_print_status();
410#endif
c89274cc 411 printConfig(); //LF Sampling config
67b7d6fa 412 printUSBSpeed();
c89274cc 413 Dbprintf("Various");
43591e64 414 Dbprintf(" MF_DBGLEVEL........%d", MF_DBGLEVEL);
415 Dbprintf(" ToSendMax..........%d", ToSendMax);
416 Dbprintf(" ToSendBit..........%d", ToSendBit);
bfb01844 417
418 cmd_send(CMD_ACK,1,0,0,0,0);
c89274cc 419}
15c4dc5a 420
a2937cea 421#if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF_StandAlone)
15c4dc5a 422
15c4dc5a 423#define OPTS 2
424
86a83668
MHS
425void StandAloneMode()
426{
427 DbpString("Stand-alone mode! No PC necessary.");
15c4dc5a 428 // Oooh pretty -- notify user we're in elite samy mode now
429 LED(LED_RED, 200);
430 LED(LED_ORANGE, 200);
431 LED(LED_GREEN, 200);
432 LED(LED_ORANGE, 200);
433 LED(LED_RED, 200);
434 LED(LED_ORANGE, 200);
435 LED(LED_GREEN, 200);
436 LED(LED_ORANGE, 200);
437 LED(LED_RED, 200);
438
86a83668
MHS
439}
440
441#endif
442
443
444
445#ifdef WITH_ISO14443a_StandAlone
446void StandAloneMode14a()
447{
448 StandAloneMode();
449 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
450
15c4dc5a 451 int selected = 0;
44964fd1 452 bool playing = false, GotoRecord = false, GotoClone = false;
453 bool cardRead[OPTS] = {false};
86a83668
MHS
454 uint8_t readUID[10] = {0};
455 uint32_t uid_1st[OPTS]={0};
456 uint32_t uid_2nd[OPTS]={0};
c89274cc
CY
457 uint32_t uid_tmp1 = 0;
458 uint32_t uid_tmp2 = 0;
459 iso14a_card_select_t hi14a_card[OPTS];
15c4dc5a 460
15c4dc5a 461 LED(selected + 1, 0);
462
463 for (;;)
464 {
6e82300d 465 usb_poll();
86a83668 466 WDT_HIT();
15c4dc5a 467 SpinDelay(300);
468
44964fd1 469 if (GotoRecord || !cardRead[selected])
15c4dc5a 470 {
44964fd1 471 GotoRecord = false;
15c4dc5a 472 LEDsoff();
473 LED(selected + 1, 0);
474 LED(LED_RED2, 0);
475
476 // record
86a83668 477 Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
15c4dc5a 478 /* need this delay to prevent catching some weird data */
479 SpinDelay(500);
86a83668
MHS
480 /* Code for reading from 14a tag */
481 uint8_t uid[10] ={0};
482 uint32_t cuid;
483 iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
15c4dc5a 484
86a83668
MHS
485 for ( ; ; )
486 {
487 WDT_HIT();
c89274cc
CY
488 if (BUTTON_PRESS()) {
489 if (cardRead[selected]) {
490 Dbprintf("Button press detected -- replaying card in bank[%d]", selected);
491 break;
492 }
493 else if (cardRead[(selected+1)%OPTS]) {
494 Dbprintf("Button press detected but no card in bank[%d] so playing from bank[%d]", selected, (selected+1)%OPTS);
495 selected = (selected+1)%OPTS;
44964fd1 496 break;
c89274cc
CY
497 }
498 else {
499 Dbprintf("Button press detected but no stored tag to play. (Ignoring button)");
500 SpinDelay(300);
501 }
502 }
c04a4b60 503 if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0, true))
86a83668
MHS
504 continue;
505 else
506 {
507 Dbprintf("Read UID:"); Dbhexdump(10,uid,0);
508 memcpy(readUID,uid,10*sizeof(uint8_t));
c89274cc 509 uint8_t *dst = (uint8_t *)&uid_tmp1;
86a83668
MHS
510 // Set UID byte order
511 for (int i=0; i<4; i++)
512 dst[i] = uid[3-i];
c89274cc 513 dst = (uint8_t *)&uid_tmp2;
86a83668
MHS
514 for (int i=0; i<4; i++)
515 dst[i] = uid[7-i];
c89274cc
CY
516 if (uid_1st[(selected+1)%OPTS] == uid_tmp1 && uid_2nd[(selected+1)%OPTS] == uid_tmp2) {
517 Dbprintf("Card selected has same UID as what is stored in the other bank. Skipping.");
518 }
519 else {
520 if (uid_tmp2) {
521 Dbprintf("Bank[%d] received a 7-byte UID",selected);
522 uid_1st[selected] = (uid_tmp1)>>8;
523 uid_2nd[selected] = (uid_tmp1<<24) + (uid_tmp2>>8);
524 }
525 else {
526 Dbprintf("Bank[%d] received a 4-byte UID",selected);
527 uid_1st[selected] = uid_tmp1;
528 uid_2nd[selected] = uid_tmp2;
529 }
530 break;
531 }
86a83668
MHS
532 }
533 }
c89274cc
CY
534 Dbprintf("ATQA = %02X%02X",hi14a_card[selected].atqa[0],hi14a_card[selected].atqa[1]);
535 Dbprintf("SAK = %02X",hi14a_card[selected].sak);
86a83668
MHS
536 LEDsoff();
537 LED(LED_GREEN, 200);
538 LED(LED_ORANGE, 200);
539 LED(LED_GREEN, 200);
540 LED(LED_ORANGE, 200);
15c4dc5a 541
542 LEDsoff();
543 LED(selected + 1, 0);
15c4dc5a 544
c89274cc 545 // Next state is replay:
44964fd1 546 playing = true;
3fe4ff4f 547
44964fd1 548 cardRead[selected] = true;
86a83668 549 }
c89274cc 550 /* MF Classic UID clone */
44964fd1 551 else if (GotoClone)
3fe4ff4f 552 {
44964fd1 553 GotoClone=false;
c89274cc
CY
554 LEDsoff();
555 LED(selected + 1, 0);
556 LED(LED_ORANGE, 250);
3fe4ff4f 557
3fe4ff4f 558
c89274cc
CY
559 // record
560 Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
3fe4ff4f 561
c89274cc
CY
562 // wait for button to be released
563 while(BUTTON_PRESS())
564 {
565 // Delay cloning until card is in place
566 WDT_HIT();
567 }
568 Dbprintf("Starting clone. [Bank: %u]", selected);
569 // need this delay to prevent catching some weird data
570 SpinDelay(500);
571 // Begin clone function here:
572 /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
573 UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
574 memcpy(c.d.asBytes, data, 16);
575 SendCommand(&c);
576
577 Block read is similar:
578 UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
579 We need to imitate that call with blockNo 0 to set a uid.
580
581 The get and set commands are handled in this file:
582 // Work with "magic Chinese" card
583 case CMD_MIFARE_CSETBLOCK:
584 MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
585 break;
586 case CMD_MIFARE_CGETBLOCK:
587 MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
588 break;
589
590 mfCSetUID provides example logic for UID set workflow:
591 -Read block0 from card in field with MifareCGetBlock()
592 -Configure new values without replacing reserved bytes
593 memcpy(block0, uid, 4); // Copy UID bytes from byte array
594 // Mifare UID BCC
595 block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
596 Bytes 5-7 are reserved SAK and ATQA for mifare classic
597 -Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
598 */
599 uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
600 // arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo
601 MifareCGetBlock(0x3F, 1, 0, oldBlock0);
602 if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1] && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
603 Dbprintf("No changeable tag detected. Returning to replay mode for bank[%d]", selected);
44964fd1 604 playing = true;
c89274cc
CY
605 }
606 else {
607 Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
608 memcpy(newBlock0,oldBlock0,16);
609 // Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
610
611 newBlock0[0] = uid_1st[selected]>>24;
612 newBlock0[1] = 0xFF & (uid_1st[selected]>>16);
613 newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
614 newBlock0[3] = 0xFF & (uid_1st[selected]);
615 newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
616 // arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
617 MifareCSetBlock(0, 0xFF,0, newBlock0);
618 MifareCGetBlock(0x3F, 1, 0, testBlock0);
619 if (memcmp(testBlock0,newBlock0,16)==0)
620 {
621 DbpString("Cloned successfull!");
44964fd1 622 cardRead[selected] = false; // Only if the card was cloned successfully should we clear it
623 playing = false;
624 GotoRecord = true;
c89274cc
CY
625 selected = (selected+1) % OPTS;
626 }
627 else {
628 Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
44964fd1 629 playing = true;
c89274cc
CY
630 }
631 }
632 LEDsoff();
633 LED(selected + 1, 0);
15c4dc5a 634
86a83668 635 }
15c4dc5a 636 // Change where to record (or begin playing)
44964fd1 637 else if (playing) // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
15c4dc5a 638 {
15c4dc5a 639 LEDsoff();
640 LED(selected + 1, 0);
641
642 // Begin transmitting
44964fd1 643 LED(LED_GREEN, 0);
644 DbpString("Playing");
645 for ( ; ; ) {
646 WDT_HIT();
647 int button_action = BUTTON_HELD(1000);
648 if (button_action == 0) { // No button action, proceed with sim
649 uint8_t data[512] = {0}; // in case there is a read command received we shouldn't break
650 Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected);
651 if (hi14a_card[selected].sak == 8 && hi14a_card[selected].atqa[0] == 4 && hi14a_card[selected].atqa[1] == 0) {
652 DbpString("Mifare Classic");
653 SimulateIso14443aTag(1,uid_1st[selected], uid_2nd[selected], data); // Mifare Classic
c89274cc 654 }
44964fd1 655 else if (hi14a_card[selected].sak == 0 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 0) {
656 DbpString("Mifare Ultralight");
657 SimulateIso14443aTag(2,uid_1st[selected],uid_2nd[selected],data); // Mifare Ultralight
15c4dc5a 658 }
44964fd1 659 else if (hi14a_card[selected].sak == 20 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 3) {
660 DbpString("Mifare DESFire");
661 SimulateIso14443aTag(3,uid_1st[selected],uid_2nd[selected],data); // Mifare DESFire
662 }
663 else {
664 Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
665 SimulateIso14443aTag(1,uid_1st[selected], uid_2nd[selected], data);
c89274cc 666 }
c89274cc 667 }
44964fd1 668 else if (button_action == BUTTON_SINGLE_CLICK) {
669 selected = (selected + 1) % OPTS;
670 Dbprintf("Done playing. Switching to record mode on bank %d",selected);
671 GotoRecord = true;
672 break;
673 }
674 else if (button_action == BUTTON_HOLD) {
675 Dbprintf("Playtime over. Begin cloning...");
676 GotoClone = true;
677 break;
678 }
679 WDT_HIT();
15c4dc5a 680 }
44964fd1 681
682 /* We pressed a button so ignore it here with a delay */
683 SpinDelay(300);
684 LEDsoff();
685 LED(selected + 1, 0);
15c4dc5a 686 }
687 }
688}
a2937cea 689#elif WITH_LF_StandAlone
86a83668
MHS
690// samy's sniff and repeat routine
691void SamyRun()
e46fe044 692{
86a83668
MHS
693 StandAloneMode();
694 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
e46fe044 695
53e2f2fa 696 int tops[OPTS], high[OPTS], low[OPTS];
15c4dc5a 697 int selected = 0;
698 int playing = 0;
3fe4ff4f 699 int cardRead = 0;
15c4dc5a 700
701 // Turn on selected LED
702 LED(selected + 1, 0);
703
704 for (;;)
705 {
6e82300d 706 usb_poll();
86a83668 707 WDT_HIT();
15c4dc5a 708
709 // Was our button held down or pressed?
710 int button_pressed = BUTTON_HELD(1000);
711 SpinDelay(300);
712
713 // Button was held for a second, begin recording
3fe4ff4f 714 if (button_pressed > 0 && cardRead == 0)
15c4dc5a 715 {
716 LEDsoff();
717 LED(selected + 1, 0);
718 LED(LED_RED2, 0);
719
720 // record
721 DbpString("Starting recording");
722
723 // wait for button to be released
724 while(BUTTON_PRESS())
725 WDT_HIT();
726
727 /* need this delay to prevent catching some weird data */
728 SpinDelay(500);
729
53e2f2fa 730 CmdHIDdemodFSK(1, &tops[selected], &high[selected], &low[selected], 0);
731 if (tops[selected] > 0)
732 Dbprintf("Recorded %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]);
733 else
734 Dbprintf("Recorded %x %x%08x", selected, high[selected], low[selected]);
15c4dc5a 735
736 LEDsoff();
737 LED(selected + 1, 0);
738 // Finished recording
739
740 // If we were previously playing, set playing off
741 // so next button push begins playing what we recorded
742 playing = 0;
3fe4ff4f 743
744 cardRead = 1;
745
746 }
747
748 else if (button_pressed > 0 && cardRead == 1)
749 {
750 LEDsoff();
751 LED(selected + 1, 0);
752 LED(LED_ORANGE, 0);
753
754 // record
53e2f2fa 755 if (tops[selected] > 0)
756 Dbprintf("Cloning %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]);
757 else
758 Dbprintf("Cloning %x %x%08x", selected, high[selected], low[selected]);
3fe4ff4f 759
760 // wait for button to be released
761 while(BUTTON_PRESS())
762 WDT_HIT();
763
764 /* need this delay to prevent catching some weird data */
765 SpinDelay(500);
766
5f84531b 767 CopyHIDtoT55x7(tops[selected] & 0x000FFFFF, high[selected], low[selected], (tops[selected] != 0 && ((high[selected]& 0xFFFFFFC0) != 0)), 0x1D);
53e2f2fa 768 if (tops[selected] > 0)
769 Dbprintf("Cloned %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]);
770 else
771 Dbprintf("Cloned %x %x%08x", selected, high[selected], low[selected]);
3fe4ff4f 772
773 LEDsoff();
774 LED(selected + 1, 0);
775 // Finished recording
776
777 // If we were previously playing, set playing off
778 // so next button push begins playing what we recorded
779 playing = 0;
780
781 cardRead = 0;
782
15c4dc5a 783 }
784
785 // Change where to record (or begin playing)
786 else if (button_pressed)
787 {
788 // Next option if we were previously playing
789 if (playing)
790 selected = (selected + 1) % OPTS;
791 playing = !playing;
792
793 LEDsoff();
794 LED(selected + 1, 0);
795
796 // Begin transmitting
797 if (playing)
798 {
799 LED(LED_GREEN, 0);
800 DbpString("Playing");
801 // wait for button to be released
802 while(BUTTON_PRESS())
803 WDT_HIT();
53e2f2fa 804 if (tops[selected] > 0)
805 Dbprintf("%x %x%08x%08x", selected, tops[selected], high[selected], low[selected]);
806 else
807 Dbprintf("%x %x%08x", selected, high[selected], low[selected]);
808
809 CmdHIDsimTAG(tops[selected], high[selected], low[selected], 0);
15c4dc5a 810 DbpString("Done playing");
811 if (BUTTON_HELD(1000) > 0)
812 {
813 DbpString("Exiting");
814 LEDsoff();
815 return;
816 }
817
818 /* We pressed a button so ignore it here with a delay */
819 SpinDelay(300);
820
821 // when done, we're done playing, move to next option
822 selected = (selected + 1) % OPTS;
823 playing = !playing;
824 LEDsoff();
825 LED(selected + 1, 0);
826 }
827 else
828 while(BUTTON_PRESS())
829 WDT_HIT();
830 }
831 }
832}
15c4dc5a 833
e46fe044 834#endif
15c4dc5a 835/*
836OBJECTIVE
837Listen and detect an external reader. Determine the best location
838for the antenna.
839
840INSTRUCTIONS:
841Inside the ListenReaderField() function, there is two mode.
842By default, when you call the function, you will enter mode 1.
843If you press the PM3 button one time, you will enter mode 2.
844If you press the PM3 button a second time, you will exit the function.
845
846DESCRIPTION OF MODE 1:
847This mode just listens for an external reader field and lights up green
848for HF and/or red for LF. This is the original mode of the detectreader
849function.
850
851DESCRIPTION OF MODE 2:
852This mode will visually represent, using the LEDs, the actual strength of the
853current compared to the maximum current detected. Basically, once you know
854what kind of external reader is present, it will help you spot the best location to place
855your antenna. You will probably not get some good results if there is a LF and a HF reader
856at the same place! :-)
857
858LIGHT SCHEME USED:
859*/
860static const char LIGHT_SCHEME[] = {
861 0x0, /* ---- | No field detected */
862 0x1, /* X--- | 14% of maximum current detected */
863 0x2, /* -X-- | 29% of maximum current detected */
864 0x4, /* --X- | 43% of maximum current detected */
865 0x8, /* ---X | 57% of maximum current detected */
866 0xC, /* --XX | 71% of maximum current detected */
867 0xE, /* -XXX | 86% of maximum current detected */
868 0xF, /* XXXX | 100% of maximum current detected */
869};
870static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]);
871
872void ListenReaderField(int limit)
873{
050aa18b 874 int lf_av, lf_av_new=0, lf_baseline= 0, lf_max;
875 int hf_av, hf_av_new=0, hf_baseline= 0, hf_max;
15c4dc5a 876 int mode=1, display_val, display_max, i;
877
050aa18b 878#define LF_ONLY 1
879#define HF_ONLY 2
880#define REPORT_CHANGE_PERCENT 5 // report new values only if they have changed at least by REPORT_CHANGE_PERCENT
881#define MIN_HF_FIELD 300 // in mode 1 signal HF field greater than MIN_HF_FIELD above baseline
882#define MIN_LF_FIELD 1200 // in mode 1 signal LF field greater than MIN_LF_FIELD above baseline
3b692427 883
884
885 // switch off FPGA - we don't want to measure our own signal
886 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
887 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
15c4dc5a 888
889 LEDsoff();
890
050aa18b 891 lf_av = lf_max = AvgAdc_Voltage_LF();
15c4dc5a 892
893 if(limit != HF_ONLY) {
050aa18b 894 Dbprintf("LF 125/134kHz Baseline: %dmV", lf_av);
15c4dc5a 895 lf_baseline = lf_av;
896 }
897
050aa18b 898 hf_av = hf_max = AvgAdc_Voltage_HF();
899
15c4dc5a 900 if (limit != LF_ONLY) {
050aa18b 901 Dbprintf("HF 13.56MHz Baseline: %dmV", hf_av);
15c4dc5a 902 hf_baseline = hf_av;
903 }
904
905 for(;;) {
050aa18b 906 SpinDelay(500);
15c4dc5a 907 if (BUTTON_PRESS()) {
15c4dc5a 908 switch (mode) {
909 case 1:
910 mode=2;
911 DbpString("Signal Strength Mode");
912 break;
913 case 2:
914 default:
915 DbpString("Stopped");
916 LEDsoff();
917 return;
918 break;
919 }
050aa18b 920 while (BUTTON_PRESS());
15c4dc5a 921 }
922 WDT_HIT();
923
924 if (limit != HF_ONLY) {
3b692427 925 if(mode == 1) {
050aa18b 926 if (lf_av - lf_baseline > MIN_LF_FIELD)
3b692427 927 LED_D_ON();
928 else
929 LED_D_OFF();
15c4dc5a 930 }
e30c654b 931
050aa18b 932 lf_av_new = AvgAdc_Voltage_LF();
15c4dc5a 933 // see if there's a significant change
050aa18b 934 if (ABS((lf_av - lf_av_new)*100/(lf_av?lf_av:1)) > REPORT_CHANGE_PERCENT) {
935 Dbprintf("LF 125/134kHz Field Change: %5dmV", lf_av_new);
15c4dc5a 936 lf_av = lf_av_new;
937 if (lf_av > lf_max)
938 lf_max = lf_av;
15c4dc5a 939 }
940 }
941
942 if (limit != LF_ONLY) {
943 if (mode == 1){
050aa18b 944 if (hf_av - hf_baseline > MIN_HF_FIELD)
3b692427 945 LED_B_ON();
946 else
947 LED_B_OFF();
15c4dc5a 948 }
e30c654b 949
050aa18b 950 hf_av_new = AvgAdc_Voltage_HF();
951
15c4dc5a 952 // see if there's a significant change
050aa18b 953 if (ABS((hf_av - hf_av_new)*100/(hf_av?hf_av:1)) > REPORT_CHANGE_PERCENT) {
954 Dbprintf("HF 13.56MHz Field Change: %5dmV", hf_av_new);
15c4dc5a 955 hf_av = hf_av_new;
956 if (hf_av > hf_max)
957 hf_max = hf_av;
15c4dc5a 958 }
959 }
e30c654b 960
15c4dc5a 961 if(mode == 2) {
962 if (limit == LF_ONLY) {
963 display_val = lf_av;
964 display_max = lf_max;
965 } else if (limit == HF_ONLY) {
966 display_val = hf_av;
967 display_max = hf_max;
968 } else { /* Pick one at random */
969 if( (hf_max - hf_baseline) > (lf_max - lf_baseline) ) {
970 display_val = hf_av;
971 display_max = hf_max;
972 } else {
973 display_val = lf_av;
974 display_max = lf_max;
975 }
976 }
977 for (i=0; i<LIGHT_LEN; i++) {
978 if (display_val >= ((display_max/LIGHT_LEN)*i) && display_val <= ((display_max/LIGHT_LEN)*(i+1))) {
979 if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF();
980 if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF();
981 if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF();
982 if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF();
983 break;
984 }
985 }
986 }
987 }
988}
989
f7e3ed82 990void UsbPacketReceived(uint8_t *packet, int len)
15c4dc5a 991{
992 UsbCommand *c = (UsbCommand *)packet;
15c4dc5a 993
902cb3c0 994// Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]);
995
15c4dc5a 996 switch(c->cmd) {
997#ifdef WITH_LF
31abe49f
MHS
998 case CMD_SET_LF_SAMPLING_CONFIG:
999 setSamplingConfig((sample_config *) c->d.asBytes);
1000 break;
15c4dc5a 1001 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
b9957414 1002 cmd_send(CMD_ACK,SampleLF(c->arg[0], c->arg[1]),0,0,0,0);
15c4dc5a 1003 break;
15c4dc5a 1004 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
1005 ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
1006 break;
b014c96d 1007 case CMD_LF_SNOOP_RAW_ADC_SAMPLES:
31abe49f 1008 cmd_send(CMD_ACK,SnoopLF(),0,0,0,0);
b014c96d 1009 break;
7e67e42f 1010 case CMD_HID_DEMOD_FSK:
be59094d 1011 CmdHIDdemodFSK(c->arg[0], 0, 0, 0, 1);
7e67e42f 1012 break;
1013 case CMD_HID_SIM_TAG:
be59094d 1014 CmdHIDsimTAG(c->arg[0], c->arg[1], c->arg[2], 1);
7e67e42f 1015 break;
abd6112f 1016 case CMD_FSK_SIM_TAG:
1017 CmdFSKsimTAG(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1018 break;
1019 case CMD_ASK_SIM_TAG:
1020 CmdASKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1021 break;
872e3d4d 1022 case CMD_PSK_SIM_TAG:
1023 CmdPSKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1024 break;
1025 case CMD_HID_CLONE_TAG:
5f84531b
SS
1026 CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0], 0x1D);
1027 break;
1028 case CMD_PARADOX_CLONE_TAG:
1029 // Paradox cards are the same as HID, with a different preamble, so we can reuse the same function
1030 CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0], 0x0F);
7e67e42f 1031 break;
a1f3bb12 1032 case CMD_IO_DEMOD_FSK:
3fe4ff4f 1033 CmdIOdemodFSK(c->arg[0], 0, 0, 1);
a1f3bb12 1034 break;
3fe4ff4f 1035 case CMD_IO_CLONE_TAG:
9f669cb2 1036 CopyIOtoT55x7(c->arg[0], c->arg[1]);
a1f3bb12 1037 break;
66707a3b 1038 case CMD_EM410X_DEMOD:
1039 CmdEM410xdemod(c->arg[0], 0, 0, 1);
1040 break;
2d4eae76 1041 case CMD_EM410X_WRITE_TAG:
1042 WriteEM410x(c->arg[0], c->arg[1], c->arg[2]);
1043 break;
7e67e42f 1044 case CMD_READ_TI_TYPE:
1045 ReadTItag();
1046 break;
1047 case CMD_WRITE_TI_TYPE:
1048 WriteTItag(c->arg[0],c->arg[1],c->arg[2]);
1049 break;
1050 case CMD_SIMULATE_TAG_125K:
31d1caa5 1051 LED_A_ON();
7e67e42f 1052 SimulateTagLowFrequency(c->arg[0], c->arg[1], 1);
31d1caa5 1053 LED_A_OFF();
7e67e42f 1054 break;
1055 case CMD_LF_SIMULATE_BIDIR:
1056 SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);
1057 break;
3fe4ff4f 1058 case CMD_INDALA_CLONE_TAG:
2414f978 1059 CopyIndala64toT55x7(c->arg[0], c->arg[1]);
1060 break;
3fe4ff4f 1061 case CMD_INDALA_CLONE_TAG_L:
2414f978 1062 CopyIndala224toT55x7(c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]);
1063 break;
1c611bbd 1064 case CMD_T55XX_READ_BLOCK:
8e99ec25 1065 T55xxReadBlock(c->arg[0], c->arg[1], c->arg[2]);
1c611bbd 1066 break;
1067 case CMD_T55XX_WRITE_BLOCK:
1068 T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
1069 break;
be2d41b7 1070 case CMD_T55XX_WAKEUP:
1071 T55xxWakeUp(c->arg[0]);
1c611bbd 1072 break;
66837a03 1073 case CMD_T55XX_RESET_READ:
1074 T55xxResetRead();
1075 break;
3fe4ff4f 1076 case CMD_PCF7931_READ:
1c611bbd 1077 ReadPCF7931();
1c611bbd 1078 break;
dc4300ba 1079 case CMD_PCF7931_WRITE:
d10e08ae 1080 WritePCF7931(c->d.asBytes[0],c->d.asBytes[1],c->d.asBytes[2],c->d.asBytes[3],c->d.asBytes[4],c->d.asBytes[5],c->d.asBytes[6], c->d.asBytes[9], c->d.asBytes[7]-128,c->d.asBytes[8]-128, c->arg[0], c->arg[1], c->arg[2]);
dc4300ba 1081 break;
818e15b0
S
1082 case CMD_PCF7931_BRUTEFORCE:
1083 BruteForcePCF7931(c->arg[0], (c->arg[1] & 0xFF), c->d.asBytes[9], c->d.asBytes[7]-128,c->d.asBytes[8]-128);
1084 break;
1c611bbd 1085 case CMD_EM4X_READ_WORD:
7666f460 1086 EM4xReadWord(c->arg[0], c->arg[1],c->arg[2]);
1c611bbd 1087 break;
1088 case CMD_EM4X_WRITE_WORD:
7666f460 1089 EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2]);
1c611bbd 1090 break;
2de26056 1091 case CMD_EM4X_PROTECT:
1092 EM4xProtect(c->arg[0], c->arg[1], c->arg[2]);
1093 break;
dbf6e824
CY
1094 case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
1095 CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
7cfc777b 1096 break;
709665b5 1097 case CMD_VIKING_CLONE_TAG:
1098 CopyVikingtoT55xx(c->arg[0], c->arg[1], c->arg[2]);
1099 break;
e04475c4 1100 case CMD_COTAG:
1101 Cotag(c->arg[0]);
1102 break;
15c4dc5a 1103#endif
1104
d19929cb 1105#ifdef WITH_HITAG
1106 case CMD_SNOOP_HITAG: // Eavesdrop Hitag tag, args = type
1107 SnoopHitag(c->arg[0]);
1108 break;
1109 case CMD_SIMULATE_HITAG: // Simulate Hitag tag, args = memory content
1110 SimulateHitagTag((bool)c->arg[0],(byte_t*)c->d.asBytes);
1111 break;
1112 case CMD_READER_HITAG: // Reader for Hitag tags, args = type and function
1113 ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
1114 break;
4e12287d
RS
1115 case CMD_SIMULATE_HITAG_S:// Simulate Hitag s tag, args = memory content
1116 SimulateHitagSTag((bool)c->arg[0],(byte_t*)c->d.asBytes);
1117 break;
1118 case CMD_TEST_HITAGS_TRACES:// Tests every challenge within the given file
7b6e3205 1119 check_challenges_cmd((bool)c->arg[0], (byte_t*)c->d.asBytes, (uint8_t)c->arg[1]);
4e12287d
RS
1120 break;
1121 case CMD_READ_HITAG_S://Reader for only Hitag S tags, args = key or challenge
7b6e3205 1122 ReadHitagSCmd((hitag_function)c->arg[0], (hitag_data*)c->d.asBytes, (uint8_t)c->arg[1], (uint8_t)c->arg[2], false);
1123 break;
1124 case CMD_READ_HITAG_S_BLK:
1125 ReadHitagSCmd((hitag_function)c->arg[0], (hitag_data*)c->d.asBytes, (uint8_t)c->arg[1], (uint8_t)c->arg[2], true);
4e12287d
RS
1126 break;
1127 case CMD_WR_HITAG_S://writer for Hitag tags args=data to write,page and key or challenge
52244230
HJ
1128 if ((hitag_function)c->arg[0] < 10) {
1129 WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
1130 }
1131 else if ((hitag_function)c->arg[0] >= 10) {
1132 WriterHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes, c->arg[2]);
1133 }
4e12287d 1134 break;
d19929cb 1135#endif
f168b263 1136
15c4dc5a 1137#ifdef WITH_ISO15693
1138 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
1139 AcquireRawAdcSamplesIso15693();
1140 break;
d9de20fa 1141
1142 case CMD_SNOOP_ISO_15693:
1143 SnoopIso15693();
9455b51c 1144 break;
1145
1146 case CMD_ISO_15693_COMMAND:
1147 DirectTag15693Command(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
1148 break;
1149
1150 case CMD_ISO_15693_FIND_AFI:
1151 BruteforceIso15693Afi(c->arg[0]);
1152 break;
1153
1154 case CMD_ISO_15693_DEBUG:
1155 SetDebugIso15693(c->arg[0]);
1156 break;
15c4dc5a 1157
15c4dc5a 1158 case CMD_READER_ISO_15693:
1159 ReaderIso15693(c->arg[0]);
1160 break;
096dee17 1161
7e67e42f 1162 case CMD_SIMTAG_ISO_15693:
3fe4ff4f 1163 SimTagIso15693(c->arg[0], c->d.asBytes);
7e67e42f 1164 break;
096dee17 1165
1166 case CMD_CSETUID_ISO_15693:
1167 SetTag15693Uid(c->d.asBytes);
1168 break;
15c4dc5a 1169#endif
1170
7e67e42f 1171#ifdef WITH_LEGICRF
1172 case CMD_SIMULATE_TAG_LEGIC_RF:
1b902aa0 1173 LegicRfSimulate(c->arg[0]);
7e67e42f 1174 break;
3612a8a8 1175
7e67e42f 1176 case CMD_WRITER_LEGIC_RF:
1177 LegicRfWriter(c->arg[1], c->arg[0]);
1178 break;
3612a8a8 1179
15c4dc5a 1180 case CMD_READER_LEGIC_RF:
1181 LegicRfReader(c->arg[0], c->arg[1]);
1182 break;
15c4dc5a 1183#endif
1184
1185#ifdef WITH_ISO14443b
15c4dc5a 1186 case CMD_READ_SRI512_TAG:
51d4f6f1 1187 ReadSTMemoryIso14443b(0x0F);
15c4dc5a 1188 break;
7e67e42f 1189 case CMD_READ_SRIX4K_TAG:
51d4f6f1 1190 ReadSTMemoryIso14443b(0x7F);
7e67e42f 1191 break;
132a0217 1192 case CMD_SNOOP_ISO_14443B:
51d4f6f1 1193 SnoopIso14443b();
7e67e42f 1194 break;
132a0217 1195 case CMD_SIMULATE_TAG_ISO_14443B:
51d4f6f1 1196 SimulateIso14443bTag();
7e67e42f 1197 break;
7cf3ef20 1198 case CMD_ISO_14443B_COMMAND:
1199 SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
1200 break;
15c4dc5a 1201#endif
1202
1203#ifdef WITH_ISO14443a
7e67e42f 1204 case CMD_SNOOP_ISO_14443a:
5cd9ec01 1205 SnoopIso14443a(c->arg[0]);
7e67e42f 1206 break;
15c4dc5a 1207 case CMD_READER_ISO_14443a:
902cb3c0 1208 ReaderIso14443a(c);
15c4dc5a 1209 break;
7e67e42f 1210 case CMD_SIMULATE_TAG_ISO_14443a:
28afbd2b 1211 SimulateIso14443aTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); // ## Simulate iso14443a tag - pass tag type & UID
7e67e42f 1212 break;
3fe4ff4f 1213
5acd09bd 1214 case CMD_EPA_PACE_COLLECT_NONCE:
902cb3c0 1215 EPA_PACE_Collect_Nonce(c);
5acd09bd 1216 break;
3bb07d96
FM
1217 case CMD_EPA_PACE_REPLAY:
1218 EPA_PACE_Replay(c);
1219 break;
7e67e42f 1220
15c4dc5a 1221 case CMD_READER_MIFARE:
f168b263 1222 ReaderMifare(c->arg[0]);
15c4dc5a 1223 break;
20f9a2a1
M
1224 case CMD_MIFARE_READBL:
1225 MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1226 break;
981bd429 1227 case CMD_MIFAREU_READBL:
f168b263 1228 MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
981bd429 1229 break;
8258f409 1230 case CMD_MIFAREUC_AUTH:
1231 MifareUC_Auth(c->arg[0],c->d.asBytes);
a631936e 1232 break;
981bd429 1233 case CMD_MIFAREU_READCARD:
75377d29 1234 MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
117d9ec2 1235 break;
f168b263 1236 case CMD_MIFAREUC_SETPWD:
1237 MifareUSetPwd(c->arg[0], c->d.asBytes);
1238 break;
20f9a2a1
M
1239 case CMD_MIFARE_READSC:
1240 MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1241 break;
1242 case CMD_MIFARE_WRITEBL:
1243 MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1244 break;
4973f23d 1245 //case CMD_MIFAREU_WRITEBL_COMPAT:
1246 //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes);
1247 //break;
981bd429 1248 case CMD_MIFAREU_WRITEBL:
4973f23d 1249 MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
f168b263 1250 break;
c48c4d78 1251 case CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES:
1252 MifareAcquireEncryptedNonces(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1253 break;
20f9a2a1
M
1254 case CMD_MIFARE_NESTED:
1255 MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
f397b5cc
M
1256 break;
1257 case CMD_MIFARE_CHKKEYS:
1258 MifareChkKeys(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
20f9a2a1
M
1259 break;
1260 case CMD_SIMULATE_MIFARE_CARD:
a8561e35 1261 MifareSim(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
20f9a2a1 1262 break;
8556b852
M
1263
1264 // emulator
1265 case CMD_MIFARE_SET_DBGMODE:
1266 MifareSetDbgLvl(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1267 break;
1268 case CMD_MIFARE_EML_MEMCLR:
1269 MifareEMemClr(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1270 break;
1271 case CMD_MIFARE_EML_MEMSET:
1272 MifareEMemSet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1273 break;
1274 case CMD_MIFARE_EML_MEMGET:
1275 MifareEMemGet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1276 break;
1277 case CMD_MIFARE_EML_CARDLOAD:
1278 MifareECardLoad(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
0675f200
M
1279 break;
1280
1281 // Work with "magic Chinese" card
3a05a1e7
OM
1282 case CMD_MIFARE_CWIPE:
1283 MifareCWipe(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1284 break;
3fe4ff4f 1285 case CMD_MIFARE_CSETBLOCK:
0675f200 1286 MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
545a1f38 1287 break;
3fe4ff4f 1288 case CMD_MIFARE_CGETBLOCK:
545a1f38 1289 MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
8556b852 1290 break;
3fe4ff4f 1291 case CMD_MIFARE_CIDENT:
1292 MifareCIdent();
1293 break;
b62a5a84
M
1294
1295 // mifare sniffer
1296 case CMD_MIFARE_SNIFFER:
5cd9ec01 1297 SniffMifare(c->arg[0]);
b62a5a84 1298 break;
a631936e 1299
20f9a2a1
M
1300#endif
1301
7e67e42f 1302#ifdef WITH_ICLASS
cee5a30d 1303 // Makes use of ISO14443a FPGA Firmware
1304 case CMD_SNOOP_ICLASS:
1305 SnoopIClass();
1306 break;
1e262141 1307 case CMD_SIMULATE_TAG_ICLASS:
ff7bb4ef 1308 SimulateIClass(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1e262141 1309 break;
1310 case CMD_READER_ICLASS:
1311 ReaderIClass(c->arg[0]);
1312 break;
c3963755 1313 case CMD_READER_ICLASS_REPLAY:
aa53efc3 1314 ReaderIClass_Replay(c->arg[0], c->d.asBytes);
c3963755 1315 break;
aa53efc3 1316 case CMD_ICLASS_EML_MEMSET:
e80aeb96
MHS
1317 emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
1318 break;
aa53efc3 1319 case CMD_ICLASS_WRITEBLOCK:
3ac22ee1 1320 iClass_WriteBlock(c->arg[0], c->d.asBytes);
1321 break;
1322 case CMD_ICLASS_READCHECK: // auth step 1
1323 iClass_ReadCheck(c->arg[0], c->arg[1]);
aa53efc3 1324 break;
1325 case CMD_ICLASS_READBLOCK:
3ac22ee1 1326 iClass_ReadBlk(c->arg[0]);
aa53efc3 1327 break;
3ac22ee1 1328 case CMD_ICLASS_AUTHENTICATION: //check
aa53efc3 1329 iClass_Authentication(c->d.asBytes);
1330 break;
1331 case CMD_ICLASS_DUMP:
3ac22ee1 1332 iClass_Dump(c->arg[0], c->arg[1]);
aa53efc3 1333 break;
1334 case CMD_ICLASS_CLONE:
3ac22ee1 1335 iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes);
aa53efc3 1336 break;
cee5a30d 1337#endif
fc52fbd4 1338
0472d76d 1339#ifdef WITH_HFSNOOP
1340 case CMD_HF_SNIFFER:
1341 HfSnoop(c->arg[0], c->arg[1]);
1342 break;
fc52fbd4 1343 case CMD_HF_PLOT:
1344 HfPlot();
1345 break;
0472d76d 1346#endif
fc52fbd4 1347
43591e64 1348#ifdef WITH_SMARTCARD
1349 case CMD_SMART_ATR: {
1350 SmartCardAtr();
1351 break;
1352 }
1353 case CMD_SMART_SETCLOCK:{
1354 SmartCardSetClock(c->arg[0]);
1355 break;
1356 }
1357 case CMD_SMART_RAW: {
1358 SmartCardRaw(c->arg[0], c->arg[1], c->d.asBytes);
1359 break;
1360 }
1361 case CMD_SMART_UPLOAD: {
1362 // upload file from client
1363 uint8_t *mem = BigBuf_get_addr();
1364 memcpy( mem + c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
1365 cmd_send(CMD_ACK,1,0,0,0,0);
1366 break;
1367 }
1368 case CMD_SMART_UPGRADE: {
1369 SmartCardUpgrade(c->arg[0]);
1370 break;
1371 }
1372#endif
cee5a30d 1373
7e67e42f 1374 case CMD_BUFF_CLEAR:
117d9ec2 1375 BigBuf_Clear();
15c4dc5a 1376 break;
15c4dc5a 1377
1378 case CMD_MEASURE_ANTENNA_TUNING:
fdcfbdcc 1379 MeasureAntennaTuning(c->arg[0]);
15c4dc5a 1380 break;
1381
1382 case CMD_MEASURE_ANTENNA_TUNING_HF:
1383 MeasureAntennaTuningHf();
1384 break;
1385
1386 case CMD_LISTEN_READER_FIELD:
1387 ListenReaderField(c->arg[0]);
1388 break;
1389
15c4dc5a 1390 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
1391 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1392 SpinDelay(200);
1393 LED_D_OFF(); // LED D indicates field ON or OFF
1394 break;
1395
1c611bbd 1396 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
1c611bbd 1397 LED_B_ON();
117d9ec2 1398 uint8_t *BigBuf = BigBuf_get_addr();
1c611bbd 1399 for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
1400 size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
3000dc4e 1401 cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len);
1c611bbd 1402 }
1403 // Trigger a finish downloading signal with an ACK frame
3000dc4e 1404 cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config));
d3b1f4e4 1405 LED_B_OFF();
1c611bbd 1406 break;
15c4dc5a 1407
1408 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
8c8317a5 1409 // iceman; since changing fpga_bitstreams clears bigbuff, Its better to call it before.
1410 // to be able to use this one for uploading data to device
1411 // arg1 = 0 upload for LF usage
1412 // 1 upload for HF usage
1413 if (c->arg[1] == 0)
1414 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
1415 else
1416 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1417
117d9ec2 1418 uint8_t *b = BigBuf_get_addr();
3fe4ff4f 1419 memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
1c611bbd 1420 cmd_send(CMD_ACK,0,0,0,0,0);
1421 break;
1422 }
15c4dc5a 1423 case CMD_READ_MEM:
1424 ReadMem(c->arg[0]);
1425 break;
1426
1427 case CMD_SET_LF_DIVISOR:
8c8317a5 1428 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
15c4dc5a 1429 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]);
1430 break;
1431
1432 case CMD_SET_ADC_MUX:
1433 switch(c->arg[0]) {
1434 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break;
1435 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break;
1436 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break;
1437 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break;
1438 }
1439 break;
1440
1441 case CMD_VERSION:
1442 SendVersion();
1443 break;
c89274cc 1444 case CMD_STATUS:
67b7d6fa 1445 SendStatus();
c89274cc
CY
1446 break;
1447 case CMD_PING:
1448 cmd_send(CMD_ACK,0,0,0,0,0);
1449 break;
15c4dc5a 1450#ifdef WITH_LCD
1451 case CMD_LCD_RESET:
1452 LCDReset();
1453 break;
1454 case CMD_LCD:
1455 LCDSend(c->arg[0]);
1456 break;
1457#endif
1458 case CMD_SETUP_WRITE:
1459 case CMD_FINISH_WRITE:
1c611bbd 1460 case CMD_HARDWARE_RESET:
1461 usb_disable();
15c4dc5a 1462 SpinDelay(1000);
1463 SpinDelay(1000);
1464 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
1465 for(;;) {
1466 // We're going to reset, and the bootrom will take control.
1467 }
1c611bbd 1468 break;
15c4dc5a 1469
1c611bbd 1470 case CMD_START_FLASH:
15c4dc5a 1471 if(common_area.flags.bootrom_present) {
1472 common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
1473 }
1c611bbd 1474 usb_disable();
15c4dc5a 1475 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
1476 for(;;);
1c611bbd 1477 break;
e30c654b 1478
15c4dc5a 1479 case CMD_DEVICE_INFO: {
902cb3c0 1480 uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
1481 if(common_area.flags.bootrom_present) dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
1c611bbd 1482 cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
1483 break;
1484 }
1485 default:
15c4dc5a 1486 Dbprintf("%s: 0x%04x","unknown command:",c->cmd);
1c611bbd 1487 break;
15c4dc5a 1488 }
1489}
1490
1491void __attribute__((noreturn)) AppMain(void)
1492{
1493 SpinDelay(100);
9e8255d4 1494 clear_trace();
15c4dc5a 1495 if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
1496 /* Initialize common area */
1497 memset(&common_area, 0, sizeof(common_area));
1498 common_area.magic = COMMON_AREA_MAGIC;
1499 common_area.version = 1;
1500 }
1501 common_area.flags.osimage_present = 1;
1502
3d057cfb
SG
1503 LEDsoff();
1504
3fe4ff4f 1505 // Init USB device
050aa18b 1506 usb_enable();
15c4dc5a 1507
1508 // The FPGA gets its clock from us from PCK0 output, so set that up.
1509 AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
1510 AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;
1511 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK0;
1512 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
1513 AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK |
0472d76d 1514 AT91C_PMC_PRES_CLK_4; // 4 for 24Mhz pck0, 2 for 48 MHZ pck0
15c4dc5a 1515 AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0;
1516
1517 // Reset SPI
1518 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
1519 // Reset SSC
1520 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
1521
1522 // Load the FPGA image, which we have stored in our flash.
7cc204bf 1523 // (the HF version by default)
1524 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1525
9ca155ba 1526 StartTickCount();
902cb3c0 1527
15c4dc5a 1528#ifdef WITH_LCD
15c4dc5a 1529 LCDInit();
15c4dc5a 1530#endif
1531
902cb3c0 1532 byte_t rx[sizeof(UsbCommand)];
1533 size_t rx_len;
1534
15c4dc5a 1535 for(;;) {
902cb3c0 1536 if (usb_poll()) {
1537 rx_len = usb_read(rx,sizeof(UsbCommand));
1538 if (rx_len) {
1539 UsbPacketReceived(rx,rx_len);
1540 }
1541 }
15c4dc5a 1542 WDT_HIT();
1543
a2937cea 1544#ifdef WITH_LF_StandAlone
e46fe044 1545#ifndef WITH_ISO14443a_StandAlone
15c4dc5a 1546 if (BUTTON_HELD(1000) > 0)
1547 SamyRun();
e46fe044
CY
1548#endif
1549#endif
1550#ifdef WITH_ISO14443a
1551#ifdef WITH_ISO14443a_StandAlone
1552 if (BUTTON_HELD(1000) > 0)
1553 StandAloneMode14a();
1554#endif
15c4dc5a 1555#endif
1556 }
1557}
Impressum, Datenschutz