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