mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-17 04:34:44 -07:00
NFC: Refactor Write actions into ProtocolSupport
This commit is contained in:
@@ -213,4 +213,9 @@ const NfcProtocolSupportBase nfc_protocol_support_felica = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_felica,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -144,4 +144,9 @@ const NfcProtocolSupportBase nfc_protocol_support_iso14443_3a = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_iso14443_3a,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -111,4 +111,9 @@ const NfcProtocolSupportBase nfc_protocol_support_iso14443_3b = {
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -147,4 +147,9 @@ const NfcProtocolSupportBase nfc_protocol_support_iso14443_4a = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_iso14443_4a,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -116,4 +116,9 @@ const NfcProtocolSupportBase nfc_protocol_support_iso14443_4b = {
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -161,4 +161,9 @@ const NfcProtocolSupportBase nfc_protocol_support_iso15693_3 = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_iso15693_3,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -12,9 +12,8 @@
|
||||
|
||||
enum {
|
||||
SubmenuIndexDetectReader = SubmenuIndexCommonMax,
|
||||
SubmenuIndexWrite,
|
||||
SubmenuIndexDictAttack,
|
||||
SubmenuIndexUpdate,
|
||||
SubmenuIndexDictAttack
|
||||
};
|
||||
|
||||
static void nfc_scene_info_on_enter_mf_classic(NfcApp* instance) {
|
||||
@@ -114,6 +113,9 @@ static void nfc_scene_read_menu_on_enter_mf_classic(NfcApp* instance) {
|
||||
Submenu* submenu = instance->submenu;
|
||||
const MfClassicData* data = nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic);
|
||||
|
||||
// Doesn't make sense to show "Write to Initial Card" right after reading
|
||||
submenu_remove_item(submenu, SubmenuIndexCommonWrite);
|
||||
|
||||
if(!mf_classic_is_card_read(data)) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
@@ -152,6 +154,8 @@ static void nfc_scene_saved_menu_on_enter_mf_classic(NfcApp* instance) {
|
||||
Submenu* submenu = instance->submenu;
|
||||
const MfClassicData* data = nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic);
|
||||
|
||||
submenu_change_item_label(submenu, SubmenuIndexCommonWrite, "Write to Initial Card");
|
||||
|
||||
if(!mf_classic_is_card_read(data)) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
@@ -167,12 +171,6 @@ static void nfc_scene_saved_menu_on_enter_mf_classic(NfcApp* instance) {
|
||||
nfc_protocol_support_common_submenu_callback,
|
||||
instance);
|
||||
}
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Write to Initial Card",
|
||||
SubmenuIndexWrite,
|
||||
nfc_protocol_support_common_submenu_callback,
|
||||
instance);
|
||||
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
@@ -218,18 +216,15 @@ static bool nfc_scene_saved_menu_on_event_mf_classic(NfcApp* instance, SceneMana
|
||||
if(event.event == SubmenuIndexDetectReader) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDetectReader);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexWrite) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicWriteInitial);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexUpdate) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicUpdateInitial);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexDictAttack) {
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, NfcSceneMfClassicDictAttack)) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDictAttack);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexUpdate) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicUpdateInitial);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,8 +244,71 @@ static bool nfc_scene_save_name_on_event_mf_classic(NfcApp* instance, SceneManag
|
||||
return consumed;
|
||||
}
|
||||
|
||||
static NfcCommand
|
||||
nfc_scene_write_poller_callback_mf_classic(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolMfClassic);
|
||||
|
||||
NfcApp* instance = context;
|
||||
MfClassicPollerEvent* mfc_event = event.event_data;
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
const MfClassicData* write_data =
|
||||
nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic);
|
||||
|
||||
if(mfc_event->type == MfClassicPollerEventTypeCardDetected) {
|
||||
furi_string_reset(instance->text_box_store);
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeCardLost) {
|
||||
furi_string_set(instance->text_box_store, "Use the source\ncard only");
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardLost);
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeRequestMode) {
|
||||
const MfClassicData* tag_data = nfc_poller_get_data(instance->poller);
|
||||
if(iso14443_3a_is_equal(tag_data->iso14443_3a_data, write_data->iso14443_3a_data)) {
|
||||
mfc_event->data->poller_mode.mode = MfClassicPollerModeWrite;
|
||||
} else {
|
||||
furi_string_set(
|
||||
instance->text_box_store, "Use source card!\nTo write blanks\nuse NFC Magic app");
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventWrongCard);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeRequestSectorTrailer) {
|
||||
uint8_t sector = mfc_event->data->sec_tr_data.sector_num;
|
||||
uint8_t sec_tr = mf_classic_get_sector_trailer_num_by_sector(sector);
|
||||
if(mf_classic_is_block_read(write_data, sec_tr)) {
|
||||
mfc_event->data->sec_tr_data.sector_trailer = write_data->block[sec_tr];
|
||||
mfc_event->data->sec_tr_data.sector_trailer_provided = true;
|
||||
} else {
|
||||
mfc_event->data->sec_tr_data.sector_trailer_provided = false;
|
||||
}
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeRequestWriteBlock) {
|
||||
uint8_t block_num = mfc_event->data->write_block_data.block_num;
|
||||
if(mf_classic_is_block_read(write_data, block_num)) {
|
||||
mfc_event->data->write_block_data.write_block = write_data->block[block_num];
|
||||
mfc_event->data->write_block_data.write_block_provided = true;
|
||||
} else {
|
||||
mfc_event->data->write_block_data.write_block_provided = false;
|
||||
}
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeSuccess) {
|
||||
furi_string_reset(instance->text_box_store);
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
|
||||
command = NfcCommandStop;
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeFail) {
|
||||
furi_string_set(instance->text_box_store, "Not all sectors\nwere written\ncorrectly");
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
static void nfc_scene_write_on_enter_mf_classic(NfcApp* instance) {
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfClassic);
|
||||
nfc_poller_start(instance->poller, nfc_scene_write_poller_callback_mf_classic, instance);
|
||||
furi_string_set(instance->text_box_store, "Use the source\ncard only");
|
||||
}
|
||||
|
||||
const NfcProtocolSupportBase nfc_protocol_support_mf_classic = {
|
||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo,
|
||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo |
|
||||
NfcProtocolFeatureWrite,
|
||||
|
||||
.scene_info =
|
||||
{
|
||||
@@ -292,4 +350,9 @@ const NfcProtocolSupportBase nfc_protocol_support_mf_classic = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_mf_classic,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_scene_write_on_enter_mf_classic,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -124,4 +124,9 @@ const NfcProtocolSupportBase nfc_protocol_support_mf_desfire = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_mf_desfire,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -120,4 +120,9 @@ const NfcProtocolSupportBase nfc_protocol_support_mf_plus = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_mf_plus,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -14,7 +14,6 @@ enum {
|
||||
SubmenuIndexUnlock = SubmenuIndexCommonMax,
|
||||
SubmenuIndexUnlockByReader,
|
||||
SubmenuIndexUnlockByPassword,
|
||||
SubmenuIndexWrite,
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -182,24 +181,22 @@ static void nfc_scene_read_and_saved_menu_on_enter_mf_ultralight(NfcApp* instanc
|
||||
|
||||
const MfUltralightData* data =
|
||||
nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight);
|
||||
bool is_locked = !mf_ultralight_is_all_data_read(data);
|
||||
|
||||
if(!mf_ultralight_is_all_data_read(data)) {
|
||||
if(is_locked ||
|
||||
(data->type != MfUltralightTypeNTAG213 && data->type != MfUltralightTypeNTAG215 &&
|
||||
data->type != MfUltralightTypeNTAG216 && data->type != MfUltralightTypeUL11 &&
|
||||
data->type != MfUltralightTypeUL21 && data->type != MfUltralightTypeOrigin)) {
|
||||
submenu_remove_item(submenu, SubmenuIndexCommonWrite);
|
||||
}
|
||||
|
||||
if(is_locked) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Unlock",
|
||||
SubmenuIndexUnlock,
|
||||
nfc_protocol_support_common_submenu_callback,
|
||||
instance);
|
||||
} else if(
|
||||
data->type == MfUltralightTypeNTAG213 || data->type == MfUltralightTypeNTAG215 ||
|
||||
data->type == MfUltralightTypeNTAG216 || data->type == MfUltralightTypeUL11 ||
|
||||
data->type == MfUltralightTypeUL21 || data->type == MfUltralightTypeOrigin) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Write",
|
||||
SubmenuIndexWrite,
|
||||
nfc_protocol_support_common_submenu_callback,
|
||||
instance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,9 +249,6 @@ static bool nfc_scene_read_and_saved_menu_on_event_mf_ultralight(
|
||||
NfcSceneMfUltralightUnlockMenu;
|
||||
scene_manager_next_scene(instance->scene_manager, next_scene);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexWrite) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWrite);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexCommonEdit) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid);
|
||||
consumed = true;
|
||||
@@ -263,8 +257,52 @@ static bool nfc_scene_read_and_saved_menu_on_event_mf_ultralight(
|
||||
return consumed;
|
||||
}
|
||||
|
||||
static NfcCommand
|
||||
nfc_scene_write_poller_callback_mf_ultralight(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolMfUltralight);
|
||||
|
||||
NfcApp* instance = context;
|
||||
MfUltralightPollerEvent* mf_ultralight_event = event.event_data;
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(mf_ultralight_event->type == MfUltralightPollerEventTypeRequestMode) {
|
||||
mf_ultralight_event->data->poller_mode = MfUltralightPollerModeWrite;
|
||||
furi_string_reset(instance->text_box_store);
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
|
||||
} else if(mf_ultralight_event->type == MfUltralightPollerEventTypeAuthRequest) {
|
||||
mf_ultralight_event->data->auth_context.skip_auth = true;
|
||||
} else if(mf_ultralight_event->type == MfUltralightPollerEventTypeRequestWriteData) {
|
||||
mf_ultralight_event->data->write_data =
|
||||
nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight);
|
||||
} else if(mf_ultralight_event->type == MfUltralightPollerEventTypeCardMismatch) {
|
||||
furi_string_set(instance->text_box_store, "Card of the same\ntype should be\n presented");
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventWrongCard);
|
||||
command = NfcCommandStop;
|
||||
} else if(mf_ultralight_event->type == MfUltralightPollerEventTypeCardLocked) {
|
||||
furi_string_set(
|
||||
instance->text_box_store, "Card protected by\npassword, AUTH0\nor lock bits");
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
|
||||
command = NfcCommandStop;
|
||||
} else if(mf_ultralight_event->type == MfUltralightPollerEventTypeWriteFail) {
|
||||
command = NfcCommandStop;
|
||||
} else if(mf_ultralight_event->type == MfUltralightPollerEventTypeWriteSuccess) {
|
||||
furi_string_reset(instance->text_box_store);
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
static void nfc_scene_write_on_enter_mf_ultralight(NfcApp* instance) {
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfUltralight);
|
||||
nfc_poller_start(instance->poller, nfc_scene_write_poller_callback_mf_ultralight, instance);
|
||||
furi_string_set(instance->text_box_store, "Apply the initial\ncard only");
|
||||
}
|
||||
|
||||
const NfcProtocolSupportBase nfc_protocol_support_mf_ultralight = {
|
||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo,
|
||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo |
|
||||
NfcProtocolFeatureWrite,
|
||||
|
||||
.scene_info =
|
||||
{
|
||||
@@ -306,4 +344,9 @@ const NfcProtocolSupportBase nfc_protocol_support_mf_ultralight = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_mf_ultralight,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_scene_write_on_enter_mf_ultralight,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -258,6 +258,15 @@ static void nfc_protocol_support_scene_read_menu_on_enter(NfcApp* instance) {
|
||||
instance);
|
||||
}
|
||||
|
||||
if(nfc_protocol_support_has_feature(protocol, NfcProtocolFeatureWrite)) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Write",
|
||||
SubmenuIndexCommonWrite,
|
||||
nfc_protocol_support_common_submenu_callback,
|
||||
instance);
|
||||
}
|
||||
|
||||
nfc_protocol_support[protocol]->scene_read_menu.on_enter(instance);
|
||||
|
||||
submenu_add_item(
|
||||
@@ -291,6 +300,10 @@ static bool
|
||||
dolphin_deed(DolphinDeedNfcEmulate);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneEmulate);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexCommonWrite) {
|
||||
dolphin_deed(DolphinDeedNfcEmulate);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneWrite);
|
||||
consumed = true;
|
||||
} else {
|
||||
const NfcProtocol protocol = nfc_device_get_protocol(instance->nfc_device);
|
||||
consumed = nfc_protocol_support[protocol]->scene_read_menu.on_event(instance, event);
|
||||
@@ -383,6 +396,15 @@ static void nfc_protocol_support_scene_saved_menu_on_enter(NfcApp* instance) {
|
||||
instance);
|
||||
}
|
||||
|
||||
if(nfc_protocol_support_has_feature(protocol, NfcProtocolFeatureWrite)) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Write",
|
||||
SubmenuIndexCommonWrite,
|
||||
nfc_protocol_support_common_submenu_callback,
|
||||
instance);
|
||||
}
|
||||
|
||||
if(nfc_protocol_support_has_feature(protocol, NfcProtocolFeatureEditUid)) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
@@ -456,6 +478,12 @@ static bool
|
||||
dolphin_deed(is_added ? DolphinDeedNfcAddEmulate : DolphinDeedNfcEmulate);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneEmulate);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexCommonWrite) {
|
||||
const bool is_added =
|
||||
scene_manager_has_previous_scene(instance->scene_manager, NfcSceneSetType);
|
||||
dolphin_deed(is_added ? DolphinDeedNfcAddEmulate : DolphinDeedNfcEmulate);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneWrite);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexCommonEdit) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid);
|
||||
consumed = true;
|
||||
@@ -688,6 +716,175 @@ static void nfc_protocol_support_scene_emulate_on_exit(NfcApp* instance) {
|
||||
nfc_blink_stop(instance);
|
||||
}
|
||||
|
||||
// SceneWrite
|
||||
/**
|
||||
* @brief Current view displayed on the write scene.
|
||||
*
|
||||
* The emulation scene has five states, some protocols may not use all states.
|
||||
* Protocol handles poller events, when scene state needs to change it should
|
||||
* fill text_box_store with a short caption (when applicable) before sending
|
||||
* the relevant view dispatcher event.
|
||||
*/
|
||||
enum {
|
||||
NfcSceneWriteStateSearching, /**< Ask user to touch the card. Event: on_enter, CardLost. Needs caption. */
|
||||
NfcSceneWriteStateWriting, /**< Ask not to move while writing. Event: CardDetected. No caption. */
|
||||
NfcSceneWriteStateSuccess, /**< Card written successfully. Event: PollerSuccess. No caption. */
|
||||
NfcSceneWriteStateFailure, /**< An error is displayed. Event: PollerFailure. Needs caption. */
|
||||
NfcSceneWriteStateWrongCard, /**< Wrong card was presented. Event: WrongCard. Needs caption. */
|
||||
};
|
||||
|
||||
static void nfc_protocol_support_scene_write_popup_callback(void* context) {
|
||||
NfcApp* instance = context;
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventViewExit);
|
||||
}
|
||||
|
||||
void nfc_protocol_support_scene_write_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
NfcApp* instance = context;
|
||||
if(type == InputTypeShort && result == GuiButtonTypeLeft) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventViewExit);
|
||||
}
|
||||
}
|
||||
|
||||
static void nfc_protocol_support_scene_write_setup_view(NfcApp* instance) {
|
||||
Popup* popup = instance->popup;
|
||||
Widget* widget = instance->widget;
|
||||
popup_reset(popup);
|
||||
widget_reset(widget);
|
||||
uint32_t state = scene_manager_get_scene_state(instance->scene_manager, NfcSceneWrite);
|
||||
NfcView view = NfcViewPopup;
|
||||
|
||||
if(state == NfcSceneWriteStateSearching) {
|
||||
popup_set_header(popup, "Writing", 95, 20, AlignCenter, AlignCenter);
|
||||
popup_set_text(
|
||||
popup,
|
||||
furi_string_get_cstr(instance->text_box_store),
|
||||
95,
|
||||
38,
|
||||
AlignCenter,
|
||||
AlignCenter);
|
||||
popup_set_icon(popup, 0, 8, &I_NFC_manual_60x50);
|
||||
} else if(state == NfcSceneWriteStateWriting) {
|
||||
popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter);
|
||||
popup_set_icon(popup, 12, 23, &A_Loading_24);
|
||||
} else if(state == NfcSceneWriteStateSuccess) {
|
||||
popup_set_header(popup, "Successfully\nwritten!", 126, 2, AlignRight, AlignTop);
|
||||
popup_set_icon(popup, 0, 9, &I_DolphinSuccess_91x55);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_set_context(popup, instance);
|
||||
popup_set_callback(popup, nfc_protocol_support_scene_write_popup_callback);
|
||||
popup_enable_timeout(popup);
|
||||
} else if(state == NfcSceneWriteStateFailure) {
|
||||
view = NfcViewWidget;
|
||||
widget_add_string_element(
|
||||
widget, 7, 4, AlignLeft, AlignTop, FontPrimary, "Writing gone wrong!");
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
7,
|
||||
17,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
furi_string_get_cstr(instance->text_box_store));
|
||||
widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42);
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeLeft,
|
||||
"Retry",
|
||||
nfc_protocol_support_scene_write_widget_callback,
|
||||
instance);
|
||||
} else if(state == NfcSceneWriteStateWrongCard) {
|
||||
view = NfcViewWidget;
|
||||
widget_add_string_element(widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "Wrong card!");
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
4,
|
||||
17,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
furi_string_get_cstr(instance->text_box_store));
|
||||
widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42);
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeLeft,
|
||||
"Retry",
|
||||
nfc_protocol_support_scene_write_widget_callback,
|
||||
instance);
|
||||
}
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, view);
|
||||
}
|
||||
|
||||
static void nfc_protocol_support_scene_write_on_enter(NfcApp* instance) {
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager, NfcSceneWrite, NfcSceneWriteStateSearching);
|
||||
furi_string_reset(instance->text_box_store);
|
||||
|
||||
const NfcProtocol protocol = nfc_device_get_protocol(instance->nfc_device);
|
||||
|
||||
// instance->poller is allocated in the respective on_enter() handler
|
||||
nfc_protocol_support[protocol]->scene_write.on_enter(instance);
|
||||
|
||||
nfc_protocol_support_scene_write_setup_view(instance);
|
||||
nfc_blink_emulate_start(instance);
|
||||
}
|
||||
|
||||
static bool nfc_protocol_support_scene_write_on_event(NfcApp* instance, SceneManagerEvent event) {
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
uint32_t new_state = -1;
|
||||
|
||||
if(event.event == NfcCustomEventCardDetected) {
|
||||
new_state = NfcSceneWriteStateWriting;
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventCardLost) {
|
||||
new_state = NfcSceneWriteStateSearching;
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventPollerSuccess) {
|
||||
dolphin_deed(DolphinDeedNfcSave);
|
||||
notification_message(instance->notifications, &sequence_success);
|
||||
new_state = NfcSceneWriteStateSuccess;
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventPollerFailure) {
|
||||
notification_message(instance->notifications, &sequence_error);
|
||||
new_state = NfcSceneWriteStateFailure;
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventWrongCard) {
|
||||
notification_message(instance->notifications, &sequence_error);
|
||||
new_state = NfcSceneWriteStateWrongCard;
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventViewExit) {
|
||||
// Retry
|
||||
nfc_protocol_support_scenes[NfcProtocolSupportSceneWrite].on_exit(instance);
|
||||
nfc_protocol_support_scenes[NfcProtocolSupportSceneWrite].on_enter(instance);
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
if(new_state != (uint32_t)-1) {
|
||||
scene_manager_set_scene_state(instance->scene_manager, NfcSceneWrite, new_state);
|
||||
nfc_protocol_support_scene_write_setup_view(instance);
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
static void nfc_protocol_support_scene_write_on_exit(NfcApp* instance) {
|
||||
nfc_poller_stop(instance->poller);
|
||||
nfc_poller_free(instance->poller);
|
||||
|
||||
// Clear view
|
||||
popup_reset(instance->popup);
|
||||
widget_reset(instance->widget);
|
||||
furi_string_reset(instance->text_box_store);
|
||||
|
||||
nfc_blink_stop(instance);
|
||||
}
|
||||
|
||||
static void nfc_protocol_support_scene_rpc_on_enter(NfcApp* instance) {
|
||||
UNUSED(instance);
|
||||
}
|
||||
@@ -803,6 +1000,12 @@ static const NfcProtocolSupportCommonSceneBase
|
||||
.on_event = nfc_protocol_support_scene_emulate_on_event,
|
||||
.on_exit = nfc_protocol_support_scene_emulate_on_exit,
|
||||
},
|
||||
[NfcProtocolSupportSceneWrite] =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_scene_write_on_enter,
|
||||
.on_event = nfc_protocol_support_scene_write_on_event,
|
||||
.on_exit = nfc_protocol_support_scene_write_on_exit,
|
||||
},
|
||||
[NfcProtocolSupportSceneRpc] =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_scene_rpc_on_enter,
|
||||
|
||||
@@ -114,4 +114,13 @@ typedef struct {
|
||||
* It is responsible for creating a listener and for handling its events.
|
||||
*/
|
||||
NfcProtocolSupportSceneBase scene_emulate;
|
||||
|
||||
/**
|
||||
* @brief Handlers for protocol-specific write scene.
|
||||
*
|
||||
* This scene is activated when a write operation is in progress.
|
||||
* It is responsible for creating a poller, handling its events and
|
||||
* displaying short captions for what is happening.
|
||||
*/
|
||||
NfcProtocolSupportSceneBase scene_write;
|
||||
} NfcProtocolSupportBase;
|
||||
|
||||
@@ -13,6 +13,7 @@ typedef enum {
|
||||
NfcProtocolFeatureEmulateFull = 1UL << 1, /**< Complete emulation is supported. */
|
||||
NfcProtocolFeatureEditUid = 1UL << 2, /**< UID editing is supported. */
|
||||
NfcProtocolFeatureMoreInfo = 1UL << 3, /**< More information is provided. */
|
||||
NfcProtocolFeatureWrite = 1UL << 4, /**< Writing to real card is supported. */
|
||||
} NfcProtocolFeature;
|
||||
|
||||
/**
|
||||
@@ -30,6 +31,7 @@ typedef enum {
|
||||
NfcProtocolSupportSceneSavedMenu, /**< Menu for the card that was loaded from file. */
|
||||
NfcProtocolSupportSceneSaveName, /**< Shown when saving or renaming a file. */
|
||||
NfcProtocolSupportSceneEmulate, /**< Shown when emulating a card. */
|
||||
NfcProtocolSupportSceneWrite, /**< Shown when writing to a card. */
|
||||
NfcProtocolSupportSceneRpc, /**< Shown in remote-controlled (RPC) mode. */
|
||||
|
||||
NfcProtocolSupportSceneCount, /**< Special value equal to total scene count. Internal use. */
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
enum {
|
||||
SubmenuIndexCommonSave, /**< Save menu option. */
|
||||
SubmenuIndexCommonEmulate, /**< Emulate menu option. */
|
||||
SubmenuIndexCommonWrite, /**< Write menu option. */
|
||||
SubmenuIndexCommonEdit, /**< Edit menu option. */
|
||||
SubmenuIndexCommonInfo, /**< Info menu option. */
|
||||
SubmenuIndexCommonRename, /**< Rename menu option. */
|
||||
|
||||
@@ -157,4 +157,9 @@ const NfcProtocolSupportBase nfc_protocol_support_slix = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_slix,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -108,4 +108,9 @@ const NfcProtocolSupportBase nfc_protocol_support_st25tb = {
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -10,10 +10,6 @@
|
||||
#include "../nfc_protocol_support_common.h"
|
||||
#include "../nfc_protocol_support_gui_common.h"
|
||||
|
||||
enum {
|
||||
SubmenuIndexWrite = SubmenuIndexCommonMax,
|
||||
};
|
||||
|
||||
enum {
|
||||
NfcSceneMoreInfoStateASCII,
|
||||
NfcSceneMoreInfoStateRawData,
|
||||
@@ -126,32 +122,6 @@ static void nfc_scene_read_on_enter_type_4_tag(NfcApp* instance) {
|
||||
nfc_poller_start(instance->poller, nfc_scene_read_poller_callback_type_4_tag, instance);
|
||||
}
|
||||
|
||||
static void nfc_scene_read_and_saved_menu_on_enter_type_4_tag(NfcApp* instance) {
|
||||
Submenu* submenu = instance->submenu;
|
||||
|
||||
// FIXME: standardize this and the write scenes into protocol support helper
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Write",
|
||||
SubmenuIndexWrite,
|
||||
nfc_protocol_support_common_submenu_callback,
|
||||
instance);
|
||||
}
|
||||
|
||||
static bool
|
||||
nfc_scene_read_and_saved_menu_on_event_type_4_tag(NfcApp* instance, SceneManagerEvent event) {
|
||||
bool consumed = false;
|
||||
UNUSED(instance);
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexWrite) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneType4TagWrite);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
static void nfc_scene_read_success_on_enter_type_4_tag(NfcApp* instance) {
|
||||
const NfcDevice* device = instance->nfc_device;
|
||||
const Type4TagData* data = nfc_device_get_data(device, NfcProtocolType4Tag);
|
||||
@@ -201,8 +171,45 @@ static void nfc_scene_emulate_on_enter_type_4_tag(NfcApp* instance) {
|
||||
instance->listener, nfc_scene_emulate_listener_callback_type_4_tag, instance);
|
||||
}
|
||||
|
||||
static NfcCommand
|
||||
nfc_scene_write_poller_callback_type_4_tag(NfcGenericEvent event, void* context) {
|
||||
furi_assert(event.protocol == NfcProtocolType4Tag);
|
||||
|
||||
NfcApp* instance = context;
|
||||
Type4TagPollerEvent* type_4_tag_event = event.event_data;
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
if(type_4_tag_event->type == Type4TagPollerEventTypeRequestMode) {
|
||||
type_4_tag_event->data->poller_mode.mode = Type4TagPollerModeWrite;
|
||||
type_4_tag_event->data->poller_mode.data =
|
||||
nfc_device_get_data(instance->nfc_device, NfcProtocolType4Tag);
|
||||
furi_string_reset(instance->text_box_store);
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
|
||||
} else if(type_4_tag_event->type == Type4TagPollerEventTypeWriteFail) {
|
||||
const char* error_str = type_4_tag_event->data->error == Type4TagErrorCardLocked ?
|
||||
"Card does not\nallow writing\nnew data" :
|
||||
"Failed to\nwrite new data";
|
||||
furi_string_set(instance->text_box_store, error_str);
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
|
||||
command = NfcCommandStop;
|
||||
} else if(type_4_tag_event->type == Type4TagPollerEventTypeWriteSuccess) {
|
||||
furi_string_reset(instance->text_box_store);
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
static void nfc_scene_write_on_enter_type_4_tag(NfcApp* instance) {
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolType4Tag);
|
||||
nfc_poller_start(instance->poller, nfc_scene_write_poller_callback_type_4_tag, instance);
|
||||
furi_string_set(instance->text_box_store, "Apply card\nto the back");
|
||||
}
|
||||
|
||||
const NfcProtocolSupportBase nfc_protocol_support_type_4_tag = {
|
||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo,
|
||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo |
|
||||
NfcProtocolFeatureWrite,
|
||||
|
||||
.scene_info =
|
||||
{
|
||||
@@ -221,8 +228,8 @@ const NfcProtocolSupportBase nfc_protocol_support_type_4_tag = {
|
||||
},
|
||||
.scene_read_menu =
|
||||
{
|
||||
.on_enter = nfc_scene_read_and_saved_menu_on_enter_type_4_tag,
|
||||
.on_event = nfc_scene_read_and_saved_menu_on_event_type_4_tag,
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_read_success =
|
||||
{
|
||||
@@ -231,8 +238,8 @@ const NfcProtocolSupportBase nfc_protocol_support_type_4_tag = {
|
||||
},
|
||||
.scene_saved_menu =
|
||||
{
|
||||
.on_enter = nfc_scene_read_and_saved_menu_on_enter_type_4_tag,
|
||||
.on_event = nfc_scene_read_and_saved_menu_on_event_type_4_tag,
|
||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_save_name =
|
||||
{
|
||||
@@ -244,4 +251,9 @@ const NfcProtocolSupportBase nfc_protocol_support_type_4_tag = {
|
||||
.on_enter = nfc_scene_emulate_on_enter_type_4_tag,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
.scene_write =
|
||||
{
|
||||
.on_enter = nfc_scene_write_on_enter_type_4_tag,
|
||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@ ADD_SCENE(nfc, extra_actions, ExtraActions)
|
||||
ADD_SCENE(nfc, read_success, ReadSuccess)
|
||||
ADD_SCENE(nfc, read_menu, ReadMenu)
|
||||
ADD_SCENE(nfc, emulate, Emulate)
|
||||
ADD_SCENE(nfc, write, Write)
|
||||
ADD_SCENE(nfc, rpc, Rpc)
|
||||
ADD_SCENE(nfc, debug, Debug)
|
||||
ADD_SCENE(nfc, field, Field)
|
||||
@@ -25,10 +26,6 @@ ADD_SCENE(nfc, retry_confirm, RetryConfirm)
|
||||
ADD_SCENE(nfc, exit_confirm, ExitConfirm)
|
||||
ADD_SCENE(nfc, save_confirm, SaveConfirm)
|
||||
|
||||
ADD_SCENE(nfc, mf_ultralight_write, MfUltralightWrite)
|
||||
ADD_SCENE(nfc, mf_ultralight_write_success, MfUltralightWriteSuccess)
|
||||
ADD_SCENE(nfc, mf_ultralight_write_fail, MfUltralightWriteFail)
|
||||
ADD_SCENE(nfc, mf_ultralight_wrong_card, MfUltralightWrongCard)
|
||||
ADD_SCENE(nfc, mf_ultralight_unlock_menu, MfUltralightUnlockMenu)
|
||||
ADD_SCENE(nfc, mf_ultralight_unlock_warn, MfUltralightUnlockWarn)
|
||||
ADD_SCENE(nfc, mf_ultralight_key_input, MfUltralightKeyInput)
|
||||
@@ -46,10 +43,6 @@ ADD_SCENE(nfc, mf_classic_mfkey_complete, MfClassicMfkeyComplete)
|
||||
ADD_SCENE(nfc, mf_classic_update_initial, MfClassicUpdateInitial)
|
||||
ADD_SCENE(nfc, mf_classic_update_initial_success, MfClassicUpdateInitialSuccess)
|
||||
ADD_SCENE(nfc, mf_classic_update_initial_wrong_card, MfClassicUpdateInitialWrongCard)
|
||||
ADD_SCENE(nfc, mf_classic_write_initial, MfClassicWriteInitial)
|
||||
ADD_SCENE(nfc, mf_classic_write_initial_success, MfClassicWriteInitialSuccess)
|
||||
ADD_SCENE(nfc, mf_classic_write_initial_fail, MfClassicWriteInitialFail)
|
||||
ADD_SCENE(nfc, mf_classic_write_initial_wrong_card, MfClassicWriteInitialWrongCard)
|
||||
|
||||
ADD_SCENE(nfc, mf_classic_keys, MfClassicKeys)
|
||||
ADD_SCENE(nfc, mf_classic_keys_list, MfClassicKeysList)
|
||||
@@ -67,8 +60,4 @@ ADD_SCENE(nfc, slix_key_input, SlixKeyInput)
|
||||
ADD_SCENE(nfc, slix_unlock, SlixUnlock)
|
||||
ADD_SCENE(nfc, slix_unlock_success, SlixUnlockSuccess)
|
||||
|
||||
ADD_SCENE(nfc, type_4_tag_write, Type4TagWrite)
|
||||
ADD_SCENE(nfc, type_4_tag_write_success, Type4TagWriteSuccess)
|
||||
ADD_SCENE(nfc, type_4_tag_write_fail, Type4TagWriteFail)
|
||||
|
||||
ADD_SCENE(nfc, generate_info, GenerateInfo)
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
#include <nfc/protocols/mf_classic/mf_classic_poller.h>
|
||||
|
||||
enum {
|
||||
NfcSceneMfClassicWriteInitialStateCardSearch,
|
||||
NfcSceneMfClassicWriteInitialStateCardFound,
|
||||
};
|
||||
|
||||
NfcCommand
|
||||
nfc_scene_mf_classic_write_initial_worker_callback(NfcGenericEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
furi_assert(event.event_data);
|
||||
furi_assert(event.protocol == NfcProtocolMfClassic);
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
NfcApp* instance = context;
|
||||
MfClassicPollerEvent* mfc_event = event.event_data;
|
||||
const MfClassicData* write_data =
|
||||
nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic);
|
||||
|
||||
if(mfc_event->type == MfClassicPollerEventTypeCardDetected) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeCardLost) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardLost);
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeRequestMode) {
|
||||
const MfClassicData* tag_data = nfc_poller_get_data(instance->poller);
|
||||
if(iso14443_3a_is_equal(tag_data->iso14443_3a_data, write_data->iso14443_3a_data)) {
|
||||
mfc_event->data->poller_mode.mode = MfClassicPollerModeWrite;
|
||||
} else {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventWrongCard);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeRequestSectorTrailer) {
|
||||
uint8_t sector = mfc_event->data->sec_tr_data.sector_num;
|
||||
uint8_t sec_tr = mf_classic_get_sector_trailer_num_by_sector(sector);
|
||||
if(mf_classic_is_block_read(write_data, sec_tr)) {
|
||||
mfc_event->data->sec_tr_data.sector_trailer = write_data->block[sec_tr];
|
||||
mfc_event->data->sec_tr_data.sector_trailer_provided = true;
|
||||
} else {
|
||||
mfc_event->data->sec_tr_data.sector_trailer_provided = false;
|
||||
}
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeRequestWriteBlock) {
|
||||
uint8_t block_num = mfc_event->data->write_block_data.block_num;
|
||||
if(mf_classic_is_block_read(write_data, block_num)) {
|
||||
mfc_event->data->write_block_data.write_block = write_data->block[block_num];
|
||||
mfc_event->data->write_block_data.write_block_provided = true;
|
||||
} else {
|
||||
mfc_event->data->write_block_data.write_block_provided = false;
|
||||
}
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeSuccess) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
|
||||
command = NfcCommandStop;
|
||||
} else if(mfc_event->type == MfClassicPollerEventTypeFail) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
static void nfc_scene_mf_classic_write_initial_setup_view(NfcApp* instance) {
|
||||
Popup* popup = instance->popup;
|
||||
popup_reset(popup);
|
||||
uint32_t state =
|
||||
scene_manager_get_scene_state(instance->scene_manager, NfcSceneMfClassicWriteInitial);
|
||||
|
||||
if(state == NfcSceneMfClassicWriteInitialStateCardSearch) {
|
||||
popup_set_header(instance->popup, "Writing", 95, 20, AlignCenter, AlignCenter);
|
||||
popup_set_text(
|
||||
instance->popup, "Use the source\ncard only", 95, 38, AlignCenter, AlignCenter);
|
||||
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
|
||||
} else {
|
||||
popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter);
|
||||
popup_set_icon(popup, 12, 23, &A_Loading_24);
|
||||
}
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
|
||||
}
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
dolphin_deed(DolphinDeedNfcEmulate);
|
||||
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfClassicWriteInitial,
|
||||
NfcSceneMfClassicWriteInitialStateCardSearch);
|
||||
nfc_scene_mf_classic_write_initial_setup_view(instance);
|
||||
|
||||
// Setup and start worker
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfClassic);
|
||||
nfc_poller_start(
|
||||
instance->poller, nfc_scene_mf_classic_write_initial_worker_callback, instance);
|
||||
|
||||
nfc_blink_emulate_start(instance);
|
||||
}
|
||||
|
||||
bool nfc_scene_mf_classic_write_initial_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == NfcCustomEventCardDetected) {
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfClassicWriteInitial,
|
||||
NfcSceneMfClassicWriteInitialStateCardFound);
|
||||
nfc_scene_mf_classic_write_initial_setup_view(instance);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventCardLost) {
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfClassicWriteInitial,
|
||||
NfcSceneMfClassicWriteInitialStateCardSearch);
|
||||
nfc_scene_mf_classic_write_initial_setup_view(instance);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventWrongCard) {
|
||||
scene_manager_next_scene(
|
||||
instance->scene_manager, NfcSceneMfClassicWriteInitialWrongCard);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventPollerSuccess) {
|
||||
scene_manager_next_scene(
|
||||
instance->scene_manager, NfcSceneMfClassicWriteInitialSuccess);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventPollerFailure) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicWriteInitialFail);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
nfc_poller_stop(instance->poller);
|
||||
nfc_poller_free(instance->poller);
|
||||
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfClassicWriteInitial,
|
||||
NfcSceneMfClassicWriteInitialStateCardSearch);
|
||||
// Clear view
|
||||
popup_reset(instance->popup);
|
||||
|
||||
nfc_blink_stop(instance);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_fail_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
NfcApp* instance = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_fail_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
Widget* widget = instance->widget;
|
||||
|
||||
notification_message(instance->notifications, &sequence_error);
|
||||
|
||||
widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42);
|
||||
widget_add_string_element(
|
||||
widget, 7, 4, AlignLeft, AlignTop, FontPrimary, "Writing gone wrong!");
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
7,
|
||||
17,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
"Not all sectors\nwere written\ncorrectly.");
|
||||
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeLeft,
|
||||
"Finish",
|
||||
nfc_scene_mf_classic_write_initial_fail_widget_callback,
|
||||
instance);
|
||||
|
||||
// Setup and start worker
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
|
||||
}
|
||||
|
||||
bool nfc_scene_mf_classic_write_initial_fail_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, NfcSceneSavedMenu);
|
||||
}
|
||||
} else if(event.type == SceneManagerEventTypeBack) {
|
||||
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, NfcSceneSavedMenu);
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_fail_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
widget_reset(instance->widget);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_success_popup_callback(void* context) {
|
||||
NfcApp* instance = context;
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventViewExit);
|
||||
}
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_success_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
dolphin_deed(DolphinDeedNfcSave);
|
||||
|
||||
notification_message(instance->notifications, &sequence_success);
|
||||
|
||||
Popup* popup = instance->popup;
|
||||
popup_set_header(popup, "Success!", 75, 10, AlignLeft, AlignTop);
|
||||
popup_set_icon(popup, 0, 9, &I_DolphinSuccess_91x55);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_set_context(popup, instance);
|
||||
popup_set_callback(popup, nfc_scene_mf_classic_write_initial_success_popup_callback);
|
||||
popup_enable_timeout(popup);
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
|
||||
}
|
||||
|
||||
bool nfc_scene_mf_classic_write_initial_success_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == NfcCustomEventViewExit) {
|
||||
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, NfcSceneSavedMenu);
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_success_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
// Clear view
|
||||
popup_reset(instance->popup);
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_wrong_card_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
NfcApp* instance = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_wrong_card_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
Widget* widget = instance->widget;
|
||||
|
||||
notification_message(instance->notifications, &sequence_error);
|
||||
|
||||
widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42);
|
||||
widget_add_string_element(
|
||||
widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "Use The Source Card!");
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
4,
|
||||
17,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
"Go to NFC Magic\napp if you want to\nwrite blanks");
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeLeft,
|
||||
"Retry",
|
||||
nfc_scene_mf_classic_write_initial_wrong_card_widget_callback,
|
||||
instance);
|
||||
|
||||
// Setup and start worker
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
|
||||
}
|
||||
|
||||
bool nfc_scene_mf_classic_write_initial_wrong_card_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
consumed = scene_manager_previous_scene(instance->scene_manager);
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_classic_write_initial_wrong_card_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
widget_reset(instance->widget);
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
#include <nfc/protocols/mf_ultralight/mf_ultralight_poller.h>
|
||||
|
||||
enum {
|
||||
NfcSceneMfUltralightWriteStateCardSearch,
|
||||
NfcSceneMfUltralightWriteStateCardFound,
|
||||
};
|
||||
|
||||
NfcCommand nfc_scene_mf_ultralight_write_worker_callback(NfcGenericEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
furi_assert(event.event_data);
|
||||
furi_assert(event.protocol == NfcProtocolMfUltralight);
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
NfcApp* instance = context;
|
||||
MfUltralightPollerEvent* mfu_event = event.event_data;
|
||||
|
||||
if(mfu_event->type == MfUltralightPollerEventTypeRequestMode) {
|
||||
mfu_event->data->poller_mode = MfUltralightPollerModeWrite;
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
|
||||
} else if(mfu_event->type == MfUltralightPollerEventTypeAuthRequest) {
|
||||
mfu_event->data->auth_context.skip_auth = true;
|
||||
} else if(mfu_event->type == MfUltralightPollerEventTypeRequestWriteData) {
|
||||
mfu_event->data->write_data =
|
||||
nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight);
|
||||
} else if(mfu_event->type == MfUltralightPollerEventTypeCardMismatch) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventWrongCard);
|
||||
command = NfcCommandStop;
|
||||
} else if(mfu_event->type == MfUltralightPollerEventTypeCardLocked) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
|
||||
command = NfcCommandStop;
|
||||
} else if(mfu_event->type == MfUltralightPollerEventTypeWriteFail) {
|
||||
command = NfcCommandStop;
|
||||
} else if(mfu_event->type == MfUltralightPollerEventTypeWriteSuccess) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
static void nfc_scene_mf_ultralight_write_setup_view(NfcApp* instance) {
|
||||
Popup* popup = instance->popup;
|
||||
popup_reset(popup);
|
||||
uint32_t state =
|
||||
scene_manager_get_scene_state(instance->scene_manager, NfcSceneMfUltralightWrite);
|
||||
|
||||
if(state == NfcSceneMfUltralightWriteStateCardSearch) {
|
||||
popup_set_header(instance->popup, "Writing", 95, 20, AlignCenter, AlignCenter);
|
||||
popup_set_text(
|
||||
instance->popup, "Apply the initial\ncard only", 95, 38, AlignCenter, AlignCenter);
|
||||
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
|
||||
} else {
|
||||
popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter);
|
||||
popup_set_icon(popup, 12, 23, &A_Loading_24);
|
||||
}
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_write_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
dolphin_deed(DolphinDeedNfcEmulate);
|
||||
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfUltralightWrite,
|
||||
NfcSceneMfUltralightWriteStateCardSearch);
|
||||
nfc_scene_mf_ultralight_write_setup_view(instance);
|
||||
|
||||
// Setup and start worker
|
||||
FURI_LOG_D("WMFU", "Card searching...");
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfUltralight);
|
||||
nfc_poller_start(instance->poller, nfc_scene_mf_ultralight_write_worker_callback, instance);
|
||||
|
||||
nfc_blink_emulate_start(instance);
|
||||
}
|
||||
|
||||
bool nfc_scene_mf_ultralight_write_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == NfcCustomEventCardDetected) {
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfUltralightWrite,
|
||||
NfcSceneMfUltralightWriteStateCardFound);
|
||||
nfc_scene_mf_ultralight_write_setup_view(instance);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventWrongCard) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWrongCard);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventPollerSuccess) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWriteSuccess);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventPollerFailure) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWriteFail);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_write_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
nfc_poller_stop(instance->poller);
|
||||
nfc_poller_free(instance->poller);
|
||||
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfUltralightWrite,
|
||||
NfcSceneMfUltralightWriteStateCardSearch);
|
||||
// Clear view
|
||||
popup_reset(instance->popup);
|
||||
|
||||
nfc_blink_stop(instance);
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
void nfc_scene_mf_ultralight_write_fail_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
NfcApp* instance = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_write_fail_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
Widget* widget = instance->widget;
|
||||
|
||||
notification_message(instance->notifications, &sequence_error);
|
||||
|
||||
widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42);
|
||||
widget_add_string_element(
|
||||
widget, 7, 4, AlignLeft, AlignTop, FontPrimary, "Writing gone wrong!");
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
7,
|
||||
17,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
"Card protected by\npassword, AUTH0\nor lock bits");
|
||||
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeLeft,
|
||||
"Finish",
|
||||
nfc_scene_mf_ultralight_write_fail_widget_callback,
|
||||
instance);
|
||||
|
||||
// Setup and start worker
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
|
||||
}
|
||||
|
||||
static bool nfc_scene_mf_ultralight_write_fail_move_to_back_scene(const NfcApp* const instance) {
|
||||
bool was_saved = scene_manager_has_previous_scene(instance->scene_manager, NfcSceneSavedMenu);
|
||||
uint32_t scene_id = was_saved ? NfcSceneSavedMenu : NfcSceneReadMenu;
|
||||
|
||||
return scene_manager_search_and_switch_to_previous_scene(instance->scene_manager, scene_id);
|
||||
}
|
||||
|
||||
bool nfc_scene_mf_ultralight_write_fail_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
consumed = nfc_scene_mf_ultralight_write_fail_move_to_back_scene(instance);
|
||||
}
|
||||
} else if(event.type == SceneManagerEventTypeBack) {
|
||||
consumed = nfc_scene_mf_ultralight_write_fail_move_to_back_scene(instance);
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_write_fail_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
widget_reset(instance->widget);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
void nfc_scene_mf_ultralight_write_success_popup_callback(void* context) {
|
||||
NfcApp* instance = context;
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventViewExit);
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_write_success_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
dolphin_deed(DolphinDeedNfcSave);
|
||||
|
||||
notification_message(instance->notifications, &sequence_success);
|
||||
|
||||
Popup* popup = instance->popup;
|
||||
popup_set_icon(popup, 48, 6, &I_DolphinDone_80x58);
|
||||
popup_set_header(popup, "Successfully\nwritten", 5, 22, AlignLeft, AlignBottom);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_set_context(popup, instance);
|
||||
popup_set_callback(popup, nfc_scene_mf_ultralight_write_success_popup_callback);
|
||||
popup_enable_timeout(popup);
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
|
||||
}
|
||||
|
||||
bool nfc_scene_mf_ultralight_write_success_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == NfcCustomEventViewExit) {
|
||||
bool was_saved =
|
||||
scene_manager_has_previous_scene(instance->scene_manager, NfcSceneSavedMenu);
|
||||
|
||||
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, was_saved ? NfcSceneSavedMenu : NfcSceneReadSuccess);
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_write_success_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
// Clear view
|
||||
popup_reset(instance->popup);
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
void nfc_scene_mf_ultralight_wrong_card_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
NfcApp* instance = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_wrong_card_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
Widget* widget = instance->widget;
|
||||
|
||||
notification_message(instance->notifications, &sequence_error);
|
||||
|
||||
widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42);
|
||||
widget_add_string_element(
|
||||
widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "This is wrong card");
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
4,
|
||||
17,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
"Card of the same\ntype should be\n presented");
|
||||
//"Data management\nis only possible\nwith card of same type");
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeLeft,
|
||||
"Retry",
|
||||
nfc_scene_mf_ultralight_wrong_card_widget_callback,
|
||||
instance);
|
||||
|
||||
// Setup and start worker
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
|
||||
}
|
||||
|
||||
bool nfc_scene_mf_ultralight_wrong_card_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
consumed = scene_manager_previous_scene(instance->scene_manager);
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_wrong_card_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
widget_reset(instance->widget);
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
#include <nfc/protocols/type_4_tag/type_4_tag_poller.h>
|
||||
|
||||
enum {
|
||||
NfcSceneType4TagWriteStateCardSearch,
|
||||
NfcSceneType4TagWriteStateCardFound,
|
||||
};
|
||||
|
||||
NfcCommand nfc_scene_type_4_tag_write_worker_callback(NfcGenericEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
furi_assert(event.event_data);
|
||||
furi_assert(event.protocol == NfcProtocolType4Tag);
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
NfcApp* instance = context;
|
||||
Type4TagPollerEvent* t4t_event = event.event_data;
|
||||
|
||||
if(t4t_event->type == Type4TagPollerEventTypeRequestMode) {
|
||||
t4t_event->data->poller_mode.mode = Type4TagPollerModeWrite;
|
||||
t4t_event->data->poller_mode.data =
|
||||
nfc_device_get_data(instance->nfc_device, NfcProtocolType4Tag);
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
|
||||
} else if(t4t_event->type == Type4TagPollerEventTypeWriteFail) {
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager, NfcSceneType4TagWriteFail, t4t_event->data->error);
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
|
||||
command = NfcCommandStop;
|
||||
} else if(t4t_event->type == Type4TagPollerEventTypeWriteSuccess) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
static void nfc_scene_type_4_tag_write_setup_view(NfcApp* instance) {
|
||||
Popup* popup = instance->popup;
|
||||
popup_reset(popup);
|
||||
uint32_t state = scene_manager_get_scene_state(instance->scene_manager, NfcSceneType4TagWrite);
|
||||
|
||||
if(state == NfcSceneType4TagWriteStateCardSearch) {
|
||||
popup_set_header(instance->popup, "Writing", 95, 20, AlignCenter, AlignCenter);
|
||||
popup_set_text(
|
||||
instance->popup, "Apply card\nto the back", 95, 38, AlignCenter, AlignCenter);
|
||||
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
|
||||
} else {
|
||||
popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter);
|
||||
popup_set_icon(popup, 12, 23, &A_Loading_24);
|
||||
}
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
|
||||
}
|
||||
|
||||
void nfc_scene_type_4_tag_write_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
dolphin_deed(DolphinDeedNfcEmulate);
|
||||
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager, NfcSceneType4TagWrite, NfcSceneType4TagWriteStateCardSearch);
|
||||
nfc_scene_type_4_tag_write_setup_view(instance);
|
||||
|
||||
// Setup and start worker
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolType4Tag);
|
||||
nfc_poller_start(instance->poller, nfc_scene_type_4_tag_write_worker_callback, instance);
|
||||
|
||||
nfc_blink_emulate_start(instance);
|
||||
}
|
||||
|
||||
bool nfc_scene_type_4_tag_write_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == NfcCustomEventCardDetected) {
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneType4TagWrite,
|
||||
NfcSceneType4TagWriteStateCardFound);
|
||||
nfc_scene_type_4_tag_write_setup_view(instance);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventPollerSuccess) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneType4TagWriteSuccess);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventPollerFailure) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneType4TagWriteFail);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_type_4_tag_write_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
nfc_poller_stop(instance->poller);
|
||||
nfc_poller_free(instance->poller);
|
||||
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager, NfcSceneType4TagWrite, NfcSceneType4TagWriteStateCardSearch);
|
||||
// Clear view
|
||||
popup_reset(instance->popup);
|
||||
|
||||
nfc_blink_stop(instance);
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
#include <nfc/protocols/type_4_tag/type_4_tag_poller.h>
|
||||
|
||||
void nfc_scene_type_4_tag_write_fail_widget_callback(
|
||||
GuiButtonType result,
|
||||
InputType type,
|
||||
void* context) {
|
||||
NfcApp* instance = context;
|
||||
if(type == InputTypeShort) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, result);
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_scene_type_4_tag_write_fail_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
Widget* widget = instance->widget;
|
||||
|
||||
notification_message(instance->notifications, &sequence_error);
|
||||
|
||||
widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42);
|
||||
widget_add_string_element(
|
||||
widget, 7, 4, AlignLeft, AlignTop, FontPrimary, "Writing gone wrong!");
|
||||
Type4TagError error =
|
||||
scene_manager_get_scene_state(instance->scene_manager, NfcSceneType4TagWriteFail);
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
7,
|
||||
17,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
error == Type4TagErrorCardLocked ? "Card does not\nallow writing\nnew data" :
|
||||
"Failed to\nwrite new data");
|
||||
|
||||
widget_add_button_element(
|
||||
widget,
|
||||
GuiButtonTypeLeft,
|
||||
"Finish",
|
||||
nfc_scene_type_4_tag_write_fail_widget_callback,
|
||||
instance);
|
||||
|
||||
// Setup and start worker
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
|
||||
}
|
||||
|
||||
static bool nfc_scene_type_4_tag_write_fail_move_to_back_scene(const NfcApp* const instance) {
|
||||
bool was_saved = scene_manager_has_previous_scene(instance->scene_manager, NfcSceneSavedMenu);
|
||||
uint32_t scene_id = was_saved ? NfcSceneSavedMenu : NfcSceneReadMenu;
|
||||
|
||||
return scene_manager_search_and_switch_to_previous_scene(instance->scene_manager, scene_id);
|
||||
}
|
||||
|
||||
bool nfc_scene_type_4_tag_write_fail_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
consumed = nfc_scene_type_4_tag_write_fail_move_to_back_scene(instance);
|
||||
}
|
||||
} else if(event.type == SceneManagerEventTypeBack) {
|
||||
consumed = nfc_scene_type_4_tag_write_fail_move_to_back_scene(instance);
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_type_4_tag_write_fail_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
widget_reset(instance->widget);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
#include "../nfc_app_i.h"
|
||||
|
||||
void nfc_scene_type_4_tag_write_success_popup_callback(void* context) {
|
||||
NfcApp* instance = context;
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventViewExit);
|
||||
}
|
||||
|
||||
void nfc_scene_type_4_tag_write_success_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
dolphin_deed(DolphinDeedNfcSave);
|
||||
|
||||
notification_message(instance->notifications, &sequence_success);
|
||||
|
||||
Popup* popup = instance->popup;
|
||||
popup_set_icon(popup, 48, 6, &I_DolphinDone_80x58);
|
||||
popup_set_header(popup, "Successfully\nwritten", 5, 22, AlignLeft, AlignBottom);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_set_context(popup, instance);
|
||||
popup_set_callback(popup, nfc_scene_type_4_tag_write_success_popup_callback);
|
||||
popup_enable_timeout(popup);
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
|
||||
}
|
||||
|
||||
bool nfc_scene_type_4_tag_write_success_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == NfcCustomEventViewExit) {
|
||||
bool was_saved =
|
||||
scene_manager_has_previous_scene(instance->scene_manager, NfcSceneSavedMenu);
|
||||
|
||||
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, was_saved ? NfcSceneSavedMenu : NfcSceneReadSuccess);
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_type_4_tag_write_success_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
// Clear view
|
||||
popup_reset(instance->popup);
|
||||
}
|
||||
13
applications/main/nfc/scenes/nfc_scene_write.c
Normal file
13
applications/main/nfc/scenes/nfc_scene_write.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "../helpers/protocol_support/nfc_protocol_support.h"
|
||||
|
||||
void nfc_scene_write_on_enter(void* context) {
|
||||
nfc_protocol_support_on_enter(NfcProtocolSupportSceneWrite, context);
|
||||
}
|
||||
|
||||
bool nfc_scene_write_on_event(void* context, SceneManagerEvent event) {
|
||||
return nfc_protocol_support_on_event(NfcProtocolSupportSceneWrite, context, event);
|
||||
}
|
||||
|
||||
void nfc_scene_write_on_exit(void* context) {
|
||||
nfc_protocol_support_on_exit(NfcProtocolSupportSceneWrite, context);
|
||||
}
|
||||
Reference in New Issue
Block a user