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 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 * 1) Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2 )Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Note that this license only applies on the examples, NFC library itself is under LGPL
34 *
35 */
36
37 /**
38 * @file pn53x-tamashell.c
39 * @brief Configures the NFC device to communicate with a SAM (Secure Access Module).
40 */
41
42 #ifdef HAVE_CONFIG_H
43 # include "config.h"
44 #endif // HAVE_CONFIG_H
45
46 # include <stdio.h>
47 #if defined(HAVE_READLINE)
48 # include <readline/readline.h>
49 # include <readline/history.h>
50 #endif //HAVE_READLINE
51
52 #include <stdlib.h>
53 #include <string.h>
54 #include <ctype.h>
55 #include <time.h>
56
57 #ifndef _WIN32
58 # include <time.h>
59 # define msleep(x) do { \
60 struct timespec xsleep; \
61 xsleep.tv_sec = x / 1000; \
62 xsleep.tv_nsec = (x - xsleep.tv_sec * 1000) * 1000 * 1000; \
63 nanosleep(&xsleep, NULL); \
64 } while (0)
65 #else
66 # include <winbase.h>
67 # define msleep Sleep
68 #endif
69
70
71 #include <nfc/nfc.h>
72
73 #include "utils/nfc-utils.h"
74 #include "libnfc/chips/pn53x.h"
75
76 #define MAX_FRAME_LEN 264
77
main(int argc,const char * argv[])78 int main(int argc, const char *argv[])
79 {
80 nfc_device *pnd;
81 uint8_t abtRx[MAX_FRAME_LEN];
82 uint8_t abtTx[MAX_FRAME_LEN];
83 size_t szRx = sizeof(abtRx);
84 size_t szTx;
85 FILE *input = NULL;
86
87 if (argc >= 2) {
88 if ((input = fopen(argv[1], "r")) == NULL) {
89 ERR("%s", "Cannot open file.");
90 exit(EXIT_FAILURE);
91 }
92 }
93
94 nfc_context *context;
95 nfc_init(&context);
96 if (context == NULL) {
97 ERR("Unable to init libnfc (malloc)");
98 exit(EXIT_FAILURE);
99 }
100
101 // Try to open the NFC reader
102 pnd = nfc_open(context, NULL);
103
104 if (pnd == NULL) {
105 ERR("%s", "Unable to open NFC device.");
106 if (input != NULL) {
107 fclose(input);
108 }
109 nfc_exit(context);
110 exit(EXIT_FAILURE);
111 }
112
113 printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
114 if (nfc_initiator_init(pnd) < 0) {
115 nfc_perror(pnd, "nfc_initiator_init");
116 if (input != NULL) {
117 fclose(input);
118 }
119 nfc_close(pnd);
120 nfc_exit(context);
121 exit(EXIT_FAILURE);
122 }
123
124 const char *prompt = "> ";
125 while (1) {
126 int offset = 0;
127 char *cmd;
128 #if defined(HAVE_READLINE)
129 if (input == NULL) { // means we use stdin
130 cmd = readline(prompt);
131 // NULL if ctrl-d
132 if (cmd == NULL) {
133 printf("Bye!\n");
134 break;
135 }
136 add_history(cmd);
137 } else {
138 #endif //HAVE_READLINE
139 size_t n = 512;
140 char *ret = NULL;
141 cmd = malloc(n);
142 printf("%s", prompt);
143 fflush(0);
144 if (input != NULL) {
145 ret = fgets(cmd, n, input);
146 } else {
147 ret = fgets(cmd, n, stdin);
148 }
149 if (ret == NULL || strlen(cmd) <= 0) {
150 printf("Bye!\n");
151 free(cmd);
152 break;
153 }
154 // FIXME print only if read from redirected stdin (i.e. script)
155 printf("%s", cmd);
156 #if defined(HAVE_READLINE)
157 }
158 #endif //HAVE_READLINE
159 if (cmd[0] == 'q') {
160 printf("Bye!\n");
161 free(cmd);
162 break;
163 }
164 if (cmd[0] == 'p') {
165 int ms = 0;
166 offset++;
167 while (isspace(cmd[offset])) {
168 offset++;
169 }
170 sscanf(cmd + offset, "%10d", &ms);
171 printf("Pause for %i msecs\n", ms);
172 if (ms > 0) {
173 msleep(ms);
174 }
175 free(cmd);
176 continue;
177 }
178 szTx = 0;
179 for (int i = 0; i < MAX_FRAME_LEN; i++) {
180 int size;
181 unsigned int byte;
182 while (isspace(cmd[offset])) {
183 offset++;
184 }
185 size = sscanf(cmd + offset, "%2x", &byte);
186 if (size < 1) {
187 break;
188 }
189 abtTx[i] = byte;
190 szTx++;
191 if (cmd[offset + 1] == 0) { // if last hex was only 1 symbol
192 break;
193 }
194 offset += 2;
195 }
196
197 if ((int)szTx < 1) {
198 free(cmd);
199 continue;
200 }
201 printf("Tx: ");
202 print_hex(abtTx, szTx);
203
204 szRx = sizeof(abtRx);
205 int res = 0;
206 if ((res = pn53x_transceive(pnd, abtTx, szTx, abtRx, szRx, 0)) < 0) {
207 free(cmd);
208 nfc_perror(pnd, "Rx");
209 continue;
210 }
211 szRx = (size_t) res;
212
213 printf("Rx: ");
214 print_hex(abtRx, szRx);
215 free(cmd);
216 }
217
218 if (input != NULL) {
219 fclose(input);
220 }
221 nfc_close(pnd);
222 nfc_exit(context);
223 exit(EXIT_SUCCESS);
224 }
225