[FL-2369] NFC refactoring (#1095)

* nfc: clean up scenes
* nfc worker: remove field on from worker
* nfc worker: move full data exchange to furi hal
* nfc_device: check UID length
* nfc protocol: introduce mifare common API
* nfc: move common data to furi hal nfc
* nfc: rename emv_decoder -> emv
* nfc: move emv data structure to emv lib
* nfc: remove deactivate after detection
* nfc: rework furi hal nfc detect
* nfc: clean up CLI commands and type
* nfc: remove unused includes and function
* nfc: add TxRxType enum
* nfc: read mifare ultralight refactoring
* nfc: refactore mifare ultralight start
* rfal: fix custom data exchange
* nfc: refactor read bank card
* nfc: refactor read emv application
* nfc: refactor emv test emulation
* nfc: refactor uid emulation
* nfc: add limit to uid emulation logger
* fix source formatting
* furi_hal_nfc: fix data exchange full
* nfc: fix mifare ultralight type load

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
gornekich
2022-04-19 18:23:58 +03:00
committed by GitHub
parent e55d1572da
commit 956788c09b
58 changed files with 1349 additions and 1601 deletions

View File

@@ -17,7 +17,7 @@ void nfc_scene_card_menu_on_enter(void* context) {
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
if(nfc->dev->dev_data.nfc_data.protocol > NfcDeviceProtocolUnknown) {
if(nfc->dev->dev_data.protocol > NfcDeviceProtocolUnknown) {
submenu_add_item(
submenu,
"Run Compatible App",
@@ -49,13 +49,13 @@ bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
if(event.event == SubmenuIndexRunApp) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexRunApp);
if(nfc->dev->dev_data.nfc_data.protocol == NfcDeviceProtocolMifareUl) {
if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareUl) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareUl);
} else if(nfc->dev->dev_data.nfc_data.protocol == NfcDeviceProtocolMifareDesfire) {
} else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareDesfire) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareDesfire);
} else if(nfc->dev->dev_data.nfc_data.protocol == NfcDeviceProtocolEMV) {
} else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolEMV) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvApp);
} else if(nfc->dev->dev_data.nfc_data.protocol == NfcDeviceProtocolMifareClassic) {
} else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareClassic) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareClassic);
}
consumed = true;

View File

@@ -2,7 +2,6 @@ ADD_SCENE(nfc, start, Start)
ADD_SCENE(nfc, read_card, ReadCard)
ADD_SCENE(nfc, read_card_success, ReadCardSuccess)
ADD_SCENE(nfc, card_menu, CardMenu)
ADD_SCENE(nfc, not_implemented, NotImplemented)
ADD_SCENE(nfc, emulate_uid, EmulateUid)
ADD_SCENE(nfc, save_name, SaveName)
ADD_SCENE(nfc, save_success, SaveSuccess)

View File

@@ -6,13 +6,13 @@ enum SubmenuDebugIndex {
};
void nfc_scene_debug_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
void nfc_scene_debug_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
submenu_add_item(
@@ -28,7 +28,7 @@ void nfc_scene_debug_on_enter(void* context) {
}
bool nfc_scene_debug_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
@@ -48,7 +48,7 @@ bool nfc_scene_debug_on_event(void* context, SceneManagerEvent event) {
}
void nfc_scene_debug_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
submenu_reset(nfc->submenu);
}

View File

@@ -1,29 +1,28 @@
#include "../nfc_i.h"
void nfc_scene_delete_widget_callback(GuiButtonType result, InputType type, void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
if(type == InputTypeShort) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
}
void nfc_scene_delete_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Setup Custom Widget view
char delete_str[64];
snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", nfc->dev->dev_name);
widget_add_text_box_element(nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str);
char temp_str[64];
snprintf(temp_str, sizeof(temp_str), "\e#Delete %s?\e#", nfc->dev->dev_name);
widget_add_text_box_element(nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, temp_str);
widget_add_button_element(
nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_delete_widget_callback, nfc);
widget_add_button_element(
nfc->widget, GuiButtonTypeRight, "Delete", nfc_scene_delete_widget_callback, nfc);
char uid_str[32];
NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data;
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
if(data->uid_len == 4) {
snprintf(
uid_str,
sizeof(uid_str),
temp_str,
sizeof(temp_str),
"UID: %02X %02X %02X %02X",
data->uid[0],
data->uid[1],
@@ -31,8 +30,8 @@ void nfc_scene_delete_on_enter(void* context) {
data->uid[3]);
} else if(data->uid_len == 7) {
snprintf(
uid_str,
sizeof(uid_str),
temp_str,
sizeof(temp_str),
"UID: %02X %02X %02X %02X %02X %02X %02X",
data->uid[0],
data->uid[1],
@@ -42,12 +41,13 @@ void nfc_scene_delete_on_enter(void* context) {
data->uid[5],
data->uid[6]);
}
widget_add_string_element(nfc->widget, 64, 23, AlignCenter, AlignTop, FontSecondary, uid_str);
widget_add_string_element(nfc->widget, 64, 23, AlignCenter, AlignTop, FontSecondary, temp_str);
const char* protocol_name = NULL;
if(data->protocol == NfcDeviceProtocolEMV) {
protocol_name = nfc_guess_protocol(data->protocol);
} else if(data->protocol == NfcDeviceProtocolMifareUl) {
NfcProtocol protocol = nfc->dev->dev_data.protocol;
if(protocol == NfcDeviceProtocolEMV) {
protocol_name = nfc_guess_protocol(protocol);
} else if(protocol == NfcDeviceProtocolMifareUl) {
protocol_name = nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, false);
}
if(protocol_name) {
@@ -56,18 +56,17 @@ void nfc_scene_delete_on_enter(void* context) {
}
// TODO change dinamically
widget_add_string_element(nfc->widget, 118, 33, AlignRight, AlignTop, FontSecondary, "NFC-A");
char sak_str[16];
snprintf(sak_str, sizeof(sak_str), "SAK: %02X", data->sak);
widget_add_string_element(nfc->widget, 10, 43, AlignLeft, AlignTop, FontSecondary, sak_str);
char atqa_str[16];
snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]);
widget_add_string_element(nfc->widget, 118, 43, AlignRight, AlignTop, FontSecondary, atqa_str);
snprintf(temp_str, sizeof(temp_str), "SAK: %02X", data->sak);
widget_add_string_element(nfc->widget, 10, 43, AlignLeft, AlignTop, FontSecondary, temp_str);
snprintf(temp_str, sizeof(temp_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]);
widget_add_string_element(nfc->widget, 118, 43, AlignRight, AlignTop, FontSecondary, temp_str);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeLeft) {
@@ -79,14 +78,14 @@ bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) {
scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneStart);
}
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_delete_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
widget_reset(nfc->widget);
}

