]> git.zerfleddert.de Git - proxmark3-svn/blame_incremental - armsrc/iso15693.c
start fixing hf 15: (#684)
[proxmark3-svn] / armsrc / iso15693.c
... / ...
CommitLineData
1//-----------------------------------------------------------------------------
2// Jonathan Westhues, split Nov 2006
3// Modified by Greg Jones, Jan 2009
4// Modified by Adrian Dabrowski "atrox", Mar-Sept 2010,Oct 2011
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//-----------------------------------------------------------------------------
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.
13// Modified to perform modulation onboard in arm rather than on PC
14// Also added additional reader commands (SELECT, READ etc.)
15//-----------------------------------------------------------------------------
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
54// *) read security status of a block
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
60
61#include "proxmark3.h"
62#include "util.h"
63#include "apps.h"
64#include "string.h"
65#include "iso15693tools.h"
66#include "cmd.h"
67
68#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
69
70static int DEBUG = 0;
71
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
81
82#define Crc(data,datalen) Iso15693Crc(data,datalen)
83#define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
84#define sprintUID(target,uid) Iso15693sprintUID(target,uid)
85
86// approximate amplitude=sqrt(ci^2+cq^2)
87#define AMPLITUDE(ci, cq) (MAX(ABS(ci), ABS(cq)) + MIN(ABS(ci), ABS(cq))/2)
88
89// DMA buffer
90#define ISO15693_DMA_BUFFER_SIZE 128
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
100static void CodeIso15693AsReader(uint8_t *cmd, int n)
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
111 // SOF for 1of4
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 }
167 // EOF
168 ToSendStuffBit(1);
169 ToSendStuffBit(1);
170 ToSendStuffBit(0);
171 ToSendStuffBit(1);
172
173 // Fill remainder of last byte with 1
174 for(i = 0; i < 4; i++) {
175 ToSendStuffBit(1);
176 }
177
178 ToSendMax++;
179}
180
181// encode data using "1 out of 256" scheme
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)
185{
186 int i, j;
187
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
205 for(i = 0; i < n; i++) {
206 for (j = 0; j<=255; j++) {
207 if (cmd[i]==j) {
208 ToSendStuffBit(1);
209 ToSendStuffBit(0);
210 } else {
211 ToSendStuffBit(1);
212 ToSendStuffBit(1);
213 }
214 }
215 }
216 // EOF
217 ToSendStuffBit(1);
218 ToSendStuffBit(1);
219 ToSendStuffBit(0);
220 ToSendStuffBit(1);
221
222 // And slack at the end, too.
223 for(i = 0; i < 24; i++) {
224 ToSendStuffBit(1);
225 }
226}
227
228
229// Transmit the command (to the tag) that was placed in cmd[].
230static void TransmitTo15693Tag(const uint8_t *cmd, int len)
231{
232 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
233 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
234
235 LED_B_ON();
236 for(int c = 0; c < len; ) {
237 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
238 AT91C_BASE_SSC->SSC_THR = ~cmd[c];
239 c++;
240 }
241 WDT_HIT();
242 }
243 LED_B_OFF();
244}
245
246//-----------------------------------------------------------------------------
247// Transmit the command (to the reader) that was placed in cmd[].
248//-----------------------------------------------------------------------------
249static void TransmitTo15693Reader(const uint8_t *cmd, int len)
250{
251 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K);
252
253 LED_C_ON();
254 for(int c = 0; c < len; ) {
255 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
256 AT91C_BASE_SSC->SSC_THR = cmd[c];
257 c++;
258 }
259 WDT_HIT();
260 }
261 LED_C_OFF();
262}
263
264
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)
311{
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;
328
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;
345 }
346
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;
378
379 case DEMOD_RECEIVING_DATA:
380 if (Demod->posCount == 1) {
381 Demod->sum1 = 0;
382 Demod->sum2 = 0;
383 }
384
385 if (Demod->posCount <= 4) {
386 Demod->sum1 += AMPLITUDE(ci, cq);
387 } else {
388 Demod->sum2 += AMPLITUDE(ci, cq);
389 }
390
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;
449 }
450
451 return false;
452}
453
454
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;
471
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));
481
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;
502 }
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;
514 }
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
518 }
519 samples++;
520
521 if (Handle15693SamplesDemod(ci, cq, Demod)) {
522 gotFrame = true;
523 break;
524 }
525
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;
543}
544
545
546// Now the GetISO15693 message from sniffing command
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
550static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
551{
552 uint8_t *dest = BigBuf_get_addr();
553
554// NOW READ RESPONSE
555 LED_D_ON();
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
558 for(int c = 0; c < BIGBUF_SIZE; ) {
559 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
560 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
561 // The samples are correlations against I and Q versions of the
562 // tone that the tag AM-modulates. We just want power,
563 // so abs(I) + abs(Q) is close to what we want.
564 int8_t i = (int8_t)(iq >> 8);
565 int8_t q = (int8_t)(iq & 0xff);
566 uint8_t r = AMPLITUDE(i, q);
567 dest[c++] = r;
568 }
569 }
570 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
571 LED_D_OFF();
572
573 //////////////////////////////////////////
574 /////////// DEMODULATE ///////////////////
575 //////////////////////////////////////////
576
577 int i, j;
578 int max = 0, maxPos=0;
579
580 int skip = 2;
581
582 // First, correlate for SOF
583 for(i = 0; i < 38000; i++) {
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 }
593
594 if (DEBUG) Dbprintf("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
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 {
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(;;) {
608 int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
609 for(j = 0; j < arraylen(Logic0); j += skip) {
610 corr0 += Logic0[j]*dest[i+(j/skip)];
611 }
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 }
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.
624 corr00 *= 2;
625 corr01 *= 2;
626 corr0 *= 4;
627 corr1 *= 4;
628
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)",
631 i, corrEOF, corr01, corr00, corr1, corr0);
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 }
644 if((i+(int)arraylen(FrameEOF)/skip) >= BIGBUF_SIZE) {
645 DbpString("ran off end!");
646 break;
647 }
648 }
649 if(mask != 0x01) {
650 DbpString("sniff: error, uneven octet! (discard extra bits!)");
651 /// DbpString(" mask=%02x", mask);
652 }
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];
666 }
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
673
674static void BuildIdentifyRequest(void);
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{
682 LEDsoff();
683 LED_A_ON();
684
685 uint8_t *dest = BigBuf_get_addr();
686
687 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
688 BuildIdentifyRequest();
689
690 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
691
692 // Give the tags time to energize
693 LED_D_ON();
694 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
695 SpinDelay(100);
696
697 // Now send the command
698 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
699 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
700
701 LED_B_ON();
702 for(int c = 0; c < ToSendMax; ) {
703 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
704 AT91C_BASE_SSC->SSC_THR = ~ToSend[c];
705 c++;
706 }
707 WDT_HIT();
708 }
709 LED_B_OFF();
710
711 // wait for last transfer to complete
712 while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
713
714 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
715 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
716
717 for(int c = 0; c < 4000; ) {
718 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
719 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
720 // The samples are correlations against I and Q versions of the
721 // tone that the tag AM-modulates. We just want power,
722 // so abs(I) + abs(Q) is close to what we want.
723 int8_t i = (int8_t)(iq >> 8);
724 int8_t q = (int8_t)(iq & 0xff);
725 uint8_t r = AMPLITUDE(i, q);
726 dest[c++] = r;
727 }
728 }
729
730 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
731 LEDsoff();
732}
733
734
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...
739void RecordRawAdcSamplesIso15693(void)
740{
741 LEDsoff();
742 LED_A_ON();
743
744 uint8_t *dest = BigBuf_get_addr();
745
746 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
747 // Setup SSC
748 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
749
750 // Start from off (no field generated)
751 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
752 SpinDelay(200);
753
754 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
755
756 SpinDelay(100);
757
758 LED_D_ON();
759 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
760
761 for(int c = 0; c < 14000;) {
762 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
763 uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
764 // The samples are correlations against I and Q versions of the
765 // tone that the tag AM-modulates. We just want power,
766 // so abs(I) + abs(Q) is close to what we want.
767 int8_t i = (int8_t)(iq >> 8);
768 int8_t q = (int8_t)(iq & 0xff);
769 uint8_t r = AMPLITUDE(i, q);
770 dest[c++] = r;
771 }
772 }
773
774 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
775 LED_D_OFF();
776 Dbprintf("finished recording");
777 LED_A_OFF();
778}
779
780
781// Initialize the proxmark as iso15k reader
782// (this might produces glitches that confuse some tags
783static void Iso15693InitReader() {
784 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
785 // Setup SSC
786 // FpgaSetupSsc();
787
788 // Start from off (no field generated)
789 LED_D_OFF();
790 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
791 SpinDelay(10);
792
793 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
794 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
795
796 // Give the tags time to energize
797 LED_D_ON();
798 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
799 SpinDelay(250);
800}
801
802///////////////////////////////////////////////////////////////////////
803// ISO 15693 Part 3 - Air Interface
804// This section basically contains transmission and receiving of bits
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
861
862// Now the VICC>VCD responses when we are simulating a tag
863static void BuildInventoryResponse( uint8_t *uid)
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
870 //(1 << 2) | (1 << 5) | (1 << 1);
871 cmd[0] = 0; //
872 cmd[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported
873 // 64-bit UID
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;
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
890// Universal Method for sending to and recv bytes from a tag
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
896int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t **recv) {
897
898 LED_A_ON();
899 LED_B_OFF();
900 LED_C_OFF();
901
902 if (init) Iso15693InitReader();
903
904 int answerLen=0;
905 uint8_t *answer = BigBuf_get_addr() + 4000;
906 if (recv != NULL) memset(answer, 0, 100);
907
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
916 TransmitTo15693Tag(ToSend,ToSendMax);
917 // Now wait for a response
918 if (recv!=NULL) {
919 answerLen = GetIso15693AnswerFromTag(answer, 100);
920 *recv=answer;
921 }
922
923 LED_A_OFF();
924
925 return answerLen;
926}
927
928
929// --------------------------------------------------------------------
930// Debug Functions
931// --------------------------------------------------------------------
932
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);
948 break;
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);
975 }
976 strncat(status," ",DBD15STATLEN);
977 } else {
978 strncat(status,"NoErr ",DBD15STATLEN);
979 }
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);
988 }
989}
990
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
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//-----------------------------------------------------------------------------
1007void ReaderIso15693(uint32_t parameter)
1008{
1009 LEDsoff();
1010 LED_A_ON();
1011
1012 int answerLen1 = 0;
1013 uint8_t TagUID[8] = {0x00};
1014
1015 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1016
1017 uint8_t *answer1 = BigBuf_get_addr() + 4000;
1018 memset(answer1, 0x00, 200);
1019
1020 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
1021 // Setup SSC
1022 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
1023
1024 // Start from off (no field generated)
1025 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1026 SpinDelay(200);
1027
1028 // Give the tags time to energize
1029 LED_D_ON();
1030 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
1031 SpinDelay(200);
1032
1033 // FIRST WE RUN AN INVENTORY TO GET THE TAG UID
1034 // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
1035
1036 // Now send the IDENTIFY command
1037 BuildIdentifyRequest();
1038
1039 TransmitTo15693Tag(ToSend,ToSendMax);
1040
1041 // Now wait for a response
1042 answerLen1 = GetIso15693AnswerFromTag(answer1, 100) ;
1043
1044 if (answerLen1 >=12) // we should do a better check than this
1045 {
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
1053 TagUID[7] = answer1[9]; // always E0
1054
1055 }
1056
1057 Dbprintf("%d octets read from IDENTIFY request:", answerLen1);
1058 DbdecodeIso15693Answer(answerLen1,answer1);
1059 Dbhexdump(answerLen1,answer1,true);
1060
1061 // UID is reverse
1062 if (answerLen1 >= 12)
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]);
1066
1067
1068 // Dbprintf("%d octets read from SELECT request:", answerLen2);
1069 // DbdecodeIso15693Answer(answerLen2,answer2);
1070 // Dbhexdump(answerLen2,answer2,true);
1071
1072 // Dbprintf("%d octets read from XXX request:", answerLen3);
1073 // DbdecodeIso15693Answer(answerLen3,answer3);
1074 // Dbhexdump(answerLen3,answer3,true);
1075
1076 // read all pages
1077 if (answerLen1 >= 12 && DEBUG) {
1078 uint8_t *answer2 = BigBuf_get_addr() + 4100;
1079 int i=0;
1080 while (i<32) { // sanity check, assume max 32 pages
1081 BuildReadBlockRequest(TagUID,i);
1082 TransmitTo15693Tag(ToSend,ToSendMax);
1083 int answerLen2 = GetIso15693AnswerFromTag(answer2, 100);
1084 if (answerLen2>0) {
1085 Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
1086 DbdecodeIso15693Answer(answerLen2,answer2);
1087 Dbhexdump(answerLen2,answer2,true);
1088 if ( *((uint32_t*) answer2) == 0x07160101 ) break; // exit on NoPageErr
1089 }
1090 i++;
1091 }
1092 }
1093
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);
1097 LED_D_OFF();
1098
1099 LED_A_OFF();
1100}
1101
1102// Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
1103// all demodulation performed in arm rather than host. - greg
1104void SimTagIso15693(uint32_t parameter, uint8_t *uid)
1105{
1106 LEDsoff();
1107 LED_A_ON();
1108
1109 int answerLen1 = 0;
1110 int samples = 0;
1111 int elapsed = 0;
1112
1113 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1114
1115 uint8_t *buf = BigBuf_get_addr() + 4000;
1116 memset(buf, 0x00, 100);
1117
1118 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
1119 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
1120
1121 // Start from off (no field generated)
1122 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1123 SpinDelay(200);
1124
1125 // Listen to reader
1126 answerLen1 = GetIso15693AnswerFromSniff(buf, 100, &samples, &elapsed) ;
1127
1128 if (answerLen1 >=1) // we should do a better check than this
1129 {
1130 // Build a suitable reponse to the reader INVENTORY cocmmand
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
1135 TransmitTo15693Reader(ToSend,ToSendMax);
1136 }
1137
1138 Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1,
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]);
1145
1146 LEDsoff();
1147}
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{
1154 LEDsoff();
1155 LED_A_ON();
1156
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);
1171 recvlen=SendDataTag(data, datalen, false, speed, &recv);
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);
1188 recvlen=SendDataTag(data, datalen, false, speed, &recv);
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
1196 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1197 LEDsoff();
1198}
1199
1200// Allows to directly send commands to the tag via the client
1201void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t data[]) {
1202
1203 int recvlen=0;
1204 uint8_t *recvbuf = BigBuf_get_addr();
1205
1206 LED_A_ON();
1207
1208 if (DEBUG) {
1209 Dbprintf("SEND");
1210 Dbhexdump(datalen,data,true);
1211 }
1212
1213 recvlen = SendDataTag(data, datalen, true, speed, (recv?&recvbuf:NULL));
1214
1215 if (recv) {
1216 cmd_send(CMD_ACK, recvlen>48?48:recvlen, 0, 0, recvbuf, 48);
1217
1218 if (DEBUG) {
1219 Dbprintf("RECV");
1220 DbdecodeIso15693Answer(recvlen,recvbuf);
1221 Dbhexdump(recvlen,recvbuf,true);
1222 }
1223 }
1224
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();
1231}
1232
1233
1234
1235
1236// --------------------------------------------------------------------
1237// -- Misc & deprecated functions
1238// --------------------------------------------------------------------
1239
1240/*
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
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
1380*/
1381
1382
Impressum, Datenschutz