libnfc  1.4.2
nfc.c
Go to the documentation of this file.
1 /*-
2  * Public platform independent Near Field Communication (NFC) library
3  *
4  * Copyright (C) 2009, Roel Verdult, Romuald Conty
5  * Copyright (C) 2010, Roel Verdult, Romuald Conty, Romain Tartière
6  *
7  * This program is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>
19  */
20 
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif // HAVE_CONFIG_H
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stddef.h>
33 #include <string.h>
34 
35 #include <nfc/nfc.h>
36 
37 #ifdef _WIN32
38 # include "../contrib/windows.h"
39 #endif
40 
41 #include "chips.h"
42 #include "drivers.h"
43 
44 #include <nfc/nfc-messages.h>
45 
47 
72 {
73  nfc_device_t *pnd = NULL;
74  uint32_t uiDriver;
75 
76  // Search through the device list for an available device
77  for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
78  if (pndd == NULL) {
79  // No device description specified: try to automatically claim a device
80  if (drivers_callbacks_list[uiDriver].pick_device != NULL) {
81  DBG ("Autodetecting available devices using %s driver.", drivers_callbacks_list[uiDriver].acDriver);
82  pndd = drivers_callbacks_list[uiDriver].pick_device ();
83 
84  if (pndd != NULL) {
85  DBG ("Auto-connecting to %s using %s driver", pndd->acDevice, drivers_callbacks_list[uiDriver].acDriver);
86  pnd = drivers_callbacks_list[uiDriver].connect (pndd);
87  if (pnd == NULL) {
88  DBG ("No device available using %s driver", drivers_callbacks_list[uiDriver].acDriver);
89  pndd = NULL;
90  }
91 
92  free (pndd);
93  }
94  }
95  } else {
96  // Specific device is requested: using device description pndd
97  if (0 != strcmp (drivers_callbacks_list[uiDriver].acDriver, pndd->pcDriver)) {
98  continue;
99  } else {
100  pnd = drivers_callbacks_list[uiDriver].connect (pndd);
101  }
102  }
103 
104  // Test if the connection was successful
105  if (pnd != NULL) {
106  DBG ("[%s] has been claimed.", pnd->acName);
107  // Great we have claimed a device
108  pnd->pdc = &(drivers_callbacks_list[uiDriver]);
109 
110  // TODO: Put this pn53x related in driver_init()
111  if (!pn53x_init (pnd))
112  return NULL;
113 
114  if (pnd->pdc->init) {
115  pnd->pdc->init (pnd);
116  }
117 
118  // Set default configuration options
119  // Make sure we reset the CRC and parity to chip handling.
120  if (!nfc_configure (pnd, NDO_HANDLE_CRC, true))
121  return NULL;
122  if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true))
123  return NULL;
124 
125  // Deactivate the CRYPTO1 cipher, it may could cause problems when still active
126  if (!nfc_configure (pnd, NDO_ACTIVATE_CRYPTO1, false))
127  return NULL;
128 
129  // Activate "easy framing" feature by default
130  if (!nfc_configure (pnd, NDO_EASY_FRAMING, true))
131  return NULL;
132 
133  // Activate auto ISO14443-4 switching by default
134  if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true))
135  return NULL;
136 
137  // Disallow invalid frame
138  if (!nfc_configure (pnd, NDO_ACCEPT_INVALID_FRAMES, false))
139  return NULL;
140 
141  // Disallow multiple frames
142  if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false))
143  return NULL;
144 
145  return pnd;
146  } else {
147  DBG ("No device found using driver: %s", drivers_callbacks_list[uiDriver].acDriver);
148  }
149  }
150  // Too bad, no reader is ready to be claimed
151  return NULL;
152 }
153 
160 void
162 {
163  if (pnd) {
164  // Release and deselect all active communications
165  nfc_initiator_deselect_target (pnd);
166  // Disable RF field to avoid heating
167  nfc_configure (pnd, NDO_ACTIVATE_FIELD, false);
168  // Disconnect, clean up and release the device
169  pnd->pdc->disconnect (pnd);
170  }
171 }
172 
179 {
180  uint32_t uiDriver;
181  nfc_device_desc_t *nddRes;
182 
183  for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
184  if (drivers_callbacks_list[uiDriver].pick_device != NULL) {
185  nddRes = drivers_callbacks_list[uiDriver].pick_device ();
186  if (nddRes != NULL)
187  return nddRes;
188  }
189  }
190 
191  return NULL;
192 }
193 
200 void
201 nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
202 {
203  uint32_t uiDriver;
204  size_t szN;
205 
206  *pszDeviceFound = 0;
207 
208  for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
209  if (drivers_callbacks_list[uiDriver].list_devices != NULL) {
210  szN = 0;
211  if (drivers_callbacks_list[uiDriver].list_devices
212  (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN)) {
213  *pszDeviceFound += szN;
214  DBG ("%ld device(s) found using %s driver", (unsigned long) szN, drivers_callbacks_list[uiDriver].acDriver);
215  }
216  } else {
217  DBG ("No listing function avaible for %s driver", drivers_callbacks_list[uiDriver].acDriver);
218  }
219  }
220 }
221 
234 bool
235 nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable)
236 {
237  pnd->iLastError = 0;
238 
239  return pn53x_configure (pnd, ndo, bEnable);
240 }
241 
251 bool
253 {
254  pnd->iLastError = 0;
255 
256  // Make sure we are dealing with a active device
257  if (!pnd->bActive)
258  return false;
259 
260  // Set the PN53X to force 100% ASK Modified miller decoding (default for 14443A cards)
261  if (!pn53x_set_reg (pnd, REG_CIU_TX_AUTO, SYMBOL_FORCE_100_ASK, 0x40))
262  return false;
263 
264  // Configure the PN53X to be an Initiator or Reader/Writer
265  if (!pn53x_set_reg (pnd, REG_CIU_CONTROL, SYMBOL_INITIATOR, 0x10))
266  return false;
267 
268  return true;
269 }
270 
291 bool
293  const nfc_modulation_t nm,
294  const byte_t * pbtInitData, const size_t szInitData,
295  nfc_target_t * pnt)
296 {
297  byte_t abtInit[MAX_FRAME_LEN];
298  size_t szInit;
299 
300  pnd->iLastError = 0;
301 
302  // Make sure we are dealing with a active device
303  if (!pnd->bActive)
304  return false;
305  // TODO Put this in a function: this part is defined by ISO14443-3 (UID and Cascade levels)
306  switch (nm.nmt) {
307  case NMT_ISO14443A:
308  switch (szInitData) {
309  case 7:
310  abtInit[0] = 0x88;
311  memcpy (abtInit + 1, pbtInitData, 7);
312  szInit = 8;
313  break;
314 
315  case 10:
316  abtInit[0] = 0x88;
317  memcpy (abtInit + 1, pbtInitData, 3);
318  abtInit[4] = 0x88;
319  memcpy (abtInit + 5, pbtInitData + 3, 7);
320  szInit = 12;
321  break;
322 
323  case 4:
324  default:
325  memcpy (abtInit, pbtInitData, szInitData);
326  szInit = szInitData;
327  break;
328  }
329  break;
330 
331  default:
332  memcpy (abtInit, pbtInitData, szInitData);
333  szInit = szInitData;
334  break;
335  }
336 
337  return pn53x_initiator_select_passive_target (pnd, nm, abtInit, szInit, pnt);
338 }
339 
357 bool
359  const nfc_modulation_t nm,
360  nfc_target_t ant[], const size_t szTargets, size_t * pszTargetFound)
361 {
362  nfc_target_t nt;
363  size_t szTargetFound = 0;
364  byte_t *pbtInitData = NULL;
365  size_t szInitDataLen = 0;
366 
367  pnd->iLastError = 0;
368 
369  // Drop the field for a while
370  if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
371  return false;
372  }
373  // Let the reader only try once to find a tag
374  if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
375  return false;
376  }
377  // Enable field so more power consuming cards can power themselves up
378  if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
379  return false;
380  }
381 
382  switch (nm.nmt) {
383  case NMT_ISO14443B: {
384  // Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3)
385  pbtInitData = (byte_t *) "\x00";
386  szInitDataLen = 1;
387  }
388  break;
389  case NMT_FELICA: {
390  // polling payload must be present (see ISO/IEC 18092 11.2.2.5)
391  pbtInitData = (byte_t *) "\x00\xff\xff\x01\x00";
392  szInitDataLen = 5;
393  }
394  break;
395  default:
396  // nothing to do
397  break;
398  }
399 
400  while (nfc_initiator_select_passive_target (pnd, nm, pbtInitData, szInitDataLen, &nt)) {
401  nfc_initiator_deselect_target (pnd);
402 
403  if (szTargets > szTargetFound) {
404  memcpy (&(ant[szTargetFound]), &nt, sizeof (nfc_target_t));
405  } else {
406  break;
407  }
408  szTargetFound++;
409  // deselect has no effect on FeliCa and Jewel cards so we'll stop after one...
410  if ((nm.nmt == NMT_FELICA) || (nm.nmt == NMT_JEWEL)) {
411  break;
412  }
413  }
414  *pszTargetFound = szTargetFound;
415 
416  return true;
417 }
418 
432 bool
434  const nfc_modulation_t * pnmModulations, const size_t szModulations,
435  const byte_t btPollNr, const byte_t btPeriod,
436  nfc_target_t * pntTargets, size_t * pszTargetFound)
437 {
438  pnd->iLastError = 0;
439 
440  return pn53x_initiator_poll_targets (pnd, pnmModulations, szModulations, btPollNr, btPeriod, pntTargets, pszTargetFound);
441 }
442 
443 
459 bool
461  const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr,
462  const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt)
463 {
464  pnd->iLastError = 0;
465 
466  return pn53x_initiator_select_dep_target (pnd, ndm, nbr, pndiInitiator, pnt);
467 }
468 
481 bool
482 nfc_initiator_deselect_target (nfc_device_t * pnd)
483 {
484  pnd->iLastError = 0;
485 
486  return (pn53x_InDeselect (pnd, 0)); // 0 mean deselect all selected targets
487 }
488 
505 bool
506 nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx,
507  size_t * pszRx)
508 {
509  pnd->iLastError = 0;
510 
511  return pn53x_initiator_transceive_bytes (pnd, pbtTx, szTx, pbtRx, pszRx);
512 }
513 
549 bool
550 nfc_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar,
551  byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
552 {
553  pnd->iLastError = 0;
554 
555  return pn53x_initiator_transceive_bits (pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pszRxBits, pbtRxPar);
556 }
557 
580 bool
581 nfc_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx)
582 {
583  pnd->iLastError = 0;
584 
585  return pn53x_target_init (pnd, pnt, pbtRx, pszRx);
586 }
587 
599 bool
600 nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx)
601 {
602  pnd->iLastError = 0;
603 
604  return pn53x_target_send_bytes (pnd, pbtTx, szTx);
605 }
606 
616 bool
617 nfc_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx)
618 {
619  pnd->iLastError = 0;
620 
621  return pn53x_target_receive_bytes (pnd, pbtRx, pszRx);
622 }
623 
631 bool
632 nfc_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar)
633 {
634  pnd->iLastError = 0;
635 
636  return pn53x_target_send_bits (pnd, pbtTx, szTxBits, pbtTxPar);
637 }
638 
650 bool
651 nfc_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
652 {
653  pnd->iLastError = 0;
654 
655  return pn53x_target_receive_bits (pnd, pbtRx, pszRxBits, pbtRxPar);
656 }
657 
662 const char *
664 {
665  return pnd->pdc->pcc->strerror (pnd);
666 }
667 
672 int
673 nfc_strerror_r (const nfc_device_t * pnd, char *pcStrErrBuf, size_t szBufLen)
674 {
675  return (snprintf (pcStrErrBuf, szBufLen, "%s", nfc_strerror (pnd)) < 0) ? -1 : 0;
676 }
677 
681 void
682 nfc_perror (const nfc_device_t * pnd, const char *pcString)
683 {
684  fprintf (stderr, "%s: %s\n", pcString, nfc_strerror (pnd));
685 }
686 
687 /* Special data accessors */
688 
693 const char *
695 {
696  return pnd->acName;
697 }
698 
699 /* Misc. functions */
700 
705 const char *
707 {
708 #ifdef SVN_REVISION
709  return PACKAGE_VERSION " (r" SVN_REVISION ")";
710 #else
711  return PACKAGE_VERSION;
712 #endif // SVN_REVISION
713 }