View File

@@ -1,12 +1,12 @@
#include "../nfc_i.h"
void nfc_scene_delete_success_popup_callback(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
}
void nfc_scene_delete_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Setup view
Popup* popup = nfc->popup;
@@ -20,27 +20,21 @@ void nfc_scene_delete_success_on_enter(void* context) {
}
bool nfc_scene_delete_success_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventViewExit) {
return scene_manager_search_and_switch_to_previous_scene(
consumed = scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneStart);
}
}
return false;
return consumed;
}
void nfc_scene_delete_success_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// 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);
popup_set_callback(popup, NULL);
popup_set_context(popup, NULL);
popup_set_timeout(popup, 0);
popup_disable_timeout(popup);
}
popup_reset(nfc->popup);
}

View File

@@ -43,12 +43,12 @@ void nfc_scene_device_info_on_enter(void* context) {
widget_add_button_element(
nfc->widget, GuiButtonTypeRight, "Data", nfc_scene_device_info_widget_callback, nfc);
}
char uid_str[32];
NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data;
char temp_str[32];
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
if(data->uid_len == 4) {
snprintf(
uid_str,
sizeof(uid_str),
temp_str,
sizeof(temp_str),
"UID: %02X %02X %02X %02X",
data->uid[0],
data->uid[1],
@@ -56,8 +56,8 @@ void nfc_scene_device_info_on_enter(void* context) {
data->uid[3]);
} else if(data->uid_len == 7) {
snprintf(
uid_str,
sizeof(uid_str),
temp_str,
sizeof(temp_str),
"UID: %02X %02X %02X %02X %02X %02X %02X",
data->uid[0],
data->uid[1],
@@ -67,15 +67,15 @@ void nfc_scene_device_info_on_enter(void* context) {
data->uid[5],
data->uid[6]);
}
widget_add_string_element(nfc->widget, 64, 21, AlignCenter, AlignTop, FontSecondary, uid_str);
widget_add_string_element(nfc->widget, 64, 21, AlignCenter, AlignTop, FontSecondary, temp_str);
const char* protocol_name = NULL;
if(data->protocol == NfcDeviceProtocolEMV ||
data->protocol == NfcDeviceProtocolMifareDesfire) {
protocol_name = nfc_guess_protocol(data->protocol);
} else if(data->protocol == NfcDeviceProtocolMifareUl) {
NfcProtocol protocol = nfc->dev->dev_data.protocol;
if(protocol == NfcDeviceProtocolEMV || protocol == NfcDeviceProtocolMifareDesfire) {
protocol_name = nfc_guess_protocol(protocol);
} else if(protocol == NfcDeviceProtocolMifareUl) {
protocol_name = nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, false);
} else if(data->protocol == NfcDeviceProtocolMifareClassic) {
} else if(protocol == NfcDeviceProtocolMifareClassic) {
protocol_name = nfc_mf_classic_type(nfc->dev->dev_data.mf_classic_data.type);
}
if(protocol_name) {
@@ -84,12 +84,10 @@ void nfc_scene_device_info_on_enter(void* context) {
}
// TODO change dinamically
widget_add_string_element(nfc->widget, 118, 32, AlignRight, AlignTop, FontSecondary, "NFC-A");
char sak_str[16];
snprintf(sak_str, sizeof(sak_str), "SAK: %02X", data->sak);
widget_add_string_element(nfc->widget, 10, 42, AlignLeft, AlignTop, FontSecondary, sak_str);
char atqa_str[16];
snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]);
widget_add_string_element(nfc->widget, 118, 42, AlignRight, AlignTop, FontSecondary, atqa_str);
snprintf(temp_str, sizeof(temp_str), "SAK: %02X", data->sak);
widget_add_string_element(nfc->widget, 10, 42, AlignLeft, AlignTop, FontSecondary, temp_str);
snprintf(temp_str, sizeof(temp_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]);
widget_add_string_element(nfc->widget, 118, 42, AlignRight, AlignTop, FontSecondary, temp_str);
// Setup Data View
if(nfc->dev->format == NfcDeviceSaveFormatUid) {
@@ -99,7 +97,7 @@ void nfc_scene_device_info_on_enter(void* context) {
dialog_ex_set_context(dialog_ex, nfc);
dialog_ex_set_result_callback(dialog_ex, nfc_scene_device_info_dialog_callback);
} else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
MifareUlData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data;
MfUltralightData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data;
TextBox* text_box = nfc->text_box;
text_box_set_font(text_box, TextBoxFontHex);
for(uint16_t i = 0; i < mf_ul_data->data_size; i += 2) {
@@ -130,7 +128,7 @@ void nfc_scene_device_info_on_enter(void* context) {
widget_add_string_element(
nfc->widget, 64, 17, AlignCenter, AlignBottom, FontSecondary, nfc->text_store);
} else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data;
EmvData* emv_data = &nfc->dev->dev_data.emv_data;
BankCard* bank_card = nfc->bank_card;
bank_card_set_name(bank_card, emv_data->name);
bank_card_set_number(bank_card, emv_data->number, emv_data->number_len);
@@ -212,21 +210,16 @@ bool nfc_scene_device_info_on_event(void* context, SceneManagerEvent event) {
}
void nfc_scene_device_info_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear Custom Widget
// Clear views
widget_reset(nfc->widget);
if(nfc->dev->format == NfcDeviceSaveFormatUid) {
// Clear Dialog
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_reset(dialog_ex);
dialog_ex_reset(nfc->dialog_ex);
} else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
// Clear TextBox
text_box_reset(nfc->text_box);
string_reset(nfc->text_box_store);
} else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
// Clear Bank Card
bank_card_clear(nfc->bank_card);
}
}

