]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso15693.c
fido fix (#775)
[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
8c6cca0b 5// Modified by piwi, Oct 2018
bd20f8f4 6//
7// This code is licensed to you under the terms of the GNU GPL, version 2 or,
8// at your option, any later version. See the LICENSE.txt file for the text of
9// the license.
10//-----------------------------------------------------------------------------
15c4dc5a 11// Routines to support ISO 15693. This includes both the reader software and
8c6cca0b 12// the `fake tag' modes.
15c4dc5a 13//-----------------------------------------------------------------------------
8c6cca0b 14
15// The ISO 15693 describes two transmission modes from reader to tag, and four
16// transmission modes from tag to reader. As of Oct 2018 this code supports
17// both reader modes and the high speed variant with one subcarrier from card to reader.
18// As long as the card fully support ISO 15693 this is no problem, since the
19// reader chooses both data rates, but some non-standard tags do not.
20// For card simulation, the code supports both high and low speed modes with one subcarrier.
9455b51c 21//
22// VCD (reader) -> VICC (tag)
23// 1 out of 256:
8c6cca0b 24// data rate: 1,66 kbit/s (fc/8192)
9455b51c 25// used for long range
26// 1 out of 4:
27// data rate: 26,48 kbit/s (fc/512)
28// used for short range, high speed
8c6cca0b 29//
9455b51c 30// VICC (tag) -> VCD (reader)
31// Modulation:
32// ASK / one subcarrier (423,75 khz)
33// FSK / two subcarriers (423,75 khz && 484,28 khz)
34// Data Rates / Modes:
35// low ASK: 6,62 kbit/s
36// low FSK: 6.67 kbit/s
37// high ASK: 26,48 kbit/s
38// high FSK: 26,69 kbit/s
39//-----------------------------------------------------------------------------
9455b51c 40
41
42// Random Remarks:
43// *) UID is always used "transmission order" (LSB), which is reverse to display order
44
45// TODO / BUGS / ISSUES:
8c6cca0b 46// *) signal decoding is unable to detect collisions.
47// *) add anti-collision support for inventory-commands
e6304bca 48// *) read security status of a block
8c6cca0b 49// *) sniffing and simulation do not support two subcarrier modes.
d9de20fa 50// *) remove or refactor code under "deprecated"
9455b51c 51// *) document all the functions
52
d9de20fa 53#include "iso15693.h"
bd20f8f4 54
e30c654b 55#include "proxmark3.h"
f7e3ed82 56#include "util.h"
15c4dc5a 57#include "apps.h"
9ab7a6c7 58#include "string.h"
9455b51c 59#include "iso15693tools.h"
8c6cca0b 60#include "protocols.h"
902cb3c0 61#include "cmd.h"
d9de20fa 62#include "BigBuf.h"
15c4dc5a 63
15c4dc5a 64#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
65
70b2fc0a 66static int DEBUG = 0;
67
9455b51c 68///////////////////////////////////////////////////////////////////////
69// ISO 15693 Part 2 - Air Interface
70// This section basicly contains transmission and receiving of bits
71///////////////////////////////////////////////////////////////////////
72
9455b51c 73#define Crc(data,datalen) Iso15693Crc(data,datalen)
74#define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
75#define sprintUID(target,uid) Iso15693sprintUID(target,uid)
15c4dc5a 76
8c6cca0b 77// buffers
d9de20fa 78#define ISO15693_DMA_BUFFER_SIZE 2048 // must be a power of 2
79#define ISO15693_MAX_RESPONSE_LENGTH 36 // allows read single block with the maximum block size of 256bits. Read multiple blocks not supported yet
80#define ISO15693_MAX_COMMAND_LENGTH 45 // allows write single block with the maximum block size of 256bits. Write multiple blocks not supported yet
8c6cca0b 81
82// timing. Delays in SSP_CLK ticks.
83#define DELAY_READER_TO_ARM 8
84#define DELAY_ARM_TO_READER 1
85#define DELAY_ISO15693_VCD_TO_VICC 132 // 132/423.75kHz = 311.5us from end of EOF to start of tag response
d9de20fa 86#define DELAY_ISO15693_VICC_TO_VCD 1017 // 1017/3.39MHz = 300us between end of tag response and next reader command
9455b51c 87
88// ---------------------------
8c6cca0b 89// Signal Processing
9455b51c 90// ---------------------------
91
92// prepare data using "1 out of 4" code for later transmission
8c6cca0b 93// resulting data rate is 26.48 kbit/s (fc/512)
9455b51c 94// cmd ... data
95// n ... length of data
f7e3ed82 96static void CodeIso15693AsReader(uint8_t *cmd, int n)
15c4dc5a 97{
98 int i, j;
99
100 ToSendReset();
101
102 // Give it a bit of slack at the beginning
103 for(i = 0; i < 24; i++) {
104 ToSendStuffBit(1);
105 }
106
9455b51c 107 // SOF for 1of4
15c4dc5a 108 ToSendStuffBit(0);
109 ToSendStuffBit(1);
110 ToSendStuffBit(1);
111 ToSendStuffBit(1);
112 ToSendStuffBit(1);
113 ToSendStuffBit(0);
114 ToSendStuffBit(1);
115 ToSendStuffBit(1);
116 for(i = 0; i < n; i++) {
117 for(j = 0; j < 8; j += 2) {
118 int these = (cmd[i] >> j) & 3;
119 switch(these) {
120 case 0:
121 ToSendStuffBit(1);
122 ToSendStuffBit(0);
123 ToSendStuffBit(1);
124 ToSendStuffBit(1);
125 ToSendStuffBit(1);
126 ToSendStuffBit(1);
127 ToSendStuffBit(1);
128 ToSendStuffBit(1);
129 break;
130 case 1:
131 ToSendStuffBit(1);
132 ToSendStuffBit(1);
133 ToSendStuffBit(1);
134 ToSendStuffBit(0);
135 ToSendStuffBit(1);
136 ToSendStuffBit(1);
137 ToSendStuffBit(1);
138 ToSendStuffBit(1);
139 break;
140 case 2:
141 ToSendStuffBit(1);
142 ToSendStuffBit(1);
143 ToSendStuffBit(1);
144 ToSendStuffBit(1);
145 ToSendStuffBit(1);
146 ToSendStuffBit(0);
147 ToSendStuffBit(1);
148 ToSendStuffBit(1);
149 break;
150 case 3:
151 ToSendStuffBit(1);
152 ToSendStuffBit(1);
153 ToSendStuffBit(1);
154 ToSendStuffBit(1);
155 ToSendStuffBit(1);
156 ToSendStuffBit(1);
157 ToSendStuffBit(1);
158 ToSendStuffBit(0);
159 break;
160 }
161 }
162 }
9455b51c 163 // EOF
15c4dc5a 164 ToSendStuffBit(1);
165 ToSendStuffBit(1);
166 ToSendStuffBit(0);
167 ToSendStuffBit(1);
168
70b2fc0a 169 // Fill remainder of last byte with 1
170 for(i = 0; i < 4; i++) {
15c4dc5a 171 ToSendStuffBit(1);
172 }
bdf96aae 173
174 ToSendMax++;
15c4dc5a 175}
176
70b2fc0a 177// encode data using "1 out of 256" scheme
8c6cca0b 178// data rate is 1,66 kbit/s (fc/8192)
9455b51c 179// is designed for more robust communication over longer distances
180static void CodeIso15693AsReader256(uint8_t *cmd, int n)
15c4dc5a 181{
15c4dc5a 182 int i, j;
183
9455b51c 184 ToSendReset();
185
186 // Give it a bit of slack at the beginning
187 for(i = 0; i < 24; i++) {
188 ToSendStuffBit(1);
189 }
190
191 // SOF for 1of256
192 ToSendStuffBit(0);
193 ToSendStuffBit(1);
194 ToSendStuffBit(1);
195 ToSendStuffBit(1);
196 ToSendStuffBit(1);
197 ToSendStuffBit(1);
198 ToSendStuffBit(1);
199 ToSendStuffBit(0);
8c6cca0b 200
15c4dc5a 201 for(i = 0; i < n; i++) {
9455b51c 202 for (j = 0; j<=255; j++) {
203 if (cmd[i]==j) {
204 ToSendStuffBit(1);
205 ToSendStuffBit(0);
15c4dc5a 206 } else {
9455b51c 207 ToSendStuffBit(1);
208 ToSendStuffBit(1);
8c6cca0b 209 }
210 }
15c4dc5a 211 }
9455b51c 212 // EOF
213 ToSendStuffBit(1);
214 ToSendStuffBit(1);
215 ToSendStuffBit(0);
216 ToSendStuffBit(1);
15c4dc5a 217
8c6cca0b 218 // Fill remainder of last byte with 1
219 for(i = 0; i < 4; i++) {
9455b51c 220 ToSendStuffBit(1);
221 }
8c6cca0b 222
223 ToSendMax++;
224}
225
226
227static void CodeIso15693AsTag(uint8_t *cmd, int n)
228{
229 ToSendReset();
230
231 // SOF
232 ToSendStuffBit(0);
233 ToSendStuffBit(0);
234 ToSendStuffBit(0);
235 ToSendStuffBit(1);
236 ToSendStuffBit(1);
237 ToSendStuffBit(1);
238 ToSendStuffBit(0);
239 ToSendStuffBit(1);
240
241 // data
242 for(int i = 0; i < n; i++) {
243 for(int j = 0; j < 8; j++) {
244 if ((cmd[i] >> j) & 0x01) {
245 ToSendStuffBit(0);
246 ToSendStuffBit(1);
247 } else {
248 ToSendStuffBit(1);
249 ToSendStuffBit(0);
250 }
251 }
252 }
253
254 // EOF
255 ToSendStuffBit(1);
256 ToSendStuffBit(0);
257 ToSendStuffBit(1);
258 ToSendStuffBit(1);
259 ToSendStuffBit(1);
260 ToSendStuffBit(0);
261 ToSendStuffBit(0);
262 ToSendStuffBit(0);
263
264 ToSendMax++;
15c4dc5a 265}
266
9455b51c 267
70b2fc0a 268// Transmit the command (to the tag) that was placed in cmd[].
d9de20fa 269static void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t start_time)
15c4dc5a 270{
6a5d4e17 271 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
15c4dc5a 272 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
15c4dc5a 273
d9de20fa 274 while (GetCountSspClk() < start_time);
275
70b2fc0a 276 LED_B_ON();
277 for(int c = 0; c < len; ) {
15c4dc5a 278 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
6a5d4e17 279 AT91C_BASE_SSC->SSC_THR = ~cmd[c];
15c4dc5a 280 c++;
15c4dc5a 281 }
282 WDT_HIT();
283 }
70b2fc0a 284 LED_B_OFF();
15c4dc5a 285}
286
287//-----------------------------------------------------------------------------
8c6cca0b 288// Transmit the tag response (to the reader) that was placed in cmd[].
15c4dc5a 289//-----------------------------------------------------------------------------
8c6cca0b 290static void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t start_time, bool slow)
15c4dc5a 291{
8c6cca0b 292 // don't use the FPGA_HF_SIMULATOR_MODULATE_424K_8BIT minor mode. It would spoil GetCountSspClk()
70b2fc0a 293 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K);
15c4dc5a 294
8c6cca0b 295 uint8_t shift_delay = start_time & 0x00000007;
296 uint8_t bitmask = 0x00;
297 for (int i = 0; i < shift_delay; i++) {
298 bitmask |= (0x01 << i);
299 }
300
301 while (GetCountSspClk() < (start_time & 0xfffffff8)) ;
d9de20fa 302
8c6cca0b 303 AT91C_BASE_SSC->SSC_THR = 0x00; // clear TXRDY
304
70b2fc0a 305 LED_C_ON();
8c6cca0b 306 uint8_t bits_to_shift = 0x00;
307 for(size_t c = 0; c <= len; c++) {
308 uint8_t bits_to_send = bits_to_shift << (8 - shift_delay) | (c==len?0x00:cmd[c]) >> shift_delay;
309 bits_to_shift = cmd[c] & bitmask;
310 for (int i = 7; i >= 0; i--) {
311 for (int j = 0; j < (slow?4:1); ) {
312 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
313 if (bits_to_send >> i & 0x01) {
314 AT91C_BASE_SSC->SSC_THR = 0xff;
315 } else {
316 AT91C_BASE_SSC->SSC_THR = 0x00;
317 }
318 j++;
319 }
320 WDT_HIT();
321 }
15c4dc5a 322 }
15c4dc5a 323 }
70b2fc0a 324 LED_C_OFF();
15c4dc5a 325}
326
9455b51c 327
70b2fc0a 328//=============================================================================
8c6cca0b 329// An ISO 15693 decoder for tag responses (one subcarrier only).
d9de20fa 330// Uses cross correlation to identify each bit and EOF.
70b2fc0a 331// This function is called 8 times per bit (every 2 subcarrier cycles).
8c6cca0b 332// Subcarrier frequency fs is 424kHz, 1/fs = 2,36us,
70b2fc0a 333// i.e. function is called every 4,72us
334// LED handling:
335// LED C -> ON once we have received the SOF and are expecting the rest.
336// LED C -> OFF once we have received EOF or are unsynced
337//
338// Returns: true if we received a EOF
339// false if we are still waiting for some more
340//=============================================================================
341
c0e7527d 342#define NOISE_THRESHOLD 160 // don't try to correlate noise
70b2fc0a 343
8c6cca0b 344typedef struct DecodeTag {
70b2fc0a 345 enum {
d9de20fa 346 STATE_TAG_SOF_LOW,
347 STATE_TAG_SOF_HIGH,
348 STATE_TAG_SOF_HIGH_END,
8c6cca0b 349 STATE_TAG_RECEIVING_DATA,
d9de20fa 350 STATE_TAG_EOF
70b2fc0a 351 } state;
352 int bitCount;
353 int posCount;
354 enum {
355 LOGIC0,
356 LOGIC1,
357 SOF_PART1,
358 SOF_PART2
359 } lastBit;
360 uint16_t shiftReg;
d9de20fa 361 uint16_t max_len;
70b2fc0a 362 uint8_t *output;
363 int len;
364 int sum1, sum2;
8c6cca0b 365} DecodeTag_t;
70b2fc0a 366
d9de20fa 367
368static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *DecodeTag)
15c4dc5a 369{
8c6cca0b 370 switch(DecodeTag->state) {
d9de20fa 371 case STATE_TAG_SOF_LOW:
372 // waiting for 12 times low (11 times low is accepted as well)
373 if (amplitude < NOISE_THRESHOLD) {
8c6cca0b 374 DecodeTag->posCount++;
70b2fc0a 375 } else {
d9de20fa 376 if (DecodeTag->posCount > 10) {
377 DecodeTag->posCount = 1;
378 DecodeTag->sum1 = 0;
379 DecodeTag->state = STATE_TAG_SOF_HIGH;
380 } else {
381 DecodeTag->posCount = 0;
382 }
15c4dc5a 383 }
d9de20fa 384 break;
385
386 case STATE_TAG_SOF_HIGH:
387 // waiting for 10 times high. Take average over the last 8
388 if (amplitude > NOISE_THRESHOLD) {
389 DecodeTag->posCount++;
390 if (DecodeTag->posCount > 2) {
391 DecodeTag->sum1 += amplitude; // keep track of average high value
392 }
393 if (DecodeTag->posCount == 10) {
394 DecodeTag->sum1 >>= 4; // calculate half of average high value (8 samples)
395 DecodeTag->state = STATE_TAG_SOF_HIGH_END;
396 }
397 } else { // high phase was too short
398 DecodeTag->posCount = 1;
399 DecodeTag->state = STATE_TAG_SOF_LOW;
70b2fc0a 400 }
70b2fc0a 401 break;
402
d9de20fa 403 case STATE_TAG_SOF_HIGH_END:
404 // waiting for a falling edge
405 if (amplitude < DecodeTag->sum1) { // signal drops below 50% average high: a falling edge
406 DecodeTag->lastBit = SOF_PART1; // detected 1st part of SOF (12 samples low and 12 samples high)
407 DecodeTag->shiftReg = 0;
408 DecodeTag->bitCount = 0;
409 DecodeTag->len = 0;
410 DecodeTag->sum1 = amplitude;
8c6cca0b 411 DecodeTag->sum2 = 0;
412 DecodeTag->posCount = 2;
413 DecodeTag->state = STATE_TAG_RECEIVING_DATA;
70b2fc0a 414 LED_C_ON();
d9de20fa 415 } else {
416 DecodeTag->posCount++;
417 if (DecodeTag->posCount > 13) { // high phase too long
418 DecodeTag->posCount = 0;
419 DecodeTag->state = STATE_TAG_SOF_LOW;
420 LED_C_OFF();
421 }
70b2fc0a 422 }
70b2fc0a 423 break;
15c4dc5a 424
8c6cca0b 425 case STATE_TAG_RECEIVING_DATA:
426 if (DecodeTag->posCount == 1) {
427 DecodeTag->sum1 = 0;
428 DecodeTag->sum2 = 0;
70b2fc0a 429 }
8c6cca0b 430 if (DecodeTag->posCount <= 4) {
d9de20fa 431 DecodeTag->sum1 += amplitude;
70b2fc0a 432 } else {
d9de20fa 433 DecodeTag->sum2 += amplitude;
70b2fc0a 434 }
8c6cca0b 435 if (DecodeTag->posCount == 8) {
d9de20fa 436 int32_t corr_1 = DecodeTag->sum2 - DecodeTag->sum1;
437 int32_t corr_0 = -corr_1;
438 int32_t corr_EOF = (DecodeTag->sum1 + DecodeTag->sum2) / 2;
70b2fc0a 439 if (corr_EOF > corr_0 && corr_EOF > corr_1) {
d9de20fa 440 if (DecodeTag->lastBit == LOGIC0) { // this was already part of EOF
441 DecodeTag->state = STATE_TAG_EOF;
442 } else {
443 DecodeTag->posCount = 0;
444 DecodeTag->state = STATE_TAG_SOF_LOW;
445 LED_C_OFF();
446 }
70b2fc0a 447 } else if (corr_1 > corr_0) {
448 // logic 1
8c6cca0b 449 if (DecodeTag->lastBit == SOF_PART1) { // still part of SOF
d9de20fa 450 DecodeTag->lastBit = SOF_PART2; // SOF completed
70b2fc0a 451 } else {
8c6cca0b 452 DecodeTag->lastBit = LOGIC1;
453 DecodeTag->shiftReg >>= 1;
454 DecodeTag->shiftReg |= 0x80;
455 DecodeTag->bitCount++;
456 if (DecodeTag->bitCount == 8) {
457 DecodeTag->output[DecodeTag->len] = DecodeTag->shiftReg;
458 DecodeTag->len++;
d9de20fa 459 if (DecodeTag->len > DecodeTag->max_len) {
460 // buffer overflow, give up
461 DecodeTag->posCount = 0;
462 DecodeTag->state = STATE_TAG_SOF_LOW;
463 LED_C_OFF();
464 }
8c6cca0b 465 DecodeTag->bitCount = 0;
466 DecodeTag->shiftReg = 0;
70b2fc0a 467 }
468 }
469 } else {
470 // logic 0
8c6cca0b 471 if (DecodeTag->lastBit == SOF_PART1) { // incomplete SOF
d9de20fa 472 DecodeTag->posCount = 0;
473 DecodeTag->state = STATE_TAG_SOF_LOW;
70b2fc0a 474 LED_C_OFF();
475 } else {
8c6cca0b 476 DecodeTag->lastBit = LOGIC0;
477 DecodeTag->shiftReg >>= 1;
478 DecodeTag->bitCount++;
479 if (DecodeTag->bitCount == 8) {
480 DecodeTag->output[DecodeTag->len] = DecodeTag->shiftReg;
481 DecodeTag->len++;
d9de20fa 482 if (DecodeTag->len > DecodeTag->max_len) {
483 // buffer overflow, give up
484 DecodeTag->posCount = 0;
485 DecodeTag->state = STATE_TAG_SOF_LOW;
486 LED_C_OFF();
487 }
8c6cca0b 488 DecodeTag->bitCount = 0;
489 DecodeTag->shiftReg = 0;
70b2fc0a 490 }
491 }
492 }
8c6cca0b 493 DecodeTag->posCount = 0;
70b2fc0a 494 }
8c6cca0b 495 DecodeTag->posCount++;
70b2fc0a 496 break;
8c6cca0b 497
d9de20fa 498 case STATE_TAG_EOF:
499 if (DecodeTag->posCount == 1) {
500 DecodeTag->sum1 = 0;
501 DecodeTag->sum2 = 0;
502 }
503 if (DecodeTag->posCount <= 4) {
504 DecodeTag->sum1 += amplitude;
70b2fc0a 505 } else {
d9de20fa 506 DecodeTag->sum2 += amplitude;
70b2fc0a 507 }
d9de20fa 508 if (DecodeTag->posCount == 8) {
509 int32_t corr_1 = DecodeTag->sum2 - DecodeTag->sum1;
510 int32_t corr_0 = -corr_1;
511 int32_t corr_EOF = (DecodeTag->sum1 + DecodeTag->sum2) / 2;
512 if (corr_EOF > corr_0 || corr_1 > corr_0) {
513 DecodeTag->posCount = 0;
514 DecodeTag->state = STATE_TAG_SOF_LOW;
515 LED_C_OFF();
516 } else {
517 LED_C_OFF();
518 return true;
519 }
520 }
521 DecodeTag->posCount++;
70b2fc0a 522 break;
523
15c4dc5a 524 }
15c4dc5a 525
70b2fc0a 526 return false;
527}
15c4dc5a 528
15c4dc5a 529
d9de20fa 530static void DecodeTagInit(DecodeTag_t *DecodeTag, uint8_t *data, uint16_t max_len)
70b2fc0a 531{
d9de20fa 532 DecodeTag->posCount = 0;
533 DecodeTag->state = STATE_TAG_SOF_LOW;
8c6cca0b 534 DecodeTag->output = data;
d9de20fa 535 DecodeTag->max_len = max_len;
536}
537
538
539static void DecodeTagReset(DecodeTag_t *DecodeTag)
540{
541 DecodeTag->posCount = 0;
542 DecodeTag->state = STATE_TAG_SOF_LOW;
70b2fc0a 543}
544
d9de20fa 545
70b2fc0a 546/*
8c6cca0b 547 * Receive and decode the tag response, also log to tracebuffer
70b2fc0a 548 */
d9de20fa 549static int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, int timeout)
70b2fc0a 550{
d9de20fa 551 int samples = 0;
70b2fc0a 552 bool gotFrame = false;
70b2fc0a 553
d9de20fa 554 uint16_t *dmaBuf = (uint16_t*)BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE*sizeof(uint16_t));
555
8c6cca0b 556 // the Decoder data structure
d9de20fa 557 DecodeTag_t DecodeTag = { 0 };
558 DecodeTagInit(&DecodeTag, response, max_len);
70b2fc0a 559
560 // wait for last transfer to complete
561 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
562
563 // And put the FPGA in the appropriate mode
d9de20fa 564 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_AMPLITUDE);
70b2fc0a 565
566 // Setup and start DMA.
567 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
568 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
70b2fc0a 569 uint16_t *upTo = dmaBuf;
70b2fc0a 570
571 for(;;) {
d9de20fa 572 uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1);
70b2fc0a 573
d9de20fa 574 if (behindBy == 0) continue;
8c6cca0b 575
d9de20fa 576 uint16_t tagdata = *upTo++;
70b2fc0a 577
70b2fc0a 578 if(upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
579 upTo = dmaBuf; // start reading the circular buffer from the beginning
d9de20fa 580 if(behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
581 Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy);
582 break;
583 }
15c4dc5a 584 }
70b2fc0a 585 if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated.
586 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and
587 AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers
15c4dc5a 588 }
d9de20fa 589
70b2fc0a 590 samples++;
15c4dc5a 591
d9de20fa 592 if (Handle15693SamplesFromTag(tagdata, &DecodeTag)) {
70b2fc0a 593 gotFrame = true;
594 break;
595 }
15c4dc5a 596
d9de20fa 597 if (samples > timeout && DecodeTag.state < STATE_TAG_RECEIVING_DATA) {
8c6cca0b 598 DecodeTag.len = 0;
70b2fc0a 599 break;
600 }
8c6cca0b 601
70b2fc0a 602 }
603
604 FpgaDisableSscDma();
d9de20fa 605 BigBuf_free();
606
607 if (DEBUG) Dbprintf("samples = %d, gotFrame = %d, Decoder: state = %d, len = %d, bitCount = %d, posCount = %d",
608 samples, gotFrame, DecodeTag.state, DecodeTag.len, DecodeTag.bitCount, DecodeTag.posCount);
70b2fc0a 609
d9de20fa 610 if (DecodeTag.len > 0) {
8c6cca0b 611 LogTrace(DecodeTag.output, DecodeTag.len, 0, 0, NULL, false);
70b2fc0a 612 }
613
8c6cca0b 614 return DecodeTag.len;
15c4dc5a 615}
616
9455b51c 617
8c6cca0b 618//=============================================================================
619// An ISO15693 decoder for reader commands.
620//
621// This function is called 4 times per bit (every 2 subcarrier cycles).
622// Subcarrier frequency fs is 848kHz, 1/fs = 1,18us, i.e. function is called every 2,36us
623// LED handling:
624// LED B -> ON once we have received the SOF and are expecting the rest.
625// LED B -> OFF once we have received EOF or are in error state or unsynced
626//
627// Returns: true if we received a EOF
628// false if we are still waiting for some more
629//=============================================================================
630
631typedef struct DecodeReader {
632 enum {
633 STATE_READER_UNSYNCD,
634 STATE_READER_AWAIT_1ST_RISING_EDGE_OF_SOF,
635 STATE_READER_AWAIT_2ND_FALLING_EDGE_OF_SOF,
636 STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF,
637 STATE_READER_AWAIT_END_OF_SOF_1_OUT_OF_4,
638 STATE_READER_RECEIVE_DATA_1_OUT_OF_4,
639 STATE_READER_RECEIVE_DATA_1_OUT_OF_256
640 } state;
641 enum {
642 CODING_1_OUT_OF_4,
643 CODING_1_OUT_OF_256
644 } Coding;
645 uint8_t shiftReg;
646 uint8_t bitCount;
647 int byteCount;
648 int byteCountMax;
649 int posCount;
650 int sum1, sum2;
651 uint8_t *output;
652} DecodeReader_t;
653
654
d9de20fa 655static void DecodeReaderInit(DecodeReader_t* DecodeReader, uint8_t *data, uint16_t max_len)
656{
657 DecodeReader->output = data;
658 DecodeReader->byteCountMax = max_len;
659 DecodeReader->state = STATE_READER_UNSYNCD;
660 DecodeReader->byteCount = 0;
661 DecodeReader->bitCount = 0;
662 DecodeReader->posCount = 1;
663 DecodeReader->shiftReg = 0;
664}
665
666
667static void DecodeReaderReset(DecodeReader_t* DecodeReader)
668{
669 DecodeReader->state = STATE_READER_UNSYNCD;
670}
671
672
673static int inline __attribute__((always_inline)) Handle15693SampleFromReader(uint8_t bit, DecodeReader_t *restrict DecodeReader)
15c4dc5a 674{
8c6cca0b 675 switch(DecodeReader->state) {
676 case STATE_READER_UNSYNCD:
677 if(!bit) {
678 // we went low, so this could be the beginning of a SOF
8c6cca0b 679 DecodeReader->posCount = 1;
d9de20fa 680 DecodeReader->state = STATE_READER_AWAIT_1ST_RISING_EDGE_OF_SOF;
8c6cca0b 681 }
682 break;
15c4dc5a 683
8c6cca0b 684 case STATE_READER_AWAIT_1ST_RISING_EDGE_OF_SOF:
685 DecodeReader->posCount++;
686 if(bit) { // detected rising edge
687 if(DecodeReader->posCount < 4) { // rising edge too early (nominally expected at 5)
d9de20fa 688 DecodeReaderReset(DecodeReader);
8c6cca0b 689 } else { // SOF
690 DecodeReader->state = STATE_READER_AWAIT_2ND_FALLING_EDGE_OF_SOF;
691 }
692 } else {
693 if(DecodeReader->posCount > 5) { // stayed low for too long
d9de20fa 694 DecodeReaderReset(DecodeReader);
8c6cca0b 695 } else {
696 // do nothing, keep waiting
697 }
698 }
699 break;
700
701 case STATE_READER_AWAIT_2ND_FALLING_EDGE_OF_SOF:
702 DecodeReader->posCount++;
703 if(!bit) { // detected a falling edge
704 if (DecodeReader->posCount < 20) { // falling edge too early (nominally expected at 21 earliest)
d9de20fa 705 DecodeReaderReset(DecodeReader);
8c6cca0b 706 } else if (DecodeReader->posCount < 23) { // SOF for 1 out of 4 coding
707 DecodeReader->Coding = CODING_1_OUT_OF_4;
708 DecodeReader->state = STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF;
709 } else if (DecodeReader->posCount < 28) { // falling edge too early (nominally expected at 29 latest)
d9de20fa 710 DecodeReaderReset(DecodeReader);
8c6cca0b 711 } else { // SOF for 1 out of 4 coding
712 DecodeReader->Coding = CODING_1_OUT_OF_256;
713 DecodeReader->state = STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF;
714 }
715 } else {
716 if(DecodeReader->posCount > 29) { // stayed high for too long
d9de20fa 717 DecodeReaderReset(DecodeReader);
8c6cca0b 718 } else {
719 // do nothing, keep waiting
720 }
721 }
722 break;
723
724 case STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF:
725 DecodeReader->posCount++;
726 if (bit) { // detected rising edge
727 if (DecodeReader->Coding == CODING_1_OUT_OF_256) {
728 if (DecodeReader->posCount < 32) { // rising edge too early (nominally expected at 33)
d9de20fa 729 DecodeReaderReset(DecodeReader);
8c6cca0b 730 } else {
731 DecodeReader->posCount = 1;
732 DecodeReader->bitCount = 0;
733 DecodeReader->byteCount = 0;
734 DecodeReader->sum1 = 1;
735 DecodeReader->state = STATE_READER_RECEIVE_DATA_1_OUT_OF_256;
736 LED_B_ON();
737 }
738 } else { // CODING_1_OUT_OF_4
739 if (DecodeReader->posCount < 24) { // rising edge too early (nominally expected at 25)
d9de20fa 740 DecodeReaderReset(DecodeReader);
8c6cca0b 741 } else {
742 DecodeReader->state = STATE_READER_AWAIT_END_OF_SOF_1_OUT_OF_4;
743 }
744 }
745 } else {
746 if (DecodeReader->Coding == CODING_1_OUT_OF_256) {
747 if (DecodeReader->posCount > 34) { // signal stayed low for too long
d9de20fa 748 DecodeReaderReset(DecodeReader);
8c6cca0b 749 } else {
750 // do nothing, keep waiting
751 }
752 } else { // CODING_1_OUT_OF_4
753 if (DecodeReader->posCount > 26) { // signal stayed low for too long
d9de20fa 754 DecodeReaderReset(DecodeReader);
8c6cca0b 755 } else {
756 // do nothing, keep waiting
757 }
758 }
759 }
760 break;
761
762 case STATE_READER_AWAIT_END_OF_SOF_1_OUT_OF_4:
763 DecodeReader->posCount++;
764 if (bit) {
765 if (DecodeReader->posCount == 33) {
766 DecodeReader->posCount = 1;
767 DecodeReader->bitCount = 0;
768 DecodeReader->byteCount = 0;
769 DecodeReader->sum1 = 1;
770 DecodeReader->state = STATE_READER_RECEIVE_DATA_1_OUT_OF_4;
771 LED_B_ON();
772 } else {
773 // do nothing, keep waiting
774 }
775 } else { // unexpected falling edge
d9de20fa 776 DecodeReaderReset(DecodeReader);
8c6cca0b 777 }
778 break;
779
780 case STATE_READER_RECEIVE_DATA_1_OUT_OF_4:
781 DecodeReader->posCount++;
782 if (DecodeReader->posCount == 1) {
783 DecodeReader->sum1 = bit;
784 } else if (DecodeReader->posCount <= 4) {
785 DecodeReader->sum1 += bit;
786 } else if (DecodeReader->posCount == 5) {
787 DecodeReader->sum2 = bit;
788 } else {
789 DecodeReader->sum2 += bit;
790 }
791 if (DecodeReader->posCount == 8) {
792 DecodeReader->posCount = 0;
793 int corr10 = DecodeReader->sum1 - DecodeReader->sum2;
794 int corr01 = DecodeReader->sum2 - DecodeReader->sum1;
795 int corr11 = (DecodeReader->sum1 + DecodeReader->sum2) / 2;
796 if (corr01 > corr11 && corr01 > corr10) { // EOF
797 LED_B_OFF(); // Finished receiving
d9de20fa 798 DecodeReaderReset(DecodeReader);
8c6cca0b 799 if (DecodeReader->byteCount != 0) {
800 return true;
801 }
802 }
803 if (corr10 > corr11) { // detected a 2bit position
804 DecodeReader->shiftReg >>= 2;
805 DecodeReader->shiftReg |= (DecodeReader->bitCount << 6);
806 }
807 if (DecodeReader->bitCount == 15) { // we have a full byte
808 DecodeReader->output[DecodeReader->byteCount++] = DecodeReader->shiftReg;
809 if (DecodeReader->byteCount > DecodeReader->byteCountMax) {
810 // buffer overflow, give up
811 LED_B_OFF();
d9de20fa 812 DecodeReaderReset(DecodeReader);
8c6cca0b 813 }
814 DecodeReader->bitCount = 0;
d9de20fa 815 DecodeReader->shiftReg = 0;
8c6cca0b 816 } else {
817 DecodeReader->bitCount++;
818 }
819 }
820 break;
821
822 case STATE_READER_RECEIVE_DATA_1_OUT_OF_256:
823 DecodeReader->posCount++;
824 if (DecodeReader->posCount == 1) {
825 DecodeReader->sum1 = bit;
826 } else if (DecodeReader->posCount <= 4) {
827 DecodeReader->sum1 += bit;
828 } else if (DecodeReader->posCount == 5) {
829 DecodeReader->sum2 = bit;
830 } else {
831 DecodeReader->sum2 += bit;
832 }
833 if (DecodeReader->posCount == 8) {
834 DecodeReader->posCount = 0;
835 int corr10 = DecodeReader->sum1 - DecodeReader->sum2;
836 int corr01 = DecodeReader->sum2 - DecodeReader->sum1;
837 int corr11 = (DecodeReader->sum1 + DecodeReader->sum2) / 2;
838 if (corr01 > corr11 && corr01 > corr10) { // EOF
839 LED_B_OFF(); // Finished receiving
d9de20fa 840 DecodeReaderReset(DecodeReader);
8c6cca0b 841 if (DecodeReader->byteCount != 0) {
842 return true;
843 }
844 }
845 if (corr10 > corr11) { // detected the bit position
846 DecodeReader->shiftReg = DecodeReader->bitCount;
847 }
848 if (DecodeReader->bitCount == 255) { // we have a full byte
849 DecodeReader->output[DecodeReader->byteCount++] = DecodeReader->shiftReg;
850 if (DecodeReader->byteCount > DecodeReader->byteCountMax) {
851 // buffer overflow, give up
852 LED_B_OFF();
d9de20fa 853 DecodeReaderReset(DecodeReader);
8c6cca0b 854 }
855 }
856 DecodeReader->bitCount++;
857 }
858 break;
859
860 default:
861 LED_B_OFF();
d9de20fa 862 DecodeReaderReset(DecodeReader);
8c6cca0b 863 break;
15c4dc5a 864 }
8c6cca0b 865
866 return false;
867}
868
869
8c6cca0b 870//-----------------------------------------------------------------------------
871// Receive a command (from the reader to us, where we are the simulated tag),
872// and store it in the given buffer, up to the given maximum length. Keeps
873// spinning, waiting for a well-framed command, until either we get one
874// (returns true) or someone presses the pushbutton on the board (false).
875//
876// Assume that we're called with the SSC (to the FPGA) and ADC path set
877// correctly.
878//-----------------------------------------------------------------------------
879
880static int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time)
881{
d9de20fa 882 int samples = 0;
8c6cca0b 883 bool gotFrame = false;
884 uint8_t b;
885
d9de20fa 886 uint8_t *dmaBuf = BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE);
8c6cca0b 887
888 // the decoder data structure
6eeb5f1c 889 DecodeReader_t DecodeReader = {0};
d9de20fa 890 DecodeReaderInit(&DecodeReader, received, max_len);
8c6cca0b 891
892 // wait for last transfer to complete
893 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
894
70b2fc0a 895 LED_D_OFF();
8c6cca0b 896 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
15c4dc5a 897
8c6cca0b 898 // clear receive register and wait for next transfer
899 uint32_t temp = AT91C_BASE_SSC->SSC_RHR;
900 (void) temp;
901 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) ;
15c4dc5a 902
8c6cca0b 903 uint32_t bit_time = GetCountSspClk() & 0xfffffff8;
15c4dc5a 904
8c6cca0b 905 // Setup and start DMA.
906 FpgaSetupSscDma(dmaBuf, ISO15693_DMA_BUFFER_SIZE);
907 uint8_t *upTo = dmaBuf;
15c4dc5a 908
8c6cca0b 909 for(;;) {
d9de20fa 910 uint16_t behindBy = ((uint8_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1);
70b2fc0a 911
d9de20fa 912 if (behindBy == 0) continue;
15c4dc5a 913
8c6cca0b 914 b = *upTo++;
8c6cca0b 915 if(upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
916 upTo = dmaBuf; // start reading the circular buffer from the beginning
d9de20fa 917 if(behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
918 Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy);
919 break;
920 }
8c6cca0b 921 }
922 if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated.
923 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and
924 AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers
925 }
15c4dc5a 926
8c6cca0b 927 for (int i = 7; i >= 0; i--) {
928 if (Handle15693SampleFromReader((b >> i) & 0x01, &DecodeReader)) {
929 *eof_time = bit_time + samples - DELAY_READER_TO_ARM; // end of EOF
930 gotFrame = true;
9455b51c 931 break;
932 }
8c6cca0b 933 samples++;
15c4dc5a 934 }
8c6cca0b 935
936 if (gotFrame) {
937 break;
15c4dc5a 938 }
8c6cca0b 939
940 if (BUTTON_PRESS()) {
941 DecodeReader.byteCount = 0;
942 break;
15c4dc5a 943 }
15c4dc5a 944
8c6cca0b 945 WDT_HIT();
946 }
947
948
949 FpgaDisableSscDma();
d9de20fa 950 BigBuf_free_keep_EM();
951
952 if (DEBUG) Dbprintf("samples = %d, gotFrame = %d, Decoder: state = %d, len = %d, bitCount = %d, posCount = %d",
953 samples, gotFrame, DecodeReader.state, DecodeReader.byteCount, DecodeReader.bitCount, DecodeReader.posCount);
8c6cca0b 954
d9de20fa 955 if (DecodeReader.byteCount > 0) {
8c6cca0b 956 LogTrace(DecodeReader.output, DecodeReader.byteCount, 0, 0, NULL, true);
957 }
958
959 return DecodeReader.byteCount;
15c4dc5a 960}
961
9455b51c 962
d9de20fa 963// Encode (into the ToSend buffers) an identify request, which is the first
964// thing that you must send to a tag to get a response.
965static void BuildIdentifyRequest(void)
966{
967 uint8_t cmd[5];
968
969 uint16_t crc;
970 // one sub-carrier, inventory, 1 slot, fast rate
971 // AFI is at bit 5 (1<<4) when doing an INVENTORY
972 cmd[0] = (1 << 2) | (1 << 5) | (1 << 1);
973 // inventory command code
974 cmd[1] = 0x01;
975 // no mask
976 cmd[2] = 0x00;
977 //Now the CRC
978 crc = Crc(cmd, 3);
979 cmd[3] = crc & 0xff;
980 cmd[4] = crc >> 8;
981
982 CodeIso15693AsReader(cmd, sizeof(cmd));
983}
984
985
15c4dc5a 986//-----------------------------------------------------------------------------
987// Start to read an ISO 15693 tag. We send an identify request, then wait
988// for the response. The response is not demodulated, just left in the buffer
989// so that it can be downloaded to a PC and processed there.
990//-----------------------------------------------------------------------------
991void AcquireRawAdcSamplesIso15693(void)
992{
70b2fc0a 993 LEDsoff();
994 LED_A_ON();
8c6cca0b 995
117d9ec2 996 uint8_t *dest = BigBuf_get_addr();
15c4dc5a 997
7cc204bf 998 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 999 BuildIdentifyRequest();
1000
1001 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
1002
1003 // Give the tags time to energize
70b2fc0a 1004 LED_D_ON();
15c4dc5a 1005 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
1006 SpinDelay(100);
1007
1008 // Now send the command
6a5d4e17 1009 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
15c4dc5a 1010 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
1011
70b2fc0a 1012 LED_B_ON();
1013 for(int c = 0; c < ToSendMax; ) {
15c4dc5a 1014 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
6a5d4e17 1015 AT91C_BASE_SSC->SSC_THR = ~ToSend[c];
15c4dc5a 1016 c++;
15c4dc5a 1017 }
15c4dc5a 1018 WDT_HIT();
1019 }
70b2fc0a 1020 LED_B_OFF();
1021
1022 // wait for last transfer to complete
1023 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
15c4dc5a 1024
6a5d4e17 1025 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
d9de20fa 1026 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_AMPLITUDE);
15c4dc5a 1027
70b2fc0a 1028 for(int c = 0; c < 4000; ) {
15c4dc5a 1029 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
d9de20fa 1030 uint16_t r = AT91C_BASE_SSC->SSC_RHR;
1031 dest[c++] = r >> 5;
9455b51c 1032 }
1033 }
70b2fc0a 1034
1035 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1036 LEDsoff();
9455b51c 1037}
1038
1039
d9de20fa 1040void SnoopIso15693(void)
9455b51c 1041{
d9de20fa 1042 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1043 BigBuf_free();
8c6cca0b 1044
d9de20fa 1045 clear_trace();
1046 set_tracing(true);
3fe4ff4f 1047
9455b51c 1048
d9de20fa 1049 // The DMA buffer, used to stream samples from the FPGA
1050 uint16_t* dmaBuf = (uint16_t*)BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE*sizeof(uint16_t));
1051 uint16_t *upTo;
1052
1053 // Count of samples received so far, so that we can include timing
1054 // information in the trace buffer.
1055 int samples = 0;
1056
1057 DecodeTag_t DecodeTag = {0};
1058 uint8_t response[ISO15693_MAX_RESPONSE_LENGTH];
1059 DecodeTagInit(&DecodeTag, response, sizeof(response));
9455b51c 1060
d9de20fa 1061 DecodeReader_t DecodeReader = {0};;
1062 uint8_t cmd[ISO15693_MAX_COMMAND_LENGTH];
1063 DecodeReaderInit(&DecodeReader, cmd, sizeof(cmd));
1064
1065 // Print some debug information about the buffer sizes
1066 if (DEBUG) {
1067 Dbprintf("Snooping buffers initialized:");
1068 Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
1069 Dbprintf(" Reader -> tag: %i bytes", ISO15693_MAX_COMMAND_LENGTH);
1070 Dbprintf(" tag -> Reader: %i bytes", ISO15693_MAX_RESPONSE_LENGTH);
1071 Dbprintf(" DMA: %i bytes", ISO15693_DMA_BUFFER_SIZE * sizeof(uint16_t));
1072 }
1073 Dbprintf("Snoop started. Press button to stop.");
1074
1075 // Signal field is off, no reader signal, no tag signal
1076 LEDsoff();
1077 // And put the FPGA in the appropriate mode
1078 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_SNOOP | FPGA_HF_READER_RX_XCORR_AMPLITUDE);
9455b51c 1079 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
1080
d9de20fa 1081 // Setup for the DMA.
1082 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
1083 upTo = dmaBuf;
1084 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
9455b51c 1085
d9de20fa 1086 bool TagIsActive = false;
1087 bool ReaderIsActive = false;
1088 bool ExpectTagAnswer = false;
9455b51c 1089
d9de20fa 1090 // And now we loop, receiving samples.
1091 for(;;) {
1092 uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1);
1093
1094 if (behindBy == 0) continue;
1095
1096 uint16_t snoopdata = *upTo++;
1097
1098 if(upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
1099 upTo = dmaBuf; // start reading the circular buffer from the beginning
1100 if(behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
1101 Dbprintf("About to blow circular buffer - aborted! behindBy=%d, samples=%d", behindBy, samples);
1102 break;
1103 }
1104 if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated.
1105 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and
1106 AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers
1107 WDT_HIT();
1108 if(BUTTON_PRESS()) {
1109 DbpString("Snoop stopped.");
1110 break;
1111 }
1112 }
1113 }
1114 samples++;
1115
1116 if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
1117 if (Handle15693SampleFromReader(snoopdata & 0x02, &DecodeReader)) {
1118 FpgaDisableSscDma();
1119 ExpectTagAnswer = true;
1120 LogTrace(DecodeReader.output, DecodeReader.byteCount, samples, samples, NULL, true);
1121 /* And ready to receive another command. */
1122 DecodeReaderReset(&DecodeReader);
1123 /* And also reset the demod code, which might have been */
1124 /* false-triggered by the commands from the reader. */
1125 DecodeTagReset(&DecodeTag);
1126 upTo = dmaBuf;
1127 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
1128 }
1129 if (Handle15693SampleFromReader(snoopdata & 0x01, &DecodeReader)) {
1130 FpgaDisableSscDma();
1131 ExpectTagAnswer = true;
1132 LogTrace(DecodeReader.output, DecodeReader.byteCount, samples, samples, NULL, true);
1133 /* And ready to receive another command. */
1134 DecodeReaderReset(&DecodeReader);
1135 /* And also reset the demod code, which might have been */
1136 /* false-triggered by the commands from the reader. */
1137 DecodeTagReset(&DecodeTag);
1138 upTo = dmaBuf;
1139 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
1140 }
1141 ReaderIsActive = (DecodeReader.state >= STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF);
9455b51c 1142 }
d9de20fa 1143
1144 if (!ReaderIsActive && ExpectTagAnswer) { // no need to try decoding tag data if the reader is currently sending or no answer expected yet
1145 if (Handle15693SamplesFromTag(snoopdata >> 2, &DecodeTag)) {
1146 FpgaDisableSscDma();
1147 //Use samples as a time measurement
1148 LogTrace(DecodeTag.output, DecodeTag.len, samples, samples, NULL, false);
1149 // And ready to receive another response.
1150 DecodeTagReset(&DecodeTag);
1151 DecodeReaderReset(&DecodeReader);
1152 ExpectTagAnswer = false;
1153 upTo = dmaBuf;
1154 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
1155 }
1156 TagIsActive = (DecodeTag.state >= STATE_TAG_RECEIVING_DATA);
1157 }
1158
9455b51c 1159 }
70b2fc0a 1160
d9de20fa 1161 FpgaDisableSscDma();
1162 BigBuf_free();
1163
1164 LEDsoff();
1165
1166 DbpString("Snoop statistics:");
1167 Dbprintf(" ExpectTagAnswer: %d", ExpectTagAnswer);
1168 Dbprintf(" DecodeTag State: %d", DecodeTag.state);
1169 Dbprintf(" DecodeTag byteCnt: %d", DecodeTag.len);
1170 Dbprintf(" DecodeReader State: %d", DecodeReader.state);
1171 Dbprintf(" DecodeReader byteCnt: %d", DecodeReader.byteCount);
1172 Dbprintf(" Trace length: %d", BigBuf_get_traceLen());
9455b51c 1173}
1174
1175
8c6cca0b 1176// Initialize the proxmark as iso15k reader
e6304bca 1177// (this might produces glitches that confuse some tags
70b2fc0a 1178static void Iso15693InitReader() {
7cc204bf 1179 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
9455b51c 1180 // Setup SSC
e6304bca 1181 // FpgaSetupSsc();
9455b51c 1182
1183 // Start from off (no field generated)
70b2fc0a 1184 LED_D_OFF();
9455b51c 1185 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
e6304bca 1186 SpinDelay(10);
9455b51c 1187
1188 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
6a5d4e17 1189 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
9455b51c 1190
1191 // Give the tags time to energize
70b2fc0a 1192 LED_D_ON();
9455b51c 1193 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
e6304bca 1194 SpinDelay(250);
9455b51c 1195}
1196
1197///////////////////////////////////////////////////////////////////////
1198// ISO 15693 Part 3 - Air Interface
70b2fc0a 1199// This section basically contains transmission and receiving of bits
9455b51c 1200///////////////////////////////////////////////////////////////////////
1201
9455b51c 1202
1203// uid is in transmission order (which is reverse of display order)
1204static void BuildReadBlockRequest(uint8_t *uid, uint8_t blockNumber )
1205{
1206 uint8_t cmd[13];
1207
1208 uint16_t crc;
d9de20fa 1209 // If we set the Option_Flag in this request, the VICC will respond with the security status of the block
1210 // followed by the block data
1211 cmd[0] = ISO15693_REQ_OPTION | ISO15693_REQ_ADDRESS | ISO15693_REQ_DATARATE_HIGH;
9455b51c 1212 // READ BLOCK command code
d9de20fa 1213 cmd[1] = ISO15693_READBLOCK;
9455b51c 1214 // UID may be optionally specified here
1215 // 64-bit UID
1216 cmd[2] = uid[0];
1217 cmd[3] = uid[1];
1218 cmd[4] = uid[2];
1219 cmd[5] = uid[3];
1220 cmd[6] = uid[4];
1221 cmd[7] = uid[5];
1222 cmd[8] = uid[6];
1223 cmd[9] = uid[7]; // 0xe0; // always e0 (not exactly unique)
1224 // Block number to read
d9de20fa 1225 cmd[10] = blockNumber;
9455b51c 1226 //Now the CRC
8c6cca0b 1227 crc = Crc(cmd, 11); // the crc needs to be calculated over 11 bytes
9455b51c 1228 cmd[11] = crc & 0xff;
1229 cmd[12] = crc >> 8;
1230
1231 CodeIso15693AsReader(cmd, sizeof(cmd));
1232}
1233
70b2fc0a 1234
9455b51c 1235// Now the VICC>VCD responses when we are simulating a tag
8c6cca0b 1236static void BuildInventoryResponse(uint8_t *uid)
9455b51c 1237{
1238 uint8_t cmd[12];
1239
1240 uint16_t crc;
8c6cca0b 1241
1242 cmd[0] = 0; // No error, no protocol format extension
3fe4ff4f 1243 cmd[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported
9455b51c 1244 // 64-bit UID
3fe4ff4f 1245 cmd[2] = uid[7]; //0x32;
1246 cmd[3] = uid[6]; //0x4b;
1247 cmd[4] = uid[5]; //0x03;
1248 cmd[5] = uid[4]; //0x01;
1249 cmd[6] = uid[3]; //0x00;
1250 cmd[7] = uid[2]; //0x10;
1251 cmd[8] = uid[1]; //0x05;
1252 cmd[9] = uid[0]; //0xe0;
9455b51c 1253 //Now the CRC
1254 crc = Crc(cmd, 10);
1255 cmd[10] = crc & 0xff;
1256 cmd[11] = crc >> 8;
1257
8c6cca0b 1258 CodeIso15693AsTag(cmd, sizeof(cmd));
9455b51c 1259}
1260
e6304bca 1261// Universal Method for sending to and recv bytes from a tag
9455b51c 1262// init ... should we initialize the reader?
8c6cca0b 1263// speed ... 0 low speed, 1 hi speed
d9de20fa 1264// *recv will contain the tag's answer
9455b51c 1265// return: lenght of received data
d9de20fa 1266int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *recv, uint16_t max_recv_len, uint32_t start_time) {
9455b51c 1267
9455b51c 1268 LED_A_ON();
70b2fc0a 1269 LED_B_OFF();
9455b51c 1270 LED_C_OFF();
8c6cca0b 1271
09ffd16e 1272 if (init) Iso15693InitReader();
1273
9455b51c 1274 int answerLen=0;
9455b51c 1275
9455b51c 1276 if (!speed) {
1277 // low speed (1 out of 256)
1278 CodeIso15693AsReader256(send, sendlen);
1279 } else {
1280 // high speed (1 out of 4)
1281 CodeIso15693AsReader(send, sendlen);
1282 }
8c6cca0b 1283
d9de20fa 1284 TransmitTo15693Tag(ToSend, ToSendMax, start_time);
1285
9455b51c 1286 // Now wait for a response
d9de20fa 1287 if (recv != NULL) {
1288 answerLen = GetIso15693AnswerFromTag(recv, max_recv_len, DELAY_ISO15693_VCD_TO_VICC * 2);
9455b51c 1289 }
1290
1291 LED_A_OFF();
8c6cca0b 1292
9455b51c 1293 return answerLen;
1294}
15c4dc5a 1295
15c4dc5a 1296
9455b51c 1297// --------------------------------------------------------------------
8c6cca0b 1298// Debug Functions
9455b51c 1299// --------------------------------------------------------------------
15c4dc5a 1300
9455b51c 1301// Decodes a message from a tag and displays its metadata and content
1302#define DBD15STATLEN 48
1303void DbdecodeIso15693Answer(int len, uint8_t *d) {
1304 char status[DBD15STATLEN+1]={0};
1305 uint16_t crc;
1306
d9de20fa 1307 if (len > 3) {
1308 if (d[0] & ISO15693_RES_EXT)
1309 strncat(status,"ProtExt ", DBD15STATLEN);
1310 if (d[0] & ISO15693_RES_ERROR) {
9455b51c 1311 // error
d9de20fa 1312 strncat(status,"Error ", DBD15STATLEN);
9455b51c 1313 switch (d[1]) {
8c6cca0b 1314 case 0x01:
d9de20fa 1315 strncat(status,"01:notSupp", DBD15STATLEN);
15c4dc5a 1316 break;
8c6cca0b 1317 case 0x02:
d9de20fa 1318 strncat(status,"02:notRecog", DBD15STATLEN);
9455b51c 1319 break;
8c6cca0b 1320 case 0x03:
d9de20fa 1321 strncat(status,"03:optNotSupp", DBD15STATLEN);
9455b51c 1322 break;
8c6cca0b 1323 case 0x0f:
d9de20fa 1324 strncat(status,"0f:noInfo", DBD15STATLEN);
9455b51c 1325 break;
8c6cca0b 1326 case 0x10:
d9de20fa 1327 strncat(status,"10:doesn'tExist", DBD15STATLEN);
9455b51c 1328 break;
8c6cca0b 1329 case 0x11:
d9de20fa 1330 strncat(status,"11:lockAgain", DBD15STATLEN);
9455b51c 1331 break;
8c6cca0b 1332 case 0x12:
d9de20fa 1333 strncat(status,"12:locked", DBD15STATLEN);
9455b51c 1334 break;
8c6cca0b 1335 case 0x13:
d9de20fa 1336 strncat(status,"13:progErr", DBD15STATLEN);
9455b51c 1337 break;
8c6cca0b 1338 case 0x14:
d9de20fa 1339 strncat(status,"14:lockErr", DBD15STATLEN);
9455b51c 1340 break;
1341 default:
d9de20fa 1342 strncat(status,"unknownErr", DBD15STATLEN);
15c4dc5a 1343 }
d9de20fa 1344 strncat(status," ", DBD15STATLEN);
9455b51c 1345 } else {
d9de20fa 1346 strncat(status,"NoErr ", DBD15STATLEN);
15c4dc5a 1347 }
8c6cca0b 1348
9455b51c 1349 crc=Crc(d,len-2);
8c6cca0b 1350 if ( (( crc & 0xff ) == d[len-2]) && (( crc >> 8 ) == d[len-1]) )
9455b51c 1351 strncat(status,"CrcOK",DBD15STATLEN);
1352 else
8c6cca0b 1353 strncat(status,"CrcFail!",DBD15STATLEN);
9455b51c 1354
1355 Dbprintf("%s",status);
15c4dc5a 1356 }
1357}
1358
9455b51c 1359
1360
1361///////////////////////////////////////////////////////////////////////
1362// Functions called via USB/Client
1363///////////////////////////////////////////////////////////////////////
1364
1365void SetDebugIso15693(uint32_t debug) {
1366 DEBUG=debug;
1367 Dbprintf("Iso15693 Debug is now %s",DEBUG?"on":"off");
1368 return;
1369}
1370
d9de20fa 1371
15c4dc5a 1372//-----------------------------------------------------------------------------
1373// Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector
1374// all demodulation performed in arm rather than host. - greg
1375//-----------------------------------------------------------------------------
f7e3ed82 1376void ReaderIso15693(uint32_t parameter)
15c4dc5a 1377{
70b2fc0a 1378 LEDsoff();
15c4dc5a 1379 LED_A_ON();
15c4dc5a 1380
d9de20fa 1381 set_tracing(true);
1382
1383 int answerLen = 0;
3fe4ff4f 1384 uint8_t TagUID[8] = {0x00};
1385
09ffd16e 1386 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1387
d9de20fa 1388 uint8_t answer[ISO15693_MAX_RESPONSE_LENGTH];
15c4dc5a 1389
3fe4ff4f 1390 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
15c4dc5a 1391 // Setup SSC
6a5d4e17 1392 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
15c4dc5a 1393
1394 // Start from off (no field generated)
09ffd16e 1395 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1396 SpinDelay(200);
15c4dc5a 1397
15c4dc5a 1398 // Give the tags time to energize
70b2fc0a 1399 LED_D_ON();
15c4dc5a 1400 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
1401 SpinDelay(200);
d9de20fa 1402 StartCountSspClk();
1403
15c4dc5a 1404
15c4dc5a 1405 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
1406 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
15c4dc5a 1407
1408 // Now send the IDENTIFY command
1409 BuildIdentifyRequest();
d9de20fa 1410 TransmitTo15693Tag(ToSend, ToSendMax, 0);
8c6cca0b 1411
15c4dc5a 1412 // Now wait for a response
d9de20fa 1413 answerLen = GetIso15693AnswerFromTag(answer, sizeof(answer), DELAY_ISO15693_VCD_TO_VICC * 2) ;
1414 uint32_t start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD;
15c4dc5a 1415
d9de20fa 1416 if (answerLen >=12) // we should do a better check than this
15c4dc5a 1417 {
d9de20fa 1418 TagUID[0] = answer[2];
1419 TagUID[1] = answer[3];
1420 TagUID[2] = answer[4];
1421 TagUID[3] = answer[5];
1422 TagUID[4] = answer[6];
1423 TagUID[5] = answer[7];
1424 TagUID[6] = answer[8]; // IC Manufacturer code
1425 TagUID[7] = answer[9]; // always E0
15c4dc5a 1426
15c4dc5a 1427 }
1428
d9de20fa 1429 Dbprintf("%d octets read from IDENTIFY request:", answerLen);
1430 DbdecodeIso15693Answer(answerLen, answer);
1431 Dbhexdump(answerLen, answer, false);
9455b51c 1432
1433 // UID is reverse
d9de20fa 1434 if (answerLen >= 12)
3fe4ff4f 1435 Dbprintf("UID = %02hX%02hX%02hX%02hX%02hX%02hX%02hX%02hX",
1436 TagUID[7],TagUID[6],TagUID[5],TagUID[4],
1437 TagUID[3],TagUID[2],TagUID[1],TagUID[0]);
9455b51c 1438
1439
315e18e6 1440 // Dbprintf("%d octets read from SELECT request:", answerLen2);
1441 // DbdecodeIso15693Answer(answerLen2,answer2);
1442 // Dbhexdump(answerLen2,answer2,true);
9455b51c 1443
315e18e6 1444 // Dbprintf("%d octets read from XXX request:", answerLen3);
1445 // DbdecodeIso15693Answer(answerLen3,answer3);
1446 // Dbhexdump(answerLen3,answer3,true);
9455b51c 1447
9455b51c 1448 // read all pages
d9de20fa 1449 if (answerLen >= 12 && DEBUG) {
1450
1451 // debugptr = BigBuf_get_addr();
1452
8c6cca0b 1453 int i = 0;
1454 while (i < 32) { // sanity check, assume max 32 pages
1455 BuildReadBlockRequest(TagUID, i);
d9de20fa 1456 TransmitTo15693Tag(ToSend, ToSendMax, start_time);
1457 int answerLen = GetIso15693AnswerFromTag(answer, sizeof(answer), DELAY_ISO15693_VCD_TO_VICC * 2);
1458 start_time = GetCountSspClk() + DELAY_ISO15693_VICC_TO_VCD;
1459 if (answerLen > 0) {
1460 Dbprintf("READ SINGLE BLOCK %d returned %d octets:", i, answerLen);
1461 DbdecodeIso15693Answer(answerLen, answer);
1462 Dbhexdump(answerLen, answer, false);
1463 if ( *((uint32_t*) answer) == 0x07160101 ) break; // exit on NoPageErr
8c6cca0b 1464 }
9455b51c 1465 i++;
8c6cca0b 1466 }
9455b51c 1467 }
15c4dc5a 1468
8c6cca0b 1469 // for the time being, switch field off to protect rdv4.0
70b2fc0a 1470 // note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
1471 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
15c4dc5a 1472 LED_D_OFF();
8c6cca0b 1473
70b2fc0a 1474 LED_A_OFF();
15c4dc5a 1475}
1476
8c6cca0b 1477
1478// Simulate an ISO15693 TAG.
1479// For Inventory command: print command and send Inventory Response with given UID
1480// TODO: interpret other reader commands and send appropriate response
3fe4ff4f 1481void SimTagIso15693(uint32_t parameter, uint8_t *uid)
15c4dc5a 1482{
70b2fc0a 1483 LEDsoff();
15c4dc5a 1484 LED_A_ON();
15c4dc5a 1485
7cc204bf 1486 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1487 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
8c6cca0b 1488 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
1489 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
15c4dc5a 1490
8c6cca0b 1491 StartCountSspClk();
15c4dc5a 1492
8c6cca0b 1493 uint8_t cmd[ISO15693_MAX_COMMAND_LENGTH];
15c4dc5a 1494
8c6cca0b 1495 // Build a suitable response to the reader INVENTORY command
1496 BuildInventoryResponse(uid);
15c4dc5a 1497
8c6cca0b 1498 // Listen to reader
1499 while (!BUTTON_PRESS()) {
1500 uint32_t eof_time = 0, start_time = 0;
1501 int cmd_len = GetIso15693CommandFromReader(cmd, sizeof(cmd), &eof_time);
1502
1503 if ((cmd_len >= 5) && (cmd[0] & ISO15693_REQ_INVENTORY) && (cmd[1] == ISO15693_INVENTORY)) { // TODO: check more flags
1504 bool slow = !(cmd[0] & ISO15693_REQ_DATARATE_HIGH);
1505 start_time = eof_time + DELAY_ISO15693_VCD_TO_VICC - DELAY_ARM_TO_READER;
1506 TransmitTo15693Reader(ToSend, ToSendMax, start_time, slow);
1507 }
3fe4ff4f 1508
8c6cca0b 1509 Dbprintf("%d bytes read from reader:", cmd_len);
1510 Dbhexdump(cmd_len, cmd, false);
1511 }
15c4dc5a 1512
70b2fc0a 1513 LEDsoff();
15c4dc5a 1514}
9455b51c 1515
1516
1517// Since there is no standardized way of reading the AFI out of a tag, we will brute force it
1518// (some manufactures offer a way to read the AFI, though)
8c6cca0b 1519void BruteforceIso15693Afi(uint32_t speed)
1520{
70b2fc0a 1521 LEDsoff();
1522 LED_A_ON();
8c6cca0b 1523
d9de20fa 1524 uint8_t data[6];
1525 uint8_t recv[ISO15693_MAX_RESPONSE_LENGTH];
1526
9455b51c 1527 int datalen=0, recvlen=0;
8c6cca0b 1528
9455b51c 1529 Iso15693InitReader();
d9de20fa 1530 StartCountSspClk();
1531
9455b51c 1532 // first without AFI
8c6cca0b 1533 // Tags should respond without AFI and with AFI=0 even when AFI is active
1534
1535 data[0] = ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_INVENTORY | ISO15693_REQINV_SLOT1;
1536 data[1] = ISO15693_INVENTORY;
1537 data[2] = 0; // mask length
1538 datalen = AddCrc(data,3);
d9de20fa 1539 recvlen = SendDataTag(data, datalen, false, speed, recv, sizeof(recv), 0);
1540 uint32_t start_time = GetCountSspClk() + DELAY_ISO15693_VCD_TO_VICC;
9455b51c 1541 WDT_HIT();
1542 if (recvlen>=12) {
d9de20fa 1543 Dbprintf("NoAFI UID=%s", sprintUID(NULL, &recv[2]));
9455b51c 1544 }
8c6cca0b 1545
9455b51c 1546 // now with AFI
8c6cca0b 1547
1548 data[0] = ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_INVENTORY | ISO15693_REQINV_AFI | ISO15693_REQINV_SLOT1;
1549 data[1] = ISO15693_INVENTORY;
1550 data[2] = 0; // AFI
1551 data[3] = 0; // mask length
1552
d9de20fa 1553 for (int i = 0; i < 256; i++) {
1554 data[2] = i & 0xFF;
1555 datalen = AddCrc(data,4);
1556 recvlen = SendDataTag(data, datalen, false, speed, recv, sizeof(recv), start_time);
1557 start_time = GetCountSspClk() + DELAY_ISO15693_VCD_TO_VICC;
9455b51c 1558 WDT_HIT();
d9de20fa 1559 if (recvlen >= 12) {
1560 Dbprintf("AFI=%i UID=%s", i, sprintUID(NULL, &recv[2]));
9455b51c 1561 }
8c6cca0b 1562 }
9455b51c 1563 Dbprintf("AFI Bruteforcing done.");
8c6cca0b 1564
70b2fc0a 1565 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1566 LEDsoff();
9455b51c 1567}
1568
1569// Allows to directly send commands to the tag via the client
70b2fc0a 1570void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t data[]) {
9455b51c 1571
d9de20fa 1572 int recvlen = 0;
1573 uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
8c6cca0b 1574
70b2fc0a 1575 LED_A_ON();
8c6cca0b 1576
9455b51c 1577 if (DEBUG) {
d9de20fa 1578 Dbprintf("SEND:");
8c6cca0b 1579 Dbhexdump(datalen, data, false);
9455b51c 1580 }
8c6cca0b 1581
d9de20fa 1582 recvlen = SendDataTag(data, datalen, true, speed, (recv?recvbuf:NULL), sizeof(recvbuf), 0);
9455b51c 1583
8c6cca0b 1584 if (recv) {
9455b51c 1585 if (DEBUG) {
d9de20fa 1586 Dbprintf("RECV:");
8c6cca0b 1587 Dbhexdump(recvlen, recvbuf, false);
d9de20fa 1588 DbdecodeIso15693Answer(recvlen, recvbuf);
9455b51c 1589 }
d9de20fa 1590
1591 cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
1592
9455b51c 1593 }
1594
8c6cca0b 1595 // for the time being, switch field off to protect rdv4.0
70b2fc0a 1596 // note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
1597 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1598 LED_D_OFF();
8c6cca0b 1599
70b2fc0a 1600 LED_A_OFF();
9455b51c 1601}
1602
1603
1604
1605
1606// --------------------------------------------------------------------
1607// -- Misc & deprecated functions
1608// --------------------------------------------------------------------
1609
e6304bca 1610/*
9455b51c 1611
1612// do not use; has a fix UID
1613static void __attribute__((unused)) BuildSysInfoRequest(uint8_t *uid)
1614{
1615 uint8_t cmd[12];
1616
1617 uint16_t crc;
1618 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1619 // followed by teh block data
1620 // one sub-carrier, inventory, 1 slot, fast rate
1621 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1622 // System Information command code
1623 cmd[1] = 0x2B;
1624 // UID may be optionally specified here
1625 // 64-bit UID
1626 cmd[2] = 0x32;
1627 cmd[3]= 0x4b;
1628 cmd[4] = 0x03;
1629 cmd[5] = 0x01;
1630 cmd[6] = 0x00;
1631 cmd[7] = 0x10;
1632 cmd[8] = 0x05;
1633 cmd[9]= 0xe0; // always e0 (not exactly unique)
1634 //Now the CRC
1635 crc = Crc(cmd, 10); // the crc needs to be calculated over 2 bytes
1636 cmd[10] = crc & 0xff;
1637 cmd[11] = crc >> 8;
1638
1639 CodeIso15693AsReader(cmd, sizeof(cmd));
1640}
1641
9455b51c 1642
1643// do not use; has a fix UID
1644static void __attribute__((unused)) BuildReadMultiBlockRequest(uint8_t *uid)
1645{
1646 uint8_t cmd[14];
1647
1648 uint16_t crc;
1649 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1650 // followed by teh block data
1651 // one sub-carrier, inventory, 1 slot, fast rate
1652 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1653 // READ Multi BLOCK command code
1654 cmd[1] = 0x23;
1655 // UID may be optionally specified here
1656 // 64-bit UID
1657 cmd[2] = 0x32;
1658 cmd[3]= 0x4b;
1659 cmd[4] = 0x03;
1660 cmd[5] = 0x01;
1661 cmd[6] = 0x00;
1662 cmd[7] = 0x10;
1663 cmd[8] = 0x05;
1664 cmd[9]= 0xe0; // always e0 (not exactly unique)
1665 // First Block number to read
1666 cmd[10] = 0x00;
1667 // Number of Blocks to read
1668 cmd[11] = 0x2f; // read quite a few
1669 //Now the CRC
1670 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1671 cmd[12] = crc & 0xff;
1672 cmd[13] = crc >> 8;
1673
1674 CodeIso15693AsReader(cmd, sizeof(cmd));
1675}
1676
1677// do not use; has a fix UID
1678static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t CmdCode)
1679{
1680 uint8_t cmd[14];
1681
1682 uint16_t crc;
1683 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1684 // followed by teh block data
1685 // one sub-carrier, inventory, 1 slot, fast rate
1686 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1687 // READ BLOCK command code
1688 cmd[1] = CmdCode;
1689 // UID may be optionally specified here
1690 // 64-bit UID
1691 cmd[2] = 0x32;
1692 cmd[3]= 0x4b;
1693 cmd[4] = 0x03;
1694 cmd[5] = 0x01;
1695 cmd[6] = 0x00;
1696 cmd[7] = 0x10;
1697 cmd[8] = 0x05;
1698 cmd[9]= 0xe0; // always e0 (not exactly unique)
1699 // Parameter
1700 cmd[10] = 0x00;
1701 cmd[11] = 0x0a;
1702
1703// cmd[12] = 0x00;
1704// cmd[13] = 0x00; //Now the CRC
1705 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1706 cmd[12] = crc & 0xff;
1707 cmd[13] = crc >> 8;
1708
1709 CodeIso15693AsReader(cmd, sizeof(cmd));
1710}
1711
1712// do not use; has a fix UID
1713static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], uint8_t CmdCode)
1714{
1715 uint8_t cmd[14];
1716
1717 uint16_t crc;
1718 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1719 // followed by teh block data
1720 // one sub-carrier, inventory, 1 slot, fast rate
1721 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1722 // READ BLOCK command code
1723 cmd[1] = CmdCode;
1724 // UID may be optionally specified here
1725 // 64-bit UID
1726 cmd[2] = 0x32;
1727 cmd[3]= 0x4b;
1728 cmd[4] = 0x03;
1729 cmd[5] = 0x01;
1730 cmd[6] = 0x00;
1731 cmd[7] = 0x10;
1732 cmd[8] = 0x05;
1733 cmd[9]= 0xe0; // always e0 (not exactly unique)
1734 // Parameter
1735 cmd[10] = 0x05; // for custom codes this must be manufcturer code
1736 cmd[11] = 0x00;
1737
1738// cmd[12] = 0x00;
1739// cmd[13] = 0x00; //Now the CRC
1740 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1741 cmd[12] = crc & 0xff;
1742 cmd[13] = crc >> 8;
1743
1744 CodeIso15693AsReader(cmd, sizeof(cmd));
1745}
1746
1747
1748
1749
e6304bca 1750*/
9455b51c 1751
1752
Impressum, Datenschutz