From 3f0101bd3f664bbf11f5622b1c07b01cb68fbe94 Mon Sep 17 00:00:00 2001 From: Benjamin Delpy Date: Sun, 28 Jul 2024 12:36:49 +0200 Subject: [PATCH] Fix `nfc_initiator_select_passive_target` target count on PN53x when not using `InListPassiveTarget` When using `pn53x` chip with target not compatible with `InListPassiveTarget` (like `NMT_ISO14443BICLASS`, `NMT_ISO14443B2CT` & `NMT_ISO14443B2SR` by eg.), the logic behind `nfc_initiator_select_passive_target` to return target count seems to be buggy `nfc_initiator_select_passive_target`: > Returns: > Returns selected passive target count on success, otherwise returns libnfc's error code (negative value) In `pn53x_initiator_select_passive_target_ext`, the return value in success is always `abtTargetsData[0]`. This is correct when using `InListPassiveTarget` as the first byte is `NbTg`, but it can be problematic for other cases. - Example with a Mifare: ``` gentilkiwi@pi5:~/libnfc-dev $ ./utils/nfc-list -t 1 NFC device: Elechouse NFC Module V3 (SPI) opened ## End of function 'pn53x_initiator_select_passive_target_ext'... ## abtTargetsData content is : 01 01 00 04 08 04 1a da 74 44 ## return will be: 0x01 (?) 1 ISO14443A passive target(s) found: ISO/IEC 14443A (106 kbps) target: ATQA (SENS_RES): 00 04 UID (NFCID1): 1a da 74 44 SAK (SEL_RES): 08 ``` - Example with 2x ST25TB: ``` gentilkiwi@pi5:~/libnfc-dev $ ./utils/nfc-list -t 32 NFC device: Elechouse NFC Module V3 (SPI) opened ## End of function 'pn53x_initiator_select_passive_target_ext'... ## abtTargetsData content is : 35 a5 f2 a4 68 1f 02 d0 ## return will be: 0x35 (?) 1 ISO14443B-2 ST SRx passive target(s) found: ISO/IEC 14443-2B ST SRx (106 kbps) target: UID: 35 a5 f2 a4 68 1f 02 d0 ``` ``` gentilkiwi@pi5:~/libnfc-dev $ ./utils/nfc-list -t 32 NFC device: Elechouse NFC Module V3 (SPI) opened ## End of function 'pn53x_initiator_select_passive_target_ext'... ## abtTargetsData content is : 00 92 f0 a4 68 1f 02 d0 ## return will be: 0x00 (?) 0 ISO14443B-2 ST SRx passive target(s) found. ``` The proposed PR will fix the target count to 1 when not using `InListPassiveTarget`, since current versions of target initialisation do not support for more. - Results: ``` gentilkiwi@pi5:~/libnfc-dev $ ./utils/nfc-list -t 32 NFC device: Elechouse NFC Module V3 (SPI) opened 1 ISO14443B-2 ST SRx passive target(s) found: ISO/IEC 14443-2B ST SRx (106 kbps) target: UID: 00 92 f0 a4 68 1f 02 d0 gentilkiwi@pi5:~/libnfc-dev $ ./examples/nfc-st25tb |mode : info Reader : Elechouse NFC Module V3 (SPI) - via pn532_spi:/dev/spidev0.0:500000 ...wait for card... Target : ISO/IEC 14443-2B ST SRx (106 kbps) UID : 00 92 f0 a4 68 1f 02 d0 Manuf : 0x02 - STMicroelectronics ChipId : 0x1f - ST25TB04K Serial : 0x68a4f09200 |blk sz : 32 bits |nb blks: 128 |sys idx: 255 ``` (also checked for non-regression with `InListPassiveTarget`, including multiples `A` targets) --- examples/nfc-st25tb.c | 4 +++- libnfc/chips/pn53x.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/examples/nfc-st25tb.c b/examples/nfc-st25tb.c index 7eb5dee..178b57c 100644 --- a/examples/nfc-st25tb.c +++ b/examples/nfc-st25tb.c @@ -205,7 +205,8 @@ int main(int argc, char *argv[]) { printf("Reader : %s - via %s\n ...wait for card...\n", nfc_device_get_name(pnd), nfc_device_get_connstring(pnd)); - if (nfc_initiator_select_passive_target(pnd, nm, NULL, 0, &nt) > 0) + res = nfc_initiator_select_passive_target(pnd, nm, NULL, 0, &nt); + if (res > 0) { stcurrent = get_info(&nt, true); if(stcurrent) @@ -234,6 +235,7 @@ int main(int argc, char *argv[]) } } } + else printf("ERROR - nfc_initiator_select_passive_target: %i\n", res); } else printf("ERROR - nfc_initiator_init: %i\n", res); diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index e5d9d94..fdfa600 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -1267,6 +1267,7 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd, szTargetsData = (size_t)res; } found = true; + res = 1; // TargetCount to 1 as only one target is supported here break; } while (pnd->bInfiniteSelect); if (! found) @@ -1347,6 +1348,7 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd, return res; } found = true; + res = 1; // TargetCount to 1 as only one target is supported here break; } while (pnd->bInfiniteSelect); if (! found) { @@ -1377,6 +1379,7 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd, return res; } } + res = abtTargetsData[0]; // TargetCount to abtTargetsData[0] (Tg from InListPassiveTarget answer) } if (pn53x_current_target_new(pnd, &nttmp) == NULL) { pnd->last_error = NFC_ESOFT; @@ -1386,7 +1389,7 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd, if (pnt) { memcpy(pnt, &nttmp, sizeof(nfc_target)); } - return abtTargetsData[0]; + return res; } int