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 
37 struct 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 
45 struct card_sak {
46  uint8_t sak;
47  uint8_t mask;
48  char type[128];
49 };
50 
51 struct 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 
110 struct 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 
126 int
127 snprint_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 
142 void
143 snprint_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 
478 void
479 snprint_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 
491 void
492 snprint_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 
502 void
503 snprint_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
521 void
522 snprint_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 
579 void
580 snprint_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 
604 void
605 snprint_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 
613 void
614 snprint_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 
622 void
623 snprint_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 
636 void
637 snprint_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 
653 void
654 snprint_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_baud_rate(const nfc_baud_rate nbr)
Convert nfc_baud_rate value to string.
Definition: nfc.c:1359
const char * str_nfc_modulation_type(const nfc_modulation_type nmt)
Convert nfc_modulation_type value to string.
Definition: nfc.c:1383
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