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