1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // Routines to support a mangeled ISO 14443 type A for Thinfilm tags by Kovio
17 //-----------------------------------------------------------------------------
21 #include "proxmark3_arm.h"
25 #include "iso14443a.h"
26 #include "fpgaloader.h"
33 * https://www.thinfilmnfc.com/wp-content/uploads/2017/09/Thinfilm-Kovio-NFC-Barcode-Protocol-Tag-Functional-Specification-v3.4-2017-05-26.pdf
34 * https://developer.android.com/reference/android/nfc/tech/NfcBarcode
38 void ReadThinFilm(void) {
43 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
);
46 uint8_t buf
[36] = {0x00};
48 // power on and listen for answer.
49 bool status
= GetIso14443aAnswerFromTag_Thinfilm(buf
, sizeof(buf
), &len
);
50 reply_ng(CMD_HF_THINFILM_READ
, status
? PM3_SUCCESS
: PM3_ENODATA
, buf
, len
);
59 static uint16_t FpgaSendQueueDelay
;
61 static uint16_t ReadReaderField(void) {
62 return AvgAdc(ADC_CHAN_HF
);
65 static void CodeThinfilmAsTag(const uint8_t *cmd
, uint16_t len
) {
69 tosend_t
*ts
= get_tosend();
71 for (uint16_t i
= 0; i
< len
; i
++) {
73 for (uint8_t j
= 0; j
< 8; j
++) {
74 ts
->buf
[++ts
->max
] = (b
& 0x80) ? SEC_D
: SEC_E
;
81 static int EmSendCmdThinfilmRaw(const uint8_t *resp
, uint16_t respLen
) {
84 uint32_t ThisTransferTime
;
85 // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line)
86 for (uint8_t j
= 0; j
< 5; j
++) { // allow timeout - better late than never
87 while (!(AT91C_BASE_SSC
->SSC_SR
& AT91C_SSC_RXRDY
));
88 if (AT91C_BASE_SSC
->SSC_RHR
) break;
90 while ((ThisTransferTime
= GetCountSspClk()) & 0x00000007);
94 AT91C_BASE_SSC
->SSC_THR
= SEC_F
;
97 for (; i
< respLen
;) {
98 if (AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
99 AT91C_BASE_SSC
->SSC_THR
= resp
[i
++];
100 FpgaSendQueueDelay
= (uint8_t)AT91C_BASE_SSC
->SSC_RHR
;
103 if (AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_RXRDY
)) {
104 b
= (uint8_t)(AT91C_BASE_SSC
->SSC_RHR
);
107 if (BUTTON_PRESS()) break;
110 // Ensure that the FPGA Delay Queue is empty
111 uint8_t fpga_queued_bits
= FpgaSendQueueDelay
>> 3;
112 for (i
= 0; i
<= fpga_queued_bits
/ 8 + 1;) {
113 if (AT91C_BASE_SSC
->SSC_SR
& (AT91C_SSC_TXRDY
)) {
114 AT91C_BASE_SSC
->SSC_THR
= SEC_F
;
115 FpgaSendQueueDelay
= (uint8_t)AT91C_BASE_SSC
->SSC_RHR
;
123 void SimulateThinFilm(uint8_t *data
, size_t len
) {
125 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
127 Dbprintf("Simulate " _YELLOW_("%i-bit Thinfilm") " tag", len
* 8);
128 Dbhexdump(len
, data
, true);
130 // Set up the synchronous serial port
131 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER
);
133 // connect Demodulated Signal to ADC:
134 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
136 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A
| FPGA_HF_ISO14443A_TAGSIM_MOD
);
141 uint16_t hf_baseline
= ReadReaderField();
143 int8_t status
= PM3_SUCCESS
;
144 CodeThinfilmAsTag(data
, len
);
146 tosend_t
*ts
= get_tosend();
148 bool reader_detected
= false;
154 if (BUTTON_PRESS() || data_available()) {
155 status
= PM3_EOPABORTED
;
159 uint16_t hf_av
= ReadReaderField();
161 if (hf_av
< hf_baseline
) {
165 if (hf_av
> hf_baseline
+ 10) {
167 EmSendCmdThinfilmRaw(ts
->buf
, ts
->max
);
169 if (reader_detected
== false) {
171 //Dbprintf("Reader detected, start beaming data");
172 reader_detected
= true;
175 if (reader_detected
) {
177 // Dbprintf("Reader gone, stop beaming data");
178 reader_detected
= false;
183 reply_ng(CMD_HF_THINFILM_SIMULATE
, status
, NULL
, 0);