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