diff --git a/applications/external b/applications/external index 9ac0d425e..dfd6c1585 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 9ac0d425ed9517d609d2ed09f36389ee2fa83839 +Subproject commit dfd6c1585d195d26550771ca320807356a5015bb diff --git a/applications/main/archive/helpers/archive_files.c b/applications/main/archive/helpers/archive_files.c index 3406ceea9..71aae893d 100644 --- a/applications/main/archive/helpers/archive_files.c +++ b/applications/main/archive/helpers/archive_files.c @@ -1,9 +1,9 @@ #include "archive_files.h" #include "archive_apps.h" #include "archive_browser.h" -#include -#include -#include +#include +#include +#include #define TAG "Archive" diff --git a/applications/system/hex_viewer/LICENSE b/applications/system/hex_viewer/LICENSE deleted file mode 100644 index 69004dc62..000000000 --- a/applications/system/hex_viewer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Roman Shchekin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/applications/system/hex_viewer/application.fam b/applications/system/hex_viewer/application.fam deleted file mode 100644 index c67fe12c5..000000000 --- a/applications/system/hex_viewer/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="hex_viewer", - name="HEX Viewer", - apptype=FlipperAppType.EXTERNAL, - entry_point="hex_viewer_app", - requires=[ - "gui", - "dialogs", - ], - stack_size=2 * 1024, - fap_icon="icons/hex_10px.bmp", - fap_icon_assets="icons", - fap_category="Tools", - fap_author="@QtRoS", - fap_version="2.0", - fap_description="App allows to view various files as HEX", -) diff --git a/applications/system/hex_viewer/helpers/hex_viewer_custom_event.h b/applications/system/hex_viewer/helpers/hex_viewer_custom_event.h deleted file mode 100644 index f6dde56e6..000000000 --- a/applications/system/hex_viewer/helpers/hex_viewer_custom_event.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -typedef enum { - HexViewerCustomEventStartscreenUp, - HexViewerCustomEventStartscreenDown, - HexViewerCustomEventStartscreenLeft, - HexViewerCustomEventStartscreenRight, - HexViewerCustomEventStartscreenOk, - HexViewerCustomEventStartscreenBack, - HexViewerCustomEventScene1Up, - HexViewerCustomEventScene1Down, - HexViewerCustomEventScene1Left, - HexViewerCustomEventScene1Right, - HexViewerCustomEventScene1Ok, - HexViewerCustomEventScene1Back, - HexViewerCustomEventScene2Up, - HexViewerCustomEventScene2Down, - HexViewerCustomEventScene2Left, - HexViewerCustomEventScene2Right, - HexViewerCustomEventScene2Ok, - HexViewerCustomEventScene2Back, -} HexViewerCustomEvent; - -enum HexViewerCustomEventType { - // Reserve first 100 events for button types and indexes, starting from 0 - HexViewerCustomEventMenuVoid, - HexViewerCustomEventMenuSelected, - HexViewerCustomEventMenuPercentEntered, -}; - -#pragma pack(push, 1) -typedef union { - uint32_t packed_value; - struct { - uint16_t type; - int16_t value; - } content; -} HexViewerCustomEventMenu; -#pragma pack(pop) - -static inline uint32_t hex_viewer_custom_menu_event_pack(uint16_t type, int16_t value) { - HexViewerCustomEventMenu event = {.content = {.type = type, .value = value}}; - return event.packed_value; -} -static inline void - hex_viewer_custom_menu_event_unpack(uint32_t packed_value, uint16_t* type, int16_t* value) { - HexViewerCustomEventMenu event = {.packed_value = packed_value}; - if(type) *type = event.content.type; - if(value) *value = event.content.value; -} - -static inline uint16_t hex_viewer_custom_menu_event_get_type(uint32_t packed_value) { - uint16_t type; - hex_viewer_custom_menu_event_unpack(packed_value, &type, NULL); - return type; -} - -static inline int16_t hex_viewer_custom_menu_event_get_value(uint32_t packed_value) { - int16_t value; - hex_viewer_custom_menu_event_unpack(packed_value, NULL, &value); - return value; -} \ No newline at end of file diff --git a/applications/system/hex_viewer/helpers/hex_viewer_haptic.c b/applications/system/hex_viewer/helpers/hex_viewer_haptic.c deleted file mode 100644 index b3d230468..000000000 --- a/applications/system/hex_viewer/helpers/hex_viewer_haptic.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "hex_viewer_haptic.h" -#include "../hex_viewer.h" - -void hex_viewer_play_happy_bump(void* context) { - HexViewer* app = context; - if(app->haptic != 1) { - return; - } - notification_message(app->notification, &sequence_set_vibro_on); - furi_thread_flags_wait(0, FuriFlagWaitAny, 20); - notification_message(app->notification, &sequence_reset_vibro); -} - -void hex_viewer_play_bad_bump(void* context) { - HexViewer* app = context; - if(app->haptic != 1) { - return; - } - notification_message(app->notification, &sequence_set_vibro_on); - furi_thread_flags_wait(0, FuriFlagWaitAny, 100); - notification_message(app->notification, &sequence_reset_vibro); -} - -void hex_viewer_play_long_bump(void* context) { - HexViewer* app = context; - if(app->haptic != 1) { - return; - } - for(int i = 0; i < 4; i++) { - notification_message(app->notification, &sequence_set_vibro_on); - furi_thread_flags_wait(0, FuriFlagWaitAny, 50); - notification_message(app->notification, &sequence_reset_vibro); - furi_thread_flags_wait(0, FuriFlagWaitAny, 100); - } -} diff --git a/applications/system/hex_viewer/helpers/hex_viewer_haptic.h b/applications/system/hex_viewer/helpers/hex_viewer_haptic.h deleted file mode 100644 index ade33bc78..000000000 --- a/applications/system/hex_viewer/helpers/hex_viewer_haptic.h +++ /dev/null @@ -1,7 +0,0 @@ -#include - -void hex_viewer_play_happy_bump(void* context); - -void hex_viewer_play_bad_bump(void* context); - -void hex_viewer_play_long_bump(void* context); diff --git a/applications/system/hex_viewer/helpers/hex_viewer_led.c b/applications/system/hex_viewer/helpers/hex_viewer_led.c deleted file mode 100644 index d52fa5622..000000000 --- a/applications/system/hex_viewer/helpers/hex_viewer_led.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "hex_viewer_led.h" -#include "../hex_viewer.h" - -void hex_viewer_led_set_rgb(void* context, int red, int green, int blue) { - HexViewer* app = context; - if(app->led != 1) { - return; - } - NotificationMessage notification_led_message_1; - notification_led_message_1.type = NotificationMessageTypeLedRed; - NotificationMessage notification_led_message_2; - notification_led_message_2.type = NotificationMessageTypeLedGreen; - NotificationMessage notification_led_message_3; - notification_led_message_3.type = NotificationMessageTypeLedBlue; - - notification_led_message_1.data.led.value = red; - notification_led_message_2.data.led.value = green; - notification_led_message_3.data.led.value = blue; - const NotificationSequence notification_sequence = { - ¬ification_led_message_1, - ¬ification_led_message_2, - ¬ification_led_message_3, - &message_do_not_reset, - NULL, - }; - notification_message(app->notification, ¬ification_sequence); - furi_thread_flags_wait( - 0, FuriFlagWaitAny, 10); //Delay, prevent removal from RAM before LED value set -} - -void hex_viewer_led_reset(void* context) { - HexViewer* app = context; - notification_message(app->notification, &sequence_reset_red); - notification_message(app->notification, &sequence_reset_green); - notification_message(app->notification, &sequence_reset_blue); - - furi_thread_flags_wait( - 0, FuriFlagWaitAny, 300); //Delay, prevent removal from RAM before LED value set -} diff --git a/applications/system/hex_viewer/helpers/hex_viewer_led.h b/applications/system/hex_viewer/helpers/hex_viewer_led.h deleted file mode 100644 index ba0e1cdad..000000000 --- a/applications/system/hex_viewer/helpers/hex_viewer_led.h +++ /dev/null @@ -1,5 +0,0 @@ - - -void hex_viewer_led_set_rgb(void* context, int red, int green, int blue); - -void hex_viewer_led_reset(void* context); diff --git a/applications/system/hex_viewer/helpers/hex_viewer_speaker.c b/applications/system/hex_viewer/helpers/hex_viewer_speaker.c deleted file mode 100644 index 4ee3de8dc..000000000 --- a/applications/system/hex_viewer/helpers/hex_viewer_speaker.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "hex_viewer_speaker.h" -#include "../hex_viewer.h" - -#define NOTE_INPUT 587.33f - -void hex_viewer_play_input_sound(void* context) { - HexViewer* app = context; - if(app->speaker != 1) { - return; - } - float volume = 1.0f; - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { - furi_hal_speaker_start(NOTE_INPUT, volume); - } -} - -void hex_viewer_stop_all_sound(void* context) { - HexViewer* app = context; - if(app->speaker != 1) { - return; - } - if(furi_hal_speaker_is_mine()) { - furi_hal_speaker_stop(); - furi_hal_speaker_release(); - } -} diff --git a/applications/system/hex_viewer/helpers/hex_viewer_speaker.h b/applications/system/hex_viewer/helpers/hex_viewer_speaker.h deleted file mode 100644 index 747d79146..000000000 --- a/applications/system/hex_viewer/helpers/hex_viewer_speaker.h +++ /dev/null @@ -1,4 +0,0 @@ -#define NOTE_INPUT 587.33f - -void hex_viewer_play_input_sound(void* context); -void hex_viewer_stop_all_sound(void* context); diff --git a/applications/system/hex_viewer/helpers/hex_viewer_storage.c b/applications/system/hex_viewer/helpers/hex_viewer_storage.c deleted file mode 100644 index 0b795bc5f..000000000 --- a/applications/system/hex_viewer/helpers/hex_viewer_storage.c +++ /dev/null @@ -1,173 +0,0 @@ -#include "hex_viewer_storage.h" - -static Storage* hex_viewer_open_storage() { - return furi_record_open(RECORD_STORAGE); -} - -static void hex_viewer_close_storage() { - furi_record_close(RECORD_STORAGE); -} - -static void hex_viewer_close_config_file(FlipperFormat* file) { - if(file == NULL) return; - flipper_format_file_close(file); - flipper_format_free(file); -} - -void hex_viewer_save_settings(void* context) { - HexViewer* app = context; - if(app->save_settings == 0) { - return; - } - - FURI_LOG_D(TAG, "Saving Settings"); - Storage* storage = hex_viewer_open_storage(); - FlipperFormat* fff_file = flipper_format_file_alloc(storage); - - // Overwrite wont work, so delete first - if(storage_file_exists(storage, HEX_VIEWER_SETTINGS_SAVE_PATH)) { - storage_simply_remove(storage, HEX_VIEWER_SETTINGS_SAVE_PATH); - } - - // Open File, create if not exists - if(!storage_common_stat(storage, HEX_VIEWER_SETTINGS_SAVE_PATH, NULL) == FSE_OK) { - FURI_LOG_D( - TAG, "Config file %s is not found. Will create new.", HEX_VIEWER_SETTINGS_SAVE_PATH); - if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) { - FURI_LOG_D( - TAG, "Directory %s doesn't exist. Will create new.", CONFIG_FILE_DIRECTORY_PATH); - if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) { - FURI_LOG_E(TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH); - } - } - } - - if(!flipper_format_file_open_new(fff_file, HEX_VIEWER_SETTINGS_SAVE_PATH)) { - //totp_close_config_file(fff_file); - FURI_LOG_E(TAG, "Error creating new file %s", HEX_VIEWER_SETTINGS_SAVE_PATH); - hex_viewer_close_storage(); - return; - } - - // Store Settings - flipper_format_write_header_cstr( - fff_file, HEX_VIEWER_SETTINGS_HEADER, HEX_VIEWER_SETTINGS_FILE_VERSION); - flipper_format_write_uint32(fff_file, HEX_VIEWER_SETTINGS_KEY_HAPTIC, &app->haptic, 1); - flipper_format_write_uint32(fff_file, HEX_VIEWER_SETTINGS_KEY_SPEAKER, &app->speaker, 1); - flipper_format_write_uint32(fff_file, HEX_VIEWER_SETTINGS_KEY_LED, &app->led, 1); - flipper_format_write_uint32( - fff_file, HEX_VIEWER_SETTINGS_KEY_SAVE_SETTINGS, &app->save_settings, 1); - - if(!flipper_format_rewind(fff_file)) { - hex_viewer_close_config_file(fff_file); - FURI_LOG_E(TAG, "Rewind error"); - hex_viewer_close_storage(); - return; - } - - hex_viewer_close_config_file(fff_file); - hex_viewer_close_storage(); -} - -void hex_viewer_read_settings(void* context) { - HexViewer* app = context; - Storage* storage = hex_viewer_open_storage(); - FlipperFormat* fff_file = flipper_format_file_alloc(storage); - - if(storage_common_stat(storage, HEX_VIEWER_SETTINGS_SAVE_PATH, NULL) != FSE_OK) { - hex_viewer_close_config_file(fff_file); - hex_viewer_close_storage(); - return; - } - uint32_t file_version; - FuriString* temp_str = furi_string_alloc(); - - if(!flipper_format_file_open_existing(fff_file, HEX_VIEWER_SETTINGS_SAVE_PATH)) { - FURI_LOG_E(TAG, "Cannot open file %s", HEX_VIEWER_SETTINGS_SAVE_PATH); - hex_viewer_close_config_file(fff_file); - hex_viewer_close_storage(); - return; - } - - if(!flipper_format_read_header(fff_file, temp_str, &file_version)) { - FURI_LOG_E(TAG, "Missing Header Data"); - hex_viewer_close_config_file(fff_file); - hex_viewer_close_storage(); - furi_string_free(temp_str); - return; - } - furi_string_free(temp_str); - - if(file_version < HEX_VIEWER_SETTINGS_FILE_VERSION) { - FURI_LOG_I(TAG, "old config version, will be removed."); - hex_viewer_close_config_file(fff_file); - hex_viewer_close_storage(); - return; - } - - flipper_format_read_uint32(fff_file, HEX_VIEWER_SETTINGS_KEY_HAPTIC, &app->haptic, 1); - flipper_format_read_uint32(fff_file, HEX_VIEWER_SETTINGS_KEY_SPEAKER, &app->speaker, 1); - flipper_format_read_uint32(fff_file, HEX_VIEWER_SETTINGS_KEY_LED, &app->led, 1); - flipper_format_read_uint32( - fff_file, HEX_VIEWER_SETTINGS_KEY_SAVE_SETTINGS, &app->save_settings, 1); - - flipper_format_rewind(fff_file); - - hex_viewer_close_config_file(fff_file); - hex_viewer_close_storage(); -} - -bool hex_viewer_open_file(void* context, const char* file_path) { - HexViewer* hex_viewer = context; - furi_assert(hex_viewer); - furi_assert(file_path); - - // TODO Separate function? - if(hex_viewer->model->stream) { - buffered_file_stream_close(hex_viewer->model->stream); - stream_free(hex_viewer->model->stream); - hex_viewer->model->file_offset = 0; - } - - hex_viewer->model->stream = buffered_file_stream_alloc(hex_viewer->storage); - bool isOk = true; - - do { - if(!buffered_file_stream_open( - hex_viewer->model->stream, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) { - FURI_LOG_E(TAG, "Unable to open stream: %s", file_path); - isOk = false; - break; - }; - - hex_viewer->model->file_size = stream_size(hex_viewer->model->stream); - } while(false); - - return isOk; -} - -bool hex_viewer_read_file(void* context) { - HexViewer* hex_viewer = context; - furi_assert(hex_viewer); - furi_assert(hex_viewer->model->stream); - furi_assert(hex_viewer->model->file_offset % HEX_VIEWER_BYTES_PER_LINE == 0); - - memset(hex_viewer->model->file_bytes, 0x0, HEX_VIEWER_BUF_SIZE); - bool isOk = true; - - do { - uint32_t offset = hex_viewer->model->file_offset; - if(!stream_seek(hex_viewer->model->stream, offset, true)) { - FURI_LOG_E(TAG, "Unable to seek stream"); - isOk = false; - break; - } - - hex_viewer->model->file_read_bytes = stream_read( - hex_viewer->model->stream, - (uint8_t*)hex_viewer->model->file_bytes, - HEX_VIEWER_BUF_SIZE); - } while(false); - - return isOk; -} \ No newline at end of file diff --git a/applications/system/hex_viewer/helpers/hex_viewer_storage.h b/applications/system/hex_viewer/helpers/hex_viewer_storage.h deleted file mode 100644 index cd0c5277b..000000000 --- a/applications/system/hex_viewer/helpers/hex_viewer_storage.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "../hex_viewer.h" - -#define HEX_VIEWER_SETTINGS_FILE_VERSION 1 -#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("apps_data/hex_viewer") -#define HEX_VIEWER_SETTINGS_SAVE_PATH CONFIG_FILE_DIRECTORY_PATH "/hex_viewer.conf" -#define HEX_VIEWER_SETTINGS_SAVE_PATH_TMP HEX_VIEWER_SETTINGS_SAVE_PATH ".tmp" -#define HEX_VIEWER_SETTINGS_HEADER "HexViewer Config File" -#define HEX_VIEWER_SETTINGS_KEY_HAPTIC "Haptic" -#define HEX_VIEWER_SETTINGS_KEY_LED "Led" -#define HEX_VIEWER_SETTINGS_KEY_SPEAKER "Speaker" -#define HEX_VIEWER_SETTINGS_KEY_SAVE_SETTINGS "SaveSettings" - -void hex_viewer_save_settings(void* context); -void hex_viewer_read_settings(void* context); - -bool hex_viewer_open_file(void* context, const char* file_path); -bool hex_viewer_read_file(void* context); \ No newline at end of file diff --git a/applications/system/hex_viewer/hex_viewer.c b/applications/system/hex_viewer/hex_viewer.c deleted file mode 100644 index 916ed9f7c..000000000 --- a/applications/system/hex_viewer/hex_viewer.c +++ /dev/null @@ -1,149 +0,0 @@ -#include "hex_viewer.h" - -bool hex_viewer_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - HexViewer* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -void hex_viewer_tick_event_callback(void* context) { - furi_assert(context); - HexViewer* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -//leave app if back button pressed -bool hex_viewer_navigation_event_callback(void* context) { - furi_assert(context); - HexViewer* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -HexViewer* hex_viewer_app_alloc() { - HexViewer* app = malloc(sizeof(HexViewer)); - - app->model = malloc(sizeof(HexViewerModel)); - memset(app->model, 0, sizeof(HexViewerModel)); - - app->gui = furi_record_open(RECORD_GUI); - app->storage = furi_record_open(RECORD_STORAGE); - app->notification = furi_record_open(RECORD_NOTIFICATION); - - //Turn backlight on, believe me this makes testing your app easier - notification_message(app->notification, &sequence_display_backlight_on); - - //Scene additions - app->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_enable_queue(app->view_dispatcher); - - app->scene_manager = scene_manager_alloc(&hex_viewer_scene_handlers, app); - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, hex_viewer_navigation_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, hex_viewer_tick_event_callback, 100); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, hex_viewer_custom_event_callback); - - // Set defaults, in case no config loaded - app->haptic = 1; - app->speaker = 1; - app->led = 1; - app->save_settings = 1; - - // Used for File Browser - app->dialogs = furi_record_open(RECORD_DIALOGS); - app->file_path = furi_string_alloc(); - - // Load configs - hex_viewer_read_settings(app); - - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, HexViewerViewIdMenu, submenu_get_view(app->submenu)); - - app->hex_viewer_startscreen = hex_viewer_startscreen_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - HexViewerViewIdStartscreen, - hex_viewer_startscreen_get_view(app->hex_viewer_startscreen)); - - app->text_input = text_input_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, HexViewerViewIdScroll, text_input_get_view(app->text_input)); - - app->variable_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - HexViewerViewIdSettings, - variable_item_list_get_view(app->variable_item_list)); - - //End Scene Additions - - return app; -} - -void hex_viewer_app_free(HexViewer* app) { - furi_assert(app); - - if(app->model->stream) { - buffered_file_stream_close(app->model->stream); - stream_free(app->model->stream); - } - - // Scene manager - scene_manager_free(app->scene_manager); - - // View Dispatcher - view_dispatcher_remove_view(app->view_dispatcher, HexViewerViewIdMenu); - submenu_free(app->submenu); - view_dispatcher_remove_view(app->view_dispatcher, HexViewerViewIdStartscreen); - hex_viewer_startscreen_free(app->hex_viewer_startscreen); - view_dispatcher_remove_view(app->view_dispatcher, HexViewerViewIdScroll); - text_input_free(app->text_input); - view_dispatcher_remove_view(app->view_dispatcher, HexViewerViewIdSettings); - variable_item_list_free(app->variable_item_list); - - view_dispatcher_free(app->view_dispatcher); - furi_record_close(RECORD_STORAGE); - furi_record_close(RECORD_GUI); - - app->storage = NULL; - app->gui = NULL; - app->notification = NULL; - - // Close File Browser - furi_record_close(RECORD_DIALOGS); - furi_string_free(app->file_path); - - free(app->model); - - //Remove whatever is left - free(app); -} - -int32_t hex_viewer_app(void* p) { - UNUSED(p); - HexViewer* app = hex_viewer_app_alloc(); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - if(p && strlen(p) && hex_viewer_open_file(app, (const char*)p)) { - hex_viewer_read_file(app); - scene_manager_next_scene(app->scene_manager, HexViewerSceneStartscreen); - } else { - scene_manager_next_scene(app->scene_manager, HexViewerSceneStartscreen); - scene_manager_next_scene(app->scene_manager, HexViewerSceneOpen); - } - - furi_hal_power_suppress_charge_enter(); - - view_dispatcher_run(app->view_dispatcher); - - hex_viewer_save_settings(app); - - furi_hal_power_suppress_charge_exit(); - hex_viewer_app_free(app); - - return 0; -} diff --git a/applications/system/hex_viewer/hex_viewer.h b/applications/system/hex_viewer/hex_viewer.h deleted file mode 100644 index c8b98926f..000000000 --- a/applications/system/hex_viewer/hex_viewer.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "scenes/hex_viewer_scene.h" -#include "views/hex_viewer_startscreen.h" -#include "helpers/hex_viewer_storage.h" - -#include -#include -#include -#include - -#define TAG "HexViewer" - -#define HEX_VIEWER_APP_PATH_FOLDER "/any" // TODO ANY_PATH -#define HEX_VIEWER_APP_EXTENSION "*" -#define HEX_VIEWER_PERCENT_INPUT 16 - -#define HEX_VIEWER_BYTES_PER_LINE 4u -#define HEX_VIEWER_LINES_ON_SCREEN 4u -#define HEX_VIEWER_BUF_SIZE (HEX_VIEWER_LINES_ON_SCREEN * HEX_VIEWER_BYTES_PER_LINE) - -typedef struct { - uint8_t file_bytes[HEX_VIEWER_LINES_ON_SCREEN][HEX_VIEWER_BYTES_PER_LINE]; - uint32_t file_offset; - uint32_t file_read_bytes; - uint32_t file_size; - - Stream* stream; -} HexViewerModel; - -typedef struct { - HexViewerModel* model; - - Gui* gui; - Storage* storage; - NotificationApp* notification; - ViewDispatcher* view_dispatcher; - Submenu* submenu; - TextInput* text_input; - SceneManager* scene_manager; - VariableItemList* variable_item_list; - HexViewerStartscreen* hex_viewer_startscreen; - DialogsApp* dialogs; // File Browser - FuriString* file_path; // File Browser - uint32_t haptic; - uint32_t speaker; - uint32_t led; - uint32_t save_settings; - char percent_buf[HEX_VIEWER_PERCENT_INPUT]; -} HexViewer; - -typedef enum { - HexViewerViewIdStartscreen, - HexViewerViewIdMenu, - HexViewerViewIdScroll, - HexViewerViewIdSettings, -} HexViewerViewId; - -typedef enum { - HexViewerHapticOff, - HexViewerHapticOn, -} HexViewerHapticState; - -typedef enum { - HexViewerSpeakerOff, - HexViewerSpeakerOn, -} HexViewerSpeakerState; - -typedef enum { - HexViewerLedOff, - HexViewerLedOn, -} HexViewerLedState; - -typedef enum { - HexViewerSettingsOff, - HexViewerSettingsOn, -} HexViewerSettingsStoreState; diff --git a/applications/system/hex_viewer/icons/hex_10px.bmp b/applications/system/hex_viewer/icons/hex_10px.bmp deleted file mode 100644 index 54b78dc42..000000000 Binary files a/applications/system/hex_viewer/icons/hex_10px.bmp and /dev/null differ diff --git a/applications/system/hex_viewer/icons/hex_10px.png b/applications/system/hex_viewer/icons/hex_10px.png deleted file mode 100644 index 582e288c6..000000000 Binary files a/applications/system/hex_viewer/icons/hex_10px.png and /dev/null differ diff --git a/applications/system/hex_viewer/scenes/hex_viewer_scene.c b/applications/system/hex_viewer/scenes/hex_viewer_scene.c deleted file mode 100644 index 385828b0d..000000000 --- a/applications/system/hex_viewer/scenes/hex_viewer_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "hex_viewer_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const hex_viewer_on_enter_handlers[])(void*) = { -#include "hex_viewer_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const hex_viewer_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "hex_viewer_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const hex_viewer_on_exit_handlers[])(void* context) = { -#include "hex_viewer_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers hex_viewer_scene_handlers = { - .on_enter_handlers = hex_viewer_on_enter_handlers, - .on_event_handlers = hex_viewer_on_event_handlers, - .on_exit_handlers = hex_viewer_on_exit_handlers, - .scene_num = HexViewerSceneNum, -}; diff --git a/applications/system/hex_viewer/scenes/hex_viewer_scene.h b/applications/system/hex_viewer/scenes/hex_viewer_scene.h deleted file mode 100644 index e1f322fca..000000000 --- a/applications/system/hex_viewer/scenes/hex_viewer_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) HexViewerScene##id, -typedef enum { -#include "hex_viewer_scene_config.h" - HexViewerSceneNum, -} HexViewerScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers hex_viewer_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "hex_viewer_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "hex_viewer_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "hex_viewer_scene_config.h" -#undef ADD_SCENE diff --git a/applications/system/hex_viewer/scenes/hex_viewer_scene_config.h b/applications/system/hex_viewer/scenes/hex_viewer_scene_config.h deleted file mode 100644 index 7db382bc5..000000000 --- a/applications/system/hex_viewer/scenes/hex_viewer_scene_config.h +++ /dev/null @@ -1,6 +0,0 @@ -ADD_SCENE(hex_viewer, startscreen, Startscreen) -ADD_SCENE(hex_viewer, menu, Menu) -ADD_SCENE(hex_viewer, scroll, Scroll) -ADD_SCENE(hex_viewer, info, Info) -ADD_SCENE(hex_viewer, open, Open) -ADD_SCENE(hex_viewer, settings, Settings) \ No newline at end of file diff --git a/applications/system/hex_viewer/scenes/hex_viewer_scene_info.c b/applications/system/hex_viewer/scenes/hex_viewer_scene_info.c deleted file mode 100644 index 39d51b8c5..000000000 --- a/applications/system/hex_viewer/scenes/hex_viewer_scene_info.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../hex_viewer.h" - -void hex_viewer_scene_info_on_enter(void* context) { - furi_assert(context); - HexViewer* app = context; - - FuriString* buffer; - buffer = furi_string_alloc(); - furi_string_printf( - buffer, - "File path: %s\nFile size: %lu (0x%lX)", - furi_string_get_cstr(app->file_path), - app->model->file_size, - app->model->file_size); - - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_header(message, "Hex Viewer v2.0", 16, 2, AlignLeft, AlignTop); - dialog_message_set_icon(message, &I_hex_10px, 3, 2); - dialog_message_set_text(message, furi_string_get_cstr(buffer), 3, 16, AlignLeft, AlignTop); - dialog_message_set_buttons(message, NULL, NULL, "Back"); - dialog_message_show(app->dialogs, message); - - furi_string_free(buffer); - dialog_message_free(message); - - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, HexViewerViewIdStartscreen); -} - -bool hex_viewer_scene_info_on_event(void* context, SceneManagerEvent event) { - HexViewer* app = context; - UNUSED(app); - UNUSED(event); - bool consumed = true; - - return consumed; -} - -void hex_viewer_scene_info_on_exit(void* context) { - HexViewer* app = context; - UNUSED(app); -} diff --git a/applications/system/hex_viewer/scenes/hex_viewer_scene_menu.c b/applications/system/hex_viewer/scenes/hex_viewer_scene_menu.c deleted file mode 100644 index 50e0b55ba..000000000 --- a/applications/system/hex_viewer/scenes/hex_viewer_scene_menu.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "../hex_viewer.h" - -enum SubmenuIndex { - SubmenuIndexScroll = 10, - SubmenuIndexInfo, - SubmenuIndexOpen, - // SubmenuIndexSettings, -}; - -void hex_viewer_scene_menu_submenu_callback(void* context, uint32_t index) { - HexViewer* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void hex_viewer_scene_menu_on_enter(void* context) { - HexViewer* app = context; - - submenu_set_header(app->submenu, "Select action"); - submenu_add_item( - app->submenu, - "Open file ...", - SubmenuIndexOpen, - hex_viewer_scene_menu_submenu_callback, - app); - submenu_add_item( - app->submenu, - "Scroll to ...", - SubmenuIndexScroll, - hex_viewer_scene_menu_submenu_callback, - app); - submenu_add_item( - app->submenu, - "Show info ...", - SubmenuIndexInfo, - hex_viewer_scene_menu_submenu_callback, - app); - // submenu_add_item(app->submenu, "Settings", SubmenuIndexSettings, hex_viewer_scene_menu_submenu_callback, app); - - submenu_set_selected_item( - app->submenu, scene_manager_get_scene_state(app->scene_manager, HexViewerSceneMenu)); - - view_dispatcher_switch_to_view(app->view_dispatcher, HexViewerViewIdMenu); -} - -bool hex_viewer_scene_menu_on_event(void* context, SceneManagerEvent event) { - HexViewer* app = context; - - if(event.type == SceneManagerEventTypeBack) { - //exit app - // scene_manager_stop(app->scene_manager); - // view_dispatcher_stop(app->view_dispatcher); - scene_manager_previous_scene(app->scene_manager); - return true; - } else if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexScroll) { - scene_manager_set_scene_state( - app->scene_manager, HexViewerSceneMenu, SubmenuIndexScroll); - scene_manager_next_scene(app->scene_manager, HexViewerSceneScroll); - return true; - } else if(event.event == SubmenuIndexInfo) { - scene_manager_set_scene_state( - app->scene_manager, HexViewerSceneMenu, SubmenuIndexInfo); - scene_manager_next_scene(app->scene_manager, HexViewerSceneInfo); - return true; - } else if(event.event == SubmenuIndexOpen) { - scene_manager_set_scene_state( - app->scene_manager, HexViewerSceneMenu, SubmenuIndexOpen); - scene_manager_next_scene(app->scene_manager, HexViewerSceneOpen); - // } else if (event.event == SubmenuIndexSettings) { - // scene_manager_set_scene_state( - // app->scene_manager, HexViewerSceneMenu, SubmenuIndexSettings); - // scene_manager_next_scene(app->scene_manager, HexViewerSceneSettings); - // return true; - } - } - - return false; -} - -void hex_viewer_scene_menu_on_exit(void* context) { - HexViewer* app = context; - submenu_reset(app->submenu); -} \ No newline at end of file diff --git a/applications/system/hex_viewer/scenes/hex_viewer_scene_open.c b/applications/system/hex_viewer/scenes/hex_viewer_scene_open.c deleted file mode 100644 index cd9e90b7f..000000000 --- a/applications/system/hex_viewer/scenes/hex_viewer_scene_open.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../hex_viewer.h" - -void hex_viewer_scene_open_on_enter(void* context) { - furi_assert(context); - HexViewer* app = context; - - FuriString* initial_path; - initial_path = furi_string_alloc(); - furi_string_set(initial_path, HEX_VIEWER_APP_PATH_FOLDER); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, HEX_VIEWER_APP_EXTENSION, &I_hex_10px); - browser_options.hide_ext = false; - - bool success = - dialog_file_browser_show(app->dialogs, app->file_path, initial_path, &browser_options); - furi_string_free(initial_path); - - if(success) { - success = hex_viewer_open_file(app, furi_string_get_cstr(app->file_path)); - if(success) hex_viewer_read_file(app); - } - - if(success) { - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, HexViewerViewIdStartscreen); - } else { - scene_manager_previous_scene(app->scene_manager); - } -} - -bool hex_viewer_scene_open_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - bool consumed = true; - - return consumed; -} - -void hex_viewer_scene_open_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/system/hex_viewer/scenes/hex_viewer_scene_scroll.c b/applications/system/hex_viewer/scenes/hex_viewer_scene_scroll.c deleted file mode 100644 index 9613f5390..000000000 --- a/applications/system/hex_viewer/scenes/hex_viewer_scene_scroll.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "../hex_viewer.h" -#include "../helpers/hex_viewer_custom_event.h" - -void hex_viewer_scene_scroll_callback(void* context) { - HexViewer* app = (HexViewer*)context; - view_dispatcher_send_custom_event( - app->view_dispatcher, HexViewerCustomEventMenuPercentEntered); -} - -void hex_viewer_scene_scroll_on_enter(void* context) { - furi_assert(context); - HexViewer* app = context; - - TextInput* text_input = app->text_input; - - text_input_set_header_text(text_input, "Scroll to percentage (0..100)"); - text_input_set_result_callback( - text_input, - hex_viewer_scene_scroll_callback, - app, - app->percent_buf, - HEX_VIEWER_PERCENT_INPUT, - false); - - view_dispatcher_switch_to_view(app->view_dispatcher, HexViewerSceneScroll); -} - -bool hex_viewer_scene_scroll_on_event(void* context, SceneManagerEvent event) { - HexViewer* app = (HexViewer*)context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == HexViewerCustomEventMenuPercentEntered) { - int ipercent = atoi(app->percent_buf); - ipercent = MIN(ipercent, 100); - ipercent = MAX(ipercent, 0); - float percent = ipercent / 100.0; - - uint32_t line_count = app->model->file_size / HEX_VIEWER_BYTES_PER_LINE; - if(app->model->file_size % HEX_VIEWER_BYTES_PER_LINE != 0) line_count += 1; - uint32_t scrollable_lines = line_count - HEX_VIEWER_LINES_ON_SCREEN; - uint32_t target_line = (uint32_t)(percent * scrollable_lines); - - uint32_t new_file_offset = target_line * HEX_VIEWER_BYTES_PER_LINE; - if(app->model->file_size > new_file_offset) { - app->model->file_offset = new_file_offset; - if(!hex_viewer_read_file(app)) new_file_offset = new_file_offset; // TODO Do smth - } - - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, HexViewerViewIdStartscreen); - - consumed = true; - } - } - return consumed; -} - -void hex_viewer_scene_scroll_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/system/hex_viewer/scenes/hex_viewer_scene_settings.c b/applications/system/hex_viewer/scenes/hex_viewer_scene_settings.c deleted file mode 100644 index 70a8b3a41..000000000 --- a/applications/system/hex_viewer/scenes/hex_viewer_scene_settings.c +++ /dev/null @@ -1,133 +0,0 @@ -#include "../hex_viewer.h" -#include - -enum SettingsIndex { - SettingsIndexHaptic = 10, - SettingsIndexValue1, - SettingsIndexValue2, -}; - -const char* const haptic_text[2] = { - "OFF", - "ON", -}; -const uint32_t haptic_value[2] = { - HexViewerHapticOff, - HexViewerHapticOn, -}; - -const char* const speaker_text[2] = { - "OFF", - "ON", -}; -const uint32_t speaker_value[2] = { - HexViewerSpeakerOff, - HexViewerSpeakerOn, -}; - -const char* const led_text[2] = { - "OFF", - "ON", -}; -const uint32_t led_value[2] = { - HexViewerLedOff, - HexViewerLedOn, -}; - -const char* const settings_text[2] = { - "OFF", - "ON", -}; -const uint32_t settings_value[2] = { - HexViewerSettingsOff, - HexViewerSettingsOn, -}; - -static void hex_viewer_scene_settings_set_haptic(VariableItem* item) { - HexViewer* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, haptic_text[index]); - app->haptic = haptic_value[index]; -} - -static void hex_viewer_scene_settings_set_speaker(VariableItem* item) { - HexViewer* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, speaker_text[index]); - app->speaker = speaker_value[index]; -} - -static void hex_viewer_scene_settings_set_led(VariableItem* item) { - HexViewer* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, led_text[index]); - app->led = led_value[index]; -} - -static void hex_viewer_scene_settings_set_save_settings(VariableItem* item) { - HexViewer* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, settings_text[index]); - app->save_settings = settings_value[index]; -} - -void hex_viewer_scene_settings_submenu_callback(void* context, uint32_t index) { - HexViewer* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void hex_viewer_scene_settings_on_enter(void* context) { - HexViewer* app = context; - VariableItem* item; - uint8_t value_index; - - // Vibro on/off - item = variable_item_list_add( - app->variable_item_list, "Vibro/Haptic:", 2, hex_viewer_scene_settings_set_haptic, app); - value_index = value_index_uint32(app->haptic, haptic_value, 2); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, haptic_text[value_index]); - - // Sound on/off - item = variable_item_list_add( - app->variable_item_list, "Sound:", 2, hex_viewer_scene_settings_set_speaker, app); - value_index = value_index_uint32(app->speaker, speaker_value, 2); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, speaker_text[value_index]); - - // LED Effects on/off - item = variable_item_list_add( - app->variable_item_list, "LED FX:", 2, hex_viewer_scene_settings_set_led, app); - value_index = value_index_uint32(app->led, led_value, 2); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, led_text[value_index]); - - // Save Settings to File - item = variable_item_list_add( - app->variable_item_list, - "Save Settings", - 2, - hex_viewer_scene_settings_set_save_settings, - app); - value_index = value_index_uint32(app->save_settings, settings_value, 2); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, settings_text[value_index]); - - view_dispatcher_switch_to_view(app->view_dispatcher, HexViewerViewIdSettings); -} - -bool hex_viewer_scene_settings_on_event(void* context, SceneManagerEvent event) { - HexViewer* app = context; - UNUSED(app); - bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - } - return consumed; -} - -void hex_viewer_scene_settings_on_exit(void* context) { - HexViewer* app = context; - variable_item_list_set_selected_item(app->variable_item_list, 0); - variable_item_list_reset(app->variable_item_list); -} \ No newline at end of file diff --git a/applications/system/hex_viewer/scenes/hex_viewer_scene_startscreen.c b/applications/system/hex_viewer/scenes/hex_viewer_scene_startscreen.c deleted file mode 100644 index 6793655af..000000000 --- a/applications/system/hex_viewer/scenes/hex_viewer_scene_startscreen.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "../hex_viewer.h" -#include "../helpers/hex_viewer_custom_event.h" -#include "../views/hex_viewer_startscreen.h" - -void hex_viewer_scene_startscreen_callback(HexViewerCustomEvent event, void* context) { - furi_assert(context); - HexViewer* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void hex_viewer_scene_startscreen_on_enter(void* context) { - furi_assert(context); - HexViewer* app = context; - hex_viewer_startscreen_set_callback( - app->hex_viewer_startscreen, hex_viewer_scene_startscreen_callback, app); - view_dispatcher_switch_to_view(app->view_dispatcher, HexViewerViewIdStartscreen); -} - -bool hex_viewer_scene_startscreen_on_event(void* context, SceneManagerEvent event) { - HexViewer* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - switch(event.event) { - case HexViewerCustomEventStartscreenLeft: - //app->model->mode = !app->model->mode; - consumed = true; - break; - case HexViewerCustomEventStartscreenRight: - consumed = true; - break; - case HexViewerCustomEventStartscreenUp: - consumed = true; - break; - case HexViewerCustomEventStartscreenDown: - consumed = true; - break; - case HexViewerCustomEventStartscreenOk: - if(!app->model->file_size) - scene_manager_next_scene(app->scene_manager, HexViewerSceneOpen); - else - scene_manager_next_scene(app->scene_manager, HexViewerSceneMenu); - consumed = true; - break; - case HexViewerCustomEventStartscreenBack: // TODO Delete - notification_message(app->notification, &sequence_reset_red); - notification_message(app->notification, &sequence_reset_green); - notification_message(app->notification, &sequence_reset_blue); - if(!scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, HexViewerSceneStartscreen)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } - consumed = true; - break; - } - } - - return consumed; -} - -void hex_viewer_scene_startscreen_on_exit(void* context) { - HexViewer* app = context; - UNUSED(app); -} \ No newline at end of file diff --git a/applications/system/hex_viewer/views/hex_viewer_startscreen.c b/applications/system/hex_viewer/views/hex_viewer_startscreen.c deleted file mode 100644 index 515a0b139..000000000 --- a/applications/system/hex_viewer/views/hex_viewer_startscreen.c +++ /dev/null @@ -1,248 +0,0 @@ -#include "../hex_viewer.h" -#include -#include -#include -#include - -struct HexViewerStartscreen { - View* view; - HexViewerStartscreenCallback callback; - void* context; -}; - -typedef struct { - uint8_t file_bytes[HEX_VIEWER_LINES_ON_SCREEN][HEX_VIEWER_BYTES_PER_LINE]; - uint32_t file_offset; - uint32_t file_read_bytes; - uint32_t file_size; - bool mode; - uint32_t dbg; -} HexViewerStartscreenModel; - -void hex_viewer_startscreen_set_callback( - HexViewerStartscreen* instance, - HexViewerStartscreenCallback callback, - void* context) { - furi_assert(instance); - furi_assert(callback); - instance->callback = callback; - instance->context = context; -} - -void hex_viewer_startscreen_draw(Canvas* canvas, HexViewerStartscreenModel* model) { - canvas_clear(canvas); - - if(!model->file_size) { - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignTop, "HexViewer v2.0"); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 64, 22, AlignCenter, AlignTop, "Basic hex viewer"); - canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignTop, "for your Flipper"); - elements_button_center(canvas, "Open"); - } else { - canvas_set_color(canvas, ColorBlack); - - elements_button_left(canvas, model->mode ? "Addr" : "Text"); - //elements_button_right(canvas, "Info"); - elements_button_center(canvas, "Menu"); - - int ROW_HEIGHT = 12; - int TOP_OFFSET = 10; - int LEFT_OFFSET = 3; - - uint32_t line_count = model->file_size / HEX_VIEWER_BYTES_PER_LINE; - if(model->file_size % HEX_VIEWER_BYTES_PER_LINE != 0) line_count += 1; - uint32_t first_line_on_screen = model->file_offset / HEX_VIEWER_BYTES_PER_LINE; - if(line_count > HEX_VIEWER_LINES_ON_SCREEN) { - uint8_t width = canvas_width(canvas); - elements_scrollbar_pos( - canvas, - width, - 0, - ROW_HEIGHT * HEX_VIEWER_LINES_ON_SCREEN, - first_line_on_screen, - line_count - (HEX_VIEWER_LINES_ON_SCREEN - 1)); - } - - char temp_buf[32]; - uint32_t row_iters = model->file_read_bytes / HEX_VIEWER_BYTES_PER_LINE; - if(model->file_read_bytes % HEX_VIEWER_BYTES_PER_LINE != 0) row_iters += 1; - - // For the rest of drawing. - canvas_set_font(canvas, FontKeyboard); - - for(uint32_t i = 0; i < row_iters; ++i) { - uint32_t bytes_left_per_row = model->file_read_bytes - i * HEX_VIEWER_BYTES_PER_LINE; - bytes_left_per_row = MIN(bytes_left_per_row, HEX_VIEWER_BYTES_PER_LINE); - - if(model->mode) { - memcpy(temp_buf, model->file_bytes[i], bytes_left_per_row); - temp_buf[bytes_left_per_row] = '\0'; - for(uint32_t j = 0; j < bytes_left_per_row; ++j) - if(!isprint((int)temp_buf[j])) temp_buf[j] = '.'; - - //canvas_set_font(canvas, FontKeyboard); - canvas_draw_str(canvas, LEFT_OFFSET, TOP_OFFSET + i * ROW_HEIGHT, temp_buf); - } else { - uint32_t addr = model->file_offset + i * HEX_VIEWER_BYTES_PER_LINE; - snprintf(temp_buf, 32, "%04lX", addr); - - //canvas_set_font(canvas, FontKeyboard); - canvas_draw_str(canvas, LEFT_OFFSET, TOP_OFFSET + i * ROW_HEIGHT, temp_buf); - } - - char* p = temp_buf; - for(uint32_t j = 0; j < bytes_left_per_row; ++j) - p += snprintf(p, 32, "%02X ", model->file_bytes[i][j]); - - //canvas_set_font(canvas, FontKeyboard); - canvas_draw_str(canvas, LEFT_OFFSET + 41, TOP_OFFSET + i * ROW_HEIGHT, temp_buf); - } - - // Poor man's debug - // snprintf(temp_buf, 32, "D %02lX", model->dbg); - // elements_button_right(canvas, temp_buf); - } -} - -static void hex_viewer_startscreen_model_init(HexViewerStartscreenModel* const model) { - memset(model->file_bytes, 0, sizeof(model->file_bytes)); - model->file_offset = 0; - model->file_read_bytes = 0; - model->file_size = 0; - model->mode = false; - model->dbg = 0; -} - -static void - update_local_model_from_app(HexViewer* const app, HexViewerStartscreenModel* const model) { - memcpy(model->file_bytes, app->model->file_bytes, sizeof(model->file_bytes)); - model->file_offset = app->model->file_offset; - model->file_read_bytes = app->model->file_read_bytes; - model->file_size = app->model->file_size; - //model->mode = app->model->mode; -} - -bool hex_viewer_startscreen_input(InputEvent* event, void* context) { - furi_assert(context); - HexViewerStartscreen* instance = context; - HexViewer* app = instance->context; // TO so good, but works - - if(event->type == InputTypeRelease || event->type == InputTypeRepeat) { - switch(event->key) { - case InputKeyBack: - with_view_model( - instance->view, - HexViewerStartscreenModel * model, - { - instance->callback(HexViewerCustomEventStartscreenBack, instance->context); - update_local_model_from_app(instance->context, model); - }, - true); - break; - case InputKeyLeft: - with_view_model( - instance->view, - HexViewerStartscreenModel * model, - { model->mode = !model->mode; }, - true); - break; - case InputKeyRight: - with_view_model( - instance->view, HexViewerStartscreenModel * model, { model->dbg = 0; }, true); - break; - case InputKeyUp: - with_view_model( - instance->view, - HexViewerStartscreenModel * model, - { - if(app->model->file_offset > 0) { - app->model->file_offset -= HEX_VIEWER_BYTES_PER_LINE; - if(!hex_viewer_read_file(app)) break; // TODO Do smth - } - - update_local_model_from_app(instance->context, model); - }, - true); - break; - case InputKeyDown: - with_view_model( - instance->view, - HexViewerStartscreenModel * model, - { - uint32_t last_byte_on_screen = - app->model->file_offset + app->model->file_read_bytes; - if(app->model->file_size > last_byte_on_screen) { - app->model->file_offset += HEX_VIEWER_BYTES_PER_LINE; - if(!hex_viewer_read_file(app)) break; // TODO Do smth - } - - update_local_model_from_app(instance->context, model); - }, - true); - break; - case InputKeyOk: - with_view_model( - instance->view, - HexViewerStartscreenModel * model, - { - instance->callback(HexViewerCustomEventStartscreenOk, instance->context); - update_local_model_from_app(instance->context, model); - }, - true); - break; - case InputKeyMAX: - break; - } - } - - return true; -} - -void hex_viewer_startscreen_exit(void* context) { - furi_assert(context); -} - -void hex_viewer_startscreen_enter(void* context) { - furi_assert(context); - HexViewerStartscreen* instance = (HexViewerStartscreen*)context; - with_view_model( - instance->view, - HexViewerStartscreenModel * model, - { update_local_model_from_app(instance->context, model); }, - true); -} - -HexViewerStartscreen* hex_viewer_startscreen_alloc() { - HexViewerStartscreen* instance = malloc(sizeof(HexViewerStartscreen)); - instance->view = view_alloc(); - view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(HexViewerStartscreenModel)); - view_set_context(instance->view, instance); - view_set_draw_callback(instance->view, (ViewDrawCallback)hex_viewer_startscreen_draw); - view_set_input_callback(instance->view, hex_viewer_startscreen_input); - view_set_enter_callback(instance->view, hex_viewer_startscreen_enter); - view_set_exit_callback(instance->view, hex_viewer_startscreen_exit); - - with_view_model( - instance->view, - HexViewerStartscreenModel * model, - { hex_viewer_startscreen_model_init(model); }, - true); - - return instance; -} - -void hex_viewer_startscreen_free(HexViewerStartscreen* instance) { - furi_assert(instance); - - with_view_model( - instance->view, HexViewerStartscreenModel * model, { UNUSED(model); }, true); - view_free(instance->view); - free(instance); -} - -View* hex_viewer_startscreen_get_view(HexViewerStartscreen* instance) { - furi_assert(instance); - return instance->view; -} diff --git a/applications/system/hex_viewer/views/hex_viewer_startscreen.h b/applications/system/hex_viewer/views/hex_viewer_startscreen.h deleted file mode 100644 index 3bda82744..000000000 --- a/applications/system/hex_viewer/views/hex_viewer_startscreen.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include "../helpers/hex_viewer_custom_event.h" - -typedef struct HexViewerStartscreen HexViewerStartscreen; - -typedef void (*HexViewerStartscreenCallback)(HexViewerCustomEvent event, void* context); - -void hex_viewer_startscreen_set_callback( - HexViewerStartscreen* hex_viewer_startscreen, - HexViewerStartscreenCallback callback, - void* context); - -View* hex_viewer_startscreen_get_view(HexViewerStartscreen* hex_viewer_static); - -HexViewerStartscreen* hex_viewer_startscreen_alloc(); - -void hex_viewer_startscreen_free(HexViewerStartscreen* hex_viewer_static); \ No newline at end of file diff --git a/applications/system/ir_remote/application.fam b/applications/system/ir_remote/application.fam deleted file mode 100644 index c6c3de570..000000000 --- a/applications/system/ir_remote/application.fam +++ /dev/null @@ -1,18 +0,0 @@ -App( - appid="ir_remote", - name="IR Remote", - apptype=FlipperAppType.EXTERNAL, - entry_point="infrared_remote_app", - stack_size=3 * 1024, - requires=[ - "gui", - "dialogs", - ], - fap_category="Infrared", - fap_icon="ir_10px.png", - fap_icon_assets="images", - fap_author="@Hong5489 & @friebel & @d4ve10", - fap_weburl="https://github.com/Hong5489/ir_remote", - fap_version="1.0", - fap_description="Bind any IR remote button to each button on flipper d-pad, provides another way to use flipper as IR remote.", -) diff --git a/applications/system/ir_remote/infrared_remote.c b/applications/system/ir_remote/infrared_remote.c deleted file mode 100644 index 033df2d4e..000000000 --- a/applications/system/ir_remote/infrared_remote.c +++ /dev/null @@ -1,188 +0,0 @@ -#include "infrared_remote.h" - -#include -#include -#include -#include -#include -#include -#include - -#define TAG "InfraredRemote" - -ARRAY_DEF(InfraredButtonArray, InfraredRemoteButton*, M_PTR_OPLIST); - -struct InfraredRemote { - InfraredButtonArray_t buttons; - FuriString* name; - FuriString* path; -}; - -static void infrared_remote_clear_buttons(InfraredRemote* remote) { - InfraredButtonArray_it_t it; - for(InfraredButtonArray_it(it, remote->buttons); !InfraredButtonArray_end_p(it); - InfraredButtonArray_next(it)) { - infrared_remote_button_free(*InfraredButtonArray_cref(it)); - } - InfraredButtonArray_reset(remote->buttons); -} - -InfraredRemote* infrared_remote_alloc(void) { - InfraredRemote* remote = malloc(sizeof(InfraredRemote)); - InfraredButtonArray_init(remote->buttons); - remote->name = furi_string_alloc(); - remote->path = furi_string_alloc(); - return remote; -} - -void infrared_remote_free(InfraredRemote* remote) { - infrared_remote_clear_buttons(remote); - InfraredButtonArray_clear(remote->buttons); - furi_string_free(remote->path); - furi_string_free(remote->name); - free(remote); -} - -void infrared_remote_reset(InfraredRemote* remote) { - infrared_remote_clear_buttons(remote); - furi_string_reset(remote->name); - furi_string_reset(remote->path); -} - -void infrared_remote_set_name(InfraredRemote* remote, const char* name) { - furi_string_set(remote->name, name); -} - -const char* infrared_remote_get_name(InfraredRemote* remote) { - return furi_string_get_cstr(remote->name); -} - -void infrared_remote_set_path(InfraredRemote* remote, const char* path) { - furi_string_set(remote->path, path); -} - -const char* infrared_remote_get_path(InfraredRemote* remote) { - return furi_string_get_cstr(remote->path); -} - -size_t infrared_remote_get_button_count(InfraredRemote* remote) { - return InfraredButtonArray_size(remote->buttons); -} - -InfraredRemoteButton* infrared_remote_get_button(InfraredRemote* remote, size_t index) { - furi_assert(index < InfraredButtonArray_size(remote->buttons)); - return *InfraredButtonArray_get(remote->buttons, index); -} - -bool infrared_remote_find_button_by_name(InfraredRemote* remote, const char* name, size_t* index) { - for(size_t i = 0; i < InfraredButtonArray_size(remote->buttons); i++) { - InfraredRemoteButton* button = *InfraredButtonArray_get(remote->buttons, i); - if(!strcmp(infrared_remote_button_get_name(button), name)) { - *index = i; - return true; - } - } - return false; -} - -bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal) { - InfraredRemoteButton* button = infrared_remote_button_alloc(); - infrared_remote_button_set_name(button, name); - infrared_remote_button_set_signal(button, signal); - InfraredButtonArray_push_back(remote->buttons, button); - return infrared_remote_store(remote); -} - -bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index) { - furi_assert(index < InfraredButtonArray_size(remote->buttons)); - InfraredRemoteButton* button = *InfraredButtonArray_get(remote->buttons, index); - infrared_remote_button_set_name(button, new_name); - return infrared_remote_store(remote); -} - -bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) { - furi_assert(index < InfraredButtonArray_size(remote->buttons)); - InfraredRemoteButton* button; - InfraredButtonArray_pop_at(&button, remote->buttons, index); - infrared_remote_button_free(button); - return infrared_remote_store(remote); -} - -bool infrared_remote_store(InfraredRemote* remote) { - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* ff = flipper_format_file_alloc(storage); - const char* path = furi_string_get_cstr(remote->path); - - FURI_LOG_I(TAG, "store file: \'%s\'", path); - - bool success = flipper_format_file_open_always(ff, path) && - flipper_format_write_header_cstr(ff, "IR signals file", 1); - if(success) { - InfraredButtonArray_it_t it; - for(InfraredButtonArray_it(it, remote->buttons); !InfraredButtonArray_end_p(it); - InfraredButtonArray_next(it)) { - InfraredRemoteButton* button = *InfraredButtonArray_cref(it); - success = infrared_signal_save( - infrared_remote_button_get_signal(button), - ff, - infrared_remote_button_get_name(button)); - if(!success) { - break; - } - } - } - - flipper_format_free(ff); - furi_record_close(RECORD_STORAGE); - return success; -} - -bool infrared_remote_load(InfraredRemote* remote, FuriString* path) { - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* ff = flipper_format_buffered_file_alloc(storage); - - FuriString* buf; - buf = furi_string_alloc(); - - FURI_LOG_I(TAG, "load file: \'%s\'", furi_string_get_cstr(path)); - bool success = flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(path)); - - if(success) { - uint32_t version; - success = flipper_format_read_header(ff, buf, &version) && - !furi_string_cmp(buf, "IR signals file") && (version == 1); - } - - if(success) { - path_extract_filename(path, buf, true); - infrared_remote_clear_buttons(remote); - infrared_remote_set_name(remote, furi_string_get_cstr(buf)); - infrared_remote_set_path(remote, furi_string_get_cstr(path)); - - for(bool can_read = true; can_read;) { - InfraredRemoteButton* button = infrared_remote_button_alloc(); - can_read = infrared_signal_read(infrared_remote_button_get_signal(button), ff, buf); - if(can_read) { - infrared_remote_button_set_name(button, furi_string_get_cstr(buf)); - InfraredButtonArray_push_back(remote->buttons, button); - } else { - infrared_remote_button_free(button); - } - } - } - - furi_string_free(buf); - flipper_format_free(ff); - furi_record_close(RECORD_STORAGE); - return success; -} - -bool infrared_remote_remove(InfraredRemote* remote) { - Storage* storage = furi_record_open(RECORD_STORAGE); - - FS_Error status = storage_common_remove(storage, furi_string_get_cstr(remote->path)); - infrared_remote_reset(remote); - - furi_record_close(RECORD_STORAGE); - return (status == FSE_OK || status == FSE_NOT_EXIST); -} diff --git a/applications/system/ir_remote/infrared_remote.h b/applications/system/ir_remote/infrared_remote.h deleted file mode 100644 index fe3dc851a..000000000 --- a/applications/system/ir_remote/infrared_remote.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include - -#include "infrared_remote_button.h" - -#define IR_REMOTE_PATH EXT_PATH("infrared/remote") - -typedef struct InfraredRemote InfraredRemote; - -InfraredRemote* infrared_remote_alloc(void); -void infrared_remote_free(InfraredRemote* remote); -void infrared_remote_reset(InfraredRemote* remote); - -void infrared_remote_set_name(InfraredRemote* remote, const char* name); -const char* infrared_remote_get_name(InfraredRemote* remote); - -void infrared_remote_set_path(InfraredRemote* remote, const char* path); -const char* infrared_remote_get_path(InfraredRemote* remote); - -size_t infrared_remote_get_button_count(InfraredRemote* remote); -InfraredRemoteButton* infrared_remote_get_button(InfraredRemote* remote, size_t index); -bool infrared_remote_find_button_by_name(InfraredRemote* remote, const char* name, size_t* index); - -bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal); -bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index); -bool infrared_remote_delete_button(InfraredRemote* remote, size_t index); - -bool infrared_remote_store(InfraredRemote* remote); -bool infrared_remote_load(InfraredRemote* remote, FuriString* path); -bool infrared_remote_remove(InfraredRemote* remote); diff --git a/applications/system/ir_remote/infrared_remote_app.c b/applications/system/ir_remote/infrared_remote_app.c deleted file mode 100644 index 730982640..000000000 --- a/applications/system/ir_remote/infrared_remote_app.c +++ /dev/null @@ -1,611 +0,0 @@ -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "infrared_signal.h" -#include "infrared_remote.h" -#include "infrared_remote_button.h" -#define TAG "ir_remote" - -#include - -typedef struct { - int status; - ViewPort* view_port; - FuriString* up_button; - FuriString* down_button; - FuriString* left_button; - FuriString* right_button; - FuriString* ok_button; - FuriString* back_button; - FuriString* up_hold_button; - FuriString* down_hold_button; - FuriString* left_hold_button; - FuriString* right_hold_button; - FuriString* ok_hold_button; - InfraredWorker* infrared_worker; -} IRApp; - -// Screen is 128x64 px -static void app_draw_callback(Canvas* canvas, void* ctx) { - // Show config is incorrect when cannot read the remote file - // Showing button string in the screen, upper part is short press, lower part is long press - IRApp* app = ctx; - if(app->status) { - canvas_clear(canvas); - view_port_set_orientation(app->view_port, ViewPortOrientationHorizontal); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 62, 5, AlignCenter, AlignTop, "Config is incorrect."); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignTop, "Please configure map."); - canvas_draw_str_aligned(canvas, 62, 60, AlignCenter, AlignBottom, "Press Back to Exit."); - } else { - canvas_clear(canvas); - view_port_set_orientation(app->view_port, ViewPortOrientationVertical); - canvas_draw_icon(canvas, 1, 5, &I_ButtonUp_7x4); - canvas_draw_icon(canvas, 1, 15, &I_ButtonDown_7x4); - canvas_draw_icon(canvas, 2, 23, &I_ButtonLeft_4x7); - canvas_draw_icon(canvas, 2, 33, &I_ButtonRight_4x7); - canvas_draw_icon(canvas, 0, 42, &I_Ok_btn_9x9); - canvas_draw_icon(canvas, 0, 53, &I_back_10px); - - //Labels - canvas_set_font(canvas, FontSecondary); - - canvas_draw_str_aligned( - canvas, 32, 8, AlignCenter, AlignCenter, furi_string_get_cstr(app->up_button)); - canvas_draw_str_aligned( - canvas, 32, 18, AlignCenter, AlignCenter, furi_string_get_cstr(app->down_button)); - canvas_draw_str_aligned( - canvas, 32, 28, AlignCenter, AlignCenter, furi_string_get_cstr(app->left_button)); - canvas_draw_str_aligned( - canvas, 32, 38, AlignCenter, AlignCenter, furi_string_get_cstr(app->right_button)); - canvas_draw_str_aligned( - canvas, 32, 48, AlignCenter, AlignCenter, furi_string_get_cstr(app->ok_button)); - canvas_draw_str_aligned( - canvas, 32, 58, AlignCenter, AlignCenter, furi_string_get_cstr(app->back_button)); - - canvas_draw_line(canvas, 0, 65, 64, 65); - - canvas_draw_icon(canvas, 1, 70, &I_ButtonUp_7x4); - canvas_draw_icon(canvas, 1, 80, &I_ButtonDown_7x4); - canvas_draw_icon(canvas, 2, 88, &I_ButtonLeft_4x7); - canvas_draw_icon(canvas, 2, 98, &I_ButtonRight_4x7); - canvas_draw_icon(canvas, 0, 107, &I_Ok_btn_9x9); - canvas_draw_icon(canvas, 0, 118, &I_back_10px); - - canvas_draw_str_aligned( - canvas, 32, 73, AlignCenter, AlignCenter, furi_string_get_cstr(app->up_hold_button)); - canvas_draw_str_aligned( - canvas, 32, 83, AlignCenter, AlignCenter, furi_string_get_cstr(app->down_hold_button)); - canvas_draw_str_aligned( - canvas, 32, 93, AlignCenter, AlignCenter, furi_string_get_cstr(app->left_hold_button)); - canvas_draw_str_aligned( - canvas, - 32, - 103, - AlignCenter, - AlignCenter, - furi_string_get_cstr(app->right_hold_button)); - canvas_draw_str_aligned( - canvas, 32, 113, AlignCenter, AlignCenter, furi_string_get_cstr(app->ok_hold_button)); - canvas_draw_str_aligned(canvas, 32, 123, AlignCenter, AlignCenter, "Exit App"); - } -} - -static void app_input_callback(InputEvent* input_event, void* ctx) { - furi_assert(ctx); - - FuriMessageQueue* event_queue = ctx; - furi_message_queue_put(event_queue, input_event, FuriWaitForever); -} - -int32_t infrared_remote_app(char* p) { - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - - // App button string - IRApp* app = malloc(sizeof(IRApp)); - app->up_button = furi_string_alloc(); - app->down_button = furi_string_alloc(); - app->left_button = furi_string_alloc(); - app->right_button = furi_string_alloc(); - app->ok_button = furi_string_alloc(); - app->back_button = furi_string_alloc(); - app->up_hold_button = furi_string_alloc(); - app->down_hold_button = furi_string_alloc(); - app->left_hold_button = furi_string_alloc(); - app->right_hold_button = furi_string_alloc(); - app->ok_hold_button = furi_string_alloc(); - app->view_port = view_port_alloc(); - app->infrared_worker = infrared_worker_alloc(); - - // Configure view port - view_port_draw_callback_set(app->view_port, app_draw_callback, app); - view_port_input_callback_set(app->view_port, app_input_callback, event_queue); - - // Register view port in GUI - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, app->view_port, GuiLayerFullscreen); - - InputEvent event; - - FuriString* map_file = furi_string_alloc(); - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* ff = flipper_format_file_alloc(storage); - if(!storage_file_exists(storage, IR_REMOTE_PATH)) { - storage_common_mkdir(storage, IR_REMOTE_PATH); //Make Folder If dir not exist - } - - bool res; - if(p && strlen(p)) { - furi_string_set(map_file, p); - res = true; - } else { - DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, ".txt", &I_sub1_10px); - browser_options.base_path = IR_REMOTE_PATH; - furi_string_set(map_file, IR_REMOTE_PATH); - res = dialog_file_browser_show(dialogs, map_file, map_file, &browser_options); - furi_record_close(RECORD_DIALOGS); - } - - // if user didn't choose anything, free everything and exit - if(!res) { - FURI_LOG_I(TAG, "exit"); - flipper_format_free(ff); - furi_record_close(RECORD_STORAGE); - - furi_string_free(app->up_button); - furi_string_free(app->down_button); - furi_string_free(app->left_button); - furi_string_free(app->right_button); - furi_string_free(app->ok_button); - furi_string_free(app->back_button); - furi_string_free(app->up_hold_button); - furi_string_free(app->down_hold_button); - furi_string_free(app->left_hold_button); - furi_string_free(app->right_hold_button); - furi_string_free(app->ok_hold_button); - - view_port_enabled_set(app->view_port, false); - gui_remove_view_port(gui, app->view_port); - view_port_free(app->view_port); - free(app); - furi_message_queue_free(event_queue); - - furi_record_close(RECORD_GUI); - return 255; - } - - InfraredRemote* remote = infrared_remote_alloc(); - FuriString* remote_path = furi_string_alloc(); - - InfraredSignal* up_signal = infrared_signal_alloc(); - InfraredSignal* down_signal = infrared_signal_alloc(); - InfraredSignal* left_signal = infrared_signal_alloc(); - InfraredSignal* right_signal = infrared_signal_alloc(); - InfraredSignal* ok_signal = infrared_signal_alloc(); - InfraredSignal* back_signal = infrared_signal_alloc(); - InfraredSignal* up_hold_signal = infrared_signal_alloc(); - InfraredSignal* down_hold_signal = infrared_signal_alloc(); - InfraredSignal* left_hold_signal = infrared_signal_alloc(); - InfraredSignal* right_hold_signal = infrared_signal_alloc(); - InfraredSignal* ok_hold_signal = infrared_signal_alloc(); - - InfraredSignal* active_signal = NULL; - bool is_transmitting = false; - - bool up_enabled = false; - bool down_enabled = false; - bool left_enabled = false; - bool right_enabled = false; - bool ok_enabled = false; - bool back_enabled = false; - bool up_hold_enabled = false; - bool down_hold_enabled = false; - bool left_hold_enabled = false; - bool right_hold_enabled = false; - bool ok_hold_enabled = false; - - if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(map_file))) { - FURI_LOG_E(TAG, "Could not open MAP file %s", furi_string_get_cstr(map_file)); - app->status = 1; - } else { - //Filename Assignment/Check Start - - if(!flipper_format_read_string(ff, "REMOTE", remote_path)) { - FURI_LOG_E(TAG, "Could not read REMOTE string"); - app->status = 1; - } else { - if(!infrared_remote_load(remote, remote_path)) { - FURI_LOG_E(TAG, "Could not load ir file: %s", furi_string_get_cstr(remote_path)); - app->status = 1; - } else { - FURI_LOG_I(TAG, "Loaded REMOTE file: %s", furi_string_get_cstr(remote_path)); - } - } - - //assign variables to values within map file - //set missing filenames to N/A - //assign button signals - size_t index = 0; - if(!flipper_format_read_string(ff, "UP", app->up_button)) { - FURI_LOG_W(TAG, "Could not read UP string"); - furi_string_set(app->up_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->up_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - up_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - up_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "DOWN", app->down_button)) { - FURI_LOG_W(TAG, "Could not read DOWN string"); - furi_string_set(app->down_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->down_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - down_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - down_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "LEFT", app->left_button)) { - FURI_LOG_W(TAG, "Could not read LEFT string"); - furi_string_set(app->left_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->left_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - left_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - left_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "RIGHT", app->right_button)) { - FURI_LOG_W(TAG, "Could not read RIGHT string"); - furi_string_set(app->right_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->right_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - right_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - right_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "OK", app->ok_button)) { - FURI_LOG_W(TAG, "Could not read OK string"); - furi_string_set(app->ok_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->ok_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - ok_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - ok_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "BACK", app->back_button)) { - FURI_LOG_W(TAG, "Could not read BACK string"); - furi_string_set(app->back_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->back_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - back_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - back_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "UPHOLD", app->up_hold_button)) { - FURI_LOG_W(TAG, "Could not read UPHOLD string"); - furi_string_set(app->up_hold_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->up_hold_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - up_hold_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - up_hold_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "DOWNHOLD", app->down_hold_button)) { - FURI_LOG_W(TAG, "Could not read DOWNHOLD string"); - furi_string_set(app->down_hold_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->down_hold_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - down_hold_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - down_hold_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "LEFTHOLD", app->left_hold_button)) { - FURI_LOG_W(TAG, "Could not read LEFTHOLD string"); - furi_string_set(app->left_hold_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->left_hold_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - left_hold_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - left_hold_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "RIGHTHOLD", app->right_hold_button)) { - FURI_LOG_W(TAG, "Could not read RIGHTHOLD string"); - furi_string_set(app->right_hold_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->right_hold_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - right_hold_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - right_hold_enabled = true; - } - } - - if(!flipper_format_read_string(ff, "OKHOLD", app->ok_hold_button)) { - FURI_LOG_W(TAG, "Could not read OKHOLD string"); - furi_string_set(app->ok_hold_button, "N/A"); - } else { - if(!infrared_remote_find_button_by_name( - remote, furi_string_get_cstr(app->ok_hold_button), &index)) { - FURI_LOG_W(TAG, "Error"); - } else { - ok_hold_signal = - infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); - ok_hold_enabled = true; - } - } - } - - furi_string_free(remote_path); - - flipper_format_free(ff); - furi_record_close(RECORD_STORAGE); - - bool otg_was_enabled = furi_hal_power_is_otg_enabled(); - InfraredSettings settings = {0}; - saved_struct_load( - INFRARED_SETTINGS_PATH, - &settings, - sizeof(InfraredSettings), - INFRARED_SETTINGS_MAGIC, - INFRARED_SETTINGS_VERSION); - if(settings.tx_pin < FuriHalInfraredTxPinMax) { - furi_hal_infrared_set_tx_output(settings.tx_pin); - if(settings.otg_enabled != otg_was_enabled) { - if(settings.otg_enabled) { - furi_hal_power_enable_otg(); - } else { - furi_hal_power_disable_otg(); - } - } - } else { - FuriHalInfraredTxPin tx_pin_detected = furi_hal_infrared_detect_tx_output(); - furi_hal_infrared_set_tx_output(tx_pin_detected); - if(tx_pin_detected != FuriHalInfraredTxPinInternal) { - furi_hal_power_enable_otg(); - } - } - - bool running = true; - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - - if(app->status) { - view_port_update(app->view_port); - while(running) { - if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) { - if(event.type == InputTypeShort) { - switch(event.key) { - case InputKeyBack: - running = false; - break; - default: - break; - } - } - } - } - } else { - view_port_update(app->view_port); - while(running) { - if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) { - // short press signal - if(event.type == InputTypeShort) { - switch(event.key) { - case InputKeyUp: - if(up_enabled) { - active_signal = up_signal; - FURI_LOG_I(TAG, "up"); - } - break; - case InputKeyDown: - if(down_enabled) { - active_signal = down_signal; - FURI_LOG_I(TAG, "down"); - } - break; - case InputKeyRight: - if(right_enabled) { - active_signal = right_signal; - FURI_LOG_I(TAG, "right"); - } - break; - case InputKeyLeft: - if(left_enabled) { - active_signal = left_signal; - FURI_LOG_I(TAG, "left"); - } - break; - case InputKeyOk: - if(ok_enabled) { - active_signal = ok_signal; - FURI_LOG_I(TAG, "ok"); - } - break; - case InputKeyBack: - if(back_enabled) { - active_signal = back_signal; - FURI_LOG_I(TAG, "back"); - } - break; - default: - running = false; - break; - } - // long press signal - } else if(event.type == InputTypeLong) { - switch(event.key) { - case InputKeyUp: - if(up_hold_enabled) { - active_signal = up_hold_signal; - FURI_LOG_I(TAG, "up!"); - } - break; - case InputKeyDown: - if(down_hold_enabled) { - active_signal = down_hold_signal; - FURI_LOG_I(TAG, "down!"); - } - break; - case InputKeyRight: - if(right_hold_enabled) { - active_signal = right_hold_signal; - FURI_LOG_I(TAG, "right!"); - } - break; - case InputKeyLeft: - if(left_hold_enabled) { - active_signal = left_hold_signal; - FURI_LOG_I(TAG, "left!"); - } - break; - case InputKeyOk: - if(ok_hold_enabled) { - active_signal = ok_hold_signal; - FURI_LOG_I(TAG, "ok!"); - } - break; - default: - running = false; - break; - } - } else if(event.type == InputTypeRelease && is_transmitting) { - notification_message(notification, &sequence_blink_stop); - infrared_worker_tx_stop(app->infrared_worker); - is_transmitting = false; - active_signal = NULL; - } - - if(active_signal != NULL && - (event.type == InputTypeShort || event.type == InputTypeLong)) { - if(is_transmitting) { - infrared_worker_tx_stop(app->infrared_worker); - } - - if(infrared_signal_is_raw(active_signal)) { - InfraredRawSignal* raw_signal = - infrared_signal_get_raw_signal(active_signal); - infrared_worker_set_raw_signal( - app->infrared_worker, - raw_signal->timings, - raw_signal->timings_size, - raw_signal->frequency, - raw_signal->duty_cycle); - } else { - InfraredMessage* message = infrared_signal_get_message(active_signal); - infrared_worker_set_decoded_signal(app->infrared_worker, message); - } - - infrared_worker_tx_set_get_signal_callback( - app->infrared_worker, infrared_worker_tx_get_signal_steady_callback, app); - - infrared_worker_tx_start(app->infrared_worker); - notification_message(notification, &sequence_blink_start_magenta); - is_transmitting = true; - } - } - view_port_update(app->view_port); - } - } - - furi_hal_infrared_set_tx_output(FuriHalInfraredTxPinInternal); - if(furi_hal_power_is_otg_enabled() != otg_was_enabled) { - if(otg_was_enabled) { - furi_hal_power_enable_otg(); - } else { - furi_hal_power_disable_otg(); - } - } - - // Free all things - furi_string_free(app->up_button); - furi_string_free(app->down_button); - furi_string_free(app->left_button); - furi_string_free(app->right_button); - furi_string_free(app->ok_button); - furi_string_free(app->back_button); - furi_string_free(app->up_hold_button); - furi_string_free(app->down_hold_button); - furi_string_free(app->left_hold_button); - furi_string_free(app->right_hold_button); - furi_string_free(app->ok_hold_button); - - if(is_transmitting) { - infrared_worker_tx_stop(app->infrared_worker); - notification_message(notification, &sequence_blink_stop); - } - infrared_worker_free(app->infrared_worker); - - infrared_remote_free(remote); - view_port_enabled_set(app->view_port, false); - gui_remove_view_port(gui, app->view_port); - view_port_free(app->view_port); - free(app); - furi_message_queue_free(event_queue); - - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_GUI); - - return 0; -} diff --git a/applications/system/ir_remote/infrared_remote_button.c b/applications/system/ir_remote/infrared_remote_button.c deleted file mode 100644 index 510c9da12..000000000 --- a/applications/system/ir_remote/infrared_remote_button.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "infrared_remote_button.h" - -#include - -struct InfraredRemoteButton { - FuriString* name; - InfraredSignal* signal; -}; - -InfraredRemoteButton* infrared_remote_button_alloc(void) { - InfraredRemoteButton* button = malloc(sizeof(InfraredRemoteButton)); - button->name = furi_string_alloc(); - button->signal = infrared_signal_alloc(); - return button; -} - -void infrared_remote_button_free(InfraredRemoteButton* button) { - furi_string_free(button->name); - infrared_signal_free(button->signal); - free(button); -} - -void infrared_remote_button_set_name(InfraredRemoteButton* button, const char* name) { - furi_string_set(button->name, name); -} - -const char* infrared_remote_button_get_name(InfraredRemoteButton* button) { - return furi_string_get_cstr(button->name); -} - -void infrared_remote_button_set_signal(InfraredRemoteButton* button, InfraredSignal* signal) { - infrared_signal_set_signal(button->signal, signal); -} - -InfraredSignal* infrared_remote_button_get_signal(InfraredRemoteButton* button) { - return button->signal; -} diff --git a/applications/system/ir_remote/infrared_remote_button.h b/applications/system/ir_remote/infrared_remote_button.h deleted file mode 100644 index 1b9b65188..000000000 --- a/applications/system/ir_remote/infrared_remote_button.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "infrared_signal.h" - -typedef struct InfraredRemoteButton InfraredRemoteButton; - -InfraredRemoteButton* infrared_remote_button_alloc(void); -void infrared_remote_button_free(InfraredRemoteButton* button); - -void infrared_remote_button_set_name(InfraredRemoteButton* button, const char* name); -const char* infrared_remote_button_get_name(InfraredRemoteButton* button); - -void infrared_remote_button_set_signal(InfraredRemoteButton* button, InfraredSignal* signal); -InfraredSignal* infrared_remote_button_get_signal(InfraredRemoteButton* button); diff --git a/applications/system/ir_remote/infrared_signal.c b/applications/system/ir_remote/infrared_signal.c deleted file mode 100644 index 3c0944ea7..000000000 --- a/applications/system/ir_remote/infrared_signal.c +++ /dev/null @@ -1,300 +0,0 @@ -#include "infrared_signal.h" - -#include -#include -#include -#include -#include - -#define TAG "InfraredSignal" - -struct InfraredSignal { - bool is_raw; - union { - InfraredMessage message; - InfraredRawSignal raw; - } payload; -}; - -static void infrared_signal_clear_timings(InfraredSignal* signal) { - if(signal->is_raw) { - free(signal->payload.raw.timings); - signal->payload.raw.timings_size = 0; - signal->payload.raw.timings = NULL; - } -} - -static bool infrared_signal_is_message_valid(InfraredMessage* message) { - if(!infrared_is_protocol_valid(message->protocol)) { - FURI_LOG_E(TAG, "Unknown protocol"); - return false; - } - - uint32_t address_length = infrared_get_protocol_address_length(message->protocol); - uint32_t address_mask = (1UL << address_length) - 1; - - if(message->address != (message->address & address_mask)) { - FURI_LOG_E( - TAG, - "Address is out of range (mask 0x%08lX): 0x%lX\r\n", - address_mask, - message->address); - return false; - } - - uint32_t command_length = infrared_get_protocol_command_length(message->protocol); - uint32_t command_mask = (1UL << command_length) - 1; - - if(message->command != (message->command & command_mask)) { - FURI_LOG_E( - TAG, - "Command is out of range (mask 0x%08lX): 0x%lX\r\n", - command_mask, - message->command); - return false; - } - - return true; -} - -static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) { - if((raw->frequency > INFRARED_MAX_FREQUENCY) || (raw->frequency < INFRARED_MIN_FREQUENCY)) { - FURI_LOG_E( - TAG, - "Frequency is out of range (%X - %X): %lX", - INFRARED_MIN_FREQUENCY, - INFRARED_MAX_FREQUENCY, - raw->frequency); - return false; - - } else if((raw->duty_cycle <= 0) || (raw->duty_cycle > 1)) { - FURI_LOG_E(TAG, "Duty cycle is out of range (0 - 1): %f", (double)raw->duty_cycle); - return false; - - } else if((raw->timings_size <= 0) || (raw->timings_size > MAX_TIMINGS_AMOUNT)) { - FURI_LOG_E( - TAG, - "Timings amount is out of range (0 - %X): %X", - MAX_TIMINGS_AMOUNT, - raw->timings_size); - return false; - } - - return true; -} - -static inline bool infrared_signal_save_message(InfraredMessage* message, FlipperFormat* ff) { - const char* protocol_name = infrared_get_protocol_name(message->protocol); - return flipper_format_write_string_cstr(ff, "type", "parsed") && - flipper_format_write_string_cstr(ff, "protocol", protocol_name) && - flipper_format_write_hex(ff, "address", (uint8_t*)&message->address, 4) && - flipper_format_write_hex(ff, "command", (uint8_t*)&message->command, 4); -} - -static inline bool infrared_signal_save_raw(InfraredRawSignal* raw, FlipperFormat* ff) { - furi_assert(raw->timings_size <= MAX_TIMINGS_AMOUNT); - return flipper_format_write_string_cstr(ff, "type", "raw") && - flipper_format_write_uint32(ff, "frequency", &raw->frequency, 1) && - flipper_format_write_float(ff, "duty_cycle", &raw->duty_cycle, 1) && - flipper_format_write_uint32(ff, "data", raw->timings, raw->timings_size); -} - -static inline bool infrared_signal_read_message(InfraredSignal* signal, FlipperFormat* ff) { - FuriString* buf; - buf = furi_string_alloc(); - bool success = false; - - do { - if(!flipper_format_read_string(ff, "protocol", buf)) break; - - InfraredMessage message; - message.protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf)); - - success = flipper_format_read_hex(ff, "address", (uint8_t*)&message.address, 4) && - flipper_format_read_hex(ff, "command", (uint8_t*)&message.command, 4) && - infrared_signal_is_message_valid(&message); - - if(!success) break; - - infrared_signal_set_message(signal, &message); - } while(0); - - furi_string_free(buf); - return success; -} - -static inline bool infrared_signal_read_raw(InfraredSignal* signal, FlipperFormat* ff) { - uint32_t timings_size, frequency; - float duty_cycle; - - bool success = flipper_format_read_uint32(ff, "frequency", &frequency, 1) && - flipper_format_read_float(ff, "duty_cycle", &duty_cycle, 1) && - flipper_format_get_value_count(ff, "data", &timings_size); - - if(!success || timings_size > MAX_TIMINGS_AMOUNT) { - return false; - } - - uint32_t* timings = malloc(sizeof(uint32_t) * timings_size); - success = flipper_format_read_uint32(ff, "data", timings, timings_size); - - if(success) { - infrared_signal_set_raw_signal(signal, timings, timings_size, frequency, duty_cycle); - } - - free(timings); - return success; -} - -static bool infrared_signal_read_body(InfraredSignal* signal, FlipperFormat* ff) { - FuriString* tmp = furi_string_alloc(); - - bool success = false; - - do { - if(!flipper_format_read_string(ff, "type", tmp)) break; - if(furi_string_equal(tmp, "raw")) { - success = infrared_signal_read_raw(signal, ff); - } else if(furi_string_equal(tmp, "parsed")) { - success = infrared_signal_read_message(signal, ff); - } else { - FURI_LOG_E(TAG, "Unknown signal type"); - } - } while(false); - - furi_string_free(tmp); - return success; -} - -InfraredSignal* infrared_signal_alloc(void) { - InfraredSignal* signal = malloc(sizeof(InfraredSignal)); - - signal->is_raw = false; - signal->payload.message.protocol = InfraredProtocolUnknown; - - return signal; -} - -void infrared_signal_free(InfraredSignal* signal) { - infrared_signal_clear_timings(signal); - free(signal); -} - -bool infrared_signal_is_raw(InfraredSignal* signal) { - return signal->is_raw; -} - -bool infrared_signal_is_valid(InfraredSignal* signal) { - return signal->is_raw ? infrared_signal_is_raw_valid(&signal->payload.raw) : - infrared_signal_is_message_valid(&signal->payload.message); -} - -void infrared_signal_set_signal(InfraredSignal* signal, const InfraredSignal* other) { - if(other->is_raw) { - const InfraredRawSignal* raw = &other->payload.raw; - infrared_signal_set_raw_signal( - signal, raw->timings, raw->timings_size, raw->frequency, raw->duty_cycle); - } else { - const InfraredMessage* message = &other->payload.message; - infrared_signal_set_message(signal, message); - } -} - -void infrared_signal_set_raw_signal( - InfraredSignal* signal, - const uint32_t* timings, - size_t timings_size, - uint32_t frequency, - float duty_cycle) { - infrared_signal_clear_timings(signal); - - signal->is_raw = true; - - signal->payload.raw.timings_size = timings_size; - signal->payload.raw.frequency = frequency; - signal->payload.raw.duty_cycle = duty_cycle; - - signal->payload.raw.timings = malloc(timings_size * sizeof(uint32_t)); - memcpy(signal->payload.raw.timings, timings, timings_size * sizeof(uint32_t)); -} - -InfraredRawSignal* infrared_signal_get_raw_signal(InfraredSignal* signal) { - furi_assert(signal->is_raw); - return &signal->payload.raw; -} - -void infrared_signal_set_message(InfraredSignal* signal, const InfraredMessage* message) { - infrared_signal_clear_timings(signal); - - signal->is_raw = false; - signal->payload.message = *message; -} - -InfraredMessage* infrared_signal_get_message(InfraredSignal* signal) { - furi_assert(!signal->is_raw); - return &signal->payload.message; -} - -bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name) { - if(!flipper_format_write_comment_cstr(ff, "") || - !flipper_format_write_string_cstr(ff, "name", name)) { - return false; - } else if(signal->is_raw) { - return infrared_signal_save_raw(&signal->payload.raw, ff); - } else { - return infrared_signal_save_message(&signal->payload.message, ff); - } -} - -bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name) { - FuriString* tmp = furi_string_alloc(); - - bool success = false; - - do { - if(!flipper_format_read_string(ff, "name", tmp)) break; - furi_string_set(name, tmp); - if(!infrared_signal_read_body(signal, ff)) break; - success = true; - } while(0); - - furi_string_free(tmp); - return success; -} - -bool infrared_signal_search_and_read( - InfraredSignal* signal, - FlipperFormat* ff, - const FuriString* name) { - bool success = false; - FuriString* tmp = furi_string_alloc(); - - do { - bool is_name_found = false; - while(flipper_format_read_string(ff, "name", tmp)) { - is_name_found = furi_string_equal(name, tmp); - if(is_name_found) break; - } - if(!is_name_found) break; - if(!infrared_signal_read_body(signal, ff)) break; - success = true; - } while(false); - - furi_string_free(tmp); - return success; -} - -void infrared_signal_transmit(InfraredSignal* signal) { - if(signal->is_raw) { - InfraredRawSignal* raw_signal = &signal->payload.raw; - infrared_send_raw_ext( - raw_signal->timings, - raw_signal->timings_size, - true, - raw_signal->frequency, - raw_signal->duty_cycle); - } else { - InfraredMessage* message = &signal->payload.message; - infrared_send(message, 2); - } -} diff --git a/applications/system/ir_remote/infrared_signal.h b/applications/system/ir_remote/infrared_signal.h deleted file mode 100644 index e0ef355d9..000000000 --- a/applications/system/ir_remote/infrared_signal.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include - -typedef struct InfraredSignal InfraredSignal; - -typedef struct { - size_t timings_size; - uint32_t* timings; - uint32_t frequency; - float duty_cycle; -} InfraredRawSignal; - -InfraredSignal* infrared_signal_alloc(void); -void infrared_signal_free(InfraredSignal* signal); - -bool infrared_signal_is_raw(InfraredSignal* signal); -bool infrared_signal_is_valid(InfraredSignal* signal); - -void infrared_signal_set_signal(InfraredSignal* signal, const InfraredSignal* other); - -void infrared_signal_set_raw_signal( - InfraredSignal* signal, - const uint32_t* timings, - size_t timings_size, - uint32_t frequency, - float duty_cycle); -InfraredRawSignal* infrared_signal_get_raw_signal(InfraredSignal* signal); - -void infrared_signal_set_message(InfraredSignal* signal, const InfraredMessage* message); -InfraredMessage* infrared_signal_get_message(InfraredSignal* signal); - -bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name); -bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name); -bool infrared_signal_search_and_read( - InfraredSignal* signal, - FlipperFormat* ff, - const FuriString* name); - -void infrared_signal_transmit(InfraredSignal* signal); diff --git a/applications/system/ir_remote/ir_10px.png b/applications/system/ir_remote/ir_10px.png deleted file mode 100644 index 22c986180..000000000 Binary files a/applications/system/ir_remote/ir_10px.png and /dev/null differ diff --git a/applications/system/mass_storage/application.fam b/applications/system/mass_storage/application.fam deleted file mode 100644 index 48af27d59..000000000 --- a/applications/system/mass_storage/application.fam +++ /dev/null @@ -1,16 +0,0 @@ -App( - appid="mass_storage", - name="Mass Storage", - apptype=FlipperAppType.EXTERNAL, - entry_point="mass_storage_app", - requires=[ - "gui", - "dialogs", - ], - stack_size=2 * 1024, - fap_description="Implements a mass storage device over USB for disk images", - fap_version="1.3", - fap_icon="assets/floppydisk_10px.png", - fap_icon_assets="assets", - fap_category="USB", -) diff --git a/applications/system/mass_storage/assets/floppydisk_10px.png b/applications/system/mass_storage/assets/floppydisk_10px.png deleted file mode 100644 index 91af40ba7..000000000 Binary files a/applications/system/mass_storage/assets/floppydisk_10px.png and /dev/null differ diff --git a/applications/system/mass_storage/helpers/mass_storage_scsi.c b/applications/system/mass_storage/helpers/mass_storage_scsi.c deleted file mode 100644 index c1efacf8e..000000000 --- a/applications/system/mass_storage/helpers/mass_storage_scsi.c +++ /dev/null @@ -1,266 +0,0 @@ -#include "mass_storage_scsi.h" - -#include - -#define TAG "MassStorageSCSI" - -#define SCSI_TEST_UNIT_READY (0x00) -#define SCSI_REQUEST_SENSE (0x03) -#define SCSI_INQUIRY (0x12) -#define SCSI_READ_FORMAT_CAPACITIES (0x23) -#define SCSI_READ_CAPACITY_10 (0x25) -#define SCSI_MODE_SENSE_6 (0x1A) -#define SCSI_READ_10 (0x28) -#define SCSI_PREVENT_MEDIUM_REMOVAL (0x1E) -#define SCSI_START_STOP_UNIT (0x1B) -#define SCSI_WRITE_10 (0x2A) - -bool scsi_cmd_start(SCSISession* scsi, uint8_t* cmd, uint8_t len) { - if(!len) { - scsi->sk = SCSI_SK_ILLEGAL_REQUEST; - scsi->asc = SCSI_ASC_INVALID_COMMAND_OPERATION_CODE; - return false; - } - FURI_LOG_T(TAG, "START %02X", cmd[0]); - scsi->cmd = cmd; - scsi->cmd_len = len; - scsi->rx_done = false; - scsi->tx_done = false; - switch(cmd[0]) { - case SCSI_WRITE_10: { - if(len < 10) return false; - scsi->write_10.lba = cmd[2] << 24 | cmd[3] << 16 | cmd[4] << 8 | cmd[5]; - scsi->write_10.count = cmd[7] << 8 | cmd[8]; - FURI_LOG_D(TAG, "SCSI_WRITE_10 %08lX %04X", scsi->write_10.lba, scsi->write_10.count); - return true; - }; break; - case SCSI_READ_10: { - if(len < 10) return false; - scsi->read_10.lba = cmd[2] << 24 | cmd[3] << 16 | cmd[4] << 8 | cmd[5]; - scsi->read_10.count = cmd[7] << 8 | cmd[8]; - FURI_LOG_D(TAG, "SCSI_READ_10 %08lX %04X", scsi->read_10.lba, scsi->read_10.count); - return true; - }; break; - } - return true; -} - -bool scsi_cmd_rx_data(SCSISession* scsi, uint8_t* data, uint32_t len) { - FURI_LOG_T(TAG, "RX %02X len %lu", scsi->cmd[0], len); - if(scsi->rx_done) return false; - switch(scsi->cmd[0]) { - case SCSI_WRITE_10: { - uint32_t block_size = SCSI_BLOCK_SIZE; - uint16_t blocks = len / block_size; - bool result = - scsi->fn.write(scsi->fn.ctx, scsi->write_10.lba, blocks, data, blocks * block_size); - scsi->write_10.lba += blocks; - scsi->write_10.count -= blocks; - if(!scsi->write_10.count) { - scsi->rx_done = true; - } - return result; - }; break; - default: { - FURI_LOG_W(TAG, "unexpected scsi rx data cmd=%02X", scsi->cmd[0]); - scsi->sk = SCSI_SK_ILLEGAL_REQUEST; - scsi->asc = SCSI_ASC_INVALID_COMMAND_OPERATION_CODE; - return false; - }; break; - } -} - -bool scsi_cmd_tx_data(SCSISession* scsi, uint8_t* data, uint32_t* len, uint32_t cap) { - FURI_LOG_T(TAG, "TX %02X cap %lu", scsi->cmd[0], cap); - if(scsi->tx_done) return false; - switch(scsi->cmd[0]) { - case SCSI_REQUEST_SENSE: { - FURI_LOG_D(TAG, "SCSI_REQUEST_SENSE"); - if(cap < 18) return false; - memset(data, 0, cap); - data[0] = 0x70; // fixed format sense data - data[1] = 0; // obsolete - data[2] = scsi->sk; // sense key - data[3] = 0; // information - data[4] = 0; // information - data[5] = 0; // information - data[6] = 0; // information - data[7] = 10; // additional sense length (len-8) - data[8] = 0; // command specific information - data[9] = 0; // command specific information - data[10] = 0; // command specific information - data[11] = 0; // command specific information - data[12] = scsi->asc; // additional sense code - data[13] = 0; // additional sense code qualifier - data[14] = 0; // field replaceable unit code - data[15] = 0; // sense key specific information - data[16] = 0; // sense key specific information - data[17] = 0; // sense key specific information - *len = 18; - scsi->sk = 0; - scsi->asc = 0; - scsi->tx_done = true; - return true; - }; break; - case SCSI_INQUIRY: { - FURI_LOG_D(TAG, "SCSI_INQUIRY"); - if(scsi->cmd_len < 5) return false; - - if(cap < 36) return false; - - bool evpd = scsi->cmd[1] & 1; - uint8_t page_code = scsi->cmd[2]; - if(evpd == 0) { - if(page_code != 0) return false; - - data[0] = 0x00; // device type: direct access block device - data[1] = 0x80; // removable: true - data[2] = 0x04; // version - data[3] = 0x02; // response data format - data[4] = 31; // additional length (len - 5) - data[5] = 0; // flags - data[6] = 0; // flags - data[7] = 0; // flags - memcpy(data + 8, "Flipper ", 8); // vendor id - memcpy(data + 16, "Mass Storage ", 16); // product id - memcpy(data + 32, "0001", 4); // product revision level - *len = 36; - scsi->tx_done = true; - return true; - } else { - if(page_code != 0x80) { - FURI_LOG_W(TAG, "Unsupported VPD code %02X", page_code); - return false; - } - data[0] = 0x00; - data[1] = 0x80; - data[2] = 0x00; - data[3] = 0x01; // Serial len - data[4] = '0'; - *len = 5; - scsi->tx_done = true; - return true; - } - }; break; - case SCSI_READ_FORMAT_CAPACITIES: { - FURI_LOG_D(TAG, "SCSI_READ_FORMAT_CAPACITIES"); - if(cap < 12) { - return false; - } - uint32_t n_blocks = scsi->fn.num_blocks(scsi->fn.ctx); - uint32_t block_size = SCSI_BLOCK_SIZE; - // Capacity List Header - data[0] = 0; - data[1] = 0; - data[2] = 0; - data[3] = 8; - - // Capacity Descriptor - data[4] = (n_blocks - 1) >> 24; - data[5] = (n_blocks - 1) >> 16; - data[6] = (n_blocks - 1) >> 8; - data[7] = (n_blocks - 1) & 0xFF; - data[8] = 0x02; // Formatted media - data[9] = block_size >> 16; - data[10] = block_size >> 8; - data[11] = block_size & 0xFF; - *len = 12; - scsi->tx_done = true; - return true; - }; break; - case SCSI_READ_CAPACITY_10: { - FURI_LOG_D(TAG, "SCSI_READ_CAPACITY_10"); - if(cap < 8) return false; - uint32_t n_blocks = scsi->fn.num_blocks(scsi->fn.ctx); - uint32_t block_size = SCSI_BLOCK_SIZE; - data[0] = (n_blocks - 1) >> 24; - data[1] = (n_blocks - 1) >> 16; - data[2] = (n_blocks - 1) >> 8; - data[3] = (n_blocks - 1) & 0xFF; - data[4] = block_size >> 24; - data[5] = block_size >> 16; - data[6] = block_size >> 8; - data[7] = block_size & 0xFF; - *len = 8; - scsi->tx_done = true; - return true; - }; break; - case SCSI_MODE_SENSE_6: { - FURI_LOG_D(TAG, "SCSI_MODE_SENSE_6 %lu", cap); - if(cap < 4) return false; - data[0] = 3; // mode data length (len - 1) - data[1] = 0; // medium type - data[2] = 0; // device-specific parameter - data[3] = 0; // block descriptor length - *len = 4; - scsi->tx_done = true; - return true; - }; break; - case SCSI_READ_10: { - uint32_t block_size = SCSI_BLOCK_SIZE; - bool result = - scsi->fn.read(scsi->fn.ctx, scsi->read_10.lba, scsi->read_10.count, data, len, cap); - *len -= *len % block_size; - uint16_t blocks = *len / block_size; - scsi->read_10.lba += blocks; - scsi->read_10.count -= blocks; - if(!scsi->read_10.count) { - scsi->tx_done = true; - } - return result; - }; break; - default: { - FURI_LOG_W(TAG, "unexpected scsi tx data cmd=%02X", scsi->cmd[0]); - scsi->sk = SCSI_SK_ILLEGAL_REQUEST; - scsi->asc = SCSI_ASC_INVALID_COMMAND_OPERATION_CODE; - return false; - }; break; - } -} - -bool scsi_cmd_end(SCSISession* scsi) { - FURI_LOG_T(TAG, "END %02X", scsi->cmd[0]); - uint8_t* cmd = scsi->cmd; - uint8_t len = scsi->cmd_len; - scsi->cmd = NULL; - scsi->cmd_len = 0; - switch(cmd[0]) { - case SCSI_WRITE_10: - return scsi->rx_done; - - case SCSI_REQUEST_SENSE: - case SCSI_INQUIRY: - case SCSI_READ_FORMAT_CAPACITIES: - case SCSI_READ_CAPACITY_10: - case SCSI_MODE_SENSE_6: - case SCSI_READ_10: - return scsi->tx_done; - - case SCSI_TEST_UNIT_READY: { - FURI_LOG_D(TAG, "SCSI_TEST_UNIT_READY"); - return true; - }; break; - case SCSI_PREVENT_MEDIUM_REMOVAL: { - if(len < 6) return false; - bool prevent = cmd[5]; - FURI_LOG_D(TAG, "SCSI_PREVENT_MEDIUM_REMOVAL prevent=%d", prevent); - return !prevent; - }; break; - case SCSI_START_STOP_UNIT: { - if(len < 6) return false; - bool eject = (cmd[4] & 2) != 0; - bool start = (cmd[4] & 1) != 0; - FURI_LOG_D(TAG, "SCSI_START_STOP_UNIT eject=%d start=%d", eject, start); - if(eject) { - scsi->fn.eject(scsi->fn.ctx); - } - return true; - }; break; - default: { - FURI_LOG_W(TAG, "unexpected scsi cmd=%02X", cmd[0]); - scsi->sk = SCSI_SK_ILLEGAL_REQUEST; - scsi->asc = SCSI_ASC_INVALID_COMMAND_OPERATION_CODE; - return false; - }; break; - } -} diff --git a/applications/system/mass_storage/helpers/mass_storage_scsi.h b/applications/system/mass_storage/helpers/mass_storage_scsi.h deleted file mode 100644 index a35d6aff3..000000000 --- a/applications/system/mass_storage/helpers/mass_storage_scsi.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include - -#define SCSI_BLOCK_SIZE (0x200UL) - -#define SCSI_SK_ILLEGAL_REQUEST (5) - -#define SCSI_ASC_INVALID_COMMAND_OPERATION_CODE (0x20) -#define SCSI_ASC_LBA_OOB (0x21) -#define SCSI_ASC_INVALID_FIELD_IN_CDB (0x24) - -typedef struct { - void* ctx; - bool (*read)( - void* ctx, - uint32_t lba, - uint16_t count, - uint8_t* out, - uint32_t* out_len, - uint32_t out_cap); - bool (*write)(void* ctx, uint32_t lba, uint16_t count, uint8_t* buf, uint32_t len); - uint32_t (*num_blocks)(void* ctx); - void (*eject)(void* ctx); -} SCSIDeviceFunc; - -typedef struct { - SCSIDeviceFunc fn; - - uint8_t* cmd; - uint8_t cmd_len; - bool rx_done; - bool tx_done; - - uint8_t sk; // sense key - uint8_t asc; // additional sense code - - // command-specific data - // valid from cmd_start to cmd_end - union { - struct { - uint16_t count; - uint32_t lba; - } read_10; // SCSI_READ_10 - - struct { - uint16_t count; - uint32_t lba; - } write_10; // SCSI_WRITE_10 - }; -} SCSISession; - -bool scsi_cmd_start(SCSISession* scsi, uint8_t* cmd, uint8_t len); -bool scsi_cmd_rx_data(SCSISession* scsi, uint8_t* data, uint32_t len); -bool scsi_cmd_tx_data(SCSISession* scsi, uint8_t* data, uint32_t* len, uint32_t cap); -bool scsi_cmd_end(SCSISession* scsi); \ No newline at end of file diff --git a/applications/system/mass_storage/helpers/mass_storage_usb.c b/applications/system/mass_storage/helpers/mass_storage_usb.c deleted file mode 100644 index f493203a6..000000000 --- a/applications/system/mass_storage/helpers/mass_storage_usb.c +++ /dev/null @@ -1,481 +0,0 @@ -#include "mass_storage_usb.h" -#include - -#define TAG "MassStorageUsb" - -#define USB_MSC_RX_EP (0x01) -#define USB_MSC_TX_EP (0x82) - -#define USB_MSC_RX_EP_SIZE (64UL) -#define USB_MSC_TX_EP_SIZE (64UL) - -#define USB_MSC_BOT_GET_MAX_LUN (0xFE) -#define USB_MSC_BOT_RESET (0xFF) - -#define CBW_SIG (0x43425355) -#define CBW_FLAGS_DEVICE_TO_HOST (0x80) - -#define CSW_SIG (0x53425355) -#define CSW_STATUS_OK (0) -#define CSW_STATUS_NOK (1) -#define CSW_STATUS_PHASE_ERROR (2) - -// must be SCSI_BLOCK_SIZE aligned -// larger than 0x10000 exceeds size_t, storage_file_* ops fail -#define USB_MSC_BUF_MAX (0x10000UL - SCSI_BLOCK_SIZE) - -static usbd_respond usb_ep_config(usbd_device* dev, uint8_t cfg); -static usbd_respond usb_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback); - -typedef enum { - EventExit = 1 << 0, - EventReset = 1 << 1, - EventRxTx = 1 << 2, - - EventAll = EventExit | EventReset | EventRxTx, -} MassStorageEvent; - -typedef struct { - uint32_t sig; - uint32_t tag; - uint32_t len; - uint8_t flags; - uint8_t lun; - uint8_t cmd_len; - uint8_t cmd[16]; -} __attribute__((packed)) CBW; - -typedef struct { - uint32_t sig; - uint32_t tag; - uint32_t residue; - uint8_t status; -} __attribute__((packed)) CSW; - -struct MassStorageUsb { - FuriHalUsbInterface usb; - FuriHalUsbInterface* usb_prev; - - FuriThread* thread; - usbd_device* dev; - SCSIDeviceFunc fn; -}; - -static int32_t mass_thread_worker(void* context) { - MassStorageUsb* mass = context; - usbd_device* dev = mass->dev; - SCSISession scsi = { - .fn = mass->fn, - }; - CBW cbw = {0}; - CSW csw = {0}; - uint8_t* buf = NULL; - uint32_t buf_len = 0, buf_cap = 0, buf_sent = 0; - enum { - StateReadCBW, - StateReadData, - StateWriteData, - StateBuildCSW, - StateWriteCSW, - } state = StateReadCBW; - while(true) { - uint32_t flags = furi_thread_flags_wait(EventAll, FuriFlagWaitAny, FuriWaitForever); - if(flags & EventExit) { - FURI_LOG_D(TAG, "exit"); - break; - } - if(flags & EventReset) { - FURI_LOG_D(TAG, "reset"); - scsi.sk = 0; - scsi.asc = 0; - memset(&cbw, 0, sizeof(cbw)); - memset(&csw, 0, sizeof(csw)); - if(buf) { - free(buf); - buf = NULL; - } - buf_len = buf_cap = buf_sent = 0; - state = StateReadCBW; - } - if(flags & EventRxTx) do { - switch(state) { - case StateReadCBW: { - FURI_LOG_T(TAG, "StateReadCBW"); - int32_t len = usbd_ep_read(dev, USB_MSC_RX_EP, &cbw, sizeof(cbw)); - if(len <= 0) { - FURI_LOG_T(TAG, "cbw not ready"); - break; - } - if(len != sizeof(cbw) || cbw.sig != CBW_SIG) { - FURI_LOG_W(TAG, "bad cbw sig=%08lx", cbw.sig); - usbd_ep_stall(dev, USB_MSC_TX_EP); - usbd_ep_stall(dev, USB_MSC_RX_EP); - continue; - } - if(!scsi_cmd_start(&scsi, cbw.cmd, cbw.cmd_len)) { - FURI_LOG_W(TAG, "bad cmd"); - usbd_ep_stall(dev, USB_MSC_RX_EP); - csw.sig = CSW_SIG; - csw.tag = cbw.tag; - csw.status = CSW_STATUS_NOK; - state = StateWriteCSW; - continue; - } - if(cbw.flags & CBW_FLAGS_DEVICE_TO_HOST) { - buf_len = 0; - buf_sent = 0; - state = StateWriteData; - } else { - buf_len = 0; - state = StateReadData; - } - continue; - }; break; - case StateReadData: { - FURI_LOG_T(TAG, "StateReadData %lu/%lu", buf_len, cbw.len); - if(!cbw.len) { - state = StateBuildCSW; - continue; - } - uint32_t buf_clamp = MIN(cbw.len, USB_MSC_BUF_MAX); - if(buf_clamp > buf_cap) { - FURI_LOG_T(TAG, "growing buf %lu -> %lu", buf_cap, buf_clamp); - if(buf) { - free(buf); - } - buf_cap = buf_clamp; - buf = malloc(buf_cap); - } - if(buf_len < buf_clamp) { - int32_t len = - usbd_ep_read(dev, USB_MSC_RX_EP, buf + buf_len, buf_clamp - buf_len); - if(len < 0) { - FURI_LOG_T(TAG, "rx not ready %ld", len); - break; - } - FURI_LOG_T(TAG, "clamp %lu len %ld", buf_clamp, len); - buf_len += len; - } - if(buf_len == buf_clamp) { - if(!scsi_cmd_rx_data(&scsi, buf, buf_len)) { - FURI_LOG_W(TAG, "short rx"); - usbd_ep_stall(dev, USB_MSC_RX_EP); - csw.sig = CSW_SIG; - csw.tag = cbw.tag; - csw.status = CSW_STATUS_NOK; - csw.residue = cbw.len; - state = StateWriteCSW; - continue; - } - cbw.len -= buf_len; - buf_len = 0; - } - continue; - }; break; - case StateWriteData: { - FURI_LOG_T(TAG, "StateWriteData %lu", cbw.len); - if(!cbw.len) { - state = StateBuildCSW; - continue; - } - uint32_t buf_clamp = MIN(cbw.len, USB_MSC_BUF_MAX); - if(buf_clamp > buf_cap) { - FURI_LOG_T(TAG, "growing buf %lu -> %lu", buf_cap, buf_clamp); - if(buf) { - free(buf); - } - buf_cap = buf_clamp; - buf = malloc(buf_cap); - } - if(!buf_len && !scsi_cmd_tx_data(&scsi, buf, &buf_len, buf_clamp)) { - FURI_LOG_W(TAG, "short tx"); - // usbd_ep_stall(dev, USB_MSC_TX_EP); - state = StateBuildCSW; - continue; - } - int32_t len = usbd_ep_write( - dev, - USB_MSC_TX_EP, - buf + buf_sent, - MIN(USB_MSC_TX_EP_SIZE, buf_len - buf_sent)); - if(len < 0) { - FURI_LOG_T(TAG, "tx not ready %ld", len); - break; - } - buf_sent += len; - if(buf_sent == buf_len) { - cbw.len -= buf_len; - buf_len = 0; - buf_sent = 0; - } - continue; - }; break; - case StateBuildCSW: { - FURI_LOG_T(TAG, "StateBuildCSW"); - csw.sig = CSW_SIG; - csw.tag = cbw.tag; - if(scsi_cmd_end(&scsi)) { - csw.status = CSW_STATUS_OK; - } else { - csw.status = CSW_STATUS_NOK; - } - csw.residue = cbw.len; - state = StateWriteCSW; - continue; - }; break; - case StateWriteCSW: { - FURI_LOG_T(TAG, "StateWriteCSW"); - if(csw.status) { - FURI_LOG_W( - TAG, - "csw sig=%08lx tag=%08lx residue=%08lx status=%02x", - csw.sig, - csw.tag, - csw.residue, - csw.status); - } - int32_t len = usbd_ep_write(dev, USB_MSC_TX_EP, &csw, sizeof(csw)); - if(len < 0) { - FURI_LOG_T(TAG, "csw not ready"); - break; - } - if(len != sizeof(csw)) { - FURI_LOG_W(TAG, "bad csw write %ld", len); - usbd_ep_stall(dev, USB_MSC_TX_EP); - break; - } - memset(&cbw, 0, sizeof(cbw)); - memset(&csw, 0, sizeof(csw)); - state = StateReadCBW; - continue; - }; break; - } - break; - } while(true); - } - if(buf) { - free(buf); - } - return 0; -} - -// needed in usb_deinit, usb_suspend, usb_rxtx_ep_callback, usb_control, -// where if_ctx isn't passed -static MassStorageUsb* mass_cur = NULL; - -static void usb_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) { - UNUSED(intf); - MassStorageUsb* mass = ctx; - mass_cur = mass; - mass->dev = dev; - - usbd_reg_config(dev, usb_ep_config); - usbd_reg_control(dev, usb_control); - usbd_connect(dev, true); - - mass->thread = furi_thread_alloc(); - furi_thread_set_name(mass->thread, "MassStorageUsb"); - furi_thread_set_stack_size(mass->thread, 1024); - furi_thread_set_context(mass->thread, ctx); - furi_thread_set_callback(mass->thread, mass_thread_worker); - furi_thread_start(mass->thread); -} - -static void usb_deinit(usbd_device* dev) { - usbd_reg_config(dev, NULL); - usbd_reg_control(dev, NULL); - - MassStorageUsb* mass = mass_cur; - if(!mass || mass->dev != dev) { - FURI_LOG_E(TAG, "deinit mass_cur leak"); - return; - } - mass_cur = NULL; - - furi_assert(mass->thread); - furi_thread_flags_set(furi_thread_get_id(mass->thread), EventExit); - furi_thread_join(mass->thread); - furi_thread_free(mass->thread); - mass->thread = NULL; - - free(mass->usb.str_prod_descr); - mass->usb.str_prod_descr = NULL; - free(mass->usb.str_serial_descr); - mass->usb.str_serial_descr = NULL; - free(mass); -} - -static void usb_wakeup(usbd_device* dev) { - UNUSED(dev); -} - -static void usb_suspend(usbd_device* dev) { - MassStorageUsb* mass = mass_cur; - if(!mass || mass->dev != dev) return; - furi_thread_flags_set(furi_thread_get_id(mass->thread), EventReset); -} - -static void usb_rxtx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { - UNUSED(ep); - UNUSED(event); - MassStorageUsb* mass = mass_cur; - if(!mass || mass->dev != dev) return; - furi_thread_flags_set(furi_thread_get_id(mass->thread), EventRxTx); -} - -static usbd_respond usb_ep_config(usbd_device* dev, uint8_t cfg) { - switch(cfg) { - case 0: // deconfig - usbd_ep_deconfig(dev, USB_MSC_RX_EP); - usbd_ep_deconfig(dev, USB_MSC_TX_EP); - usbd_reg_endpoint(dev, USB_MSC_RX_EP, NULL); - usbd_reg_endpoint(dev, USB_MSC_TX_EP, NULL); - return usbd_ack; - case 1: // config - usbd_ep_config( - dev, USB_MSC_RX_EP, USB_EPTYPE_BULK /* | USB_EPTYPE_DBLBUF*/, USB_MSC_RX_EP_SIZE); - usbd_ep_config( - dev, USB_MSC_TX_EP, USB_EPTYPE_BULK /* | USB_EPTYPE_DBLBUF*/, USB_MSC_TX_EP_SIZE); - usbd_reg_endpoint(dev, USB_MSC_RX_EP, usb_rxtx_ep_callback); - usbd_reg_endpoint(dev, USB_MSC_TX_EP, usb_rxtx_ep_callback); - return usbd_ack; - } - return usbd_fail; -} - -static usbd_respond usb_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback) { - UNUSED(callback); - if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) != - (USB_REQ_INTERFACE | USB_REQ_CLASS)) { - return usbd_fail; - } - switch(req->bRequest) { - case USB_MSC_BOT_GET_MAX_LUN: { - static uint8_t max_lun = 0; - dev->status.data_ptr = &max_lun; - dev->status.data_count = 1; - return usbd_ack; - }; break; - case USB_MSC_BOT_RESET: { - MassStorageUsb* mass = mass_cur; - if(!mass || mass->dev != dev) return usbd_fail; - furi_thread_flags_set(furi_thread_get_id(mass->thread), EventReset); - return usbd_ack; - }; break; - } - return usbd_fail; -} - -static const struct usb_string_descriptor dev_manuf_desc = USB_STRING_DESC("Flipper Devices Inc."); - -struct MassStorageDescriptor { - struct usb_config_descriptor config; - struct usb_interface_descriptor intf; - struct usb_endpoint_descriptor ep_rx; - struct usb_endpoint_descriptor ep_tx; -} __attribute__((packed)); - -static const struct usb_device_descriptor usb_mass_dev_descr = { - .bLength = sizeof(struct usb_device_descriptor), - .bDescriptorType = USB_DTYPE_DEVICE, - .bcdUSB = VERSION_BCD(2, 0, 0), - .bDeviceClass = USB_CLASS_PER_INTERFACE, - .bDeviceSubClass = USB_SUBCLASS_NONE, - .bDeviceProtocol = USB_PROTO_NONE, - .bMaxPacketSize0 = 8, // USB_EP0_SIZE - .idVendor = 0x0483, - .idProduct = 0x5720, - .bcdDevice = VERSION_BCD(1, 0, 0), - .iManufacturer = 1, // UsbDevManuf - .iProduct = 2, // UsbDevProduct - .iSerialNumber = 3, // UsbDevSerial - .bNumConfigurations = 1, -}; - -static const struct MassStorageDescriptor usb_mass_cfg_descr = { - .config = - { - .bLength = sizeof(struct usb_config_descriptor), - .bDescriptorType = USB_DTYPE_CONFIGURATION, - .wTotalLength = sizeof(struct MassStorageDescriptor), - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = NO_DESCRIPTOR, - .bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED, - .bMaxPower = USB_CFG_POWER_MA(100), - }, - .intf = - { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DTYPE_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = 0x06, // scsi transparent - .bInterfaceProtocol = 0x50, // bulk only - .iInterface = NO_DESCRIPTOR, - }, - .ep_rx = - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DTYPE_ENDPOINT, - .bEndpointAddress = USB_MSC_RX_EP, - .bmAttributes = USB_EPTYPE_BULK, - .wMaxPacketSize = USB_MSC_RX_EP_SIZE, - .bInterval = 0, - }, - .ep_tx = - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DTYPE_ENDPOINT, - .bEndpointAddress = USB_MSC_TX_EP, - .bmAttributes = USB_EPTYPE_BULK, - .wMaxPacketSize = USB_MSC_TX_EP_SIZE, - .bInterval = 0, - }, -}; - -MassStorageUsb* mass_storage_usb_start(const char* filename, SCSIDeviceFunc fn) { - MassStorageUsb* mass = malloc(sizeof(MassStorageUsb)); - mass->usb_prev = furi_hal_usb_get_config(); - mass->usb.init = usb_init; - mass->usb.deinit = usb_deinit; - mass->usb.wakeup = usb_wakeup; - mass->usb.suspend = usb_suspend; - mass->usb.dev_descr = (struct usb_device_descriptor*)&usb_mass_dev_descr; - mass->usb.str_manuf_descr = (void*)&dev_manuf_desc; - mass->usb.str_prod_descr = NULL; - mass->usb.str_serial_descr = NULL; - mass->usb.cfg_descr = (void*)&usb_mass_cfg_descr; - - const char* name = furi_hal_version_get_device_name_ptr(); - if(!name) name = "Flipper Zero"; - size_t len = strlen(name); - struct usb_string_descriptor* str_prod_descr = malloc(len * 2 + 2); - str_prod_descr->bLength = len * 2 + 2; - str_prod_descr->bDescriptorType = USB_DTYPE_STRING; - for(uint8_t i = 0; i < len; i++) str_prod_descr->wString[i] = name[i]; - mass->usb.str_prod_descr = str_prod_descr; - - len = strlen(filename); - struct usb_string_descriptor* str_serial_descr = malloc(len * 2 + 2); - str_serial_descr->bLength = len * 2 + 2; - str_serial_descr->bDescriptorType = USB_DTYPE_STRING; - for(uint8_t i = 0; i < len; i++) str_serial_descr->wString[i] = filename[i]; - mass->usb.str_serial_descr = str_serial_descr; - - mass->fn = fn; - if(!furi_hal_usb_set_config(&mass->usb, mass)) { - FURI_LOG_E(TAG, "USB locked, cannot start Mass Storage"); - free(mass->usb.str_prod_descr); - free(mass->usb.str_serial_descr); - free(mass); - return NULL; - } - return mass; -} - -void mass_storage_usb_stop(MassStorageUsb* mass) { - furi_hal_usb_set_config(mass->usb_prev, NULL); -} diff --git a/applications/system/mass_storage/helpers/mass_storage_usb.h b/applications/system/mass_storage/helpers/mass_storage_usb.h deleted file mode 100644 index 0f370f98e..000000000 --- a/applications/system/mass_storage/helpers/mass_storage_usb.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include -#include "mass_storage_scsi.h" - -typedef struct MassStorageUsb MassStorageUsb; - -MassStorageUsb* mass_storage_usb_start(const char* filename, SCSIDeviceFunc fn); -void mass_storage_usb_stop(MassStorageUsb* mass); diff --git a/applications/system/mass_storage/mass_storage_app.c b/applications/system/mass_storage/mass_storage_app.c deleted file mode 100644 index 497708f0c..000000000 --- a/applications/system/mass_storage/mass_storage_app.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "mass_storage_app_i.h" -#include -#include -#include - -static bool mass_storage_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - MassStorageApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool mass_storage_app_back_event_callback(void* context) { - furi_assert(context); - MassStorageApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void mass_storage_app_tick_event_callback(void* context) { - furi_assert(context); - MassStorageApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -void mass_storage_app_show_loading_popup(MassStorageApp* app, bool show) { - if(show) { - // Raise timer priority so that animations can play - furi_timer_set_thread_priority(FuriTimerThreadPriorityElevated); - view_dispatcher_switch_to_view(app->view_dispatcher, MassStorageAppViewLoading); - } else { - // Restore default timer priority - furi_timer_set_thread_priority(FuriTimerThreadPriorityNormal); - } -} - -MassStorageApp* mass_storage_app_alloc(char* arg) { - MassStorageApp* app = malloc(sizeof(MassStorageApp)); - app->file_path = furi_string_alloc(); - - if(arg != NULL) { - furi_string_set_str(app->file_path, arg); - } else { - furi_string_set_str(app->file_path, MASS_STORAGE_APP_PATH_FOLDER); - } - - app->gui = furi_record_open(RECORD_GUI); - app->fs_api = furi_record_open(RECORD_STORAGE); - app->dialogs = furi_record_open(RECORD_DIALOGS); - - app->create_image_size = (uint8_t)-1; - SDInfo sd_info; - if(storage_sd_info(app->fs_api, &sd_info) == FSE_OK) { - switch(sd_info.fs_type) { - case FST_FAT12: - app->create_image_max = 16LL * 1024 * 1024; - break; - case FST_FAT16: - app->create_image_max = 2LL * 1024 * 1024 * 1024; - break; - case FST_FAT32: - app->create_image_max = 4LL * 1024 * 1024 * 1024; - break; - default: - app->create_image_max = 0; - break; - } - } - - app->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_enable_queue(app->view_dispatcher); - - app->scene_manager = scene_manager_alloc(&mass_storage_scene_handlers, app); - - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, mass_storage_app_tick_event_callback, 500); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, mass_storage_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, mass_storage_app_back_event_callback); - - app->mass_storage_view = mass_storage_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - MassStorageAppViewWork, - mass_storage_get_view(app->mass_storage_view)); - - app->text_input = text_input_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, MassStorageAppViewTextInput, text_input_get_view(app->text_input)); - - app->loading = loading_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, MassStorageAppViewLoading, loading_get_view(app->loading)); - - app->variable_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - MassStorageAppViewStart, - variable_item_list_get_view(app->variable_item_list)); - - app->popup = popup_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, MassStorageAppViewPopup, popup_get_view(app->popup)); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - if(storage_file_exists(app->fs_api, furi_string_get_cstr(app->file_path))) { - scene_manager_next_scene(app->scene_manager, MassStorageSceneWork); - } else { - scene_manager_next_scene(app->scene_manager, MassStorageSceneStart); - } - - return app; -} - -void mass_storage_app_free(MassStorageApp* app) { - furi_assert(app); - - // Views - view_dispatcher_remove_view(app->view_dispatcher, MassStorageAppViewWork); - view_dispatcher_remove_view(app->view_dispatcher, MassStorageAppViewTextInput); - view_dispatcher_remove_view(app->view_dispatcher, MassStorageAppViewStart); - view_dispatcher_remove_view(app->view_dispatcher, MassStorageAppViewLoading); - view_dispatcher_remove_view(app->view_dispatcher, MassStorageAppViewPopup); - - mass_storage_free(app->mass_storage_view); - text_input_free(app->text_input); - variable_item_list_free(app->variable_item_list); - loading_free(app->loading); - popup_free(app->popup); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - furi_string_free(app->file_path); - - // Close records - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_STORAGE); - furi_record_close(RECORD_DIALOGS); - - free(app); -} - -int32_t mass_storage_app(void* p) { - MassStorageApp* mass_storage_app = mass_storage_app_alloc((char*)p); - view_dispatcher_run(mass_storage_app->view_dispatcher); - mass_storage_app_free(mass_storage_app); - return 0; -} diff --git a/applications/system/mass_storage/mass_storage_app.h b/applications/system/mass_storage/mass_storage_app.h deleted file mode 100644 index 820ad2b6c..000000000 --- a/applications/system/mass_storage/mass_storage_app.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct MassStorageApp MassStorageApp; - -#ifdef __cplusplus -} -#endif diff --git a/applications/system/mass_storage/mass_storage_app_i.h b/applications/system/mass_storage/mass_storage_app_i.h deleted file mode 100644 index 952fe429a..000000000 --- a/applications/system/mass_storage/mass_storage_app_i.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include "mass_storage_app.h" -#include "scenes/mass_storage_scene.h" -#include "helpers/mass_storage_usb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "views/mass_storage_view.h" -#include - -#include - -#define MASS_STORAGE_APP_PATH_FOLDER STORAGE_APP_DATA_PATH_PREFIX -#define MASS_STORAGE_APP_EXTENSION ".img" -#define MASS_STORAGE_FILE_NAME_LEN 40 - -struct MassStorageApp { - Gui* gui; - Storage* fs_api; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - Popup* popup; - DialogsApp* dialogs; - TextInput* text_input; - VariableItemList* variable_item_list; - Loading* loading; - - FuriString* file_path; - File* file; - MassStorage* mass_storage_view; - - FuriMutex* usb_mutex; - MassStorageUsb* usb; - - uint64_t create_image_max; - uint8_t create_image_size; - char create_image_name[MASS_STORAGE_FILE_NAME_LEN]; - - uint32_t bytes_read, bytes_written; -}; - -typedef enum { - MassStorageAppViewStart, - MassStorageAppViewTextInput, - MassStorageAppViewWork, - MassStorageAppViewLoading, - MassStorageAppViewPopup, -} MassStorageAppView; - -enum MassStorageCustomEvent { - // Reserve first 100 events for button types and indexes, starting from 0 - MassStorageCustomEventReserved = 100, - - MassStorageCustomEventEject, -}; - -void mass_storage_app_show_loading_popup(MassStorageApp* app, bool show); diff --git a/applications/system/mass_storage/scenes/mass_storage_scene.c b/applications/system/mass_storage/scenes/mass_storage_scene.c deleted file mode 100644 index bab24ca40..000000000 --- a/applications/system/mass_storage/scenes/mass_storage_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "mass_storage_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const mass_storage_scene_on_enter_handlers[])(void*) = { -#include "mass_storage_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const mass_storage_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "mass_storage_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const mass_storage_scene_on_exit_handlers[])(void* context) = { -#include "mass_storage_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers mass_storage_scene_handlers = { - .on_enter_handlers = mass_storage_scene_on_enter_handlers, - .on_event_handlers = mass_storage_scene_on_event_handlers, - .on_exit_handlers = mass_storage_scene_on_exit_handlers, - .scene_num = MassStorageSceneNum, -}; diff --git a/applications/system/mass_storage/scenes/mass_storage_scene.h b/applications/system/mass_storage/scenes/mass_storage_scene.h deleted file mode 100644 index d43bb4c97..000000000 --- a/applications/system/mass_storage/scenes/mass_storage_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) MassStorageScene##id, -typedef enum { -#include "mass_storage_scene_config.h" - MassStorageSceneNum, -} MassStorageScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers mass_storage_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "mass_storage_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "mass_storage_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "mass_storage_scene_config.h" -#undef ADD_SCENE diff --git a/applications/system/mass_storage/scenes/mass_storage_scene_config.h b/applications/system/mass_storage/scenes/mass_storage_scene_config.h deleted file mode 100644 index ff0418fdf..000000000 --- a/applications/system/mass_storage/scenes/mass_storage_scene_config.h +++ /dev/null @@ -1,5 +0,0 @@ -ADD_SCENE(mass_storage, start, Start) -ADD_SCENE(mass_storage, file_select, FileSelect) -ADD_SCENE(mass_storage, work, Work) -ADD_SCENE(mass_storage, create_image, CreateImage) -ADD_SCENE(mass_storage, create_image_name, CreateImageName) diff --git a/applications/system/mass_storage/scenes/mass_storage_scene_create_image.c b/applications/system/mass_storage/scenes/mass_storage_scene_create_image.c deleted file mode 100644 index c1b6ca46a..000000000 --- a/applications/system/mass_storage/scenes/mass_storage_scene_create_image.c +++ /dev/null @@ -1,193 +0,0 @@ -#include "../mass_storage_app_i.h" -#include - -enum VarItemListIndex { - VarItemListIndexImageSize, - VarItemListIndexImageName, - VarItemListIndexCreateImage, -}; - -void mass_storage_scene_create_image_variable_item_list_callback(void* context, uint32_t index) { - MassStorageApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -static const struct { - char* name; - uint64_t value; -} image_sizes[] = { - {"1MB", 1LL * 1024 * 1024}, - {"2MB", 2LL * 1024 * 1024}, - {"4MB", 4LL * 1024 * 1024}, - {"8MB", 8LL * 1024 * 1024}, - {"16MB", 16LL * 1024 * 1024}, - {"32MB", 32LL * 1024 * 1024}, - {"64MB", 64LL * 1024 * 1024}, - {"128MB", 128LL * 1024 * 1024}, - {"256MB", 256LL * 1024 * 1024}, - {"512MB", 512LL * 1024 * 1024}, - {"1GB", 1LL * 1024 * 1024 * 1024}, - {"2GB", 2LL * 1024 * 1024 * 1024}, - {"4GB", 4LL * 1024 * 1024 * 1024}, - {"8GB", 8LL * 1024 * 1024 * 1024}, - {"16GB", 16LL * 1024 * 1024 * 1024}, - {"32GB", 32LL * 1024 * 1024 * 1024}, - {"64GB", 64LL * 1024 * 1024 * 1024}, - {"128GB", 128LL * 1024 * 1024 * 1024}, - {"256GB", 256LL * 1024 * 1024 * 1024}, - {"512GB", 512LL * 1024 * 1024 * 1024}, -}; -static void mass_storage_scene_create_image_image_size_changed(VariableItem* item) { - MassStorageApp* app = variable_item_get_context(item); - app->create_image_size = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, image_sizes[app->create_image_size].name); -} - -void mass_storage_scene_create_image_on_enter(void* context) { - MassStorageApp* app = context; - VariableItemList* variable_item_list = app->variable_item_list; - VariableItem* item; - - uint8_t size_count = COUNT_OF(image_sizes); - if(app->create_image_max) { - for(size_t i = 1; i < size_count; i++) { - if(image_sizes[i].value > app->create_image_max) { - size_count = i; - break; - } - } - } - if(app->create_image_size == (uint8_t)-1) { - app->create_image_size = CLAMP(7, size_count - 2, 0); // 7 = 128MB - } - item = variable_item_list_add( - variable_item_list, - "Image Size", - size_count, - mass_storage_scene_create_image_image_size_changed, - app); - variable_item_set_current_value_index(item, app->create_image_size); - variable_item_set_current_value_text(item, image_sizes[app->create_image_size].name); - - item = variable_item_list_add(variable_item_list, "Image Name", 0, NULL, app); - variable_item_set_current_value_text(item, app->create_image_name); - - variable_item_list_add(variable_item_list, "Create Image", 0, NULL, app); - - variable_item_list_set_enter_callback( - variable_item_list, mass_storage_scene_create_image_variable_item_list_callback, app); - - variable_item_list_set_header(variable_item_list, "Create Disk Image"); - - variable_item_list_set_selected_item( - variable_item_list, - scene_manager_get_scene_state(app->scene_manager, MassStorageSceneCreateImage)); - - view_dispatcher_switch_to_view(app->view_dispatcher, MassStorageAppViewStart); -} - -static void popup_callback_ok(void* context) { - MassStorageApp* app = context; - scene_manager_set_scene_state( - app->scene_manager, MassStorageSceneStart, MassStorageSceneFileSelect); - scene_manager_previous_scene(app->scene_manager); - scene_manager_next_scene(app->scene_manager, MassStorageSceneFileSelect); -} - -static void popup_callback_error(void* context) { - MassStorageApp* app = context; - view_dispatcher_switch_to_view(app->view_dispatcher, MassStorageAppViewStart); -} - -bool mass_storage_scene_create_image_on_event(void* context, SceneManagerEvent event) { - MassStorageApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - scene_manager_set_scene_state( - app->scene_manager, MassStorageSceneCreateImage, event.event); - consumed = true; - switch(event.event) { - case VarItemListIndexImageName: - scene_manager_next_scene(app->scene_manager, MassStorageSceneCreateImageName); - break; - case VarItemListIndexCreateImage: { - mass_storage_app_show_loading_popup(app, true); - const char* name = strnlen(app->create_image_name, sizeof(app->create_image_name)) ? - app->create_image_name : - image_sizes[app->create_image_size].name; - furi_string_printf( - app->file_path, - "%s/%s%s", - MASS_STORAGE_APP_PATH_FOLDER, - name, - MASS_STORAGE_APP_EXTENSION); - - app->file = storage_file_alloc(app->fs_api); - const char* error = NULL; - bool success = false; - - do { - if(!storage_file_open( - app->file, - furi_string_get_cstr(app->file_path), - FSAM_READ | FSAM_WRITE, - FSOM_CREATE_NEW)) - break; - - uint64_t size = image_sizes[app->create_image_size].value; - if(size == app->create_image_max) size--; - if(!storage_file_expand(app->file, size)) break; - - // Format as exFAT - error = "Image formatting failed"; - if(storage_virtual_init(app->fs_api, app->file) != FSE_OK) { - if(storage_virtual_quit(app->fs_api) != FSE_OK) break; - if(storage_virtual_init(app->fs_api, app->file) != FSE_OK) break; - } - if(storage_virtual_format(app->fs_api) == FSE_OK) { - success = true; - error = NULL; - } - storage_virtual_quit(app->fs_api); - } while(false); - - if(!success) { - error = storage_file_get_error_desc(app->file); - FS_Error error = storage_file_get_error(app->file); - storage_file_close(app->file); - if(error != FSE_EXIST) { - storage_common_remove(app->fs_api, furi_string_get_cstr(app->file_path)); - } - } - storage_file_free(app->file); - mass_storage_app_show_loading_popup(app, false); - - if(error) { - popup_set_header( - app->popup, "Error Creating Image!", 64, 26, AlignCenter, AlignCenter); - popup_set_text(app->popup, error, 64, 40, AlignCenter, AlignCenter); - popup_set_callback(app->popup, popup_callback_error); - } else { - popup_set_header(app->popup, "Image Created!", 64, 32, AlignCenter, AlignCenter); - popup_set_text(app->popup, "", 0, 0, AlignLeft, AlignBottom); - popup_set_callback(app->popup, popup_callback_ok); - } - popup_set_context(app->popup, app); - popup_set_timeout(app->popup, 0); - popup_disable_timeout(app->popup); - view_dispatcher_switch_to_view(app->view_dispatcher, MassStorageAppViewPopup); - break; - } - default: - break; - } - } - - return consumed; -} - -void mass_storage_scene_create_image_on_exit(void* context) { - MassStorageApp* app = context; - variable_item_list_reset(app->variable_item_list); -} diff --git a/applications/system/mass_storage/scenes/mass_storage_scene_create_image_name.c b/applications/system/mass_storage/scenes/mass_storage_scene_create_image_name.c deleted file mode 100644 index 38efa7cb6..000000000 --- a/applications/system/mass_storage/scenes/mass_storage_scene_create_image_name.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "../mass_storage_app_i.h" - -enum TextInputIndex { - TextInputResultOk, -}; - -static void mass_storage_scene_create_image_name_text_input_callback(void* context) { - MassStorageApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, TextInputResultOk); -} - -void mass_storage_scene_create_image_name_on_enter(void* context) { - MassStorageApp* app = context; - TextInput* text_input = app->text_input; - - text_input_set_header_text(text_input, "Image name, empty = default"); - - text_input_set_minimum_length(text_input, 0); - - text_input_set_result_callback( - text_input, - mass_storage_scene_create_image_name_text_input_callback, - app, - app->create_image_name, - sizeof(app->create_image_name), - false); - - view_dispatcher_switch_to_view(app->view_dispatcher, MassStorageAppViewTextInput); -} - -bool mass_storage_scene_create_image_name_on_event(void* context, SceneManagerEvent event) { - MassStorageApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - consumed = true; - switch(event.event) { - case TextInputResultOk: - scene_manager_previous_scene(app->scene_manager); - break; - default: - break; - } - } - - return consumed; -} - -void mass_storage_scene_create_image_name_on_exit(void* context) { - MassStorageApp* app = context; - text_input_reset(app->text_input); -} diff --git a/applications/system/mass_storage/scenes/mass_storage_scene_file_select.c b/applications/system/mass_storage/scenes/mass_storage_scene_file_select.c deleted file mode 100644 index b1c7c180c..000000000 --- a/applications/system/mass_storage/scenes/mass_storage_scene_file_select.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "../mass_storage_app_i.h" -#include "furi_hal_power.h" - -static bool mass_storage_file_select(MassStorageApp* mass_storage) { - furi_assert(mass_storage); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, ".img|.iso", &I_floppydisk_10px); - browser_options.base_path = MASS_STORAGE_APP_PATH_FOLDER; - browser_options.hide_ext = false; - - // Input events and views are managed by file_select - bool res = dialog_file_browser_show( - mass_storage->dialogs, mass_storage->file_path, mass_storage->file_path, &browser_options); - return res; -} - -void mass_storage_scene_file_select_on_enter(void* context) { - MassStorageApp* mass_storage = context; - - if(mass_storage_file_select(mass_storage)) { - scene_manager_next_scene(mass_storage->scene_manager, MassStorageSceneWork); - } else { - scene_manager_previous_scene(mass_storage->scene_manager); - } -} - -bool mass_storage_scene_file_select_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - // MassStorageApp* mass_storage = context; - return false; -} - -void mass_storage_scene_file_select_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/system/mass_storage/scenes/mass_storage_scene_start.c b/applications/system/mass_storage/scenes/mass_storage_scene_start.c deleted file mode 100644 index 5ae40d84c..000000000 --- a/applications/system/mass_storage/scenes/mass_storage_scene_start.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "../mass_storage_app_i.h" - -enum VarItemListIndex { - VarItemListIndexSelectDiskImage, - VarItemListIndexCreateDiskImage, -}; - -static void mass_storage_scene_start_variable_item_list_callback(void* context, uint32_t index) { - MassStorageApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void mass_storage_scene_start_on_enter(void* context) { - MassStorageApp* app = context; - VariableItemList* variable_item_list = app->variable_item_list; - - variable_item_list_add(variable_item_list, "Select Disk Image", 0, NULL, app); - - variable_item_list_add(variable_item_list, "Create Disk Image", 0, NULL, app); - - variable_item_list_set_enter_callback( - variable_item_list, mass_storage_scene_start_variable_item_list_callback, app); - - variable_item_list_set_header(variable_item_list, "USB Mass Storage"); - - variable_item_list_set_selected_item( - variable_item_list, - scene_manager_get_scene_state(app->scene_manager, MassStorageSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, MassStorageAppViewStart); -} - -bool mass_storage_scene_start_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - MassStorageApp* app = context; - - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - scene_manager_set_scene_state(app->scene_manager, MassStorageSceneStart, event.event); - consumed = true; - switch(event.event) { - case VarItemListIndexSelectDiskImage: - scene_manager_next_scene(app->scene_manager, MassStorageSceneFileSelect); - break; - case VarItemListIndexCreateDiskImage: - scene_manager_set_scene_state(app->scene_manager, MassStorageSceneCreateImage, 0); - scene_manager_next_scene(app->scene_manager, MassStorageSceneCreateImage); - break; - default: - break; - } - } - - return consumed; -} - -void mass_storage_scene_start_on_exit(void* context) { - UNUSED(context); - MassStorageApp* app = context; - variable_item_list_reset(app->variable_item_list); -} diff --git a/applications/system/mass_storage/scenes/mass_storage_scene_work.c b/applications/system/mass_storage/scenes/mass_storage_scene_work.c deleted file mode 100644 index 1ae27852c..000000000 --- a/applications/system/mass_storage/scenes/mass_storage_scene_work.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "../mass_storage_app_i.h" -#include "../views/mass_storage_view.h" -#include "../helpers/mass_storage_usb.h" -#include - -#define TAG "MassStorageSceneWork" - -static bool file_read( - void* ctx, - uint32_t lba, - uint16_t count, - uint8_t* out, - uint32_t* out_len, - uint32_t out_cap) { - MassStorageApp* app = ctx; - FURI_LOG_T(TAG, "file_read lba=%08lX count=%04X out_cap=%08lX", lba, count, out_cap); - if(!storage_file_seek(app->file, lba * SCSI_BLOCK_SIZE, true)) { - FURI_LOG_W(TAG, "seek failed"); - return false; - } - uint16_t clamp = MIN(out_cap, count * SCSI_BLOCK_SIZE); - *out_len = storage_file_read(app->file, out, clamp); - FURI_LOG_T(TAG, "%lu/%lu", *out_len, count * SCSI_BLOCK_SIZE); - app->bytes_read += *out_len; - return *out_len == clamp; -} - -static bool file_write(void* ctx, uint32_t lba, uint16_t count, uint8_t* buf, uint32_t len) { - MassStorageApp* app = ctx; - FURI_LOG_T(TAG, "file_write lba=%08lX count=%04X len=%08lX", lba, count, len); - if(len != count * SCSI_BLOCK_SIZE) { - FURI_LOG_W(TAG, "bad write params count=%u len=%lu", count, len); - return false; - } - if(!storage_file_seek(app->file, lba * SCSI_BLOCK_SIZE, true)) { - FURI_LOG_W(TAG, "seek failed"); - return false; - } - app->bytes_written += len; - return storage_file_write(app->file, buf, len) == len; -} - -static uint32_t file_num_blocks(void* ctx) { - MassStorageApp* app = ctx; - return storage_file_size(app->file) / SCSI_BLOCK_SIZE; -} - -static void file_eject(void* ctx) { - MassStorageApp* app = ctx; - FURI_LOG_D(TAG, "EJECT"); - view_dispatcher_send_custom_event(app->view_dispatcher, MassStorageCustomEventEject); -} - -bool mass_storage_scene_work_on_event(void* context, SceneManagerEvent event) { - MassStorageApp* app = context; - bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == MassStorageCustomEventEject) { - consumed = scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, MassStorageSceneFileSelect); - if(!consumed) { - consumed = scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, MassStorageSceneStart); - } - } - } else if(event.type == SceneManagerEventTypeTick) { - mass_storage_set_stats(app->mass_storage_view, app->bytes_read, app->bytes_written); - } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, MassStorageSceneFileSelect); - if(!consumed) { - consumed = scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, MassStorageSceneStart); - } - } - return consumed; -} - -void mass_storage_scene_work_on_enter(void* context) { - MassStorageApp* app = context; - app->bytes_read = app->bytes_written = 0; - - if(!storage_file_exists(app->fs_api, furi_string_get_cstr(app->file_path))) { - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, MassStorageSceneStart); - return; - } - - mass_storage_app_show_loading_popup(app, true); - - app->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - - FuriString* file_name = furi_string_alloc(); - path_extract_filename(app->file_path, file_name, true); - - mass_storage_set_file_name(app->mass_storage_view, file_name); - app->file = storage_file_alloc(app->fs_api); - furi_assert(storage_file_open( - app->file, - furi_string_get_cstr(app->file_path), - FSAM_READ | FSAM_WRITE, - FSOM_OPEN_EXISTING)); - - SCSIDeviceFunc fn = { - .ctx = app, - .read = file_read, - .write = file_write, - .num_blocks = file_num_blocks, - .eject = file_eject, - }; - - furi_hal_usb_unlock(); - app->usb = mass_storage_usb_start(furi_string_get_cstr(file_name), fn); - - furi_string_free(file_name); - - mass_storage_app_show_loading_popup(app, false); - view_dispatcher_switch_to_view(app->view_dispatcher, MassStorageAppViewWork); -} - -void mass_storage_scene_work_on_exit(void* context) { - MassStorageApp* app = context; - mass_storage_app_show_loading_popup(app, true); - - if(app->usb_mutex) { - furi_mutex_free(app->usb_mutex); - app->usb_mutex = NULL; - } - if(app->usb) { - mass_storage_usb_stop(app->usb); - app->usb = NULL; - } - if(app->file) { - storage_file_free(app->file); - app->file = NULL; - } - mass_storage_app_show_loading_popup(app, false); -} diff --git a/applications/system/mass_storage/views/mass_storage_view.c b/applications/system/mass_storage/views/mass_storage_view.c deleted file mode 100644 index 25eeb5c19..000000000 --- a/applications/system/mass_storage/views/mass_storage_view.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "mass_storage_view.h" -#include "../mass_storage_app_i.h" -#include - -struct MassStorage { - View* view; -}; - -typedef struct { - FuriString *file_name, *status_string; - uint32_t read_speed, write_speed; - uint32_t bytes_read, bytes_written; - uint32_t update_time; -} MassStorageModel; - -static void append_suffixed_byte_count(FuriString* string, uint32_t count) { - if(count < 1024) { - furi_string_cat_printf(string, "%luB", count); - } else if(count < 1024 * 1024) { - furi_string_cat_printf(string, "%luK", count / 1024); - } else if(count < 1024 * 1024 * 1024) { - furi_string_cat_printf(string, "%.1fM", (double)count / (1024 * 1024)); - } else { - furi_string_cat_printf(string, "%.1fG", (double)count / (1024 * 1024 * 1024)); - } -} - -static void mass_storage_draw_callback(Canvas* canvas, void* _model) { - MassStorageModel* model = _model; - - canvas_draw_icon(canvas, 8, 14, &I_Drive_112x35); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned( - canvas, canvas_width(canvas) / 2, 0, AlignCenter, AlignTop, "USB Mass Storage"); - - canvas_set_font(canvas, FontBatteryPercent); - elements_string_fit_width(canvas, model->file_name, 89 - 2); - canvas_draw_str_aligned( - canvas, 92, 24, AlignRight, AlignBottom, furi_string_get_cstr(model->file_name)); - - furi_string_set_str(model->status_string, "R:"); - append_suffixed_byte_count(model->status_string, model->bytes_read); - if(model->read_speed) { - furi_string_cat_str(model->status_string, "/"); - append_suffixed_byte_count(model->status_string, model->read_speed); - furi_string_cat_str(model->status_string, "s"); - } - canvas_draw_str(canvas, 14, 34, furi_string_get_cstr(model->status_string)); - - furi_string_set_str(model->status_string, "W:"); - append_suffixed_byte_count(model->status_string, model->bytes_written); - if(model->write_speed) { - furi_string_cat_str(model->status_string, "/"); - append_suffixed_byte_count(model->status_string, model->write_speed); - furi_string_cat_str(model->status_string, "s"); - } - canvas_draw_str(canvas, 14, 43, furi_string_get_cstr(model->status_string)); -} - -MassStorage* mass_storage_alloc() { - MassStorage* mass_storage = malloc(sizeof(MassStorage)); - - mass_storage->view = view_alloc(); - view_allocate_model(mass_storage->view, ViewModelTypeLocking, sizeof(MassStorageModel)); - with_view_model( - mass_storage->view, - MassStorageModel * model, - { - model->file_name = furi_string_alloc(); - model->status_string = furi_string_alloc(); - }, - false); - view_set_context(mass_storage->view, mass_storage); - view_set_draw_callback(mass_storage->view, mass_storage_draw_callback); - - return mass_storage; -} - -void mass_storage_free(MassStorage* mass_storage) { - furi_assert(mass_storage); - with_view_model( - mass_storage->view, - MassStorageModel * model, - { - furi_string_free(model->file_name); - furi_string_free(model->status_string); - }, - false); - view_free(mass_storage->view); - free(mass_storage); -} - -View* mass_storage_get_view(MassStorage* mass_storage) { - furi_assert(mass_storage); - return mass_storage->view; -} - -void mass_storage_set_file_name(MassStorage* mass_storage, FuriString* name) { - furi_assert(name); - with_view_model( - mass_storage->view, - MassStorageModel * model, - { furi_string_set(model->file_name, name); }, - true); -} - -void mass_storage_set_stats(MassStorage* mass_storage, uint32_t read, uint32_t written) { - with_view_model( - mass_storage->view, - MassStorageModel * model, - { - uint32_t now = furi_get_tick(); - model->read_speed = (read - model->bytes_read) * 1000 / (now - model->update_time); - model->write_speed = - (written - model->bytes_written) * 1000 / (now - model->update_time); - model->bytes_read = read; - model->bytes_written = written; - model->update_time = now; - }, - true); -} diff --git a/applications/system/mass_storage/views/mass_storage_view.h b/applications/system/mass_storage/views/mass_storage_view.h deleted file mode 100644 index 2edbf2a62..000000000 --- a/applications/system/mass_storage/views/mass_storage_view.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -typedef struct MassStorage MassStorage; - -MassStorage* mass_storage_alloc(); - -void mass_storage_free(MassStorage* mass_storage); - -View* mass_storage_get_view(MassStorage* mass_storage); - -void mass_storage_set_file_name(MassStorage* mass_storage, FuriString* name); - -void mass_storage_set_stats(MassStorage* mass_storage, uint32_t read, uint32_t written); diff --git a/applications/system/nightstand/application.fam b/applications/system/nightstand/application.fam deleted file mode 100644 index 380c34b16..000000000 --- a/applications/system/nightstand/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="nightstand", - name="Nightstand Clock", - apptype=FlipperAppType.EXTERNAL, - entry_point="clock_app", - requires=["gui"], - stack_size=2 * 1024, - fap_icon="clock.png", - fap_category="Tools", - fap_author="@nymda & @Willy-JL", - fap_weburl="https://github.com/nymda/FlipperNightStand", - fap_version="1.0", - fap_description="Clock with screen brightness controls", -) diff --git a/applications/system/nightstand/clock.png b/applications/system/nightstand/clock.png deleted file mode 100644 index 8a5406e6c..000000000 Binary files a/applications/system/nightstand/clock.png and /dev/null differ diff --git a/applications/system/nightstand/clock_app.c b/applications/system/nightstand/clock_app.c deleted file mode 100644 index e8d00906b..000000000 --- a/applications/system/nightstand/clock_app.c +++ /dev/null @@ -1,366 +0,0 @@ -#include -#include - -#include -#include - -#include -#include - -#include "clock_app.h" - -/* - This is a modified version of the default clock app intended for use overnight - Up / Down controls the displays brightness. Down at brightness 0 turns the notification LED on and off. -*/ - -int brightness = 5; -bool led = false; -NotificationApp* notif = 0; - -int dspBrightnessBarFrames = 0; -const int dspBrightnessBarDisplayFrames = 8; - -const NotificationMessage message_red_dim = { - .type = NotificationMessageTypeLedRed, - .data.led.value = 0xFF / 16, -}; - -const NotificationMessage message_red_off = { - .type = NotificationMessageTypeLedRed, - .data.led.value = 0x00, -}; - -static const NotificationSequence led_on = { - &message_red_dim, - &message_do_not_reset, - NULL, -}; - -static const NotificationSequence led_off = { - &message_red_off, - &message_do_not_reset, - NULL, -}; - -static const NotificationSequence led_reset = { - &message_red_0, - NULL, -}; - -void set_backlight_brightness(float brightness) { - notif->settings.display_brightness = brightness; - notification_message(notif, &sequence_display_backlight_on); -} - -void handle_up() { - dspBrightnessBarFrames = dspBrightnessBarDisplayFrames; - if(brightness < 100) { - led = false; - notification_message(notif, &led_off); - brightness += 5; - } - set_backlight_brightness((float)(brightness / 100.f)); -} - -void handle_down() { - dspBrightnessBarFrames = dspBrightnessBarDisplayFrames; - if(brightness > 0) { - brightness -= 5; - if(brightness == 0) { //trigger only on the first brightness 5 -> 0 transition - led = true; - notification_message(notif, &led_on); - } - } else if(brightness == 0) { //trigger on every down press afterwards - led = !led; - if(led) { - notification_message(notif, &led_on); - } else { - notification_message(notif, &led_off); - } - } - set_backlight_brightness((float)(brightness / 100.f)); -} - -static void clock_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -//do you are have stupid? -void elements_progress_bar_vertical( - Canvas* canvas, - uint8_t x, - uint8_t y, - uint8_t height, - float progress) { - furi_assert(canvas); - furi_assert((progress >= 0) && (progress <= 1.0)); - uint8_t width = 9; - - uint8_t progress_length = roundf((1.f - progress) * (height - 2)); - - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, x + 1, y + 1, width - 2, height - 2); - - canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, x + 1, y + 1, width - 2, progress_length); - - canvas_set_color(canvas, ColorBlack); - canvas_draw_rframe(canvas, x, y, width, height, 3); -} - -static void clock_render_callback(Canvas* const canvas, void* ctx) { - //canvas_clear(canvas); - //canvas_set_color(canvas, ColorBlack); - - //avoids a bug with the brightness being reverted after the backlight-off period - set_backlight_brightness((float)(brightness / 100.f)); - - if(dspBrightnessBarFrames > 0) { - elements_progress_bar_vertical(canvas, 119, 1, 62, (float)(brightness / 100.f)); - dspBrightnessBarFrames--; - } - - ClockState* state = ctx; - if(furi_mutex_acquire(state->mutex, 200) != FuriStatusOk) { - //FURI_LOG_D(TAG, "Can't obtain mutex, requeue render"); - PluginEvent event = {.type = EventTypeTick}; - furi_message_queue_put(state->event_queue, &event, 0); - return; - } - - DateTime curr_dt; - furi_hal_rtc_get_datetime(&curr_dt); - uint32_t curr_ts = datetime_datetime_to_timestamp(&curr_dt); - - char time_string[TIME_LEN]; - char date_string[DATE_LEN]; - char meridian_string[MERIDIAN_LEN]; - char timer_string[20]; - - if(state->time_format == LocaleTimeFormat24h) { - snprintf( - time_string, TIME_LEN, CLOCK_TIME_FORMAT, curr_dt.hour, curr_dt.minute, curr_dt.second); - } else { - bool pm = curr_dt.hour > 12; - bool pm12 = curr_dt.hour >= 12; - snprintf( - time_string, - TIME_LEN, - CLOCK_TIME_FORMAT, - pm ? curr_dt.hour - 12 : curr_dt.hour, - curr_dt.minute, - curr_dt.second); - - snprintf( - meridian_string, - MERIDIAN_LEN, - MERIDIAN_FORMAT, - pm12 ? MERIDIAN_STRING_PM : MERIDIAN_STRING_AM); - } - - if(state->date_format == LocaleDateFormatYMD) { - snprintf( - date_string, DATE_LEN, CLOCK_ISO_DATE_FORMAT, curr_dt.year, curr_dt.month, curr_dt.day); - } else if(state->date_format == LocaleDateFormatMDY) { - snprintf( - date_string, DATE_LEN, CLOCK_RFC_DATE_FORMAT, curr_dt.month, curr_dt.day, curr_dt.year); - } else { - snprintf( - date_string, DATE_LEN, CLOCK_RFC_DATE_FORMAT, curr_dt.day, curr_dt.month, curr_dt.year); - } - - bool timer_running = state->timer_running; - uint32_t timer_start_timestamp = state->timer_start_timestamp; - uint32_t timer_stopped_seconds = state->timer_stopped_seconds; - - furi_mutex_release(state->mutex); - - canvas_set_font(canvas, FontBigNumbers); - - if(timer_start_timestamp != 0) { - int32_t elapsed_secs = timer_running ? (curr_ts - timer_start_timestamp) : - timer_stopped_seconds; - snprintf(timer_string, 20, "%.2ld:%.2ld", elapsed_secs / 60, elapsed_secs % 60); - canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, time_string); // DRAW TIME - canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignTop, timer_string); // DRAW TIMER - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignTop, date_string); // DRAW DATE - elements_button_left(canvas, "Reset"); - } else { - canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, time_string); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 65, 17, AlignCenter, AlignCenter, date_string); - - if(state->time_format == LocaleTimeFormat12h) - canvas_draw_str_aligned(canvas, 64, 47, AlignCenter, AlignCenter, meridian_string); - } - if(timer_running) { - elements_button_center(canvas, "Stop"); - } else if(timer_start_timestamp != 0 && !timer_running) { - elements_button_center(canvas, "Start"); - } -} - -static void clock_state_init(ClockState* const state) { - state->time_format = locale_get_time_format(); - - state->date_format = locale_get_date_format(); - - //FURI_LOG_D(TAG, "Time format: %s", state->settings.time_format == H12 ? "12h" : "24h"); - //FURI_LOG_D(TAG, "Date format: %s", state->settings.date_format == Iso ? "ISO 8601" : "RFC 5322"); - //furi_hal_rtc_get_datetime(&state->datetime); -} - -// Runs every 1000ms by default -static void clock_tick(void* ctx) { - furi_assert(ctx); - FuriMessageQueue* event_queue = ctx; - PluginEvent event = {.type = EventTypeTick}; - // It's OK to loose this event if system overloaded - furi_message_queue_put(event_queue, &event, 0); -} - -void timer_start_stop(ClockState* plugin_state) { - // START/STOP TIMER - uint32_t curr_ts = furi_hal_rtc_get_timestamp(); - - if(plugin_state->timer_running) { - // Update stopped seconds - plugin_state->timer_stopped_seconds = curr_ts - plugin_state->timer_start_timestamp; - } else { - if(plugin_state->timer_start_timestamp == 0) { - // Set starting timestamp if this is first time - plugin_state->timer_start_timestamp = curr_ts; - } else { - // Timer was already running, need to slightly readjust so we don't - // count the intervening time - plugin_state->timer_start_timestamp = curr_ts - plugin_state->timer_stopped_seconds; - } - } - plugin_state->timer_running = !plugin_state->timer_running; -} - -void timer_reset_seconds(ClockState* plugin_state) { - if(plugin_state->timer_start_timestamp != 0) { - // Reset seconds - plugin_state->timer_running = false; - plugin_state->timer_start_timestamp = 0; - plugin_state->timer_stopped_seconds = 0; - } -} - -int32_t clock_app(void* p) { - UNUSED(p); - ClockState* plugin_state = malloc(sizeof(ClockState)); - - plugin_state->event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - if(plugin_state->event_queue == NULL) { - FURI_LOG_E(TAG, "Cannot create event queue"); - free(plugin_state); - return 255; - } - //FURI_LOG_D(TAG, "Event queue created"); - - plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(plugin_state->mutex == NULL) { - FURI_LOG_E(TAG, "Cannot create mutex"); - furi_message_queue_free(plugin_state->event_queue); - free(plugin_state); - return 255; - } - //FURI_LOG_D(TAG, "Mutex created"); - - clock_state_init(plugin_state); - - notif = furi_record_open(RECORD_NOTIFICATION); - float tmpBrightness = notif->settings.display_brightness; - brightness = tmpBrightness * 100; // Keep current brightness by default - - notification_message(notif, &sequence_display_backlight_enforce_on); - notification_message(notif, &led_off); - - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, clock_render_callback, plugin_state); - view_port_input_callback_set(view_port, clock_input_callback, plugin_state->event_queue); - - FuriTimer* timer = - furi_timer_alloc(clock_tick, FuriTimerTypePeriodic, plugin_state->event_queue); - - if(timer == NULL) { - FURI_LOG_E(TAG, "Cannot create timer"); - furi_mutex_free(plugin_state->mutex); - furi_message_queue_free(plugin_state->event_queue); - free(plugin_state); - return 255; - } - //FURI_LOG_D(TAG, "Timer created"); - - // Open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - furi_timer_start(timer, furi_kernel_get_tick_frequency()); - //FURI_LOG_D(TAG, "Timer started"); - - // Main loop - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(plugin_state->event_queue, &event, 100); - - if(event_status != FuriStatusOk) continue; - - if(furi_mutex_acquire(plugin_state->mutex, FuriWaitForever) != FuriStatusOk) continue; - // press events - if(event.type == EventTypeKey) { - if(event.input.type == InputTypeShort) { - switch(event.input.key) { - case InputKeyLeft: - // Reset seconds - timer_reset_seconds(plugin_state); - break; - case InputKeyOk: - // Toggle timer - timer_start_stop(plugin_state); - break; - case InputKeyBack: - // Exit the plugin - processing = false; - break; - case InputKeyUp: - handle_up(); - break; - case InputKeyDown: - handle_down(); - break; - default: - break; - } - } - } /*else if(event.type == EventTypeTick) { - furi_hal_rtc_get_datetime(&plugin_state->datetime); - }*/ - - furi_mutex_release(plugin_state->mutex); - view_port_update(view_port); - } - - furi_timer_free(timer); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - view_port_free(view_port); - furi_message_queue_free(plugin_state->event_queue); - furi_mutex_free(plugin_state->mutex); - free(plugin_state); - - set_backlight_brightness(tmpBrightness); - notification_message(notif, &sequence_display_backlight_enforce_auto); - notification_message(notif, &led_reset); - - return 0; -} \ No newline at end of file diff --git a/applications/system/nightstand/clock_app.h b/applications/system/nightstand/clock_app.h deleted file mode 100644 index 74648ba33..000000000 --- a/applications/system/nightstand/clock_app.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include - -#define TAG "Clock" - -#define CLOCK_ISO_DATE_FORMAT "%.4d-%.2d-%.2d" -#define CLOCK_RFC_DATE_FORMAT "%.2d-%.2d-%.4d" -#define CLOCK_TIME_FORMAT "%.2d:%.2d:%.2d" - -#define MERIDIAN_FORMAT "%s" -#define MERIDIAN_STRING_AM "AM" -#define MERIDIAN_STRING_PM "PM" - -#define TIME_LEN 12 -#define DATE_LEN 14 -#define MERIDIAN_LEN 3 - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -typedef struct { - LocaleDateFormat date_format; - LocaleTimeFormat time_format; - DateTime datetime; - FuriMutex* mutex; - FuriMessageQueue* event_queue; - uint32_t timer_start_timestamp; - uint32_t timer_stopped_seconds; - bool timer_running; -} ClockState; diff --git a/applications/system/subghz_playlist/application.fam b/applications/system/subghz_playlist/application.fam deleted file mode 100644 index 4f112ff96..000000000 --- a/applications/system/subghz_playlist/application.fam +++ /dev/null @@ -1,15 +0,0 @@ -App( - appid="subghz_playlist", - name="Sub-GHz Playlist", - apptype=FlipperAppType.EXTERNAL, - entry_point="playlist_app", - requires=["storage", "gui", "dialogs", "subghz"], - stack_size=2 * 1024, - order=14, - fap_icon="subplaylist_10px.png", - fap_category="Sub-GHz", - fap_icon_assets="images", - fap_author="@darmiel", - fap_version="1.0", - fap_description="App works with list of sub-ghz files from .txt file that contains paths to target files.", -) diff --git a/applications/system/subghz_playlist/canvas_helper.c b/applications/system/subghz_playlist/canvas_helper.c deleted file mode 100644 index ecb2eed8b..000000000 --- a/applications/system/subghz_playlist/canvas_helper.c +++ /dev/null @@ -1,81 +0,0 @@ -#include - -#define WIDTH 128 -#define HEIGHT 64 - -void draw_centered_boxed_str(Canvas* canvas, int x, int y, int height, int pad, const char* text) { - // get width of text - int w = canvas_string_width(canvas, text); - canvas_draw_rframe(canvas, x, y, w + pad, height, 2); - canvas_draw_str_aligned(canvas, x + pad / 2, y + height / 2, AlignLeft, AlignCenter, text); -} - -void draw_corner_aligned(Canvas* canvas, int width, int height, Align horizontal, Align vertical) { - canvas_set_color(canvas, ColorBlack); - switch(horizontal) { - case AlignLeft: - switch(vertical) { - case AlignTop: - canvas_draw_rbox(canvas, 0, 0, width, height, 3); - canvas_draw_box(canvas, 0, 0, width, 3); - canvas_draw_box(canvas, 0, 0, 3, height); - break; - case AlignCenter: - canvas_draw_rbox(canvas, 0, HEIGHT - height / 2, width, height, 3); - canvas_draw_box(canvas, 0, HEIGHT - height / 2, 3, height); - break; - case AlignBottom: - canvas_draw_rbox(canvas, 0, HEIGHT - height, width, height, 3); - canvas_draw_box(canvas, 0, HEIGHT - height, 3, height); - canvas_draw_box(canvas, 0, HEIGHT - 3, width, 3); - break; - default: - break; - } - break; - case AlignRight: - switch(vertical) { - case AlignTop: - canvas_draw_rbox(canvas, WIDTH - width, 0, width, height, 3); - canvas_draw_box(canvas, WIDTH - width, 0, width, 3); // bottom corner - canvas_draw_box(canvas, WIDTH - 3, 0, 3, height); // right corner - break; - case AlignCenter: - canvas_draw_rbox(canvas, WIDTH - width, HEIGHT / 2 - height / 2, width, height, 3); - canvas_draw_box(canvas, WIDTH - 3, HEIGHT / 2 - height / 2, 3, height); // right corner - break; - case AlignBottom: - canvas_draw_rbox(canvas, WIDTH - width, HEIGHT - height, width, height, 3); - canvas_draw_box(canvas, WIDTH - 3, HEIGHT - height, 3, height); // right corner - canvas_draw_box(canvas, WIDTH - width, HEIGHT - 3, width, 3); // bottom corner - break; - default: - break; - } - break; - case AlignCenter: - switch(vertical) { - case AlignTop: - canvas_draw_rbox(canvas, WIDTH / 2 - width / 2, 0, width, height, 3); - canvas_draw_box(canvas, WIDTH / 2 - width / 2, 0, width, 3); // bottom corner - canvas_draw_box(canvas, WIDTH / 2 - 3, 0, 3, height); // right corner - break; - case AlignCenter: - canvas_draw_rbox( - canvas, WIDTH / 2 - width / 2, HEIGHT / 2 - height / 2, width, height, 3); - canvas_draw_box( - canvas, WIDTH / 2 - 3, HEIGHT / 2 - height / 2, 3, height); // right corner - break; - case AlignBottom: - canvas_draw_rbox(canvas, WIDTH / 2 - width / 2, HEIGHT - height, width, height, 3); - canvas_draw_box(canvas, WIDTH / 2 - 3, HEIGHT - height, 3, height); // right corner - canvas_draw_box(canvas, WIDTH / 2 - width / 2, HEIGHT - 3, width, 3); // bottom corner - break; - default: - break; - } - break; - default: - break; - } -} \ No newline at end of file diff --git a/applications/system/subghz_playlist/canvas_helper.h b/applications/system/subghz_playlist/canvas_helper.h deleted file mode 100644 index cf73bdb32..000000000 --- a/applications/system/subghz_playlist/canvas_helper.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -void draw_centered_boxed_str(Canvas* canvas, int x, int y, int height, int pad, const char* text); - -void draw_corner_aligned(Canvas* canvas, int width, int height, Align horizontal, Align vertical); \ No newline at end of file diff --git a/applications/system/subghz_playlist/helpers/radio_device_loader.c b/applications/system/subghz_playlist/helpers/radio_device_loader.c deleted file mode 100644 index d2cffde58..000000000 --- a/applications/system/subghz_playlist/helpers/radio_device_loader.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "radio_device_loader.h" - -#include -#include - -static void radio_device_loader_power_on() { - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - //CC1101 power-up time - furi_delay_ms(10); - } -} - -static void radio_device_loader_power_off() { - if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg(); -} - -bool radio_device_loader_is_connect_external(const char* name) { - bool is_connect = false; - bool is_otg_enabled = furi_hal_power_is_otg_enabled(); - - if(!is_otg_enabled) { - radio_device_loader_power_on(); - } - - const SubGhzDevice* device = subghz_devices_get_by_name(name); - if(device) { - is_connect = subghz_devices_is_connect(device); - } - - if(!is_otg_enabled) { - radio_device_loader_power_off(); - } - return is_connect; -} - -const SubGhzDevice* radio_device_loader_set( - const SubGhzDevice* current_radio_device, - SubGhzRadioDeviceType radio_device_type) { - const SubGhzDevice* radio_device; - - if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 && - radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) { - radio_device_loader_power_on(); - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME); - subghz_devices_begin(radio_device); - } else if(current_radio_device == NULL) { - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - } else { - radio_device_loader_end(current_radio_device); - radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - } - - return radio_device; -} - -void radio_device_loader_end(const SubGhzDevice* radio_device) { - furi_assert(radio_device); - radio_device_loader_power_off(); - if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) { - subghz_devices_end(radio_device); - } -} \ No newline at end of file diff --git a/applications/system/subghz_playlist/helpers/radio_device_loader.h b/applications/system/subghz_playlist/helpers/radio_device_loader.h deleted file mode 100644 index bee4e2c36..000000000 --- a/applications/system/subghz_playlist/helpers/radio_device_loader.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -/** SubGhzRadioDeviceType */ -typedef enum { - SubGhzRadioDeviceTypeInternal, - SubGhzRadioDeviceTypeExternalCC1101, -} SubGhzRadioDeviceType; - -const SubGhzDevice* radio_device_loader_set( - const SubGhzDevice* current_radio_device, - SubGhzRadioDeviceType radio_device_type); - -void radio_device_loader_end(const SubGhzDevice* radio_device); \ No newline at end of file diff --git a/applications/system/subghz_playlist/playlist.c b/applications/system/subghz_playlist/playlist.c deleted file mode 100644 index 4dfc2cd69..000000000 --- a/applications/system/subghz_playlist/playlist.c +++ /dev/null @@ -1,843 +0,0 @@ -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "helpers/radio_device_loader.h" - -#include "flipper_format_stream.h" -#include "flipper_format_stream_i.h" - -#include -#include - -#include "playlist_file.h" -#include "canvas_helper.h" - -#define TAG "Playlist" - -#define STATE_NONE 0 -#define STATE_OVERVIEW 1 -#define STATE_SENDING 2 - -#define WIDTH 128 -#define HEIGHT 64 - -typedef struct { - int current_count; // number of processed files - int total_count; // number of items in the playlist - - int playlist_repetitions; // number of times to repeat the whole playlist - int current_playlist_repetition; // current playlist repetition - - // last 3 files - FuriString* prev_0_path; // current file - FuriString* prev_1_path; // previous file - FuriString* prev_2_path; // previous previous file - FuriString* prev_3_path; // you get the idea - - int state; // current state - - ViewPort* view_port; -} DisplayMeta; - -typedef struct { - FuriThread* thread; - Storage* storage; - FlipperFormat* format; - - DisplayMeta* meta; - - FuriString* file_path; // path to the playlist file - const SubGhzDevice* radio_device; - - bool ctl_request_exit; // can be set to true if the worker should exit - bool ctl_pause; // can be set to true if the worker should pause - bool ctl_request_skip; // can be set to true if the worker should skip the current file - bool ctl_request_prev; // can be set to true if the worker should go to the previous file - - bool is_running; // indicates if the worker is running -} PlaylistWorker; - -typedef struct { - FuriMutex* mutex; - FuriMessageQueue* input_queue; - ViewPort* view_port; - Gui* gui; - - DisplayMeta* meta; - PlaylistWorker* worker; - - FuriString* file_path; // Path to the playlist file -} Playlist; - -//////////////////////////////////////////////////////////////////////////////// - -void meta_set_state(DisplayMeta* meta, int state) { - meta->state = state; - view_port_update(meta->view_port); -} - -static FuriHalSubGhzPreset str_to_preset(FuriString* preset) { - if(furi_string_cmp_str(preset, "FuriHalSubGhzPresetOok270Async") == 0) { - return FuriHalSubGhzPresetOok270Async; - } - if(furi_string_cmp_str(preset, "FuriHalSubGhzPresetOok650Async") == 0) { - return FuriHalSubGhzPresetOok650Async; - } - if(furi_string_cmp_str(preset, "FuriHalSubGhzPreset2FSKDev238Async") == 0) { - return FuriHalSubGhzPreset2FSKDev238Async; - } - if(furi_string_cmp_str(preset, "FuriHalSubGhzPreset2FSKDev476Async") == 0) { - return FuriHalSubGhzPreset2FSKDev476Async; - } - if(furi_string_cmp_str(preset, "FuriHalSubGhzPresetMSK99_97KbAsync") == 0) { - return FuriHalSubGhzPresetMSK99_97KbAsync; - } - if(furi_string_cmp_str(preset, "FuriHalSubGhzPresetMSK99_97KbAsync") == 0) { - return FuriHalSubGhzPresetMSK99_97KbAsync; - } - return FuriHalSubGhzPresetCustom; -} - -// -4: missing protocol -// -3: missing preset -// -2: transmit error -// -1: error -// 0: ok -// 1: resend -// 2: exited -static int playlist_worker_process( - PlaylistWorker* worker, - FlipperFormat* fff_file, - FlipperFormat* fff_data, - const char* path, - FuriString* preset, - FuriString* protocol) { - // actual sending of .sub file - - if(!flipper_format_file_open_existing(fff_file, path)) { - FURI_LOG_E(TAG, " (TX) Failed to open %s", path); - return -1; - } - - // read frequency or default to 433.92MHz - uint32_t frequency = 0; - if(!flipper_format_read_uint32(fff_file, "Frequency", &frequency, 1)) { - FURI_LOG_W(TAG, " (TX) Missing Frequency, defaulting to 433.92MHz"); - frequency = 433920000; - } - if(!subghz_devices_is_frequency_valid(worker->radio_device, frequency)) { - FURI_LOG_E( - TAG, " (TX) The SubGhz device used does not support the frequency %lu", frequency); - return -2; - } - - // check if preset is present - if(!flipper_format_read_string(fff_file, "Preset", preset)) { - FURI_LOG_E(TAG, " (TX) Missing Preset"); - return -3; - } - - // check if protocol is present - if(!flipper_format_read_string(fff_file, "Protocol", protocol)) { - FURI_LOG_E(TAG, " (TX) Missing Protocol"); - return -4; - } - - if(!furi_string_cmp_str(protocol, "RAW")) { - subghz_protocol_raw_gen_fff_data( - fff_data, path, subghz_devices_get_name(worker->radio_device)); - } else { - stream_copy_full( - flipper_format_get_raw_stream(fff_file), flipper_format_get_raw_stream(fff_data)); - } - flipper_format_file_close(fff_file); - flipper_format_free(fff_file); - - // (try to) send file - SubGhzEnvironment* environment = subghz_environment_alloc(); - subghz_environment_set_protocol_registry(environment, (void*)&subghz_protocol_registry); - SubGhzTransmitter* transmitter = - subghz_transmitter_alloc_init(environment, furi_string_get_cstr(protocol)); - - subghz_transmitter_deserialize(transmitter, fff_data); - - subghz_devices_load_preset(worker->radio_device, str_to_preset(preset), NULL); - // there is no check for a custom preset - frequency = subghz_devices_set_frequency(worker->radio_device, frequency); - - // Set device to TX and check frequency is alowed to TX - if(!subghz_devices_set_tx(worker->radio_device)) { - FURI_LOG_E( - TAG, - " (TX) The SubGhz device used does not support the frequency for transmitеing, %lu", - frequency); - return -5; - } - FURI_LOG_D(TAG, " (TX) Start sending ..."); - int status = 0; - - subghz_devices_start_async_tx(worker->radio_device, subghz_transmitter_yield, transmitter); - while(!subghz_devices_is_async_complete_tx(worker->radio_device)) { - if(worker->ctl_request_exit) { - FURI_LOG_D(TAG, " (TX) Requested to exit. Cancelling sending..."); - status = 2; - break; - } - if(worker->ctl_pause) { - FURI_LOG_D(TAG, " (TX) Requested to pause. Cancelling and resending..."); - status = 1; - break; - } - if(worker->ctl_request_skip) { - worker->ctl_request_skip = false; - FURI_LOG_D(TAG, " (TX) Requested to skip. Cancelling and resending..."); - status = 0; - break; - } - if(worker->ctl_request_prev) { - worker->ctl_request_prev = false; - FURI_LOG_D(TAG, " (TX) Requested to prev. Cancelling and resending..."); - status = 3; - break; - } - furi_delay_ms(50); - } - - FURI_LOG_D(TAG, " (TX) Done sending."); - - subghz_devices_stop_async_tx(worker->radio_device); - subghz_devices_idle(worker->radio_device); - - subghz_transmitter_free(transmitter); - subghz_environment_free(environment); - - return status; -} - -// true - the worker can continue -// false - the worker should exit -static bool playlist_worker_wait_pause(PlaylistWorker* worker) { - // wait if paused - while(worker->ctl_pause && !worker->ctl_request_exit) { - furi_delay_ms(50); - } - // exit loop if requested to stop - if(worker->ctl_request_exit) { - FURI_LOG_D(TAG, "Requested to exit. Exiting loop..."); - return false; - } - return true; -} - -void updatePlayListView(PlaylistWorker* worker, const char* str) { - furi_string_reset(worker->meta->prev_3_path); - furi_string_set(worker->meta->prev_3_path, furi_string_get_cstr(worker->meta->prev_2_path)); - - furi_string_reset(worker->meta->prev_2_path); - furi_string_set(worker->meta->prev_2_path, furi_string_get_cstr(worker->meta->prev_1_path)); - - furi_string_reset(worker->meta->prev_1_path); - furi_string_set(worker->meta->prev_1_path, furi_string_get_cstr(worker->meta->prev_0_path)); - - furi_string_reset(worker->meta->prev_0_path); - furi_string_set(worker->meta->prev_0_path, str); - - view_port_update(worker->meta->view_port); -} - -static bool playlist_worker_play_playlist_once( - PlaylistWorker* worker, - Storage* storage, - FlipperFormat* fff_head, - FlipperFormat* fff_data, - FuriString* data, - FuriString* preset, - FuriString* protocol) { - // - if(!flipper_format_rewind(fff_head)) { - FURI_LOG_E(TAG, "Failed to rewind file"); - return false; - } - - while(flipper_format_read_string(fff_head, "sub", data)) { - if(!playlist_worker_wait_pause(worker)) { - break; - } - - // update state to sending - meta_set_state(worker->meta, STATE_SENDING); - - ++worker->meta->current_count; - const char* str = furi_string_get_cstr(data); - - // it's not fancy, but it works for now :) - updatePlayListView(worker, str); - - for(int i = 0; i < 1; i++) { - if(!playlist_worker_wait_pause(worker)) { - break; - } - - view_port_update(worker->meta->view_port); - - FURI_LOG_D(TAG, "(worker) Sending %s", str); - - FlipperFormat* fff_file = flipper_format_file_alloc(storage); - - int status = - playlist_worker_process(worker, fff_file, fff_data, str, preset, protocol); - - // if there was an error, fff_file is not already freed - if(status < 0) { - flipper_format_file_close(fff_file); - flipper_format_free(fff_file); - } - - // re-send file is paused mid-send - if(status == 1) { - i -= 1; - // errored, skip to next file - } else if(status < 0) { - break; - // exited, exit loop - } else if(status == 2) { - return false; - } else if(status == 3) { - //aqui rebobinamos y avanzamos de nuevo el fichero n-1 veces - //decrementamos el contador de ficheros enviados - worker->meta->current_count--; - if(worker->meta->current_count > 0) { - worker->meta->current_count--; - } - //rebobinamos el fichero - if(!flipper_format_rewind(fff_head)) { - FURI_LOG_E(TAG, "Failed to rewind file"); - return false; - } - //avanzamos el fichero n-1 veces - for(int j = 0; j < worker->meta->current_count; j++) { - flipper_format_read_string(fff_head, "sub", data); - } - break; - } - } - } // end of loop - return true; -} - -static int32_t playlist_worker_thread(void* ctx) { - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* fff_head = flipper_format_file_alloc(storage); - - PlaylistWorker* worker = ctx; - if(!flipper_format_file_open_existing(fff_head, furi_string_get_cstr(worker->file_path))) { - FURI_LOG_E(TAG, "Failed to open %s", furi_string_get_cstr(worker->file_path)); - worker->is_running = false; - - furi_record_close(RECORD_STORAGE); - flipper_format_free(fff_head); - return 0; - } - - playlist_worker_wait_pause(worker); - FlipperFormat* fff_data = flipper_format_string_alloc(); - - FuriString* data; - FuriString* preset; - FuriString* protocol; - data = furi_string_alloc(); - preset = furi_string_alloc(); - protocol = furi_string_alloc(); - - for(int i = 0; i < MAX(1, worker->meta->playlist_repetitions); i++) { - // infinite repetitions if playlist_repetitions is 0 - if(worker->meta->playlist_repetitions <= 0) { - --i; - } - ++worker->meta->current_playlist_repetition; - // send playlist - worker->meta->current_count = 0; - if(worker->ctl_request_exit) { - break; - } - - FURI_LOG_D( - TAG, - "Sending playlist (i %d rep %d b %d)", - i, - worker->meta->current_playlist_repetition, - worker->meta->playlist_repetitions); - - if(!playlist_worker_play_playlist_once( - worker, storage, fff_head, fff_data, data, preset, protocol)) { - break; - } - } - - furi_record_close(RECORD_STORAGE); - flipper_format_free(fff_head); - - furi_string_free(data); - furi_string_free(preset); - furi_string_free(protocol); - - flipper_format_free(fff_data); - - FURI_LOG_D(TAG, "Done reading. Read %d data lines.", worker->meta->current_count); - worker->is_running = false; - - // update state to overview - meta_set_state(worker->meta, STATE_OVERVIEW); - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// - -void playlist_meta_reset(DisplayMeta* instance) { - instance->current_count = 0; - instance->current_playlist_repetition = 0; - - furi_string_reset(instance->prev_0_path); - furi_string_reset(instance->prev_1_path); - furi_string_reset(instance->prev_2_path); - furi_string_reset(instance->prev_3_path); -} - -DisplayMeta* playlist_meta_alloc() { - DisplayMeta* instance = malloc(sizeof(DisplayMeta)); - instance->prev_0_path = furi_string_alloc(); - instance->prev_1_path = furi_string_alloc(); - instance->prev_2_path = furi_string_alloc(); - instance->prev_3_path = furi_string_alloc(); - playlist_meta_reset(instance); - instance->state = STATE_NONE; - instance->playlist_repetitions = 1; - return instance; -} - -void playlist_meta_free(DisplayMeta* instance) { - furi_string_free(instance->prev_0_path); - furi_string_free(instance->prev_1_path); - furi_string_free(instance->prev_2_path); - furi_string_free(instance->prev_3_path); - free(instance); -} - -//////////////////////////////////////////////////////////////////////////////// - -PlaylistWorker* playlist_worker_alloc(DisplayMeta* meta) { - PlaylistWorker* instance = malloc(sizeof(PlaylistWorker)); - - instance->thread = furi_thread_alloc(); - furi_thread_set_name(instance->thread, "PlaylistWorker"); - furi_thread_set_stack_size(instance->thread, 2048); - furi_thread_set_context(instance->thread, instance); - furi_thread_set_callback(instance->thread, playlist_worker_thread); - - instance->meta = meta; - instance->ctl_pause = true; // require the user to manually start the worker - - instance->file_path = furi_string_alloc(); - - subghz_devices_init(); - - instance->radio_device = - radio_device_loader_set(instance->radio_device, SubGhzRadioDeviceTypeExternalCC1101); - - subghz_devices_reset(instance->radio_device); - subghz_devices_idle(instance->radio_device); - - return instance; -} - -void playlist_worker_free(PlaylistWorker* instance) { - furi_assert(instance); - furi_thread_free(instance->thread); - furi_string_free(instance->file_path); - - subghz_devices_sleep(instance->radio_device); - radio_device_loader_end(instance->radio_device); - - subghz_devices_deinit(); - - free(instance); -} - -void playlist_worker_stop(PlaylistWorker* worker) { - furi_assert(worker); - furi_assert(worker->is_running); - - worker->ctl_request_exit = true; - furi_thread_join(worker->thread); -} - -bool playlist_worker_running(PlaylistWorker* worker) { - furi_assert(worker); - return worker->is_running; -} - -void playlist_worker_start(PlaylistWorker* instance, const char* file_path) { - furi_assert(instance); - furi_assert(!instance->is_running); - - furi_string_set(instance->file_path, file_path); - instance->is_running = true; - - // reset meta (current/total) - playlist_meta_reset(instance->meta); - - FURI_LOG_D(TAG, "Starting thread..."); - furi_thread_start(instance->thread); -} - -//////////////////////////////////////////////////////////////////////////////// - -static void render_callback(Canvas* canvas, void* ctx) { - Playlist* app = ctx; - furi_check(furi_mutex_acquire(app->mutex, FuriWaitForever) == FuriStatusOk); - - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - - FuriString* temp_str; - temp_str = furi_string_alloc(); - - switch(app->meta->state) { - case STATE_NONE: - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned( - canvas, WIDTH / 2, HEIGHT / 2, AlignCenter, AlignCenter, "No playlist loaded"); - break; - - case STATE_OVERVIEW: - // draw file name - { - path_extract_filename(app->file_path, temp_str, true); - - canvas_set_font(canvas, FontPrimary); - draw_centered_boxed_str(canvas, 1, 1, 15, 6, furi_string_get_cstr(temp_str)); - } - - canvas_set_font(canvas, FontSecondary); - - // draw loaded count - { - furi_string_printf(temp_str, "%d Items in playlist", app->meta->total_count); - canvas_draw_str_aligned( - canvas, 1, 19, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); - - if(app->meta->playlist_repetitions <= 0) { - furi_string_set(temp_str, "Repeat: inf"); - } else if(app->meta->playlist_repetitions == 1) { - furi_string_set(temp_str, "Repeat: no"); - } else { - furi_string_printf(temp_str, "Repeat: %dx", app->meta->playlist_repetitions); - } - canvas_draw_str_aligned( - canvas, 1, 29, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); - } - - // draw buttons - draw_corner_aligned(canvas, 40, 15, AlignCenter, AlignBottom); - - canvas_set_color(canvas, ColorWhite); - canvas_draw_str_aligned(canvas, WIDTH / 2 - 7, HEIGHT - 11, AlignLeft, AlignTop, "Start"); - canvas_draw_disc(canvas, WIDTH / 2 - 14, HEIGHT - 8, 3); - - // - canvas_set_color(canvas, ColorBlack); - draw_corner_aligned(canvas, 20, 15, AlignLeft, AlignBottom); - - canvas_set_color(canvas, ColorWhite); - canvas_draw_str_aligned(canvas, 4, HEIGHT - 11, AlignLeft, AlignTop, "R-"); - - // - canvas_set_color(canvas, ColorBlack); - draw_corner_aligned(canvas, 20, 15, AlignRight, AlignBottom); - canvas_set_color(canvas, ColorWhite); - canvas_draw_str_aligned(canvas, WIDTH - 4, HEIGHT - 11, AlignRight, AlignTop, "R+"); - - canvas_set_color(canvas, ColorBlack); - - break; - case STATE_SENDING: - canvas_set_color(canvas, ColorBlack); - if(app->worker->ctl_pause) { - canvas_draw_icon(canvas, 2, HEIGHT - 8, &I_ButtonRight_4x7); - } else { - canvas_draw_box(canvas, 2, HEIGHT - 8, 2, 7); - canvas_draw_box(canvas, 5, HEIGHT - 8, 2, 7); - } - - // draw progress text - { - canvas_set_font(canvas, FontSecondary); - furi_string_printf( - temp_str, "[%d/%d]", app->meta->current_count, app->meta->total_count); - canvas_draw_str_aligned( - canvas, 11, HEIGHT - 8, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); - - int h = canvas_string_width(canvas, furi_string_get_cstr(temp_str)); - int xs = 11 + h + 2; - int w = WIDTH - xs - 1; - canvas_draw_box(canvas, xs, HEIGHT - 5, w, 1); - - float progress = (float)app->meta->current_count / (float)app->meta->total_count; - int wp = (int)(progress * w); - canvas_draw_box(canvas, xs + wp - 1, HEIGHT - 7, 2, 5); - } - - { - if(app->meta->playlist_repetitions <= 0) { - furi_string_printf(temp_str, "[%d/Inf]", app->meta->current_playlist_repetition); - } else { - furi_string_printf( - temp_str, - "[%d/%d]", - app->meta->current_playlist_repetition, - app->meta->playlist_repetitions); - } - canvas_set_color(canvas, ColorBlack); - int w = canvas_string_width(canvas, furi_string_get_cstr(temp_str)); - draw_corner_aligned(canvas, w + 6, 13, AlignRight, AlignTop); - canvas_set_color(canvas, ColorWhite); - canvas_draw_str_aligned( - canvas, WIDTH - 3, 3, AlignRight, AlignTop, furi_string_get_cstr(temp_str)); - } - - // draw last and current file - { - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - - // current - if(!furi_string_empty(app->meta->prev_0_path)) { - path_extract_filename(app->meta->prev_0_path, temp_str, true); - int w = canvas_string_width(canvas, furi_string_get_cstr(temp_str)); - canvas_set_color(canvas, ColorBlack); - canvas_draw_rbox(canvas, 1, 1, w + 4, 12, 2); - canvas_set_color(canvas, ColorWhite); - canvas_draw_str_aligned( - canvas, 3, 3, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); - } - - // last 3 - canvas_set_color(canvas, ColorBlack); - - if(!furi_string_empty(app->meta->prev_1_path)) { - path_extract_filename(app->meta->prev_1_path, temp_str, true); - canvas_draw_str_aligned( - canvas, 3, 15, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); - } - - if(!furi_string_empty(app->meta->prev_2_path)) { - path_extract_filename(app->meta->prev_2_path, temp_str, true); - canvas_draw_str_aligned( - canvas, 3, 26, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); - } - - if(!furi_string_empty(app->meta->prev_3_path)) { - path_extract_filename(app->meta->prev_3_path, temp_str, true); - canvas_draw_str_aligned( - canvas, 3, 37, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); - } - } - break; - default: - break; - } - - furi_string_free(temp_str); - furi_mutex_release(app->mutex); -} - -static void input_callback(InputEvent* event, void* ctx) { - Playlist* app = ctx; - furi_message_queue_put(app->input_queue, event, 0); -} - -//////////////////////////////////////////////////////////////////////////////// - -Playlist* playlist_alloc(DisplayMeta* meta) { - Playlist* app = malloc(sizeof(Playlist)); - app->file_path = furi_string_alloc(); - furi_string_set(app->file_path, PLAYLIST_FOLDER); - - app->meta = meta; - app->worker = NULL; - - app->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - app->input_queue = furi_message_queue_alloc(32, sizeof(InputEvent)); - - // view port - app->view_port = view_port_alloc(); - view_port_draw_callback_set(app->view_port, render_callback, app); - view_port_input_callback_set(app->view_port, input_callback, app); - - // gui - app->gui = furi_record_open(RECORD_GUI); - gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); - - return app; -} - -void playlist_start_worker(Playlist* app, DisplayMeta* meta) { - app->worker = playlist_worker_alloc(meta); - - // count playlist items - Storage* storage = furi_record_open(RECORD_STORAGE); - app->meta->total_count = - playlist_count_playlist_items(storage, furi_string_get_cstr(app->file_path)); - furi_record_close(RECORD_STORAGE); - - // start thread - playlist_worker_start(app->worker, furi_string_get_cstr(app->file_path)); -} - -void playlist_free(Playlist* app) { - furi_string_free(app->file_path); - - gui_remove_view_port(app->gui, app->view_port); - furi_record_close(RECORD_GUI); - view_port_free(app->view_port); - - furi_message_queue_free(app->input_queue); - furi_mutex_free(app->mutex); - - playlist_meta_free(app->meta); - - free(app); -} - -int32_t playlist_app(char* p) { - // create playlist folder - { - Storage* storage = furi_record_open(RECORD_STORAGE); - if(!storage_simply_mkdir(storage, PLAYLIST_FOLDER)) { - FURI_LOG_E(TAG, "Could not create folder %s", PLAYLIST_FOLDER); - } - furi_record_close(RECORD_STORAGE); - } - - // create app - DisplayMeta* meta = playlist_meta_alloc(); - Playlist* app = playlist_alloc(meta); - meta->view_port = app->view_port; - - furi_hal_power_suppress_charge_enter(); - - // select playlist file - if(p && strlen(p)) { - furi_string_set(app->file_path, p); - } else { - DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, PLAYLIST_EXT, &I_sub1_10px); - browser_options.base_path = PLAYLIST_FOLDER; - - const bool res = - dialog_file_browser_show(dialogs, app->file_path, app->file_path, &browser_options); - furi_record_close(RECORD_DIALOGS); - // check if a file was selected - if(!res) { - FURI_LOG_E(TAG, "No file selected"); - goto exit_cleanup; - } - } - - //////////////////////////////////////////////////////////////////////////////// - - playlist_start_worker(app, meta); - meta_set_state(app->meta, STATE_OVERVIEW); - - bool exit_loop = false; - InputEvent input; - while(1) { // close application if no file was selected - furi_check( - furi_message_queue_get(app->input_queue, &input, FuriWaitForever) == FuriStatusOk); - - switch(input.key) { - case InputKeyLeft: - if(app->meta->state == STATE_OVERVIEW) { - if(input.type == InputTypeShort && app->meta->playlist_repetitions > 0) { - --app->meta->playlist_repetitions; - } - } else if(app->meta->state == STATE_SENDING) { - if(input.type == InputTypeShort) { - app->worker->ctl_request_prev = true; - } - } - break; - - case InputKeyRight: - if(app->meta->state == STATE_OVERVIEW) { - if(input.type == InputTypeShort) { - ++app->meta->playlist_repetitions; - } - } else if(app->meta->state == STATE_SENDING) { - if(input.type == InputTypeShort) { - app->worker->ctl_request_skip = true; - } - } - break; - - case InputKeyOk: - if(input.type == InputTypeShort) { - // toggle pause state - if(!app->worker->is_running) { - app->worker->ctl_pause = false; - app->worker->ctl_request_exit = false; - playlist_worker_start(app->worker, furi_string_get_cstr(app->file_path)); - } else { - app->worker->ctl_pause = !app->worker->ctl_pause; - } - } - break; - case InputKeyBack: - FURI_LOG_D(TAG, "Pressed Back button. Application will exit"); - exit_loop = true; - break; - default: - break; - } - - furi_mutex_release(app->mutex); - - // exit application - if(exit_loop == true) { - break; - } - - view_port_update(app->view_port); - } - -exit_cleanup: - - furi_hal_power_suppress_charge_exit(); - - if(app->worker != NULL) { - if(playlist_worker_running(app->worker)) { - FURI_LOG_D(TAG, "Thread is still running. Requesting thread to finish ..."); - playlist_worker_stop(app->worker); - } - FURI_LOG_D(TAG, "Freeing Worker ..."); - playlist_worker_free(app->worker); - } - - FURI_LOG_D(TAG, "Freeing Playlist ..."); - playlist_free(app); - return 0; -} diff --git a/applications/system/subghz_playlist/playlist_file.c b/applications/system/subghz_playlist/playlist_file.c deleted file mode 100644 index e3540648e..000000000 --- a/applications/system/subghz_playlist/playlist_file.c +++ /dev/null @@ -1,21 +0,0 @@ -#include - -#include -#include - -int playlist_count_playlist_items(Storage* storage, const char* file_path) { - FlipperFormat* format = flipper_format_file_alloc(storage); - if(!flipper_format_file_open_existing(format, file_path)) { - return -1; - } - int count = 0; - FuriString* data; - data = furi_string_alloc(); - while(flipper_format_read_string(format, "sub", data)) { - ++count; - } - flipper_format_file_close(format); - flipper_format_free(format); - furi_string_free(data); - return count; -} diff --git a/applications/system/subghz_playlist/playlist_file.h b/applications/system/subghz_playlist/playlist_file.h deleted file mode 100644 index 7e853fb28..000000000 --- a/applications/system/subghz_playlist/playlist_file.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include - -#include - -#define PLAYLIST_FOLDER EXT_PATH("subghz/playlist") -#define PLAYLIST_EXT ".txt" - -int playlist_count_playlist_items(Storage* storage, const char* file_path); diff --git a/applications/system/subghz_playlist/subplaylist_10px.png b/applications/system/subghz_playlist/subplaylist_10px.png deleted file mode 100644 index 3d3f1d27f..000000000 Binary files a/applications/system/subghz_playlist/subplaylist_10px.png and /dev/null differ diff --git a/applications/system/subghz_remote/application.fam b/applications/system/subghz_remote/application.fam deleted file mode 100644 index 2249931b9..000000000 --- a/applications/system/subghz_remote/application.fam +++ /dev/null @@ -1,19 +0,0 @@ -App( - appid="subghz_remote", - name="Sub-GHz Remote", - apptype=FlipperAppType.EXTERNAL, - entry_point="subghz_remote_app", - requires=[ - "gui", - "dialogs", - ], - stack_size=2 * 1024, - targets=["f7"], - fap_icon="icon.png", - fap_author="@gid9798 and @xMasterX", - fap_description="SubGhz Remote, uses up to 5 .sub files", - fap_category="Sub-GHz", - fap_icon_assets="icons", - fap_version="1.3", - fap_weburl="https://github.com/DarkFlippers/SubGHz_Remote", -) diff --git a/applications/system/subghz_remote/helpers/subrem_custom_event.h b/applications/system/subghz_remote/helpers/subrem_custom_event.h deleted file mode 100644 index 810df6a89..000000000 --- a/applications/system/subghz_remote/helpers/subrem_custom_event.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -typedef enum { - SubRemEditMenuStateUP = 0, - SubRemEditMenuStateDOWN, - SubRemEditMenuStateLEFT, - SubRemEditMenuStateRIGHT, - SubRemEditMenuStateOK, -} SubRemEditMenuState; - -typedef enum { - // StartSubmenuIndex - SubmenuIndexSubRemOpenMapFile = 0, - SubmenuIndexSubRemEditMapFile, - SubmenuIndexSubRemNewMapFile, -#if FURI_DEBUG - SubmenuIndexSubRemRemoteView, -#endif - // SubmenuIndexSubRemAbout, - - // EditSubmenuIndex - EditSubmenuIndexEditLabel, - EditSubmenuIndexEditFile, - - // SubRemCustomEvent - SubRemCustomEventViewRemoteStartUP = 100, - SubRemCustomEventViewRemoteStartDOWN, - SubRemCustomEventViewRemoteStartLEFT, - SubRemCustomEventViewRemoteStartRIGHT, - SubRemCustomEventViewRemoteStartOK, - SubRemCustomEventViewRemoteBack, - SubRemCustomEventViewRemoteStop, - SubRemCustomEventViewRemoteForcedStop, - - SubRemCustomEventViewEditMenuBack, - SubRemCustomEventViewEditMenuUP, - SubRemCustomEventViewEditMenuDOWN, - SubRemCustomEventViewEditMenuEdit, - SubRemCustomEventViewEditMenuSave, - - SubRemCustomEventSceneEditsubmenu, - SubRemCustomEventSceneEditLabelInputDone, - SubRemCustomEventSceneEditLabelWidgetAcces, - SubRemCustomEventSceneEditLabelWidgetBack, - - SubRemCustomEventSceneEditOpenSubErrorPopup, - - SubRemCustomEventSceneEditPreviewSaved, - - SubRemCustomEventSceneNewName, - -#ifdef FW_ORIGIN_Official - SubRemCustomEventSceneFwWarningExit, - SubRemCustomEventSceneFwWarningNext, - SubRemCustomEventSceneFwWarningContinue, -#endif - -} SubRemCustomEvent; \ No newline at end of file diff --git a/applications/system/subghz_remote/helpers/subrem_presets.c b/applications/system/subghz_remote/helpers/subrem_presets.c deleted file mode 100644 index b0ce1932d..000000000 --- a/applications/system/subghz_remote/helpers/subrem_presets.c +++ /dev/null @@ -1,192 +0,0 @@ -#include "subrem_presets.h" - -#define TAG "SubRemPresets" - -SubRemSubFilePreset* subrem_sub_file_preset_alloc(void) { - SubRemSubFilePreset* sub_preset = malloc(sizeof(SubRemSubFilePreset)); - - sub_preset->fff_data = flipper_format_string_alloc(); - sub_preset->file_path = furi_string_alloc(); - sub_preset->protocaol_name = furi_string_alloc(); - sub_preset->label = furi_string_alloc(); - - sub_preset->freq_preset.name = furi_string_alloc(); - - sub_preset->type = SubGhzProtocolTypeUnknown; - sub_preset->load_state = SubRemLoadSubStateNotSet; - - return sub_preset; -} - -void subrem_sub_file_preset_free(SubRemSubFilePreset* sub_preset) { - furi_assert(sub_preset); - - furi_string_free(sub_preset->label); - furi_string_free(sub_preset->protocaol_name); - furi_string_free(sub_preset->file_path); - flipper_format_free(sub_preset->fff_data); - - furi_string_free(sub_preset->freq_preset.name); - - free(sub_preset); -} - -void subrem_sub_file_preset_reset(SubRemSubFilePreset* sub_preset) { - furi_assert(sub_preset); - - furi_string_set_str(sub_preset->label, ""); - furi_string_reset(sub_preset->protocaol_name); - furi_string_reset(sub_preset->file_path); - - Stream* fff_data_stream = flipper_format_get_raw_stream(sub_preset->fff_data); - stream_clean(fff_data_stream); - - sub_preset->type = SubGhzProtocolTypeUnknown; - sub_preset->load_state = SubRemLoadSubStateNotSet; -} - -SubRemLoadSubState subrem_sub_preset_load( - SubRemSubFilePreset* sub_preset, - SubGhzTxRx* txrx, - FlipperFormat* fff_data_file) { - furi_assert(sub_preset); - furi_assert(txrx); - furi_assert(fff_data_file); - - Stream* fff_data_stream = flipper_format_get_raw_stream(sub_preset->fff_data); - - SubRemLoadSubState ret; - FuriString* temp_str = furi_string_alloc(); - uint32_t temp_data32; - uint32_t repeat = 200; - - ret = SubRemLoadSubStateError; - - do { - stream_clean(fff_data_stream); - if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) { - FURI_LOG_E(TAG, "Missing or incorrect header"); - break; - } - - if(((!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_KEY_FILE_TYPE)) || - (!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE))) && - temp_data32 == SUBGHZ_KEY_FILE_VERSION) { - } else { - FURI_LOG_E(TAG, "Type or version mismatch"); - break; - } - - SubGhzSetting* setting = subghz_txrx_get_setting(txrx); - - //Load frequency or using default from settings - ret = SubRemLoadSubStateErrorFreq; - if(!flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) { - FURI_LOG_W(TAG, "Cannot read frequency. Set default frequency"); - sub_preset->freq_preset.frequency = subghz_setting_get_default_frequency(setting); - } else if(!subghz_txrx_radio_device_is_frequency_valid(txrx, temp_data32)) { - FURI_LOG_E(TAG, "Frequency not supported on chosen radio module"); - break; - } - sub_preset->freq_preset.frequency = temp_data32; - - //Load preset - ret = SubRemLoadSubStateErrorMod; - if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) { - FURI_LOG_E(TAG, "Missing Preset"); - break; - } - - furi_string_set_str( - temp_str, subghz_txrx_get_preset_name(txrx, furi_string_get_cstr(temp_str))); - if(!strcmp(furi_string_get_cstr(temp_str), "")) { - break; - } - - if(!strcmp(furi_string_get_cstr(temp_str), "CUSTOM")) { - //TODO FL-3551: add Custom_preset_module - //delete preset if it already exists - subghz_setting_delete_custom_preset(setting, furi_string_get_cstr(temp_str)); - //load custom preset from file - if(!subghz_setting_load_custom_preset( - setting, furi_string_get_cstr(temp_str), fff_data_file)) { - FURI_LOG_E(TAG, "Missing Custom preset"); - break; - } - // FURI_LOG_E(TAG, "CUSTOM preset is not supported"); - // break; - // TODO Custom preset loading logic if need - // sub_preset->freq_preset.preset_index = - // subghz_setting_get_inx_preset_by_name(setting, furi_string_get_cstr(temp_str)); - } - - furi_string_set(sub_preset->freq_preset.name, temp_str); - - // Load protocol - ret = SubRemLoadSubStateErrorProtocol; - if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) { - FURI_LOG_E(TAG, "Missing Protocol"); - break; - } - - FlipperFormat* fff_data = sub_preset->fff_data; - if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) { - //if RAW - subghz_protocol_raw_gen_fff_data( - fff_data, - furi_string_get_cstr(sub_preset->file_path), - subghz_txrx_radio_device_get_name(txrx)); - } else { - stream_copy_full( - flipper_format_get_raw_stream(fff_data_file), - flipper_format_get_raw_stream(fff_data)); - } - - if(subghz_txrx_load_decoder_by_name_protocol(txrx, furi_string_get_cstr(temp_str))) { - SubGhzProtocolStatus status = - subghz_protocol_decoder_base_deserialize(subghz_txrx_get_decoder(txrx), fff_data); - if(status != SubGhzProtocolStatusOk) { - break; - } - } else { - FURI_LOG_E(TAG, "Protocol not found"); - break; - } - - const SubGhzProtocol* protocol = subghz_txrx_get_decoder(txrx)->protocol; - - if(protocol->flag & SubGhzProtocolFlag_Send) { - if((protocol->type == SubGhzProtocolTypeStatic) || - (protocol->type == SubGhzProtocolTypeDynamic) || -#ifndef FW_ORIGIN_Official - (protocol->type == SubGhzProtocolTypeBinRAW) || -#endif - (protocol->type == SubGhzProtocolTypeRAW)) { - sub_preset->type = protocol->type; - } else { - FURI_LOG_E(TAG, "Unsuported Protocol"); - break; - } - - furi_string_set(sub_preset->protocaol_name, temp_str); - } else { - FURI_LOG_E(TAG, "Protocol does not support transmission"); - break; - } - - if(!flipper_format_insert_or_update_uint32(fff_data, "Repeat", &repeat, 1)) { - FURI_LOG_E(TAG, "Unable Repeat"); - break; - } - - ret = SubRemLoadSubStateOK; - -#if FURI_DEBUG - FURI_LOG_I(TAG, "%-16s - protocol Loaded", furi_string_get_cstr(sub_preset->label)); -#endif - } while(false); - - furi_string_free(temp_str); - sub_preset->load_state = ret; - return ret; -} diff --git a/applications/system/subghz_remote/helpers/subrem_presets.h b/applications/system/subghz_remote/helpers/subrem_presets.h deleted file mode 100644 index b9f9e7cbb..000000000 --- a/applications/system/subghz_remote/helpers/subrem_presets.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "subrem_types.h" -#include "txrx/subghz_txrx.h" - -#include -#include - -typedef struct { - FuriString* name; - uint32_t frequency; - // size_t preset_index; // Need for custom preset -} FreqPreset; - -// Sub File preset -typedef struct { - FlipperFormat* fff_data; - FreqPreset freq_preset; - FuriString* file_path; - FuriString* protocaol_name; - FuriString* label; - SubGhzProtocolType type; - SubRemLoadSubState load_state; -} SubRemSubFilePreset; - -typedef struct { - SubRemSubFilePreset* subs_preset[SubRemSubKeyNameMaxCount]; -} SubRemMapPreset; - -SubRemSubFilePreset* subrem_sub_file_preset_alloc(void); - -void subrem_sub_file_preset_free(SubRemSubFilePreset* sub_preset); - -void subrem_sub_file_preset_reset(SubRemSubFilePreset* sub_preset); - -SubRemLoadSubState subrem_sub_preset_load( - SubRemSubFilePreset* sub_preset, - SubGhzTxRx* txrx, - FlipperFormat* fff_data_file); diff --git a/applications/system/subghz_remote/helpers/subrem_types.h b/applications/system/subghz_remote/helpers/subrem_types.h deleted file mode 100644 index b43f8499d..000000000 --- a/applications/system/subghz_remote/helpers/subrem_types.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include - -#define SUBREM_APP_APP_FILE_VERSION 1 -#define SUBREM_APP_APP_FILE_TYPE "Flipper SubRem Map file" -#define SUBREM_APP_EXTENSION ".txt" - -typedef enum { - SubRemSubKeyNameUp = (0U), - SubRemSubKeyNameDown, - SubRemSubKeyNameLeft, - SubRemSubKeyNameRight, - SubRemSubKeyNameOk, - SubRemSubKeyNameMaxCount, -} SubRemSubKeyName; - -typedef enum { - SubRemViewIDSubmenu, - SubRemViewIDWidget, - SubRemViewIDPopup, - SubRemViewIDTextInput, - SubRemViewIDRemote, - SubRemViewIDEditMenu, -} SubRemViewID; - -typedef enum { - SubRemLoadSubStateNotSet = 0, - SubRemLoadSubStatePreloaded, - SubRemLoadSubStateError, - SubRemLoadSubStateErrorIncorectPath, - SubRemLoadSubStateErrorNoFile, - SubRemLoadSubStateErrorFreq, - SubRemLoadSubStateErrorMod, - SubRemLoadSubStateErrorProtocol, - SubRemLoadSubStateOK, -} SubRemLoadSubState; - -typedef enum { - SubRemLoadMapStateBack = 0, - SubRemLoadMapStateError, - SubRemLoadMapStateErrorOpenError, - SubRemLoadMapStateErrorStorage, - SubRemLoadMapStateErrorBrokenFile, - SubRemLoadMapStateNotAllOK, - SubRemLoadMapStateOK, -} SubRemLoadMapState; \ No newline at end of file diff --git a/applications/system/subghz_remote/helpers/txrx/Readme.md b/applications/system/subghz_remote/helpers/txrx/Readme.md deleted file mode 100644 index 918160198..000000000 --- a/applications/system/subghz_remote/helpers/txrx/Readme.md +++ /dev/null @@ -1,4 +0,0 @@ -This is part of the official `SubGhz` app from [flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware/tree/3217f286f03da119398586daf94c0723d28b872a/applications/main/subghz) - -With changes from [unleashed-firmware -](https://github.com/DarkFlippers/unleashed-firmware/tree/3eac6ccd48a3851cf5d63bf7899b387a293e5319/applications/main/subghz) \ No newline at end of file diff --git a/applications/system/subghz_remote/helpers/txrx/subghz_txrx.c b/applications/system/subghz_remote/helpers/txrx/subghz_txrx.c deleted file mode 100644 index a9b382847..000000000 --- a/applications/system/subghz_remote/helpers/txrx/subghz_txrx.c +++ /dev/null @@ -1,672 +0,0 @@ -#include "subghz_txrx_i.h" - -#include -#include -#include - -#ifndef FW_ORIGIN_Official -#include -#endif - -#define TAG "SubGhz" - -static void subghz_txrx_radio_device_power_on(SubGhzTxRx* instance) { - UNUSED(instance); - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - //CC1101 power-up time - furi_delay_ms(10); - } -} - -static void subghz_txrx_radio_device_power_off(SubGhzTxRx* instance) { - UNUSED(instance); - if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg(); -} - -SubGhzTxRx* subghz_txrx_alloc(void) { - SubGhzTxRx* instance = malloc(sizeof(SubGhzTxRx)); - instance->setting = subghz_setting_alloc(); - subghz_setting_load(instance->setting, EXT_PATH("subghz/assets/setting_user")); - - instance->preset = malloc(sizeof(SubGhzRadioPreset)); - instance->preset->name = furi_string_alloc(); - subghz_txrx_set_preset( - instance, "AM650", subghz_setting_get_default_frequency(instance->setting), NULL, 0); - - instance->txrx_state = SubGhzTxRxStateSleep; - - subghz_txrx_hopper_set_state(instance, SubGhzHopperStateOFF); - subghz_txrx_speaker_set_state(instance, SubGhzSpeakerStateDisable); - subghz_txrx_set_debug_pin_state(instance, false); - - instance->worker = subghz_worker_alloc(); - instance->fff_data = flipper_format_string_alloc(); - - instance->environment = subghz_environment_alloc(); - instance->is_database_loaded = - subghz_environment_load_keystore(instance->environment, SUBGHZ_KEYSTORE_DIR_NAME); - subghz_environment_load_keystore(instance->environment, SUBGHZ_KEYSTORE_DIR_USER_NAME); - subghz_environment_set_alutech_at_4n_rainbow_table_file_name( - instance->environment, SUBGHZ_ALUTECH_AT_4N_DIR_NAME); - subghz_environment_set_nice_flor_s_rainbow_table_file_name( - instance->environment, SUBGHZ_NICE_FLOR_S_DIR_NAME); - subghz_environment_set_protocol_registry( - instance->environment, (void*)&subghz_protocol_registry); - instance->receiver = subghz_receiver_alloc_init(instance->environment); - - subghz_worker_set_overrun_callback( - instance->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); - subghz_worker_set_pair_callback( - instance->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode); - subghz_worker_set_context(instance->worker, instance->receiver); - - //set default device Internal - subghz_devices_init(); - instance->radio_device_type = SubGhzRadioDeviceTypeInternal; - instance->radio_device_type = - subghz_txrx_radio_device_set(instance, SubGhzRadioDeviceTypeExternalCC1101); - - return instance; -} - -void subghz_txrx_free(SubGhzTxRx* instance) { - furi_assert(instance); - - if(instance->radio_device_type != SubGhzRadioDeviceTypeInternal) { - subghz_txrx_radio_device_power_off(instance); - subghz_devices_end(instance->radio_device); - } - - subghz_devices_deinit(); - - subghz_worker_free(instance->worker); - subghz_receiver_free(instance->receiver); - subghz_environment_free(instance->environment); - flipper_format_free(instance->fff_data); - furi_string_free(instance->preset->name); - subghz_setting_free(instance->setting); - - free(instance->preset); - free(instance); -} - -bool subghz_txrx_is_database_loaded(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->is_database_loaded; -} - -void subghz_txrx_set_preset( - SubGhzTxRx* instance, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size) { - furi_assert(instance); - furi_string_set(instance->preset->name, preset_name); - SubGhzRadioPreset* preset = instance->preset; - preset->frequency = frequency; - preset->data = preset_data; - preset->data_size = preset_data_size; -} - -const char* subghz_txrx_get_preset_name(SubGhzTxRx* instance, const char* preset) { - UNUSED(instance); - const char* preset_name = ""; - if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) { - preset_name = "AM270"; - } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) { - preset_name = "AM650"; - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { - preset_name = "FM238"; - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { - preset_name = "FM476"; - } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { - preset_name = "CUSTOM"; - } else { - FURI_LOG_E(TAG, "Unknown preset"); - } - return preset_name; -} - -SubGhzRadioPreset subghz_txrx_get_preset(SubGhzTxRx* instance) { - furi_assert(instance); - return *instance->preset; -} - -void subghz_txrx_get_frequency_and_modulation( - SubGhzTxRx* instance, - FuriString* frequency, - FuriString* modulation, - bool long_name) { - furi_assert(instance); - SubGhzRadioPreset* preset = instance->preset; - if(frequency != NULL) { - furi_string_printf( - frequency, - "%03ld.%02ld", - preset->frequency / 1000000 % 1000, - preset->frequency / 10000 % 100); - } - if(modulation != NULL) { - if(long_name) { - furi_string_printf(modulation, "%s", furi_string_get_cstr(preset->name)); - } else { - furi_string_printf(modulation, "%.2s", furi_string_get_cstr(preset->name)); - } - } -} - -static void subghz_txrx_begin(SubGhzTxRx* instance, uint8_t* preset_data) { - furi_assert(instance); - subghz_devices_reset(instance->radio_device); - subghz_devices_idle(instance->radio_device); - subghz_devices_load_preset(instance->radio_device, FuriHalSubGhzPresetCustom, preset_data); - instance->txrx_state = SubGhzTxRxStateIDLE; -} - -static uint32_t subghz_txrx_rx(SubGhzTxRx* instance, uint32_t frequency) { - furi_assert(instance); - furi_assert( - instance->txrx_state != SubGhzTxRxStateRx && instance->txrx_state != SubGhzTxRxStateSleep); - - subghz_devices_idle(instance->radio_device); - - uint32_t value = subghz_devices_set_frequency(instance->radio_device, frequency); - subghz_devices_flush_rx(instance->radio_device); - subghz_txrx_speaker_on(instance); - - subghz_devices_start_async_rx( - instance->radio_device, subghz_worker_rx_callback, instance->worker); - subghz_worker_start(instance->worker); - instance->txrx_state = SubGhzTxRxStateRx; - return value; -} - -static void subghz_txrx_idle(SubGhzTxRx* instance) { - furi_assert(instance); - furi_assert(instance->txrx_state != SubGhzTxRxStateSleep); - subghz_devices_idle(instance->radio_device); - subghz_txrx_speaker_off(instance); - instance->txrx_state = SubGhzTxRxStateIDLE; -} - -static void subghz_txrx_rx_end(SubGhzTxRx* instance) { - furi_assert(instance); - furi_assert(instance->txrx_state == SubGhzTxRxStateRx); - - if(subghz_worker_is_running(instance->worker)) { - subghz_worker_stop(instance->worker); - subghz_devices_stop_async_rx(instance->radio_device); - } - subghz_devices_idle(instance->radio_device); - subghz_txrx_speaker_off(instance); - instance->txrx_state = SubGhzTxRxStateIDLE; -} - -void subghz_txrx_sleep(SubGhzTxRx* instance) { - furi_assert(instance); - subghz_devices_sleep(instance->radio_device); - instance->txrx_state = SubGhzTxRxStateSleep; -} - -static bool subghz_txrx_tx(SubGhzTxRx* instance, uint32_t frequency) { - furi_assert(instance); - furi_assert(instance->txrx_state != SubGhzTxRxStateSleep); - - subghz_devices_idle(instance->radio_device); - subghz_devices_set_frequency(instance->radio_device, frequency); - - bool ret = subghz_devices_set_tx(instance->radio_device); - if(ret) { - subghz_txrx_speaker_on(instance); - instance->txrx_state = SubGhzTxRxStateTx; - } - - return ret; -} - -SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat* flipper_format) { - furi_assert(instance); - furi_assert(flipper_format); - - subghz_txrx_stop(instance); - - SubGhzTxRxStartTxState ret = SubGhzTxRxStartTxStateErrorParserOthers; - FuriString* temp_str = furi_string_alloc(); - uint32_t repeat = 200; - do { - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_string(flipper_format, "Protocol", temp_str)) { - FURI_LOG_E(TAG, "Missing Protocol"); - break; - } - if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) { - FURI_LOG_E(TAG, "Unable Repeat"); - break; - } - ret = SubGhzTxRxStartTxStateOk; - - SubGhzRadioPreset* preset = instance->preset; - instance->transmitter = - subghz_transmitter_alloc_init(instance->environment, furi_string_get_cstr(temp_str)); - - if(instance->transmitter) { - if(subghz_transmitter_deserialize(instance->transmitter, flipper_format) == - SubGhzProtocolStatusOk) { - if(strcmp(furi_string_get_cstr(preset->name), "") != 0) { - subghz_txrx_begin( - instance, - subghz_setting_get_preset_data_by_name( - instance->setting, furi_string_get_cstr(preset->name))); - if(preset->frequency) { - if(!subghz_txrx_tx(instance, preset->frequency)) { - FURI_LOG_E(TAG, "Only Rx"); - ret = SubGhzTxRxStartTxStateErrorOnlyRx; - } - } else { - ret = SubGhzTxRxStartTxStateErrorParserOthers; - } - - } else { - FURI_LOG_E( - TAG, "Unknown name preset \" %s \"", furi_string_get_cstr(preset->name)); - ret = SubGhzTxRxStartTxStateErrorParserOthers; - } - - if(ret == SubGhzTxRxStartTxStateOk) { - //Start TX - subghz_devices_start_async_tx( - instance->radio_device, subghz_transmitter_yield, instance->transmitter); - } - } else { - ret = SubGhzTxRxStartTxStateErrorParserOthers; - } - } else { - ret = SubGhzTxRxStartTxStateErrorParserOthers; - } - if(ret != SubGhzTxRxStartTxStateOk) { - subghz_transmitter_free(instance->transmitter); - if(instance->txrx_state != SubGhzTxRxStateIDLE) { - subghz_txrx_idle(instance); - } - } - - } while(false); - furi_string_free(temp_str); - return ret; -} - -void subghz_txrx_rx_start(SubGhzTxRx* instance) { - furi_assert(instance); - subghz_txrx_stop(instance); - subghz_txrx_begin( - instance, - subghz_setting_get_preset_data_by_name( - subghz_txrx_get_setting(instance), furi_string_get_cstr(instance->preset->name))); - subghz_txrx_rx(instance, instance->preset->frequency); -} - -void subghz_txrx_set_need_save_callback( - SubGhzTxRx* instance, - SubGhzTxRxNeedSaveCallback callback, - void* context) { - furi_assert(instance); - instance->need_save_callback = callback; - instance->need_save_context = context; -} - -static void subghz_txrx_tx_stop(SubGhzTxRx* instance) { - furi_assert(instance); - furi_assert(instance->txrx_state == SubGhzTxRxStateTx); - //Stop TX - subghz_devices_stop_async_tx(instance->radio_device); - subghz_transmitter_stop(instance->transmitter); - subghz_transmitter_free(instance->transmitter); - - //if protocol dynamic then we save the last upload - if(instance->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) { - if(instance->need_save_callback) { - instance->need_save_callback(instance->need_save_context); - } - } - subghz_txrx_idle(instance); - subghz_txrx_speaker_off(instance); - //Todo: Show message -} - -FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->fff_data; -} - -SubGhzSetting* subghz_txrx_get_setting(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->setting; -} - -void subghz_txrx_stop(SubGhzTxRx* instance) { - furi_assert(instance); - - switch(instance->txrx_state) { - case SubGhzTxRxStateTx: - subghz_txrx_tx_stop(instance); - subghz_txrx_speaker_unmute(instance); - break; - case SubGhzTxRxStateRx: - subghz_txrx_rx_end(instance); - subghz_txrx_speaker_mute(instance); - break; - - default: - break; - } -} - -void subghz_txrx_hopper_update(SubGhzTxRx* instance) { - furi_assert(instance); - - switch(instance->hopper_state) { - case SubGhzHopperStateOFF: - case SubGhzHopperStatePause: - return; - case SubGhzHopperStateRSSITimeOut: - if(instance->hopper_timeout != 0) { - instance->hopper_timeout--; - return; - } - break; - default: - break; - } - float rssi = -127.0f; - if(instance->hopper_state != SubGhzHopperStateRSSITimeOut) { - // See RSSI Calculation timings in CC1101 17.3 RSSI - rssi = subghz_devices_get_rssi(instance->radio_device); - - // Stay if RSSI is high enough - if(rssi > -90.0f) { - instance->hopper_timeout = 10; - instance->hopper_state = SubGhzHopperStateRSSITimeOut; - return; - } - } else { - instance->hopper_state = SubGhzHopperStateRunning; - } - // Select next frequency - if(instance->hopper_idx_frequency < - subghz_setting_get_hopper_frequency_count(instance->setting) - 1) { - instance->hopper_idx_frequency++; - } else { - instance->hopper_idx_frequency = 0; - } - - if(instance->txrx_state == SubGhzTxRxStateRx) { - subghz_txrx_rx_end(instance); - }; - if(instance->txrx_state == SubGhzTxRxStateIDLE) { - subghz_receiver_reset(instance->receiver); - instance->preset->frequency = - subghz_setting_get_hopper_frequency(instance->setting, instance->hopper_idx_frequency); - subghz_txrx_rx(instance, instance->preset->frequency); - } -} - -SubGhzHopperState subghz_txrx_hopper_get_state(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->hopper_state; -} - -void subghz_txrx_hopper_set_state(SubGhzTxRx* instance, SubGhzHopperState state) { - furi_assert(instance); - instance->hopper_state = state; -} - -void subghz_txrx_hopper_unpause(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->hopper_state == SubGhzHopperStatePause) { - instance->hopper_state = SubGhzHopperStateRunning; - } -} - -void subghz_txrx_hopper_pause(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->hopper_state == SubGhzHopperStateRunning) { - instance->hopper_state = SubGhzHopperStatePause; - } -} - -void subghz_txrx_speaker_on(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_ibutton); - } - - if(instance->speaker_state == SubGhzSpeakerStateEnable) { - if(furi_hal_speaker_acquire(30)) { - if(!instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_speaker); - } - } else { - instance->speaker_state = SubGhzSpeakerStateDisable; - } - } -} - -void subghz_txrx_speaker_off(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, NULL); - } - if(instance->speaker_state != SubGhzSpeakerStateDisable) { - if(furi_hal_speaker_is_mine()) { - if(!instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, NULL); - } - furi_hal_speaker_release(); - if(instance->speaker_state == SubGhzSpeakerStateShutdown) - instance->speaker_state = SubGhzSpeakerStateDisable; - } - } -} - -void subghz_txrx_speaker_mute(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, NULL); - } - if(instance->speaker_state == SubGhzSpeakerStateEnable) { - if(furi_hal_speaker_is_mine()) { - if(!instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, NULL); - } - } - } -} - -void subghz_txrx_speaker_unmute(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_ibutton); - } - if(instance->speaker_state == SubGhzSpeakerStateEnable) { - if(furi_hal_speaker_is_mine()) { - if(!instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_speaker); - } - } - } -} - -void subghz_txrx_speaker_set_state(SubGhzTxRx* instance, SubGhzSpeakerState state) { - furi_assert(instance); - instance->speaker_state = state; -} - -SubGhzSpeakerState subghz_txrx_speaker_get_state(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->speaker_state; -} - -bool subghz_txrx_load_decoder_by_name_protocol(SubGhzTxRx* instance, const char* name_protocol) { - furi_assert(instance); - furi_assert(name_protocol); - bool res = false; - instance->decoder_result = - subghz_receiver_search_decoder_base_by_name(instance->receiver, name_protocol); - if(instance->decoder_result) { - res = true; - } - return res; -} - -SubGhzProtocolDecoderBase* subghz_txrx_get_decoder(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->decoder_result; -} - -bool subghz_txrx_protocol_is_serializable(SubGhzTxRx* instance) { - furi_assert(instance); - return ( - (instance->decoder_result->protocol->flag & SubGhzProtocolFlag_Save) == - SubGhzProtocolFlag_Save); -} - -bool subghz_txrx_protocol_is_transmittable(SubGhzTxRx* instance, bool check_type) { - furi_assert(instance); - const SubGhzProtocol* protocol = instance->decoder_result->protocol; - if(check_type) { - return ( - ((protocol->flag & SubGhzProtocolFlag_Send) == SubGhzProtocolFlag_Send) && - protocol->encoder->deserialize && protocol->type == SubGhzProtocolTypeStatic); - } - return ( - ((protocol->flag & SubGhzProtocolFlag_Send) == SubGhzProtocolFlag_Send) && - protocol->encoder->deserialize); -} - -void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag filter) { - furi_assert(instance); - subghz_receiver_set_filter(instance->receiver, filter); -} - -void subghz_txrx_set_rx_calback( - SubGhzTxRx* instance, - SubGhzReceiverCallback callback, - void* context) { - subghz_receiver_set_rx_callback(instance->receiver, callback, context); -} - -void subghz_txrx_set_raw_file_encoder_worker_callback_end( - SubGhzTxRx* instance, - SubGhzProtocolEncoderRAWCallbackEnd callback, - void* context) { - subghz_protocol_raw_file_encoder_worker_set_callback_end( - (SubGhzProtocolEncoderRAW*)subghz_transmitter_get_protocol_instance(instance->transmitter), - callback, - context); -} - -bool subghz_txrx_radio_device_is_external_connected(SubGhzTxRx* instance, const char* name) { - furi_assert(instance); - - bool is_connect = false; - bool is_otg_enabled = furi_hal_power_is_otg_enabled(); - - if(!is_otg_enabled) { - subghz_txrx_radio_device_power_on(instance); - } - - const SubGhzDevice* device = subghz_devices_get_by_name(name); - if(device) { - is_connect = subghz_devices_is_connect(device); - } - - if(!is_otg_enabled) { - subghz_txrx_radio_device_power_off(instance); - } - return is_connect; -} - -SubGhzRadioDeviceType - subghz_txrx_radio_device_set(SubGhzTxRx* instance, SubGhzRadioDeviceType radio_device_type) { - furi_assert(instance); - - if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 && - subghz_txrx_radio_device_is_external_connected(instance, SUBGHZ_DEVICE_CC1101_EXT_NAME)) { - subghz_txrx_radio_device_power_on(instance); - instance->radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME); - subghz_devices_begin(instance->radio_device); - instance->radio_device_type = SubGhzRadioDeviceTypeExternalCC1101; - } else { - subghz_txrx_radio_device_power_off(instance); - if(instance->radio_device_type != SubGhzRadioDeviceTypeInternal) { - subghz_devices_end(instance->radio_device); - } - instance->radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - instance->radio_device_type = SubGhzRadioDeviceTypeInternal; - } - - return instance->radio_device_type; -} - -SubGhzRadioDeviceType subghz_txrx_radio_device_get(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->radio_device_type; -} - -float subghz_txrx_radio_device_get_rssi(SubGhzTxRx* instance) { - furi_assert(instance); - return subghz_devices_get_rssi(instance->radio_device); -} - -const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance) { - furi_assert(instance); - return subghz_devices_get_name(instance->radio_device); -} - -bool subghz_txrx_radio_device_is_frequency_valid(SubGhzTxRx* instance, uint32_t frequency) { - furi_assert(instance); - return subghz_devices_is_frequency_valid(instance->radio_device, frequency); -} - -bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequency) { - furi_assert(instance); - furi_assert(instance->txrx_state != SubGhzTxRxStateSleep); - - subghz_devices_idle(instance->radio_device); - subghz_devices_set_frequency(instance->radio_device, frequency); - - bool ret = subghz_devices_set_tx(instance->radio_device); - subghz_devices_idle(instance->radio_device); - - return ret; -} - -void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state) { - furi_assert(instance); - instance->debug_pin_state = state; -} - -bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->debug_pin_state; -} - -#ifndef FW_ORIGIN_Official -void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) { - furi_assert(instance); - subghz_environment_reset_keeloq(instance->environment); - - subghz_custom_btns_reset(); -} -#endif - -SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->receiver; -} \ No newline at end of file diff --git a/applications/system/subghz_remote/helpers/txrx/subghz_txrx.h b/applications/system/subghz_remote/helpers/txrx/subghz_txrx.h deleted file mode 100644 index 8a96c54c3..000000000 --- a/applications/system/subghz_remote/helpers/txrx/subghz_txrx.h +++ /dev/null @@ -1,375 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -typedef struct SubGhzTxRx SubGhzTxRx; - -typedef void (*SubGhzTxRxNeedSaveCallback)(void* context); - -typedef enum { - SubGhzTxRxStartTxStateOk, - SubGhzTxRxStartTxStateErrorOnlyRx, - SubGhzTxRxStartTxStateErrorParserOthers, -} SubGhzTxRxStartTxState; - -// Type from subghz_types.h need for txrx working -/** SubGhzTxRx state */ -typedef enum { - SubGhzTxRxStateIDLE, - SubGhzTxRxStateRx, - SubGhzTxRxStateTx, - SubGhzTxRxStateSleep, -} SubGhzTxRxState; - -/** SubGhzHopperState state */ -typedef enum { - SubGhzHopperStateOFF, - SubGhzHopperStateRunning, - SubGhzHopperStatePause, - SubGhzHopperStateRSSITimeOut, -} SubGhzHopperState; - -/** SubGhzSpeakerState state */ -typedef enum { - SubGhzSpeakerStateDisable, - SubGhzSpeakerStateShutdown, - SubGhzSpeakerStateEnable, -} SubGhzSpeakerState; - -/** SubGhzRadioDeviceType */ -typedef enum { - SubGhzRadioDeviceTypeAuto, - SubGhzRadioDeviceTypeInternal, - SubGhzRadioDeviceTypeExternalCC1101, -} SubGhzRadioDeviceType; - -/** - * Allocate SubGhzTxRx - * - * @return SubGhzTxRx* pointer to SubGhzTxRx - */ -SubGhzTxRx* subghz_txrx_alloc(void); - -/** - * Free SubGhzTxRx - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_free(SubGhzTxRx* instance); - -/** - * Check if the database is loaded - * - * @param instance Pointer to a SubGhzTxRx - * @return bool True if the database is loaded - */ -bool subghz_txrx_is_database_loaded(SubGhzTxRx* instance); - -/** - * Set preset - * - * @param instance Pointer to a SubGhzTxRx - * @param preset_name Name of preset - * @param frequency Frequency in Hz - * @param preset_data Data of preset - * @param preset_data_size Size of preset data - */ -void subghz_txrx_set_preset( - SubGhzTxRx* instance, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size); - -/** - * Get name of preset - * - * @param instance Pointer to a SubGhzTxRx - * @param preset String of preset - * @return const char* Name of preset - */ -const char* subghz_txrx_get_preset_name(SubGhzTxRx* instance, const char* preset); - -/** - * Get of preset - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzRadioPreset Preset - */ -SubGhzRadioPreset subghz_txrx_get_preset(SubGhzTxRx* instance); - -/** - * Get string frequency and modulation - * - * @param instance Pointer to a SubGhzTxRx - * @param frequency Pointer to a string frequency - * @param modulation Pointer to a string modulation - */ -void subghz_txrx_get_frequency_and_modulation( - SubGhzTxRx* instance, - FuriString* frequency, - FuriString* modulation, - bool long_name); - -/** - * Start TX CC1101 - * - * @param instance Pointer to a SubGhzTxRx - * @param flipper_format Pointer to a FlipperFormat - * @return SubGhzTxRxStartTxState - */ -SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat* flipper_format); - -/** - * Start RX CC1101 - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_rx_start(SubGhzTxRx* instance); - -/** - * Stop TX/RX CC1101 - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_stop(SubGhzTxRx* instance); - -/** - * Set sleep mode CC1101 - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_sleep(SubGhzTxRx* instance); - -/** - * Update frequency CC1101 in automatic mode (hopper) - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_hopper_update(SubGhzTxRx* instance); - -/** - * Get state hopper - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzHopperState - */ -SubGhzHopperState subghz_txrx_hopper_get_state(SubGhzTxRx* instance); - -/** - * Set state hopper - * - * @param instance Pointer to a SubGhzTxRx - * @param state State hopper - */ -void subghz_txrx_hopper_set_state(SubGhzTxRx* instance, SubGhzHopperState state); - -/** - * Unpause hopper - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_hopper_unpause(SubGhzTxRx* instance); - -/** - * Set pause hopper - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_hopper_pause(SubGhzTxRx* instance); - -/** - * Speaker on - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_speaker_on(SubGhzTxRx* instance); - -/** - * Speaker off - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_speaker_off(SubGhzTxRx* instance); - -/** - * Speaker mute - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_speaker_mute(SubGhzTxRx* instance); - -/** - * Speaker unmute - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_speaker_unmute(SubGhzTxRx* instance); - -/** - * Set state speaker - * - * @param instance Pointer to a SubGhzTxRx - * @param state State speaker - */ -void subghz_txrx_speaker_set_state(SubGhzTxRx* instance, SubGhzSpeakerState state); - -/** - * Get state speaker - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzSpeakerState - */ -SubGhzSpeakerState subghz_txrx_speaker_get_state(SubGhzTxRx* instance); - -/** - * load decoder by name protocol - * - * @param instance Pointer to a SubGhzTxRx - * @param name_protocol Name protocol - * @return bool True if the decoder is loaded - */ -bool subghz_txrx_load_decoder_by_name_protocol(SubGhzTxRx* instance, const char* name_protocol); - -/** - * Get decoder - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzProtocolDecoderBase* Pointer to a SubGhzProtocolDecoderBase - */ -SubGhzProtocolDecoderBase* subghz_txrx_get_decoder(SubGhzTxRx* instance); - -/** - * Set callback for save data - * - * @param instance Pointer to a SubGhzTxRx - * @param callback Callback for save data - * @param context Context for callback - */ -void subghz_txrx_set_need_save_callback( - SubGhzTxRx* instance, - SubGhzTxRxNeedSaveCallback callback, - void* context); - -/** - * Get pointer to a load data key - * - * @param instance Pointer to a SubGhzTxRx - * @return FlipperFormat* - */ -FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance); - -/** - * Get pointer to a SugGhzSetting - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzSetting* - */ -SubGhzSetting* subghz_txrx_get_setting(SubGhzTxRx* instance); - -/** - * Is it possible to save this protocol - * - * @param instance Pointer to a SubGhzTxRx - * @return bool True if it is possible to save this protocol - */ -bool subghz_txrx_protocol_is_serializable(SubGhzTxRx* instance); - -/** - * Is it possible to send this protocol - * - * @param instance Pointer to a SubGhzTxRx - * @return bool True if it is possible to send this protocol - */ -bool subghz_txrx_protocol_is_transmittable(SubGhzTxRx* instance, bool check_type); - -/** - * Set filter, what types of decoder to use - * - * @param instance Pointer to a SubGhzTxRx - * @param filter Filter - */ -void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag filter); - -/** - * Set callback for receive data - * - * @param instance Pointer to a SubGhzTxRx - * @param callback Callback for receive data - * @param context Context for callback - */ -void subghz_txrx_set_rx_calback( - SubGhzTxRx* instance, - SubGhzReceiverCallback callback, - void* context); - -/** - * Set callback for Raw decoder, end of data transfer - * - * @param instance Pointer to a SubGhzTxRx - * @param callback Callback for Raw decoder, end of data transfer - * @param context Context for callback - */ -void subghz_txrx_set_raw_file_encoder_worker_callback_end( - SubGhzTxRx* instance, - SubGhzProtocolEncoderRAWCallbackEnd callback, - void* context); - -/* Checking if an external radio device is connected -* -* @param instance Pointer to a SubGhzTxRx -* @param name Name of external radio device -* @return bool True if is connected to the external radio device -*/ -bool subghz_txrx_radio_device_is_external_connected(SubGhzTxRx* instance, const char* name); - -/* Set the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @param radio_device_type Radio device type -* @return SubGhzRadioDeviceType Type of installed radio device -*/ -SubGhzRadioDeviceType - subghz_txrx_radio_device_set(SubGhzTxRx* instance, SubGhzRadioDeviceType radio_device_type); - -/* Get the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @return SubGhzRadioDeviceType Type of installed radio device -*/ -SubGhzRadioDeviceType subghz_txrx_radio_device_get(SubGhzTxRx* instance); - -/* Get RSSI the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @return float RSSI -*/ -float subghz_txrx_radio_device_get_rssi(SubGhzTxRx* instance); - -/* Get name the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @return const char* Name of installed radio device -*/ -const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance); - -/* Get get intelligence whether frequency the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @return bool True if the frequency is valid -*/ -bool subghz_txrx_radio_device_is_frequency_valid(SubGhzTxRx* instance, uint32_t frequency); - -bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequency); - -void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state); -bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance); -#ifndef FW_ORIGIN_Official -void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance); -#endif -SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw diff --git a/applications/system/subghz_remote/helpers/txrx/subghz_txrx_i.h b/applications/system/subghz_remote/helpers/txrx/subghz_txrx_i.h deleted file mode 100644 index f058c2282..000000000 --- a/applications/system/subghz_remote/helpers/txrx/subghz_txrx_i.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "subghz_txrx.h" - -struct SubGhzTxRx { - SubGhzWorker* worker; - - SubGhzEnvironment* environment; - SubGhzReceiver* receiver; - SubGhzTransmitter* transmitter; - SubGhzProtocolDecoderBase* decoder_result; - FlipperFormat* fff_data; - - SubGhzRadioPreset* preset; - SubGhzSetting* setting; - - uint8_t hopper_timeout; - uint8_t hopper_idx_frequency; - bool is_database_loaded; - SubGhzHopperState hopper_state; - - SubGhzTxRxState txrx_state; - SubGhzSpeakerState speaker_state; - const SubGhzDevice* radio_device; - SubGhzRadioDeviceType radio_device_type; - - SubGhzTxRxNeedSaveCallback need_save_callback; - void* need_save_context; - - bool debug_pin_state; -}; diff --git a/applications/system/subghz_remote/icon.png b/applications/system/subghz_remote/icon.png deleted file mode 100644 index c6b410f4c..000000000 Binary files a/applications/system/subghz_remote/icon.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/down.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/down.png deleted file mode 100644 index 198e22ea2..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/down.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/down_hover.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/down_hover.png deleted file mode 100644 index 39ac087e7..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/down_hover.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/left.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/left.png deleted file mode 100644 index 38b83c79b..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/left.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/left_hover.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/left_hover.png deleted file mode 100644 index 45f58b8b6..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/left_hover.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/ok.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/ok.png deleted file mode 100644 index dfd3d2fd1..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/ok.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/ok_hover.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/ok_hover.png deleted file mode 100644 index 9107c1a79..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/ok_hover.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/right.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/right.png deleted file mode 100644 index ca6748f9a..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/right.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/right_hover.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/right_hover.png deleted file mode 100644 index 2d53ce701..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/right_hover.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/up.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/up.png deleted file mode 100644 index cd032ed12..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/up.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/Dpad/up_hover.png b/applications/system/subghz_remote/icons/remote_scene/Dpad/up_hover.png deleted file mode 100644 index 8bc334750..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/Dpad/up_hover.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/statusbar/External_antenna_20x12.png b/applications/system/subghz_remote/icons/remote_scene/statusbar/External_antenna_20x12.png deleted file mode 100644 index 940087071..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/statusbar/External_antenna_20x12.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/statusbar/Internal_antenna_20x12.png b/applications/system/subghz_remote/icons/remote_scene/statusbar/Internal_antenna_20x12.png deleted file mode 100644 index a8a5be09f..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/statusbar/Internal_antenna_20x12.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/statusbar/Status_cube_14x14.png b/applications/system/subghz_remote/icons/remote_scene/statusbar/Status_cube_14x14.png deleted file mode 100644 index f1e72cbbd..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/statusbar/Status_cube_14x14.png and /dev/null differ diff --git a/applications/system/subghz_remote/icons/remote_scene/statusbar/status_bar.png b/applications/system/subghz_remote/icons/remote_scene/statusbar/status_bar.png deleted file mode 100644 index 8136fe32e..000000000 Binary files a/applications/system/subghz_remote/icons/remote_scene/statusbar/status_bar.png and /dev/null differ diff --git a/applications/system/subghz_remote/scenes/subrem_scene.c b/applications/system/subghz_remote/scenes/subrem_scene.c deleted file mode 100644 index c45285b96..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "../subghz_remote_app_i.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const subrem_scene_on_enter_handlers[])(void*) = { -#include "subrem_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const subrem_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "subrem_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const subrem_scene_on_exit_handlers[])(void* context) = { -#include "subrem_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers subrem_scene_handlers = { - .on_enter_handlers = subrem_scene_on_enter_handlers, - .on_event_handlers = subrem_scene_on_event_handlers, - .on_exit_handlers = subrem_scene_on_exit_handlers, - .scene_num = SubRemSceneNum, -}; diff --git a/applications/system/subghz_remote/scenes/subrem_scene.h b/applications/system/subghz_remote/scenes/subrem_scene.h deleted file mode 100644 index 5c01f8ca5..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) SubRemScene##id, -typedef enum { -#include "subrem_scene_config.h" - SubRemSceneNum, -} SubRemScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers subrem_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "subrem_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "subrem_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "subrem_scene_config.h" -#undef ADD_SCENE diff --git a/applications/system/subghz_remote/scenes/subrem_scene_config.h b/applications/system/subghz_remote/scenes/subrem_scene_config.h deleted file mode 100644 index 56fe641a6..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_config.h +++ /dev/null @@ -1,12 +0,0 @@ -ADD_SCENE(subrem, start, Start) -ADD_SCENE(subrem, open_map_file, OpenMapFile) -ADD_SCENE(subrem, remote, Remote) -ADD_SCENE(subrem, edit_menu, EditMenu) -ADD_SCENE(subrem, edit_submenu, EditSubMenu) -ADD_SCENE(subrem, edit_label, EditLabel) -ADD_SCENE(subrem, open_sub_file, OpenSubFile) -ADD_SCENE(subrem, edit_preview, EditPreview) -ADD_SCENE(subrem, enter_new_name, EnterNewName) -#ifdef FW_ORIGIN_Official -ADD_SCENE(subrem, fw_warning, FwWarning) -#endif \ No newline at end of file diff --git a/applications/system/subghz_remote/scenes/subrem_scene_edit_label.c b/applications/system/subghz_remote/scenes/subrem_scene_edit_label.c deleted file mode 100644 index 25c10bb46..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_edit_label.c +++ /dev/null @@ -1,133 +0,0 @@ -#include "../subghz_remote_app_i.h" - -#include - -typedef enum { - SubRemSceneEditLabelStateTextInput, - SubRemSceneEditLabelStateWidget, -} SubRemSceneEditLabelState; - -void subrem_scene_edit_label_text_input_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditLabelInputDone); -} - -void subrem_scene_edit_label_widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - if((result == GuiButtonTypeCenter) && (type == InputTypeShort)) { - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditLabelWidgetAcces); - } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditLabelWidgetBack); - } -} - -void subrem_scene_edit_label_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - SubRemSubFilePreset* sub_preset = app->map_preset->subs_preset[app->chosen_sub]; - - FuriString* temp_str = furi_string_alloc(); - - if(furi_string_empty(sub_preset->label)) { - if(furi_string_empty(sub_preset->file_path)) { - path_extract_filename(sub_preset->file_path, temp_str, true); - strcpy(app->file_name_tmp, furi_string_get_cstr(temp_str)); - } else { - strcpy(app->file_name_tmp, ""); - } - } else { - strcpy(app->file_name_tmp, furi_string_get_cstr(sub_preset->label)); - } - - TextInput* text_input = app->text_input; - text_input_set_header_text(text_input, "Label name"); - text_input_set_result_callback( - text_input, - subrem_scene_edit_label_text_input_callback, - app, - app->file_name_tmp, - 25, - false); -#ifndef FW_ORIGIN_Official - text_input_set_minimum_length(app->text_input, 0); -#endif - widget_add_string_element( - app->widget, 63, 12, AlignCenter, AlignCenter, FontPrimary, "Empty Label Name"); - widget_add_string_element( - app->widget, 63, 32, AlignCenter, AlignCenter, FontSecondary, "Continue?"); - - widget_add_button_element( - app->widget, GuiButtonTypeCenter, "Ok", subrem_scene_edit_label_widget_callback, app); - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Back", subrem_scene_edit_label_widget_callback, app); - - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditLabel, SubRemSceneEditLabelStateTextInput); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDTextInput); - - furi_string_free(temp_str); -} - -bool subrem_scene_edit_label_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - - FuriString* label = app->map_preset->subs_preset[app->chosen_sub]->label; - - if(event.type == SceneManagerEventTypeBack) { - if(scene_manager_get_scene_state(app->scene_manager, SubRemSceneEditLabel) == - SubRemSceneEditLabelStateWidget) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditLabel, SubRemSceneEditLabelStateTextInput); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDTextInput); - return true; - } else if( - scene_manager_get_scene_state(app->scene_manager, SubRemSceneEditLabel) == - SubRemSceneEditLabelStateTextInput) { - scene_manager_previous_scene(app->scene_manager); - return true; - } - - scene_manager_previous_scene(app->scene_manager); - return true; - } else if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventSceneEditLabelInputDone) { - if(strcmp(app->file_name_tmp, "") == 0) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditLabel, SubRemSceneEditLabelStateWidget); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); - - } else { - furi_string_set(label, app->file_name_tmp); - app->map_not_saved = true; - scene_manager_previous_scene(app->scene_manager); - } - return true; - } else if(event.event == SubRemCustomEventSceneEditLabelWidgetAcces) { - furi_string_set(label, app->file_name_tmp); - app->map_not_saved = true; - scene_manager_previous_scene(app->scene_manager); - - return true; - } else if(event.event == SubRemCustomEventSceneEditLabelWidgetBack) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditLabel, SubRemSceneEditLabelStateTextInput); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDTextInput); - - return true; - } - } - return false; -} - -void subrem_scene_edit_label_on_exit(void* context) { - SubGhzRemoteApp* app = context; - - // Clear view - text_input_reset(app->text_input); - widget_reset(app->widget); -} diff --git a/applications/system/subghz_remote/scenes/subrem_scene_edit_menu.c b/applications/system/subghz_remote/scenes/subrem_scene_edit_menu.c deleted file mode 100644 index bc54311c5..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_edit_menu.c +++ /dev/null @@ -1,123 +0,0 @@ -#include "../subghz_remote_app_i.h" - -void subrem_scene_edit_menu_callback(SubRemCustomEvent event, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void subrem_scene_edit_menu_widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { - app->map_not_saved = false; - view_dispatcher_send_custom_event(app->view_dispatcher, SubRemCustomEventViewEditMenuBack); - } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDEditMenu); - } -} - -static uint8_t subrem_scene_edit_menu_state_to_index(SubRemEditMenuState event_id) { - uint8_t ret = 0; - - if(event_id == SubRemEditMenuStateUP) { - ret = SubRemSubKeyNameUp; - } else if(event_id == SubRemEditMenuStateDOWN) { - ret = SubRemSubKeyNameDown; - } else if(event_id == SubRemEditMenuStateLEFT) { - ret = SubRemSubKeyNameLeft; - } else if(event_id == SubRemEditMenuStateRIGHT) { - ret = SubRemSubKeyNameRight; - } else if(event_id == SubRemEditMenuStateOK) { - ret = SubRemSubKeyNameOk; - } - - return ret; -} - -static void subrem_scene_edit_menu_update_data(SubGhzRemoteApp* app) { - furi_assert(app); - uint8_t index = subrem_scene_edit_menu_state_to_index( - scene_manager_get_scene_state(app->scene_manager, SubRemSceneEditMenu)); - - subrem_view_edit_menu_add_data_to_show( - app->subrem_edit_menu, - index, - app->map_preset->subs_preset[index]->label, - app->map_preset->subs_preset[index]->file_path, - app->map_preset->subs_preset[index]->load_state); -} - -void subrem_scene_edit_menu_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - subrem_view_edit_menu_set_callback( - app->subrem_edit_menu, subrem_scene_edit_menu_callback, app); - - subrem_scene_edit_menu_update_data(app); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDEditMenu); - - Widget* widget = app->widget; - - widget_add_string_element( - widget, 63, 12, AlignCenter, AlignBottom, FontPrimary, "Changes are not saved"); - widget_add_string_element( - widget, 63, 32, AlignCenter, AlignBottom, FontPrimary, "do you want to exit?"); - - widget_add_button_element( - widget, GuiButtonTypeRight, "Yes", subrem_scene_edit_menu_widget_callback, app); - widget_add_button_element( - widget, GuiButtonTypeLeft, "No", subrem_scene_edit_menu_widget_callback, app); -} - -bool subrem_scene_edit_menu_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - - if(event.type == SceneManagerEventTypeBack) { - // Catch widget backEvent - return true; - } - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventViewEditMenuBack) { - if(app->map_not_saved) { - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); - } else if(!scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SubRemSceneStart)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } - - return true; - } else if( - event.event == SubRemCustomEventViewEditMenuUP || - event.event == SubRemCustomEventViewEditMenuDOWN) { - scene_manager_set_scene_state( - app->scene_manager, - SubRemSceneEditMenu, - subrem_view_edit_menu_get_index(app->subrem_edit_menu)); - subrem_scene_edit_menu_update_data(app); - - return true; - } else if(event.event == SubRemCustomEventViewEditMenuEdit) { - app->chosen_sub = subrem_view_edit_menu_get_index(app->subrem_edit_menu); - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditSubMenu, EditSubmenuIndexEditLabel); - scene_manager_next_scene(app->scene_manager, SubRemSceneEditSubMenu); - - return true; - } else if(event.event == SubRemCustomEventViewEditMenuSave) { - scene_manager_next_scene(app->scene_manager, SubRemSceneEditPreview); - - return true; - } - } - - return false; -} - -void subrem_scene_edit_menu_on_exit(void* context) { - SubGhzRemoteApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/system/subghz_remote/scenes/subrem_scene_edit_preview.c b/applications/system/subghz_remote/scenes/subrem_scene_edit_preview.c deleted file mode 100644 index 9f5812890..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_edit_preview.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../views/remote.h" - -#define TAG "SubRemScenRemote" - -void subghz_scene_edit_preview_save_popup_callback(void* context) { - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditPreviewSaved); -} - -void subrem_scene_edit_preview_callback(SubRemCustomEvent event, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void subrem_scene_edit_preview_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - // Setup view - Popup* popup = app->popup; - popup_set_icon(popup, 36, 5, &I_DolphinDone_80x58); - popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, app); - popup_set_callback(popup, subghz_scene_edit_preview_save_popup_callback); - popup_enable_timeout(popup); - - subrem_view_remote_update_data_labels(app->subrem_remote_view, app->map_preset->subs_preset); - subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateOFF, 0); - - subrem_view_remote_set_callback( - app->subrem_remote_view, subrem_scene_edit_preview_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDRemote); -} - -bool subrem_scene_edit_preview_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - - if(event.type == SceneManagerEventTypeBack || - (event.type == SceneManagerEventTypeCustom && - (event.event == SubRemCustomEventViewRemoteStartLEFT || - event.event == SubRemCustomEventViewRemoteForcedStop))) { - scene_manager_previous_scene(app->scene_manager); - return true; - } else if( - event.type == SceneManagerEventTypeCustom && - (event.event == SubRemCustomEventViewRemoteStartRIGHT || - event.event == SubRemCustomEventViewRemoteStartOK)) { - if(subrem_save_map_to_file(app)) { - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDPopup); - app->map_not_saved = false; - return true; - } - // TODO error screen - return true; - } else if( - event.type == SceneManagerEventTypeCustom && - event.event == SubRemCustomEventSceneEditPreviewSaved) { - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, SubRemSceneEditMenu); - } - // } else if(event.type == SceneManagerEventTypeTick) { - // } - return false; -} - -void subrem_scene_edit_preview_on_exit(void* context) { - SubGhzRemoteApp* app = context; - - subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - popup_reset(app->popup); -} diff --git a/applications/system/subghz_remote/scenes/subrem_scene_edit_submenu.c b/applications/system/subghz_remote/scenes/subrem_scene_edit_submenu.c deleted file mode 100644 index 447beb96d..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_edit_submenu.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../helpers/subrem_custom_event.h" - -void subrem_scene_edit_submenu_text_input_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SubRemCustomEventSceneEditsubmenu); -} - -void subrem_scene_edit_submenu_callback(void* context, uint32_t index) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void subrem_scene_edit_submenu_on_enter(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - Submenu* submenu = app->submenu; - submenu_add_item( - submenu, "Edit Label", EditSubmenuIndexEditLabel, subrem_scene_edit_submenu_callback, app); - submenu_add_item( - submenu, "Edit File", EditSubmenuIndexEditFile, subrem_scene_edit_submenu_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDSubmenu); -} - -bool subrem_scene_edit_submenu_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == EditSubmenuIndexEditLabel) { - scene_manager_next_scene(app->scene_manager, SubRemSceneEditLabel); - consumed = true; - } else if(event.event == EditSubmenuIndexEditFile) { - scene_manager_next_scene(app->scene_manager, SubRemSceneOpenSubFile); - consumed = true; - } - } - - return consumed; -} - -void subrem_scene_edit_submenu_on_exit(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/system/subghz_remote/scenes/subrem_scene_enter_new_name.c b/applications/system/subghz_remote/scenes/subrem_scene_enter_new_name.c deleted file mode 100644 index b829723a3..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_enter_new_name.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../helpers/subrem_custom_event.h" - -#include - -void subrem_scene_enter_new_name_text_input_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SubRemCustomEventSceneNewName); -} - -void subrem_scene_enter_new_name_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - // Setup view - TextInput* text_input = app->text_input; - - //strncpy(app->file_name_tmp, "subrem_", SUBREM_MAX_LEN_NAME); - text_input_set_header_text(text_input, "Map file Name"); - text_input_set_result_callback( - text_input, - subrem_scene_enter_new_name_text_input_callback, - app, - app->file_name_tmp, - 25, - false); - - ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - furi_string_get_cstr(app->file_path), SUBREM_APP_EXTENSION, ""); - text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDTextInput); -} - -bool subrem_scene_enter_new_name_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventSceneNewName) { - if(strcmp(app->file_name_tmp, "") != 0) { - furi_string_set(app->file_path, SUBREM_APP_FOLDER); - furi_string_cat_printf( - app->file_path, "/%s%s", app->file_name_tmp, SUBREM_APP_EXTENSION); - - subrem_map_preset_reset(app->map_preset); - scene_manager_next_scene(app->scene_manager, SubRemSceneEditMenu); - } else { //error - } - consumed = true; - } - } - - return consumed; -} - -void subrem_scene_enter_new_name_on_exit(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - submenu_reset(app->submenu); - - // Clear validator & view - void* validator_context = text_input_get_validator_callback_context(app->text_input); - text_input_set_validator(app->text_input, NULL, NULL); - validator_is_file_free(validator_context); - text_input_reset(app->text_input); -} diff --git a/applications/system/subghz_remote/scenes/subrem_scene_fw_warning.c b/applications/system/subghz_remote/scenes/subrem_scene_fw_warning.c deleted file mode 100644 index de473b72c..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_fw_warning.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../helpers/subrem_custom_event.h" -#ifdef FW_ORIGIN_Official -typedef enum { - SceneFwWarningStateAttention, - SceneFwWarningStateAccept, -} SceneFwWarningState; - -static void subrem_scene_fw_warning_widget_render(SubGhzRemoteApp* app, SceneFwWarningState state); - -static void - subrem_scene_fw_warning_widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - if(type == InputTypeShort) { - SubRemCustomEvent event = SubRemCustomEventSceneFwWarningExit; - - switch(scene_manager_get_scene_state(app->scene_manager, SubRemSceneFwWarning)) { - case SceneFwWarningStateAttention: - if(result == GuiButtonTypeRight) { - event = SubRemCustomEventSceneFwWarningNext; - } - break; - - case SceneFwWarningStateAccept: - if(result == GuiButtonTypeRight) { - event = SubRemCustomEventSceneFwWarningContinue; - } - - break; - } - - view_dispatcher_send_custom_event(app->view_dispatcher, event); - } -} - -static void - subrem_scene_fw_warning_widget_render(SubGhzRemoteApp* app, SceneFwWarningState state) { - furi_assert(app); - Widget* widget = app->widget; - - widget_reset(widget); - - switch(state) { - case SceneFwWarningStateAttention: - widget_add_button_element( - widget, GuiButtonTypeLeft, "Exit", subrem_scene_fw_warning_widget_callback, app); - widget_add_button_element( - widget, GuiButtonTypeRight, "Continue", subrem_scene_fw_warning_widget_callback, app); - widget_add_string_element( - widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, "Not official FW"); - widget_add_string_multiline_element( - widget, - 64, - 32, - AlignCenter, - AlignCenter, - FontSecondary, - "You are using custom firmware\nPlease download a compatible\nversion of the application"); - break; - - case SceneFwWarningStateAccept: - widget_add_button_element( - widget, GuiButtonTypeLeft, "Exit", subrem_scene_fw_warning_widget_callback, app); - widget_add_button_element( - widget, GuiButtonTypeRight, "Accept", subrem_scene_fw_warning_widget_callback, app); - widget_add_string_element( - widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, "Not official FW"); - widget_add_string_multiline_element( - widget, - 64, - 32, - AlignCenter, - AlignCenter, - FontSecondary, - "Yes, I understand that\nthe application can\nbreak my subghz key file"); - break; - } -} - -void subrem_scene_fw_warning_on_enter(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneFwWarning, SceneFwWarningStateAttention); - - subrem_scene_fw_warning_widget_render(app, SceneFwWarningStateAttention); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); -} - -bool subrem_scene_fw_warning_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeBack) { - consumed = true; - } else if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventSceneFwWarningExit) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - consumed = true; - } else if(event.event == SubRemCustomEventSceneFwWarningNext) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneFwWarning, SceneFwWarningStateAccept); - subrem_scene_fw_warning_widget_render(app, SceneFwWarningStateAccept); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); - consumed = true; - } else if(event.event == SubRemCustomEventSceneFwWarningContinue) { - scene_manager_previous_scene(app->scene_manager); - consumed = true; - } - } - - return consumed; -} - -void subrem_scene_fw_warning_on_exit(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - widget_reset(app->widget); -} -#endif \ No newline at end of file diff --git a/applications/system/subghz_remote/scenes/subrem_scene_open_map_file.c b/applications/system/subghz_remote/scenes/subrem_scene_open_map_file.c deleted file mode 100644 index b91a35129..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_open_map_file.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "../subghz_remote_app_i.h" - -void subrem_scene_open_map_file_on_enter(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - SubRemLoadMapState load_state = subrem_load_from_file(app); - uint32_t start_scene_state = - scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart); - - if(load_state == SubRemLoadMapStateBack) { - scene_manager_previous_scene(app->scene_manager); - } else if(start_scene_state == SubmenuIndexSubRemEditMapFile) { - scene_manager_set_scene_state(app->scene_manager, SubRemSceneEditMenu, SubRemSubKeyNameUp); - scene_manager_next_scene(app->scene_manager, SubRemSceneEditMenu); - } else if(start_scene_state == SubmenuIndexSubRemOpenMapFile) { - scene_manager_next_scene(app->scene_manager, SubRemSceneRemote); - } -} - -bool subrem_scene_open_map_file_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void subrem_scene_open_map_file_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/system/subghz_remote/scenes/subrem_scene_open_sub_file.c b/applications/system/subghz_remote/scenes/subrem_scene_open_sub_file.c deleted file mode 100644 index d34f01b99..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_open_sub_file.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "../subghz_remote_app_i.h" - -void subrem_scene_open_sub_file_error_popup_callback(void* context) { - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditOpenSubErrorPopup); -} - -SubRemLoadSubState subrem_scene_open_sub_file_dialog(SubGhzRemoteApp* app) { - furi_assert(app); - - SubRemSubFilePreset* sub = app->map_preset->subs_preset[app->chosen_sub]; - - FuriString* temp_file_path = furi_string_alloc(); - - if(furi_string_empty(sub->file_path)) { - furi_string_set(temp_file_path, SUBGHZ_RAW_FOLDER); - } else { - furi_string_set(temp_file_path, sub->file_path); - } - - SubRemLoadSubState ret = SubRemLoadSubStateNotSet; - - DialogsFileBrowserOptions browser_options; - - dialog_file_browser_set_basic_options( - &browser_options, SUBGHZ_APP_FILENAME_EXTENSION, &I_sub1_10px); - browser_options.base_path = SUBGHZ_RAW_FOLDER; - - // Input events and views are managed by file_select - if(!dialog_file_browser_show(app->dialogs, temp_file_path, temp_file_path, &browser_options)) { - } else { - // Check sub file - SubRemSubFilePreset* sub_candidate = subrem_sub_file_preset_alloc(); - furi_string_set(sub_candidate->label, sub->label); - furi_string_set(sub_candidate->file_path, temp_file_path); - - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* fff_file = flipper_format_file_alloc(storage); - - if(flipper_format_file_open_existing( - fff_file, furi_string_get_cstr(sub_candidate->file_path))) { - ret = subrem_sub_preset_load(sub_candidate, app->txrx, fff_file); - } - - flipper_format_file_close(fff_file); - flipper_format_free(fff_file); - furi_record_close(RECORD_STORAGE); - - if(ret == SubRemLoadSubStateOK) { - subrem_sub_file_preset_free(app->map_preset->subs_preset[app->chosen_sub]); - app->map_preset->subs_preset[app->chosen_sub] = sub_candidate; - app->map_not_saved = true; - } else { - subrem_sub_file_preset_free(sub_candidate); - } - } - - furi_string_free(temp_file_path); - - return ret; -} - -void subrem_scene_open_sub_file_on_enter(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - SubRemLoadSubState load_state = subrem_scene_open_sub_file_dialog(app); - - Popup* popup = app->popup; - // popup_set_icon(); - popup_set_header(popup, "ERROR", 63, 16, AlignCenter, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, app); - popup_set_callback(popup, subrem_scene_open_sub_file_error_popup_callback); - popup_enable_timeout(popup); - - if(load_state == SubRemLoadSubStateOK) { - scene_manager_previous_scene(app->scene_manager); - } else if(load_state == SubRemLoadSubStateNotSet) { - scene_manager_previous_scene(app->scene_manager); - } else { - switch(load_state) { - case SubRemLoadSubStateErrorFreq: - - popup_set_text(popup, "Bad frequency", 63, 30, AlignCenter, AlignBottom); - break; - case SubRemLoadSubStateErrorMod: - - popup_set_text(popup, "Bad modulation", 63, 30, AlignCenter, AlignBottom); - break; - case SubRemLoadSubStateErrorProtocol: - - popup_set_text(popup, "Unsupported protocol", 63, 30, AlignCenter, AlignBottom); - break; - - default: - break; - } - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDPopup); - } -} - -bool subrem_scene_open_sub_file_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - - if(event.type == SceneManagerEventTypeCustom && - event.event == SubRemCustomEventSceneEditOpenSubErrorPopup) { - scene_manager_previous_scene(app->scene_manager); - return true; - } - return false; -} - -void subrem_scene_open_sub_file_on_exit(void* context) { - SubGhzRemoteApp* app = context; - - popup_reset(app->popup); -} diff --git a/applications/system/subghz_remote/scenes/subrem_scene_remote.c b/applications/system/subghz_remote/scenes/subrem_scene_remote.c deleted file mode 100644 index efe289871..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_remote.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../views/remote.h" - -#include - -#define TAG "SubRemScenRemote" - -void subrem_scene_remote_callback(SubRemCustomEvent event, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void subrem_scene_remote_raw_callback_end_tx(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SubRemCustomEventViewRemoteForcedStop); -} - -static uint8_t subrem_scene_remote_event_to_index(SubRemCustomEvent event_id) { - uint8_t ret = 0; - - if(event_id == SubRemCustomEventViewRemoteStartUP) { - ret = SubRemSubKeyNameUp; - } else if(event_id == SubRemCustomEventViewRemoteStartDOWN) { - ret = SubRemSubKeyNameDown; - } else if(event_id == SubRemCustomEventViewRemoteStartLEFT) { - ret = SubRemSubKeyNameLeft; - } else if(event_id == SubRemCustomEventViewRemoteStartRIGHT) { - ret = SubRemSubKeyNameRight; - } else if(event_id == SubRemCustomEventViewRemoteStartOK) { - ret = SubRemSubKeyNameOk; - } - - return ret; -} - -void subrem_scene_remote_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - subrem_view_remote_update_data_labels(app->subrem_remote_view, app->map_preset->subs_preset); - subrem_view_remote_set_radio( - app->subrem_remote_view, - subghz_txrx_radio_device_get(app->txrx) != SubGhzRadioDeviceTypeInternal); - - subrem_view_remote_set_callback(app->subrem_remote_view, subrem_scene_remote_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDRemote); -} - -bool subrem_scene_remote_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventViewRemoteBack) { - if(!scene_manager_previous_scene(app->scene_manager)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } - return true; - } else if( - event.event == SubRemCustomEventViewRemoteStartUP || - event.event == SubRemCustomEventViewRemoteStartDOWN || - event.event == SubRemCustomEventViewRemoteStartLEFT || - event.event == SubRemCustomEventViewRemoteStartRIGHT || - event.event == SubRemCustomEventViewRemoteStartOK) { - // Start sending sub - subrem_tx_stop_sub(app, true); - - uint8_t chosen_sub = subrem_scene_remote_event_to_index(event.event); - app->chosen_sub = chosen_sub; - - subrem_view_remote_set_state( - app->subrem_remote_view, SubRemViewRemoteStateLoading, chosen_sub); - - if(subrem_tx_start_sub(app, app->map_preset->subs_preset[chosen_sub])) { - if(app->map_preset->subs_preset[chosen_sub]->type == SubGhzProtocolTypeRAW) { - subghz_txrx_set_raw_file_encoder_worker_callback_end( - app->txrx, subrem_scene_remote_raw_callback_end_tx, app); - } - subrem_view_remote_set_state( - app->subrem_remote_view, SubRemViewRemoteStateSending, chosen_sub); - notification_message(app->notifications, &sequence_blink_start_magenta); - } else { - subrem_view_remote_set_state( - app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - notification_message(app->notifications, &sequence_blink_red_100); - } - return true; - } else if(event.event == SubRemCustomEventViewRemoteForcedStop) { - subrem_tx_stop_sub(app, true); - subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - - notification_message(app->notifications, &sequence_blink_stop); - return true; - } else if(event.event == SubRemCustomEventViewRemoteStop) { - if(subrem_tx_stop_sub(app, false)) { - subrem_view_remote_set_state( - app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - - notification_message(app->notifications, &sequence_blink_stop); - } - return true; - } - } - // } else if(event.type == SceneManagerEventTypeTick) { - // } - return false; -} - -void subrem_scene_remote_on_exit(void* context) { - SubGhzRemoteApp* app = context; - - subrem_tx_stop_sub(app, true); - - subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - - notification_message(app->notifications, &sequence_blink_stop); -} diff --git a/applications/system/subghz_remote/scenes/subrem_scene_start.c b/applications/system/subghz_remote/scenes/subrem_scene_start.c deleted file mode 100644 index 0f3399b7c..000000000 --- a/applications/system/subghz_remote/scenes/subrem_scene_start.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../helpers/subrem_custom_event.h" - -void subrem_scene_start_submenu_callback(void* context, uint32_t index) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void subrem_scene_start_on_enter(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - Submenu* submenu = app->submenu; - submenu_add_item( - submenu, - "Open Map File", - SubmenuIndexSubRemOpenMapFile, - subrem_scene_start_submenu_callback, - app); -#if FURI_DEBUG - submenu_add_item( - submenu, - "Remote_Debug", - SubmenuIndexSubRemRemoteView, - subrem_scene_start_submenu_callback, - app); -#endif - submenu_add_item( - submenu, - "Edit Map File", - SubmenuIndexSubRemEditMapFile, - subrem_scene_start_submenu_callback, - app); - submenu_add_item( - submenu, - "New Map File", - SubmenuIndexSubRemNewMapFile, - subrem_scene_start_submenu_callback, - app); - // submenu_add_item( - // submenu, - // "About", - // SubmenuIndexSubGhzRemoteAbout, - // subrem_scene_start_submenu_callback, - // app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDSubmenu); -} - -bool subrem_scene_start_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexSubRemOpenMapFile) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneStart, SubmenuIndexSubRemOpenMapFile); - - scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile); - consumed = true; - } -#if FURI_DEBUG - else if(event.event == SubmenuIndexSubRemRemoteView) { - scene_manager_next_scene(app->scene_manager, SubRemSceneRemote); - consumed = true; - } -#endif - else if(event.event == SubmenuIndexSubRemEditMapFile) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneStart, SubmenuIndexSubRemEditMapFile); - scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile); - consumed = true; - } else if(event.event == SubmenuIndexSubRemNewMapFile) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneStart, SubmenuIndexSubRemNewMapFile); - scene_manager_next_scene(app->scene_manager, SubRemSceneEnterNewName); - consumed = true; - } - // } else if(event.event == SubmenuIndexSubRemAbout) { - // scene_manager_next_scene(app->scene_manager, SubRemSceneAbout); - // consumed = true; - // } - } - - return consumed; -} - -void subrem_scene_start_on_exit(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/system/subghz_remote/subghz_remote_app.c b/applications/system/subghz_remote/subghz_remote_app.c deleted file mode 100644 index 473e3c012..000000000 --- a/applications/system/subghz_remote/subghz_remote_app.c +++ /dev/null @@ -1,218 +0,0 @@ -#include "subghz_remote_app_i.h" -#include - -static bool subghz_remote_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - SubGhzRemoteApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool subghz_remote_app_back_event_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void subghz_remote_app_tick_event_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -static void subghz_remote_make_app_folder(SubGhzRemoteApp* app) { - furi_assert(app); - - Storage* storage = furi_record_open(RECORD_STORAGE); - - // Migrate old users data - storage_common_migrate(storage, EXT_PATH("unirf"), SUBREM_APP_FOLDER); - - if(!storage_simply_mkdir(storage, SUBREM_APP_FOLDER)) { - // FURI_LOG_E(TAG, "Could not create folder %s", SUBREM_APP_FOLDER); - dialog_message_show_storage_error(app->dialogs, "Cannot create\napp folder"); - } - furi_record_close(RECORD_STORAGE); -} - -SubGhzRemoteApp* subghz_remote_app_alloc() { - SubGhzRemoteApp* app = malloc(sizeof(SubGhzRemoteApp)); - - furi_hal_power_suppress_charge_enter(); - - app->file_path = furi_string_alloc(); - furi_string_set(app->file_path, SUBREM_APP_FOLDER); - - // GUI - app->gui = furi_record_open(RECORD_GUI); - - // View Dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - - app->scene_manager = scene_manager_alloc(&subrem_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, subghz_remote_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, subghz_remote_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, subghz_remote_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - // Open Notification record - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - // SubMenu - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SubRemViewIDSubmenu, submenu_get_view(app->submenu)); - - // Dialog - app->dialogs = furi_record_open(RECORD_DIALOGS); - - // TextInput - app->text_input = text_input_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SubRemViewIDTextInput, text_input_get_view(app->text_input)); - - // Widget - app->widget = widget_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SubRemViewIDWidget, widget_get_view(app->widget)); - - // Popup - app->popup = popup_alloc(); - view_dispatcher_add_view(app->view_dispatcher, SubRemViewIDPopup, popup_get_view(app->popup)); - - // Remote view - app->subrem_remote_view = subrem_view_remote_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - SubRemViewIDRemote, - subrem_view_remote_get_view(app->subrem_remote_view)); - - // Edit Menu view - app->subrem_edit_menu = subrem_view_edit_menu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - SubRemViewIDEditMenu, - subrem_view_edit_menu_get_view(app->subrem_edit_menu)); - - app->map_preset = malloc(sizeof(SubRemMapPreset)); - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - app->map_preset->subs_preset[i] = subrem_sub_file_preset_alloc(); - } - - app->txrx = subghz_txrx_alloc(); - - subghz_txrx_set_need_save_callback(app->txrx, subrem_save_active_sub, app); - - app->map_not_saved = false; - - return app; -} - -void subghz_remote_app_free(SubGhzRemoteApp* app) { - furi_assert(app); - - furi_hal_power_suppress_charge_exit(); - - // Submenu - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDSubmenu); - submenu_free(app->submenu); - - // Dialog - furi_record_close(RECORD_DIALOGS); - - // TextInput - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDTextInput); - text_input_free(app->text_input); - - // Widget - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDWidget); - widget_free(app->widget); - - // Popup - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDPopup); - popup_free(app->popup); - - // Remote view - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDRemote); - subrem_view_remote_free(app->subrem_remote_view); - - // Edit view - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDEditMenu); - subrem_view_edit_menu_free(app->subrem_edit_menu); - - scene_manager_free(app->scene_manager); - view_dispatcher_free(app->view_dispatcher); - - subghz_txrx_free(app->txrx); - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - subrem_sub_file_preset_free(app->map_preset->subs_preset[i]); - } - free(app->map_preset); - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - app->notifications = NULL; - - // Close records - furi_record_close(RECORD_GUI); - - // Path strings - furi_string_free(app->file_path); - - free(app); -} - -int32_t subghz_remote_app(void* arg) { - SubGhzRemoteApp* subghz_remote_app = subghz_remote_app_alloc(); - - subghz_remote_make_app_folder(subghz_remote_app); - - bool map_loaded = false; -#ifdef FW_ORIGIN_Official - const bool fw_ofw = strcmp(version_get_firmware_origin(version_get()), "Official") == 0; -#endif - if((arg != NULL) && (strlen(arg) != 0)) { - furi_string_set(subghz_remote_app->file_path, (const char*)arg); - SubRemLoadMapState load_state = subrem_map_file_load( - subghz_remote_app, furi_string_get_cstr(subghz_remote_app->file_path)); - - if(load_state == SubRemLoadMapStateOK || load_state == SubRemLoadMapStateNotAllOK) { - map_loaded = true; - } else { - // TODO Replace - dialog_message_show_storage_error(subghz_remote_app->dialogs, "Cannot load\nmap file"); - } - } - - if(map_loaded) { - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneRemote); - } else { - furi_string_set(subghz_remote_app->file_path, SUBREM_APP_FOLDER); - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneStart); -#ifdef FW_ORIGIN_Official - if(fw_ofw) { - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneOpenMapFile); - } - } - - if(!fw_ofw) { - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneFwWarning); - } -#else - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneOpenMapFile); - } -#endif - - view_dispatcher_run(subghz_remote_app->view_dispatcher); - - subghz_remote_app_free(subghz_remote_app); - - return 0; -} diff --git a/applications/system/subghz_remote/subghz_remote_app_i.c b/applications/system/subghz_remote/subghz_remote_app_i.c deleted file mode 100644 index 45321441d..000000000 --- a/applications/system/subghz_remote/subghz_remote_app_i.c +++ /dev/null @@ -1,317 +0,0 @@ -#include "subghz_remote_app_i.h" -#include -#include - -#include "helpers/txrx/subghz_txrx.h" -#ifndef FW_ORIGIN_Official -#include -#endif - -#define TAG "SubGhzRemote" - -static const char* map_file_labels[SubRemSubKeyNameMaxCount][2] = { - [SubRemSubKeyNameUp] = {"UP", "ULABEL"}, - [SubRemSubKeyNameDown] = {"DOWN", "DLABEL"}, - [SubRemSubKeyNameLeft] = {"LEFT", "LLABEL"}, - [SubRemSubKeyNameRight] = {"RIGHT", "RLABEL"}, - [SubRemSubKeyNameOk] = {"OK", "OKLABEL"}, -}; - -void subrem_map_preset_reset(SubRemMapPreset* map_preset) { - furi_assert(map_preset); - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - subrem_sub_file_preset_reset(map_preset->subs_preset[i]); - } -} - -static SubRemLoadMapState subrem_map_preset_check( - SubRemMapPreset* map_preset, - SubGhzTxRx* txrx, - FlipperFormat* fff_data_file) { - furi_assert(map_preset); - furi_assert(txrx); - - bool all_loaded = true; - SubRemLoadMapState ret = SubRemLoadMapStateErrorBrokenFile; - - SubRemLoadSubState sub_loadig_state; - SubRemSubFilePreset* sub_preset; - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = map_preset->subs_preset[i]; - - sub_loadig_state = SubRemLoadSubStateErrorNoFile; - - if(furi_string_empty(sub_preset->file_path)) { - // FURI_LOG_I(TAG, "Empty file path"); - } else if(!flipper_format_file_open_existing( - fff_data_file, furi_string_get_cstr(sub_preset->file_path))) { - sub_preset->load_state = SubRemLoadSubStateErrorNoFile; - FURI_LOG_W(TAG, "Error open file %s", furi_string_get_cstr(sub_preset->file_path)); - } else { - sub_loadig_state = subrem_sub_preset_load(sub_preset, txrx, fff_data_file); - } - - if(sub_loadig_state != SubRemLoadSubStateOK) { - all_loaded = false; - } else { - ret = SubRemLoadMapStateNotAllOK; - } - - if(ret != SubRemLoadMapStateErrorBrokenFile && all_loaded) { - ret = SubRemLoadMapStateOK; - } - - flipper_format_file_close(fff_data_file); - } - - return ret; -} - -static bool subrem_map_preset_load(SubRemMapPreset* map_preset, FlipperFormat* fff_data_file) { - furi_assert(map_preset); - bool ret = false; - SubRemSubFilePreset* sub_preset; - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = map_preset->subs_preset[i]; - if(!flipper_format_read_string( - fff_data_file, map_file_labels[i][0], sub_preset->file_path)) { -#if FURI_DEBUG - FURI_LOG_W(TAG, "No file patch for %s", map_file_labels[i][0]); -#endif - sub_preset->type = SubGhzProtocolTypeUnknown; - } else if(!path_contains_only_ascii(furi_string_get_cstr(sub_preset->file_path))) { - FURI_LOG_E(TAG, "Incorrect characters in [%s] file path", map_file_labels[i][0]); - sub_preset->type = SubGhzProtocolTypeUnknown; - } else if(!flipper_format_rewind(fff_data_file)) { - // Rewind error - } else if(!flipper_format_read_string( - fff_data_file, map_file_labels[i][1], sub_preset->label)) { -#if FURI_DEBUG - FURI_LOG_W(TAG, "No Label for %s", map_file_labels[i][0]); -#endif - ret = true; - } else { - ret = true; - } - if(ret) { - // Preload seccesful - FURI_LOG_I( - TAG, - "%-5s: %s %s", - map_file_labels[i][0], - furi_string_get_cstr(sub_preset->label), - furi_string_get_cstr(sub_preset->file_path)); - sub_preset->load_state = SubRemLoadSubStatePreloaded; - } - - flipper_format_rewind(fff_data_file); - } - return ret; -} - -SubRemLoadMapState subrem_map_file_load(SubGhzRemoteApp* app, const char* file_path) { - furi_assert(app); - furi_assert(file_path); -#if FURI_DEBUG - FURI_LOG_I(TAG, "Load Map File Start"); -#endif - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - SubRemLoadMapState ret = SubRemLoadMapStateErrorOpenError; -#if FURI_DEBUG - FURI_LOG_I(TAG, "Open Map File.."); -#endif - subrem_map_preset_reset(app->map_preset); - - if(!flipper_format_file_open_existing(fff_data_file, file_path)) { - FURI_LOG_E(TAG, "Could not open MAP file %s", file_path); - ret = SubRemLoadMapStateErrorOpenError; - } else { - if(!subrem_map_preset_load(app->map_preset, fff_data_file)) { - FURI_LOG_E(TAG, "Could no Sub file path in MAP file"); - // ret = // error for popup - } else if(!flipper_format_file_close(fff_data_file)) { - ret = SubRemLoadMapStateErrorOpenError; - } else { - ret = subrem_map_preset_check(app->map_preset, app->txrx, fff_data_file); - } - } - - if(ret == SubRemLoadMapStateOK) { - FURI_LOG_I(TAG, "Load Map File Seccesful"); - } else if(ret == SubRemLoadMapStateNotAllOK) { - FURI_LOG_I(TAG, "Load Map File Seccesful [Not all files]"); - } else { - FURI_LOG_E(TAG, "Broken Map File"); - } - - flipper_format_file_close(fff_data_file); - flipper_format_free(fff_data_file); - - furi_record_close(RECORD_STORAGE); - return ret; -} - -bool subrem_save_protocol_to_file(FlipperFormat* flipper_format, const char* sub_file_name) { - furi_assert(flipper_format); - furi_assert(sub_file_name); - - Storage* storage = furi_record_open(RECORD_STORAGE); - Stream* flipper_format_stream = flipper_format_get_raw_stream(flipper_format); - - bool saved = false; - uint32_t repeat = 200; - FuriString* file_dir = furi_string_alloc(); - - path_extract_dirname(sub_file_name, file_dir); - do { - // removing additional fields - flipper_format_delete_key(flipper_format, "Repeat"); - // flipper_format_delete_key(flipper_format, "Manufacture"); - - if(!storage_simply_remove(storage, sub_file_name)) { - break; - } - - //ToDo check Write - stream_seek(flipper_format_stream, 0, StreamOffsetFromStart); - stream_save_to_file(flipper_format_stream, storage, sub_file_name, FSOM_CREATE_ALWAYS); - - if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) { - FURI_LOG_E(TAG, "Unable Repeat"); - break; - } - - saved = true; - } while(0); - - furi_string_free(file_dir); - furi_record_close(RECORD_STORAGE); - return saved; -} - -void subrem_save_active_sub(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - SubRemSubFilePreset* sub_preset = app->map_preset->subs_preset[app->chosen_sub]; - subrem_save_protocol_to_file( - sub_preset->fff_data, furi_string_get_cstr(sub_preset->file_path)); -} - -bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) { - furi_assert(app); - furi_assert(sub_preset); - bool ret = false; - - subrem_tx_stop_sub(app, true); - - if(sub_preset->type == SubGhzProtocolTypeUnknown) { - ret = false; - } else { - FURI_LOG_I(TAG, "Send %s", furi_string_get_cstr(sub_preset->label)); - - subghz_txrx_load_decoder_by_name_protocol( - app->txrx, furi_string_get_cstr(sub_preset->protocaol_name)); - - subghz_txrx_set_preset( - app->txrx, - furi_string_get_cstr(sub_preset->freq_preset.name), - sub_preset->freq_preset.frequency, - NULL, - 0); -#ifndef FW_ORIGIN_Official - subghz_custom_btns_reset(); -#endif - if(subghz_txrx_tx_start(app->txrx, sub_preset->fff_data) == SubGhzTxRxStartTxStateOk) { - ret = true; - } - } - - return ret; -} - -bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { - furi_assert(app); - SubRemSubFilePreset* sub_preset = app->map_preset->subs_preset[app->chosen_sub]; - - if(forced || (sub_preset->type != SubGhzProtocolTypeRAW)) { - subghz_txrx_stop(app->txrx); -#ifndef FW_ORIGIN_Official - if(sub_preset->type == SubGhzProtocolTypeDynamic) { - subghz_txrx_reset_dynamic_and_custom_btns(app->txrx); - } - subghz_custom_btns_reset(); -#endif - return true; - } - - return false; -} - -SubRemLoadMapState subrem_load_from_file(SubGhzRemoteApp* app) { - furi_assert(app); - - FuriString* file_path = furi_string_alloc(); - SubRemLoadMapState ret = SubRemLoadMapStateBack; - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, SUBREM_APP_EXTENSION, &I_subrem_10px); - browser_options.base_path = SUBREM_APP_FOLDER; - - // Input events and views are managed by file_select - if(!dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options)) { - } else { - ret = subrem_map_file_load(app, furi_string_get_cstr(app->file_path)); - } - - furi_string_free(file_path); - - return ret; -} - -bool subrem_save_map_to_file(SubGhzRemoteApp* app) { - furi_assert(app); - - const char* file_name = furi_string_get_cstr(app->file_path); - bool saved = false; - FlipperFormat* fff_data = flipper_format_string_alloc(); - - SubRemSubFilePreset* sub_preset; - - flipper_format_write_header_cstr( - fff_data, SUBREM_APP_APP_FILE_TYPE, SUBREM_APP_APP_FILE_VERSION); - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = app->map_preset->subs_preset[i]; - if(!furi_string_empty(sub_preset->file_path)) { - flipper_format_write_string(fff_data, map_file_labels[i][0], sub_preset->file_path); - } - } - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = app->map_preset->subs_preset[i]; - if(!furi_string_empty(sub_preset->file_path)) { - flipper_format_write_string(fff_data, map_file_labels[i][1], sub_preset->label); - } - } - - Storage* storage = furi_record_open(RECORD_STORAGE); - Stream* flipper_format_stream = flipper_format_get_raw_stream(fff_data); - - do { - if(!storage_simply_remove(storage, file_name)) { - break; - } - //ToDo check Write - stream_seek(flipper_format_stream, 0, StreamOffsetFromStart); - stream_save_to_file(flipper_format_stream, storage, file_name, FSOM_CREATE_ALWAYS); - - saved = true; - } while(0); - - furi_record_close(RECORD_STORAGE); - flipper_format_free(fff_data); - - return saved; -} \ No newline at end of file diff --git a/applications/system/subghz_remote/subghz_remote_app_i.h b/applications/system/subghz_remote/subghz_remote_app_i.h deleted file mode 100644 index 825e23121..000000000 --- a/applications/system/subghz_remote/subghz_remote_app_i.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include "helpers/subrem_types.h" -#include "helpers/subrem_presets.h" -#include "scenes/subrem_scene.h" - -#include "helpers/txrx/subghz_txrx.h" - -#if __has_include("subghz_remote_icons.h") -#include "subghz_remote_icons.h" -#endif - -#include - -#include "views/remote.h" -#include "views/edit_menu.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define SUBREM_APP_FOLDER EXT_PATH("subghz/remote") -#define SUBREM_MAX_LEN_NAME 64 - -typedef struct { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - NotificationApp* notifications; - DialogsApp* dialogs; - Widget* widget; - Popup* popup; - TextInput* text_input; - Submenu* submenu; - - FuriString* file_path; - char file_name_tmp[SUBREM_MAX_LEN_NAME]; - - SubRemViewRemote* subrem_remote_view; - SubRemViewEditMenu* subrem_edit_menu; - - SubRemMapPreset* map_preset; - - SubGhzTxRx* txrx; - - bool map_not_saved; - - uint8_t chosen_sub; -} SubGhzRemoteApp; - -SubRemLoadMapState subrem_load_from_file(SubGhzRemoteApp* app); - -bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset); - -bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced); - -SubRemLoadMapState subrem_map_file_load(SubGhzRemoteApp* app, const char* file_path); - -void subrem_map_preset_reset(SubRemMapPreset* map_preset); - -bool subrem_save_map_to_file(SubGhzRemoteApp* app); - -void subrem_save_active_sub(void* context); \ No newline at end of file diff --git a/applications/system/subghz_remote/views/edit_menu.c b/applications/system/subghz_remote/views/edit_menu.c deleted file mode 100644 index 91d826f03..000000000 --- a/applications/system/subghz_remote/views/edit_menu.c +++ /dev/null @@ -1,290 +0,0 @@ -#include "edit_menu.h" -#include "../subghz_remote_app_i.h" - -#include -#include - -#define subrem_view_edit_menu_MAX_LABEL_LENGTH 12 - -#define FRAME_HEIGHT 12 - -struct SubRemViewEditMenu { - View* view; - SubRemViewEditMenuCallback callback; - void* context; -}; - -typedef struct { - FuriString* label; - FuriString* file_path; - SubRemLoadSubState sub_state; - - uint8_t chosen; -} SubRemViewEditMenuModel; - -void subrem_view_edit_menu_set_callback( - SubRemViewEditMenu* subrem_view_edit_menu, - SubRemViewEditMenuCallback callback, - void* context) { - furi_assert(subrem_view_edit_menu); - - subrem_view_edit_menu->callback = callback; - subrem_view_edit_menu->context = context; -} - -void subrem_view_edit_menu_add_data_to_show( - SubRemViewEditMenu* subrem_view_edit_remote, - uint8_t index, - FuriString* label, - FuriString* path, - SubRemLoadSubState state) { - furi_assert(subrem_view_edit_remote); - - with_view_model( - subrem_view_edit_remote->view, - SubRemViewEditMenuModel * model, - { - model->chosen = index; - if(!furi_string_empty(label)) { - furi_string_set(model->label, label); - } else { - furi_string_set(model->label, "Empty label"); - } - furi_string_set(model->file_path, path); - model->sub_state = state; - }, - true); -} - -uint8_t subrem_view_edit_menu_get_index(SubRemViewEditMenu* subrem_view_edit_remote) { - furi_assert(subrem_view_edit_remote); - uint8_t index; - - with_view_model( - subrem_view_edit_remote->view, - SubRemViewEditMenuModel * model, - { index = model->chosen; }, - true); - return index; -} - -void subrem_view_edit_menu_draw(Canvas* canvas, SubRemViewEditMenuModel* model) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - canvas_clear(canvas); - - // Draw bottom btn - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Back"); - elements_button_center(canvas, "Edit"); - elements_button_right(canvas, "Save"); - - // Draw top frame - canvas_draw_line(canvas, 1, 0, 125, 0); - canvas_draw_box(canvas, 0, 1, 127, FRAME_HEIGHT - 2); - canvas_draw_line(canvas, 1, FRAME_HEIGHT - 1, 125, FRAME_HEIGHT - 1); - - canvas_set_color(canvas, ColorWhite); - - // Draw btn name - canvas_set_font(canvas, FontPrimary); - switch(model->chosen) { - case SubRemSubKeyNameUp: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "UP"); - break; - - case SubRemSubKeyNameDown: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "DOWN"); - break; - - case SubRemSubKeyNameLeft: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "LEFT"); - break; - - case SubRemSubKeyNameRight: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "RIGHT"); - break; - - case SubRemSubKeyNameOk: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "OK"); - break; - - default: - break; - } - - // Draw Label - canvas_set_font(canvas, FontSecondary); - elements_text_box( - canvas, - 38, - 2, - 127 - 38, - FRAME_HEIGHT, - AlignCenter, - AlignBottom, - furi_string_empty(model->label) ? "Empty label" : furi_string_get_cstr(model->label), - true); - - // Draw arrow - canvas_set_color(canvas, ColorBlack); - if(model->chosen != 0) { - canvas_draw_icon(canvas, 119, 13, &I_Pin_arrow_up_7x9); - } - if(model->chosen != 4) { - canvas_draw_icon_ex(canvas, 119, 42, &I_Pin_arrow_up_7x9, IconRotation180); - } - - // Draw file_path - if(model->sub_state == SubRemLoadSubStateOK) { - canvas_set_font(canvas, FontSecondary); - elements_text_box( - canvas, - 1, - FRAME_HEIGHT + 1, - 118, - (63 - FRAME_HEIGHT * 2), - AlignLeft, - AlignTop, - furi_string_get_cstr(model->file_path), - false); - } else if(furi_string_empty(model->file_path)) { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 1, FRAME_HEIGHT * 2 - 2, "Button not set"); - } else { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 1, FRAME_HEIGHT * 2 - 2, "ERR:"); - canvas_set_font(canvas, FontSecondary); - switch(model->sub_state) { - case SubRemLoadSubStateErrorNoFile: - canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "File not found"); - break; - case SubRemLoadSubStateErrorFreq: - canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "Bad frequency"); - break; - case SubRemLoadSubStateErrorMod: - canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "Bad modulation"); - break; - case SubRemLoadSubStateErrorProtocol: - canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "Unsupported protocol"); - break; - - default: - break; - } - elements_text_box( - canvas, - 1, - FRAME_HEIGHT * 2, - 118, - 30, - AlignLeft, - AlignTop, - furi_string_get_cstr(model->file_path), - false); - } -} - -bool subrem_view_edit_menu_input(InputEvent* event, void* context) { - furi_assert(context); - SubRemViewEditMenu* subrem_view_edit_menu = context; - - if((event->key == InputKeyBack || event->key == InputKeyLeft) && - event->type == InputTypeShort) { - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuBack, subrem_view_edit_menu->context); - return true; - } else if(event->key == InputKeyUp && event->type == InputTypeShort) { - with_view_model( - subrem_view_edit_menu->view, - SubRemViewEditMenuModel * model, - { - if(model->chosen > 0) { - model->chosen -= 1; - }; - }, - true); - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuUP, subrem_view_edit_menu->context); - return true; - } else if(event->key == InputKeyDown && event->type == InputTypeShort) { - with_view_model( - subrem_view_edit_menu->view, - SubRemViewEditMenuModel * model, - { - if(model->chosen < 4) { - model->chosen += 1; - }; - }, - true); - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuDOWN, subrem_view_edit_menu->context); - return true; - } else if(event->key == InputKeyOk && event->type == InputTypeShort) { - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuEdit, subrem_view_edit_menu->context); - return true; - } else if(event->key == InputKeyRight && event->type == InputTypeShort) { - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuSave, subrem_view_edit_menu->context); - return true; - } - - return true; -} - -void subrem_view_edit_menu_enter(void* context) { - furi_assert(context); -} - -void subrem_view_edit_menu_exit(void* context) { - furi_assert(context); -} - -SubRemViewEditMenu* subrem_view_edit_menu_alloc(void) { - SubRemViewEditMenu* subrem_view_edit_menu = malloc(sizeof(SubRemViewEditMenu)); - - // View allocation and configuration - subrem_view_edit_menu->view = view_alloc(); - view_allocate_model( - subrem_view_edit_menu->view, ViewModelTypeLocking, sizeof(SubRemViewEditMenuModel)); - view_set_context(subrem_view_edit_menu->view, subrem_view_edit_menu); - view_set_draw_callback( - subrem_view_edit_menu->view, (ViewDrawCallback)subrem_view_edit_menu_draw); - view_set_input_callback(subrem_view_edit_menu->view, subrem_view_edit_menu_input); - view_set_enter_callback(subrem_view_edit_menu->view, subrem_view_edit_menu_enter); - view_set_exit_callback(subrem_view_edit_menu->view, subrem_view_edit_menu_exit); - - with_view_model( - subrem_view_edit_menu->view, - SubRemViewEditMenuModel * model, - { - model->label = furi_string_alloc(); // furi_string_alloc_set_str("LABEL"); - model->file_path = furi_string_alloc(); // furi_string_alloc_set_str("FILE_PATH"); - - model->chosen = 0; - }, - true); - return subrem_view_edit_menu; -} - -void subrem_view_edit_menu_free(SubRemViewEditMenu* subghz_edit_menu) { - furi_assert(subghz_edit_menu); - - with_view_model( - subghz_edit_menu->view, - SubRemViewEditMenuModel * model, - { - furi_string_free(model->label); - furi_string_free(model->file_path); - }, - true); - view_free(subghz_edit_menu->view); - free(subghz_edit_menu); -} - -View* subrem_view_edit_menu_get_view(SubRemViewEditMenu* subrem_view_edit_menu) { - furi_assert(subrem_view_edit_menu); - return subrem_view_edit_menu->view; -} \ No newline at end of file diff --git a/applications/system/subghz_remote/views/edit_menu.h b/applications/system/subghz_remote/views/edit_menu.h deleted file mode 100644 index 12d33e8ba..000000000 --- a/applications/system/subghz_remote/views/edit_menu.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include "../helpers/subrem_custom_event.h" -#include "../helpers/subrem_presets.h" - -typedef struct SubRemViewEditMenu SubRemViewEditMenu; - -typedef void (*SubRemViewEditMenuCallback)(SubRemCustomEvent event, void* context); - -void subrem_view_edit_menu_set_callback( - SubRemViewEditMenu* subrem_view_edit_menu, - SubRemViewEditMenuCallback callback, - void* context); - -SubRemViewEditMenu* subrem_view_edit_menu_alloc(void); - -void subrem_view_edit_menu_free(SubRemViewEditMenu* subrem_view_edit_menu); - -View* subrem_view_edit_menu_get_view(SubRemViewEditMenu* subrem_view_edit_menu); - -void subrem_view_edit_menu_add_data_to_show( - SubRemViewEditMenu* subrem_view_edit_remote, - uint8_t index, - FuriString* label, - FuriString* path, - SubRemLoadSubState state); - -uint8_t subrem_view_edit_menu_get_index(SubRemViewEditMenu* subrem_view_edit_remote); \ No newline at end of file diff --git a/applications/system/subghz_remote/views/remote.c b/applications/system/subghz_remote/views/remote.c deleted file mode 100644 index ca6df70a3..000000000 --- a/applications/system/subghz_remote/views/remote.c +++ /dev/null @@ -1,331 +0,0 @@ -#include "remote.h" -#include "../subghz_remote_app_i.h" - -#include -#include - -#include - -#define SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH 30 -#define SUBREM_VIEW_REMOTE_LEFT_OFFSET 10 -#define SUBREM_VIEW_REMOTE_RIGHT_OFFSET 0 - -struct SubRemViewRemote { - View* view; - SubRemViewRemoteCallback callback; - void* context; -}; - -typedef struct { - char* labels[SubRemSubKeyNameMaxCount]; - - SubRemViewRemoteState state; - - uint8_t pressed_btn; - bool is_external; -} SubRemViewRemoteModel; - -void subrem_view_remote_set_callback( - SubRemViewRemote* subrem_view_remote, - SubRemViewRemoteCallback callback, - void* context) { - furi_assert(subrem_view_remote); - - subrem_view_remote->callback = callback; - subrem_view_remote->context = context; -} - -void subrem_view_remote_update_data_labels( - SubRemViewRemote* subrem_view_remote, - SubRemSubFilePreset** subs_presets) { - furi_assert(subrem_view_remote); - furi_assert(subs_presets); - - FuriString* labels[SubRemSubKeyNameMaxCount]; - SubRemSubFilePreset* sub_preset; - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = subs_presets[i]; - switch(sub_preset->load_state) { - case SubRemLoadSubStateOK: - if(!furi_string_empty(sub_preset->label)) { - labels[i] = furi_string_alloc_set(sub_preset->label); - } else if(!furi_string_empty(sub_preset->file_path)) { - labels[i] = furi_string_alloc(); - path_extract_filename(sub_preset->file_path, labels[i], true); - } else { - labels[i] = furi_string_alloc_set("Empty Label"); - } - break; - - case SubRemLoadSubStateErrorNoFile: - labels[i] = furi_string_alloc_set("[X] Can't open file"); - break; - - case SubRemLoadSubStateErrorFreq: - case SubRemLoadSubStateErrorMod: - case SubRemLoadSubStateErrorProtocol: - labels[i] = furi_string_alloc_set("[X] Error in .sub file"); - break; - - default: - labels[i] = furi_string_alloc_set(""); - break; - } - } - - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - strncpy( - model->labels[i], - furi_string_get_cstr(labels[i]), - SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); - } - }, - true); - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - furi_string_free(labels[i]); - } -} - -void subrem_view_remote_set_state( - SubRemViewRemote* subrem_view_remote, - SubRemViewRemoteState state, - uint8_t presed_btn) { - furi_assert(subrem_view_remote); - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { - model->state = state; - model->pressed_btn = presed_btn; - }, - true); -} - -void subrem_view_remote_set_radio(SubRemViewRemote* subrem_view_remote, bool external) { - furi_assert(subrem_view_remote); - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { model->is_external = external; }, - true); -} - -void subrem_view_remote_draw(Canvas* canvas, SubRemViewRemoteModel* model) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - // Statusbar - canvas_draw_icon(canvas, 0, 0, &I_status_bar); - if(model->state == SubRemViewRemoteStateOFF) { - canvas_invert_color(canvas); - canvas_draw_rbox(canvas, 12, 0, 52 - 12, 13, 2); - canvas_invert_color(canvas); - canvas_draw_rframe(canvas, 12, 0, 52 - 12, 13, 2); - canvas_draw_str_aligned(canvas, 32, 3, AlignCenter, AlignTop, "Preview"); - } else { - canvas_draw_icon( - canvas, - 0, - 2, - (model->is_external) ? &I_External_antenna_20x12 : &I_Internal_antenna_20x12); - canvas_draw_icon(canvas, 50, 0, &I_Status_cube_14x14); - if(model->state == SubRemViewRemoteStateSending) { - canvas_draw_icon_ex(canvas, 52, 3, &I_Pin_arrow_up_7x9, IconRotation90); - } - } - - //Icons for Labels - const uint8_t list_y = 14; - canvas_draw_icon(canvas, 1, list_y + 5, &I_ButtonUp_7x4); - canvas_draw_icon(canvas, 1, list_y + 15, &I_ButtonDown_7x4); - canvas_draw_icon(canvas, 2, list_y + 23, &I_ButtonLeft_4x7); - canvas_draw_icon(canvas, 2, list_y + 33, &I_ButtonRight_4x7); - canvas_draw_icon(canvas, 0, list_y + 42, &I_Ok_btn_9x9); - - //Labels - canvas_set_font(canvas, FontSecondary); - uint8_t y = list_y; - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - elements_text_box( - canvas, - SUBREM_VIEW_REMOTE_LEFT_OFFSET, - y + 2, - 64 - SUBREM_VIEW_REMOTE_LEFT_OFFSET - SUBREM_VIEW_REMOTE_RIGHT_OFFSET, - 12, - AlignLeft, - AlignBottom, - model->labels[i], - false); - y += 10; - } - - if(model->state != SubRemViewRemoteStateOFF) { - // D-pad 59x62 - const uint8_t d_pad_x = 3; - const uint8_t d_pad_y = 66; - - canvas_draw_icon(canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 0 * (20 + 1), &I_up); - - canvas_draw_icon(canvas, d_pad_x + 0 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_left); - canvas_draw_icon(canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_ok); - canvas_draw_icon(canvas, d_pad_x + 2 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_right); - - canvas_draw_icon(canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 2 * (20 + 1), &I_down); - if(model->state == SubRemViewRemoteStateSending) { - switch(model->pressed_btn) { - case SubRemSubKeyNameUp: - canvas_draw_icon( - canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 0 * (20 + 1), &I_up_hover); - break; - case SubRemSubKeyNameDown: - canvas_draw_icon( - canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 2 * (20 + 1), &I_down_hover); - break; - case SubRemSubKeyNameLeft: - canvas_draw_icon( - canvas, d_pad_x + 0 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_left_hover); - break; - case SubRemSubKeyNameRight: - canvas_draw_icon( - canvas, d_pad_x + 2 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_right_hover); - break; - case SubRemSubKeyNameOk: - canvas_draw_icon( - canvas, d_pad_x + 1 * (19 + 1), d_pad_y + 1 * (20 + 1), &I_ok_hover); - break; - default: - break; - } - } - } else { - canvas_draw_icon(canvas, 2, 128 - 11, &I_ButtonLeft_4x7); - canvas_draw_str_aligned(canvas, 8, 128 - 4, AlignLeft, AlignBottom, "Back"); - - canvas_draw_icon(canvas, 58, 128 - 11, &I_ButtonRight_4x7); - canvas_draw_str_aligned(canvas, 56, 128 - 4, AlignRight, AlignBottom, "Save"); - } -} - -bool subrem_view_remote_input(InputEvent* event, void* context) { - furi_assert(context); - SubRemViewRemote* subrem_view_remote = context; - - if(event->key == InputKeyBack && event->type == InputTypePress) { - bool is_stopping = false; - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { - if(model->state == SubRemViewRemoteStateSending) { - is_stopping = true; - model->pressed_btn = 0; - } - }, - true); - - //Cant send exit the app inside that with_model,locks the model and the app will hang and not unload! - if(is_stopping) - subrem_view_remote->callback( - SubRemCustomEventViewRemoteForcedStop, subrem_view_remote->context); - else - subrem_view_remote->callback( - SubRemCustomEventViewRemoteBack, subrem_view_remote->context); - - return true; - } - // BACK button processing end - - if(event->key == InputKeyUp && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartUP, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyDown && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartDOWN, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyLeft && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartLEFT, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyRight && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartRIGHT, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyOk && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartOK, subrem_view_remote->context); - return true; - } else if(event->type == InputTypeRelease) { - subrem_view_remote->callback(SubRemCustomEventViewRemoteStop, subrem_view_remote->context); - return true; - } - - return true; -} - -void subrem_view_remote_enter(void* context) { - furi_assert(context); -} - -void subrem_view_remote_exit(void* context) { - furi_assert(context); -} - -SubRemViewRemote* subrem_view_remote_alloc(void) { - SubRemViewRemote* subrem_view_remote = malloc(sizeof(SubRemViewRemote)); - - // View allocation and configuration - subrem_view_remote->view = view_alloc(); - view_allocate_model( - subrem_view_remote->view, ViewModelTypeLocking, sizeof(SubRemViewRemoteModel)); - view_set_context(subrem_view_remote->view, subrem_view_remote); - view_set_orientation(subrem_view_remote->view, ViewOrientationVertical); - view_set_draw_callback(subrem_view_remote->view, (ViewDrawCallback)subrem_view_remote_draw); - view_set_input_callback(subrem_view_remote->view, subrem_view_remote_input); - view_set_enter_callback(subrem_view_remote->view, subrem_view_remote_enter); - view_set_exit_callback(subrem_view_remote->view, subrem_view_remote_exit); - - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { - model->state = SubRemViewRemoteStateIdle; - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - model->labels[i] = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); - strcpy(model->labels[i], ""); - } - - model->pressed_btn = 0; - model->is_external = false; - }, - true); - return subrem_view_remote; -} - -void subrem_view_remote_free(SubRemViewRemote* subghz_remote) { - furi_assert(subghz_remote); - - with_view_model( - subghz_remote->view, - SubRemViewRemoteModel * model, - { - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - free(model->labels[i]); - } - }, - true); - view_free(subghz_remote->view); - free(subghz_remote); -} - -View* subrem_view_remote_get_view(SubRemViewRemote* subrem_view_remote) { - furi_assert(subrem_view_remote); - return subrem_view_remote->view; -} \ No newline at end of file diff --git a/applications/system/subghz_remote/views/remote.h b/applications/system/subghz_remote/views/remote.h deleted file mode 100644 index 505140298..000000000 --- a/applications/system/subghz_remote/views/remote.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include "../helpers/subrem_custom_event.h" -#include "../helpers/subrem_presets.h" - -typedef enum { - SubRemViewRemoteStateIdle, - SubRemViewRemoteStateLoading, - SubRemViewRemoteStateSending, - SubRemViewRemoteStateOFF, -} SubRemViewRemoteState; - -typedef struct SubRemViewRemote SubRemViewRemote; - -typedef void (*SubRemViewRemoteCallback)(SubRemCustomEvent event, void* context); - -void subrem_view_remote_set_callback( - SubRemViewRemote* subrem_view_remote, - SubRemViewRemoteCallback callback, - void* context); - -SubRemViewRemote* subrem_view_remote_alloc(void); - -void subrem_view_remote_free(SubRemViewRemote* subrem_view_remote); - -View* subrem_view_remote_get_view(SubRemViewRemote* subrem_view_remote); - -void subrem_view_remote_update_data_labels( - SubRemViewRemote* subrem_view_remote, - SubRemSubFilePreset** subs_presets); - -void subrem_view_remote_set_state( - SubRemViewRemote* subrem_view_remote, - SubRemViewRemoteState state, - uint8_t presed_btn); - -void subrem_view_remote_set_radio(SubRemViewRemote* subrem_view_remote, bool external); \ No newline at end of file diff --git a/applications/system/text_viewer/application.fam b/applications/system/text_viewer/application.fam deleted file mode 100644 index c186f4a3d..000000000 --- a/applications/system/text_viewer/application.fam +++ /dev/null @@ -1,18 +0,0 @@ -App( - appid="text_viewer", - name="Text Viewer", - apptype=FlipperAppType.EXTERNAL, - entry_point="text_viewer", - requires=[ - "gui", - "dialogs", - ], - stack_size=10 * 1024, - order=20, - fap_icon="icons/text_10px.png", - fap_category="Tools", - fap_icon_assets="icons", - fap_author="@Willy-JL", # Original by @kowalski7cc & @kyhwana, new has code borrowed from archive > show - fap_version="1.5", - fap_description="Text viewer application", -) diff --git a/applications/system/text_viewer/icons/text_10px.png b/applications/system/text_viewer/icons/text_10px.png deleted file mode 100644 index 8e8a6183d..000000000 Binary files a/applications/system/text_viewer/icons/text_10px.png and /dev/null differ diff --git a/applications/system/text_viewer/scenes/text_viewer_scene.c b/applications/system/text_viewer/scenes/text_viewer_scene.c deleted file mode 100644 index a507da4af..000000000 --- a/applications/system/text_viewer/scenes/text_viewer_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "text_viewer_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const text_viewer_on_enter_handlers[])(void*) = { -#include "text_viewer_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const text_viewer_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "text_viewer_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const text_viewer_on_exit_handlers[])(void* context) = { -#include "text_viewer_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers text_viewer_scene_handlers = { - .on_enter_handlers = text_viewer_on_enter_handlers, - .on_event_handlers = text_viewer_on_event_handlers, - .on_exit_handlers = text_viewer_on_exit_handlers, - .scene_num = TextViewerSceneNum, -}; diff --git a/applications/system/text_viewer/scenes/text_viewer_scene.h b/applications/system/text_viewer/scenes/text_viewer_scene.h deleted file mode 100644 index a8770db3b..000000000 --- a/applications/system/text_viewer/scenes/text_viewer_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) TextViewerScene##id, -typedef enum { -#include "text_viewer_scene_config.h" - TextViewerSceneNum, -} TextViewerScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers text_viewer_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "text_viewer_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "text_viewer_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "text_viewer_scene_config.h" -#undef ADD_SCENE diff --git a/applications/system/text_viewer/scenes/text_viewer_scene_config.h b/applications/system/text_viewer/scenes/text_viewer_scene_config.h deleted file mode 100644 index 86c69441e..000000000 --- a/applications/system/text_viewer/scenes/text_viewer_scene_config.h +++ /dev/null @@ -1 +0,0 @@ -ADD_SCENE(text_viewer, show, Show) diff --git a/applications/system/text_viewer/scenes/text_viewer_scene_show.c b/applications/system/text_viewer/scenes/text_viewer_scene_show.c deleted file mode 100644 index 3d5aa077a..000000000 --- a/applications/system/text_viewer/scenes/text_viewer_scene_show.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "../text_viewer.h" - -#define SHOW_MAX_FILE_SIZE 8000 - -void text_viewer_scene_show_widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - TextViewer* app = (TextViewer*)context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -static bool text_show_read_lines(File* file, FuriString* str_result) { - //furi_string_reset(str_result); - uint8_t buffer[SHOW_MAX_FILE_SIZE]; - - uint16_t read_count = storage_file_read(file, buffer, SHOW_MAX_FILE_SIZE); - if(storage_file_get_error(file) != FSE_OK) { - return false; - } - - for(uint16_t i = 0; i < read_count; i++) { - furi_string_push_back(str_result, buffer[i]); - } - - return true; -} - -void text_viewer_scene_show_on_enter(void* context) { - furi_assert(context); - TextViewer* app = context; - - FuriString* buffer; - buffer = furi_string_alloc(); - - Storage* storage = furi_record_open(RECORD_STORAGE); - File* file = storage_file_alloc(storage); - - FileInfo fileinfo; - FS_Error error = storage_common_stat(storage, furi_string_get_cstr(app->path), &fileinfo); - if(error == FSE_OK) { - if((fileinfo.size < SHOW_MAX_FILE_SIZE) && (fileinfo.size > 2)) { - bool ok = storage_file_open( - file, furi_string_get_cstr(app->path), FSAM_READ, FSOM_OPEN_EXISTING); - if(ok) { - if(!text_show_read_lines(file, buffer)) { - goto text_file_read_err; - } - if(!furi_string_size(buffer)) { - goto text_file_read_err; - } - - storage_file_seek(file, 0, true); - - widget_add_text_scroll_element( - app->widget, 0, 0, 128, 64, furi_string_get_cstr(buffer)); - - } else { - text_file_read_err: - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 64, - AlignLeft, - AlignCenter, - "\e#Error:\nStorage file open error\e#", - false); - } - storage_file_close(file); - } else if(fileinfo.size < 2) { - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 64, - AlignLeft, - AlignCenter, - "\e#Error:\nFile is too small\e#", - false); - } else { - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 64, - AlignLeft, - AlignCenter, - "\e#Error:\nFile is too large to show\e#", - false); - } - } else { - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 64, - AlignLeft, - AlignCenter, - "\e#Error:\nFile system error\e#", - false); - } - - furi_string_free(buffer); - - storage_file_free(file); - furi_record_close(RECORD_STORAGE); - - view_dispatcher_switch_to_view(app->view_dispatcher, TextViewerViewWidget); -} - -bool text_viewer_scene_show_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - TextViewer* app = (TextViewer*)context; - - if(event.type == SceneManagerEventTypeCustom) { - scene_manager_previous_scene(app->scene_manager); - return true; - } - return false; -} - -void text_viewer_scene_show_on_exit(void* context) { - furi_assert(context); - TextViewer* app = (TextViewer*)context; - - widget_reset(app->widget); -} diff --git a/applications/system/text_viewer/text_viewer.c b/applications/system/text_viewer/text_viewer.c deleted file mode 100644 index 782b44c6f..000000000 --- a/applications/system/text_viewer/text_viewer.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "text_viewer.h" - -static bool text_viewer_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - TextViewer* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool text_viewer_back_event_callback(void* context) { - furi_assert(context); - TextViewer* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -TextViewer* text_viewer_alloc() { - TextViewer* app = malloc(sizeof(TextViewer)); - app->gui = furi_record_open(RECORD_GUI); - - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&text_viewer_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, text_viewer_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, text_viewer_back_event_callback); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - app->widget = widget_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, TextViewerViewWidget, widget_get_view(app->widget)); - - app->path = furi_string_alloc(); - - return app; -} - -void text_viewer_free(TextViewer* app) { - furi_assert(app); - - view_dispatcher_remove_view(app->view_dispatcher, TextViewerViewWidget); - widget_free(app->widget); - - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - furi_string_free(app->path); - - furi_record_close(RECORD_GUI); - free(app); -} - -extern int32_t text_viewer(void* p) { - TextViewer* app = text_viewer_alloc(); - - do { - if(p && strlen(p)) { - furi_string_set(app->path, (const char*)p); - } else { - furi_string_set(app->path, TEXT_VIEWER_PATH); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options( - &browser_options, TEXT_VIEWER_EXTENSION, &I_text_10px); - browser_options.hide_ext = false; - - DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); - bool res = dialog_file_browser_show(dialogs, app->path, app->path, &browser_options); - - furi_record_close(RECORD_DIALOGS); - if(!res) { - break; - } - } - - scene_manager_next_scene(app->scene_manager, TextViewerSceneShow); - view_dispatcher_run(app->view_dispatcher); - } while(false); - - text_viewer_free(app); - return 0; -} diff --git a/applications/system/text_viewer/text_viewer.h b/applications/system/text_viewer/text_viewer.h deleted file mode 100644 index f0427ca28..000000000 --- a/applications/system/text_viewer/text_viewer.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "text_viewer_icons.h" -#include "scenes/text_viewer_scene.h" - -#define TEXT_VIEWER_PATH STORAGE_EXT_PATH_PREFIX -#define TEXT_VIEWER_EXTENSION "*" - -typedef struct { - Gui* gui; - SceneManager* scene_manager; - ViewDispatcher* view_dispatcher; - Widget* widget; - - FuriString* path; -} TextViewer; - -typedef enum { - TextViewerViewWidget, -} TextViewerView;