diff --git a/applications/main/subghz/scenes/subghz_scene_config.h b/applications/main/subghz/scenes/subghz_scene_config.h index b12a66f9845f..f0d47723ccd6 100644 --- a/applications/main/subghz/scenes/subghz_scene_config.h +++ b/applications/main/subghz/scenes/subghz_scene_config.h @@ -23,4 +23,5 @@ ADD_SCENE(subghz, more_raw, MoreRAW) ADD_SCENE(subghz, decode_raw, DecodeRAW) ADD_SCENE(subghz, delete_raw, DeleteRAW) ADD_SCENE(subghz, need_saving, NeedSaving) +ADD_SCENE(subghz, need_saving_RX, NeedSavingRX) ADD_SCENE(subghz, rpc, Rpc) \ No newline at end of file diff --git a/applications/main/subghz/scenes/subghz_scene_need_saving_RX.c b/applications/main/subghz/scenes/subghz_scene_need_saving_RX.c new file mode 100644 index 000000000000..802e1c514e2e --- /dev/null +++ b/applications/main/subghz/scenes/subghz_scene_need_saving_RX.c @@ -0,0 +1,67 @@ +#include "../subghz_i.h" +#include "../helpers/subghz_custom_event.h" + +void subghz_scene_need_saving_RX_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + SubGhz* subghz = context; + + if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneStay); + } else if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit); + } +} + +void subghz_scene_need_saving_RX_on_enter(void* context) { + SubGhz* subghz = context; + + widget_add_string_multiline_element( + subghz->widget, 64, 13, AlignCenter, AlignCenter, FontPrimary, "Start Listening?"); + widget_add_string_multiline_element( + subghz->widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + "All unsaved data\nwill be lost!"); + + widget_add_button_element( + subghz->widget, GuiButtonTypeLeft, "Stay", subghz_scene_need_saving_RX_callback, subghz); + widget_add_button_element( + subghz->widget, GuiButtonTypeRight, "Listen", subghz_scene_need_saving_RX_callback, subghz); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdWidget); +} + +bool subghz_scene_need_saving_RX_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + if(event.type == SceneManagerEventTypeBack) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateBack); + scene_manager_previous_scene(subghz->scene_manager); + return true; + } else if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubGhzCustomEventSceneStay) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateBack); + scene_manager_previous_scene(subghz->scene_manager); + return true; + } else if(event.event == SubGhzCustomEventSceneExit) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); + if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneReceiver)) { + //Scene exists, go back to it + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneReceiver); + } else { + //Scene not started, start it now. + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver); + } + return true; + } + } + return false; +} + +void subghz_scene_need_saving_RX_on_exit(void* context) { + SubGhz* subghz = context; + widget_reset(subghz->widget); +} diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 5ce86e6b612f..0f3fe295e69e 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -256,6 +256,27 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz_txrx_stop(subghz->txrx); subghz_read_raw_stop_send(subghz->subghz_read_raw); consumed = true; + + //Go back to the Scan/Repeater if the Listen After TX flag is on. + if(subghz->ListenAfterTX) { + //needed save? + if((subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateAddKey) || + (subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateBack)) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateExit); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSavingRX); + } else { + if(scene_manager_has_previous_scene( + subghz->scene_manager, SubGhzSceneReceiver)) { + //Scene exists, go back to it + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneReceiver); + } else { + //Scene not started, start it now. + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver); + } + } + }; + break; case SubGhzCustomEventViewReadRAWIDLE: diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index c5cdb9558c10..ecc79d4a3706 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -10,6 +10,7 @@ enum SubGhzSettingIndex { SubGhzSettingIndexBinRAW, SubGhzSettingIndexRepeater, SubGhzSettingIndexSound, + SubGhzSettingIndexListenAfterTX, SubGhzSettingIndexIgnoreStarline, SubGhzSettingIndexIgnoreCars, SubGhzSettingIndexIgnoreMagellan, @@ -74,6 +75,11 @@ const uint32_t repeater_value[REPEATER_BOX_COUNT] = { SubGhzRepeaterOnShort, }; +const uint32_t listen_after_tx_value[COMBO_BOX_COUNT] = { + false, + true, +}; + const char* const combobox_text[COMBO_BOX_COUNT] = { "OFF", "ON", @@ -263,6 +269,17 @@ static void subghz_scene_receiver_config_set_bin_raw(VariableItem* item) { subghz->last_settings->filter = subghz->filter; } +static void subghz_scene_receiver_config_set_listen_after_tx(VariableItem* item) { + SubGhz* subghz = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, combobox_text[index]); + subghz->ListenAfterTX = listen_after_tx_value[index]; + + // We can set here, but during subghz_last_settings_save filter was changed to ignore BinRAW + subghz->last_settings->enable_listen_after_tx = subghz->ListenAfterTX; +} + static void subghz_scene_receiver_config_set_repeater(VariableItem* item) { SubGhz* subghz = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); @@ -495,6 +512,23 @@ void subghz_scene_receiver_config_on_enter(void* context) { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, combobox_text[value_index]); + /* And now we have the WakeUp commmand for the Repeater. Set this, record the wake up code from the car. + take wake up command to fob, play back and be in repeater or read to get the key to open and start. + Power of Repeated command may have to be played with in future so cars dont detect too much power from key. + Im sure theres a milion other ways you can set this up to do other stuff, but the Wake Up is easy now! + Time to imagine the other uses, and make sure we can accomdateg them! + */ + item = variable_item_list_add( + subghz->variable_item_list, + "Listen after TX", + COMBO_BOX_COUNT, + subghz_scene_receiver_config_set_listen_after_tx, + subghz); + value_index = + value_index_uint32(subghz->ListenAfterTX, listen_after_tx_value, COMBO_BOX_COUNT); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, combobox_text[value_index]); + if(!IsReadRAWScene) { item = variable_item_list_add( subghz->variable_item_list, diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index 0a639e56cfaa..3283dbfa09fe 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -112,8 +112,6 @@ void subghz_scene_receiver_info_draw_widget(SubGhz* subghz) { widget_add_string_element( subghz->widget, 13, 8, AlignLeft, AlignBottom, FontSecondary, "Error history parse."); } - - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdWidget); } void subghz_scene_receiver_info_on_enter(void* context) { @@ -122,6 +120,7 @@ void subghz_scene_receiver_info_on_enter(void* context) { subghz_custom_btns_reset(); subghz_scene_receiver_info_draw_widget(subghz); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdWidget); /* This does not work. The receiving does not happen, and they know it. So, why do we turn on the notification that we receive? @@ -162,11 +161,24 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) } else if(event.event == SubGhzCustomEventSceneReceiverInfoTxStop) { //CC1101 Stop Tx -> Start RX subghz->state_notifications = SubGhzNotificationStateIDLE; + subghz_txrx_stop(subghz->txrx); - widget_reset(subghz->widget); - subghz_scene_receiver_info_draw_widget(subghz); + //Go back to the Scan/Repeater if the Listen After TX flag is on. + if(subghz->ListenAfterTX) { + if(scene_manager_has_previous_scene( + subghz->scene_manager, SubGhzSceneReceiverInfo)) { + //Scene exists, go back to it + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneReceiver); + } else { + //Scene not started, start it now. + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver); + } + } else { + widget_reset(subghz->widget); + subghz_scene_receiver_info_draw_widget(subghz); + } - subghz_txrx_stop(subghz->txrx); // if(!scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneDecodeRAW)) { // subghz_txrx_rx_start(subghz->txrx); diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 39eac76a5fac..6217798c575a 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -56,6 +56,9 @@ void subghz_scene_transmitter_on_enter(void* context) { subghz_view_transmitter_set_callback( subghz->subghz_transmitter, subghz_scene_transmitter_callback, subghz); + //Put the Listen after TX back to what the user selected.. + subghz->ListenAfterTX = subghz->last_settings->enable_listen_after_tx; + subghz->state_notifications = SubGhzNotificationStateIDLE; view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTransmitter); } @@ -88,6 +91,19 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { subghz_txrx_stop(subghz->txrx); furi_hal_subghz_set_rolling_counter_mult(tmp_counter); } + + //Go back to the Scan/Repeater if the Listen After TX flag is on. + if(subghz->ListenAfterTX) { + if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneReceiver)) { + //Scene exists, go back to it + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneReceiver); + } else { + //Scene not started, start it now. + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver); + } + }; + return true; } else if(event.event == SubGhzCustomEventViewTransmitterBack) { subghz->state_notifications = SubGhzNotificationStateIDLE; diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index b5e6371e983c..5509a6b9487a 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -217,6 +217,9 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz->secure_data = malloc(sizeof(SecureData)); + //Put the Listen after TX back to what the user selected.. + subghz->ListenAfterTX = subghz->last_settings->enable_listen_after_tx; + if(!alloc_for_tx_only) { subghz->ignore_filter = subghz->last_settings->ignore_filter; subghz->filter = subghz->last_settings->filter; diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index f86a1135edb4..7789ebed4dd4 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -90,6 +90,7 @@ struct SubGhz { uint32_t RepeaterStartTime; VariableItem* BIN_Raw_menu; bool BINRawStateChanged; + bool ListenAfterTX; SecureData* secure_data; diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index d91c36eef2d3..16f73b30d02f 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -20,6 +20,7 @@ #define SUBGHZ_LAST_SETTING_FIELD_FILTER "Filter" #define SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD "RSSI" #define SUBGHZ_LAST_SETTING_FIELD_REPEATER "Repeater" +#define SUBGHZ_LAST_SETTING_FIELD_LISTEN_AFTER_TX "ListenAfterTX" SubGhzLastSettings* subghz_last_settings_alloc(void) { SubGhzLastSettings* instance = malloc(sizeof(SubGhzLastSettings)); @@ -45,6 +46,7 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count bool temp_external_module_power_amp = false; bool temp_timestamp_file_names = false; bool temp_enable_hopping = false; + bool temp_enable_listen_after_tx = false; uint32_t temp_RepeaterState = false; uint32_t temp_ignore_filter = 0; uint32_t temp_filter = 0; @@ -110,6 +112,11 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FILTER, (uint32_t*)&temp_filter, 1); flipper_format_read_uint32( fff_data_file, SUBGHZ_LAST_SETTING_FIELD_REPEATER, (uint32_t*)&temp_RepeaterState, 1); + flipper_format_read_bool( + fff_data_file, + SUBGHZ_LAST_SETTING_FIELD_LISTEN_AFTER_TX, + (bool*)&temp_enable_listen_after_tx, + 1); } else { FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH); @@ -127,6 +134,7 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count instance->timestamp_file_names = false; instance->external_module_power_amp = false; instance->enable_hopping = false; + instance->enable_listen_after_tx = false; instance->ignore_filter = 0x00; // See bin_raw_value in applications/main/subghz/scenes/subghz_scene_receiver_config.c instance->filter = SubGhzProtocolFlag_Decodable; @@ -167,6 +175,7 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count instance->rssi = rssi_was_read ? temp_rssi : SUBGHZ_RAW_THRESHOLD_MIN; instance->enable_hopping = temp_enable_hopping; + instance->enable_listen_after_tx = temp_enable_listen_after_tx; instance->RepeaterState = temp_RepeaterState; instance->ignore_filter = ignore_filter_was_read ? temp_ignore_filter : 0x00; #if SUBGHZ_LAST_SETTING_SAVE_BIN_RAW @@ -281,6 +290,13 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) { file, SUBGHZ_LAST_SETTING_FIELD_REPEATER, &instance->RepeaterState, 1)) { break; } + if(!flipper_format_insert_or_update_bool( + file, + SUBGHZ_LAST_SETTING_FIELD_LISTEN_AFTER_TX, + &instance->enable_listen_after_tx, + 1)) { + break; + } saved = true; } while(0); @@ -314,7 +330,7 @@ void subghz_last_settings_log(SubGhzLastSettings* instance) { TAG, "Frequency: %03ld.%02ld, FeedbackLevel: %ld, FATrigger: %.2f, External: %s, ExtPower: %s, TimestampNames: %s, ExtPowerAmp: %s,\n" "Hopping: %s,\nPreset: %ld, RSSI: %.2f, " - "Starline: %s, Cars: %s, Magellan: %s, NiceFloR-S: %s, BinRAW: %s", + "Starline: %s, Cars: %s, Magellan: %s, NiceFloR-S: %s, BinRAW: %s, Repeater: %lu, ListenAfterTX %s", instance->frequency / 1000000 % 1000, instance->frequency / 10000 % 100, instance->frequency_analyzer_feedback_level, @@ -334,5 +350,7 @@ void subghz_last_settings_log(SubGhzLastSettings* instance) { instance->ignore_filter, SubGhzProtocolFlag_Magellan), subghz_last_settings_log_filter_get_index( instance->ignore_filter, SubGhzProtocolFlag_NiceFlorS), - subghz_last_settings_log_filter_get_index(instance->filter, SubGhzProtocolFlag_BinRAW)); + subghz_last_settings_log_filter_get_index(instance->filter, SubGhzProtocolFlag_BinRAW), + instance->RepeaterState, + bool_to_char(instance->enable_listen_after_tx)); } diff --git a/applications/main/subghz/subghz_last_settings.h b/applications/main/subghz/subghz_last_settings.h index 16eef3e69f40..263f909dbcf3 100644 --- a/applications/main/subghz/subghz_last_settings.h +++ b/applications/main/subghz/subghz_last_settings.h @@ -27,6 +27,8 @@ typedef struct { // saved so as not to change the version bool timestamp_file_names; bool enable_hopping; + bool enable_listen_after_tx; + uint32_t RepeaterState; uint32_t ignore_filter; uint32_t filter;