mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-29 16:25:47 +03:00
6a5d63803a
* New scenes for ultralight poller write mode * Added new button and transition logic for write operation For now write is only possible for NTAG21x cards with default password and no AUTHLIM set * Poller states extended * Enums and datatypes extended for new poller mode * Added mode field to poller instance datatype * New states for poller added in order to implement write mode * Added new event type for locked cards in order to simplify state flow * New logic for poller write commands * Scenes adjustments * Scenes renamed * New field added to poller instance * Now we write in 'page per call' mode * Now function takes callback return value into account * Callback will be called only in write mode * Event type added * Log adjusted and start page to write set * Logs added and check in now false at start, then it moves to true * Now mf_ultralight_poller_handler_request_write_data halts card in case of check failure and stops poller * All fail events now returns NfcCommandStop callback * In case of fail we move back properly * Remove garbage Co-authored-by: gornekich <n.gorbadey@gmail.com> Co-authored-by: あく <alleteam@gmail.com>
120 lines
4.7 KiB
C
120 lines
4.7 KiB
C
#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_text(
|
|
instance->popup, "Apply the initial\ncard only", 128, 32, AlignRight, 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);
|
|
}
|