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