From 841804026e5cfe2692d199ffff31763347c8dc58 Mon Sep 17 00:00:00 2001 From: gornekich Date: Tue, 3 Aug 2021 20:24:20 +0300 Subject: [PATCH] [FL-1619] NFC long APDU emulation (#623) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nfc: add apdu sequence exchange debug scene * api-hal-gpio: fix GPIO initialization * nfc: pull down nfc chip IRQ pin Co-authored-by: あく --- applications/nfc/nfc_worker.c | 2 +- applications/nfc/scenes/nfc_scene_config.h | 1 + .../scenes/nfc_scene_emulate_apdu_sequence.c | 38 +++++++++++++++++++ applications/nfc/scenes/nfc_scene_start.c | 17 ++++++--- firmware/targets/f6/api-hal/api-hal-gpio.c | 2 +- firmware/targets/f6/api-hal/api-hal-nfc.c | 3 +- lib/ST25RFAL002/platform.c | 2 +- 7 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index e536620ef..c5c9ed760 100755 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -364,7 +364,7 @@ void nfc_worker_emulate_emv(NfcWorker* nfc_worker) { }; while(nfc_worker->state == NfcWorkerStateEmulateEMV) { - if(api_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 100)) { + if(api_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 300)) { FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected"); // Read data from POS terminal err = api_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false); diff --git a/applications/nfc/scenes/nfc_scene_config.h b/applications/nfc/scenes/nfc_scene_config.h index 385b84a30..149b4d7f7 100755 --- a/applications/nfc/scenes/nfc_scene_config.h +++ b/applications/nfc/scenes/nfc_scene_config.h @@ -25,3 +25,4 @@ ADD_SCENE(nfc, delete_success, DeleteSuccess) ADD_SCENE(nfc, run_emv_app_confirm, RunEmvAppConfirm) ADD_SCENE(nfc, read_emv_data, ReadEmvData) ADD_SCENE(nfc, read_emv_data_success, ReadEmvDataSuccess) +ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence) diff --git a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c new file mode 100644 index 000000000..2f5018c83 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c @@ -0,0 +1,38 @@ +#include "../nfc_i.h" + +const void nfc_scene_emulate_apdu_sequence_on_enter(void* context) { + Nfc* nfc = (Nfc*)context; + + // Setup view + Popup* popup = nfc->popup; + + popup_set_header(popup, "Run APDU reader", 64, 31, AlignCenter, AlignTop); + + // Setup and start worker + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); + nfc_worker_start(nfc->worker, NfcWorkerStateEmulateEMV, &nfc->dev.dev_data, NULL, nfc); +} + +const bool nfc_scene_emulate_apdu_sequence_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = (Nfc*)context; + + if(event.type == SceneManagerEventTypeTick) { + notification_message(nfc->notifications, &sequence_blink_blue_10); + return true; + } + return false; +} + +const void nfc_scene_emulate_apdu_sequence_on_exit(void* context) { + Nfc* nfc = (Nfc*)context; + + // Stop worker + nfc_worker_stop(nfc->worker); + + // Clear view + Popup* popup = nfc->popup; + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); +} diff --git a/applications/nfc/scenes/nfc_scene_start.c b/applications/nfc/scenes/nfc_scene_start.c index 78a4d923b..3b560c078 100755 --- a/applications/nfc/scenes/nfc_scene_start.c +++ b/applications/nfc/scenes/nfc_scene_start.c @@ -5,6 +5,7 @@ enum SubmenuIndex { SubmenuIndexRunScript, SubmenuIndexSaved, SubmenuIndexAddManualy, + SubmenuIndexDebug, }; void nfc_scene_start_submenu_callback(void* context, uint32_t index) { @@ -29,6 +30,7 @@ const void nfc_scene_start_on_enter(void* context) { submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc); submenu_add_item( submenu, "Add manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc); + submenu_add_item(submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc); submenu_set_selected_item( submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneStart)); @@ -38,29 +40,34 @@ const void nfc_scene_start_on_enter(void* context) { const bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = (Nfc*)context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexRead) { scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexRead); scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCard); - return true; + consumed = true; } else if(event.event == SubmenuIndexRunScript) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneStart, SubmenuIndexRunScript); scene_manager_next_scene(nfc->scene_manager, NfcSceneScriptsMenu); - return true; + consumed = true; } else if(event.event == SubmenuIndexSaved) { scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexSaved); scene_manager_next_scene(nfc->scene_manager, NfcSceneFileSelect); - return true; + consumed = true; } else if(event.event == SubmenuIndexAddManualy) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneStart, SubmenuIndexAddManualy); scene_manager_next_scene(nfc->scene_manager, NfcSceneSetType); - return true; + consumed = true; + } else if(event.event == SubmenuIndexDebug) { + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexDebug); + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateApduSequence); + consumed = true; } } - return false; + return consumed; } const void nfc_scene_start_on_exit(void* context) { diff --git a/firmware/targets/f6/api-hal/api-hal-gpio.c b/firmware/targets/f6/api-hal/api-hal-gpio.c index 03d79d4c7..338ee00b4 100644 --- a/firmware/targets/f6/api-hal/api-hal-gpio.c +++ b/firmware/targets/f6/api-hal/api-hal-gpio.c @@ -54,7 +54,7 @@ void hal_gpio_init( furi_assert(mode != GpioModeAltFunctionPushPull); furi_assert(mode != GpioModeAltFunctionOpenDrain); - hal_gpio_init_ex(gpio, mode, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused); } void hal_gpio_init_ex( diff --git a/firmware/targets/f6/api-hal/api-hal-nfc.c b/firmware/targets/f6/api-hal/api-hal-nfc.c index 56f675f60..cb75dd26b 100644 --- a/firmware/targets/f6/api-hal/api-hal-nfc.c +++ b/firmware/targets/f6/api-hal/api-hal-nfc.c @@ -88,12 +88,13 @@ bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t tim bool api_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout) { rfalNfcState state = rfalNfcGetState(); + if(state == RFAL_NFC_STATE_NOTINIT) { rfalNfcInitialize(); } else if(state >= RFAL_NFC_STATE_ACTIVATED) { rfalNfcDeactivate(false); } - + rfalLowPowerModeStop(); rfalNfcDiscoverParam params = { .compMode = RFAL_COMPLIANCE_MODE_NFC, .techs2Find = RFAL_NFC_LISTEN_TECH_A, diff --git a/lib/ST25RFAL002/platform.c b/lib/ST25RFAL002/platform.c index d3b0df449..c63218ff2 100644 --- a/lib/ST25RFAL002/platform.c +++ b/lib/ST25RFAL002/platform.c @@ -27,7 +27,7 @@ void platformIrqWorker() { } void platformEnableIrqCallback() { - hal_gpio_init(&pin, GpioModeInterruptRise, GpioPullNo, GpioSpeedLow); + hal_gpio_init(&pin, GpioModeInterruptRise, GpioPullDown, GpioSpeedLow); hal_gpio_enable_int_callback(&pin); }