libnfc 1.8.0
pn53x-sam.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) 2010 Emanuele Bertoldi
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
44
45#ifdef HAVE_CONFIG_H
46# include "config.h"
47#endif // HAVE_CONFIG_H
48
49#include <stdio.h>
50#include <stdlib.h>
51#include <time.h>
52#include <unistd.h>
53
54#include <nfc/nfc.h>
55
56#include "utils/nfc-utils.h"
57#include "libnfc/chips/pn53x.h"
58
59#define MAX_FRAME_LEN 264
60#define TIMEOUT 60 // secs.
61
62static void
63wait_one_minute(void)
64{
65 int secs = 0;
66
67 printf("|");
68 fflush(stdout);
69
70 while (secs < TIMEOUT) {
71 sleep(1);
72 secs++;
73 printf(".");
74 fflush(stdout);
75 }
76
77 printf("|\n");
78}
79
80int
81main(int argc, const char *argv[])
82{
83 (void) argc;
84 (void) argv;
85
86 nfc_context *context;
87 nfc_init(&context);
88 if (context == NULL) {
89 ERR("Unable to init libnfc (malloc)");
90 exit(EXIT_FAILURE);
91 }
92
93 // Display libnfc version
94 const char *acLibnfcVersion = nfc_version();
95 printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
96
97 // Open using the first available NFC device
98 nfc_device *pnd;
99 pnd = nfc_open(context, NULL);
100
101 if (pnd == NULL) {
102 ERR("%s", "Unable to open NFC device.");
103 nfc_exit(context);
104 exit(EXIT_FAILURE);
105 }
106
107 printf("NFC device: %s opened\n", nfc_device_get_name(pnd));
108
109 // Print the example's menu
110 printf("\nSelect the communication mode:\n");
111 printf("[1] Virtual card mode.\n");
112 printf("[2] Wired card mode.\n");
113 printf("[3] Dual card mode.\n");
114 printf(">> ");
115
116 // Take user's choice
117 int input = getchar();
118 printf("\n");
119 if ((input < '1') || (input > '3')) {
120 ERR("%s", "Invalid selection.");
121 nfc_close(pnd);
122 nfc_exit(context);
123 exit(EXIT_FAILURE);
124 }
125
126 /*
127 * '1' -> "Virtual mode" (0x02)
128 * '2' -> "Wired card" (0x03)
129 * '3' -> "Dual card" (0x04)
130 */
131 int iMode = input - '0' + 0x01;
132 pn532_sam_mode mode = iMode;
133
134 // Connect with the SAM
135
136 switch (mode) {
137 case PSM_VIRTUAL_CARD: {
138 // FIXME Its a private pn53x function
139 if (pn532_SAMConfiguration(pnd, mode, 0) < 0) {
140 nfc_perror(pnd, "pn53x_SAMConfiguration");
141 nfc_close(pnd);
142 nfc_exit(context);
143 exit(EXIT_FAILURE);
144 }
145 printf("Now the SAM is readable for 1 minute from an external reader.\n");
146 wait_one_minute();
147 }
148 break;
149
150 case PSM_WIRED_CARD: {
151 // Set opened NFC device to initiator mode
153 nfc_perror(pnd, "nfc_initiator_init_secure_element");
154 nfc_close(pnd);
155 nfc_exit(context);
156 exit(EXIT_FAILURE);
157 }
158
159 // Let the reader only try once to find a tag
161 nfc_perror(pnd, "nfc_device_set_property_bool");
162 nfc_close(pnd);
163 nfc_exit(context);
164 exit(EXIT_FAILURE);
165 }
166 // Read the SAM's info
167 const nfc_modulation nmSAM = {
168 .nmt = NMT_ISO14443A,
169 .nbr = NBR_106,
170 };
171 nfc_target nt;
172
173 int res;
174 if ((res = nfc_initiator_select_passive_target(pnd, nmSAM, NULL, 0, &nt)) < 0) {
175 nfc_perror(pnd, "nfc_initiator_select_passive_target");
176 nfc_close(pnd);
177 nfc_exit(context);
178 exit(EXIT_FAILURE);
179 } else if (res == 0) {
180 ERR("No SAM found.");
181 nfc_close(pnd);
182 nfc_exit(context);
183 exit(EXIT_FAILURE);
184 } else if (res == 1) {
185 printf("The following ISO14443A tag (SAM) was found:\n");
186 print_nfc_target(&nt, true);
187 } else {
188 ERR("%s", "More than one ISO14442 tag found as SAM.");
189 nfc_close(pnd);
190 nfc_exit(context);
191 exit(EXIT_FAILURE);
192 }
193 }
194 break;
195
196 case PSM_DUAL_CARD: {
197 // FIXME Its a private pn53x function
198 if (pn532_SAMConfiguration(pnd, mode, 0) < 0) {
199 nfc_perror(pnd, "pn53x_SAMConfiguration");
200 nfc_close(pnd);
201 nfc_exit(context);
202 exit(EXIT_FAILURE);
203 }
204 uint8_t abtRx[MAX_FRAME_LEN];
205
206 nfc_target nt = {
207 .nm = {
208 .nmt = NMT_ISO14443A,
209 .nbr = NBR_UNDEFINED,
210 },
211 .nti = {
212 .nai = {
213 .abtAtqa = { 0x04, 0x00 },
214 .abtUid = { 0x08, 0xad, 0xbe, 0xef },
215 .btSak = 0x20,
216 .szUidLen = 4,
217 .szAtsLen = 0,
218 },
219 },
220 };
221 printf("Now both, NFC device (configured as target) and SAM are readables from an external NFC initiator.\n");
222 printf("Please note that NFC device (configured as target) stay in target mode until it receive RATS, ATR_REQ or proprietary command.\n");
223 if (nfc_target_init(pnd, &nt, abtRx, sizeof(abtRx), 0) < 0) {
224 nfc_perror(pnd, "nfc_target_init");
225 nfc_close(pnd);
226 nfc_exit(context);
227 exit(EXIT_FAILURE);
228 }
229 // wait_one_minute ();
230 }
231 break;
232 case PSM_NORMAL:
233 // This should not happend... nothing to do.
234 break;
235 }
236
237 // Disconnect from the SAM
238 pn532_SAMConfiguration(pnd, PSM_NORMAL, -1);
239
240 // Close NFC device
241 nfc_close(pnd);
242 nfc_exit(context);
243 exit(EXIT_SUCCESS);
244}
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
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_secure_element(nfc_device *pnd)
Initialize NFC device as initiator with its secure element as target (reader)
Definition nfc.c:533
int nfc_initiator_select_passive_target(nfc_device *pnd, const nfc_modulation nm, const uint8_t *pbtInitData, const size_t szInitData, nfc_target *pnt)
Select a passive or emulated tag.
Definition nfc.c:562
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
int nfc_device_set_property_bool(nfc_device *pnd, const nfc_property property, const bool bEnable)
Set a device's boolean-property value.
Definition nfc.c:466
int nfc_target_init(nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout)
Initialize NFC device as an emulated tag.
Definition nfc.c:978
@ NP_INFINITE_SELECT
Definition nfc-types.h:115
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