View File

@@ -1,36 +1,34 @@
#include "../nfc_i.h"
void nfc_scene_emulate_apdu_sequence_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
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, NfcWorkerStateEmulateApdu, &nfc->dev->dev_data, NULL, nfc);
}
bool nfc_scene_emulate_apdu_sequence_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeTick) {
notification_message(nfc->notifications, &sequence_blink_blue_10);
return true;
consumed = true;
}
return false;
return consumed;
}
void nfc_scene_emulate_apdu_sequence_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Stop worker
nfc_worker_stop(nfc->worker);
// Clear view
Popup* popup = nfc->popup;
popup_reset(popup);
popup_reset(nfc->popup);
}

View File

@@ -5,13 +5,14 @@
#define NFC_MF_UL_DATA_CHANGED (1UL)
void nfc_emulate_mifare_ul_worker_callback(NfcWorkerEvent event, void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_UL_DATA_CHANGED);
}
void nfc_scene_emulate_mifare_ul_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcEmulate);
// Setup view
@@ -26,14 +27,14 @@ void nfc_scene_emulate_mifare_ul_on_enter(void* context) {
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
nfc_worker_start(
nfc->worker,
NfcWorkerStateEmulateMifareUl,
NfcWorkerStateEmulateMifareUltralight,
&nfc->dev->dev_data,
nfc_emulate_mifare_ul_worker_callback,
nfc);
}
bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeTick) {
@@ -55,11 +56,8 @@ bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event
}
void nfc_scene_emulate_mifare_ul_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// 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);
popup_reset(nfc->popup);
}

View File

@@ -1,6 +1,8 @@
#include "../nfc_i.h"
#include <dolphin/dolphin.h>
#define NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX (200)
enum {
NfcSceneEmulateUidStateWidget,
NfcSceneEmulateUidStateTextBox,
@@ -28,7 +30,7 @@ void nfc_emulate_uid_textbox_callback(void* context) {
// Add widget with device name or inform that data received
static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) {
NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data;
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
Widget* widget = nfc->widget;
widget_reset(widget);
string_t info_str;
@@ -95,13 +97,15 @@ bool nfc_scene_emulate_uid_on_event(void* context, SceneManagerEvent event) {
nfc_scene_emulate_uid_widget_config(nfc, true);
}
// Update TextBox data
string_cat_printf(nfc->text_box_store, "R:");
for(uint16_t i = 0; i < reader_data->size; i++) {
string_cat_printf(nfc->text_box_store, " %02X", reader_data->data[i]);
if(string_size(nfc->text_box_store) < NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX) {
string_cat_printf(nfc->text_box_store, "R:");
for(uint16_t i = 0; i < reader_data->size; i++) {
string_cat_printf(nfc->text_box_store, " %02X", reader_data->data[i]);
}
string_push_back(nfc->text_box_store, '\n');
text_box_set_text(nfc->text_box, string_get_cstr(nfc->text_box_store));
}
string_push_back(nfc->text_box_store, '\n');
memset(reader_data, 0, sizeof(NfcReaderRequestData));
text_box_set_text(nfc->text_box, string_get_cstr(nfc->text_box_store));
consumed = true;
} else if(event.event == GuiButtonTypeCenter && state == NfcSceneEmulateUidStateWidget) {
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);

View File

@@ -1,7 +1,7 @@
#include "../nfc_i.h"
void nfc_scene_field_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
furi_hal_nfc_field_on();
@@ -23,12 +23,9 @@ bool nfc_scene_field_on_event(void* context, SceneManagerEvent event) {
}
void nfc_scene_field_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
notification_internal_message(nfc->notifications, &sequence_reset_blue);
Popup* popup = nfc->popup;
popup_reset(popup);
Nfc* nfc = context;
furi_hal_nfc_field_off();
notification_internal_message(nfc->notifications, &sequence_reset_blue);
popup_reset(nfc->popup);
}

View File

@@ -1,7 +1,7 @@
#include "../nfc_i.h"
void nfc_scene_file_select_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Process file_select return
if(nfc_file_select(nfc->dev)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu);

View File

@@ -18,13 +18,13 @@ MifareDesfireApplication* nfc_scene_mifare_desfire_app_get_app(Nfc* nfc) {
}
void nfc_scene_mifare_desfire_app_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
void nfc_scene_mifare_desfire_app_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
MifareDesfireApplication* app = nfc_scene_mifare_desfire_app_get_app(nfc);
if(!app) {
@@ -73,7 +73,8 @@ void nfc_scene_mifare_desfire_app_on_enter(void* context) {
}
bool nfc_scene_mifare_desfire_app_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireApp);
if(event.type == SceneManagerEventTypeCustom) {
@@ -96,24 +97,24 @@ bool nfc_scene_mifare_desfire_app_on_event(void* context, SceneManagerEvent even
text_box_set_text(text_box, string_get_cstr(nfc->text_box_store));
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMifareDesfireApp, state | 1);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);
return true;
consumed = true;
} else if(event.type == SceneManagerEventTypeBack) {
if(state & 1) {
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMifareDesfireApp, state & ~1);
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_mifare_desfire_app_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear views
text_box_reset(nfc->text_box);
string_reset(nfc->text_box_store);
submenu_reset(nfc->submenu);
}

