Parcourir la source

[FL-1619] NFC long APDU emulation (#623)

* nfc: add apdu sequence exchange debug scene
* api-hal-gpio: fix GPIO initialization
* nfc: pull down nfc chip IRQ pin

Co-authored-by: あく <alleteam@gmail.com>
gornekich il y a 4 ans
Parent
commit
841804026e

+ 1 - 1
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);

+ 1 - 0
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)

+ 38 - 0
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);
+}

+ 12 - 5
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) {

+ 1 - 1
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(

+ 2 - 1
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,

+ 1 - 1
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);
 }