]> cvs.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso14443a.c
New bootrom
[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 static const BYTE response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce\r
918\r
919 BYTE *resp;\r
920 int respLen;\r
921\r
922 // Longest possible response will be 16 bytes + 2 CRC = 18 bytes\r
923 // This will need\r
924 // 144 data bits (18 * 8)\r
925 // 18 parity bits\r
926 // 2 Start and stop\r
927 // 1 Correction bit (Answer in 1172 or 1236 periods, see FPGA)\r
928 // 1 just for the case\r
929 // ----------- +\r
930 // 166\r
931 //\r
932 // 166 bytes, since every bit that needs to be send costs us a byte\r
933 //\r
934\r
935\r
936 // Respond with card type\r
937 BYTE *resp1 = (((BYTE *)BigBuf) + 800);\r
938 int resp1Len;\r
939\r
940 // Anticollision cascade1 - respond with uid\r
941 BYTE *resp2 = (((BYTE *)BigBuf) + 970);\r
942 int resp2Len;\r
943\r
944 // Anticollision cascade2 - respond with 2nd half of uid if asked\r
945 // we're only going to be asked if we set the 1st byte of the UID (during cascade1) to 0x88\r
946 BYTE *resp2a = (((BYTE *)BigBuf) + 1140);\r
947 int resp2aLen;\r
948\r
949 // Acknowledge select - cascade 1\r
950 BYTE *resp3 = (((BYTE *)BigBuf) + 1310);\r
951 int resp3Len;\r
952\r
953 // Acknowledge select - cascade 2\r
954 BYTE *resp3a = (((BYTE *)BigBuf) + 1480);\r
955 int resp3aLen;\r
956\r
957 // Response to a read request - not implemented atm\r
958 BYTE *resp4 = (((BYTE *)BigBuf) + 1550);\r
959 int resp4Len;\r
960\r
961 // Authenticate response - nonce\r
962 BYTE *resp5 = (((BYTE *)BigBuf) + 1720);\r
963 int resp5Len;\r
964\r
965 BYTE *receivedCmd = (BYTE *)BigBuf;\r
966 int len;\r
967\r
968 int i;\r
969 int u;\r
970 BYTE b;\r
971\r
972 // To control where we are in the protocol\r
973 int order = 0;\r
974 int lastorder;\r
975\r
976 // Just to allow some checks\r
977 int happened = 0;\r
978 int happened2 = 0;\r
979\r
980 int cmdsRecvd = 0;\r
981\r
982 BOOL fdt_indicator;\r
983\r
984 memset(receivedCmd, 0x44, 400);\r
985\r
986 // Prepare the responses of the anticollision phase\r
987 // there will be not enough time to do this at the moment the reader sends it REQA\r
988\r
989 // Answer to request\r
990 CodeIso14443aAsTag(response1, sizeof(response1));\r
991 memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;\r
992\r
993 // Send our UID (cascade 1)\r
994 CodeIso14443aAsTag(response2, sizeof(response2));\r
995 memcpy(resp2, ToSend, ToSendMax); resp2Len = ToSendMax;\r
996\r
997 // Answer to select (cascade1)\r
998 CodeIso14443aAsTag(response3, sizeof(response3));\r
999 memcpy(resp3, ToSend, ToSendMax); resp3Len = ToSendMax;\r
1000\r
1001 // Send the cascade 2 2nd part of the uid\r
1002 CodeIso14443aAsTag(response2a, sizeof(response2a));\r
1003 memcpy(resp2a, ToSend, ToSendMax); resp2aLen = ToSendMax;\r
1004\r
1005 // Answer to select (cascade 2)\r
1006 CodeIso14443aAsTag(response3a, sizeof(response3a));\r
1007 memcpy(resp3a, ToSend, ToSendMax); resp3aLen = ToSendMax;\r
1008\r
1009 // Strange answer is an example of rare message size (3 bits)\r
1010 CodeStrangeAnswer();\r
1011 memcpy(resp4, ToSend, ToSendMax); resp4Len = ToSendMax;\r
1012\r
1013 // Authentication answer (random nonce)\r
1014 CodeIso14443aAsTag(response5, sizeof(response5));\r
1015 memcpy(resp5, ToSend, ToSendMax); resp5Len = ToSendMax;\r
1016\r
1017 // We need to listen to the high-frequency, peak-detected path.\r
1018 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1019 FpgaSetupSsc();\r
1020\r
1021 cmdsRecvd = 0;\r
1022\r
1023 LED_A_ON();\r
1024 for(;;) {\r
1025\r
1026 if(!GetIso14443aCommandFromReader(receivedCmd, &len, 100)) {\r
1027 DbpString("button press");\r
1028 break;\r
1029 }\r
1030 // 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
1031 // Okay, look at the command now.\r
1032 lastorder = order;\r
1033 i = 1; // first byte transmitted\r
1034 if(receivedCmd[0] == 0x26) {\r
1035 // Received a REQUEST\r
1036 resp = resp1; respLen = resp1Len; order = 1;\r
1037 //DbpString("Hello request from reader:");\r
1038 } else if(receivedCmd[0] == 0x52) {\r
1039 // Received a WAKEUP\r
1040 resp = resp1; respLen = resp1Len; order = 6;\r
1041// //DbpString("Wakeup request from reader:");\r
1042\r
1043 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x93) { // greg - cascade 1 anti-collision\r
1044 // Received request for UID (cascade 1)\r
1045 resp = resp2; respLen = resp2Len; order = 2;\r
1046// DbpString("UID (cascade 1) request from reader:");\r
1047// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1048\r
1049\r
1050 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] ==0x95) { // greg - cascade 2 anti-collision\r
1051 // Received request for UID (cascade 2)\r
1052 resp = resp2a; respLen = resp2aLen; order = 20;\r
1053// DbpString("UID (cascade 2) request from reader:");\r
1054// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1055\r
1056\r
1057 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x93) { // greg - cascade 1 select\r
1058 // Received a SELECT\r
1059 resp = resp3; respLen = resp3Len; order = 3;\r
1060// DbpString("Select (cascade 1) request from reader:");\r
1061// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1062\r
1063\r
1064 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x95) { // greg - cascade 2 select\r
1065 // Received a SELECT\r
1066 resp = resp3a; respLen = resp3aLen; order = 30;\r
1067// DbpString("Select (cascade 2) request from reader:");\r
1068// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1069\r
1070\r
1071 } else if(receivedCmd[0] == 0x30) {\r
1072 // Received a READ\r
1073 resp = resp4; respLen = resp4Len; order = 4; // Do nothing\r
1074 DbpString("Read request from reader:");\r
1075 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1076\r
1077\r
1078 } else if(receivedCmd[0] == 0x50) {\r
1079 // Received a HALT\r
1080 resp = resp1; respLen = 0; order = 5; // Do nothing\r
1081 DbpString("Reader requested we HALT!:");\r
1082\r
1083 } else if(receivedCmd[0] == 0x60) {\r
1084 // Received an authentication request\r
1085 resp = resp5; respLen = resp5Len; order = 7;\r
1086 DbpString("Authenticate request from reader:");\r
1087 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1088\r
1089 } else if(receivedCmd[0] == 0xE0) {\r
1090 // Received a RATS request\r
1091 resp = resp1; respLen = 0;order = 70;\r
1092 DbpString("RATS request from reader:");\r
1093 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1094 } else {\r
1095 // Never seen this command before\r
1096 DbpString("Unknown command received from reader:");\r
1097 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1098 DbpIntegers(receivedCmd[3], receivedCmd[4], receivedCmd[5]);\r
1099 DbpIntegers(receivedCmd[6], receivedCmd[7], receivedCmd[8]);\r
1100\r
1101 // Do not respond\r
1102 resp = resp1; respLen = 0; order = 0;\r
1103 }\r
1104\r
1105 // Count number of wakeups received after a halt\r
1106 if(order == 6 && lastorder == 5) { happened++; }\r
1107\r
1108 // Count number of other messages after a halt\r
1109 if(order != 6 && lastorder == 5) { happened2++; }\r
1110\r
1111 // Look at last parity bit to determine timing of answer\r
1112 if((Uart.parityBits & 0x01) || receivedCmd[0] == 0x52) {\r
1113 // 1236, so correction bit needed\r
1114 i = 0;\r
1115 }\r
1116\r
1117 memset(receivedCmd, 0x44, 32);\r
1118\r
1119 if(cmdsRecvd > 999) {\r
1120 DbpString("1000 commands later...");\r
1121 break;\r
1122 }\r
1123 else {\r
1124 cmdsRecvd++;\r
1125 }\r
1126\r
1127 if(respLen <= 0) continue;\r
1128\r
1129 // Modulate Manchester\r
1130 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);\r
1131 SSC_TRANSMIT_HOLDING = 0x00;\r
1132 FpgaSetupSsc();\r
1133\r
1134 // ### Transmit the response ###\r
1135 u = 0;\r
1136 b = 0x00;\r
1137 fdt_indicator = FALSE;\r
1138 for(;;) {\r
1139 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1140 volatile BYTE b = (BYTE)SSC_RECEIVE_HOLDING;\r
1141 (void)b;\r
1142 }\r
1143 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1144 if(i > respLen) {\r
1145 b = 0x00;\r
1146 u++;\r
1147 } else {\r
1148 b = resp[i];\r
1149 i++;\r
1150 }\r
1151 SSC_TRANSMIT_HOLDING = b;\r
1152\r
1153 if(u > 4) {\r
1154 break;\r
1155 }\r
1156 }\r
1157 if(BUTTON_PRESS()) {\r
1158 break;\r
1159 }\r
1160 }\r
1161\r
1162 }\r
1163\r
1164 DbpIntegers(happened, happened2, cmdsRecvd);\r
1165 LED_A_OFF();\r
1166}\r
1167\r
1168//-----------------------------------------------------------------------------\r
1169// Transmit the command (to the tag) that was placed in ToSend[].\r
1170//-----------------------------------------------------------------------------\r
1171static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait)\r
1172{\r
1173 int c;\r
1174\r
1175 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1176\r
1177 if(*wait < 10) { *wait = 10; }\r
1178\r
1179 for(c = 0; c < *wait;) {\r
1180 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1181 SSC_TRANSMIT_HOLDING = 0x00; // For exact timing!\r
1182 c++;\r
1183 }\r
1184 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1185 volatile DWORD r = SSC_RECEIVE_HOLDING;\r
1186 (void)r;\r
1187 }\r
1188 WDT_HIT();\r
1189 }\r
1190\r
1191 c = 0;\r
1192 for(;;) {\r
1193 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1194 SSC_TRANSMIT_HOLDING = cmd[c];\r
1195 c++;\r
1196 if(c >= len) {\r
1197 break;\r
1198 }\r
1199 }\r
1200 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1201 volatile DWORD r = SSC_RECEIVE_HOLDING;\r
1202 (void)r;\r
1203 }\r
1204 WDT_HIT();\r
1205 }\r
1206 *samples = (c + *wait) << 3;\r
1207}\r
1208\r
1209//-----------------------------------------------------------------------------\r
1210// To generate an arbitrary stream from reader\r
1211//\r
1212//-----------------------------------------------------------------------------\r
1213void ArbitraryFromReader(const BYTE *cmd, int parity, int len)\r
1214{\r
1215 int i;\r
1216 int j;\r
1217 int last;\r
1218 BYTE b;\r
1219\r
1220 ToSendReset();\r
1221\r
1222 // Start of Communication (Seq. Z)\r
1223 Sequence(SEC_Z);\r
1224 last = 0;\r
1225\r
1226 for(i = 0; i < len; i++) {\r
1227 // Data bits\r
1228 b = cmd[i];\r
1229 for(j = 0; j < 8; j++) {\r
1230 if(b & 1) {\r
1231 // Sequence X\r
1232 Sequence(SEC_X);\r
1233 last = 1;\r
1234 } else {\r
1235 if(last == 0) {\r
1236 // Sequence Z\r
1237 Sequence(SEC_Z);\r
1238 }\r
1239 else {\r
1240 // Sequence Y\r
1241 Sequence(SEC_Y);\r
1242 last = 0;\r
1243 }\r
1244 }\r
1245 b >>= 1;\r
1246\r
1247 }\r
1248\r
1249 // Predefined parity bit, the flipper flips when needed, because of flips in byte sent\r
1250 if(((parity >> (len - i - 1)) & 1)) {\r
1251 // Sequence X\r
1252 Sequence(SEC_X);\r
1253 last = 1;\r
1254 } else {\r
1255 if(last == 0) {\r
1256 // Sequence Z\r
1257 Sequence(SEC_Z);\r
1258 }\r
1259 else {\r
1260 // Sequence Y\r
1261 Sequence(SEC_Y);\r
1262 last = 0;\r
1263 }\r
1264 }\r
1265 }\r
1266\r
1267 // End of Communication\r
1268 if(last == 0) {\r
1269 // Sequence Z\r
1270 Sequence(SEC_Z);\r
1271 }\r
1272 else {\r
1273 // Sequence Y\r
1274 Sequence(SEC_Y);\r
1275 last = 0;\r
1276 }\r
1277 // Sequence Y\r
1278 Sequence(SEC_Y);\r
1279\r
1280 // Just to be sure!\r
1281 Sequence(SEC_Y);\r
1282 Sequence(SEC_Y);\r
1283 Sequence(SEC_Y);\r
1284\r
1285 // Convert from last character reference to length\r
1286 ToSendMax++;\r
1287}\r
1288\r
1289//-----------------------------------------------------------------------------\r
1290// Code a 7-bit command without parity bit\r
1291// This is especially for 0x26 and 0x52 (REQA and WUPA)\r
1292//-----------------------------------------------------------------------------\r
1293void ShortFrameFromReader(const BYTE *cmd)\r
1294{\r
1295 int j;\r
1296 int last;\r
1297 BYTE b;\r
1298\r
1299 ToSendReset();\r
1300\r
1301 // Start of Communication (Seq. Z)\r
1302 Sequence(SEC_Z);\r
1303 last = 0;\r
1304\r
1305 b = cmd[0];\r
1306 for(j = 0; j < 7; j++) {\r
1307 if(b & 1) {\r
1308 // Sequence X\r
1309 Sequence(SEC_X);\r
1310 last = 1;\r
1311 } else {\r
1312 if(last == 0) {\r
1313 // Sequence Z\r
1314 Sequence(SEC_Z);\r
1315 }\r
1316 else {\r
1317 // Sequence Y\r
1318 Sequence(SEC_Y);\r
1319 last = 0;\r
1320 }\r
1321 }\r
1322 b >>= 1;\r
1323 }\r
1324\r
1325 // End of Communication\r
1326 if(last == 0) {\r
1327 // Sequence Z\r
1328 Sequence(SEC_Z);\r
1329 }\r
1330 else {\r
1331 // Sequence Y\r
1332 Sequence(SEC_Y);\r
1333 last = 0;\r
1334 }\r
1335 // Sequence Y\r
1336 Sequence(SEC_Y);\r
1337\r
1338 // Just to be sure!\r
1339 Sequence(SEC_Y);\r
1340 Sequence(SEC_Y);\r
1341 Sequence(SEC_Y);\r
1342\r
1343 // Convert from last character reference to length\r
1344 ToSendMax++;\r
1345}\r
1346\r
1347//-----------------------------------------------------------------------------\r
1348// Prepare reader command to send to FPGA\r
1349//\r
1350//-----------------------------------------------------------------------------\r
1351void CodeIso14443aAsReader(const BYTE *cmd, int len)\r
1352{\r
1353 int i, j;\r
1354 int last;\r
1355 int oddparity;\r
1356 BYTE b;\r
1357\r
1358 ToSendReset();\r
1359\r
1360 // Start of Communication (Seq. Z)\r
1361 Sequence(SEC_Z);\r
1362 last = 0;\r
1363\r
1364 for(i = 0; i < len; i++) {\r
1365 // Data bits\r
1366 b = cmd[i];\r
1367 oddparity = 0x01;\r
1368 for(j = 0; j < 8; j++) {\r
1369 oddparity ^= (b & 1);\r
1370 if(b & 1) {\r
1371 // Sequence X\r
1372 Sequence(SEC_X);\r
1373 last = 1;\r
1374 } else {\r
1375 if(last == 0) {\r
1376 // Sequence Z\r
1377 Sequence(SEC_Z);\r
1378 }\r
1379 else {\r
1380 // Sequence Y\r
1381 Sequence(SEC_Y);\r
1382 last = 0;\r
1383 }\r
1384 }\r
1385 b >>= 1;\r
1386 }\r
1387\r
1388 // Parity bit\r
1389 if(oddparity) {\r
1390 // Sequence X\r
1391 Sequence(SEC_X);\r
1392 last = 1;\r
1393 } else {\r
1394 if(last == 0) {\r
1395 // Sequence Z\r
1396 Sequence(SEC_Z);\r
1397 }\r
1398 else {\r
1399 // Sequence Y\r
1400 Sequence(SEC_Y);\r
1401 last = 0;\r
1402 }\r
1403 }\r
1404 }\r
1405\r
1406 // End of Communication\r
1407 if(last == 0) {\r
1408 // Sequence Z\r
1409 Sequence(SEC_Z);\r
1410 }\r
1411 else {\r
1412 // Sequence Y\r
1413 Sequence(SEC_Y);\r
1414 last = 0;\r
1415 }\r
1416 // Sequence Y\r
1417 Sequence(SEC_Y);\r
1418\r
1419 // Just to be sure!\r
1420 Sequence(SEC_Y);\r
1421 Sequence(SEC_Y);\r
1422 Sequence(SEC_Y);\r
1423\r
1424 // Convert from last character reference to length\r
1425 ToSendMax++;\r
1426}\r
1427\r
1428\r
1429//-----------------------------------------------------------------------------\r
1430// Wait a certain time for tag response\r
1431// If a response is captured return TRUE\r
1432// If it takes to long return FALSE\r
1433//-----------------------------------------------------------------------------\r
1434static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *samples, int *elapsed) //BYTE *buffer\r
1435{\r
1436 // buffer needs to be 512 bytes\r
1437 int c;\r
1438\r
0e25ae11 1439 // Set FPGA mode to "reader listen mode", no modulation (listen\r
6658905f 1440 // only, since we are receiving, not transmitting).\r
0e25ae11 1441 // Signal field is on with the appropriate LED\r
1442 LED_D_ON();\r
6658905f 1443 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);\r
1444\r
1445 // Now get the answer from the card\r
1446 Demod.output = receivedResponse;\r
1447 Demod.len = 0;\r
1448 Demod.state = DEMOD_UNSYNCD;\r
1449\r
1450 BYTE b;\r
1451 *elapsed = 0;\r
1452\r
1453 c = 0;\r
1454 for(;;) {\r
1455 WDT_HIT();\r
1456\r
1457 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {\r
1458 SSC_TRANSMIT_HOLDING = 0x00; // To make use of exact timing of next command from reader!!\r
1459 (*elapsed)++;\r
1460 }\r
1461 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {\r
1462 if(c < 512) { c++; } else { return FALSE; }\r
1463 b = (BYTE)SSC_RECEIVE_HOLDING;\r
1464 if(ManchesterDecoding((b & 0xf0) >> 4)) {\r
1465 *samples = ((c - 1) << 3) + 4;\r
1466 return TRUE;\r
1467 }\r
1468 if(ManchesterDecoding(b & 0x0f)) {\r
1469 *samples = c << 3;\r
1470 return TRUE;\r
1471 }\r
1472 }\r
1473 }\r
1474}\r
1475\r
1476//-----------------------------------------------------------------------------\r
1477// Read an ISO 14443a tag. Send out commands and store answers.\r
1478//\r
1479//-----------------------------------------------------------------------------\r
1480void ReaderIso14443a(DWORD parameter)\r
1481{\r
1482 // Anticollision\r
1483 static const BYTE cmd1[] = { 0x52 }; // or 0x26\r
1484 static const BYTE cmd2[] = { 0x93,0x20 };\r
1485 // UID = 0x2a,0x69,0x8d,0x43,0x8d, last two bytes are CRC bytes\r
1486 BYTE cmd3[] = { 0x93,0x70,0x2a,0x69,0x8d,0x43,0x8d,0x52,0x55 };\r
1487\r
1488 // For Ultralight add an extra anticollission layer -> 95 20 and then 95 70\r
1489\r
1490 // greg - here we will add our cascade level 2 anticolission and select functions to deal with ultralight // and 7-byte UIDs in generall...\r
1491 BYTE cmd4[] = {0x95,0x20}; // ask for cascade 2 select\r
1492 // 95 20\r
1493 //BYTE cmd3a[] = { 0x95,0x70,0x2a,0x69,0x8d,0x43,0x8d,0x52,0x55 };\r
1494 // 95 70\r
1495\r
1496 // cascade 2 select\r
1497 BYTE cmd5[] = { 0x95,0x70,0x2a,0x69,0x8d,0x43,0x8d,0x52,0x55 };\r
1498\r
1499\r
1500 // RATS (request for answer to select)\r
1501 //BYTE cmd6[] = { 0xe0,0x50,0xbc,0xa5 }; // original RATS\r
1502 BYTE cmd6[] = { 0xe0,0x21,0xb2,0xc7 }; // Desfire RATS\r
1503\r
093cbaf6 1504 // Mifare AUTH\r
1505 BYTE cmd7[] = { 0x60, 0x00, 0x00, 0x00 };\r
1506\r
6658905f 1507 int reqaddr = 2024; // was 2024 - tied to other size changes\r
1508 int reqsize = 60;\r
1509\r
1510 BYTE *req1 = (((BYTE *)BigBuf) + reqaddr);\r
1511 int req1Len;\r
1512\r
1513 BYTE *req2 = (((BYTE *)BigBuf) + reqaddr + reqsize);\r
1514 int req2Len;\r
1515\r
1516 BYTE *req3 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 2));\r
1517 int req3Len;\r
1518\r
1519// greg added req 4 & 5 to deal with cascade 2 section\r
1520 BYTE *req4 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 3));\r
1521 int req4Len;\r
1522\r
1523 BYTE *req5 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 4));\r
1524 int req5Len;\r
1525\r
1526 BYTE *req6 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 5));\r
1527 int req6Len;\r
1528\r
093cbaf6 1529 BYTE *req7 = (((BYTE *)BigBuf) + reqaddr + (reqsize * 6));\r
1530 int req7Len;\r
6658905f 1531\r
1532 BYTE *receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes\r
1533\r
1534 BYTE *trace = (BYTE *)BigBuf;\r
1535 int traceLen = 0;\r
1536 int rsamples = 0;\r
1537\r
0e25ae11 1538 memset(trace, 0x44, 2000); // was 2000 - tied to oter size chnages\r
6658905f 1539 // setting it to 3000 causes no tag responses to be detected (2900 is ok)\r
1540 // setting it to 1000 causes no tag responses to be detected\r
1541\r
1542 // Prepare some commands!\r
1543 ShortFrameFromReader(cmd1);\r
1544 memcpy(req1, ToSend, ToSendMax); req1Len = ToSendMax;\r
1545\r
1546 CodeIso14443aAsReader(cmd2, sizeof(cmd2));\r
1547 memcpy(req2, ToSend, ToSendMax); req2Len = ToSendMax;\r
1548\r
1549 CodeIso14443aAsReader(cmd3, sizeof(cmd3));\r
1550 memcpy(req3, ToSend, ToSendMax); req3Len = ToSendMax;\r
1551\r
1552\r
1553 CodeIso14443aAsReader(cmd4, sizeof(cmd4)); // 4 is cascade 2 request\r
1554 memcpy(req4, ToSend, ToSendMax); req4Len = ToSendMax;\r
1555\r
1556\r
1557 CodeIso14443aAsReader(cmd5, sizeof(cmd5)); // 5 is cascade 2 select\r
1558 memcpy(req5, ToSend, ToSendMax); req5Len = ToSendMax;\r
1559\r
1560\r
1561 CodeIso14443aAsReader(cmd6, sizeof(cmd6));\r
1562 memcpy(req6, ToSend, ToSendMax); req6Len = ToSendMax;\r
1563\r
1564 // Setup SSC\r
1565 FpgaSetupSsc();\r
1566\r
1567 // Start from off (no field generated)\r
0e25ae11 1568 // Signal field is off with the appropriate LED\r
1569 LED_D_OFF();\r
6658905f 1570 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1571 SpinDelay(200);\r
1572\r
1573 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1574 FpgaSetupSsc();\r
1575\r
1576 // Now give it time to spin up.\r
0e25ae11 1577 // Signal field is on with the appropriate LED\r
1578 LED_D_ON();\r
6658905f 1579 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1580 SpinDelay(200);\r
1581\r
1582 LED_A_ON();\r
1583 LED_B_OFF();\r
1584 LED_C_OFF();\r
6658905f 1585\r
1586 int samples = 0;\r
1587 int tsamples = 0;\r
1588 int wait = 0;\r
1589 int elapsed = 0;\r
1590\r
1591 for(;;) {\r
1592 // Send WUPA (or REQA)\r
1593 TransmitFor14443a(req1, req1Len, &tsamples, &wait);\r
1594 // Store answer in buffer\r
1595 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1596 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1597 trace[traceLen++] = 1;\r
1598 memcpy(trace+traceLen, cmd1, 1);\r
1599 traceLen += 1;\r
1600 if(traceLen > TRACE_LENGTH) goto done;\r
1601\r
1602 while(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1603 if(BUTTON_PRESS()) goto done;\r
1604\r
1605 // No answer, just continue polling\r
1606 TransmitFor14443a(req1, req1Len, &tsamples, &wait);\r
1607 // Store answer in buffer\r
1608 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1609 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1610 trace[traceLen++] = 1;\r
1611 memcpy(trace+traceLen, cmd1, 1);\r
1612 traceLen += 1;\r
1613 if(traceLen > TRACE_LENGTH) goto done;\r
1614 }\r
1615\r
1616 // Store answer in buffer\r
1617 rsamples = rsamples + (samples - Demod.samples);\r
1618 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1619 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1620 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1621 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1622 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1623 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1624 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1625 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1626 trace[traceLen++] = Demod.len;\r
1627 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1628 traceLen += Demod.len;\r
1629 if(traceLen > TRACE_LENGTH) goto done;\r
1630\r
1631 // Ask for card UID\r
1632 TransmitFor14443a(req2, req2Len, &tsamples, &wait);\r
1633 // Store answer in buffer\r
1634 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1635 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1636 trace[traceLen++] = 2;\r
1637 memcpy(trace+traceLen, cmd2, 2);\r
1638 traceLen += 2;\r
1639 if(traceLen > TRACE_LENGTH) goto done;\r
1640\r
1641 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1642 continue;\r
1643 }\r
1644\r
1645 // Store answer in buffer\r
1646 rsamples = rsamples + (samples - Demod.samples);\r
1647 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1648 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1649 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1650 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1651 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1652 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1653 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1654 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1655 trace[traceLen++] = Demod.len;\r
1656 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1657 traceLen += Demod.len;\r
1658 if(traceLen > TRACE_LENGTH) goto done;\r
1659\r
1660 // Construct SELECT UID command\r
1661 // First copy the 5 bytes (Mifare Classic) after the 93 70\r
1662 memcpy(cmd3+2,receivedAnswer,5);\r
1663 // Secondly compute the two CRC bytes at the end\r
1664 ComputeCrc14443(CRC_14443_A, cmd3, 7, &cmd3[7], &cmd3[8]);\r
1665 // Prepare the bit sequence to modulate the subcarrier\r
1666 // Store answer in buffer\r
1667 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1668 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1669 trace[traceLen++] = 9;\r
1670 memcpy(trace+traceLen, cmd3, 9);\r
1671 traceLen += 9;\r
1672 if(traceLen > TRACE_LENGTH) goto done;\r
1673 CodeIso14443aAsReader(cmd3, sizeof(cmd3));\r
1674 memcpy(req3, ToSend, ToSendMax); req3Len = ToSendMax;\r
1675\r
1676 // Select the card\r
1677 TransmitFor14443a(req3, req3Len, &samples, &wait);\r
1678 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1679 continue;\r
1680 }\r
1681\r
1682 // Store answer in buffer\r
1683 rsamples = rsamples + (samples - Demod.samples);\r
1684 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1685 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1686 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1687 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1688 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1689 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1690 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1691 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1692 trace[traceLen++] = Demod.len;\r
1693 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1694 traceLen += Demod.len;\r
1695 if(traceLen > TRACE_LENGTH) goto done;\r
1696\r
0e25ae11 1697// OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in\r
6658905f 1698// which case we need to make a cascade 2 request and select - this is a long UID\r
30f2a7d3 1699 if (receivedAnswer[0] == 0x88)\r
6658905f 1700 {\r
1701 // Do cascade level 2 stuff\r
1702 ///////////////////////////////////////////////////////////////////\r
1703 // First issue a '95 20' identify request\r
1704 // Ask for card UID (part 2)\r
1705 TransmitFor14443a(req4, req4Len, &tsamples, &wait);\r
1706 // Store answer in buffer\r
1707 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1708 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1709 trace[traceLen++] = 2;\r
1710 memcpy(trace+traceLen, cmd4, 2);\r
1711 traceLen += 2;\r
1712 if(traceLen > TRACE_LENGTH) {\r
1713 DbpString("Bugging out, just popped tracelength");\r
1714 goto done;}\r
1715\r
1716 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1717 continue;\r
1718 }\r
1719 // Store answer in buffer\r
1720 rsamples = rsamples + (samples - Demod.samples);\r
1721 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1722 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1723 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1724 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1725 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1726 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1727 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1728 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1729 trace[traceLen++] = Demod.len;\r
1730 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1731 traceLen += Demod.len;\r
1732 if(traceLen > TRACE_LENGTH) goto done;\r
1733 //////////////////////////////////////////////////////////////////\r
1734 // Then Construct SELECT UID (cascasde 2) command\r
1735 DbpString("Just about to copy the UID out of the cascade 2 id req");\r
1736 // First copy the 5 bytes (Mifare Classic) after the 95 70\r
1737 memcpy(cmd5+2,receivedAnswer,5);\r
1738 // Secondly compute the two CRC bytes at the end\r
1739 ComputeCrc14443(CRC_14443_A, cmd4, 7, &cmd5[7], &cmd5[8]);\r
1740 // Prepare the bit sequence to modulate the subcarrier\r
1741 // Store answer in buffer\r
1742 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1743 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1744 trace[traceLen++] = 9;\r
1745 memcpy(trace+traceLen, cmd5, 9);\r
1746 traceLen += 9;\r
1747 if(traceLen > TRACE_LENGTH) goto done;\r
1748 CodeIso14443aAsReader(cmd5, sizeof(cmd5));\r
1749 memcpy(req5, ToSend, ToSendMax); req5Len = ToSendMax;\r
1750\r
1751 // Select the card\r
1752 TransmitFor14443a(req4, req4Len, &samples, &wait);\r
1753 if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1754 continue;\r
1755 }\r
1756\r
1757 // Store answer in buffer\r
1758 rsamples = rsamples + (samples - Demod.samples);\r
1759 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1760 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1761 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1762 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1763 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1764 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1765 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1766 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1767 trace[traceLen++] = Demod.len;\r
1768 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1769 traceLen += Demod.len;\r
1770 if(traceLen > TRACE_LENGTH) goto done;\r
1771\r
0e25ae11 1772 }\r
6658905f 1773\r
1774 // Secondly compute the two CRC bytes at the end\r
093cbaf6 1775 ComputeCrc14443(CRC_14443_A, cmd7, 2, &cmd7[2], &cmd7[3]);\r
1776 CodeIso14443aAsReader(cmd7, sizeof(cmd7));\r
1777 memcpy(req7, ToSend, ToSendMax); req7Len = ToSendMax;\r
6658905f 1778 // Send authentication request (Mifare Classic)\r
093cbaf6 1779 TransmitFor14443a(req7, req7Len, &samples, &wait);\r
6658905f 1780 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1781 trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;\r
1782 trace[traceLen++] = 4;\r
093cbaf6 1783 memcpy(trace+traceLen, cmd7, 4);\r
6658905f 1784 traceLen += 4;\r
1785 if(traceLen > TRACE_LENGTH) goto done;\r
1786 if(GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {\r
1787 rsamples++;\r
1788 // We received probably a random, continue and trace!\r
1789 }\r
1790 else {\r
1791 // Received nothing\r
1792 continue;\r
1793 }\r
1794\r
1795 // Trace the random, i'm curious\r
1796 rsamples = rsamples + (samples - Demod.samples);\r
1797 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
1798 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
1799 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
1800 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
1801 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
1802 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
1803 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
1804 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
1805 trace[traceLen++] = Demod.len;\r
1806 memcpy(trace+traceLen, receivedAnswer, Demod.len);\r
1807 traceLen += Demod.len;\r
1808 if(traceLen > TRACE_LENGTH) goto done;\r
1809\r
1810 // Thats it...\r
1811 }\r
1812\r
1813done:\r
5435eb0c 1814 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
093cbaf6 1815 LEDsoff();\r
6658905f 1816 DbpIntegers(rsamples, 0xCC, 0xCC);\r
1817 DbpString("ready..");\r
1818}\r
Impressum, Datenschutz