Move some PN53x related code from nfc.c to pn53x.c

This commit is contained in:
Romuald Conty 2010-07-22 16:21:59 +00:00
parent 424a48714f
commit d932cd8450
3 changed files with 62 additions and 47 deletions

View file

@ -1,7 +1,7 @@
/*- /*-
* Public platform independent Near Field Communication (NFC) library * 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 * 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 * 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; 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;
}
}

View file

@ -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_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_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_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__ #endif // __NFC_CHIPS_PN53X_H__

View file

@ -1,7 +1,7 @@
/*- /*-
* Public platform independent Near Field Communication (NFC) library * 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 * 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 * 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]; byte_t abtInit[MAX_FRAME_LEN];
size_t szInitLen; 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 // Make sure we are dealing with a active device
if (!pnd->bActive) return false; 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) switch(nmInitModulation)
{ {
case NM_ISO14443A_106: case NM_ISO14443A_106:
@ -467,16 +460,13 @@ bool nfc_initiator_select_passive_target(const nfc_device_t* pnd,
break; break;
} }
// Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID). size_t szTargetFound, szTargetsData;
if (pbtInitData) memcpy(abtCmd+4,abtInit,szInitLen); byte_t abtTargetsData[MAX_FRAME_LEN];
// Try to find a tag, call the tranceive callback function of the current device if(!pn53x_InListPassiveTarget(pnd, nmInitModulation, 1, pbtInitData, szInitDataLen, &szTargetFound, abtTargetsData, &szTargetsData)) return false;
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;
// Make sure one tag has been found, the PN53X returns 0x00 if none was available // 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 // Is a tag info struct available
if (pnti) if (pnti)
@ -485,50 +475,50 @@ bool nfc_initiator_select_passive_target(const nfc_device_t* pnd,
switch(nmInitModulation) switch(nmInitModulation)
{ {
case NM_ISO14443A_106: 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 // Strip CT (Cascade Tag) to retrieve and store the _real_ UID
// (e.g. 0x8801020304050607 is in fact 0x01020304050607) // (e.g. 0x8801020304050607 is in fact 0x01020304050607)
if ((pnti->nai.szUidLen == 8) && (pnti->nai.abtUid[0] == 0x88)) { if ((pnti->nai.szUidLen == 8) && (pnti->nai.abtUid[0] == 0x88)) {
pnti->nai.szUidLen = 7; pnti->nai.szUidLen = 7;
memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 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)) { } else if ((pnti->nai.szUidLen == 12) && (pnti->nai.abtUid[0] == 0x88) && (pnti->nai.abtUid[4] == 0x88)) {
pnti->nai.szUidLen = 10; pnti->nai.szUidLen = 10;
memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 3); memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 3);
memmove (pnti->nai.abtUid + 3, pnti->nai.abtUid + 5, 7); memmove (pnti->nai.abtUid + 3, pnti->nai.abtUid + 5, 7);
} }
break; break;
case NM_FELICA_212: case NM_FELICA_212:
case NM_FELICA_424: case NM_FELICA_424:
// Store the mandatory info // Store the mandatory info
pnti->nfi.szLen = abtRx[2]; pnti->nfi.szLen = abtTargetsData[2];
pnti->nfi.btResCode = abtRx[3]; pnti->nfi.btResCode = abtTargetsData[3];
// Copy the NFCID2t // Copy the NFCID2t
memcpy(pnti->nfi.abtId,abtRx+4,8); memcpy(pnti->nfi.abtId,abtTargetsData+4,8);
// Copy the felica padding // 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 // 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; break;
case NM_ISO14443B_106: case NM_ISO14443B_106:
// Store the mandatory info // 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 // Ignore the 0x1D byte, and just store the 4 byte id
memcpy(pnti->nbi.abtId,abtRx+15,4); memcpy(pnti->nbi.abtId,abtTargetsData+15,4);
pnti->nbi.btParam1 = abtRx[19]; pnti->nbi.btParam1 = abtTargetsData[19];
pnti->nbi.btParam2 = abtRx[20]; pnti->nbi.btParam2 = abtTargetsData[20];
pnti->nbi.btParam3 = abtRx[21]; pnti->nbi.btParam3 = abtTargetsData[21];
pnti->nbi.btParam4 = abtRx[22]; pnti->nbi.btParam4 = abtTargetsData[22];
// Test if the Higher layer (INF) is available // Test if the Higher layer (INF) is available
if (szRxLen > 22) if (szTargetsData > 22)
{ {
pnti->nbi.szInfLen = abtRx[23]; pnti->nbi.szInfLen = abtTargetsData[23];
memcpy(pnti->nbi.abtInf,abtRx+24,pnti->nbi.szInfLen); memcpy(pnti->nbi.abtInf,abtTargetsData+24,pnti->nbi.szInfLen);
} else { } else {
pnti->nbi.szInfLen = 0; pnti->nbi.szInfLen = 0;
} }
@ -536,8 +526,8 @@ bool nfc_initiator_select_passive_target(const nfc_device_t* pnd,
case NM_JEWEL_106: case NM_JEWEL_106:
// Store the mandatory info // Store the mandatory info
memcpy(pnti->nji.btSensRes,abtRx+2,2); memcpy(pnti->nji.btSensRes,abtTargetsData+2,2);
memcpy(pnti->nji.btId,abtRx+4,4); memcpy(pnti->nji.btId,abtTargetsData+4,4);
break; break;
default: default: