libnfc  1.8.0
nfc-list.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  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are met:
16  * 1) Redistributions of source code must retain the above copyright notice,
17  * this list of conditions and the following disclaimer.
18  * 2 )Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Note that this license only applies on the examples, NFC library itself is under LGPL
35  *
36  */
37 
43 #ifdef HAVE_CONFIG_H
44 # include "config.h"
45 #endif // HAVE_CONFIG_H
46 
47 #include <err.h>
48 #include <stdio.h>
49 #include <stddef.h>
50 #include <stdlib.h>
51 #include <string.h>
52 
53 #include <nfc/nfc.h>
54 
55 #include "nfc-utils.h"
56 
57 #define MAX_DEVICE_COUNT 16
58 #define MAX_TARGET_COUNT 16
59 
60 static nfc_device *pnd;
61 
62 static void
63 print_usage(const char *progname)
64 {
65  printf("usage: %s [-v] [-t X]\n", progname);
66  printf(" -v\t verbose display\n");
67  printf(" -t X\t poll only for types according to bitfield X:\n");
68  printf("\t 1: ISO14443A\n");
69  printf("\t 2: Felica (212 kbps)\n");
70  printf("\t 4: Felica (424 kbps)\n");
71  printf("\t 8: ISO14443B\n");
72  printf("\t 16: ISO14443B'\n");
73  printf("\t 32: ISO14443B-2 ST SRx\n");
74  printf("\t 64: ISO14443B-2 ASK CTx\n");
75  printf("\t 128: ISO14443B iClass\n");
76  printf("\t 256: ISO14443A-3 Jewel\n");
77  printf("\t 512: ISO14443A-2 NFC Barcode\n");
78  printf("\tSo 1023 (default) polls for all types.\n");
79  printf("\tNote that if 16, 32, 64 or 128 then 8 is selected too.\n");
80 }
81 
82 int
83 main(int argc, const char *argv[])
84 {
85  (void) argc;
86  const char *acLibnfcVersion;
87  size_t i;
88  bool verbose = false;
89  int res = 0;
90  int mask = 0x3ff;
91  int arg;
92 
93  nfc_context *context;
94  nfc_init(&context);
95  if (context == NULL) {
96  ERR("Unable to init libnfc (malloc)");
97  exit(EXIT_FAILURE);
98  }
99 
100  // Display libnfc version
101  acLibnfcVersion = nfc_version();
102  printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
103 
104  // Get commandline options
105  for (arg = 1; arg < argc; arg++) {
106  if (0 == strcmp(argv[arg], "-h")) {
107  print_usage(argv[0]);
108  exit(EXIT_SUCCESS);
109  } else if (0 == strcmp(argv[arg], "-v")) {
110  verbose = true;
111  } else if ((0 == strcmp(argv[arg], "-t")) && (arg + 1 < argc)) {
112  arg++;
113  mask = atoi(argv[arg]);
114  if ((mask < 1) || (mask > 0x3ff)) {
115  ERR("%i is invalid value for type bitfield.", mask);
116  print_usage(argv[0]);
117  exit(EXIT_FAILURE);
118  }
119  // Force TypeB for all derivatives of B
120  if (mask & 0xf0)
121  mask |= 0x08;
122  } else {
123  ERR("%s is not supported option.", argv[arg]);
124  print_usage(argv[0]);
125  exit(EXIT_FAILURE);
126  }
127  }
128 
129  /* Lazy way to open an NFC device */
130 #if 0
131  pnd = nfc_open(context, NULL);
132 #endif
133 
134  /* Use connection string if specific device is wanted,
135  * i.e. PN532 UART device on /dev/ttyUSB1 */
136 #if 0
137  pnd = nfc_open(context, "pn532_uart:/dev/ttyUSB1");
138 #endif
139 
140  nfc_connstring connstrings[MAX_DEVICE_COUNT];
141  size_t szDeviceFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT);
142 
143  if (szDeviceFound == 0) {
144  printf("No NFC device found.\n");
145  }
146 
147  for (i = 0; i < szDeviceFound; i++) {
148  nfc_target ant[MAX_TARGET_COUNT];
149  pnd = nfc_open(context, connstrings[i]);
150 
151  if (pnd == NULL) {
152  ERR("Unable to open NFC device: %s", connstrings[i]);
153  continue;
154  }
155  if (nfc_initiator_init(pnd) < 0) {
156  nfc_perror(pnd, "nfc_initiator_init");
157  nfc_exit(context);
158  exit(EXIT_FAILURE);
159  }
160 
161  printf("NFC device: %s opened\n", nfc_device_get_name(pnd));
162 
163  nfc_modulation nm;
164 
165  if (mask & 0x1) {
166  nm.nmt = NMT_ISO14443A;
167  nm.nbr = NBR_106;
168  // List ISO14443A targets
169  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
170  int n;
171  if (verbose || (res > 0)) {
172  printf("%d ISO14443A passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
173  }
174  for (n = 0; n < res; n++) {
175  print_nfc_target(&ant[n], verbose);
176  printf("\n");
177  }
178  }
179  }
180 
181  if (mask & 0x02) {
182  nm.nmt = NMT_FELICA;
183  nm.nbr = NBR_212;
184  // List Felica tags
185  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
186  int n;
187  if (verbose || (res > 0)) {
188  printf("%d Felica (212 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
189  }
190  for (n = 0; n < res; n++) {
191  print_nfc_target(&ant[n], verbose);
192  printf("\n");
193  }
194  }
195  }
196 
197  if (mask & 0x04) {
198  nm.nmt = NMT_FELICA;
199  nm.nbr = NBR_424;
200  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
201  int n;
202  if (verbose || (res > 0)) {
203  printf("%d Felica (424 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
204  }
205  for (n = 0; n < res; n++) {
206  print_nfc_target(&ant[n], verbose);
207  printf("\n");
208  }
209  }
210  }
211 
212  if (mask & 0x08) {
213  nm.nmt = NMT_ISO14443B;
214  nm.nbr = NBR_106;
215  // List ISO14443B targets
216  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
217  int n;
218  if (verbose || (res > 0)) {
219  printf("%d ISO14443B passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
220  }
221  for (n = 0; n < res; n++) {
222  print_nfc_target(&ant[n], verbose);
223  printf("\n");
224  }
225  }
226  }
227 
228  if (mask & 0x10) {
229  nm.nmt = NMT_ISO14443BI;
230  nm.nbr = NBR_106;
231  // List ISO14443B' targets
232  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
233  int n;
234  if (verbose || (res > 0)) {
235  printf("%d ISO14443B' passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
236  }
237  for (n = 0; n < res; n++) {
238  print_nfc_target(&ant[n], verbose);
239  printf("\n");
240  }
241  }
242  }
243 
244  if (mask & 0x20) {
245  nm.nmt = NMT_ISO14443B2SR;
246  nm.nbr = NBR_106;
247  // List ISO14443B-2 ST SRx family targets
248  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
249  int n;
250  if (verbose || (res > 0)) {
251  printf("%d ISO14443B-2 ST SRx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
252  }
253  for (n = 0; n < res; n++) {
254  print_nfc_target(&ant[n], verbose);
255  printf("\n");
256  }
257  }
258  }
259 
260  if (mask & 0x40) {
261  nm.nmt = NMT_ISO14443B2CT;
262  nm.nbr = NBR_106;
263  // List ISO14443B-2 ASK CTx family targets
264  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
265  int n;
266  if (verbose || (res > 0)) {
267  printf("%d ISO14443B-2 ASK CTx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
268  }
269  for (n = 0; n < res; n++) {
270  print_nfc_target(&ant[n], verbose);
271  printf("\n");
272  }
273  }
274  }
275 
276  if (mask & 0x80) {
277  nm.nmt = NMT_ISO14443BICLASS;
278  nm.nbr = NBR_106;
279  // List ISO14443B iClass targets
280  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
281  int n;
282  if (verbose || (res > 0)) {
283  printf("%d ISO14443B iClass passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
284  }
285  for (n = 0; n < res; n++) {
286  print_nfc_target(&ant[n], verbose);
287  printf("\n");
288  }
289  }
290  }
291 
292  if (mask & 0x100) {
293  nm.nmt = NMT_JEWEL;
294  nm.nbr = NBR_106;
295  // List Jewel targets
296  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
297  int n;
298  if (verbose || (res > 0)) {
299  printf("%d ISO14443A-3 Jewel passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
300  }
301  for (n = 0; n < res; n++) {
302  print_nfc_target(&ant[n], verbose);
303  printf("\n");
304  }
305  }
306  }
307 
308  if (mask & 0x200) {
309  nm.nmt = NMT_BARCODE;
310  nm.nbr = NBR_106;
311  // List NFC Barcode targets
312  if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
313  int n;
314  if (verbose || (res > 0)) {
315  printf("%d ISO14443A-2 NFC Barcode passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
316  }
317  for (n = 0; n < res; n++) {
318  print_nfc_target(&ant[n], verbose);
319  printf("\n");
320  }
321  }
322  }
323 
324  nfc_close(pnd);
325  }
326 
327  nfc_exit(context);
328  exit(EXIT_SUCCESS);
329 }
const char * nfc_device_get_name(nfc_device *pnd)
Returns the device name.
Definition: nfc.c:1209
void nfc_close(nfc_device *pnd)
Close from a NFC device.
Definition: nfc.c:339
nfc_device * nfc_open(nfc_context *context, const nfc_connstring connstring)
Open a NFC device.
Definition: nfc.c:277
size_t nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
Scan for discoverable supported devices (ie. only available for some drivers)
Definition: nfc.c:356
void nfc_perror(const nfc_device *pnd, const char *pcString)
Display the last error occured on a nfc_device.
Definition: nfc.c:1183
int nfc_initiator_init(nfc_device *pnd)
Initialize NFC device as initiator (reader)
Definition: nfc.c:493
int nfc_initiator_list_passive_targets(nfc_device *pnd, const nfc_modulation nm, nfc_target ant[], const size_t szTargets)
List passive or emulated tags.
Definition: nfc.c:605
void nfc_exit(nfc_context *context)
Deinitialize libnfc. Should be called after closing all open devices and before your application term...
Definition: nfc.c:248
void nfc_init(nfc_context **context)
Initialize libnfc. This function must be called before calling any other libnfc function.
Definition: nfc.c:231
const char * nfc_version(void)
Returns the library version.
Definition: nfc.c:1319
char nfc_connstring[NFC_BUFSIZE_CONNSTRING]
Definition: nfc-types.h:63
Provide some examples shared functions like print, parity calculation, options parsing.
#define ERR(...)
Print a error message.
Definition: nfc-utils.h:85
libnfc interface
NFC library context Struct which contains internal options, references, pointers, etc....
Definition: nfc-internal.h:175
NFC device information.
Definition: nfc-internal.h:190
NFC modulation structure.
Definition: nfc-types.h:342
NFC target structure.
Definition: nfc-types.h:351