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
42
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
60static nfc_device *pnd;
61
62static void
63print_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
82int
83main(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 // Get commandline options
101 for (arg = 1; arg < argc; arg++) {
102 if (0 == strcmp(argv[arg], "-h")) {
103 print_usage(argv[0]);
104 exit(EXIT_SUCCESS);
105 } else if (0 == strcmp(argv[arg], "-v")) {
106 verbose = true;
107 } else if ((0 == strcmp(argv[arg], "-t")) && (arg + 1 < argc)) {
108 arg++;
109 mask = atoi(argv[arg]);
110 if ((mask < 1) || (mask > 0x3ff)) {
111 ERR("%i is invalid value for type bitfield.", mask);
112 print_usage(argv[0]);
113 exit(EXIT_FAILURE);
114 }
115 // Force TypeB for all derivatives of B
116 if (mask & 0xd0)
117 mask |= 0x08;
118 } else {
119 ERR("%s is not supported option.", argv[arg]);
120 print_usage(argv[0]);
121 exit(EXIT_FAILURE);
122 }
123 }
124
125 // Display libnfc version
126 if (verbose) {
127 acLibnfcVersion = nfc_version();
128 printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
129 }
130
131
132 /* Lazy way to open an NFC device */
133#if 0
134 pnd = nfc_open(context, NULL);
135#endif
136
137 /* Use connection string if specific device is wanted,
138 * i.e. PN532 UART device on /dev/ttyUSB1 */
139#if 0
140 pnd = nfc_open(context, "pn532_uart:/dev/ttyUSB1");
141#endif
142
143 nfc_connstring connstrings[MAX_DEVICE_COUNT];
144 size_t szDeviceFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT);
145
146 if (szDeviceFound == 0) {
147 printf("No NFC device found.\n");
148 }
149
150 for (i = 0; i < szDeviceFound; i++) {
151 nfc_target ant[MAX_TARGET_COUNT];
152 pnd = nfc_open(context, connstrings[i]);
153
154 if (pnd == NULL) {
155 ERR("Unable to open NFC device: %s", connstrings[i]);
156 continue;
157 }
158 if (nfc_initiator_init(pnd) < 0) {
159 nfc_perror(pnd, "nfc_initiator_init");
160 nfc_exit(context);
161 exit(EXIT_FAILURE);
162 }
163
164 printf("NFC device: %s opened\n", nfc_device_get_name(pnd));
165
167
168 if (mask & 0x1) {
169 nm.nmt = NMT_ISO14443A;
170 nm.nbr = NBR_106;
171 // List ISO14443A targets
172 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
173 int n;
174 if (verbose || (res > 0)) {
175 printf("%d ISO14443A passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
176 }
177 for (n = 0; n < res; n++) {
178 print_nfc_target(&ant[n], verbose);
179 printf("\n");
180 }
181 }
182 }
183
184 if (mask & 0x02) {
185 nm.nmt = NMT_FELICA;
186 nm.nbr = NBR_212;
187 // List Felica tags
188 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
189 int n;
190 if (verbose || (res > 0)) {
191 printf("%d Felica (212 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
192 }
193 for (n = 0; n < res; n++) {
194 print_nfc_target(&ant[n], verbose);
195 printf("\n");
196 }
197 }
198 }
199
200 if (mask & 0x04) {
201 nm.nmt = NMT_FELICA;
202 nm.nbr = NBR_424;
203 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
204 int n;
205 if (verbose || (res > 0)) {
206 printf("%d Felica (424 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
207 }
208 for (n = 0; n < res; n++) {
209 print_nfc_target(&ant[n], verbose);
210 printf("\n");
211 }
212 }
213 }
214
215 if (mask & 0x08) {
216 nm.nmt = NMT_ISO14443B;
217 nm.nbr = NBR_106;
218 // List ISO14443B targets
219 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
220 int n;
221 if (verbose || (res > 0)) {
222 printf("%d ISO14443B passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
223 }
224 for (n = 0; n < res; n++) {
225 print_nfc_target(&ant[n], verbose);
226 printf("\n");
227 }
228 }
229 }
230
231 if (mask & 0x10) {
232 nm.nmt = NMT_ISO14443BI;
233 nm.nbr = NBR_106;
234 // List ISO14443B' targets
235 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
236 int n;
237 if (verbose || (res > 0)) {
238 printf("%d ISO14443B' passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
239 }
240 for (n = 0; n < res; n++) {
241 print_nfc_target(&ant[n], verbose);
242 printf("\n");
243 }
244 }
245 }
246
247 if (mask & 0x20) {
248 nm.nmt = NMT_ISO14443B2SR;
249 nm.nbr = NBR_106;
250 // List ISO14443B-2 ST SRx family targets
251 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
252 int n;
253 if (verbose || (res > 0)) {
254 printf("%d ISO14443B-2 ST SRx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
255 }
256 for (n = 0; n < res; n++) {
257 print_nfc_target(&ant[n], verbose);
258 printf("\n");
259 }
260 }
261 }
262
263 if (mask & 0x40) {
264 nm.nmt = NMT_ISO14443B2CT;
265 nm.nbr = NBR_106;
266 // List ISO14443B-2 ASK CTx family targets
267 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
268 int n;
269 if (verbose || (res > 0)) {
270 printf("%d ISO14443B-2 ASK CTx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
271 }
272 for (n = 0; n < res; n++) {
273 print_nfc_target(&ant[n], verbose);
274 printf("\n");
275 }
276 }
277 }
278
279 if (mask & 0x80) {
280 nm.nmt = NMT_ISO14443BICLASS;
281 nm.nbr = NBR_106;
282 // List ISO14443B iClass targets
283 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
284 int n;
285 if (verbose || (res > 0)) {
286 printf("%d ISO14443B iClass passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
287 }
288 for (n = 0; n < res; n++) {
289 print_nfc_target(&ant[n], verbose);
290 printf("\n");
291 }
292 }
293 }
294
295 if (mask & 0x100) {
296 nm.nmt = NMT_JEWEL;
297 nm.nbr = NBR_106;
298 // List Jewel targets
299 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
300 int n;
301 if (verbose || (res > 0)) {
302 printf("%d ISO14443A-3 Jewel passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
303 }
304 for (n = 0; n < res; n++) {
305 print_nfc_target(&ant[n], verbose);
306 printf("\n");
307 }
308 }
309 }
310
311 if (mask & 0x200) {
312 nm.nmt = NMT_BARCODE;
313 nm.nbr = NBR_106;
314 // List NFC Barcode targets
315 if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
316 int n;
317 if (verbose || (res > 0)) {
318 printf("%d ISO14443A-2 NFC Barcode passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
319 }
320 for (n = 0; n < res; n++) {
321 print_nfc_target(&ant[n], verbose);
322 printf("\n");
323 }
324 }
325 }
326
327 nfc_close(pnd);
328 }
329
330 nfc_exit(context);
331 exit(EXIT_SUCCESS);
332}
const char * nfc_device_get_name(nfc_device *pnd)
Returns the device name.
Definition nfc.c:1213
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:1187
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:609
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:1323
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....
NFC device information.
NFC modulation structure.
Definition nfc-types.h:342
NFC target structure.
Definition nfc-types.h:351