1 /*-
2 * Free/Libre Near Field Communication (NFC) library
3 *
4 * Libnfc historical contributors:
5 * Copyright (C) 2009 Roel Verdult
6 * Copyright (C) 2009-2013 Romuald Conty
7 * Copyright (C) 2010-2012 Romain Tartière
8 * Copyright (C) 2010-2013 Philippe Teuwen
9 * Copyright (C) 2012-2013 Ludovic Rousseau
10 * See AUTHORS file for a more comprehensive list of contributors.
11 * Additional contributors of this file:
12 *
13 * This program is free software: you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published by the
15 * Free Software Foundation, either version 3 of the License, or (at your
16 * option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 * more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>
25 */
26
27 /**
28 * @file target-subr.c
29 * @brief Target-related subroutines. (ie. determine target type, print target, etc.)
30 */
31 #include <inttypes.h>
32 #include <nfc/nfc.h>
33
34 #include "target-subr.h"
35
36 struct card_atqa {
37 uint16_t atqa;
38 uint16_t mask;
39 char type[128];
40 // list of up to 8 SAK values compatible with this ATQA
41 int saklist[8];
42 };
43
44 struct card_sak {
45 uint8_t sak;
46 uint8_t mask;
47 char type[128];
48 };
49
50 struct card_atqa const_ca[] = {
51 {
52 0x0044, 0xffff, "MIFARE Ultralight",
53 {0, -1}
54 },
55 {
56 0x0044, 0xffff, "MIFARE Ultralight C",
57 {0, -1}
58 },
59 {
60 0x0004, 0xff0f, "MIFARE Mini 0.3K",
61 {1, -1}
62 },
63 {
64 0x0004, 0xff0f, "MIFARE Classic 1K",
65 {2, -1}
66 },
67 {
68 0x0002, 0xff0f, "MIFARE Classic 4K",
69 {3, -1}
70 },
71 {
72 0x0004, 0xffff, "MIFARE Plus (4 Byte UID or 4 Byte RID)",
73 {4, 5, 6, 7, 8, 9, -1}
74 },
75 {
76 0x0002, 0xffff, "MIFARE Plus (4 Byte UID or 4 Byte RID)",
77 {4, 5, 6, 7, 8, 9, -1}
78 },
79 {
80 0x0044, 0xffff, "MIFARE Plus (7 Byte UID)",
81 {4, 5, 6, 7, 8, 9, -1}
82 },
83 {
84 0x0042, 0xffff, "MIFARE Plus (7 Byte UID)",
85 {4, 5, 6, 7, 8, 9, -1}
86 },
87 {
88 0x0344, 0xffff, "MIFARE DESFire",
89 {10, 11, -1}
90 },
91 {
92 0x0044, 0xffff, "P3SR008",
93 { -1}
94 }, // TODO we need SAK info
95 {
96 0x0004, 0xf0ff, "SmartMX with MIFARE 1K emulation",
97 {12, -1}
98 },
99 {
100 0x0002, 0xf0ff, "SmartMX with MIFARE 4K emulation",
101 {12, -1}
102 },
103 {
104 0x0048, 0xf0ff, "SmartMX with 7 Byte UID",
105 {12, -1}
106 }
107 };
108
109 struct card_sak const_cs[] = {
110 {0x00, 0xff, "" }, // 00 MIFARE Ultralight / Ultralight C
111 {0x09, 0xff, "" }, // 01 MIFARE Mini 0.3K
112 {0x08, 0xff, "" }, // 02 MIFARE Classic 1K
113 {0x18, 0xff, "" }, // 03 MIFARE Classik 4K
114 {0x08, 0xff, " 2K, Security level 1" }, // 04 MIFARE Plus
115 {0x18, 0xff, " 4K, Security level 1" }, // 05 MIFARE Plus
116 {0x10, 0xff, " 2K, Security level 2" }, // 06 MIFARE Plus
117 {0x11, 0xff, " 4K, Security level 2" }, // 07 MIFARE Plus
118 {0x20, 0xff, " 2K, Security level 3" }, // 08 MIFARE Plus
119 {0x20, 0xff, " 4K, Security level 3" }, // 09 MIFARE Plus
120 {0x20, 0xff, " 4K" }, // 10 MIFARE DESFire
121 {0x20, 0xff, " EV1 2K/4K/8K" }, // 11 MIFARE DESFire
122 {0x00, 0x00, "" }, // 12 SmartMX
123 };
124
125 int
snprint_hex(char * dst,size_t size,const uint8_t * pbtData,const size_t szBytes)126 snprint_hex(char *dst, size_t size, const uint8_t *pbtData, const size_t szBytes)
127 {
128 size_t szPos;
129 size_t res = 0;
130 for (szPos = 0; szPos < szBytes; szPos++) {
131 res += snprintf(dst + res, size - res, "%02x ", pbtData[szPos]);
132 }
133 res += snprintf(dst + res, size - res, "\n");
134 return res;
135 }
136
137 #define SAK_UID_NOT_COMPLETE 0x04
138 #define SAK_ISO14443_4_COMPLIANT 0x20
139 #define SAK_ISO18092_COMPLIANT 0x40
140
141 void
snprint_nfc_iso14443a_info(char * dst,size_t size,const nfc_iso14443a_info * pnai,bool verbose)142 snprint_nfc_iso14443a_info(char *dst, size_t size, const nfc_iso14443a_info *pnai, bool verbose)
143 {
144 int off = 0;
145 off += snprintf(dst + off, size - off, " ATQA (SENS_RES): ");
146 off += snprint_hex(dst + off, size - off, pnai->abtAtqa, 2);
147 if (verbose) {
148 off += snprintf(dst + off, size - off, "* UID size: ");
149 switch ((pnai->abtAtqa[1] & 0xc0) >> 6) {
150 case 0:
151 off += snprintf(dst + off, size - off, "single\n");
152 break;
153 case 1:
154 off += snprintf(dst + off, size - off, "double\n");
155 break;
156 case 2:
157 off += snprintf(dst + off, size - off, "triple\n");
158 break;
159 case 3:
160 off += snprintf(dst + off, size - off, "RFU\n");
161 break;
162 }
163 off += snprintf(dst + off, size - off, "* bit frame anticollision ");
164 switch (pnai->abtAtqa[1] & 0x1f) {
165 case 0x01:
166 case 0x02:
167 case 0x04:
168 case 0x08:
169 case 0x10:
170 off += snprintf(dst + off, size - off, "supported\n");
171 break;
172 default:
173 off += snprintf(dst + off, size - off, "not supported\n");
174 break;
175 }
176 }
177 off += snprintf(dst + off, size - off, " UID (NFCID%c): ", (pnai->abtUid[0] == 0x08 ? '3' : '1'));
178 off += snprint_hex(dst + off, size - off, pnai->abtUid, pnai->szUidLen);
179 if (verbose) {
180 if (pnai->abtUid[0] == 0x08) {
181 off += snprintf(dst + off, size - off, "* Random UID\n");
182 }
183 }
184 off += snprintf(dst + off, size - off, " SAK (SEL_RES): ");
185 off += snprint_hex(dst + off, size - off, &pnai->btSak, 1);
186 if (verbose) {
187 if (pnai->btSak & SAK_UID_NOT_COMPLETE) {
188 off += snprintf(dst + off, size - off, "* Warning! Cascade bit set: UID not complete\n");
189 }
190 if (pnai->btSak & SAK_ISO14443_4_COMPLIANT) {
191 off += snprintf(dst + off, size - off, "* Compliant with ISO/IEC 14443-4\n");
192 } else {
193 off += snprintf(dst + off, size - off, "* Not compliant with ISO/IEC 14443-4\n");
194 }
195 if (pnai->btSak & SAK_ISO18092_COMPLIANT) {
196 off += snprintf(dst + off, size - off, "* Compliant with ISO/IEC 18092\n");
197 } else {
198 off += snprintf(dst + off, size - off, "* Not compliant with ISO/IEC 18092\n");
199 }
200 }
201 if (pnai->szAtsLen) {
202 off += snprintf(dst + off, size - off, " ATS: ");
203 off += snprint_hex(dst + off, size - off, pnai->abtAts, pnai->szAtsLen);
204 }
205 if (pnai->szAtsLen && verbose) {
206 // Decode ATS according to ISO/IEC 14443-4 (5.2 Answer to select)
207 const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
208 off += snprintf(dst + off, size - off, "* Max Frame Size accepted by PICC: %d bytes\n", iMaxFrameSizes[pnai->abtAts[0] & 0x0F]);
209
210 size_t offset = 1;
211 if (pnai->abtAts[0] & 0x10) { // TA(1) present
212 uint8_t TA = pnai->abtAts[offset];
213 offset++;
214 off += snprintf(dst + off, size - off, "* Bit Rate Capability:\n");
215 if (TA == 0) {
216 off += snprintf(dst + off, size - off, " * PICC supports only 106 kbits/s in both directions\n");
217 }
218 if (TA & 1 << 7) {
219 off += snprintf(dst + off, size - off, " * Same bitrate in both directions mandatory\n");
220 }
221 if (TA & 1 << 4) {
222 off += snprintf(dst + off, size - off, " * PICC to PCD, DS=2, bitrate 212 kbits/s supported\n");
223 }
224 if (TA & 1 << 5) {
225 off += snprintf(dst + off, size - off, " * PICC to PCD, DS=4, bitrate 424 kbits/s supported\n");
226 }
227 if (TA & 1 << 6) {
228 off += snprintf(dst + off, size - off, " * PICC to PCD, DS=8, bitrate 847 kbits/s supported\n");
229 }
230 if (TA & 1 << 0) {
231 off += snprintf(dst + off, size - off, " * PCD to PICC, DR=2, bitrate 212 kbits/s supported\n");
232 }
233 if (TA & 1 << 1) {
234 off += snprintf(dst + off, size - off, " * PCD to PICC, DR=4, bitrate 424 kbits/s supported\n");
235 }
236 if (TA & 1 << 2) {
237 off += snprintf(dst + off, size - off, " * PCD to PICC, DR=8, bitrate 847 kbits/s supported\n");
238 }
239 if (TA & 1 << 3) {
240 off += snprintf(dst + off, size - off, " * ERROR unknown value\n");
241 }
242 }
243 if (pnai->abtAts[0] & 0x20) { // TB(1) present
244 uint8_t TB = pnai->abtAts[offset];
245 offset++;
246 off += snprintf(dst + off, size - off, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((TB & 0xf0) >> 4)) / 13560.0);
247 if ((TB & 0x0f) == 0) {
248 off += snprintf(dst + off, size - off, "* No Start-up Frame Guard Time required\n");
249 } else {
250 off += snprintf(dst + off, size - off, "* Start-up Frame Guard Time: %.4g ms\n", 256.0 * 16.0 * (1 << (TB & 0x0f)) / 13560.0);
251 }
252 }
253 if (pnai->abtAts[0] & 0x40) { // TC(1) present
254 uint8_t TC = pnai->abtAts[offset];
255 offset++;
256 if (TC & 0x1) {
257 off += snprintf(dst + off, size - off, "* Node Address supported\n");
258 } else {
259 off += snprintf(dst + off, size - off, "* Node Address not supported\n");
260 }
261 if (TC & 0x2) {
262 off += snprintf(dst + off, size - off, "* Card IDentifier supported\n");
263 } else {
264 off += snprintf(dst + off, size - off, "* Card IDentifier not supported\n");
265 }
266 }
267 if (pnai->szAtsLen > offset) {
268 off += snprintf(dst + off, size - off, "* Historical bytes Tk: ");
269 off += snprint_hex(dst + off, size - off, pnai->abtAts + offset, (pnai->szAtsLen - offset));
270 uint8_t CIB = pnai->abtAts[offset];
271 offset++;
272 if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) {
273 off += snprintf(dst + off, size - off, " * Proprietary format\n");
274 if (CIB == 0xc1) {
275 off += snprintf(dst + off, size - off, " * Tag byte: Mifare or virtual cards of various types\n");
276 uint8_t L = pnai->abtAts[offset];
277 offset++;
278 if (L != (pnai->szAtsLen - offset)) {
279 off += snprintf(dst + off, size - off, " * Warning: Type Identification Coding length (%i)", L);
280 off += snprintf(dst + off, size - off, " not matching Tk length (%" PRIdPTR ")\n", (pnai->szAtsLen - offset));
281 }
282 if ((pnai->szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes
283 uint8_t CTC = pnai->abtAts[offset];
284 offset++;
285 off += snprintf(dst + off, size - off, " * Chip Type: ");
286 switch (CTC & 0xf0) {
287 case 0x00:
288 off += snprintf(dst + off, size - off, "(Multiple) Virtual Cards\n");
289 break;
290 case 0x10:
291 off += snprintf(dst + off, size - off, "Mifare DESFire\n");
292 break;
293 case 0x20:
294 off += snprintf(dst + off, size - off, "Mifare Plus\n");
295 break;
296 default:
297 off += snprintf(dst + off, size - off, "RFU\n");
298 break;
299 }
300 off += snprintf(dst + off, size - off, " * Memory size: ");
301 switch (CTC & 0x0f) {
302 case 0x00:
303 off += snprintf(dst + off, size - off, "<1 kbyte\n");
304 break;
305 case 0x01:
306 off += snprintf(dst + off, size - off, "1 kbyte\n");
307 break;
308 case 0x02:
309 off += snprintf(dst + off, size - off, "2 kbyte\n");
310 break;
311 case 0x03:
312 off += snprintf(dst + off, size - off, "4 kbyte\n");
313 break;
314 case 0x04:
315 off += snprintf(dst + off, size - off, "8 kbyte\n");
316 break;
317 case 0x0f:
318 off += snprintf(dst + off, size - off, "Unspecified\n");
319 break;
320 default:
321 off += snprintf(dst + off, size - off, "RFU\n");
322 break;
323 }
324 }
325 if ((pnai->szAtsLen - offset) > 0) { // Omit 2 CRC bytes
326 uint8_t CVC = pnai->abtAts[offset];
327 offset++;
328 off += snprintf(dst + off, size - off, " * Chip Status: ");
329 switch (CVC & 0xf0) {
330 case 0x00:
331 off += snprintf(dst + off, size - off, "Engineering sample\n");
332 break;
333 case 0x20:
334 off += snprintf(dst + off, size - off, "Released\n");
335 break;
336 default:
337 off += snprintf(dst + off, size - off, "RFU\n");
338 break;
339 }
340 off += snprintf(dst + off, size - off, " * Chip Generation: ");
341 switch (CVC & 0x0f) {
342 case 0x00:
343 off += snprintf(dst + off, size - off, "Generation 1\n");
344 break;
345 case 0x01:
346 off += snprintf(dst + off, size - off, "Generation 2\n");
347 break;
348 case 0x02:
349 off += snprintf(dst + off, size - off, "Generation 3\n");
350 break;
351 case 0x0f:
352 off += snprintf(dst + off, size - off, "Unspecified\n");
353 break;
354 default:
355 off += snprintf(dst + off, size - off, "RFU\n");
356 break;
357 }
358 }
359 if ((pnai->szAtsLen - offset) > 0) { // Omit 2 CRC bytes
360 uint8_t VCS = pnai->abtAts[offset];
361 offset++;
362 off += snprintf(dst + off, size - off, " * Specifics (Virtual Card Selection):\n");
363 if ((VCS & 0x09) == 0x00) {
364 off += snprintf(dst + off, size - off, " * Only VCSL supported\n");
365 } else if ((VCS & 0x09) == 0x01) {
366 off += snprintf(dst + off, size - off, " * VCS, VCSL and SVC supported\n");
367 }
368 if ((VCS & 0x0e) == 0x00) {
369 off += snprintf(dst + off, size - off, " * SL1, SL2(?), SL3 supported\n");
370 } else if ((VCS & 0x0e) == 0x02) {
371 off += snprintf(dst + off, size - off, " * SL3 only card\n");
372 } else if ((VCS & 0x0f) == 0x0e) {
373 off += snprintf(dst + off, size - off, " * No VCS command supported\n");
374 } else if ((VCS & 0x0f) == 0x0f) {
375 off += snprintf(dst + off, size - off, " * Unspecified\n");
376 } else {
377 off += snprintf(dst + off, size - off, " * RFU\n");
378 }
379 }
380 }
381 } else {
382 if (CIB == 0x00) {
383 off += snprintf(dst + off, size - off, " * Tk after 0x00 consist of optional consecutive COMPACT-TLV data objects\n");
384 off += snprintf(dst + off, size - off, " followed by a mandatory status indicator (the last three bytes, not in TLV)\n");
385 off += snprintf(dst + off, size - off, " See ISO/IEC 7816-4 8.1.1.3 for more info\n");
386 }
387 if (CIB == 0x10) {
388 off += snprintf(dst + off, size - off, " * DIR data reference: %02x\n", pnai->abtAts[offset]);
389 }
390 if (CIB == 0x80) {
391 if (pnai->szAtsLen == offset) {
392 off += snprintf(dst + off, size - off, " * No COMPACT-TLV objects found, no status found\n");
393 } else {
394 off += snprintf(dst + off, size - off, " * Tk after 0x80 consist of optional consecutive COMPACT-TLV data objects;\n");
395 off += snprintf(dst + off, size - off, " the last data object may carry a status indicator of one, two or three bytes.\n");
396 off += snprintf(dst + off, size - off, " See ISO/IEC 7816-4 8.1.1.3 for more info\n");
397 }
398 }
399 }
400 }
401 }
402 if (verbose) {
403 off += snprintf(dst + off, size - off, "\nFingerprinting based on MIFARE type Identification Procedure:\n"); // AN10833
404 uint16_t atqa = 0;
405 uint8_t sak = 0;
406 uint8_t i, j;
407 bool found_possible_match = false;
408
409 atqa = (((uint16_t)pnai->abtAtqa[0] & 0xff) << 8);
410 atqa += (((uint16_t)pnai->abtAtqa[1] & 0xff));
411 sak = ((uint8_t)pnai->btSak & 0xff);
412
413 for (i = 0; i < sizeof(const_ca) / sizeof(const_ca[0]); i++) {
414 if ((atqa & const_ca[i].mask) == const_ca[i].atqa) {
415 for (j = 0; (j < sizeof(const_ca[i].saklist) / sizeof(const_ca[i].saklist[0])) && (const_ca[i].saklist[j] >= 0); j++) {
416 int sakindex = const_ca[i].saklist[j];
417 if ((sak & const_cs[sakindex].mask) == const_cs[sakindex].sak) {
418 off += snprintf(dst + off, size - off, "* %s%s\n", const_ca[i].type, const_cs[sakindex].type);
419 found_possible_match = true;
420 }
421 }
422 }
423 }
424 // Other matches not described in
425 // AN10833 MIFARE Type Identification Procedure
426 // but seen in the field:
427 off += snprintf(dst + off, size - off, "Other possible matches based on ATQA & SAK values:\n");
428 uint32_t atqasak = 0;
429 atqasak += (((uint32_t)pnai->abtAtqa[0] & 0xff) << 16);
430 atqasak += (((uint32_t)pnai->abtAtqa[1] & 0xff) << 8);
431 atqasak += ((uint32_t)pnai->btSak & 0xff);
432 switch (atqasak) {
433 case 0x000488:
434 off += snprintf(dst + off, size - off, "* Mifare Classic 1K Infineon\n");
435 found_possible_match = true;
436 break;
437 case 0x000298:
438 off += snprintf(dst + off, size - off, "* Gemplus MPCOS\n");
439 found_possible_match = true;
440 break;
441 case 0x030428:
442 off += snprintf(dst + off, size - off, "* JCOP31\n");
443 found_possible_match = true;
444 break;
445 case 0x004820:
446 off += snprintf(dst + off, size - off, "* JCOP31 v2.4.1\n");
447 off += snprintf(dst + off, size - off, "* JCOP31 v2.2\n");
448 found_possible_match = true;
449 break;
450 case 0x000428:
451 off += snprintf(dst + off, size - off, "* JCOP31 v2.3.1\n");
452 found_possible_match = true;
453 break;
454 case 0x000453:
455 off += snprintf(dst + off, size - off, "* Fudan FM1208SH01\n");
456 found_possible_match = true;
457 break;
458 case 0x000820:
459 off += snprintf(dst + off, size - off, "* Fudan FM1208\n");
460 found_possible_match = true;
461 break;
462 case 0x000238:
463 off += snprintf(dst + off, size - off, "* MFC 4K emulated by Nokia 6212 Classic\n");
464 found_possible_match = true;
465 break;
466 case 0x000838:
467 off += snprintf(dst + off, size - off, "* MFC 4K emulated by Nokia 6131 NFC\n");
468 found_possible_match = true;
469 break;
470 }
471 if (! found_possible_match) {
472 snprintf(dst + off, size - off, "* Unknown card, sorry\n");
473 }
474 }
475 }
476
477 void
snprint_nfc_felica_info(char * dst,size_t size,const nfc_felica_info * pnfi,bool verbose)478 snprint_nfc_felica_info(char *dst, size_t size, const nfc_felica_info *pnfi, bool verbose)
479 {
480 (void) verbose;
481 int off = 0;
482 off += snprintf(dst + off, size - off, " ID (NFCID2): ");
483 off += snprint_hex(dst + off, size - off, pnfi->abtId, 8);
484 off += snprintf(dst + off, size - off, " Parameter (PAD): ");
485 off += snprint_hex(dst + off, size - off, pnfi->abtPad, 8);
486 off += snprintf(dst + off, size - off, " System Code (SC): ");
487 snprint_hex(dst + off, size - off, pnfi->abtSysCode, 2);
488 }
489
490 void
snprint_nfc_jewel_info(char * dst,size_t size,const nfc_jewel_info * pnji,bool verbose)491 snprint_nfc_jewel_info(char *dst, size_t size, const nfc_jewel_info *pnji, bool verbose)
492 {
493 (void) verbose;
494 int off = 0;
495 off += snprintf(dst + off, size - off, " ATQA (SENS_RES): ");
496 off += snprint_hex(dst + off, size - off, pnji->btSensRes, 2);
497 off += snprintf(dst + off, size - off, " 4-LSB JEWELID: ");
498 snprint_hex(dst + off, size - off, pnji->btId, 4);
499 }
500
501 #define PI_ISO14443_4_SUPPORTED 0x01
502 #define PI_NAD_SUPPORTED 0x01
503 #define PI_CID_SUPPORTED 0x02
504 void
snprint_nfc_iso14443b_info(char * dst,size_t size,const nfc_iso14443b_info * pnbi,bool verbose)505 snprint_nfc_iso14443b_info(char *dst, size_t size, const nfc_iso14443b_info *pnbi, bool verbose)
506 {
507 int off = 0;
508 off += snprintf(dst + off, size - off, " PUPI: ");
509 off += snprint_hex(dst + off, size - off, pnbi->abtPupi, 4);
510 off += snprintf(dst + off, size - off, " Application Data: ");
511 off += snprint_hex(dst + off, size - off, pnbi->abtApplicationData, 4);
512 off += snprintf(dst + off, size - off, " Protocol Info: ");
513 off += snprint_hex(dst + off, size - off, pnbi->abtProtocolInfo, 3);
514 if (verbose) {
515 off += snprintf(dst + off, size - off, "* Bit Rate Capability:\n");
516 if (pnbi->abtProtocolInfo[0] == 0) {
517 off += snprintf(dst + off, size - off, " * PICC supports only 106 kbits/s in both directions\n");
518 }
519 if (pnbi->abtProtocolInfo[0] & 1 << 7) {
520 off += snprintf(dst + off, size - off, " * Same bitrate in both directions mandatory\n");
521 }
522 if (pnbi->abtProtocolInfo[0] & 1 << 4) {
523 off += snprintf(dst + off, size - off, " * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n");
524 }
525 if (pnbi->abtProtocolInfo[0] & 1 << 5) {
526 off += snprintf(dst + off, size - off, " * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n");
527 }
528 if (pnbi->abtProtocolInfo[0] & 1 << 6) {
529 off += snprintf(dst + off, size - off, " * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n");
530 }
531 if (pnbi->abtProtocolInfo[0] & 1 << 0) {
532 off += snprintf(dst + off, size - off, " * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n");
533 }
534 if (pnbi->abtProtocolInfo[0] & 1 << 1) {
535 off += snprintf(dst + off, size - off, " * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n");
536 }
537 if (pnbi->abtProtocolInfo[0] & 1 << 2) {
538 off += snprintf(dst + off, size - off, " * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n");
539 }
540 if (pnbi->abtProtocolInfo[0] & 1 << 3) {
541 off += snprintf(dst + off, size - off, " * ERROR unknown value\n");
542 }
543 if ((pnbi->abtProtocolInfo[1] & 0xf0) <= 0x80) {
544 const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
545 off += snprintf(dst + off, size - off, "* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((pnbi->abtProtocolInfo[1] & 0xf0) >> 4)]);
546 }
547 if ((pnbi->abtProtocolInfo[1] & 0x01) == PI_ISO14443_4_SUPPORTED) {
548 // in principle low nibble could only be 0000 or 0001 and other values are RFU
549 // but in practice we found 0011 so let's use only last bit for -4 compatibility
550 off += snprintf(dst + off, size - off, "* Protocol types supported: ISO/IEC 14443-4\n");
551 }
552 off += snprintf(dst + off, size - off, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((pnbi->abtProtocolInfo[2] & 0xf0) >> 4)) / 13560.0);
553 if ((pnbi->abtProtocolInfo[2] & (PI_NAD_SUPPORTED | PI_CID_SUPPORTED)) != 0) {
554 off += snprintf(dst + off, size - off, "* Frame options supported: ");
555 if ((pnbi->abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) off += snprintf(dst + off, size - off, "NAD ");
556 if ((pnbi->abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) off += snprintf(dst + off, size - off, "CID ");
557 snprintf(dst + off, size - off, "\n");
558 }
559 }
560 }
561
562 void
snprint_nfc_iso14443bi_info(char * dst,size_t size,const nfc_iso14443bi_info * pnii,bool verbose)563 snprint_nfc_iso14443bi_info(char *dst, size_t size, const nfc_iso14443bi_info *pnii, bool verbose)
564 {
565 int off = 0;
566 off += snprintf(dst + off, size - off, " DIV: ");
567 off += snprint_hex(dst + off, size - off, pnii->abtDIV, 4);
568 if (verbose) {
569 int version = (pnii->btVerLog & 0x1e) >> 1;
570 off += snprintf(dst + off, size - off, " Software Version: ");
571 if (version == 15) {
572 off += snprintf(dst + off, size - off, "Undefined\n");
573 } else {
574 off += snprintf(dst + off, size - off, "%i\n", version);
575 }
576
577 if ((pnii->btVerLog & 0x80) && (pnii->btConfig & 0x80)) {
578 off += snprintf(dst + off, size - off, " Wait Enable: yes");
579 }
580 }
581 if ((pnii->btVerLog & 0x80) && (pnii->btConfig & 0x40)) {
582 off += snprintf(dst + off, size - off, " ATS: ");
583 snprint_hex(dst + off, size - off, pnii->abtAtr, pnii->szAtrLen);
584 }
585 }
586
587 void
snprint_nfc_iso14443b2sr_info(char * dst,size_t size,const nfc_iso14443b2sr_info * pnsi,bool verbose)588 snprint_nfc_iso14443b2sr_info(char *dst, size_t size, const nfc_iso14443b2sr_info *pnsi, bool verbose)
589 {
590 (void) verbose;
591 int off = 0;
592 off += snprintf(dst + off, size - off, " UID: ");
593 snprint_hex(dst + off, size - off, pnsi->abtUID, 8);
594 }
595
596 void
snprint_nfc_iso14443b2ct_info(char * dst,size_t size,const nfc_iso14443b2ct_info * pnci,bool verbose)597 snprint_nfc_iso14443b2ct_info(char *dst, size_t size, const nfc_iso14443b2ct_info *pnci, bool verbose)
598 {
599 (void) verbose;
600 int off = 0;
601 uint32_t uid;
602 uid = (pnci->abtUID[3] << 24) + (pnci->abtUID[2] << 16) + (pnci->abtUID[1] << 8) + pnci->abtUID[0];
603 off += snprintf(dst + off, size - off, " UID: ");
604 off += snprint_hex(dst + off, size - off, pnci->abtUID, sizeof(pnci->abtUID));
605 off += snprintf(dst + off, size - off, " UID (decimal): %010u\n", uid);
606 off += snprintf(dst + off, size - off, " Product Code: %02X\n", pnci->btProdCode);
607 snprintf(dst + off, size - off, " Fab Code: %02X\n", pnci->btFabCode);
608 }
609
610 void
snprint_nfc_dep_info(char * dst,size_t size,const nfc_dep_info * pndi,bool verbose)611 snprint_nfc_dep_info(char *dst, size_t size, const nfc_dep_info *pndi, bool verbose)
612 {
613 (void) verbose;
614 int off = 0;
615 off += snprintf(dst + off, size - off, " NFCID3: ");
616 off += snprint_hex(dst + off, size - off, pndi->abtNFCID3, 10);
617 off += snprintf(dst + off, size - off, " BS: %02x\n", pndi->btBS);
618 off += snprintf(dst + off, size - off, " BR: %02x\n", pndi->btBR);
619 off += snprintf(dst + off, size - off, " TO: %02x\n", pndi->btTO);
620 off += snprintf(dst + off, size - off, " PP: %02x\n", pndi->btPP);
621 if (pndi->szGB) {
622 off += snprintf(dst + off, size - off, "General Bytes: ");
623 snprint_hex(dst + off, size - off, pndi->abtGB, pndi->szGB);
624 }
625 }
626
627 void
snprint_nfc_target(char * dst,size_t size,const nfc_target * pnt,bool verbose)628 snprint_nfc_target(char *dst, size_t size, const nfc_target *pnt, bool verbose)
629 {
630 if (NULL != pnt) {
631 int off = 0;
632 off += snprintf(dst + off, size - off, "%s (%s%s) target:\n", str_nfc_modulation_type(pnt->nm.nmt), str_nfc_baud_rate(pnt->nm.nbr), (pnt->nm.nmt != NMT_DEP) ? "" : (pnt->nti.ndi.ndm == NDM_ACTIVE) ? "active mode" : "passive mode");
633 switch (pnt->nm.nmt) {
634 case NMT_ISO14443A:
635 snprint_nfc_iso14443a_info(dst + off, size - off, &pnt->nti.nai, verbose);
636 break;
637 case NMT_JEWEL:
638 snprint_nfc_jewel_info(dst + off, size - off, &pnt->nti.nji, verbose);
639 break;
640 case NMT_FELICA:
641 snprint_nfc_felica_info(dst + off, size - off, &pnt->nti.nfi, verbose);
642 break;
643 case NMT_ISO14443B:
644 snprint_nfc_iso14443b_info(dst + off, size - off, &pnt->nti.nbi, verbose);
645 break;
646 case NMT_ISO14443BI:
647 snprint_nfc_iso14443bi_info(dst + off, size - off, &pnt->nti.nii, verbose);
648 break;
649 case NMT_ISO14443B2SR:
650 snprint_nfc_iso14443b2sr_info(dst + off, size - off, &pnt->nti.nsi, verbose);
651 break;
652 case NMT_ISO14443B2CT:
653 snprint_nfc_iso14443b2ct_info(dst + off, size - off, &pnt->nti.nci, verbose);
654 break;
655 case NMT_DEP:
656 snprint_nfc_dep_info(dst + off, size - off, &pnt->nti.ndi, verbose);
657 break;
658 }
659 }
660 }
661
662