From 6126307d8568eff349c30dd620b54419fb9b8847 Mon Sep 17 00:00:00 2001 From: WillyJL Date: Fri, 2 Jan 2026 23:46:59 +0100 Subject: [PATCH] NFC: Initial ISO 15693-3 poller state machine restructure --- .../protocols/iso15693_3/iso15693_3_poller.c | 62 +++++++++++++++++++ .../protocols/iso15693_3/iso15693_3_poller.h | 38 +++++++++++- .../iso15693_3/iso15693_3_poller_i.h | 13 +++- 3 files changed, 108 insertions(+), 5 deletions(-) diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c index cf27b1f3f..c86713974 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c @@ -6,6 +6,8 @@ #define TAG "ISO15693_3Poller" +typedef NfcCommand (*Iso15693_3PollerStateHandler)(Iso15693_3Poller* instance); + const Iso15693_3Data* iso15693_3_poller_get_data(Iso15693_3Poller* instance) { furi_assert(instance); furi_assert(instance->data); @@ -48,6 +50,59 @@ static void iso15693_3_poller_free(Iso15693_3Poller* instance) { free(instance); } +static NfcCommand iso15693_3_poller_handler_idle(Iso15693_3Poller* instance) { + bit_buffer_reset(instance->tx_buffer); + bit_buffer_reset(instance->rx_buffer); + + instance->state = Iso15693_3PollerStateRequestMode; + return NfcCommandContinue; +} + +static NfcCommand iso15693_3_poller_handler_request_mode(Iso15693_3Poller* instance) { + NfcCommand command = NfcCommandContinue; + + instance->iso15693_3_event.type = Iso15693_3PollerEventTypeRequestMode; + instance->iso15693_3_event.data->poller_mode.mode = Iso15693_3PollerModeRead; + instance->iso15693_3_event.data->poller_mode.data = NULL; + + command = instance->callback(instance->general_event, instance->context); + instance->mode = instance->iso15693_3_event.data->poller_mode.mode; + if(instance->mode == Iso15693_3PollerModeWrite) { + iso15693_3_copy(instance->data, instance->iso15693_3_event.data->poller_mode.data); + } + + instance->state = Iso15693_3PollerStateActivate; + return command; +} + +static NfcCommand iso15693_3_poller_handler_failed(Iso15693_3Poller* instance) { + FURI_LOG_D(TAG, "Operation Failed"); + instance->iso15693_3_event.type = instance->mode == Iso15693_3PollerModeRead ? + Iso15693_3PollerEventTypeReadFailed : + Iso15693_3PollerEventTypeWriteFailed; + instance->iso15693_3_event.data->error = instance->error; + NfcCommand command = instance->callback(instance->general_event, instance->context); + instance->state = Iso15693_3PollerStateIdle; + return command; +} + +static NfcCommand iso15693_3_poller_handler_success(Iso15693_3Poller* instance) { + FURI_LOG_D(TAG, "Operation succeeded"); + instance->iso15693_3_event.type = instance->mode == Iso15693_3PollerModeRead ? + Iso15693_3PollerEventTypeReadSuccess : + Iso15693_3PollerEventTypeWriteSuccess; + NfcCommand command = instance->callback(instance->general_event, instance->context); + return command; +} + +static const Iso15693_3PollerStateHandler + iso15693_3_poller_read_handler[Iso15693_3PollerStateNum] = { + [Iso15693_3PollerStateIdle] = iso15693_3_poller_handler_idle, + [Iso15693_3PollerStateRequestMode] = iso15693_3_poller_handler_request_mode, + [Iso15693_3PollerStateFailed] = iso15693_3_poller_handler_failed, + [Iso15693_3PollerStateSuccess] = iso15693_3_poller_handler_success, +}; + static void iso15693_3_poller_set_callback( Iso15693_3Poller* instance, NfcGenericCallback callback, @@ -69,6 +124,9 @@ static NfcCommand iso15693_3_poller_run(NfcGenericEvent event, void* context) { NfcCommand command = NfcCommandContinue; if(nfc_event->type == NfcEventTypePollerReady) { + command = iso15693_3_poller_read_handler[instance->state](instance); + + // FIXME: convert to new state machine if(instance->state != Iso15693_3PollerStateActivated) { Iso15693_3Error error = iso15693_3_poller_activate(instance, instance->data); if(error == Iso15693_3ErrorNone) { @@ -89,6 +147,10 @@ static NfcCommand iso15693_3_poller_run(NfcGenericEvent event, void* context) { } } + if(command == NfcCommandReset) { + instance->state = Iso15693_3PollerStateIdle; + } + return command; } diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h index efe8337af..451fcdbd9 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h @@ -17,15 +17,49 @@ typedef struct Iso15693_3Poller Iso15693_3Poller; * @brief Enumeration of possible Iso15693_3 poller event types. */ typedef enum { - Iso15693_3PollerEventTypeError, /**< An error occured during activation procedure. */ - Iso15693_3PollerEventTypeReady, /**< The card was activated by the poller. */ + Iso15693_3PollerEventTypeRequestMode, /**< Poller requests for operating mode. */ + Iso15693_3PollerEventTypeReadSuccess, /**< The card was activated by the poller and maybe memory was read. */ + Iso15693_3PollerEventTypeReadFailed, /**< An error occured during activation/reading procedure. */ + Iso15693_3PollerEventTypeWriteSuccess, /**< The card was written to successfully. */ + Iso15693_3PollerEventTypeWriteFailed, /**< An error occurred during writing to the card. */ } Iso15693_3PollerEventType; +// FIXME: update usages of these in firmware, re-evaluate if they should be kept or just break api + +/** + * @warning deprecated, use Iso15693_3PollerEventTypeReadFailed instead + */ +#define Iso15693_3PollerEventTypeError Iso15693_3PollerEventTypeReadFailed + +/** + * @warning deprecated, use Iso15693_3PollerEventTypeReadSuccess instead + */ +#define Iso15693_3PollerEventTypeReady Iso15693_3PollerEventTypeReadSuccess + +/** + * @brief Enumeration of possible Iso15693_3 poller operating modes. + */ +typedef enum { + Iso15693_3PollerModeRead, /**< Poller will only read card. It's a default mode. */ + Iso15693_3PollerModeWrite, /**< Poller will write already saved card to another presented card. */ +} Iso15693_3PollerMode; + +/** + * @brief Iso15693_3 poller request mode event data. + * + * This instance of this structure must be filled on Iso15693_3PollerEventTypeRequestMode event. + */ +typedef struct { + Iso15693_3PollerMode mode; /**< Mode to be used by poller. */ + const Iso15693_3Data* data; /**< Data to be used by poller. */ +} Iso15693_3PollerEventDataRequestMode; + /** * @brief Iso15693_3 poller event data. */ typedef union { Iso15693_3Error error; /**< Error code indicating card activation fail reason. */ + Iso15693_3PollerEventDataRequestMode poller_mode; /**< Poller mode context. */ } Iso15693_3PollerEventData; /** diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h index 346d0d724..9fe942ba9 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h @@ -14,14 +14,21 @@ extern "C" { typedef enum { Iso15693_3PollerStateIdle, - Iso15693_3PollerStateColResInProgress, - Iso15693_3PollerStateColResFailed, - Iso15693_3PollerStateActivated, + Iso15693_3PollerStateRequestMode, + Iso15693_3PollerStateActivate, + Iso15693_3PollerStateRead, + Iso15693_3PollerStateWrite, + Iso15693_3PollerStateFailed, + Iso15693_3PollerStateSuccess, + + Iso15693_3PollerStateNum, } Iso15693_3PollerState; struct Iso15693_3Poller { Nfc* nfc; Iso15693_3PollerState state; + Iso15693_3PollerMode mode; + Iso15693_3Error error; Iso15693_3Data* data; BitBuffer* tx_buffer; BitBuffer* rx_buffer;