From d932cd8450e8956eefee554ddb3a72d2affb05ec Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Thu, 22 Jul 2010 16:21:59 +0000 Subject: [PATCH] Move some PN53x related code from nfc.c to pn53x.c --- libnfc/chips/pn53x.c | 27 ++++++++++++++- libnfc/chips/pn53x.h | 2 +- libnfc/nfc.c | 80 +++++++++++++++++++------------------------- 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 5e6d91d..80f2741 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -1,7 +1,7 @@ /*- * Public platform independent Near Field Communication (NFC) library * - * Copyright (C) 2009, Roel Verdult + * Copyright (C) 2009, 2010, 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 @@ -274,3 +274,28 @@ pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_chip_t } return true; } + +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, + size_t* pszTargets, byte_t* pbtTargetsData, size_t* pszTargetsData) +{ + byte_t abtCmd[sizeof(pncmd_initiator_list_passive)]; + memcpy(abtCmd,pncmd_initiator_list_passive,sizeof(pncmd_initiator_list_passive)); + + abtCmd[2] = szMaxTargets; // MaxTg + abtCmd[3] = nmInitModulation; // BrTy, the type of init modulation used for polling a passive tag + + // Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID). + if (pbtInitiatorData) memcpy(abtCmd+4,pbtInitiatorData,szInitiatorDataLen); + + // Try to find a tag, call the tranceive callback function of the current device + size_t szRxLen = MAX_FRAME_LEN; + // We can not use pn53x_transceive() because abtRx[0] gives no status info + if(pnd->pdc->transceive(pnd->nds,abtCmd,4+szInitiatorDataLen,pbtTargetsData,&szRxLen)) { + *pszTargetsData = szRxLen; + return true; + } else { + return false; + } +} \ No newline at end of file diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h index a703a16..b1f59ff 100644 --- a/libnfc/chips/pn53x.h +++ b/libnfc/chips/pn53x.h @@ -77,6 +77,6 @@ bool pn53x_set_tx_bits(const nfc_device_t* pnd, uint8_t ui8Bits); bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtFrame, size_t* pszFrameBits); bool pn53x_unwrap_frame(const byte_t* pbtFrame, const size_t szFrameBits, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar); bool pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_chip_t nc, nfc_target_type_t ntt, nfc_target_info_t* pnti); - +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, size_t* pszTargets, byte_t* pbtTargetsData, size_t* pszTargetsData); #endif // __NFC_CHIPS_PN53X_H__ diff --git a/libnfc/nfc.c b/libnfc/nfc.c index cf8bd09..a95c539 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -1,7 +1,7 @@ /*- * Public platform independent Near Field Communication (NFC) library * - * Copyright (C) 2009, Roel Verdult + * Copyright (C) 2009, 2010, 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 @@ -423,17 +423,10 @@ bool nfc_initiator_select_passive_target(const nfc_device_t* pnd, { byte_t abtInit[MAX_FRAME_LEN]; size_t szInitLen; - byte_t abtRx[MAX_FRAME_LEN]; - size_t szRxLen; - byte_t abtCmd[sizeof(pncmd_initiator_list_passive)]; - memcpy(abtCmd,pncmd_initiator_list_passive,sizeof(pncmd_initiator_list_passive)); // Make sure we are dealing with a active device if (!pnd->bActive) return false; - abtCmd[2] = 1; // MaxTg, we only want to select 1 tag at the time - abtCmd[3] = nmInitModulation; // BrTy, the type of init modulation used for polling a passive tag - switch(nmInitModulation) { case NM_ISO14443A_106: @@ -467,16 +460,13 @@ bool nfc_initiator_select_passive_target(const nfc_device_t* pnd, break; } - // Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID). - if (pbtInitData) memcpy(abtCmd+4,abtInit,szInitLen); - - // Try to find a tag, call the tranceive callback function of the current device - szRxLen = MAX_FRAME_LEN; - // We can not use pn53x_transceive() because abtRx[0] gives no status info - if (!pnd->pdc->transceive(pnd->nds,abtCmd,4+szInitLen,abtRx,&szRxLen)) return false; - + size_t szTargetFound, szTargetsData; + byte_t abtTargetsData[MAX_FRAME_LEN]; + + if(!pn53x_InListPassiveTarget(pnd, nmInitModulation, 1, pbtInitData, szInitDataLen, &szTargetFound, abtTargetsData, &szTargetsData)) return false; + // Make sure one tag has been found, the PN53X returns 0x00 if none was available - if (abtRx[0] != 1) return false; + if (abtTargetsData[0] == 0) return false; // Is a tag info struct available if (pnti) @@ -485,50 +475,50 @@ bool nfc_initiator_select_passive_target(const nfc_device_t* pnd, switch(nmInitModulation) { case NM_ISO14443A_106: - if(!pn53x_decode_target_data(&abtRx[1], szRxLen-1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) return false; + if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) return false; - // 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); - } + // 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 NM_FELICA_212: case NM_FELICA_424: // Store the mandatory info - pnti->nfi.szLen = abtRx[2]; - pnti->nfi.btResCode = abtRx[3]; + pnti->nfi.szLen = abtTargetsData[2]; + pnti->nfi.btResCode = abtTargetsData[3]; // Copy the NFCID2t - memcpy(pnti->nfi.abtId,abtRx+4,8); + memcpy(pnti->nfi.abtId,abtTargetsData+4,8); // Copy the felica padding - memcpy(pnti->nfi.abtPad,abtRx+12,8); + memcpy(pnti->nfi.abtPad,abtTargetsData+12,8); // Test if the System code (SYST_CODE) is available - if (szRxLen > 20) + if (szTargetsData > 20) { - memcpy(pnti->nfi.abtSysCode,abtRx+20,2); + memcpy(pnti->nfi.abtSysCode,abtTargetsData+20,2); } break; case NM_ISO14443B_106: // Store the mandatory info - memcpy(pnti->nbi.abtAtqb,abtRx+2,12); + memcpy(pnti->nbi.abtAtqb,abtTargetsData+2,12); // Ignore the 0x1D byte, and just store the 4 byte id - memcpy(pnti->nbi.abtId,abtRx+15,4); - pnti->nbi.btParam1 = abtRx[19]; - pnti->nbi.btParam2 = abtRx[20]; - pnti->nbi.btParam3 = abtRx[21]; - pnti->nbi.btParam4 = abtRx[22]; + 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 (szRxLen > 22) + if (szTargetsData > 22) { - pnti->nbi.szInfLen = abtRx[23]; - memcpy(pnti->nbi.abtInf,abtRx+24,pnti->nbi.szInfLen); + pnti->nbi.szInfLen = abtTargetsData[23]; + memcpy(pnti->nbi.abtInf,abtTargetsData+24,pnti->nbi.szInfLen); } else { pnti->nbi.szInfLen = 0; } @@ -536,8 +526,8 @@ bool nfc_initiator_select_passive_target(const nfc_device_t* pnd, case NM_JEWEL_106: // Store the mandatory info - memcpy(pnti->nji.btSensRes,abtRx+2,2); - memcpy(pnti->nji.btId,abtRx+4,4); + memcpy(pnti->nji.btSensRes,abtTargetsData+2,2); + memcpy(pnti->nji.btId,abtTargetsData+4,4); break; default: