Merge the libnfc-error-handling branch into trunk.
This commit is contained in:
commit
23f84a4e6a
32 changed files with 740 additions and 309 deletions
|
@ -1,3 +1,11 @@
|
|||
???
|
||||
----
|
||||
|
||||
Changes:
|
||||
- API: New nfc_perror(), nfc_strerror() and nfc_strerror_r() functions.
|
||||
|
||||
|
||||
|
||||
Apr 6, 2010 - 1.3.4
|
||||
--------------------
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* After a successful authentication it will be possible to execute other commands (e.g. Read/Write).
|
||||
* The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
|
||||
*/
|
||||
bool nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp)
|
||||
bool nfc_initiator_mifare_cmd(nfc_device_t* pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp)
|
||||
{
|
||||
byte_t abtRx[265];
|
||||
size_t szRxLen;
|
||||
|
@ -66,7 +66,10 @@ bool nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, cons
|
|||
if (szParamLen) memcpy(abtCmd+2,(byte_t*)pmp,szParamLen);
|
||||
|
||||
// Fire the mifare command
|
||||
if (!nfc_initiator_transceive_dep_bytes(pnd,abtCmd,2+szParamLen,abtRx,&szRxLen)) return false;
|
||||
if (!nfc_initiator_transceive_dep_bytes(pnd,abtCmd,2+szParamLen,abtRx,&szRxLen)) {
|
||||
nfc_perror (pnd, "nfc_initiator_transceive_dep_bytes");
|
||||
return false;
|
||||
}
|
||||
|
||||
// When we have executed a read command, copy the received bytes into the param
|
||||
if (mc == MC_READ) {
|
||||
|
|
|
@ -63,7 +63,7 @@ typedef union {
|
|||
// Reset struct alignment to default
|
||||
#pragma pack()
|
||||
|
||||
bool nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp);
|
||||
bool nfc_initiator_mifare_cmd(nfc_device_t* pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp);
|
||||
|
||||
// Compiler directive, set struct alignment to 1 byte_t for compatibility
|
||||
#pragma pack(1)
|
||||
|
|
|
@ -143,14 +143,28 @@ int main(int argc,char* argv[])
|
|||
nfc_initiator_init(pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
// Configure the CRC
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_CRC,false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure parity settings
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_PARITY,true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("\nConnected to NFC reader: %s\n\n",pnd->acName);
|
||||
|
||||
|
|
|
@ -113,8 +113,10 @@ int main(int argc, char *argv[])
|
|||
printf("[+] Received initiator command: ");
|
||||
print_hex_bits(abtRecv,szRecvBits);
|
||||
printf("[+] Configuring communication\n");
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_CRC,false) || !nfc_configure(pnd,NDO_HANDLE_PARITY,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n",abtUidBcc[0],abtUidBcc[1],abtUidBcc[2],abtUidBcc[3]);
|
||||
|
||||
while(true)
|
||||
|
@ -157,7 +159,10 @@ int main(int argc, char *argv[])
|
|||
if(szTxBits)
|
||||
{
|
||||
// Send and print the command to the screen
|
||||
nfc_target_send_bits(pnd,pbtTx,szTxBits,NULL);
|
||||
if (!nfc_target_send_bits(pnd,pbtTx,szTxBits,NULL)) {
|
||||
nfc_perror(pnd, "nfc_target_send_bits");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("T: ");
|
||||
|
@ -168,5 +173,6 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
nfc_disconnect(pnd);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -117,17 +117,32 @@ int main(int argc, const char* argv[])
|
|||
nfc_initiator_init(pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure(pnd,NDO_INFINITE_SELECT,false);
|
||||
if (!nfc_configure(pnd,NDO_INFINITE_SELECT,false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,true);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_CRC,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_PARITY,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Connected to NFC reader: %s\n",pnd->acName);
|
||||
|
||||
|
|
|
@ -414,15 +414,30 @@ main (int argc, const char *argv[])
|
|||
nfc_initiator_init (pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, false);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure (pnd, NDO_INFINITE_SELECT, false);
|
||||
nfc_configure (pnd, NDO_HANDLE_CRC, true);
|
||||
nfc_configure (pnd, NDO_HANDLE_PARITY, true);
|
||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, true);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
|
||||
nfc_configure(pnd, NDO_AUTO_ISO14443_4, false);
|
||||
|
|
|
@ -190,15 +190,30 @@ main (int argc, const char *argv[])
|
|||
nfc_initiator_init (pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, false);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure (pnd, NDO_INFINITE_SELECT, false);
|
||||
nfc_configure (pnd, NDO_HANDLE_CRC, true);
|
||||
nfc_configure (pnd, NDO_HANDLE_PARITY, true);
|
||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, true);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
||||
|
||||
|
|
|
@ -88,26 +88,35 @@ main (int argc, const char *argv[])
|
|||
nfc_initiator_init (pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, false);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure (pnd, NDO_INFINITE_SELECT, false);
|
||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
nfc_configure (pnd, NDO_HANDLE_CRC, true);
|
||||
nfc_configure (pnd, NDO_HANDLE_PARITY, true);
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, true);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
||||
|
||||
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;
|
||||
}
|
||||
printf ("PN53x will poll during %ld ms\n", (unsigned long) btPollNr * szTargetTypes * btPeriod * 150);
|
||||
res = nfc_initiator_poll_targets (pnd, &nttMifare, 1, btPollNr, btPeriod, antTargets, &szTargetFound);
|
||||
if (res) {
|
||||
|
@ -119,7 +128,8 @@ main (int argc, const char *argv[])
|
|||
print_nfc_iso14443a_info (antTargets[n].nti.nai);
|
||||
}
|
||||
} else {
|
||||
ERR ("%s", "Polling failed.");
|
||||
nfc_perror (pnd, "nfc_initiator_poll_targets");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
nfc_disconnect (pnd);
|
||||
|
|
|
@ -132,9 +132,12 @@ int main(int argc,char* argv[])
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("%s", "Configuring emulator settings...");
|
||||
nfc_configure(pndTag,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pndTag,NDO_HANDLE_PARITY,false);
|
||||
nfc_configure(pndTag,NDO_ACCEPT_INVALID_FRAMES,true);
|
||||
if (!nfc_configure(pndTag,NDO_HANDLE_CRC,false) ||
|
||||
!nfc_configure(pndTag,NDO_HANDLE_PARITY,false) ||
|
||||
!nfc_configure(pndTag,NDO_ACCEPT_INVALID_FRAMES,true)) {
|
||||
nfc_perror(pndTag, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("%s", "Done, emulated tag is initialized");
|
||||
|
||||
// Try to open the NFC reader
|
||||
|
@ -143,9 +146,12 @@ int main(int argc,char* argv[])
|
|||
printf("Connected to the NFC reader device: %s", pndReader->acName);
|
||||
printf("%s", "Configuring NFC reader settings...");
|
||||
nfc_initiator_init(pndReader);
|
||||
nfc_configure(pndReader,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pndReader,NDO_HANDLE_PARITY,false);
|
||||
nfc_configure(pndReader,NDO_ACCEPT_INVALID_FRAMES,true);
|
||||
if (!nfc_configure(pndReader,NDO_HANDLE_CRC,false) ||
|
||||
!nfc_configure(pndReader,NDO_HANDLE_PARITY,false) ||
|
||||
!nfc_configure(pndReader,NDO_ACCEPT_INVALID_FRAMES,true)) {
|
||||
nfc_perror(pndReader, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("%s", "Done, relaying frames now!");
|
||||
|
||||
while(!quitting)
|
||||
|
@ -157,10 +163,16 @@ int main(int argc,char* argv[])
|
|||
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26)
|
||||
{
|
||||
// Drop down field for a very short time (original tag will reboot)
|
||||
nfc_configure(pndReader,NDO_ACTIVATE_FIELD,false);
|
||||
if (!nfc_configure(pndReader,NDO_ACTIVATE_FIELD,false)) {
|
||||
nfc_perror(pndReader, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(!quiet_output)
|
||||
printf("\n");
|
||||
nfc_configure(pndReader,NDO_ACTIVATE_FIELD,true);
|
||||
if (!nfc_configure(pndReader,NDO_ACTIVATE_FIELD,true)) {
|
||||
nfc_perror(pndReader, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// Print the reader frame to the screen
|
||||
|
@ -173,7 +185,10 @@ int main(int argc,char* argv[])
|
|||
if (nfc_initiator_transceive_bits(pndReader,abtReaderRx,szReaderRxBits,abtReaderRxPar,abtTagRx,&szTagRxBits,abtTagRxPar))
|
||||
{
|
||||
// Redirect the answer back to the reader
|
||||
nfc_target_send_bits(pndTag,abtTagRx,szTagRxBits,abtTagRxPar);
|
||||
if (!nfc_target_send_bits(pndTag,abtTagRx,szTagRxBits,abtTagRxPar)) {
|
||||
nfc_perror(pndTag, "nfc_target_send_bits");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Print the tag frame to the screen
|
||||
if(!quiet_output)
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include <nfc/nfc.h>
|
||||
#include <nfc/nfc-messages.h>
|
||||
#include "nfc-utils.h"
|
||||
// FIXME: Remove me
|
||||
#include "chips/pn53x.h"
|
||||
|
||||
#define MAX_FRAME_LEN 264
|
||||
#define TIMEOUT 60 // secs.
|
||||
|
@ -80,7 +82,8 @@ bool sam_connection(nfc_device_t* pnd, int mode)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!pnd->pdc->transceive(pnd->nds,pncmd_sam_config,szCmd,abtRx,&szRxLen)) {
|
||||
// FIXME: Direct call
|
||||
if (!pn53x_transceive(pnd,pncmd_sam_config,szCmd,abtRx,&szRxLen)) {
|
||||
ERR("%s %d", "Unable to execute SAMConfiguration command with mode byte:", mode);
|
||||
return false;
|
||||
}
|
||||
|
@ -164,17 +167,32 @@ int main(int argc, const char* argv[])
|
|||
nfc_initiator_init(pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure(pnd,NDO_INFINITE_SELECT,false);
|
||||
if (!nfc_configure(pnd,NDO_INFINITE_SELECT,false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,true);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_CRC,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_PARITY,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Read the SAM's info
|
||||
if (!nfc_initiator_select_passive_target(pnd,NM_ISO14443A_106,NULL,0,&nti)) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <nfc/nfc-messages.h>
|
||||
|
||||
#include "nfc-utils.h"
|
||||
// FIXME: Delete me
|
||||
#include "chips/pn53x.h"
|
||||
|
||||
#define MAX_DEVICE_COUNT 16
|
||||
|
@ -78,19 +79,22 @@ int main(int argc, const char* argv[])
|
|||
|
||||
printf("NFC device [%s] connected.\n",pnd->acName);
|
||||
|
||||
result = pnd->pdc->transceive(pnd->nds,pncmd_diagnose_communication_line_test,sizeof(pncmd_diagnose_communication_line_test),abtRx,&szRxLen);
|
||||
// FIXME: Direct call
|
||||
result = pn53x_transceive(pnd,pncmd_diagnose_communication_line_test,sizeof(pncmd_diagnose_communication_line_test),abtRx,&szRxLen);
|
||||
if ( result ) {
|
||||
result = (memcmp(pncmd_diagnose_communication_line_test+2, abtRx, sizeof(pncmd_diagnose_communication_line_test)-2 ) == 0);
|
||||
}
|
||||
printf(" Communication line test: %s\n", result ? "OK" : "Failed");
|
||||
|
||||
result = pnd->pdc->transceive(pnd->nds,pncmd_diagnose_rom_test,sizeof(pncmd_diagnose_rom_test),abtRx,&szRxLen);
|
||||
// FIXME: Direct call
|
||||
result = pn53x_transceive(pnd,pncmd_diagnose_rom_test,sizeof(pncmd_diagnose_rom_test),abtRx,&szRxLen);
|
||||
if ( result ) {
|
||||
result = ((szRxLen == 1) && (abtRx[0] == 0x00));
|
||||
}
|
||||
printf(" ROM test: %s\n", result ? "OK" : "Failed");
|
||||
|
||||
result = pnd->pdc->transceive(pnd->nds,pncmd_diagnose_ram_test,sizeof(pncmd_diagnose_ram_test),abtRx,&szRxLen);
|
||||
// FIXME: Direct call
|
||||
result = pn53x_transceive(pnd,pncmd_diagnose_ram_test,sizeof(pncmd_diagnose_ram_test),abtRx,&szRxLen);
|
||||
if ( result ) {
|
||||
result = ((szRxLen == 1) && (abtRx[0] == 0x00));
|
||||
}
|
||||
|
|
|
@ -69,6 +69,15 @@ typedef struct {
|
|||
bool bPar;
|
||||
/** The last tx bits setting, we need to reset this if it does not apply anymore */
|
||||
uint8_t ui8TxBits;
|
||||
/** Last error reported by the PCD / encountered by the PCD driver
|
||||
* MSB LSB
|
||||
* | 00 | 00 |
|
||||
* || ||
|
||||
* || ++----- Chip-level error (as reported by the PCD)
|
||||
* |+---------- Driver-level specific error
|
||||
* +----------- Driver-level general error (common to all drivers)
|
||||
*/
|
||||
int iLastError;
|
||||
} nfc_device_t;
|
||||
|
||||
|
||||
|
@ -91,6 +100,15 @@ typedef struct {
|
|||
uint32_t uiBusIndex;
|
||||
} nfc_device_desc_t;
|
||||
|
||||
/**
|
||||
* @struct chip_callbacks
|
||||
* @brief Functions for chip specific functions.
|
||||
*/
|
||||
struct chip_callbacks {
|
||||
/** Error lookup */
|
||||
const char* (*strerror) (const nfc_device_t *pnd);
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct driver_callbacks
|
||||
* @brief Generic structure to handle NFC device functions.
|
||||
|
@ -98,6 +116,8 @@ typedef struct {
|
|||
struct driver_callbacks {
|
||||
/** Driver name */
|
||||
const char* acDriver;
|
||||
/** Chip specific callback functions */
|
||||
const struct chip_callbacks *pcc;
|
||||
/** Pick devices callback */
|
||||
nfc_device_desc_t *(*pick_device)(void);
|
||||
/** List devices callback */
|
||||
|
@ -105,7 +125,7 @@ struct driver_callbacks {
|
|||
/** Connect callback */
|
||||
nfc_device_t* (*connect)(const nfc_device_desc_t* pndd);
|
||||
/** Transceive callback */
|
||||
bool (*transceive)(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool (*transceive)(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
/** Disconnect callback */
|
||||
void (*disconnect)(nfc_device_t* pnd);
|
||||
};
|
||||
|
|
|
@ -60,24 +60,29 @@ NFC_EXPORT void nfc_disconnect(nfc_device_t* pnd);
|
|||
NFC_EXPORT bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEnable);
|
||||
|
||||
/* 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_init(nfc_device_t* pnd);
|
||||
NFC_EXPORT bool nfc_initiator_select_passive_target(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(const 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(const nfc_device_t* pnd);
|
||||
NFC_EXPORT bool 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);
|
||||
NFC_EXPORT bool nfc_initiator_transceive_bytes(const 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(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
NFC_EXPORT bool nfc_initiator_poll_targets(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_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);
|
||||
|
||||
/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */
|
||||
NFC_EXPORT bool nfc_target_init(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits);
|
||||
NFC_EXPORT bool nfc_target_receive_bits(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
||||
NFC_EXPORT bool nfc_target_receive_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen);
|
||||
NFC_EXPORT bool nfc_target_receive_dep_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen);
|
||||
NFC_EXPORT bool nfc_target_send_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar);
|
||||
NFC_EXPORT bool nfc_target_send_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen);
|
||||
NFC_EXPORT bool nfc_target_send_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen);
|
||||
NFC_EXPORT bool nfc_target_init(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits);
|
||||
NFC_EXPORT bool nfc_target_receive_bits(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
||||
NFC_EXPORT bool nfc_target_receive_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen);
|
||||
NFC_EXPORT bool nfc_target_receive_dep_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen);
|
||||
NFC_EXPORT bool nfc_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar);
|
||||
NFC_EXPORT bool nfc_target_send_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen);
|
||||
NFC_EXPORT bool nfc_target_send_dep_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen);
|
||||
|
||||
/* Error reporting */
|
||||
NFC_EXPORT const char *nfc_strerror (const nfc_device_t *pnd);
|
||||
NFC_EXPORT int nfc_strerror_r (const nfc_device_t *pnd, char *pcStrErrBuf, size_t szBufLen);
|
||||
NFC_EXPORT void nfc_perror (const nfc_device_t *pnd, const char *pcString);
|
||||
|
||||
/* Special data accessors */
|
||||
NFC_EXPORT const char* nfc_device_name(nfc_device_t* pnd);
|
||||
|
@ -87,6 +92,11 @@ NFC_EXPORT void iso14443a_crc(byte_t* pbtData, size_t szLen, byte_t* pbtCrc);
|
|||
NFC_EXPORT void append_iso14443a_crc(byte_t* pbtData, size_t szLen);
|
||||
NFC_EXPORT const char* nfc_version(void);
|
||||
|
||||
/* Common device-level errors */
|
||||
#define DEIO 0x1000 /* Input/output error */
|
||||
#define DEINVAL 0x2000 /* Invalid argument */
|
||||
#define DETIMEOUT 0x3000 /* Operation timeout */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
|
|
@ -36,6 +36,7 @@ http://www.teuniz.net/RS-232/index.html
|
|||
|
||||
#include "uart.h"
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
// Test if we are dealing with unix operating systems
|
||||
|
@ -109,7 +110,7 @@ serial_port uart_open(const char* pcPortName)
|
|||
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||
{
|
||||
DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||
// Set port speed (Input and Output)
|
||||
const serial_port_unix* spu = (serial_port_unix*)sp;
|
||||
|
||||
// Portability note: on some systems, B9600 != 9600 so we have to do
|
||||
// uint32_t <=> speed_t associations by hand.
|
||||
|
@ -140,16 +141,17 @@ void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
|||
default:
|
||||
ERR("Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).", uiPortSpeed);
|
||||
};
|
||||
const serial_port_unix* spu = (serial_port_unix*)sp;
|
||||
cfsetispeed((struct termios*)&spu->tiNew, stPortSpeed);
|
||||
cfsetospeed((struct termios*)&spu->tiNew, stPortSpeed);
|
||||
if( tcsetattr(spu->fd, TCSADRAIN, &spu->tiNew) == -1)
|
||||
|
||||
// Set port speed (Input and Output)
|
||||
cfsetispeed((struct termios*)&(spu->tiNew), stPortSpeed);
|
||||
cfsetospeed((struct termios*)&(spu->tiNew), stPortSpeed);
|
||||
if( tcsetattr(spu->fd, TCSADRAIN, &(spu->tiNew)) == -1)
|
||||
{
|
||||
ERR("%s", "Unable to apply new speed settings.");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t uart_get_speed(const serial_port sp)
|
||||
uint32_t uart_get_speed(serial_port sp)
|
||||
{
|
||||
uint32_t uiPortSpeed = 0;
|
||||
const serial_port_unix* spu = (serial_port_unix*)sp;
|
||||
|
@ -191,7 +193,13 @@ void uart_close(const serial_port sp)
|
|||
free(sp);
|
||||
}
|
||||
|
||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||
/**
|
||||
* @brief Receive data from UART and copy data to \a pbtRx
|
||||
*
|
||||
* @return 0 on success, otherwise driver error code
|
||||
*/
|
||||
int
|
||||
uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
int res;
|
||||
int byteCount;
|
||||
|
@ -211,7 +219,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
// Read error
|
||||
if (res < 0) {
|
||||
DBG("%s", "RX error.");
|
||||
return false;
|
||||
return DEIO;
|
||||
}
|
||||
|
||||
// Read time-out
|
||||
|
@ -219,31 +227,41 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
if (*pszRxLen == 0) {
|
||||
// Error, we received no data
|
||||
DBG("%s", "RX time-out, buffer empty.");
|
||||
return false;
|
||||
return DETIMEOUT;
|
||||
} else {
|
||||
// We received some data, but nothing more is available
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve the count of the incoming bytes
|
||||
res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount);
|
||||
if (res < 0) return false;
|
||||
if (res < 0) {
|
||||
return DEIO;
|
||||
}
|
||||
|
||||
// There is something available, read the data
|
||||
res = read(((serial_port_unix*)sp)->fd,pbtRx+(*pszRxLen),byteCount);
|
||||
|
||||
// Stop if the OS has some troubles reading the data
|
||||
if (res <= 0) return false;
|
||||
if (res <= 0) {
|
||||
return DEIO;
|
||||
}
|
||||
|
||||
*pszRxLen += res;
|
||||
|
||||
} while (byteCount);
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||
/**
|
||||
* @brief Send \a pbtTx content to UART
|
||||
*
|
||||
* @return 0 on success, otherwise a driver error is returned
|
||||
*/
|
||||
int
|
||||
uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||
{
|
||||
int32_t res;
|
||||
size_t szPos = 0;
|
||||
|
@ -261,24 +279,26 @@ bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
|||
// Write error
|
||||
if (res < 0) {
|
||||
DBG("%s", "TX error.");
|
||||
return false;
|
||||
return DEIO;
|
||||
}
|
||||
|
||||
// Write time-out
|
||||
if (res == 0) {
|
||||
DBG("%s", "TX time-out.");
|
||||
return false;
|
||||
return DETIMEOUT;
|
||||
}
|
||||
|
||||
// Send away the bytes
|
||||
res = write(((serial_port_unix*)sp)->fd,pbtTx+szPos,szTxLen-szPos);
|
||||
|
||||
// Stop if the OS has some troubles sending the data
|
||||
if (res <= 0) return false;
|
||||
if (res <= 0) {
|
||||
return DEIO;
|
||||
}
|
||||
|
||||
szPos += res;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -384,17 +404,25 @@ uint32_t uart_get_speed(const serial_port sp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||
int uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,*pszRxLen,(LPDWORD)pszRxLen,NULL);
|
||||
return (*pszRxLen != 0);
|
||||
if (!ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,*pszRxLen,(LPDWORD)pszRxLen,NULL)) {
|
||||
return DEIO;
|
||||
}
|
||||
if (!*pszRxLen)
|
||||
return DEIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||
int uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||
{
|
||||
DWORD dwTxLen = 0;
|
||||
return WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL);
|
||||
return (dwTxLen != 0);
|
||||
if (!WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL)) {
|
||||
return DEIO;
|
||||
}
|
||||
if (!dwTxLen)
|
||||
return DEIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
|
|
@ -84,9 +84,8 @@ void uart_close(const serial_port sp);
|
|||
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
|
||||
uint32_t uart_get_speed(const serial_port sp);
|
||||
|
||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen);
|
||||
int uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen);
|
||||
int uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen);
|
||||
|
||||
#endif // __NFC_BUS_UART_H__
|
||||
|
||||
|
||||
|
|
|
@ -26,9 +26,14 @@
|
|||
#include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
// FIXME: WTF are doing debug macros in this file?
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
#include "pn53x.h"
|
||||
#include "../mirror-subr.h"
|
||||
|
@ -61,8 +66,48 @@ const byte_t pncmd_target_receive [ 2] = { 0xD4,0x88 };
|
|||
const byte_t pncmd_target_send [264] = { 0xD4,0x90 };
|
||||
const byte_t pncmd_target_get_status [ 2] = { 0xD4,0x8A };
|
||||
|
||||
static const byte_t pn53x_ack_frame[] = { 0x00,0x00,0xff,0x00,0xff,0x00 };
|
||||
static const byte_t pn53x_nack_frame[] = { 0x00,0x00,0xff,0xff,0x00,0x00 };
|
||||
static const byte_t pn53x_error_frame[] = { 0x00,0x00,0xff,0x01,0xff,0x7f,0x81,0x00 };
|
||||
|
||||
bool pn53x_transceive(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
// XXX: Is this function correctly named ?
|
||||
bool pn53x_transceive_check_ack_frame_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen)
|
||||
{
|
||||
if (szRxFrameLen >= sizeof (pn53x_ack_frame)) {
|
||||
if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) {
|
||||
DBG("%s", "PN53x ACKed");
|
||||
return true;
|
||||
} else if (0 == memcmp (pbtRxFrame, pn53x_nack_frame, sizeof (pn53x_nack_frame))) {
|
||||
DBG("%s", "PN53x NACKed");
|
||||
// TODO: Try to recover
|
||||
// A counter could allow the command to be sent again (e.g. max 3 times)
|
||||
pnd->iLastError = DENACK;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pnd->iLastError = DEACKMISMATCH;
|
||||
ERR("%s", "Unexpected PN53x reply!");
|
||||
#if defined(DEBUG)
|
||||
// coredump so that we can have a backtrace about how this code was reached.
|
||||
abort();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pn53x_transceive_check_error_frame_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen)
|
||||
{
|
||||
if (szRxFrameLen >= sizeof (pn53x_error_frame)) {
|
||||
if (0 == memcmp (pbtRxFrame, pn53x_error_frame, sizeof (pn53x_error_frame))) {
|
||||
DBG("%s", "PN53x sent an error frame");
|
||||
pnd->iLastError = DEISERRFRAME;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pn53x_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
@ -76,17 +121,35 @@ bool pn53x_transceive(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
|||
|
||||
*pszRxLen = MAX_FRAME_LEN;
|
||||
// Call the tranceive callback function of the current device
|
||||
if (!pnd->pdc->transceive(pnd->nds,pbtTx,szTxLen,pbtRx,pszRxLen)) return false;
|
||||
if (!pnd->pdc->transceive(pnd,pbtTx,szTxLen,pbtRx,pszRxLen)) return false;
|
||||
|
||||
// Make sure there was no failure reported by the PN53X chip (0x00 == OK)
|
||||
// FIXME (0x00 == OK) is not always true...
|
||||
if (pbtRx[0] != 0) return false;
|
||||
|
||||
// Succesful transmission
|
||||
return true;
|
||||
switch (pbtTx[1]) {
|
||||
case 0x16: // PowerDown
|
||||
case 0x40: // InDataExchange
|
||||
case 0x42: // InCommunicateThru
|
||||
case 0x44: // InDeselect
|
||||
case 0x46: // InJumpForPSL
|
||||
case 0x4e: // InPSL
|
||||
case 0x50: // InATR
|
||||
case 0x52: // InRelease
|
||||
case 0x54: // InSelect
|
||||
case 0x56: // InJumpForDEP
|
||||
case 0x86: // TgGetData
|
||||
case 0x88: // TgGetInitiatorCommand
|
||||
case 0x8e: // TgSetData
|
||||
case 0x90: // TgResponseToInitiator
|
||||
case 0x92: // TgSetGeneralBytes
|
||||
case 0x94: // TgSetMetaData
|
||||
pnd->iLastError = pbtRx[0] & 0x3f;
|
||||
break;
|
||||
default:
|
||||
pnd->iLastError = 0;
|
||||
}
|
||||
|
||||
byte_t pn53x_get_reg(const nfc_device_t* pnd, uint16_t ui16Reg)
|
||||
return (0 == pnd->iLastError);
|
||||
}
|
||||
|
||||
byte_t pn53x_get_reg(nfc_device_t* pnd, uint16_t ui16Reg)
|
||||
{
|
||||
uint8_t ui8Value;
|
||||
size_t szValueLen = 1;
|
||||
|
@ -95,12 +158,11 @@ byte_t pn53x_get_reg(const nfc_device_t* pnd, uint16_t ui16Reg)
|
|||
|
||||
abtCmd[2] = ui16Reg >> 8;
|
||||
abtCmd[3] = ui16Reg & 0xff;
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
pnd->pdc->transceive(pnd->nds,abtCmd,4,&ui8Value,&szValueLen);
|
||||
pn53x_transceive(pnd,abtCmd,4,&ui8Value,&szValueLen);
|
||||
return ui8Value;
|
||||
}
|
||||
|
||||
bool pn53x_set_reg(const nfc_device_t* pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value)
|
||||
bool pn53x_set_reg(nfc_device_t* pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value)
|
||||
{
|
||||
byte_t abtCmd[sizeof(pncmd_set_register)];
|
||||
memcpy(abtCmd,pncmd_set_register,sizeof(pncmd_set_register));
|
||||
|
@ -108,21 +170,19 @@ bool pn53x_set_reg(const nfc_device_t* pnd, uint16_t ui16Reg, uint8_t ui8SybmolM
|
|||
abtCmd[2] = ui16Reg >> 8;
|
||||
abtCmd[3] = ui16Reg & 0xff;
|
||||
abtCmd[4] = ui8Value | (pn53x_get_reg(pnd,ui16Reg) & (~ui8SybmolMask));
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
return pnd->pdc->transceive(pnd->nds,abtCmd,5,NULL,NULL);
|
||||
return pn53x_transceive(pnd,abtCmd,5,NULL,NULL);
|
||||
}
|
||||
|
||||
bool pn53x_set_parameters(const nfc_device_t* pnd, uint8_t ui8Value)
|
||||
bool pn53x_set_parameters(nfc_device_t* pnd, uint8_t ui8Value)
|
||||
{
|
||||
byte_t abtCmd[sizeof(pncmd_set_parameters)];
|
||||
memcpy(abtCmd,pncmd_set_parameters,sizeof(pncmd_set_parameters));
|
||||
|
||||
abtCmd[2] = ui8Value;
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
return pnd->pdc->transceive(pnd->nds,abtCmd,3,NULL,NULL);
|
||||
return pn53x_transceive(pnd,abtCmd,3,NULL,NULL);
|
||||
}
|
||||
|
||||
bool pn53x_set_tx_bits(const nfc_device_t* pnd, uint8_t ui8Bits)
|
||||
bool pn53x_set_tx_bits(nfc_device_t* pnd, uint8_t ui8Bits)
|
||||
{
|
||||
// Test if we need to update the transmission bits register setting
|
||||
if (pnd->ui8TxBits != ui8Bits)
|
||||
|
@ -362,7 +422,7 @@ pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_chip_t
|
|||
* @note To decode theses TargetData[n], there is @fn pn53x_decode_target_data
|
||||
*/
|
||||
bool
|
||||
pn53x_InListPassiveTarget(const nfc_device_t* pnd,
|
||||
pn53x_InListPassiveTarget(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)
|
||||
|
@ -380,8 +440,7 @@ pn53x_InListPassiveTarget(const nfc_device_t* pnd,
|
|||
|
||||
// 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+szInitiatorDataLen,pbtTargetsData,&szRxLen)) {
|
||||
if(pn53x_transceive(pnd,abtCmd,4+szInitiatorDataLen,pbtTargetsData,&szRxLen)) {
|
||||
*pszTargetsData = szRxLen;
|
||||
return true;
|
||||
} else {
|
||||
|
@ -390,7 +449,7 @@ pn53x_InListPassiveTarget(const nfc_device_t* pnd,
|
|||
}
|
||||
|
||||
bool
|
||||
pn53x_InDeselect(const nfc_device_t* pnd, const uint8_t ui8Target)
|
||||
pn53x_InDeselect(nfc_device_t* pnd, const uint8_t ui8Target)
|
||||
{
|
||||
byte_t abtCmd[sizeof(pncmd_initiator_deselect)];
|
||||
memcpy(abtCmd,pncmd_initiator_deselect,sizeof(pncmd_initiator_deselect));
|
||||
|
@ -410,18 +469,19 @@ pn53x_InRelease(nfc_device_t* pnd, const uint8_t ui8Target)
|
|||
}
|
||||
|
||||
bool
|
||||
pn53x_InAutoPoll(const nfc_device_t* pnd,
|
||||
pn53x_InAutoPoll(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];
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
bool res;
|
||||
byte_t *pbtTxInAutoPoll;
|
||||
|
||||
if(pnd->nc == NC_PN531) {
|
||||
// TODO This function is not supported by pn531 (set errno = ENOSUPP or similar)
|
||||
if(pnd->nc != NC_PN532) {
|
||||
// This function is not supported by pn531 neither pn533
|
||||
pnd->iLastError = DENOTSUP;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -436,8 +496,8 @@ pn53x_InAutoPoll(const nfc_device_t* pnd,
|
|||
pbtTxInAutoPoll[4+n] = pnttTargetTypes[n];
|
||||
}
|
||||
|
||||
szRxLen = 256;
|
||||
res = pnd->pdc->transceive(pnd->nds, pbtTxInAutoPoll, szTxInAutoPoll, abtRx, &szRxLen);
|
||||
szRxLen = MAX_FRAME_LEN;
|
||||
res = pnd->pdc->transceive(pnd, pbtTxInAutoPoll, szTxInAutoPoll, abtRx, &szRxLen);
|
||||
|
||||
if((szRxLen == 0)||(res == false)) {
|
||||
return false;
|
||||
|
@ -466,3 +526,67 @@ pn53x_InAutoPoll(const nfc_device_t* pnd,
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct sErrorMessage {
|
||||
int iErrorCode;
|
||||
const char *pcErrorMsg;
|
||||
} sErrorMessages[] = {
|
||||
/* Chip-level errors */
|
||||
{ 0x00, "Success" },
|
||||
{ 0x01, "Timeout" },
|
||||
{ 0x02, "CRC Error" },
|
||||
{ 0x03, "Parity Error" },
|
||||
{ 0x04, "Erroneous Bit Count" },
|
||||
{ 0x05, "Framing Error" },
|
||||
{ 0x06, "Bit-collision" },
|
||||
{ 0x07, "Buffer Too Small" },
|
||||
{ 0x09, "Buffer Overflow" },
|
||||
{ 0x0a, "Timeout" },
|
||||
{ 0x0b, "Protocol Error" },
|
||||
{ 0x0d, "Overheating" },
|
||||
{ 0x0e, "Internal Buffer overflow." },
|
||||
{ 0x10, "Invalid Parameter" },
|
||||
/* DEP Errors */
|
||||
{ 0x12, "Unknown DEP Command" },
|
||||
{ 0x13, "Invalid Parameter" },
|
||||
/* MIFARE */
|
||||
{ 0x14, "Authentication Error" },
|
||||
/* */
|
||||
{ 0x23, "Wrong ISO/IEC14443-3 Check Byte" },
|
||||
{ 0x25, "Invalid State" },
|
||||
{ 0x26, "Operation Not Allowed" },
|
||||
{ 0x27, "Command Not Acceptable" },
|
||||
{ 0x29, "Target Released" },
|
||||
{ 0x2a, "Card ID Mismatch" },
|
||||
{ 0x2B, "Card Discarded" },
|
||||
{ 0x2C, "NFCID3 Mismatch" },
|
||||
{ 0x2D, "Over Current" },
|
||||
{ 0x2E, "NAD Missing in DEP Frame" },
|
||||
|
||||
/* Driver-level error */
|
||||
{ DENACK, "Received NACK" },
|
||||
{ DEACKMISMATCH, "Expected ACK/NACK" },
|
||||
{ DEISERRFRAME, "Received an error frame" },
|
||||
/* TODO: Move me in more generic code for libnfc 1.6 */
|
||||
{ DEINVAL, "Invalid argument" },
|
||||
{ DEIO, "Input/output error" },
|
||||
{ DETIMEOUT, "Operation timed-out" },
|
||||
{ DENOTSUP, "Operation not supported" }
|
||||
};
|
||||
|
||||
const char *
|
||||
pn53x_strerror (const nfc_device_t *pnd)
|
||||
{
|
||||
const char *pcRes = "Unknown error";
|
||||
size_t i;
|
||||
|
||||
for (i=0; i < (sizeof (sErrorMessages) / sizeof (struct sErrorMessage)); i++) {
|
||||
if (sErrorMessages[i].iErrorCode == pnd->iLastError) {
|
||||
pcRes = sErrorMessages[i].pcErrorMsg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pcRes;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,19 +72,33 @@
|
|||
#define RFCI_ANALOG_TYPE_B 0x0C // 3
|
||||
#define RFCI_ANALOG_TYPE_14443_4 0x0D // 9
|
||||
|
||||
bool pn53x_transceive(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
byte_t pn53x_get_reg(const nfc_device_t* pnd, uint16_t ui16Reg);
|
||||
bool pn53x_set_reg(const nfc_device_t* pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value);
|
||||
bool pn53x_set_parameters(const nfc_device_t* pnd, uint8_t ui8Value);
|
||||
bool pn53x_set_tx_bits(const nfc_device_t* pnd, uint8_t ui8Bits);
|
||||
/* PN53x specific device-level errors */
|
||||
#define DENACK 0x0100 /* NACK */
|
||||
#define DEACKMISMATCH 0x0200 /* Unexpected data */
|
||||
#define DEISERRFRAME 0x0300 /* Error frame */
|
||||
#define DENOTSUP 0x0400 /* Not supported */
|
||||
|
||||
bool pn53x_transceive_check_ack_frame_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen);
|
||||
bool pn53x_transceive_check_error_frame_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen);
|
||||
bool pn53x_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
byte_t pn53x_get_reg(nfc_device_t* pnd, uint16_t ui16Reg);
|
||||
bool pn53x_set_reg(nfc_device_t* pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value);
|
||||
bool pn53x_set_parameters(nfc_device_t* pnd, uint8_t ui8Value);
|
||||
bool pn53x_set_tx_bits(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, byte_t* pbtTargetsData, size_t* pszTargetsData);
|
||||
bool pn53x_InDeselect(const nfc_device_t* pnd, const uint8_t ui8Target);
|
||||
bool pn53x_InListPassiveTarget(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(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);
|
||||
bool pn53x_InAutoPoll(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);
|
||||
|
||||
const char *pn53x_strerror (const nfc_device_t *pnd);
|
||||
|
||||
static const struct chip_callbacks pn53x_callbacks_list = {
|
||||
pn53x_strerror
|
||||
};
|
||||
|
||||
#endif // __NFC_CHIPS_PN53X_H__
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include <nfc/nfc-types.h>
|
||||
|
||||
#include "chips/pn53x.h"
|
||||
|
||||
#if defined (DRIVER_ACR122_ENABLED)
|
||||
#include "drivers/acr122.h"
|
||||
#endif /* DRIVER_ACR122_ENABLED */
|
||||
|
@ -55,21 +57,21 @@
|
|||
#define MAX_FRAME_LEN 264
|
||||
|
||||
static const struct driver_callbacks drivers_callbacks_list[] = {
|
||||
// Driver Name Pick Device List Devices Connect Transceive Disconnect
|
||||
// Driver Name Chip callbacks Pick Device List Devices Connect Transceive Disconnect
|
||||
#if defined (DRIVER_ACR122_ENABLED)
|
||||
{ ACR122_DRIVER_NAME, acr122_pick_device, acr122_list_devices, acr122_connect, acr122_transceive, acr122_disconnect },
|
||||
{ ACR122_DRIVER_NAME, &pn53x_callbacks_list, acr122_pick_device, acr122_list_devices, acr122_connect, acr122_transceive, acr122_disconnect },
|
||||
#endif /* DRIVER_ACR122_ENABLED */
|
||||
#if defined (DRIVER_PN531_USB_ENABLED)
|
||||
{ PN531_USB_DRIVER_NAME, pn531_usb_pick_device, pn531_usb_list_devices, pn531_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
||||
{ PN531_USB_DRIVER_NAME, &pn53x_callbacks_list, pn531_usb_pick_device, pn531_usb_list_devices, pn531_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
||||
#endif /* DRIVER_PN531_USB_ENABLED */
|
||||
#if defined (DRIVER_PN533_USB_ENABLED)
|
||||
{ PN533_USB_DRIVER_NAME, pn533_usb_pick_device, pn533_usb_list_devices, pn533_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
||||
{ PN533_USB_DRIVER_NAME, &pn53x_callbacks_list, pn533_usb_pick_device, pn533_usb_list_devices, pn533_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
||||
#endif /* DRIVER_PN533_USB_ENABLED */
|
||||
#if defined (DRIVER_ARYGON_ENABLED)
|
||||
{ ARYGON_DRIVER_NAME, arygon_pick_device, arygon_list_devices, arygon_connect, arygon_transceive, arygon_disconnect },
|
||||
{ ARYGON_DRIVER_NAME, &pn53x_callbacks_list, arygon_pick_device, arygon_list_devices, arygon_connect, arygon_transceive, arygon_disconnect },
|
||||
#endif /* DRIVER_ARYGON_ENABLED */
|
||||
#if defined (DRIVER_PN532_UART_ENABLED)
|
||||
{ PN532_UART_DRIVER_NAME, pn532_uart_pick_device, pn532_uart_list_devices, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect },
|
||||
{ PN532_UART_DRIVER_NAME, &pn53x_callbacks_list, pn532_uart_pick_device, pn532_uart_list_devices, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect },
|
||||
#endif /* DRIVER_PN532_UART_ENABLED */
|
||||
};
|
||||
|
||||
|
|
|
@ -255,14 +255,14 @@ void acr122_disconnect(nfc_device_t* pnd)
|
|||
free(pnd);
|
||||
}
|
||||
|
||||
bool acr122_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool acr122_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtRxCmd[5] = { 0xFF,0xC0,0x00,0x00 };
|
||||
size_t szRxCmdLen = sizeof(abtRxCmd);
|
||||
byte_t abtRxBuf[ACR122_RESPONSE_LEN];
|
||||
size_t szRxBufLen;
|
||||
byte_t abtTxBuf[ACR122_WRAP_LEN+ACR122_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00 };
|
||||
acr122_spec_t* pas = (acr122_spec_t*)nds;
|
||||
acr122_spec_t* pas = (acr122_spec_t*)pnd->nds;
|
||||
|
||||
// Make sure the command does not overflow the send buffer
|
||||
if (szTxLen > ACR122_COMMAND_LEN) return false;
|
||||
|
|
|
@ -40,7 +40,7 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd);
|
|||
void acr122_disconnect(nfc_device_t* pnd);
|
||||
|
||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||
bool acr122_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool acr122_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
// Various additional features this device supports
|
||||
char* acr122_firmware(const nfc_device_spec_t nds);
|
||||
|
|
|
@ -113,7 +113,7 @@ arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
|||
const char* pcPort;
|
||||
int iDevice = 0;
|
||||
|
||||
while( pcPort = pcPorts[iDevice++] ) {
|
||||
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);
|
||||
|
||||
|
@ -180,15 +180,14 @@ void arygon_disconnect(nfc_device_t* pnd)
|
|||
free(pnd);
|
||||
}
|
||||
|
||||
bool arygon_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool arygon_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtTxBuf[BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRxBuf[BUFFER_LENGTH];
|
||||
size_t szRxBufLen = BUFFER_LENGTH;
|
||||
size_t szPos;
|
||||
|
||||
const byte_t pn53x_ack_frame[] = { 0x00,0x00,0xff,0x00,0xff,0x00 };
|
||||
const byte_t pn53x_nack_frame[] = { 0x00,0x00,0xff,0xff,0x00,0x00 };
|
||||
// TODO: Move this one level up for libnfc-1.6
|
||||
uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||
|
||||
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
|
||||
abtTxBuf[4] = szTxLen;
|
||||
|
@ -210,12 +209,13 @@ bool arygon_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const s
|
|||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", abtTxBuf,szTxLen+8);
|
||||
#endif
|
||||
if (!uart_send((serial_port)nds,abtTxBuf,szTxLen+8)) {
|
||||
if (!uart_send((serial_port)pnd->nds,abtTxBuf,szTxLen+8)) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) {
|
||||
szRxBufLen = 6;
|
||||
if (!uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
return false;
|
||||
}
|
||||
|
@ -224,36 +224,31 @@ bool arygon_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const s
|
|||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||
#endif
|
||||
|
||||
if(szRxBufLen >= sizeof(pn53x_ack_frame)) {
|
||||
|
||||
// Check if PN53x reply ACK
|
||||
if(0!=memcmp(pn53x_ack_frame, abtRxBuf, sizeof(pn53x_ack_frame))) {
|
||||
DBG("%s", "PN53x doesn't respond ACK frame.");
|
||||
if (0==memcmp(pn53x_nack_frame, abtRxBuf, sizeof(pn53x_nack_frame))) {
|
||||
ERR("%s", "PN53x reply NACK frame.");
|
||||
// FIXME Handle NACK frame i.e. resend frame, PN53x doesn't received it correctly
|
||||
}
|
||||
if (!pn53x_transceive_check_ack_frame_callback(pnd, abtRxBuf, szRxBufLen))
|
||||
return false;
|
||||
}
|
||||
|
||||
szRxBufLen -= sizeof(pn53x_ack_frame);
|
||||
if(szRxBufLen) {
|
||||
memmove(abtRxBuf, abtRxBuf+sizeof(pn53x_ack_frame), szRxBufLen);
|
||||
}
|
||||
}
|
||||
szRxBufLen = BUFFER_LENGTH;
|
||||
|
||||
if(szRxBufLen == 0) {
|
||||
// There was no more data than ACK frame, we need to wait next frame
|
||||
DBG("%s", "There was no more data than ACK frame, we need to wait next frame");
|
||||
while (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) {
|
||||
while (!uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen)) {
|
||||
delay_ms(10);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", ack_frame, 6);
|
||||
#endif
|
||||
if (!uart_send((serial_port)pnd->nds, ack_frame, 6)) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pn53x_transceive_check_error_frame_callback(pnd, abtRxBuf, szRxBufLen))
|
||||
return false;
|
||||
|
||||
// When the answer should be ignored, just return a successful result
|
||||
if(pbtRx == NULL || pszRxLen == NULL) return true;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd);
|
|||
void arygon_disconnect(nfc_device_t* pnd);
|
||||
|
||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||
bool arygon_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool arygon_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
#endif // ! __NFC_DRIVER_ARYGON_H__
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "pn532_uart.h"
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
// Bus
|
||||
|
@ -43,7 +44,7 @@
|
|||
#define SERIAL_DEFAULT_PORT_SPEED 115200
|
||||
|
||||
void pn532_uart_wakeup(const nfc_device_spec_t nds);
|
||||
bool pn532_uart_check_communication(const nfc_device_spec_t nds);
|
||||
bool pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success);
|
||||
|
||||
nfc_device_desc_t *
|
||||
pn532_uart_pick_device (void)
|
||||
|
@ -87,18 +88,22 @@ pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_
|
|||
const char* pcPort;
|
||||
int iDevice = 0;
|
||||
|
||||
while( pcPort = pcPorts[iDevice++] ) {
|
||||
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);
|
||||
|
||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT))
|
||||
{
|
||||
bool bComOk;
|
||||
// Serial port claimed but we need to check if a PN532_UART is connected.
|
||||
uart_set_speed(sp, SERIAL_DEFAULT_PORT_SPEED);
|
||||
// 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)
|
||||
if(!pn532_uart_check_communication((nfc_device_spec_t)sp)) continue;
|
||||
if(!pn532_uart_check_communication((nfc_device_spec_t)sp, &bComOk))
|
||||
return false;
|
||||
if (!bComOk)
|
||||
continue;
|
||||
uart_close(sp);
|
||||
|
||||
snprintf(pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", pcPort);
|
||||
|
@ -125,6 +130,7 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
{
|
||||
serial_port sp;
|
||||
nfc_device_t* pnd = NULL;
|
||||
bool bComOk;
|
||||
|
||||
DBG("Attempt to connect to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
sp = uart_open(pndd->pcPort);
|
||||
|
@ -138,7 +144,10 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
// 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)
|
||||
if(!pn532_uart_check_communication((nfc_device_spec_t)sp)) return NULL;
|
||||
if(!pn532_uart_check_communication((nfc_device_spec_t)sp, &bComOk))
|
||||
return NULL;
|
||||
if (!bComOk)
|
||||
return NULL;
|
||||
|
||||
DBG("Successfully connected to: %s",pndd->pcPort);
|
||||
|
||||
|
@ -162,14 +171,15 @@ void pn532_uart_disconnect(nfc_device_t* pnd)
|
|||
free(pnd);
|
||||
}
|
||||
|
||||
bool pn532_uart_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtTxBuf[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRxBuf[BUFFER_LENGTH];
|
||||
size_t szRxBufLen = BUFFER_LENGTH;
|
||||
size_t szPos;
|
||||
const byte_t pn53x_ack_frame[] = { 0x00,0x00,0xff,0x00,0xff,0x00 };
|
||||
const byte_t pn53x_nack_frame[] = { 0x00,0x00,0xff,0xff,0x00,0x00 };
|
||||
int res;
|
||||
// TODO: Move this one level up for libnfc-1.6
|
||||
uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||
|
||||
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
|
||||
abtTxBuf[3] = szTxLen;
|
||||
|
@ -191,13 +201,18 @@ bool pn532_uart_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, con
|
|||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", abtTxBuf,szTxLen+7);
|
||||
#endif
|
||||
if (!uart_send((serial_port)nds,abtTxBuf,szTxLen+7)) {
|
||||
res = uart_send((serial_port)pnd->nds,abtTxBuf,szTxLen+7);
|
||||
if(res != 0) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
pnd->iLastError = res;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) {
|
||||
szRxBufLen = 6;
|
||||
res = uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen);
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
pnd->iLastError = res;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -205,40 +220,45 @@ bool pn532_uart_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, con
|
|||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||
#endif
|
||||
|
||||
if(szRxBufLen >= sizeof(pn53x_ack_frame)) {
|
||||
|
||||
// Check if PN53x reply ACK
|
||||
if(0!=memcmp(pn53x_ack_frame, abtRxBuf, sizeof(pn53x_ack_frame))) {
|
||||
DBG("%s", "PN53x doesn't respond ACK frame.");
|
||||
if (0==memcmp(pn53x_nack_frame, abtRxBuf, sizeof(pn53x_nack_frame))) {
|
||||
ERR("%s", "PN53x reply NACK frame.");
|
||||
// FIXME Handle NACK frame i.e. resend frame, PN53x doesn't received it correctly
|
||||
}
|
||||
// WARN: UART is a per byte reception, so you usually receive ACK and next frame the same time
|
||||
if (!pn53x_transceive_check_ack_frame_callback(pnd, abtRxBuf, szRxBufLen))
|
||||
return false;
|
||||
}
|
||||
|
||||
szRxBufLen -= sizeof(pn53x_ack_frame);
|
||||
if(szRxBufLen) {
|
||||
memmove(abtRxBuf, abtRxBuf+sizeof(pn53x_ack_frame), szRxBufLen);
|
||||
}
|
||||
}
|
||||
szRxBufLen -= sizeof(ack_frame);
|
||||
memmove(abtRxBuf, abtRxBuf+sizeof(ack_frame), szRxBufLen);
|
||||
|
||||
if (szRxBufLen == 0) {
|
||||
// There was no more data than ACK frame, we need to wait next frame
|
||||
DBG("%s", "There was no more data than ACK frame, we need to wait next frame");
|
||||
while (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) {
|
||||
szRxBufLen = BUFFER_LENGTH;
|
||||
do {
|
||||
delay_ms(10);
|
||||
}
|
||||
res = uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen);
|
||||
} while (res != 0 );
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", ack_frame,6);
|
||||
#endif
|
||||
res = uart_send((serial_port)pnd->nds,ack_frame,6);
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
pnd->iLastError = res;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pn53x_transceive_check_error_frame_callback (pnd, abtRxBuf, szRxBufLen))
|
||||
return false;
|
||||
|
||||
// When the answer should be ignored, just return a successful result
|
||||
if(pbtRx == NULL || pszRxLen == NULL) return true;
|
||||
|
||||
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
|
||||
if(szRxBufLen < 9) return false;
|
||||
if(szRxBufLen < 9) {
|
||||
pnd->iLastError = DEINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
||||
*pszRxLen = szRxBufLen - 9;
|
||||
|
@ -260,7 +280,7 @@ pn532_uart_wakeup(const nfc_device_spec_t nds)
|
|||
PRINT_HEX("TX", pncmd_pn532c106_wakeup_preamble,sizeof(pncmd_pn532c106_wakeup_preamble));
|
||||
#endif
|
||||
uart_send((serial_port)nds, pncmd_pn532c106_wakeup_preamble, sizeof(pncmd_pn532c106_wakeup_preamble));
|
||||
if(uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
||||
if(0 == uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRx,szRxLen);
|
||||
#endif
|
||||
|
@ -268,7 +288,7 @@ pn532_uart_wakeup(const nfc_device_spec_t nds)
|
|||
}
|
||||
|
||||
bool
|
||||
pn532_uart_check_communication(const nfc_device_spec_t nds)
|
||||
pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success)
|
||||
{
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
size_t szRxLen;
|
||||
|
@ -277,22 +297,24 @@ pn532_uart_check_communication(const nfc_device_spec_t nds)
|
|||
/** To be sure that PN532 is alive, we have put a "Diagnose" command to execute a "Communication Line Test" */
|
||||
const byte_t pncmd_communication_test[] = { 0x00,0x00,0xff,0x09,0xf7,0xd4,0x00,0x00,'l','i','b','n','f','c',0xbe,0x00 };
|
||||
|
||||
*success = false;
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", pncmd_communication_test,sizeof(pncmd_communication_test));
|
||||
#endif
|
||||
uart_send((serial_port)nds, pncmd_communication_test, sizeof(pncmd_communication_test));
|
||||
if (0 != uart_send((serial_port)nds, pncmd_communication_test, sizeof(pncmd_communication_test)))
|
||||
return false;
|
||||
|
||||
if(!uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
||||
if (0 != uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
||||
return false;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRx,szRxLen);
|
||||
#endif
|
||||
|
||||
if(0 != memcmp(abtRx,attempted_result,sizeof(attempted_result))) {
|
||||
DBG("%s", "Communication test failed, result doesn't match to attempted one.");
|
||||
return false;
|
||||
}
|
||||
if(0 == memcmp(abtRx,attempted_result,sizeof(attempted_result)))
|
||||
*success = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd);
|
|||
void pn532_uart_disconnect(nfc_device_t* pnd);
|
||||
|
||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||
bool pn532_uart_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
#endif // ! __NFC_DRIVER_PN532_UART_H__
|
||||
|
||||
|
|
|
@ -37,7 +37,9 @@ Thanks to d18c7db and Okko for example code
|
|||
#include <string.h>
|
||||
|
||||
#include "../drivers.h"
|
||||
#include "../chips/pn53x.h"
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
#define BUFFER_LENGTH 256
|
||||
|
@ -232,13 +234,14 @@ void pn53x_usb_disconnect(nfc_device_t* pnd)
|
|||
free(pnd);
|
||||
}
|
||||
|
||||
bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
size_t uiPos = 0;
|
||||
int ret = 0;
|
||||
byte_t abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
usb_spec_t* pus = (usb_spec_t*)nds;
|
||||
usb_spec_t* pus = (usb_spec_t*)pnd->nds;
|
||||
// TODO: Move this one level up for libnfc-1.6
|
||||
uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||
|
||||
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
|
||||
|
@ -266,6 +269,7 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
if( ret < 0 )
|
||||
{
|
||||
DBG("usb_bulk_write failed with error %d", ret);
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -273,6 +277,7 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
if( ret < 0 )
|
||||
{
|
||||
DBG( "usb_bulk_read failed with error %d", ret);
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -280,27 +285,29 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
PRINT_HEX("RX", abtRx,ret);
|
||||
#endif
|
||||
|
||||
if ((ret != 6) || (memcmp (abtRx, ack_frame, 6))) {
|
||||
DBG ("%s", "===> No ACK!!!!!!");
|
||||
if (!pn53x_transceive_check_ack_frame_callback (pnd, abtRx, ret))
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ret == 6 )
|
||||
{
|
||||
ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
DBG("usb_bulk_read failed with error %d", ret);
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRx,ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", ack_frame,6);
|
||||
#endif
|
||||
usb_bulk_write(pus->pudh, pus->uiEndPointOut, (char *)ack_frame, 6, USB_TIMEOUT);
|
||||
|
||||
if (!pn53x_transceive_check_error_frame_callback (pnd, abtRx, ret))
|
||||
return false;
|
||||
|
||||
// When the answer should be ignored, just return a succesful result
|
||||
if(pbtRx == NULL || pszRxLen == NULL) return true;
|
||||
|
||||
|
@ -308,6 +315,7 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
if(ret < 9)
|
||||
{
|
||||
DBG("%s","No data");
|
||||
pnd->iLastError = DEINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,5 +37,5 @@ typedef struct {
|
|||
nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd,const char * target_name, int target_chip);
|
||||
void get_end_points(struct usb_device *dev, usb_spec_t* pus);
|
||||
void pn53x_usb_disconnect(nfc_device_t* pnd);
|
||||
bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound,usb_candidate_t candidates[], int num_candidates, char * target_name);
|
||||
|
|
120
libnfc/nfc.c
120
libnfc/nfc.c
|
@ -189,8 +189,7 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
|||
pnd->pdc = &(drivers_callbacks_list[uiDriver]);
|
||||
|
||||
// Try to retrieve PN53x chip revision
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
if (!pnd->pdc->transceive(pnd->nds,pncmd_get_firmware_version,2,abtFw,&szFwLen))
|
||||
if (!pn53x_transceive(pnd,pncmd_get_firmware_version,2,abtFw,&szFwLen))
|
||||
{
|
||||
// Failed to get firmware revision??, whatever...let's disconnect and clean up and return err
|
||||
DBG("Failed to get firmware revision for: %s", pnd->acName);
|
||||
|
@ -259,6 +258,9 @@ bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool
|
|||
{
|
||||
byte_t btValue;
|
||||
byte_t abtCmd[sizeof(pncmd_rf_configure)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_rf_configure,sizeof(pncmd_rf_configure));
|
||||
|
||||
// Make sure we are dealing with a active device
|
||||
|
@ -285,8 +287,7 @@ bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool
|
|||
case NDO_ACTIVATE_FIELD:
|
||||
abtCmd[2] = RFCI_FIELD;
|
||||
abtCmd[3] = (bEnable) ? 1 : 0;
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
if (!pnd->pdc->transceive(pnd->nds,abtCmd,4,NULL,NULL)) return false;
|
||||
if (!pn53x_transceive(pnd,abtCmd,4,NULL,NULL)) return false;
|
||||
break;
|
||||
|
||||
case NDO_ACTIVATE_CRYPTO1:
|
||||
|
@ -300,8 +301,7 @@ bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool
|
|||
abtCmd[3] = (bEnable) ? 0xff : 0x00; // MxRtyATR, default: active = 0xff, passive = 0x02
|
||||
abtCmd[4] = (bEnable) ? 0xff : 0x00; // MxRtyPSL, default: 0x01
|
||||
abtCmd[5] = (bEnable) ? 0xff : 0x00; // MxRtyPassiveActivation, default: 0xff
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
if (!pnd->pdc->transceive(pnd->nds,abtCmd,6,NULL,NULL)) return false;
|
||||
if (!pn53x_transceive(pnd,abtCmd,6,NULL,NULL)) return false;
|
||||
break;
|
||||
|
||||
case NDO_ACCEPT_INVALID_FRAMES:
|
||||
|
@ -338,8 +338,11 @@ bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool
|
|||
* After initialization it can be used to communicate to passive RFID tags and active NFC devices.
|
||||
* The reader will act as initiator to communicate peer 2 peer (NFCIP) to other active NFC devices.
|
||||
*/
|
||||
bool nfc_initiator_init(const nfc_device_t* pnd)
|
||||
bool nfc_initiator_init(nfc_device_t* pnd)
|
||||
{
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
// Make sure we are dealing with a active device
|
||||
if (!pnd->bActive) return false;
|
||||
|
||||
|
@ -368,12 +371,15 @@ bool nfc_initiator_init(const nfc_device_t* pnd)
|
|||
* The NFC device will try to find the available target. The standards (ISO18092 and ECMA-340) describe the modulation that can be used for reader to passive communications.
|
||||
* @note nfc_dep_info_t will be returned when the target was acquired successfully.
|
||||
*/
|
||||
bool nfc_initiator_select_dep_target(const 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* pnti)
|
||||
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* pnti)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
size_t offset;
|
||||
byte_t abtCmd[sizeof(pncmd_initiator_jump_for_dep)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_initiator_jump_for_dep,sizeof(pncmd_initiator_jump_for_dep));
|
||||
|
||||
if(nmInitModulation == NM_ACTIVE_DEP) {
|
||||
|
@ -432,7 +438,7 @@ bool nfc_initiator_select_dep_target(const nfc_device_t* pnd, const nfc_modulati
|
|||
* @note For every initial modulation type there is a different collection of information returned (in nfc_target_info_t pointer pti) They all fit in the data-type which is called nfc_target_info_t. This is a union which contains the tag information that belongs to the according initial modulation type.
|
||||
*/
|
||||
bool
|
||||
nfc_initiator_select_passive_target(const nfc_device_t* pnd,
|
||||
nfc_initiator_select_passive_target(nfc_device_t* pnd,
|
||||
const nfc_modulation_t nmInitModulation,
|
||||
const byte_t* pbtInitData, const size_t szInitDataLen,
|
||||
nfc_target_info_t* pnti)
|
||||
|
@ -443,6 +449,9 @@ nfc_initiator_select_passive_target(const nfc_device_t* pnd,
|
|||
size_t szTargetsData;
|
||||
byte_t abtTargetsData[MAX_FRAME_LEN];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
|
||||
// Make sure we are dealing with a active device
|
||||
if (!pnd->bActive) return false;
|
||||
// TODO Put this in a function
|
||||
|
@ -535,6 +544,9 @@ nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmI
|
|||
byte_t* pbtInitData = NULL;
|
||||
size_t szInitDataLen = 0;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
|
||||
// Let the reader only try once to find a target
|
||||
nfc_configure (pnd, NDO_INFINITE_SELECT, false);
|
||||
|
||||
|
@ -563,8 +575,11 @@ nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmI
|
|||
*
|
||||
* After selecting and communicating with a passive tag, this function could be used to deactivate and release the tag. This is very useful when there are multiple tags available in the field. It is possible to use the nfc_initiator_select_passive_target() function to select the first available tag, test it for the available features and support, deselect it and skip to the next tag until the correct tag is found.
|
||||
*/
|
||||
bool nfc_initiator_deselect_target(const nfc_device_t* pnd)
|
||||
bool nfc_initiator_deselect_target(nfc_device_t* pnd)
|
||||
{
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
return (pn53x_InDeselect(pnd, 0)); // 0 mean deselect all selected targets
|
||||
}
|
||||
|
||||
|
@ -580,11 +595,13 @@ bool nfc_initiator_deselect_target(const nfc_device_t* pnd)
|
|||
* @param pszTargetFound found targets count
|
||||
*/
|
||||
bool
|
||||
nfc_initiator_poll_targets(const nfc_device_t* pnd,
|
||||
nfc_initiator_poll_targets(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)
|
||||
{
|
||||
pnd->iLastError = 0;
|
||||
|
||||
return pn53x_InAutoPoll(pnd, pnttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound);
|
||||
}
|
||||
|
||||
|
@ -600,7 +617,7 @@ nfc_initiator_poll_targets(const nfc_device_t* pnd,
|
|||
*
|
||||
* The NFC reader will transmit low-level messages where only the modulation is handled by the PN53X chip. Construction of the frame (data, CRC and parity) is completely done by libnfc. This can be very useful for testing purposes. Some protocols (e.g. MIFARE Classic) require to violate the ISO14443-A standard by sending incorrect parity and CRC bytes. Using this feature you are able to simulate these frames.
|
||||
*/
|
||||
bool 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)
|
||||
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)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
@ -608,6 +625,9 @@ bool nfc_initiator_transceive_bits(const nfc_device_t* pnd, const byte_t* pbtTx,
|
|||
size_t szFrameBytes = 0;
|
||||
uint8_t ui8Bits = 0;
|
||||
byte_t abtCmd[sizeof(pncmd_initiator_exchange_raw_data)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_initiator_exchange_raw_data,sizeof(pncmd_initiator_exchange_raw_data));
|
||||
|
||||
// Check if we should prepare the parity bits ourself
|
||||
|
@ -664,11 +684,14 @@ bool nfc_initiator_transceive_bits(const nfc_device_t* pnd, const byte_t* pbtTx,
|
|||
*
|
||||
* The reader will transmit the supplied (data) bytes in pbtTx to the target (tag). It waits for the response and stores the received bytes in the pbtRx byte array. The difference between this function and nfc_initiator_transceive_bytes is that here pbtTx and pbtRx contain *only* the data sent and received and not any additional commands, that is all handled internally by the PN53X.
|
||||
*/
|
||||
bool nfc_initiator_transceive_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool nfc_initiator_transceive_dep_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
byte_t abtCmd[sizeof(pncmd_initiator_exchange_data)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_initiator_exchange_data,sizeof(pncmd_initiator_exchange_data));
|
||||
|
||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||
|
@ -708,11 +731,14 @@ bool nfc_initiator_transceive_dep_bytes(const nfc_device_t* pnd, const byte_t* p
|
|||
*
|
||||
* @warning The configuration option NDO_HANDLE_PARITY must be set to true (the default value).
|
||||
*/
|
||||
bool nfc_initiator_transceive_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool nfc_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
byte_t abtCmd[sizeof(pncmd_initiator_exchange_raw_data)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_initiator_exchange_raw_data,sizeof(pncmd_initiator_exchange_raw_data));
|
||||
|
||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||
|
@ -746,7 +772,7 @@ bool nfc_initiator_transceive_bytes(const nfc_device_t* pnd, const byte_t* pbtTx
|
|||
*
|
||||
* @warning Be aware that this function will wait (hang) until a command is received that is not part of the anti-collision. The RATS command for example would wake up the emulator. After this is received, the send and receive functions can be used.
|
||||
*/
|
||||
bool nfc_target_init(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
||||
bool nfc_target_init(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
@ -755,6 +781,9 @@ bool nfc_target_init(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
|||
bool bCrc = pnd->bCrc;
|
||||
bool bPar = pnd->bPar;
|
||||
byte_t abtCmd[sizeof(pncmd_target_init)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_target_init,sizeof(pncmd_target_init));
|
||||
|
||||
// Clear the target init struct, reset to all zeros
|
||||
|
@ -779,10 +808,9 @@ bool nfc_target_init(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
|||
// Let the PN53X be activated by the RF level detector from power down mode
|
||||
if (!pn53x_set_reg(pnd,REG_CIU_TX_AUTO, SYMBOL_INITIAL_RF_ON,0x04)) return false;
|
||||
|
||||
// Request the initialization as a target, we can not use pn53x_transceive() because
|
||||
// abtRx[0] contains the emulation mode (baudrate, 14443-4?, DEP and framing type)
|
||||
// Request the initialization as a target
|
||||
szRxLen = MAX_FRAME_LEN;
|
||||
if (!pnd->pdc->transceive(pnd->nds,abtCmd,39,abtRx,&szRxLen)) return false;
|
||||
if (!pn53x_transceive(pnd,abtCmd,39,abtRx,&szRxLen)) return false;
|
||||
|
||||
// Get the last bit-count that is stored in the received byte
|
||||
ui8Bits = pn53x_get_reg(pnd,REG_CIU_CONTROL) & SYMBOL_RX_LAST_BITS;
|
||||
|
@ -805,13 +833,16 @@ bool nfc_target_init(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
|||
*
|
||||
* This function makes it possible to receive (raw) bit-frames. It returns all the messages that are stored in the FIFO buffer of the PN53X chip. It does not require to send any frame and thereby could be used to snoop frames that are transmitted by a nearby reader. Check out the NDO_ACCEPT_MULTIPLE_FRAMES configuration option to avoid losing transmitted frames.
|
||||
*/
|
||||
bool nfc_target_receive_bits(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
||||
bool nfc_target_receive_bits(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
size_t szFrameBits;
|
||||
uint8_t ui8Bits;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
|
||||
// Try to gather a received frame from the reader
|
||||
if (!pn53x_transceive(pnd,pncmd_target_receive,2,abtRx,&szRxLen)) return false;
|
||||
|
||||
|
@ -843,11 +874,14 @@ bool nfc_target_receive_bits(const nfc_device_t* pnd, byte_t* pbtRx, size_t* psz
|
|||
*
|
||||
* The main receive function that returns the received data from a nearby reader. The difference between this function and nfc_target_receive_bytes is that here pbtRx contains *only* the data received and not any additional commands, that is all handled internally by the PN53X.
|
||||
*/
|
||||
bool nfc_target_receive_dep_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool nfc_target_receive_dep_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
|
||||
// Try to gather a received frame from the reader
|
||||
if (!pn53x_transceive(pnd,pncmd_target_get_data,2,abtRx,&szRxLen)) return false;
|
||||
|
||||
|
@ -867,11 +901,14 @@ bool nfc_target_receive_dep_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t
|
|||
*
|
||||
* The main receive function that returns the received frames from a nearby reader.
|
||||
*/
|
||||
bool nfc_target_receive_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool nfc_target_receive_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
|
||||
// Try to gather a received frame from the reader
|
||||
if (!pn53x_transceive(pnd,pncmd_target_receive,2,abtRx,&szRxLen)) return false;
|
||||
|
||||
|
@ -891,12 +928,15 @@ bool nfc_target_receive_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* ps
|
|||
*
|
||||
* This function can be used to transmit (raw) bit-frames to the reader.
|
||||
*/
|
||||
bool nfc_target_send_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar)
|
||||
bool nfc_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar)
|
||||
{
|
||||
size_t szFrameBits = 0;
|
||||
size_t szFrameBytes = 0;
|
||||
uint8_t ui8Bits = 0;
|
||||
byte_t abtCmd[sizeof(pncmd_target_send)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_target_send,sizeof(pncmd_target_send));
|
||||
|
||||
// Check if we should prepare the parity bits ourself
|
||||
|
@ -934,9 +974,12 @@ bool nfc_target_send_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const si
|
|||
*
|
||||
* To communicate byte frames and APDU responses to the reader, this function could be used.
|
||||
*/
|
||||
bool nfc_target_send_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||
bool nfc_target_send_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||
{
|
||||
byte_t abtCmd[sizeof(pncmd_target_send)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_target_send,sizeof(pncmd_target_send));
|
||||
|
||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||
|
@ -958,9 +1001,12 @@ bool nfc_target_send_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const s
|
|||
*
|
||||
* To communicate data to the reader, this function could be used. The difference between this function and nfc_target_send_bytes is that here pbtTx contains *only* the data sent and not any additional commands, that is all handled internally by the PN53X.
|
||||
*/
|
||||
bool nfc_target_send_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||
bool nfc_target_send_dep_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||
{
|
||||
byte_t abtCmd[sizeof(pncmd_target_set_data)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_target_set_data,sizeof(pncmd_target_set_data));
|
||||
|
||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||
|
@ -976,6 +1022,32 @@ bool nfc_target_send_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, con
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the PCD error string
|
||||
* @return Returns a string
|
||||
*/
|
||||
const char *nfc_strerror (const nfc_device_t *pnd)
|
||||
{
|
||||
return pnd->pdc->pcc->strerror (pnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Renders the PCD error in pcStrErrBuf for a maximum size of szBufLen chars
|
||||
* @return Returns 0 upon success
|
||||
*/
|
||||
int nfc_strerror_r (const nfc_device_t *pnd, char *pcStrErrBuf, size_t szBufLen)
|
||||
{
|
||||
return (snprintf (pcStrErrBuf, szBufLen, "%s", nfc_strerror (pnd)) < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display the PCD error a-la perror
|
||||
*/
|
||||
void nfc_perror (const nfc_device_t *pnd, const char *pcString)
|
||||
{
|
||||
fprintf (stderr, "%s: %s\n", pcString, nfc_strerror (pnd));
|
||||
}
|
||||
|
||||
/* Special data accessors */
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,12 +8,12 @@ TESTS = run-test.sh
|
|||
TESTS_ENVIRONMENT = NO_MAKE=yes CUTTER="$(CUTTER)"
|
||||
|
||||
noinst_LTLIBRARIES = \
|
||||
test_access.la
|
||||
test_access_storm.la
|
||||
|
||||
AM_LDFLAGS = -module -rpath $(libdir) -avoid-version -no-undefined
|
||||
|
||||
test_access_la_SOURCES = test_access.c
|
||||
test_access_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
||||
test_access_storm_la_SOURCES = test_access_storm.c
|
||||
test_access_storm_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
||||
|
||||
echo-cutter:
|
||||
@echo $(CUTTER)
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
#include <cutter.h>
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
#define NTESTS 42
|
||||
#define MAX_TARGET_COUNT 8
|
||||
|
||||
void
|
||||
test_access (void)
|
||||
{
|
||||
int n = NTESTS;
|
||||
nfc_device_desc_t devices[8];
|
||||
size_t device_count, ref_device_count, target_count;
|
||||
bool res;
|
||||
|
||||
nfc_list_devices (devices, 8, &ref_device_count);
|
||||
if (!ref_device_count)
|
||||
cut_omit ("No NFC device found");
|
||||
|
||||
while (n) {
|
||||
size_t i;
|
||||
|
||||
nfc_list_devices (devices, 8, &device_count);
|
||||
cut_assert_equal_int (ref_device_count, device_count, cut_message ("device count"));
|
||||
|
||||
for (i = 0; i < device_count; i++) {
|
||||
nfc_device_t *device;
|
||||
nfc_target_info_t anti[MAX_TARGET_COUNT];
|
||||
|
||||
device = nfc_connect (&(devices[i]));
|
||||
cut_assert_not_null (device, cut_message ("nfc_connect"));
|
||||
|
||||
nfc_initiator_init(device);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure(device,NDO_ACTIVATE_FIELD,false);
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure(device,NDO_INFINITE_SELECT,false);
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
nfc_configure(device,NDO_HANDLE_CRC,true);
|
||||
nfc_configure(device,NDO_HANDLE_PARITY,true);
|
||||
|
||||
// Enable field so more power consuming cards can power themselves
|
||||
nfc_configure(device,NDO_ACTIVATE_FIELD,true);
|
||||
|
||||
res = nfc_initiator_list_passive_targets(device, NM_ISO14443A_106, anti, MAX_TARGET_COUNT, &target_count);
|
||||
cut_assert_true (res, cut_message ("nfc_initiator_list_passive_targets"));
|
||||
|
||||
nfc_disconnect (device);
|
||||
}
|
||||
|
||||
n--;
|
||||
}
|
||||
}
|
67
test/test_access_storm.c
Normal file
67
test/test_access_storm.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include <cutter.h>
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
#define NTESTS 10
|
||||
#define MAX_DEVICE_COUNT 8
|
||||
#define MAX_TARGET_COUNT 8
|
||||
|
||||
/*
|
||||
* This is basically a stress-test to ensure we don't left a device in an
|
||||
* inconsistent state after use.
|
||||
*/
|
||||
void
|
||||
test_access_storm (void)
|
||||
{
|
||||
int n = NTESTS;
|
||||
nfc_device_desc_t devices[MAX_DEVICE_COUNT];
|
||||
size_t device_count, ref_device_count, target_count;
|
||||
bool res;
|
||||
|
||||
nfc_list_devices (devices, MAX_DEVICE_COUNT, &ref_device_count);
|
||||
if (!ref_device_count)
|
||||
cut_omit ("No NFC device found");
|
||||
|
||||
while (n) {
|
||||
size_t i;
|
||||
|
||||
nfc_list_devices (devices, MAX_DEVICE_COUNT, &device_count);
|
||||
cut_assert_equal_int (ref_device_count, device_count, cut_message ("device count"));
|
||||
|
||||
for (i = 0; i < device_count; i++) {
|
||||
nfc_device_t *device;
|
||||
nfc_target_info_t anti[MAX_TARGET_COUNT];
|
||||
|
||||
device = nfc_connect (&(devices[i]));
|
||||
cut_assert_not_null (device, cut_message ("nfc_connect"));
|
||||
|
||||
res = nfc_initiator_init(device);
|
||||
cut_assert_true (res, cut_message ("nfc_initiator_init"));
|
||||
|
||||
// Drop the field for a while
|
||||
res = nfc_configure(device,NDO_ACTIVATE_FIELD,false);
|
||||
cut_assert_true (res, cut_message ("nfc_configure"));
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
res = nfc_configure(device,NDO_INFINITE_SELECT,false);
|
||||
cut_assert_true (res, cut_message ("nfc_configure"));
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
res = nfc_configure(device,NDO_HANDLE_CRC,true);
|
||||
cut_assert_true (res, cut_message ("nfc_configure"));
|
||||
res = nfc_configure(device,NDO_HANDLE_PARITY,true);
|
||||
cut_assert_true (res, cut_message ("nfc_configure"));
|
||||
|
||||
// Enable field so more power consuming cards can power themselves
|
||||
res = nfc_configure(device,NDO_ACTIVATE_FIELD,true);
|
||||
cut_assert_true (res, cut_message ("nfc_configure"));
|
||||
|
||||
res = nfc_initiator_list_passive_targets(device, NM_ISO14443A_106, anti, MAX_TARGET_COUNT, &target_count);
|
||||
cut_assert_true (res, cut_message ("nfc_initiator_list_passive_targets"));
|
||||
|
||||
nfc_disconnect (device);
|
||||
}
|
||||
|
||||
n--;
|
||||
}
|
||||
}
|
|
@ -26,3 +26,6 @@ EXPORTS
|
|||
iso14443a_crc
|
||||
append_iso14443a_crc
|
||||
nfc_version
|
||||
nfc_perror
|
||||
nfc_strerror
|
||||
nfc_strerror_r
|
||||
|
|
Loading…
Add table
Reference in a new issue