diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e95006d1..254b12d86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,12 @@ - Unitemp: Numerous improvements from @MLAB-project fork (by @MLAB-project) - XRemote: Add dolphin xp and crash bugfix (by @teohumeau) - Sub-GHz: + - Sub-GHz app is now external on SD card, like on OFW (by @WillyJL) + - This was done to free some space on flash, which is always running out + - It means RAM consumption while using the Sub-GHz app has increased + - Usability remains mostly unaffected, our testing showed it can receive up to ~50 signals normally and ~10 signals with qFlipper / Flipper Mobile App connected + - You may experience some "out of memory" messages, this is inevitable as RAM eventually fragments and needs to be rearraged, simply resume as normal after the reboot + - Add Manually menu transparently refactored into a "separate app" for lower RAM usage, it is still accessed as before from Sub-GHz app (by @WillyJL) - UL: Counter editor refactoring (by @Dmitry422) - UL: Alutech AT-4N & Nice Flor S turbo speedup (by @Dmitry422) - UL: Sommer fm2 in Add manually now uses FM12K modulation (Sommer without fm2 tag uses FM476) (try this if regular option doesn't work for you) (by @xMasterX) @@ -75,6 +81,7 @@ ### Fixed: - Sub-GHz: + - Fix display of memory full (by @WillyJL) - UL: Fixed button mapping for FAAC RC/XT (by @xMasterX) - UL: Possible Sommer timings fix (by @xMasterX) - UL: Various fixes and cleanup (by @xMasterX) @@ -88,7 +95,7 @@ - Fixes to `READ_MULTI` and `GET_BLOCK_SECURITY` commands in ISO 15693-3 emulation (#501 by @WillyJL & aaronjamt) - Fix CLI with NTAG4xx and Type 4 Tag support (by @WillyJL) - UL: Fix LED not blinking at SLIX unlock (by @xMasterX) -- uFBT: Fix .clangd config for IDEs besides VSCode +- uFBT: Fix .clangd config for IDEs besides VSCode (by @WillyJL) - UL: Settings: Storage settings exit scenes properly if used via favourites (by @xMasterX) - UL: UI: Some small changes (by @xMasterX) - OFW: USB: Fix USB HID keyboard LED state reporting (by @Caballosanex) diff --git a/applications/main/subghz/application.fam b/applications/main/subghz/application.fam index fab4ec3e8..d80978b8e 100644 --- a/applications/main/subghz/application.fam +++ b/applications/main/subghz/application.fam @@ -1,38 +1,76 @@ App( appid="subghz", name="Sub-GHz", - apptype=FlipperAppType.APP, + apptype=FlipperAppType.MENUEXTERNAL, targets=["f7"], entry_point="subghz_app", icon="A_Sub1ghz_14", stack_size=3 * 1024, order=10, - # Sources separation breaks linking with subghz on internal, commented for now - # sources=[ - # "*.c", - # "!helpers/subghz_gps.c", - # "!helpers/minmea.c", - # "!subghz_cli.c", - # "!helpers/subghz_chat.c", - # "!subghz_extended_freq.c", - # ], + # Sources separation breaks linking with subghz on internal + sources=[ + "*.c", + "!subghz_fap.c", + "!subghz_gps.c", + "!minmea.c", + "!subghz_cli.c", + "!subghz_chat.c", + "!subghz_extended_freq.c", + "!subghz_gen_info.c", + "!subghz_txrx_create_protocol_key.c", + "!subghz_scene_set_button.c", + "!subghz_scene_set_counter.c", + "!subghz_scene_set_key.c", + "!subghz_scene_set_seed.c", + "!subghz_scene_set_serial.c", + "!subghz_scene_set_type.c", + ], requires=["region"], resources="resources", fap_libs=["assets", "hwdrivers"], fap_icon="icon.png", fap_category="Sub-GHz", - sdk_headers=["subghz_fap.h"], + # sdk_headers=["subghz_fap.h"], ) +# App( +# appid="subghz_fap", +# name="Sub-GHz", +# apptype=FlipperAppType.EXTERNAL, +# entry_point="subghz_fap", +# stack_size=3 * 1024, +# sources=["subghz_fap.c"], +# fap_icon="icon.png", +# fap_category="Sub-GHz", +# ) + App( - appid="subghz_fap", - name="Sub-GHz", + appid="subghz_add_manually", + name="Sub-GHz Add Manually", apptype=FlipperAppType.EXTERNAL, - entry_point="subghz_fap", + targets=["f7"], + entry_point="subghz_add_manually", stack_size=3 * 1024, - sources=["subghz_fap.c"], - fap_icon="icon.png", - fap_category="Sub-GHz", + sources=[ + "subghz.c", + "subghz_i.c", + "helpers/subghz_gen_info.c", + "helpers/subghz_txrx.c", + "helpers/subghz_txrx_create_protocol_key.c", + "scenes/subghz_scene.c", + "scenes/subghz_scene_set_button.c", + "scenes/subghz_scene_set_counter.c", + "scenes/subghz_scene_set_key.c", + "scenes/subghz_scene_set_seed.c", + "scenes/subghz_scene_set_serial.c", + "scenes/subghz_scene_set_type.c", + "scenes/subghz_scene_save_name.c", + "scenes/subghz_scene_save_success.c", + "scenes/subghz_scene_show_error.c", + "scenes/subghz_scene_show_error_sub.c", + ], + cdefines=["SUBGHZ_ADD_MANUALLY"], + fap_category="assets", ) App( @@ -58,6 +96,6 @@ App( targets=["f7"], apptype=FlipperAppType.STARTUP, entry_point="subghz_extended_freq", - # sources=["subghz_extended_freq.c"], + sources=["subghz_extended_freq.c"], order=650, ) diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index fde5e4b67..4a7d6bd77 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -59,11 +59,13 @@ SubGhzTxRx* subghz_txrx_alloc(void) { instance->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode); subghz_worker_set_context(instance->worker, instance->receiver); +#ifndef SUBGHZ_ADD_MANUALLY //set default device External subghz_devices_init(); instance->radio_device_type = SubGhzRadioDeviceTypeInternal; instance->radio_device_type = subghz_txrx_radio_device_set(instance, SubGhzRadioDeviceTypeExternalCC1101); +#endif return instance; } @@ -71,12 +73,14 @@ SubGhzTxRx* subghz_txrx_alloc(void) { void subghz_txrx_free(SubGhzTxRx* instance) { furi_assert(instance); +#ifndef SUBGHZ_ADD_MANUALLY if(instance->radio_device_type != SubGhzRadioDeviceTypeInternal) { subghz_txrx_radio_device_power_off(instance); subghz_devices_end(instance->radio_device); } subghz_devices_deinit(); +#endif subghz_worker_free(instance->worker); subghz_receiver_free(instance->receiver); @@ -122,7 +126,7 @@ uint8_t* //I had to skip the +10dBM and -6dBm Values, use only ones AM/FM have in common. //Highest Value is 12dBm for AM, 10 for FM. So Menu needs to reflect that. - const uint8_t tx_pa_table[TX_PATABLE_COUNT] = { + static const uint8_t tx_pa_table[TX_PATABLE_COUNT] = { 0, 0xC0, //12dBm 0xCD, //7dBm diff --git a/applications/main/subghz/scenes/subghz_scene_config.h b/applications/main/subghz/scenes/subghz_scene_config.h index 0e95fd261..c855a9b2b 100644 --- a/applications/main/subghz/scenes/subghz_scene_config.h +++ b/applications/main/subghz/scenes/subghz_scene_config.h @@ -1,22 +1,13 @@ +#ifndef SUBGHZ_ADD_MANUALLY ADD_SCENE(subghz, start, Start) ADD_SCENE(subghz, receiver, Receiver) ADD_SCENE(subghz, receiver_config, ReceiverConfig) ADD_SCENE(subghz, receiver_info, ReceiverInfo) -ADD_SCENE(subghz, save_name, SaveName) -ADD_SCENE(subghz, save_success, SaveSuccess) ADD_SCENE(subghz, saved, Saved) ADD_SCENE(subghz, transmitter, Transmitter) -ADD_SCENE(subghz, show_error, ShowError) -ADD_SCENE(subghz, show_error_sub, ShowErrorSub) ADD_SCENE(subghz, saved_menu, SavedMenu) ADD_SCENE(subghz, delete, Delete) ADD_SCENE(subghz, delete_success, DeleteSuccess) -ADD_SCENE(subghz, set_type, SetType) -ADD_SCENE(subghz, set_key, SetKey) -ADD_SCENE(subghz, set_serial, SetSerial) -ADD_SCENE(subghz, set_button, SetButton) -ADD_SCENE(subghz, set_counter, SetCounter) -ADD_SCENE(subghz, set_seed, SetSeed) ADD_SCENE(subghz, frequency_analyzer, FrequencyAnalyzer) ADD_SCENE(subghz, radio_settings, ExtModuleSettings) ADD_SCENE(subghz, read_raw, ReadRAW) @@ -27,3 +18,16 @@ ADD_SCENE(subghz, need_saving, NeedSaving) ADD_SCENE(subghz, rpc, Rpc) ADD_SCENE(subghz, show_gps, ShowGps) ADD_SCENE(subghz, signal_settings, SignalSettings) +#else +ADD_SCENE(subghz, set_type, SetType) +ADD_SCENE(subghz, set_key, SetKey) +ADD_SCENE(subghz, set_serial, SetSerial) +ADD_SCENE(subghz, set_button, SetButton) +ADD_SCENE(subghz, set_counter, SetCounter) +ADD_SCENE(subghz, set_seed, SetSeed) +#define SubGhzSceneStart SubGhzSceneSetType +#endif +ADD_SCENE(subghz, save_name, SaveName) +ADD_SCENE(subghz, save_success, SaveSuccess) +ADD_SCENE(subghz, show_error, ShowError) +ADD_SCENE(subghz, show_error_sub, ShowErrorSub) diff --git a/applications/main/subghz/scenes/subghz_scene_more_raw.c b/applications/main/subghz/scenes/subghz_scene_more_raw.c index 95d586934..fb2ae5085 100644 --- a/applications/main/subghz/scenes/subghz_scene_more_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_more_raw.c @@ -45,48 +45,27 @@ bool subghz_scene_more_raw_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { + if(!subghz_file_available(subghz)) { + if(!scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneStart)) { + scene_manager_stop(subghz->scene_manager); + view_dispatcher_stop(subghz->view_dispatcher); + } + return true; + } + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneMoreRAW, event.event); if(event.event == SubmenuIndexDelete) { - if(subghz_file_available(subghz)) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneMoreRAW, SubmenuIndexDelete); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteRAW); - return true; - } else { - if(!scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneStart)) { - scene_manager_stop(subghz->scene_manager); - view_dispatcher_stop(subghz->view_dispatcher); - } - } + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteRAW); + return true; } else if(event.event == SubmenuIndexEdit) { - if(subghz_file_available(subghz)) { - furi_string_reset(subghz->file_path_tmp); - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneMoreRAW, SubmenuIndexEdit); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); - return true; - } else { - if(!scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneStart)) { - scene_manager_stop(subghz->scene_manager); - view_dispatcher_stop(subghz->view_dispatcher); - } - } + furi_string_reset(subghz->file_path_tmp); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + return true; } else if(event.event == SubmenuIndexDecode) { - if(subghz_file_available(subghz)) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneMoreRAW, SubmenuIndexDecode); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDecodeRAW); - return true; - } else { - if(!scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneStart)) { - scene_manager_stop(subghz->scene_manager); - view_dispatcher_stop(subghz->view_dispatcher); - } - } + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDecodeRAW); + return true; } } return false; diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index 10a6c141c..65dfd475e 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -97,9 +97,9 @@ static void subghz_scene_receiver_update_statusbar(void* context) { } else { subghz_view_receiver_add_data_statusbar( subghz->subghz_receiver, + "", + "", furi_string_get_cstr(history_stat_str), - "", - "", subghz_txrx_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF, READ_BIT(subghz->filter, SubGhzProtocolFlag_BinRAW) > 0, show_sats, diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index fed134512..5589ad4b5 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -25,11 +25,17 @@ void subghz_scene_save_name_on_enter(void* context) { char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0}; DateTime* datetime = subghz->save_datetime_set ? &subghz->save_datetime : NULL; subghz->save_datetime_set = false; +#ifdef SUBGHZ_ADD_MANUALLY + name_generator_make_auto_datetime( + file_name_buf, SUBGHZ_MAX_LEN_NAME, SUBGHZ_APP_FILENAME_PREFIX, datetime); + furi_string_set(file_name, file_name_buf); + furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); + dev_name_empty = true; +#else if(!subghz_path_is_file(subghz->file_path)) { SubGhzProtocolDecoderBase* decoder_result = subghz_txrx_get_decoder(subghz->txrx); if(subghz->last_settings->protocol_file_names && decoder_result != NULL && - strlen(decoder_result->protocol->name) != 0 && - !scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneSetType)) { + strlen(decoder_result->protocol->name) != 0) { name_generator_make_auto_datetime( file_name_buf, SUBGHZ_MAX_LEN_NAME, decoder_result->protocol->name, datetime); } else { @@ -62,6 +68,7 @@ void subghz_scene_save_name_on_enter(void* context) { } furi_string_set(subghz->file_path, dir_name); } +#endif strlcpy(subghz->file_name_tmp, furi_string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME); text_input_set_header_text(text_input, "Name signal"); @@ -89,6 +96,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { // Set file path to default furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); // +#ifndef SUBGHZ_ADD_MANUALLY if(!(strcmp(subghz->file_name_tmp, "") == 0) || scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { @@ -96,6 +104,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { furi_string_set(subghz->file_path, subghz->file_path_tmp); } } +#endif scene_manager_previous_scene(subghz->scene_manager); @@ -113,24 +122,26 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { return false; } } else { - if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType) != - SubGhzCustomEventManagerNoSet) { - subghz_save_protocol_to_file( - subghz, - subghz_txrx_get_fff_data(subghz->txrx), - furi_string_get_cstr(subghz->file_path)); - scene_manager_set_scene_state( - subghz->scene_manager, - SubGhzSceneSetType, - SubGhzCustomEventManagerNoSet); - } else { - subghz_save_protocol_to_file( - subghz, - subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen), - furi_string_get_cstr(subghz->file_path)); +#ifdef SUBGHZ_ADD_MANUALLY + if(!subghz_save_protocol_to_file( + subghz, + subghz_txrx_get_fff_data(subghz->txrx), + furi_string_get_cstr(subghz->file_path))) { + return true; } +#else + if(!subghz_save_protocol_to_file( + subghz, + subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen), + furi_string_get_cstr(subghz->file_path))) { + return true; + } +#endif } +#ifdef SUBGHZ_ADD_MANUALLY + subghz_file_name_clear(subghz); +#else if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { subghz_protocol_raw_gen_fff_data( @@ -142,19 +153,21 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { } else { subghz_file_name_clear(subghz); } +#endif scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); +#ifdef SUBGHZ_ADD_MANUALLY + dolphin_deed(DolphinDeedSubGhzAddManually); +#else if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneSavedMenu)) { // Nothing, do not count editing as saving } else if(scene_manager_has_previous_scene( subghz->scene_manager, SubGhzSceneMoreRAW)) { // Ditto, for RAW signals - } else if(scene_manager_has_previous_scene( - subghz->scene_manager, SubGhzSceneSetType)) { - dolphin_deed(DolphinDeedSubGhzAddManually); } else { dolphin_deed(DolphinDeedSubGhzSave); } +#endif return true; } else { furi_string_set(subghz->error_str, "No name file"); diff --git a/applications/main/subghz/scenes/subghz_scene_save_success.c b/applications/main/subghz/scenes/subghz_scene_save_success.c index 9a71c74a7..8c316981d 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_success.c +++ b/applications/main/subghz/scenes/subghz_scene_save_success.c @@ -24,6 +24,12 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneSaveSuccess) { +#ifdef SUBGHZ_ADD_MANUALLY + while(scene_manager_previous_scene(subghz->scene_manager)) + ; + scene_manager_stop(subghz->scene_manager); + view_dispatcher_stop(subghz->view_dispatcher); +#else if(!scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneDecodeRAW)) { if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneReceiver)) { @@ -59,6 +65,7 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); } } +#endif return true; } } diff --git a/applications/main/subghz/scenes/subghz_scene_saved_menu.c b/applications/main/subghz/scenes/subghz_scene_saved_menu.c index 949fb871a..386d4d005 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved_menu.c +++ b/applications/main/subghz/scenes/subghz_scene_saved_menu.c @@ -69,30 +69,21 @@ bool subghz_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneSavedMenu, event.event); if(event.event == SubmenuIndexEmulate) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEmulate); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); return true; } else if(event.event == SubmenuIndexDelete) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexDelete); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDelete); return true; } else if(event.event == SubmenuIndexEdit) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEdit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); return true; } else if(event.event == SubmenuIndexGeo) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexGeo); scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneShowGps, true); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowGps); return true; } else if(event.event == SubmenuIndexSignalSettings) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexSignalSettings); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSignalSettings); return true; } diff --git a/applications/main/subghz/scenes/subghz_scene_set_counter.c b/applications/main/subghz/scenes/subghz_scene_set_counter.c index be13499b8..130f9b048 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_counter.c +++ b/applications/main/subghz/scenes/subghz_scene_set_counter.c @@ -296,8 +296,6 @@ bool subghz_scene_set_counter_on_event(void* context, SceneManagerEvent event) { } else { subghz_file_name_clear(subghz); - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSetType, SubGhzCustomEventManagerSet); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); } } diff --git a/applications/main/subghz/scenes/subghz_scene_set_key.c b/applications/main/subghz/scenes/subghz_scene_set_key.c index 690c62182..a760e8ffa 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_key.c +++ b/applications/main/subghz/scenes/subghz_scene_set_key.c @@ -76,8 +76,6 @@ bool subghz_scene_set_key_on_event(void* context, SceneManagerEvent event) { } else { subghz_file_name_clear(subghz); - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSetType, SubGhzCustomEventManagerSet); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); } } diff --git a/applications/main/subghz/scenes/subghz_scene_set_seed.c b/applications/main/subghz/scenes/subghz_scene_set_seed.c index b3bd447e6..0d844d0dc 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_seed.c +++ b/applications/main/subghz/scenes/subghz_scene_set_seed.c @@ -119,8 +119,6 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { } else { subghz_file_name_clear(subghz); - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSetType, SubGhzCustomEventManagerSet); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); } } diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index 7ee72ea21..6b44d39e4 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -104,9 +104,6 @@ void subghz_scene_set_type_on_enter(void* context) { subghz->submenu, submenu_names[i], i, subghz_scene_set_type_submenu_callback, subghz); } - submenu_set_selected_item( - subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType)); - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdMenu); } @@ -275,8 +272,6 @@ bool subghz_scene_set_type_generate_protocol_from_infos(SubGhz* subghz) { if(generated_protocol) { subghz_file_name_clear(subghz); - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSetType, SubGhzCustomEventManagerSet); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); } else { furi_string_set(subghz->error_str, "Function requires\nan SD card with\nfresh databases."); @@ -293,16 +288,15 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { if(event.event >= SetTypeMAX) { return false; } - scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneSetType, event.event); subghz_gen_info_reset(subghz->gen_info); subghz_scene_set_type_fill_generation_infos(subghz->gen_info, event.event); - if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneStart) == + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType) == SubmenuIndexAddManually) { generated_protocol = subghz_scene_set_type_generate_protocol_from_infos(subghz); } else if( - scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneStart) == + scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType) == SubmenuIndexAddManuallyAdvanced) { switch(subghz->gen_info->type) { case GenData: // Key (u64) diff --git a/applications/main/subghz/scenes/subghz_scene_signal_settings.c b/applications/main/subghz/scenes/subghz_scene_signal_settings.c index 9b582d2ee..f4635844f 100644 --- a/applications/main/subghz/scenes/subghz_scene_signal_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_signal_settings.c @@ -51,7 +51,7 @@ typedef struct { } Protocols; // List of protocols names and appropriate CounterMode counts -static Protocols protocols[] = { +static const Protocols protocols[] = { {"Nice FloR-S", 3}, {"CAME Atomo", 4}, {"Alutech AT-4N", 3}, diff --git a/applications/main/subghz/scenes/subghz_scene_start.c b/applications/main/subghz/scenes/subghz_scene_start.c index 6046b2c6d..9816562f0 100644 --- a/applications/main/subghz/scenes/subghz_scene_start.c +++ b/applications/main/subghz/scenes/subghz_scene_start.c @@ -1,6 +1,7 @@ #include "../subghz_i.h" #include "subghz_scene_start.h" #include +#include #include @@ -63,42 +64,46 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { view_dispatcher_stop(subghz->view_dispatcher); return true; } else if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneStart, event.event); if(event.event == SubmenuIndexReadRAW) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW); subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); return true; } else if(event.event == SubmenuIndexRead) { subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver); return true; } else if(event.event == SubmenuIndexSaved) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneStart, SubmenuIndexSaved); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); return true; - } else if(event.event == SubmenuIndexAddManually) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneStart, SubmenuIndexAddManually); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetType); - return true; - } else if(event.event == SubmenuIndexAddManuallyAdvanced) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneStart, SubmenuIndexAddManuallyAdvanced); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetType); + } else if( + event.event == SubmenuIndexAddManually || + event.event == SubmenuIndexAddManuallyAdvanced) { + const char* arg = (event.event == SubmenuIndexAddManuallyAdvanced) ? + "AddManuallyAdvanced" : + "AddManually"; + FuriString* self_path = furi_string_alloc(); + Loader* loader = furi_record_open(RECORD_LOADER); + furi_check(loader_get_application_launch_path(loader, self_path)); + loader_enqueue_launch( + loader, + EXT_PATH("apps/assets/subghz_add_manually.fap"), + arg, + LoaderDeferredLaunchFlagGui); + loader_enqueue_launch( + loader, furi_string_get_cstr(self_path), arg, LoaderDeferredLaunchFlagGui); + furi_record_close(RECORD_LOADER); + furi_string_free(self_path); + while(scene_manager_previous_scene(subghz->scene_manager)) + ; + scene_manager_stop(subghz->scene_manager); + view_dispatcher_stop(subghz->view_dispatcher); return true; } else if(event.event == SubmenuIndexFrequencyAnalyzer) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer); dolphin_deed(DolphinDeedSubGhzFrequencyAnalyzer); return true; } else if(event.event == SubmenuIndexExtSettings) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneStart, SubmenuIndexExtSettings); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneExtModuleSettings); return true; } diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 3bdcbdb07..9b0507bf5 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -8,6 +8,8 @@ #include #include +#include "scenes/subghz_scene_start.h" + #include "subghz_fap.h" #define TAG "SubGhzApp" @@ -64,7 +66,7 @@ static void subghz_rpc_command_callback(const RpcAppSystemEvent* event, void* co static void subghz_load_custom_presets(SubGhzSetting* setting) { furi_assert(setting); - const char* presets[][2] = { + static const char* presets[][2] = { // FM95 {"FM95", "02 0D 0B 06 08 32 07 04 14 00 13 02 12 04 11 83 10 67 15 24 18 18 19 16 1D 91 1C 00 1B 07 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"}, @@ -128,12 +130,14 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { view_dispatcher_add_view( subghz->view_dispatcher, SubGhzViewIdMenu, submenu_get_view(subghz->submenu)); +#ifndef SUBGHZ_ADD_MANUALLY // Receiver subghz->subghz_receiver = subghz_view_receiver_alloc(); view_dispatcher_add_view( subghz->view_dispatcher, SubGhzViewIdReceiver, subghz_view_receiver_get_view(subghz->subghz_receiver)); +#endif } // Popup subghz->popup = popup_alloc(); @@ -162,12 +166,14 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { //Dialog subghz->dialogs = furi_record_open(RECORD_DIALOGS); +#ifndef SUBGHZ_ADD_MANUALLY // Transmitter subghz->subghz_transmitter = subghz_view_transmitter_alloc(); view_dispatcher_add_view( subghz->view_dispatcher, SubGhzViewIdTransmitter, subghz_view_transmitter_get_view(subghz->subghz_transmitter)); +#endif if(!alloc_for_tx_only) { // Variable Item List subghz->variable_item_list = variable_item_list_alloc(); @@ -176,6 +182,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { SubGhzViewIdVariableItemList, variable_item_list_get_view(subghz->variable_item_list)); +#ifndef SUBGHZ_ADD_MANUALLY // Frequency Analyzer // View knows too much subghz->subghz_frequency_analyzer = subghz_frequency_analyzer_alloc(subghz->txrx); @@ -183,7 +190,10 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz->view_dispatcher, SubGhzViewIdFrequencyAnalyzer, subghz_frequency_analyzer_get_view(subghz->subghz_frequency_analyzer)); +#endif } + +#ifndef SUBGHZ_ADD_MANUALLY // Read RAW subghz->subghz_read_raw = subghz_read_raw_alloc(alloc_for_tx_only); view_dispatcher_add_view( @@ -238,8 +248,6 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); - subghz->gen_info = malloc(sizeof(GenInfo)); - if(!alloc_for_tx_only) { subghz->remove_duplicates = subghz->last_settings->remove_duplicates; subghz->ignore_filter = subghz->last_settings->ignore_filter; @@ -263,6 +271,9 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz->last_settings->rssi = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER; } } +#else + subghz->gen_info = malloc(sizeof(GenInfo)); +#endif #if SUBGHZ_MEASURE_LOADING load_ticks = furi_get_tick() - load_ticks; FURI_LOG_I(TAG, "Loaded: %ld ms.", load_ticks); @@ -270,9 +281,11 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { //Init Error_str subghz->error_str = furi_string_alloc(); +#ifndef SUBGHZ_ADD_MANUALLY if(subghz->last_settings->gps_baudrate != 0) { subghz->gps = subghz_gps_plugin_init(subghz->last_settings->gps_baudrate); } +#endif return subghz; } @@ -280,6 +293,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { furi_assert(subghz); +#ifndef SUBGHZ_ADD_MANUALLY if(subghz->rpc_ctx) { rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL); rpc_system_app_send_exited(subghz->rpc_ctx); @@ -290,11 +304,14 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { subghz_txrx_speaker_off(subghz->txrx); subghz_txrx_stop(subghz->txrx); subghz_txrx_sleep(subghz->txrx); +#endif if(!alloc_for_tx_only) { +#ifndef SUBGHZ_ADD_MANUALLY // Receiver view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdReceiver); subghz_view_receiver_free(subghz->subghz_receiver); +#endif // TextInput view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTextInput); @@ -311,21 +328,27 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { //Dialog furi_record_close(RECORD_DIALOGS); +#ifndef SUBGHZ_ADD_MANUALLY // Transmitter view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTransmitter); subghz_view_transmitter_free(subghz->subghz_transmitter); +#endif if(!alloc_for_tx_only) { // Variable Item List view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList); variable_item_list_free(subghz->variable_item_list); +#ifndef SUBGHZ_ADD_MANUALLY // Frequency Analyzer view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdFrequencyAnalyzer); subghz_frequency_analyzer_free(subghz->subghz_frequency_analyzer); +#endif } +#ifndef SUBGHZ_ADD_MANUALLY // Read RAW view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdReadRAW); subghz_read_raw_free(subghz->subghz_read_raw); +#endif if(!alloc_for_tx_only) { // Submenu view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdMenu); @@ -345,6 +368,7 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { furi_record_close(RECORD_GUI); subghz->gui = NULL; +#ifndef SUBGHZ_ADD_MANUALLY // threshold rssi subghz_threshold_rssi_free(subghz->threshold_rssi); @@ -352,7 +376,9 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { subghz_history_free(subghz->history); } +#else free(subghz->gen_info); +#endif //TxRx subghz_txrx_free(subghz->txrx); @@ -368,18 +394,32 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { furi_string_free(subghz->file_path); furi_string_free(subghz->file_path_tmp); +#ifndef SUBGHZ_ADD_MANUALLY // GPS if(subghz->gps) { subghz_gps_plugin_deinit(subghz->gps); } subghz_last_settings_free(subghz->last_settings); +#endif // The rest free(subghz); } +#ifndef SUBGHZ_ADD_MANUALLY int32_t subghz_app(char* p) { + enum SubmenuIndex start_scene_state = 0; + if(p) { + if(!strcmp(p, "AddManually")) { + start_scene_state = SubmenuIndexAddManually; + p = NULL; + } else if(!strcmp(p, "AddManuallyAdvanced")) { + start_scene_state = SubmenuIndexAddManuallyAdvanced; + p = NULL; + } + } + bool alloc_for_tx; if(p && strlen(p)) { alloc_for_tx = true; @@ -432,6 +472,7 @@ int32_t subghz_app(char* p) { view_dispatcher_attach_to_gui( subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneStart, start_scene_state); if(subghz_txrx_is_database_loaded(subghz->txrx)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); } else { @@ -459,3 +500,35 @@ int32_t subghz_app(char* p) { return 0; } +#else +int32_t subghz_add_manually(void* p) { + enum SubmenuIndex add_manually_scene_state = 0; + if(p) { + if(!strcmp(p, "AddManually")) { + add_manually_scene_state = SubmenuIndexAddManually; + } else if(!strcmp(p, "AddManuallyAdvanced")) { + add_manually_scene_state = SubmenuIndexAddManuallyAdvanced; + } + } + if(!add_manually_scene_state) return 0; + + bool alloc_for_tx = false; + SubGhz* subghz = subghz_alloc(alloc_for_tx); + UNUSED(subghz_rpc_command_callback); + UNUSED(subghz_load_custom_presets); + + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneSetType, add_manually_scene_state); + + view_dispatcher_attach_to_gui( + subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); + furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetType); + + view_dispatcher_run(subghz->view_dispatcher); + + subghz_free(subghz, alloc_for_tx); + + return 0; +} +#endif diff --git a/applications/main/subghz/subghz_history.c b/applications/main/subghz/subghz_history.c index 697c9ff5b..39896ce88 100644 --- a/applications/main/subghz/subghz_history.c +++ b/applications/main/subghz/subghz_history.c @@ -5,7 +5,8 @@ #include #define SUBGHZ_HISTORY_MAX 65535 // uint16_t index max, ram limit below -#define SUBGHZ_HISTORY_FREE_HEAP (10240 * (3 - MIN(rpc_get_sessions_count(instance->rpc), 2U))) +// #define SUBGHZ_HISTORY_FREE_HEAP (23624 * (1 - MIN(rpc_get_sessions_count(instance->rpc), 1U))) +#define SUBGHZ_HISTORY_FREE_HEAP (4 * 1024) #define TAG "SubGhzHistory" @@ -199,11 +200,11 @@ bool subghz_history_get_text_space_left( furi_assert(instance); if(!ignore_full) { if(memmgr_get_free_heap() < SUBGHZ_HISTORY_FREE_HEAP) { - if(output != NULL) furi_string_printf(output, " Memory is FULL"); + if(output != NULL) furi_string_set(output, "Memory is FULL"); return true; } if(instance->last_index_write == SUBGHZ_HISTORY_MAX) { - if(output != NULL) furi_string_printf(output, " History is FULL"); + if(output != NULL) furi_string_set(output, "History is FULL"); return true; } } diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index 47772ac2d..960cbd38c 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -435,8 +435,10 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_draw_str(canvas, 44, 62, frequency_str); #ifdef SUBGHZ_EXT_PRESET_NAME if(model->history_item == 0 && model->mode == SubGhzViewReceiverModeLive) { - canvas_draw_str( - canvas, 44 + canvas_string_width(canvas, frequency_str) + 1, 62, "MHz"); + if(*frequency_str) { + canvas_draw_str( + canvas, 44 + canvas_string_width(canvas, frequency_str) + 1, 62, "MHz"); + } const char* str = furi_string_get_cstr(model->preset_str); const uint8_t vertical_offset = 7; const uint8_t horizontal_offset = 3; diff --git a/applications/main/subghz/views/subghz_read_raw.c b/applications/main/subghz/views/subghz_read_raw.c index c9c01e2ec..5571e7780 100644 --- a/applications/main/subghz/views/subghz_read_raw.c +++ b/applications/main/subghz/views/subghz_read_raw.c @@ -151,11 +151,12 @@ void subghz_read_raw_update_sin(SubGhzReadRAW* instance) { } static int8_t subghz_read_raw_tab_sin(uint8_t x) { - const uint8_t tab_sin[64] = {0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37, - 40, 43, 46, 49, 51, 54, 57, 60, 63, 65, 68, 71, 73, - 76, 78, 81, 83, 85, 88, 90, 92, 94, 96, 98, 100, 102, - 104, 106, 107, 109, 111, 112, 113, 115, 116, 117, 118, 120, 121, - 122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127}; + static const uint8_t tab_sin[64] = {0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, + 34, 37, 40, 43, 46, 49, 51, 54, 57, 60, 63, + 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, 90, + 92, 94, 96, 98, 100, 102, 104, 106, 107, 109, 111, + 112, 113, 115, 116, 117, 118, 120, 121, 122, 122, 123, + 124, 125, 125, 126, 126, 126, 127, 127, 127}; int8_t r = tab_sin[((x & 0x40) ? -x - 1 : x) & 0x3f]; if(x & 0x80) return -r; diff --git a/firmware.scons b/firmware.scons index bbd4a54a4..cb6e47e22 100644 --- a/firmware.scons +++ b/firmware.scons @@ -217,12 +217,12 @@ sources.extend( ) # Link-Time Optimization for firmware dfu only, we are desperately out of flash space -if ENV["COMPACT"]: - fwenv.Append( - CCFLAGS=[ - "-flto", - ], - ) +# if ENV["COMPACT"]: +# fwenv.Append( +# CCFLAGS=[ +# "-flto", +# ], +# ) # Debug # print(fwenv.Dump()) diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 1634dff7e..2bd11bd2a 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -2,7 +2,6 @@ entry,status,name,type,params Version,+,87.1,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/main/archive/helpers/archive_helpers_ext.h,, -Header,+,applications/main/subghz/subghz_fap.h,, Header,+,applications/services/applications.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, @@ -3614,7 +3613,6 @@ Function,-,strupr,char*,char* Function,-,strverscmp,int,"const char*, const char*" Function,-,strxfrm,size_t,"char*, const char*, size_t" Function,-,strxfrm_l,size_t,"char*, const char*, size_t, locale_t" -Function,+,subghz_app,int32_t,char* Function,+,subghz_block_generic_deserialize,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*" Function,+,subghz_block_generic_deserialize_check_count_bit,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*, uint16_t" Function,+,subghz_block_generic_get_preset_name,void,"const char*, FuriString*"