mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-20 04:54:45 -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_enter = nfc_scene_emulate_on_enter_felica,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -144,4 +144,9 @@ const NfcProtocolSupportBase nfc_protocol_support_iso14443_3a = {
|
|||||||
.on_enter = nfc_scene_emulate_on_enter_iso14443_3a,
|
.on_enter = nfc_scene_emulate_on_enter_iso14443_3a,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,4 +111,9 @@ const NfcProtocolSupportBase nfc_protocol_support_iso14443_3b = {
|
|||||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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_enter = nfc_scene_emulate_on_enter_iso14443_4a,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -116,4 +116,9 @@ const NfcProtocolSupportBase nfc_protocol_support_iso14443_4b = {
|
|||||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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_enter = nfc_scene_emulate_on_enter_iso15693_3,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,9 +12,8 @@
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
SubmenuIndexDetectReader = SubmenuIndexCommonMax,
|
SubmenuIndexDetectReader = SubmenuIndexCommonMax,
|
||||||
SubmenuIndexWrite,
|
SubmenuIndexDictAttack,
|
||||||
SubmenuIndexUpdate,
|
SubmenuIndexUpdate,
|
||||||
SubmenuIndexDictAttack
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void nfc_scene_info_on_enter_mf_classic(NfcApp* instance) {
|
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;
|
Submenu* submenu = instance->submenu;
|
||||||
const MfClassicData* data = nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic);
|
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)) {
|
if(!mf_classic_is_card_read(data)) {
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
@@ -152,6 +154,8 @@ static void nfc_scene_saved_menu_on_enter_mf_classic(NfcApp* instance) {
|
|||||||
Submenu* submenu = instance->submenu;
|
Submenu* submenu = instance->submenu;
|
||||||
const MfClassicData* data = nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic);
|
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)) {
|
if(!mf_classic_is_card_read(data)) {
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
@@ -167,12 +171,6 @@ static void nfc_scene_saved_menu_on_enter_mf_classic(NfcApp* instance) {
|
|||||||
nfc_protocol_support_common_submenu_callback,
|
nfc_protocol_support_common_submenu_callback,
|
||||||
instance);
|
instance);
|
||||||
}
|
}
|
||||||
submenu_add_item(
|
|
||||||
submenu,
|
|
||||||
"Write to Initial Card",
|
|
||||||
SubmenuIndexWrite,
|
|
||||||
nfc_protocol_support_common_submenu_callback,
|
|
||||||
instance);
|
|
||||||
|
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
@@ -218,18 +216,15 @@ static bool nfc_scene_saved_menu_on_event_mf_classic(NfcApp* instance, SceneMana
|
|||||||
if(event.event == SubmenuIndexDetectReader) {
|
if(event.event == SubmenuIndexDetectReader) {
|
||||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDetectReader);
|
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDetectReader);
|
||||||
consumed = true;
|
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) {
|
} else if(event.event == SubmenuIndexDictAttack) {
|
||||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||||
instance->scene_manager, NfcSceneMfClassicDictAttack)) {
|
instance->scene_manager, NfcSceneMfClassicDictAttack)) {
|
||||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDictAttack);
|
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDictAttack);
|
||||||
}
|
}
|
||||||
consumed = true;
|
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;
|
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 = {
|
const NfcProtocolSupportBase nfc_protocol_support_mf_classic = {
|
||||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo,
|
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo |
|
||||||
|
NfcProtocolFeatureWrite,
|
||||||
|
|
||||||
.scene_info =
|
.scene_info =
|
||||||
{
|
{
|
||||||
@@ -292,4 +350,9 @@ const NfcProtocolSupportBase nfc_protocol_support_mf_classic = {
|
|||||||
.on_enter = nfc_scene_emulate_on_enter_mf_classic,
|
.on_enter = nfc_scene_emulate_on_enter_mf_classic,
|
||||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
.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_enter = nfc_scene_emulate_on_enter_mf_desfire,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -120,4 +120,9 @@ const NfcProtocolSupportBase nfc_protocol_support_mf_plus = {
|
|||||||
.on_enter = nfc_scene_emulate_on_enter_mf_plus,
|
.on_enter = nfc_scene_emulate_on_enter_mf_plus,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ enum {
|
|||||||
SubmenuIndexUnlock = SubmenuIndexCommonMax,
|
SubmenuIndexUnlock = SubmenuIndexCommonMax,
|
||||||
SubmenuIndexUnlockByReader,
|
SubmenuIndexUnlockByReader,
|
||||||
SubmenuIndexUnlockByPassword,
|
SubmenuIndexUnlockByPassword,
|
||||||
SubmenuIndexWrite,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -182,24 +181,22 @@ static void nfc_scene_read_and_saved_menu_on_enter_mf_ultralight(NfcApp* instanc
|
|||||||
|
|
||||||
const MfUltralightData* data =
|
const MfUltralightData* data =
|
||||||
nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight);
|
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_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
"Unlock",
|
"Unlock",
|
||||||
SubmenuIndexUnlock,
|
SubmenuIndexUnlock,
|
||||||
nfc_protocol_support_common_submenu_callback,
|
nfc_protocol_support_common_submenu_callback,
|
||||||
instance);
|
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;
|
NfcSceneMfUltralightUnlockMenu;
|
||||||
scene_manager_next_scene(instance->scene_manager, next_scene);
|
scene_manager_next_scene(instance->scene_manager, next_scene);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexWrite) {
|
|
||||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWrite);
|
|
||||||
consumed = true;
|
|
||||||
} else if(event.event == SubmenuIndexCommonEdit) {
|
} else if(event.event == SubmenuIndexCommonEdit) {
|
||||||
scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid);
|
scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
@@ -263,8 +257,52 @@ static bool nfc_scene_read_and_saved_menu_on_event_mf_ultralight(
|
|||||||
return consumed;
|
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 = {
|
const NfcProtocolSupportBase nfc_protocol_support_mf_ultralight = {
|
||||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo,
|
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo |
|
||||||
|
NfcProtocolFeatureWrite,
|
||||||
|
|
||||||
.scene_info =
|
.scene_info =
|
||||||
{
|
{
|
||||||
@@ -306,4 +344,9 @@ const NfcProtocolSupportBase nfc_protocol_support_mf_ultralight = {
|
|||||||
.on_enter = nfc_scene_emulate_on_enter_mf_ultralight,
|
.on_enter = nfc_scene_emulate_on_enter_mf_ultralight,
|
||||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
.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);
|
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);
|
nfc_protocol_support[protocol]->scene_read_menu.on_enter(instance);
|
||||||
|
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
@@ -291,6 +300,10 @@ static bool
|
|||||||
dolphin_deed(DolphinDeedNfcEmulate);
|
dolphin_deed(DolphinDeedNfcEmulate);
|
||||||
scene_manager_next_scene(instance->scene_manager, NfcSceneEmulate);
|
scene_manager_next_scene(instance->scene_manager, NfcSceneEmulate);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
|
} else if(event.event == SubmenuIndexCommonWrite) {
|
||||||
|
dolphin_deed(DolphinDeedNfcEmulate);
|
||||||
|
scene_manager_next_scene(instance->scene_manager, NfcSceneWrite);
|
||||||
|
consumed = true;
|
||||||
} else {
|
} else {
|
||||||
const NfcProtocol protocol = nfc_device_get_protocol(instance->nfc_device);
|
const NfcProtocol protocol = nfc_device_get_protocol(instance->nfc_device);
|
||||||
consumed = nfc_protocol_support[protocol]->scene_read_menu.on_event(instance, event);
|
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);
|
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)) {
|
if(nfc_protocol_support_has_feature(protocol, NfcProtocolFeatureEditUid)) {
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
@@ -456,6 +478,12 @@ static bool
|
|||||||
dolphin_deed(is_added ? DolphinDeedNfcAddEmulate : DolphinDeedNfcEmulate);
|
dolphin_deed(is_added ? DolphinDeedNfcAddEmulate : DolphinDeedNfcEmulate);
|
||||||
scene_manager_next_scene(instance->scene_manager, NfcSceneEmulate);
|
scene_manager_next_scene(instance->scene_manager, NfcSceneEmulate);
|
||||||
consumed = true;
|
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) {
|
} else if(event.event == SubmenuIndexCommonEdit) {
|
||||||
scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid);
|
scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
@@ -688,6 +716,175 @@ static void nfc_protocol_support_scene_emulate_on_exit(NfcApp* instance) {
|
|||||||
nfc_blink_stop(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) {
|
static void nfc_protocol_support_scene_rpc_on_enter(NfcApp* instance) {
|
||||||
UNUSED(instance);
|
UNUSED(instance);
|
||||||
}
|
}
|
||||||
@@ -803,6 +1000,12 @@ static const NfcProtocolSupportCommonSceneBase
|
|||||||
.on_event = nfc_protocol_support_scene_emulate_on_event,
|
.on_event = nfc_protocol_support_scene_emulate_on_event,
|
||||||
.on_exit = nfc_protocol_support_scene_emulate_on_exit,
|
.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] =
|
[NfcProtocolSupportSceneRpc] =
|
||||||
{
|
{
|
||||||
.on_enter = nfc_protocol_support_scene_rpc_on_enter,
|
.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.
|
* It is responsible for creating a listener and for handling its events.
|
||||||
*/
|
*/
|
||||||
NfcProtocolSupportSceneBase scene_emulate;
|
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;
|
} NfcProtocolSupportBase;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ typedef enum {
|
|||||||
NfcProtocolFeatureEmulateFull = 1UL << 1, /**< Complete emulation is supported. */
|
NfcProtocolFeatureEmulateFull = 1UL << 1, /**< Complete emulation is supported. */
|
||||||
NfcProtocolFeatureEditUid = 1UL << 2, /**< UID editing is supported. */
|
NfcProtocolFeatureEditUid = 1UL << 2, /**< UID editing is supported. */
|
||||||
NfcProtocolFeatureMoreInfo = 1UL << 3, /**< More information is provided. */
|
NfcProtocolFeatureMoreInfo = 1UL << 3, /**< More information is provided. */
|
||||||
|
NfcProtocolFeatureWrite = 1UL << 4, /**< Writing to real card is supported. */
|
||||||
} NfcProtocolFeature;
|
} NfcProtocolFeature;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +31,7 @@ typedef enum {
|
|||||||
NfcProtocolSupportSceneSavedMenu, /**< Menu for the card that was loaded from file. */
|
NfcProtocolSupportSceneSavedMenu, /**< Menu for the card that was loaded from file. */
|
||||||
NfcProtocolSupportSceneSaveName, /**< Shown when saving or renaming a file. */
|
NfcProtocolSupportSceneSaveName, /**< Shown when saving or renaming a file. */
|
||||||
NfcProtocolSupportSceneEmulate, /**< Shown when emulating a card. */
|
NfcProtocolSupportSceneEmulate, /**< Shown when emulating a card. */
|
||||||
|
NfcProtocolSupportSceneWrite, /**< Shown when writing to a card. */
|
||||||
NfcProtocolSupportSceneRpc, /**< Shown in remote-controlled (RPC) mode. */
|
NfcProtocolSupportSceneRpc, /**< Shown in remote-controlled (RPC) mode. */
|
||||||
|
|
||||||
NfcProtocolSupportSceneCount, /**< Special value equal to total scene count. Internal use. */
|
NfcProtocolSupportSceneCount, /**< Special value equal to total scene count. Internal use. */
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
enum {
|
enum {
|
||||||
SubmenuIndexCommonSave, /**< Save menu option. */
|
SubmenuIndexCommonSave, /**< Save menu option. */
|
||||||
SubmenuIndexCommonEmulate, /**< Emulate menu option. */
|
SubmenuIndexCommonEmulate, /**< Emulate menu option. */
|
||||||
|
SubmenuIndexCommonWrite, /**< Write menu option. */
|
||||||
SubmenuIndexCommonEdit, /**< Edit menu option. */
|
SubmenuIndexCommonEdit, /**< Edit menu option. */
|
||||||
SubmenuIndexCommonInfo, /**< Info menu option. */
|
SubmenuIndexCommonInfo, /**< Info menu option. */
|
||||||
SubmenuIndexCommonRename, /**< Rename 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_enter = nfc_scene_emulate_on_enter_slix,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -108,4 +108,9 @@ const NfcProtocolSupportBase nfc_protocol_support_st25tb = {
|
|||||||
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||||
.on_event = nfc_protocol_support_common_on_event_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_common.h"
|
||||||
#include "../nfc_protocol_support_gui_common.h"
|
#include "../nfc_protocol_support_gui_common.h"
|
||||||
|
|
||||||
enum {
|
|
||||||
SubmenuIndexWrite = SubmenuIndexCommonMax,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NfcSceneMoreInfoStateASCII,
|
NfcSceneMoreInfoStateASCII,
|
||||||
NfcSceneMoreInfoStateRawData,
|
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);
|
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) {
|
static void nfc_scene_read_success_on_enter_type_4_tag(NfcApp* instance) {
|
||||||
const NfcDevice* device = instance->nfc_device;
|
const NfcDevice* device = instance->nfc_device;
|
||||||
const Type4TagData* data = nfc_device_get_data(device, NfcProtocolType4Tag);
|
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);
|
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 = {
|
const NfcProtocolSupportBase nfc_protocol_support_type_4_tag = {
|
||||||
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo,
|
.features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo |
|
||||||
|
NfcProtocolFeatureWrite,
|
||||||
|
|
||||||
.scene_info =
|
.scene_info =
|
||||||
{
|
{
|
||||||
@@ -221,8 +228,8 @@ const NfcProtocolSupportBase nfc_protocol_support_type_4_tag = {
|
|||||||
},
|
},
|
||||||
.scene_read_menu =
|
.scene_read_menu =
|
||||||
{
|
{
|
||||||
.on_enter = nfc_scene_read_and_saved_menu_on_enter_type_4_tag,
|
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||||
.on_event = nfc_scene_read_and_saved_menu_on_event_type_4_tag,
|
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||||
},
|
},
|
||||||
.scene_read_success =
|
.scene_read_success =
|
||||||
{
|
{
|
||||||
@@ -231,8 +238,8 @@ const NfcProtocolSupportBase nfc_protocol_support_type_4_tag = {
|
|||||||
},
|
},
|
||||||
.scene_saved_menu =
|
.scene_saved_menu =
|
||||||
{
|
{
|
||||||
.on_enter = nfc_scene_read_and_saved_menu_on_enter_type_4_tag,
|
.on_enter = nfc_protocol_support_common_on_enter_empty,
|
||||||
.on_event = nfc_scene_read_and_saved_menu_on_event_type_4_tag,
|
.on_event = nfc_protocol_support_common_on_event_empty,
|
||||||
},
|
},
|
||||||
.scene_save_name =
|
.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_enter = nfc_scene_emulate_on_enter_type_4_tag,
|
||||||
.on_event = nfc_protocol_support_common_on_event_empty,
|
.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_success, ReadSuccess)
|
||||||
ADD_SCENE(nfc, read_menu, ReadMenu)
|
ADD_SCENE(nfc, read_menu, ReadMenu)
|
||||||
ADD_SCENE(nfc, emulate, Emulate)
|
ADD_SCENE(nfc, emulate, Emulate)
|
||||||
|
ADD_SCENE(nfc, write, Write)
|
||||||
ADD_SCENE(nfc, rpc, Rpc)
|
ADD_SCENE(nfc, rpc, Rpc)
|
||||||
ADD_SCENE(nfc, debug, Debug)
|
ADD_SCENE(nfc, debug, Debug)
|
||||||
ADD_SCENE(nfc, field, Field)
|
ADD_SCENE(nfc, field, Field)
|
||||||
@@ -25,10 +26,6 @@ ADD_SCENE(nfc, retry_confirm, RetryConfirm)
|
|||||||
ADD_SCENE(nfc, exit_confirm, ExitConfirm)
|
ADD_SCENE(nfc, exit_confirm, ExitConfirm)
|
||||||
ADD_SCENE(nfc, save_confirm, SaveConfirm)
|
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_menu, MfUltralightUnlockMenu)
|
||||||
ADD_SCENE(nfc, mf_ultralight_unlock_warn, MfUltralightUnlockWarn)
|
ADD_SCENE(nfc, mf_ultralight_unlock_warn, MfUltralightUnlockWarn)
|
||||||
ADD_SCENE(nfc, mf_ultralight_key_input, MfUltralightKeyInput)
|
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, MfClassicUpdateInitial)
|
||||||
ADD_SCENE(nfc, mf_classic_update_initial_success, MfClassicUpdateInitialSuccess)
|
ADD_SCENE(nfc, mf_classic_update_initial_success, MfClassicUpdateInitialSuccess)
|
||||||
ADD_SCENE(nfc, mf_classic_update_initial_wrong_card, MfClassicUpdateInitialWrongCard)
|
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, MfClassicKeys)
|
||||||
ADD_SCENE(nfc, mf_classic_keys_list, MfClassicKeysList)
|
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, SlixUnlock)
|
||||||
ADD_SCENE(nfc, slix_unlock_success, SlixUnlockSuccess)
|
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)
|
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