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