Add software polling for non-PN532 equipped device (Fixes Issue 136)
This commit is contained in:
parent
66e3ea6146
commit
dccfd65c80
14 changed files with 215 additions and 118 deletions
|
@ -16,20 +16,19 @@ Improvements:
|
||||||
- libnfc: add ISO/IEC 14443 B' aka Type B' modulation partial support
|
- libnfc: add ISO/IEC 14443 B' aka Type B' modulation partial support
|
||||||
- libnfc: add partial support (list) for ISO14443B-3 ST SRx & ASK CTx cards
|
- libnfc: add partial support (list) for ISO14443B-3 ST SRx & ASK CTx cards
|
||||||
- libnfc: compile unit tests only on demand unless using --enable-debug.
|
- libnfc: compile unit tests only on demand unless using --enable-debug.
|
||||||
- libnfc: enhance logging system, libnfc now uses the flexible log4c library to log all messages
|
|
||||||
- libnfc: error handling improvements
|
- libnfc: error handling improvements
|
||||||
- libnfc: new function nfc_idle() to set the NFC device in idle mode
|
- libnfc: new function nfc_idle() to set the NFC device in idle mode
|
||||||
- libnfc: add partial support for Sony S360 reader
|
- libnfc: add partial support for Sony S360 reader
|
||||||
- libnfc: some manual test reports have been added
|
- libnfc: some manual test reports have been added
|
||||||
- libnfc: list_targets support for ASK CTS512B (no anticol support yet)
|
- libnfc: list_targets support for ASK CTS512B (no anticol support yet)
|
||||||
- libnfc: nfc_disconnect() now switches NFC device into idle before disconnecting
|
- libnfc: nfc_disconnect() now switches NFC device into idle before disconnecting
|
||||||
|
- libnfc: nfc_initiator_poll_target() is now available for all devices
|
||||||
- chips/pn53x: add pn53x_data_new() function to alloc and init pn53x_data structure
|
- chips/pn53x: add pn53x_data_new() function to alloc and init pn53x_data structure
|
||||||
- chips/pn53x: add some SFR registers description
|
- chips/pn53x: add some SFR registers description
|
||||||
- chips/pn53x: implement WriteBack cache
|
- chips/pn53x: implement WriteBack cache
|
||||||
- chips/pn53x: new pn53x_PowerDown wrapper for PowerDown (PN532) command
|
- chips/pn53x: new pn53x_PowerDown wrapper for PowerDown (PN532) command
|
||||||
- chips/pn53x: prints a debug trace when reading PN53x registers
|
- chips/pn53x: prints a debug trace when reading PN53x registers
|
||||||
- chips/pn53x: set some parameters in ISO/IEC 14443A when using DEP mode (ie. SAK says ISO/IEC 18092 compliant) (Android NFC stack now detects the target as DEP)
|
- chips/pn53x: set some parameters in ISO/IEC 14443A when using DEP mode (ie. SAK says ISO/IEC 18092 compliant) (Android NFC stack now detects the target as DEP)
|
||||||
- chips/pn53x: set ui8LastCommand in chip layer instead of driver layer
|
|
||||||
- chips/pn53x: some optimisations in registers initialisation
|
- chips/pn53x: some optimisations in registers initialisation
|
||||||
- chips/pn53x: list_passive_targets() fixed for TypeB on LoGO
|
- chips/pn53x: list_passive_targets() fixed for TypeB on LoGO
|
||||||
- chips/pn53x: pn53x_data now have a operating_mode enum to know the current running mode (initiator, target or idle)
|
- chips/pn53x: pn53x_data now have a operating_mode enum to know the current running mode (initiator, target or idle)
|
||||||
|
|
22
NEWS
22
NEWS
|
@ -1,3 +1,25 @@
|
||||||
|
New in 1.5.1:
|
||||||
|
|
||||||
|
API Changes
|
||||||
|
|
||||||
|
* Types
|
||||||
|
- Communication-level errors DEIO and DETIMEOUT are now know as ECOMIO,
|
||||||
|
ECOMTIMEOUT respectively
|
||||||
|
- Common device-level errors DEINVAL and DEABORT are now know as EINVALARG,
|
||||||
|
EOPABORT respectively
|
||||||
|
- New errors: EFRAACKMISMATCH, EFRAISERRFRAME, EDEVNOTSUP and ENOTIMPL
|
||||||
|
|
||||||
|
* Functions
|
||||||
|
- nfc_abort_command() returns a boolean
|
||||||
|
- timeout (struct timeval) pointer added to
|
||||||
|
nfc_initiator_transceive_bytes(), nfc_target_send_bytes() and
|
||||||
|
nfc_target_receive_bytes()
|
||||||
|
- timed functions nfc_initiator_transceive_bytes_timed() and
|
||||||
|
nfc_initiator_transceive_bits_timed() now takes uint32_t as cycles
|
||||||
|
pointer
|
||||||
|
- nfc_initiator_poll_targets() renamed to nfc_initiator_poll_target() and
|
||||||
|
only return one target
|
||||||
|
|
||||||
New in 1.5.0:
|
New in 1.5.0:
|
||||||
|
|
||||||
Installed files
|
Installed files
|
||||||
|
|
|
@ -97,9 +97,8 @@ main (int argc, const char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < szFound; i++) {
|
for (i = 0; i < szFound; i++) {
|
||||||
|
const uint8_t uiPollNr = 20;
|
||||||
const byte_t btPollNr = 20;
|
const uint8_t uiPeriod = 2;
|
||||||
const byte_t btPeriod = 2;
|
|
||||||
const nfc_modulation_t nmModulations[5] = {
|
const nfc_modulation_t nmModulations[5] = {
|
||||||
{ .nmt = NMT_ISO14443A, .nbr = NBR_106 },
|
{ .nmt = NMT_ISO14443A, .nbr = NBR_106 },
|
||||||
{ .nmt = NMT_ISO14443B, .nbr = NBR_106 },
|
{ .nmt = NMT_ISO14443B, .nbr = NBR_106 },
|
||||||
|
@ -109,8 +108,7 @@ main (int argc, const char *argv[])
|
||||||
};
|
};
|
||||||
const size_t szModulations = 5;
|
const size_t szModulations = 5;
|
||||||
|
|
||||||
nfc_target_t antTargets[2];
|
nfc_target_t nt;
|
||||||
size_t szTargetFound;
|
|
||||||
bool res;
|
bool res;
|
||||||
|
|
||||||
pnd = nfc_connect (&(pnddDevices[i]));
|
pnd = nfc_connect (&(pnddDevices[i]));
|
||||||
|
@ -121,28 +119,19 @@ main (int argc, const char *argv[])
|
||||||
}
|
}
|
||||||
nfc_initiator_init (pnd);
|
nfc_initiator_init (pnd);
|
||||||
|
|
||||||
// Let the reader only try once to find a tag
|
|
||||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
|
||||||
nfc_perror (pnd, "nfc_configure");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
||||||
|
printf ("NFC device will poll during %ld ms (%u pollings of %lu ms for %zd modulations)\n", (unsigned long) uiPollNr * szModulations * uiPeriod * 150, uiPollNr, (unsigned long) uiPeriod * 150, szModulations);
|
||||||
printf ("PN532 will poll during %ld ms\n", (unsigned long) btPollNr * szModulations * btPeriod * 150);
|
res = nfc_initiator_poll_target (pnd, nmModulations, szModulations, uiPollNr, uiPeriod, &nt);
|
||||||
res = nfc_initiator_poll_targets (pnd, nmModulations, szModulations, btPollNr, btPeriod, antTargets, &szTargetFound);
|
|
||||||
if (res) {
|
if (res) {
|
||||||
uint8_t n;
|
print_nfc_target ( nt, verbose );
|
||||||
printf ("%ld target(s) have been found.\n", (unsigned long) szTargetFound);
|
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
|
||||||
printf ("T%d: ", n + 1);
|
|
||||||
print_nfc_target ( antTargets[n], verbose );
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
nfc_perror (pnd, "nfc_initiator_poll_targets");
|
if (pnd->iLastError) {
|
||||||
nfc_disconnect (pnd);
|
nfc_perror (pnd, "nfc_initiator_poll_targets");
|
||||||
exit (EXIT_FAILURE);
|
nfc_disconnect (pnd);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
|
printf ("No target found.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nfc_disconnect (pnd);
|
nfc_disconnect (pnd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ extern "C" {
|
||||||
NFC_EXPORT bool nfc_initiator_init (nfc_device_t * pnd);
|
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 nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt);
|
NFC_EXPORT bool nfc_initiator_select_passive_target (nfc_device_t * pnd, const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt);
|
||||||
NFC_EXPORT bool nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nm, nfc_target_t ant[], const size_t szTargets, size_t * pszTargetFound);
|
NFC_EXPORT bool nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nm, nfc_target_t ant[], const size_t szTargets, size_t * pszTargetFound);
|
||||||
NFC_EXPORT bool nfc_initiator_poll_targets (nfc_device_t * pnd, const nfc_modulation_t * pnmTargetTypes, const size_t szTargetTypes, const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets, size_t * pszTargetFound);
|
NFC_EXPORT bool nfc_initiator_poll_target (nfc_device_t * pnd, const nfc_modulation_t * pnmTargetTypes, const size_t szTargetTypes, const uint8_t uiPollNr, const uint8_t uiPeriod, nfc_target_t * pnt);
|
||||||
NFC_EXPORT bool nfc_initiator_select_dep_target (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt);
|
NFC_EXPORT bool nfc_initiator_select_dep_target (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt);
|
||||||
NFC_EXPORT bool nfc_initiator_deselect_target (nfc_device_t * pnd);
|
NFC_EXPORT bool nfc_initiator_deselect_target (nfc_device_t * pnd);
|
||||||
NFC_EXPORT bool nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
NFC_EXPORT bool nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
||||||
|
|
|
@ -15,7 +15,9 @@ libnfc_la_SOURCES = \
|
||||||
mirror-subr.c \
|
mirror-subr.c \
|
||||||
nfc.c \
|
nfc.c \
|
||||||
nfc-device.c \
|
nfc-device.c \
|
||||||
nfc-emulation.c
|
nfc-emulation.c \
|
||||||
|
nfc-internal.c
|
||||||
|
|
||||||
libnfc_la_LDFLAGS = -no-undefined -version-info 2:0:0
|
libnfc_la_LDFLAGS = -no-undefined -version-info 2:0:0
|
||||||
libnfc_la_CFLAGS = @DRIVERS_CFLAGS@
|
libnfc_la_CFLAGS = @DRIVERS_CFLAGS@
|
||||||
libnfc_la_LIBADD = \
|
libnfc_la_LIBADD = \
|
||||||
|
|
|
@ -61,8 +61,6 @@ pn53x_target_type_t pn53x_nm_to_ptt (const nfc_modulation_t nm);
|
||||||
bool
|
bool
|
||||||
pn53x_init(nfc_device_t * pnd)
|
pn53x_init(nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "pn53x_init");
|
|
||||||
|
|
||||||
// GetFirmwareVersion command is used to set PN53x chips type (PN531, PN532 or PN533)
|
// GetFirmwareVersion command is used to set PN53x chips type (PN531, PN532 or PN533)
|
||||||
char abtFirmwareText[22];
|
char abtFirmwareText[22];
|
||||||
if (!pn53x_get_firmware_version (pnd, abtFirmwareText)) {
|
if (!pn53x_get_firmware_version (pnd, abtFirmwareText)) {
|
||||||
|
@ -111,6 +109,9 @@ pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, b
|
||||||
}
|
}
|
||||||
|
|
||||||
PNCMD_TRACE (pbtTx[0]);
|
PNCMD_TRACE (pbtTx[0]);
|
||||||
|
if (timeout)
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Timeout values: %li s, %li us", timeout->tv_sec, timeout->tv_usec);
|
||||||
|
|
||||||
byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
|
|
||||||
|
@ -855,10 +856,11 @@ pn53x_initiator_init (nfc_device_t * pnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
pn53x_initiator_select_passive_target_ext (nfc_device_t * pnd,
|
||||||
const nfc_modulation_t nm,
|
const nfc_modulation_t nm,
|
||||||
const byte_t * pbtInitData, const size_t szInitData,
|
const byte_t * pbtInitData, const size_t szInitData,
|
||||||
nfc_target_t * pnt)
|
nfc_target_t * pnt,
|
||||||
|
struct timeval* timeout)
|
||||||
{
|
{
|
||||||
byte_t abtTargetsData[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
byte_t abtTargetsData[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||||
size_t szTargetsData = sizeof(abtTargetsData);
|
size_t szTargetsData = sizeof(abtTargetsData);
|
||||||
|
@ -889,11 +891,11 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
||||||
byte_t abtRx[1];
|
byte_t abtRx[1];
|
||||||
size_t szRxLen = 1;
|
size_t szRxLen = 1;
|
||||||
// Getting random Chip_ID
|
// Getting random Chip_ID
|
||||||
if (!pn53x_initiator_transceive_bytes (pnd, abtInitiate, szInitiateLen, abtRx, &szRxLen, NULL)) {
|
if (!pn53x_initiator_transceive_bytes (pnd, abtInitiate, szInitiateLen, abtRx, &szRxLen, timeout)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
abtSelect[1] = abtRx[0];
|
abtSelect[1] = abtRx[0];
|
||||||
if (!pn53x_initiator_transceive_bytes (pnd, abtSelect, szSelectLen, abtRx, &szRxLen, NULL)) {
|
if (!pn53x_initiator_transceive_bytes (pnd, abtSelect, szSelectLen, abtRx, &szRxLen, timeout)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -902,11 +904,11 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
||||||
byte_t abtReqt[]="\x10";
|
byte_t abtReqt[]="\x10";
|
||||||
size_t szReqtLen = 1;
|
size_t szReqtLen = 1;
|
||||||
// Getting product code / fab code & store it in output buffer after the serial nr we'll obtain later
|
// Getting product code / fab code & store it in output buffer after the serial nr we'll obtain later
|
||||||
if (!pn53x_initiator_transceive_bytes (pnd, abtReqt, szReqtLen, abtTargetsData+2, &szTargetsData, NULL) || szTargetsData != 2) {
|
if (!pn53x_initiator_transceive_bytes (pnd, abtReqt, szReqtLen, abtTargetsData+2, &szTargetsData, timeout) || szTargetsData != 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pn53x_initiator_transceive_bytes (pnd, pbtInitData, szInitData, abtTargetsData, &szTargetsData, NULL)) {
|
if (!pn53x_initiator_transceive_bytes (pnd, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (nm.nmt == NMT_ISO14443B2CT) {
|
if (nm.nmt == NMT_ISO14443B2CT) {
|
||||||
|
@ -914,7 +916,7 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
||||||
return false;
|
return false;
|
||||||
byte_t abtRead[]="\xC4"; // Reading UID_MSB (Read address 4)
|
byte_t abtRead[]="\xC4"; // Reading UID_MSB (Read address 4)
|
||||||
size_t szReadLen = 1;
|
size_t szReadLen = 1;
|
||||||
if (!pn53x_initiator_transceive_bytes (pnd, abtRead, szReadLen, abtTargetsData+4, &szTargetsData, NULL) || szTargetsData != 2) {
|
if (!pn53x_initiator_transceive_bytes (pnd, abtRead, szReadLen, abtTargetsData+4, &szTargetsData, timeout) || szTargetsData != 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
szTargetsData = 6; // u16 UID_LSB, u8 prod code, u8 fab code, u16 UID_MSB
|
szTargetsData = 6; // u16 UID_LSB, u8 prod code, u8 fab code, u16 UID_MSB
|
||||||
|
@ -932,7 +934,7 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
||||||
size_t szAttribLen = sizeof(abtAttrib);
|
size_t szAttribLen = sizeof(abtAttrib);
|
||||||
memcpy(abtAttrib, abtTargetsData, szAttribLen);
|
memcpy(abtAttrib, abtTargetsData, szAttribLen);
|
||||||
abtAttrib[1] = 0x0f; // ATTRIB
|
abtAttrib[1] = 0x0f; // ATTRIB
|
||||||
if (!pn53x_initiator_transceive_bytes (pnd, abtAttrib, szAttribLen, NULL, NULL, NULL)) {
|
if (!pn53x_initiator_transceive_bytes (pnd, abtAttrib, szAttribLen, NULL, NULL, timeout)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -945,7 +947,7 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pn53x_InListPassiveTarget (pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData))
|
if (!pn53x_InListPassiveTarget (pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Make sure one tag has been found, the PN53X returns 0x00 if none was available
|
// Make sure one tag has been found, the PN53X returns 0x00 if none was available
|
||||||
|
@ -964,29 +966,76 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pn53x_initiator_poll_targets (nfc_device_t * pnd,
|
pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
||||||
const nfc_modulation_t * pnmModulations, const size_t szModulations,
|
const nfc_modulation_t nm,
|
||||||
const byte_t btPollNr, const byte_t btPeriod,
|
const byte_t * pbtInitData, const size_t szInitData,
|
||||||
nfc_target_t * pntTargets, size_t * pszTargetFound)
|
nfc_target_t * pnt)
|
||||||
{
|
{
|
||||||
size_t szTargetTypes = 0;
|
return pn53x_initiator_select_passive_target_ext (pnd, nm, pbtInitData, szInitData, pnt, NULL);
|
||||||
pn53x_target_type_t apttTargetTypes[32];
|
}
|
||||||
for (size_t n=0; n<szModulations; n++) {
|
|
||||||
const pn53x_target_type_t ptt = pn53x_nm_to_ptt(pnmModulations[n]);
|
|
||||||
if (PTT_UNDEFINED == ptt) {
|
|
||||||
pnd->iLastError = EINVALARG;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
apttTargetTypes[szTargetTypes] = ptt;
|
|
||||||
if ((pnd->bAutoIso14443_4) && (ptt == PTT_MIFARE)) { // Hack to have ATS
|
|
||||||
apttTargetTypes[szTargetTypes] = PTT_ISO14443_4A_106;
|
|
||||||
szTargetTypes++;
|
|
||||||
apttTargetTypes[szTargetTypes] = PTT_MIFARE;
|
|
||||||
}
|
|
||||||
szTargetTypes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pn53x_InAutoPoll (pnd, apttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound);
|
bool
|
||||||
|
pn53x_initiator_poll_target (nfc_device_t * pnd,
|
||||||
|
const nfc_modulation_t * pnmModulations, const size_t szModulations,
|
||||||
|
const uint8_t uiPollNr, const uint8_t uiPeriod,
|
||||||
|
nfc_target_t * pnt)
|
||||||
|
{
|
||||||
|
if (CHIP_DATA(pnd)->type == PN532) {
|
||||||
|
size_t szTargetTypes = 0;
|
||||||
|
pn53x_target_type_t apttTargetTypes[32];
|
||||||
|
for (size_t n=0; n<szModulations; n++) {
|
||||||
|
const pn53x_target_type_t ptt = pn53x_nm_to_ptt(pnmModulations[n]);
|
||||||
|
if (PTT_UNDEFINED == ptt) {
|
||||||
|
pnd->iLastError = EINVALARG;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
apttTargetTypes[szTargetTypes] = ptt;
|
||||||
|
if ((pnd->bAutoIso14443_4) && (ptt == PTT_MIFARE)) { // Hack to have ATS
|
||||||
|
apttTargetTypes[szTargetTypes] = PTT_ISO14443_4A_106;
|
||||||
|
szTargetTypes++;
|
||||||
|
apttTargetTypes[szTargetTypes] = PTT_MIFARE;
|
||||||
|
}
|
||||||
|
szTargetTypes++;
|
||||||
|
}
|
||||||
|
size_t szTargetFound = 0;
|
||||||
|
nfc_target_t ntTargets[2];
|
||||||
|
if (!pn53x_InAutoPoll (pnd, apttTargetTypes, szTargetTypes, uiPollNr, uiPeriod, ntTargets, &szTargetFound))
|
||||||
|
return false;
|
||||||
|
switch (szTargetFound) {
|
||||||
|
case 1:
|
||||||
|
*pnt = ntTargets[0];
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*pnt = ntTargets[1]; // We keep the selected one
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pn53x_configure (pnd, NDO_INFINITE_SELECT, true);
|
||||||
|
for (size_t p=0; p<uiPollNr; p++) {
|
||||||
|
for (size_t n=0; n<szModulations; n++) {
|
||||||
|
byte_t *pbtInitiatorData;
|
||||||
|
size_t szInitiatorData;
|
||||||
|
prepare_initiator_data (pnmModulations[n], &pbtInitiatorData, &szInitiatorData);
|
||||||
|
const int timeout_ms = uiPeriod * 150;
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = timeout_ms / 1000;
|
||||||
|
timeout.tv_usec = (timeout_ms - (timeout.tv_sec * 1000)) * 1000;
|
||||||
|
|
||||||
|
if (!pn53x_initiator_select_passive_target_ext (pnd, pnmModulations[n], pbtInitiatorData, szInitiatorData, pnt, &timeout)) {
|
||||||
|
if (pnd->iLastError != ECOMTIMEOUT)
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1992,7 +2041,8 @@ bool
|
||||||
pn53x_InListPassiveTarget (nfc_device_t * pnd,
|
pn53x_InListPassiveTarget (nfc_device_t * pnd,
|
||||||
const pn53x_modulation_t pmInitModulation, const byte_t szMaxTargets,
|
const pn53x_modulation_t pmInitModulation, const byte_t szMaxTargets,
|
||||||
const byte_t * pbtInitiatorData, const size_t szInitiatorData,
|
const byte_t * pbtInitiatorData, const size_t szInitiatorData,
|
||||||
byte_t * pbtTargetsData, size_t * pszTargetsData)
|
byte_t * pbtTargetsData, size_t * pszTargetsData,
|
||||||
|
struct timeval* timeout)
|
||||||
{
|
{
|
||||||
byte_t abtCmd[15] = { InListPassiveTarget };
|
byte_t abtCmd[15] = { InListPassiveTarget };
|
||||||
|
|
||||||
|
@ -2037,7 +2087,7 @@ pn53x_InListPassiveTarget (nfc_device_t * pnd,
|
||||||
if (pbtInitiatorData)
|
if (pbtInitiatorData)
|
||||||
memcpy (abtCmd + 3, pbtInitiatorData, szInitiatorData);
|
memcpy (abtCmd + 3, pbtInitiatorData, szInitiatorData);
|
||||||
|
|
||||||
return pn53x_transceive (pnd, abtCmd, 3 + szInitiatorData, pbtTargetsData, pszTargetsData, NULL);
|
return pn53x_transceive (pnd, abtCmd, 3 + szInitiatorData, pbtTargetsData, pszTargetsData, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -280,10 +280,10 @@ bool pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
||||||
const nfc_modulation_t nm,
|
const nfc_modulation_t nm,
|
||||||
const byte_t * pbtInitData, const size_t szInitData,
|
const byte_t * pbtInitData, const size_t szInitData,
|
||||||
nfc_target_t * pnt);
|
nfc_target_t * pnt);
|
||||||
bool pn53x_initiator_poll_targets (nfc_device_t * pnd,
|
bool pn53x_initiator_poll_target (nfc_device_t * pnd,
|
||||||
const nfc_modulation_t * pnmModulations, const size_t szModulations,
|
const nfc_modulation_t * pnmModulations, const size_t szModulations,
|
||||||
const byte_t btPollNr, const byte_t btPeriod,
|
const uint8_t uiPollNr, const uint8_t uiPeriod,
|
||||||
nfc_target_t * pntTargets, size_t * pszTargetFound);
|
nfc_target_t * pnt);
|
||||||
bool pn53x_initiator_select_dep_target (nfc_device_t * pnd,
|
bool pn53x_initiator_select_dep_target (nfc_device_t * pnd,
|
||||||
const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr,
|
const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr,
|
||||||
const nfc_dep_info_t * pndiInitiator,
|
const nfc_dep_info_t * pndiInitiator,
|
||||||
|
@ -304,8 +304,7 @@ bool pn53x_initiator_deselect_target (nfc_device_t * pnd);
|
||||||
bool pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx);
|
bool pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx);
|
||||||
bool pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
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 * pszRx, struct timeval *timeout);
|
bool pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
||||||
bool pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
|
bool pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar);
|
||||||
const byte_t * pbtTxPar);
|
|
||||||
bool pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout);
|
bool pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout);
|
||||||
|
|
||||||
// Error handling functions
|
// Error handling functions
|
||||||
|
@ -317,7 +316,8 @@ bool pn53x_SAMConfiguration (nfc_device_t * pnd, const pn532_sam_mode mode, s
|
||||||
bool pn53x_PowerDown (nfc_device_t * pnd);
|
bool pn53x_PowerDown (nfc_device_t * pnd);
|
||||||
bool pn53x_InListPassiveTarget (nfc_device_t * pnd, const pn53x_modulation_t pmInitModulation,
|
bool pn53x_InListPassiveTarget (nfc_device_t * pnd, const pn53x_modulation_t pmInitModulation,
|
||||||
const byte_t szMaxTargets, const byte_t * pbtInitiatorData,
|
const byte_t szMaxTargets, const byte_t * pbtInitiatorData,
|
||||||
const size_t szInitiatorDataLen, byte_t * pbtTargetsData, size_t * pszTargetsData);
|
const size_t szInitiatorDataLen, byte_t * pbtTargetsData, size_t * pszTargetsData,
|
||||||
|
struct timeval *timeout);
|
||||||
bool pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target);
|
bool pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target);
|
||||||
bool pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target);
|
bool pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target);
|
||||||
bool pn53x_InAutoPoll (nfc_device_t * pnd, const pn53x_target_type_t * ppttTargetTypes, const size_t szTargetTypes,
|
bool pn53x_InAutoPoll (nfc_device_t * pnd, const pn53x_target_type_t * ppttTargetTypes, const size_t szTargetTypes,
|
||||||
|
|
|
@ -415,7 +415,7 @@ const struct nfc_driver_t acr122_driver = {
|
||||||
|
|
||||||
.initiator_init = pn53x_initiator_init,
|
.initiator_init = pn53x_initiator_init,
|
||||||
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
||||||
.initiator_poll_targets = pn53x_initiator_poll_targets,
|
.initiator_poll_target = pn53x_initiator_poll_target,
|
||||||
.initiator_select_dep_target = pn53x_initiator_select_dep_target,
|
.initiator_select_dep_target = pn53x_initiator_select_dep_target,
|
||||||
.initiator_deselect_target = pn53x_initiator_deselect_target,
|
.initiator_deselect_target = pn53x_initiator_deselect_target,
|
||||||
.initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
|
.initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
|
||||||
|
|
|
@ -508,7 +508,7 @@ const struct nfc_driver_t arygon_driver = {
|
||||||
|
|
||||||
.initiator_init = pn53x_initiator_init,
|
.initiator_init = pn53x_initiator_init,
|
||||||
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
||||||
.initiator_poll_targets = pn53x_initiator_poll_targets,
|
.initiator_poll_target = pn53x_initiator_poll_target,
|
||||||
.initiator_select_dep_target = pn53x_initiator_select_dep_target,
|
.initiator_select_dep_target = pn53x_initiator_select_dep_target,
|
||||||
.initiator_deselect_target = pn53x_initiator_deselect_target,
|
.initiator_deselect_target = pn53x_initiator_deselect_target,
|
||||||
.initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
|
.initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
|
||||||
|
|
|
@ -454,7 +454,7 @@ const struct nfc_driver_t pn532_uart_driver = {
|
||||||
|
|
||||||
.initiator_init = pn53x_initiator_init,
|
.initiator_init = pn53x_initiator_init,
|
||||||
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
||||||
.initiator_poll_targets = pn53x_initiator_poll_targets,
|
.initiator_poll_target = pn53x_initiator_poll_target,
|
||||||
.initiator_select_dep_target = pn53x_initiator_select_dep_target,
|
.initiator_select_dep_target = pn53x_initiator_select_dep_target,
|
||||||
.initiator_deselect_target = pn53x_initiator_deselect_target,
|
.initiator_deselect_target = pn53x_initiator_deselect_target,
|
||||||
.initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
|
.initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
|
||||||
|
|
|
@ -751,7 +751,7 @@ const struct nfc_driver_t pn53x_usb_driver = {
|
||||||
|
|
||||||
.initiator_init = pn53x_initiator_init,
|
.initiator_init = pn53x_initiator_init,
|
||||||
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
||||||
.initiator_poll_targets = pn53x_initiator_poll_targets,
|
.initiator_poll_target = pn53x_initiator_poll_target,
|
||||||
.initiator_select_dep_target = pn53x_initiator_select_dep_target,
|
.initiator_select_dep_target = pn53x_initiator_select_dep_target,
|
||||||
.initiator_deselect_target = pn53x_initiator_deselect_target,
|
.initiator_deselect_target = pn53x_initiator_deselect_target,
|
||||||
.initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
|
.initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
|
||||||
|
|
67
libnfc/nfc-internal.c
Normal file
67
libnfc/nfc-internal.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*-
|
||||||
|
* Public platform independent Near Field Communication (NFC) library
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011, Romuald Conty
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* 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 <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file nfc-internal.c
|
||||||
|
* @brief Provide some useful internal functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nfc/nfc.h>
|
||||||
|
#include <nfc/nfc-emulation.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
prepare_initiator_data (const nfc_modulation_t nm, byte_t **ppbtInitiatorData, size_t * pszInitiatorData)
|
||||||
|
{
|
||||||
|
switch (nm.nmt) {
|
||||||
|
case NMT_ISO14443B: {
|
||||||
|
// Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3)
|
||||||
|
*ppbtInitiatorData = (byte_t *) "\x00";
|
||||||
|
*pszInitiatorData = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NMT_ISO14443BI: {
|
||||||
|
// APGEN
|
||||||
|
*ppbtInitiatorData = (byte_t *) "\x01\x0b\x3f\x80";
|
||||||
|
*pszInitiatorData = 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NMT_ISO14443B2SR: {
|
||||||
|
// Get_UID
|
||||||
|
*ppbtInitiatorData = (byte_t *) "\x0b";
|
||||||
|
*pszInitiatorData = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NMT_ISO14443B2CT: {
|
||||||
|
// SELECT-ALL
|
||||||
|
*ppbtInitiatorData = (byte_t *) "\x9F\xFF\xFF";
|
||||||
|
*pszInitiatorData = 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NMT_FELICA: {
|
||||||
|
// polling payload must be present (see ISO/IEC 18092 11.2.2.5)
|
||||||
|
*ppbtInitiatorData = (byte_t *) "\x00\xff\xff\x01\x00";
|
||||||
|
*pszInitiatorData = 5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*ppbtInitiatorData = NULL;
|
||||||
|
*pszInitiatorData = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -133,7 +133,7 @@ struct nfc_driver_t {
|
||||||
|
|
||||||
bool (*initiator_init) (nfc_device_t * pnd);
|
bool (*initiator_init) (nfc_device_t * pnd);
|
||||||
bool (*initiator_select_passive_target) (nfc_device_t * pnd, const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt);
|
bool (*initiator_select_passive_target) (nfc_device_t * pnd, const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt);
|
||||||
bool (*initiator_poll_targets) (nfc_device_t * pnd, const nfc_modulation_t * pnmModulations, const size_t szModulations, const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets, size_t * pszTargetFound);
|
bool (*initiator_poll_target) (nfc_device_t * pnd, const nfc_modulation_t * pnmModulations, const size_t szModulations, const uint8_t uiPollNr, const uint8_t btPeriod, nfc_target_t * pnt);
|
||||||
bool (*initiator_select_dep_target) (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt);
|
bool (*initiator_select_dep_target) (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt);
|
||||||
bool (*initiator_deselect_target) (nfc_device_t * pnd);
|
bool (*initiator_deselect_target) (nfc_device_t * pnd);
|
||||||
bool (*initiator_transceive_bytes) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
bool (*initiator_transceive_bytes) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
||||||
|
@ -158,4 +158,6 @@ void nfc_device_free (nfc_device_t *nfc_device);
|
||||||
|
|
||||||
void iso14443_cascade_uid (const byte_t abtUID[], const size_t szUID, byte_t * pbtCascadedUID, size_t * pszCascadedUID);
|
void iso14443_cascade_uid (const byte_t abtUID[], const size_t szUID, byte_t * pbtCascadedUID, size_t * pszCascadedUID);
|
||||||
|
|
||||||
|
void prepare_initiator_data (const nfc_modulation_t nm, byte_t **ppbtInitiatorData, size_t * pszInitiatorData);
|
||||||
|
|
||||||
#endif // __NFC_INTERNAL_H__
|
#endif // __NFC_INTERNAL_H__
|
||||||
|
|
54
libnfc/nfc.c
54
libnfc/nfc.c
|
@ -325,41 +325,7 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (nm.nmt) {
|
prepare_initiator_data (nm, &pbtInitData, &szInitDataLen);
|
||||||
case NMT_ISO14443B: {
|
|
||||||
// Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3)
|
|
||||||
pbtInitData = (byte_t *) "\x00";
|
|
||||||
szInitDataLen = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NMT_ISO14443BI: {
|
|
||||||
// APGEN
|
|
||||||
pbtInitData = (byte_t *) "\x01\x0b\x3f\x80";
|
|
||||||
szInitDataLen = 4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NMT_ISO14443B2SR: {
|
|
||||||
// Get_UID
|
|
||||||
pbtInitData = (byte_t *) "\x0b";
|
|
||||||
szInitDataLen = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NMT_ISO14443B2CT: {
|
|
||||||
// SELECT-ALL
|
|
||||||
pbtInitData = (byte_t *) "\x9F\xFF\xFF";
|
|
||||||
szInitDataLen = 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NMT_FELICA: {
|
|
||||||
// polling payload must be present (see ISO/IEC 18092 11.2.2.5)
|
|
||||||
pbtInitData = (byte_t *) "\x00\xff\xff\x01\x00";
|
|
||||||
szInitDataLen = 5;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// nothing to do
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (nfc_initiator_select_passive_target (pnd, nm, pbtInitData, szInitDataLen, &nt)) {
|
while (nfc_initiator_select_passive_target (pnd, nm, pbtInitData, szInitDataLen, &nt)) {
|
||||||
nfc_initiator_deselect_target (pnd);
|
nfc_initiator_deselect_target (pnd);
|
||||||
|
@ -397,19 +363,19 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd,
|
||||||
* @param pnd \a nfc_device_t struct pointer that represent currently used device
|
* @param pnd \a nfc_device_t struct pointer that represent currently used device
|
||||||
* @param ppttTargetTypes array of desired target types
|
* @param ppttTargetTypes array of desired target types
|
||||||
* @param szTargetTypes \e ppttTargetTypes count
|
* @param szTargetTypes \e ppttTargetTypes count
|
||||||
* @param btPollNr specifies the number of polling
|
* @param uiPollNr specifies the number of polling (0x01 – 0xFE: 1 up to 254 polling, 0xFF: Endless polling)
|
||||||
* @note one polling is a polling for each desired target type
|
* @note one polling is a polling for each desired target type
|
||||||
* @param btPeriod indicates the polling period in units of 150 ms
|
* @param uiPeriod indicates the polling period in units of 150 ms (0x01 – 0x0F: 150ms – 2.25s)
|
||||||
* @param[out] pntTargets pointer on array of 2 \a nfc_target_t (over)writables struct
|
* @note e.g. if uiPeriod=10, it will poll each desired target type during 1.5s
|
||||||
* @param[out] pszTargetFound found targets count
|
* @param[out] pnt pointer on \a nfc_target_t (over)writable struct
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
nfc_initiator_poll_targets (nfc_device_t * pnd,
|
nfc_initiator_poll_target (nfc_device_t * pnd,
|
||||||
const nfc_modulation_t * pnmModulations, const size_t szModulations,
|
const nfc_modulation_t * pnmModulations, const size_t szModulations,
|
||||||
const byte_t btPollNr, const byte_t btPeriod,
|
const uint8_t uiPollNr, const uint8_t uiPeriod,
|
||||||
nfc_target_t * pntTargets, size_t * pszTargetFound)
|
nfc_target_t * pnt)
|
||||||
{
|
{
|
||||||
HAL (initiator_poll_targets, pnd, pnmModulations, szModulations, btPollNr, btPeriod, pntTargets, pszTargetFound);
|
HAL (initiator_poll_target, pnd, pnmModulations, szModulations, uiPollNr, uiPeriod, pnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue