diff --git a/examples/nfc-list.c b/examples/nfc-list.c index 4658d95..e8e5171 100644 --- a/examples/nfc-list.c +++ b/examples/nfc-list.c @@ -1,7 +1,7 @@ /*- * Public platform independent Near Field Communication (NFC) library * - * Copyright (C) 2009, Roel Verdult + * Copyright (C) 2009, 2O1O, Roel Verdult, Romuald Conty * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the @@ -44,26 +44,29 @@ #include "nfc-utils.h" #define MAX_DEVICE_COUNT 16 +#define MAX_TARGET_COUNT 16 static nfc_device_t* pnd; static byte_t abtFelica[5] = { 0x00, 0xff, 0xff, 0x00, 0x00 }; int main(int argc, const char* argv[]) { - size_t szFound; + const char* acLibnfcVersion; + size_t szDeviceFound; + size_t szTargetFound; size_t i; nfc_target_info_t nti; - nfc_device_desc_t *pnddDevices = parse_device_desc(argc, argv, &szFound); - const char* acLibnfcVersion; - - if (argc > 1 && szFound == 0) { - errx (1, "usage: %s [--device driver:port:speed]", argv[0]); - } - + // Display libnfc version acLibnfcVersion = nfc_version(); printf("%s use libnfc %s\n", argv[0], acLibnfcVersion); + nfc_device_desc_t *pnddDevices = parse_device_desc(argc, argv, &szDeviceFound); + + if (argc > 1 && szDeviceFound == 0) { + errx (1, "usage: %s [--device driver:port:speed]", argv[0]); + } + #ifdef HAVE_LIBUSB #ifdef DEBUG usb_set_debug(4); @@ -85,7 +88,7 @@ int main(int argc, const char* argv[]) pnd = nfc_connect(&ndd); #endif - if (szFound == 0) + if (szDeviceFound == 0) { if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) { @@ -93,15 +96,15 @@ int main(int argc, const char* argv[]) return EXIT_FAILURE; } - nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound); + nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound); } - if (szFound == 0) + if (szDeviceFound == 0) { INFO("%s", "No device found."); } - for (i = 0; i < szFound; i++) + for (i = 0; i < szDeviceFound; i++) { pnd = nfc_connect(&(pnddDevices[i])); @@ -126,15 +129,18 @@ int main(int argc, const char* argv[]) // Enable field so more power consuming cards can power themselves up nfc_configure(pnd,NDO_ACTIVATE_FIELD,true); - printf("\nConnected to NFC reader: %s\n\n",pnd->acName); + printf("Connected to NFC reader: %s\n",pnd->acName); - // Poll for a ISO14443A (MIFARE) tag - if (nfc_initiator_select_passive_target(pnd,NM_ISO14443A_106,NULL,0,&nti)) - { - printf("The following (NFC) ISO14443A tag was found:\n\n"); - print_nfc_iso14443a_info (nti.nai); + nfc_target_info_t anti[MAX_TARGET_COUNT]; + if (nfc_initiator_list_passive_targets(pnd, NM_ISO14443A_106, anti, MAX_TARGET_COUNT, &szTargetFound )) { + printf("%zu ISO14443A passive targets was found:\n", szTargetFound); + for(size_t n=0; n szTargetFound) { + memcpy( &(anti[szTargetFound]), &nti, sizeof(nfc_target_info_t) ); + } + szTargetFound++; + } + *pszTargetFound = szTargetFound; + + DBG("%zu targets was found%s.", *pszTargetFound, bCollisionDetected?" (with SENS_RES collision)":""); + +/* + // TODO This chunk of code attempt to retrieve SENS_RES (ATQA) for ISO14443A which collide previously. + // XXX Unfortunately at this stage, I'm not able to REQA each tag correctly to retrieve this SENS_REQ. + + + // Drop the field for a while + nfc_configure(pnd,NDO_ACTIVATE_FIELD,false); + // Let the reader only try once to find a tag + nfc_configure(pnd,NDO_INFINITE_SELECT,false); + + // Configure the CRC and Parity settings + nfc_configure(pnd,NDO_HANDLE_CRC,true); + nfc_configure(pnd,NDO_HANDLE_PARITY,true); + + // Enable field so more power consuming cards can power themselves up + nfc_configure(pnd,NDO_ACTIVATE_FIELD,true); + + if(bCollisionDetected && (nmInitModulation == NM_ISO14443A_106)) { + // nfc_initiator_select_passive_target(pnd, NM_ISO14443A_106, anti[0].nai.abtUid, anti[0].nai.szUidLen, NULL); + + for( size_t n = 0; n < szTargetFound; n++ ) { + size_t szTargetsData; + byte_t abtTargetsData[MAX_FRAME_LEN]; + if(!pn53x_InListPassiveTarget(pnd, NM_ISO14443A_106, 2, NULL, 0, abtTargetsData, &szTargetsData)) return false; + DBG("pn53x_InListPassiveTarget(): %d selected target(s)", abtTargetsData[0]); + if(szTargetsData && (abtTargetsData[0] > 0)) { + byte_t* pbtTargetData = abtTargetsData+1; + size_t szTargetData = 5 + *(pbtTargetData + 4); // Tg, SENS_RES (2), SEL_RES, NFCIDLength, NFCID1 (NFCIDLength) + + if( (*(pbtTargetData + 3) & 0x40) && ((~(*(pbtTargetData + 3))) & 0x04) ) { // Check if SAK looks like 0bxx1xx0xx, which means compliant with ISO/IEC 14443-4 (= ATS available) (See ISO14443-3 document) + szTargetData += 1 + *(pbtTargetData + szTargetData); // Add ATS length + } + if(!pn53x_decode_target_data(pbtTargetData, szTargetData, pnd->nc, NTT_GENERIC_PASSIVE_106, &nti)) return false; + #ifdef DEBUG + for(size_t n=0;n