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