libnfc 1.3.9
|
00001 /*- 00002 * Public platform independent Near Field Communication (NFC) library 00003 * 00004 * Copyright (C) 2009, 2010, Roel Verdult, Romuald Conty 00005 * 00006 * This program is free software: you can redistribute it and/or modify it 00007 * under the terms of the GNU Lesser General Public License as published by the 00008 * Free Software Foundation, either version 3 of the License, or (at your 00009 * option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, but WITHOUT 00012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00014 * more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 00025 #ifdef HAVE_CONFIG_H 00026 # include "config.h" 00027 #endif // HAVE_CONFIG_H 00028 00029 #include <stdio.h> 00030 #include <stdlib.h> 00031 #include <stddef.h> 00032 #include <string.h> 00033 00034 #include <nfc/nfc.h> 00035 00036 #ifdef _WIN32 00037 # include <windows.h> 00038 00039 # define snprintf sprintf_s 00040 #endif 00041 00042 #include "chips.h" 00043 #include "drivers.h" 00044 00045 #include <nfc/nfc-messages.h> 00046 00047 nfc_device_desc_t *nfc_pick_device (void); 00048 00053 nfc_device_desc_t * 00054 nfc_pick_device (void) 00055 { 00056 uint32_t uiDriver; 00057 nfc_device_desc_t *nddRes; 00058 00059 for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) { 00060 if (drivers_callbacks_list[uiDriver].pick_device != NULL) { 00061 nddRes = drivers_callbacks_list[uiDriver].pick_device (); 00062 if (nddRes != NULL) 00063 return nddRes; 00064 } 00065 } 00066 00067 return NULL; 00068 } 00069 00076 void 00077 nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound) 00078 { 00079 uint32_t uiDriver; 00080 size_t szN; 00081 00082 *pszDeviceFound = 0; 00083 00084 for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) { 00085 if (drivers_callbacks_list[uiDriver].list_devices != NULL) { 00086 szN = 0; 00087 if (drivers_callbacks_list[uiDriver]. 00088 list_devices (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN)) { 00089 *pszDeviceFound += szN; 00090 DBG ("%ld device(s) found using %s driver", (unsigned long) szN, drivers_callbacks_list[uiDriver].acDriver); 00091 } 00092 } else { 00093 DBG ("No listing function avaible for %s driver", drivers_callbacks_list[uiDriver].acDriver); 00094 } 00095 } 00096 } 00097 00111 nfc_device_t * 00112 nfc_connect (nfc_device_desc_t * pndd) 00113 { 00114 nfc_device_t *pnd = NULL; 00115 uint32_t uiDriver; 00116 00117 // Search through the device list for an available device 00118 for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) { 00119 if (pndd == NULL) { 00120 // No device description specified: try to automatically claim a device 00121 if (drivers_callbacks_list[uiDriver].pick_device != NULL) { 00122 DBG ("Autodetecting available devices using %s driver.", drivers_callbacks_list[uiDriver].acDriver); 00123 pndd = drivers_callbacks_list[uiDriver].pick_device (); 00124 00125 if (pndd != NULL) { 00126 DBG ("Auto-connecting to %s using %s driver", pndd->acDevice, drivers_callbacks_list[uiDriver].acDriver); 00127 pnd = drivers_callbacks_list[uiDriver].connect (pndd); 00128 if (pnd == NULL) { 00129 DBG ("No device available using %s driver", drivers_callbacks_list[uiDriver].acDriver); 00130 pndd = NULL; 00131 } 00132 00133 free (pndd); 00134 } 00135 } 00136 } else { 00137 // Specific device is requested: using device description pndd 00138 if (0 != strcmp (drivers_callbacks_list[uiDriver].acDriver, pndd->pcDriver)) { 00139 continue; 00140 } else { 00141 pnd = drivers_callbacks_list[uiDriver].connect (pndd); 00142 } 00143 } 00144 00145 // Test if the connection was successful 00146 if (pnd != NULL) { 00147 DBG ("[%s] has been claimed.", pnd->acName); 00148 // Great we have claimed a device 00149 pnd->pdc = &(drivers_callbacks_list[uiDriver]); 00150 00151 if (!pn53x_get_firmware_version (pnd)) 00152 return NULL; 00153 00154 // Reset the ending transmission bits register, it is unknown what the last tranmission used there 00155 if (!pn53x_set_reg (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, 0x00)) 00156 return NULL; 00157 00158 // Set default configuration options 00159 // Make sure we reset the CRC and parity to chip handling. 00160 if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) 00161 return NULL; 00162 if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) 00163 return NULL; 00164 00165 // Deactivate the CRYPTO1 chiper, it may could cause problems when still active 00166 if (!nfc_configure (pnd, NDO_ACTIVATE_CRYPTO1, false)) 00167 return NULL; 00168 00169 // Activate "easy framing" feature by default 00170 if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) 00171 return NULL; 00172 00173 // Activate auto ISO14443-4 switching by default 00174 if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true)) 00175 return NULL; 00176 00177 // Disallow invalid frame 00178 if (!nfc_configure (pnd, NDO_ACCEPT_INVALID_FRAMES, false)) 00179 return NULL; 00180 00181 // Disallow multiple frames 00182 if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false)) 00183 return NULL; 00184 00185 return pnd; 00186 } else { 00187 DBG ("No device found using driver: %s", drivers_callbacks_list[uiDriver].acDriver); 00188 } 00189 } 00190 // Too bad, no reader is ready to be claimed 00191 return NULL; 00192 } 00193 00200 void 00201 nfc_disconnect (nfc_device_t * pnd) 00202 { 00203 if (pnd) { 00204 // Release and deselect all active communications 00205 nfc_initiator_deselect_target (pnd); 00206 // Disable RF field to avoid heating 00207 nfc_configure (pnd, NDO_ACTIVATE_FIELD, false); 00208 // Disconnect, clean up and release the device 00209 pnd->pdc->disconnect (pnd); 00210 } 00211 } 00212 00224 bool 00225 nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable) 00226 { 00227 pnd->iLastError = 0; 00228 00229 return pn53x_configure (pnd, ndo, bEnable); 00230 } 00231 00232 00242 bool 00243 nfc_initiator_init (nfc_device_t * pnd) 00244 { 00245 pnd->iLastError = 0; 00246 00247 // Make sure we are dealing with a active device 00248 if (!pnd->bActive) 00249 return false; 00250 00251 // Set the PN53X to force 100% ASK Modified miller decoding (default for 14443A cards) 00252 if (!pn53x_set_reg (pnd, REG_CIU_TX_AUTO, SYMBOL_FORCE_100_ASK, 0x40)) 00253 return false; 00254 00255 // Configure the PN53X to be an Initiator or Reader/Writer 00256 if (!pn53x_set_reg (pnd, REG_CIU_CONTROL, SYMBOL_INITIATOR, 0x10)) 00257 return false; 00258 00259 return true; 00260 } 00261 00278 bool 00279 nfc_initiator_select_dep_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, const byte_t * pbtPidData, 00280 const size_t szPidDataLen, const byte_t * pbtNFCID3i, const size_t szNFCID3iDataLen, 00281 const byte_t * pbtGbData, const size_t szGbDataLen, nfc_target_info_t * pnti) 00282 { 00283 pnd->iLastError = 0; 00284 00285 return pn53x_initiator_select_dep_target (pnd, nmInitModulation, pbtPidData, szPidDataLen, pbtNFCID3i, 00286 szNFCID3iDataLen, pbtGbData, szGbDataLen, pnti); 00287 } 00288 00303 bool 00304 nfc_initiator_select_passive_target (nfc_device_t * pnd, 00305 const nfc_modulation_t nmInitModulation, 00306 const byte_t * pbtInitData, const size_t szInitDataLen, nfc_target_info_t * pnti) 00307 { 00308 byte_t abtInit[MAX_FRAME_LEN]; 00309 size_t szInitLen; 00310 00311 size_t szTargetsData; 00312 byte_t abtTargetsData[MAX_FRAME_LEN]; 00313 00314 pnd->iLastError = 0; 00315 00316 // Make sure we are dealing with a active device 00317 if (!pnd->bActive) 00318 return false; 00319 // TODO Put this in a function 00320 switch (nmInitModulation) { 00321 case NM_ISO14443A_106: 00322 switch (szInitDataLen) { 00323 case 7: 00324 abtInit[0] = 0x88; 00325 memcpy (abtInit + 1, pbtInitData, 7); 00326 szInitLen = 8; 00327 break; 00328 00329 case 10: 00330 abtInit[0] = 0x88; 00331 memcpy (abtInit + 1, pbtInitData, 3); 00332 abtInit[4] = 0x88; 00333 memcpy (abtInit + 5, pbtInitData + 3, 7); 00334 szInitLen = 12; 00335 break; 00336 00337 case 4: 00338 default: 00339 memcpy (abtInit, pbtInitData, szInitDataLen); 00340 szInitLen = szInitDataLen; 00341 break; 00342 } 00343 break; 00344 00345 default: 00346 memcpy (abtInit, pbtInitData, szInitDataLen); 00347 szInitLen = szInitDataLen; 00348 break; 00349 } 00350 00351 if (!pn53x_InListPassiveTarget (pnd, nmInitModulation, 1, abtInit, szInitLen, abtTargetsData, &szTargetsData)) 00352 return false; 00353 00354 // Make sure one tag has been found, the PN53X returns 0x00 if none was available 00355 if (abtTargetsData[0] == 0) 00356 return false; 00357 00358 // Is a tag info struct available 00359 if (pnti) { 00360 // Fill the tag info struct with the values corresponding to this init modulation 00361 switch (nmInitModulation) { 00362 case NM_ISO14443A_106: 00363 if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) { 00364 return false; 00365 } 00366 break; 00367 00368 case NM_FELICA_212: 00369 if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_FELICA_212, pnti)) { 00370 return false; 00371 } 00372 break; 00373 case NM_FELICA_424: 00374 if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_FELICA_424, pnti)) { 00375 return false; 00376 } 00377 break; 00378 00379 case NM_ISO14443B_106: 00380 if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_ISO14443B_106, pnti)) { 00381 return false; 00382 } 00383 break; 00384 00385 case NM_JEWEL_106: 00386 if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_JEWEL_106, pnti)) { 00387 return false; 00388 } 00389 break; 00390 00391 default: 00392 // Should not be possible, so whatever... 00393 break; 00394 } 00395 } 00396 return true; 00397 } 00398 00399 bool 00400 nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, 00401 nfc_target_info_t anti[], const size_t szTargets, size_t * pszTargetFound) 00402 { 00403 nfc_target_info_t nti; 00404 size_t szTargetFound = 0; 00405 byte_t *pbtInitData = NULL; 00406 size_t szInitDataLen = 0; 00407 00408 pnd->iLastError = 0; 00409 00410 // Let the reader only try once to find a target 00411 nfc_configure (pnd, NDO_INFINITE_SELECT, false); 00412 00413 if (nmInitModulation == NM_ISO14443B_106) { 00414 // Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3) 00415 pbtInitData = (byte_t *) "\x00"; 00416 szInitDataLen = 1; 00417 } 00418 while (nfc_initiator_select_passive_target (pnd, nmInitModulation, pbtInitData, szInitDataLen, &nti)) { 00419 nfc_initiator_deselect_target (pnd); 00420 00421 if (szTargets > szTargetFound) { 00422 memcpy (&(anti[szTargetFound]), &nti, sizeof (nfc_target_info_t)); 00423 } 00424 szTargetFound++; 00425 } 00426 *pszTargetFound = szTargetFound; 00427 00428 return true; 00429 } 00430 00438 bool 00439 nfc_initiator_deselect_target (nfc_device_t * pnd) 00440 { 00441 pnd->iLastError = 0; 00442 00443 return (pn53x_InDeselect (pnd, 0)); // 0 mean deselect all selected targets 00444 } 00445 00457 bool 00458 nfc_initiator_poll_targets (nfc_device_t * pnd, 00459 const nfc_target_type_t * pnttTargetTypes, const size_t szTargetTypes, 00460 const byte_t btPollNr, const byte_t btPeriod, 00461 nfc_target_t * pntTargets, size_t * pszTargetFound) 00462 { 00463 pnd->iLastError = 0; 00464 00465 return pn53x_InAutoPoll (pnd, pnttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound); 00466 } 00467 00480 bool 00481 nfc_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, 00482 byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar) 00483 { 00484 pnd->iLastError = 0; 00485 00486 return pn53x_initiator_transceive_bits (pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pszRxBits, pbtRxPar); 00487 } 00488 00502 bool 00503 nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx, 00504 size_t * pszRxLen) 00505 { 00506 pnd->iLastError = 0; 00507 00508 return pn53x_initiator_transceive_bytes (pnd, pbtTx, szTxLen, pbtRx, pszRxLen); 00509 } 00510 00519 bool 00520 nfc_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits) 00521 { 00522 pnd->iLastError = 0; 00523 00524 return pn53x_target_init (pnd, pbtRx, pszRxBits); 00525 } 00526 00533 bool 00534 nfc_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar) 00535 { 00536 pnd->iLastError = 0; 00537 00538 return pn53x_target_receive_bits (pnd, pbtRx, pszRxBits, pbtRxPar); 00539 } 00540 00547 bool 00548 nfc_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxLen) 00549 { 00550 pnd->iLastError = 0; 00551 00552 return pn53x_target_receive_bytes (pnd, pbtRx, pszRxLen); 00553 } 00554 00561 bool 00562 nfc_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar) 00563 { 00564 pnd->iLastError = 0; 00565 00566 return pn53x_target_send_bits (pnd, pbtTx, szTxBits, pbtTxPar); 00567 } 00568 00569 00576 bool 00577 nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen) 00578 { 00579 pnd->iLastError = 0; 00580 00581 return pn53x_target_send_bytes (pnd, pbtTx, szTxLen); 00582 } 00583 00588 const char * 00589 nfc_strerror (const nfc_device_t * pnd) 00590 { 00591 return pnd->pdc->pcc->strerror (pnd); 00592 } 00593 00598 int 00599 nfc_strerror_r (const nfc_device_t * pnd, char *pcStrErrBuf, size_t szBufLen) 00600 { 00601 return (snprintf (pcStrErrBuf, szBufLen, "%s", nfc_strerror (pnd)) < 0) ? -1 : 0; 00602 } 00603 00607 void 00608 nfc_perror (const nfc_device_t * pnd, const char *pcString) 00609 { 00610 fprintf (stderr, "%s: %s\n", pcString, nfc_strerror (pnd)); 00611 } 00612 00613 /* Special data accessors */ 00614 00619 const char * 00620 nfc_device_name (nfc_device_t * pnd) 00621 { 00622 return pnd->acName; 00623 } 00624 00625 /* Misc. functions */ 00626 00631 const char * 00632 nfc_version (void) 00633 { 00634 #ifdef SVN_REVISION 00635 return PACKAGE_VERSION " (r" SVN_REVISION ")"; 00636 #else 00637 return PACKAGE_VERSION; 00638 #endif // SVN_REVISION 00639 }