]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso15693.c
test: hf 15 sim..
[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"
7bd30f12 67#include "crapto1.h"
68#include "mifareutil.h"
15c4dc5a 69
15c4dc5a 70#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
71
9455b51c 72///////////////////////////////////////////////////////////////////////
73// ISO 15693 Part 2 - Air Interface
74// This section basicly contains transmission and receiving of bits
75///////////////////////////////////////////////////////////////////////
76
77#define FrameSOF Iso15693FrameSOF
78#define Logic0 Iso15693Logic0
79#define Logic1 Iso15693Logic1
80#define FrameEOF Iso15693FrameEOF
15c4dc5a 81
9455b51c 82#define Crc(data,datalen) Iso15693Crc(data,datalen)
83#define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
84#define sprintUID(target,uid) Iso15693sprintUID(target,uid)
15c4dc5a 85
9455b51c 86int DEBUG=0;
87
88
89// ---------------------------
90// Signal Processing
91// ---------------------------
92
93// prepare data using "1 out of 4" code for later transmission
94// resulting data rate is 26,48 kbit/s (fc/512)
95// cmd ... data
96// n ... length of data
f7e3ed82 97static void CodeIso15693AsReader(uint8_t *cmd, int n)
15c4dc5a 98{
99 int i, j;
100
101 ToSendReset();
102
103 // Give it a bit of slack at the beginning
104 for(i = 0; i < 24; i++) {
105 ToSendStuffBit(1);
106 }
107
9455b51c 108 // SOF for 1of4
15c4dc5a 109 ToSendStuffBit(0);
110 ToSendStuffBit(1);
111 ToSendStuffBit(1);
112 ToSendStuffBit(1);
113 ToSendStuffBit(1);
114 ToSendStuffBit(0);
115 ToSendStuffBit(1);
116 ToSendStuffBit(1);
117 for(i = 0; i < n; i++) {
118 for(j = 0; j < 8; j += 2) {
119 int these = (cmd[i] >> j) & 3;
120 switch(these) {
121 case 0:
122 ToSendStuffBit(1);
123 ToSendStuffBit(0);
124 ToSendStuffBit(1);
125 ToSendStuffBit(1);
126 ToSendStuffBit(1);
127 ToSendStuffBit(1);
128 ToSendStuffBit(1);
129 ToSendStuffBit(1);
130 break;
131 case 1:
132 ToSendStuffBit(1);
133 ToSendStuffBit(1);
134 ToSendStuffBit(1);
135 ToSendStuffBit(0);
136 ToSendStuffBit(1);
137 ToSendStuffBit(1);
138 ToSendStuffBit(1);
139 ToSendStuffBit(1);
140 break;
141 case 2:
142 ToSendStuffBit(1);
143 ToSendStuffBit(1);
144 ToSendStuffBit(1);
145 ToSendStuffBit(1);
146 ToSendStuffBit(1);
147 ToSendStuffBit(0);
148 ToSendStuffBit(1);
149 ToSendStuffBit(1);
150 break;
151 case 3:
152 ToSendStuffBit(1);
153 ToSendStuffBit(1);
154 ToSendStuffBit(1);
155 ToSendStuffBit(1);
156 ToSendStuffBit(1);
157 ToSendStuffBit(1);
158 ToSendStuffBit(1);
159 ToSendStuffBit(0);
160 break;
161 }
162 }
163 }
9455b51c 164 // EOF
15c4dc5a 165 ToSendStuffBit(1);
166 ToSendStuffBit(1);
167 ToSendStuffBit(0);
168 ToSendStuffBit(1);
169
170 // And slack at the end, too.
171 for(i = 0; i < 24; i++) {
172 ToSendStuffBit(1);
173 }
174}
175
9455b51c 176// encode data using "1 out of 256" sheme
177// data rate is 1,66 kbit/s (fc/8192)
178// is designed for more robust communication over longer distances
179static void CodeIso15693AsReader256(uint8_t *cmd, int n)
15c4dc5a 180{
15c4dc5a 181 int i, j;
182
9455b51c 183 ToSendReset();
184
185 // Give it a bit of slack at the beginning
186 for(i = 0; i < 24; i++) {
187 ToSendStuffBit(1);
188 }
189
190 // SOF for 1of256
191 ToSendStuffBit(0);
192 ToSendStuffBit(1);
193 ToSendStuffBit(1);
194 ToSendStuffBit(1);
195 ToSendStuffBit(1);
196 ToSendStuffBit(1);
197 ToSendStuffBit(1);
198 ToSendStuffBit(0);
199
15c4dc5a 200 for(i = 0; i < n; i++) {
9455b51c 201 for (j = 0; j<=255; j++) {
202 if (cmd[i]==j) {
203 ToSendStuffBit(1);
204 ToSendStuffBit(0);
15c4dc5a 205 } else {
9455b51c 206 ToSendStuffBit(1);
207 ToSendStuffBit(1);
208 }
209 }
15c4dc5a 210 }
9455b51c 211 // EOF
212 ToSendStuffBit(1);
213 ToSendStuffBit(1);
214 ToSendStuffBit(0);
215 ToSendStuffBit(1);
15c4dc5a 216
9455b51c 217 // And slack at the end, too.
218 for(i = 0; i < 24; i++) {
219 ToSendStuffBit(1);
220 }
15c4dc5a 221}
222
9455b51c 223
15c4dc5a 224// Transmit the command (to the tag) that was placed in ToSend[].
f7e3ed82 225static void TransmitTo15693Tag(const uint8_t *cmd, int len, int *samples, int *wait)
15c4dc5a 226{
227 int c;
228
229// FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
230 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
231 if(*wait < 10) { *wait = 10; }
232
233// for(c = 0; c < *wait;) {
234// if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
235// AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
236// c++;
237// }
238// if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
f7e3ed82 239// volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
15c4dc5a 240// (void)r;
241// }
242// WDT_HIT();
243// }
244
245 c = 0;
246 for(;;) {
247 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
248 AT91C_BASE_SSC->SSC_THR = cmd[c];
249 c++;
250 if(c >= len) {
251 break;
252 }
253 }
254 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
f7e3ed82 255 volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
15c4dc5a 256 (void)r;
257 }
258 WDT_HIT();
259 }
260 *samples = (c + *wait) << 3;
261}
262
263//-----------------------------------------------------------------------------
264// Transmit the command (to the reader) that was placed in ToSend[].
265//-----------------------------------------------------------------------------
f7e3ed82 266static void TransmitTo15693Reader(const uint8_t *cmd, int len, int *samples, int *wait)
15c4dc5a 267{
3649b640 268 int c = 0;
269 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K);
15c4dc5a 270 if(*wait < 10) { *wait = 10; }
271
15c4dc5a 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
3649b640 456 // NOW READ RESPONSE
15c4dc5a 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{
7bd30f12 602 uint8_t *dest = mifare_get_bigbufptr();
603
15c4dc5a 604 int c = 0;
15c4dc5a 605 int getNext = 0;
f7e3ed82 606 int8_t prev = 0;
15c4dc5a 607
7cc204bf 608 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 609 BuildIdentifyRequest();
610
611 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
612
613 // Give the tags time to energize
614 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
615 SpinDelay(100);
616
617 // Now send the command
618 FpgaSetupSsc();
619 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
620
621 c = 0;
622 for(;;) {
623 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
624 AT91C_BASE_SSC->SSC_THR = ToSend[c];
625 c++;
626 if(c == ToSendMax+3) {
627 break;
628 }
629 }
630 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
f7e3ed82 631 volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
15c4dc5a 632 (void)r;
633 }
634 WDT_HIT();
635 }
636
637 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
638
639 c = 0;
640 getNext = FALSE;
641 for(;;) {
642 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
643 AT91C_BASE_SSC->SSC_THR = 0x43;
644 }
645 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
f7e3ed82 646 int8_t b;
647 b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
15c4dc5a 648
9455b51c 649 // The samples are correlations against I and Q versions of the
650 // tone that the tag AM-modulates, so every other sample is I,
651 // every other is Q. We just want power, so abs(I) + abs(Q) is
652 // close to what we want.
653 if(getNext) {
654 int8_t r;
655
656 if(b < 0) {
657 r = -b;
658 } else {
659 r = b;
660 }
661 if(prev < 0) {
662 r -= prev;
663 } else {
664 r += prev;
665 }
666
667 dest[c++] = (uint8_t)r;
668
669 if(c >= 2000) {
670 break;
671 }
672 } else {
673 prev = b;
674 }
675
676 getNext = !getNext;
677 }
678 }
679}
680
681
682void RecordRawAdcSamplesIso15693(void)
683{
7bd30f12 684 uint8_t *dest = mifare_get_bigbufptr();
685
9455b51c 686 int c = 0;
9455b51c 687 int getNext = 0;
9455b51c 688 int8_t prev = 0;
689
7cc204bf 690 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
9455b51c 691 // Setup SSC
692 FpgaSetupSsc();
693
694 // Start from off (no field generated)
7bd30f12 695 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
696 SpinDelay(200);
9455b51c 697
698 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
699
700 SpinDelay(100);
701
702 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
703
704 c = 0;
705 getNext = FALSE;
706 for(;;) {
707 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
708 AT91C_BASE_SSC->SSC_THR = 0x43;
709 }
710 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
711 int8_t b;
712 b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
713
714 // The samples are correlations against I and Q versions of the
715 // tone that the tag AM-modulates, so every other sample is I,
716 // every other is Q. We just want power, so abs(I) + abs(Q) is
717 // close to what we want.
718 if(getNext) {
719 int8_t r;
720
721 if(b < 0) {
722 r = -b;
723 } else {
724 r = b;
725 }
726 if(prev < 0) {
727 r -= prev;
728 } else {
729 r += prev;
730 }
731
732 dest[c++] = (uint8_t)r;
733
734 if(c >= 7000) {
735 break;
736 }
737 } else {
738 prev = b;
739 }
740
741 getNext = !getNext;
742 WDT_HIT();
743 }
744 }
745 Dbprintf("fin record");
746}
747
748
749// Initialize the proxmark as iso15k reader
e6304bca 750// (this might produces glitches that confuse some tags
9455b51c 751void Iso15693InitReader() {
752 LED_A_ON();
753 LED_B_ON();
754 LED_C_OFF();
755 LED_D_OFF();
756
7cc204bf 757 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
9455b51c 758 // Setup SSC
e6304bca 759 // FpgaSetupSsc();
9455b51c 760
761 // Start from off (no field generated)
762 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
e6304bca 763 SpinDelay(10);
9455b51c 764
765 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
766 FpgaSetupSsc();
767
768 // Give the tags time to energize
769 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
e6304bca 770 SpinDelay(250);
9455b51c 771
772 LED_A_ON();
773 LED_B_OFF();
774 LED_C_OFF();
775 LED_D_OFF();
776}
777
778///////////////////////////////////////////////////////////////////////
779// ISO 15693 Part 3 - Air Interface
780// This section basicly contains transmission and receiving of bits
781///////////////////////////////////////////////////////////////////////
782
783// Encode (into the ToSend buffers) an identify request, which is the first
784// thing that you must send to a tag to get a response.
785static void BuildIdentifyRequest(void)
786{
787 uint8_t cmd[5];
788
789 uint16_t crc;
790 // one sub-carrier, inventory, 1 slot, fast rate
791 // AFI is at bit 5 (1<<4) when doing an INVENTORY
792 cmd[0] = (1 << 2) | (1 << 5) | (1 << 1);
793 // inventory command code
794 cmd[1] = 0x01;
795 // no mask
796 cmd[2] = 0x00;
797 //Now the CRC
798 crc = Crc(cmd, 3);
799 cmd[3] = crc & 0xff;
800 cmd[4] = crc >> 8;
801
802 CodeIso15693AsReader(cmd, sizeof(cmd));
803}
804
805// uid is in transmission order (which is reverse of display order)
806static void BuildReadBlockRequest(uint8_t *uid, uint8_t blockNumber )
807{
808 uint8_t cmd[13];
809
810 uint16_t crc;
811 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
812 // followed by teh block data
813 // one sub-carrier, inventory, 1 slot, fast rate
814 cmd[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit, ADDR bit, OPTION bit
815 // READ BLOCK command code
816 cmd[1] = 0x20;
817 // UID may be optionally specified here
818 // 64-bit UID
819 cmd[2] = uid[0];
820 cmd[3] = uid[1];
821 cmd[4] = uid[2];
822 cmd[5] = uid[3];
823 cmd[6] = uid[4];
824 cmd[7] = uid[5];
825 cmd[8] = uid[6];
826 cmd[9] = uid[7]; // 0xe0; // always e0 (not exactly unique)
827 // Block number to read
828 cmd[10] = blockNumber;//0x00;
829 //Now the CRC
830 crc = Crc(cmd, 11); // the crc needs to be calculated over 12 bytes
831 cmd[11] = crc & 0xff;
832 cmd[12] = crc >> 8;
833
834 CodeIso15693AsReader(cmd, sizeof(cmd));
835}
836
837// Now the VICC>VCD responses when we are simulating a tag
3649b640 838 static void BuildInventoryResponse( uint8_t *uid)
9455b51c 839{
a25d5c1c 840 uint8_t cmd[13];
9455b51c 841
842 uint16_t crc;
843 // one sub-carrier, inventory, 1 slot, fast rate
844 // AFI is at bit 5 (1<<4) when doing an INVENTORY
a25d5c1c 845 cmd[0] = 0x0d; // COM LEN? Data 8 + 4 //(1 << 2) | (1 << 5) | (1 << 1);
846 cmd[1] = 0; // com_Adr
847 cmd[2] = 0; // status 00 = success
9455b51c 848 // 64-bit UID
a25d5c1c 849 cmd[3] = uid[7]; //0x32;
850 cmd[4] = uid[6]; //0x4b;
851 cmd[5] = uid[5]; //0x03;
852 cmd[6] = uid[4]; //0x01;
853 cmd[7] = uid[3]; //0x00;
854 cmd[8] = uid[2]; //0x10;
855 cmd[9] = uid[1]; //0x05;
856 cmd[10] = uid[0]; //0xe0;
9455b51c 857 //Now the CRC
858 crc = Crc(cmd, 10);
a25d5c1c 859 cmd[11] = crc & 0xff;
860 cmd[12] = crc >> 8;
9455b51c 861
862 CodeIso15693AsReader(cmd, sizeof(cmd));
863}
864
e6304bca 865// Universal Method for sending to and recv bytes from a tag
9455b51c 866// init ... should we initialize the reader?
867// speed ... 0 low speed, 1 hi speed
868// **recv will return you a pointer to the received data
869// If you do not need the answer use NULL for *recv[]
870// return: lenght of received data
871int SendDataTag(uint8_t *send, int sendlen, int init, int speed, uint8_t **recv) {
872
873 int samples = 0;
874 int tsamples = 0;
875 int wait = 0;
876 int elapsed = 0;
877
878 LED_A_ON();
879 LED_B_ON();
880 LED_C_OFF();
881 LED_D_OFF();
882
883 int answerLen=0;
884 uint8_t *answer = (((uint8_t *)BigBuf) + 3660);
885 if (recv!=NULL) memset(BigBuf + 3660, 0, 100);
886
887 if (init) Iso15693InitReader();
888
889 if (!speed) {
890 // low speed (1 out of 256)
891 CodeIso15693AsReader256(send, sendlen);
892 } else {
893 // high speed (1 out of 4)
894 CodeIso15693AsReader(send, sendlen);
895 }
896
897 LED_A_ON();
898 LED_B_OFF();
899
900 TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);
901 // Now wait for a response
902 if (recv!=NULL) {
903 LED_A_OFF();
904 LED_B_ON();
905 answerLen = GetIso15693AnswerFromTag(answer, 100, &samples, &elapsed) ;
906 *recv=answer;
907 }
908
909 LED_A_OFF();
910 LED_B_OFF();
911 LED_C_OFF();
912 LED_D_OFF();
913
914 return answerLen;
915}
15c4dc5a 916
15c4dc5a 917
9455b51c 918// --------------------------------------------------------------------
919// Debug Functions
920// --------------------------------------------------------------------
15c4dc5a 921
9455b51c 922// Decodes a message from a tag and displays its metadata and content
923#define DBD15STATLEN 48
924void DbdecodeIso15693Answer(int len, uint8_t *d) {
925 char status[DBD15STATLEN+1]={0};
926 uint16_t crc;
927
928 if (len>3) {
929 if (d[0]&(1<<3))
930 strncat(status,"ProtExt ",DBD15STATLEN);
931 if (d[0]&1) {
932 // error
933 strncat(status,"Error ",DBD15STATLEN);
934 switch (d[1]) {
935 case 0x01:
936 strncat(status,"01:notSupp",DBD15STATLEN);
15c4dc5a 937 break;
9455b51c 938 case 0x02:
939 strncat(status,"02:notRecog",DBD15STATLEN);
940 break;
941 case 0x03:
942 strncat(status,"03:optNotSupp",DBD15STATLEN);
943 break;
944 case 0x0f:
945 strncat(status,"0f:noInfo",DBD15STATLEN);
946 break;
947 case 0x10:
948 strncat(status,"10:dontExist",DBD15STATLEN);
949 break;
950 case 0x11:
951 strncat(status,"11:lockAgain",DBD15STATLEN);
952 break;
953 case 0x12:
954 strncat(status,"12:locked",DBD15STATLEN);
955 break;
956 case 0x13:
957 strncat(status,"13:progErr",DBD15STATLEN);
958 break;
959 case 0x14:
960 strncat(status,"14:lockErr",DBD15STATLEN);
961 break;
962 default:
963 strncat(status,"unknownErr",DBD15STATLEN);
15c4dc5a 964 }
9455b51c 965 strncat(status," ",DBD15STATLEN);
966 } else {
967 strncat(status,"NoErr ",DBD15STATLEN);
15c4dc5a 968 }
9455b51c 969
970 crc=Crc(d,len-2);
971 if ( (( crc & 0xff ) == d[len-2]) && (( crc >> 8 ) == d[len-1]) )
972 strncat(status,"CrcOK",DBD15STATLEN);
973 else
974 strncat(status,"CrcFail!",DBD15STATLEN);
975
976 Dbprintf("%s",status);
15c4dc5a 977 }
978}
979
9455b51c 980
981
982///////////////////////////////////////////////////////////////////////
983// Functions called via USB/Client
984///////////////////////////////////////////////////////////////////////
985
986void SetDebugIso15693(uint32_t debug) {
987 DEBUG=debug;
988 Dbprintf("Iso15693 Debug is now %s",DEBUG?"on":"off");
989 return;
990}
991
992
993
15c4dc5a 994//-----------------------------------------------------------------------------
995// Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector
996// all demodulation performed in arm rather than host. - greg
997//-----------------------------------------------------------------------------
3649b640 998void ReaderIso15693(uint32_t parameter )
15c4dc5a 999{
1000 LED_A_ON();
1001 LED_B_ON();
1002 LED_C_OFF();
1003 LED_D_OFF();
1004
f7e3ed82 1005 uint8_t *answer1 = (((uint8_t *)BigBuf) + 3660); //
1006 uint8_t *answer2 = (((uint8_t *)BigBuf) + 3760);
1007 uint8_t *answer3 = (((uint8_t *)BigBuf) + 3860);
3649b640 1008
15c4dc5a 1009 int answerLen1 = 0;
1010 int answerLen2 = 0;
1011 int answerLen3 = 0;
3649b640 1012 int i = 0;
1013 int samples = 0;
1014 int tsamples = 0;
1015 int wait = 0;
1016 int elapsed = 0;
1017 uint8_t TagUID[8] = {0x00};
15c4dc5a 1018
3649b640 1019
15c4dc5a 1020 // Blank arrays
3649b640 1021 memset(BigBuf + 3660, 0x00, 300);
15c4dc5a 1022
7cc204bf 1023 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1024
1025 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
3649b640 1026 // Setup SSC
15c4dc5a 1027 FpgaSetupSsc();
1028
3649b640 1029 // Start from off (no field generated)
1030 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1031 SpinDelay(200);
1032
15c4dc5a 1033 // Give the tags time to energize
1034 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
1035 SpinDelay(200);
1036
1037 LED_A_ON();
1038 LED_B_OFF();
1039 LED_C_OFF();
1040 LED_D_OFF();
1041
15c4dc5a 1042 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
1043 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
15c4dc5a 1044
1045 // Now send the IDENTIFY command
1046 BuildIdentifyRequest();
3649b640 1047
1048 TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);
1049
15c4dc5a 1050 // Now wait for a response
1051 answerLen1 = GetIso15693AnswerFromTag(answer1, 100, &samples, &elapsed) ;
1052
1053 if (answerLen1 >=12) // we should do a better check than this
1054 {
15c4dc5a 1055 TagUID[0] = answer1[2];
1056 TagUID[1] = answer1[3];
1057 TagUID[2] = answer1[4];
1058 TagUID[3] = answer1[5];
1059 TagUID[4] = answer1[6];
1060 TagUID[5] = answer1[7];
1061 TagUID[6] = answer1[8]; // IC Manufacturer code
9455b51c 1062 TagUID[7] = answer1[9]; // always E0
15c4dc5a 1063
15c4dc5a 1064 }
1065
9455b51c 1066 Dbprintf("%d octets read from IDENTIFY request:", answerLen1);
1067 DbdecodeIso15693Answer(answerLen1,answer1);
d19929cb 1068 Dbhexdump(answerLen1,answer1,true);
9455b51c 1069
1070 // UID is reverse
3649b640 1071 if (answerLen1 >= 12)
1072 Dbprintf("UID = %02hX%02hX%02hX%02hX%02hX%02hX%02hX%02hX",
1073 TagUID[7],TagUID[6],TagUID[5],TagUID[4],
1074 TagUID[3],TagUID[2],TagUID[1],TagUID[0]);
9455b51c 1075
1076
1077 Dbprintf("%d octets read from SELECT request:", answerLen2);
1078 DbdecodeIso15693Answer(answerLen2,answer2);
d19929cb 1079 Dbhexdump(answerLen2,answer2,true);
9455b51c 1080
1081 Dbprintf("%d octets read from XXX request:", answerLen3);
1082 DbdecodeIso15693Answer(answerLen3,answer3);
d19929cb 1083 Dbhexdump(answerLen3,answer3,true);
9455b51c 1084
3649b640 1085 // read all pages
1086 if (answerLen1 >= 12 && DEBUG) {
9455b51c 1087 i=0;
3649b640 1088 while (i < 32) { // sanity check, assume max 32 pages
9455b51c 1089 BuildReadBlockRequest(TagUID,i);
3649b640 1090 TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);
1091 answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed);
1092 if (answerLen2 > 0) {
9455b51c 1093 Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
1094 DbdecodeIso15693Answer(answerLen2,answer2);
d19929cb 1095 Dbhexdump(answerLen2,answer2,true);
9455b51c 1096 if ( *((uint32_t*) answer2) == 0x07160101 ) break; // exit on NoPageErr
1097 }
1098 i++;
1099 }
1100 }
15c4dc5a 1101
15c4dc5a 1102 LED_A_OFF();
1103 LED_B_OFF();
1104 LED_C_OFF();
1105 LED_D_OFF();
1106}
1107
15c4dc5a 1108// Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
1109// all demodulation performed in arm rather than host. - greg
3649b640 1110void SimTagIso15693(uint32_t parameter, uint8_t *uid)
15c4dc5a 1111{
1112 LED_A_ON();
1113 LED_B_ON();
1114 LED_C_OFF();
1115 LED_D_OFF();
1116
3649b640 1117 uint8_t *buf = (((uint8_t *)BigBuf) + 3660); //
1118
15c4dc5a 1119 int answerLen1 = 0;
3649b640 1120 int samples = 0;
1121 int tsamples = 0;
1122 int wait = 0;
1123 int elapsed = 0;
1124
1125 memset(buf, 0x00, 100);
1126
1127 // Inventory response
1128 BuildInventoryResponse(uid);
1129
7cc204bf 1130 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1131
1132 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
3649b640 1133
15c4dc5a 1134 FpgaSetupSsc();
1135
3649b640 1136 // Start from off (no field generated)
1137 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1138 SpinDelay(200);
15c4dc5a 1139
1140 LED_A_OFF();
1141 LED_B_OFF();
1142 LED_C_ON();
1143 LED_D_OFF();
1144
3649b640 1145 // Listen to reader
1146 answerLen1 = GetIso15693AnswerFromSniff(buf, 100, &samples, &elapsed) ;
15c4dc5a 1147
1148 if (answerLen1 >=1) // we should do a better check than this
1149 {
1150 // Build a suitable reponse to the reader INVENTORY cocmmand
3649b640 1151 // not so obsvious, but in the call to BuildInventoryResponse, the command is copied to the global ToSend buffer used below.
1152 TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait);
15c4dc5a 1153 }
1154
1155 Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1,
3649b640 1156 buf[0], buf[1], buf[2], buf[3],
1157 buf[4], buf[5], buf[6], buf[7], buf[8]);
15c4dc5a 1158
1159 LED_A_OFF();
1160 LED_B_OFF();
1161 LED_C_OFF();
1162 LED_D_OFF();
1163}
9455b51c 1164
1165
1166// Since there is no standardized way of reading the AFI out of a tag, we will brute force it
1167// (some manufactures offer a way to read the AFI, though)
1168void BruteforceIso15693Afi(uint32_t speed)
1169{
1170 uint8_t data[20];
1171 uint8_t *recv=data;
1172 int datalen=0, recvlen=0;
1173
1174 Iso15693InitReader();
1175
1176 // first without AFI
1177 // Tags should respond wihtout AFI and with AFI=0 even when AFI is active
1178
1179 data[0]=ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
1180 ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
1181 data[1]=ISO15_CMD_INVENTORY;
1182 data[2]=0; // mask length
1183 datalen=AddCrc(data,3);
1184 recvlen=SendDataTag(data,datalen,0,speed,&recv);
1185 WDT_HIT();
1186 if (recvlen>=12) {
1187 Dbprintf("NoAFI UID=%s",sprintUID(NULL,&recv[2]));
1188 }
1189
1190 // now with AFI
1191
1192 data[0]=ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
1193 ISO15_REQ_INVENTORY | ISO15_REQINV_AFI | ISO15_REQINV_SLOT1;
1194 data[1]=ISO15_CMD_INVENTORY;
1195 data[2]=0; // AFI
1196 data[3]=0; // mask length
1197
1198 for (int i=0;i<256;i++) {
1199 data[2]=i & 0xFF;
1200 datalen=AddCrc(data,4);
1201 recvlen=SendDataTag(data,datalen,0,speed,&recv);
1202 WDT_HIT();
1203 if (recvlen>=12) {
1204 Dbprintf("AFI=%i UID=%s",i,sprintUID(NULL,&recv[2]));
1205 }
1206 }
1207 Dbprintf("AFI Bruteforcing done.");
1208
1209}
1210
1211// Allows to directly send commands to the tag via the client
1212void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]) {
1213
1214 int recvlen=0;
1215 uint8_t *recvbuf=(uint8_t *)BigBuf;
902cb3c0 1216// UsbCommand n;
9455b51c 1217
1218 if (DEBUG) {
1219 Dbprintf("SEND");
d19929cb 1220 Dbhexdump(datalen,data,true);
9455b51c 1221 }
1222
1223 recvlen=SendDataTag(data,datalen,1,speed,(recv?&recvbuf:NULL));
1224
1225 if (recv) {
9455b51c 1226 LED_B_ON();
902cb3c0 1227 cmd_send(CMD_ACK,recvlen>48?48:recvlen,0,0,recvbuf,48);
9455b51c 1228 LED_B_OFF();
1229
1230 if (DEBUG) {
1231 Dbprintf("RECV");
1232 DbdecodeIso15693Answer(recvlen,recvbuf);
d19929cb 1233 Dbhexdump(recvlen,recvbuf,true);
9455b51c 1234 }
1235 }
1236
1237}
1238
1239
1240
1241
1242// --------------------------------------------------------------------
1243// -- Misc & deprecated functions
1244// --------------------------------------------------------------------
1245
e6304bca 1246/*
9455b51c 1247
1248// do not use; has a fix UID
1249static void __attribute__((unused)) BuildSysInfoRequest(uint8_t *uid)
1250{
1251 uint8_t cmd[12];
1252
1253 uint16_t crc;
1254 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1255 // followed by teh block data
1256 // one sub-carrier, inventory, 1 slot, fast rate
1257 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1258 // System Information command code
1259 cmd[1] = 0x2B;
1260 // UID may be optionally specified here
1261 // 64-bit UID
1262 cmd[2] = 0x32;
1263 cmd[3]= 0x4b;
1264 cmd[4] = 0x03;
1265 cmd[5] = 0x01;
1266 cmd[6] = 0x00;
1267 cmd[7] = 0x10;
1268 cmd[8] = 0x05;
1269 cmd[9]= 0xe0; // always e0 (not exactly unique)
1270 //Now the CRC
1271 crc = Crc(cmd, 10); // the crc needs to be calculated over 2 bytes
1272 cmd[10] = crc & 0xff;
1273 cmd[11] = crc >> 8;
1274
1275 CodeIso15693AsReader(cmd, sizeof(cmd));
1276}
1277
9455b51c 1278
1279// do not use; has a fix UID
1280static void __attribute__((unused)) BuildReadMultiBlockRequest(uint8_t *uid)
1281{
1282 uint8_t cmd[14];
1283
1284 uint16_t crc;
1285 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1286 // followed by teh block data
1287 // one sub-carrier, inventory, 1 slot, fast rate
1288 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1289 // READ Multi BLOCK command code
1290 cmd[1] = 0x23;
1291 // UID may be optionally specified here
1292 // 64-bit UID
1293 cmd[2] = 0x32;
1294 cmd[3]= 0x4b;
1295 cmd[4] = 0x03;
1296 cmd[5] = 0x01;
1297 cmd[6] = 0x00;
1298 cmd[7] = 0x10;
1299 cmd[8] = 0x05;
1300 cmd[9]= 0xe0; // always e0 (not exactly unique)
1301 // First Block number to read
1302 cmd[10] = 0x00;
1303 // Number of Blocks to read
1304 cmd[11] = 0x2f; // read quite a few
1305 //Now the CRC
1306 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1307 cmd[12] = crc & 0xff;
1308 cmd[13] = crc >> 8;
1309
1310 CodeIso15693AsReader(cmd, sizeof(cmd));
1311}
1312
1313// do not use; has a fix UID
1314static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t CmdCode)
1315{
1316 uint8_t cmd[14];
1317
1318 uint16_t crc;
1319 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1320 // followed by teh block data
1321 // one sub-carrier, inventory, 1 slot, fast rate
1322 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1323 // READ BLOCK command code
1324 cmd[1] = CmdCode;
1325 // UID may be optionally specified here
1326 // 64-bit UID
1327 cmd[2] = 0x32;
1328 cmd[3]= 0x4b;
1329 cmd[4] = 0x03;
1330 cmd[5] = 0x01;
1331 cmd[6] = 0x00;
1332 cmd[7] = 0x10;
1333 cmd[8] = 0x05;
1334 cmd[9]= 0xe0; // always e0 (not exactly unique)
1335 // Parameter
1336 cmd[10] = 0x00;
1337 cmd[11] = 0x0a;
1338
1339// cmd[12] = 0x00;
1340// cmd[13] = 0x00; //Now the CRC
1341 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1342 cmd[12] = crc & 0xff;
1343 cmd[13] = crc >> 8;
1344
1345 CodeIso15693AsReader(cmd, sizeof(cmd));
1346}
1347
1348// do not use; has a fix UID
1349static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], uint8_t CmdCode)
1350{
1351 uint8_t cmd[14];
1352
1353 uint16_t crc;
1354 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1355 // followed by teh block data
1356 // one sub-carrier, inventory, 1 slot, fast rate
1357 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1358 // READ BLOCK command code
1359 cmd[1] = CmdCode;
1360 // UID may be optionally specified here
1361 // 64-bit UID
1362 cmd[2] = 0x32;
1363 cmd[3]= 0x4b;
1364 cmd[4] = 0x03;
1365 cmd[5] = 0x01;
1366 cmd[6] = 0x00;
1367 cmd[7] = 0x10;
1368 cmd[8] = 0x05;
1369 cmd[9]= 0xe0; // always e0 (not exactly unique)
1370 // Parameter
1371 cmd[10] = 0x05; // for custom codes this must be manufcturer code
1372 cmd[11] = 0x00;
1373
1374// cmd[12] = 0x00;
1375// cmd[13] = 0x00; //Now the CRC
1376 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1377 cmd[12] = crc & 0xff;
1378 cmd[13] = crc >> 8;
1379
1380 CodeIso15693AsReader(cmd, sizeof(cmd));
1381}
1382
1383
1384
1385
e6304bca 1386*/
9455b51c 1387
1388
Impressum, Datenschutz