1 //-----------------------------------------------------------------------------
2 // Jonathan Westhues, split Nov 2006
3 // Modified by Greg Jones, Jan 2009
4 // Modified by Adrian Dabrowski "atrox", Mar-Sept 2010,Oct 2011
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
9 //-----------------------------------------------------------------------------
10 // Routines to support ISO 15693. This includes both the reader software and
11 // the `fake tag' modes, but at the moment I've implemented only the reader
12 // stuff, and that barely.
13 // Modified to perform modulation onboard in arm rather than on PC
14 // Also added additional reader commands (SELECT, READ etc.)
15 //-----------------------------------------------------------------------------
16 // The ISO 15693 describes two transmission modes from reader to tag, and 4
17 // transmission modes from tag to reader. As of Mar 2010 this code only
18 // supports one of each: "1of4" mode from reader to tag, and the highspeed
19 // variant with one subcarrier from card to reader.
20 // As long, as the card fully support ISO 15693 this is no problem, since the
21 // reader chooses both data rates, but some non-standard tags do not. Further for
22 // the simulation to work, we will need to support all data rates.
24 // VCD (reader) -> VICC (tag)
26 // data rate: 1,66 kbit/s (fc/8192)
27 // used for long range
29 // data rate: 26,48 kbit/s (fc/512)
30 // used for short range, high speed
32 // VICC (tag) -> VCD (reader)
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
46 // *) UID is always used "transmission order" (LSB), which is reverse to display order
48 // TODO / BUGS / ISSUES:
49 // *) writing to tags takes longer: we miss the answer from the tag in most cases
50 // -> tweak the read-timeout times
51 // *) signal decoding from the card is still a bit shaky.
52 // *) signal decoding is unable to detect collissions.
53 // *) add anti-collission support for inventory-commands
54 // *) read security status of a block
55 // *) sniffing and simulation do only support one transmission mode. need to support
56 // all 8 transmission combinations
57 // *) remove or refactor code under "depricated"
58 // *) document all the functions
61 #include "proxmark3.h"
65 #include "iso15693tools.h"
68 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
72 ///////////////////////////////////////////////////////////////////////
73 // ISO 15693 Part 2 - Air Interface
74 // This section basicly contains transmission and receiving of bits
75 ///////////////////////////////////////////////////////////////////////
77 #define FrameSOF Iso15693FrameSOF
78 #define Logic0 Iso15693Logic0
79 #define Logic1 Iso15693Logic1
80 #define FrameEOF Iso15693FrameEOF
82 #define Crc(data,datalen) Iso15693Crc(data,datalen)
83 #define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
84 #define sprintUID(target,uid) Iso15693sprintUID(target,uid)
86 // approximate amplitude=sqrt(ci^2+cq^2)
87 #define AMPLITUDE(ci, cq) (MAX(ABS(ci), ABS(cq)) + MIN(ABS(ci), ABS(cq))/2)
90 #define ISO15693_DMA_BUFFER_SIZE 128
92 // ---------------------------
94 // ---------------------------
96 // prepare data using "1 out of 4" code for later transmission
97 // resulting data rate is 26,48 kbit/s (fc/512)
99 // n ... length of data
100 static void CodeIso15693AsReader(uint8_t *cmd
, int n
)
106 // Give it a bit of slack at the beginning
107 for(i
= 0; i
< 24; i
++) {
120 for(i
= 0; i
< n
; i
++) {
121 for(j
= 0; j
< 8; j
+= 2) {
122 int these
= (cmd
[i
] >> j
) & 3;
173 // Fill remainder of last byte with 1
174 for(i
= 0; i
< 4; i
++) {
181 // encode data using "1 out of 256" scheme
182 // data rate is 1,66 kbit/s (fc/8192)
183 // is designed for more robust communication over longer distances
184 static void CodeIso15693AsReader256(uint8_t *cmd
, int n
)
190 // Give it a bit of slack at the beginning
191 for(i
= 0; i
< 24; i
++) {
205 for(i
= 0; i
< n
; i
++) {
206 for (j
= 0; j
<=255; j
++) {
222 // And slack at the end, too.
223 for(i
= 0; i
< 24; i
++) {
229 // Transmit the command (to the tag) that was placed in cmd[].
230 static void TransmitTo15693Tag(const uint8_t *cmd
, int len
)
232 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX
);
233 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX
);
236 for(int c
= 0; c
< len
; ) {
237 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
238 AT91C_BASE_SSC
->SSC_THR
= ~cmd
[c
];
246 //-----------------------------------------------------------------------------
247 // Transmit the command (to the reader) that was placed in cmd[].
248 //-----------------------------------------------------------------------------
249 static void TransmitTo15693Reader(const uint8_t *cmd
, int len
)
251 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR
| FPGA_HF_SIMULATOR_MODULATE_424K
);
254 for(int c
= 0; c
< len
; ) {
255 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
256 AT91C_BASE_SSC
->SSC_THR
= cmd
[c
];
265 //=============================================================================
266 // An ISO 15693 demodulator (one subcarrier only). Uses cross correlation to
267 // identify the SOF, each bit, and EOF.
268 // This function is called 8 times per bit (every 2 subcarrier cycles).
269 // Subcarrier frequency fs is 424kHz, 1/fs = 2,36us,
270 // i.e. function is called every 4,72us
272 // LED C -> ON once we have received the SOF and are expecting the rest.
273 // LED C -> OFF once we have received EOF or are unsynced
275 // Returns: true if we received a EOF
276 // false if we are still waiting for some more
277 //=============================================================================
279 #define SUBCARRIER_DETECT_THRESHOLD 2
280 #define SOF_CORRELATOR_LEN (1<<5)
282 typedef struct Demod
{
287 DEMOD_RECEIVING_DATA
,
306 int32_t SOF_corr_prev
;
307 uint8_t SOF_correlator
[SOF_CORRELATOR_LEN
];
310 static RAMFUNC
int Handle15693SamplesDemod(int8_t ci
, int8_t cq
, Demod_t
*Demod
)
312 switch(Demod
->state
) {
314 // initialize SOF correlator. We are looking for 12 samples low and 12 samples high.
316 Demod
->SOF_high
= 12;
317 Demod
->SOF_last
= 23;
318 memset(Demod
->SOF_correlator
, 0x00, Demod
->SOF_last
+ 1);
319 Demod
->SOF_correlator
[Demod
->SOF_last
] = AMPLITUDE(ci
,cq
);
320 Demod
->SOF_corr
= Demod
->SOF_correlator
[Demod
->SOF_last
];
321 Demod
->SOF_corr_prev
= Demod
->SOF_corr
;
322 // initialize Demodulator
326 Demod
->state
= DEMOD_AWAIT_SOF_1
;
329 case DEMOD_AWAIT_SOF_1
:
330 // calculate the correlation in real time. Look at differences only.
331 Demod
->SOF_corr
+= Demod
->SOF_correlator
[Demod
->SOF_low
++];
332 Demod
->SOF_corr
-= 2*Demod
->SOF_correlator
[Demod
->SOF_high
++];
334 Demod
->SOF_low
&= (SOF_CORRELATOR_LEN
-1);
335 Demod
->SOF_high
&= (SOF_CORRELATOR_LEN
-1);
336 Demod
->SOF_last
&= (SOF_CORRELATOR_LEN
-1);
337 Demod
->SOF_correlator
[Demod
->SOF_last
] = AMPLITUDE(ci
,cq
);
338 Demod
->SOF_corr
+= Demod
->SOF_correlator
[Demod
->SOF_last
];
340 // if correlation increases for 10 consecutive samples, we are close to maximum correlation
341 if (Demod
->SOF_corr
> Demod
->SOF_corr_prev
+ SUBCARRIER_DETECT_THRESHOLD
) {
347 if (Demod
->posCount
== 10) { // correlation increased 10 times
348 Demod
->state
= DEMOD_AWAIT_SOF_2
;
351 Demod
->SOF_corr_prev
= Demod
->SOF_corr
;
355 case DEMOD_AWAIT_SOF_2
:
356 // calculate the correlation in real time. Look at differences only.
357 Demod
->SOF_corr
+= Demod
->SOF_correlator
[Demod
->SOF_low
++];
358 Demod
->SOF_corr
-= 2*Demod
->SOF_correlator
[Demod
->SOF_high
++];
360 Demod
->SOF_low
&= (SOF_CORRELATOR_LEN
-1);
361 Demod
->SOF_high
&= (SOF_CORRELATOR_LEN
-1);
362 Demod
->SOF_last
&= (SOF_CORRELATOR_LEN
-1);
363 Demod
->SOF_correlator
[Demod
->SOF_last
] = AMPLITUDE(ci
,cq
);
364 Demod
->SOF_corr
+= Demod
->SOF_correlator
[Demod
->SOF_last
];
366 if (Demod
->SOF_corr
>= Demod
->SOF_corr_prev
) { // we are looking for the maximum correlation
367 Demod
->SOF_corr_prev
= Demod
->SOF_corr
;
369 Demod
->lastBit
= SOF_PART1
; // detected 1st part of SOF
370 Demod
->sum1
= Demod
->SOF_correlator
[Demod
->SOF_last
];
373 Demod
->state
= DEMOD_RECEIVING_DATA
;
379 case DEMOD_RECEIVING_DATA
:
380 if (Demod
->posCount
== 1) {
385 if (Demod
->posCount
<= 4) {
386 Demod
->sum1
+= AMPLITUDE(ci
, cq
);
388 Demod
->sum2
+= AMPLITUDE(ci
, cq
);
391 if (Demod
->posCount
== 8) {
392 int16_t corr_1
= (Demod
->sum2
- Demod
->sum1
) / 4;
393 int16_t corr_0
= (Demod
->sum1
- Demod
->sum2
) / 4;
394 int16_t corr_EOF
= (Demod
->sum1
+ Demod
->sum2
) / 8;
395 if (corr_EOF
> corr_0
&& corr_EOF
> corr_1
) {
396 Demod
->state
= DEMOD_AWAIT_EOF
;
397 } else if (corr_1
> corr_0
) {
399 if (Demod
->lastBit
== SOF_PART1
) { // still part of SOF
400 Demod
->lastBit
= SOF_PART2
;
402 Demod
->lastBit
= LOGIC1
;
403 Demod
->shiftReg
>>= 1;
404 Demod
->shiftReg
|= 0x80;
406 if (Demod
->bitCount
== 8) {
407 Demod
->output
[Demod
->len
] = Demod
->shiftReg
;
415 if (Demod
->lastBit
== SOF_PART1
) { // incomplete SOF
416 Demod
->state
= DEMOD_UNSYNCD
;
419 Demod
->lastBit
= LOGIC0
;
420 Demod
->shiftReg
>>= 1;
422 if (Demod
->bitCount
== 8) {
423 Demod
->output
[Demod
->len
] = Demod
->shiftReg
;
435 case DEMOD_AWAIT_EOF
:
436 if (Demod
->lastBit
== LOGIC0
) { // this was already part of EOF
440 Demod
->state
= DEMOD_UNSYNCD
;
446 Demod
->state
= DEMOD_UNSYNCD
;
455 static void DemodInit(Demod_t
* Demod
, uint8_t* data
)
457 Demod
->output
= data
;
458 Demod
->state
= DEMOD_UNSYNCD
;
463 * Demodulate the samples we received from the tag, also log to tracebuffer
465 static int GetIso15693AnswerFromTag(uint8_t* response
, int timeout
)
468 int lastRxCounter
, samples
= 0;
470 bool gotFrame
= false;
472 // Allocate memory from BigBuf for some buffers
473 // free all previous allocations first
476 // The DMA buffer, used to stream samples from the FPGA
477 uint16_t* dmaBuf
= (uint16_t*) BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE
* sizeof(uint16_t));
479 // the Demodulatur data structure
480 Demod_t
* Demod
= (Demod_t
*) BigBuf_malloc(sizeof(Demod_t
));
482 // Set up the demodulator for tag -> reader responses.
483 DemodInit(Demod
, response
);
485 // wait for last transfer to complete
486 while (!(AT91C_BASE_SSC
->SSC_SR
& AT91C_SSC_TXEMPTY
));
488 // And put the FPGA in the appropriate mode
489 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
491 // Setup and start DMA.
492 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
493 FpgaSetupSscDma((uint8_t*) dmaBuf
, ISO15693_DMA_BUFFER_SIZE
);
495 uint16_t *upTo
= dmaBuf
;
496 lastRxCounter
= ISO15693_DMA_BUFFER_SIZE
;
499 int behindBy
= (lastRxCounter
- AT91C_BASE_PDC_SSC
->PDC_RCR
) & (ISO15693_DMA_BUFFER_SIZE
-1);
500 if(behindBy
> maxBehindBy
) {
501 maxBehindBy
= behindBy
;
504 if (behindBy
< 1) continue;
506 ci
= (int8_t)(*upTo
>> 8);
507 cq
= (int8_t)(*upTo
& 0xff);
511 if(upTo
>= dmaBuf
+ ISO15693_DMA_BUFFER_SIZE
) { // we have read all of the DMA buffer content.
512 upTo
= dmaBuf
; // start reading the circular buffer from the beginning
513 lastRxCounter
+= ISO15693_DMA_BUFFER_SIZE
;
515 if (AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_ENDRX
)) { // DMA Counter Register had reached 0, already rotated.
516 AT91C_BASE_PDC_SSC
->PDC_RNPR
= (uint32_t) dmaBuf
; // refresh the DMA Next Buffer and
517 AT91C_BASE_PDC_SSC
->PDC_RNCR
= ISO15693_DMA_BUFFER_SIZE
; // DMA Next Counter registers
521 if (Handle15693SamplesDemod(ci
, cq
, Demod
)) {
526 if(samples
> timeout
&& Demod
->state
< DEMOD_RECEIVING_DATA
) {
534 if (DEBUG
) Dbprintf("max behindby = %d, samples = %d, gotFrame = %d, Demod.state = %d, Demod.len = %d, Demod.bitCount = %d, Demod.posCount = %d",
535 maxBehindBy
, samples
, gotFrame
, Demod
->state
, Demod
->len
, Demod
->bitCount
, Demod
->posCount
);
537 if (tracing
&& Demod
->len
> 0) {
538 uint8_t parity
[MAX_PARITY_SIZE
];
539 LogTrace(Demod
->output
, Demod
->len
, 0, 0, parity
, false);
546 // Now the GetISO15693 message from sniffing command
547 // TODO: fix it. This cannot work for several reasons:
548 // 1. Carrier is switched on during sniffing?
549 // 2. We most probable miss the next reader command when demodulating
550 static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse
, int maxLen
, int *samples
, int *elapsed
)
552 uint8_t *dest
= BigBuf_get_addr();
556 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
557 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
558 for(int c
= 0; c
< BIGBUF_SIZE
; ) {
559 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
560 uint16_t iq
= AT91C_BASE_SSC
->SSC_RHR
;
561 // The samples are correlations against I and Q versions of the
562 // tone that the tag AM-modulates. We just want power,
563 // so abs(I) + abs(Q) is close to what we want.
564 int8_t i
= (int8_t)(iq
>> 8);
565 int8_t q
= (int8_t)(iq
& 0xff);
566 uint8_t r
= AMPLITUDE(i
, q
);
570 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
573 //////////////////////////////////////////
574 /////////// DEMODULATE ///////////////////
575 //////////////////////////////////////////
578 int max
= 0, maxPos
=0;
582 // First, correlate for SOF
583 for(i
= 0; i
< 38000; i
++) {
585 for(j
= 0; j
< arraylen(FrameSOF
); j
+= skip
) {
586 corr
+= FrameSOF
[j
]*dest
[i
+(j
/skip
)];
594 if (DEBUG
) Dbprintf("SOF at %d, correlation %d", maxPos
,max
/(arraylen(FrameSOF
)/skip
));
596 int k
= 0; // this will be our return value
598 // greg - If correlation is less than 1 then there's little point in continuing
599 if ((max
/(arraylen(FrameSOF
)/skip
)) >= 1) // THIS SHOULD BE 1
602 i
= maxPos
+ arraylen(FrameSOF
)/skip
;
605 memset(outBuf
, 0, sizeof(outBuf
));
608 int corr0
= 0, corr00
= 0, corr01
= 0, corr1
= 0, corrEOF
= 0;
609 for(j
= 0; j
< arraylen(Logic0
); j
+= skip
) {
610 corr0
+= Logic0
[j
]*dest
[i
+(j
/skip
)];
612 corr01
= corr00
= corr0
;
613 for(j
= 0; j
< arraylen(Logic0
); j
+= skip
) {
614 corr00
+= Logic0
[j
]*dest
[i
+arraylen(Logic0
)/skip
+(j
/skip
)];
615 corr01
+= Logic1
[j
]*dest
[i
+arraylen(Logic0
)/skip
+(j
/skip
)];
617 for(j
= 0; j
< arraylen(Logic1
); j
+= skip
) {
618 corr1
+= Logic1
[j
]*dest
[i
+(j
/skip
)];
620 for(j
= 0; j
< arraylen(FrameEOF
); j
+= skip
) {
621 corrEOF
+= FrameEOF
[j
]*dest
[i
+(j
/skip
)];
623 // Even things out by the length of the target waveform.
629 if(corrEOF
> corr1
&& corrEOF
> corr00
&& corrEOF
> corr01
) {
630 if (DEBUG
) Dbprintf("EOF at %d, correlation %d (corr01: %d, corr00: %d, corr1: %d, corr0: %d)",
631 i
, corrEOF
, corr01
, corr00
, corr1
, corr0
);
633 } else if(corr1
> corr0
) {
634 i
+= arraylen(Logic1
)/skip
;
637 i
+= arraylen(Logic0
)/skip
;
644 if((i
+(int)arraylen(FrameEOF
)/skip
) >= BIGBUF_SIZE
) {
645 DbpString("ran off end!");
650 DbpString("sniff: error, uneven octet! (discard extra bits!)");
651 /// DbpString(" mask=%02x", mask);
655 // strncat(str1," octets read",8);
657 // DbpString( str1); // DbpString("%d octets", k);
659 // for(i = 0; i < k; i+=3) {
660 // //DbpString("# %2d: %02x ", i, outBuf[i]);
661 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
664 for(i
= 0; i
< k
; i
++) {
665 receivedResponse
[i
] = outBuf
[i
];
667 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
668 return k
; // return the number of bytes demodulated
670 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
674 static void BuildIdentifyRequest(void);
675 //-----------------------------------------------------------------------------
676 // Start to read an ISO 15693 tag. We send an identify request, then wait
677 // for the response. The response is not demodulated, just left in the buffer
678 // so that it can be downloaded to a PC and processed there.
679 //-----------------------------------------------------------------------------
680 void AcquireRawAdcSamplesIso15693(void)
685 uint8_t *dest
= BigBuf_get_addr();
687 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
688 BuildIdentifyRequest();
690 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
692 // Give the tags time to energize
694 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
697 // Now send the command
698 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX
);
699 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX
);
702 for(int c
= 0; c
< ToSendMax
; ) {
703 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
704 AT91C_BASE_SSC
->SSC_THR
= ~ToSend
[c
];
711 // wait for last transfer to complete
712 while (!(AT91C_BASE_SSC
->SSC_SR
& AT91C_SSC_TXEMPTY
));
714 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
715 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
717 for(int c
= 0; c
< 4000; ) {
718 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
719 uint16_t iq
= AT91C_BASE_SSC
->SSC_RHR
;
720 // The samples are correlations against I and Q versions of the
721 // tone that the tag AM-modulates. We just want power,
722 // so abs(I) + abs(Q) is close to what we want.
723 int8_t i
= (int8_t)(iq
>> 8);
724 int8_t q
= (int8_t)(iq
& 0xff);
725 uint8_t r
= AMPLITUDE(i
, q
);
730 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
735 // TODO: there is no trigger condition. The 14000 samples represent a time frame of 66ms.
736 // It is unlikely that we get something meaningful.
737 // TODO: Currently we only record tag answers. Add tracing of reader commands.
738 // TODO: would we get something at all? The carrier is switched on...
739 void RecordRawAdcSamplesIso15693(void)
744 uint8_t *dest
= BigBuf_get_addr();
746 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
748 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
750 // Start from off (no field generated)
751 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
754 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
759 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
761 for(int c
= 0; c
< 14000;) {
762 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
763 uint16_t iq
= AT91C_BASE_SSC
->SSC_RHR
;
764 // The samples are correlations against I and Q versions of the
765 // tone that the tag AM-modulates. We just want power,
766 // so abs(I) + abs(Q) is close to what we want.
767 int8_t i
= (int8_t)(iq
>> 8);
768 int8_t q
= (int8_t)(iq
& 0xff);
769 uint8_t r
= AMPLITUDE(i
, q
);
774 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
776 Dbprintf("finished recording");
781 // Initialize the proxmark as iso15k reader
782 // (this might produces glitches that confuse some tags
783 static void Iso15693InitReader() {
784 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
788 // Start from off (no field generated)
790 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
793 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
794 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
796 // Give the tags time to energize
798 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
802 ///////////////////////////////////////////////////////////////////////
803 // ISO 15693 Part 3 - Air Interface
804 // This section basically contains transmission and receiving of bits
805 ///////////////////////////////////////////////////////////////////////
807 // Encode (into the ToSend buffers) an identify request, which is the first
808 // thing that you must send to a tag to get a response.
809 static void BuildIdentifyRequest(void)
814 // one sub-carrier, inventory, 1 slot, fast rate
815 // AFI is at bit 5 (1<<4) when doing an INVENTORY
816 cmd
[0] = (1 << 2) | (1 << 5) | (1 << 1);
817 // inventory command code
826 CodeIso15693AsReader(cmd
, sizeof(cmd
));
829 // uid is in transmission order (which is reverse of display order)
830 static void BuildReadBlockRequest(uint8_t *uid
, uint8_t blockNumber
)
835 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
836 // followed by teh block data
837 // one sub-carrier, inventory, 1 slot, fast rate
838 cmd
[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit, ADDR bit, OPTION bit
839 // READ BLOCK command code
841 // UID may be optionally specified here
850 cmd
[9] = uid
[7]; // 0xe0; // always e0 (not exactly unique)
851 // Block number to read
852 cmd
[10] = blockNumber
;//0x00;
854 crc
= Crc(cmd
, 11); // the crc needs to be calculated over 12 bytes
855 cmd
[11] = crc
& 0xff;
858 CodeIso15693AsReader(cmd
, sizeof(cmd
));
862 // Now the VICC>VCD responses when we are simulating a tag
863 static void BuildInventoryResponse( uint8_t *uid
)
868 // one sub-carrier, inventory, 1 slot, fast rate
869 // AFI is at bit 5 (1<<4) when doing an INVENTORY
870 //(1 << 2) | (1 << 5) | (1 << 1);
872 cmd
[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported
874 cmd
[2] = uid
[7]; //0x32;
875 cmd
[3] = uid
[6]; //0x4b;
876 cmd
[4] = uid
[5]; //0x03;
877 cmd
[5] = uid
[4]; //0x01;
878 cmd
[6] = uid
[3]; //0x00;
879 cmd
[7] = uid
[2]; //0x10;
880 cmd
[8] = uid
[1]; //0x05;
881 cmd
[9] = uid
[0]; //0xe0;
884 cmd
[10] = crc
& 0xff;
887 CodeIso15693AsReader(cmd
, sizeof(cmd
));
890 // Universal Method for sending to and recv bytes from a tag
891 // init ... should we initialize the reader?
892 // speed ... 0 low speed, 1 hi speed
893 // **recv will return you a pointer to the received data
894 // If you do not need the answer use NULL for *recv[]
895 // return: lenght of received data
896 int SendDataTag(uint8_t *send
, int sendlen
, bool init
, int speed
, uint8_t **recv
) {
902 if (init
) Iso15693InitReader();
905 uint8_t *answer
= BigBuf_get_addr() + 4000;
906 if (recv
!= NULL
) memset(answer
, 0, 100);
909 // low speed (1 out of 256)
910 CodeIso15693AsReader256(send
, sendlen
);
912 // high speed (1 out of 4)
913 CodeIso15693AsReader(send
, sendlen
);
916 TransmitTo15693Tag(ToSend
,ToSendMax
);
917 // Now wait for a response
919 answerLen
= GetIso15693AnswerFromTag(answer
, 100);
929 // --------------------------------------------------------------------
931 // --------------------------------------------------------------------
933 // Decodes a message from a tag and displays its metadata and content
934 #define DBD15STATLEN 48
935 void DbdecodeIso15693Answer(int len
, uint8_t *d
) {
936 char status
[DBD15STATLEN
+1]={0};
941 strncat(status
,"ProtExt ",DBD15STATLEN
);
944 strncat(status
,"Error ",DBD15STATLEN
);
947 strncat(status
,"01:notSupp",DBD15STATLEN
);
950 strncat(status
,"02:notRecog",DBD15STATLEN
);
953 strncat(status
,"03:optNotSupp",DBD15STATLEN
);
956 strncat(status
,"0f:noInfo",DBD15STATLEN
);
959 strncat(status
,"10:dontExist",DBD15STATLEN
);
962 strncat(status
,"11:lockAgain",DBD15STATLEN
);
965 strncat(status
,"12:locked",DBD15STATLEN
);
968 strncat(status
,"13:progErr",DBD15STATLEN
);
971 strncat(status
,"14:lockErr",DBD15STATLEN
);
974 strncat(status
,"unknownErr",DBD15STATLEN
);
976 strncat(status
," ",DBD15STATLEN
);
978 strncat(status
,"NoErr ",DBD15STATLEN
);
982 if ( (( crc
& 0xff ) == d
[len
-2]) && (( crc
>> 8 ) == d
[len
-1]) )
983 strncat(status
,"CrcOK",DBD15STATLEN
);
985 strncat(status
,"CrcFail!",DBD15STATLEN
);
987 Dbprintf("%s",status
);
993 ///////////////////////////////////////////////////////////////////////
994 // Functions called via USB/Client
995 ///////////////////////////////////////////////////////////////////////
997 void SetDebugIso15693(uint32_t debug
) {
999 Dbprintf("Iso15693 Debug is now %s",DEBUG
?"on":"off");
1003 //-----------------------------------------------------------------------------
1004 // Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector
1005 // all demodulation performed in arm rather than host. - greg
1006 //-----------------------------------------------------------------------------
1007 void ReaderIso15693(uint32_t parameter
)
1013 uint8_t TagUID
[8] = {0x00};
1015 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
1017 uint8_t *answer1
= BigBuf_get_addr() + 4000;
1018 memset(answer1
, 0x00, 200);
1020 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
1022 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
1024 // Start from off (no field generated)
1025 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1028 // Give the tags time to energize
1030 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
1033 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
1034 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
1036 // Now send the IDENTIFY command
1037 BuildIdentifyRequest();
1039 TransmitTo15693Tag(ToSend
,ToSendMax
);
1041 // Now wait for a response
1042 answerLen1
= GetIso15693AnswerFromTag(answer1
, 100) ;
1044 if (answerLen1
>=12) // we should do a better check than this
1046 TagUID
[0] = answer1
[2];
1047 TagUID
[1] = answer1
[3];
1048 TagUID
[2] = answer1
[4];
1049 TagUID
[3] = answer1
[5];
1050 TagUID
[4] = answer1
[6];
1051 TagUID
[5] = answer1
[7];
1052 TagUID
[6] = answer1
[8]; // IC Manufacturer code
1053 TagUID
[7] = answer1
[9]; // always E0
1057 Dbprintf("%d octets read from IDENTIFY request:", answerLen1
);
1058 DbdecodeIso15693Answer(answerLen1
,answer1
);
1059 Dbhexdump(answerLen1
,answer1
,true);
1062 if (answerLen1
>= 12)
1063 Dbprintf("UID = %02hX%02hX%02hX%02hX%02hX%02hX%02hX%02hX",
1064 TagUID
[7],TagUID
[6],TagUID
[5],TagUID
[4],
1065 TagUID
[3],TagUID
[2],TagUID
[1],TagUID
[0]);
1068 // Dbprintf("%d octets read from SELECT request:", answerLen2);
1069 // DbdecodeIso15693Answer(answerLen2,answer2);
1070 // Dbhexdump(answerLen2,answer2,true);
1072 // Dbprintf("%d octets read from XXX request:", answerLen3);
1073 // DbdecodeIso15693Answer(answerLen3,answer3);
1074 // Dbhexdump(answerLen3,answer3,true);
1077 if (answerLen1
>= 12 && DEBUG
) {
1078 uint8_t *answer2
= BigBuf_get_addr() + 4100;
1080 while (i
<32) { // sanity check, assume max 32 pages
1081 BuildReadBlockRequest(TagUID
,i
);
1082 TransmitTo15693Tag(ToSend
,ToSendMax
);
1083 int answerLen2
= GetIso15693AnswerFromTag(answer2
, 100);
1085 Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i
,answerLen2
);
1086 DbdecodeIso15693Answer(answerLen2
,answer2
);
1087 Dbhexdump(answerLen2
,answer2
,true);
1088 if ( *((uint32_t*) answer2
) == 0x07160101 ) break; // exit on NoPageErr
1094 // for the time being, switch field off to protect rdv4.0
1095 // note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
1096 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1102 // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
1103 // all demodulation performed in arm rather than host. - greg
1104 void SimTagIso15693(uint32_t parameter
, uint8_t *uid
)
1113 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
1115 uint8_t *buf
= BigBuf_get_addr() + 4000;
1116 memset(buf
, 0x00, 100);
1118 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
1119 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
1121 // Start from off (no field generated)
1122 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1126 answerLen1
= GetIso15693AnswerFromSniff(buf
, 100, &samples
, &elapsed
) ;
1128 if (answerLen1
>=1) // we should do a better check than this
1130 // Build a suitable reponse to the reader INVENTORY cocmmand
1131 // not so obsvious, but in the call to BuildInventoryResponse, the command is copied to the global ToSend buffer used below.
1133 BuildInventoryResponse(uid
);
1135 TransmitTo15693Reader(ToSend
,ToSendMax
);
1138 Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1
,
1139 buf
[0], buf
[1], buf
[2], buf
[3],
1140 buf
[4], buf
[5], buf
[6], buf
[7], buf
[8]);
1142 Dbprintf("Simulationg uid: %x %x %x %x %x %x %x %x",
1143 uid
[0], uid
[1], uid
[2], uid
[3],
1144 uid
[4], uid
[5], uid
[6], uid
[7]);
1150 // Since there is no standardized way of reading the AFI out of a tag, we will brute force it
1151 // (some manufactures offer a way to read the AFI, though)
1152 void BruteforceIso15693Afi(uint32_t speed
)
1159 int datalen
=0, recvlen
=0;
1161 Iso15693InitReader();
1163 // first without AFI
1164 // Tags should respond wihtout AFI and with AFI=0 even when AFI is active
1166 data
[0]=ISO15_REQ_SUBCARRIER_SINGLE
| ISO15_REQ_DATARATE_HIGH
|
1167 ISO15_REQ_INVENTORY
| ISO15_REQINV_SLOT1
;
1168 data
[1]=ISO15_CMD_INVENTORY
;
1169 data
[2]=0; // mask length
1170 datalen
=AddCrc(data
,3);
1171 recvlen
=SendDataTag(data
, datalen
, false, speed
, &recv
);
1174 Dbprintf("NoAFI UID=%s",sprintUID(NULL
,&recv
[2]));
1179 data
[0]=ISO15_REQ_SUBCARRIER_SINGLE
| ISO15_REQ_DATARATE_HIGH
|
1180 ISO15_REQ_INVENTORY
| ISO15_REQINV_AFI
| ISO15_REQINV_SLOT1
;
1181 data
[1]=ISO15_CMD_INVENTORY
;
1183 data
[3]=0; // mask length
1185 for (int i
=0;i
<256;i
++) {
1187 datalen
=AddCrc(data
,4);
1188 recvlen
=SendDataTag(data
, datalen
, false, speed
, &recv
);
1191 Dbprintf("AFI=%i UID=%s",i
,sprintUID(NULL
,&recv
[2]));
1194 Dbprintf("AFI Bruteforcing done.");
1196 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1200 // Allows to directly send commands to the tag via the client
1201 void DirectTag15693Command(uint32_t datalen
, uint32_t speed
, uint32_t recv
, uint8_t data
[]) {
1204 uint8_t *recvbuf
= BigBuf_get_addr();
1210 Dbhexdump(datalen
,data
,true);
1213 recvlen
= SendDataTag(data
, datalen
, true, speed
, (recv
?&recvbuf
:NULL
));
1216 cmd_send(CMD_ACK
, recvlen
>48?48:recvlen
, 0, 0, recvbuf
, 48);
1220 DbdecodeIso15693Answer(recvlen
,recvbuf
);
1221 Dbhexdump(recvlen
,recvbuf
,true);
1225 // for the time being, switch field off to protect rdv4.0
1226 // note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
1227 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1236 // --------------------------------------------------------------------
1237 // -- Misc & deprecated functions
1238 // --------------------------------------------------------------------
1242 // do not use; has a fix UID
1243 static void __attribute__((unused)) BuildSysInfoRequest(uint8_t *uid)
1248 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1249 // followed by teh block data
1250 // one sub-carrier, inventory, 1 slot, fast rate
1251 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1252 // System Information command code
1254 // UID may be optionally specified here
1263 cmd[9]= 0xe0; // always e0 (not exactly unique)
1265 crc = Crc(cmd, 10); // the crc needs to be calculated over 2 bytes
1266 cmd[10] = crc & 0xff;
1269 CodeIso15693AsReader(cmd, sizeof(cmd));
1273 // do not use; has a fix UID
1274 static void __attribute__((unused)) BuildReadMultiBlockRequest(uint8_t *uid)
1279 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1280 // followed by teh block data
1281 // one sub-carrier, inventory, 1 slot, fast rate
1282 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1283 // READ Multi BLOCK command code
1285 // UID may be optionally specified here
1294 cmd[9]= 0xe0; // always e0 (not exactly unique)
1295 // First Block number to read
1297 // Number of Blocks to read
1298 cmd[11] = 0x2f; // read quite a few
1300 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1301 cmd[12] = crc & 0xff;
1304 CodeIso15693AsReader(cmd, sizeof(cmd));
1307 // do not use; has a fix UID
1308 static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t CmdCode)
1313 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1314 // followed by teh block data
1315 // one sub-carrier, inventory, 1 slot, fast rate
1316 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1317 // READ BLOCK command code
1319 // UID may be optionally specified here
1328 cmd[9]= 0xe0; // always e0 (not exactly unique)
1334 // cmd[13] = 0x00; //Now the CRC
1335 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1336 cmd[12] = crc & 0xff;
1339 CodeIso15693AsReader(cmd, sizeof(cmd));
1342 // do not use; has a fix UID
1343 static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], uint8_t CmdCode)
1348 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1349 // followed by teh block data
1350 // one sub-carrier, inventory, 1 slot, fast rate
1351 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1352 // READ BLOCK command code
1354 // UID may be optionally specified here
1363 cmd[9]= 0xe0; // always e0 (not exactly unique)
1365 cmd[10] = 0x05; // for custom codes this must be manufcturer code
1369 // cmd[13] = 0x00; //Now the CRC
1370 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1371 cmd[12] = crc & 0xff;
1374 CodeIso15693AsReader(cmd, sizeof(cmd));