]> git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/iso15693.c
rework iso14443b device functions including FPGA I/Q signal transfer (#669)
[proxmark3-svn] / armsrc / iso15693.c
1 //-----------------------------------------------------------------------------
2 // Jonathan Westhues, split Nov 2006
3 // Modified by Greg Jones, Jan 2009
4 // Modified by Adrian Dabrowski "atrox", Mar-Sept 2010,Oct 2011
5 //
6 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
7 // at your option, any later version. See the LICENSE.txt file for the text of
8 // the license.
9 //-----------------------------------------------------------------------------
10 // Routines to support ISO 15693. This includes both the reader software and
11 // the `fake tag' modes, but at the moment I've implemented only the reader
12 // stuff, and that barely.
13 // Modified to perform modulation onboard in arm rather than on PC
14 // Also added additional reader commands (SELECT, READ etc.)
15 //-----------------------------------------------------------------------------
16 // The ISO 15693 describes two transmission modes from reader to tag, and 4
17 // transmission modes from tag to reader. As of Mar 2010 this code only
18 // supports one of each: "1of4" mode from reader to tag, and the highspeed
19 // variant with one subcarrier from card to reader.
20 // As long, as the card fully support ISO 15693 this is no problem, since the
21 // reader chooses both data rates, but some non-standard tags do not. Further for
22 // the simulation to work, we will need to support all data rates.
23 //
24 // VCD (reader) -> VICC (tag)
25 // 1 out of 256:
26 // data rate: 1,66 kbit/s (fc/8192)
27 // used for long range
28 // 1 out of 4:
29 // data rate: 26,48 kbit/s (fc/512)
30 // used for short range, high speed
31 //
32 // VICC (tag) -> VCD (reader)
33 // Modulation:
34 // ASK / one subcarrier (423,75 khz)
35 // FSK / two subcarriers (423,75 khz && 484,28 khz)
36 // Data Rates / Modes:
37 // low ASK: 6,62 kbit/s
38 // low FSK: 6.67 kbit/s
39 // high ASK: 26,48 kbit/s
40 // high FSK: 26,69 kbit/s
41 //-----------------------------------------------------------------------------
42 // added "1 out of 256" mode (for VCD->PICC) - atrox 20100911
43
44
45 // Random Remarks:
46 // *) UID is always used "transmission order" (LSB), which is reverse to display order
47
48 // TODO / BUGS / ISSUES:
49 // *) writing to tags takes longer: we miss the answer from the tag in most cases
50 // -> tweak the read-timeout times
51 // *) signal decoding from the card is still a bit shaky.
52 // *) signal decoding is unable to detect collissions.
53 // *) add anti-collission support for inventory-commands
54 // *) read security status of a block
55 // *) sniffing and simulation do only support one transmission mode. need to support
56 // all 8 transmission combinations
57 // *) remove or refactor code under "depricated"
58 // *) document all the functions
59
60
61 #include "proxmark3.h"
62 #include "util.h"
63 #include "apps.h"
64 #include "string.h"
65 #include "iso15693tools.h"
66 #include "cmd.h"
67
68 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
69
70 ///////////////////////////////////////////////////////////////////////
71 // ISO 15693 Part 2 - Air Interface
72 // This section basicly contains transmission and receiving of bits
73 ///////////////////////////////////////////////////////////////////////
74
75 #define FrameSOF Iso15693FrameSOF
76 #define Logic0 Iso15693Logic0
77 #define Logic1 Iso15693Logic1
78 #define FrameEOF Iso15693FrameEOF
79
80 #define Crc(data,datalen) Iso15693Crc(data,datalen)
81 #define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
82 #define sprintUID(target,uid) Iso15693sprintUID(target,uid)
83
84 // approximate amplitude=sqrt(ci^2+cq^2)
85 #define AMPLITUDE(ci, cq) (MAX(ABS(ci), ABS(cq)) + (MIN(ABS(ci), ABS(cq))>>1))
86
87 static int DEBUG = 0;
88
89
90 // ---------------------------
91 // Signal Processing
92 // ---------------------------
93
94 // prepare data using "1 out of 4" code for later transmission
95 // resulting data rate is 26,48 kbit/s (fc/512)
96 // cmd ... data
97 // n ... length of data
98 static void CodeIso15693AsReader(uint8_t *cmd, int n)
99 {
100 int i, j;
101
102 ToSendReset();
103
104 // Give it a bit of slack at the beginning
105 for(i = 0; i < 24; i++) {
106 ToSendStuffBit(1);
107 }
108
109 // SOF for 1of4
110 ToSendStuffBit(0);
111 ToSendStuffBit(1);
112 ToSendStuffBit(1);
113 ToSendStuffBit(1);
114 ToSendStuffBit(1);
115 ToSendStuffBit(0);
116 ToSendStuffBit(1);
117 ToSendStuffBit(1);
118 for(i = 0; i < n; i++) {
119 for(j = 0; j < 8; j += 2) {
120 int these = (cmd[i] >> j) & 3;
121 switch(these) {
122 case 0:
123 ToSendStuffBit(1);
124 ToSendStuffBit(0);
125 ToSendStuffBit(1);
126 ToSendStuffBit(1);
127 ToSendStuffBit(1);
128 ToSendStuffBit(1);
129 ToSendStuffBit(1);
130 ToSendStuffBit(1);
131 break;
132 case 1:
133 ToSendStuffBit(1);
134 ToSendStuffBit(1);
135 ToSendStuffBit(1);
136 ToSendStuffBit(0);
137 ToSendStuffBit(1);
138 ToSendStuffBit(1);
139 ToSendStuffBit(1);
140 ToSendStuffBit(1);
141 break;
142 case 2:
143 ToSendStuffBit(1);
144 ToSendStuffBit(1);
145 ToSendStuffBit(1);
146 ToSendStuffBit(1);
147 ToSendStuffBit(1);
148 ToSendStuffBit(0);
149 ToSendStuffBit(1);
150 ToSendStuffBit(1);
151 break;
152 case 3:
153 ToSendStuffBit(1);
154 ToSendStuffBit(1);
155 ToSendStuffBit(1);
156 ToSendStuffBit(1);
157 ToSendStuffBit(1);
158 ToSendStuffBit(1);
159 ToSendStuffBit(1);
160 ToSendStuffBit(0);
161 break;
162 }
163 }
164 }
165 // EOF
166 ToSendStuffBit(1);
167 ToSendStuffBit(1);
168 ToSendStuffBit(0);
169 ToSendStuffBit(1);
170
171 // And slack at the end, too.
172 for(i = 0; i < 24; i++) {
173 ToSendStuffBit(1);
174 }
175 }
176
177 // encode data using "1 out of 256" sheme
178 // data rate is 1,66 kbit/s (fc/8192)
179 // is designed for more robust communication over longer distances
180 static void CodeIso15693AsReader256(uint8_t *cmd, int n)
181 {
182 int i, j;
183
184 ToSendReset();
185
186 // Give it a bit of slack at the beginning
187 for(i = 0; i < 24; i++) {
188 ToSendStuffBit(1);
189 }
190
191 // SOF for 1of256
192 ToSendStuffBit(0);
193 ToSendStuffBit(1);
194 ToSendStuffBit(1);
195 ToSendStuffBit(1);
196 ToSendStuffBit(1);
197 ToSendStuffBit(1);
198 ToSendStuffBit(1);
199 ToSendStuffBit(0);
200
201 for(i = 0; i < n; i++) {
202 for (j = 0; j<=255; j++) {
203 if (cmd[i]==j) {
204 ToSendStuffBit(1);
205 ToSendStuffBit(0);
206 } else {
207 ToSendStuffBit(1);
208 ToSendStuffBit(1);
209 }
210 }
211 }
212 // EOF
213 ToSendStuffBit(1);
214 ToSendStuffBit(1);
215 ToSendStuffBit(0);
216 ToSendStuffBit(1);
217
218 // And slack at the end, too.
219 for(i = 0; i < 24; i++) {
220 ToSendStuffBit(1);
221 }
222 }
223
224
225 // Transmit the command (to the tag) that was placed in ToSend[].
226 static void TransmitTo15693Tag(const uint8_t *cmd, int len, int *samples, int *wait)
227 {
228 int c;
229
230 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
231 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
232 if(*wait < 10) { *wait = 10; }
233
234 c = 0;
235 for(;;) {
236 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
237 AT91C_BASE_SSC->SSC_THR = ~cmd[c];
238 c++;
239 if(c >= len) {
240 break;
241 }
242 }
243 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
244 volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
245 (void)r;
246 }
247 WDT_HIT();
248 }
249 *samples = (c + *wait) << 3;
250 }
251
252 //-----------------------------------------------------------------------------
253 // Transmit the command (to the reader) that was placed in ToSend[].
254 //-----------------------------------------------------------------------------
255 static void TransmitTo15693Reader(const uint8_t *cmd, int len, int *samples, int *wait)
256 {
257 int c = 0;
258 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K);
259 if(*wait < 10) { *wait = 10; }
260
261 for(;;) {
262 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
263 AT91C_BASE_SSC->SSC_THR = cmd[c];
264 c++;
265 if(c >= len) {
266 break;
267 }
268 }
269 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
270 volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
271 (void)r;
272 }
273 WDT_HIT();
274 }
275 *samples = (c + *wait) << 3;
276 }
277
278
279 // Read from Tag
280 // Parameters:
281 // receivedResponse
282 // maxLen
283 // samples
284 // elapsed
285 // returns:
286 // number of decoded bytes
287 static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
288 {
289 int c = 0;
290 uint8_t *dest = BigBuf_get_addr();
291
292 // NOW READ RESPONSE
293 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
294 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
295 c = 0;
296 for(;;) {
297 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
298 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
299 // The samples are correlations against I and Q versions of the
300 // tone that the tag AM-modulates. We just want power.
301 int8_t i = iq >> 8;
302 int8_t q = iq;
303 uint8_t r = AMPLITUDE(i, q);
304
305 dest[c++] = r;
306
307 if(c >= 4000) {
308 break;
309 }
310 }
311 }
312
313 //////////////////////////////////////////
314 /////////// DEMODULATE ///////////////////
315 //////////////////////////////////////////
316
317 int i, j;
318 int max = 0, maxPos=0;
319
320 int skip = 2;
321
322 // First, correlate for SOF
323 for(i = 0; i < 200; i++) { // usually, SOF is found around i = 60
324 int corr = 0;
325 for(j = 0; j < arraylen(FrameSOF); j += skip) {
326 corr += FrameSOF[j]*dest[i+(j/skip)];
327 }
328 if(corr > max) {
329 max = corr;
330 maxPos = i;
331 }
332 }
333 if (DEBUG) Dbprintf("SOF at %d, correlation %d", maxPos, max/(arraylen(FrameSOF)/skip));
334
335 int k = 0; // this will be our return value
336
337 // greg - If correlation is less than 1 then there's little point in continuing
338 if ((max/(arraylen(FrameSOF)/skip)) >= 1)
339 {
340
341 i = maxPos + arraylen(FrameSOF)/skip;
342
343 uint8_t outBuf[20];
344 memset(outBuf, 0, sizeof(outBuf));
345 uint8_t mask = 0x01;
346 for(;;) {
347 int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
348 for(j = 0; j < arraylen(Logic0); j += skip) {
349 corr0 += Logic0[j]*dest[i+(j/skip)];
350 }
351 corr01 = corr00 = corr0;
352 for(j = 0; j < arraylen(Logic0); j += skip) {
353 corr00 += Logic0[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
354 corr01 += Logic1[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
355 }
356 for(j = 0; j < arraylen(Logic1); j += skip) {
357 corr1 += Logic1[j]*dest[i+(j/skip)];
358 }
359 for(j = 0; j < arraylen(FrameEOF); j += skip) {
360 corrEOF += FrameEOF[j]*dest[i+(j/skip)];
361 }
362 // Even things out by the length of the target waveform.
363 corr00 *= 2;
364 corr01 *= 2;
365 corr0 *= 4;
366 corr1 *= 4;
367
368 if(corrEOF > corr1 && corrEOF > corr00 && corrEOF > corr01) {
369 if (DEBUG) Dbprintf("EOF at %d, correlation %d (corr01: %d, corr00: %d, corr1: %d, corr0: %d)",
370 i, corrEOF, corr01, corr00, corr1, corr0);
371 break;
372 } else if(corr1 > corr0) {
373 i += arraylen(Logic1)/skip;
374 outBuf[k] |= mask;
375 } else {
376 i += arraylen(Logic0)/skip;
377 }
378 mask <<= 1;
379 if(mask == 0) {
380 k++;
381 mask = 0x01;
382 }
383 if((i+(int)arraylen(FrameEOF)/skip) >= 4000) {
384 DbpString("ran off end!");
385 break;
386 }
387 }
388 if(mask != 0x01) { // this happens, when we miss the EOF
389 // TODO: for some reason this happens quite often
390 if (DEBUG) Dbprintf("error, uneven octet! (extra bits!) mask=%02x", mask);
391 if (mask<0x08) k--; // discard the last uneven octet;
392 // 0x08 is an assumption - but works quite often
393 }
394 // uint8_t str1 [8];
395 // itoa(k,str1);
396 // strncat(str1," octets read",8);
397
398 // DbpString( str1); // DbpString("%d octets", k);
399
400 // for(i = 0; i < k; i+=3) {
401 // //DbpString("# %2d: %02x ", i, outBuf[i]);
402 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
403 // }
404
405 for(i = 0; i < k; i++) {
406 receivedResponse[i] = outBuf[i];
407 }
408 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
409 return k; // return the number of bytes demodulated
410
411 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
412
413 }
414
415
416 // Now the GetISO15693 message from sniffing command
417 static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
418 {
419 int c = 0;
420 uint8_t *dest = BigBuf_get_addr();
421
422 // NOW READ RESPONSE
423 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
424 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
425 c = 0;
426 for(;;) {
427 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
428 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
429 // The samples are correlations against I and Q versions of the
430 // tone that the tag AM-modulates. We just want power,
431 // so abs(I) + abs(Q) is close to what we want.
432 int8_t i = iq >> 8;
433 int8_t q = iq;
434 uint8_t r = AMPLITUDE(i, q);
435
436 dest[c++] = r;
437
438 if(c >= BIGBUF_SIZE) {
439 break;
440 }
441 }
442 }
443
444 //////////////////////////////////////////
445 /////////// DEMODULATE ///////////////////
446 //////////////////////////////////////////
447
448 int i, j;
449 int max = 0, maxPos=0;
450
451 int skip = 2;
452
453 // First, correlate for SOF
454 for(i = 0; i < 38000; i++) {
455 int corr = 0;
456 for(j = 0; j < arraylen(FrameSOF); j += skip) {
457 corr += FrameSOF[j]*dest[i+(j/skip)];
458 }
459 if(corr > max) {
460 max = corr;
461 maxPos = i;
462 }
463 }
464 if (DEBUG) Dbprintf("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
465
466 int k = 0; // this will be our return value
467
468 // greg - If correlation is less than 1 then there's little point in continuing
469 if ((max/(arraylen(FrameSOF)/skip)) >= 1) // THIS SHOULD BE 1
470 {
471
472 i = maxPos + arraylen(FrameSOF)/skip;
473
474 uint8_t outBuf[20];
475 memset(outBuf, 0, sizeof(outBuf));
476 uint8_t mask = 0x01;
477 for(;;) {
478 int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
479 for(j = 0; j < arraylen(Logic0); j += skip) {
480 corr0 += Logic0[j]*dest[i+(j/skip)];
481 }
482 corr01 = corr00 = corr0;
483 for(j = 0; j < arraylen(Logic0); j += skip) {
484 corr00 += Logic0[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
485 corr01 += Logic1[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
486 }
487 for(j = 0; j < arraylen(Logic1); j += skip) {
488 corr1 += Logic1[j]*dest[i+(j/skip)];
489 }
490 for(j = 0; j < arraylen(FrameEOF); j += skip) {
491 corrEOF += FrameEOF[j]*dest[i+(j/skip)];
492 }
493 // Even things out by the length of the target waveform.
494 corr00 *= 2;
495 corr01 *= 2;
496 corr0 *= 4;
497 corr1 *= 4;
498
499 if(corrEOF > corr1 && corrEOF > corr00 && corrEOF > corr01) {
500 if (DEBUG) Dbprintf("EOF at %d, correlation %d (corr01: %d, corr00: %d, corr1: %d, corr0: %d)",
501 i, corrEOF, corr01, corr00, corr1, corr0);
502 break;
503 } else if(corr1 > corr0) {
504 i += arraylen(Logic1)/skip;
505 outBuf[k] |= mask;
506 } else {
507 i += arraylen(Logic0)/skip;
508 }
509 mask <<= 1;
510 if(mask == 0) {
511 k++;
512 mask = 0x01;
513 }
514 if((i+(int)arraylen(FrameEOF)/skip) >= BIGBUF_SIZE) {
515 DbpString("ran off end!");
516 break;
517 }
518 }
519 if(mask != 0x01) {
520 DbpString("sniff: error, uneven octet! (discard extra bits!)");
521 /// DbpString(" mask=%02x", mask);
522 }
523 // uint8_t str1 [8];
524 // itoa(k,str1);
525 // strncat(str1," octets read",8);
526
527 // DbpString( str1); // DbpString("%d octets", k);
528
529 // for(i = 0; i < k; i+=3) {
530 // //DbpString("# %2d: %02x ", i, outBuf[i]);
531 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
532 // }
533
534 for(i = 0; i < k; i++) {
535 receivedResponse[i] = outBuf[i];
536 }
537 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
538 return k; // return the number of bytes demodulated
539
540 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
541 }
542
543
544 static void BuildIdentifyRequest(void);
545 //-----------------------------------------------------------------------------
546 // Start to read an ISO 15693 tag. We send an identify request, then wait
547 // for the response. The response is not demodulated, just left in the buffer
548 // so that it can be downloaded to a PC and processed there.
549 //-----------------------------------------------------------------------------
550 void AcquireRawAdcSamplesIso15693(void)
551 {
552 uint8_t *dest = BigBuf_get_addr();
553
554 int c = 0;
555
556 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
557 BuildIdentifyRequest();
558
559 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
560
561 // Give the tags time to energize
562 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
563 SpinDelay(100);
564
565 // Now send the command
566 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
567 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
568
569 c = 0;
570 for(;;) {
571 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
572 AT91C_BASE_SSC->SSC_THR = ~ToSend[c];
573 c++;
574 if(c == ToSendMax+3) {
575 break;
576 }
577 }
578 WDT_HIT();
579 }
580
581 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
582 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
583
584 c = 0;
585 for(;;) {
586 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
587 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
588 // The samples are correlations against I and Q versions of the
589 // tone that the tag AM-modulates. We just want power,
590 // so abs(I) + abs(Q) is close to what we want.
591 int8_t i = iq >> 8;
592 int8_t q = iq;
593 uint8_t r = AMPLITUDE(i, q);
594
595 dest[c++] = r;
596
597 if(c >= 4000) {
598 break;
599 }
600 }
601 }
602 }
603
604
605 void RecordRawAdcSamplesIso15693(void)
606 {
607 uint8_t *dest = BigBuf_get_addr();
608
609 int c = 0;
610
611 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
612 // Setup SSC
613 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
614
615 // Start from off (no field generated)
616 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
617 SpinDelay(200);
618
619 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
620
621 SpinDelay(100);
622
623 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
624
625 c = 0;
626 for(;;) {
627 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
628 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
629 // The samples are correlations against I and Q versions of the
630 // tone that the tag AM-modulates. We just want power,
631 // so abs(I) + abs(Q) is close to what we want.
632 int8_t i = iq >> 8;
633 int8_t q = iq;
634 uint8_t r = AMPLITUDE(i, q);
635
636 dest[c++] = r;
637
638 if(c >= 14000) {
639 break;
640 }
641 }
642 }
643 Dbprintf("finished recording");
644 }
645
646
647 // Initialize the proxmark as iso15k reader
648 // (this might produces glitches that confuse some tags
649 void Iso15693InitReader() {
650 LED_A_ON();
651 LED_B_ON();
652 LED_C_OFF();
653 LED_D_OFF();
654
655 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
656 // Setup SSC
657 // FpgaSetupSsc();
658
659 // Start from off (no field generated)
660 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
661 SpinDelay(10);
662
663 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
664 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
665
666 // Give the tags time to energize
667 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
668 SpinDelay(250);
669
670 LED_A_ON();
671 LED_B_OFF();
672 LED_C_OFF();
673 LED_D_OFF();
674 }
675
676 ///////////////////////////////////////////////////////////////////////
677 // ISO 15693 Part 3 - Air Interface
678 // This section basicly contains transmission and receiving of bits
679 ///////////////////////////////////////////////////////////////////////
680
681 // Encode (into the ToSend buffers) an identify request, which is the first
682 // thing that you must send to a tag to get a response.
683 static void BuildIdentifyRequest(void)
684 {
685 uint8_t cmd[5];
686
687 uint16_t crc;
688 // one sub-carrier, inventory, 1 slot, fast rate
689 // AFI is at bit 5 (1<<4) when doing an INVENTORY
690 cmd[0] = (1 << 2) | (1 << 5) | (1 << 1);
691 // inventory command code
692 cmd[1] = 0x01;
693 // no mask
694 cmd[2] = 0x00;
695 //Now the CRC
696 crc = Crc(cmd, 3);
697 cmd[3] = crc & 0xff;
698 cmd[4] = crc >> 8;
699
700 CodeIso15693AsReader(cmd, sizeof(cmd));
701 }
702
703 // uid is in transmission order (which is reverse of display order)
704 static void BuildReadBlockRequest(uint8_t *uid, uint8_t blockNumber )
705 {
706 uint8_t cmd[13];
707
708 uint16_t crc;
709 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
710 // followed by teh block data
711 // one sub-carrier, inventory, 1 slot, fast rate
712 cmd[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit, ADDR bit, OPTION bit
713 // READ BLOCK command code
714 cmd[1] = 0x20;
715 // UID may be optionally specified here
716 // 64-bit UID
717 cmd[2] = uid[0];
718 cmd[3] = uid[1];
719 cmd[4] = uid[2];
720 cmd[5] = uid[3];
721 cmd[6] = uid[4];
722 cmd[7] = uid[5];
723 cmd[8] = uid[6];
724 cmd[9] = uid[7]; // 0xe0; // always e0 (not exactly unique)
725 // Block number to read
726 cmd[10] = blockNumber;//0x00;
727 //Now the CRC
728 crc = Crc(cmd, 11); // the crc needs to be calculated over 12 bytes
729 cmd[11] = crc & 0xff;
730 cmd[12] = crc >> 8;
731
732 CodeIso15693AsReader(cmd, sizeof(cmd));
733 }
734
735 // Now the VICC>VCD responses when we are simulating a tag
736 static void BuildInventoryResponse( uint8_t *uid)
737 {
738 uint8_t cmd[12];
739
740 uint16_t crc;
741 // one sub-carrier, inventory, 1 slot, fast rate
742 // AFI is at bit 5 (1<<4) when doing an INVENTORY
743 //(1 << 2) | (1 << 5) | (1 << 1);
744 cmd[0] = 0; //
745 cmd[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported
746 // 64-bit UID
747 cmd[2] = uid[7]; //0x32;
748 cmd[3] = uid[6]; //0x4b;
749 cmd[4] = uid[5]; //0x03;
750 cmd[5] = uid[4]; //0x01;
751 cmd[6] = uid[3]; //0x00;
752 cmd[7] = uid[2]; //0x10;
753 cmd[8] = uid[1]; //0x05;
754 cmd[9] = uid[0]; //0xe0;
755 //Now the CRC
756 crc = Crc(cmd, 10);
757 cmd[10] = crc & 0xff;
758 cmd[11] = crc >> 8;
759
760 CodeIso15693AsReader(cmd, sizeof(cmd));
761 }
762
763 // Universal Method for sending to and recv bytes from a tag
764 // init ... should we initialize the reader?
765 // speed ... 0 low speed, 1 hi speed
766 // **recv will return you a pointer to the received data
767 // If you do not need the answer use NULL for *recv[]
768 // return: lenght of received data
769 int SendDataTag(uint8_t *send, int sendlen, int init, int speed, uint8_t **recv) {
770
771 int samples = 0;
772 int tsamples = 0;
773 int wait = 0;
774 int elapsed = 0;
775
776 LED_A_ON();
777 LED_B_ON();
778 LED_C_OFF();
779 LED_D_OFF();
780
781 if (init) Iso15693InitReader();
782
783 int answerLen=0;
784 uint8_t *answer = BigBuf_get_addr() + 4000;
785 if (recv != NULL) memset(answer, 0, 100);
786
787 if (!speed) {
788 // low speed (1 out of 256)
789 CodeIso15693AsReader256(send, sendlen);
790 } else {
791 // high speed (1 out of 4)
792 CodeIso15693AsReader(send, sendlen);
793 }
794
795 LED_A_ON();
796 LED_B_OFF();
797
798 TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);
799 // Now wait for a response
800 if (recv!=NULL) {
801 LED_A_OFF();
802 LED_B_ON();
803 answerLen = GetIso15693AnswerFromTag(answer, 100, &samples, &elapsed) ;
804 *recv=answer;
805 }
806
807 LED_A_OFF();
808 LED_B_OFF();
809 LED_C_OFF();
810 LED_D_OFF();
811
812 return answerLen;
813 }
814
815
816 // --------------------------------------------------------------------
817 // Debug Functions
818 // --------------------------------------------------------------------
819
820 // Decodes a message from a tag and displays its metadata and content
821 #define DBD15STATLEN 48
822 void DbdecodeIso15693Answer(int len, uint8_t *d) {
823 char status[DBD15STATLEN+1]={0};
824 uint16_t crc;
825
826 if (len>3) {
827 if (d[0]&(1<<3))
828 strncat(status,"ProtExt ",DBD15STATLEN);
829 if (d[0]&1) {
830 // error
831 strncat(status,"Error ",DBD15STATLEN);
832 switch (d[1]) {
833 case 0x01:
834 strncat(status,"01:notSupp",DBD15STATLEN);
835 break;
836 case 0x02:
837 strncat(status,"02:notRecog",DBD15STATLEN);
838 break;
839 case 0x03:
840 strncat(status,"03:optNotSupp",DBD15STATLEN);
841 break;
842 case 0x0f:
843 strncat(status,"0f:noInfo",DBD15STATLEN);
844 break;
845 case 0x10:
846 strncat(status,"10:dontExist",DBD15STATLEN);
847 break;
848 case 0x11:
849 strncat(status,"11:lockAgain",DBD15STATLEN);
850 break;
851 case 0x12:
852 strncat(status,"12:locked",DBD15STATLEN);
853 break;
854 case 0x13:
855 strncat(status,"13:progErr",DBD15STATLEN);
856 break;
857 case 0x14:
858 strncat(status,"14:lockErr",DBD15STATLEN);
859 break;
860 default:
861 strncat(status,"unknownErr",DBD15STATLEN);
862 }
863 strncat(status," ",DBD15STATLEN);
864 } else {
865 strncat(status,"NoErr ",DBD15STATLEN);
866 }
867
868 crc=Crc(d,len-2);
869 if ( (( crc & 0xff ) == d[len-2]) && (( crc >> 8 ) == d[len-1]) )
870 strncat(status,"CrcOK",DBD15STATLEN);
871 else
872 strncat(status,"CrcFail!",DBD15STATLEN);
873
874 Dbprintf("%s",status);
875 }
876 }
877
878
879
880 ///////////////////////////////////////////////////////////////////////
881 // Functions called via USB/Client
882 ///////////////////////////////////////////////////////////////////////
883
884 void SetDebugIso15693(uint32_t debug) {
885 DEBUG=debug;
886 Dbprintf("Iso15693 Debug is now %s",DEBUG?"on":"off");
887 return;
888 }
889
890
891
892 //-----------------------------------------------------------------------------
893 // Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector
894 // all demodulation performed in arm rather than host. - greg
895 //-----------------------------------------------------------------------------
896 void ReaderIso15693(uint32_t parameter)
897 {
898 LED_A_ON();
899 LED_B_ON();
900 LED_C_OFF();
901 LED_D_OFF();
902
903 int answerLen1 = 0;
904 int answerLen2 = 0;
905 // int answerLen3 = 0;
906 int i = 0;
907 int samples = 0;
908 int tsamples = 0;
909 int wait = 0;
910 int elapsed = 0;
911 uint8_t TagUID[8] = {0x00};
912
913 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
914
915 uint8_t *answer1 = BigBuf_get_addr() + 4000;
916 uint8_t *answer2 = BigBuf_get_addr() + 4100;
917 // uint8_t *answer3 = BigBuf_get_addr() + 4200;
918 // Blank arrays
919 memset(answer1, 0x00, 200);
920
921 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
922 // Setup SSC
923 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
924
925 // Start from off (no field generated)
926 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
927 SpinDelay(200);
928
929 // Give the tags time to energize
930 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
931 SpinDelay(200);
932
933 LED_A_ON();
934 LED_B_OFF();
935 LED_C_OFF();
936 LED_D_OFF();
937
938 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
939 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
940
941 // Now send the IDENTIFY command
942 BuildIdentifyRequest();
943
944 TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);
945
946 // Now wait for a response
947 answerLen1 = GetIso15693AnswerFromTag(answer1, 100, &samples, &elapsed) ;
948
949 if (answerLen1 >=12) // we should do a better check than this
950 {
951 TagUID[0] = answer1[2];
952 TagUID[1] = answer1[3];
953 TagUID[2] = answer1[4];
954 TagUID[3] = answer1[5];
955 TagUID[4] = answer1[6];
956 TagUID[5] = answer1[7];
957 TagUID[6] = answer1[8]; // IC Manufacturer code
958 TagUID[7] = answer1[9]; // always E0
959
960 }
961
962 Dbprintf("%d octets read from IDENTIFY request:", answerLen1);
963 DbdecodeIso15693Answer(answerLen1,answer1);
964 Dbhexdump(answerLen1,answer1,true);
965
966 // UID is reverse
967 if (answerLen1>=12)
968 Dbprintf("UID = %02hX%02hX%02hX%02hX%02hX%02hX%02hX%02hX",
969 TagUID[7],TagUID[6],TagUID[5],TagUID[4],
970 TagUID[3],TagUID[2],TagUID[1],TagUID[0]);
971
972
973 // Dbprintf("%d octets read from SELECT request:", answerLen2);
974 // DbdecodeIso15693Answer(answerLen2,answer2);
975 // Dbhexdump(answerLen2,answer2,true);
976
977 // Dbprintf("%d octets read from XXX request:", answerLen3);
978 // DbdecodeIso15693Answer(answerLen3,answer3);
979 // Dbhexdump(answerLen3,answer3,true);
980
981 // read all pages
982 if (answerLen1>=12 && DEBUG) {
983 i=0;
984 while (i<32) { // sanity check, assume max 32 pages
985 BuildReadBlockRequest(TagUID,i);
986 TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);
987 answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed);
988 if (answerLen2>0) {
989 Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
990 DbdecodeIso15693Answer(answerLen2,answer2);
991 Dbhexdump(answerLen2,answer2,true);
992 if ( *((uint32_t*) answer2) == 0x07160101 ) break; // exit on NoPageErr
993 }
994 i++;
995 }
996 }
997
998 LED_A_OFF();
999 LED_B_OFF();
1000 LED_C_OFF();
1001 LED_D_OFF();
1002 }
1003
1004 // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
1005 // all demodulation performed in arm rather than host. - greg
1006 void SimTagIso15693(uint32_t parameter, uint8_t *uid)
1007 {
1008 LED_A_ON();
1009 LED_B_ON();
1010 LED_C_OFF();
1011 LED_D_OFF();
1012
1013 int answerLen1 = 0;
1014 int samples = 0;
1015 int tsamples = 0;
1016 int wait = 0;
1017 int elapsed = 0;
1018
1019 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1020
1021 uint8_t *buf = BigBuf_get_addr() + 4000;
1022 memset(buf, 0x00, 100);
1023
1024 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
1025 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
1026
1027 // Start from off (no field generated)
1028 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1029 SpinDelay(200);
1030
1031 LED_A_OFF();
1032 LED_B_OFF();
1033 LED_C_ON();
1034 LED_D_OFF();
1035
1036 // Listen to reader
1037 answerLen1 = GetIso15693AnswerFromSniff(buf, 100, &samples, &elapsed) ;
1038
1039 if (answerLen1 >=1) // we should do a better check than this
1040 {
1041 // Build a suitable reponse to the reader INVENTORY cocmmand
1042 // not so obsvious, but in the call to BuildInventoryResponse, the command is copied to the global ToSend buffer used below.
1043
1044 BuildInventoryResponse(uid);
1045
1046 TransmitTo15693Reader(ToSend,ToSendMax, &tsamples, &wait);
1047 }
1048
1049 Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1,
1050 buf[0], buf[1], buf[2], buf[3],
1051 buf[4], buf[5], buf[6], buf[7], buf[8]);
1052
1053 Dbprintf("Simulationg uid: %x %x %x %x %x %x %x %x",
1054 uid[0], uid[1], uid[2], uid[3],
1055 uid[4], uid[5], uid[6], uid[7]);
1056
1057 LED_A_OFF();
1058 LED_B_OFF();
1059 LED_C_OFF();
1060 LED_D_OFF();
1061 }
1062
1063
1064 // Since there is no standardized way of reading the AFI out of a tag, we will brute force it
1065 // (some manufactures offer a way to read the AFI, though)
1066 void BruteforceIso15693Afi(uint32_t speed)
1067 {
1068 uint8_t data[20];
1069 uint8_t *recv=data;
1070 int datalen=0, recvlen=0;
1071
1072 Iso15693InitReader();
1073
1074 // first without AFI
1075 // Tags should respond wihtout AFI and with AFI=0 even when AFI is active
1076
1077 data[0]=ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
1078 ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
1079 data[1]=ISO15_CMD_INVENTORY;
1080 data[2]=0; // mask length
1081 datalen=AddCrc(data,3);
1082 recvlen=SendDataTag(data,datalen,0,speed,&recv);
1083 WDT_HIT();
1084 if (recvlen>=12) {
1085 Dbprintf("NoAFI UID=%s",sprintUID(NULL,&recv[2]));
1086 }
1087
1088 // now with AFI
1089
1090 data[0]=ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
1091 ISO15_REQ_INVENTORY | ISO15_REQINV_AFI | ISO15_REQINV_SLOT1;
1092 data[1]=ISO15_CMD_INVENTORY;
1093 data[2]=0; // AFI
1094 data[3]=0; // mask length
1095
1096 for (int i=0;i<256;i++) {
1097 data[2]=i & 0xFF;
1098 datalen=AddCrc(data,4);
1099 recvlen=SendDataTag(data,datalen,0,speed,&recv);
1100 WDT_HIT();
1101 if (recvlen>=12) {
1102 Dbprintf("AFI=%i UID=%s",i,sprintUID(NULL,&recv[2]));
1103 }
1104 }
1105 Dbprintf("AFI Bruteforcing done.");
1106
1107 }
1108
1109 // Allows to directly send commands to the tag via the client
1110 void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]) {
1111
1112 int recvlen=0;
1113 uint8_t *recvbuf = BigBuf_get_addr();
1114 // UsbCommand n;
1115
1116 if (DEBUG) {
1117 Dbprintf("SEND");
1118 Dbhexdump(datalen,data,true);
1119 }
1120
1121 recvlen=SendDataTag(data,datalen,1,speed,(recv?&recvbuf:NULL));
1122
1123 if (recv) {
1124 LED_B_ON();
1125 cmd_send(CMD_ACK,recvlen>48?48:recvlen,0,0,recvbuf,48);
1126 LED_B_OFF();
1127
1128 if (DEBUG) {
1129 Dbprintf("RECV");
1130 DbdecodeIso15693Answer(recvlen,recvbuf);
1131 Dbhexdump(recvlen,recvbuf,true);
1132 }
1133 }
1134
1135 }
1136
1137
1138
1139
1140 // --------------------------------------------------------------------
1141 // -- Misc & deprecated functions
1142 // --------------------------------------------------------------------
1143
1144 /*
1145
1146 // do not use; has a fix UID
1147 static void __attribute__((unused)) BuildSysInfoRequest(uint8_t *uid)
1148 {
1149 uint8_t cmd[12];
1150
1151 uint16_t crc;
1152 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1153 // followed by teh block data
1154 // one sub-carrier, inventory, 1 slot, fast rate
1155 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1156 // System Information command code
1157 cmd[1] = 0x2B;
1158 // UID may be optionally specified here
1159 // 64-bit UID
1160 cmd[2] = 0x32;
1161 cmd[3]= 0x4b;
1162 cmd[4] = 0x03;
1163 cmd[5] = 0x01;
1164 cmd[6] = 0x00;
1165 cmd[7] = 0x10;
1166 cmd[8] = 0x05;
1167 cmd[9]= 0xe0; // always e0 (not exactly unique)
1168 //Now the CRC
1169 crc = Crc(cmd, 10); // the crc needs to be calculated over 2 bytes
1170 cmd[10] = crc & 0xff;
1171 cmd[11] = crc >> 8;
1172
1173 CodeIso15693AsReader(cmd, sizeof(cmd));
1174 }
1175
1176
1177 // do not use; has a fix UID
1178 static void __attribute__((unused)) BuildReadMultiBlockRequest(uint8_t *uid)
1179 {
1180 uint8_t cmd[14];
1181
1182 uint16_t crc;
1183 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1184 // followed by teh block data
1185 // one sub-carrier, inventory, 1 slot, fast rate
1186 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1187 // READ Multi BLOCK command code
1188 cmd[1] = 0x23;
1189 // UID may be optionally specified here
1190 // 64-bit UID
1191 cmd[2] = 0x32;
1192 cmd[3]= 0x4b;
1193 cmd[4] = 0x03;
1194 cmd[5] = 0x01;
1195 cmd[6] = 0x00;
1196 cmd[7] = 0x10;
1197 cmd[8] = 0x05;
1198 cmd[9]= 0xe0; // always e0 (not exactly unique)
1199 // First Block number to read
1200 cmd[10] = 0x00;
1201 // Number of Blocks to read
1202 cmd[11] = 0x2f; // read quite a few
1203 //Now the CRC
1204 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1205 cmd[12] = crc & 0xff;
1206 cmd[13] = crc >> 8;
1207
1208 CodeIso15693AsReader(cmd, sizeof(cmd));
1209 }
1210
1211 // do not use; has a fix UID
1212 static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t CmdCode)
1213 {
1214 uint8_t cmd[14];
1215
1216 uint16_t crc;
1217 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1218 // followed by teh block data
1219 // one sub-carrier, inventory, 1 slot, fast rate
1220 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1221 // READ BLOCK command code
1222 cmd[1] = CmdCode;
1223 // UID may be optionally specified here
1224 // 64-bit UID
1225 cmd[2] = 0x32;
1226 cmd[3]= 0x4b;
1227 cmd[4] = 0x03;
1228 cmd[5] = 0x01;
1229 cmd[6] = 0x00;
1230 cmd[7] = 0x10;
1231 cmd[8] = 0x05;
1232 cmd[9]= 0xe0; // always e0 (not exactly unique)
1233 // Parameter
1234 cmd[10] = 0x00;
1235 cmd[11] = 0x0a;
1236
1237 // cmd[12] = 0x00;
1238 // cmd[13] = 0x00; //Now the CRC
1239 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1240 cmd[12] = crc & 0xff;
1241 cmd[13] = crc >> 8;
1242
1243 CodeIso15693AsReader(cmd, sizeof(cmd));
1244 }
1245
1246 // do not use; has a fix UID
1247 static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], uint8_t CmdCode)
1248 {
1249 uint8_t cmd[14];
1250
1251 uint16_t crc;
1252 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1253 // followed by teh block data
1254 // one sub-carrier, inventory, 1 slot, fast rate
1255 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1256 // READ BLOCK command code
1257 cmd[1] = CmdCode;
1258 // UID may be optionally specified here
1259 // 64-bit UID
1260 cmd[2] = 0x32;
1261 cmd[3]= 0x4b;
1262 cmd[4] = 0x03;
1263 cmd[5] = 0x01;
1264 cmd[6] = 0x00;
1265 cmd[7] = 0x10;
1266 cmd[8] = 0x05;
1267 cmd[9]= 0xe0; // always e0 (not exactly unique)
1268 // Parameter
1269 cmd[10] = 0x05; // for custom codes this must be manufcturer code
1270 cmd[11] = 0x00;
1271
1272 // cmd[12] = 0x00;
1273 // cmd[13] = 0x00; //Now the CRC
1274 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1275 cmd[12] = crc & 0xff;
1276 cmd[13] = crc >> 8;
1277
1278 CodeIso15693AsReader(cmd, sizeof(cmd));
1279 }
1280
1281
1282
1283
1284 */
1285
1286
Impressum, Datenschutz