diff --git a/applications/external/hid_app/hid.c b/applications/external/hid_app/hid.c index c86def18f..f29a3b22a 100644 --- a/applications/external/hid_app/hid.c +++ b/applications/external/hid_app/hid.c @@ -131,7 +131,7 @@ Hid* hid_alloc(HidTransport transport) { app); submenu_add_item( app->device_type_submenu, - "[Beta]YT Shorts Controller", + "YT Shorts Controller", HidSubmenuIndexYTShorts, hid_submenu_callback, app); diff --git a/applications/external/pocsag_pager/pocsag_pager_app.c b/applications/external/pocsag_pager/pocsag_pager_app.c index d4b12c466..b52b2f37f 100644 --- a/applications/external/pocsag_pager/pocsag_pager_app.c +++ b/applications/external/pocsag_pager/pocsag_pager_app.c @@ -128,7 +128,8 @@ POCSAGPagerApp* pocsag_pager_app_alloc() { // Auto switch to internal radio if external radio is not available furi_delay_ms(15); if(!furi_hal_subghz_check_radio()) { - furi_hal_subghz_set_radio_type(SubGhzRadioInternal); + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } furi_hal_power_suppress_charge_enter(); @@ -146,6 +147,8 @@ void pocsag_pager_app_free(POCSAGPagerApp* app) { // Disable power for External CC1101 if it was enabled and module is connected furi_hal_subghz_disable_ext_power(); + // Reinit SPI handles for internal radio / nfc + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); // Submenu view_dispatcher_remove_view(app->view_dispatcher, POCSAGPagerViewSubmenu); diff --git a/applications/external/protoview/app.c b/applications/external/protoview/app.c index 2d3acccac..70205a0a4 100644 --- a/applications/external/protoview/app.c +++ b/applications/external/protoview/app.c @@ -173,7 +173,8 @@ ProtoViewApp* protoview_app_alloc() { // Auto switch to internal radio if external radio is not available furi_delay_ms(15); if(!furi_hal_subghz_check_radio()) { - furi_hal_subghz_set_radio_type(SubGhzRadioInternal); + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } furi_hal_power_suppress_charge_enter(); @@ -193,6 +194,8 @@ void protoview_app_free(ProtoViewApp* app) { // Disable power for External CC1101 if it was enabled and module is connected furi_hal_subghz_disable_ext_power(); + // Reinit SPI handles for internal radio / nfc + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); // View related. view_port_enabled_set(app->view_port, false); diff --git a/applications/external/spectrum_analyzer/spectrum_analyzer.c b/applications/external/spectrum_analyzer/spectrum_analyzer.c index 7148ad92b..6250ac039 100644 --- a/applications/external/spectrum_analyzer/spectrum_analyzer.c +++ b/applications/external/spectrum_analyzer/spectrum_analyzer.c @@ -396,6 +396,8 @@ void spectrum_analyzer_free(SpectrumAnalyzer* instance) { // Disable power for External CC1101 if it was enabled and module is connected furi_hal_subghz_disable_ext_power(); + // Reinit SPI handles for internal radio / nfc + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } int32_t spectrum_analyzer_app(void* p) { @@ -410,7 +412,8 @@ int32_t spectrum_analyzer_app(void* p) { // Auto switch to internal radio if external radio is not available furi_delay_ms(15); if(!furi_hal_subghz_check_radio()) { - furi_hal_subghz_set_radio_type(SubGhzRadioInternal); + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } furi_hal_power_suppress_charge_enter(); diff --git a/applications/external/subghz_playlist/playlist.c b/applications/external/subghz_playlist/playlist.c index 345b19927..906df0725 100644 --- a/applications/external/subghz_playlist/playlist.c +++ b/applications/external/subghz_playlist/playlist.c @@ -718,7 +718,8 @@ int32_t playlist_app(void* p) { // Auto switch to internal radio if external radio is not available furi_delay_ms(15); if(!furi_hal_subghz_check_radio()) { - furi_hal_subghz_set_radio_type(SubGhzRadioInternal); + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } furi_hal_power_suppress_charge_enter(); @@ -811,6 +812,8 @@ exit_cleanup: furi_hal_power_suppress_charge_exit(); // Disable power for External CC1101 if it was enabled and module is connected furi_hal_subghz_disable_ext_power(); + // Reinit SPI handles for internal radio / nfc + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); if(app->worker != NULL) { if(playlist_worker_running(app->worker)) { diff --git a/applications/external/subghz_remote/subghz_remote_app.c b/applications/external/subghz_remote/subghz_remote_app.c index a0daddc12..015d57dac 100644 --- a/applications/external/subghz_remote/subghz_remote_app.c +++ b/applications/external/subghz_remote/subghz_remote_app.c @@ -766,7 +766,8 @@ SubGHzRemote* subghz_remote_alloc(void) { // Auto switch to internal radio if external radio is not available furi_delay_ms(15); if(!furi_hal_subghz_check_radio()) { - furi_hal_subghz_set_radio_type(SubGhzRadioInternal); + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } furi_hal_power_suppress_charge_enter(); @@ -793,6 +794,8 @@ void subghz_remote_free(SubGHzRemote* app, bool with_subghz) { // Disable power for External CC1101 if it was enabled and module is connected furi_hal_subghz_disable_ext_power(); + // Reinit SPI handles for internal radio / nfc + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); furi_string_free(app->up_file); furi_string_free(app->down_file); diff --git a/applications/external/weather_station/weather_station_app.c b/applications/external/weather_station/weather_station_app.c index a3135a6b0..8bea4961d 100644 --- a/applications/external/weather_station/weather_station_app.c +++ b/applications/external/weather_station/weather_station_app.c @@ -110,7 +110,8 @@ WeatherStationApp* weather_station_app_alloc() { // Auto switch to internal radio if external radio is not available furi_delay_ms(15); if(!furi_hal_subghz_check_radio()) { - furi_hal_subghz_set_radio_type(SubGhzRadioInternal); + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } furi_hal_power_suppress_charge_enter(); @@ -128,6 +129,8 @@ void weather_station_app_free(WeatherStationApp* app) { // Disable power for External CC1101 if it was enabled and module is connected furi_hal_subghz_disable_ext_power(); + // Reinit SPI handles for internal radio / nfc + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); // Submenu view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewSubmenu); diff --git a/applications/main/bad_kb/helpers/ducky_script_commands.c b/applications/main/bad_kb/helpers/ducky_script_commands.c index ef8da0b8a..f23ab2f8a 100644 --- a/applications/main/bad_kb/helpers/ducky_script_commands.c +++ b/applications/main/bad_kb/helpers/ducky_script_commands.c @@ -169,22 +169,22 @@ static int32_t ducky_fnc_waitforbutton(BadKbScript* bad_kb, const char* line, in } static const DuckyCmd ducky_commands[] = { - {"REM ", NULL, -1}, - {"ID ", NULL, -1}, - {"DELAY ", ducky_fnc_delay, -1}, - {"STRING ", ducky_fnc_string, 0}, - {"STRINGLN ", ducky_fnc_string, 1}, - {"DEFAULT_DELAY ", ducky_fnc_defdelay, -1}, - {"DEFAULTDELAY ", ducky_fnc_defdelay, -1}, - {"STRINGDELAY ", ducky_fnc_strdelay, -1}, - {"STRING_DELAY ", ducky_fnc_strdelay, -1}, - {"REPEAT ", ducky_fnc_repeat, -1}, - {"SYSRQ ", ducky_fnc_sysrq, -1}, - {"ALTCHAR ", ducky_fnc_altchar, -1}, - {"ALTSTRING ", ducky_fnc_altstring, -1}, - {"ALTCODE ", ducky_fnc_altstring, -1}, - {"HOLD ", ducky_fnc_hold, -1}, - {"RELEASE ", ducky_fnc_release, -1}, + {"REM", NULL, -1}, + {"ID", NULL, -1}, + {"DELAY", ducky_fnc_delay, -1}, + {"STRING", ducky_fnc_string, 0}, + {"STRINGLN", ducky_fnc_string, 1}, + {"DEFAULT_DELAY", ducky_fnc_defdelay, -1}, + {"DEFAULTDELAY", ducky_fnc_defdelay, -1}, + {"STRINGDELAY", ducky_fnc_strdelay, -1}, + {"STRING_DELAY", ducky_fnc_strdelay, -1}, + {"REPEAT", ducky_fnc_repeat, -1}, + {"SYSRQ", ducky_fnc_sysrq, -1}, + {"ALTCHAR", ducky_fnc_altchar, -1}, + {"ALTSTRING", ducky_fnc_altstring, -1}, + {"ALTCODE", ducky_fnc_altstring, -1}, + {"HOLD", ducky_fnc_hold, -1}, + {"RELEASE", ducky_fnc_release, -1}, {"WAIT_FOR_BUTTON_PRESS", ducky_fnc_waitforbutton, -1}, }; @@ -192,8 +192,15 @@ static const DuckyCmd ducky_commands[] = { #define WORKER_TAG TAG "Worker" int32_t ducky_execute_cmd(BadKbScript* bad_kb, const char* line) { + size_t cmd_word_len = strcspn(line, " "); for(size_t i = 0; i < COUNT_OF(ducky_commands); i++) { - if(strncmp(line, ducky_commands[i].name, strlen(ducky_commands[i].name)) == 0) { + size_t cmd_compare_len = strlen(ducky_commands[i].name); + + if(cmd_compare_len != cmd_word_len) { + continue; + } + + if(strncmp(line, ducky_commands[i].name, cmd_compare_len) == 0) { if(ducky_commands[i].callback == NULL) { return 0; } else { diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index 85a00eea0..a2bcdcf52 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -243,6 +243,27 @@ bool lfrfid_load_key_from_file_select(LfRfid* app) { return result; } +bool lfrfid_load_raw_key_from_file_select(LfRfid* app) { + furi_assert(app); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options( + &browser_options, LFRFID_APP_RAW_ASK_EXTENSION, &I_125_10px); + browser_options.base_path = LFRFID_APP_FOLDER; + + // Input events and views are managed by file_browser + bool result = + dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options); + + if(result) { + // Extract .raw and then .ask + path_extract_filename(app->file_path, app->file_name, true); + path_extract_filename(app->file_name, app->file_name, true); + } + + return result; +} + bool lfrfid_delete_key(LfRfid* app) { furi_assert(app); diff --git a/applications/main/lfrfid/lfrfid_i.h b/applications/main/lfrfid/lfrfid_i.h index 72b061930..86929a14a 100644 --- a/applications/main/lfrfid/lfrfid_i.h +++ b/applications/main/lfrfid/lfrfid_i.h @@ -125,6 +125,8 @@ bool lfrfid_save_key(LfRfid* app); bool lfrfid_load_key_from_file_select(LfRfid* app); +bool lfrfid_load_raw_key_from_file_select(LfRfid* app); + bool lfrfid_delete_key(LfRfid* app); bool lfrfid_load_key_data(LfRfid* app, FuriString* path, bool show_dialog); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_config.h b/applications/main/lfrfid/scenes/lfrfid_scene_config.h index 10dc46fe6..54b840844 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_config.h +++ b/applications/main/lfrfid/scenes/lfrfid_scene_config.h @@ -22,4 +22,6 @@ ADD_SCENE(lfrfid, raw_info, RawInfo) ADD_SCENE(lfrfid, raw_name, RawName) ADD_SCENE(lfrfid, raw_read, RawRead) ADD_SCENE(lfrfid, raw_success, RawSuccess) +ADD_SCENE(lfrfid, raw_emulate, RawEmulate) +ADD_SCENE(lfrfid, select_raw_key, SelectRawKey) ADD_SCENE(lfrfid, rpc, Rpc) diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c index d322b2d01..7aa85e0eb 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c @@ -6,6 +6,7 @@ typedef enum { SubmenuIndexPSK, SubmenuIndexClearT5577, SubmenuIndexRAW, + SubmenuIndexRAWEmulate, } SubmenuIndex; static void lfrfid_scene_extra_actions_submenu_callback(void* context, uint32_t index) { @@ -45,6 +46,14 @@ void lfrfid_scene_extra_actions_on_enter(void* context) { app, !furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug), "Enable\nDebug!"); + submenu_add_lockable_item( + submenu, + "Emulate RAW RFID data", + SubmenuIndexRAWEmulate, + lfrfid_scene_extra_actions_submenu_callback, + app, + !furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug), + "Enable\nDebug!"); submenu_set_selected_item( submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneExtraActions)); @@ -78,6 +87,9 @@ bool lfrfid_scene_extra_actions_on_event(void* context, SceneManagerEvent event) } else if(event.event == SubmenuIndexRAW) { scene_manager_next_scene(app->scene_manager, LfRfidSceneRawName); consumed = true; + } else if(event.event == SubmenuIndexRAWEmulate) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneSelectRawKey); + consumed = true; } scene_manager_set_scene_state(app->scene_manager, LfRfidSceneExtraActions, event.event); } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_emulate.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_emulate.c new file mode 100644 index 000000000..c06a5eebf --- /dev/null +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_emulate.c @@ -0,0 +1,86 @@ +#include "../lfrfid_i.h" + +#define TAG "ADC" + +typedef struct { + FuriString* string_file_name; + bool error; +} LfRfidEmulateRawState; + +static void lfrfid_raw_emulate_callback(LFRFIDWorkerEmulateRawResult result, void* context) { + LfRfid* app = context; + + if(result == LFRFIDWorkerEmulateRawFileError) { + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadError); + } else if(result == LFRFIDWorkerEmulateRawOverrun) { + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadOverrun); + } +} + +void lfrfid_scene_raw_emulate_on_enter(void* context) { + LfRfid* app = context; + Popup* popup = app->popup; + + LfRfidEmulateRawState* state = malloc(sizeof(LfRfidEmulateRawState)); + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawEmulate, (uint32_t)state); + state->string_file_name = furi_string_alloc(); + + popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); + lfrfid_worker_start_thread(app->lfworker); + lfrfid_make_app_folder(app); + + furi_string_printf( + state->string_file_name, + "%s/%s%s", + LFRFID_SD_FOLDER, + furi_string_get_cstr(app->file_name), + LFRFID_APP_RAW_ASK_EXTENSION); + FURI_LOG_D(TAG, "raw_emulate->file_name=%s", furi_string_get_cstr(state->string_file_name)); + popup_set_header(popup, "Emulating\nRAW RFID\nASK", 89, 30, AlignCenter, AlignTop); + lfrfid_worker_emulate_raw_start( + app->lfworker, + furi_string_get_cstr(state->string_file_name), + lfrfid_raw_emulate_callback, + app); + + notification_message(app->notifications, &sequence_blink_start_cyan); + + state->error = false; +} + +bool lfrfid_scene_raw_emulate_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + Popup* popup = app->popup; + LfRfidEmulateRawState* state = (LfRfidEmulateRawState*)scene_manager_get_scene_state( + app->scene_manager, LfRfidSceneRawEmulate); + bool consumed = false; + + furi_assert(state); + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == LfRfidEventReadError) { + consumed = true; + state->error = true; + popup_set_header( + popup, "Reading\nRAW RFID\nFile error", 89, 30, AlignCenter, AlignTop); + notification_message(app->notifications, &sequence_blink_start_red); + } + } + + return consumed; +} + +void lfrfid_scene_raw_emulate_on_exit(void* context) { + LfRfid* app = context; + LfRfidEmulateRawState* state = (LfRfidEmulateRawState*)scene_manager_get_scene_state( + app->scene_manager, LfRfidSceneRawEmulate); + + notification_message(app->notifications, &sequence_blink_stop); + popup_reset(app->popup); + lfrfid_worker_stop(app->lfworker); + lfrfid_worker_stop_thread(app->lfworker); + + furi_string_free(state->string_file_name); + free(state); +} diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_select_raw_key.c b/applications/main/lfrfid/scenes/lfrfid_scene_select_raw_key.c new file mode 100644 index 000000000..f12d280aa --- /dev/null +++ b/applications/main/lfrfid/scenes/lfrfid_scene_select_raw_key.c @@ -0,0 +1,23 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_select_raw_key_on_enter(void* context) { + LfRfid* app = context; + + if(lfrfid_load_raw_key_from_file_select(app)) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneRawEmulate); + + } else { + scene_manager_previous_scene(app->scene_manager); + } +} + +bool lfrfid_scene_select_raw_key_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + bool consumed = false; + return consumed; +} + +void lfrfid_scene_select_raw_key_on_exit(void* context) { + UNUSED(context); +} diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index 9d2be7ee5..ad49bf09b 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -103,5 +103,8 @@ typedef enum { SubGhzCustomEventViewTransmitterSendStop, SubGhzCustomEventViewTransmitterError, + SubGhzCustomEventViewFreqAnalOkShort, + SubGhzCustomEventViewFreqAnalOkLong, + SubGhzCustomEventByteInputDone, } SubGhzCustomEvent; diff --git a/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c b/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c index 767589693..b6b9e18a7 100644 --- a/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c @@ -211,14 +211,16 @@ bool subghz_scene_ext_module_settings_on_event(void* context, SceneManagerEvent UNUSED(event); // Set selected radio module - furi_hal_subghz_set_radio_type(value_index_exm); + furi_hal_subghz_select_radio_type(value_index_exm); + furi_hal_subghz_init_radio_type(value_index_exm); furi_hal_subghz_enable_ext_power(); // Check if module is present, if no -> show error if(!furi_hal_subghz_check_radio()) { value_index_exm = 0; - furi_hal_subghz_set_radio_type(SubGhzRadioInternal); + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); furi_string_set(subghz->error_str, "Please connect\nexternal radio"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); } diff --git a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c index bed044244..b1071d836 100644 --- a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c +++ b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c @@ -54,7 +54,7 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e } else if(event.event == SubGhzCustomEventSceneAnalyzerUnlock) { notification_message(subghz->notifications, &sequence_reset_rgb); return true; - } else if(event.event == SubGhzCustomEventViewReceiverOK) { + } else if(event.event == SubGhzCustomEventViewFreqAnalOkShort) { notification_message(subghz->notifications, &sequence_saved); uint32_t frequency = subghz_frequency_analyzer_get_frequency_to_save(subghz->subghz_frequency_analyzer); @@ -64,11 +64,12 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e } return true; - } else if(event.event == SubGhzCustomEventViewReceiverUnlock) { + } else if(event.event == SubGhzCustomEventViewFreqAnalOkLong) { // Don't need to save, we already saved on short event #ifdef FURI_DEBUG FURI_LOG_W(TAG, "Goto next scene!"); #endif + //scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneStart, 10); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver); return true; } diff --git a/applications/main/subghz/scenes/subghz_scene_start.c b/applications/main/subghz/scenes/subghz_scene_start.c index 00b7ddbac..e3c70aaf6 100644 --- a/applications/main/subghz/scenes/subghz_scene_start.c +++ b/applications/main/subghz/scenes/subghz_scene_start.c @@ -88,7 +88,8 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { furi_hal_subghz_enable_ext_power(); if(!furi_hal_subghz_check_radio()) { - furi_hal_subghz_set_radio_type(SubGhzRadioInternal); + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); subghz->last_settings->external_module_enabled = false; furi_string_set(subghz->error_str, "Please connect\nexternal radio"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 75c6e627a..47da7ae40 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -451,7 +451,8 @@ int32_t subghz_app(void* p) { // Auto switch to internal radio if external radio is not available if(!furi_hal_subghz_check_radio()) { subghz->last_settings->external_module_enabled = false; - furi_hal_subghz_set_radio_type(SubGhzRadioInternal); + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } // Check argument and run corresponding scene if(p && strlen(p)) { @@ -507,6 +508,8 @@ int32_t subghz_app(void* p) { furi_hal_power_suppress_charge_exit(); // Disable power for External CC1101 if it was enabled and module is connected furi_hal_subghz_disable_ext_power(); + // Reinit SPI handles for internal radio / nfc + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); subghz_free(subghz, alloc_for_tx); diff --git a/applications/main/subghz/subghz_history.c b/applications/main/subghz/subghz_history.c index 51d5ada7d..3c018ec8b 100644 --- a/applications/main/subghz/subghz_history.c +++ b/applications/main/subghz/subghz_history.c @@ -125,6 +125,11 @@ uint8_t subghz_history_get_type_protocol(SubGhzHistory* instance, uint16_t idx) const char* subghz_history_get_protocol_name(SubGhzHistory* instance, uint16_t idx) { furi_assert(instance); SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); + if(!item || !item->flipper_string) { + FURI_LOG_E(TAG, "Missing Item"); + furi_string_reset(instance->tmp_string); + return furi_string_get_cstr(instance->tmp_string); + } flipper_format_rewind(item->flipper_string); if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) { FURI_LOG_E(TAG, "Missing Protocol"); diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index 2f4445a42..7ee2554b0 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -129,7 +129,8 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count // Set selected radio module if(instance->external_module_enabled) { - furi_hal_subghz_set_radio_type(SubGhzRadioExternal); + furi_hal_subghz_select_radio_type(SubGhzRadioExternal); + furi_hal_subghz_init_radio_type(SubGhzRadioExternal); } /*/} else { diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index 3b8c37d73..23c05e4c5 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -372,7 +372,7 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { #endif if(updated) { - instance->callback(SubGhzCustomEventViewReceiverOK, instance->context); + instance->callback(SubGhzCustomEventViewFreqAnalOkShort, instance->context); } // First device receive short, then when user release button we get long @@ -385,7 +385,7 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { subghz_frequency_analyzer_worker_stop(instance->worker); } - instance->callback(SubGhzCustomEventViewReceiverUnlock, instance->context); + instance->callback(SubGhzCustomEventViewFreqAnalOkLong, instance->context); } } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index ddc753aa7..33f3ff301 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1453,6 +1453,7 @@ Function,+,furi_hal_subghz_get_timestamp_file_names,_Bool, Function,+,furi_hal_subghz_idle,void, Function,-,furi_hal_subghz_init,void, Function,+,furi_hal_subghz_init_check,_Bool, +Function,+,furi_hal_subghz_init_radio_type,_Bool,SubGhzRadioType Function,+,furi_hal_subghz_is_async_tx_complete,_Bool, Function,+,furi_hal_subghz_is_frequency_valid,_Bool,uint32_t Function,+,furi_hal_subghz_is_rx_data_crc_valid,_Bool, @@ -1465,13 +1466,13 @@ Function,+,furi_hal_subghz_read_packet,void,"uint8_t*, uint8_t*" Function,+,furi_hal_subghz_reset,void, Function,+,furi_hal_subghz_rx,void, Function,+,furi_hal_subghz_rx_pipe_not_empty,_Bool, +Function,+,furi_hal_subghz_select_radio_type,void,SubGhzRadioType Function,+,furi_hal_subghz_set_async_mirror_pin,void,const GpioPin* Function,+,furi_hal_subghz_set_extend_settings,void,"_Bool, _Bool" Function,+,furi_hal_subghz_set_external_power_disable,void,_Bool Function,+,furi_hal_subghz_set_frequency,uint32_t,uint32_t Function,+,furi_hal_subghz_set_frequency_and_path,uint32_t,uint32_t Function,+,furi_hal_subghz_set_path,void,FuriHalSubGhzPath -Function,+,furi_hal_subghz_set_radio_type,_Bool,SubGhzRadioType Function,+,furi_hal_subghz_set_rolling_counter_mult,void,uint8_t Function,+,furi_hal_subghz_set_timestamp_file_names,void,_Bool Function,-,furi_hal_subghz_shutdown,void, diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 35ea2e36a..573c5b8ab 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -43,11 +43,19 @@ volatile FuriHalSubGhz furi_hal_subghz = { .timestamp_file_names = false, }; -bool furi_hal_subghz_set_radio_type(SubGhzRadioType state) { +void furi_hal_subghz_select_radio_type(SubGhzRadioType state) { furi_hal_subghz.radio_type = state; +} + +bool furi_hal_subghz_init_radio_type(SubGhzRadioType state) { + if(state == SubGhzRadioInternal && furi_hal_subghz.cc1101_g0_pin == &gpio_cc1101_g0) { + return true; + } else if(state == SubGhzRadioExternal && furi_hal_subghz.cc1101_g0_pin == &gpio_cc1101_g0_ext) { + return true; + } furi_hal_spi_bus_handle_deinit(furi_hal_subghz.spi_bus_handle); - if(furi_hal_subghz.radio_type == SubGhzRadioInternal) { + if(state == SubGhzRadioInternal) { furi_hal_subghz.spi_bus_handle = &furi_hal_spi_bus_handle_subghz; furi_hal_subghz.cc1101_g0_pin = &gpio_cc1101_g0; } else { @@ -120,6 +128,8 @@ void furi_hal_subghz_disable_ext_power(void) { bool furi_hal_subghz_check_radio(void) { bool result = true; + furi_hal_subghz_init_radio_type(furi_hal_subghz.radio_type); + furi_hal_spi_acquire(furi_hal_subghz.spi_bus_handle); uint8_t ver = cc1101_get_version(furi_hal_subghz.spi_bus_handle); diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.h b/firmware/targets/f7/furi_hal/furi_hal_subghz.h index a6a5e20de..a292c642f 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.h +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.h @@ -306,7 +306,7 @@ void furi_hal_subghz_stop_async_tx(); * @param state SubGhzRadioInternal or SubGhzRadioExternal * @return true if switching is successful */ -bool furi_hal_subghz_set_radio_type(SubGhzRadioType state); +bool furi_hal_subghz_init_radio_type(SubGhzRadioType state); /** Get current radio * @return SubGhzRadioInternal or SubGhzRadioExternal @@ -353,6 +353,10 @@ void furi_hal_subghz_set_timestamp_file_names(bool state); */ bool furi_hal_subghz_get_timestamp_file_names(void); +/** Set what radio module we will be using + */ +void furi_hal_subghz_select_radio_type(SubGhzRadioType state); + #ifdef __cplusplus } #endif diff --git a/scripts/flipper/storage.py b/scripts/flipper/storage.py index 7b56ee0d0..cff32ceb1 100644 --- a/scripts/flipper/storage.py +++ b/scripts/flipper/storage.py @@ -335,7 +335,9 @@ class FlipperStorage: def _check_no_error(self, response, path=None): if self.has_error(response): - raise FlipperStorageException.from_error_code(self.get_error(response)) + raise FlipperStorageException.from_error_code( + path, self.get_error(response) + ) def size(self, path: str): """file size on Flipper"""