View File

@@ -19,7 +19,7 @@ void nfc_scene_mifare_desfire_data_submenu_callback(void* context, uint32_t inde
}
void nfc_scene_mifare_desfire_data_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireData);
MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data;
@@ -61,7 +61,8 @@ void nfc_scene_mifare_desfire_data_on_enter(void* context) {
}
bool nfc_scene_mifare_desfire_data_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireData);
MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data;
@@ -76,7 +77,7 @@ bool nfc_scene_mifare_desfire_data_on_event(void* context, SceneManagerEvent eve
nfc->scene_manager,
NfcSceneMifareDesfireData,
MifareDesfireDataStateItem + SubmenuIndexCardInfo);
return true;
consumed = true;
} else {
uint16_t index = event.event - SubmenuIndexDynamic;
scene_manager_set_scene_state(
@@ -84,25 +85,25 @@ bool nfc_scene_mifare_desfire_data_on_event(void* context, SceneManagerEvent eve
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMifareDesfireApp, index << 1);
scene_manager_next_scene(nfc->scene_manager, NfcSceneMifareDesfireApp);
return true;
consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
if(state >= MifareDesfireDataStateItem) {
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMifareDesfireData, MifareDesfireDataStateMenu);
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_mifare_desfire_data_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear views
text_box_reset(nfc->text_box);
string_reset(nfc->text_box_store);
submenu_reset(nfc->submenu);
}

View File

@@ -5,13 +5,13 @@ enum SubmenuIndex {
};
void nfc_scene_mifare_desfire_menu_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
void nfc_scene_mifare_desfire_menu_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
submenu_add_item(
@@ -24,7 +24,8 @@ void nfc_scene_mifare_desfire_menu_on_enter(void* context) {
}
bool nfc_scene_mifare_desfire_menu_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexSave) {
@@ -34,15 +35,16 @@ bool nfc_scene_mifare_desfire_menu_on_event(void* context, SceneManagerEvent eve
// Clear device name
nfc_device_set_name(nfc->dev, "");
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_mifare_desfire_menu_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear view
submenu_reset(nfc->submenu);
}

View File

@@ -6,13 +6,13 @@ enum SubmenuIndex {
};
void nfc_scene_mifare_ul_menu_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
void nfc_scene_mifare_ul_menu_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
submenu_add_item(
@@ -26,7 +26,8 @@ void nfc_scene_mifare_ul_menu_on_enter(void* context) {
}
bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexSave) {
@@ -36,23 +37,24 @@ bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) {
// Clear device name
nfc_device_set_name(nfc->dev, "");
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
return true;
consumed = true;
} else if(event.event == SubmenuIndexEmulate) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexEmulate);
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl);
return true;
consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
return scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneStart);
consumed =
scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart);
}
return false;
return consumed;
}
void nfc_scene_mifare_ul_menu_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear view
submenu_reset(nfc->submenu);
}

View File

@@ -1,42 +0,0 @@
#include "../nfc_i.h"
void nfc_scene_not_implemented_dialog_callback(DialogExResult result, void* context) {
Nfc* nfc = (Nfc*)context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
void nfc_scene_not_implemented_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
// TODO Set data from worker
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Back");
dialog_ex_set_header(dialog_ex, "Not implemented", 60, 24, AlignCenter, AlignCenter);
dialog_ex_set_context(dialog_ex, nfc);
dialog_ex_set_result_callback(dialog_ex, nfc_scene_not_implemented_dialog_callback);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
}
bool nfc_scene_not_implemented_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == DialogExResultLeft) {
return scene_manager_previous_scene(nfc->scene_manager);
}
}
return false;
}
void nfc_scene_not_implemented_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
}

View File

@@ -2,12 +2,12 @@
#include <dolphin/dolphin.h>
void nfc_read_card_worker_callback(NfcWorkerEvent event, void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit);
}
void nfc_scene_read_card_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcRead);
// Setup view
@@ -22,29 +22,26 @@ void nfc_scene_read_card_on_enter(void* context) {
}
bool nfc_scene_read_card_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventWorkerExit) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardSuccess);
return true;
consumed = true;
}
} else if(event.type == SceneManagerEventTypeTick) {
notification_message(nfc->notifications, &sequence_blink_blue_10);
return true;
consumed = true;
}
return false;
return consumed;
}
void nfc_scene_read_card_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
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);
popup_reset(nfc->popup);
}

View File

@@ -7,13 +7,15 @@ void nfc_scene_read_card_success_widget_callback(
void* context) {
furi_assert(context);
Nfc* nfc = context;
if(type == InputTypeShort) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
}
void nfc_scene_read_card_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
string_t data_str;
string_t uid_str;
string_init(data_str);
@@ -24,9 +26,9 @@ void nfc_scene_read_card_success_on_enter(void* context) {
notification_message(nfc->notifications, &sequence_success);
// Setup view
NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data;
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
Widget* widget = nfc->widget;
string_set_str(data_str, nfc_get_dev_type(data->device));
string_set_str(data_str, nfc_get_dev_type(data->type));
string_set_str(uid_str, "UID:");
for(uint8_t i = 0; i < data->uid_len; i++) {
string_cat_printf(uid_str, " %02X", data->uid[i]);
@@ -34,7 +36,7 @@ void nfc_scene_read_card_success_on_enter(void* context) {
widget_add_button_element(
widget, GuiButtonTypeLeft, "Retry", nfc_scene_read_card_success_widget_callback, nfc);
if(data->device == NfcDeviceNfca) {
if(data->type == FuriHalNfcTypeA) {
widget_add_button_element(
widget, GuiButtonTypeRight, "More", nfc_scene_read_card_success_widget_callback, nfc);
widget_add_icon_element(widget, 8, 13, &I_Medium_chip_22x21);
@@ -44,7 +46,7 @@ void nfc_scene_read_card_success_on_enter(void* context) {
string_printf(
data_str,
"%s\nATQA: %02X%02X SAK: %02X",
nfc_guess_protocol(data->protocol),
nfc_guess_protocol(nfc->dev->dev_data.protocol),
data->atqa[0],
data->atqa[1],
data->sak);
@@ -66,14 +68,14 @@ void nfc_scene_read_card_success_on_enter(void* context) {
}
bool nfc_scene_read_card_success_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data;
Nfc* nfc = context;
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeLeft) {
consumed = scene_manager_previous_scene(nfc->scene_manager);
} else if(data->device == NfcDeviceNfca && event.event == GuiButtonTypeRight) {
} else if(data->type == FuriHalNfcTypeA && event.event == GuiButtonTypeRight) {
// Clear device name
nfc_device_set_name(nfc->dev, "");
scene_manager_next_scene(nfc->scene_manager, NfcSceneCardMenu);
@@ -84,6 +86,8 @@ bool nfc_scene_read_card_success_on_event(void* context, SceneManagerEvent event
}
void nfc_scene_read_card_success_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear view
widget_reset(nfc->widget);
}

View File

@@ -2,12 +2,12 @@
#include <dolphin/dolphin.h>
void nfc_read_emv_app_worker_callback(NfcWorkerEvent event, void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit);
}
void nfc_scene_read_emv_app_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcRead);
// Setup view
@@ -26,31 +26,30 @@ void nfc_scene_read_emv_app_on_enter(void* context) {
}
bool nfc_scene_read_emv_app_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventWorkerExit) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneReadEmvAppSuccess, NFC_SEND_NOTIFICATION_TRUE);
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvAppSuccess);
return true;
consumed = true;
}
} else if(event.type == SceneManagerEventTypeTick) {
notification_message(nfc->notifications, &sequence_blink_blue_10);
return true;
consumed = true;
}
return false;
return consumed;
}
void nfc_scene_read_emv_app_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
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);
popup_reset(nfc->popup);
}

View File

