Merge r478-485 from trunk.

This commit is contained in:
Romain Tartiere
2010-07-30 16:34:12 +00:00
8 changed files with 152 additions and 58 deletions

View File

@@ -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)