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