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