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