@@ -2,27 +2,38 @@
#include "../helpers/nfc_emv_parser.h"
#include <dolphin/dolphin.h>
#define NFC_SCENE_READ_SUCCESS_SHIFT " "
void nfc_scene_read_emv_app_success_dialog_callback(DialogExResult result, void* context) {
Nfc* nfc = (Nfc*)context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
void nfc_scene_read_emv_app_widget_callback(GuiButtonType result, InputType type, void* context) {
Nfc* nfc = context;
if(type == InputTypeShort) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
}
void nfc_scene_read_emv_app_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
// Setup view
NfcDeviceCommonData* nfc_data = &nfc->dev->dev_data.nfc_data;
NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data;
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Retry");
dialog_ex_set_right_button_text(dialog_ex, "Run app");
dialog_ex_set_header(dialog_ex, "Found EMV App", 36, 8, AlignLeft, AlignCenter);
dialog_ex_set_icon(dialog_ex, 8, 13, &I_Medium_chip_22x21);
// Display UID and AID
FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data;
EmvData* emv_data = &nfc->dev->dev_data.emv_data;
Widget* widget = nfc->widget;
widget_add_button_element(
widget, GuiButtonTypeLeft, "Retry", nfc_scene_read_emv_app_widget_callback, nfc);
widget_add_button_element(
widget, GuiButtonTypeRight, "Run app", nfc_scene_read_emv_app_widget_callback, nfc);
widget_add_string_element(widget, 36, 5, AlignLeft, AlignTop, FontPrimary, "Found EMV App");
widget_add_icon_element(widget, 8, 5, &I_Medium_chip_22x21);
// Display UID
string_t temp_str;
string_init_printf(temp_str, "UID:");
for(size_t i = 0; i < nfc_data->uid_len; i++) {
string_cat_printf(temp_str, " %02X", nfc_data->uid[i]);
}
widget_add_string_element(
widget, 36, 18, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str));
string_reset(temp_str);
// Display application
string_printf(temp_str, "App: ");
string_t aid;
string_init(aid);
bool aid_found =
@@ -32,19 +43,11 @@ void nfc_scene_read_emv_app_success_on_enter(void* context) {
string_cat_printf(aid, "%02X", emv_data->aid[i]);
}
}
nfc_text_store_set(
nfc,
NFC_SCENE_READ_SUCCESS_SHIFT "UID: %02X %02X %02X %02X \n" NFC_SCENE_READ_SUCCESS_SHIFT
"Application:\n%s",
nfc_data->uid[0],
nfc_data->uid[1],
nfc_data->uid[2],
nfc_data->uid[3],
string_get_cstr(aid));
string_cat(temp_str, aid);
widget_add_string_element(
widget, 7, 29, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str));
string_clear(temp_str);
string_clear(aid);
dialog_ex_set_text(dialog_ex, nfc->text_store, 8, 16, AlignLeft, AlignTop);
dialog_ex_set_context(dialog_ex, nfc);
dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_emv_app_success_dialog_callback);
// Send notification
if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadEmvAppSuccess) ==
@@ -54,32 +57,27 @@ void nfc_scene_read_emv_app_success_on_enter(void* context) {
nfc->scene_manager, NfcSceneReadEmvAppSuccess, NFC_SEND_NOTIFICATION_FALSE);
}
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
bool nfc_scene_read_emv_app_success_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == DialogExResultLeft) {
return scene_manager_previous_scene(nfc->scene_manager);
} else if(event.event == DialogExResultRight) {
if(event.event == GuiButtonTypeLeft) {
consumed = scene_manager_previous_scene(nfc->scene_manager);
} else if(event.event == GuiButtonTypeRight) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneRunEmvAppConfirm);
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_read_emv_app_success_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
// Clear views
widget_reset(nfc->widget);
}

View File

@@ -2,12 +2,12 @@
#include <dolphin/dolphin.h>
void nfc_read_emv_data_worker_callback(NfcWorkerEvent event, void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit);
}
void nfc_scene_read_emv_data_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcRead);
// Setup view
@@ -21,38 +21,35 @@ void nfc_scene_read_emv_data_on_enter(void* context) {
// Start worker
nfc_worker_start(
nfc->worker,
NfcWorkerStateReadEMV,
NfcWorkerStateReadEMVData,
&nfc->dev->dev_data,
nfc_read_emv_data_worker_callback,
nfc);
}
bool nfc_scene_read_emv_data_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventWorkerExit) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneReadEmvDataSuccess, NFC_SEND_NOTIFICATION_TRUE);
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvDataSuccess);
return true;
consumed = true;
}
} else if(event.type == SceneManagerEventTypeTick) {
notification_message(nfc->notifications, &sequence_blink_blue_10);
return true;
consumed = true;
}
return false;
return consumed;
}
void nfc_scene_read_emv_data_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
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);
popup_reset(nfc->popup);
}

View File

@@ -6,16 +6,16 @@ void nfc_scene_read_emv_data_success_widget_callback(
GuiButtonType result,
InputType type,
void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
if(type == InputTypeShort) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
}
void nfc_scene_read_emv_data_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data;
NfcDeviceCommonData* nfc_data = &nfc->dev->dev_data.nfc_data;
Nfc* nfc = context;
EmvData* emv_data = &nfc->dev->dev_data.emv_data;
FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data;
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
// Setup Custom Widget view
@@ -78,25 +78,23 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) {
string_clear(disp_currency);
}
string_clear(currency_name);
char temp_str[32];
// Add ATQA
char atqa_str[16];
snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", nfc_data->atqa[0], nfc_data->atqa[1]);
widget_add_string_element(nfc->widget, 121, 32, AlignRight, AlignTop, FontSecondary, atqa_str);
snprintf(temp_str, sizeof(temp_str), "ATQA: %02X%02X", nfc_data->atqa[0], nfc_data->atqa[1]);
widget_add_string_element(nfc->widget, 121, 32, AlignRight, AlignTop, FontSecondary, temp_str);
// Add UID
char uid_str[32];
snprintf(
uid_str,
sizeof(uid_str),
temp_str,
sizeof(temp_str),
"UID: %02X %02X %02X %02X",
nfc_data->uid[0],
nfc_data->uid[1],
nfc_data->uid[2],
nfc_data->uid[3]);
widget_add_string_element(nfc->widget, 7, 42, AlignLeft, AlignTop, FontSecondary, uid_str);
widget_add_string_element(nfc->widget, 7, 42, AlignLeft, AlignTop, FontSecondary, temp_str);
// Add SAK
char sak_str[16];
snprintf(sak_str, sizeof(sak_str), "SAK: %02X", nfc_data->sak);
widget_add_string_element(nfc->widget, 121, 42, AlignRight, AlignTop, FontSecondary, sak_str);
snprintf(temp_str, sizeof(temp_str), "SAK: %02X", nfc_data->sak);
widget_add_string_element(nfc->widget, 121, 42, AlignRight, AlignTop, FontSecondary, temp_str);
// Add expiration date
if(emv_data->exp_mon) {
char exp_str[16];
@@ -117,28 +115,30 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) {
}
bool nfc_scene_read_emv_data_success_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeLeft) {
return scene_manager_search_and_switch_to_previous_scene(
consumed = scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneReadEmvAppSuccess);
} else if(event.event == GuiButtonTypeRight) {
// Clear device name
nfc_device_set_name(nfc->dev, "");
nfc->dev->format = NfcDeviceSaveFormatBankCard;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
return true;
consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
return scene_manager_search_and_switch_to_previous_scene(
consumed = scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneReadEmvAppSuccess);
}
return false;
return consumed;
}
void nfc_scene_read_emv_data_success_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear view
widget_reset(nfc->widget);
}

