diff --git a/examples/nfc-emulate-ndef.c b/examples/nfc-emulate-ndef.c
new file mode 100644
index 0000000..a109368
--- /dev/null
+++ b/examples/nfc-emulate-ndef.c
@@ -0,0 +1,107 @@
+/*-
+ * Public platform independent Near Field Communication (NFC) library
+ *
+ * Copyright (C) 2009, Roel Verdult
+ *
+ * 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
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see
+ */
+
+/**
+ * @file nfc-emulate.c
+ * @brief
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif // HAVE_CONFIG_H
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include "nfc-utils.h"
+
+#define MAX_FRAME_LEN 264
+
+static byte_t abtRx[MAX_FRAME_LEN];
+static size_t szRxLen;
+static nfc_device_t *pnd;
+static bool quiet_output = false;
+
+#define SYMBOL_PARAM_fISO14443_4_PICC 0x20
+
+bool
+transmit_bytes (const byte_t * pbtTx, const size_t szTxLen)
+{
+ // Show transmitted command
+ if (!quiet_output) {
+ printf ("Tx: ");
+ print_hex (pbtTx, szTxLen);
+ }
+
+ // Transmit the command bytes
+ pn53x_set_parameters(pnd,0);
+ if (!nfc_target_send_bytes(pnd, pbtTx, szTxLen))
+ return false;
+ pn53x_set_parameters(pnd,SYMBOL_PARAM_fISO14443_4_PICC);
+
+ if (!pn53x_target_receive_bytes(pnd,abtRx,&szRxLen))
+ return false;
+
+ // Show received answer
+ if (!quiet_output) {
+ printf ("Rx: ");
+ print_hex (abtRx, szRxLen);
+ }
+ // Succesful transfer
+ return true;
+}
+
+int
+main (int argc, char *argv[])
+{
+ // Try to open the NFC reader
+ pnd = nfc_connect (NULL);
+
+ if (pnd == NULL) {
+ printf ("Error connecting NFC reader\n");
+ return 1;
+ }
+
+ printf ("[+] Connected to NFC reader: %s\n", pnd->acName);
+ printf ("[+] Emulating NDEF tag now, please touch it with a second NFC device\n");
+ if (!nfc_target_init (pnd, NTM_PICC, abtRx, &szRxLen)) {
+ printf ("Error: Could not come out of auto-emulation, no command was received\n");
+ return 1;
+ }
+
+ transmit_bytes("\x0a\x00\x6a\x87",4);
+ transmit_bytes("\x0b\x00\x6a\x87",4);
+ transmit_bytes("\x0a\x00\x90\x00",4);
+ transmit_bytes("\x0b\x00\x90\x00",4);
+ transmit_bytes("\x0a\x00\x00\x0f\x10\x00\x3b\x00\x34\x04\x06\xe1\x04\x0e\xe0\x00\x00\x90\x00",19);
+ transmit_bytes("\x0b\x00\x90\x00",4);
+ transmit_bytes("\x0a\x00\x00\x21\x90\x00",6);
+ transmit_bytes("\x0b\x00\xd1\x02\x1c\x53\x70\x91\x01\x09\x54\x02\x65\x6e\x4c\x69\x62\x6e\x66\x63\x51\x01\x0b\x55\x03\x6c\x69\x62\x6e\x66\x63\x2e\x6f\x72\x67\x90\x00",37);
+ transmit_bytes("\xca\x00",2);
+
+ nfc_disconnect(pnd);
+ exit (EXIT_SUCCESS);
+}
+
diff --git a/examples/nfc-emulate.c b/examples/nfc-emulate.c
index a04fd08..799614b 100644
--- a/examples/nfc-emulate.c
+++ b/examples/nfc-emulate.c
@@ -106,7 +106,7 @@ main (int argc, char *argv[])
printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n");
printf ("[+] To do this, please send any command after the anti-collision\n");
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
- if (!nfc_target_init (pnd, abtRecv, &szRecvBits)) {
+ if (!nfc_target_init (pnd, NTM_PASSIVE, abtRecv, &szRecvBits)) {
printf ("Error: Could not come out of auto-emulation, no command was received\n");
return 1;
}
diff --git a/examples/nfc-relay.c b/examples/nfc-relay.c
index 28d00d5..be38d64 100644
--- a/examples/nfc-relay.c
+++ b/examples/nfc-relay.c
@@ -125,7 +125,7 @@ main (int argc, char *argv[])
printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n");
printf ("[+] To do this, please send any command after the anti-collision\n");
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
- if (!nfc_target_init (pndTag, abtReaderRx, &szReaderRxBits)) {
+ if (!nfc_target_init (pndTag, NTM_PASSIVE, abtReaderRx, &szReaderRxBits)) {
ERR ("%s", "Initialization of NFC emulator failed");
nfc_disconnect (pndTag);
return EXIT_FAILURE;
diff --git a/examples/nfc-sam.c b/examples/nfc-sam.c
index 817103b..2107400 100644
--- a/examples/nfc-sam.c
+++ b/examples/nfc-sam.c
@@ -207,7 +207,7 @@ main (int argc, const char *argv[])
// FIXME: it does not work as expected...Probably the issue is in "nfc_target_init"
// which doesn't provide a way to set custom data for SENS_RES, NFCID1, SEL_RES, etc.
- if (!nfc_target_init (pnd, abtRx, &szRxLen))
+ if (!nfc_target_init (pnd, NTM_PICC, abtRx, &szRxLen))
return EXIT_FAILURE;
printf ("Now both the NFC reader and SAM are readable for 1 minute from an external reader.\n");
diff --git a/examples/nfcip-target.c b/examples/nfcip-target.c
index 4205df6..a8456f3 100644
--- a/examples/nfcip-target.c
+++ b/examples/nfcip-target.c
@@ -59,7 +59,7 @@ main (int argc, const char *argv[])
errx (1, "usage: %s", argv[0]);
}
- if (!pnd || !nfc_target_init (pnd, abtRecv, &szRecvBits)) {
+ if (!pnd || !nfc_target_init (pnd, NTM_DEP, abtRecv, &szRecvBits)) {
printf ("unable to connect or initialize\n");
return 1;
}
diff --git a/include/nfc/nfc-types.h b/include/nfc/nfc-types.h
index 048b0ea..ae4c12b 100644
--- a/include/nfc/nfc-types.h
+++ b/include/nfc/nfc-types.h
@@ -262,6 +262,19 @@ typedef union {
nfc_dep_info_t ndi;
} nfc_target_info_t;
+/**
+ * @enum nfc_target_mode_t
+ * @brief NFC target type enumeration
+ */
+typedef enum {
+ /** Configure the PN532 to accept to be initialized only in passive mode */
+ NTM_PASSIVE = 0x01,
+ /** configure the PN532 to accept to be initialized only as DEP target */
+ NTM_DEP = 0x02,
+ /** configure the PN532 to accept to be initialized only as ISO/IEC14443-4 PICC */
+ NTM_PICC = 0x04
+} nfc_target_mode_t;
+
/**
* @enum nfc_target_type_t
* @brief NFC target type enumeration
diff --git a/include/nfc/nfc.h b/include/nfc/nfc.h
index b8dbb42..9f11878 100644
--- a/include/nfc/nfc.h
+++ b/include/nfc/nfc.h
@@ -90,7 +90,7 @@ extern "C" {
byte_t * pbtRxPar);
/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */
- NFC_EXPORT bool nfc_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits);
+ NFC_EXPORT bool nfc_target_init (nfc_device_t * pnd, nfc_target_mode_t tm, byte_t * pbtRx, size_t * pszRxLen);
NFC_EXPORT bool nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen);
NFC_EXPORT bool nfc_target_receive_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,
diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c
index 20186eb..9a4fcc4 100644
--- a/libnfc/chips/pn53x.c
+++ b/libnfc/chips/pn53x.c
@@ -910,12 +910,10 @@ pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, cons
}
bool
-pn53x_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits)
+pn53x_target_init (nfc_device_t * pnd, nfc_target_mode_t tm, byte_t * pbtRx, size_t * pszRxLen)
{
byte_t abtRx[MAX_FRAME_LEN];
size_t szRxLen;
- uint8_t ui8rcc;
- uint8_t ui8Bits;
// Save the current configuration settings
bool bCrc = pnd->bCrc;
bool bPar = pnd->bPar;
@@ -926,6 +924,9 @@ pn53x_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits)
// Clear the target init struct, reset to all zeros
memset (abtCmd + 2, 0x00, 37);
+ // Store the target mode in the initialization params
+ abtCmd[2] = tm;
+
// Set ATQA (SENS_RES)
abtCmd[3] = 0x04;
abtCmd[4] = 0x00;
@@ -938,6 +939,29 @@ pn53x_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits)
abtCmd[6] = 0xb0;
abtCmd[7] = 0x0b;
+ // Configure the target corresponding to the requested mode
+ switch(tm)
+ {
+ case NTM_PASSIVE:
+ pn53x_set_parameters(pnd,0);
+ pn53x_configure(pnd,NDO_EASY_FRAMING,false);
+ break;
+
+ case NTM_DEP:
+ pn53x_set_parameters(pnd,SYMBOL_PARAM_fAutomaticATR_RES);
+ pn53x_configure(pnd,NDO_EASY_FRAMING,true);
+ break;
+
+ case NTM_PICC:
+ pn53x_set_parameters(pnd,SYMBOL_PARAM_fISO14443_4_PICC);
+ pn53x_configure(pnd,NDO_EASY_FRAMING,false);
+ break;
+
+ default:
+ // Unknown mode
+ return false;
+ }
+
// Make sure the CRC & parity are handled by the device, this is needed for target_init to work properly
if (!bCrc)
pn53x_configure ((nfc_device_t *) pnd, NDO_HANDLE_CRC, true);
@@ -953,15 +977,11 @@ pn53x_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits)
if (!pn53x_transceive (pnd, abtCmd, 39, abtRx, &szRxLen))
return false;
- // Get the last bit-count that is stored in the received byte
- if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
- return false;
- ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
+ // Save the received byte count
+ *pszRxLen = szRxLen - 1;
- // We are sure the parity is handled by the PN53X chip, so we handle it this way
- *pszRxBits = ((szRxLen - 1 - ((ui8Bits == 0) ? 0 : 1)) * 8) + ui8Bits;
// Copy the received bytes
- memcpy (pbtRx, abtRx + 1, szRxLen - 1);
+ memcpy (pbtRx, abtRx + 1, *pszRxLen);
// Restore the CRC & parity setting to the original value (if needed)
if (!bCrc)
diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h
index 3efebc4..0b1b029 100644
--- a/libnfc/chips/pn53x.h
+++ b/libnfc/chips/pn53x.h
@@ -66,6 +66,7 @@
# define SYMBOL_PARAM_fAutomaticRATS 0x10
# define SYMBOL_PARAM_fAutomaticATR_RES 0x04
+# define SYMBOL_PARAM_fISO14443_4_PICC 0x20
// Internal parameters flags
# define PARAM_NONE 0x00
@@ -131,7 +132,7 @@ bool pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtT
bool pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen,
byte_t * pbtRx, size_t * pszRxLen);
-bool pn53x_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits);
+bool pn53x_target_init (nfc_device_t * pnd, nfc_target_mode_t tm, byte_t * pbtRx, size_t * pszRxLen);
bool pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
bool pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxLen);
bool pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
diff --git a/libnfc/nfc.c b/libnfc/nfc.c
index 457a69e..262c1f7 100644
--- a/libnfc/nfc.c
+++ b/libnfc/nfc.c
@@ -544,11 +544,11 @@ nfc_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const s
* @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 (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits)
+nfc_target_init (nfc_device_t * pnd, nfc_target_mode_t tm, byte_t * pbtRx, size_t * pszRxLen)
{
pnd->iLastError = 0;
- return pn53x_target_init (pnd, pbtRx, pszRxBits);
+ return pn53x_target_init (pnd, tm, pbtRx, pszRxLen);
}
/**