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