View File

@@ -2,12 +2,12 @@
#include <dolphin/dolphin.h>
void nfc_read_mifare_desfire_worker_callback(NfcWorkerEvent event, void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit);
}
void nfc_scene_read_mifare_desfire_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcRead);
// Setup view
@@ -26,31 +26,28 @@ void nfc_scene_read_mifare_desfire_on_enter(void* context) {
}
bool nfc_scene_read_mifare_desfire_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventWorkerExit) {
notification_message(nfc->notifications, &sequence_success);
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareDesfireSuccess);
return true;
consumed = true;
}
} else if(event.type == SceneManagerEventTypeTick) {
notification_message(nfc->notifications, &sequence_blink_blue_10);
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
return true;
consumed = true;
}
return false;
return consumed;
}
void nfc_scene_read_mifare_desfire_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
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);
popup_reset(nfc->popup);
}

View File

@@ -9,13 +9,13 @@ enum {
};
void nfc_scene_read_mifare_desfire_success_dialog_callback(DialogExResult result, void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
void nfc_scene_read_mifare_desfire_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data;
DialogEx* dialog_ex = nfc->dialog_ex;
@@ -67,9 +67,9 @@ void nfc_scene_read_mifare_desfire_success_on_enter(void* context) {
bool nfc_scene_read_mifare_desfire_success_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
bool consumed = false;
uint32_t state =
scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadMifareDesfireSuccess);
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(state == ReadMifareDesfireSuccessStateShowUID && event.event == DialogExResultLeft) {
@@ -98,9 +98,8 @@ bool nfc_scene_read_mifare_desfire_success_on_event(void* context, SceneManagerE
}
void nfc_scene_read_mifare_desfire_success_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clean dialog
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_reset(dialog_ex);
dialog_ex_reset(nfc->dialog_ex);
}

View File

@@ -19,7 +19,7 @@ void nfc_scene_read_mifare_ul_on_enter(void* context) {
// Start worker
nfc_worker_start(
nfc->worker,
NfcWorkerStateReadMifareUl,
NfcWorkerStateReadMifareUltralight,
&nfc->dev->dev_data,
nfc_read_mifare_ul_worker_callback,
nfc);
@@ -43,6 +43,7 @@ bool nfc_scene_read_mifare_ul_on_event(void* context, SceneManagerEvent event) {
void nfc_scene_read_mifare_ul_on_exit(void* context) {
Nfc* nfc = context;
// Stop worker
nfc_worker_stop(nfc->worker);
// Clear view

View File

@@ -9,21 +9,21 @@ enum {
};
void nfc_scene_read_mifare_ul_success_dialog_callback(DialogExResult result, void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
void nfc_scene_read_mifare_ul_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
// Send notification
notification_message(nfc->notifications, &sequence_success);
// Setup dialog view
NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data;
MifareUlData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data;
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
MfUltralightData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data;
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Retry");
dialog_ex_set_right_button_text(dialog_ex, "More");
@@ -69,9 +69,9 @@ void nfc_scene_read_mifare_ul_success_on_enter(void* context) {
bool nfc_scene_read_mifare_ul_success_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
bool consumed = false;
uint32_t state =
scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadMifareUlSuccess);
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(state == ReadMifareUlStateShowUID && event.event == DialogExResultLeft) {
@@ -99,14 +99,10 @@ bool nfc_scene_read_mifare_ul_success_on_event(void* context, SceneManagerEvent
}
void nfc_scene_read_mifare_ul_success_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clean dialog
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_reset(dialog_ex);
// Clean TextBox
TextBox* text_box = nfc->text_box;
text_box_reset(text_box);
// Clean views
dialog_ex_reset(nfc->dialog_ex);
text_box_reset(nfc->text_box);
string_reset(nfc->text_box_store);
}

View File

@@ -1,12 +1,12 @@
#include "../nfc_i.h"
void nfc_scene_restore_original_popup_callback(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
}
void nfc_scene_restore_original_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Setup view
Popup* popup = nfc->popup;
@@ -20,7 +20,7 @@ void nfc_scene_restore_original_on_enter(void* context) {
}
bool nfc_scene_restore_original_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
@@ -32,15 +32,8 @@ bool nfc_scene_restore_original_on_event(void* context, SceneManagerEvent event)
}
void nfc_scene_restore_original_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// 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);
popup_set_callback(popup, NULL);
popup_set_context(popup, NULL);
popup_set_timeout(popup, 0);
popup_disable_timeout(popup);
popup_reset(nfc->popup);
}

View File

@@ -1,15 +1,13 @@
#include "../nfc_i.h"
#define NFC_SCENE_READ_SUCCESS_SHIFT " "
void nfc_scene_run_emv_app_confirm_dialog_callback(DialogExResult result, void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
}
void nfc_scene_run_emv_app_confirm_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Back");
@@ -29,28 +27,23 @@ void nfc_scene_run_emv_app_confirm_on_enter(void* context) {
}
bool nfc_scene_run_emv_app_confirm_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == DialogExResultLeft) {
return scene_manager_previous_scene(nfc->scene_manager);
consumed = scene_manager_previous_scene(nfc->scene_manager);
} else if(event.event == DialogExResultRight) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvData);
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_run_emv_app_confirm_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
dialog_ex_set_left_button_text(dialog_ex, NULL);
dialog_ex_set_right_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL);
// Clean view
dialog_ex_reset(nfc->dialog_ex);
}

