diff --git a/nfc_playlist.h b/nfc_playlist.h index f7d78847595..d25e723b51b 100644 --- a/nfc_playlist.h +++ b/nfc_playlist.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include #include @@ -7,6 +8,7 @@ #include #include #include +#include typedef enum { NfcPlaylistView_Menu, @@ -25,6 +27,8 @@ typedef struct { VariableItemList* variable_item_list; Popup* popup; NotificationApp* notification; + FuriThread* thread; + NfcPlaylistWorker* nfc_playlist_worker; uint8_t emulate_timeout; uint8_t emulate_delay; bool emulate_led_indicator; diff --git a/scences/emulation.c b/scences/emulation.c index b1030f1995c..cbb99c6e240 100644 --- a/scences/emulation.c +++ b/scences/emulation.c @@ -1,24 +1,84 @@ #include "nfc_playlist.h" #include "scences/emulation.h" +bool cancel = false; + void nfc_playlist_emulation_scene_on_enter(void* context) { NfcPlaylist* nfc_playlist = context; + nfc_playlist_emulation_setup(nfc_playlist); + nfc_playlist_emulation_start(nfc_playlist); +} + +bool nfc_playlist_emulation_scene_on_event(void* context, SceneManagerEvent event) { + NfcPlaylist* nfc_playlist = context; + UNUSED(nfc_playlist); + FURI_LOG_RAW_I("nfc_playlist_emulation_scene_on_event: %ld", event.event); + switch (event.event) { + case 0: + if (nfc_playlist_worker_is_emulating(nfc_playlist->nfc_playlist_worker) && cancel != true) { + cancel = true; + return true; + } + default: + break; + } + + return false; +} +void nfc_playlist_emulation_scene_on_exit(void* context) { + NfcPlaylist* nfc_playlist = context; + cancel = false; + nfc_playlist_emulation_stop(nfc_playlist); + nfc_playlist_emulation_free(nfc_playlist); + popup_reset(nfc_playlist->popup); +} + +void nfc_playlist_emulation_setup(void* context) { + NfcPlaylist* nfc_playlist = context; + + nfc_playlist->thread = furi_thread_alloc_ex( + "NfcPlaylistEmulationWorker", 8192, nfc_playlist_emulation_task, nfc_playlist); + nfc_playlist->nfc_playlist_worker = nfc_playlist_worker_alloc(); +} + +void nfc_playlist_emulation_free(NfcPlaylist* nfc_playlist) { + furi_assert(nfc_playlist); + furi_thread_free(nfc_playlist->thread); + nfc_playlist_worker_free(nfc_playlist->nfc_playlist_worker); + nfc_playlist->thread = NULL; + nfc_playlist->nfc_playlist_worker = NULL; +} + +void nfc_playlist_emulation_start(NfcPlaylist* nfc_playlist) { + furi_assert(nfc_playlist); + furi_thread_start(nfc_playlist->thread); +} + +void nfc_playlist_emulation_stop(NfcPlaylist* nfc_playlist) { + furi_assert(nfc_playlist); + furi_thread_join(nfc_playlist->thread); +} + +int32_t nfc_playlist_emulation_task(void* context) { + NfcPlaylist* nfc_playlist = context; // open/alloc resources Storage* storage = furi_record_open(RECORD_STORAGE); Stream* stream = file_stream_alloc(storage); FuriString* line = furi_string_alloc(); - NfcPlaylistWorker* nfc_worker = nfc_playlist_worker_alloc(); + + popup_reset(nfc_playlist->popup); + popup_set_context(nfc_playlist->popup, nfc_playlist); + view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup); + // Read file if(file_stream_open(stream, APP_DATA_PATH("playlist.txt"), FSAM_READ, FSOM_OPEN_EXISTING)) { - popup_reset(nfc_playlist->popup); - popup_set_context(nfc_playlist->popup, nfc_playlist); + popup_set_header(nfc_playlist->popup, "Emulating:", 64, 10, AlignCenter, AlignTop); - view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup); int file_position = 0; // read the file line by line and print the text - while(stream_read_line(stream, line)) { + while(stream_read_line(stream, line) && cancel == false) { if (options_emulate_delay[nfc_playlist->emulate_delay] > 0) { if (file_position > 0) { start_error_blink(nfc_playlist); @@ -29,7 +89,7 @@ void nfc_playlist_emulation_scene_on_enter(void* context) { popup_set_text(nfc_playlist->popup, display_text, 64, 25, AlignCenter, AlignTop); furi_delay_ms(500); time_counter_delay_ms -= 500; - } while(time_counter_delay_ms > 0); + } while(time_counter_delay_ms > 0 && cancel == false); } else { file_position++; } @@ -64,36 +124,22 @@ void nfc_playlist_emulation_scene_on_enter(void* context) { popup_set_text(nfc_playlist->popup, popup_text, 64, 25, AlignCenter, AlignTop); furi_delay_ms(500); time_counter_ms -= 500; - } while(nfc_playlist_worker_is_emulating(nfc_worker) && time_counter_ms > 0); - nfc_playlist_worker_stop(nfc_worker); + } while(nfc_playlist_worker_is_emulating(nfc_playlist->nfc_playlist_worker) && time_counter_ms > 0 && cancel == false); + nfc_playlist_worker_stop(nfc_playlist->nfc_playlist_worker); } } popup_reset(nfc_playlist->popup); - scene_manager_previous_scene(nfc_playlist->scene_manager); + popup_set_header(nfc_playlist->popup, "Emulation finished", 64, 10, AlignCenter, AlignTop); + popup_set_text(nfc_playlist->popup, "Press back", 64, 25, AlignCenter, AlignTop); stop_blink(nfc_playlist); } else { - popup_reset(nfc_playlist->popup); - popup_set_context(nfc_playlist->popup, nfc_playlist); popup_set_header(nfc_playlist->popup, "Error:", 64, 10, AlignCenter, AlignTop); popup_set_text(nfc_playlist->popup, "Failed to open file\n/ext/apps_data/nfc_playlist/playlist.txt", 64, 25, AlignCenter, AlignTop); - view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup); } // Free/close resources furi_string_free(line); file_stream_close(stream); stream_free(stream); - nfc_playlist_worker_free(nfc_worker); - // Close storage - furi_record_close(RECORD_STORAGE); -} - -bool nfc_playlist_emulation_scene_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void nfc_playlist_emulation_scene_on_exit(void* context) { - NfcPlaylist* nfc_playlist = context; - popup_reset(nfc_playlist->popup); + // Close storage + return 0; } \ No newline at end of file diff --git a/scences/emulation.h b/scences/emulation.h index 872f6b29761..b1404f3592b 100644 --- a/scences/emulation.h +++ b/scences/emulation.h @@ -12,4 +12,10 @@ void nfc_playlist_emulation_scene_on_enter(void* context); bool nfc_playlist_emulation_scene_on_event(void* context, SceneManagerEvent event); -void nfc_playlist_emulation_scene_on_exit(void* context); \ No newline at end of file +void nfc_playlist_emulation_scene_on_exit(void* context); + +void nfc_playlist_emulation_setup(void* context); +void nfc_playlist_emulation_free(NfcPlaylist* nfc_playlist); +void nfc_playlist_emulation_start(NfcPlaylist* nfc_playlist); +void nfc_playlist_emulation_stop(NfcPlaylist* nfc_playlist); +int32_t nfc_playlist_emulation_task(void* context); \ No newline at end of file