Attempt to provide target listing function (WARNING: this function is actually incomplete)
New issue Summary: Provide a target listing function Labels: Milestone-1.4.x Libnfc lacks of target listing function. Actually, applications or libraries based on libnfc have to wrote their own listing function which can provide side effect if two or more of theses libraries are used together in the same application. Plus, some kind of problem could appears during listing multiples targets (i.e. collisions) and this problem should be solved in libnfc (i.e. using NFC chip capabilities), not in applications based on libnfc.
This commit is contained in:
parent
7113d1418b
commit
0afaf656fa
3 changed files with 103 additions and 21 deletions
|
@ -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; n++) {
|
||||
print_nfc_iso14443a_info (anti[n].nai);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("-------------------\n");
|
||||
|
||||
// Poll for a Felica tag
|
||||
if (nfc_initiator_select_passive_target(pnd,NM_FELICA_212,abtFelica,5,&nti) || nfc_initiator_select_passive_target(pnd,NM_FELICA_424,abtFelica,5,&nti))
|
||||
{
|
||||
|
|
|
@ -62,9 +62,10 @@ NFC_EXPORT bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo,
|
|||
/* NFC initiator: act as "reader" */
|
||||
NFC_EXPORT bool nfc_initiator_init(const nfc_device_t* pnd);
|
||||
NFC_EXPORT bool nfc_initiator_select_passive_target(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtInitData, const size_t szInitDataLen, nfc_target_info_t* pti);
|
||||
NFC_EXPORT bool nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, nfc_target_info_t anti[], const size_t szTargets, size_t *pszTargetFound );
|
||||
NFC_EXPORT bool nfc_initiator_poll_targets(const nfc_device_t* pnd, const nfc_target_type_t* pnttTargetTypes, const size_t szTargetTypes, const byte_t btPollNr, const byte_t btPeriod, nfc_target_t* pntTargets, size_t* pszTargetFound);
|
||||
NFC_EXPORT bool nfc_initiator_select_dep_target(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtPidData, const size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, nfc_target_info_t* pti);
|
||||
NFC_EXPORT bool nfc_initiator_deselect_target(const nfc_device_t* pnd);
|
||||
NFC_EXPORT bool nfc_initiator_poll_targets(const nfc_device_t* pnd, const nfc_target_type_t* pnttTargetTypes, const size_t szTargetTypes, const byte_t btPollNr, const byte_t btPeriod, nfc_target_t* pntTargets, size_t* pszTargetFound);
|
||||
NFC_EXPORT bool nfc_initiator_transceive_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
||||
NFC_EXPORT bool nfc_initiator_transceive_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
NFC_EXPORT bool nfc_initiator_transceive_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
|
75
libnfc/nfc.c
75
libnfc/nfc.c
|
@ -537,6 +537,81 @@ nfc_initiator_select_passive_target(const nfc_device_t* pnd,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, nfc_target_info_t anti[], const size_t szTargets, size_t *pszTargetFound )
|
||||
{
|
||||
// Let the reader only try once to find a target
|
||||
nfc_configure (pnd, NDO_INFINITE_SELECT, false);
|
||||
|
||||
nfc_target_info_t nti;
|
||||
|
||||
bool bCollisionDetected = false;
|
||||
size_t szTargetFound = 0;
|
||||
|
||||
|
||||
while (nfc_initiator_select_passive_target (pnd, nmInitModulation, NULL, 0, &nti)) {
|
||||
nfc_initiator_deselect_target(pnd);
|
||||
|
||||
if(nmInitModulation == NM_ISO14443A_106) {
|
||||
if((nti.nai.abtAtqa[0] == 0x00) && (nti.nai.abtAtqa[1] == 0x00)) {
|
||||
bCollisionDetected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(szTargets > 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<sizeof(nti.nai);n++) printf("%02x ", *(((byte_t*)(&nti.nai)) + n));
|
||||
printf("\n");
|
||||
#endif // DEBUG
|
||||
pn53x_InDeselect(pnd, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn nfc_initiator_deselect_target(const nfc_device_t* pnd);
|
||||
* @brief Deselect a selected passive or emulated tag
|
||||
|
|
Loading…
Reference in a new issue