From fab08a39516b5a9112ea9d75478672eb5b1f8529 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Fri, 13 Aug 2010 19:10:31 +0000 Subject: [PATCH 01/20] Fix doxygen comment: the string SHALL NOT be freed (it's const BTW). Or maybe I would rather have removed the const and called strdup(3)? New issue Summary: Sync code and comments Owner: rconty@il4p.fr Status: New Romuald, can you please review this changeset and fix the code if I corrected the wrong way (i.e. the comment was Okay and the code bogus while I fixed the comment thinking the cod was right). Thanks! --- libnfc/nfc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnfc/nfc.c b/libnfc/nfc.c index f52ed21..0565af3 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -1095,7 +1095,7 @@ bool nfc_target_send_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, con /** * @brief Returns the device name - * @return Returns a string with the device name ( MUST be freed with free() ) + * @return Returns a string with the device name */ const char* nfc_device_name(nfc_device_t* pnd) { From 655fdb569a79023f3cc45cadf0b5fd422458f424 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Fri, 13 Aug 2010 19:53:13 +0000 Subject: [PATCH 02/20] Fix nfc_initiator_mifare_cmd() in examples. In r509, a direct call to pn53x_transceive() was changed into a call to nfc_initiator_transceive_dep_bytes() which is part of the public API. The command to send was updated accordingly, but the code that extracts the response have not. Update issue 98 This should fix the problem: because the response was not the expected length, the actual card data was not copied to the buffer, so it was always the same 16 uninitialized bytes that where returned for any block. PR: Issue 98 Submitted by: zamby.ing Pointy hat to: me --- examples/mifare.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mifare.c b/examples/mifare.c index 0645429..cd8d811 100644 --- a/examples/mifare.c +++ b/examples/mifare.c @@ -69,7 +69,7 @@ bool nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, cons if (!nfc_initiator_transceive_dep_bytes(pnd,abtCmd,2+szParamLen,abtRx,&szRxLen)) return false; // When we have executed a read command, copy the received bytes into the param - if (mc == MC_READ && szRxLen == 17) memcpy(pmp->mpd.abtData,abtRx+1,16); + if (mc == MC_READ && szRxLen == 16) memcpy(pmp->mpd.abtData,abtRx,16); // Command succesfully executed return true; From 8a75f5b45ee05b67e3109dfeed0fb659ab0f489a Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Sun, 15 Aug 2010 12:42:40 +0000 Subject: [PATCH 03/20] Fix wrong comment --- libnfc/nfc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnfc/nfc.c b/libnfc/nfc.c index 0565af3..5c662ea 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -797,7 +797,7 @@ bool nfc_initiator_transceive_dep_bytes(const nfc_device_t* pnd, const byte_t* p if (!pn53x_set_tx_bits(pnd,0)) return false; // Send the frame to the PN53X chip and get the answer - // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42) + // We have to give the amount of bytes + (the two command bytes 0xD4, 0x40) if (!pn53x_transceive(pnd,abtCmd,szTxLen+3,abtRx,&szRxLen)) return false; // Save the received byte count From 41b1455f04c6605d9f79adcfa101d81321e427de Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Mon, 16 Aug 2010 16:27:50 +0000 Subject: [PATCH 04/20] Clean up wrong comments in nfc-poll. --- examples/nfc-poll.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/examples/nfc-poll.c b/examples/nfc-poll.c index 1536610..304816a 100644 --- a/examples/nfc-poll.c +++ b/examples/nfc-poll.c @@ -102,14 +102,9 @@ main (int argc, const char *argv[]) printf ("Connected to NFC reader: %s\n", pnd->acName); -// NOTE we can't use pn53x_transceive() because rx[0] is not status byte (0x00 != status OK) -// bool pn53x_transceive(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen); -// bool res = pn53x_transceive(pnd, abtTx, szTxLen, abtRx, &szRxLen); - -// bool (*transceive)(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen); - if (pnd->nc == NC_PN531) { // PN531 doesn't support hardware polling (InAutoPoll) + // TODO find a way to handle this in higher level (i.e. libnfc) WARN ("%s", "PN531 doesn't support hardware polling."); continue; } From ae044799687dbe430e16873e1a272bd2d524e10c Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Tue, 17 Aug 2010 08:24:38 +0000 Subject: [PATCH 05/20] Move hardware polling function in pn53x.c/h. --- libnfc/chips/pn53x.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ libnfc/chips/pn53x.h | 1 + libnfc/nfc.c | 55 +++-------------------------------------- 3 files changed, 64 insertions(+), 51 deletions(-) diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 373adec..8ea1352 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -28,6 +28,7 @@ #include #include +#include #include "pn53x.h" #include "../mirror-subr.h" @@ -336,3 +337,61 @@ pn53x_InRelease(nfc_device_t* pnd, const uint8_t ui8Target) return(pn53x_transceive(pnd,abtCmd,sizeof(abtCmd),NULL,NULL)); } + +bool +pn53x_InAutoPoll(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) +{ + size_t szTxInAutoPoll, n, szRxLen; + byte_t abtRx[256]; + bool res; + byte_t *pbtTxInAutoPoll; + + if(pnd->nc == NC_PN531) { + // TODO This function is not supported by pn531 (set errno = ENOSUPP or similar) + return false; + } + + // InAutoPoll frame looks like this { 0xd4, 0x60, 0x0f, 0x01, 0x00 } => { direction, command, pollnr, period, types... } + szTxInAutoPoll = 4 + szTargetTypes; + pbtTxInAutoPoll = malloc( szTxInAutoPoll ); + pbtTxInAutoPoll[0] = 0xd4; + pbtTxInAutoPoll[1] = 0x60; + pbtTxInAutoPoll[2] = btPollNr; + pbtTxInAutoPoll[3] = btPeriod; + for(n=0; npdc->transceive(pnd->nds, pbtTxInAutoPoll, szTxInAutoPoll, abtRx, &szRxLen); + + if((szRxLen == 0)||(res == false)) { + return false; + } else { + *pszTargetFound = abtRx[0]; + if( *pszTargetFound ) { + uint8_t ln; + byte_t* pbt = abtRx + 1; + /* 1st target */ + // Target type + pntTargets[0].ntt = *(pbt++); + // AutoPollTargetData length + ln = *(pbt++); + pn53x_decode_target_data(pbt, ln, pnd->nc, pntTargets[0].ntt, &(pntTargets[0].nti)); + 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)); + } + } + } + return true; +} diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h index fbcc784..88130a8 100644 --- a/libnfc/chips/pn53x.h +++ b/libnfc/chips/pn53x.h @@ -81,6 +81,7 @@ bool pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_ch bool pn53x_InListPassiveTarget(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t szMaxTargets, const byte_t* pbtInitiatorData, const size_t szInitiatorDataLen, byte_t* pbtTargetsData, size_t* pszTargetsData); bool pn53x_InDeselect(const nfc_device_t* pnd, const uint8_t ui8Target); bool pn53x_InRelease(nfc_device_t* pnd, const uint8_t ui8Target); +bool pn53x_InAutoPoll(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); #endif // __NFC_CHIPS_PN53X_H__ diff --git a/libnfc/nfc.c b/libnfc/nfc.c index 5c662ea..f8558f1 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -438,7 +438,7 @@ nfc_initiator_select_passive_target(const nfc_device_t* pnd, // Make sure we are dealing with a active device if (!pnd->bActive) return false; - + // TODO Put this in a function switch(nmInitModulation) { case NM_ISO14443A_106: @@ -485,7 +485,8 @@ nfc_initiator_select_passive_target(const nfc_device_t* pnd, { case NM_ISO14443A_106: if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) return false; - + // TODO this should be handled by pn53x_decode_target_data() + // Strip CT (Cascade Tag) to retrieve and store the _real_ UID // (e.g. 0x8801020304050607 is in fact 0x01020304050607) if ((pnti->nai.szUidLen == 8) && (pnti->nai.abtUid[0] == 0x88)) { @@ -651,55 +652,7 @@ nfc_initiator_poll_targets(const nfc_device_t* pnd, const byte_t btPollNr, const byte_t btPeriod, nfc_target_t* pntTargets, size_t* pszTargetFound) { - size_t szTxInAutoPoll, n, szRxLen; - byte_t abtRx[256]; - bool res; - byte_t *pbtTxInAutoPoll; - if(pnd->nc == NC_PN531) { - // errno = ENOSUPP - return false; - } -// byte_t abtInAutoPoll[] = { 0xd4, 0x60, 0x0f, 0x01, 0x00 }; - szTxInAutoPoll = 4 + szTargetTypes; - pbtTxInAutoPoll = malloc( szTxInAutoPoll ); - pbtTxInAutoPoll[0] = 0xd4; - pbtTxInAutoPoll[1] = 0x60; - pbtTxInAutoPoll[2] = btPollNr; - pbtTxInAutoPoll[3] = btPeriod; - for(n=0; npdc->transceive(pnd->nds, pbtTxInAutoPoll, szTxInAutoPoll, abtRx, &szRxLen); - - if((szRxLen == 0)||(res == false)) { - DBG("pnd->pdc->tranceive() failed: szRxLen=%ld, res=%d", (unsigned long) szRxLen, res); - return false; - } else { - *pszTargetFound = abtRx[0]; - if( *pszTargetFound ) { - uint8_t ln; - byte_t* pbt = abtRx + 1; - /* 1st target */ - // Target type - pntTargets[0].ntt = *(pbt++); - // AutoPollTargetData length - ln = *(pbt++); - pn53x_decode_target_data(pbt, ln, pnd->nc, pntTargets[0].ntt, &(pntTargets[0].nti)); - 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)); - } - } - } - return true; + return pn53x_InAutoPoll(pnd, pnttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound); } /** From 3c57861d6b27b9da1d5b7195104d75df6407a255 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Tue, 17 Aug 2010 10:01:11 +0000 Subject: [PATCH 06/20] Improve pn53x_decode_target_data() function: move code from nfc_initiator_select_passive_target() to the right place (pn53x.c). --- libnfc/chips/pn53x.c | 72 +++++++++++++++++++++++++++++++++++++++++++- libnfc/nfc.c | 64 +++++++++++---------------------------- 2 files changed, 89 insertions(+), 47 deletions(-) diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 8ea1352..ef3800a 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -245,8 +245,8 @@ pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_chip_t case NTT_MIFARE: case NTT_GENERIC_PASSIVE_106: // We skip the first byte: its the target number (Tg) - pbtRawData++; + // Somehow they switched the lower and upper ATQA bytes around for the PN531 chipset if (nc == NC_PN531) { pnti->nai.abtAtqa[1] = *(pbtRawData++); @@ -268,6 +268,76 @@ pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_chip_t } else { pnti->nai.szAtsLen = 0; } + + // Strip CT (Cascade Tag) to retrieve and store the _real_ UID + // (e.g. 0x8801020304050607 is in fact 0x01020304050607) + if ((pnti->nai.szUidLen == 8) && (pnti->nai.abtUid[0] == 0x88)) { + pnti->nai.szUidLen = 7; + memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 7); + } else if ((pnti->nai.szUidLen == 12) && (pnti->nai.abtUid[0] == 0x88) && (pnti->nai.abtUid[4] == 0x88)) { + pnti->nai.szUidLen = 10; + memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 3); + memmove (pnti->nai.abtUid + 3, pnti->nai.abtUid + 5, 7); + } + break; + + case NTT_ISO14443B_106: + // We skip the first byte: its the target number (Tg) + pbtRawData++; + + // Store the mandatory info + memcpy(pnti->nbi.abtAtqb, pbtRawData, 12); + pbtRawData += 12; + + // Store temporarily the ATTRIB_RES length + uint8_t ui8AttribResLen = *(pbtRawData++); + + // Store the 4 bytes ID + memcpy(pnti->nbi.abtId, pbtRawData,4); + pbtRawData += 4; + + pnti->nbi.btParam1 = *(pbtRawData++); + pnti->nbi.btParam2 = *(pbtRawData++); + pnti->nbi.btParam3 = *(pbtRawData++); + pnti->nbi.btParam4 = *(pbtRawData++); + + // Test if the Higher layer (INF) is available + if (ui8AttribResLen > 8) { + pnti->nbi.szInfLen = *(pbtRawData++); + memcpy(pnti->nbi.abtInf, pbtRawData, pnti->nbi.szInfLen); + } else { + pnti->nbi.szInfLen = 0; + } + break; + + case NTT_FELICA_212: + case NTT_FELICA_424: + // We skip the first byte: its the target number (Tg) + pbtRawData++; + + // Store the mandatory info + pnti->nfi.szLen = *(pbtRawData++); + pnti->nfi.btResCode = *(pbtRawData++); + // Copy the NFCID2t + memcpy(pnti->nfi.abtId, pbtRawData, 8); + pbtRawData += 8; + // Copy the felica padding + memcpy(pnti->nfi.abtPad, pbtRawData, 8); + pbtRawData += 8; + // Test if the System code (SYST_CODE) is available + if (pnti->nfi.szLen > 18) + { + memcpy(pnti->nfi.abtSysCode, pbtRawData, 2); + } + break; + case NTT_JEWEL_106: + // We skip the first byte: its the target number (Tg) + pbtRawData++; + + // Store the mandatory info + memcpy(pnti->nji.btSensRes, pbtRawData, 2); + pbtRawData += 2; + memcpy(pnti->nji.btId, pbtRawData, 4); break; default: return false; diff --git a/libnfc/nfc.c b/libnfc/nfc.c index f8558f1..c2ad950 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -484,61 +484,33 @@ nfc_initiator_select_passive_target(const nfc_device_t* pnd, switch(nmInitModulation) { case NM_ISO14443A_106: - if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) return false; - // TODO this should be handled by pn53x_decode_target_data() - - // Strip CT (Cascade Tag) to retrieve and store the _real_ UID - // (e.g. 0x8801020304050607 is in fact 0x01020304050607) - if ((pnti->nai.szUidLen == 8) && (pnti->nai.abtUid[0] == 0x88)) { - pnti->nai.szUidLen = 7; - memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 7); - } else if ((pnti->nai.szUidLen == 12) && (pnti->nai.abtUid[0] == 0x88) && (pnti->nai.abtUid[4] == 0x88)) { - pnti->nai.szUidLen = 10; - memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 3); - memmove (pnti->nai.abtUid + 3, pnti->nai.abtUid + 5, 7); - } + if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) { + return false; + } break; case NM_FELICA_212: - case NM_FELICA_424: - // Store the mandatory info - pnti->nfi.szLen = abtTargetsData[2]; - pnti->nfi.btResCode = abtTargetsData[3]; - // Copy the NFCID2t - memcpy(pnti->nfi.abtId,abtTargetsData+4,8); - // Copy the felica padding - memcpy(pnti->nfi.abtPad,abtTargetsData+12,8); - // Test if the System code (SYST_CODE) is available - if (szTargetsData > 20) - { - memcpy(pnti->nfi.abtSysCode,abtTargetsData+20,2); + if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_FELICA_212, pnti)) { + return false; } - break; + break; + case NM_FELICA_424: + if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_FELICA_424, pnti)) { + return false; + } + break; case NM_ISO14443B_106: - // Store the mandatory info - memcpy(pnti->nbi.abtAtqb,abtTargetsData+2,12); - // Ignore the 0x1D byte, and just store the 4 byte id - memcpy(pnti->nbi.abtId,abtTargetsData+15,4); - pnti->nbi.btParam1 = abtTargetsData[19]; - pnti->nbi.btParam2 = abtTargetsData[20]; - pnti->nbi.btParam3 = abtTargetsData[21]; - pnti->nbi.btParam4 = abtTargetsData[22]; - // Test if the Higher layer (INF) is available - if (szTargetsData > 22) - { - pnti->nbi.szInfLen = abtTargetsData[23]; - memcpy(pnti->nbi.abtInf,abtTargetsData+24,pnti->nbi.szInfLen); - } else { - pnti->nbi.szInfLen = 0; + if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_ISO14443B_106, pnti)) { + return false; } - break; + break; case NM_JEWEL_106: - // Store the mandatory info - memcpy(pnti->nji.btSensRes,abtTargetsData+2,2); - memcpy(pnti->nji.btId,abtTargetsData+4,4); - break; + if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_JEWEL_106, pnti)) { + return false; + } + break; default: // Should not be possible, so whatever... From 476c05cfb40e1162f319acd9aafa09a74efb7e3a Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Tue, 17 Aug 2010 10:08:38 +0000 Subject: [PATCH 07/20] Cleanup up nfc_initiator_list_passive_targets(): remove attempts to retrieve ATQA when collision occurs, after a lot of tests by Romain and me we are not able to find a way to retrieve all tags ATQA if different card types are on the nfc device. --- libnfc/nfc.c | 53 ---------------------------------------------------- 1 file changed, 53 deletions(-) diff --git a/libnfc/nfc.c b/libnfc/nfc.c index c2ad950..e06f24c 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -523,8 +523,6 @@ nfc_initiator_select_passive_target(const nfc_device_t* pnd, 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_target_info_t nti; - - bool bCollisionDetected = false; size_t szTargetFound = 0; // Let the reader only try once to find a target @@ -533,12 +531,6 @@ bool nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_ 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) ); } @@ -546,51 +538,6 @@ bool nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_ } *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 Date: Tue, 17 Aug 2010 13:29:01 +0000 Subject: [PATCH 08/20] Default serial-port paths are now fully hardcoded instead of half-hardcoded and soft-expanded. --- libnfc/buses/uart.h | 14 ++++++------ libnfc/drivers/arygon.c | 43 +++++++++++++---------------------- libnfc/drivers/pn532_uart.c | 45 +++++++++++++------------------------ 3 files changed, 38 insertions(+), 64 deletions(-) diff --git a/libnfc/buses/uart.h b/libnfc/buses/uart.h index 8b0ea8a..8ec4978 100644 --- a/libnfc/buses/uart.h +++ b/libnfc/buses/uart.h @@ -59,16 +59,16 @@ // Try to guess what we should use. // // XXX: Some review from users cross-compiling is welcome! -#if defined(_WIN32) - #define SERIAL_STRING "COM" -//#elif defined(__APPLE__) -// TODO: find UART connection string for PN53X device on Mac OS X -// #define SERIAL_STRING "" +#if defined (_WIN32) + #define DEFAULT_SERIAL_PORTS { "COM1", "COM2", "COM3", "COM4", NULL } +#elif defined(__APPLE__) + // XXX: find UART connection string for PN53X device on Mac OS X when multiples devices are used + #define DEFAULT_SERIAL_PORTS { "/dev/tty.SLAB_USBtoUART", NULL } #elif defined (__FreeBSD__) || defined (__OpenBSD__) // XXX: Not tested - #define SERIAL_STRING "/dev/cuau" + #define DEFAULT_SERIAL_PORTS { "/dev/cuau0", "/dev/cuau1", "/dev/cuau2", "/dev/cuau3", NULL } #elif defined (__linux__) - #define SERIAL_STRING "/dev/ttyUSB" + #define DEFAULT_SERIAL_PORTS { "/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyUSB2", "/dev/ttyUSB3", "/dev/tty0", "/dev/tty1", "/dev/tty2", "/dev/tty3", NULL } #else #error "Can't determine serial string for your system" #endif diff --git a/libnfc/drivers/arygon.c b/libnfc/drivers/arygon.c index 0ff9090..eeb1bf5 100644 --- a/libnfc/drivers/arygon.c +++ b/libnfc/drivers/arygon.c @@ -109,21 +109,13 @@ arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p *pszDeviceFound = 0; serial_port sp; - char acPort[BUFFER_LENGTH]; - int iDevice; + const char** pcPorts = UNIX_SERIAL_PORT_DEVS; + const char* pcPort; + int iDevice = 0; - // I have no idea how MAC OS X deals with multiple devices, so a quick workaround - for (iDevice=0; iDevice= szDevices) break; } #ifdef DEBUG - if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s",acPort); - if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s",acPort); + if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s", pcPort); + if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s", pcPort); #endif /* DEBUG */ } #endif /* SERIAL_AUTOPROBE_ENABLED */ @@ -157,19 +149,14 @@ nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd) serial_port sp; nfc_device_t* pnd = NULL; - if( pndd == NULL ) { - DBG("%s", "arygon_connect() need an nfc_device_desc_t struct."); - return NULL; - } else { - DBG("Attempt to connect to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed); - sp = uart_open(pndd->pcPort); + 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); - if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",pndd->pcPort); - if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL; + if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",pndd->pcPort); + if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",pndd->pcPort); + if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL; - uart_set_speed(sp, pndd->uiSpeed); - } + uart_set_speed(sp, pndd->uiSpeed); DBG("Successfully connected to: %s",pndd->pcPort); diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index 6359bcd..a0c3833 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -83,21 +83,13 @@ pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_ *pszDeviceFound = 0; serial_port sp; - char acPort[BUFFER_LENGTH]; - int iDevice; - - // I have no idea how MAC OS X deals with multiple devices, so a quick workaround - for (iDevice=0; iDevicepcPort, pndd->uiSpeed); - sp = uart_open(pndd->pcPort); + 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); - if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",pndd->pcPort); - if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL; + if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",pndd->pcPort); + if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",pndd->pcPort); + if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL; - uart_set_speed(sp, pndd->uiSpeed); - } + uart_set_speed(sp, pndd->uiSpeed); + // PN532 could be powered down, we need to wake it up before line testing. pn532_uart_wakeup((nfc_device_spec_t)sp); // Check communication using "Diagnose" command, with "Comunication test" (0x00) From 88002bf977b797e03ce17bd973c6542418223b2f Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Tue, 17 Aug 2010 13:31:32 +0000 Subject: [PATCH 09/20] Code cleaning: driver_connect() is never executed with pndd==NULL. --- libnfc/drivers/acr122.c | 2 -- libnfc/drivers/pn53x_usb.c | 3 --- 2 files changed, 5 deletions(-) diff --git a/libnfc/drivers/acr122.c b/libnfc/drivers/acr122.c index 4b94db8..402593a 100644 --- a/libnfc/drivers/acr122.c +++ b/libnfc/drivers/acr122.c @@ -205,8 +205,6 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd) SCARDCONTEXT *pscc; 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 if (!(pscc = acr122_get_scardcontext ())) return NULL; // Test if we were able to connect to the "emulator" card diff --git a/libnfc/drivers/pn53x_usb.c b/libnfc/drivers/pn53x_usb.c index 15bcd5e..accdb4b 100644 --- a/libnfc/drivers/pn53x_usb.c +++ b/libnfc/drivers/pn53x_usb.c @@ -160,9 +160,6 @@ 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("Attempt to connect to %s device", target_name); usb_init(); From c021a50768e3c0a491e2314341ca6d0170bd2566 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Tue, 17 Aug 2010 13:50:49 +0000 Subject: [PATCH 10/20] Oups, r534 was not a joke... just a mistake ;-) This commit fix my r534. --- libnfc/drivers/arygon.c | 6 +++--- libnfc/drivers/pn532_uart.c | 8 ++++---- libnfc/nfc.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libnfc/drivers/arygon.c b/libnfc/drivers/arygon.c index eeb1bf5..056bb04 100644 --- a/libnfc/drivers/arygon.c +++ b/libnfc/drivers/arygon.c @@ -109,11 +109,11 @@ arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p *pszDeviceFound = 0; serial_port sp; - const char** pcPorts = UNIX_SERIAL_PORT_DEVS; + const char* pcPorts[] = DEFAULT_SERIAL_PORTS; const char* pcPort; int iDevice = 0; - while( pcPort = pcPorts[i++] ) { + while( pcPort = pcPorts[iDevice++] ) { sp = uart_open(pcPort); DBG("Trying to find ARYGON device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED); @@ -124,7 +124,7 @@ arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p uart_close(sp); // ARYGON reader is found - snprintf(pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "ARYGON", acPort); + snprintf(pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "ARYGON", pcPort); pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0'; pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME; pnddDevices[*pszDeviceFound].pcPort = strdup(pcPort); diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index a0c3833..ba00791 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -83,11 +83,11 @@ pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_ *pszDeviceFound = 0; serial_port sp; - const char** pcPorts = UNIX_SERIAL_PORT_DEVS; + const char* pcPorts[] = DEFAULT_SERIAL_PORTS; const char* pcPort; int iDevice = 0; - while( pcPort = pcPorts[i++] ) { + while( pcPort = pcPorts[iDevice++] ) { sp = uart_open(pcPort); DBG("Trying to find PN532 device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED); @@ -113,8 +113,8 @@ pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_ if((*pszDeviceFound) >= szDevices) break; } #ifdef DEBUG - if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s",acPort); - if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s",acPort); + if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s", pcPort); + if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s", pcPort); #endif /* DEBUG */ } #endif /* SERIAL_AUTOPROBE_ENABLED */ diff --git a/libnfc/nfc.c b/libnfc/nfc.c index e06f24c..e64df26 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -520,7 +520,8 @@ 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 ) +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_target_info_t nti; size_t szTargetFound = 0; From 6e84e757c723c69cf3d2ffbb8e5c3b95d6245da3 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Tue, 17 Aug 2010 14:40:35 +0000 Subject: [PATCH 11/20] List available drivers in ./configure --help --- m4/libnfc_drivers.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/m4/libnfc_drivers.m4 b/m4/libnfc_drivers.m4 index 0c7296f..2ed6aef 100644 --- a/m4/libnfc_drivers.m4 +++ b/m4/libnfc_drivers.m4 @@ -4,7 +4,7 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS], [ AC_MSG_CHECKING(which drivers to build) AC_ARG_WITH(drivers, - AC_HELP_STRING([--with-drivers=driver@<:@[[[,]]]driver...@:>@], [Only use specific drivers (default set)]), + AC_HELP_STRING([--with-drivers=driver@<:@[[[,]]]driver...@:>@], [Only use specific drivers (available drivers: acr122,arygon,pn531_usb,pn533_usb,pn532_uart)]), [ case "${withval}" in yes | no) dnl ignore calls without any arguments From eeaad85151d7521438604d32c79763d0165e8363 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Tue, 17 Aug 2010 15:24:37 +0000 Subject: [PATCH 12/20] Add SAK decoding for compliance with ISO/IEC. --- examples/nfc-utils.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/nfc-utils.c b/examples/nfc-utils.c index 95b01e1..46fe5c7 100644 --- a/examples/nfc-utils.c +++ b/examples/nfc-utils.c @@ -84,6 +84,9 @@ void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbt printf("\n"); } +#define SAK_ISO14443_4_COMPLIANT 0x20 +#define SAK_ISO18092_COMPLIANT 0x40 + void print_nfc_iso14443a_info(const nfc_iso14443a_info_t nai) { printf(" ATQA (SENS_RES): "); print_hex(nai.abtAtqa,2); @@ -93,6 +96,12 @@ void print_nfc_iso14443a_info(const nfc_iso14443a_info_t nai) printf(" ATS (ATR): "); print_hex(nai.abtAts, nai.szAtsLen); } + if ( (nai.btSak & SAK_ISO14443_4_COMPLIANT) || (nai.btSak & SAK_ISO18092_COMPLIANT) ) { + printf(" Compliant with: "); + if (nai.btSak & SAK_ISO14443_4_COMPLIANT) printf("ISO/IEC 14443-4 "); + if (nai.btSak & SAK_ISO18092_COMPLIANT) printf("ISO/IEC 18092"); + printf("\n"); + } } /** From 0c19124984b0592674a081887d9e5e25da60ff40 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Wed, 18 Aug 2010 08:06:35 +0000 Subject: [PATCH 13/20] Increase UART timeout to gain in stability. --- libnfc/buses/uart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libnfc/buses/uart.c b/libnfc/buses/uart.c index 45d555d..9a43937 100644 --- a/libnfc/buses/uart.c +++ b/libnfc/buses/uart.c @@ -50,10 +50,10 @@ typedef struct { term_info tiNew; // Terminal info during the transaction } serial_port_unix; -// Set time-out on 30 miliseconds +// timeval struct that define timeout delay for serial port const struct timeval timeout = { .tv_sec = 0, // 0 second - .tv_usec = 50000 // 50 ms + .tv_usec = 60000 // 60 ms }; // Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct From 43694183fffaefb537ffb26b6eb048166db1c129 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Wed, 18 Aug 2010 12:39:32 +0000 Subject: [PATCH 14/20] Minor documentation improvements. --- libnfc/nfc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libnfc/nfc.c b/libnfc/nfc.c index e64df26..b1a8893 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -543,7 +543,6 @@ nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmI } /** - * @fn nfc_initiator_deselect_target(const nfc_device_t* pnd); * @brief Deselect a selected passive or emulated tag * @return Returns true if action was successfully performed; otherwise returns false. * @param pnd nfc_device_t struct pointer that represent currently used device @@ -576,7 +575,6 @@ nfc_initiator_poll_targets(const nfc_device_t* pnd, } /** - * @fn 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) * @brief Transceive raw bit-frames * @return Returns true if action was successfully performed; otherwise returns false. * @param pbtTx contains a byte array of the frame that needs to be transmitted. @@ -684,10 +682,10 @@ bool nfc_initiator_transceive_dep_bytes(const nfc_device_t* pnd, const byte_t* p } /** - * @brief Transceive byte and APDU frames + * @brief Send raw data to target then retrieve raw data from target * @return Returns true if action was successfully performed; otherwise returns false. * - * The reader will transmit the supplied bytes in pbtTx to the target (tag). + * The reader will transmit the supplied bytes (\a pbtTx) to the target in raw mode: PN53x will not handle input neither output data. * 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. From 3dd2257b577f5848bcbfa231976264c38c56fe73 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Wed, 18 Aug 2010 12:50:40 +0000 Subject: [PATCH 15/20] Add print_nfc_felica_info() and print_nfc_iso14443b_info() functions to nfc-utils (used by examples) --- examples/nfc-utils.c | 16 ++++++++++++++++ examples/nfc-utils.h | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/examples/nfc-utils.c b/examples/nfc-utils.c index 46fe5c7..2626760 100644 --- a/examples/nfc-utils.c +++ b/examples/nfc-utils.c @@ -103,6 +103,22 @@ void print_nfc_iso14443a_info(const nfc_iso14443a_info_t nai) printf("\n"); } } +void print_nfc_felica_info(const nfc_felica_info_t nfi) +{ + printf(" ID (NFCID2): "); print_hex(nfi.abtId,8); + printf(" Parameter (PAD): "); print_hex(nfi.abtPad,8); +} + +void print_nfc_iso14443b_info(const nfc_iso14443b_info_t nbi) +{ + printf(" ATQB: "); print_hex(nbi.abtAtqb,12); + printf(" ID: "); print_hex(nbi.abtId,4); + printf(" CID: %02x\n",nbi.btCid); + if (nbi.szInfLen>0) { + printf(" INF: "); print_hex(nbi.abtInf,nbi.szInfLen); + } + printf(" PARAMS: %02x %02x %02x %02x\n",nbi.btParam1,nbi.btParam2,nbi.btParam3,nbi.btParam4); +} /** * @brief Tries to parse arguments to find device descriptions. diff --git a/examples/nfc-utils.h b/examples/nfc-utils.h index c672efd..aaacf93 100644 --- a/examples/nfc-utils.h +++ b/examples/nfc-utils.h @@ -31,7 +31,11 @@ void print_hex(const byte_t* pbtData, const size_t szLen); void print_hex_bits(const byte_t* pbtData, const size_t szBits); void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbtDataPar); + void print_nfc_iso14443a_info(const nfc_iso14443a_info_t nai); +void print_nfc_iso14443b_info(const nfc_iso14443b_info_t nbi); +void print_nfc_felica_info(const nfc_felica_info_t nfi); + nfc_device_desc_t* parse_device_desc(int argc, const char *argv[], size_t* szFound); #endif From 5c206b78150ef6ac69a6c83aa5bc6a7daa27c4e4 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Wed, 18 Aug 2010 13:10:21 +0000 Subject: [PATCH 16/20] Improve ISO14443B support of nfc_initiator_list_passive_targets() function. --- libnfc/nfc.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libnfc/nfc.c b/libnfc/nfc.c index b1a8893..3cb5fa0 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -528,8 +528,15 @@ nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmI // Let the reader only try once to find a target nfc_configure (pnd, NDO_INFINITE_SELECT, false); - - while (nfc_initiator_select_passive_target (pnd, nmInitModulation, NULL, 0, &nti)) { + byte_t* pbtInitData = NULL; + size_t szInitDataLen = 0; + + if(nmInitModulation == NM_ISO14443B_106) { + // Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3) + pbtInitData = (byte_t*)"\x00"; + szInitDataLen = 1; + } + while (nfc_initiator_select_passive_target (pnd, nmInitModulation, pbtInitData, szInitDataLen, &nti)) { nfc_initiator_deselect_target(pnd); if(szTargets > szTargetFound) { From cf9af4ee49991082a06903d012fda5215c052234 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Wed, 18 Aug 2010 13:13:14 +0000 Subject: [PATCH 17/20] nfc-list example now use nfc_initiator_list_passive_targets() function. --- examples/nfc-list.c | 64 +++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/examples/nfc-list.c b/examples/nfc-list.c index 3e00620..7d9493e 100644 --- a/examples/nfc-list.c +++ b/examples/nfc-list.c @@ -47,7 +47,6 @@ #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[]) { @@ -133,45 +132,54 @@ int main(int argc, const char* argv[]) printf("Connected to NFC reader: %s\n",pnd->acName); + // List ISO14443A targets if (nfc_initiator_list_passive_targets(pnd, NM_ISO14443A_106, anti, MAX_TARGET_COUNT, &szTargetFound )) { size_t n; - printf("%zu ISO14443A passive targets was found:\n", szTargetFound); + printf("%zu ISO14443A passive target(s) was found%s\n", szTargetFound, (szTargetFound==0)?".\n":":"); for(n=0; n0) - { - printf(" INF: "); print_hex(nti.nbi.abtInf,nti.nbi.szInfLen); + // List Felica tags + if (nfc_initiator_list_passive_targets(pnd, NM_FELICA_212, anti, MAX_TARGET_COUNT, &szTargetFound )) { + size_t n; + printf("%zu Felica (212 kbps) passive target(s) was found%s\n", szTargetFound, (szTargetFound==0)?".\n":":"); + for(n=0; n Date: Wed, 18 Aug 2010 13:20:40 +0000 Subject: [PATCH 18/20] nfc-mfclassic now fails ealier when something goes wrong (this allow to prevent from false-success). --- examples/nfc-mfclassic.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/nfc-mfclassic.c b/examples/nfc-mfclassic.c index 58855be..7b1e628 100644 --- a/examples/nfc-mfclassic.c +++ b/examples/nfc-mfclassic.c @@ -141,9 +141,6 @@ authenticate (uint32_t uiBlock) for (key_index = 0; key_index < num_keys; key_index++) { memcpy (mp.mpa.abtKey, keys + (key_index * 6), 6); if (nfc_initiator_mifare_cmd (pnd, mc, uiBlock, &mp)) { - /** - * @note: what about the other key? - */ if (bUseKeyA) memcpy (mtKeys.amb[uiBlock].mbt.abtKeyA, &mp.mpa.abtKey, 6); else @@ -190,7 +187,7 @@ read_card (void) // Try to authenticate for the current sector if (!authenticate (iBlock)) { - printf ("!\nError: authentication failed for block %02x\n", iBlock); + printf ("!\nError: authentication failed for block 0x%02x\n", iBlock); return false; } // Try to read out the trailer @@ -199,6 +196,8 @@ read_card (void) memcpy (mtDump.amb[iBlock].mbt.abtKeyA, mtKeys.amb[iBlock].mbt.abtKeyA, 6); memcpy (mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpd.abtData + 6, 4); memcpy (mtDump.amb[iBlock].mbt.abtKeyB, mtKeys.amb[iBlock].mbt.abtKeyB, 6); + } else { + printf("!\nError: unable to read trailer block 0x%02x\n", iBlock); } } else { // Make sure a earlier readout did not fail @@ -208,6 +207,8 @@ read_card (void) memcpy (mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, 16); } else { bFailure = true; + printf("!\nError: unable to read block 0x%02x\n", iBlock); + return false; } } } From 6354e9465799767d6d81995ccdfc0c3e7d428cd0 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Wed, 18 Aug 2010 13:53:34 +0000 Subject: [PATCH 19/20] mifare function improvement: it now failed when read command does not return a whole block (16 bytes). --- examples/mifare.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/mifare.c b/examples/mifare.c index cd8d811..45387d0 100644 --- a/examples/mifare.c +++ b/examples/mifare.c @@ -69,7 +69,13 @@ bool nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, cons if (!nfc_initiator_transceive_dep_bytes(pnd,abtCmd,2+szParamLen,abtRx,&szRxLen)) return false; // When we have executed a read command, copy the received bytes into the param - if (mc == MC_READ && szRxLen == 16) memcpy(pmp->mpd.abtData,abtRx,16); + if (mc == MC_READ) { + if(szRxLen == 16) { + memcpy(pmp->mpd.abtData,abtRx,16); + } else { + return false; + } + } // Command succesfully executed return true; From d0fe1f8255369674cc699bd6ef65e5d535cb1457 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Wed, 18 Aug 2010 13:56:31 +0000 Subject: [PATCH 20/20] Fix debug trace of pn532_uart driver. --- libnfc/drivers/pn532_uart.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index ba00791..1474994 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -229,11 +229,10 @@ bool pn532_uart_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, con while (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) { delay_ms(10); } - } - #ifdef DEBUG - PRINT_HEX("RX", abtRxBuf,szRxBufLen); + PRINT_HEX("RX", abtRxBuf,szRxBufLen); #endif + } // When the answer should be ignored, just return a successful result if(pbtRx == NULL || pszRxLen == NULL) return true;