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 "../include/proxmark3.h"
65 #include "../common/iso15693tools.h"
66 #include "../common/cmd.h"
69 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
71 ///////////////////////////////////////////////////////////////////////
72 // ISO 15693 Part 2 - Air Interface
73 // This section basicly contains transmission and receiving of bits
74 ///////////////////////////////////////////////////////////////////////
76 #define FrameSOF Iso15693FrameSOF
77 #define Logic0 Iso15693Logic0
78 #define Logic1 Iso15693Logic1
79 #define FrameEOF Iso15693FrameEOF
81 #define Crc(data,datalen) Iso15693Crc(data,datalen)
82 #define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
83 #define sprintUID(target,uid) Iso15693sprintUID(target,uid)
88 // ---------------------------
90 // ---------------------------
92 // prepare data using "1 out of 4" code for later transmission
93 // resulting data rate is 26,48 kbit/s (fc/512)
95 // n ... length of data
96 static void CodeIso15693AsReader(uint8_t *cmd
, int n
)
102 // Give it a bit of slack at the beginning
103 for(i
= 0; i
< 24; i
++) {
116 for(i
= 0; i
< n
; i
++) {
117 for(j
= 0; j
< 8; j
+= 2) {
118 int these
= (cmd
[i
] >> j
) & 3;
169 // And slack at the end, too.
170 for(i
= 0; i
< 24; i
++) {
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
178 static void CodeIso15693AsReader256(uint8_t *cmd
, int n
)
184 // Give it a bit of slack at the beginning
185 for(i
= 0; i
< 24; i
++) {
199 for(i
= 0; i
< n
; i
++) {
200 for (j
= 0; j
<=255; j
++) {
216 // And slack at the end, too.
217 for(i
= 0; i
< 24; i
++) {
223 // Transmit the command (to the tag) that was placed in ToSend[].
224 static void TransmitTo15693Tag(const uint8_t *cmd
, int len
, int *samples
, int *wait
)
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; }
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!
237 // if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
238 // volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
246 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
247 AT91C_BASE_SSC
->SSC_THR
= cmd
[c
];
253 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
254 volatile uint32_t r
= AT91C_BASE_SSC
->SSC_RHR
;
259 *samples
= (c
+ *wait
) << 3;
262 //-----------------------------------------------------------------------------
263 // Transmit the command (to the reader) that was placed in ToSend[].
264 //-----------------------------------------------------------------------------
265 static void TransmitTo15693Reader(const uint8_t *cmd
, int len
, int *samples
, int *wait
)
268 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR
|FPGA_HF_SIMULATOR_MODULATE_424K
);
269 if(*wait
< 10) { *wait
= 10; }
272 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
273 AT91C_BASE_SSC
->SSC_THR
= cmd
[c
];
279 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
280 volatile uint32_t r
= AT91C_BASE_SSC
->SSC_RHR
;
285 *samples
= (c
+ *wait
) << 3;
296 // number of decoded bytes
297 static int GetIso15693AnswerFromTag(uint8_t *receivedResponse
, int maxLen
, int *samples
, int *elapsed
)
300 uint8_t *dest
= (uint8_t *)BigBuf
;
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
311 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
312 AT91C_BASE_SSC
->SSC_THR
= 0x43;
314 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
316 b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
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.
336 dest
[c
++] = (uint8_t)r
;
349 //////////////////////////////////////////
350 /////////// DEMODULATE ///////////////////
351 //////////////////////////////////////////
354 int max
= 0, maxPos
=0;
358 // if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL
360 // First, correlate for SOF
361 for(i
= 0; i
< 100; i
++) {
363 for(j
= 0; j
< arraylen(FrameSOF
); j
+= skip
) {
364 corr
+= FrameSOF
[j
]*dest
[i
+(j
/skip
)];
371 // DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
373 int k
= 0; // this will be our return value
375 // greg - If correlation is less than 1 then there's little point in continuing
376 if ((max
/(arraylen(FrameSOF
)/skip
)) >= 1)
379 i
= maxPos
+ arraylen(FrameSOF
)/skip
;
382 memset(outBuf
, 0, sizeof(outBuf
));
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
)];
389 for(j
= 0; j
< arraylen(Logic1
); j
+= skip
) {
390 corr1
+= Logic1
[j
]*dest
[i
+(j
/skip
)];
392 for(j
= 0; j
< arraylen(FrameEOF
); j
+= skip
) {
393 corrEOF
+= FrameEOF
[j
]*dest
[i
+(j
/skip
)];
395 // Even things out by the length of the target waveform.
399 if(corrEOF
> corr1
&& corrEOF
> corr0
) {
400 // DbpString("EOF at %d", i);
402 } else if(corr1
> corr0
) {
403 i
+= arraylen(Logic1
)/skip
;
406 i
+= arraylen(Logic0
)/skip
;
413 if((i
+(int)arraylen(FrameEOF
)) >= 2000) {
414 DbpString("ran off end!");
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
426 // strncat(str1," octets read",8);
428 // DbpString( str1); // DbpString("%d octets", k);
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]);
435 for(i
= 0; i
< k
; i
++) {
436 receivedResponse
[i
] = outBuf
[i
];
438 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
439 return k
; // return the number of bytes demodulated
441 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
446 // Now the GetISO15693 message from sniffing command
447 static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse
, int maxLen
, int *samples
, int *elapsed
)
450 uint8_t *dest
= (uint8_t *)BigBuf
;
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
461 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
462 AT91C_BASE_SSC
->SSC_THR
= 0x43;
464 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
465 int8_t b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
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.
485 dest
[c
++] = (uint8_t)r
;
498 //////////////////////////////////////////
499 /////////// DEMODULATE ///////////////////
500 //////////////////////////////////////////
503 int max
= 0, maxPos
=0;
507 // if(GraphTraceLen < 1000) return; // THIS CHECKS FOR A BUFFER TO SMALL
509 // First, correlate for SOF
510 for(i
= 0; i
< 19000; i
++) {
512 for(j
= 0; j
< arraylen(FrameSOF
); j
+= skip
) {
513 corr
+= FrameSOF
[j
]*dest
[i
+(j
/skip
)];
520 // DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
522 int k
= 0; // this will be our return value
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
528 i
= maxPos
+ arraylen(FrameSOF
)/skip
;
531 memset(outBuf
, 0, sizeof(outBuf
));
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
)];
538 for(j
= 0; j
< arraylen(Logic1
); j
+= skip
) {
539 corr1
+= Logic1
[j
]*dest
[i
+(j
/skip
)];
541 for(j
= 0; j
< arraylen(FrameEOF
); j
+= skip
) {
542 corrEOF
+= FrameEOF
[j
]*dest
[i
+(j
/skip
)];
544 // Even things out by the length of the target waveform.
548 if(corrEOF
> corr1
&& corrEOF
> corr0
) {
549 // DbpString("EOF at %d", i);
551 } else if(corr1
> corr0
) {
552 i
+= arraylen(Logic1
)/skip
;
555 i
+= arraylen(Logic0
)/skip
;
562 if((i
+(int)arraylen(FrameEOF
)) >= 2000) {
563 DbpString("ran off end!");
568 DbpString("sniff: error, uneven octet! (discard extra bits!)");
569 /// DbpString(" mask=%02x", mask);
573 // strncat(str1," octets read",8);
575 // DbpString( str1); // DbpString("%d octets", k);
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]);
582 for(i
= 0; i
< k
; i
++) {
583 receivedResponse
[i
] = outBuf
[i
];
585 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
586 return k
; // return the number of bytes demodulated
588 /// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
592 static void BuildIdentifyRequest(void);
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 //-----------------------------------------------------------------------------
598 void AcquireRawAdcSamplesIso15693(void)
600 uint8_t *dest
= (uint8_t *)BigBuf
;
606 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
607 BuildIdentifyRequest();
609 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
611 // Give the tags time to energize
612 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
615 // Now send the command
617 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX
);
621 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
622 AT91C_BASE_SSC
->SSC_THR
= ToSend
[c
];
624 if(c
== ToSendMax
+3) {
628 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
629 volatile uint32_t r
= AT91C_BASE_SSC
->SSC_RHR
;
635 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
640 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
641 AT91C_BASE_SSC
->SSC_THR
= 0x43;
643 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
645 b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
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.
665 dest
[c
++] = (uint8_t)r
;
680 void RecordRawAdcSamplesIso15693(void)
682 uint8_t *dest
= (uint8_t *)BigBuf
;
688 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
692 // Start from off (no field generated)
693 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
696 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
700 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
705 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
706 AT91C_BASE_SSC
->SSC_THR
= 0x43;
708 if(AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
710 b
= (int8_t)AT91C_BASE_SSC
->SSC_RHR
;
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.
730 dest
[c
++] = (uint8_t)r
;
743 Dbprintf("fin record");
747 // Initialize the proxmark as iso15k reader
748 // (this might produces glitches that confuse some tags
749 void Iso15693InitReader() {
755 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
759 // Start from off (no field generated)
760 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
763 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
766 // Give the tags time to energize
767 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
776 ///////////////////////////////////////////////////////////////////////
777 // ISO 15693 Part 3 - Air Interface
778 // This section basicly contains transmission and receiving of bits
779 ///////////////////////////////////////////////////////////////////////
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.
783 static void BuildIdentifyRequest(void)
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
800 CodeIso15693AsReader(cmd
, sizeof(cmd
));
803 // uid is in transmission order (which is reverse of display order)
804 static void BuildReadBlockRequest(uint8_t *uid
, uint8_t blockNumber
)
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
815 // UID may be optionally specified here
824 cmd
[9] = uid
[7]; // 0xe0; // always e0 (not exactly unique)
825 // Block number to read
826 cmd
[10] = blockNumber
;//0x00;
828 crc
= Crc(cmd
, 11); // the crc needs to be calculated over 12 bytes
829 cmd
[11] = crc
& 0xff;
832 CodeIso15693AsReader(cmd
, sizeof(cmd
));
835 // Now the VICC>VCD responses when we are simulating a tag
836 static void BuildInventoryResponse( uint8_t *uid
)
841 // one sub-carrier, inventory, 1 slot, fast rate
842 // AFI is at bit 5 (1<<4) when doing an INVENTORY
843 //(1 << 2) | (1 << 5) | (1 << 1);
845 cmd
[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported
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;
857 cmd
[10] = crc
& 0xff;
860 CodeIso15693AsReader(cmd
, sizeof(cmd
));
863 // Universal Method for sending to and recv bytes from a tag
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
869 int SendDataTag(uint8_t *send
, int sendlen
, int init
, int speed
, uint8_t **recv
) {
882 uint8_t *answer
= (((uint8_t *)BigBuf
) + 3660);
883 if (recv
!=NULL
) memset(BigBuf
+ 3660, 0, 100);
885 if (init
) Iso15693InitReader();
888 // low speed (1 out of 256)
889 CodeIso15693AsReader256(send
, sendlen
);
891 // high speed (1 out of 4)
892 CodeIso15693AsReader(send
, sendlen
);
898 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
);
899 // Now wait for a response
903 answerLen
= GetIso15693AnswerFromTag(answer
, 100, &samples
, &elapsed
) ;
916 // --------------------------------------------------------------------
918 // --------------------------------------------------------------------
920 // Decodes a message from a tag and displays its metadata and content
921 #define DBD15STATLEN 48
922 void DbdecodeIso15693Answer(int len
, uint8_t *d
) {
923 char status
[DBD15STATLEN
+1]={0};
928 strncat(status
,"ProtExt ",DBD15STATLEN
);
931 strncat(status
,"Error ",DBD15STATLEN
);
934 strncat(status
,"01:notSupp",DBD15STATLEN
);
937 strncat(status
,"02:notRecog",DBD15STATLEN
);
940 strncat(status
,"03:optNotSupp",DBD15STATLEN
);
943 strncat(status
,"0f:noInfo",DBD15STATLEN
);
946 strncat(status
,"10:dontExist",DBD15STATLEN
);
949 strncat(status
,"11:lockAgain",DBD15STATLEN
);
952 strncat(status
,"12:locked",DBD15STATLEN
);
955 strncat(status
,"13:progErr",DBD15STATLEN
);
958 strncat(status
,"14:lockErr",DBD15STATLEN
);
961 strncat(status
,"unknownErr",DBD15STATLEN
);
963 strncat(status
," ",DBD15STATLEN
);
965 strncat(status
,"NoErr ",DBD15STATLEN
);
969 if ( (( crc
& 0xff ) == d
[len
-2]) && (( crc
>> 8 ) == d
[len
-1]) )
970 strncat(status
,"CrcOK",DBD15STATLEN
);
972 strncat(status
,"CrcFail!",DBD15STATLEN
);
974 Dbprintf("%s",status
);
980 ///////////////////////////////////////////////////////////////////////
981 // Functions called via USB/Client
982 ///////////////////////////////////////////////////////////////////////
984 void SetDebugIso15693(uint32_t debug
) {
986 Dbprintf("Iso15693 Debug is now %s",DEBUG
?"on":"off");
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 //-----------------------------------------------------------------------------
996 void ReaderIso15693(uint32_t parameter
)
1003 uint8_t *answer1
= (((uint8_t *)BigBuf
) + 3660); //
1004 uint8_t *answer2
= (((uint8_t *)BigBuf
) + 3760);
1005 uint8_t *answer3
= (((uint8_t *)BigBuf
) + 3860);
1015 uint8_t TagUID
[8] = {0x00};
1019 memset(BigBuf
+ 3660, 0x00, 300);
1021 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
1023 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
1027 // Start from off (no field generated)
1028 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1031 // Give the tags time to energize
1032 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
);
1040 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
1041 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
1043 // Now send the IDENTIFY command
1044 BuildIdentifyRequest();
1046 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
);
1048 // Now wait for a response
1049 answerLen1
= GetIso15693AnswerFromTag(answer1
, 100, &samples
, &elapsed
) ;
1051 if (answerLen1
>=12) // we should do a better check than this
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
1060 TagUID
[7] = answer1
[9]; // always E0
1064 Dbprintf("%d octets read from IDENTIFY request:", answerLen1
);
1065 DbdecodeIso15693Answer(answerLen1
,answer1
);
1066 Dbhexdump(answerLen1
,answer1
,true);
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]);
1075 Dbprintf("%d octets read from SELECT request:", answerLen2
);
1076 DbdecodeIso15693Answer(answerLen2
,answer2
);
1077 Dbhexdump(answerLen2
,answer2
,true);
1079 Dbprintf("%d octets read from XXX request:", answerLen3
);
1080 DbdecodeIso15693Answer(answerLen3
,answer3
);
1081 Dbhexdump(answerLen3
,answer3
,true);
1084 if (answerLen1
>= 12 && DEBUG
) {
1086 while (i
< 32) { // sanity check, assume max 32 pages
1087 BuildReadBlockRequest(TagUID
,i
);
1088 TransmitTo15693Tag(ToSend
,ToSendMax
,&tsamples
, &wait
);
1089 answerLen2
= GetIso15693AnswerFromTag(answer2
, 100, &samples
, &elapsed
);
1090 if (answerLen2
> 0) {
1091 Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i
,answerLen2
);
1092 DbdecodeIso15693Answer(answerLen2
,answer2
);
1093 Dbhexdump(answerLen2
,answer2
,true);
1094 if ( *((uint32_t*) answer2
) == 0x07160101 ) break; // exit on NoPageErr
1106 // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
1107 // all demodulation performed in arm rather than host. - greg
1108 void SimTagIso15693(uint32_t parameter
, uint8_t *uid
)
1115 uint8_t *buf
= (((uint8_t *)BigBuf
) + 3660); //
1123 memset(buf
, 0x00, 100);
1125 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
1127 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
1131 // Start from off (no field generated)
1132 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1141 answerLen1
= GetIso15693AnswerFromSniff(buf
, 100, &samples
, &elapsed
) ;
1143 if (answerLen1
>=1) // we should do a better check than this
1145 // Build a suitable reponse to the reader INVENTORY cocmmand
1146 // not so obsvious, but in the call to BuildInventoryResponse, the command is copied to the global ToSend buffer used below.
1148 BuildInventoryResponse(uid
);
1150 TransmitTo15693Reader(ToSend
, ToSendMax
, &tsamples
, &wait
);
1153 Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1
,
1154 buf
[0], buf
[1], buf
[2], buf
[3],
1155 buf
[4], buf
[5], buf
[6], buf
[7], buf
[8]);
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]);
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)
1170 void BruteforceIso15693Afi(uint32_t speed
)
1174 int datalen
=0, recvlen
=0;
1176 Iso15693InitReader();
1178 // first without AFI
1179 // Tags should respond wihtout AFI and with AFI=0 even when AFI is active
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
);
1189 Dbprintf("NoAFI UID=%s",sprintUID(NULL
,&recv
[2]));
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
;
1198 data
[3]=0; // mask length
1200 for (int i
=0;i
<256;i
++) {
1202 datalen
=AddCrc(data
,4);
1203 recvlen
=SendDataTag(data
,datalen
,0,speed
,&recv
);
1206 Dbprintf("AFI=%i UID=%s",i
,sprintUID(NULL
,&recv
[2]));
1209 Dbprintf("AFI Bruteforcing done.");
1213 // Allows to directly send commands to the tag via the client
1214 void DirectTag15693Command(uint32_t datalen
,uint32_t speed
, uint32_t recv
, uint8_t data
[]) {
1217 uint8_t *recvbuf
=(uint8_t *)BigBuf
;
1222 Dbhexdump(datalen
,data
,true);
1225 recvlen
=SendDataTag(data
,datalen
,1,speed
,(recv
?&recvbuf
:NULL
));
1229 cmd_send(CMD_ACK
,recvlen
>48?48:recvlen
,0,0,recvbuf
,48);
1234 DbdecodeIso15693Answer(recvlen
,recvbuf
);
1235 Dbhexdump(recvlen
,recvbuf
,true);
1244 // --------------------------------------------------------------------
1245 // -- Misc & deprecated functions
1246 // --------------------------------------------------------------------
1250 // do not use; has a fix UID
1251 static void __attribute__((unused)) BuildSysInfoRequest(uint8_t *uid)
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
1262 // UID may be optionally specified here
1271 cmd[9]= 0xe0; // always e0 (not exactly unique)
1273 crc = Crc(cmd, 10); // the crc needs to be calculated over 2 bytes
1274 cmd[10] = crc & 0xff;
1277 CodeIso15693AsReader(cmd, sizeof(cmd));
1281 // do not use; has a fix UID
1282 static void __attribute__((unused)) BuildReadMultiBlockRequest(uint8_t *uid)
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
1293 // UID may be optionally specified here
1302 cmd[9]= 0xe0; // always e0 (not exactly unique)
1303 // First Block number to read
1305 // Number of Blocks to read
1306 cmd[11] = 0x2f; // read quite a few
1308 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1309 cmd[12] = crc & 0xff;
1312 CodeIso15693AsReader(cmd, sizeof(cmd));
1315 // do not use; has a fix UID
1316 static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t CmdCode)
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
1327 // UID may be optionally specified here
1336 cmd[9]= 0xe0; // always e0 (not exactly unique)
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;
1347 CodeIso15693AsReader(cmd, sizeof(cmd));
1350 // do not use; has a fix UID
1351 static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], uint8_t CmdCode)
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
1362 // UID may be optionally specified here
1371 cmd[9]= 0xe0; // always e0 (not exactly unique)
1373 cmd[10] = 0x05; // for custom codes this must be manufcturer code
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;
1382 CodeIso15693AsReader(cmd, sizeof(cmd));