From 21236f4204e4731c71260090b59d4a81cb5f904e Mon Sep 17 00:00:00 2001 From: Leeroy <135471162+LeeroysHub@users.noreply.github.com> Date: Mon, 28 Sep 2026 00:36:22 +1000 Subject: [PATCH 1/4] REFACTOR: My plugins used view displatcher events, zero-mega used global variables. I have removed the globals, added generic plugin navigation targets for all plugins to use, and cleaned up the code. * Moved plugin helpers to their own new module, protopirate_plugins.c --- helpers/protopirate_plugins.c | 315 ++++++++++++++++++ helpers/protopirate_plugins.h | 24 ++ helpers/protopirate_protocol_plugin_host.c | 2 +- helpers/protopirate_psa_bf_host.c | 2 +- helpers/protopirate_tool_scene_host.c | 34 +- helpers/protopirate_types.h | 10 +- protopirate_app.c | 289 +--------------- protopirate_app_i.h | 34 -- scenes/plugins/protopirate_emulate_plugin.c | 53 +-- .../plugins/protopirate_saved_info_plugin.c | 32 +- scenes/protopirate_scene_about.c | 1 + scenes/protopirate_scene_emulate.c | 35 +- scenes/protopirate_scene_receiver_config.c | 1 + scenes/protopirate_scene_saved_info.c | 20 +- scenes/protopirate_scene_sub_decode.c | 43 ++- scenes/protopirate_scene_timing_tuner.c | 32 +- 16 files changed, 460 insertions(+), 467 deletions(-) create mode 100644 helpers/protopirate_plugins.c create mode 100644 helpers/protopirate_plugins.h diff --git a/helpers/protopirate_plugins.c b/helpers/protopirate_plugins.c new file mode 100644 index 0000000..a01f6ba --- /dev/null +++ b/helpers/protopirate_plugins.c @@ -0,0 +1,315 @@ +#include "protopirate_plugins.h" +#include + +// ----------------------------------------------------------------------------- +// Plugin load / unload +// ----------------------------------------------------------------------------- +const FlipperAppPluginDescriptor* load_plugin_fal( + FlipperApplication** fal_app, + const char* plugin_path, + const char* application_id, + uint32_t api_version) { + const FlipperAppPluginDescriptor* app_descriptor; + + bool return_value = false; + do { + FlipperApplicationPreloadStatus preload_res = + flipper_application_preload(*fal_app, plugin_path); + if(preload_res != FlipperApplicationPreloadStatusSuccess) { + FURI_LOG_E(TAG, "Failed to preload plugin: %s", plugin_path); + break; + } + + if(!flipper_application_is_plugin(*fal_app)) { + FURI_LOG_E(TAG, "Plugin file is not a library"); + break; + } + + FlipperApplicationLoadStatus load_status = flipper_application_map_to_memory(*fal_app); + if(load_status != FlipperApplicationLoadStatusSuccess) { + FURI_LOG_E(TAG, "Failed to load plugin file"); + break; + } + + FURI_LOG_D(TAG, "is mapped to memory"); + app_descriptor = flipper_application_plugin_get_descriptor(*fal_app); + if(strcmp(app_descriptor->appid, application_id) != 0) { + FURI_LOG_E(TAG, "Application id mismatch %s", application_id); + break; + } + + if(app_descriptor->ep_api_version != api_version) { + FURI_LOG_E(TAG, "API version mismatch %lu", api_version); + break; + } + + FURI_LOG_I( + TAG, + "Loaded plugin for appid '%s', API %lu", + app_descriptor->appid, + app_descriptor->ep_api_version); + return_value = true; + } while(false); + + //Free the applciation if there was an error, otherwise return the app descriptor. + if(return_value) { + return app_descriptor; + } else { + if(*fal_app) { + flipper_application_free(*fal_app); + *fal_app = NULL; + } + return NULL; + } +} + +void shared_plugin_unload(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type) { + //Clear the invalid reference to the plugin. + FlipperApplication** fal_needs_free = NULL; + switch(plugin_type) { + case ProtoPirateSharedPluginsConfig: { + fal_needs_free = &app->plugin_flipper_application; + app->config_plugin = NULL; + break; + } + case ProtoPirateSharedPluginsSavedInfo: { + fal_needs_free = &app->plugin_flipper_application; + app->saved_info_plugin = NULL; + break; + } + case ProtoPirateSharedPluginsAbout: { + fal_needs_free = &app->plugin_flipper_application; + app->about_plugin = NULL; + break; + } +#ifdef ENABLE_EMULATE_FEATURE + case ProtoPirateSharedPluginsEmulate: { + fal_needs_free = &app->plugin_flipper_application; + app->emulate_plugin = NULL; + break; + } +#endif + case ProtoPirateSharedPluginsToolScene: + case ProtoPirateSharedPluginsSubDecode: +#ifdef ENABLE_TIMING_TUNER_SCENE + case ProtoPirateSharedPluginsTimingTuner: +#endif + { + fal_needs_free = &app->tool_scene_plugin_flipper_application; + app->tool_scene_plugin = NULL; + break; + } + case ProtoPirateSharedPluginsPSABruteforce: { + fal_needs_free = &app->psa_bf_plugin_flipper_application; + app->psa_bf_plugin = NULL; + break; + } + case ProtoPirateSharedPluginsTXRX: { + fal_needs_free = &app->txrx->protocol_plugin_flipper_application; + app->txrx->protocol_plugin = NULL; + break; + } + default: + return; + } + + //Free the flipper application. + if(*fal_needs_free) { + flipper_application_free(*fal_needs_free); + *fal_needs_free = NULL; + } +} + +bool shared_plugin_load( + ProtoPirateApp* app, + ProtoPirateSharedPlugin plugin_type, + const char* txrx_path) { + //Get the APPID and API VERSION for the Plugin we are loading. + const char* application_id = NULL; + const char* plugin_path = NULL; + uint32_t api_version = 0; + FlipperApplication** fal_needs_alloc = NULL; + + switch(plugin_type) { + case ProtoPirateSharedPluginsConfig: { + if(app->config_plugin) return true; + application_id = PROTOPIRATE_CONFIG_PLUGIN_APP_ID; + api_version = PROTOPIRATE_CONFIG_PLUGIN_API_VERSION; + plugin_path = CONFIG_PLUGIN_PATH; + fal_needs_alloc = &app->plugin_flipper_application; + break; + } + case ProtoPirateSharedPluginsSavedInfo: { + if(app->saved_info_plugin) return true; + application_id = PROTOPIRATE_SAVED_INFO_PLUGIN_APP_ID; + api_version = PROTOPIRATE_SAVED_INFO_PLUGIN_API_VERSION; + plugin_path = SAVED_INFO_PLUGIN_PATH; + fal_needs_alloc = &app->plugin_flipper_application; + break; + } + case ProtoPirateSharedPluginsAbout: { + if(app->about_plugin) return true; + application_id = PROTOPIRATE_ABOUT_PLUGIN_APP_ID; + api_version = PROTOPIRATE_ABOUT_PLUGIN_API_VERSION; + plugin_path = ABOUT_PLUGIN_PATH; + fal_needs_alloc = &app->plugin_flipper_application; + break; + } +#ifdef ENABLE_EMULATE_FEATURE + case ProtoPirateSharedPluginsEmulate: { + if(app->emulate_plugin) return true; + application_id = PROTOPIRATE_EMULATE_PLUGIN_APP_ID; + api_version = PROTOPIRATE_EMULATE_PLUGIN_API_VERSION; + plugin_path = EMULATE_PLUGIN_PATH; + fal_needs_alloc = &app->plugin_flipper_application; + break; + } +#endif + case ProtoPirateSharedPluginsSubDecode: { + if(app->tool_scene_plugin) return true; + application_id = PROTOPIRATE_TOOL_SCENE_PLUGIN_APP_ID; + api_version = PROTOPIRATE_TOOL_SCENE_PLUGIN_API_VERSION; + plugin_path = SUB_DECODE_PLUGIN_PATH; + fal_needs_alloc = &app->tool_scene_plugin_flipper_application; + break; + } +#ifdef ENABLE_TIMING_TUNER_SCENE + case ProtoPirateSharedPluginsTimingTuner: { + if(app->tool_scene_plugin) return true; + application_id = PROTOPIRATE_TOOL_SCENE_PLUGIN_APP_ID; + api_version = PROTOPIRATE_TOOL_SCENE_PLUGIN_API_VERSION; + plugin_path = TIMING_TUNER_PLUGIN_PATH; + fal_needs_alloc = &app->tool_scene_plugin_flipper_application; + break; + } +#endif + case ProtoPirateSharedPluginsPSABruteforce: { + if(app->psa_bf_plugin) return true; + application_id = PROTOPIRATE_PSA_BF_PLUGIN_APP_ID; + api_version = PROTOPIRATE_PSA_BF_PLUGIN_API_VERSION; + plugin_path = PSA_BF_PLUGIN_PATH; + fal_needs_alloc = &app->psa_bf_plugin_flipper_application; + break; + } + case ProtoPirateSharedPluginsTXRX: { + if(app->txrx->protocol_plugin) return true; + application_id = PROTOPIRATE_PROTOCOL_PLUGIN_APP_ID; + api_version = PROTOPIRATE_PROTOCOL_PLUGIN_API_VERSION; + plugin_path = txrx_path; + fal_needs_alloc = &app->txrx->protocol_plugin_flipper_application; + break; + } + default: + return false; + } + + FURI_LOG_D(TAG, "Loading plugin: %s", plugin_path); + + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperApplication* fal_app = flipper_application_alloc(storage, firmware_api_interface); + bool return_value = false; + do { + //Load the FAP + const FlipperAppPluginDescriptor* app_descriptor = + load_plugin_fal(&fal_app, plugin_path, application_id, api_version); + if(app_descriptor) { + //Get the Plugin and assign it. + if(plugin_type == ProtoPirateSharedPluginsConfig) { + const ProtoPirateConfigPlugin* plugin_config = app_descriptor->entry_point; + if(!plugin_config || !plugin_config->on_enter) { + FURI_LOG_E(TAG, "Config plugin entry point is invalid"); + } else { + app->config_plugin = plugin_config; + return_value = true; + } + } else if(plugin_type == ProtoPirateSharedPluginsSavedInfo) { + const ProtoPirateSavedInfoPlugin* plugin_saved_info = app_descriptor->entry_point; + if(!plugin_saved_info || !plugin_saved_info->on_enter) { + FURI_LOG_E(TAG, "Saved Info plugin entry point is invalid"); + } else { + app->saved_info_plugin = plugin_saved_info; + return_value = true; + } + } else if(plugin_type == ProtoPirateSharedPluginsAbout) { + const ProtoPirateAboutPlugin* plugin_about = app_descriptor->entry_point; + if(!plugin_about || !plugin_about->on_enter) { + FURI_LOG_E(TAG, "About plugin entry point is invalid"); + } else { + app->about_plugin = plugin_about; + return_value = true; + } + } +#ifdef ENABLE_EMULATE_FEATURE + else if(plugin_type == ProtoPirateSharedPluginsEmulate) { + const ProtoPirateEmulatePlugin* plugin_emulate = app_descriptor->entry_point; + if(!plugin_emulate || !plugin_emulate->on_enter) { + FURI_LOG_E(TAG, "Emulate plugin entry point is invalid"); + } else { + app->emulate_plugin = plugin_emulate; + return_value = true; + } + } +#endif + else if( + plugin_type == ProtoPirateSharedPluginsSubDecode +#ifdef ENABLE_TIMING_TUNER_SCENE + || plugin_type == ProtoPirateSharedPluginsTimingTuner +#endif + ) { + const ProtoPirateToolScenePlugin* plugin_tool_scene = app_descriptor->entry_point; + if(!plugin_tool_scene || !plugin_tool_scene->on_enter) { + FURI_LOG_E(TAG, "Tool Scene plugin entry point is invalid"); + } else { + app->tool_scene_plugin = plugin_tool_scene; + return_value = true; + } + } else if(plugin_type == ProtoPirateSharedPluginsPSABruteforce) { + const ProtoPiratePsaBfPlugin* plugin_psa_bf = app_descriptor->entry_point; + if(!plugin_psa_bf || !plugin_psa_bf->needs_bruteforce) { + FURI_LOG_E(TAG, "PSA plugin entry needs_bruteforce is invalid"); + } else { + app->psa_bf_plugin = plugin_psa_bf; + return_value = true; + } + } else if(plugin_type == ProtoPirateSharedPluginsTXRX) { + const ProtoPirateProtocolPlugin* plugin_txrx = app_descriptor->entry_point; + if(!plugin_txrx || !plugin_txrx->registry) { + FURI_LOG_E(TAG, "Protocol plugin registry entry is invalid"); + } else { + app->txrx->protocol_plugin = plugin_txrx; + return_value = true; + } + } + } + } while(false); + + //Free the plugin if there was an error, otherwise we are done! + if(fal_needs_alloc) *fal_needs_alloc = fal_app; + furi_record_close(RECORD_STORAGE); + return return_value; +} + +bool shared_plugin_handle_navigation_events(void* context, SceneManagerEvent event) { + ProtoPirateApp* app = (ProtoPirateApp*)context; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == ProtoPirateCustomEventPluginNavigateEmulate) { +#ifdef ENABLE_EMULATE_FEATURE + scene_manager_next_scene(app->scene_manager, ProtoPirateSceneEmulate); +#endif + return true; + } + if(event.event == ProtoPirateCustomEventPluginNavigateConfig) { + scene_manager_next_scene(app->scene_manager, ProtoPirateSceneReceiverConfig); + return true; + } else if(event.event == ProtoPirateCustomEventPluginNavigateBack) { + scene_manager_previous_scene(app->scene_manager); + return true; + } else if(event.event == ProtoPirateCustomEventPluginNavigateStopApp) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + return true; + } + } + return false; +} diff --git a/helpers/protopirate_plugins.h b/helpers/protopirate_plugins.h new file mode 100644 index 0000000..3cca6c7 --- /dev/null +++ b/helpers/protopirate_plugins.h @@ -0,0 +1,24 @@ +#include "../protopirate_app_i.h" + +typedef enum ProtoPirateSharedPlugin { + ProtoPirateSharedPluginsConfig, + ProtoPirateSharedPluginsSavedInfo, + ProtoPirateSharedPluginsAbout, +#ifdef ENABLE_EMULATE_FEATURE + ProtoPirateSharedPluginsEmulate, +#endif + ProtoPirateSharedPluginsToolScene, + ProtoPirateSharedPluginsSubDecode, +#ifdef ENABLE_TIMING_TUNER_SCENE + ProtoPirateSharedPluginsTimingTuner, +#endif + ProtoPirateSharedPluginsPSABruteforce, + ProtoPirateSharedPluginsTXRX, +} ProtoPirateSharedPlugin; + +bool shared_plugin_load( + ProtoPirateApp* app, + ProtoPirateSharedPlugin plugin_type, + const char* txrx_path); +void shared_plugin_unload(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type); +bool shared_plugin_handle_navigation_events(void* context, SceneManagerEvent event); diff --git a/helpers/protopirate_protocol_plugin_host.c b/helpers/protopirate_protocol_plugin_host.c index 327d3e8..f9228c5 100644 --- a/helpers/protopirate_protocol_plugin_host.c +++ b/helpers/protopirate_protocol_plugin_host.c @@ -1,8 +1,8 @@ #include "../protopirate_app_i.h" #include "protopirate_txrx.h" #include "../protocols/protocol_items.h" +#include "helpers/protopirate_plugins.h" -#include #include #include diff --git a/helpers/protopirate_psa_bf_host.c b/helpers/protopirate_psa_bf_host.c index eecbb4d..836ba59 100644 --- a/helpers/protopirate_psa_bf_host.c +++ b/helpers/protopirate_psa_bf_host.c @@ -3,8 +3,8 @@ #include "../protopirate_history.h" #include "../protocols/protocols_common.h" #include "../scenes/plugins/protopirate_psa_bf_plugin.h" +#include "helpers/protopirate_plugins.h" -#include #include #define TAG "PPPsaBfHost" diff --git a/helpers/protopirate_tool_scene_host.c b/helpers/protopirate_tool_scene_host.c index e697de1..52b53ba 100644 --- a/helpers/protopirate_tool_scene_host.c +++ b/helpers/protopirate_tool_scene_host.c @@ -1,8 +1,8 @@ #include "../protopirate_app_i.h" #include "protopirate_psa_bf_host.h" #include "radio_device_loader.h" +#include "helpers/protopirate_plugins.h" -#include #include #define TAG "PPToolScene" @@ -141,40 +141,10 @@ static bool protopirate_tool_scene_plugin_ensure_loaded( return true; } -static void protopirate_tool_scene_apply_pending_nav(ProtoPirateApp* app) { - furi_check(app); - - const uint8_t nav = app->tool_scene_nav_pending; - if(nav == TOOL_SCENE_NAV_NONE) { - return; - } - - const uint32_t target = app->tool_scene_nav_target; - app->tool_scene_nav_pending = TOOL_SCENE_NAV_NONE; - app->tool_scene_nav_target = 0; - - switch(nav) { - case TOOL_SCENE_NAV_POP: - scene_manager_previous_scene(app->scene_manager); - break; - case TOOL_SCENE_NAV_NEXT: - scene_manager_next_scene(app->scene_manager, target); - break; - case TOOL_SCENE_NAV_SEARCH_PREVIOUS: - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, target); - break; - default: - break; - } -} - bool protopirate_tool_scene_on_enter(void* context, ProtoPirateToolScenePluginKind kind) { ProtoPirateApp* app = context; furi_check(app); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_NONE; - app->tool_scene_nav_target = 0; - if(!protopirate_tool_scene_plugin_ensure_loaded(app, kind) || !app->tool_scene_plugin) { notification_message(app->notifications, &sequence_error); scene_manager_previous_scene(app->scene_manager); @@ -182,7 +152,6 @@ bool protopirate_tool_scene_on_enter(void* context, ProtoPirateToolScenePluginKi } app->tool_scene_plugin->on_enter(app); - protopirate_tool_scene_apply_pending_nav(app); return true; } @@ -193,7 +162,6 @@ bool protopirate_tool_scene_on_event(void* context, SceneManagerEvent event) { } const bool consumed = app->tool_scene_plugin->on_event(app, event); - protopirate_tool_scene_apply_pending_nav(app); return consumed; } diff --git a/helpers/protopirate_types.h b/helpers/protopirate_types.h index 657d3c0..e953a3d 100644 --- a/helpers/protopirate_types.h +++ b/helpers/protopirate_types.h @@ -31,22 +31,19 @@ typedef enum { ProtoPirateCustomEventReceiverInfoUpdate, ProtoPirateCustomEventReceiverInfoEmulate, ProtoPirateCustomEventSavedInfoDelete, - ProtoPirateCustomEventSavedInfoExit, //Bruteforcing PSA & Renault ProtoPirateCustomEventBruteforceStart, ProtoPirateCustomEventBruteforceComplete, // Emulator - ProtoPirateCustomEventSavedInfoEmulate, - ProtoPirateCustomEventSavedInfoEmulateDelayedStart, ProtoPirateCustomEventEmulateTransmit, ProtoPirateCustomEventEmulateStop, ProtoPirateCustomEventEmulateExit, + ProtoPirateCustomEventSavedInfoEmulate, // Sub decode ProtoPirateCustomEventSubDecodeUpdate, ProtoPirateCustomEventSubDecodeSave, ProtoPirateCustomEventSubDecodeEmulate, ProtoPirateCustomEventSubDecodeSaveConfirm, - ProtoPirateCustomEventSubDecodeEmulateDelayedStart, // File Browser ProtoPirateCustomEventSavedFileSelected, // Need saving confirmation @@ -54,6 +51,11 @@ typedef enum { ProtoPirateCustomEventSceneExit, // About scene ProtoPirateCustomEventAboutToggleEmulate, + //Plugin Scenes + ProtoPirateCustomEventPluginNavigateBack, + ProtoPirateCustomEventPluginNavigateEmulate, + ProtoPirateCustomEventPluginNavigateConfig, + ProtoPirateCustomEventPluginNavigateStopApp, } ProtoPirateCustomEvent; typedef enum { diff --git a/protopirate_app.c b/protopirate_app.c index 32fd420..a73d9cf 100644 --- a/protopirate_app.c +++ b/protopirate_app.c @@ -8,298 +8,11 @@ #include "helpers/protopirate_psa_bf_host.h" #include "helpers/protopirate_views.h" #include "helpers/protopirate_radio.h" +#include "helpers/protopirate_plugins.h" #include #define TAG "PPApp" -// ----------------------------------------------------------------------------- -// Plugin load / unload -// ----------------------------------------------------------------------------- -const FlipperAppPluginDescriptor* load_plugin_fal( - FlipperApplication** fal_app, - const char* plugin_path, - const char* application_id, - uint32_t api_version) { - const FlipperAppPluginDescriptor* app_descriptor; - - bool return_value = false; - do { - FlipperApplicationPreloadStatus preload_res = - flipper_application_preload(*fal_app, plugin_path); - if(preload_res != FlipperApplicationPreloadStatusSuccess) { - FURI_LOG_E(TAG, "Failed to preload plugin: %s", plugin_path); - break; - } - - if(!flipper_application_is_plugin(*fal_app)) { - FURI_LOG_E(TAG, "Plugin file is not a library"); - break; - } - - FlipperApplicationLoadStatus load_status = flipper_application_map_to_memory(*fal_app); - if(load_status != FlipperApplicationLoadStatusSuccess) { - FURI_LOG_E(TAG, "Failed to load plugin file"); - break; - } - - FURI_LOG_D(TAG, "is mapped to memory"); - app_descriptor = flipper_application_plugin_get_descriptor(*fal_app); - if(strcmp(app_descriptor->appid, application_id) != 0) { - FURI_LOG_E(TAG, "Application id mismatch %s", application_id); - break; - } - - if(app_descriptor->ep_api_version != api_version) { - FURI_LOG_E(TAG, "API version mismatch %lu", api_version); - break; - } - - FURI_LOG_I( - TAG, - "Loaded plugin for appid '%s', API %lu", - app_descriptor->appid, - app_descriptor->ep_api_version); - return_value = true; - } while(false); - - //Free the applciation if there was an error, otherwise return the app descriptor. - if(return_value) { - return app_descriptor; - } else { - if(*fal_app) { - flipper_application_free(*fal_app); - *fal_app = NULL; - } - return NULL; - } -} - -void shared_plugin_unload(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type) { - //Clear the invalid reference to the plugin. - FlipperApplication** fal_needs_free = NULL; - switch(plugin_type) { - case ProtoPirateSharedPluginsConfig: { - fal_needs_free = &app->plugin_flipper_application; - app->config_plugin = NULL; - break; - } - case ProtoPirateSharedPluginsSavedInfo: { - fal_needs_free = &app->plugin_flipper_application; - app->saved_info_plugin = NULL; - break; - } - case ProtoPirateSharedPluginsAbout: { - fal_needs_free = &app->plugin_flipper_application; - app->about_plugin = NULL; - break; - } -#ifdef ENABLE_EMULATE_FEATURE - case ProtoPirateSharedPluginsEmulate: { - fal_needs_free = &app->plugin_flipper_application; - app->emulate_plugin = NULL; - break; - } -#endif - case ProtoPirateSharedPluginsToolScene: - case ProtoPirateSharedPluginsSubDecode: -#ifdef ENABLE_TIMING_TUNER_SCENE - case ProtoPirateSharedPluginsTimingTuner: -#endif - { - fal_needs_free = &app->tool_scene_plugin_flipper_application; - app->tool_scene_plugin = NULL; - break; - } - case ProtoPirateSharedPluginsPSABruteforce: { - fal_needs_free = &app->psa_bf_plugin_flipper_application; - app->psa_bf_plugin = NULL; - break; - } - case ProtoPirateSharedPluginsTXRX: { - fal_needs_free = &app->txrx->protocol_plugin_flipper_application; - app->txrx->protocol_plugin = NULL; - break; - } - default: - return; - } - - //Free the flipper application. - if(*fal_needs_free) { - flipper_application_free(*fal_needs_free); - *fal_needs_free = NULL; - } -} - -bool shared_plugin_load( - ProtoPirateApp* app, - ProtoPirateSharedPlugin plugin_type, - const char* txrx_path) { - //Get the APPID and API VERSION for the Plugin we are loading. - const char* application_id = NULL; - const char* plugin_path = NULL; - uint32_t api_version = 0; - FlipperApplication** fal_needs_alloc = NULL; - - switch(plugin_type) { - case ProtoPirateSharedPluginsConfig: { - if(app->config_plugin) return true; - application_id = PROTOPIRATE_CONFIG_PLUGIN_APP_ID; - api_version = PROTOPIRATE_CONFIG_PLUGIN_API_VERSION; - plugin_path = CONFIG_PLUGIN_PATH; - fal_needs_alloc = &app->plugin_flipper_application; - break; - } - case ProtoPirateSharedPluginsSavedInfo: { - if(app->saved_info_plugin) return true; - application_id = PROTOPIRATE_SAVED_INFO_PLUGIN_APP_ID; - api_version = PROTOPIRATE_SAVED_INFO_PLUGIN_API_VERSION; - plugin_path = SAVED_INFO_PLUGIN_PATH; - fal_needs_alloc = &app->plugin_flipper_application; - break; - } - case ProtoPirateSharedPluginsAbout: { - if(app->about_plugin) return true; - application_id = PROTOPIRATE_ABOUT_PLUGIN_APP_ID; - api_version = PROTOPIRATE_ABOUT_PLUGIN_API_VERSION; - plugin_path = ABOUT_PLUGIN_PATH; - fal_needs_alloc = &app->plugin_flipper_application; - break; - } -#ifdef ENABLE_EMULATE_FEATURE - case ProtoPirateSharedPluginsEmulate: { - if(app->emulate_plugin) return true; - application_id = PROTOPIRATE_EMULATE_PLUGIN_APP_ID; - api_version = PROTOPIRATE_EMULATE_PLUGIN_API_VERSION; - plugin_path = EMULATE_PLUGIN_PATH; - fal_needs_alloc = &app->plugin_flipper_application; - break; - } -#endif - case ProtoPirateSharedPluginsSubDecode: { - if(app->tool_scene_plugin) return true; - application_id = PROTOPIRATE_TOOL_SCENE_PLUGIN_APP_ID; - api_version = PROTOPIRATE_TOOL_SCENE_PLUGIN_API_VERSION; - plugin_path = SUB_DECODE_PLUGIN_PATH; - fal_needs_alloc = &app->tool_scene_plugin_flipper_application; - break; - } -#ifdef ENABLE_TIMING_TUNER_SCENE - case ProtoPirateSharedPluginsTimingTuner: { - if(app->tool_scene_plugin) return true; - application_id = PROTOPIRATE_TOOL_SCENE_PLUGIN_APP_ID; - api_version = PROTOPIRATE_TOOL_SCENE_PLUGIN_API_VERSION; - plugin_path = TIMING_TUNER_PLUGIN_PATH; - fal_needs_alloc = &app->tool_scene_plugin_flipper_application; - break; - } -#endif - case ProtoPirateSharedPluginsPSABruteforce: { - if(app->psa_bf_plugin) return true; - application_id = PROTOPIRATE_PSA_BF_PLUGIN_APP_ID; - api_version = PROTOPIRATE_PSA_BF_PLUGIN_API_VERSION; - plugin_path = PSA_BF_PLUGIN_PATH; - fal_needs_alloc = &app->psa_bf_plugin_flipper_application; - break; - } - case ProtoPirateSharedPluginsTXRX: { - if(app->txrx->protocol_plugin) return true; - application_id = PROTOPIRATE_PROTOCOL_PLUGIN_APP_ID; - api_version = PROTOPIRATE_PROTOCOL_PLUGIN_API_VERSION; - plugin_path = txrx_path; - fal_needs_alloc = &app->txrx->protocol_plugin_flipper_application; - break; - } - default: - return false; - } - - FURI_LOG_D(TAG, "Loading plugin: %s", plugin_path); - - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperApplication* fal_app = flipper_application_alloc(storage, firmware_api_interface); - bool return_value = false; - do { - //Load the FAP - const FlipperAppPluginDescriptor* app_descriptor = - load_plugin_fal(&fal_app, plugin_path, application_id, api_version); - if(app_descriptor) { - //Get the Plugin and assign it. - if(plugin_type == ProtoPirateSharedPluginsConfig) { - const ProtoPirateConfigPlugin* plugin_config = app_descriptor->entry_point; - if(!plugin_config || !plugin_config->on_enter) { - FURI_LOG_E(TAG, "Config plugin entry point is invalid"); - } else { - app->config_plugin = plugin_config; - return_value = true; - } - } else if(plugin_type == ProtoPirateSharedPluginsSavedInfo) { - const ProtoPirateSavedInfoPlugin* plugin_saved_info = app_descriptor->entry_point; - if(!plugin_saved_info || !plugin_saved_info->on_enter) { - FURI_LOG_E(TAG, "Saved Info plugin entry point is invalid"); - } else { - app->saved_info_plugin = plugin_saved_info; - return_value = true; - } - } else if(plugin_type == ProtoPirateSharedPluginsAbout) { - const ProtoPirateAboutPlugin* plugin_about = app_descriptor->entry_point; - if(!plugin_about || !plugin_about->on_enter) { - FURI_LOG_E(TAG, "About plugin entry point is invalid"); - } else { - app->about_plugin = plugin_about; - return_value = true; - } - } -#ifdef ENABLE_EMULATE_FEATURE - else if(plugin_type == ProtoPirateSharedPluginsEmulate) { - const ProtoPirateEmulatePlugin* plugin_emulate = app_descriptor->entry_point; - if(!plugin_emulate || !plugin_emulate->on_enter) { - FURI_LOG_E(TAG, "Emulate plugin entry point is invalid"); - } else { - app->emulate_plugin = plugin_emulate; - return_value = true; - } - } -#endif - else if( - plugin_type == ProtoPirateSharedPluginsSubDecode -#ifdef ENABLE_TIMING_TUNER_SCENE - || plugin_type == ProtoPirateSharedPluginsTimingTuner -#endif - ) { - const ProtoPirateToolScenePlugin* plugin_tool_scene = app_descriptor->entry_point; - if(!plugin_tool_scene || !plugin_tool_scene->on_enter) { - FURI_LOG_E(TAG, "Tool Scene plugin entry point is invalid"); - } else { - app->tool_scene_plugin = plugin_tool_scene; - return_value = true; - } - } else if(plugin_type == ProtoPirateSharedPluginsPSABruteforce) { - const ProtoPiratePsaBfPlugin* plugin_psa_bf = app_descriptor->entry_point; - if(!plugin_psa_bf || !plugin_psa_bf->needs_bruteforce) { - FURI_LOG_E(TAG, "PSA plugin entry needs_bruteforce is invalid"); - } else { - app->psa_bf_plugin = plugin_psa_bf; - return_value = true; - } - } else if(plugin_type == ProtoPirateSharedPluginsTXRX) { - const ProtoPirateProtocolPlugin* plugin_txrx = app_descriptor->entry_point; - if(!plugin_txrx || !plugin_txrx->registry) { - FURI_LOG_E(TAG, "Protocol plugin registry entry is invalid"); - } else { - app->txrx->protocol_plugin = plugin_txrx; - return_value = true; - } - } - } - } while(false); - - //Free the plugin if there was an error, otherwise we are done! - if(fal_needs_alloc) *fal_needs_alloc = fal_app; - furi_record_close(RECORD_STORAGE); - return return_value; -} - static bool protopirate_app_custom_event_callback(void* context, uint32_t event) { furi_check(context); ProtoPirateApp* app = context; diff --git a/protopirate_app_i.h b/protopirate_app_i.h index fb8cbe8..6f1fefd 100644 --- a/protopirate_app_i.h +++ b/protopirate_app_i.h @@ -40,7 +40,6 @@ #include "helpers/protopirate_protocol_plugin_host.h" #include "helpers/protopirate_txrx.h" #include "helpers/protopirate_models.h" -#include #include "helpers/protopirate_settings.h" #define CONFIG_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_config.fal") @@ -110,9 +109,6 @@ struct ProtoPirateApp { uint16_t save_history_idx; FlipperApplication* plugin_flipper_application; #ifdef ENABLE_EMULATE_FEATURE -#define EMULATE_NAV_NONE 0U -#define EMULATE_NAV_POP 1U -#define EMULATE_NAV_STOP_APP 2U const ProtoPirateEmulatePlugin* emulate_plugin; uint8_t emulate_nav_pending; #endif @@ -124,13 +120,6 @@ struct ProtoPirateApp { FlipperApplication* tool_scene_plugin_flipper_application; const ProtoPirateToolScenePlugin* tool_scene_plugin; ProtoPirateToolScenePluginKind tool_scene_plugin_kind; -#define TOOL_SCENE_NAV_NONE 0U -#define TOOL_SCENE_NAV_POP 1U -#define TOOL_SCENE_NAV_NEXT 2U -#define TOOL_SCENE_NAV_SEARCH_PREVIOUS 3U - uint8_t tool_scene_nav_pending; - uint32_t tool_scene_nav_target; - ProtoPirateCarModel* selected_model; uint16_t car_models_count; }; @@ -148,29 +137,6 @@ bool protopirate_tool_scene_on_enter(void* app, ProtoPirateToolScenePluginKind k bool protopirate_tool_scene_on_event(void* app, SceneManagerEvent event); void protopirate_tool_scene_on_exit(void* app); void protopirate_tool_scene_plugin_release(ProtoPirateApp* app); - -typedef enum ProtoPirateSharedPlugin { - ProtoPirateSharedPluginsConfig, - ProtoPirateSharedPluginsSavedInfo, - ProtoPirateSharedPluginsAbout, -#ifdef ENABLE_EMULATE_FEATURE - ProtoPirateSharedPluginsEmulate, -#endif - ProtoPirateSharedPluginsToolScene, - ProtoPirateSharedPluginsSubDecode, -#ifdef ENABLE_TIMING_TUNER_SCENE - ProtoPirateSharedPluginsTimingTuner, -#endif - ProtoPirateSharedPluginsPSABruteforce, - ProtoPirateSharedPluginsTXRX, -} ProtoPirateSharedPlugin; - -bool shared_plugin_load( - ProtoPirateApp* app, - ProtoPirateSharedPlugin plugin_type, - const char* txrx_path); -void shared_plugin_unload(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type); - void protopirate_app_free(ProtoPirateApp* app); static const NotificationSequence sequence_tx = { diff --git a/scenes/plugins/protopirate_emulate_plugin.c b/scenes/plugins/protopirate_emulate_plugin.c index 84d7414..0b20687 100644 --- a/scenes/plugins/protopirate_emulate_plugin.c +++ b/scenes/plugins/protopirate_emulate_plugin.c @@ -179,18 +179,6 @@ static bool emulate_hitag2_recovered_yes(FlipperFormat* flipper_format) { return false; } -static void emulate_request_nav_pop(ProtoPirateApp* app) { - app->emulate_nav_pending = EMULATE_NAV_POP; -} - -static void emulate_request_nav_after_exit(ProtoPirateApp* app) { - if(scene_manager_has_previous_scene(app->scene_manager, ProtoPirateSceneStart)) { - app->emulate_nav_pending = EMULATE_NAV_POP; - } else { - app->emulate_nav_pending = EMULATE_NAV_STOP_APP; - } -} - static bool emulate_prompt_hitag2_key(ProtoPirateApp* app, EmulateContext* ctx); static void emulate_hitag2_key_input_callback(void* context) { @@ -211,7 +199,8 @@ static void emulate_hitag2_key_input_callback(void* context) { if(!emulate_write_hitag2_key(ctx->flipper_format, key)) { notification_message(app->notifications, &sequence_error); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -1080,7 +1069,8 @@ static void plugin_on_enter(void* context) { if(!g_host_api->ensure_view_about || !g_host_api->ensure_view_about(app)) { notification_message(app->notifications, &sequence_error); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -1101,7 +1091,8 @@ static void plugin_on_enter(void* context) { if(!g_host_api->radio_init || !g_host_api->radio_init(app)) { FURI_LOG_E(TAG, "Failed to initialize radio for emulate scene"); notification_message(app->notifications, &sequence_error); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } } @@ -1109,14 +1100,16 @@ static void plugin_on_enter(void* context) { if(!emulate_radio_ready(app)) { FURI_LOG_E(TAG, "Radio still incomplete after emulate init"); notification_message(app->notifications, &sequence_error); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } emulate_context = malloc(sizeof(EmulateContext)); if(!emulate_context) { FURI_LOG_E(TAG, "Failed to allocate emulate context"); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } memset(emulate_context, 0, sizeof(EmulateContext)); @@ -1126,7 +1119,8 @@ static void plugin_on_enter(void* context) { if(!ctx->protocol_name) { FURI_LOG_E(TAG, "Failed to allocate protocol name string"); emulate_context_free(); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -1134,7 +1128,8 @@ static void plugin_on_enter(void* context) { FURI_LOG_E(TAG, "No file path set"); emulate_context_free(); notification_message(app->notifications, &sequence_error); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -1143,7 +1138,8 @@ static void plugin_on_enter(void* context) { FURI_LOG_E(TAG, "Failed to open storage"); emulate_context_free(); notification_message(app->notifications, &sequence_error); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -1152,7 +1148,8 @@ static void plugin_on_enter(void* context) { FURI_LOG_E(TAG, "Failed to allocate FlipperFormat"); emulate_context_free(); notification_message(app->notifications, &sequence_error); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -1160,7 +1157,8 @@ static void plugin_on_enter(void* context) { FURI_LOG_E(TAG, "Failed to open file: %s", app->loaded_file_path); emulate_context_free(); notification_message(app->notifications, &sequence_error); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -1313,7 +1311,8 @@ static void plugin_on_enter(void* context) { FURI_LOG_E(TAG, "Failed to show HITAG2 key input"); notification_message(app->notifications, &sequence_error); emulate_context_free(); - emulate_request_nav_pop(app); + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); } return; } @@ -1474,7 +1473,13 @@ static bool plugin_on_event(void* context, SceneManagerEvent event) { } } - emulate_request_nav_after_exit(app); + if(!scene_manager_has_previous_scene(app->scene_manager, ProtoPirateSceneStart)) { + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateStopApp); + } else { + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); + } consumed = true; break; } diff --git a/scenes/plugins/protopirate_saved_info_plugin.c b/scenes/plugins/protopirate_saved_info_plugin.c index 202b156..e4c81bb 100644 --- a/scenes/plugins/protopirate_saved_info_plugin.c +++ b/scenes/plugins/protopirate_saved_info_plugin.c @@ -47,8 +47,12 @@ void plugin_protopirate_scene_saved_info_on_enter(void* context) { if(!g_saved_info_scene_host_api->ensure_widget(app)) { notification_message(app->notifications, &sequence_error); - view_dispatcher_send_custom_event( - app->view_dispatcher, ProtoPirateCustomEventSavedInfoExit); + if(!scene_manager_has_previous_scene(app->scene_manager, ProtoPirateSceneStart)) { + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateStopApp); + } else + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -285,9 +289,16 @@ bool plugin_protopirate_scene_saved_info_on_event(void* context, SceneManagerEve consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { - return ( - app->psa_bf_plugin && app->psa_bf_plugin->is_running && - app->psa_bf_plugin->on_scene_event(app, ProtoPiratePsaBfContextReceiverInfo, event)); + if(app->psa_bf_plugin && app->psa_bf_plugin->is_running && + app->psa_bf_plugin->on_scene_event(app, ProtoPiratePsaBfContextReceiverInfo, event)) { + consumed = true; + } else { + if(!scene_manager_has_previous_scene(app->scene_manager, ProtoPirateSceneStart)) { + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateStopApp); + consumed = true; + } + } } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == ProtoPirateCustomEventSavedInfoDelete) { FURI_LOG_I(TAG, "Delete requested"); @@ -312,8 +323,13 @@ bool plugin_protopirate_scene_saved_info_on_event(void* context, SceneManagerEve g_saved_info_scene_host_api->storage_delete_file(app->loaded_file_path); notification_message(app->notifications, &sequence_semi_success); - view_dispatcher_send_custom_event( - app->view_dispatcher, ProtoPirateCustomEventSavedInfoExit); + if(!scene_manager_has_previous_scene( + app->scene_manager, ProtoPirateSceneStart)) { + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateStopApp); + } else + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); } } consumed = true; @@ -336,7 +352,7 @@ bool plugin_protopirate_scene_saved_info_on_event(void* context, SceneManagerEve //Send custom event back to the scene, so it can start emulate for us and avoid the crashes. view_dispatcher_send_custom_event( - app->view_dispatcher, ProtoPirateCustomEventSavedInfoEmulateDelayedStart); + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateEmulate); consumed = true; } diff --git a/scenes/protopirate_scene_about.c b/scenes/protopirate_scene_about.c index 049797c..5b11011 100644 --- a/scenes/protopirate_scene_about.c +++ b/scenes/protopirate_scene_about.c @@ -1,6 +1,7 @@ // scenes/protopirate_scene_about.c #include "../protopirate_app_i.h" #include "../helpers/protopirate_settings.h" +#include "helpers/protopirate_plugins.h" static const ProtoPirateAboutSceneHostApi protopirate_about_scene_host_api = { .ensure_view_about = protopirate_ensure_view_about, diff --git a/scenes/protopirate_scene_emulate.c b/scenes/protopirate_scene_emulate.c index d97ae3e..052a0c0 100644 --- a/scenes/protopirate_scene_emulate.c +++ b/scenes/protopirate_scene_emulate.c @@ -1,5 +1,6 @@ // scenes/protopirate_scene_emulate.c #include "../protopirate_app_i.h" +#include "helpers/protopirate_plugins.h" #ifdef ENABLE_EMULATE_FEATURE @@ -7,8 +8,6 @@ #include "../helpers/protopirate_storage.h" #include "../protopirate_history.h" -#include - #define TAG "PPSceneEmulate" static bool host_radio_init(void* app) { @@ -53,24 +52,6 @@ static void host_storage_delete_temp(void) { protopirate_storage_delete_temp(); } -static void protopirate_emulate_apply_pending_nav(ProtoPirateApp* app) { - furi_check(app); - - const uint8_t nav = app->emulate_nav_pending; - if(nav == EMULATE_NAV_NONE) { - return; - } - - app->emulate_nav_pending = EMULATE_NAV_NONE; - - if(nav == EMULATE_NAV_POP) { - scene_manager_previous_scene(app->scene_manager); - } else if(nav == EMULATE_NAV_STOP_APP) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } -} - static const ProtoPirateEmulateHostApi protopirate_emulate_host_api = { .radio_init = host_radio_init, .apply_protocol_registry_for_context = host_apply_protocol_registry_for_context, @@ -92,8 +73,6 @@ void protopirate_emulate_context_release(ProtoPirateApp* app) { void protopirate_scene_emulate_on_enter(void* context) { ProtoPirateApp* app = context; - app->emulate_nav_pending = EMULATE_NAV_NONE; - if(!shared_plugin_load(app, ProtoPirateSharedPluginsEmulate, NULL)) { notification_message(app->notifications, &sequence_error); scene_manager_previous_scene(app->scene_manager); @@ -103,18 +82,18 @@ void protopirate_scene_emulate_on_enter(void* context) { } app->emulate_plugin->on_enter(app); - protopirate_emulate_apply_pending_nav(app); } bool protopirate_scene_emulate_on_event(void* context, SceneManagerEvent event) { ProtoPirateApp* app = context; - if(!app->emulate_plugin || !app->emulate_plugin->on_event) { - return false; + bool consumed = false; + if(shared_plugin_handle_navigation_events(app, event)) { + consumed = true; + } else { + if(app->emulate_plugin && app->emulate_plugin->on_event) + consumed = app->emulate_plugin->on_event(app, event); } - - const bool consumed = app->emulate_plugin->on_event(app, event); - protopirate_emulate_apply_pending_nav(app); return consumed; } diff --git a/scenes/protopirate_scene_receiver_config.c b/scenes/protopirate_scene_receiver_config.c index 1da7720..45e3593 100644 --- a/scenes/protopirate_scene_receiver_config.c +++ b/scenes/protopirate_scene_receiver_config.c @@ -2,6 +2,7 @@ #include "protopirate_app_i.h" #include "plugins/protopirate_config_plugin.h" #include "../helpers/protopirate_protocol_plugin_host.h" +#include "helpers/protopirate_plugins.h" static const ProtoPirateConfigSceneHostApi protopirate_config_scene_host_api = { .protopirate_refresh_protocol_registry = protopirate_refresh_protocol_registry, diff --git a/scenes/protopirate_scene_saved_info.c b/scenes/protopirate_scene_saved_info.c index 3bc6297..d9918d0 100644 --- a/scenes/protopirate_scene_saved_info.c +++ b/scenes/protopirate_scene_saved_info.c @@ -3,6 +3,7 @@ #include "plugins/protopirate_saved_info_plugin.h" #include "../helpers/protopirate_psa_bf_host.h" #include "../helpers/protopirate_storage.h" +#include "helpers/protopirate_plugins.h" static const ProtoPirateSavedInfoSceneHostApi protopirate_saved_info_scene_host_api = { .ensure_widget = protopirate_ensure_widget, @@ -30,21 +31,12 @@ bool protopirate_scene_saved_info_on_event(void* context, SceneManagerEvent even ProtoPirateApp* app = ((ProtoPirateApp*)context); //I can't set the next scene from inside the plugin, or it causes crazy crashes. - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == ProtoPirateCustomEventSavedInfoEmulateDelayedStart) { -//Start Emulate Scene. -#ifdef ENABLE_EMULATE_FEATURE - scene_manager_next_scene(app->scene_manager, ProtoPirateSceneEmulate); - return true; -#endif - } else if(event.event == ProtoPirateCustomEventSavedInfoExit) { - scene_manager_previous_scene(((ProtoPirateApp*)context)->scene_manager); - return true; - } + if(shared_plugin_handle_navigation_events(app, event)) { + //Handle Saved Info event in plugin. + return true; + } else { + return app->saved_info_plugin->on_event(app, event); } - - //Handle Saved Info event in plugin. - return app->saved_info_plugin->on_event(app, event); } void protopirate_scene_saved_info_on_exit(void* context) { diff --git a/scenes/protopirate_scene_sub_decode.c b/scenes/protopirate_scene_sub_decode.c index f7c258a..4d439ea 100644 --- a/scenes/protopirate_scene_sub_decode.c +++ b/scenes/protopirate_scene_sub_decode.c @@ -1,6 +1,7 @@ // scenes/protopirate_scene_sub_decode.c #include "../protopirate_app_i.h" #ifdef ENABLE_SUB_DECODE_SCENE +#include "helpers/protopirate_plugins.h" #define STATE_EMULATE 0 #define STATE_BF 1 @@ -12,17 +13,11 @@ void protopirate_scene_sub_decode_on_enter(void* context) { } bool protopirate_scene_sub_decode_on_event(void* context, SceneManagerEvent event) { - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == ProtoPirateCustomEventSubDecodeEmulateDelayedStart) { -#ifdef ENABLE_EMULATE_FEATURE - scene_manager_next_scene( - ((ProtoPirateApp*)context)->scene_manager, ProtoPirateSceneEmulate); -#endif - return true; - } + if(shared_plugin_handle_navigation_events(context, event)) { + return true; + } else { + return protopirate_tool_scene_on_event(context, event); } - - return protopirate_tool_scene_on_event(context, event); } void protopirate_scene_sub_decode_on_exit(void* context) { @@ -523,14 +518,16 @@ void protopirate_scene_sub_decode_on_enter(void* context) { if(!protopirate_ensure_receiver_view(app) || !protopirate_ensure_widget(app)) { notification_message(app->notifications, &sequence_error); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } if(!app->radio_initialized && !protopirate_radio_init(app)) { FURI_LOG_E(TAG, "Failed to initialize radio for sub decode scene"); notification_message(app->notifications, &sequence_error); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -542,7 +539,8 @@ void protopirate_scene_sub_decode_on_enter(void* context) { if(!app->txrx->receiver) { FURI_LOG_E(TAG, "Failed to allocate receiver for sub decode scene"); notification_message(app->notifications, &sequence_error); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -551,7 +549,8 @@ void protopirate_scene_sub_decode_on_enter(void* context) { g_decode_ctx = malloc(sizeof(SubDecodeContext)); if(!g_decode_ctx) { FURI_LOG_E(TAG, "Failed to allocate decode context"); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } memset(g_decode_ctx, 0, sizeof(SubDecodeContext)); @@ -579,7 +578,8 @@ void protopirate_scene_sub_decode_on_enter(void* context) { free(g_decode_ctx); g_decode_ctx = NULL; notification_message(app->notifications, &sequence_error); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } owns_history = true; @@ -607,17 +607,17 @@ void protopirate_scene_sub_decode_on_enter(void* context) { g_decode_ctx->state = DecodeStateOpenFile; protopirate_scene_sub_decode_prepare_receiver_view(app); } else { - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); } } bool protopirate_scene_sub_decode_on_event(void* context, SceneManagerEvent event) { ProtoPirateApp* app = context; - bool consumed = false; SubDecodeContext* ctx = g_decode_ctx; if(!ctx) return false; - + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == ProtoPirateCustomEventSubDecodeUpdate) { // Update receiver view with new history items (when signals are detected during decoding) @@ -786,7 +786,7 @@ bool protopirate_scene_sub_decode_on_event(void* context, SceneManagerEvent even FURI_LOG_I(TAG, "Emulate from sub-decode temp file: %s", app->loaded_file_path); view_dispatcher_send_custom_event( - app->view_dispatcher, ProtoPirateCustomEventSubDecodeEmulateDelayedStart); + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateEmulate); } else { FURI_LOG_E( TAG, "Failed to prepare emulate capture %u", ctx->selected_history_index); @@ -836,8 +836,8 @@ bool protopirate_scene_sub_decode_on_event(void* context, SceneManagerEvent even if(!protopirate_scene_sub_decode_open_browser_for_next_file(app)) { protopirate_history_reset(ctx->history); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_SEARCH_PREVIOUS; - app->tool_scene_nav_target = ProtoPirateSceneStart; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); } consumed = true; } @@ -1420,7 +1420,6 @@ bool protopirate_scene_sub_decode_on_event(void* context, SceneManagerEvent even } // If in history view, back is handled by ViewReceiverBack event } - return consumed; } diff --git a/scenes/protopirate_scene_timing_tuner.c b/scenes/protopirate_scene_timing_tuner.c index 0281ade..8d70ac5 100644 --- a/scenes/protopirate_scene_timing_tuner.c +++ b/scenes/protopirate_scene_timing_tuner.c @@ -1,6 +1,8 @@ // scenes/protopirate_scene_timing_tuner.c #include "../protopirate_app_i.h" + #ifdef ENABLE_TIMING_TUNER_SCENE +#include "helpers/protopirate_plugins.h" #ifndef PROTOPIRATE_TIMING_TUNER_PLUGIN_BUILD @@ -9,7 +11,11 @@ void protopirate_scene_timing_tuner_on_enter(void* context) { } bool protopirate_scene_timing_tuner_on_event(void* context, SceneManagerEvent event) { - return protopirate_tool_scene_on_event(context, event); + if(shared_plugin_handle_navigation_events(context, event)) { + return true; + } else { + return protopirate_tool_scene_on_event(context, event); + } } void protopirate_scene_timing_tuner_on_exit(void* context) { @@ -651,14 +657,16 @@ void protopirate_scene_timing_tuner_on_enter(void* context) { if(!protopirate_ensure_view_about(app)) { notification_message(app->notifications, &sequence_error); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } if(!app->radio_initialized && !protopirate_radio_init(app)) { FURI_LOG_E(TAG, "Failed to initialize radio for timing tuner"); notification_message(app->notifications, &sequence_error); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -670,7 +678,8 @@ void protopirate_scene_timing_tuner_on_enter(void* context) { if(!app->txrx->receiver) { FURI_LOG_E(TAG, "Failed to allocate receiver for timing tuner"); notification_message(app->notifications, &sequence_error); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } @@ -678,7 +687,8 @@ void protopirate_scene_timing_tuner_on_enter(void* context) { if(!g_timing_ctx) { FURI_LOG_E(TAG, "Failed to allocate timing tuner context"); notification_message(app->notifications, &sequence_error); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } memset(g_timing_ctx, 0, sizeof(TimingTunerContext)); @@ -706,7 +716,8 @@ void protopirate_scene_timing_tuner_on_enter(void* context) { view_set_input_callback(app->view_about, NULL); timing_tuner_context_free(); notification_message(app->notifications, &sequence_error); - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); return; } // Set up worker callbacks @@ -738,19 +749,20 @@ void protopirate_scene_timing_tuner_on_enter(void* context) { bool protopirate_scene_timing_tuner_on_event(void* context, SceneManagerEvent event) { ProtoPirateApp* app = context; - bool consumed = false; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == 0) { - app->tool_scene_nav_pending = TOOL_SCENE_NAV_POP; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateBack); consumed = true; } else if(event.event == 1) { if(g_timing_ctx && g_timing_ctx->is_receiving) { protopirate_rx_end(app); g_timing_ctx->is_receiving = false; } - app->tool_scene_nav_pending = TOOL_SCENE_NAV_NEXT; - app->tool_scene_nav_target = ProtoPirateSceneReceiverConfig; + view_dispatcher_send_custom_event( + app->view_dispatcher, ProtoPirateCustomEventPluginNavigateConfig); consumed = true; } } else if(event.type == SceneManagerEventTypeTick) { From 71f7cb93a8363df29e3470ecf2c4a4469a198f87 Mon Sep 17 00:00:00 2001 From: Leeroy <135471162+LeeroysHub@users.noreply.github.com> Date: Mon, 28 Sep 2026 13:02:37 +1000 Subject: [PATCH 2/4] REFACTOR: Fix Encapsulation issues in plugins. * Removed dependencies on App Struct in Plugin Module * Cleaned up headers * Only check navigation events if plugin doesnt handle the event --- helpers/protopirate_plugins.c | 119 +++++------------- helpers/protopirate_plugins.h | 38 +++++- helpers/protopirate_protocol_plugin_host.c | 17 ++- helpers/protopirate_psa_bf_host.c | 14 ++- helpers/protopirate_tool_scene_host.c | 26 +++- protocols/plugins/protopirate_am_plugin.c | 1 + protocols/plugins/protopirate_am_vag_plugin.c | 1 + protocols/plugins/protopirate_fm_f4_plugin.c | 1 + .../plugins/protopirate_fm_honda1_plugin.c | 1 + protocols/plugins/protopirate_fm_plugin.c | 1 + .../plugins/protopirate_tx_protocol_plugin.c | 1 + protocols/protopirate_protocol_plugins.h | 1 - protopirate_app.c | 21 ++-- protopirate_app_i.h | 11 +- scenes/plugins/protopirate_config_plugin.c | 5 +- scenes/plugins/protopirate_config_plugin.h | 1 + scenes/plugins/protopirate_emulate_plugin.h | 1 - scenes/plugins/protopirate_psa_bf_plugin.c | 2 + scenes/plugins/protopirate_psa_bf_plugin.h | 1 - .../plugins/protopirate_tool_scene_plugin.h | 1 - scenes/protopirate_scene_about.c | 10 +- scenes/protopirate_scene_emulate.c | 17 ++- scenes/protopirate_scene_receiver_config.c | 11 +- scenes/protopirate_scene_saved_info.c | 18 +-- scenes/protopirate_scene_start.c | 2 - scenes/protopirate_scene_sub_decode.c | 7 +- scenes/protopirate_scene_timing_tuner.c | 8 +- 27 files changed, 178 insertions(+), 159 deletions(-) diff --git a/helpers/protopirate_plugins.c b/helpers/protopirate_plugins.c index a01f6ba..5735fb0 100644 --- a/helpers/protopirate_plugins.c +++ b/helpers/protopirate_plugins.c @@ -1,6 +1,8 @@ #include "protopirate_plugins.h" #include +#define TAG "PPPlugins" + // ----------------------------------------------------------------------------- // Plugin load / unload // ----------------------------------------------------------------------------- @@ -63,140 +65,81 @@ const FlipperAppPluginDescriptor* load_plugin_fal( } } -void shared_plugin_unload(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type) { - //Clear the invalid reference to the plugin. - FlipperApplication** fal_needs_free = NULL; - switch(plugin_type) { - case ProtoPirateSharedPluginsConfig: { - fal_needs_free = &app->plugin_flipper_application; - app->config_plugin = NULL; - break; - } - case ProtoPirateSharedPluginsSavedInfo: { - fal_needs_free = &app->plugin_flipper_application; - app->saved_info_plugin = NULL; - break; - } - case ProtoPirateSharedPluginsAbout: { - fal_needs_free = &app->plugin_flipper_application; - app->about_plugin = NULL; - break; - } -#ifdef ENABLE_EMULATE_FEATURE - case ProtoPirateSharedPluginsEmulate: { - fal_needs_free = &app->plugin_flipper_application; - app->emulate_plugin = NULL; - break; - } -#endif - case ProtoPirateSharedPluginsToolScene: - case ProtoPirateSharedPluginsSubDecode: -#ifdef ENABLE_TIMING_TUNER_SCENE - case ProtoPirateSharedPluginsTimingTuner: -#endif - { - fal_needs_free = &app->tool_scene_plugin_flipper_application; - app->tool_scene_plugin = NULL; - break; - } - case ProtoPirateSharedPluginsPSABruteforce: { - fal_needs_free = &app->psa_bf_plugin_flipper_application; - app->psa_bf_plugin = NULL; - break; - } - case ProtoPirateSharedPluginsTXRX: { - fal_needs_free = &app->txrx->protocol_plugin_flipper_application; - app->txrx->protocol_plugin = NULL; - break; - } - default: - return; +void shared_plugin_unload(void** flipper_application_pointer, const void** plugin_pointer) { + //Free the flipper application. + if(*flipper_application_pointer) { + flipper_application_free(*flipper_application_pointer); + *flipper_application_pointer = NULL; } - //Free the flipper application. - if(*fal_needs_free) { - flipper_application_free(*fal_needs_free); - *fal_needs_free = NULL; + //Free the pointer. + if(*plugin_pointer) { + *plugin_pointer = NULL; } } bool shared_plugin_load( - ProtoPirateApp* app, + void** flipper_application_pointer, + const void** plugin_pointer, ProtoPirateSharedPlugin plugin_type, const char* txrx_path) { - //Get the APPID and API VERSION for the Plugin we are loading. const char* application_id = NULL; const char* plugin_path = NULL; uint32_t api_version = 0; - FlipperApplication** fal_needs_alloc = NULL; + + if(*plugin_pointer) return true; switch(plugin_type) { case ProtoPirateSharedPluginsConfig: { - if(app->config_plugin) return true; application_id = PROTOPIRATE_CONFIG_PLUGIN_APP_ID; api_version = PROTOPIRATE_CONFIG_PLUGIN_API_VERSION; plugin_path = CONFIG_PLUGIN_PATH; - fal_needs_alloc = &app->plugin_flipper_application; break; } case ProtoPirateSharedPluginsSavedInfo: { - if(app->saved_info_plugin) return true; application_id = PROTOPIRATE_SAVED_INFO_PLUGIN_APP_ID; api_version = PROTOPIRATE_SAVED_INFO_PLUGIN_API_VERSION; plugin_path = SAVED_INFO_PLUGIN_PATH; - fal_needs_alloc = &app->plugin_flipper_application; break; } case ProtoPirateSharedPluginsAbout: { - if(app->about_plugin) return true; application_id = PROTOPIRATE_ABOUT_PLUGIN_APP_ID; api_version = PROTOPIRATE_ABOUT_PLUGIN_API_VERSION; plugin_path = ABOUT_PLUGIN_PATH; - fal_needs_alloc = &app->plugin_flipper_application; break; } #ifdef ENABLE_EMULATE_FEATURE case ProtoPirateSharedPluginsEmulate: { - if(app->emulate_plugin) return true; application_id = PROTOPIRATE_EMULATE_PLUGIN_APP_ID; api_version = PROTOPIRATE_EMULATE_PLUGIN_API_VERSION; plugin_path = EMULATE_PLUGIN_PATH; - fal_needs_alloc = &app->plugin_flipper_application; break; } #endif case ProtoPirateSharedPluginsSubDecode: { - if(app->tool_scene_plugin) return true; application_id = PROTOPIRATE_TOOL_SCENE_PLUGIN_APP_ID; api_version = PROTOPIRATE_TOOL_SCENE_PLUGIN_API_VERSION; plugin_path = SUB_DECODE_PLUGIN_PATH; - fal_needs_alloc = &app->tool_scene_plugin_flipper_application; break; } #ifdef ENABLE_TIMING_TUNER_SCENE case ProtoPirateSharedPluginsTimingTuner: { - if(app->tool_scene_plugin) return true; application_id = PROTOPIRATE_TOOL_SCENE_PLUGIN_APP_ID; api_version = PROTOPIRATE_TOOL_SCENE_PLUGIN_API_VERSION; plugin_path = TIMING_TUNER_PLUGIN_PATH; - fal_needs_alloc = &app->tool_scene_plugin_flipper_application; break; } #endif case ProtoPirateSharedPluginsPSABruteforce: { - if(app->psa_bf_plugin) return true; application_id = PROTOPIRATE_PSA_BF_PLUGIN_APP_ID; api_version = PROTOPIRATE_PSA_BF_PLUGIN_API_VERSION; plugin_path = PSA_BF_PLUGIN_PATH; - fal_needs_alloc = &app->psa_bf_plugin_flipper_application; break; } case ProtoPirateSharedPluginsTXRX: { - if(app->txrx->protocol_plugin) return true; application_id = PROTOPIRATE_PROTOCOL_PLUGIN_APP_ID; api_version = PROTOPIRATE_PROTOCOL_PLUGIN_API_VERSION; plugin_path = txrx_path; - fal_needs_alloc = &app->txrx->protocol_plugin_flipper_application; break; } default: @@ -219,7 +162,7 @@ bool shared_plugin_load( if(!plugin_config || !plugin_config->on_enter) { FURI_LOG_E(TAG, "Config plugin entry point is invalid"); } else { - app->config_plugin = plugin_config; + *plugin_pointer = plugin_config; return_value = true; } } else if(plugin_type == ProtoPirateSharedPluginsSavedInfo) { @@ -227,7 +170,7 @@ bool shared_plugin_load( if(!plugin_saved_info || !plugin_saved_info->on_enter) { FURI_LOG_E(TAG, "Saved Info plugin entry point is invalid"); } else { - app->saved_info_plugin = plugin_saved_info; + *plugin_pointer = plugin_saved_info; return_value = true; } } else if(plugin_type == ProtoPirateSharedPluginsAbout) { @@ -235,7 +178,7 @@ bool shared_plugin_load( if(!plugin_about || !plugin_about->on_enter) { FURI_LOG_E(TAG, "About plugin entry point is invalid"); } else { - app->about_plugin = plugin_about; + *plugin_pointer = plugin_about; return_value = true; } } @@ -245,7 +188,7 @@ bool shared_plugin_load( if(!plugin_emulate || !plugin_emulate->on_enter) { FURI_LOG_E(TAG, "Emulate plugin entry point is invalid"); } else { - app->emulate_plugin = plugin_emulate; + *plugin_pointer = plugin_emulate; return_value = true; } } @@ -260,7 +203,7 @@ bool shared_plugin_load( if(!plugin_tool_scene || !plugin_tool_scene->on_enter) { FURI_LOG_E(TAG, "Tool Scene plugin entry point is invalid"); } else { - app->tool_scene_plugin = plugin_tool_scene; + *plugin_pointer = plugin_tool_scene; return_value = true; } } else if(plugin_type == ProtoPirateSharedPluginsPSABruteforce) { @@ -268,7 +211,7 @@ bool shared_plugin_load( if(!plugin_psa_bf || !plugin_psa_bf->needs_bruteforce) { FURI_LOG_E(TAG, "PSA plugin entry needs_bruteforce is invalid"); } else { - app->psa_bf_plugin = plugin_psa_bf; + *plugin_pointer = plugin_psa_bf; return_value = true; } } else if(plugin_type == ProtoPirateSharedPluginsTXRX) { @@ -276,7 +219,7 @@ bool shared_plugin_load( if(!plugin_txrx || !plugin_txrx->registry) { FURI_LOG_E(TAG, "Protocol plugin registry entry is invalid"); } else { - app->txrx->protocol_plugin = plugin_txrx; + *plugin_pointer = plugin_txrx; return_value = true; } } @@ -284,30 +227,30 @@ bool shared_plugin_load( } while(false); //Free the plugin if there was an error, otherwise we are done! - if(fal_needs_alloc) *fal_needs_alloc = fal_app; + *flipper_application_pointer = fal_app; furi_record_close(RECORD_STORAGE); return return_value; } - -bool shared_plugin_handle_navigation_events(void* context, SceneManagerEvent event) { - ProtoPirateApp* app = (ProtoPirateApp*)context; - +bool shared_plugin_handle_navigation_events( + SceneManager* scene_manager, + ViewDispatcher* view_dispatcher, + SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == ProtoPirateCustomEventPluginNavigateEmulate) { #ifdef ENABLE_EMULATE_FEATURE - scene_manager_next_scene(app->scene_manager, ProtoPirateSceneEmulate); + scene_manager_next_scene(scene_manager, ProtoPirateSceneEmulate); #endif return true; } if(event.event == ProtoPirateCustomEventPluginNavigateConfig) { - scene_manager_next_scene(app->scene_manager, ProtoPirateSceneReceiverConfig); + scene_manager_next_scene(scene_manager, ProtoPirateSceneReceiverConfig); return true; } else if(event.event == ProtoPirateCustomEventPluginNavigateBack) { - scene_manager_previous_scene(app->scene_manager); + scene_manager_previous_scene(scene_manager); return true; } else if(event.event == ProtoPirateCustomEventPluginNavigateStopApp) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); + scene_manager_stop(scene_manager); + view_dispatcher_stop(view_dispatcher); return true; } } diff --git a/helpers/protopirate_plugins.h b/helpers/protopirate_plugins.h index 3cca6c7..cabf712 100644 --- a/helpers/protopirate_plugins.h +++ b/helpers/protopirate_plugins.h @@ -1,4 +1,30 @@ -#include "../protopirate_app_i.h" +#pragma once +#include "../defines.h" + +#include +#include +#include + +#ifdef ENABLE_EMULATE_FEATURE +#include "scenes/plugins/protopirate_emulate_plugin.h" +#endif +#include "scenes/plugins/protopirate_config_plugin.h" +#include "scenes/plugins/protopirate_saved_info_plugin.h" +#include "scenes/plugins/protopirate_about_plugin.h" +#include "scenes/plugins/protopirate_psa_bf_plugin.h" +#include "scenes/plugins/protopirate_tool_scene_plugin.h" + +#define CONFIG_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_config.fal") +#define SAVED_INFO_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_saved_info.fal") +#define ABOUT_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_about.fal") +#ifdef ENABLE_EMULATE_FEATURE +#define EMULATE_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_emulate.fal") +#endif +#define SUB_DECODE_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_sub_decode.fal") +#ifdef ENABLE_TIMING_TUNER_SCENE +#define TIMING_TUNER_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_timing_tuner.fal") +#endif +#define PSA_BF_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_bf.fal") typedef enum ProtoPirateSharedPlugin { ProtoPirateSharedPluginsConfig, @@ -17,8 +43,12 @@ typedef enum ProtoPirateSharedPlugin { } ProtoPirateSharedPlugin; bool shared_plugin_load( - ProtoPirateApp* app, + void** flipper_application_pointer, + const void** plugin_pointer, ProtoPirateSharedPlugin plugin_type, const char* txrx_path); -void shared_plugin_unload(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type); -bool shared_plugin_handle_navigation_events(void* context, SceneManagerEvent event); +void shared_plugin_unload(void** flipper_application_pointer, const void** plugin_pointer); +bool shared_plugin_handle_navigation_events( + SceneManager* scene_manager, + ViewDispatcher* view_dispatcher, + SceneManagerEvent event); diff --git a/helpers/protopirate_protocol_plugin_host.c b/helpers/protopirate_protocol_plugin_host.c index f9228c5..6f941c4 100644 --- a/helpers/protopirate_protocol_plugin_host.c +++ b/helpers/protopirate_protocol_plugin_host.c @@ -1,7 +1,6 @@ #include "../protopirate_app_i.h" #include "protopirate_txrx.h" #include "../protocols/protocol_items.h" -#include "helpers/protopirate_plugins.h" #include #include @@ -61,7 +60,9 @@ void protopirate_unload_protocol_plugin(ProtoPirateApp* app) { app->txrx->protocol_plugin->release(); } - shared_plugin_unload(app, ProtoPirateSharedPluginsTXRX); + shared_plugin_unload( + (void**)&app->txrx->protocol_plugin_flipper_application, + (const void**)&app->txrx->protocol_plugin); } static bool protopirate_ensure_protocol_registry_plugin( @@ -91,7 +92,11 @@ static bool protopirate_ensure_protocol_registry_plugin( } const char* plugin_path = protopirate_get_registry_plugin_path(route); - shared_plugin_load(app, ProtoPirateSharedPluginsTXRX, plugin_path); + shared_plugin_load( + (void**)&app->txrx->protocol_plugin_flipper_application, + (const void**)&app->txrx->protocol_plugin, + ProtoPirateSharedPluginsTXRX, + plugin_path); if(app->txrx->protocol_plugin->kind != ProtoPirateProtocolPluginKindRx) { FURI_LOG_E(TAG, "Protocol plugin kind mismatch for RX route"); @@ -157,7 +162,11 @@ static bool protopirate_ensure_tx_protocol_plugin( protopirate_unload_protocol_plugin(app); } - shared_plugin_load(app, ProtoPirateSharedPluginsTXRX, plugin_path); + shared_plugin_load( + (void**)&app->txrx->protocol_plugin_flipper_application, + (const void**)&app->txrx->protocol_plugin, + ProtoPirateSharedPluginsTXRX, + plugin_path); const SubGhzProtocol* tx_protocol = app->txrx->protocol_plugin->registry->items[0]; if(!tx_protocol || !tx_protocol->encoder || !tx_protocol->encoder->alloc || diff --git a/helpers/protopirate_psa_bf_host.c b/helpers/protopirate_psa_bf_host.c index 836ba59..84c7984 100644 --- a/helpers/protopirate_psa_bf_host.c +++ b/helpers/protopirate_psa_bf_host.c @@ -3,7 +3,6 @@ #include "../protopirate_history.h" #include "../protocols/protocols_common.h" #include "../scenes/plugins/protopirate_psa_bf_plugin.h" -#include "helpers/protopirate_plugins.h" #include @@ -114,7 +113,11 @@ static const ProtoPiratePsaBfHostApi protopirate_psa_bf_host_api = { }; bool protopirate_psa_bf_plugin_ensure_loaded(ProtoPirateApp* app) { - if(shared_plugin_load(app, ProtoPirateSharedPluginsPSABruteforce, NULL)) { + if(shared_plugin_load( + (void**)&app->psa_bf_plugin_flipper_application, + (const void**)&app->psa_bf_plugin, + ProtoPirateSharedPluginsPSABruteforce, + NULL)) { app->psa_bf_plugin->set_host_api(&protopirate_psa_bf_host_api); return true; } else { @@ -127,7 +130,9 @@ void protopirate_psa_bf_plugin_unload_if_idle(ProtoPirateApp* app) { app->psa_bf_plugin->is_running(app)) { return; } - shared_plugin_unload(app, ProtoPirateSharedPluginsPSABruteforce); + + shared_plugin_unload( + (void**)&app->psa_bf_plugin_flipper_application, (const void**)&app->psa_bf_plugin); } void protopirate_psa_bf_context_release(ProtoPirateApp* app) { @@ -135,5 +140,6 @@ void protopirate_psa_bf_context_release(ProtoPirateApp* app) { if(app->psa_bf_plugin && app->psa_bf_plugin->context_release) { app->psa_bf_plugin->context_release(app); } - shared_plugin_unload(app, ProtoPirateSharedPluginsPSABruteforce); + shared_plugin_unload( + (void**)&app->psa_bf_plugin_flipper_application, (const void**)&app->psa_bf_plugin); } diff --git a/helpers/protopirate_tool_scene_host.c b/helpers/protopirate_tool_scene_host.c index 52b53ba..fea9a32 100644 --- a/helpers/protopirate_tool_scene_host.c +++ b/helpers/protopirate_tool_scene_host.c @@ -1,7 +1,6 @@ #include "../protopirate_app_i.h" #include "protopirate_psa_bf_host.h" #include "radio_device_loader.h" -#include "helpers/protopirate_plugins.h" #include @@ -126,14 +125,25 @@ static bool protopirate_tool_scene_plugin_ensure_loaded( if(app->tool_scene_plugin->release) { app->tool_scene_plugin->release(app); } - shared_plugin_unload(app, ProtoPirateSharedPluginsToolScene); + + shared_plugin_unload( + (void**)&app->tool_scene_plugin_flipper_application, + (const void**)&app->tool_scene_plugin); } if(kind == ProtoPirateToolScenePluginKindSubDecode) - shared_plugin_load(app, ProtoPirateSharedPluginsSubDecode, NULL); + shared_plugin_load( + (void**)&app->tool_scene_plugin_flipper_application, + (const void**)&app->tool_scene_plugin, + ProtoPirateSharedPluginsSubDecode, + NULL); #ifdef ENABLE_TIMING_TUNER_SCENE else if(kind == ProtoPirateToolScenePluginKindTimingTuner) - shared_plugin_load(app, ProtoPirateSharedPluginsTimingTuner, NULL); + shared_plugin_load( + (void**)&app->tool_scene_plugin_flipper_application, + (const void**)&app->tool_scene_plugin, + ProtoPirateSharedPluginsTimingTuner, + NULL); #endif app->tool_scene_plugin_kind = kind; @@ -178,7 +188,9 @@ void protopirate_tool_scene_on_exit(void* context) { } } - shared_plugin_unload(app, ProtoPirateSharedPluginsToolScene); + shared_plugin_unload( + (void**)&app->tool_scene_plugin_flipper_application, + (const void**)&app->tool_scene_plugin); } void protopirate_tool_scene_plugin_release(ProtoPirateApp* app) { @@ -187,5 +199,7 @@ void protopirate_tool_scene_plugin_release(ProtoPirateApp* app) { if(app->tool_scene_plugin && app->tool_scene_plugin->release) { app->tool_scene_plugin->release(app); } - shared_plugin_unload(app, ProtoPirateSharedPluginsToolScene); + shared_plugin_unload( + (void**)&app->tool_scene_plugin_flipper_application, + (const void**)&app->tool_scene_plugin); } diff --git a/protocols/plugins/protopirate_am_plugin.c b/protocols/plugins/protopirate_am_plugin.c index cc71995..5ea0bbb 100644 --- a/protocols/plugins/protopirate_am_plugin.c +++ b/protocols/plugins/protopirate_am_plugin.c @@ -15,6 +15,7 @@ #include "../subaru.h" #include "../star_line.h" #include "../honda_v1.h" +#include static const SubGhzProtocol* const protopirate_protocol_registry_am_items[] = { &chrysler_protocol_v0, diff --git a/protocols/plugins/protopirate_am_vag_plugin.c b/protocols/plugins/protopirate_am_vag_plugin.c index 752360a..3f8b8fa 100644 --- a/protocols/plugins/protopirate_am_vag_plugin.c +++ b/protocols/plugins/protopirate_am_vag_plugin.c @@ -1,6 +1,7 @@ #include "../protopirate_protocol_plugins.h" #include "../protocols_common.h" #include "../vag.h" +#include static const SubGhzProtocol* const protopirate_protocol_registry_am_vag_items[] = { &vag_protocol, diff --git a/protocols/plugins/protopirate_fm_f4_plugin.c b/protocols/plugins/protopirate_fm_f4_plugin.c index b3ee0fa..8799a92 100644 --- a/protocols/plugins/protopirate_fm_f4_plugin.c +++ b/protocols/plugins/protopirate_fm_f4_plugin.c @@ -4,6 +4,7 @@ #include "../ford_v2.h" #include "../ford_v3.h" #include "../honda_v2.h" +#include static const SubGhzProtocol* const protopirate_protocol_registry_fm_f4_items[] = { &ford_protocol_v1, diff --git a/protocols/plugins/protopirate_fm_honda1_plugin.c b/protocols/plugins/protopirate_fm_honda1_plugin.c index 9bfdb4c..9560dae 100644 --- a/protocols/plugins/protopirate_fm_honda1_plugin.c +++ b/protocols/plugins/protopirate_fm_honda1_plugin.c @@ -1,6 +1,7 @@ #include "../protopirate_protocol_plugins.h" #include "../protocols_common.h" #include "../honda_static.h" +#include static const SubGhzProtocol* const protopirate_protocol_registry_fm_honda1_items[] = { &honda_static_protocol, diff --git a/protocols/plugins/protopirate_fm_plugin.c b/protocols/plugins/protopirate_fm_plugin.c index 8cba9d5..c86646d 100644 --- a/protocols/plugins/protopirate_fm_plugin.c +++ b/protocols/plugins/protopirate_fm_plugin.c @@ -9,6 +9,7 @@ #include "../mazda_v0.h" #include "../psa.h" #include "../renault_v1.h" +#include static const SubGhzProtocol* const protopirate_protocol_registry_fm_items[] = { &subghz_protocol_scher_khan, diff --git a/protocols/plugins/protopirate_tx_protocol_plugin.c b/protocols/plugins/protopirate_tx_protocol_plugin.c index 895fd08..e2793e1 100644 --- a/protocols/plugins/protopirate_tx_protocol_plugin.c +++ b/protocols/plugins/protopirate_tx_protocol_plugin.c @@ -1,5 +1,6 @@ #include "../protopirate_protocol_plugins.h" #include "../protocols_common.h" +#include #ifndef PP_TX_PROTOCOL_HEADER #error "PP_TX_PROTOCOL_HEADER must be defined for TX protocol plugins" diff --git a/protocols/protopirate_protocol_plugins.h b/protocols/protopirate_protocol_plugins.h index 60fb3c0..c326b5d 100644 --- a/protocols/protopirate_protocol_plugins.h +++ b/protocols/protopirate_protocol_plugins.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include "protocol_items.h" diff --git a/protopirate_app.c b/protopirate_app.c index a73d9cf..e603307 100644 --- a/protopirate_app.c +++ b/protopirate_app.c @@ -164,9 +164,15 @@ ProtoPirateApp* protopirate_app_alloc() { app->psa_bf_plugin = NULL; app->tool_scene_plugin_flipper_application = NULL; app->tool_scene_plugin = NULL; + app->variable_item_list = NULL; //Load the models database, get the count of the models for the list. - if(shared_plugin_load(app, ProtoPirateSharedPluginsConfig, NULL) && app->config_plugin) { + if(shared_plugin_load( + (void**)&app->plugin_flipper_application, + (const void**)&app->config_plugin, + ProtoPirateSharedPluginsConfig, + NULL) && + app->config_plugin) { app->car_models_count = app->config_plugin->car_model_get_count(); } else { notification_message(app->notifications, &sequence_error); @@ -176,7 +182,6 @@ ProtoPirateApp* protopirate_app_alloc() { app->selected_model->name = NULL; app->selected_model->preset = NULL; // important initialization app->selected_model->index = 0; // optional but clean - app->variable_item_list = NULL; //Grab selected car model. if(app->config_plugin) { @@ -203,7 +208,8 @@ ProtoPirateApp* protopirate_app_alloc() { } //Kill the config plugin now. - shared_plugin_unload(app, ProtoPirateSharedPluginsConfig); + shared_plugin_unload( + (void**)&app->plugin_flipper_application, (const void**)&app->config_plugin); } else { //Preset set in Config. protopirate_preset_init(app, preset_name, frequency, preset_data, preset_data_size); @@ -358,15 +364,14 @@ void protopirate_app_free(ProtoPirateApp* app) { } int32_t protopirate_app(char* p) { - //Stop charging while running the app. - furi_hal_power_suppress_charge_enter(); - ProtoPirateApp* protopirate_app = protopirate_app_alloc(); if(!protopirate_app) { - furi_hal_power_suppress_charge_exit(); return -1; } + //Stop charging while running the app. + furi_hal_power_suppress_charge_enter(); + // Handle Command line PSF that may have been passed to us bool load_saved = (p && strlen(p)); if(load_saved) { @@ -396,6 +401,8 @@ int32_t protopirate_app(char* p) { //Free the App and allow chargin again. protopirate_app_free(protopirate_app); + + //Restore Charging State furi_hal_power_suppress_charge_exit(); return 0; } diff --git a/protopirate_app_i.h b/protopirate_app_i.h index 6f1fefd..f342f23 100644 --- a/protopirate_app_i.h +++ b/protopirate_app_i.h @@ -35,6 +35,7 @@ #include "scenes/plugins/protopirate_about_plugin.h" #include "scenes/plugins/protopirate_psa_bf_plugin.h" #include "scenes/plugins/protopirate_tool_scene_plugin.h" +#include "helpers/protopirate_plugins.h" #include "helpers/protopirate_views.h" #include "helpers/protopirate_radio.h" #include "helpers/protopirate_protocol_plugin_host.h" @@ -42,16 +43,6 @@ #include "helpers/protopirate_models.h" #include "helpers/protopirate_settings.h" -#define CONFIG_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_config.fal") -#define SAVED_INFO_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_saved_info.fal") -#define ABOUT_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_about.fal") -#define EMULATE_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_emulate.fal") -#define SUB_DECODE_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_sub_decode.fal") -#ifdef ENABLE_TIMING_TUNER_SCENE -#define TIMING_TUNER_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_timing_tuner.fal") -#endif -#define PSA_BF_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_bf.fal") - #define PROTOPIRATE_KEYSTORE_DIR_NAME APP_ASSETS_PATH("encrypted") typedef struct VariableItemList VariableItemList; diff --git a/scenes/plugins/protopirate_config_plugin.c b/scenes/plugins/protopirate_config_plugin.c index 6151237..741015d 100644 --- a/scenes/plugins/protopirate_config_plugin.c +++ b/scenes/plugins/protopirate_config_plugin.c @@ -131,7 +131,6 @@ static void protopirate_scene_receiver_config_set_hopping_running(VariableItem* app->scene_manager, ProtoPirateSceneReceiverConfig), subghz_setting_get_frequency_default_index(app->setting)); } - app->txrx->hopper_state = hopping_value[index]; } @@ -279,13 +278,13 @@ static uint8_t protopirate_scene_receiver_config_hopper_value_index( ProtoPirateApp* app = context; if(value == values[0]) { - return 0; + return false; } else { variable_item_set_current_value_text( (VariableItem*)scene_manager_get_scene_state( app->scene_manager, ProtoPirateSceneReceiverConfig), " -----"); - return 1; + return true; } } diff --git a/scenes/plugins/protopirate_config_plugin.h b/scenes/plugins/protopirate_config_plugin.h index 4fa028f..ab00f21 100644 --- a/scenes/plugins/protopirate_config_plugin.h +++ b/scenes/plugins/protopirate_config_plugin.h @@ -2,6 +2,7 @@ #include "../../protopirate_app_i.h" #include "helpers/protopirate_models.h" #include + #include "helpers/variable_item_list.h" #define PROTOPIRATE_CONFIG_PLUGIN_APP_ID "pp_config" diff --git a/scenes/plugins/protopirate_emulate_plugin.h b/scenes/plugins/protopirate_emulate_plugin.h index a5d4309..b99a038 100644 --- a/scenes/plugins/protopirate_emulate_plugin.h +++ b/scenes/plugins/protopirate_emulate_plugin.h @@ -3,7 +3,6 @@ #include #include #include -#include #include #define PROTOPIRATE_EMULATE_PLUGIN_APP_ID "pp_emulate" diff --git a/scenes/plugins/protopirate_psa_bf_plugin.c b/scenes/plugins/protopirate_psa_bf_plugin.c index 98a9fa1..5374cf2 100644 --- a/scenes/plugins/protopirate_psa_bf_plugin.c +++ b/scenes/plugins/protopirate_psa_bf_plugin.c @@ -8,6 +8,8 @@ #include #include +#include + #ifdef PROTOPIRATE_PSA_BF_PLUGIN_BUILD #include "pp_bf_icons.h" #else diff --git a/scenes/plugins/protopirate_psa_bf_plugin.h b/scenes/plugins/protopirate_psa_bf_plugin.h index e8ae1e9..91fae80 100644 --- a/scenes/plugins/protopirate_psa_bf_plugin.h +++ b/scenes/plugins/protopirate_psa_bf_plugin.h @@ -2,7 +2,6 @@ #include #include -#include #include #include diff --git a/scenes/plugins/protopirate_tool_scene_plugin.h b/scenes/plugins/protopirate_tool_scene_plugin.h index b70a43a..5b49bb1 100644 --- a/scenes/plugins/protopirate_tool_scene_plugin.h +++ b/scenes/plugins/protopirate_tool_scene_plugin.h @@ -5,7 +5,6 @@ #include #include -#include #include #include "../../defines.h" diff --git a/scenes/protopirate_scene_about.c b/scenes/protopirate_scene_about.c index 5b11011..10240a0 100644 --- a/scenes/protopirate_scene_about.c +++ b/scenes/protopirate_scene_about.c @@ -1,7 +1,6 @@ // scenes/protopirate_scene_about.c #include "../protopirate_app_i.h" #include "../helpers/protopirate_settings.h" -#include "helpers/protopirate_plugins.h" static const ProtoPirateAboutSceneHostApi protopirate_about_scene_host_api = { .ensure_view_about = protopirate_ensure_view_about, @@ -13,7 +12,11 @@ static const ProtoPirateAboutSceneHostApi protopirate_about_scene_host_api = { void protopirate_scene_about_on_enter(void* context) { ProtoPirateApp* app = context; - if(!shared_plugin_load(app, ProtoPirateSharedPluginsAbout, NULL)) { + if(!shared_plugin_load( + (void**)&app->plugin_flipper_application, + (const void**)&app->about_plugin, + ProtoPirateSharedPluginsAbout, + NULL)) { notification_message(app->notifications, &sequence_error); scene_manager_previous_scene(app->scene_manager); return; @@ -41,5 +44,6 @@ void protopirate_scene_about_on_exit(void* context) { view_set_draw_callback(app->view_about, NULL); view_set_input_callback(app->view_about, NULL); view_set_context(app->view_about, NULL); - shared_plugin_unload(app, ProtoPirateSharedPluginsAbout); + shared_plugin_unload( + (void**)&app->plugin_flipper_application, (const void**)&app->about_plugin); } diff --git a/scenes/protopirate_scene_emulate.c b/scenes/protopirate_scene_emulate.c index 052a0c0..5ffd1ac 100644 --- a/scenes/protopirate_scene_emulate.c +++ b/scenes/protopirate_scene_emulate.c @@ -1,6 +1,5 @@ // scenes/protopirate_scene_emulate.c #include "../protopirate_app_i.h" -#include "helpers/protopirate_plugins.h" #ifdef ENABLE_EMULATE_FEATURE @@ -67,13 +66,18 @@ void protopirate_emulate_context_release(ProtoPirateApp* app) { if(app->emulate_plugin && app->emulate_plugin->context_release) { app->emulate_plugin->context_release(app); } - shared_plugin_unload(app, ProtoPirateSharedPluginsEmulate); + shared_plugin_unload( + (void**)&app->plugin_flipper_application, (const void**)&app->emulate_plugin); } void protopirate_scene_emulate_on_enter(void* context) { ProtoPirateApp* app = context; - if(!shared_plugin_load(app, ProtoPirateSharedPluginsEmulate, NULL)) { + if(!shared_plugin_load( + (void**)&app->plugin_flipper_application, + (const void**)&app->emulate_plugin, + ProtoPirateSharedPluginsEmulate, + NULL)) { notification_message(app->notifications, &sequence_error); scene_manager_previous_scene(app->scene_manager); return; @@ -88,11 +92,12 @@ bool protopirate_scene_emulate_on_event(void* context, SceneManagerEvent event) ProtoPirateApp* app = context; bool consumed = false; - if(shared_plugin_handle_navigation_events(app, event)) { + //Handle Saved event in plugin. + if(app->emulate_plugin && app->emulate_plugin->on_event(app, event)) { consumed = true; } else { - if(app->emulate_plugin && app->emulate_plugin->on_event) - consumed = app->emulate_plugin->on_event(app, event); + consumed = shared_plugin_handle_navigation_events( + app->scene_manager, app->view_dispatcher, event); } return consumed; } diff --git a/scenes/protopirate_scene_receiver_config.c b/scenes/protopirate_scene_receiver_config.c index 45e3593..627914b 100644 --- a/scenes/protopirate_scene_receiver_config.c +++ b/scenes/protopirate_scene_receiver_config.c @@ -2,7 +2,6 @@ #include "protopirate_app_i.h" #include "plugins/protopirate_config_plugin.h" #include "../helpers/protopirate_protocol_plugin_host.h" -#include "helpers/protopirate_plugins.h" static const ProtoPirateConfigSceneHostApi protopirate_config_scene_host_api = { .protopirate_refresh_protocol_registry = protopirate_refresh_protocol_registry, @@ -12,7 +11,11 @@ static const ProtoPirateConfigSceneHostApi protopirate_config_scene_host_api = { void protopirate_scene_receiver_config_on_enter(void* context) { ProtoPirateApp* app = context; - if(!shared_plugin_load(app, ProtoPirateSharedPluginsConfig, NULL)) { + if(!shared_plugin_load( + (void**)&app->plugin_flipper_application, + (const void**)&app->config_plugin, + ProtoPirateSharedPluginsConfig, + NULL)) { notification_message(app->notifications, &sequence_error); scene_manager_previous_scene(app->scene_manager); return; @@ -40,6 +43,6 @@ bool protopirate_scene_receiver_config_on_event(void* context, SceneManagerEvent void protopirate_scene_receiver_config_on_exit(void* context) { ProtoPirateApp* app = context; - - shared_plugin_unload(app, ProtoPirateSharedPluginsConfig); + shared_plugin_unload( + (void**)&app->plugin_flipper_application, (const void**)&app->config_plugin); } diff --git a/scenes/protopirate_scene_saved_info.c b/scenes/protopirate_scene_saved_info.c index d9918d0..7463126 100644 --- a/scenes/protopirate_scene_saved_info.c +++ b/scenes/protopirate_scene_saved_info.c @@ -3,7 +3,6 @@ #include "plugins/protopirate_saved_info_plugin.h" #include "../helpers/protopirate_psa_bf_host.h" #include "../helpers/protopirate_storage.h" -#include "helpers/protopirate_plugins.h" static const ProtoPirateSavedInfoSceneHostApi protopirate_saved_info_scene_host_api = { .ensure_widget = protopirate_ensure_widget, @@ -17,7 +16,11 @@ static const ProtoPirateSavedInfoSceneHostApi protopirate_saved_info_scene_host_ void protopirate_scene_saved_info_on_enter(void* context) { ProtoPirateApp* app = context; - if(!shared_plugin_load(app, ProtoPirateSharedPluginsSavedInfo, NULL)) { + if(!shared_plugin_load( + (void**)&app->plugin_flipper_application, + (const void**)&app->saved_info_plugin, + ProtoPirateSharedPluginsSavedInfo, + NULL)) { notification_message(app->notifications, &sequence_error); scene_manager_previous_scene(app->scene_manager); return; @@ -30,17 +33,18 @@ void protopirate_scene_saved_info_on_enter(void* context) { bool protopirate_scene_saved_info_on_event(void* context, SceneManagerEvent event) { ProtoPirateApp* app = ((ProtoPirateApp*)context); - //I can't set the next scene from inside the plugin, or it causes crazy crashes. - if(shared_plugin_handle_navigation_events(app, event)) { - //Handle Saved Info event in plugin. + //Handle event in plugin. + if(app->saved_info_plugin->on_event(app, event)) { return true; } else { - return app->saved_info_plugin->on_event(app, event); + return shared_plugin_handle_navigation_events( + app->scene_manager, app->view_dispatcher, event); } } void protopirate_scene_saved_info_on_exit(void* context) { ProtoPirateApp* app = context; widget_reset(app->widget); - shared_plugin_unload(app, ProtoPirateSharedPluginsSavedInfo); + shared_plugin_unload( + (void**)&app->plugin_flipper_application, (const void**)&app->saved_info_plugin); } diff --git a/scenes/protopirate_scene_start.c b/scenes/protopirate_scene_start.c index 9a77086..2d1b8ec 100644 --- a/scenes/protopirate_scene_start.c +++ b/scenes/protopirate_scene_start.c @@ -92,7 +92,6 @@ bool protopirate_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { scene_manager_set_scene_state(app->scene_manager, ProtoPirateSceneStart, event.event); - FURI_LOG_I(TAG, "Suppressing Charging While in a scene."); if(event.event == SubmenuIndexProtoPirateAbout) { scene_manager_next_scene(app->scene_manager, ProtoPirateSceneAbout); consumed = true; @@ -128,7 +127,6 @@ bool protopirate_scene_start_on_event(void* context, SceneManagerEvent event) { } void protopirate_scene_start_on_exit(void* context) { - furi_check(context); ProtoPirateApp* app = context; submenu_reset(app->submenu); } diff --git a/scenes/protopirate_scene_sub_decode.c b/scenes/protopirate_scene_sub_decode.c index 4d439ea..5cf938d 100644 --- a/scenes/protopirate_scene_sub_decode.c +++ b/scenes/protopirate_scene_sub_decode.c @@ -1,7 +1,6 @@ // scenes/protopirate_scene_sub_decode.c #include "../protopirate_app_i.h" #ifdef ENABLE_SUB_DECODE_SCENE -#include "helpers/protopirate_plugins.h" #define STATE_EMULATE 0 #define STATE_BF 1 @@ -13,10 +12,12 @@ void protopirate_scene_sub_decode_on_enter(void* context) { } bool protopirate_scene_sub_decode_on_event(void* context, SceneManagerEvent event) { - if(shared_plugin_handle_navigation_events(context, event)) { + ProtoPirateApp* app = (ProtoPirateApp*)context; + if(protopirate_tool_scene_on_event(context, event)) { return true; } else { - return protopirate_tool_scene_on_event(context, event); + return shared_plugin_handle_navigation_events( + app->scene_manager, app->view_dispatcher, event); } } diff --git a/scenes/protopirate_scene_timing_tuner.c b/scenes/protopirate_scene_timing_tuner.c index 8d70ac5..6445020 100644 --- a/scenes/protopirate_scene_timing_tuner.c +++ b/scenes/protopirate_scene_timing_tuner.c @@ -2,8 +2,6 @@ #include "../protopirate_app_i.h" #ifdef ENABLE_TIMING_TUNER_SCENE -#include "helpers/protopirate_plugins.h" - #ifndef PROTOPIRATE_TIMING_TUNER_PLUGIN_BUILD void protopirate_scene_timing_tuner_on_enter(void* context) { @@ -11,10 +9,12 @@ void protopirate_scene_timing_tuner_on_enter(void* context) { } bool protopirate_scene_timing_tuner_on_event(void* context, SceneManagerEvent event) { - if(shared_plugin_handle_navigation_events(context, event)) { + ProtoPirateApp* app = (ProtoPirateApp*)context; + if(protopirate_tool_scene_on_event(context, event)) { return true; } else { - return protopirate_tool_scene_on_event(context, event); + return shared_plugin_handle_navigation_events( + app->scene_manager, app->view_dispatcher, event); } } From e28d45aeee32aa361c2caa89cd56d1338e84328f Mon Sep 17 00:00:00 2001 From: Leeroy <135471162+LeeroysHub@users.noreply.github.com> Date: Tue, 29 Sep 2026 08:28:15 +1000 Subject: [PATCH 3/4] UI BUG: Not drawing History once a key is received. * This code also refactors the frequency, preset, and history_stat strings, makes them char* instead of FuriString* --- helpers/protopirate_txrx.c | 15 +++--- helpers/protopirate_txrx.h | 5 +- protopirate_history.c | 13 ----- protopirate_history.h | 1 - .../plugins/protopirate_tool_scene_plugin.h | 4 ++ scenes/protopirate_scene_receiver.c | 17 +++--- scenes/protopirate_scene_sub_decode.c | 38 ++++++++++--- views/protopirate_receiver.c | 54 ++++++++++--------- views/protopirate_receiver.h | 3 ++ 9 files changed, 89 insertions(+), 61 deletions(-) diff --git a/helpers/protopirate_txrx.c b/helpers/protopirate_txrx.c index ffeda9d..96ae7ab 100644 --- a/helpers/protopirate_txrx.c +++ b/helpers/protopirate_txrx.c @@ -58,13 +58,13 @@ void protopirate_get_frequency_modulation_str( size_t modulation_size) { furi_check(app); - if(frequency && frequency_size > 0) { + if(frequency) { unsigned long mhz = (unsigned long)((app->txrx->preset->frequency / 1000000UL) % 1000UL); unsigned long khz = (unsigned long)((app->txrx->preset->frequency / 10000UL) % 100UL); snprintf(frequency, frequency_size, "%03lu.%02lu", mhz, khz); } - if(modulation && modulation_size > 0) { + if(modulation) { snprintf( modulation, modulation_size, "%.2s", furi_string_get_cstr(app->txrx->preset->name)); } @@ -73,19 +73,20 @@ void protopirate_get_frequency_modulation_str( void protopirate_get_frequency_modulation( ProtoPirateApp* app, FuriString* frequency, - FuriString* modulation) { + size_t frequency_size, + FuriString* modulation, + size_t modulation_size) { furi_check(app); char frequency_buf[16] = {0}; char modulation_buf[8] = {0}; - protopirate_get_frequency_modulation_str( - app, frequency_buf, sizeof(frequency_buf), modulation_buf, sizeof(modulation_buf)); + protopirate_get_frequency_modulation_str(app, frequency_buf, 16, modulation_buf, 8); if(frequency != NULL) { - furi_string_set_str(frequency, frequency_buf); + memcpy(frequency, frequency_buf, frequency_size); } if(modulation != NULL) { - furi_string_set_str(modulation, modulation_buf); + memcpy(modulation, modulation_buf, modulation_size); } } diff --git a/helpers/protopirate_txrx.h b/helpers/protopirate_txrx.h index f947b71..9ac99aa 100644 --- a/helpers/protopirate_txrx.h +++ b/helpers/protopirate_txrx.h @@ -20,7 +20,10 @@ void protopirate_preset_init( void protopirate_get_frequency_modulation( ProtoPirateApp* app, FuriString* frequency, - FuriString* modulation); + size_t frequency_size, + FuriString* modulation, + size_t modulation_size); + void protopirate_get_frequency_modulation_str( ProtoPirateApp* app, char* frequency, diff --git a/protopirate_history.c b/protopirate_history.c index 6229d36..0032847 100644 --- a/protopirate_history.c +++ b/protopirate_history.c @@ -204,10 +204,6 @@ void protopirate_history_format_status_text( furi_check(instance); furi_check(output); - if(output_size == 0) { - return; - } - uint16_t n = protopirate_history_get_item(instance); if(n >= PROTOPIRATE_HISTORY_MAX) { snprintf(output, output_size, "FULL"); @@ -216,15 +212,6 @@ void protopirate_history_format_status_text( } } -void protopirate_history_get_status_text(ProtoPirateHistory* instance, FuriString* output) { - furi_check(instance); - furi_check(output); - - char status_text[16]; - protopirate_history_format_status_text(instance, status_text, sizeof(status_text)); - furi_string_set_str(output, status_text); -} - bool protopirate_history_get_capture_path( ProtoPirateHistory* instance, uint16_t idx, diff --git a/protopirate_history.h b/protopirate_history.h index c218d17..e6d3b22 100644 --- a/protopirate_history.h +++ b/protopirate_history.h @@ -19,7 +19,6 @@ void protopirate_history_format_status_text( ProtoPirateHistory* instance, char* output, size_t output_size); -void protopirate_history_get_status_text(ProtoPirateHistory* instance, FuriString* output); bool protopirate_history_get_capture_path( ProtoPirateHistory* instance, diff --git a/scenes/plugins/protopirate_tool_scene_plugin.h b/scenes/plugins/protopirate_tool_scene_plugin.h index 5b49bb1..27a0364 100644 --- a/scenes/plugins/protopirate_tool_scene_plugin.h +++ b/scenes/plugins/protopirate_tool_scene_plugin.h @@ -57,9 +57,13 @@ typedef struct { void (*receiver_add_data_statusbar)( ProtoPirateReceiver* receiver, const char* frequency_str, + size_t frequency_size, const char* preset_str, + size_t preset_size, const char* history_stat_str, + size_t history_stat_size, bool external_radio); + uint16_t (*receiver_get_idx_menu)(ProtoPirateReceiver* receiver); void (*receiver_set_idx_menu)(ProtoPirateReceiver* receiver, uint16_t idx); void (*receiver_set_callback)( diff --git a/scenes/protopirate_scene_receiver.c b/scenes/protopirate_scene_receiver.c index ff545b2..24f86be 100644 --- a/scenes/protopirate_scene_receiver.c +++ b/scenes/protopirate_scene_receiver.c @@ -24,8 +24,7 @@ static void protopirate_scene_receiver_update_statusbar(void* context) { char modulation_str[8] = {0}; char history_stat_str[16] = {0}; - protopirate_get_frequency_modulation_str( - app, frequency_str, sizeof(frequency_str), modulation_str, sizeof(modulation_str)); + protopirate_get_frequency_modulation_str(app, frequency_str, 16, modulation_str, 8); bool is_external = false; if(app->radio_initialized && app->txrx->radio_device) { @@ -33,14 +32,20 @@ static void protopirate_scene_receiver_update_statusbar(void* context) { } if(app->txrx->history) { - protopirate_history_format_status_text( - app->txrx->history, history_stat_str, sizeof(history_stat_str)); + protopirate_history_format_status_text(app->txrx->history, history_stat_str, 20); } else { - snprintf(history_stat_str, sizeof(history_stat_str), "0/%u", PROTOPIRATE_HISTORY_MAX); + snprintf(history_stat_str, 16, "0/%u", PROTOPIRATE_HISTORY_MAX); } protopirate_view_receiver_add_data_statusbar( - app->protopirate_receiver, frequency_str, modulation_str, history_stat_str, is_external); + app->protopirate_receiver, + frequency_str, + 16, + modulation_str, + 8, + history_stat_str, + 16, + is_external); } static void protopirate_scene_receiver_callback( diff --git a/scenes/protopirate_scene_sub_decode.c b/scenes/protopirate_scene_sub_decode.c index 5cf938d..b15df69 100644 --- a/scenes/protopirate_scene_sub_decode.c +++ b/scenes/protopirate_scene_sub_decode.c @@ -70,10 +70,26 @@ static const ProtoPirateToolSceneHostApi* g_tool_scene_host_api = NULL; app, frequency, frequency_size, modulation, modulation_size) #define radio_device_loader_is_external(radio_device) \ g_tool_scene_host_api->radio_device_is_external(radio_device) + #define protopirate_view_receiver_add_data_statusbar( \ - receiver, frequency, modulation, history, external) \ + receiver, \ + frequency, \ + frequency_size, \ + modulation, \ + modulation_size, \ + history, \ + history_size, \ + external) \ g_tool_scene_host_api->receiver_add_data_statusbar( \ - receiver, frequency, modulation, history, external) + receiver, \ + frequency, \ + frequency_size, \ + modulation, \ + modulation_size, \ + history, \ + history_size, \ + external) + #define protopirate_view_receiver_get_idx_menu(receiver) \ g_tool_scene_host_api->receiver_get_idx_menu(receiver) #define protopirate_view_receiver_set_idx_menu(receiver, idx) \ @@ -227,12 +243,11 @@ static void protopirate_scene_sub_decode_update_receiver_statusbar( char modulation_str[8] = {0}; char history_stat_str[16] = {0}; - protopirate_get_frequency_modulation_str( - app, frequency_str, sizeof(frequency_str), modulation_str, sizeof(modulation_str)); + protopirate_get_frequency_modulation_str(app, frequency_str, 16, modulation_str, 8); if(ctx && ctx->frequency > 0U) { snprintf( frequency_str, - sizeof(frequency_str), + 20, "%03lu.%02lu", (unsigned long)((ctx->frequency / 1000000UL) % 1000UL), (unsigned long)((ctx->frequency / 10000UL) % 100UL)); @@ -240,13 +255,20 @@ static void protopirate_scene_sub_decode_update_receiver_statusbar( const uint16_t signal_count = (ctx && ctx->history) ? protopirate_history_get_item(ctx->history) : 0U; - snprintf( - history_stat_str, sizeof(history_stat_str), "%u/%u", signal_count, PROTOPIRATE_HISTORY_MAX); + snprintf(history_stat_str, 16, "%u/%u", signal_count, PROTOPIRATE_HISTORY_MAX); bool is_external = app->txrx->radio_device ? radio_device_loader_is_external(app->txrx->radio_device) : false; + protopirate_view_receiver_add_data_statusbar( - app->protopirate_receiver, frequency_str, modulation_str, history_stat_str, is_external); + app->protopirate_receiver, + frequency_str, + 16, + modulation_str, + 8, + history_stat_str, + 16, + is_external); } static void protopirate_scene_sub_decode_update_receiver_progress( diff --git a/views/protopirate_receiver.c b/views/protopirate_receiver.c index 2dcc99c..cd7e5ff 100644 --- a/views/protopirate_receiver.c +++ b/views/protopirate_receiver.c @@ -27,9 +27,9 @@ typedef struct { uint8_t history_item; float rssi; bool auto_save; - FuriString* frequency_str; - FuriString* preset_str; - FuriString* history_stat_str; + char* frequency_str; + char* preset_str; + char* history_stat_str; FuriString* draw_scratch; bool external_radio; ProtoPirateLock lock; @@ -191,24 +191,26 @@ static void protopirate_view_receiver_update_offset(ProtoPirateReceiver* receive void protopirate_view_receiver_add_data_statusbar( ProtoPirateReceiver* receiver, const char* frequency_str, + size_t freqency_size, const char* preset_str, + size_t preset_size, const char* history_stat_str, + size_t history_stat_size, bool external_radio) { furi_check(receiver); with_view_model( receiver->view, ProtoPirateReceiverModel * model, { - furi_string_set_str(model->frequency_str, frequency_str); - furi_string_set_str(model->preset_str, preset_str); - furi_string_set_str(model->history_stat_str, history_stat_str); + memcpy(model->frequency_str, frequency_str, freqency_size); + memcpy(model->preset_str, preset_str, preset_size); + memcpy(model->history_stat_str, history_stat_str, history_stat_size); model->external_radio = external_radio; }, true); } static void protopirate_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { - canvas_set_color(canvas, ColorBlack); canvas_draw_box(canvas, 0, 0 + idx * FRAME_HEIGHT, scrollbar ? 122 : 127, FRAME_HEIGHT); canvas_set_color(canvas, ColorWhite); @@ -280,6 +282,9 @@ void protopirate_view_receiver_draw(Canvas* canvas, ProtoPirateReceiverModel* mo canvas, 4, 9 + (i * FRAME_HEIGHT), furi_string_get_cstr(model->draw_scratch)); } + //Last item may be selected, it wont reset. + canvas_set_color(canvas, ColorBlack); + //Draw scrollbar if needed if(scrollbar) { // Calculate maximum scroll position @@ -360,8 +365,7 @@ void protopirate_view_receiver_draw(Canvas* canvas, ProtoPirateReceiverModel* mo canvas_set_font(canvas, FontSecondary); if(model->sub_decode_mode) { - canvas_draw_str_aligned( - canvas, 127, 0, AlignRight, AlignTop, furi_string_get_cstr(model->preset_str)); + canvas_draw_str_aligned(canvas, 127, 0, AlignRight, AlignTop, model->preset_str); } else { if(model->external_radio) { canvas_draw_str_aligned(canvas, 127, 0, AlignRight, AlignTop, "Ext"); @@ -381,12 +385,12 @@ void protopirate_view_receiver_draw(Canvas* canvas, ProtoPirateReceiverModel* mo //Draw the unlock instructions last, so they appear on top... if(model->lock_count) { if(model->sub_decode_mode) { - canvas_draw_str(canvas, 44, 63, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 96, 63, furi_string_get_cstr(model->history_stat_str)); + canvas_draw_str(canvas, 44, 63, model->frequency_str); + canvas_draw_str(canvas, 96, 63, model->history_stat_str); } else { - canvas_draw_str(canvas, 44, 63, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 63, furi_string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 63, furi_string_get_cstr(model->history_stat_str)); + canvas_draw_str(canvas, 44, 63, model->frequency_str); + canvas_draw_str(canvas, 79, 63, model->preset_str); + canvas_draw_str(canvas, 96, 63, model->history_stat_str); } canvas_set_font(canvas, FontSecondary); elements_bold_rounded_frame(canvas, 14, 8, 99, 48); @@ -402,12 +406,12 @@ void protopirate_view_receiver_draw(Canvas* canvas, ProtoPirateReceiverModel* mo canvas_draw_str(canvas, 74, 62, "Locked"); } else { if(model->sub_decode_mode) { - canvas_draw_str(canvas, 44, 63, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 96, 63, furi_string_get_cstr(model->history_stat_str)); + canvas_draw_str(canvas, 44, 63, model->frequency_str); + canvas_draw_str(canvas, 96, 63, model->history_stat_str); } else { - canvas_draw_str(canvas, 44, 63, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 63, furi_string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 63, furi_string_get_cstr(model->history_stat_str)); + canvas_draw_str(canvas, 44, 63, model->frequency_str); + canvas_draw_str(canvas, 79, 63, model->preset_str); + canvas_draw_str(canvas, 96, 63, model->history_stat_str); } } } @@ -583,9 +587,9 @@ ProtoPirateReceiver* protopirate_view_receiver_alloc(bool auto_save) { ProtoPirateReceiverModel * model, { model->history = NULL; - model->frequency_str = furi_string_alloc(); - model->preset_str = furi_string_alloc(); - model->history_stat_str = furi_string_alloc(); + model->frequency_str = malloc(16); + model->preset_str = malloc(8); + model->history_stat_str = malloc(16); model->draw_scratch = furi_string_alloc(); furi_check(model->draw_scratch); model->list_offset = 0; @@ -612,9 +616,9 @@ void protopirate_view_receiver_free(ProtoPirateReceiver* receiver) { receiver->view, ProtoPirateReceiverModel * model, { - furi_string_free(model->frequency_str); - furi_string_free(model->preset_str); - furi_string_free(model->history_stat_str); + free(model->frequency_str); + free(model->preset_str); + free(model->history_stat_str); furi_string_free(model->draw_scratch); }, false); diff --git a/views/protopirate_receiver.h b/views/protopirate_receiver.h index 679391d..f7b8d2e 100644 --- a/views/protopirate_receiver.h +++ b/views/protopirate_receiver.h @@ -21,8 +21,11 @@ View* protopirate_view_receiver_get_view(ProtoPirateReceiver* receiver); void protopirate_view_receiver_add_data_statusbar( ProtoPirateReceiver* receiver, const char* frequency_str, + size_t freqency_size, const char* preset_str, + size_t preset_size, const char* history_stat_str, + size_t history_stat_size, bool external_radio); uint16_t protopirate_view_receiver_get_idx_menu(ProtoPirateReceiver* receiver); From 144d22cf3d608c4116475fe3ee0f8759ac5a70cf Mon Sep 17 00:00:00 2001 From: Leeroy <135471162+LeeroysHub@users.noreply.github.com> Date: Mon, 28 Sep 2026 10:13:11 +1000 Subject: [PATCH 4/4] ENABLE_MODELS_DATABASE build flag * Completely removes all the code and variables for Models DB * Can be used to slim the app down a bit if required. * ASSETS: Make models_db and keystore seperate, models not in FAP if disabled. --- application.fam | 9 ++++++++- {keystore => assets/keystore}/encrypted | 0 {keystore => assets/keystore}/vag | 0 {keystore => assets/models_db}/models.txt | 0 defines.h | 2 ++ helpers/protopirate_models.c | 4 +++- helpers/protopirate_models.h | 4 ++++ helpers/protopirate_settings.c | 10 +++++++--- helpers/protopirate_settings.h | 3 +++ helpers/variable_item_list.c | 4 ++++ protocols/vag.c | 11 +++++++++-- protopirate_app.c | 6 ++++++ protopirate_app_i.h | 6 ++++++ scenes/plugins/protopirate_config_plugin.c | 20 ++++++++++++++++---- scenes/plugins/protopirate_config_plugin.h | 4 ++++ 15 files changed, 72 insertions(+), 11 deletions(-) rename {keystore => assets/keystore}/encrypted (100%) rename {keystore => assets/keystore}/vag (100%) rename {keystore => assets/models_db}/models.txt (100%) diff --git a/application.fam b/application.fam index 58d43f5..672b5c8 100644 --- a/application.fam +++ b/application.fam @@ -14,6 +14,7 @@ def ProtoPirateDefineEnabled(name, app_manifest_path=app_manifest_path): _ENABLE_TIMING_TUNER = ProtoPirateDefineEnabled("ENABLE_TIMING_TUNER_SCENE") _ENABLE_EMULATE = ProtoPirateDefineEnabled("ENABLE_EMULATE_FEATURE") +_ENABLE_MODELS_DATABASE = ProtoPirateDefineEnabled("ENABLE_MODELS_DATABASE") _MAIN_APP_SOURCES = [ "*.c*", @@ -43,6 +44,12 @@ if not _ENABLE_EMULATE: "!protopirate_scene_emulate.c", ] + +if _ENABLE_MODELS_DATABASE: + _ASSETS="assets" +else: + _ASSETS="assets/keystore" + App( appid="proto_pirate", name="ProtoPirate", @@ -56,7 +63,7 @@ App( fap_icon="images/protopirate_10px.png", fap_category="Sub-GHz", fap_icon_assets="images", - fap_file_assets="keystore", + fap_file_assets=_ASSETS, cdefines=["PROTOPIRATE_PROTOCOL_RX_ONLY=1"], sources=_MAIN_APP_SOURCES, ) diff --git a/keystore/encrypted b/assets/keystore/encrypted similarity index 100% rename from keystore/encrypted rename to assets/keystore/encrypted diff --git a/keystore/vag b/assets/keystore/vag similarity index 100% rename from keystore/vag rename to assets/keystore/vag diff --git a/keystore/models.txt b/assets/models_db/models.txt similarity index 100% rename from keystore/models.txt rename to assets/models_db/models.txt diff --git a/defines.h b/defines.h index 4818d37..b1c6041 100644 --- a/defines.h +++ b/defines.h @@ -1,8 +1,10 @@ #pragma once +#include // #define ENABLE_TIMING_TUNER_SCENE #define ENABLE_SUB_DECODE_SCENE #define ENABLE_EMULATE_FEATURE +#define ENABLE_MODELS_DATABASE #if defined(ENABLE_EMULATE_FEATURE) && !defined(PROTOPIRATE_PROTOCOL_RX_ONLY) #define PROTOPIRATE_WITH_ENCODER 1 diff --git a/helpers/protopirate_models.c b/helpers/protopirate_models.c index b19cf67..17d128f 100644 --- a/helpers/protopirate_models.c +++ b/helpers/protopirate_models.c @@ -1,8 +1,9 @@ #include "protopirate_models.h" +#ifdef ENABLE_MODELS_DATABASE #define TAG "PPModels" -#define PROTOPIRATE_MODELS_FILE APP_ASSETS_PATH("models.txt") +#define PROTOPIRATE_MODELS_FILE APP_ASSETS_PATH("models_db/models.txt") //Models File Format. #define MODELS_FILE_HEADER "ProtoPirate Car Models Database" @@ -294,3 +295,4 @@ uint16_t car_model_get_count(void) { //Finished, return the count or 0 if error. return (uint16_t)model_count; } +#endif diff --git a/helpers/protopirate_models.h b/helpers/protopirate_models.h index 7a4670f..bac8ece 100644 --- a/helpers/protopirate_models.h +++ b/helpers/protopirate_models.h @@ -1,5 +1,8 @@ #pragma once #include +#include "../defines.h" + +#ifdef ENABLE_MODELS_DATABASE #include #include "core/record.h" #include @@ -18,3 +21,4 @@ bool car_model_get_by_index( SubGhzSetting* app_settings); uint16_t car_model_get_count(void); +#endif diff --git a/helpers/protopirate_settings.c b/helpers/protopirate_settings.c index ee1b0e0..49854d8 100644 --- a/helpers/protopirate_settings.c +++ b/helpers/protopirate_settings.c @@ -4,7 +4,6 @@ #include #include #include -#include "../defines.h" #include "../protocols/protocols_common.h" #define TAG "PPSettings" @@ -22,7 +21,9 @@ void protopirate_settings_set_defaults(ProtoPirateSettings* settings) { settings->emulate_feature_enabled = false; settings->check_saved = false; settings->datetime_filenames = false; +#ifdef ENABLE_MODELS_DATABASE settings->car_model_index = 0; +#endif } void protopirate_settings_load(ProtoPirateSettings* settings) { @@ -135,13 +136,14 @@ void protopirate_settings_load(ProtoPirateSettings* settings) { } settings->datetime_filenames = (datetime_filenames_temp == 1); - // Read Selected Car Model +// Read Selected Car Model +#ifdef ENABLE_MODELS_DATABASE uint32_t car_model_index_temp = 0; if(!flipper_format_read_uint32(ff, "CarModelIndex", &car_model_index_temp, 1)) { car_model_index_temp = 0; } settings->car_model_index = car_model_index_temp; - +#endif FURI_LOG_I( TAG, "Settings loaded: freq=%lu, preset=%u, auto_save=%d, hopping=%d, emulate=%d, check_saved=%d, sound = %d", @@ -234,12 +236,14 @@ void protopirate_settings_save(ProtoPirateSettings* settings) { if(!flipper_format_write_uint32(ff, "DateTimeFilenames", &datetime_filenames_temp, 1)) { FURI_LOG_E(TAG, "Failed to write Date Time Filenames"); } +#ifdef ENABLE_MODELS_DATABASE uint32_t car_model_index_temp = settings->car_model_index; if(!flipper_format_write_uint32(ff, "CarModelIndex", &car_model_index_temp, 1)) { FURI_LOG_E(TAG, "Failed to write car model"); break; } +#endif write_ok = true; FURI_LOG_I( diff --git a/helpers/protopirate_settings.h b/helpers/protopirate_settings.h index b25fbaa..fa6b837 100644 --- a/helpers/protopirate_settings.h +++ b/helpers/protopirate_settings.h @@ -1,6 +1,7 @@ // helpers/protopirate_settings.h #pragma once +#include "../defines.h" #include #include @@ -19,7 +20,9 @@ typedef struct { bool emulate_feature_enabled; bool check_saved; bool datetime_filenames; +#ifdef ENABLE_MODELS_DATABASE uint16_t car_model_index; +#endif } ProtoPirateSettings; void protopirate_settings_load(ProtoPirateSettings* settings); diff --git a/helpers/variable_item_list.c b/helpers/variable_item_list.c index e9f2f9a..bd2134e 100644 --- a/helpers/variable_item_list.c +++ b/helpers/variable_item_list.c @@ -1,3 +1,6 @@ +#include "../defines.h" + +#ifdef ENABLE_MODELS_DATABASE #include "helpers/variable_item_list.h" #include #include @@ -639,3 +642,4 @@ void* variable_item_get_context(VariableItem* item) { furi_check(item); return item->context; } +#endif diff --git a/protocols/vag.c b/protocols/vag.c index 4c2a7c5..95f9d10 100644 --- a/protocols/vag.c +++ b/protocols/vag.c @@ -1,9 +1,16 @@ +#include "../defines.h" #include "vag.h" #include "aut64.h" #include "protocols_common.h" #include #include +#ifdef ENABLE_MODELS_DATABASE +#define PROTOPIRATE_VAG_KEYS_FILE_NAME APP_ASSETS_PATH("keystore/vag") +#else +#define PROTOPIRATE_VAG_KEYS_FILE_NAME APP_ASSETS_PATH("vag") +#endif + #define TAG "VAGProtocol" #define VAG_ENCODER_UPLOAD_TYPE12_SIZE 635 @@ -548,7 +555,7 @@ void* subghz_protocol_decoder_vag_alloc(SubGhzEnvironment* environment) { instance->decrypted = false; instance->key_idx = 0xFF; - protocol_vag_load_keys(APP_ASSETS_PATH("vag")); + protocol_vag_load_keys(PROTOPIRATE_VAG_KEYS_FILE_NAME); return instance; } @@ -1544,7 +1551,7 @@ void* subghz_protocol_encoder_vag_alloc(SubGhzEnvironment* environment) { instance->is_running = false; instance->key_idx = 0xFF; - protocol_vag_load_keys(APP_ASSETS_PATH("vag")); + protocol_vag_load_keys(APP_ASSETS_PATH("keystore/vag")); FURI_LOG_I(TAG, "VAG encoder alloc complete, keys loaded: %d", protocol_vag_keys_loaded); diff --git a/protopirate_app.c b/protopirate_app.c index e603307..b5f6afe 100644 --- a/protopirate_app.c +++ b/protopirate_app.c @@ -167,6 +167,7 @@ ProtoPirateApp* protopirate_app_alloc() { app->variable_item_list = NULL; //Load the models database, get the count of the models for the list. +#ifdef ENABLE_MODELS_DATABASE if(shared_plugin_load( (void**)&app->plugin_flipper_application, (const void**)&app->config_plugin, @@ -211,9 +212,12 @@ ProtoPirateApp* protopirate_app_alloc() { shared_plugin_unload( (void**)&app->plugin_flipper_application, (const void**)&app->config_plugin); } else { +#endif //Preset set in Config. protopirate_preset_init(app, preset_name, frequency, preset_data, preset_data_size); +#ifdef ENABLE_MODELS_DATABASE } +#endif // Apply hopping state from settings app->txrx->hopper_state = settings.hopping_enabled ? ProtoPirateHopperStateRunning : @@ -249,6 +253,7 @@ void protopirate_app_free(ProtoPirateApp* app) { #endif //Get the selected Model, and get the preset to save. +#ifdef ENABLE_MODELS_DATABASE if(app->selected_model && app->selected_model->index) { //Get Preset Index before model was selected. settings.car_model_index = app->selected_model->index; @@ -289,6 +294,7 @@ void protopirate_app_free(ProtoPirateApp* app) { //Free the Model. free(app->selected_model); app->selected_model = NULL; +#endif FURI_LOG_I( TAG, diff --git a/protopirate_app_i.h b/protopirate_app_i.h index f342f23..872e19d 100644 --- a/protopirate_app_i.h +++ b/protopirate_app_i.h @@ -43,7 +43,11 @@ #include "helpers/protopirate_models.h" #include "helpers/protopirate_settings.h" +#ifdef ENABLE_MODELS_DATABASE +#define PROTOPIRATE_KEYSTORE_DIR_NAME APP_ASSETS_PATH("keystore/encrypted") +#else #define PROTOPIRATE_KEYSTORE_DIR_NAME APP_ASSETS_PATH("encrypted") +#endif typedef struct VariableItemList VariableItemList; @@ -111,8 +115,10 @@ struct ProtoPirateApp { FlipperApplication* tool_scene_plugin_flipper_application; const ProtoPirateToolScenePlugin* tool_scene_plugin; ProtoPirateToolScenePluginKind tool_scene_plugin_kind; +#ifdef ENABLE_MODELS_DATABASE ProtoPirateCarModel* selected_model; uint16_t car_models_count; +#endif }; #ifdef ENABLE_EMULATE_FEATURE diff --git a/scenes/plugins/protopirate_config_plugin.c b/scenes/plugins/protopirate_config_plugin.c index 741015d..3200b71 100644 --- a/scenes/plugins/protopirate_config_plugin.c +++ b/scenes/plugins/protopirate_config_plugin.c @@ -134,6 +134,7 @@ static void protopirate_scene_receiver_config_set_hopping_running(VariableItem* app->txrx->hopper_state = hopping_value[index]; } +#ifdef ENABLE_MODELS_DATABASE static void protopirate_scene_receiver_config_set_model(VariableItem* item) { ProtoPirateApp* app = variable_item_get_context(item); uint8_t direction = variable_item_get_current_value_index(item); @@ -237,6 +238,7 @@ static void protopirate_scene_receiver_config_set_model(VariableItem* item) { variable_item_set_locked(hop_menu, lock, "Turn off\nCar Model\nto do that!"); variable_item_set_locked(preset_menu, lock, "Turn off\nCar Model\nto do that!"); } +#endif static uint8_t protopirate_scene_receiver_config_next_frequency(const uint32_t value, void* context) { @@ -338,20 +340,20 @@ static void FURI_LOG_D("TEST", "Index= %lu", index); switch(index) { - case ProtoPirateSettingIndexCarModel: { +#ifdef ENABLE_MODELS_DATABASE + case ProtoPirateSettingIndexCarModel: //Reset the Models Menu VariableItem* model_menu = variable_item_list_get(app->variable_item_list, ProtoPirateSettingIndexCarModel); variable_item_set_current_value_index(model_menu, 0); protopirate_scene_receiver_config_set_model(model_menu); break; - } - case ProtoPirateSettingIndexLock: { +#endif + case ProtoPirateSettingIndexLock: view_dispatcher_send_custom_event( app->view_dispatcher, ProtoPirateCustomEventSceneSettingLock); break; } - } } static void plugin_on_enter(void* context, bool show_lock_keyboard) { @@ -366,12 +368,14 @@ static void plugin_on_enter(void* context, bool show_lock_keyboard) { } //Add he car model the list, with the correct selection and text. +#ifdef ENABLE_MODELS_DATABASE item = variable_item_list_add( app->variable_item_list, app->selected_model->name, 0, //Plus NONE protopirate_scene_receiver_config_set_model, app); +#endif item = variable_item_list_add( app->variable_item_list, @@ -392,10 +396,12 @@ static void plugin_on_enter(void* context, bool show_lock_keyboard) { subghz_setting_get_frequency(app->setting, value_index) / 1000000, (subghz_setting_get_frequency(app->setting, value_index) % 1000000) / 10000); variable_item_set_current_value_text(item, text_buf); +#ifdef ENABLE_MODELS_DATABASE variable_item_set_locked( item, app->selected_model && (app->selected_model->index), "Turn off\nCar Model\nto do that!"); +#endif item = variable_item_list_add( app->variable_item_list, @@ -407,10 +413,12 @@ static void plugin_on_enter(void* context, bool show_lock_keyboard) { app->txrx->hopper_state, hopping_value, ON_OFF_COUNT, app); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, on_off_text[value_index]); +#ifdef ENABLE_MODELS_DATABASE variable_item_set_locked( item, app->selected_model && (app->selected_model->index), "Turn off\nCar Model\nto do that!"); +#endif item = variable_item_list_add( app->variable_item_list, @@ -423,10 +431,12 @@ static void plugin_on_enter(void* context, bool show_lock_keyboard) { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text( item, subghz_setting_get_preset_name(app->setting, value_index)); +#ifdef ENABLE_MODELS_DATABASE variable_item_set_locked( item, app->selected_model && (app->selected_model->index), "Turn off\nCar Model\nto do that!"); +#endif #ifdef ENABLE_EMULATE_FEATURE // TX power option @@ -494,8 +504,10 @@ void config_plugin_set_host_api(const ProtoPirateConfigSceneHostApi* host_api) { static const ProtoPirateConfigPlugin protopirate_config_plugin = { .plugin_name = "Config", +#ifdef ENABLE_MODELS_DATABASE .car_model_get_by_index = car_model_get_by_index, .car_model_get_count = car_model_get_count, +#endif .on_enter = plugin_on_enter, .set_host_api = config_plugin_set_host_api, }; diff --git a/scenes/plugins/protopirate_config_plugin.h b/scenes/plugins/protopirate_config_plugin.h index ab00f21..342ad4a 100644 --- a/scenes/plugins/protopirate_config_plugin.h +++ b/scenes/plugins/protopirate_config_plugin.h @@ -9,7 +9,9 @@ #define PROTOPIRATE_CONFIG_PLUGIN_API_VERSION 2U enum ProtoPirateSettingIndex { +#ifdef ENABLE_MODELS_DATABASE ProtoPirateSettingIndexCarModel, +#endif ProtoPirateSettingIndexFrequency, ProtoPirateSettingIndexHopping, ProtoPirateSettingIndexModulation, @@ -36,12 +38,14 @@ typedef struct ProtoPirateConfigSceneHostApi { typedef struct ProtoPirateConfigPlugin { const char* plugin_name; +#ifdef ENABLE_MODELS_DATABASE bool (*car_model_get_by_index)( ProtoPirateCarModel* car_model, uint16_t index, uint16_t model_count, SubGhzSetting* app_settings); uint16_t (*car_model_get_count)(void); +#endif void (*on_enter)(void* app, bool show_lock_keyboard); void (*set_host_api)(const ProtoPirateConfigSceneHostApi* host_api); } ProtoPirateConfigPlugin;