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) 2011 Anugrah Redja Kusuma
13 *
14 * This program is free software: you can redistribute it and/or modify it
15 * under the terms of the GNU Lesser General Public License as published by the
16 * Free Software Foundation, either version 3 of the License, or (at your
17 * option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but WITHOUT
20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
22 * more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with this program. If not, see <http://www.gnu.org/licenses/>
26 */
27
28 /**
29 * @file acr122s.c
30 * @brief Driver for ACS ACR122S devices
31 */
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #include "acr122s.h"
38
39 #include <stdio.h>
40 #include <inttypes.h>
41 #include <string.h>
42 #include <string.h>
43 #include <unistd.h>
44
45 #include <nfc/nfc.h>
46
47 #include "drivers.h"
48 #include "nfc-internal.h"
49 #include "chips/pn53x.h"
50 #include "chips/pn53x-internal.h"
51 #include "uart.h"
52
53 #define ACR122S_DEFAULT_SPEED 9600
54 #define ACR122S_DRIVER_NAME "ACR122S"
55
56 #define LOG_CATEGORY "libnfc.driver.acr122s"
57 #define LOG_GROUP NFC_LOG_GROUP_DRIVER
58
59 // Internal data structs
60 struct acr122s_data {
61 serial_port port;
62 uint8_t seq;
63 #ifndef WIN32
64 int abort_fds[2];
65 #else
66 volatile bool abort_flag;
67 #endif
68 };
69
70 const struct pn53x_io acr122s_io;
71
72 #define STX 2
73 #define ETX 3
74
75 #define APDU_SIZE(p) ((uint32_t) (p[2] | p[3] << 8 | p[4] << 16 | p[5] << 24))
76 #define FRAME_OVERHEAD 13
77 #define FRAME_SIZE(p) (APDU_SIZE(p) + FRAME_OVERHEAD)
78 #define MAX_FRAME_SIZE (FRAME_OVERHEAD + 5 + 255)
79
80 enum {
81 ICC_POWER_ON_REQ_MSG = 0x62,
82 ICC_POWER_OFF_REQ_MSG = 0x63,
83 XFR_BLOCK_REQ_MSG = 0x6F,
84
85 ICC_POWER_ON_RES_MSG = 0x80,
86 ICC_POWER_OFF_RES_MSG = 0x81,
87 XFR_BLOCK_RES_MSG = 0x80,
88 };
89
90 enum {
91 POWER_AUTO = 0,
92 POWER_5_0_V = 1,
93 POWER_3_0_V = 2,
94 POWER_1_8_V = 3,
95 };
96
97 #pragma pack(push, 1)
98
99 struct icc_power_on_req {
100 uint8_t message_type;
101 uint32_t length;
102 uint8_t slot;
103 uint8_t seq;
104 uint8_t power_select;
105 uint8_t rfu[2];
106 };
107
108 struct icc_power_on_res {
109 uint8_t message_type;
110 uint32_t length;
111 uint8_t slot;
112 uint8_t seq;
113 uint8_t status;
114 uint8_t error;
115 uint8_t chain_parameter;
116 };
117
118 struct icc_power_off_req {
119 uint8_t message_type;
120 uint32_t length;
121 uint8_t slot;
122 uint8_t seq;
123 uint8_t rfu[3];
124 };
125
126 struct icc_power_off_res {
127 uint8_t message_type;
128 uint32_t length;
129 uint8_t slot;
130 uint8_t seq;
131 uint8_t status;
132 uint8_t error;
133 uint8_t clock_status;
134 };
135
136 struct xfr_block_req {
137 uint8_t message_type;
138 uint32_t length;
139 uint8_t slot;
140 uint8_t seq;
141 uint8_t bwi;
142 uint8_t rfu[2];
143 };
144
145 struct xfr_block_res {
146 uint8_t message_type;
147 uint32_t length;
148 uint8_t slot;
149 uint8_t seq;
150 uint8_t status;
151 uint8_t error;
152 uint8_t chain_parameter;
153 };
154
155 struct apdu_header {
156 uint8_t class;
157 uint8_t ins;
158 uint8_t p1;
159 uint8_t p2;
160 uint8_t length;
161 };
162
163 #pragma pack(pop)
164
165 #define DRIVER_DATA(pnd) ((struct acr122s_data *) (pnd->driver_data))
166
167 /**
168 * Fix a command frame with a valid prefix, checksum, and suffix.
169 *
170 * @param frame is command frame to fix
171 * @note command frame length (uint32_t at offset 2) should be valid
172 */
173 static void
acr122s_fix_frame(uint8_t * frame)174 acr122s_fix_frame(uint8_t *frame)
175 {
176 size_t frame_size = FRAME_SIZE(frame);
177 frame[0] = STX;
178 frame[frame_size - 1] = ETX;
179
180 uint8_t *csum = frame + frame_size - 2;
181 *csum = 0;
182 for (uint8_t *p = frame + 1; p < csum; p++)
183 *csum ^= *p;
184 }
185
186 /**
187 * Send a command frame to ACR122S and check its ACK status.
188 *
189 * @param: pnd is target nfc device
190 * @param: cmd is command frame to send
191 * @param: timeout
192 * @return 0 if success
193 */
194 static int
acr122s_send_frame(nfc_device * pnd,uint8_t * frame,int timeout)195 acr122s_send_frame(nfc_device *pnd, uint8_t *frame, int timeout)
196 {
197 size_t frame_size = FRAME_SIZE(frame);
198 uint8_t ack[4];
199 uint8_t positive_ack[4] = { STX, 0, 0, ETX };
200 serial_port port = DRIVER_DATA(pnd)->port;
201 int ret;
202 void *abort_p;
203
204 #ifndef WIN32
205 abort_p = &(DRIVER_DATA(pnd)->abort_fds[1]);
206 #else
207 abort_p = &(DRIVER_DATA(pnd)->abort_flag);
208 #endif
209
210 if ((ret = uart_send(port, frame, frame_size, timeout)) < 0)
211 return ret;
212
213 if ((ret = uart_receive(port, ack, 4, abort_p, timeout)) < 0)
214 return ret;
215
216 if (memcmp(ack, positive_ack, 4) != 0) {
217 pnd->last_error = NFC_EIO;
218 return pnd->last_error;
219 }
220
221 struct xfr_block_req *req = (struct xfr_block_req *) &frame[1];
222 DRIVER_DATA(pnd)->seq = req->seq + 1;
223
224 return 0;
225 }
226
227 /**
228 * Receive response frame after a successfull acr122s_send_command().
229 *
230 * @param: pnd is target nfc device
231 * @param: frame is buffer where received response frame will be stored
232 * @param: frame_size is frame size
233 * @param: abort_p
234 * @param: timeout
235 * @note returned frame size can be fetched using FRAME_SIZE macro
236 *
237 * @return 0 if success
238 */
239 static int
acr122s_recv_frame(nfc_device * pnd,uint8_t * frame,size_t frame_size,void * abort_p,int timeout)240 acr122s_recv_frame(nfc_device *pnd, uint8_t *frame, size_t frame_size, void *abort_p, int timeout)
241 {
242 if (frame_size < 13) {
243 pnd->last_error = NFC_EINVARG;
244 return pnd->last_error;
245 }
246 int ret;
247 serial_port port = DRIVER_DATA(pnd)->port;
248
249 if ((ret = uart_receive(port, frame, 11, abort_p, timeout)) != 0)
250 return ret;
251
252 // Is buffer sufficient to store response?
253 if (frame_size < FRAME_SIZE(frame)) {
254 pnd->last_error = NFC_EIO;
255 return pnd->last_error;
256 }
257
258 size_t remaining = FRAME_SIZE(frame) - 11;
259 if ((ret = uart_receive(port, frame + 11, remaining, abort_p, timeout)) != 0)
260 return ret;
261
262 struct xfr_block_res *res = (struct xfr_block_res *) &frame[1];
263 if ((uint8_t)(res->seq + 1) != DRIVER_DATA(pnd)->seq) {
264 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Invalid response sequence number.");
265 pnd->last_error = NFC_EIO;
266 return pnd->last_error;
267 }
268
269 return 0;
270 }
271
272 #define APDU_OVERHEAD (FRAME_OVERHEAD + 5)
273
274 /**
275 * Convert host uint32 to litle endian uint32
276 */
277 static uint32_t
le32(uint32_t val)278 le32(uint32_t val)
279 {
280 uint32_t res;
281 uint8_t *p = (uint8_t *) &res;
282 p[0] = val;
283 p[1] = val >> 8;
284 p[2] = val >> 16;
285 p[3] = val >> 24;
286 return res;
287 }
288
289 /**
290 * Build an ACR122S command frame from a PN532 command.
291 *
292 * @param pnd is device for which the command frame will be generated
293 * @param frame is where the resulting command frame will be generated
294 * @param frame_size is the passed command frame size
295 * @param p1
296 * @param p2
297 * @param data is PN532 APDU data without the direction prefix (0xD4)
298 * @param data_size is APDU data size
299 * @param should_prefix 1 if prefix 0xD4 should be inserted before APDU data, 0 if not
300 *
301 * @return true if frame built successfully
302 */
303 static bool
acr122s_build_frame(nfc_device * pnd,uint8_t * frame,size_t frame_size,uint8_t p1,uint8_t p2,const uint8_t * data,size_t data_size,int should_prefix)304 acr122s_build_frame(nfc_device *pnd,
305 uint8_t *frame, size_t frame_size, uint8_t p1, uint8_t p2,
306 const uint8_t *data, size_t data_size, int should_prefix)
307 {
308 if (frame_size < data_size + APDU_OVERHEAD + should_prefix)
309 return false;
310 if (data_size + should_prefix > 255)
311 return false;
312 if (data == NULL)
313 return false;
314
315 struct xfr_block_req *req = (struct xfr_block_req *) &frame[1];
316 req->message_type = XFR_BLOCK_REQ_MSG;
317 req->length = le32(5 + data_size + should_prefix);
318 req->slot = 0;
319 req->seq = DRIVER_DATA(pnd)->seq;
320 req->bwi = 0;
321 req->rfu[0] = 0;
322 req->rfu[1] = 0;
323
324 struct apdu_header *header = (struct apdu_header *) &frame[11];
325 header->class = 0xff;
326 header->ins = 0;
327 header->p1 = p1;
328 header->p2 = p2;
329 header->length = data_size + should_prefix;
330
331 uint8_t *buf = (uint8_t *) &frame[16];
332 if (should_prefix)
333 *buf++ = 0xD4;
334 memcpy(buf, data, data_size);
335 acr122s_fix_frame(frame);
336
337 return true;
338 }
339
340 static int
acr122s_activate_sam(nfc_device * pnd)341 acr122s_activate_sam(nfc_device *pnd)
342 {
343 uint8_t cmd[13];
344 memset(cmd, 0, sizeof(cmd));
345 cmd[1] = ICC_POWER_ON_REQ_MSG;
346 acr122s_fix_frame(cmd);
347
348 uint8_t resp[MAX_FRAME_SIZE];
349 int ret;
350
351 if ((ret = acr122s_send_frame(pnd, cmd, 0)) != 0)
352 return ret;
353
354 if ((ret = acr122s_recv_frame(pnd, resp, MAX_FRAME_SIZE, 0, 0)) != 0)
355 return ret;
356
357 CHIP_DATA(pnd)->power_mode = NORMAL;
358
359 return 0;
360 }
361
362 static int
acr122s_deactivate_sam(nfc_device * pnd)363 acr122s_deactivate_sam(nfc_device *pnd)
364 {
365 uint8_t cmd[13];
366 memset(cmd, 0, sizeof(cmd));
367 cmd[1] = ICC_POWER_OFF_REQ_MSG;
368 acr122s_fix_frame(cmd);
369
370 uint8_t resp[MAX_FRAME_SIZE];
371 int ret;
372
373 if ((ret = acr122s_send_frame(pnd, cmd, 0)) != 0)
374 return ret;
375
376 if ((ret = acr122s_recv_frame(pnd, resp, MAX_FRAME_SIZE, 0, 0)) != 0)
377 return ret;
378
379 CHIP_DATA(pnd)->power_mode = LOWVBAT;
380
381 return 0;
382 }
383
384 static int
acr122s_get_firmware_version(nfc_device * pnd,char * version,size_t length)385 acr122s_get_firmware_version(nfc_device *pnd, char *version, size_t length)
386 {
387 int ret;
388 uint8_t cmd[MAX_FRAME_SIZE];
389
390 if (! acr122s_build_frame(pnd, cmd, sizeof(cmd), 0x48, 0, NULL, 0, 0)) {
391 return NFC_EINVARG;
392 }
393
394 if ((ret = acr122s_send_frame(pnd, cmd, 1000)) != 0)
395 return ret;
396
397 if ((ret = acr122s_recv_frame(pnd, cmd, sizeof(cmd), 0, 0)) != 0)
398 return ret;
399
400 size_t len = APDU_SIZE(cmd);
401 if (len + 1 > length)
402 len = length - 1;
403 memcpy(version, cmd + 11, len);
404 version[len] = 0;
405
406 return 0;
407 }
408
409 struct acr122s_descriptor {
410 char *port;
411 uint32_t speed;
412 };
413
414 static size_t
acr122s_scan(const nfc_context * context,nfc_connstring connstrings[],const size_t connstrings_len)415 acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
416 {
417 size_t device_found = 0;
418 serial_port sp;
419 char **acPorts = uart_list_ports();
420 const char *acPort;
421 int iDevice = 0;
422
423 while ((acPort = acPorts[iDevice++])) {
424 sp = uart_open(acPort);
425 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find ACR122S device on serial port: %s at %d bauds.", acPort, ACR122S_DEFAULT_SPEED);
426
427 if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
428 // We need to flush input to be sure first reply does not comes from older byte transceive
429 uart_flush_input(sp, true);
430 uart_set_speed(sp, ACR122S_DEFAULT_SPEED);
431
432 nfc_connstring connstring;
433 snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ACR122S_DRIVER_NAME, acPort, ACR122S_DEFAULT_SPEED);
434 nfc_device *pnd = nfc_device_new(context, connstring);
435 if (!pnd) {
436 perror("malloc");
437 uart_close(sp);
438 iDevice = 0;
439 while ((acPort = acPorts[iDevice++])) {
440 free((void *)acPort);
441 }
442 free(acPorts);
443 return 0;
444 }
445
446 pnd->driver = &acr122s_driver;
447 pnd->driver_data = malloc(sizeof(struct acr122s_data));
448 if (!pnd->driver_data) {
449 perror("malloc");
450 uart_close(sp);
451 nfc_device_free(pnd);
452 iDevice = 0;
453 while ((acPort = acPorts[iDevice++])) {
454 free((void *)acPort);
455 }
456 free(acPorts);
457 return 0;
458 }
459 DRIVER_DATA(pnd)->port = sp;
460 DRIVER_DATA(pnd)->seq = 0;
461
462 #ifndef WIN32
463 if (pipe(DRIVER_DATA(pnd)->abort_fds) < 0) {
464 uart_close(DRIVER_DATA(pnd)->port);
465 nfc_device_free(pnd);
466 iDevice = 0;
467 while ((acPort = acPorts[iDevice++])) {
468 free((void *)acPort);
469 }
470 free(acPorts);
471 return 0;
472 }
473 #else
474 DRIVER_DATA(pnd)->abort_flag = false;
475 #endif
476
477 if (pn53x_data_new(pnd, &acr122s_io) == NULL) {
478 perror("malloc");
479 uart_close(DRIVER_DATA(pnd)->port);
480 nfc_device_free(pnd);
481 iDevice = 0;
482 while ((acPort = acPorts[iDevice++])) {
483 free((void *)acPort);
484 }
485 free(acPorts);
486 return 0;
487 }
488 CHIP_DATA(pnd)->type = PN532;
489 CHIP_DATA(pnd)->power_mode = NORMAL;
490
491 char version[32];
492 int ret = acr122s_get_firmware_version(pnd, version, sizeof(version));
493 if (ret == 0 && strncmp("ACR122S", version, 7) != 0) {
494 ret = -1;
495 }
496
497 uart_close(DRIVER_DATA(pnd)->port);
498 pn53x_data_free(pnd);
499 nfc_device_free(pnd);
500
501 if (ret != 0)
502 continue;
503
504 // ACR122S reader is found
505 memcpy(connstrings[device_found], connstring, sizeof(nfc_connstring));
506 device_found++;
507
508 // Test if we reach the maximum "wanted" devices
509 if (device_found >= connstrings_len)
510 break;
511 }
512 }
513 iDevice = 0;
514 while ((acPort = acPorts[iDevice++])) {
515 free((void *)acPort);
516 }
517 free(acPorts);
518 return device_found;
519 }
520
521 static void
acr122s_close(nfc_device * pnd)522 acr122s_close(nfc_device *pnd)
523 {
524 acr122s_deactivate_sam(pnd);
525 pn53x_idle(pnd);
526
527 uart_close(DRIVER_DATA(pnd)->port);
528
529 #ifndef WIN32
530 // Release file descriptors used for abort mecanism
531 close(DRIVER_DATA(pnd)->abort_fds[0]);
532 close(DRIVER_DATA(pnd)->abort_fds[1]);
533 #endif
534
535 pn53x_data_free(pnd);
536 nfc_device_free(pnd);
537 }
538
539 static nfc_device *
acr122s_open(const nfc_context * context,const nfc_connstring connstring)540 acr122s_open(const nfc_context *context, const nfc_connstring connstring)
541 {
542 serial_port sp;
543 nfc_device *pnd;
544 struct acr122s_descriptor ndd;
545 char *speed_s;
546 int connstring_decode_level = connstring_decode(connstring, ACR122S_DRIVER_NAME, NULL, &ndd.port, &speed_s);
547 if (connstring_decode_level == 3) {
548 ndd.speed = 0;
549 if (sscanf(speed_s, "%10"PRIu32, &ndd.speed) != 1) {
550 // speed_s is not a number
551 free(ndd.port);
552 free(speed_s);
553 return NULL;
554 }
555 free(speed_s);
556 }
557 if (connstring_decode_level < 2) {
558 return NULL;
559 }
560 if (connstring_decode_level < 3) {
561 ndd.speed = ACR122S_DEFAULT_SPEED;
562 }
563
564 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
565 "Attempt to connect to: %s at %d bauds.", ndd.port, ndd.speed);
566
567 sp = uart_open(ndd.port);
568 if (sp == INVALID_SERIAL_PORT) {
569 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
570 "Invalid serial port: %s", ndd.port);
571 free(ndd.port);
572 return NULL;
573 }
574 if (sp == CLAIMED_SERIAL_PORT) {
575 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
576 "Serial port already claimed: %s", ndd.port);
577 free(ndd.port);
578 return NULL;
579 }
580
581 uart_flush_input(sp, true);
582 uart_set_speed(sp, ndd.speed);
583
584 pnd = nfc_device_new(context, connstring);
585 if (!pnd) {
586 perror("malloc");
587 free(ndd.port);
588 uart_close(sp);
589 return NULL;
590 }
591 pnd->driver = &acr122s_driver;
592 strcpy(pnd->name, ACR122S_DRIVER_NAME);
593 free(ndd.port);
594
595 pnd->driver_data = malloc(sizeof(struct acr122s_data));
596 if (!pnd->driver_data) {
597 perror("malloc");
598 uart_close(sp);
599 nfc_device_free(pnd);
600 return NULL;
601 }
602
603 DRIVER_DATA(pnd)->port = sp;
604 DRIVER_DATA(pnd)->seq = 0;
605
606 #ifndef WIN32
607 if (pipe(DRIVER_DATA(pnd)->abort_fds) < 0) {
608 uart_close(DRIVER_DATA(pnd)->port);
609 nfc_device_free(pnd);
610 return NULL;
611 }
612 #else
613 DRIVER_DATA(pnd)->abort_flag = false;
614 #endif
615
616 if (pn53x_data_new(pnd, &acr122s_io) == NULL) {
617 perror("malloc");
618 uart_close(DRIVER_DATA(pnd)->port);
619 nfc_device_free(pnd);
620 return NULL;
621 }
622 CHIP_DATA(pnd)->type = PN532;
623
624 #if 1
625 // Retrieve firmware version
626 char version[DEVICE_NAME_LENGTH];
627 if (acr122s_get_firmware_version(pnd, version, sizeof(version)) != 0) {
628 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Cannot get reader firmware.");
629 acr122s_close(pnd);
630 return NULL;
631 }
632
633 if (strncmp(version, "ACR122S", 7) != 0) {
634 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Invalid firmware version: %s",
635 version);
636 acr122s_close(pnd);
637 return NULL;
638 }
639
640 snprintf(pnd->name, sizeof(pnd->name), "%s", version);
641
642 // Activate SAM before operating
643 if (acr122s_activate_sam(pnd) != 0) {
644 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Cannot activate SAM.");
645 acr122s_close(pnd);
646 return NULL;
647 }
648 #endif
649
650 if (pn53x_init(pnd) < 0) {
651 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Failed initializing PN532 chip.");
652 acr122s_close(pnd);
653 return NULL;
654 }
655
656 return pnd;
657 }
658
659 static int
acr122s_send(nfc_device * pnd,const uint8_t * buf,const size_t buf_len,int timeout)660 acr122s_send(nfc_device *pnd, const uint8_t *buf, const size_t buf_len, int timeout)
661 {
662 uart_flush_input(DRIVER_DATA(pnd)->port, false);
663
664 uint8_t cmd[MAX_FRAME_SIZE];
665 if (! acr122s_build_frame(pnd, cmd, sizeof(cmd), 0, 0, buf, buf_len, 1)) {
666 return NFC_EINVARG;
667 }
668
669 int ret;
670 if ((ret = acr122s_send_frame(pnd, cmd, timeout)) != 0) {
671 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
672 pnd->last_error = ret;
673 return pnd->last_error;
674 }
675
676 return NFC_SUCCESS;
677 }
678
679 static int
acr122s_receive(nfc_device * pnd,uint8_t * buf,size_t buf_len,int timeout)680 acr122s_receive(nfc_device *pnd, uint8_t *buf, size_t buf_len, int timeout)
681 {
682 void *abort_p;
683
684 #ifndef WIN32
685 abort_p = &(DRIVER_DATA(pnd)->abort_fds[1]);
686 #else
687 abort_p = &(DRIVER_DATA(pnd)->abort_flag);
688 #endif
689
690 uint8_t tmp[MAX_FRAME_SIZE];
691 pnd->last_error = acr122s_recv_frame(pnd, tmp, sizeof(tmp), abort_p, timeout);
692
693 if (abort_p && (NFC_EOPABORTED == pnd->last_error)) {
694 pnd->last_error = NFC_EOPABORTED;
695 return pnd->last_error;
696 }
697
698 if (pnd->last_error < 0) {
699 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
700 return -1;
701 }
702
703 size_t data_len = FRAME_SIZE(tmp) - 17;
704 if (data_len > buf_len) {
705 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Receive buffer too small. (buf_len: %" PRIuPTR ", data_len: %" PRIuPTR ")", buf_len, data_len);
706 pnd->last_error = NFC_EIO;
707 return pnd->last_error;
708 }
709
710 memcpy(buf, tmp + 13, data_len);
711 return data_len;
712 }
713
714 static int
acr122s_abort_command(nfc_device * pnd)715 acr122s_abort_command(nfc_device *pnd)
716 {
717 if (pnd) {
718 #ifndef WIN32
719 close(DRIVER_DATA(pnd)->abort_fds[0]);
720 close(DRIVER_DATA(pnd)->abort_fds[1]);
721 if (pipe(DRIVER_DATA(pnd)->abort_fds) < 0) {
722 return NFC_ESOFT;
723 }
724 #else
725 DRIVER_DATA(pnd)->abort_flag = true;
726 #endif
727 }
728 return NFC_SUCCESS;
729 }
730
731 const struct pn53x_io acr122s_io = {
732 .send = acr122s_send,
733 .receive = acr122s_receive,
734 };
735
736 const struct nfc_driver acr122s_driver = {
737 .name = ACR122S_DRIVER_NAME,
738 .scan_type = INTRUSIVE,
739 .scan = acr122s_scan,
740 .open = acr122s_open,
741 .close = acr122s_close,
742 .strerror = pn53x_strerror,
743
744 .initiator_init = pn53x_initiator_init,
745 .initiator_init_secure_element = NULL, // No secure-element support
746 .initiator_select_passive_target = pn53x_initiator_select_passive_target,
747 .initiator_poll_target = pn53x_initiator_poll_target,
748 .initiator_select_dep_target = pn53x_initiator_select_dep_target,
749 .initiator_deselect_target = pn53x_initiator_deselect_target,
750 .initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
751 .initiator_transceive_bits = pn53x_initiator_transceive_bits,
752 .initiator_transceive_bytes_timed = pn53x_initiator_transceive_bytes_timed,
753 .initiator_transceive_bits_timed = pn53x_initiator_transceive_bits_timed,
754 .initiator_target_is_present = pn53x_initiator_target_is_present,
755
756 .target_init = pn53x_target_init,
757 .target_send_bytes = pn53x_target_send_bytes,
758 .target_receive_bytes = pn53x_target_receive_bytes,
759 .target_send_bits = pn53x_target_send_bits,
760 .target_receive_bits = pn53x_target_receive_bits,
761
762 .device_set_property_bool = pn53x_set_property_bool,
763 .device_set_property_int = pn53x_set_property_int,
764 .get_supported_modulation = pn53x_get_supported_modulation,
765 .get_supported_baud_rate = pn53x_get_supported_baud_rate,
766 .device_get_information_about = pn53x_get_information_about,
767
768 .abort_command = acr122s_abort_command,
769 .idle = pn53x_idle,
770 /* Even if PN532, PowerDown is not recommended on those devices */
771 .powerdown = NULL,
772 };
773