]> cvs.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso14443a.c
Updated logic in lo_read.v so it's much tidier now, better timing.
[proxmark3-svn] / armsrc / iso14443a.c
CommitLineData
6658905f 1//-----------------------------------------------------------------------------\r
2// Routines to support ISO 14443 type A.\r
3//\r
4// Gerhard de Koning Gans - May 2008\r
5//-----------------------------------------------------------------------------\r
6#include <proxmark3.h>\r
7#include "apps.h"\r
30f2a7d3 8#include "../common/iso14443_crc.c"\r
6658905f 9\r
10typedef enum {\r
11 SEC_D = 1,\r
12 SEC_E = 2,\r
13 SEC_F = 3,\r
14 SEC_X = 4,\r
15 SEC_Y = 5,\r
16 SEC_Z = 6\r
17} SecType;\r
18\r
19//-----------------------------------------------------------------------------\r
20// The software UART that receives commands from the reader, and its state\r
21// variables.\r
22//-----------------------------------------------------------------------------\r
23static struct {\r
24 enum {\r
25 STATE_UNSYNCD,\r
26 STATE_START_OF_COMMUNICATION,\r
27 STATE_MILLER_X,\r
28 STATE_MILLER_Y,\r
29 STATE_MILLER_Z,\r
30 STATE_ERROR_WAIT\r
31 } state;\r
32 WORD shiftReg;\r
33 int bitCnt;\r
34 int byteCnt;\r
35 int byteCntMax;\r
36 int posCnt;\r
37 int syncBit;\r
38 int parityBits;\r
39 int samples;\r
40 int highCnt;\r
41 int bitBuffer;\r
42 enum {\r
43 DROP_NONE,\r
44 DROP_FIRST_HALF,\r
45 DROP_SECOND_HALF\r
46 } drop;\r
47 BYTE *output;\r
48} Uart;\r
49\r
50static BOOL MillerDecoding(int bit)\r
51{\r
52 int error = 0;\r
53 int bitright;\r
54\r
55 if(!Uart.bitBuffer) {\r
56 Uart.bitBuffer = bit ^ 0xFF0;\r
57 return FALSE;\r
58 }\r
59 else {\r
60 Uart.bitBuffer <<= 4;\r
61 Uart.bitBuffer ^= bit;\r
62 }\r
63\r
64 BOOL EOC = FALSE;\r
65\r
66 if(Uart.state != STATE_UNSYNCD) {\r
67 Uart.posCnt++;\r
68\r
69 if((Uart.bitBuffer & Uart.syncBit) ^ Uart.syncBit) {\r
70 bit = 0x00;\r
71 }\r
72 else {\r
73 bit = 0x01;\r
74 }\r
75 if(((Uart.bitBuffer << 1) & Uart.syncBit) ^ Uart.syncBit) {\r
76 bitright = 0x00;\r
77 }\r
78 else {\r
79 bitright = 0x01;\r
80 }\r
81 if(bit != bitright) { bit = bitright; }\r
82\r
83 if(Uart.posCnt == 1) {\r
84 // measurement first half bitperiod\r
85 if(!bit) {\r
86 Uart.drop = DROP_FIRST_HALF;\r
87 }\r
88 }\r
89 else {\r
90 // measurement second half bitperiod\r
91 if(!bit & (Uart.drop == DROP_NONE)) {\r
92 Uart.drop = DROP_SECOND_HALF;\r
93 }\r
94 else if(!bit) {\r
95 // measured a drop in first and second half\r
96 // which should not be possible\r
97 Uart.state = STATE_ERROR_WAIT;\r
98 error = 0x01;\r
99 }\r
100\r
101 Uart.posCnt = 0;\r
102\r
103 switch(Uart.state) {\r
104 case STATE_START_OF_COMMUNICATION:\r
105 Uart.shiftReg = 0;\r
106 if(Uart.drop == DROP_SECOND_HALF) {\r
107 // error, should not happen in SOC\r
108 Uart.state = STATE_ERROR_WAIT;\r
109 error = 0x02;\r
110 }\r
111 else {\r
112 // correct SOC\r
113 Uart.state = STATE_MILLER_Z;\r
114 }\r
115 break;\r
116\r
117 case STATE_MILLER_Z:\r
118 Uart.bitCnt++;\r
119 Uart.shiftReg >>= 1;\r
120 if(Uart.drop == DROP_NONE) {\r
121 // logic '0' followed by sequence Y\r
122 // end of communication\r
123 Uart.state = STATE_UNSYNCD;\r
124 EOC = TRUE;\r
125 }\r
126 // if(Uart.drop == DROP_FIRST_HALF) {\r
127 // Uart.state = STATE_MILLER_Z; stay the same\r
128 // we see a logic '0' }\r
129 if(Uart.drop == DROP_SECOND_HALF) {\r
130 // we see a logic '1'\r
131 Uart.shiftReg |= 0x100;\r
132 Uart.state = STATE_MILLER_X;\r
133 }\r
134 break;\r
135\r
136 case STATE_MILLER_X:\r
137 Uart.shiftReg >>= 1;\r
138 if(Uart.drop == DROP_NONE) {\r
139 // sequence Y, we see a '0'\r
140 Uart.state = STATE_MILLER_Y;\r
141 Uart.bitCnt++;\r
142 }\r
143 if(Uart.drop == DROP_FIRST_HALF) {\r
144 // Would be STATE_MILLER_Z\r
145 // but Z does not follow X, so error\r
146 Uart.state = STATE_ERROR_WAIT;\r
147 error = 0x03;\r
148 }\r
149 if(Uart.drop == DROP_SECOND_HALF) {\r
150 // We see a '1' and stay in state X\r
151 Uart.shiftReg |= 0x100;\r
152 Uart.bitCnt++;\r
153 }\r
154 break;\r
155\r
156 case STATE_MILLER_Y:\r
157 Uart.bitCnt++;\r
158 Uart.shiftReg >>= 1;\r
159 if(Uart.drop == DROP_NONE) {\r
160 // logic '0' followed by sequence Y\r
161 // end of communication\r
162 Uart.state = STATE_UNSYNCD;\r
163 EOC = TRUE;\r
164 }\r
165 if(Uart.drop == DROP_FIRST_HALF) {\r
166 // we see a '0'\r
167 Uart.state = STATE_MILLER_Z;\r
168 }\r
169 if(Uart.drop == DROP_SECOND_HALF) {\r
170 // We see a '1' and go to state X\r
171 Uart.shiftReg |= 0x100;\r
172 Uart.state = STATE_MILLER_X;\r
173 }\r
174 break;\r
175\r
176 case STATE_ERROR_WAIT:\r
177 // That went wrong. Now wait for at least two bit periods\r
178 // and try to sync again\r
179 if(Uart.drop == DROP_NONE) {\r
180 Uart.highCnt = 6;\r
181 Uart.state = STATE_UNSYNCD;\r
182 }\r
183 break;\r
184\r
185 default:\r
186 Uart.state = STATE_UNSYNCD;\r
187 Uart.highCnt = 0;\r
188 break;\r
189 }\r
190\r
191 Uart.drop = DROP_NONE;\r
192\r
193 // should have received at least one whole byte...\r
194 if((Uart.bitCnt == 2) && EOC && (Uart.byteCnt > 0)) {\r
195 return TRUE;\r
196 }\r
197\r
198 if(Uart.bitCnt == 9) {\r
199 Uart.output[Uart.byteCnt] = (Uart.shiftReg & 0xff);\r
200 Uart.byteCnt++;\r
201\r
202 Uart.parityBits <<= 1;\r
203 Uart.parityBits ^= ((Uart.shiftReg >> 8) & 0x01);\r
204\r
205 if(EOC) {\r
206 // when End of Communication received and\r
207 // all data bits processed..\r
208 return TRUE;\r
209 }\r
210 Uart.bitCnt = 0;\r
211 }\r
212\r
213 /*if(error) {\r
214 Uart.output[Uart.byteCnt] = 0xAA;\r
215 Uart.byteCnt++;\r
216 Uart.output[Uart.byteCnt] = error & 0xFF;\r
217 Uart.byteCnt++;\r
218 Uart.output[Uart.byteCnt] = 0xAA;\r
219 Uart.byteCnt++;\r
220 Uart.output[Uart.byteCnt] = (Uart.bitBuffer >> 8) & 0xFF;\r
221 Uart.byteCnt++;\r
222 Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF;\r
223 Uart.byteCnt++;\r
224 Uart.output[Uart.byteCnt] = (Uart.syncBit >> 3) & 0xFF;\r
225 Uart.byteCnt++;\r
226 Uart.output[Uart.byteCnt] = 0xAA;\r
227 Uart.byteCnt++;\r
228 return TRUE;\r
229 }*/\r
230 }\r
231\r
232 }\r
233 else {\r
234 bit = Uart.bitBuffer & 0xf0;\r
235 bit >>= 4;\r
236 bit ^= 0x0F;\r
237 if(bit) {\r
238 // should have been high or at least (4 * 128) / fc\r
239 // according to ISO this should be at least (9 * 128 + 20) / fc\r
240 if(Uart.highCnt == 8) {\r
241 // we went low, so this could be start of communication\r
242 // it turns out to be safer to choose a less significant\r
243 // syncbit... so we check whether the neighbour also represents the drop\r
244 Uart.posCnt = 1; // apparently we are busy with our first half bit period\r
245 Uart.syncBit = bit & 8;\r
246 Uart.samples = 3;\r
247 if(!Uart.syncBit) { Uart.syncBit = bit & 4; Uart.samples = 2; }\r
248 else if(bit & 4) { Uart.syncBit = bit & 4; Uart.samples = 2; bit <<= 2; }\r
249 if(!Uart.syncBit) { Uart.syncBit = bit & 2; Uart.samples = 1; }\r
250 else if(bit & 2) { Uart.syncBit = bit & 2; Uart.samples = 1; bit <<= 1; }\r
251 if(!Uart.syncBit) { Uart.syncBit = bit & 1; Uart.samples = 0;\r
252 if(Uart.syncBit & (Uart.bitBuffer & 8)) {\r
253 Uart.syncBit = 8;\r
254\r
255 // the first half bit period is expected in next sample\r
256 Uart.posCnt = 0;\r
257 Uart.samples = 3;\r
258 }\r
259 }\r
260 else if(bit & 1) { Uart.syncBit = bit & 1; Uart.samples = 0; }\r
261\r
262 Uart.syncBit <<= 4;\r
263 Uart.state = STATE_START_OF_COMMUNICATION;\r
264 Uart.drop = DROP_FIRST_HALF;\r
265 Uart.bitCnt = 0;\r
266 Uart.byteCnt = 0;\r
267 Uart.parityBits = 0;\r
268 error = 0;\r
269 }\r
270 else {\r
271 Uart.highCnt = 0;\r
272 }\r
273 }\r
274 else {\r
275 if(Uart.highCnt < 8) {\r
276 Uart.highCnt++;\r
277 }\r
278 }\r
279 }\r
280\r
281 return FALSE;\r
282}\r
283\r
284//=============================================================================\r
285// ISO 14443 Type A - Manchester\r
286//=============================================================================\r
287\r
288static struct {\r
289 enum {\r
290 DEMOD_UNSYNCD,\r
291 DEMOD_START_OF_COMMUNICATION,\r
292 DEMOD_MANCHESTER_D,\r
293 DEMOD_MANCHESTER_E,\r
294 DEMOD_MANCHESTER_F,\r
295 DEMOD_ERROR_WAIT\r
296 } state;\r
297 int bitCount;\r
298 int posCount;\r
299 int syncBit;\r
300 int parityBits;\r
301 WORD shiftReg;\r
302 int buffer;\r
303 int buff;\r
304 int samples;\r
305 int len;\r
306 enum {\r
307 SUB_NONE,\r
308 SUB_FIRST_HALF,\r
309 SUB_SECOND_HALF\r
310 } sub;\r
311 BYTE *output;\r
312} Demod;\r
313\r
314static BOOL ManchesterDecoding(int v)\r
315{\r
316 int bit;\r
317 int modulation;\r
318 int error = 0;\r
319\r
320 if(!Demod.buff) {\r
321 Demod.buff = 1;\r
322 Demod.buffer = v;\r
323 return FALSE;\r
324 }\r
325 else {\r
326 bit = Demod.buffer;\r
327 Demod.buffer = v;\r
328 }\r
329\r
330 if(Demod.state==DEMOD_UNSYNCD) {\r
331 Demod.output[Demod.len] = 0xfa;\r
332 Demod.syncBit = 0;\r
333 //Demod.samples = 0;\r
334 Demod.posCount = 1; // This is the first half bit period, so after syncing handle the second part\r
335 if(bit & 0x08) { Demod.syncBit = 0x08; }\r
336 if(!Demod.syncBit) {\r
337 if(bit & 0x04) { Demod.syncBit = 0x04; }\r
338 }\r
339 else if(bit & 0x04) { Demod.syncBit = 0x04; bit <<= 4; }\r
340 if(!Demod.syncBit) {\r
341 if(bit & 0x02) { Demod.syncBit = 0x02; }\r
342 }\r
343 else if(bit & 0x02) { Demod.syncBit = 0x02; bit <<= 4; }\r
344 if(!Demod.syncBit) {\r
345 if(bit & 0x01) { Demod.syncBit = 0x01; }\r
346\r
347 if(Demod.syncBit & (Demod.buffer & 0x08)) {\r
348 Demod.syncBit = 0x08;\r
349\r
350 // The first half bitperiod is expected in next sample\r
351 Demod.posCount = 0;\r
352 Demod.output[Demod.len] = 0xfb;\r
353 }\r
354 }\r
355 else if(bit & 0x01) { Demod.syncBit = 0x01; }\r
356\r
357 if(Demod.syncBit) {\r
358 Demod.len = 0;\r
359 Demod.state = DEMOD_START_OF_COMMUNICATION;\r
360 Demod.sub = SUB_FIRST_HALF;\r
361 Demod.bitCount = 0;\r
362 Demod.shiftReg = 0;\r
363 Demod.parityBits = 0;\r
364 Demod.samples = 0;\r
365 if(Demod.posCount) {\r
366 switch(Demod.syncBit) {\r
367 case 0x08: Demod.samples = 3; break;\r
368 case 0x04: Demod.samples = 2; break;\r
369 case 0x02: Demod.samples = 1; break;\r
370 case 0x01: Demod.samples = 0; break;\r
371 }\r
372 }\r
373 error = 0;\r
374 }\r
375 }\r
376 else {\r
377 //modulation = bit & Demod.syncBit;\r
378 modulation = ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit;\r
379\r
380 Demod.samples += 4;\r
381\r
382 if(Demod.posCount==0) {\r
383 Demod.posCount = 1;\r
384 if(modulation) {\r
385 Demod.sub = SUB_FIRST_HALF;\r
386 }\r
387 else {\r
388 Demod.sub = SUB_NONE;\r
389 }\r
390 }\r
391 else {\r
392 Demod.posCount = 0;\r
393 if(modulation && (Demod.sub == SUB_FIRST_HALF)) {\r
394 if(Demod.state!=DEMOD_ERROR_WAIT) {\r
395 Demod.state = DEMOD_ERROR_WAIT;\r
396 Demod.output[Demod.len] = 0xaa;\r
397 error = 0x01;\r
398 }\r
399 }\r
400 else if(modulation) {\r
401 Demod.sub = SUB_SECOND_HALF;\r
402 }\r
403\r
404 switch(Demod.state) {\r
405 case DEMOD_START_OF_COMMUNICATION:\r
406 if(Demod.sub == SUB_FIRST_HALF) {\r
407 Demod.state = DEMOD_MANCHESTER_D;\r
408 }\r
409 else {\r
410 Demod.output[Demod.len] = 0xab;\r
411 Demod.state = DEMOD_ERROR_WAIT;\r
412 error = 0x02;\r
413 }\r
414 break;\r
415\r
416 case DEMOD_MANCHESTER_D:\r
417 case DEMOD_MANCHESTER_E:\r
418 if(Demod.sub == SUB_FIRST_HALF) {\r
419 Demod.bitCount++;\r
420 Demod.shiftReg = (Demod.shiftReg >> 1) ^ 0x100;\r
421 Demod.state = DEMOD_MANCHESTER_D;\r
422 }\r
423 else if(Demod.sub == SUB_SECOND_HALF) {\r
424 Demod.bitCount++;\r
425 Demod.shiftReg >>= 1;\r
426 Demod.state = DEMOD_MANCHESTER_E;\r
427 }\r
428 else {\r
429 Demod.state = DEMOD_MANCHESTER_F;\r
430 }\r
431 break;\r
432\r
433 case DEMOD_MANCHESTER_F:\r
434 // Tag response does not need to be a complete byte!\r
435 if(Demod.len > 0 || Demod.bitCount > 0) {\r
436 if(Demod.bitCount > 0) {\r
437 Demod.shiftReg >>= (9 - Demod.bitCount);\r
438 Demod.output[Demod.len] = Demod.shiftReg & 0xff;\r
439 Demod.len++;\r
440 // No parity bit, so just shift a 0\r
441 Demod.parityBits <<= 1;\r
442 }\r
443\r
444 Demod.state = DEMOD_UNSYNCD;\r
445 return TRUE;\r
446 }\r
447 else {\r
448 Demod.output[Demod.len] = 0xad;\r
449 Demod.state = DEMOD_ERROR_WAIT;\r
450 error = 0x03;\r
451 }\r
452 break;\r
453\r
454 case DEMOD_ERROR_WAIT:\r
455 Demod.state = DEMOD_UNSYNCD;\r
456 break;\r
457\r
458 default:\r
459 Demod.output[Demod.len] = 0xdd;\r
460 Demod.state = DEMOD_UNSYNCD;\r
461 break;\r
462 }\r
463\r
464 if(Demod.bitCount>=9) {\r
465 Demod.output[Demod.len] = Demod.shiftReg & 0xff;\r
466 Demod.len++;\r
467\r
468 Demod.parityBits <<= 1;\r
469 Demod.parityBits ^= ((Demod.shiftReg >> 8) & 0x01);\r
470\r
471 Demod.bitCount = 0;\r
472 Demod.shiftReg = 0;\r
473 }\r
474\r
475 /*if(error) {\r
476 Demod.output[Demod.len] = 0xBB;\r
477 Demod.len++;\r
478 Demod.output[Demod.len] = error & 0xFF;\r
479 Demod.len++;\r
480 Demod.output[Demod.len] = 0xBB;\r
481 Demod.len++;\r
482 Demod.output[Demod.len] = bit & 0xFF;\r
483 Demod.len++;\r
484 Demod.output[Demod.len] = Demod.buffer & 0xFF;\r
485 Demod.len++;\r
486 Demod.output[Demod.len] = Demod.syncBit & 0xFF;\r
487 Demod.len++;\r
488 Demod.output[Demod.len] = 0xBB;\r
489 Demod.len++;\r
490 return TRUE;\r
491 }*/\r
492\r
493 }\r
494\r
495 } // end (state != UNSYNCED)\r
496\r
497 return FALSE;\r
498}\r
499\r
500//=============================================================================\r
501// Finally, a `sniffer' for ISO 14443 Type A\r
502// Both sides of communication!\r
503//=============================================================================\r
504\r
505//-----------------------------------------------------------------------------\r
506// Record the sequence of commands sent by the reader to the tag, with\r
507// triggering so that we start recording at the point that the tag is moved\r
508// near the reader.\r
509//-----------------------------------------------------------------------------\r
510void SnoopIso14443a(void)\r
511{\r
512\r
513 // BIG CHANGE - UNDERSTAND THIS BEFORE WE COMMIT\r
514\r
515 #define RECV_CMD_OFFSET 3032\r
516 #define RECV_RES_OFFSET 3096\r
517 #define DMA_BUFFER_OFFSET 3160\r
518 #define DMA_BUFFER_SIZE 4096\r
519 #define TRACE_LENGTH 3000 \r
520 \r
521// #define RECV_CMD_OFFSET 2032 // original (working as of 21/2/09) values\r
522// #define RECV_RES_OFFSET 2096 // original (working as of 21/2/09) values\r
523// #define DMA_BUFFER_OFFSET 2160 // original (working as of 21/2/09) values\r
524// #define DMA_BUFFER_SIZE 4096 // original (working as of 21/2/09) values\r
525// #define TRACE_LENGTH 2000 // original (working as of 21/2/09) values\r
526\r
527 // We won't start recording the frames that we acquire until we trigger;\r
528 // a good trigger condition to get started is probably when we see a\r
529 // response from the tag.\r
530 BOOL triggered = TRUE; // FALSE to wait first for card\r
531\r
532 // The command (reader -> tag) that we're receiving.\r
533 // The length of a received command will in most cases be no more than 18 bytes.\r
534 // So 32 should be enough!\r
535 BYTE *receivedCmd = (((BYTE *)BigBuf) + RECV_CMD_OFFSET);\r
536 // The response (tag -> reader) that we're receiving.\r
537 BYTE *receivedResponse = (((BYTE *)BigBuf) + RECV_RES_OFFSET);\r
538\r
539 // As we receive stuff, we copy it from receivedCmd or receivedResponse\r
540 // into trace, along with its length and other annotations.\r
541 BYTE *trace = (BYTE *)BigBuf;\r
542 int traceLen = 0;\r
543\r
544 // The DMA buffer, used to stream samples from the FPGA\r
545 SBYTE *dmaBuf = ((SBYTE *)BigBuf) + DMA_BUFFER_OFFSET;\r
546 int lastRxCounter;\r
547 SBYTE *upTo;\r
548 int smpl;\r
549 int maxBehindBy = 0;\r
550\r
551 // Count of samples received so far, so that we can include timing\r
552 // information in the trace buffer.\r
553 int samples = 0;\r
554 int rsamples = 0;\r
555\r
556 memset(trace, 0x44, RECV_CMD_OFFSET);\r
557\r
558 // Set up the demodulator for tag -> reader responses.\r
559 Demod.output = receivedResponse;\r
560 Demod.len = 0;\r
561 Demod.state = DEMOD_UNSYNCD;\r
562\r
563 // And the reader -> tag commands\r
564 memset(&Uart, 0, sizeof(Uart));\r
565 Uart.output = receivedCmd;\r
566 Uart.byteCntMax = 32; // was 100 (greg)////////////////////////////////////////////////////////////////////////\r
567 Uart.state = STATE_UNSYNCD;\r
568\r
569 // And put the FPGA in the appropriate mode\r
570 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);\r
571 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
572\r
573 // Setup for the DMA.\r
574 FpgaSetupSsc();\r
575 upTo = dmaBuf;\r
576 lastRxCounter = DMA_BUFFER_SIZE;\r
577 FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE);\r
578\r
579 LED_A_ON();\r
580\r
581 // And now we loop, receiving samples.\r
582 for(;;) {\r
583 WDT_HIT();\r
584 int behindBy = (lastRxCounter - PDC_RX_COUNTER(SSC_BASE)) &\r
585 (DMA_BUFFER_SIZE-1);\r
586 if(behindBy > maxBehindBy) {\r
587 maxBehindBy = behindBy;\r
588 if(behindBy > 400) {\r
589 DbpString("blew circular buffer!");\r
590 goto done;\r
591 }\r
592 }\r
593 if(behindBy < 1) continue;\r
594\r
595 smpl = upTo[0];\r
596 upTo++;\r
597 lastRxCounter -= 1;\r
598 if(upTo - dmaBuf > DMA_BUFFER_SIZE) {\r
599 upTo -= DMA_BUFFER_SIZE;\r
600 lastRxCounter += DMA_BUFFER_SIZE;\r
601 PDC_RX_NEXT_POINTER(SSC_BASE) = (DWORD)upTo;\r
602 PDC_RX_NEXT_COUNTER(SSC_BASE) = DMA_BUFFER_SIZE;\r
603 }\r
604\r
605 samples += 4;\r
606#define HANDLE_BIT_IF_BODY \\r
607 LED_C_ON(); \\r
608 if(triggered) { \\r
609 trace[traceLen++] = ((rsamples >> 0) & 0xff); \\r
610 trace[traceLen++] = ((rsamples >> 8) & 0xff); \\r
611 trace[traceLen++] = ((rsamples >> 16) & 0xff); \\r
612 trace[traceLen++] = ((rsamples >> 24) & 0xff); \\r
613 trace[traceLen++] = ((Uart.parityBits >> 0) & 0xff); \\r
614 trace[traceLen++] = ((Uart.parityBits >> 8) & 0xff); \\r
615 trace[traceLen++] = ((Uart.parityBits >> 16) & 0xff); \\r
616 trace[traceLen++] = ((Uart.parityBits >> 24) & 0xff); \\r
617 trace[traceLen++] = Uart.byteCnt; \\r
618 memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \\r
619 traceLen += Uart.byteCnt; \\r
620 if(traceLen > TRACE_LENGTH) break; \\r
621 } \\r
622 /* And ready to receive another command. */ \\r
623 Uart.state = STATE_UNSYNCD; \\r
624 /* And also reset the demod code, which might have been */ \\r
625 /* false-triggered by the commands from the reader. */ \\r
626 Demod.state = DEMOD_UNSYNCD; \\r
627 LED_B_OFF(); \\r
628\r
629 if(MillerDecoding((smpl & 0xF0) >> 4)) {\r
630 rsamples = samples - Uart.samples;\r
631 HANDLE_BIT_IF_BODY\r
632 }\r
633 if(ManchesterDecoding(smpl & 0x0F)) {\r
634 rsamples = samples - Demod.samples;\r
635 LED_B_ON();\r
636\r
637 // timestamp, as a count of samples\r
638 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
639 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
640 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
641 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
642 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
643 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
644 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
645 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
646 // length\r
647 trace[traceLen++] = Demod.len;\r
648 memcpy(trace+traceLen, receivedResponse, Demod.len);\r
649 traceLen += Demod.len;\r
650 if(traceLen > TRACE_LENGTH) break;\r
651\r
652 triggered = TRUE;\r
653\r
654 // And ready to receive another response.\r
655 memset(&Demod, 0, sizeof(Demod));\r
656 Demod.output = receivedResponse;\r
657 Demod.state = DEMOD_UNSYNCD;\r
658 LED_C_OFF();\r
659 }\r
660\r
661 if(BUTTON_PRESS()) {\r
662 DbpString("cancelled_a");\r
663 goto done;\r
664 }\r
665 }\r
666\r
667 DbpString("COMMAND FINISHED");\r
668\r
669 DbpIntegers(maxBehindBy, Uart.state, Uart.byteCnt);\r
670 DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
671\r
672done:\r
673 PDC_CONTROL(SSC_BASE) = PDC_RX_DISABLE;\r
674 DbpIntegers(maxBehindBy, Uart.state, Uart.byteCnt);\r
675 DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
676 LED_A_OFF();\r
677 LED_B_OFF();\r
678 LED_C_OFF();\r
679 LED_D_OFF();\r
680}\r
681\r
682// Prepare communication bits to send to FPGA\r
683void Sequence(SecType seq)\r
684{\r
685 ToSendMax++;\r
686 switch(seq) {\r
687 // CARD TO READER\r
688 case SEC_D:\r
689 // Sequence D: 11110000\r
690 // modulation with subcarrier during first half\r
691 ToSend[ToSendMax] = 0xf0;\r
692 break;\r
693 case SEC_E:\r
694 // Sequence E: 00001111\r
695 // modulation with subcarrier during second half\r
696 ToSend[ToSendMax] = 0x0f;\r
697 break;\r
698 case SEC_F:\r
699 // Sequence F: 00000000\r
700 // no modulation with subcarrier\r
701 ToSend[ToSendMax] = 0x00;\r
702 break;\r
703 // READER TO CARD\r
704 case SEC_X:\r
705 // Sequence X: 00001100\r
706 // drop after half a period\r
707 ToSend[ToSendMax] = 0x0c;\r
708 break;\r
709 case SEC_Y:\r
710 default:\r
711 // Sequence Y: 00000000\r
712 // no drop\r
713 ToSend[ToSendMax] = 0x00;\r
714 break;\r
715 case SEC_Z:\r
716 // Sequence Z: 11000000\r
717 // drop at start\r
718 ToSend[ToSendMax] = 0xc0;\r
719 break;\r
720 }\r
721}\r
722\r
723//-----------------------------------------------------------------------------\r
724// Prepare tag messages\r
725//-----------------------------------------------------------------------------\r
726static void CodeIso14443aAsTag(const BYTE *cmd, int len)\r
727{\r
728 int i;\r
729 int oddparity;\r
730\r
731 ToSendReset();\r
732\r
733 // Correction bit, might be removed when not needed\r
734 ToSendStuffBit(0);\r
735 ToSendStuffBit(0);\r
736 ToSendStuffBit(0);\r
737 ToSendStuffBit(0);\r
738 ToSendStuffBit(1); // 1\r
739 ToSendStuffBit(0);\r
740 ToSendStuffBit(0);\r
741 ToSendStuffBit(0);\r
742\r
743 // Send startbit\r
744 Sequence(SEC_D);\r
745\r
746 for(i = 0; i < len; i++) {\r
747 int j;\r
748 BYTE b = cmd[i];\r
749\r
750 // Data bits\r
751 oddparity = 0x01;\r
752 for(j = 0; j < 8; j++) {\r
753 oddparity ^= (b & 1);\r
754 if(b & 1) {\r
755 Sequence(SEC_D);\r
756 } else {\r
757 Sequence(SEC_E);\r
758 }\r
759 b >>= 1;\r
760 }\r
761\r
762 // Parity bit\r
763 if(oddparity) {\r
764 Sequence(SEC_D);\r
765 } else {\r
766 Sequence(SEC_E);\r
767 }\r
768 }\r
769\r
770 // Send stopbit\r
771 Sequence(SEC_F);\r
772\r
773 // Flush the buffer in FPGA!!\r
774 for(i = 0; i < 5; i++) {\r
775 Sequence(SEC_F);\r
776 }\r
777\r
778 // Convert from last byte pos to length\r
779 ToSendMax++;\r
780\r
781 // Add a few more for slop\r
782 ToSend[ToSendMax++] = 0x00;\r
783 ToSend[ToSendMax++] = 0x00;\r
784 //ToSendMax += 2;\r
785}\r
786\r
787//-----------------------------------------------------------------------------\r
788// This is to send a NACK kind of answer, its only 3 bits, I know it should be 4\r
789//-----------------------------------------------------------------------------\r
790static void CodeStrangeAnswer()\r
791{\r
792 int i;\r
793\r
794 ToSendReset();\r
795\r
796 // Correction bit, might be removed when not needed\r
797 ToSendStuffBit(0);\r
798 ToSendStuffBit(0);\r
799 ToSendStuffBit(0);\r
800 ToSendStuffBit(0);\r
801 ToSendStuffBit(1); // 1\r
802 ToSendStuffBit(0);\r
803 ToSendStuffBit(0);\r
804 ToSendStuffBit(0);\r
805\r
806 // Send startbit\r
807 Sequence(SEC_D);\r
808\r
809 // 0\r
810 Sequence(SEC_E);\r
811\r
812 // 0\r
813 Sequence(SEC_E);\r
814\r
815 // 1\r
816 Sequence(SEC_D);\r
817\r
818 // Send stopbit\r
819 Sequence(SEC_F);\r
820\r
821 // Flush the buffer in FPGA!!\r
822 for(i = 0; i < 5; i++) {\r
823 Sequence(SEC_F);\r
824 }\r
825\r
826 // Convert from last byte pos to length\r
827 ToSendMax++;\r
828\r
829 // Add a few more for slop\r
830 ToSend[ToSendMax++] = 0x00;\r
831 ToSend[ToSendMax++] = 0x00;\r
832 //ToSendMax += 2;\r
833}\r
834\r
835//-----------------------------------------------------------------------------\r
836// Wait for commands from reader\r
837// Stop when button is pressed\r
838// Or return TRUE when command is captured\r
839//-----------------------------------------------------------------------------\r
840static BOOL GetIso14443aCommandFromReader(BYTE *received, int *len, int maxLen)\r
841{\r
842 // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen\r
843 // only, since we are receiving, not transmitting).\r
844 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);\r
845\r
846 // Now run a `software UART' on the stream of incoming samples.\r
847 Uart.output = received;\r
848 Uart.byteCntMax = maxLen;\r
849 Uart.state = STATE_UNSYNCD;\r
850\r
851 for(;;) {\r
852 WDT_HIT();\r
853\r
854 if(BUTTON_PRESS()) return FALSE;\r
855\r
856 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
857 SSC_TRANSMIT_HOLDING = 0x00;\r
858 }\r
859 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
860 BYTE b = (BYTE)SSC_RECEIVE_HOLDING;\r
861 if(MillerDecoding((b & 0xf0) >> 4)) {\r
862 *len = Uart.byteCnt;\r
863 return TRUE;\r
864 }\r
865 if(MillerDecoding(b & 0x0f)) {\r
866 *len = Uart.byteCnt;\r
867 return TRUE;\r
868 }\r
869 }\r
870 }\r
871}\r
872\r
873//-----------------------------------------------------------------------------\r
874// Main loop of simulated tag: receive commands from reader, decide what\r
875// response to send, and send it.\r
876//-----------------------------------------------------------------------------\r
877void SimulateIso14443aTag(int tagType, int TagUid)\r
878{\r
879 // This function contains the tag emulation\r
880\r
881 // Prepare protocol messages\r
882 // static const BYTE cmd1[] = { 0x26 };\r
883// static const BYTE response1[] = { 0x02, 0x00 }; // Says: I am Mifare 4k - original line - greg\r
884//\r
885 static const BYTE response1[] = { 0x44, 0x03 }; // Says: I am a DESFire Tag, ph33r me\r
886// static const BYTE response1[] = { 0x44, 0x00 }; // Says: I am a ULTRALITE Tag, 0wn me\r
887\r
888 // UID response\r
889 // static const BYTE cmd2[] = { 0x93, 0x20 };\r
890 //static const BYTE response2[] = { 0x9a, 0xe5, 0xe4, 0x43, 0xd8 }; // original value - greg\r
891\r
892\r
893\r
894// my desfire\r
895 static const BYTE response2[] = { 0x88, 0x04, 0x21, 0x3f, 0x4d }; // known uid - note cascade (0x88), 2nd byte (0x04) = NXP/Phillips\r
896 \r
897 \r
898// When reader selects us during cascade1 it will send cmd3\r
899//BYTE response3[] = { 0x04, 0x00, 0x00 }; // SAK Select (cascade1) successful response (ULTRALITE)\r
900BYTE response3[] = { 0x24, 0x00, 0x00 }; // SAK Select (cascade1) successful response (DESFire)\r
901ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);\r
902\r
903// send cascade2 2nd half of UID\r
904static const BYTE response2a[] = { 0x51, 0x48, 0x1d, 0x80, 0x84 }; // uid - cascade2 - 2nd half (4 bytes) of UID+ BCCheck\r
905// NOTE : THE CRC on the above may be wrong as I have obfuscated the actual UID\r
906\r
907\r
908// When reader selects us during cascade2 it will send cmd3a\r
909//BYTE response3a[] = { 0x00, 0x00, 0x00 }; // SAK Select (cascade2) successful response (ULTRALITE)\r
910BYTE response3a[] = { 0x20, 0x00, 0x00 }; // SAK Select (cascade2) successful response (DESFire)\r
911ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);\r
912 \r
913// When reader tries to authenticate\r
914 // static const BYTE cmd5[] = { 0x60, 0x00, 0xf5, 0x7b };\r
915 static const BYTE response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce\r
916\r
917 BYTE *resp;\r
918 int respLen;\r
919\r
920 // Longest possible response will be 16 bytes + 2 CRC = 18 bytes\r
921 // This will need\r
922 // 144 data bits (18 * 8)\r
923 // 18 parity bits\r
924 // 2 Start and stop\r
925 // 1 Correction bit (Answer in 1172 or 1236 periods, see FPGA)\r
926 // 1 just for the case\r
927 // ----------- +\r
928 // 166\r
929 //\r
930 // 166 bytes, since every bit that needs to be send costs us a byte\r
931 //\r
932\r
933\r
934 // Respond with card type\r
935 BYTE *resp1 = (((BYTE *)BigBuf) + 800);\r
936 int resp1Len;\r
937\r
938 // Anticollision cascade1 - respond with uid\r
939 BYTE *resp2 = (((BYTE *)BigBuf) + 970);\r
940 int resp2Len;\r
941\r
942 // Anticollision cascade2 - respond with 2nd half of uid if asked\r
943 // we're only going to be asked if we set the 1st byte of the UID (during cascade1) to 0x88\r
944 BYTE *resp2a = (((BYTE *)BigBuf) + 1140);\r
945 int resp2aLen;\r
946\r
947 // Acknowledge select - cascade 1\r
948 BYTE *resp3 = (((BYTE *)BigBuf) + 1310);\r
949 int resp3Len;\r
950\r
951 // Acknowledge select - cascade 2\r
952 BYTE *resp3a = (((BYTE *)BigBuf) + 1480);\r
953 int resp3aLen;\r
954\r
955 // Response to a read request - not implemented atm\r
956 BYTE *resp4 = (((BYTE *)BigBuf) + 1550);\r
957 int resp4Len;\r
958\r
959 // Authenticate response - nonce\r
960 BYTE *resp5 = (((BYTE *)BigBuf) + 1720);\r
961 int resp5Len;\r
962\r
963 BYTE *receivedCmd = (BYTE *)BigBuf;\r
964 int len;\r
965\r
966 int i;\r
967 int u;\r
968 BYTE b;\r
969\r
970 // To control where we are in the protocol\r
971 int order = 0;\r
972 int lastorder;\r
973\r
974 // Just to allow some checks\r
975 int happened = 0;\r
976 int happened2 = 0;\r
977\r
978 int cmdsRecvd = 0;\r
979\r
980 BOOL fdt_indicator;\r
981\r
982 memset(receivedCmd, 0x44, 400);\r
983\r
984 // Prepare the responses of the anticollision phase\r
985 // there will be not enough time to do this at the moment the reader sends it REQA\r
986\r
987 // Answer to request\r
988 CodeIso14443aAsTag(response1, sizeof(response1));\r
989 memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;\r
990\r
991 // Send our UID (cascade 1)\r
992 CodeIso14443aAsTag(response2, sizeof(response2));\r
993 memcpy(resp2, ToSend, ToSendMax); resp2Len = ToSendMax;\r
994\r
995 // Answer to select (cascade1)\r
996 CodeIso14443aAsTag(response3, sizeof(response3));\r
997 memcpy(resp3, ToSend, ToSendMax); resp3Len = ToSendMax;\r
998\r
999 // Send the cascade 2 2nd part of the uid\r
1000 CodeIso14443aAsTag(response2a, sizeof(response2a));\r
1001 memcpy(resp2a, ToSend, ToSendMax); resp2aLen = ToSendMax;\r
1002\r
1003 // Answer to select (cascade 2)\r
1004 CodeIso14443aAsTag(response3a, sizeof(response3a));\r
1005 memcpy(resp3a, ToSend, ToSendMax); resp3aLen = ToSendMax;\r
1006\r
1007 // Strange answer is an example of rare message size (3 bits)\r
1008 CodeStrangeAnswer();\r
1009 memcpy(resp4, ToSend, ToSendMax); resp4Len = ToSendMax;\r
1010\r
1011 // Authentication answer (random nonce)\r
1012 CodeIso14443aAsTag(response5, sizeof(response5));\r
1013 memcpy(resp5, ToSend, ToSendMax); resp5Len = ToSendMax;\r
1014\r
1015 // We need to listen to the high-frequency, peak-detected path.\r
1016 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1017 FpgaSetupSsc();\r
1018\r
1019 cmdsRecvd = 0;\r
1020\r
1021 LED_A_ON();\r
1022 for(;;) {\r
1023\r
1024 if(!GetIso14443aCommandFromReader(receivedCmd, &len, 100)) {\r
1025 DbpString("button press");\r
1026 break;\r
1027 }\r
1028 // doob - added loads of debug strings so we can see what the reader is saying to us during the sim as hi14alist is not populated\r
1029 // Okay, look at the command now.\r
1030 lastorder = order;\r
1031 i = 1; // first byte transmitted\r
1032 if(receivedCmd[0] == 0x26) {\r
1033 // Received a REQUEST\r
1034 resp = resp1; respLen = resp1Len; order = 1;\r
1035 //DbpString("Hello request from reader:");\r
1036 } else if(receivedCmd[0] == 0x52) {\r
1037 // Received a WAKEUP\r
1038 resp = resp1; respLen = resp1Len; order = 6;\r
1039// //DbpString("Wakeup request from reader:");\r
1040\r
1041 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x93) { // greg - cascade 1 anti-collision\r
1042 // Received request for UID (cascade 1)\r
1043 resp = resp2; respLen = resp2Len; order = 2;\r
1044// DbpString("UID (cascade 1) request from reader:");\r
1045// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1046\r
1047\r
1048 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] ==0x95) { // greg - cascade 2 anti-collision\r
1049 // Received request for UID (cascade 2)\r
1050 resp = resp2a; respLen = resp2aLen; order = 20;\r
1051// DbpString("UID (cascade 2) request from reader:");\r
1052// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1053\r
1054\r
1055 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x93) { // greg - cascade 1 select\r
1056 // Received a SELECT\r
1057 resp = resp3; respLen = resp3Len; order = 3;\r
1058// DbpString("Select (cascade 1) request from reader:");\r
1059// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1060\r
1061\r
1062 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x95) { // greg - cascade 2 select\r
1063 // Received a SELECT\r
1064 resp = resp3a; respLen = resp3aLen; order = 30;\r
1065// DbpString("Select (cascade 2) request from reader:");\r
1066// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1067\r
1068\r
1069 } else if(receivedCmd[0] == 0x30) {\r
1070 // Received a READ\r
1071 resp = resp4; respLen = resp4Len; order = 4; // Do nothing\r
1072 DbpString("Read request from reader:");\r
1073 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1074\r
1075\r
1076 } else if(receivedCmd[0] == 0x50) {\r
1077 // Received a HALT\r
1078 resp = resp1; respLen = 0; order = 5; // Do nothing\r
1079 DbpString("Reader requested we HALT!:");\r
1080\r
1081 } else if(receivedCmd[0] == 0x60) {\r
1082 // Received an authentication request\r
1083 resp = resp5; respLen = resp5Len; order = 7;\r
1084 DbpString("Authenticate request from reader:");\r
1085 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1086\r
1087 } else if(receivedCmd[0] == 0xE0) {\r
1088 // Received a RATS request\r
1089 resp = resp1; respLen = 0;order = 70;\r
1090 DbpString("RATS request from reader:");\r
1091 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1092 } else {\r
1093 // Never seen this command before\r
1094 DbpString("Unknown command received from reader:");\r
1095 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1096 DbpIntegers(receivedCmd[3], receivedCmd[4], receivedCmd[5]);\r
1097 DbpIntegers(receivedCmd[6], receivedCmd[7], receivedCmd[8]);\r
1098\r
1099 // Do not respond\r
1100 resp = resp1; respLen = 0; order = 0;\r
1101 }\r
1102\r
1103 // Count number of wakeups received after a halt\r
1104 if(order == 6 && lastorder == 5) { happened++; }\r
1105\r
1106 // Count number of other messages after a halt\r
1107 if(order != 6 && lastorder == 5) { happened2++; }\r
1108\r
1109 // Look at last parity bit to determine timing of answer\r
1110 if((Uart.parityBits & 0x01) || receivedCmd[0] == 0x52) {\r
1111 // 1236, so correction bit needed\r
1112 i = 0;\r
1113 }\r
1114\r
1115 memset(receivedCmd, 0x44, 32);\r
1116\r
1117 if(cmdsRecvd > 999) {\r
1118 DbpString("1000 commands later...");\r
1119 break;\r
1120 }\r
1121 else {\r
1122 cmdsRecvd++;\r
1123 }\r
1124\r
1125 if(respLen <= 0) continue;\r
1126\r
1127 // Modulate Manchester\r
1128 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);\r
1129 SSC_TRANSMIT_HOLDING = 0x00;\r
1130 FpgaSetupSsc();\r
1131\r
1132 // ### Transmit the response ###\r
1133 u = 0;\r
1134 b = 0x00;\r
1135 fdt_indicator = FALSE;\r
1136 for(;;) {\r
1137 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1138 volatile BYTE b = (BYTE)SSC_RECEIVE_HOLDING;\r
1139 (void)b;\r
1140 }\r
1141 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1142 if(i > respLen) {\r
1143 b = 0x00;\r
1144 u++;\r
1145 } else {\r
1146 b = resp[i];\r
1147 i++;\r
1148 }\r
1149 SSC_TRANSMIT_HOLDING = b;\r
1150\r
1151 if(u > 4) {\r
1152 break;\r
1153 }\r
1154 }\r
1155 if(BUTTON_PRESS()) {\r
1156 break;\r
1157 }\r
1158 }\r
1159\r
1160 }\r
1161\r
1162 DbpIntegers(happened, happened2, cmdsRecvd);\r
1163 LED_A_OFF();\r
1164}\r
1165\r
1166//-----------------------------------------------------------------------------\r
1167// Transmit the command (to the tag) that was placed in ToSend[].\r
1168//-----------------------------------------------------------------------------\r
1169static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait)\r
1170{\r
1171 int c;\r
1172\r
1173 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1174\r
1175 if(*wait < 10) { *wait = 10; }\r
1176\r
1177 for(c = 0; c < *wait;) {\r
1178 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1179 SSC_TRANSMIT_HOLDING = 0x00; // For exact timing!\r
1180 c++;\r
1181 }\r
1182 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1183 volatile DWORD r = SSC_RECEIVE_HOLDING;\r
1184 (void)r;\r
1185 }\r
1186 WDT_HIT();\r
1187 }\r
1188\r
1189 c = 0;\r
1190 for(;;) {\r
1191 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1192 SSC_TRANSMIT_HOLDING = cmd[c];\r
1193 c++;\r
1194 if(c >= len) {\r
1195 break;\r
1196 }\r
1197 }\r
1198 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1199 volatile DWORD r = SSC_RECEIVE_HOLDING;\r
1200 (void)r;\r
1201 }\r
1202 WDT_HIT();\r
1203 }\r
1204 *samples = (c + *wait) << 3;\r
1205}\r
1206\r
1207//-----------------------------------------------------------------------------\r
1208// To generate an arbitrary stream from reader\r
1209//\r
1210//-----------------------------------------------------------------------------\r
1211void ArbitraryFromReader(const BYTE *cmd, int parity, int len)\r
1212{\r
1213 int i;\r
1214 int j;\r
1215 int last;\r
1216 BYTE b;\r
1217\r
1218 ToSendReset();\r
1219\r
1220 // Start of Communication (Seq. Z)\r
1221 Sequence(SEC_Z);\r
1222 last = 0;\r
1223\r
1224 for(i = 0; i < len; i++) {\r
1225 // Data bits\r
1226 b = cmd[i];\r
1227 for(j = 0; j < 8; j++) {\r
1228 if(b & 1) {\r
1229 // Sequence X\r
1230 Sequence(SEC_X);\r
1231 last = 1;\r
1232 } else {\r
1233 if(last == 0) {\r
1234 // Sequence Z\r
1235 Sequence(SEC_Z);\r
1236 }\r
1237 else {\r
1238 // Sequence Y\r
1239 Sequence(SEC_Y);\r
1240 last = 0;\r
1241 }\r
1242 }\r
1243 b >>= 1;\r
1244\r
1245 }\r
1246\r
1247 // Predefined parity bit, the flipper flips when needed, because of flips in byte sent\r
1248 if(((parity >> (len - i - 1)) & 1)) {\r
1249 // Sequence X\r
1250 Sequence(SEC_X);\r
1251 last = 1;\r
1252 } else {\r
1253 if(last == 0) {\r
1254 // Sequence Z\r
1255 Sequence(SEC_Z);\r
1256 }\r
1257 else {\r
1258 // Sequence Y\r
1259 Sequence(SEC_Y);\r
1260 last = 0;\r
1261 }\r
1262 }\r
1263 }\r
1264\r
1265 // End of Communication\r
1266 if(last == 0) {\r
1267 // Sequence Z\r
1268 Sequence(SEC_Z);\r
1269 }\r
1270 else {\r
1271 // Sequence Y\r
1272 Sequence(SEC_Y);\r
1273 last = 0;\r
1274 }\r
1275 // Sequence Y\r
1276 Sequence(SEC_Y);\r
1277\r
1278 // Just to be sure!\r
1279 Sequence(SEC_Y);\r
1280 Sequence(SEC_Y);\r
1281 Sequence(SEC_Y);\r
1282\r
1283 // Convert from last character reference to length\r
1284 ToSendMax++;\r
1285}\r
1286\r
1287//-----------------------------------------------------------------------------\r
1288// Code a 7-bit command without parity bit\r
1289// This is especially for 0x26 and 0x52 (REQA and WUPA)\r
1290//-----------------------------------------------------------------------------\r
1291void ShortFrameFromReader(const BYTE *cmd)\r
1292{\r
1293 int j;\r
1294 int last;\r
1295 BYTE b;\r
1296\r
1297 ToSendReset();\r
1298\r
1299 // Start of Communication (Seq. Z)\r
1300 Sequence(SEC_Z);\r
1301 last = 0;\r
1302\r
1303 b = cmd[0];\r
1304 for(j = 0; j < 7; j++) {\r
1305 if(b & 1) {\r
1306 // Sequence X\r
1307 Sequence(SEC_X);\r
1308 last = 1;\r
1309 } else {\r
1310 if(last == 0) {\r
1311 // Sequence Z\r
1312 Sequence(SEC_Z);\r
1313 }\r
1314 else {\r
1315 // Sequence Y\r
1316 Sequence(SEC_Y);\r
1317 last = 0;\r
1318 }\r
1319 }\r
1320 b >>= 1;\r
1321 }\r
1322\r
1323 // End of Communication\r
1324 if(last == 0) {\r
1325 // Sequence Z\r
1326 Sequence(SEC_Z);\r
1327 }\r
1328 else {\r
1329 // Sequence Y\r
1330 Sequence(SEC_Y);\r
1331 last = 0;\r
1332 }\r
1333 // Sequence Y\r
1334 Sequence(SEC_Y);\r
1335\r
1336 // Just to be sure!\r
1337 Sequence(SEC_Y);\r
1338 Sequence(SEC_Y);\r
1339 Sequence(SEC_Y);\r
1340\r
1341 // Convert from last character reference to length\r
1342 ToSendMax++;\r
1343}\r
1344\r
1345//-----------------------------------------------------------------------------\r
1346// Prepare reader command to send to FPGA\r
1347//\r
1348//-----------------------------------------------------------------------------\r
1349void CodeIso14443aAsReader(const BYTE *cmd, int len)\r
1350{\r
1351 int i, j;\r
1352 int last;\r
1353 int oddparity;\r
1354 BYTE b;\r
1355\r
1356 ToSendReset();\r
1357\r
1358 // Start of Communication (Seq. Z)\r
1359 Sequence(SEC_Z);\r
1360 last = 0;\r
1361\r
1362 for(i = 0; i < len; i++) {\r
1363 // Data bits\r
1364 b = cmd[i];\r
1365 oddparity = 0x01;\r
1366 for(j = 0; j < 8; j++) {\r
1367 oddparity ^= (b & 1);\r
1368 if(b & 1) {\r
1369 // Sequence X\r
1370 Sequence(SEC_X);\r
1371 last = 1;\r
1372 } else {\r
1373 if(last == 0) {\r
1374 // Sequence Z\r
1375 Sequence(SEC_Z);\r
1376 }\r
1377 else {\r
1378 // Sequence Y\r
1379 Sequence(SEC_Y);\r
1380 last = 0;\r
1381 }\r
1382 }\r
1383 b >>= 1;\r
1384 }\r
1385\r
1386 // Parity bit\r
1387 if(oddparity) {\r
1388 // Sequence X\r
1389 Sequence(SEC_X);\r
1390 last = 1;\r
1391 } else {\r
1392 if(last == 0) {\r
1393 // Sequence Z\r
1394 Sequence(SEC_Z);\r
1395 }\r
1396 else {\r
1397 // Sequence Y\r
1398 Sequence(SEC_Y);\r
1399 last = 0;\r
1400 }\r
1401 }\r
1402 }\r
1403\r
1404 // End of Communication\r
1405 if(last == 0) {\r
1406 // Sequence Z\r
1407 Sequence(SEC_Z);\r
1408 }\r
1409 else {\r
1410 // Sequence Y\r
1411 Sequence(SEC_Y);\r
1412 last = 0;\r
1413 }\r
1414 // Sequence Y\r
1415 Sequence(SEC_Y);\r
1416\r
1417 // Just to be sure!\r
1418 Sequence(SEC_Y);\r
1419 Sequence(SEC_Y);\r
1420 Sequence(SEC_Y);\r
1421\r
1422 // Convert from last character reference to length\r
1423 ToSendMax++;\r
1424}\r
1425\r
1426\r
1427//-----------------------------------------------------------------------------\r
1428// Wait a certain time for tag response\r
1429// If a response is captured return TRUE\r
1430// If it takes to long return FALSE\r
1431//-----------------------------------------------------------------------------\r
1432static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *samples, int *elapsed) //BYTE *buffer\r
1433{\r
1434 // buffer needs to be 512 bytes\r
1435 int c;\r
1436\r
1437 // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen\r
1438 // only, since we are receiving, not transmitting).\r
1439 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);\r
1440\r
1441 // Now get the answer from the card\r
1442 Demod.output = receivedResponse;\r
1443 Demod.len = 0;\r
1444 Demod.state = DEMOD_UNSYNCD;\r
1445\r
1446 BYTE b;\r
1447 *elapsed = 0;\r
1448\r
1449 c = 0;\r
1450 for(;;) {\r
1451 WDT_HIT();\r
1452\r
1453 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1454 SSC_TRANSMIT_HOLDING = 0x00; // To make use of exact timing of next command from reader!!\r
1455 (*elapsed)++;\r
1456 }\r
1457 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1458 if(c < 512) { c++; } else { return FALSE; }\r
1459 b = (BYTE)SSC_RECEIVE_HOLDING;\r
1460 if(ManchesterDecoding((b & 0xf0) >> 4)) {\r
1461 *samples = ((c - 1) << 3) + 4;\r
1462 return TRUE;\r
1463 }\r
1464 if(ManchesterDecoding(b & 0x0f)) {\r
1465 *samples = c << 3;\r
1466 return TRUE;\r
1467 }\r
1468 }\r
1469 }\r
1470}\r
1471\r
1472//-----------------------------------------------------------------------------\r
1473// Read an ISO 14443a tag. Send out commands and store answers.\r
1474//\r
1475//-----------------------------------------------------------------------------\r
1476void ReaderIso14443a(DWORD parameter)\r
1477{\r
1478 // Anticollision\r
1479 static const BYTE cmd1[] = { 0x52 }; // or 0x26\r
1480 static const BYTE cmd2[] = { 0x93,0x20 };\r
1481 // UID = 0x2a,0x69,0x8d,0x43,0x8d, last two bytes are CRC bytes\r
1482 BYTE cmd3[] = { 0x93,0x70,0x2a,0x69,0x8d,0x43,0x8d,0x52,0x55 };\r
1483\r
1484 // For Ultralight add an extra anticollission layer -> 95 20 and then 95 70\r
1485\r
1486 // greg - here we will add our cascade level 2 anticolission and select functions to deal with ultralight // and 7-byte UIDs in generall...\r
1487 BYTE cmd4[] = {0x95,0x20}; // ask for cascade 2 select\r
1488 // 95 20\r
1489 //BYTE cmd3a[] = { 0x95,0x70,0x2a,0x69,0x8d,0x43,0x8d,0x52,0x55 };\r
1490 // 95 70\r
1491\r
1492 // cascade 2 select\r
1493 BYTE cmd5[] = { 0x95,0x70,0x2a,0x69,0x8d,0x43,0x8d,0x52,0x55 };\r
1494\r
1495\r
1496 // RATS (request for answer to select)\r
1497 //BYTE cmd6[] = { 0xe0,0x50,0xbc,0xa5 }; // original RATS\r
1498 BYTE cmd6[] = { 0xe0,0x21,0xb2,0xc7 }; // Desfire RATS\r
1499\r
1500 int reqaddr = 2024; // was 2024 - tied to other size changes\r
1501 int reqsize = 60;\r
1502\r
1503 BYTE *req1 = (((BYTE *)BigBuf) + reqaddr);\r
1504 int req1Len;\r
1505\r
1506 BYTE *req2 = (((BYTE *)BigBuf) + reqaddr + reqsize);\r
1507 int req2Len;\r
1508\r
1509 BYTE *req3 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 2));\r
1510 int req3Len;\r
1511\r
1512// greg added req 4 & 5 to deal with cascade 2 section\r
1513 BYTE *req4 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 3));\r
1514 int req4Len;\r
1515\r
1516 BYTE *req5 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 4));\r
1517 int req5Len;\r
1518\r
1519 BYTE *req6 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 5));\r
1520 int req6Len;\r
1521\r
1522 //BYTE *req7 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 6));\r
1523 //int req7Len;\r
1524\r
1525 BYTE *receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes\r
1526\r
1527 BYTE *trace = (BYTE *)BigBuf;\r
1528 int traceLen = 0;\r
1529 int rsamples = 0;\r
1530\r
1531 memset(trace, 0x44, 2000); // was 2000 - tied to oter size chnages \r
1532 // setting it to 3000 causes no tag responses to be detected (2900 is ok)\r
1533 // setting it to 1000 causes no tag responses to be detected\r
1534\r
1535 // Prepare some commands!\r
1536 ShortFrameFromReader(cmd1);\r
1537 memcpy(req1, ToSend, ToSendMax); req1Len = ToSendMax;\r
1538\r
1539 CodeIso14443aAsReader(cmd2, sizeof(cmd2));\r
1540 memcpy(req2, ToSend, ToSendMax); req2Len = ToSendMax;\r
1541\r
1542 CodeIso14443aAsReader(cmd3, sizeof(cmd3));\r
1543 memcpy(req3, ToSend, ToSendMax); req3Len = ToSendMax;\r
1544\r
1545\r
1546 CodeIso14443aAsReader(cmd4, sizeof(cmd4)); // 4 is cascade 2 request\r
1547 memcpy(req4, ToSend, ToSendMax); req4Len = ToSendMax;\r
1548\r
1549\r
1550 CodeIso14443aAsReader(cmd5, sizeof(cmd5)); // 5 is cascade 2 select\r
1551 memcpy(req5, ToSend, ToSendMax); req5Len = ToSendMax;\r
1552\r
1553\r
1554 CodeIso14443aAsReader(cmd6, sizeof(cmd6));\r
1555 memcpy(req6, ToSend, ToSendMax); req6Len = ToSendMax;\r
1556\r
1557 // Setup SSC\r
1558 FpgaSetupSsc();\r
1559\r
1560 // Start from off (no field generated)\r
1561 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1562 SpinDelay(200);\r
1563\r
1564 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1565 FpgaSetupSsc();\r
1566\r
1567 // Now give it time to spin up.\r
1568 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1569 SpinDelay(200);\r
1570\r
1571 LED_A_ON();\r
1572 LED_B_OFF();\r
1573 LED_C_OFF();\r
1574 LED_D_OFF();\r
1575\r
1576 int samples = 0;\r
1577 int tsamples = 0;\r
1578 int wait = 0;\r
1579 int elapsed = 0;\r
1580\r
1581 for(;;) {\r
1582 // Send WUPA (or REQA)\r
1583 TransmitFor14443a(req1, req1Len, &tsamples, &wait);\r
1584 // Store answer in buffer\r
1585 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1586 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1587 trace[traceLen++] = 1;\r
1588 memcpy(trace+traceLen, cmd1, 1);\r
1589 traceLen += 1;\r
1590 if(traceLen > TRACE_LENGTH) goto done;\r
1591\r
1592 while(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1593 if(BUTTON_PRESS()) goto done;\r
1594\r
1595 // No answer, just continue polling\r
1596 TransmitFor14443a(req1, req1Len, &tsamples, &wait);\r
1597 // Store answer in buffer\r
1598 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1599 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1600 trace[traceLen++] = 1;\r
1601 memcpy(trace+traceLen, cmd1, 1);\r
1602 traceLen += 1;\r
1603 if(traceLen > TRACE_LENGTH) goto done;\r
1604 }\r
1605\r
1606 // Store answer in buffer\r
1607 rsamples = rsamples + (samples - Demod.samples);\r
1608 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1609 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1610 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1611 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1612 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1613 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1614 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1615 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1616 trace[traceLen++] = Demod.len;\r
1617 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1618 traceLen += Demod.len;\r
1619 if(traceLen > TRACE_LENGTH) goto done;\r
1620\r
1621 // Ask for card UID\r
1622 TransmitFor14443a(req2, req2Len, &tsamples, &wait);\r
1623 // Store answer in buffer\r
1624 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1625 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1626 trace[traceLen++] = 2;\r
1627 memcpy(trace+traceLen, cmd2, 2);\r
1628 traceLen += 2;\r
1629 if(traceLen > TRACE_LENGTH) goto done;\r
1630\r
1631 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1632 continue;\r
1633 }\r
1634\r
1635 // Store answer in buffer\r
1636 rsamples = rsamples + (samples - Demod.samples);\r
1637 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1638 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1639 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1640 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1641 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1642 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1643 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1644 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1645 trace[traceLen++] = Demod.len;\r
1646 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1647 traceLen += Demod.len;\r
1648 if(traceLen > TRACE_LENGTH) goto done;\r
1649\r
1650 // Construct SELECT UID command\r
1651 // First copy the 5 bytes (Mifare Classic) after the 93 70\r
1652 memcpy(cmd3+2,receivedAnswer,5);\r
1653 // Secondly compute the two CRC bytes at the end\r
1654 ComputeCrc14443(CRC_14443_A, cmd3, 7, &cmd3[7], &cmd3[8]);\r
1655 // Prepare the bit sequence to modulate the subcarrier\r
1656 // Store answer in buffer\r
1657 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1658 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1659 trace[traceLen++] = 9;\r
1660 memcpy(trace+traceLen, cmd3, 9);\r
1661 traceLen += 9;\r
1662 if(traceLen > TRACE_LENGTH) goto done;\r
1663 CodeIso14443aAsReader(cmd3, sizeof(cmd3));\r
1664 memcpy(req3, ToSend, ToSendMax); req3Len = ToSendMax;\r
1665\r
1666 // Select the card\r
1667 TransmitFor14443a(req3, req3Len, &samples, &wait);\r
1668 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1669 continue;\r
1670 }\r
1671\r
1672 // Store answer in buffer\r
1673 rsamples = rsamples + (samples - Demod.samples);\r
1674 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1675 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1676 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1677 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1678 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1679 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1680 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1681 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1682 trace[traceLen++] = Demod.len;\r
1683 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1684 traceLen += Demod.len;\r
1685 if(traceLen > TRACE_LENGTH) goto done;\r
1686\r
1687// OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in \r
1688// which case we need to make a cascade 2 request and select - this is a long UID\r
30f2a7d3 1689 if (receivedAnswer[0] == 0x88)\r
6658905f 1690 {\r
1691 // Do cascade level 2 stuff\r
1692 ///////////////////////////////////////////////////////////////////\r
1693 // First issue a '95 20' identify request\r
1694 // Ask for card UID (part 2)\r
1695 TransmitFor14443a(req4, req4Len, &tsamples, &wait);\r
1696 // Store answer in buffer\r
1697 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1698 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1699 trace[traceLen++] = 2;\r
1700 memcpy(trace+traceLen, cmd4, 2);\r
1701 traceLen += 2;\r
1702 if(traceLen > TRACE_LENGTH) {\r
1703 DbpString("Bugging out, just popped tracelength");\r
1704 goto done;}\r
1705\r
1706 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1707 continue;\r
1708 }\r
1709 // Store answer in buffer\r
1710 rsamples = rsamples + (samples - Demod.samples);\r
1711 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1712 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1713 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1714 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1715 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1716 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1717 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1718 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1719 trace[traceLen++] = Demod.len;\r
1720 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1721 traceLen += Demod.len;\r
1722 if(traceLen > TRACE_LENGTH) goto done;\r
1723 //////////////////////////////////////////////////////////////////\r
1724 // Then Construct SELECT UID (cascasde 2) command\r
1725 DbpString("Just about to copy the UID out of the cascade 2 id req");\r
1726 // First copy the 5 bytes (Mifare Classic) after the 95 70\r
1727 memcpy(cmd5+2,receivedAnswer,5);\r
1728 // Secondly compute the two CRC bytes at the end\r
1729 ComputeCrc14443(CRC_14443_A, cmd4, 7, &cmd5[7], &cmd5[8]);\r
1730 // Prepare the bit sequence to modulate the subcarrier\r
1731 // Store answer in buffer\r
1732 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1733 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1734 trace[traceLen++] = 9;\r
1735 memcpy(trace+traceLen, cmd5, 9);\r
1736 traceLen += 9;\r
1737 if(traceLen > TRACE_LENGTH) goto done;\r
1738 CodeIso14443aAsReader(cmd5, sizeof(cmd5));\r
1739 memcpy(req5, ToSend, ToSendMax); req5Len = ToSendMax;\r
1740\r
1741 // Select the card\r
1742 TransmitFor14443a(req4, req4Len, &samples, &wait);\r
1743 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1744 continue;\r
1745 }\r
1746\r
1747 // Store answer in buffer\r
1748 rsamples = rsamples + (samples - Demod.samples);\r
1749 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1750 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1751 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1752 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1753 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1754 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1755 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1756 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1757 trace[traceLen++] = Demod.len;\r
1758 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1759 traceLen += Demod.len;\r
1760 if(traceLen > TRACE_LENGTH) goto done;\r
1761\r
1762\r
1763\r
1764\r
1765\r
1766\r
1767 } \r
1768\r
1769 \r
1770\r
1771 // Secondly compute the two CRC bytes at the end\r
1772 ComputeCrc14443(CRC_14443_A, cmd5, 2, &cmd5[2], &cmd5[3]);\r
1773 // Send authentication request (Mifare Classic)\r
1774 TransmitFor14443a(req5, req5Len, &samples, &wait);\r
1775 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1776 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1777 trace[traceLen++] = 4;\r
1778 memcpy(trace+traceLen, cmd5, 4);\r
1779 traceLen += 4;\r
1780 if(traceLen > TRACE_LENGTH) goto done;\r
1781 if(GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1782 rsamples++;\r
1783 // We received probably a random, continue and trace!\r
1784 }\r
1785 else {\r
1786 // Received nothing\r
1787 continue;\r
1788 }\r
1789\r
1790 // Trace the random, i'm curious\r
1791 rsamples = rsamples + (samples - Demod.samples);\r
1792 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1793 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1794 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1795 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1796 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1797 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1798 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1799 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1800 trace[traceLen++] = Demod.len;\r
1801 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1802 traceLen += Demod.len;\r
1803 if(traceLen > TRACE_LENGTH) goto done;\r
1804\r
1805 // Thats it...\r
1806 }\r
1807\r
1808done:\r
1809 LED_A_OFF();\r
1810 LED_B_OFF();\r
1811 LED_C_OFF();\r
1812 LED_D_OFF();\r
1813 DbpIntegers(rsamples, 0xCC, 0xCC);\r
1814 DbpString("ready..");\r
1815}\r
Impressum, Datenschutz