View File

@@ -3,13 +3,13 @@
#include <gui/modules/validators.h>
void nfc_scene_save_name_text_input_callback(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventTextInputDone);
}
void nfc_scene_save_name_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Setup view
TextInput* text_input = nfc->text_input;
@@ -37,7 +37,8 @@ void nfc_scene_save_name_on_enter(void* context) {
}
bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventTextInputDone) {
@@ -50,18 +51,18 @@ bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) {
strlcpy(nfc->dev->dev_name, nfc->text_store, strlen(nfc->text_store) + 1);
if(nfc_device_save(nfc->dev, nfc->text_store)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
return true;
consumed = true;
} else {
return scene_manager_search_and_switch_to_previous_scene(
consumed = scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneStart);
}
}
}
return false;
return consumed;
}
void nfc_scene_save_name_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear view
void* validator_context = text_input_get_validator_callback_context(nfc->text_input);

View File

@@ -2,12 +2,12 @@
#include <dolphin/dolphin.h>
void nfc_scene_save_success_popup_callback(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
}
void nfc_scene_save_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcSave);
// Setup view
@@ -22,7 +22,7 @@ void nfc_scene_save_success_on_enter(void* context) {
}
bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
@@ -47,15 +47,8 @@ bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) {
}
void nfc_scene_save_success_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// 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);
popup_set_callback(popup, NULL);
popup_set_context(popup, NULL);
popup_set_timeout(popup, 0);
popup_disable_timeout(popup);
popup_reset(nfc->popup);
}

View File

@@ -9,13 +9,13 @@ enum SubmenuIndex {
};
void nfc_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
void nfc_scene_saved_menu_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
if(nfc->dev->format == NfcDeviceSaveFormatUid ||
@@ -56,7 +56,7 @@ void nfc_scene_saved_menu_on_enter(void* context) {
}
bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
@@ -92,7 +92,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
}
void nfc_scene_saved_menu_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
submenu_reset(nfc->submenu);
}

View File

@@ -1,13 +1,13 @@
#include "../nfc_i.h"
void nfc_scene_set_atqa_byte_input_callback(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventByteInputDone);
}
void nfc_scene_set_atqa_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Setup view
ByteInput* byte_input = nfc->byte_input;
@@ -23,19 +23,20 @@ void nfc_scene_set_atqa_on_enter(void* context) {
}
bool nfc_scene_set_atqa_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventByteInputDone) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid);
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_set_atqa_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear view
byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0);

View File

@@ -1,13 +1,13 @@
#include "../nfc_i.h"
void nfc_scene_set_sak_byte_input_callback(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventByteInputDone);
}
void nfc_scene_set_sak_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Setup view
ByteInput* byte_input = nfc->byte_input;
@@ -23,19 +23,20 @@ void nfc_scene_set_sak_on_enter(void* context) {
}
bool nfc_scene_set_sak_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventByteInputDone) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetAtqua);
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_set_sak_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear view
byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0);

View File

@@ -6,13 +6,13 @@ enum SubmenuIndex {
};
void nfc_scene_set_type_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
void nfc_scene_set_type_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
// Clear device name
nfc_device_set_name(nfc->dev, "");
@@ -24,26 +24,27 @@ void nfc_scene_set_type_on_enter(void* context) {
}
bool nfc_scene_set_type_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexNFCA7) {
nfc->dev->dev_data.nfc_data.uid_len = 7;
nfc->dev->format = NfcDeviceSaveFormatUid;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak);
return true;
consumed = true;
} else if(event.event == SubmenuIndexNFCA4) {
nfc->dev->dev_data.nfc_data.uid_len = 4;
nfc->dev->format = NfcDeviceSaveFormatUid;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak);
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_set_type_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
submenu_reset(nfc->submenu);
}

View File

@@ -2,13 +2,13 @@
#include <dolphin/dolphin.h>
void nfc_scene_set_uid_byte_input_callback(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventByteInputDone);
}
void nfc_scene_set_uid_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Setup view
ByteInput* byte_input = nfc->byte_input;
@@ -26,19 +26,20 @@ void nfc_scene_set_uid_on_enter(void* context) {
bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventByteInputDone) {
DOLPHIN_DEED(DolphinDeedNfcAdd);
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
return true;
consumed = true;
}
}
return false;
return consumed;
}
void nfc_scene_set_uid_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
// Clear view
byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0);

View File

@@ -9,13 +9,13 @@ enum SubmenuIndex {
};
void nfc_scene_start_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
void nfc_scene_start_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
submenu_add_item(
@@ -43,7 +43,7 @@ void nfc_scene_start_on_enter(void* context) {
}
bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
@@ -70,7 +70,7 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
}
void nfc_scene_start_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
Nfc* nfc = context;
submenu_reset(nfc->submenu);
}