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