Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #22

Merged
merged 6 commits into from
May 19, 2024
Merged

Dev #22

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ All the playlists should be placed in ext/apps_data/nfc_playlist and an example
```
An example file can be found in the repository
## How to build
This app was design, built and tested using the <a href="https://github.com/Flipper-XFW/Xtreme-Firmware">Xtreme firmware</a> so keep that in mind when building the FAP for yourself
This app was design, built and tested using the <a href="https://github.com/Next-Flip/Momentum-Firmware">Momentum</a> so keep that in mind when building the FAP for yourself
## Supported Firmwares
As i know these firmwares are supported and working if you know any more please let me know
- <a href="https://github.com/Flipper-XFW/Xtreme-Firmware">Xtreme</a>
Expand All @@ -20,6 +20,7 @@ As i know these firmwares are supported and working if you know any more please
- Emulate time (How long the NFC card will be emulated for)
- Delay time (How long the gap between the cards will be)
- LED indicator (Whether or not the LED's will be on)
- Skip errors (Makes it so you can make the emulation screen hide errors and skip delays between errors and emulation)
- Reset settings (Puts all the settings back to the defaults)
## Playlist editor:
- Create PLaylist (Creates a new playlist with the given name)
Expand Down
2 changes: 1 addition & 1 deletion application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ App(
fap_category="NFC",
fap_author="@acegoal07",
fap_weburl="https://github.com/acegoal07/FlipperZero_NFC_Playlist/tree/main",
fap_version="1.7",
fap_version="1.8",
fap_icon="assets/icon.png",
fap_private_libs=[
Lib(
Expand Down
1 change: 1 addition & 0 deletions nfc_playlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static NfcPlaylist* nfc_playlist_alloc() {
nfc_playlist->settings.emulate_timeout = default_emulate_timeout;
nfc_playlist->settings.emulate_delay = default_emulate_delay;
nfc_playlist->settings.emulate_led_indicator = default_emulate_led_indicator;
nfc_playlist->settings.skip_error = default_skip_error;

nfc_playlist->notification = furi_record_open(RECORD_NOTIFICATION);
nfc_playlist->file_browser = file_browser_alloc(nfc_playlist->file_browser_output);
Expand Down
6 changes: 5 additions & 1 deletion nfc_playlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ typedef enum {
NfcPlaylistView_VariableItemList,
NfcPlaylistView_FileBrowser,
NfcPlaylistView_TextInput
} NfcPlaylistView;
} NfcPlaylistViews;

typedef struct {
FuriString* file_path;
bool playlist_selected;
uint8_t emulate_timeout;
uint8_t emulate_delay;
bool emulate_led_indicator;
bool skip_error;
} NfcPlaylistSettings;

typedef struct {
Expand All @@ -58,6 +59,7 @@ typedef struct {
char* text_input_output;
NotificationApp* notification;
FuriThread* thread;
FuriString* temp_furi_string;
NfcPlaylistWorker* nfc_playlist_worker;
NfcPlaylistSettings settings;
} NfcPlaylist;
Expand All @@ -67,9 +69,11 @@ static const int default_emulate_timeout = 4;
static const int options_emulate_delay[] = {0, 1, 2, 3, 4, 5, 6};
static const int default_emulate_delay = 0;
static const bool default_emulate_led_indicator = true;
static const bool default_skip_error = false;

#define PLAYLIST_LOCATION "/ext/apps_data/nfc_playlist/"
#define PLAYLIST_DIR "/ext/apps_data/nfc_playlist"
#define PLAYLIST_VIEW_MAX_SIZE 1000

typedef enum NfcPlaylistLedState {
NfcPlaylistLedState_Normal,
Expand Down
41 changes: 25 additions & 16 deletions scenes/nfc_playlist_scene_emulation.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ int32_t nfc_playlist_emulation_task(void* context) {

Storage* storage = furi_record_open(RECORD_STORAGE);
Stream* stream = file_stream_alloc(storage);
bool skip_delay = false;

popup_reset(nfc_playlist->popup);
popup_set_context(nfc_playlist->popup, nfc_playlist);

view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup);

if (file_stream_open(stream, furi_string_get_cstr(nfc_playlist->settings.file_path), FSAM_READ, FSOM_OPEN_EXISTING)) {
Expand All @@ -31,19 +32,20 @@ int32_t nfc_playlist_emulation_task(void* context) {

char* file_path = (char*)furi_string_get_cstr(line);

if(strlen(file_path) <= 1) {continue;}
if (strlen(file_path) <= 1) {continue;}

if(nfc_playlist->settings.emulate_delay > 0 && file_position != 0) {
if (nfc_playlist->settings.emulate_delay > 0 && file_position != 0 && !skip_delay) {
popup_set_header(nfc_playlist->popup, "Delaying", 64, 10, AlignCenter, AlignTop);
start_blink(nfc_playlist, NfcPlaylistLedState_Error);
int time_counter_delay_ms = (options_emulate_delay[nfc_playlist->settings.emulate_delay]*1000);
do {
while(time_counter_delay_ms > 0 && EmulationState == NfcPlaylistEmulationState_Emulating) {
furi_string_printf(tmp_counter_str, "%ds", (time_counter_delay_ms/1000));
popup_set_text(nfc_playlist->popup, furi_string_get_cstr(tmp_counter_str), 64, 50, AlignCenter, AlignTop);
furi_delay_ms(50);
time_counter_delay_ms -= 50;
} while(time_counter_delay_ms > 0 && EmulationState == NfcPlaylistEmulationState_Emulating);
};
} else if (nfc_playlist->settings.emulate_delay > 0) {
skip_delay = false;
file_position++;
}

Expand All @@ -53,38 +55,46 @@ int32_t nfc_playlist_emulation_task(void* context) {
char const* file_ext = &strrchr(file_path, '.')[1];
int time_counter_ms = (options_emulate_timeout[nfc_playlist->settings.emulate_timeout]*1000);

if(storage_file_exists(storage, file_path) == false) {
furi_string_printf(tmp_header_str, "ERROR not found:\n%s", file_name);
if(!strcasestr(file_ext, "nfc")) {
if(nfc_playlist->settings.skip_error) {
skip_delay = true;
continue;
}
furi_string_printf(tmp_header_str, "ERROR invalid file:\n%s", file_name);
popup_set_header(nfc_playlist->popup, furi_string_get_cstr(tmp_header_str), 64, 10, AlignCenter, AlignTop);
start_blink(nfc_playlist, NfcPlaylistLedState_Error);
do {
while(time_counter_ms > 0 && EmulationState == NfcPlaylistEmulationState_Emulating) {
furi_string_printf(tmp_counter_str, "%ds", (time_counter_ms/1000));
popup_set_text(nfc_playlist->popup, furi_string_get_cstr(tmp_counter_str), 64, 50, AlignCenter, AlignTop);
furi_delay_ms(50);
time_counter_ms -= 50;
} while(time_counter_ms > 0 && EmulationState == NfcPlaylistEmulationState_Emulating);
} else if (strcasestr(file_ext, "nfc") == NULL) {
furi_string_printf(tmp_header_str, "ERROR invalid file:\n%s", file_name);
};
} else if(!storage_file_exists(storage, file_path)) {
if(nfc_playlist->settings.skip_error) {
skip_delay = true;
continue;
}
furi_string_printf(tmp_header_str, "ERROR not found:\n%s", file_name);
popup_set_header(nfc_playlist->popup, furi_string_get_cstr(tmp_header_str), 64, 10, AlignCenter, AlignTop);
start_blink(nfc_playlist, NfcPlaylistLedState_Error);
do {
while(time_counter_ms > 0 && EmulationState == NfcPlaylistEmulationState_Emulating) {
furi_string_printf(tmp_counter_str, "%ds", (time_counter_ms/1000));
popup_set_text(nfc_playlist->popup, furi_string_get_cstr(tmp_counter_str), 64, 50, AlignCenter, AlignTop);
furi_delay_ms(50);
time_counter_ms -= 50;
} while(time_counter_ms > 0 && EmulationState == NfcPlaylistEmulationState_Emulating);
};
} else {
furi_string_printf(tmp_header_str, "Emulating:\n%s", file_name);
popup_set_header(nfc_playlist->popup, furi_string_get_cstr(tmp_header_str), 64, 10, AlignCenter, AlignTop);
nfc_playlist_worker_set_nfc_data(nfc_playlist->nfc_playlist_worker, file_path);
nfc_playlist_worker_start(nfc_playlist->nfc_playlist_worker);
start_blink(nfc_playlist, NfcPlaylistLedState_Normal);
do {
while(nfc_playlist_worker_is_emulating(nfc_playlist->nfc_playlist_worker) && time_counter_ms > 0 && EmulationState == NfcPlaylistEmulationState_Emulating) {
furi_string_printf(tmp_counter_str, "%ds", (time_counter_ms/1000));
popup_set_text(nfc_playlist->popup, furi_string_get_cstr(tmp_counter_str), 64, 50, AlignCenter, AlignTop);
furi_delay_ms(50);
time_counter_ms -= 50;
} while(nfc_playlist_worker_is_emulating(nfc_playlist->nfc_playlist_worker) && time_counter_ms > 0 && EmulationState == NfcPlaylistEmulationState_Emulating);
};
nfc_playlist_worker_stop(nfc_playlist->nfc_playlist_worker);
nfc_playlist_worker_clear_nfc_data(nfc_playlist->nfc_playlist_worker);
}
Expand All @@ -98,7 +108,6 @@ int32_t nfc_playlist_emulation_task(void* context) {
furi_string_free(line);
furi_string_free(tmp_header_str);
furi_string_free(tmp_counter_str);

} else {
popup_set_header(nfc_playlist->popup, "Failed to open playlist", 64, 10, AlignCenter, AlignTop);
popup_set_text(nfc_playlist->popup, "Press back", 64, 50, AlignCenter, AlignTop);
Expand Down
18 changes: 12 additions & 6 deletions scenes/nfc_playlist_scene_file_rename.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
void nfc_playlist_file_rename_menu_callback(void* context) {
NfcPlaylist* nfc_playlist = context;
Storage* storage = furi_record_open(RECORD_STORAGE);
FuriString* tmp_old_file_path = furi_string_alloc();
FuriString* tmp_new_file_path = furi_string_alloc();

char const* old_file_path = (char*)furi_string_get_cstr(nfc_playlist->settings.file_path);
char const* old_file_name = strchr(old_file_path, '/') != NULL ? &strrchr(old_file_path, '/')[1] : old_file_path;

furi_string_printf(tmp_old_file_path, "%s", old_file_path);
FuriString* tmp_old_file_path = furi_string_alloc_set_str(old_file_path);
furi_string_replace(tmp_old_file_path, old_file_name, "");

FuriString* tmp_new_file_path = furi_string_alloc();
furi_string_printf(tmp_new_file_path, "%s%s.txt", furi_string_get_cstr(tmp_old_file_path), nfc_playlist->text_input_output);

if(!storage_file_exists(storage, furi_string_get_cstr(tmp_new_file_path))) {
Expand All @@ -27,11 +26,18 @@ void nfc_playlist_file_rename_menu_callback(void* context) {

void nfc_playlist_file_rename_scene_on_enter(void* context) {
NfcPlaylist* nfc_playlist = context;
nfc_playlist->text_input_output = (char*)malloc(50);

char const* tmp_file_path = (char*)furi_string_get_cstr(nfc_playlist->settings.file_path);
char const* tmp_file_name = strchr(tmp_file_path, '/') != NULL ? &strrchr(tmp_file_path, '/')[1] : tmp_file_path;

FuriString* tmp_file_name_furi = furi_string_alloc_set_str(tmp_file_name);
furi_string_replace(tmp_file_name_furi, ".txt", "");

nfc_playlist->text_input_output = (char*)furi_string_get_cstr(tmp_file_name_furi);
text_input_set_header_text(nfc_playlist->text_input, "Enter new file name");
text_input_set_minimum_length(nfc_playlist->text_input, 1);
text_input_set_result_callback(nfc_playlist->text_input, nfc_playlist_file_rename_menu_callback, nfc_playlist, nfc_playlist->text_input_output, 50, true);
text_input_set_result_callback(nfc_playlist->text_input, nfc_playlist_file_rename_menu_callback, nfc_playlist, nfc_playlist->text_input_output, 50, false);

view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_TextInput);
}

Expand Down
2 changes: 1 addition & 1 deletion scenes/nfc_playlist_scene_main_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void nfc_playlist_main_menu_scene_on_enter(void* context) {
NfcPlaylistMenuSelection_Settings,
nfc_playlist_main_menu_menu_callback,
nfc_playlist);

view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Submenu);
}

Expand Down
4 changes: 2 additions & 2 deletions scenes/nfc_playlist_scene_name_new_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void nfc_playlist_name_new_file_menu_callback(void* context) {
storage_file_close(file);
furi_string_swap(nfc_playlist->settings.file_path, file_name);
}

storage_file_free(file);
furi_string_free(file_name);
furi_record_close(RECORD_STORAGE);
Expand All @@ -25,7 +25,7 @@ void nfc_playlist_name_new_file_scene_on_enter(void* context) {
text_input_set_header_text(nfc_playlist->text_input, "Enter file name");
text_input_set_minimum_length(nfc_playlist->text_input, 1);
text_input_set_result_callback(nfc_playlist->text_input, nfc_playlist_name_new_file_menu_callback, nfc_playlist, nfc_playlist->text_input_output, 50, true);

view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_TextInput);
}

Expand Down
12 changes: 5 additions & 7 deletions scenes/nfc_playlist_scene_nfc_select.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
#include "../nfc_playlist.h"

#define MAX_PLAYLIST_SIZE 1000

void nfc_playlist_nfc_select_menu_callback(void* context) {
NfcPlaylist* nfc_playlist = context;

Storage* storage = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(storage);

if (storage_file_open(file, furi_string_get_cstr(nfc_playlist->settings.file_path), FSAM_READ_WRITE, FSOM_OPEN_EXISTING)) {
uint8_t buffer[MAX_PLAYLIST_SIZE];
uint16_t read_count = storage_file_read(file, buffer, MAX_PLAYLIST_SIZE);
uint8_t buffer[PLAYLIST_VIEW_MAX_SIZE];
uint16_t read_count = storage_file_read(file, buffer, PLAYLIST_VIEW_MAX_SIZE);
FuriString* playlist_content = furi_string_alloc();

for(uint16_t i = 0; i < read_count; i++) {
Expand All @@ -32,7 +30,7 @@ void nfc_playlist_nfc_select_menu_callback(void* context) {
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
furi_string_reset(nfc_playlist->file_browser_output);

scene_manager_previous_scene(nfc_playlist->scene_manager);
}

Expand All @@ -50,7 +48,7 @@ void nfc_playlist_nfc_select_scene_on_enter(void* context) {
FuriString* tmp_str = furi_string_alloc_set_str("/ext/nfc/");
file_browser_start(nfc_playlist->file_browser, tmp_str);
furi_string_free(tmp_str);

view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_FileBrowser);
}

Expand Down
4 changes: 2 additions & 2 deletions scenes/nfc_playlist_scene_playlist_select.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ void nfc_playlist_playlist_select_scene_on_enter(void* context) {
PLAYLIST_LOCATION,
true,
true,
&I_Nfc_10px,
&I_unknown_10px,
true);
file_browser_set_callback(nfc_playlist->file_browser, nfc_playlist_playlist_select_menu_callback, nfc_playlist);
FuriString* tmp_str = furi_string_alloc_set_str(PLAYLIST_LOCATION);
file_browser_start(nfc_playlist->file_browser, tmp_str);
furi_string_free(tmp_str);

view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_FileBrowser);
}

Expand Down
Loading