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