From 80a5ad1fd6e6e26107c52200c162d4eab25770e8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 7 Jun 2011 20:36:20 +0000 Subject: [PATCH] More attempt to support Sony S360 reader Initialisation of RC-S360 in mode 0 Better generic nfc-list, does not rely only on DeSelect to avoid duplicates Restore SetParameters for RC-S360 Handle Diagnose communication test properly Tested: - nfc-list => ok except for B' & 3B - nfc-anticol => fails to send raw frames before select - nfc-mfultralight => ok - nfc-mfclassic => ok - pn53x-tamashell => ok - pn53x-diagnose => ok - nfc-dep-initiator => ok - nfc-dep-target => fails in InitAsTarget - nfc-emulate-* => fails in InitAsTarget Commands momentarily disabled for RC-S330: - InDeselect - InRelease - select_passive_target for B'& 3B --- examples/pn53x-diagnose.c | 4 +++- libnfc/chips/pn53x-internal.h | 4 ++-- libnfc/chips/pn53x.c | 21 ++++++++++----------- libnfc/drivers/pn53x_usb.c | 14 ++++++++++---- libnfc/nfc.c | 16 +++++++++++++--- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/examples/pn53x-diagnose.c b/examples/pn53x-diagnose.c index fb57f67..7c47ba9 100644 --- a/examples/pn53x-diagnose.c +++ b/examples/pn53x-diagnose.c @@ -89,7 +89,9 @@ main (int argc, const char *argv[]) result = pn53x_transceive (pnd, pncmd_diagnose_communication_line_test, sizeof (pncmd_diagnose_communication_line_test), abtRx, &szRx); if (result) { - result = (memcmp (pncmd_diagnose_communication_line_test + 1, abtRx, sizeof (pncmd_diagnose_communication_line_test) - 1) == 0); + // Result of Diagnose ping for RC-S360 doesn't contain status byte so we've to handle both cases + result = (memcmp (pncmd_diagnose_communication_line_test + 1, abtRx, sizeof (pncmd_diagnose_communication_line_test) - 1) == 0) || + (memcmp (pncmd_diagnose_communication_line_test + 2, abtRx, sizeof (pncmd_diagnose_communication_line_test) - 2) == 0); } else { nfc_perror (pnd, "pn53x_transceive"); } diff --git a/libnfc/chips/pn53x-internal.h b/libnfc/chips/pn53x-internal.h index f61a3d7..f8d7c0c 100644 --- a/libnfc/chips/pn53x-internal.h +++ b/libnfc/chips/pn53x-internal.h @@ -120,7 +120,7 @@ typedef enum { PN531 = 0x01, PN532 = 0x02, PN533 = 0x04, - S330 = 0x08 + RCS360 = 0x08 } pn53x_type; #ifndef DEBUG @@ -142,7 +142,7 @@ typedef enum { static const pn53x_command pn53x_commands[] = { // Miscellaneous PNCMD( Diagnose, PN531|PN532|PN533 ), - PNCMD( GetFirmwareVersion, PN531|PN532|PN533|S330 ), + PNCMD( GetFirmwareVersion, PN531|PN532|PN533|RCS360 ), PNCMD( GetGeneralStatus, PN531|PN532|PN533 ), PNCMD( ReadRegister, PN531|PN532|PN533 ), PNCMD( WriteRegister, PN531|PN532|PN533 ), diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index dffc1ac..dac2db6 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -595,7 +595,7 @@ pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[22]) CHIP_DATA(pnd)->type = PN532; } else if (abtFw[0] == 0x33) { // PN533 version IC if (abtFw[1] == 0x01) { // Sony ROM code - CHIP_DATA(pnd)->type = S330; + CHIP_DATA(pnd)->type = RCS360; } else { CHIP_DATA(pnd)->type = PN533; } @@ -618,7 +618,7 @@ pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[22]) pnd->btSupportByte = abtFw[3]; break; case PN533: - case S330: + case RCS360: snprintf (abtFirmwareText, 22, "PN533 v%d.%d (0x%02x)", abtFw[1], abtFw[2], abtFw[3]); pnd->btSupportByte = abtFw[3]; break; @@ -855,6 +855,10 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, size_t szTargetsData = sizeof(abtTargetsData); if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT) { + if (CHIP_DATA(pnd)->type == RCS360) { + // TODO add support for RC-S360, at the moment it refuses to send raw frames without a first select + return false; + } // No native support in InListPassiveTarget so we do discovery by hand if (!nfc_configure (pnd, NDO_FORCE_ISO14443_B, true)) { return false; @@ -1843,11 +1847,6 @@ pn53x_strerror (const nfc_device_t * pnd) bool pn53x_SetParameters (nfc_device_t * pnd, const uint8_t ui8Value) { - if (CHIP_DATA (pnd)->type == S330) { - // TODO add support for S330 - return true; - } - byte_t abtCmd[] = { SetParameters, ui8Value }; if(!pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL)) { @@ -1965,8 +1964,8 @@ pn53x_InListPassiveTarget (nfc_device_t * pnd, bool pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target) { - if (CHIP_DATA(pnd)->type == S330) { - // TODO Add support for S330 + if (CHIP_DATA(pnd)->type == RCS360) { + // TODO Add support for RC-S360 return true; } byte_t abtCmd[] = { InDeselect, ui8Target }; @@ -1977,8 +1976,8 @@ pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target) bool pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target) { - if (CHIP_DATA(pnd)->type == S330) { - // TODO Add support for S330 + if (CHIP_DATA(pnd)->type == RCS360) { + // TODO Add support for RC-S360 return true; } byte_t abtCmd[] = { InRelease, ui8Target }; diff --git a/libnfc/drivers/pn53x_usb.c b/libnfc/drivers/pn53x_usb.c index 7c097d4..93cf73b 100644 --- a/libnfc/drivers/pn53x_usb.c +++ b/libnfc/drivers/pn53x_usb.c @@ -58,7 +58,7 @@ typedef enum { NXP_PN533, ASK_LOGO, SCM_SCL3711, - SONY_S330 + SONY_RCS360 } pn53x_usb_model; struct pn53x_usb_data { @@ -117,7 +117,7 @@ const struct pn53x_usb_supported_device pn53x_usb_supported_devices[] = { { 0x04E6, 0x5591, SCM_SCL3711, "SCM Micro / SCL3711-NFC&RW" }, { 0x054c, 0x0193, SONY_PN531, "Sony / PN531" }, { 0x1FD3, 0x0608, ASK_LOGO, "ASK / LoGO" }, - { 0x054C, 0x02E1, SONY_S330, "Sony / FeliCa S330 [PaSoRi]" } + { 0x054C, 0x02E1, SONY_RCS360, "Sony / FeliCa S360 [PaSoRi]" } }; pn53x_usb_model @@ -125,7 +125,7 @@ pn53x_usb_get_device_model (uint16_t vendor_id, uint16_t product_id) { for (size_t n = 0; n < sizeof (pn53x_usb_supported_devices) / sizeof (struct pn53x_usb_supported_device); n++) { if ((vendor_id == pn53x_usb_supported_devices[n].vendor_id) && - (product_id == pn53x_usb_supported_devices[n].product_id)) + (product_id == pn53x_usb_supported_devices[n].product_id)) return pn53x_usb_supported_devices[n].model; } @@ -570,11 +570,17 @@ bool pn53x_usb_init (nfc_device_t *pnd) { // Sometimes PN53x USB doesn't reply ACK one the first frame, so we need to send a dummy one... - //pn53x_check_communication (pnd); // Sony S330 doesn't support this command for now so let's use a get_firmware_version instead: + //pn53x_check_communication (pnd); // Sony RC-S360 doesn't support this command for now so let's use a get_firmware_version instead: const byte_t abtCmd[] = { GetFirmwareVersion }; pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL); // ...and we don't care about error pnd->iLastError = 0; + if (SONY_RCS360 == DRIVER_DATA (pnd)->model) { + DBG ("SONY RC-S360 initialization."); + const byte_t abtCmd2[] = { 0x18, 0x01 }; + pn53x_transceive (pnd, abtCmd2, sizeof (abtCmd2), NULL, NULL); + pn53x_usb_ack (pnd); + } if (!pn53x_init (pnd)) return false; diff --git a/libnfc/nfc.c b/libnfc/nfc.c index a534de0..4fda208 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -406,11 +406,21 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, while (nfc_initiator_select_passive_target (pnd, nm, pbtInitData, szInitDataLen, &nt)) { nfc_initiator_deselect_target (pnd); - if (szTargets > szTargetFound) { - memcpy (&(ant[szTargetFound]), &nt, sizeof (nfc_target_t)); - } else { + if (szTargets == szTargetFound) { break; } + int i; + bool seen = false; + // Check if we've already seen this tag + for (i = 0; i < szTargetFound; i++) { + if (memcmp(&(ant[i]), &nt, sizeof (nfc_target_t)) == 0) { + seen = true; + } + } + if (seen) { + break; + } + memcpy (&(ant[szTargetFound]), &nt, sizeof (nfc_target_t)); szTargetFound++; // deselect has no effect on FeliCa and Jewel cards so we'll stop after one... // ISO/IEC 14443 B' cards are polled at 100% probability so it's not possible to detect correctly two cards at the same time