libnfc 1.4.2
nfc.c
Go to the documentation of this file.
00001 /*-
00002  * Public platform independent Near Field Communication (NFC) library
00003  * 
00004  * Copyright (C) 2009, Roel Verdult, Romuald Conty
00005  * Copyright (C) 2010, Roel Verdult, Romuald Conty, Romain Tartière
00006  * 
00007  * This program is free software: you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation, either version 3 of the License, or (at your
00010  * option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00015  * more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00019  */
00020 
00026 #ifdef HAVE_CONFIG_H
00027 #  include "config.h"
00028 #endif // HAVE_CONFIG_H
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <stddef.h>
00033 #include <string.h>
00034 
00035 #include <nfc/nfc.h>
00036 
00037 #ifdef _WIN32
00038 #  include "../contrib/windows.h"
00039 #endif
00040 
00041 #include "chips.h"
00042 #include "drivers.h"
00043 
00044 #include <nfc/nfc-messages.h>
00045 
00046 nfc_device_desc_t *nfc_pick_device (void);
00047 
00070 nfc_device_t *
00071 nfc_connect (nfc_device_desc_t * pndd)
00072 {
00073   nfc_device_t *pnd = NULL;
00074   uint32_t uiDriver;
00075 
00076   // Search through the device list for an available device
00077   for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
00078     if (pndd == NULL) {
00079       // No device description specified: try to automatically claim a device
00080       if (drivers_callbacks_list[uiDriver].pick_device != NULL) {
00081         DBG ("Autodetecting available devices using %s driver.", drivers_callbacks_list[uiDriver].acDriver);
00082         pndd = drivers_callbacks_list[uiDriver].pick_device ();
00083 
00084         if (pndd != NULL) {
00085           DBG ("Auto-connecting to %s using %s driver", pndd->acDevice, drivers_callbacks_list[uiDriver].acDriver);
00086           pnd = drivers_callbacks_list[uiDriver].connect (pndd);
00087           if (pnd == NULL) {
00088             DBG ("No device available using %s driver", drivers_callbacks_list[uiDriver].acDriver);
00089             pndd = NULL;
00090           }
00091 
00092           free (pndd);
00093         }
00094       }
00095     } else {
00096       // Specific device is requested: using device description pndd
00097       if (0 != strcmp (drivers_callbacks_list[uiDriver].acDriver, pndd->pcDriver)) {
00098         continue;
00099       } else {
00100         pnd = drivers_callbacks_list[uiDriver].connect (pndd);
00101       }
00102     }
00103 
00104     // Test if the connection was successful
00105     if (pnd != NULL) {
00106       DBG ("[%s] has been claimed.", pnd->acName);
00107       // Great we have claimed a device
00108       pnd->pdc = &(drivers_callbacks_list[uiDriver]);
00109 
00110       // TODO: Put this pn53x related in driver_init()
00111       if (!pn53x_init (pnd))
00112         return NULL;
00113 
00114       if (pnd->pdc->init) {
00115         pnd->pdc->init (pnd);
00116       }
00117 
00118       // Set default configuration options
00119       // Make sure we reset the CRC and parity to chip handling.
00120       if (!nfc_configure (pnd, NDO_HANDLE_CRC, true))
00121         return NULL;
00122       if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true))
00123         return NULL;
00124 
00125       // Deactivate the CRYPTO1 cipher, it may could cause problems when still active
00126       if (!nfc_configure (pnd, NDO_ACTIVATE_CRYPTO1, false))
00127         return NULL;
00128 
00129       // Activate "easy framing" feature by default
00130       if (!nfc_configure (pnd, NDO_EASY_FRAMING, true))
00131         return NULL;
00132 
00133       // Activate auto ISO14443-4 switching by default
00134       if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true))
00135         return NULL;
00136 
00137       // Disallow invalid frame
00138       if (!nfc_configure (pnd, NDO_ACCEPT_INVALID_FRAMES, false))
00139         return NULL;
00140 
00141       // Disallow multiple frames
00142       if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false))
00143         return NULL;
00144 
00145       return pnd;
00146     } else {
00147       DBG ("No device found using driver: %s", drivers_callbacks_list[uiDriver].acDriver);
00148     }
00149   }
00150   // Too bad, no reader is ready to be claimed
00151   return NULL;
00152 }
00153 
00160 void
00161 nfc_disconnect (nfc_device_t * pnd)
00162 {
00163   if (pnd) {
00164     // Release and deselect all active communications
00165     nfc_initiator_deselect_target (pnd);
00166     // Disable RF field to avoid heating
00167     nfc_configure (pnd, NDO_ACTIVATE_FIELD, false);
00168     // Disconnect, clean up and release the device 
00169     pnd->pdc->disconnect (pnd);
00170   }
00171 }
00172 
00177 nfc_device_desc_t *
00178 nfc_pick_device (void)
00179 {
00180   uint32_t uiDriver;
00181   nfc_device_desc_t *nddRes;
00182 
00183   for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
00184     if (drivers_callbacks_list[uiDriver].pick_device != NULL) {
00185       nddRes = drivers_callbacks_list[uiDriver].pick_device ();
00186       if (nddRes != NULL)
00187         return nddRes;
00188     }
00189   }
00190 
00191   return NULL;
00192 }
00193 
00200 void
00201 nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
00202 {
00203   uint32_t uiDriver;
00204   size_t  szN;
00205 
00206   *pszDeviceFound = 0;
00207 
00208   for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
00209     if (drivers_callbacks_list[uiDriver].list_devices != NULL) {
00210       szN = 0;
00211       if (drivers_callbacks_list[uiDriver].list_devices
00212           (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN)) {
00213         *pszDeviceFound += szN;
00214         DBG ("%ld device(s) found using %s driver", (unsigned long) szN, drivers_callbacks_list[uiDriver].acDriver);
00215       }
00216     } else {
00217       DBG ("No listing function avaible for %s driver", drivers_callbacks_list[uiDriver].acDriver);
00218     }
00219   }
00220 }
00221 
00234 bool
00235 nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable)
00236 {
00237   pnd->iLastError = 0;
00238 
00239   return pn53x_configure (pnd, ndo, bEnable);
00240 }
00241 
00251 bool
00252 nfc_initiator_init (nfc_device_t * pnd)
00253 {
00254   pnd->iLastError = 0;
00255 
00256   // Make sure we are dealing with a active device
00257   if (!pnd->bActive)
00258     return false;
00259 
00260   // Set the PN53X to force 100% ASK Modified miller decoding (default for 14443A cards)
00261   if (!pn53x_set_reg (pnd, REG_CIU_TX_AUTO, SYMBOL_FORCE_100_ASK, 0x40))
00262     return false;
00263 
00264   // Configure the PN53X to be an Initiator or Reader/Writer
00265   if (!pn53x_set_reg (pnd, REG_CIU_CONTROL, SYMBOL_INITIATOR, 0x10))
00266     return false;
00267 
00268   return true;
00269 }
00270 
00291 bool
00292 nfc_initiator_select_passive_target (nfc_device_t * pnd,
00293                                      const nfc_modulation_t nm,
00294                                      const byte_t * pbtInitData, const size_t szInitData,
00295                                      nfc_target_t * pnt)
00296 {
00297   byte_t  abtInit[MAX_FRAME_LEN];
00298   size_t  szInit;
00299 
00300   pnd->iLastError = 0;
00301 
00302   // Make sure we are dealing with a active device
00303   if (!pnd->bActive)
00304     return false;
00305   // TODO Put this in a function: this part is defined by ISO14443-3 (UID and Cascade levels)
00306   switch (nm.nmt) {
00307   case NMT_ISO14443A:
00308     switch (szInitData) {
00309     case 7:
00310       abtInit[0] = 0x88;
00311       memcpy (abtInit + 1, pbtInitData, 7);
00312       szInit = 8;
00313       break;
00314 
00315     case 10:
00316       abtInit[0] = 0x88;
00317       memcpy (abtInit + 1, pbtInitData, 3);
00318       abtInit[4] = 0x88;
00319       memcpy (abtInit + 5, pbtInitData + 3, 7);
00320       szInit = 12;
00321       break;
00322 
00323     case 4:
00324     default:
00325       memcpy (abtInit, pbtInitData, szInitData);
00326       szInit = szInitData;
00327       break;
00328     }
00329     break;
00330 
00331   default:
00332     memcpy (abtInit, pbtInitData, szInitData);
00333     szInit = szInitData;
00334     break;
00335   }
00336 
00337   return pn53x_initiator_select_passive_target (pnd, nm, abtInit, szInit, pnt);
00338 }
00339 
00357 bool
00358 nfc_initiator_list_passive_targets (nfc_device_t * pnd,
00359                                     const nfc_modulation_t nm,
00360                                     nfc_target_t ant[], const size_t szTargets, size_t * pszTargetFound)
00361 {
00362   nfc_target_t nt;
00363   size_t  szTargetFound = 0;
00364   byte_t *pbtInitData = NULL;
00365   size_t  szInitDataLen = 0;
00366 
00367   pnd->iLastError = 0;
00368 
00369   // Drop the field for a while
00370   if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
00371     return false;
00372   }
00373   // Let the reader only try once to find a tag
00374   if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
00375     return false;
00376   }
00377   // Enable field so more power consuming cards can power themselves up
00378   if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
00379     return false;
00380   }
00381 
00382   switch (nm.nmt) {
00383     case NMT_ISO14443B: {
00384       // Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3)
00385       pbtInitData = (byte_t *) "\x00";
00386       szInitDataLen = 1;
00387     }
00388     break;
00389     case NMT_FELICA: {
00390       // polling payload must be present (see ISO/IEC 18092 11.2.2.5)
00391       pbtInitData = (byte_t *) "\x00\xff\xff\x01\x00";
00392       szInitDataLen = 5;
00393     }
00394     break;
00395     default:
00396       // nothing to do
00397     break;
00398   }
00399 
00400   while (nfc_initiator_select_passive_target (pnd, nm, pbtInitData, szInitDataLen, &nt)) {
00401     nfc_initiator_deselect_target (pnd);
00402 
00403     if (szTargets > szTargetFound) {
00404       memcpy (&(ant[szTargetFound]), &nt, sizeof (nfc_target_t));
00405     } else {
00406       break;
00407     }
00408     szTargetFound++;
00409     // deselect has no effect on FeliCa and Jewel cards so we'll stop after one...
00410     if ((nm.nmt == NMT_FELICA) || (nm.nmt == NMT_JEWEL)) {
00411         break;
00412     }
00413   }
00414   *pszTargetFound = szTargetFound;
00415 
00416   return true;
00417 }
00418 
00432 bool
00433 nfc_initiator_poll_targets (nfc_device_t * pnd,
00434                             const nfc_modulation_t * pnmModulations, const size_t szModulations,
00435                             const byte_t btPollNr, const byte_t btPeriod,
00436                             nfc_target_t * pntTargets, size_t * pszTargetFound)
00437 {
00438   pnd->iLastError = 0;
00439 
00440   return pn53x_initiator_poll_targets (pnd, pnmModulations, szModulations, btPollNr, btPeriod, pntTargets, pszTargetFound);
00441 }
00442 
00443 
00459 bool
00460 nfc_initiator_select_dep_target (nfc_device_t * pnd, 
00461                                  const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr,
00462                                  const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt)
00463 {
00464   pnd->iLastError = 0;
00465 
00466   return pn53x_initiator_select_dep_target (pnd, ndm, nbr, pndiInitiator, pnt);
00467 }
00468 
00481 bool
00482 nfc_initiator_deselect_target (nfc_device_t * pnd)
00483 {
00484   pnd->iLastError = 0;
00485 
00486   return (pn53x_InDeselect (pnd, 0));   // 0 mean deselect all selected targets
00487 }
00488 
00505 bool
00506 nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx,
00507                                 size_t * pszRx)
00508 {
00509   pnd->iLastError = 0;
00510 
00511   return pn53x_initiator_transceive_bytes (pnd, pbtTx, szTx, pbtRx, pszRx);
00512 }
00513 
00549 bool
00550 nfc_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar,
00551                                byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
00552 {
00553   pnd->iLastError = 0;
00554 
00555   return pn53x_initiator_transceive_bits (pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pszRxBits, pbtRxPar);
00556 }
00557 
00580 bool
00581 nfc_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx)
00582 {
00583   pnd->iLastError = 0;
00584 
00585   return pn53x_target_init (pnd, pnt, pbtRx, pszRx);
00586 }
00587 
00599 bool
00600 nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx)
00601 {
00602   pnd->iLastError = 0;
00603 
00604   return pn53x_target_send_bytes (pnd, pbtTx, szTx);
00605 }
00606 
00616 bool
00617 nfc_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx)
00618 {
00619   pnd->iLastError = 0;
00620 
00621   return pn53x_target_receive_bytes (pnd, pbtRx, pszRx);
00622 }
00623 
00631 bool
00632 nfc_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar)
00633 {
00634   pnd->iLastError = 0;
00635 
00636   return pn53x_target_send_bits (pnd, pbtTx, szTxBits, pbtTxPar);
00637 }
00638 
00650 bool
00651 nfc_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
00652 {
00653   pnd->iLastError = 0;
00654 
00655   return pn53x_target_receive_bits (pnd, pbtRx, pszRxBits, pbtRxPar);
00656 }
00657 
00662 const char *
00663 nfc_strerror (const nfc_device_t * pnd)
00664 {
00665   return pnd->pdc->pcc->strerror (pnd);
00666 }
00667 
00672 int
00673 nfc_strerror_r (const nfc_device_t * pnd, char *pcStrErrBuf, size_t szBufLen)
00674 {
00675   return (snprintf (pcStrErrBuf, szBufLen, "%s", nfc_strerror (pnd)) < 0) ? -1 : 0;
00676 }
00677 
00681 void
00682 nfc_perror (const nfc_device_t * pnd, const char *pcString)
00683 {
00684   fprintf (stderr, "%s: %s\n", pcString, nfc_strerror (pnd));
00685 }
00686 
00687 /* Special data accessors */
00688 
00693 const char *
00694 nfc_device_name (nfc_device_t * pnd)
00695 {
00696   return pnd->acName;
00697 }
00698 
00699 /* Misc. functions */
00700 
00705 const char *
00706 nfc_version (void)
00707 {
00708 #ifdef SVN_REVISION
00709   return PACKAGE_VERSION " (r" SVN_REVISION ")";
00710 #else
00711   return PACKAGE_VERSION;
00712 #endif // SVN_REVISION
00713 }