From a7b60bf2a610e1a364d26a925f3713c08d16d49c Mon Sep 17 00:00:00 2001 From: gornekich Date: Fri, 29 Dec 2023 07:24:20 +0400 Subject: [PATCH] MFC emulation fixes (#3324) * mf classic listener: fix write block * nfc: go to idle state instead of sleep * lib nfc: fix documentation --- lib/nfc/nfc.c | 2 +- lib/nfc/protocols/felica/felica_poller.h | 4 ++-- lib/nfc/protocols/iso14443_3a/iso14443_3a_poller.h | 4 ++-- lib/nfc/protocols/iso14443_3b/iso14443_3b_poller.h | 4 ++-- lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h | 4 ++-- lib/nfc/protocols/iso14443_4b/iso14443_4b_poller.h | 4 ++-- lib/nfc/protocols/iso15693_3/iso15693_3_poller.h | 4 ++-- lib/nfc/protocols/mf_classic/mf_classic_listener.c | 6 +++++- lib/nfc/protocols/mf_classic/mf_classic_listener_i.h | 3 +++ 9 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/nfc/nfc.c b/lib/nfc/nfc.c index 6475cce4..22a21c9d 100644 --- a/lib/nfc/nfc.c +++ b/lib/nfc/nfc.c @@ -150,7 +150,7 @@ static int32_t nfc_worker_listener(void* context) { } else if(command == NfcCommandReset) { furi_hal_nfc_listener_enable_rx(); } else if(command == NfcCommandSleep) { - furi_hal_nfc_listener_sleep(); + furi_hal_nfc_listener_idle(); } } } diff --git a/lib/nfc/protocols/felica/felica_poller.h b/lib/nfc/protocols/felica/felica_poller.h index 45fd9a9a..b0e6778a 100644 --- a/lib/nfc/protocols/felica/felica_poller.h +++ b/lib/nfc/protocols/felica/felica_poller.h @@ -18,8 +18,8 @@ typedef struct FelicaPoller FelicaPoller; * @brief Enumeration of possible Felica poller event types. */ typedef enum { - FelicaPollerEventTypeError, /**< The card was activated by the poller. */ - FelicaPollerEventTypeReady, /**< An error occured during activation procedure. */ + FelicaPollerEventTypeError, /**< An error occured during activation procedure. */ + FelicaPollerEventTypeReady, /**< The card was activated by the poller. */ } FelicaPollerEventType; /** diff --git a/lib/nfc/protocols/iso14443_3a/iso14443_3a_poller.h b/lib/nfc/protocols/iso14443_3a/iso14443_3a_poller.h index 42e4b4bf..c6649152 100644 --- a/lib/nfc/protocols/iso14443_3a/iso14443_3a_poller.h +++ b/lib/nfc/protocols/iso14443_3a/iso14443_3a_poller.h @@ -18,8 +18,8 @@ typedef struct Iso14443_3aPoller Iso14443_3aPoller; * @brief Enumeration of possible Iso14443_3a poller event types. */ typedef enum { - Iso14443_3aPollerEventTypeError, /**< The card was activated by the poller. */ - Iso14443_3aPollerEventTypeReady, /**< An error occured during activation procedure. */ + Iso14443_3aPollerEventTypeError, /**< An error occured during activation procedure. */ + Iso14443_3aPollerEventTypeReady, /**< The card was activated by the poller. */ } Iso14443_3aPollerEventType; /** diff --git a/lib/nfc/protocols/iso14443_3b/iso14443_3b_poller.h b/lib/nfc/protocols/iso14443_3b/iso14443_3b_poller.h index 940903c1..cdf8ddf6 100644 --- a/lib/nfc/protocols/iso14443_3b/iso14443_3b_poller.h +++ b/lib/nfc/protocols/iso14443_3b/iso14443_3b_poller.h @@ -18,8 +18,8 @@ typedef struct Iso14443_3bPoller Iso14443_3bPoller; * @brief Enumeration of possible Iso14443_3b poller event types. */ typedef enum { - Iso14443_3bPollerEventTypeError, /**< The card was activated by the poller. */ - Iso14443_3bPollerEventTypeReady, /**< An error occured during activation procedure. */ + Iso14443_3bPollerEventTypeError, /**< An error occured during activation procedure. */ + Iso14443_3bPollerEventTypeReady, /**< The card was activated by the poller. */ } Iso14443_3bPollerEventType; /** diff --git a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h index 73eb6ef7..fef565e5 100644 --- a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h +++ b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h @@ -17,8 +17,8 @@ typedef struct Iso14443_4aPoller Iso14443_4aPoller; * @brief Enumeration of possible Iso14443_4a poller event types. */ typedef enum { - Iso14443_4aPollerEventTypeError, /**< The card was activated by the poller. */ - Iso14443_4aPollerEventTypeReady, /**< An error occured during activation procedure. */ + Iso14443_4aPollerEventTypeError, /**< An error occured during activation procedure. */ + Iso14443_4aPollerEventTypeReady, /**< The card was activated by the poller. */ } Iso14443_4aPollerEventType; /** diff --git a/lib/nfc/protocols/iso14443_4b/iso14443_4b_poller.h b/lib/nfc/protocols/iso14443_4b/iso14443_4b_poller.h index 03b288c0..faccf2f3 100644 --- a/lib/nfc/protocols/iso14443_4b/iso14443_4b_poller.h +++ b/lib/nfc/protocols/iso14443_4b/iso14443_4b_poller.h @@ -17,8 +17,8 @@ typedef struct Iso14443_4bPoller Iso14443_4bPoller; * @brief Enumeration of possible Iso14443_4b poller event types. */ typedef enum { - Iso14443_4bPollerEventTypeError, /**< The card was activated by the poller. */ - Iso14443_4bPollerEventTypeReady, /**< An error occured during activation procedure. */ + Iso14443_4bPollerEventTypeError, /**< An error occured during activation procedure. */ + Iso14443_4bPollerEventTypeReady, /**< The card was activated by the poller. */ } Iso14443_4bPollerEventType; /** diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h index a187ceac..efe8337a 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h @@ -17,8 +17,8 @@ typedef struct Iso15693_3Poller Iso15693_3Poller; * @brief Enumeration of possible Iso15693_3 poller event types. */ typedef enum { - Iso15693_3PollerEventTypeError, /**< The card was activated by the poller. */ - Iso15693_3PollerEventTypeReady, /**< An error occured during activation procedure. */ + Iso15693_3PollerEventTypeError, /**< An error occured during activation procedure. */ + Iso15693_3PollerEventTypeReady, /**< The card was activated by the poller. */ } Iso15693_3PollerEventType; /** diff --git a/lib/nfc/protocols/mf_classic/mf_classic_listener.c b/lib/nfc/protocols/mf_classic/mf_classic_listener.c index bd25aba2..9f6f1f85 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_listener.c +++ b/lib/nfc/protocols/mf_classic/mf_classic_listener.c @@ -33,6 +33,7 @@ static void mf_classic_listener_reset_state(MfClassicListener* instance) { instance->state = MfClassicListenerStateIdle; instance->cmd_in_progress = false; instance->current_cmd_handler_idx = 0; + instance->write_block = 0; instance->transfer_value = 0; instance->transfer_valid = false; instance->value_cmd = MfClassicValueCommandInvalid; @@ -240,11 +241,13 @@ static MfClassicListenerCommand mf_classic_listener_write_block_first_part_handl uint8_t block_num = bit_buffer_get_byte(buff, 1); if(block_num >= instance->total_block_num) break; + if(block_num == 0) break; uint8_t sector_num = mf_classic_get_sector_by_block(block_num); uint8_t auth_sector_num = mf_classic_get_sector_by_block(auth_ctx->block_num); if(sector_num != auth_sector_num) break; + instance->write_block = block_num; instance->cmd_in_progress = true; instance->current_cmd_handler_idx++; command = MfClassicListenerCommandAck; @@ -265,7 +268,7 @@ static MfClassicListenerCommand mf_classic_listener_write_block_second_part_hand size_t buff_size = bit_buffer_get_size_bytes(buff); if(buff_size != sizeof(MfClassicBlock)) break; - uint8_t block_num = auth_ctx->block_num; + uint8_t block_num = instance->write_block; MfClassicKeyType key_type = auth_ctx->key_type; MfClassicBlock block = instance->data->block[block_num]; @@ -609,6 +612,7 @@ NfcCommand mf_classic_listener_run(NfcGenericEvent event, void* context) { mf_classic_listener_send_short_frame(instance, nack); mf_classic_listener_reset_state(instance); + command = NfcCommandSleep; } else if(mfc_command == MfClassicListenerCommandSilent) { command = NfcCommandReset; } else if(mfc_command == MfClassicListenerCommandSleep) { diff --git a/lib/nfc/protocols/mf_classic/mf_classic_listener_i.h b/lib/nfc/protocols/mf_classic/mf_classic_listener_i.h index 52273be9..5269743b 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_listener_i.h +++ b/lib/nfc/protocols/mf_classic/mf_classic_listener_i.h @@ -40,6 +40,9 @@ struct MfClassicListener { Crypto1* crypto; MfClassicAuthContext auth_context; + // Write block context + uint8_t write_block; + // Value operation data int32_t transfer_value; bool transfer_valid;