]> cvs.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso14443a.c
[rleroy] add signal strength meter to 'detectreader' command (HF only)
[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
0e25ae11 519 #define TRACE_LENGTH 3000\r
520\r
6658905f 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
0e25ae11 570 // Signal field is off with the appropriate LED\r
571 LED_D_OFF();\r
6658905f 572 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);\r
573 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
574\r
575 // Setup for the DMA.\r
576 FpgaSetupSsc();\r
577 upTo = dmaBuf;\r
578 lastRxCounter = DMA_BUFFER_SIZE;\r
579 FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE);\r
580\r
581 LED_A_ON();\r
582\r
583 // And now we loop, receiving samples.\r
584 for(;;) {\r
585 WDT_HIT();\r
586 int behindBy = (lastRxCounter - PDC_RX_COUNTER(SSC_BASE)) &\r
587 (DMA_BUFFER_SIZE-1);\r
588 if(behindBy > maxBehindBy) {\r
589 maxBehindBy = behindBy;\r
590 if(behindBy > 400) {\r
591 DbpString("blew circular buffer!");\r
592 goto done;\r
593 }\r
594 }\r
595 if(behindBy < 1) continue;\r
596\r
597 smpl = upTo[0];\r
598 upTo++;\r
599 lastRxCounter -= 1;\r
600 if(upTo - dmaBuf > DMA_BUFFER_SIZE) {\r
601 upTo -= DMA_BUFFER_SIZE;\r
602 lastRxCounter += DMA_BUFFER_SIZE;\r
603 PDC_RX_NEXT_POINTER(SSC_BASE) = (DWORD)upTo;\r
604 PDC_RX_NEXT_COUNTER(SSC_BASE) = DMA_BUFFER_SIZE;\r
605 }\r
606\r
607 samples += 4;\r
608#define HANDLE_BIT_IF_BODY \\r
609 LED_C_ON(); \\r
610 if(triggered) { \\r
611 trace[traceLen++] = ((rsamples >> 0) & 0xff); \\r
612 trace[traceLen++] = ((rsamples >> 8) & 0xff); \\r
613 trace[traceLen++] = ((rsamples >> 16) & 0xff); \\r
614 trace[traceLen++] = ((rsamples >> 24) & 0xff); \\r
615 trace[traceLen++] = ((Uart.parityBits >> 0) & 0xff); \\r
616 trace[traceLen++] = ((Uart.parityBits >> 8) & 0xff); \\r
617 trace[traceLen++] = ((Uart.parityBits >> 16) & 0xff); \\r
618 trace[traceLen++] = ((Uart.parityBits >> 24) & 0xff); \\r
619 trace[traceLen++] = Uart.byteCnt; \\r
620 memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \\r
621 traceLen += Uart.byteCnt; \\r
622 if(traceLen > TRACE_LENGTH) break; \\r
623 } \\r
624 /* And ready to receive another command. */ \\r
625 Uart.state = STATE_UNSYNCD; \\r
626 /* And also reset the demod code, which might have been */ \\r
627 /* false-triggered by the commands from the reader. */ \\r
628 Demod.state = DEMOD_UNSYNCD; \\r
629 LED_B_OFF(); \\r
630\r
631 if(MillerDecoding((smpl & 0xF0) >> 4)) {\r
632 rsamples = samples - Uart.samples;\r
633 HANDLE_BIT_IF_BODY\r
634 }\r
635 if(ManchesterDecoding(smpl & 0x0F)) {\r
636 rsamples = samples - Demod.samples;\r
637 LED_B_ON();\r
638\r
639 // timestamp, as a count of samples\r
640 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
641 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
642 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
643 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
644 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
645 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
646 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
647 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
648 // length\r
649 trace[traceLen++] = Demod.len;\r
650 memcpy(trace+traceLen, receivedResponse, Demod.len);\r
651 traceLen += Demod.len;\r
652 if(traceLen > TRACE_LENGTH) break;\r
653\r
654 triggered = TRUE;\r
655\r
656 // And ready to receive another response.\r
657 memset(&Demod, 0, sizeof(Demod));\r
658 Demod.output = receivedResponse;\r
659 Demod.state = DEMOD_UNSYNCD;\r
660 LED_C_OFF();\r
661 }\r
662\r
663 if(BUTTON_PRESS()) {\r
664 DbpString("cancelled_a");\r
665 goto done;\r
666 }\r
667 }\r
668\r
669 DbpString("COMMAND FINISHED");\r
670\r
671 DbpIntegers(maxBehindBy, Uart.state, Uart.byteCnt);\r
672 DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
673\r
674done:\r
675 PDC_CONTROL(SSC_BASE) = PDC_RX_DISABLE;\r
676 DbpIntegers(maxBehindBy, Uart.state, Uart.byteCnt);\r
677 DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
678 LED_A_OFF();\r
679 LED_B_OFF();\r
680 LED_C_OFF();\r
681 LED_D_OFF();\r
682}\r
683\r
684// Prepare communication bits to send to FPGA\r
685void Sequence(SecType seq)\r
686{\r
687 ToSendMax++;\r
688 switch(seq) {\r
689 // CARD TO READER\r
690 case SEC_D:\r
691 // Sequence D: 11110000\r
692 // modulation with subcarrier during first half\r
693 ToSend[ToSendMax] = 0xf0;\r
694 break;\r
695 case SEC_E:\r
696 // Sequence E: 00001111\r
697 // modulation with subcarrier during second half\r
698 ToSend[ToSendMax] = 0x0f;\r
699 break;\r
700 case SEC_F:\r
701 // Sequence F: 00000000\r
702 // no modulation with subcarrier\r
703 ToSend[ToSendMax] = 0x00;\r
704 break;\r
705 // READER TO CARD\r
706 case SEC_X:\r
707 // Sequence X: 00001100\r
708 // drop after half a period\r
709 ToSend[ToSendMax] = 0x0c;\r
710 break;\r
711 case SEC_Y:\r
712 default:\r
713 // Sequence Y: 00000000\r
714 // no drop\r
715 ToSend[ToSendMax] = 0x00;\r
716 break;\r
717 case SEC_Z:\r
718 // Sequence Z: 11000000\r
719 // drop at start\r
720 ToSend[ToSendMax] = 0xc0;\r
721 break;\r
722 }\r
723}\r
724\r
725//-----------------------------------------------------------------------------\r
726// Prepare tag messages\r
727//-----------------------------------------------------------------------------\r
728static void CodeIso14443aAsTag(const BYTE *cmd, int len)\r
729{\r
730 int i;\r
731 int oddparity;\r
732\r
733 ToSendReset();\r
734\r
735 // Correction bit, might be removed when not needed\r
736 ToSendStuffBit(0);\r
737 ToSendStuffBit(0);\r
738 ToSendStuffBit(0);\r
739 ToSendStuffBit(0);\r
740 ToSendStuffBit(1); // 1\r
741 ToSendStuffBit(0);\r
742 ToSendStuffBit(0);\r
743 ToSendStuffBit(0);\r
744\r
745 // Send startbit\r
746 Sequence(SEC_D);\r
747\r
748 for(i = 0; i < len; i++) {\r
749 int j;\r
750 BYTE b = cmd[i];\r
751\r
752 // Data bits\r
753 oddparity = 0x01;\r
754 for(j = 0; j < 8; j++) {\r
755 oddparity ^= (b & 1);\r
756 if(b & 1) {\r
757 Sequence(SEC_D);\r
758 } else {\r
759 Sequence(SEC_E);\r
760 }\r
761 b >>= 1;\r
762 }\r
763\r
764 // Parity bit\r
765 if(oddparity) {\r
766 Sequence(SEC_D);\r
767 } else {\r
768 Sequence(SEC_E);\r
769 }\r
770 }\r
771\r
772 // Send stopbit\r
773 Sequence(SEC_F);\r
774\r
775 // Flush the buffer in FPGA!!\r
776 for(i = 0; i < 5; i++) {\r
777 Sequence(SEC_F);\r
778 }\r
779\r
780 // Convert from last byte pos to length\r
781 ToSendMax++;\r
782\r
783 // Add a few more for slop\r
784 ToSend[ToSendMax++] = 0x00;\r
785 ToSend[ToSendMax++] = 0x00;\r
786 //ToSendMax += 2;\r
787}\r
788\r
789//-----------------------------------------------------------------------------\r
790// This is to send a NACK kind of answer, its only 3 bits, I know it should be 4\r
791//-----------------------------------------------------------------------------\r
792static void CodeStrangeAnswer()\r
793{\r
794 int i;\r
795\r
796 ToSendReset();\r
797\r
798 // Correction bit, might be removed when not needed\r
799 ToSendStuffBit(0);\r
800 ToSendStuffBit(0);\r
801 ToSendStuffBit(0);\r
802 ToSendStuffBit(0);\r
803 ToSendStuffBit(1); // 1\r
804 ToSendStuffBit(0);\r
805 ToSendStuffBit(0);\r
806 ToSendStuffBit(0);\r
807\r
808 // Send startbit\r
809 Sequence(SEC_D);\r
810\r
811 // 0\r
812 Sequence(SEC_E);\r
813\r
814 // 0\r
815 Sequence(SEC_E);\r
816\r
817 // 1\r
818 Sequence(SEC_D);\r
819\r
820 // Send stopbit\r
821 Sequence(SEC_F);\r
822\r
823 // Flush the buffer in FPGA!!\r
824 for(i = 0; i < 5; i++) {\r
825 Sequence(SEC_F);\r
826 }\r
827\r
828 // Convert from last byte pos to length\r
829 ToSendMax++;\r
830\r
831 // Add a few more for slop\r
832 ToSend[ToSendMax++] = 0x00;\r
833 ToSend[ToSendMax++] = 0x00;\r
834 //ToSendMax += 2;\r
835}\r
836\r
837//-----------------------------------------------------------------------------\r
838// Wait for commands from reader\r
839// Stop when button is pressed\r
840// Or return TRUE when command is captured\r
841//-----------------------------------------------------------------------------\r
842static BOOL GetIso14443aCommandFromReader(BYTE *received, int *len, int maxLen)\r
843{\r
844 // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen\r
845 // only, since we are receiving, not transmitting).\r
0e25ae11 846 // Signal field is off with the appropriate LED\r
847 LED_D_OFF();\r
6658905f 848 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);\r
849\r
850 // Now run a `software UART' on the stream of incoming samples.\r
851 Uart.output = received;\r
852 Uart.byteCntMax = maxLen;\r
853 Uart.state = STATE_UNSYNCD;\r
854\r
855 for(;;) {\r
856 WDT_HIT();\r
857\r
858 if(BUTTON_PRESS()) return FALSE;\r
859\r
860 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
861 SSC_TRANSMIT_HOLDING = 0x00;\r
862 }\r
863 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
864 BYTE b = (BYTE)SSC_RECEIVE_HOLDING;\r
865 if(MillerDecoding((b & 0xf0) >> 4)) {\r
866 *len = Uart.byteCnt;\r
867 return TRUE;\r
868 }\r
869 if(MillerDecoding(b & 0x0f)) {\r
870 *len = Uart.byteCnt;\r
871 return TRUE;\r
872 }\r
873 }\r
874 }\r
875}\r
876\r
877//-----------------------------------------------------------------------------\r
878// Main loop of simulated tag: receive commands from reader, decide what\r
879// response to send, and send it.\r
880//-----------------------------------------------------------------------------\r
881void SimulateIso14443aTag(int tagType, int TagUid)\r
882{\r
883 // This function contains the tag emulation\r
884\r
885 // Prepare protocol messages\r
886 // static const BYTE cmd1[] = { 0x26 };\r
887// static const BYTE response1[] = { 0x02, 0x00 }; // Says: I am Mifare 4k - original line - greg\r
888//\r
889 static const BYTE response1[] = { 0x44, 0x03 }; // Says: I am a DESFire Tag, ph33r me\r
890// static const BYTE response1[] = { 0x44, 0x00 }; // Says: I am a ULTRALITE Tag, 0wn me\r
891\r
892 // UID response\r
893 // static const BYTE cmd2[] = { 0x93, 0x20 };\r
894 //static const BYTE response2[] = { 0x9a, 0xe5, 0xe4, 0x43, 0xd8 }; // original value - greg\r
895\r
896\r
897\r
898// my desfire\r
899 static const BYTE response2[] = { 0x88, 0x04, 0x21, 0x3f, 0x4d }; // known uid - note cascade (0x88), 2nd byte (0x04) = NXP/Phillips\r
0e25ae11 900\r
901\r
6658905f 902// When reader selects us during cascade1 it will send cmd3\r
903//BYTE response3[] = { 0x04, 0x00, 0x00 }; // SAK Select (cascade1) successful response (ULTRALITE)\r
904BYTE response3[] = { 0x24, 0x00, 0x00 }; // SAK Select (cascade1) successful response (DESFire)\r
905ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);\r
906\r
907// send cascade2 2nd half of UID\r
908static const BYTE response2a[] = { 0x51, 0x48, 0x1d, 0x80, 0x84 }; // uid - cascade2 - 2nd half (4 bytes) of UID+ BCCheck\r
909// NOTE : THE CRC on the above may be wrong as I have obfuscated the actual UID\r
910\r
911\r
912// When reader selects us during cascade2 it will send cmd3a\r
913//BYTE response3a[] = { 0x00, 0x00, 0x00 }; // SAK Select (cascade2) successful response (ULTRALITE)\r
914BYTE response3a[] = { 0x20, 0x00, 0x00 }; // SAK Select (cascade2) successful response (DESFire)\r
915ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);\r
0e25ae11 916\r
6658905f 917// When reader tries to authenticate\r
918 // static const BYTE cmd5[] = { 0x60, 0x00, 0xf5, 0x7b };\r
919 static const BYTE response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce\r
920\r
921 BYTE *resp;\r
922 int respLen;\r
923\r
924 // Longest possible response will be 16 bytes + 2 CRC = 18 bytes\r
925 // This will need\r
926 // 144 data bits (18 * 8)\r
927 // 18 parity bits\r
928 // 2 Start and stop\r
929 // 1 Correction bit (Answer in 1172 or 1236 periods, see FPGA)\r
930 // 1 just for the case\r
931 // ----------- +\r
932 // 166\r
933 //\r
934 // 166 bytes, since every bit that needs to be send costs us a byte\r
935 //\r
936\r
937\r
938 // Respond with card type\r
939 BYTE *resp1 = (((BYTE *)BigBuf) + 800);\r
940 int resp1Len;\r
941\r
942 // Anticollision cascade1 - respond with uid\r
943 BYTE *resp2 = (((BYTE *)BigBuf) + 970);\r
944 int resp2Len;\r
945\r
946 // Anticollision cascade2 - respond with 2nd half of uid if asked\r
947 // we're only going to be asked if we set the 1st byte of the UID (during cascade1) to 0x88\r
948 BYTE *resp2a = (((BYTE *)BigBuf) + 1140);\r
949 int resp2aLen;\r
950\r
951 // Acknowledge select - cascade 1\r
952 BYTE *resp3 = (((BYTE *)BigBuf) + 1310);\r
953 int resp3Len;\r
954\r
955 // Acknowledge select - cascade 2\r
956 BYTE *resp3a = (((BYTE *)BigBuf) + 1480);\r
957 int resp3aLen;\r
958\r
959 // Response to a read request - not implemented atm\r
960 BYTE *resp4 = (((BYTE *)BigBuf) + 1550);\r
961 int resp4Len;\r
962\r
963 // Authenticate response - nonce\r
964 BYTE *resp5 = (((BYTE *)BigBuf) + 1720);\r
965 int resp5Len;\r
966\r
967 BYTE *receivedCmd = (BYTE *)BigBuf;\r
968 int len;\r
969\r
970 int i;\r
971 int u;\r
972 BYTE b;\r
973\r
974 // To control where we are in the protocol\r
975 int order = 0;\r
976 int lastorder;\r
977\r
978 // Just to allow some checks\r
979 int happened = 0;\r
980 int happened2 = 0;\r
981\r
982 int cmdsRecvd = 0;\r
983\r
984 BOOL fdt_indicator;\r
985\r
986 memset(receivedCmd, 0x44, 400);\r
987\r
988 // Prepare the responses of the anticollision phase\r
989 // there will be not enough time to do this at the moment the reader sends it REQA\r
990\r
991 // Answer to request\r
992 CodeIso14443aAsTag(response1, sizeof(response1));\r
993 memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;\r
994\r
995 // Send our UID (cascade 1)\r
996 CodeIso14443aAsTag(response2, sizeof(response2));\r
997 memcpy(resp2, ToSend, ToSendMax); resp2Len = ToSendMax;\r
998\r
999 // Answer to select (cascade1)\r
1000 CodeIso14443aAsTag(response3, sizeof(response3));\r
1001 memcpy(resp3, ToSend, ToSendMax); resp3Len = ToSendMax;\r
1002\r
1003 // Send the cascade 2 2nd part of the uid\r
1004 CodeIso14443aAsTag(response2a, sizeof(response2a));\r
1005 memcpy(resp2a, ToSend, ToSendMax); resp2aLen = ToSendMax;\r
1006\r
1007 // Answer to select (cascade 2)\r
1008 CodeIso14443aAsTag(response3a, sizeof(response3a));\r
1009 memcpy(resp3a, ToSend, ToSendMax); resp3aLen = ToSendMax;\r
1010\r
1011 // Strange answer is an example of rare message size (3 bits)\r
1012 CodeStrangeAnswer();\r
1013 memcpy(resp4, ToSend, ToSendMax); resp4Len = ToSendMax;\r
1014\r
1015 // Authentication answer (random nonce)\r
1016 CodeIso14443aAsTag(response5, sizeof(response5));\r
1017 memcpy(resp5, ToSend, ToSendMax); resp5Len = ToSendMax;\r
1018\r
1019 // We need to listen to the high-frequency, peak-detected path.\r
1020 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1021 FpgaSetupSsc();\r
1022\r
1023 cmdsRecvd = 0;\r
1024\r
1025 LED_A_ON();\r
1026 for(;;) {\r
1027\r
1028 if(!GetIso14443aCommandFromReader(receivedCmd, &len, 100)) {\r
1029 DbpString("button press");\r
1030 break;\r
1031 }\r
1032 // 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
1033 // Okay, look at the command now.\r
1034 lastorder = order;\r
1035 i = 1; // first byte transmitted\r
1036 if(receivedCmd[0] == 0x26) {\r
1037 // Received a REQUEST\r
1038 resp = resp1; respLen = resp1Len; order = 1;\r
1039 //DbpString("Hello request from reader:");\r
1040 } else if(receivedCmd[0] == 0x52) {\r
1041 // Received a WAKEUP\r
1042 resp = resp1; respLen = resp1Len; order = 6;\r
1043// //DbpString("Wakeup request from reader:");\r
1044\r
1045 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x93) { // greg - cascade 1 anti-collision\r
1046 // Received request for UID (cascade 1)\r
1047 resp = resp2; respLen = resp2Len; order = 2;\r
1048// DbpString("UID (cascade 1) request from reader:");\r
1049// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1050\r
1051\r
1052 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] ==0x95) { // greg - cascade 2 anti-collision\r
1053 // Received request for UID (cascade 2)\r
1054 resp = resp2a; respLen = resp2aLen; order = 20;\r
1055// DbpString("UID (cascade 2) request from reader:");\r
1056// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1057\r
1058\r
1059 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x93) { // greg - cascade 1 select\r
1060 // Received a SELECT\r
1061 resp = resp3; respLen = resp3Len; order = 3;\r
1062// DbpString("Select (cascade 1) request from reader:");\r
1063// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1064\r
1065\r
1066 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x95) { // greg - cascade 2 select\r
1067 // Received a SELECT\r
1068 resp = resp3a; respLen = resp3aLen; order = 30;\r
1069// DbpString("Select (cascade 2) request from reader:");\r
1070// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1071\r
1072\r
1073 } else if(receivedCmd[0] == 0x30) {\r
1074 // Received a READ\r
1075 resp = resp4; respLen = resp4Len; order = 4; // Do nothing\r
1076 DbpString("Read request from reader:");\r
1077 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1078\r
1079\r
1080 } else if(receivedCmd[0] == 0x50) {\r
1081 // Received a HALT\r
1082 resp = resp1; respLen = 0; order = 5; // Do nothing\r
1083 DbpString("Reader requested we HALT!:");\r
1084\r
1085 } else if(receivedCmd[0] == 0x60) {\r
1086 // Received an authentication request\r
1087 resp = resp5; respLen = resp5Len; order = 7;\r
1088 DbpString("Authenticate request from reader:");\r
1089 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1090\r
1091 } else if(receivedCmd[0] == 0xE0) {\r
1092 // Received a RATS request\r
1093 resp = resp1; respLen = 0;order = 70;\r
1094 DbpString("RATS request from reader:");\r
1095 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1096 } else {\r
1097 // Never seen this command before\r
1098 DbpString("Unknown command received from reader:");\r
1099 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1100 DbpIntegers(receivedCmd[3], receivedCmd[4], receivedCmd[5]);\r
1101 DbpIntegers(receivedCmd[6], receivedCmd[7], receivedCmd[8]);\r
1102\r
1103 // Do not respond\r
1104 resp = resp1; respLen = 0; order = 0;\r
1105 }\r
1106\r
1107 // Count number of wakeups received after a halt\r
1108 if(order == 6 && lastorder == 5) { happened++; }\r
1109\r
1110 // Count number of other messages after a halt\r
1111 if(order != 6 && lastorder == 5) { happened2++; }\r
1112\r
1113 // Look at last parity bit to determine timing of answer\r
1114 if((Uart.parityBits & 0x01) || receivedCmd[0] == 0x52) {\r
1115 // 1236, so correction bit needed\r
1116 i = 0;\r
1117 }\r
1118\r
1119 memset(receivedCmd, 0x44, 32);\r
1120\r
1121 if(cmdsRecvd > 999) {\r
1122 DbpString("1000 commands later...");\r
1123 break;\r
1124 }\r
1125 else {\r
1126 cmdsRecvd++;\r
1127 }\r
1128\r
1129 if(respLen <= 0) continue;\r
1130\r
1131 // Modulate Manchester\r
1132 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);\r
1133 SSC_TRANSMIT_HOLDING = 0x00;\r
1134 FpgaSetupSsc();\r
1135\r
1136 // ### Transmit the response ###\r
1137 u = 0;\r
1138 b = 0x00;\r
1139 fdt_indicator = FALSE;\r
1140 for(;;) {\r
1141 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1142 volatile BYTE b = (BYTE)SSC_RECEIVE_HOLDING;\r
1143 (void)b;\r
1144 }\r
1145 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1146 if(i > respLen) {\r
1147 b = 0x00;\r
1148 u++;\r
1149 } else {\r
1150 b = resp[i];\r
1151 i++;\r
1152 }\r
1153 SSC_TRANSMIT_HOLDING = b;\r
1154\r
1155 if(u > 4) {\r
1156 break;\r
1157 }\r
1158 }\r
1159 if(BUTTON_PRESS()) {\r
1160 break;\r
1161 }\r
1162 }\r
1163\r
1164 }\r
1165\r
1166 DbpIntegers(happened, happened2, cmdsRecvd);\r
1167 LED_A_OFF();\r
1168}\r
1169\r
1170//-----------------------------------------------------------------------------\r
1171// Transmit the command (to the tag) that was placed in ToSend[].\r
1172//-----------------------------------------------------------------------------\r
1173static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait)\r
1174{\r
1175 int c;\r
1176\r
1177 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1178\r
1179 if(*wait < 10) { *wait = 10; }\r
1180\r
1181 for(c = 0; c < *wait;) {\r
1182 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1183 SSC_TRANSMIT_HOLDING = 0x00; // For exact timing!\r
1184 c++;\r
1185 }\r
1186 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1187 volatile DWORD r = SSC_RECEIVE_HOLDING;\r
1188 (void)r;\r
1189 }\r
1190 WDT_HIT();\r
1191 }\r
1192\r
1193 c = 0;\r
1194 for(;;) {\r
1195 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1196 SSC_TRANSMIT_HOLDING = cmd[c];\r
1197 c++;\r
1198 if(c >= len) {\r
1199 break;\r
1200 }\r
1201 }\r
1202 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1203 volatile DWORD r = SSC_RECEIVE_HOLDING;\r
1204 (void)r;\r
1205 }\r
1206 WDT_HIT();\r
1207 }\r
1208 *samples = (c + *wait) << 3;\r
1209}\r
1210\r
1211//-----------------------------------------------------------------------------\r
1212// To generate an arbitrary stream from reader\r
1213//\r
1214//-----------------------------------------------------------------------------\r
1215void ArbitraryFromReader(const BYTE *cmd, int parity, int len)\r
1216{\r
1217 int i;\r
1218 int j;\r
1219 int last;\r
1220 BYTE b;\r
1221\r
1222 ToSendReset();\r
1223\r
1224 // Start of Communication (Seq. Z)\r
1225 Sequence(SEC_Z);\r
1226 last = 0;\r
1227\r
1228 for(i = 0; i < len; i++) {\r
1229 // Data bits\r
1230 b = cmd[i];\r
1231 for(j = 0; j < 8; j++) {\r
1232 if(b & 1) {\r
1233 // Sequence X\r
1234 Sequence(SEC_X);\r
1235 last = 1;\r
1236 } else {\r
1237 if(last == 0) {\r
1238 // Sequence Z\r
1239 Sequence(SEC_Z);\r
1240 }\r
1241 else {\r
1242 // Sequence Y\r
1243 Sequence(SEC_Y);\r
1244 last = 0;\r
1245 }\r
1246 }\r
1247 b >>= 1;\r
1248\r
1249 }\r
1250\r
1251 // Predefined parity bit, the flipper flips when needed, because of flips in byte sent\r
1252 if(((parity >> (len - i - 1)) & 1)) {\r
1253 // Sequence X\r
1254 Sequence(SEC_X);\r
1255 last = 1;\r
1256 } else {\r
1257 if(last == 0) {\r
1258 // Sequence Z\r
1259 Sequence(SEC_Z);\r
1260 }\r
1261 else {\r
1262 // Sequence Y\r
1263 Sequence(SEC_Y);\r
1264 last = 0;\r
1265 }\r
1266 }\r
1267 }\r
1268\r
1269 // End of Communication\r
1270 if(last == 0) {\r
1271 // Sequence Z\r
1272 Sequence(SEC_Z);\r
1273 }\r
1274 else {\r
1275 // Sequence Y\r
1276 Sequence(SEC_Y);\r
1277 last = 0;\r
1278 }\r
1279 // Sequence Y\r
1280 Sequence(SEC_Y);\r
1281\r
1282 // Just to be sure!\r
1283 Sequence(SEC_Y);\r
1284 Sequence(SEC_Y);\r
1285 Sequence(SEC_Y);\r
1286\r
1287 // Convert from last character reference to length\r
1288 ToSendMax++;\r
1289}\r
1290\r
1291//-----------------------------------------------------------------------------\r
1292// Code a 7-bit command without parity bit\r
1293// This is especially for 0x26 and 0x52 (REQA and WUPA)\r
1294//-----------------------------------------------------------------------------\r
1295void ShortFrameFromReader(const BYTE *cmd)\r
1296{\r
1297 int j;\r
1298 int last;\r
1299 BYTE b;\r
1300\r
1301 ToSendReset();\r
1302\r
1303 // Start of Communication (Seq. Z)\r
1304 Sequence(SEC_Z);\r
1305 last = 0;\r
1306\r
1307 b = cmd[0];\r
1308 for(j = 0; j < 7; j++) {\r
1309 if(b & 1) {\r
1310 // Sequence X\r
1311 Sequence(SEC_X);\r
1312 last = 1;\r
1313 } else {\r
1314 if(last == 0) {\r
1315 // Sequence Z\r
1316 Sequence(SEC_Z);\r
1317 }\r
1318 else {\r
1319 // Sequence Y\r
1320 Sequence(SEC_Y);\r
1321 last = 0;\r
1322 }\r
1323 }\r
1324 b >>= 1;\r
1325 }\r
1326\r
1327 // End of Communication\r
1328 if(last == 0) {\r
1329 // Sequence Z\r
1330 Sequence(SEC_Z);\r
1331 }\r
1332 else {\r
1333 // Sequence Y\r
1334 Sequence(SEC_Y);\r
1335 last = 0;\r
1336 }\r
1337 // Sequence Y\r
1338 Sequence(SEC_Y);\r
1339\r
1340 // Just to be sure!\r
1341 Sequence(SEC_Y);\r
1342 Sequence(SEC_Y);\r
1343 Sequence(SEC_Y);\r
1344\r
1345 // Convert from last character reference to length\r
1346 ToSendMax++;\r
1347}\r
1348\r
1349//-----------------------------------------------------------------------------\r
1350// Prepare reader command to send to FPGA\r
1351//\r
1352//-----------------------------------------------------------------------------\r
1353void CodeIso14443aAsReader(const BYTE *cmd, int len)\r
1354{\r
1355 int i, j;\r
1356 int last;\r
1357 int oddparity;\r
1358 BYTE b;\r
1359\r
1360 ToSendReset();\r
1361\r
1362 // Start of Communication (Seq. Z)\r
1363 Sequence(SEC_Z);\r
1364 last = 0;\r
1365\r
1366 for(i = 0; i < len; i++) {\r
1367 // Data bits\r
1368 b = cmd[i];\r
1369 oddparity = 0x01;\r
1370 for(j = 0; j < 8; j++) {\r
1371 oddparity ^= (b & 1);\r
1372 if(b & 1) {\r
1373 // Sequence X\r
1374 Sequence(SEC_X);\r
1375 last = 1;\r
1376 } else {\r
1377 if(last == 0) {\r
1378 // Sequence Z\r
1379 Sequence(SEC_Z);\r
1380 }\r
1381 else {\r
1382 // Sequence Y\r
1383 Sequence(SEC_Y);\r
1384 last = 0;\r
1385 }\r
1386 }\r
1387 b >>= 1;\r
1388 }\r
1389\r
1390 // Parity bit\r
1391 if(oddparity) {\r
1392 // Sequence X\r
1393 Sequence(SEC_X);\r
1394 last = 1;\r
1395 } else {\r
1396 if(last == 0) {\r
1397 // Sequence Z\r
1398 Sequence(SEC_Z);\r
1399 }\r
1400 else {\r
1401 // Sequence Y\r
1402 Sequence(SEC_Y);\r
1403 last = 0;\r
1404 }\r
1405 }\r
1406 }\r
1407\r
1408 // End of Communication\r
1409 if(last == 0) {\r
1410 // Sequence Z\r
1411 Sequence(SEC_Z);\r
1412 }\r
1413 else {\r
1414 // Sequence Y\r
1415 Sequence(SEC_Y);\r
1416 last = 0;\r
1417 }\r
1418 // Sequence Y\r
1419 Sequence(SEC_Y);\r
1420\r
1421 // Just to be sure!\r
1422 Sequence(SEC_Y);\r
1423 Sequence(SEC_Y);\r
1424 Sequence(SEC_Y);\r
1425\r
1426 // Convert from last character reference to length\r
1427 ToSendMax++;\r
1428}\r
1429\r
1430\r
1431//-----------------------------------------------------------------------------\r
1432// Wait a certain time for tag response\r
1433// If a response is captured return TRUE\r
1434// If it takes to long return FALSE\r
1435//-----------------------------------------------------------------------------\r
1436static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *samples, int *elapsed) //BYTE *buffer\r
1437{\r
1438 // buffer needs to be 512 bytes\r
1439 int c;\r
1440\r
0e25ae11 1441 // Set FPGA mode to "reader listen mode", no modulation (listen\r
6658905f 1442 // only, since we are receiving, not transmitting).\r
0e25ae11 1443 // Signal field is on with the appropriate LED\r
1444 LED_D_ON();\r
6658905f 1445 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);\r
1446\r
1447 // Now get the answer from the card\r
1448 Demod.output = receivedResponse;\r
1449 Demod.len = 0;\r
1450 Demod.state = DEMOD_UNSYNCD;\r
1451\r
1452 BYTE b;\r
1453 *elapsed = 0;\r
1454\r
1455 c = 0;\r
1456 for(;;) {\r
1457 WDT_HIT();\r
1458\r
1459 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1460 SSC_TRANSMIT_HOLDING = 0x00; // To make use of exact timing of next command from reader!!\r
1461 (*elapsed)++;\r
1462 }\r
1463 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1464 if(c < 512) { c++; } else { return FALSE; }\r
1465 b = (BYTE)SSC_RECEIVE_HOLDING;\r
1466 if(ManchesterDecoding((b & 0xf0) >> 4)) {\r
1467 *samples = ((c - 1) << 3) + 4;\r
1468 return TRUE;\r
1469 }\r
1470 if(ManchesterDecoding(b & 0x0f)) {\r
1471 *samples = c << 3;\r
1472 return TRUE;\r
1473 }\r
1474 }\r
1475 }\r
1476}\r
1477\r
1478//-----------------------------------------------------------------------------\r
1479// Read an ISO 14443a tag. Send out commands and store answers.\r
1480//\r
1481//-----------------------------------------------------------------------------\r
1482void ReaderIso14443a(DWORD parameter)\r
1483{\r
1484 // Anticollision\r
1485 static const BYTE cmd1[] = { 0x52 }; // or 0x26\r
1486 static const BYTE cmd2[] = { 0x93,0x20 };\r
1487 // UID = 0x2a,0x69,0x8d,0x43,0x8d, last two bytes are CRC bytes\r
1488 BYTE cmd3[] = { 0x93,0x70,0x2a,0x69,0x8d,0x43,0x8d,0x52,0x55 };\r
1489\r
1490 // For Ultralight add an extra anticollission layer -> 95 20 and then 95 70\r
1491\r
1492 // greg - here we will add our cascade level 2 anticolission and select functions to deal with ultralight // and 7-byte UIDs in generall...\r
1493 BYTE cmd4[] = {0x95,0x20}; // ask for cascade 2 select\r
1494 // 95 20\r
1495 //BYTE cmd3a[] = { 0x95,0x70,0x2a,0x69,0x8d,0x43,0x8d,0x52,0x55 };\r
1496 // 95 70\r
1497\r
1498 // cascade 2 select\r
1499 BYTE cmd5[] = { 0x95,0x70,0x2a,0x69,0x8d,0x43,0x8d,0x52,0x55 };\r
1500\r
1501\r
1502 // RATS (request for answer to select)\r
1503 //BYTE cmd6[] = { 0xe0,0x50,0xbc,0xa5 }; // original RATS\r
1504 BYTE cmd6[] = { 0xe0,0x21,0xb2,0xc7 }; // Desfire RATS\r
1505\r
1506 int reqaddr = 2024; // was 2024 - tied to other size changes\r
1507 int reqsize = 60;\r
1508\r
1509 BYTE *req1 = (((BYTE *)BigBuf) + reqaddr);\r
1510 int req1Len;\r
1511\r
1512 BYTE *req2 = (((BYTE *)BigBuf) + reqaddr + reqsize);\r
1513 int req2Len;\r
1514\r
1515 BYTE *req3 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 2));\r
1516 int req3Len;\r
1517\r
1518// greg added req 4 & 5 to deal with cascade 2 section\r
1519 BYTE *req4 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 3));\r
1520 int req4Len;\r
1521\r
1522 BYTE *req5 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 4));\r
1523 int req5Len;\r
1524\r
1525 BYTE *req6 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 5));\r
1526 int req6Len;\r
1527\r
1528 //BYTE *req7 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 6));\r
1529 //int req7Len;\r
1530\r
1531 BYTE *receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes\r
1532\r
1533 BYTE *trace = (BYTE *)BigBuf;\r
1534 int traceLen = 0;\r
1535 int rsamples = 0;\r
1536\r
0e25ae11 1537 memset(trace, 0x44, 2000); // was 2000 - tied to oter size chnages\r
6658905f 1538 // setting it to 3000 causes no tag responses to be detected (2900 is ok)\r
1539 // setting it to 1000 causes no tag responses to be detected\r
1540\r
1541 // Prepare some commands!\r
1542 ShortFrameFromReader(cmd1);\r
1543 memcpy(req1, ToSend, ToSendMax); req1Len = ToSendMax;\r
1544\r
1545 CodeIso14443aAsReader(cmd2, sizeof(cmd2));\r
1546 memcpy(req2, ToSend, ToSendMax); req2Len = ToSendMax;\r
1547\r
1548 CodeIso14443aAsReader(cmd3, sizeof(cmd3));\r
1549 memcpy(req3, ToSend, ToSendMax); req3Len = ToSendMax;\r
1550\r
1551\r
1552 CodeIso14443aAsReader(cmd4, sizeof(cmd4)); // 4 is cascade 2 request\r
1553 memcpy(req4, ToSend, ToSendMax); req4Len = ToSendMax;\r
1554\r
1555\r
1556 CodeIso14443aAsReader(cmd5, sizeof(cmd5)); // 5 is cascade 2 select\r
1557 memcpy(req5, ToSend, ToSendMax); req5Len = ToSendMax;\r
1558\r
1559\r
1560 CodeIso14443aAsReader(cmd6, sizeof(cmd6));\r
1561 memcpy(req6, ToSend, ToSendMax); req6Len = ToSendMax;\r
1562\r
1563 // Setup SSC\r
1564 FpgaSetupSsc();\r
1565\r
1566 // Start from off (no field generated)\r
0e25ae11 1567 // Signal field is off with the appropriate LED\r
1568 LED_D_OFF();\r
6658905f 1569 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1570 SpinDelay(200);\r
1571\r
1572 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1573 FpgaSetupSsc();\r
1574\r
1575 // Now give it time to spin up.\r
0e25ae11 1576 // Signal field is on with the appropriate LED\r
1577 LED_D_ON();\r
6658905f 1578 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1579 SpinDelay(200);\r
1580\r
1581 LED_A_ON();\r
1582 LED_B_OFF();\r
1583 LED_C_OFF();\r
6658905f 1584\r
1585 int samples = 0;\r
1586 int tsamples = 0;\r
1587 int wait = 0;\r
1588 int elapsed = 0;\r
1589\r
1590 for(;;) {\r
1591 // Send WUPA (or REQA)\r
1592 TransmitFor14443a(req1, req1Len, &tsamples, &wait);\r
1593 // Store answer in buffer\r
1594 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1595 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1596 trace[traceLen++] = 1;\r
1597 memcpy(trace+traceLen, cmd1, 1);\r
1598 traceLen += 1;\r
1599 if(traceLen > TRACE_LENGTH) goto done;\r
1600\r
1601 while(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1602 if(BUTTON_PRESS()) goto done;\r
1603\r
1604 // No answer, just continue polling\r
1605 TransmitFor14443a(req1, req1Len, &tsamples, &wait);\r
1606 // Store answer in buffer\r
1607 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1608 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1609 trace[traceLen++] = 1;\r
1610 memcpy(trace+traceLen, cmd1, 1);\r
1611 traceLen += 1;\r
1612 if(traceLen > TRACE_LENGTH) goto done;\r
1613 }\r
1614\r
1615 // Store answer in buffer\r
1616 rsamples = rsamples + (samples - Demod.samples);\r
1617 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1618 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1619 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1620 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1621 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1622 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1623 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1624 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1625 trace[traceLen++] = Demod.len;\r
1626 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1627 traceLen += Demod.len;\r
1628 if(traceLen > TRACE_LENGTH) goto done;\r
1629\r
1630 // Ask for card UID\r
1631 TransmitFor14443a(req2, req2Len, &tsamples, &wait);\r
1632 // Store answer in buffer\r
1633 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1634 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1635 trace[traceLen++] = 2;\r
1636 memcpy(trace+traceLen, cmd2, 2);\r
1637 traceLen += 2;\r
1638 if(traceLen > TRACE_LENGTH) goto done;\r
1639\r
1640 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1641 continue;\r
1642 }\r
1643\r
1644 // Store answer in buffer\r
1645 rsamples = rsamples + (samples - Demod.samples);\r
1646 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1647 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1648 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1649 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1650 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1651 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1652 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1653 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1654 trace[traceLen++] = Demod.len;\r
1655 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1656 traceLen += Demod.len;\r
1657 if(traceLen > TRACE_LENGTH) goto done;\r
1658\r
1659 // Construct SELECT UID command\r
1660 // First copy the 5 bytes (Mifare Classic) after the 93 70\r
1661 memcpy(cmd3+2,receivedAnswer,5);\r
1662 // Secondly compute the two CRC bytes at the end\r
1663 ComputeCrc14443(CRC_14443_A, cmd3, 7, &cmd3[7], &cmd3[8]);\r
1664 // Prepare the bit sequence to modulate the subcarrier\r
1665 // Store answer in buffer\r
1666 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1667 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1668 trace[traceLen++] = 9;\r
1669 memcpy(trace+traceLen, cmd3, 9);\r
1670 traceLen += 9;\r
1671 if(traceLen > TRACE_LENGTH) goto done;\r
1672 CodeIso14443aAsReader(cmd3, sizeof(cmd3));\r
1673 memcpy(req3, ToSend, ToSendMax); req3Len = ToSendMax;\r
1674\r
1675 // Select the card\r
1676 TransmitFor14443a(req3, req3Len, &samples, &wait);\r
1677 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1678 continue;\r
1679 }\r
1680\r
1681 // Store answer in buffer\r
1682 rsamples = rsamples + (samples - Demod.samples);\r
1683 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1684 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1685 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1686 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1687 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1688 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1689 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1690 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1691 trace[traceLen++] = Demod.len;\r
1692 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1693 traceLen += Demod.len;\r
1694 if(traceLen > TRACE_LENGTH) goto done;\r
1695\r
0e25ae11 1696// OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in\r
6658905f 1697// which case we need to make a cascade 2 request and select - this is a long UID\r
30f2a7d3 1698 if (receivedAnswer[0] == 0x88)\r
6658905f 1699 {\r
1700 // Do cascade level 2 stuff\r
1701 ///////////////////////////////////////////////////////////////////\r
1702 // First issue a '95 20' identify request\r
1703 // Ask for card UID (part 2)\r
1704 TransmitFor14443a(req4, req4Len, &tsamples, &wait);\r
1705 // Store answer in buffer\r
1706 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1707 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1708 trace[traceLen++] = 2;\r
1709 memcpy(trace+traceLen, cmd4, 2);\r
1710 traceLen += 2;\r
1711 if(traceLen > TRACE_LENGTH) {\r
1712 DbpString("Bugging out, just popped tracelength");\r
1713 goto done;}\r
1714\r
1715 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1716 continue;\r
1717 }\r
1718 // Store answer in buffer\r
1719 rsamples = rsamples + (samples - Demod.samples);\r
1720 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1721 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1722 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1723 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1724 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1725 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1726 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1727 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1728 trace[traceLen++] = Demod.len;\r
1729 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1730 traceLen += Demod.len;\r
1731 if(traceLen > TRACE_LENGTH) goto done;\r
1732 //////////////////////////////////////////////////////////////////\r
1733 // Then Construct SELECT UID (cascasde 2) command\r
1734 DbpString("Just about to copy the UID out of the cascade 2 id req");\r
1735 // First copy the 5 bytes (Mifare Classic) after the 95 70\r
1736 memcpy(cmd5+2,receivedAnswer,5);\r
1737 // Secondly compute the two CRC bytes at the end\r
1738 ComputeCrc14443(CRC_14443_A, cmd4, 7, &cmd5[7], &cmd5[8]);\r
1739 // Prepare the bit sequence to modulate the subcarrier\r
1740 // Store answer in buffer\r
1741 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1742 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1743 trace[traceLen++] = 9;\r
1744 memcpy(trace+traceLen, cmd5, 9);\r
1745 traceLen += 9;\r
1746 if(traceLen > TRACE_LENGTH) goto done;\r
1747 CodeIso14443aAsReader(cmd5, sizeof(cmd5));\r
1748 memcpy(req5, ToSend, ToSendMax); req5Len = ToSendMax;\r
1749\r
1750 // Select the card\r
1751 TransmitFor14443a(req4, req4Len, &samples, &wait);\r
1752 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1753 continue;\r
1754 }\r
1755\r
1756 // Store answer in buffer\r
1757 rsamples = rsamples + (samples - Demod.samples);\r
1758 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1759 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1760 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1761 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1762 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1763 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1764 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1765 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1766 trace[traceLen++] = Demod.len;\r
1767 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1768 traceLen += Demod.len;\r
1769 if(traceLen > TRACE_LENGTH) goto done;\r
1770\r
0e25ae11 1771 }\r
6658905f 1772\r
1773 // Secondly compute the two CRC bytes at the end\r
1774 ComputeCrc14443(CRC_14443_A, cmd5, 2, &cmd5[2], &cmd5[3]);\r
1775 // Send authentication request (Mifare Classic)\r
1776 TransmitFor14443a(req5, req5Len, &samples, &wait);\r
1777 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1778 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1779 trace[traceLen++] = 4;\r
1780 memcpy(trace+traceLen, cmd5, 4);\r
1781 traceLen += 4;\r
1782 if(traceLen > TRACE_LENGTH) goto done;\r
1783 if(GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1784 rsamples++;\r
1785 // We received probably a random, continue and trace!\r
1786 }\r
1787 else {\r
1788 // Received nothing\r
1789 continue;\r
1790 }\r
1791\r
1792 // Trace the random, i'm curious\r
1793 rsamples = rsamples + (samples - Demod.samples);\r
1794 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1795 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1796 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1797 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1798 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1799 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1800 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1801 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1802 trace[traceLen++] = Demod.len;\r
1803 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1804 traceLen += Demod.len;\r
1805 if(traceLen > TRACE_LENGTH) goto done;\r
1806\r
1807 // Thats it...\r
1808 }\r
1809\r
1810done:\r
1811 LED_A_OFF();\r
1812 LED_B_OFF();\r
1813 LED_C_OFF();\r
6658905f 1814 DbpIntegers(rsamples, 0xCC, 0xCC);\r
1815 DbpString("ready..");\r
1816}\r
Impressum, Datenschutz