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 arygon.c
29 * @brief ARYGON readers driver
30 *
31 * This driver can handle ARYGON readers that use UART as bus.
32 * UART connection can be direct (host<->arygon_uc) or could be provided by internal USB to serial interface (e.g. host<->ftdi_chip<->arygon_uc)
33 */
34
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 #endif // HAVE_CONFIG_H
38
39 #include "arygon.h"
40
41 #include <stdio.h>
42 #include <inttypes.h>
43 #include <string.h>
44 #include <string.h>
45 #include <unistd.h>
46
47 #include <nfc/nfc.h>
48
49 #include "drivers.h"
50 #include "nfc-internal.h"
51 #include "chips/pn53x.h"
52 #include "chips/pn53x-internal.h"
53 #include "uart.h"
54
55 /** @def DEV_ARYGON_PROTOCOL_ARYGON_ASCII
56 * @brief High level language in ASCII format. (Common µC commands and Mifare® commands)
57 */
58 #define DEV_ARYGON_PROTOCOL_ARYGON_ASCII '0'
59 /** @def DEV_ARYGON_MODE_HL_ASCII
60 * @brief High level language in Binary format With AddressingByte for party line. (Common µC commands and Mifare® commands)
61 */
62 #define DEV_ARYGON_PROTOCOL_ARYGON_BINARY_WAB '1'
63 /** @def DEV_ARYGON_PROTOCOL_TAMA
64 * @brief Philips protocol (TAMA language) in binary format.
65 */
66 #define DEV_ARYGON_PROTOCOL_TAMA '2'
67 /** @def DEV_ARYGON_PROTOCOL_TAMA_WAB
68 * @brief Philips protocol (TAMA language) in binary With AddressingByte for party line.
69 */
70 #define DEV_ARYGON_PROTOCOL_TAMA_WAB '3'
71
72 #define ARYGON_DEFAULT_SPEED 9600
73 #define ARYGON_DRIVER_NAME "arygon"
74
75 #define LOG_CATEGORY "libnfc.driver.arygon"
76 #define LOG_GROUP NFC_LOG_GROUP_DRIVER
77
78 #define DRIVER_DATA(pnd) ((struct arygon_data*)(pnd->driver_data))
79
80 // Internal data structs
81 const struct pn53x_io arygon_tama_io;
82
83 struct arygon_data {
84 serial_port port;
85 #ifndef WIN32
86 int iAbortFds[2];
87 #else
88 volatile bool abort_flag;
89 #endif
90 };
91
92 // ARYGON frames
93 static const uint8_t arygon_error_none[] = "FF000000\x0d\x0a";
94 static const uint8_t arygon_error_incomplete_command[] = "FF0C0000\x0d\x0a";
95 static const uint8_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
96
97 // Prototypes
98 int arygon_reset_tama(nfc_device *pnd);
99 void arygon_firmware(nfc_device *pnd, char *str);
100
101 static size_t
arygon_scan(const nfc_context * context,nfc_connstring connstrings[],const size_t connstrings_len)102 arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
103 {
104 size_t device_found = 0;
105 serial_port sp;
106 char **acPorts = uart_list_ports();
107 const char *acPort;
108 int iDevice = 0;
109
110 while ((acPort = acPorts[iDevice++])) {
111 sp = uart_open(acPort);
112 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find ARYGON device on serial port: %s at %d bauds.", acPort, ARYGON_DEFAULT_SPEED);
113
114 if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
115 // We need to flush input to be sure first reply does not comes from older byte transceive
116 uart_flush_input(sp, true);
117 uart_set_speed(sp, ARYGON_DEFAULT_SPEED);
118
119 nfc_connstring connstring;
120 snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ARYGON_DRIVER_NAME, acPort, ARYGON_DEFAULT_SPEED);
121 nfc_device *pnd = nfc_device_new(context, connstring);
122 if (!pnd) {
123 perror("malloc");
124 uart_close(sp);
125 iDevice = 0;
126 while ((acPort = acPorts[iDevice++])) {
127 free((void *)acPort);
128 }
129 free(acPorts);
130 return 0;
131 }
132
133 pnd->driver = &arygon_driver;
134 pnd->driver_data = malloc(sizeof(struct arygon_data));
135 if (!pnd->driver_data) {
136 perror("malloc");
137 uart_close(sp);
138 nfc_device_free(pnd);
139 iDevice = 0;
140 while ((acPort = acPorts[iDevice++])) {
141 free((void *)acPort);
142 }
143 free(acPorts);
144 return 0;
145 }
146 DRIVER_DATA(pnd)->port = sp;
147
148 // Alloc and init chip's data
149 if (pn53x_data_new(pnd, &arygon_tama_io) == NULL) {
150 perror("malloc");
151 uart_close(DRIVER_DATA(pnd)->port);
152 nfc_device_free(pnd);
153 iDevice = 0;
154 while ((acPort = acPorts[iDevice++])) {
155 free((void *)acPort);
156 }
157 free(acPorts);
158 return 0;
159 }
160
161 #ifndef WIN32
162 // pipe-based abort mecanism
163 if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
164 uart_close(DRIVER_DATA(pnd)->port);
165 pn53x_data_free(pnd);
166 nfc_device_free(pnd);
167 iDevice = 0;
168 while ((acPort = acPorts[iDevice++])) {
169 free((void *)acPort);
170 }
171 free(acPorts);
172 return 0;
173 }
174 #else
175 DRIVER_DATA(pnd)->abort_flag = false;
176 #endif
177
178 int res = arygon_reset_tama(pnd);
179 uart_close(DRIVER_DATA(pnd)->port);
180 pn53x_data_free(pnd);
181 nfc_device_free(pnd);
182 if (res < 0) {
183 continue;
184 }
185
186 // ARYGON reader is found
187 memcpy(connstrings[device_found], connstring, sizeof(nfc_connstring));
188 device_found++;
189
190 // Test if we reach the maximum "wanted" devices
191 if (device_found >= connstrings_len)
192 break;
193 }
194 }
195 iDevice = 0;
196 while ((acPort = acPorts[iDevice++])) {
197 free((void *)acPort);
198 }
199 free(acPorts);
200 return device_found;
201 }
202
203 struct arygon_descriptor {
204 char *port;
205 uint32_t speed;
206 };
207
208 static void
arygon_close_step2(nfc_device * pnd)209 arygon_close_step2(nfc_device *pnd)
210 {
211 // Release UART port
212 uart_close(DRIVER_DATA(pnd)->port);
213
214 #ifndef WIN32
215 // Release file descriptors used for abort mecanism
216 close(DRIVER_DATA(pnd)->iAbortFds[0]);
217 close(DRIVER_DATA(pnd)->iAbortFds[1]);
218 #endif
219
220 pn53x_data_free(pnd);
221 nfc_device_free(pnd);
222 }
223
224 static void
arygon_close(nfc_device * pnd)225 arygon_close(nfc_device *pnd)
226 {
227 pn53x_idle(pnd);
228 arygon_close_step2(pnd);
229 }
230
231 static nfc_device *
arygon_open(const nfc_context * context,const nfc_connstring connstring)232 arygon_open(const nfc_context *context, const nfc_connstring connstring)
233 {
234 struct arygon_descriptor ndd;
235 char *speed_s;
236 int connstring_decode_level = connstring_decode(connstring, ARYGON_DRIVER_NAME, NULL, &ndd.port, &speed_s);
237 if (connstring_decode_level == 3) {
238 ndd.speed = 0;
239 if (sscanf(speed_s, "%10"PRIu32, &ndd.speed) != 1) {
240 // speed_s is not a number
241 free(ndd.port);
242 free(speed_s);
243 return NULL;
244 }
245 free(speed_s);
246 }
247 if (connstring_decode_level < 2) {
248 return NULL;
249 }
250 if (connstring_decode_level < 3) {
251 ndd.speed = ARYGON_DEFAULT_SPEED;
252 }
253 serial_port sp;
254 nfc_device *pnd = NULL;
255
256 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempt to open: %s at %d bauds.", ndd.port, ndd.speed);
257 sp = uart_open(ndd.port);
258
259 if (sp == INVALID_SERIAL_PORT)
260 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Invalid serial port: %s", ndd.port);
261 if (sp == CLAIMED_SERIAL_PORT)
262 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Serial port already claimed: %s", ndd.port);
263 if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) {
264 free(ndd.port);
265 return NULL;
266 }
267
268 // We need to flush input to be sure first reply does not comes from older byte transceive
269 uart_flush_input(sp, true);
270 uart_set_speed(sp, ndd.speed);
271
272 // We have a connection
273 pnd = nfc_device_new(context, connstring);
274 if (!pnd) {
275 perror("malloc");
276 free(ndd.port);
277 uart_close(sp);
278 return NULL;
279 }
280 snprintf(pnd->name, sizeof(pnd->name), "%s:%s", ARYGON_DRIVER_NAME, ndd.port);
281 free(ndd.port);
282
283 pnd->driver_data = malloc(sizeof(struct arygon_data));
284 if (!pnd->driver_data) {
285 perror("malloc");
286 uart_close(sp);
287 nfc_device_free(pnd);
288 return NULL;
289 }
290 DRIVER_DATA(pnd)->port = sp;
291
292 // Alloc and init chip's data
293 if (pn53x_data_new(pnd, &arygon_tama_io) == NULL) {
294 perror("malloc");
295 uart_close(DRIVER_DATA(pnd)->port);
296 nfc_device_free(pnd);
297 return NULL;
298 }
299
300 // The PN53x chip opened to ARYGON MCU doesn't seems to be in LowVBat mode
301 CHIP_DATA(pnd)->power_mode = NORMAL;
302
303 // empirical tuning
304 CHIP_DATA(pnd)->timer_correction = 46;
305 pnd->driver = &arygon_driver;
306
307 #ifndef WIN32
308 // pipe-based abort mecanism
309 if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
310 uart_close(DRIVER_DATA(pnd)->port);
311 pn53x_data_free(pnd);
312 nfc_device_free(pnd);
313 return NULL;
314 }
315 #else
316 DRIVER_DATA(pnd)->abort_flag = false;
317 #endif
318
319 // Check communication using "Reset TAMA" command
320 if (arygon_reset_tama(pnd) < 0) {
321 arygon_close_step2(pnd);
322 return NULL;
323 }
324
325 char arygon_firmware_version[10];
326 arygon_firmware(pnd, arygon_firmware_version);
327 char *pcName;
328 pcName = strdup(pnd->name);
329 snprintf(pnd->name, sizeof(pnd->name), "%s %s", pcName, arygon_firmware_version);
330 free(pcName);
331
332 pn53x_init(pnd);
333 return pnd;
334 }
335
336 #define ARYGON_TX_BUFFER_LEN (PN53x_NORMAL_FRAME__DATA_MAX_LEN + PN53x_NORMAL_FRAME__OVERHEAD + 1)
337 #define ARYGON_RX_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
338 static int
arygon_tama_send(nfc_device * pnd,const uint8_t * pbtData,const size_t szData,int timeout)339 arygon_tama_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
340 {
341 int res = 0;
342 // Before sending anything, we need to discard from any junk bytes
343 uart_flush_input(DRIVER_DATA(pnd)->port, false);
344
345 uint8_t abtFrame[ARYGON_TX_BUFFER_LEN] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff"
346
347 size_t szFrame = 0;
348 if (szData > PN53x_NORMAL_FRAME__DATA_MAX_LEN) {
349 // ARYGON Reader with PN532 equipped does not support extended frame (bug in ARYGON firmware?)
350 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "ARYGON device does not support more than %d bytes as payload (requested: %" PRIdPTR ")", PN53x_NORMAL_FRAME__DATA_MAX_LEN, szData);
351 pnd->last_error = NFC_EDEVNOTSUPP;
352 return pnd->last_error;
353 }
354
355 if ((res = pn53x_build_frame(abtFrame + 1, &szFrame, pbtData, szData)) < 0) {
356 pnd->last_error = res;
357 return pnd->last_error;
358 }
359
360 if ((res = uart_send(DRIVER_DATA(pnd)->port, abtFrame, szFrame + 1, timeout)) != 0) {
361 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
362 pnd->last_error = res;
363 return pnd->last_error;
364 }
365
366 uint8_t abtRxBuf[PN53x_ACK_FRAME__LEN];
367 if ((res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, sizeof(abtRxBuf), 0, timeout)) != 0) {
368 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to read ACK");
369 pnd->last_error = res;
370 return pnd->last_error;
371 }
372
373 if (pn53x_check_ack_frame(pnd, abtRxBuf, sizeof(abtRxBuf)) == 0) {
374 // The PN53x is running the sent command
375 } else if (0 == memcmp(arygon_error_unknown_mode, abtRxBuf, sizeof(abtRxBuf))) {
376 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Bad frame format.");
377 // We have already read 6 bytes and arygon_error_unknown_mode is 10 bytes long
378 // so we have to read 4 remaining bytes to be synchronized at the next receiving pass.
379 pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 4, 0, timeout);
380 return pnd->last_error;
381 } else {
382 return pnd->last_error;
383 }
384 return NFC_SUCCESS;
385 }
386
387 static int
arygon_abort(nfc_device * pnd)388 arygon_abort(nfc_device *pnd)
389 {
390 // Send a valid TAMA packet to wakup the PN53x (we will not have an answer, according to Arygon manual)
391 uint8_t dummy[] = { 0x32, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 0x6c, 0x69, 0x62, 0x6e, 0x66, 0x63, 0xbe, 0x00 };
392
393 uart_send(DRIVER_DATA(pnd)->port, dummy, sizeof(dummy), 0);
394
395 // Using Arygon device we can't send ACK frame to abort the running command
396 return pn53x_check_communication(pnd);
397 }
398
399 static int
arygon_tama_receive(nfc_device * pnd,uint8_t * pbtData,const size_t szDataLen,int timeout)400 arygon_tama_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout)
401 {
402 uint8_t abtRxBuf[5];
403 size_t len;
404 void *abort_p = NULL;
405
406 #ifndef WIN32
407 abort_p = &(DRIVER_DATA(pnd)->iAbortFds[1]);
408 #else
409 abort_p = (void *) & (DRIVER_DATA(pnd)->abort_flag);
410 #endif
411
412 pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 5, abort_p, timeout);
413
414 if (abort_p && (NFC_EOPABORTED == pnd->last_error)) {
415 arygon_abort(pnd);
416
417 /* last_error got reset by arygon_abort() */
418 pnd->last_error = NFC_EOPABORTED;
419 return pnd->last_error;
420 }
421
422 if (pnd->last_error != 0) {
423 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
424 return pnd->last_error;
425 }
426
427 const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
428 if (0 != (memcmp(abtRxBuf, pn53x_preamble, 3))) {
429 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
430 pnd->last_error = NFC_EIO;
431 return pnd->last_error;
432 }
433
434 if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
435 // Error frame
436 uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
437 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Application level error detected");
438 pnd->last_error = NFC_EIO;
439 return pnd->last_error;
440 } else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
441 // Extended frame
442 // ARYGON devices does not support extended frame sending
443 abort();
444 } else {
445 // Normal frame
446 if (256 != (abtRxBuf[3] + abtRxBuf[4])) {
447 // TODO: Retry
448 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch");
449 pnd->last_error = NFC_EIO;
450 return pnd->last_error;
451 }
452
453 // abtRxBuf[3] (LEN) include TFI + (CC+1)
454 len = abtRxBuf[3] - 2;
455 }
456
457 if (len > szDataLen) {
458 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
459 pnd->last_error = NFC_EIO;
460 return pnd->last_error;
461 }
462
463 // TFI + PD0 (CC+1)
464 pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
465 if (pnd->last_error != 0) {
466 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
467 return pnd->last_error;
468 }
469
470 if (abtRxBuf[0] != 0xD5) {
471 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "TFI Mismatch");
472 pnd->last_error = NFC_EIO;
473 return pnd->last_error;
474 }
475
476 if (abtRxBuf[1] != CHIP_DATA(pnd)->last_command + 1) {
477 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Command Code verification failed");
478 pnd->last_error = NFC_EIO;
479 return pnd->last_error;
480 }
481
482 if (len) {
483 pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, pbtData, len, 0, timeout);
484 if (pnd->last_error != 0) {
485 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
486 return pnd->last_error;
487 }
488 }
489
490 pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
491 if (pnd->last_error != 0) {
492 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
493 return pnd->last_error;
494 }
495
496 uint8_t btDCS = (256 - 0xD5);
497 btDCS -= CHIP_DATA(pnd)->last_command + 1;
498 for (size_t szPos = 0; szPos < len; szPos++) {
499 btDCS -= pbtData[szPos];
500 }
501
502 if (btDCS != abtRxBuf[0]) {
503 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Data checksum mismatch");
504 pnd->last_error = NFC_EIO;
505 return pnd->last_error;
506 }
507
508 if (0x00 != abtRxBuf[1]) {
509 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
510 pnd->last_error = NFC_EIO;
511 return pnd->last_error;
512 }
513 // The PN53x command is done and we successfully received the reply
514 return len;
515 }
516
517 void
arygon_firmware(nfc_device * pnd,char * str)518 arygon_firmware(nfc_device *pnd, char *str)
519 {
520 const uint8_t arygon_firmware_version_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'v' };
521 uint8_t abtRx[16];
522 size_t szRx = sizeof(abtRx);
523
524
525 int res = uart_send(DRIVER_DATA(pnd)->port, arygon_firmware_version_cmd, sizeof(arygon_firmware_version_cmd), 0);
526 if (res != 0) {
527 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Unable to send ARYGON firmware command.");
528 return;
529 }
530 res = uart_receive(DRIVER_DATA(pnd)->port, abtRx, szRx, 0, 0);
531 if (res != 0) {
532 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Unable to retrieve ARYGON firmware version.");
533 return;
534 }
535
536 if (0 == memcmp(abtRx, arygon_error_none, 6)) {
537 uint8_t *p = abtRx + 6;
538 unsigned int szData;
539 sscanf((const char *)p, "%02x%9s", &szData, p);
540 if (szData > 9)
541 szData = 9;
542 memcpy(str, p, szData);
543 *(str + szData) = '\0';
544 }
545 }
546
547 int
arygon_reset_tama(nfc_device * pnd)548 arygon_reset_tama(nfc_device *pnd)
549 {
550 const uint8_t arygon_reset_tama_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'r' };
551 uint8_t abtRx[10]; // Attempted response is 10 bytes long
552 size_t szRx = sizeof(abtRx);
553 int res;
554
555 uart_send(DRIVER_DATA(pnd)->port, arygon_reset_tama_cmd, sizeof(arygon_reset_tama_cmd), 500);
556
557 // Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent)
558 // or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted)
559 res = uart_receive(DRIVER_DATA(pnd)->port, abtRx, szRx, 0, 1000);
560 if (res != 0) {
561 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "No reply to 'reset TAMA' command.");
562 pnd->last_error = res;
563 return pnd->last_error;
564 }
565
566 if (0 != memcmp(abtRx, arygon_error_none, sizeof(arygon_error_none) - 1)) {
567 pnd->last_error = NFC_EIO;
568 return pnd->last_error;
569 }
570
571 return NFC_SUCCESS;
572 }
573
574 static int
arygon_abort_command(nfc_device * pnd)575 arygon_abort_command(nfc_device *pnd)
576 {
577 if (pnd) {
578 #ifndef WIN32
579 close(DRIVER_DATA(pnd)->iAbortFds[0]);
580 if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
581 return NFC_ESOFT;
582 }
583 #else
584 DRIVER_DATA(pnd)->abort_flag = true;
585 #endif
586 }
587 return NFC_SUCCESS;
588 }
589
590
591 const struct pn53x_io arygon_tama_io = {
592 .send = arygon_tama_send,
593 .receive = arygon_tama_receive,
594 };
595
596 const struct nfc_driver arygon_driver = {
597 .name = ARYGON_DRIVER_NAME,
598 .scan_type = INTRUSIVE,
599 .scan = arygon_scan,
600 .open = arygon_open,
601 .close = arygon_close,
602 .strerror = pn53x_strerror,
603
604 .initiator_init = pn53x_initiator_init,
605 .initiator_init_secure_element = NULL, // No secure-element support
606 .initiator_select_passive_target = pn53x_initiator_select_passive_target,
607 .initiator_poll_target = pn53x_initiator_poll_target,
608 .initiator_select_dep_target = pn53x_initiator_select_dep_target,
609 .initiator_deselect_target = pn53x_initiator_deselect_target,
610 .initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
611 .initiator_transceive_bits = pn53x_initiator_transceive_bits,
612 .initiator_transceive_bytes_timed = pn53x_initiator_transceive_bytes_timed,
613 .initiator_transceive_bits_timed = pn53x_initiator_transceive_bits_timed,
614 .initiator_target_is_present = pn53x_initiator_target_is_present,
615
616 .target_init = pn53x_target_init,
617 .target_send_bytes = pn53x_target_send_bytes,
618 .target_receive_bytes = pn53x_target_receive_bytes,
619 .target_send_bits = pn53x_target_send_bits,
620 .target_receive_bits = pn53x_target_receive_bits,
621
622 .device_set_property_bool = pn53x_set_property_bool,
623 .device_set_property_int = pn53x_set_property_int,
624 .get_supported_modulation = pn53x_get_supported_modulation,
625 .get_supported_baud_rate = pn53x_get_supported_baud_rate,
626 .device_get_information_about = pn53x_get_information_about,
627
628 .abort_command = arygon_abort_command,
629 .idle = pn53x_idle,
630 /* Even if PN532, PowerDown is not recommended on those devices */
631 .powerdown = NULL,
632 };
633
634