libnfc  1.7.1
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  *
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 
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
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
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
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
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
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
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
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
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
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
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 
nfc_dep_info::btBR
uint8_t btBR
Definition: nfc-types.h:169
nfc_dep_info::ndm
nfc_dep_mode ndm
Definition: nfc-types.h:178
nfc_iso14443b_info
NFC ISO14443B tag information.
Definition: nfc-types.h:210
nfc_jewel_info
NFC Jewel tag information.
Definition: nfc-types.h:259
nfc_dep_info
NFC target information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 (NFCIP-1)
Definition: nfc-types.h:161
nfc_dep_info::abtGB
uint8_t abtGB[48]
Definition: nfc-types.h:175
nfc_target
NFC target structure.
Definition: nfc-types.h:328
nfc_dep_info::btPP
uint8_t btPP
Definition: nfc-types.h:173
str_nfc_baud_rate
const char * str_nfc_baud_rate(const nfc_baud_rate nbr)
Convert nfc_baud_rate value to string.
Definition: nfc.c:1258
nfc_iso14443b2sr_info
NFC ISO14443-2B ST SRx tag information.
Definition: nfc-types.h:241
nfc_iso14443b2ct_info
NFC ISO14443-2B ASK CTx tag information.
Definition: nfc-types.h:249
nfc_iso14443b_info::abtPupi
uint8_t abtPupi[4]
Definition: nfc-types.h:212
nfc_iso14443b_info::abtProtocolInfo
uint8_t abtProtocolInfo[3]
Definition: nfc-types.h:216
nfc_iso14443bi_info::btVerLog
uint8_t btVerLog
Definition: nfc-types.h:229
nfc_iso14443bi_info
NFC ISO14443B' tag information.
Definition: nfc-types.h:225
nfc_iso14443a_info
NFC ISO14443A tag (MIFARE) information.
Definition: nfc-types.h:185
nfc_dep_info::btTO
uint8_t btTO
Definition: nfc-types.h:171
nfc_felica_info
NFC FeLiCa tag information.
Definition: nfc-types.h:198
nfc_iso14443bi_info::szAtrLen
size_t szAtrLen
Definition: nfc-types.h:233
nfc_dep_info::btBS
uint8_t btBS
Definition: nfc-types.h:167
nfc_iso14443b_info::abtApplicationData
uint8_t abtApplicationData[4]
Definition: nfc-types.h:214
nfc_iso14443bi_info::btConfig
uint8_t btConfig
Definition: nfc-types.h:231
nfc_dep_info::abtNFCID3
uint8_t abtNFCID3[10]
Definition: nfc-types.h:163
str_nfc_modulation_type
const char * str_nfc_modulation_type(const nfc_modulation_type nmt)
Convert nfc_modulation_type value to string.
Definition: nfc.c:1287
nfc_iso14443bi_info::abtDIV
uint8_t abtDIV[4]
Definition: nfc-types.h:227
nfc.h
libnfc interface