]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso15693.c
deploy in msys2 and proxspace (#702)
[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
bd20f8f4 5//
6// This code is licensed to you under the terms of the GNU GPL, version 2 or,
7// at your option, any later version. See the LICENSE.txt file for the text of
8// the license.
9//-----------------------------------------------------------------------------
15c4dc5a 10// Routines to support ISO 15693. This includes both the reader software and
11// the `fake tag' modes, but at the moment I've implemented only the reader
12// stuff, and that barely.
bd20f8f4 13// Modified to perform modulation onboard in arm rather than on PC
15c4dc5a 14// Also added additional reader commands (SELECT, READ etc.)
15c4dc5a 15//-----------------------------------------------------------------------------
9455b51c 16// The ISO 15693 describes two transmission modes from reader to tag, and 4
17// transmission modes from tag to reader. As of Mar 2010 this code only
18// supports one of each: "1of4" mode from reader to tag, and the highspeed
19// variant with one subcarrier from card to reader.
20// As long, as the card fully support ISO 15693 this is no problem, since the
21// reader chooses both data rates, but some non-standard tags do not. Further for
22// the simulation to work, we will need to support all data rates.
23//
24// VCD (reader) -> VICC (tag)
25// 1 out of 256:
26// data rate: 1,66 kbit/s (fc/8192)
27// used for long range
28// 1 out of 4:
29// data rate: 26,48 kbit/s (fc/512)
30// used for short range, high speed
31//
32// VICC (tag) -> VCD (reader)
33// Modulation:
34// ASK / one subcarrier (423,75 khz)
35// FSK / two subcarriers (423,75 khz && 484,28 khz)
36// Data Rates / Modes:
37// low ASK: 6,62 kbit/s
38// low FSK: 6.67 kbit/s
39// high ASK: 26,48 kbit/s
40// high FSK: 26,69 kbit/s
41//-----------------------------------------------------------------------------
42// added "1 out of 256" mode (for VCD->PICC) - atrox 20100911
43
44
45// Random Remarks:
46// *) UID is always used "transmission order" (LSB), which is reverse to display order
47
48// TODO / BUGS / ISSUES:
49// *) writing to tags takes longer: we miss the answer from the tag in most cases
50// -> tweak the read-timeout times
51// *) signal decoding from the card is still a bit shaky.
52// *) signal decoding is unable to detect collissions.
53// *) add anti-collission support for inventory-commands
e6304bca 54// *) read security status of a block
9455b51c 55// *) sniffing and simulation do only support one transmission mode. need to support
56// all 8 transmission combinations
57// *) remove or refactor code under "depricated"
58// *) document all the functions
59
bd20f8f4 60
e30c654b 61#include "proxmark3.h"
f7e3ed82 62#include "util.h"
15c4dc5a 63#include "apps.h"
9ab7a6c7 64#include "string.h"
9455b51c 65#include "iso15693tools.h"
902cb3c0 66#include "cmd.h"
15c4dc5a 67
15c4dc5a 68#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
69
70b2fc0a 70static int DEBUG = 0;
71
9455b51c 72///////////////////////////////////////////////////////////////////////
73// ISO 15693 Part 2 - Air Interface
74// This section basicly contains transmission and receiving of bits
75///////////////////////////////////////////////////////////////////////
76
77#define FrameSOF Iso15693FrameSOF
78#define Logic0 Iso15693Logic0
79#define Logic1 Iso15693Logic1
80#define FrameEOF Iso15693FrameEOF
15c4dc5a 81
9455b51c 82#define Crc(data,datalen) Iso15693Crc(data,datalen)
83#define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
84#define sprintUID(target,uid) Iso15693sprintUID(target,uid)
15c4dc5a 85
315e18e6 86// approximate amplitude=sqrt(ci^2+cq^2)
70b2fc0a 87#define AMPLITUDE(ci, cq) (MAX(ABS(ci), ABS(cq)) + MIN(ABS(ci), ABS(cq))/2)
9455b51c 88
70b2fc0a 89// DMA buffer
90#define ISO15693_DMA_BUFFER_SIZE 128
9455b51c 91
92// ---------------------------
93// Signal Processing
94// ---------------------------
95
96// prepare data using "1 out of 4" code for later transmission
97// resulting data rate is 26,48 kbit/s (fc/512)
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 }
70b2fc0a 177
178 ToSendMax++;
15c4dc5a 179}
180
70b2fc0a 181// encode data using "1 out of 256" scheme
9455b51c 182// data rate is 1,66 kbit/s (fc/8192)
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);
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);
213 }
214 }
15c4dc5a 215 }
9455b51c 216 // EOF
217 ToSendStuffBit(1);
218 ToSendStuffBit(1);
219 ToSendStuffBit(0);
220 ToSendStuffBit(1);
15c4dc5a 221
9455b51c 222 // And slack at the end, too.
223 for(i = 0; i < 24; i++) {
224 ToSendStuffBit(1);
225 }
15c4dc5a 226}
227
9455b51c 228
70b2fc0a 229// Transmit the command (to the tag) that was placed in cmd[].
230static void TransmitTo15693Tag(const uint8_t *cmd, int len)
15c4dc5a 231{
6a5d4e17 232 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
15c4dc5a 233 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
15c4dc5a 234
70b2fc0a 235 LED_B_ON();
236 for(int c = 0; c < len; ) {
15c4dc5a 237 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
6a5d4e17 238 AT91C_BASE_SSC->SSC_THR = ~cmd[c];
15c4dc5a 239 c++;
15c4dc5a 240 }
241 WDT_HIT();
242 }
70b2fc0a 243 LED_B_OFF();
15c4dc5a 244}
245
246//-----------------------------------------------------------------------------
70b2fc0a 247// Transmit the command (to the reader) that was placed in cmd[].
15c4dc5a 248//-----------------------------------------------------------------------------
70b2fc0a 249static void TransmitTo15693Reader(const uint8_t *cmd, int len)
15c4dc5a 250{
70b2fc0a 251 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K);
15c4dc5a 252
70b2fc0a 253 LED_C_ON();
254 for(int c = 0; c < len; ) {
15c4dc5a 255 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
256 AT91C_BASE_SSC->SSC_THR = cmd[c];
257 c++;
15c4dc5a 258 }
259 WDT_HIT();
260 }
70b2fc0a 261 LED_C_OFF();
15c4dc5a 262}
263
9455b51c 264
70b2fc0a 265//=============================================================================
266// An ISO 15693 demodulator (one subcarrier only). Uses cross correlation to
267// identify the SOF, each bit, and EOF.
268// This function is called 8 times per bit (every 2 subcarrier cycles).
269// Subcarrier frequency fs is 424kHz, 1/fs = 2,36us,
270// i.e. function is called every 4,72us
271// LED handling:
272// LED C -> ON once we have received the SOF and are expecting the rest.
273// LED C -> OFF once we have received EOF or are unsynced
274//
275// Returns: true if we received a EOF
276// false if we are still waiting for some more
277//=============================================================================
278
279#define SUBCARRIER_DETECT_THRESHOLD 2
280#define SOF_CORRELATOR_LEN (1<<5)
281
282typedef struct Demod {
283 enum {
284 DEMOD_UNSYNCD,
285 DEMOD_AWAIT_SOF_1,
286 DEMOD_AWAIT_SOF_2,
287 DEMOD_RECEIVING_DATA,
288 DEMOD_AWAIT_EOF
289 } state;
290 int bitCount;
291 int posCount;
292 enum {
293 LOGIC0,
294 LOGIC1,
295 SOF_PART1,
296 SOF_PART2
297 } lastBit;
298 uint16_t shiftReg;
299 uint8_t *output;
300 int len;
301 int sum1, sum2;
302 uint8_t SOF_low;
303 uint8_t SOF_high;
304 uint8_t SOF_last;
305 int32_t SOF_corr;
306 int32_t SOF_corr_prev;
307 uint8_t SOF_correlator[SOF_CORRELATOR_LEN];
308} Demod_t;
309
310static RAMFUNC int Handle15693SamplesDemod(int8_t ci, int8_t cq, Demod_t *Demod)
15c4dc5a 311{
70b2fc0a 312 switch(Demod->state) {
313 case DEMOD_UNSYNCD:
314 // initialize SOF correlator. We are looking for 12 samples low and 12 samples high.
315 Demod->SOF_low = 0;
316 Demod->SOF_high = 12;
317 Demod->SOF_last = 23;
318 memset(Demod->SOF_correlator, 0x00, Demod->SOF_last + 1);
319 Demod->SOF_correlator[Demod->SOF_last] = AMPLITUDE(ci,cq);
320 Demod->SOF_corr = Demod->SOF_correlator[Demod->SOF_last];
321 Demod->SOF_corr_prev = Demod->SOF_corr;
322 // initialize Demodulator
323 Demod->posCount = 0;
324 Demod->bitCount = 0;
325 Demod->len = 0;
326 Demod->state = DEMOD_AWAIT_SOF_1;
327 break;
6a5d4e17 328
70b2fc0a 329 case DEMOD_AWAIT_SOF_1:
330 // calculate the correlation in real time. Look at differences only.
331 Demod->SOF_corr += Demod->SOF_correlator[Demod->SOF_low++];
332 Demod->SOF_corr -= 2*Demod->SOF_correlator[Demod->SOF_high++];
333 Demod->SOF_last++;
334 Demod->SOF_low &= (SOF_CORRELATOR_LEN-1);
335 Demod->SOF_high &= (SOF_CORRELATOR_LEN-1);
336 Demod->SOF_last &= (SOF_CORRELATOR_LEN-1);
337 Demod->SOF_correlator[Demod->SOF_last] = AMPLITUDE(ci,cq);
338 Demod->SOF_corr += Demod->SOF_correlator[Demod->SOF_last];
339
340 // if correlation increases for 10 consecutive samples, we are close to maximum correlation
341 if (Demod->SOF_corr > Demod->SOF_corr_prev + SUBCARRIER_DETECT_THRESHOLD) {
342 Demod->posCount++;
343 } else {
344 Demod->posCount = 0;
15c4dc5a 345 }
15c4dc5a 346
70b2fc0a 347 if (Demod->posCount == 10) { // correlation increased 10 times
348 Demod->state = DEMOD_AWAIT_SOF_2;
349 }
350
351 Demod->SOF_corr_prev = Demod->SOF_corr;
352
353 break;
354
355 case DEMOD_AWAIT_SOF_2:
356 // calculate the correlation in real time. Look at differences only.
357 Demod->SOF_corr += Demod->SOF_correlator[Demod->SOF_low++];
358 Demod->SOF_corr -= 2*Demod->SOF_correlator[Demod->SOF_high++];
359 Demod->SOF_last++;
360 Demod->SOF_low &= (SOF_CORRELATOR_LEN-1);
361 Demod->SOF_high &= (SOF_CORRELATOR_LEN-1);
362 Demod->SOF_last &= (SOF_CORRELATOR_LEN-1);
363 Demod->SOF_correlator[Demod->SOF_last] = AMPLITUDE(ci,cq);
364 Demod->SOF_corr += Demod->SOF_correlator[Demod->SOF_last];
365
366 if (Demod->SOF_corr >= Demod->SOF_corr_prev) { // we are looking for the maximum correlation
367 Demod->SOF_corr_prev = Demod->SOF_corr;
368 } else {
369 Demod->lastBit = SOF_PART1; // detected 1st part of SOF
370 Demod->sum1 = Demod->SOF_correlator[Demod->SOF_last];
371 Demod->sum2 = 0;
372 Demod->posCount = 2;
373 Demod->state = DEMOD_RECEIVING_DATA;
374 LED_C_ON();
375 }
376
377 break;
15c4dc5a 378
70b2fc0a 379 case DEMOD_RECEIVING_DATA:
380 if (Demod->posCount == 1) {
381 Demod->sum1 = 0;
382 Demod->sum2 = 0;
383 }
15c4dc5a 384
70b2fc0a 385 if (Demod->posCount <= 4) {
386 Demod->sum1 += AMPLITUDE(ci, cq);
387 } else {
388 Demod->sum2 += AMPLITUDE(ci, cq);
389 }
15c4dc5a 390
70b2fc0a 391 if (Demod->posCount == 8) {
392 int16_t corr_1 = (Demod->sum2 - Demod->sum1) / 4;
393 int16_t corr_0 = (Demod->sum1 - Demod->sum2) / 4;
394 int16_t corr_EOF = (Demod->sum1 + Demod->sum2) / 8;
395 if (corr_EOF > corr_0 && corr_EOF > corr_1) {
396 Demod->state = DEMOD_AWAIT_EOF;
397 } else if (corr_1 > corr_0) {
398 // logic 1
399 if (Demod->lastBit == SOF_PART1) { // still part of SOF
400 Demod->lastBit = SOF_PART2;
401 } else {
402 Demod->lastBit = LOGIC1;
403 Demod->shiftReg >>= 1;
404 Demod->shiftReg |= 0x80;
405 Demod->bitCount++;
406 if (Demod->bitCount == 8) {
407 Demod->output[Demod->len] = Demod->shiftReg;
408 Demod->len++;
409 Demod->bitCount = 0;
410 Demod->shiftReg = 0;
411 }
412 }
413 } else {
414 // logic 0
415 if (Demod->lastBit == SOF_PART1) { // incomplete SOF
416 Demod->state = DEMOD_UNSYNCD;
417 LED_C_OFF();
418 } else {
419 Demod->lastBit = LOGIC0;
420 Demod->shiftReg >>= 1;
421 Demod->bitCount++;
422 if (Demod->bitCount == 8) {
423 Demod->output[Demod->len] = Demod->shiftReg;
424 Demod->len++;
425 Demod->bitCount = 0;
426 Demod->shiftReg = 0;
427 }
428 }
429 }
430 Demod->posCount = 0;
431 }
432 Demod->posCount++;
433 break;
434
435 case DEMOD_AWAIT_EOF:
436 if (Demod->lastBit == LOGIC0) { // this was already part of EOF
437 LED_C_OFF();
438 return true;
439 } else {
440 Demod->state = DEMOD_UNSYNCD;
441 LED_C_OFF();
442 }
443 break;
444
445 default:
446 Demod->state = DEMOD_UNSYNCD;
447 LED_C_OFF();
448 break;
15c4dc5a 449 }
15c4dc5a 450
70b2fc0a 451 return false;
452}
15c4dc5a 453
15c4dc5a 454
70b2fc0a 455static void DemodInit(Demod_t* Demod, uint8_t* data)
456{
457 Demod->output = data;
458 Demod->state = DEMOD_UNSYNCD;
459}
460
461
462/*
463 * Demodulate the samples we received from the tag, also log to tracebuffer
464 */
465static int GetIso15693AnswerFromTag(uint8_t* response, int timeout)
466{
467 int maxBehindBy = 0;
468 int lastRxCounter, samples = 0;
469 int8_t ci, cq;
470 bool gotFrame = false;
9455b51c 471
70b2fc0a 472 // Allocate memory from BigBuf for some buffers
473 // free all previous allocations first
474 BigBuf_free();
475
476 // The DMA buffer, used to stream samples from the FPGA
477 uint16_t* dmaBuf = (uint16_t*) BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE * sizeof(uint16_t));
478
479 // the Demodulatur data structure
480 Demod_t* Demod = (Demod_t*) BigBuf_malloc(sizeof(Demod_t));
9455b51c 481
70b2fc0a 482 // Set up the demodulator for tag -> reader responses.
483 DemodInit(Demod, response);
484
485 // wait for last transfer to complete
486 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
487
488 // And put the FPGA in the appropriate mode
489 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
490
491 // Setup and start DMA.
492 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
493 FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
494
495 uint16_t *upTo = dmaBuf;
496 lastRxCounter = ISO15693_DMA_BUFFER_SIZE;
497
498 for(;;) {
499 int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO15693_DMA_BUFFER_SIZE-1);
500 if(behindBy > maxBehindBy) {
501 maxBehindBy = behindBy;
15c4dc5a 502 }
70b2fc0a 503
504 if (behindBy < 1) continue;
505
506 ci = (int8_t)(*upTo >> 8);
507 cq = (int8_t)(*upTo & 0xff);
508
509 upTo++;
510 lastRxCounter--;
511 if(upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
512 upTo = dmaBuf; // start reading the circular buffer from the beginning
513 lastRxCounter += ISO15693_DMA_BUFFER_SIZE;
15c4dc5a 514 }
70b2fc0a 515 if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated.
516 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and
517 AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers
15c4dc5a 518 }
70b2fc0a 519 samples++;
15c4dc5a 520
70b2fc0a 521 if (Handle15693SamplesDemod(ci, cq, Demod)) {
522 gotFrame = true;
523 break;
524 }
15c4dc5a 525
70b2fc0a 526 if(samples > timeout && Demod->state < DEMOD_RECEIVING_DATA) {
527 Demod->len = 0;
528 break;
529 }
530 }
531
532 FpgaDisableSscDma();
533
534 if (DEBUG) Dbprintf("max behindby = %d, samples = %d, gotFrame = %d, Demod.state = %d, Demod.len = %d, Demod.bitCount = %d, Demod.posCount = %d",
535 maxBehindBy, samples, gotFrame, Demod->state, Demod->len, Demod->bitCount, Demod->posCount);
536
537 if (tracing && Demod->len > 0) {
538 uint8_t parity[MAX_PARITY_SIZE];
539 LogTrace(Demod->output, Demod->len, 0, 0, parity, false);
540 }
541
542 return Demod->len;
15c4dc5a 543}
544
9455b51c 545
15c4dc5a 546// Now the GetISO15693 message from sniffing command
70b2fc0a 547// TODO: fix it. This cannot work for several reasons:
548// 1. Carrier is switched on during sniffing?
549// 2. We most probable miss the next reader command when demodulating
f7e3ed82 550static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
15c4dc5a 551{
117d9ec2 552 uint8_t *dest = BigBuf_get_addr();
15c4dc5a 553
554// NOW READ RESPONSE
70b2fc0a 555 LED_D_ON();
15c4dc5a 556 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
557 //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
70b2fc0a 558 for(int c = 0; c < BIGBUF_SIZE; ) {
15c4dc5a 559 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
6a5d4e17 560 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
15c4dc5a 561 // The samples are correlations against I and Q versions of the
6a5d4e17 562 // tone that the tag AM-modulates. We just want power,
563 // so abs(I) + abs(Q) is close to what we want.
70b2fc0a 564 int8_t i = (int8_t)(iq >> 8);
565 int8_t q = (int8_t)(iq & 0xff);
6a5d4e17 566 uint8_t r = AMPLITUDE(i, q);
6a5d4e17 567 dest[c++] = r;
15c4dc5a 568 }
569 }
70b2fc0a 570 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
571 LED_D_OFF();
15c4dc5a 572
9455b51c 573 //////////////////////////////////////////
574 /////////// DEMODULATE ///////////////////
575 //////////////////////////////////////////
15c4dc5a 576
577 int i, j;
578 int max = 0, maxPos=0;
579
315e18e6 580 int skip = 2;
15c4dc5a 581
582 // First, correlate for SOF
315e18e6 583 for(i = 0; i < 38000; i++) {
15c4dc5a 584 int corr = 0;
585 for(j = 0; j < arraylen(FrameSOF); j += skip) {
586 corr += FrameSOF[j]*dest[i+(j/skip)];
587 }
588 if(corr > max) {
589 max = corr;
590 maxPos = i;
591 }
592 }
70b2fc0a 593
315e18e6 594 if (DEBUG) Dbprintf("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
15c4dc5a 595
596 int k = 0; // this will be our return value
597
598 // greg - If correlation is less than 1 then there's little point in continuing
599 if ((max/(arraylen(FrameSOF)/skip)) >= 1) // THIS SHOULD BE 1
600 {
9455b51c 601
602 i = maxPos + arraylen(FrameSOF)/skip;
603
604 uint8_t outBuf[20];
605 memset(outBuf, 0, sizeof(outBuf));
606 uint8_t mask = 0x01;
607 for(;;) {
315e18e6 608 int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
9455b51c 609 for(j = 0; j < arraylen(Logic0); j += skip) {
610 corr0 += Logic0[j]*dest[i+(j/skip)];
611 }
315e18e6 612 corr01 = corr00 = corr0;
613 for(j = 0; j < arraylen(Logic0); j += skip) {
614 corr00 += Logic0[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
615 corr01 += Logic1[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
616 }
9455b51c 617 for(j = 0; j < arraylen(Logic1); j += skip) {
618 corr1 += Logic1[j]*dest[i+(j/skip)];
619 }
620 for(j = 0; j < arraylen(FrameEOF); j += skip) {
621 corrEOF += FrameEOF[j]*dest[i+(j/skip)];
622 }
623 // Even things out by the length of the target waveform.
315e18e6 624 corr00 *= 2;
625 corr01 *= 2;
9455b51c 626 corr0 *= 4;
627 corr1 *= 4;
628
315e18e6 629 if(corrEOF > corr1 && corrEOF > corr00 && corrEOF > corr01) {
630 if (DEBUG) Dbprintf("EOF at %d, correlation %d (corr01: %d, corr00: %d, corr1: %d, corr0: %d)",
70b2fc0a 631 i, corrEOF, corr01, corr00, corr1, corr0);
9455b51c 632 break;
633 } else if(corr1 > corr0) {
634 i += arraylen(Logic1)/skip;
635 outBuf[k] |= mask;
636 } else {
637 i += arraylen(Logic0)/skip;
638 }
639 mask <<= 1;
640 if(mask == 0) {
641 k++;
642 mask = 0x01;
643 }
315e18e6 644 if((i+(int)arraylen(FrameEOF)/skip) >= BIGBUF_SIZE) {
9455b51c 645 DbpString("ran off end!");
646 break;
647 }
15c4dc5a 648 }
9455b51c 649 if(mask != 0x01) {
650 DbpString("sniff: error, uneven octet! (discard extra bits!)");
651 /// DbpString(" mask=%02x", mask);
15c4dc5a 652 }
9455b51c 653 // uint8_t str1 [8];
654 // itoa(k,str1);
655 // strncat(str1," octets read",8);
656
657 // DbpString( str1); // DbpString("%d octets", k);
658
659 // for(i = 0; i < k; i+=3) {
660 // //DbpString("# %2d: %02x ", i, outBuf[i]);
661 // DbpIntegers(outBuf[i],outBuf[i+1],outBuf[i+2]);
662 // }
663
664 for(i = 0; i < k; i++) {
665 receivedResponse[i] = outBuf[i];
15c4dc5a 666 }
15c4dc5a 667 } // "end if correlation > 0" (max/(arraylen(FrameSOF)/skip))
668 return k; // return the number of bytes demodulated
669
670/// DbpString("CRC=%04x", Iso15693Crc(outBuf, k-2));
671}
672
9455b51c 673
674static void BuildIdentifyRequest(void);
15c4dc5a 675//-----------------------------------------------------------------------------
676// Start to read an ISO 15693 tag. We send an identify request, then wait
677// for the response. The response is not demodulated, just left in the buffer
678// so that it can be downloaded to a PC and processed there.
679//-----------------------------------------------------------------------------
680void AcquireRawAdcSamplesIso15693(void)
681{
70b2fc0a 682 LEDsoff();
683 LED_A_ON();
684
117d9ec2 685 uint8_t *dest = BigBuf_get_addr();
15c4dc5a 686
7cc204bf 687 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 688 BuildIdentifyRequest();
689
690 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
691
692 // Give the tags time to energize
70b2fc0a 693 LED_D_ON();
15c4dc5a 694 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
695 SpinDelay(100);
696
697 // Now send the command
6a5d4e17 698 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
15c4dc5a 699 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
700
70b2fc0a 701 LED_B_ON();
702 for(int c = 0; c < ToSendMax; ) {
15c4dc5a 703 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
6a5d4e17 704 AT91C_BASE_SSC->SSC_THR = ~ToSend[c];
15c4dc5a 705 c++;
15c4dc5a 706 }
15c4dc5a 707 WDT_HIT();
708 }
70b2fc0a 709 LED_B_OFF();
710
711 // wait for last transfer to complete
712 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
15c4dc5a 713
6a5d4e17 714 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
15c4dc5a 715 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
716
70b2fc0a 717 for(int c = 0; c < 4000; ) {
15c4dc5a 718 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
6a5d4e17 719 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
9455b51c 720 // The samples are correlations against I and Q versions of the
6a5d4e17 721 // tone that the tag AM-modulates. We just want power,
722 // so abs(I) + abs(Q) is close to what we want.
70b2fc0a 723 int8_t i = (int8_t)(iq >> 8);
724 int8_t q = (int8_t)(iq & 0xff);
6a5d4e17 725 uint8_t r = AMPLITUDE(i, q);
6a5d4e17 726 dest[c++] = r;
9455b51c 727 }
728 }
70b2fc0a 729
730 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
731 LEDsoff();
9455b51c 732}
733
734
70b2fc0a 735// TODO: there is no trigger condition. The 14000 samples represent a time frame of 66ms.
736// It is unlikely that we get something meaningful.
737// TODO: Currently we only record tag answers. Add tracing of reader commands.
738// TODO: would we get something at all? The carrier is switched on...
9455b51c 739void RecordRawAdcSamplesIso15693(void)
740{
70b2fc0a 741 LEDsoff();
742 LED_A_ON();
743
117d9ec2 744 uint8_t *dest = BigBuf_get_addr();
3fe4ff4f 745
7cc204bf 746 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
9455b51c 747 // Setup SSC
6a5d4e17 748 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
9455b51c 749
750 // Start from off (no field generated)
6a5d4e17 751 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
752 SpinDelay(200);
9455b51c 753
754 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
755
756 SpinDelay(100);
757
70b2fc0a 758 LED_D_ON();
9455b51c 759 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
760
70b2fc0a 761 for(int c = 0; c < 14000;) {
9455b51c 762 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
6a5d4e17 763 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
9455b51c 764 // The samples are correlations against I and Q versions of the
6a5d4e17 765 // tone that the tag AM-modulates. We just want power,
766 // so abs(I) + abs(Q) is close to what we want.
70b2fc0a 767 int8_t i = (int8_t)(iq >> 8);
768 int8_t q = (int8_t)(iq & 0xff);
6a5d4e17 769 uint8_t r = AMPLITUDE(i, q);
6a5d4e17 770 dest[c++] = r;
9455b51c 771 }
772 }
70b2fc0a 773
774 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
775 LED_D_OFF();
6a5d4e17 776 Dbprintf("finished recording");
70b2fc0a 777 LED_A_OFF();
9455b51c 778}
779
780
781// Initialize the proxmark as iso15k reader
e6304bca 782// (this might produces glitches that confuse some tags
70b2fc0a 783static void Iso15693InitReader() {
7cc204bf 784 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
9455b51c 785 // Setup SSC
e6304bca 786 // FpgaSetupSsc();
9455b51c 787
788 // Start from off (no field generated)
70b2fc0a 789 LED_D_OFF();
9455b51c 790 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
e6304bca 791 SpinDelay(10);
9455b51c 792
793 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
6a5d4e17 794 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
9455b51c 795
796 // Give the tags time to energize
70b2fc0a 797 LED_D_ON();
9455b51c 798 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
e6304bca 799 SpinDelay(250);
9455b51c 800}
801
802///////////////////////////////////////////////////////////////////////
803// ISO 15693 Part 3 - Air Interface
70b2fc0a 804// This section basically contains transmission and receiving of bits
9455b51c 805///////////////////////////////////////////////////////////////////////
806
807// Encode (into the ToSend buffers) an identify request, which is the first
808// thing that you must send to a tag to get a response.
809static void BuildIdentifyRequest(void)
810{
811 uint8_t cmd[5];
812
813 uint16_t crc;
814 // one sub-carrier, inventory, 1 slot, fast rate
815 // AFI is at bit 5 (1<<4) when doing an INVENTORY
816 cmd[0] = (1 << 2) | (1 << 5) | (1 << 1);
817 // inventory command code
818 cmd[1] = 0x01;
819 // no mask
820 cmd[2] = 0x00;
821 //Now the CRC
822 crc = Crc(cmd, 3);
823 cmd[3] = crc & 0xff;
824 cmd[4] = crc >> 8;
825
826 CodeIso15693AsReader(cmd, sizeof(cmd));
827}
828
829// uid is in transmission order (which is reverse of display order)
830static void BuildReadBlockRequest(uint8_t *uid, uint8_t blockNumber )
831{
832 uint8_t cmd[13];
833
834 uint16_t crc;
835 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
836 // followed by teh block data
837 // one sub-carrier, inventory, 1 slot, fast rate
838 cmd[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit, ADDR bit, OPTION bit
839 // READ BLOCK command code
840 cmd[1] = 0x20;
841 // UID may be optionally specified here
842 // 64-bit UID
843 cmd[2] = uid[0];
844 cmd[3] = uid[1];
845 cmd[4] = uid[2];
846 cmd[5] = uid[3];
847 cmd[6] = uid[4];
848 cmd[7] = uid[5];
849 cmd[8] = uid[6];
850 cmd[9] = uid[7]; // 0xe0; // always e0 (not exactly unique)
851 // Block number to read
852 cmd[10] = blockNumber;//0x00;
853 //Now the CRC
854 crc = Crc(cmd, 11); // the crc needs to be calculated over 12 bytes
855 cmd[11] = crc & 0xff;
856 cmd[12] = crc >> 8;
857
858 CodeIso15693AsReader(cmd, sizeof(cmd));
859}
860
70b2fc0a 861
9455b51c 862// Now the VICC>VCD responses when we are simulating a tag
70b2fc0a 863static void BuildInventoryResponse( uint8_t *uid)
9455b51c 864{
865 uint8_t cmd[12];
866
867 uint16_t crc;
868 // one sub-carrier, inventory, 1 slot, fast rate
869 // AFI is at bit 5 (1<<4) when doing an INVENTORY
3fe4ff4f 870 //(1 << 2) | (1 << 5) | (1 << 1);
871 cmd[0] = 0; //
872 cmd[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported
9455b51c 873 // 64-bit UID
3fe4ff4f 874 cmd[2] = uid[7]; //0x32;
875 cmd[3] = uid[6]; //0x4b;
876 cmd[4] = uid[5]; //0x03;
877 cmd[5] = uid[4]; //0x01;
878 cmd[6] = uid[3]; //0x00;
879 cmd[7] = uid[2]; //0x10;
880 cmd[8] = uid[1]; //0x05;
881 cmd[9] = uid[0]; //0xe0;
9455b51c 882 //Now the CRC
883 crc = Crc(cmd, 10);
884 cmd[10] = crc & 0xff;
885 cmd[11] = crc >> 8;
886
887 CodeIso15693AsReader(cmd, sizeof(cmd));
888}
889
e6304bca 890// Universal Method for sending to and recv bytes from a tag
9455b51c 891// init ... should we initialize the reader?
892// speed ... 0 low speed, 1 hi speed
893// **recv will return you a pointer to the received data
894// If you do not need the answer use NULL for *recv[]
895// return: lenght of received data
70b2fc0a 896int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t **recv) {
9455b51c 897
9455b51c 898 LED_A_ON();
70b2fc0a 899 LED_B_OFF();
9455b51c 900 LED_C_OFF();
9455b51c 901
09ffd16e 902 if (init) Iso15693InitReader();
903
9455b51c 904 int answerLen=0;
315e18e6 905 uint8_t *answer = BigBuf_get_addr() + 4000;
117d9ec2 906 if (recv != NULL) memset(answer, 0, 100);
9455b51c 907
9455b51c 908 if (!speed) {
909 // low speed (1 out of 256)
910 CodeIso15693AsReader256(send, sendlen);
911 } else {
912 // high speed (1 out of 4)
913 CodeIso15693AsReader(send, sendlen);
914 }
915
70b2fc0a 916 TransmitTo15693Tag(ToSend,ToSendMax);
9455b51c 917 // Now wait for a response
918 if (recv!=NULL) {
70b2fc0a 919 answerLen = GetIso15693AnswerFromTag(answer, 100);
9455b51c 920 *recv=answer;
921 }
922
923 LED_A_OFF();
9455b51c 924
925 return answerLen;
926}
15c4dc5a 927
15c4dc5a 928
9455b51c 929// --------------------------------------------------------------------
930// Debug Functions
931// --------------------------------------------------------------------
15c4dc5a 932
9455b51c 933// Decodes a message from a tag and displays its metadata and content
934#define DBD15STATLEN 48
935void DbdecodeIso15693Answer(int len, uint8_t *d) {
936 char status[DBD15STATLEN+1]={0};
937 uint16_t crc;
938
939 if (len>3) {
940 if (d[0]&(1<<3))
941 strncat(status,"ProtExt ",DBD15STATLEN);
942 if (d[0]&1) {
943 // error
944 strncat(status,"Error ",DBD15STATLEN);
945 switch (d[1]) {
946 case 0x01:
947 strncat(status,"01:notSupp",DBD15STATLEN);
15c4dc5a 948 break;
9455b51c 949 case 0x02:
950 strncat(status,"02:notRecog",DBD15STATLEN);
951 break;
952 case 0x03:
953 strncat(status,"03:optNotSupp",DBD15STATLEN);
954 break;
955 case 0x0f:
956 strncat(status,"0f:noInfo",DBD15STATLEN);
957 break;
958 case 0x10:
959 strncat(status,"10:dontExist",DBD15STATLEN);
960 break;
961 case 0x11:
962 strncat(status,"11:lockAgain",DBD15STATLEN);
963 break;
964 case 0x12:
965 strncat(status,"12:locked",DBD15STATLEN);
966 break;
967 case 0x13:
968 strncat(status,"13:progErr",DBD15STATLEN);
969 break;
970 case 0x14:
971 strncat(status,"14:lockErr",DBD15STATLEN);
972 break;
973 default:
974 strncat(status,"unknownErr",DBD15STATLEN);
15c4dc5a 975 }
9455b51c 976 strncat(status," ",DBD15STATLEN);
977 } else {
978 strncat(status,"NoErr ",DBD15STATLEN);
15c4dc5a 979 }
9455b51c 980
981 crc=Crc(d,len-2);
982 if ( (( crc & 0xff ) == d[len-2]) && (( crc >> 8 ) == d[len-1]) )
983 strncat(status,"CrcOK",DBD15STATLEN);
984 else
985 strncat(status,"CrcFail!",DBD15STATLEN);
986
987 Dbprintf("%s",status);
15c4dc5a 988 }
989}
990
9455b51c 991
992
993///////////////////////////////////////////////////////////////////////
994// Functions called via USB/Client
995///////////////////////////////////////////////////////////////////////
996
997void SetDebugIso15693(uint32_t debug) {
998 DEBUG=debug;
999 Dbprintf("Iso15693 Debug is now %s",DEBUG?"on":"off");
1000 return;
1001}
1002
15c4dc5a 1003//-----------------------------------------------------------------------------
1004// Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector
1005// all demodulation performed in arm rather than host. - greg
1006//-----------------------------------------------------------------------------
f7e3ed82 1007void ReaderIso15693(uint32_t parameter)
15c4dc5a 1008{
70b2fc0a 1009 LEDsoff();
15c4dc5a 1010 LED_A_ON();
15c4dc5a 1011
15c4dc5a 1012 int answerLen1 = 0;
3fe4ff4f 1013 uint8_t TagUID[8] = {0x00};
1014
09ffd16e 1015 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1016
315e18e6 1017 uint8_t *answer1 = BigBuf_get_addr() + 4000;
315e18e6 1018 memset(answer1, 0x00, 200);
15c4dc5a 1019
3fe4ff4f 1020 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
15c4dc5a 1021 // Setup SSC
6a5d4e17 1022 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
15c4dc5a 1023
1024 // Start from off (no field generated)
09ffd16e 1025 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1026 SpinDelay(200);
15c4dc5a 1027
15c4dc5a 1028 // Give the tags time to energize
70b2fc0a 1029 LED_D_ON();
15c4dc5a 1030 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
1031 SpinDelay(200);
1032
15c4dc5a 1033 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
1034 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
15c4dc5a 1035
1036 // Now send the IDENTIFY command
1037 BuildIdentifyRequest();
3fe4ff4f 1038
70b2fc0a 1039 TransmitTo15693Tag(ToSend,ToSendMax);
3fe4ff4f 1040
15c4dc5a 1041 // Now wait for a response
70b2fc0a 1042 answerLen1 = GetIso15693AnswerFromTag(answer1, 100) ;
15c4dc5a 1043
1044 if (answerLen1 >=12) // we should do a better check than this
1045 {
15c4dc5a 1046 TagUID[0] = answer1[2];
1047 TagUID[1] = answer1[3];
1048 TagUID[2] = answer1[4];
1049 TagUID[3] = answer1[5];
1050 TagUID[4] = answer1[6];
1051 TagUID[5] = answer1[7];
1052 TagUID[6] = answer1[8]; // IC Manufacturer code
9455b51c 1053 TagUID[7] = answer1[9]; // always E0
15c4dc5a 1054
15c4dc5a 1055 }
1056
9455b51c 1057 Dbprintf("%d octets read from IDENTIFY request:", answerLen1);
1058 DbdecodeIso15693Answer(answerLen1,answer1);
d19929cb 1059 Dbhexdump(answerLen1,answer1,true);
9455b51c 1060
1061 // UID is reverse
70b2fc0a 1062 if (answerLen1 >= 12)
3fe4ff4f 1063 Dbprintf("UID = %02hX%02hX%02hX%02hX%02hX%02hX%02hX%02hX",
1064 TagUID[7],TagUID[6],TagUID[5],TagUID[4],
1065 TagUID[3],TagUID[2],TagUID[1],TagUID[0]);
9455b51c 1066
1067
315e18e6 1068 // Dbprintf("%d octets read from SELECT request:", answerLen2);
1069 // DbdecodeIso15693Answer(answerLen2,answer2);
1070 // Dbhexdump(answerLen2,answer2,true);
9455b51c 1071
315e18e6 1072 // Dbprintf("%d octets read from XXX request:", answerLen3);
1073 // DbdecodeIso15693Answer(answerLen3,answer3);
1074 // Dbhexdump(answerLen3,answer3,true);
9455b51c 1075
9455b51c 1076 // read all pages
70b2fc0a 1077 if (answerLen1 >= 12 && DEBUG) {
1078 uint8_t *answer2 = BigBuf_get_addr() + 4100;
1079 int i=0;
9455b51c 1080 while (i<32) { // sanity check, assume max 32 pages
1081 BuildReadBlockRequest(TagUID,i);
70b2fc0a 1082 TransmitTo15693Tag(ToSend,ToSendMax);
1083 int answerLen2 = GetIso15693AnswerFromTag(answer2, 100);
9455b51c 1084 if (answerLen2>0) {
1085 Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
1086 DbdecodeIso15693Answer(answerLen2,answer2);
d19929cb 1087 Dbhexdump(answerLen2,answer2,true);
9455b51c 1088 if ( *((uint32_t*) answer2) == 0x07160101 ) break; // exit on NoPageErr
1089 }
1090 i++;
1091 }
1092 }
15c4dc5a 1093
70b2fc0a 1094 // for the time being, switch field off to protect rdv4.0
1095 // note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
1096 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
15c4dc5a 1097 LED_D_OFF();
70b2fc0a 1098
1099 LED_A_OFF();
15c4dc5a 1100}
1101
15c4dc5a 1102// Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
1103// all demodulation performed in arm rather than host. - greg
3fe4ff4f 1104void SimTagIso15693(uint32_t parameter, uint8_t *uid)
15c4dc5a 1105{
70b2fc0a 1106 LEDsoff();
15c4dc5a 1107 LED_A_ON();
15c4dc5a 1108
15c4dc5a 1109 int answerLen1 = 0;
3fe4ff4f 1110 int samples = 0;
3fe4ff4f 1111 int elapsed = 0;
15c4dc5a 1112
7cc204bf 1113 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1114
315e18e6 1115 uint8_t *buf = BigBuf_get_addr() + 4000;
09ffd16e 1116 memset(buf, 0x00, 100);
1117
15c4dc5a 1118 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
6a5d4e17 1119 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
15c4dc5a 1120
3fe4ff4f 1121 // Start from off (no field generated)
09ffd16e 1122 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
15c4dc5a 1123 SpinDelay(200);
1124
3fe4ff4f 1125 // Listen to reader
1126 answerLen1 = GetIso15693AnswerFromSniff(buf, 100, &samples, &elapsed) ;
15c4dc5a 1127
1128 if (answerLen1 >=1) // we should do a better check than this
1129 {
1130 // Build a suitable reponse to the reader INVENTORY cocmmand
3fe4ff4f 1131 // not so obsvious, but in the call to BuildInventoryResponse, the command is copied to the global ToSend buffer used below.
1132
1133 BuildInventoryResponse(uid);
1134
70b2fc0a 1135 TransmitTo15693Reader(ToSend,ToSendMax);
15c4dc5a 1136 }
1137
1138 Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1,
3fe4ff4f 1139 buf[0], buf[1], buf[2], buf[3],
1140 buf[4], buf[5], buf[6], buf[7], buf[8]);
1141
1142 Dbprintf("Simulationg uid: %x %x %x %x %x %x %x %x",
1143 uid[0], uid[1], uid[2], uid[3],
1144 uid[4], uid[5], uid[6], uid[7]);
15c4dc5a 1145
70b2fc0a 1146 LEDsoff();
15c4dc5a 1147}
9455b51c 1148
1149
1150// Since there is no standardized way of reading the AFI out of a tag, we will brute force it
1151// (some manufactures offer a way to read the AFI, though)
1152void BruteforceIso15693Afi(uint32_t speed)
1153{
70b2fc0a 1154 LEDsoff();
1155 LED_A_ON();
1156
9455b51c 1157 uint8_t data[20];
1158 uint8_t *recv=data;
1159 int datalen=0, recvlen=0;
1160
1161 Iso15693InitReader();
1162
1163 // first without AFI
1164 // Tags should respond wihtout AFI and with AFI=0 even when AFI is active
1165
1166 data[0]=ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
1167 ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
1168 data[1]=ISO15_CMD_INVENTORY;
1169 data[2]=0; // mask length
1170 datalen=AddCrc(data,3);
70b2fc0a 1171 recvlen=SendDataTag(data, datalen, false, speed, &recv);
9455b51c 1172 WDT_HIT();
1173 if (recvlen>=12) {
1174 Dbprintf("NoAFI UID=%s",sprintUID(NULL,&recv[2]));
1175 }
1176
1177 // now with AFI
1178
1179 data[0]=ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
1180 ISO15_REQ_INVENTORY | ISO15_REQINV_AFI | ISO15_REQINV_SLOT1;
1181 data[1]=ISO15_CMD_INVENTORY;
1182 data[2]=0; // AFI
1183 data[3]=0; // mask length
1184
1185 for (int i=0;i<256;i++) {
1186 data[2]=i & 0xFF;
1187 datalen=AddCrc(data,4);
70b2fc0a 1188 recvlen=SendDataTag(data, datalen, false, speed, &recv);
9455b51c 1189 WDT_HIT();
1190 if (recvlen>=12) {
1191 Dbprintf("AFI=%i UID=%s",i,sprintUID(NULL,&recv[2]));
1192 }
1193 }
1194 Dbprintf("AFI Bruteforcing done.");
1195
70b2fc0a 1196 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1197 LEDsoff();
9455b51c 1198}
1199
1200// Allows to directly send commands to the tag via the client
70b2fc0a 1201void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t data[]) {
9455b51c 1202
1203 int recvlen=0;
117d9ec2 1204 uint8_t *recvbuf = BigBuf_get_addr();
70b2fc0a 1205
1206 LED_A_ON();
9455b51c 1207
1208 if (DEBUG) {
1209 Dbprintf("SEND");
d19929cb 1210 Dbhexdump(datalen,data,true);
9455b51c 1211 }
1212
70b2fc0a 1213 recvlen = SendDataTag(data, datalen, true, speed, (recv?&recvbuf:NULL));
9455b51c 1214
1215 if (recv) {
70b2fc0a 1216 cmd_send(CMD_ACK, recvlen>48?48:recvlen, 0, 0, recvbuf, 48);
9455b51c 1217
1218 if (DEBUG) {
1219 Dbprintf("RECV");
1220 DbdecodeIso15693Answer(recvlen,recvbuf);
d19929cb 1221 Dbhexdump(recvlen,recvbuf,true);
9455b51c 1222 }
1223 }
1224
70b2fc0a 1225 // for the time being, switch field off to protect rdv4.0
1226 // note: this prevents using hf 15 cmd with s option - which isn't implemented yet anyway
1227 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1228 LED_D_OFF();
1229
1230 LED_A_OFF();
9455b51c 1231}
1232
1233
1234
1235
1236// --------------------------------------------------------------------
1237// -- Misc & deprecated functions
1238// --------------------------------------------------------------------
1239
e6304bca 1240/*
9455b51c 1241
1242// do not use; has a fix UID
1243static void __attribute__((unused)) BuildSysInfoRequest(uint8_t *uid)
1244{
1245 uint8_t cmd[12];
1246
1247 uint16_t crc;
1248 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1249 // followed by teh block data
1250 // one sub-carrier, inventory, 1 slot, fast rate
1251 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1252 // System Information command code
1253 cmd[1] = 0x2B;
1254 // UID may be optionally specified here
1255 // 64-bit UID
1256 cmd[2] = 0x32;
1257 cmd[3]= 0x4b;
1258 cmd[4] = 0x03;
1259 cmd[5] = 0x01;
1260 cmd[6] = 0x00;
1261 cmd[7] = 0x10;
1262 cmd[8] = 0x05;
1263 cmd[9]= 0xe0; // always e0 (not exactly unique)
1264 //Now the CRC
1265 crc = Crc(cmd, 10); // the crc needs to be calculated over 2 bytes
1266 cmd[10] = crc & 0xff;
1267 cmd[11] = crc >> 8;
1268
1269 CodeIso15693AsReader(cmd, sizeof(cmd));
1270}
1271
9455b51c 1272
1273// do not use; has a fix UID
1274static void __attribute__((unused)) BuildReadMultiBlockRequest(uint8_t *uid)
1275{
1276 uint8_t cmd[14];
1277
1278 uint16_t crc;
1279 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1280 // followed by teh block data
1281 // one sub-carrier, inventory, 1 slot, fast rate
1282 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1283 // READ Multi BLOCK command code
1284 cmd[1] = 0x23;
1285 // UID may be optionally specified here
1286 // 64-bit UID
1287 cmd[2] = 0x32;
1288 cmd[3]= 0x4b;
1289 cmd[4] = 0x03;
1290 cmd[5] = 0x01;
1291 cmd[6] = 0x00;
1292 cmd[7] = 0x10;
1293 cmd[8] = 0x05;
1294 cmd[9]= 0xe0; // always e0 (not exactly unique)
1295 // First Block number to read
1296 cmd[10] = 0x00;
1297 // Number of Blocks to read
1298 cmd[11] = 0x2f; // read quite a few
1299 //Now the CRC
1300 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1301 cmd[12] = crc & 0xff;
1302 cmd[13] = crc >> 8;
1303
1304 CodeIso15693AsReader(cmd, sizeof(cmd));
1305}
1306
1307// do not use; has a fix UID
1308static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t CmdCode)
1309{
1310 uint8_t cmd[14];
1311
1312 uint16_t crc;
1313 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1314 // followed by teh block data
1315 // one sub-carrier, inventory, 1 slot, fast rate
1316 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1317 // READ BLOCK command code
1318 cmd[1] = CmdCode;
1319 // UID may be optionally specified here
1320 // 64-bit UID
1321 cmd[2] = 0x32;
1322 cmd[3]= 0x4b;
1323 cmd[4] = 0x03;
1324 cmd[5] = 0x01;
1325 cmd[6] = 0x00;
1326 cmd[7] = 0x10;
1327 cmd[8] = 0x05;
1328 cmd[9]= 0xe0; // always e0 (not exactly unique)
1329 // Parameter
1330 cmd[10] = 0x00;
1331 cmd[11] = 0x0a;
1332
1333// cmd[12] = 0x00;
1334// cmd[13] = 0x00; //Now the CRC
1335 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1336 cmd[12] = crc & 0xff;
1337 cmd[13] = crc >> 8;
1338
1339 CodeIso15693AsReader(cmd, sizeof(cmd));
1340}
1341
1342// do not use; has a fix UID
1343static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], uint8_t CmdCode)
1344{
1345 uint8_t cmd[14];
1346
1347 uint16_t crc;
1348 // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
1349 // followed by teh block data
1350 // one sub-carrier, inventory, 1 slot, fast rate
1351 cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
1352 // READ BLOCK command code
1353 cmd[1] = CmdCode;
1354 // UID may be optionally specified here
1355 // 64-bit UID
1356 cmd[2] = 0x32;
1357 cmd[3]= 0x4b;
1358 cmd[4] = 0x03;
1359 cmd[5] = 0x01;
1360 cmd[6] = 0x00;
1361 cmd[7] = 0x10;
1362 cmd[8] = 0x05;
1363 cmd[9]= 0xe0; // always e0 (not exactly unique)
1364 // Parameter
1365 cmd[10] = 0x05; // for custom codes this must be manufcturer code
1366 cmd[11] = 0x00;
1367
1368// cmd[12] = 0x00;
1369// cmd[13] = 0x00; //Now the CRC
1370 crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
1371 cmd[12] = crc & 0xff;
1372 cmd[13] = crc >> 8;
1373
1374 CodeIso15693AsReader(cmd, sizeof(cmd));
1375}
1376
1377
1378
1379
e6304bca 1380*/
9455b51c 1381
1382
Impressum, Datenschutz