libnfc 1.4.2
|
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 }