Merge r478-485 from trunk.
This commit is contained in:
commit
36ee32f81a
8 changed files with 152 additions and 58 deletions
examples
include/nfc
libnfc
|
@ -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(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(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(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(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(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
|
|
@ -272,6 +272,20 @@ pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_chip_t
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief C wrapper to InListPassiveTarget command
|
||||
* @return true if command is successfully sent
|
||||
*
|
||||
* @param pnd nfc_device_t struct pointer that represent currently used device
|
||||
* @param nmInitModulation Desired modulation
|
||||
* @param pbtInitiatorData Optional initiator data used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID
|
||||
* @param szInitiatorDataLen Length of initiator data \a pbtInitiatorData
|
||||
* @param pbtTargetsData pointer on a pre-allocated byte array to receive TargetData[n] as described in pn53x user manual
|
||||
* @param pszTargetsData size_t pointer where size of \a pbtTargetsData will be written
|
||||
*
|
||||
* @note Selected targets count can be found in \a pbtTargetsData[0] if available (i.e. \a pszTargetsData content is more than 0)
|
||||
* @note To decode theses TargetData[n], there is @fn pn53x_decode_target_data
|
||||
*/
|
||||
bool
|
||||
pn53x_InListPassiveTarget(const nfc_device_t* pnd,
|
||||
const nfc_modulation_t nmInitModulation, const byte_t szMaxTargets,
|
||||
|
@ -281,6 +295,7 @@ pn53x_InListPassiveTarget(const nfc_device_t* pnd,
|
|||
byte_t abtCmd[sizeof(pncmd_initiator_list_passive)];
|
||||
memcpy(abtCmd,pncmd_initiator_list_passive,sizeof(pncmd_initiator_list_passive));
|
||||
|
||||
// FIXME PN531 doesn't support all available modulations
|
||||
abtCmd[2] = szMaxTargets; // MaxTg
|
||||
abtCmd[3] = nmInitModulation; // BrTy, the type of init modulation used for polling a passive tag
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
/**
|
||||
* @file acr122.c
|
||||
* @brief
|
||||
* @brief Driver for ACR122 devices (e.g. Tikitag, Touchatag, ACS ACR122)
|
||||
*/
|
||||
|
||||
#ifdef DRIVER_ACR122_ENABLED
|
||||
|
@ -160,12 +160,12 @@ acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
|||
// Retrieve the string array of all available pcsc readers
|
||||
if (SCardListReaders(*pscc,NULL,acDeviceNames,(void*)&szDeviceNamesLen) != SCARD_S_SUCCESS) return false;
|
||||
|
||||
DBG("%s", "PCSC reports following device(s):");
|
||||
// DBG("%s", "PCSC reports following device(s):");
|
||||
|
||||
while ((acDeviceNames[szPos] != '\0') && ((*pszDeviceFound) < szDevices)) {
|
||||
uiBusIndex++;
|
||||
|
||||
DBG("- %s (pos=%ld)", acDeviceNames + szPos, (unsigned long) szPos);
|
||||
// DBG("- %s (pos=%ld)", acDeviceNames + szPos, (unsigned long) szPos);
|
||||
|
||||
bSupported = false;
|
||||
for (i = 0; supported_devices[i] && !bSupported; i++) {
|
||||
|
@ -206,7 +206,7 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
|||
|
||||
SCARDCONTEXT *pscc;
|
||||
|
||||
DBG("Connecting to %s",pndd->acDevice);
|
||||
DBG("Attempt to connect to %s",pndd->acDevice);
|
||||
// We no longer support connecting with a NULL
|
||||
if(pndd == NULL) return NULL;
|
||||
// Test if context succeeded
|
||||
|
|
|
@ -182,7 +182,7 @@ nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd)
|
|||
DBG("%s", "arygon_connect() need an nfc_device_desc_t struct.");
|
||||
return NULL;
|
||||
} else {
|
||||
DBG("Connecting to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
DBG("Attempt to connect to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
sp = uart_open(pndd->pcPort);
|
||||
|
||||
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",pndd->pcPort);
|
||||
|
|
|
@ -161,7 +161,7 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
DBG("%s", "pn532_uart_connect() need an nfc_device_desc_t struct.");
|
||||
return NULL;
|
||||
} else {
|
||||
DBG("Connecting to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
DBG("Attempt to connect to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
sp = uart_open(pndd->pcPort);
|
||||
|
||||
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",pndd->pcPort);
|
||||
|
|
|
@ -63,14 +63,12 @@ void get_end_points(struct usb_device *dev, usb_spec_t* pus)
|
|||
// Test if we dealing with a bulk IN endpoint
|
||||
if((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
|
||||
{
|
||||
DBG("Bulk endpoint in : 0x%02X", uiEndPoint);
|
||||
pus->uiEndPointIn = uiEndPoint;
|
||||
}
|
||||
|
||||
// Test if we dealing with a bulk OUT endpoint
|
||||
if((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
|
||||
{
|
||||
DBG("Bulk endpoint in : 0x%02X", uiEndPoint);
|
||||
pus->uiEndPointOut = uiEndPoint;
|
||||
}
|
||||
}
|
||||
|
@ -89,12 +87,12 @@ bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, s
|
|||
string[0]= '\0';
|
||||
usb_init();
|
||||
|
||||
// usb_find_busses will find all of the busses on the system. Returns the number of changes since previous call to this function (total of new busses and busses removed).
|
||||
if ((ret= usb_find_busses() < 0)) return false;
|
||||
DBG("%d busses",ret);
|
||||
// usb_find_devices will find all of the devices on each bus. This should be called after usb_find_busses. Returns the number of changes since the previous call to this function (total of new device and devices removed).
|
||||
if ((ret= usb_find_devices() < 0)) return false;
|
||||
DBG("%d devices",ret);
|
||||
|
||||
*pszDeviceFound= 0;
|
||||
*pszDeviceFound = 0;
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
{
|
||||
|
@ -102,7 +100,7 @@ bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, s
|
|||
{
|
||||
for(i = 0; i < num_candidates; ++i)
|
||||
{
|
||||
DBG("Checking device %04x:%04x (%04x:%04x)",dev->descriptor.idVendor,dev->descriptor.idProduct,candidates[i].idVendor,candidates[i].idProduct);
|
||||
// DBG("Checking device %04x:%04x (%04x:%04x)",dev->descriptor.idVendor,dev->descriptor.idProduct,candidates[i].idVendor,candidates[i].idProduct);
|
||||
if (candidates[i].idVendor==dev->descriptor.idVendor && candidates[i].idProduct==dev->descriptor.idProduct)
|
||||
{
|
||||
// Make sure there are 2 endpoints available
|
||||
|
@ -136,18 +134,15 @@ bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, s
|
|||
pnddDevices[*pszDeviceFound].pcDriver = target_name;
|
||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
||||
(*pszDeviceFound)++;
|
||||
DBG("%s","Match!");
|
||||
// Test if we reach the maximum "wanted" devices
|
||||
if((*pszDeviceFound) == szDevices)
|
||||
{
|
||||
DBG("Found %ld devices", (unsigned long) *pszDeviceFound);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DBG("Found %ld devices", (unsigned long) *pszDeviceFound);
|
||||
if(*pszDeviceFound)
|
||||
return true;
|
||||
return false;
|
||||
|
@ -166,25 +161,21 @@ nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd,const char * targe
|
|||
us.uiEndPointOut = 0;
|
||||
us.pudh = NULL;
|
||||
|
||||
|
||||
// must specify device to connect to
|
||||
if(pndd == NULL) return NULL;
|
||||
|
||||
DBG("Connecting %s device",target_name);
|
||||
DBG("Attempt to connect to %s device", target_name);
|
||||
usb_init();
|
||||
|
||||
uiBusIndex= pndd->uiBusIndex;
|
||||
|
||||
DBG("Skipping to device no. %d",uiBusIndex);
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
{
|
||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex--)
|
||||
{
|
||||
DBG("Checking device %04x:%04x",dev->descriptor.idVendor,dev->descriptor.idProduct);
|
||||
// DBG("Checking device %04x:%04x",dev->descriptor.idVendor,dev->descriptor.idProduct);
|
||||
if(uiBusIndex == 0)
|
||||
{
|
||||
DBG("Found device index %d", pndd->uiBusIndex);
|
||||
|
||||
// Open the USB device
|
||||
us.pudh = usb_open(dev);
|
||||
|
||||
|
@ -229,15 +220,19 @@ void pn53x_usb_disconnect(nfc_device_t* pnd)
|
|||
usb_spec_t* pus = (usb_spec_t*)pnd->nds;
|
||||
int ret;
|
||||
|
||||
if((ret = usb_release_interface(pus->pudh,0)) < 0)
|
||||
if((ret = usb_release_interface(pus->pudh,0)) < 0) {
|
||||
DBG("usb_release failed %i",ret);
|
||||
DBG("%s","resetting USB");
|
||||
if((ret = usb_close(pus->pudh)) < 0)
|
||||
}
|
||||
|
||||
if((ret = usb_close(pus->pudh)) < 0) {
|
||||
DBG("usb_close failed %i",ret);
|
||||
}
|
||||
|
||||
DBG("%s","resetting USB");
|
||||
usb_reset(pus->pudh);
|
||||
|
||||
free(pnd->nds);
|
||||
free(pnd);
|
||||
DBG("%s","done!");
|
||||
}
|
||||
|
||||
bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
|
@ -265,7 +260,6 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
// End of stream marker
|
||||
abtTx[szTxLen+6] = 0;
|
||||
|
||||
DBG("%s","pn53x_usb_transceive");
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", abtTx,szTxLen+7);
|
||||
#endif
|
||||
|
@ -317,7 +311,7 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
|
||||
// Get register: nuke extra byte (awful hack)
|
||||
if ((abtRx[5]==0xd5) && (abtRx[6]==0x07) && (*pszRxLen==2)) {
|
||||
// printf("Got %02x %02x, keep %02x\n", abtRx[7], abtRx[8], abtRx[8]);
|
||||
// DBG("awful hack: abtRx[7]=%02x, abtRx[8]=%02x, we only keep abtRx[8]=%02x", abtRx[7], abtRx[8], abtRx[8]);
|
||||
*pszRxLen = (*pszRxLen) - 1;
|
||||
memcpy( pbtRx, abtRx + 8, *pszRxLen);
|
||||
return true;
|
||||
|
|
98
libnfc/nfc.c
98
libnfc/nfc.c
|
@ -109,7 +109,6 @@ nfc_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszD
|
|||
{
|
||||
if (drivers_callbacks_list[uiDriver].list_devices != NULL)
|
||||
{
|
||||
DBG("List avaible device using %s driver",drivers_callbacks_list[uiDriver].acDriver);
|
||||
szN = 0;
|
||||
if (drivers_callbacks_list[uiDriver].list_devices (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN))
|
||||
{
|
||||
|
@ -168,10 +167,8 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
|||
// Specific device is requested: using device description pndd
|
||||
if( 0 != strcmp(drivers_callbacks_list[uiDriver].acDriver, pndd->pcDriver ) )
|
||||
{
|
||||
DBG("Looking for %s, found %s... Skip it.", pndd->pcDriver, drivers_callbacks_list[uiDriver].acDriver);
|
||||
continue;
|
||||
} else {
|
||||
DBG("Looking for %s, found %s... Use it.", pndd->pcDriver, drivers_callbacks_list[uiDriver].acDriver);
|
||||
pnd = drivers_callbacks_list[uiDriver].connect(pndd);
|
||||
}
|
||||
}
|
||||
|
@ -540,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
|
||||
|
@ -609,12 +681,12 @@ nfc_initiator_poll_targets(const nfc_device_t* pnd,
|
|||
pbt += ln;
|
||||
|
||||
if(abtRx[0] > 1) {
|
||||
/* 2nd target */
|
||||
// Target type
|
||||
pntTargets[1].ntt = *(pbt++);
|
||||
// AutoPollTargetData length
|
||||
ln = *(pbt++);
|
||||
pn53x_decode_target_data(pbt, ln, pnd->nc, pntTargets[1].ntt, &(pntTargets[1].nti));
|
||||
/* 2nd target */
|
||||
// Target type
|
||||
pntTargets[1].ntt = *(pbt++);
|
||||
// AutoPollTargetData length
|
||||
ln = *(pbt++);
|
||||
pn53x_decode_target_data(pbt, ln, pnd->nc, pntTargets[1].ntt, &(pntTargets[1].nti));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -733,7 +805,13 @@ bool nfc_initiator_transceive_dep_bytes(nfc_device_t* pnd, const byte_t* pbtTx,
|
|||
* @brief Transceive byte and APDU frames
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
* The reader will transmit the supplied bytes in pbtTx to the target (tag). It waits for the response and stores the received bytes in the pbtRx byte array. The parity bits are handled by the PN53X chip. The CRC can be generated automatically or handled manually. Using this function, frames can be communicated very fast via the NFC reader to the tag. Tests show that on average this way of communicating is much faster than using the regular driver/middle-ware (often supplied by manufacturers).
|
||||
* The reader will transmit the supplied bytes in pbtTx to the target (tag).
|
||||
* It waits for the response and stores the received bytes in the pbtRx byte array.
|
||||
* The parity bits are handled by the PN53X chip. The CRC can be generated automatically or handled manually.
|
||||
* Using this function, frames can be communicated very fast via the NFC reader to the tag.
|
||||
*
|
||||
* Tests show that on average this way of communicating is much faster than using the regular driver/middle-ware (often supplied by manufacturers).
|
||||
*
|
||||
* @warning The configuration option NDO_HANDLE_PARITY must be set to true (the default value).
|
||||
*/
|
||||
bool nfc_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
|
|
Loading…
Add table
Reference in a new issue