From 3a86da5526282ff4eece5d397803c50d7b9293ec Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 22 Dec 2021 17:01:20 +0400 Subject: [PATCH] [FL-2139] SubGhz: refactoring GUI SubGhz (#910) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: refactoring GUI ReadRAW * SubGhz: replacing memcpy with strcpy * SubGhz: fix button name "Mode", fix delete scene, fix show name when loading a key * SubGhz: refactoring GUI SubGhz * scene_manager: add exit from last scene API * subghz: stop scene manager before stopping view dispatcher Co-authored-by: gornekich Co-authored-by: あく --- applications/gui/scene_manager.c | 9 + applications/gui/scene_manager.h | 6 + .../subghz/helpers/subghz_custom_event.h | 9 +- .../subghz/scenes/subghz_scene_config.h | 3 + .../subghz/scenes/subghz_scene_delete.c | 2 +- .../subghz/scenes/subghz_scene_delete_raw.c | 79 ++++++++ .../scenes/subghz_scene_delete_success.c | 7 +- .../subghz/scenes/subghz_scene_more_raw.c | 60 +++++++ .../subghz/scenes/subghz_scene_read_raw.c | 152 +++++++++------- .../subghz/scenes/subghz_scene_receiver.c | 18 +- .../subghz/scenes/subghz_scene_save_name.c | 15 +- .../subghz/scenes/subghz_scene_save_success.c | 7 +- .../subghz/scenes/subghz_scene_set_type.c | 5 +- .../subghz/scenes/subghz_scene_show_error.c | 82 ++++++--- .../scenes/subghz_scene_show_error_sub.c | 48 +++++ .../subghz/scenes/subghz_scene_start.c | 8 +- .../subghz/scenes/subghz_scene_transmitter.c | 2 +- applications/subghz/subghz.c | 42 +++-- applications/subghz/subghz_i.c | 2 +- applications/subghz/subghz_i.h | 1 + applications/subghz/views/subghz_read_raw.c | 169 ++++++++++++++---- applications/subghz/views/subghz_read_raw.h | 5 + lib/subghz/subghz_parser.c | 5 +- lib/subghz/subghz_parser.h | 3 +- 24 files changed, 580 insertions(+), 159 deletions(-) create mode 100644 applications/subghz/scenes/subghz_scene_delete_raw.c create mode 100644 applications/subghz/scenes/subghz_scene_more_raw.c create mode 100644 applications/subghz/scenes/subghz_scene_show_error_sub.c diff --git a/applications/gui/scene_manager.c b/applications/gui/scene_manager.c index f4492a58..a3aadb74 100755 --- a/applications/gui/scene_manager.c +++ b/applications/gui/scene_manager.c @@ -181,3 +181,12 @@ bool scene_manager_search_and_switch_to_another_scene( return true; } + +void scene_manager_stop(SceneManager* scene_manager) { + furi_assert(scene_manager); + + if(SceneManagerIdStack_size(scene_manager->scene_id_stack)) { + uint32_t cur_scene_id = *SceneManagerIdStack_back(scene_manager->scene_id_stack); + scene_manager->scene_handlers->on_exit_handlers[cur_scene_id](scene_manager->context); + } +} diff --git a/applications/gui/scene_manager.h b/applications/gui/scene_manager.h index 53f8d775..69162853 100755 --- a/applications/gui/scene_manager.h +++ b/applications/gui/scene_manager.h @@ -157,6 +157,12 @@ bool scene_manager_search_and_switch_to_another_scene( SceneManager* scene_manager, uint32_t scene_id); +/** Exit from current scene + * + * @param scene_manager SceneManager instance + */ +void scene_manager_stop(SceneManager* scene_manager); + #ifdef __cplusplus } #endif diff --git a/applications/subghz/helpers/subghz_custom_event.h b/applications/subghz/helpers/subghz_custom_event.h index 65b412f8..55363c41 100644 --- a/applications/subghz/helpers/subghz_custom_event.h +++ b/applications/subghz/helpers/subghz_custom_event.h @@ -6,12 +6,17 @@ typedef enum { SubghzCustomEventSceneDeleteSuccess = 100, SubghzCustomEventSceneDelete, + SubghzCustomEventSceneDeleteRAW, + SubghzCustomEventSceneDeleteRAWBack, + SubghzCustomEventSceneReceiverInfoTxStart, SubghzCustomEventSceneReceiverInfoTxStop, SubghzCustomEventSceneReceiverInfoSave, SubghzCustomEventSceneSaveName, SubghzCustomEventSceneSaveSuccess, - SubghzCustomEventSceneShowError, + SubghzCustomEventSceneShowErrorBack, + SubghzCustomEventSceneShowErrorOk, + SubghzCustomEventSceneShowErrorSub, SubghzCustomEventSceneShowOnlyRX, SubghzCustomEventSceneExit, @@ -30,6 +35,8 @@ typedef enum { SubghzCustomEventViewReadRAWSendStop, SubghzCustomEventViewReadRAWSave, SubghzCustomEventViewReadRAWVibro, + SubghzCustomEventViewReadRAWTXRXStop, + SubghzCustomEventViewReadRAWMore, SubghzCustomEventViewTransmitterBack, SubghzCustomEventViewTransmitterSendStart, diff --git a/applications/subghz/scenes/subghz_scene_config.h b/applications/subghz/scenes/subghz_scene_config.h index d0be3c00..71cd2668 100644 --- a/applications/subghz/scenes/subghz_scene_config.h +++ b/applications/subghz/scenes/subghz_scene_config.h @@ -7,6 +7,7 @@ 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, show_only_rx, ShowOnlyRx) ADD_SCENE(subghz, saved_menu, SavedMenu) ADD_SCENE(subghz, delete, Delete) @@ -18,4 +19,6 @@ ADD_SCENE(subghz, test_packet, TestPacket) ADD_SCENE(subghz, set_type, SetType) ADD_SCENE(subghz, frequency_analyzer, FrequencyAnalyzer) ADD_SCENE(subghz, read_raw, ReadRAW) +ADD_SCENE(subghz, more_raw, MoreRAW) +ADD_SCENE(subghz, delete_raw, DeleteRAW) ADD_SCENE(subghz, need_saving, NeedSaving) \ No newline at end of file diff --git a/applications/subghz/scenes/subghz_scene_delete.c b/applications/subghz/scenes/subghz_scene_delete.c index eb8a2217..9452946e 100644 --- a/applications/subghz/scenes/subghz_scene_delete.c +++ b/applications/subghz/scenes/subghz_scene_delete.c @@ -50,7 +50,7 @@ bool subghz_scene_delete_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubghzCustomEventSceneDelete) { - memcpy(subghz->file_name_tmp, subghz->file_name, strlen(subghz->file_name) + 1); + strcpy(subghz->file_name_tmp, subghz->file_name); if(subghz_delete_file(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); } else { diff --git a/applications/subghz/scenes/subghz_scene_delete_raw.c b/applications/subghz/scenes/subghz_scene_delete_raw.c new file mode 100644 index 00000000..5c620989 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_delete_raw.c @@ -0,0 +1,79 @@ +#include "../subghz_i.h" +#include "../helpers/subghz_custom_event.h" + +void subghz_scene_delete_raw_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + SubGhz* subghz = context; + if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubghzCustomEventSceneDeleteRAW); + } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubghzCustomEventSceneDeleteRAWBack); + } +} + +void subghz_scene_delete_raw_on_enter(void* context) { + SubGhz* subghz = context; + string_t frequency_str; + string_t modulation_str; + string_t text; + + string_init(frequency_str); + string_init(modulation_str); + string_init(text); + + string_printf(text, "Delete\n%s?", subghz->file_name); + widget_add_string_multiline_element( + subghz->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, string_get_cstr(text)); + + widget_add_string_element( + subghz->widget, 38, 25, AlignLeft, AlignTop, FontSecondary, "RAW signal"); + subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + widget_add_string_element( + subghz->widget, 35, 37, AlignLeft, AlignTop, FontSecondary, string_get_cstr(frequency_str)); + + widget_add_string_element( + subghz->widget, + 72, + 37, + AlignLeft, + AlignTop, + FontSecondary, + string_get_cstr(modulation_str)); + + string_clear(frequency_str); + string_clear(modulation_str); + string_clear(text); + + widget_add_button_element( + subghz->widget, GuiButtonTypeRight, "Delete", subghz_scene_delete_raw_callback, subghz); + widget_add_button_element( + subghz->widget, GuiButtonTypeLeft, "Back", subghz_scene_delete_raw_callback, subghz); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewWidget); +} + +bool subghz_scene_delete_raw_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubghzCustomEventSceneDeleteRAW) { + strcpy(subghz->file_name_tmp, subghz->file_name); + if(subghz_delete_file(subghz)) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); + } else { + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneStart); + } + return true; + } else if(event.event == SubghzCustomEventSceneDeleteRAWBack) { + return scene_manager_previous_scene(subghz->scene_manager); + } + } + return false; +} + +void subghz_scene_delete_raw_on_exit(void* context) { + SubGhz* subghz = context; + widget_clear(subghz->widget); +} diff --git a/applications/subghz/scenes/subghz_scene_delete_success.c b/applications/subghz/scenes/subghz_scene_delete_success.c index 04b48531..8c67e3c5 100644 --- a/applications/subghz/scenes/subghz_scene_delete_success.c +++ b/applications/subghz/scenes/subghz_scene_delete_success.c @@ -26,8 +26,11 @@ bool subghz_scene_delete_success_on_event(void* context, SceneManagerEvent event if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubghzCustomEventSceneDeleteSuccess) { - return scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneStart); + if(!scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneSaved)) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); + } + return true; } } return false; diff --git a/applications/subghz/scenes/subghz_scene_more_raw.c b/applications/subghz/scenes/subghz_scene_more_raw.c new file mode 100644 index 00000000..c8fde230 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_more_raw.c @@ -0,0 +1,60 @@ +#include "../subghz_i.h" + +enum SubmenuIndex { + SubmenuIndexEdit, + SubmenuIndexDelete, +}; + +void subghz_scene_more_raw_submenu_callback(void* context, uint32_t index) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, index); +} + +void subghz_scene_more_raw_on_enter(void* context) { + SubGhz* subghz = context; + + submenu_add_item( + subghz->submenu, + "Edit name", + SubmenuIndexEdit, + subghz_scene_more_raw_submenu_callback, + subghz); + + submenu_add_item( + subghz->submenu, + "Delete", + SubmenuIndexDelete, + subghz_scene_more_raw_submenu_callback, + subghz); + + submenu_set_selected_item( + subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneMoreRAW)); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewMenu); +} + +bool subghz_scene_more_raw_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexDelete) { + 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(event.event == SubmenuIndexEdit) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneMoreRAW, SubmenuIndexEdit); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + return true; + } + } + return false; +} + +void subghz_scene_more_raw_on_exit(void* context) { + SubGhz* subghz = context; + submenu_clean(subghz->submenu); +} diff --git a/applications/subghz/scenes/subghz_scene_read_raw.c b/applications/subghz/scenes/subghz_scene_read_raw.c index 615df4cb..aaa51c76 100644 --- a/applications/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/subghz/scenes/subghz_scene_read_raw.c @@ -6,6 +6,32 @@ #define RAW_FILE_NAME "Raw_temp" +bool subghz_scene_read_raw_update_filename(SubGhz* subghz) { + bool ret = false; + //set the path to read the file + if(strcmp( + subghz_protocol_raw_get_last_file_name( + (SubGhzProtocolRAW*)subghz->txrx->protocol_result), + "")) { + string_t temp_str; + string_init_printf( + temp_str, + "%s", + subghz_protocol_raw_get_last_file_name( + (SubGhzProtocolRAW*)subghz->txrx->protocol_result)); + path_extract_filename_no_ext(string_get_cstr(temp_str), temp_str); + strcpy(subghz->file_name, string_get_cstr(temp_str)); + string_printf( + temp_str, "%s/%s%s", SUBGHZ_APP_PATH_FOLDER, subghz->file_name, SUBGHZ_APP_EXTENSION); + + subghz_protocol_raw_set_last_file_name( + (SubGhzProtocolRAW*)subghz->txrx->protocol_result, string_get_cstr(temp_str)); + string_clear(temp_str); + ret = true; + } + return ret; +} + static void subghz_scene_read_raw_update_statusbar(void* context) { furi_assert(context); SubGhz* subghz = context; @@ -40,15 +66,24 @@ void subghz_scene_read_raw_callback_end_tx(void* context) { void subghz_scene_read_raw_on_enter(void* context) { SubGhz* subghz = context; - if(subghz->txrx->rx_key_state == SubGhzRxKeyStateBack) { + switch(subghz->txrx->rx_key_state) { + case SubGhzRxKeyStateBack: subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusIDLE, ""); - } else if(subghz->txrx->rx_key_state == SubGhzRxKeyStateRAWLoad) { + break; + case SubGhzRxKeyStateRAWLoad: subghz_read_raw_set_status( - subghz->subghz_read_raw, SubghzReadRAWStatusTX, subghz->file_name); - subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; - } else { + subghz->subghz_read_raw, SubghzReadRAWStatusLoadKeyTX, subghz->file_name); + subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + break; + case SubGhzRxKeyStateRAWSave: + subghz_read_raw_set_status( + subghz->subghz_read_raw, SubghzReadRAWStatusSaveKey, subghz->file_name); + subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + break; + default: subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusStart, ""); subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + break; } subghz_scene_read_raw_update_statusbar(subghz); @@ -96,53 +131,64 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { //Restore default setting subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; - scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneStart); + if(!scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneSaved)) { + 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; break; + + case SubghzCustomEventViewReadRAWTXRXStop: + //Stop TX + if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { + subghz_tx_stop(subghz); + subghz_sleep(subghz); + } + //Stop RX + if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { + subghz_rx_end(subghz); + subghz_sleep(subghz); + }; + subghz->state_notifications = SubGhzNotificationStateIDLE; + return true; + break; + case SubghzCustomEventViewReadRAWConfig: scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); return true; break; + case SubghzCustomEventViewReadRAWErase: subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; return true; break; + case SubghzCustomEventViewReadRAWVibro: notification_message(subghz->notifications, &sequence_single_vibro); return true; break; - case SubghzCustomEventViewReadRAWSendStart: - //set the path to read the file - if(strcmp( - subghz_protocol_raw_get_last_file_name( - (SubGhzProtocolRAW*)subghz->txrx->protocol_result), - "")) { - string_t temp_str; - string_init_printf( - temp_str, - "%s", - subghz_protocol_raw_get_last_file_name( - (SubGhzProtocolRAW*)subghz->txrx->protocol_result)); - path_extract_filename_no_ext(string_get_cstr(temp_str), temp_str); - strlcpy( - subghz->file_name, - string_get_cstr(temp_str), - strlen(string_get_cstr(temp_str)) + 1); - string_printf( - temp_str, - "%s/%s%s", - SUBGHZ_APP_PATH_FOLDER, - subghz->file_name, - SUBGHZ_APP_EXTENSION); - subghz_protocol_raw_set_last_file_name( - (SubGhzProtocolRAW*)subghz->txrx->protocol_result, string_get_cstr(temp_str)); - string_clear(temp_str); + case SubghzCustomEventViewReadRAWMore: + if(subghz_scene_read_raw_update_filename(subghz)) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet); + subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneMoreRAW); + return true; + } else { + furi_crash(NULL); + } + break; + + case SubghzCustomEventViewReadRAWSendStart: + if(subghz_scene_read_raw_update_filename(subghz)) { //start send subghz->state_notifications = SubGhzNotificationStateIDLE; if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { @@ -154,12 +200,12 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); } else { subghz->state_notifications = SubGhzNotificationStateTX; - subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } } } return true; break; + case SubghzCustomEventViewReadRAWSendStop: subghz->state_notifications = SubGhzNotificationStateIDLE; if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { @@ -169,6 +215,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz_read_raw_stop_send(subghz->subghz_read_raw); return true; break; + case SubghzCustomEventViewReadRAWIDLE: if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { subghz_rx_end(subghz); @@ -182,8 +229,8 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { return true; break; - case SubghzCustomEventViewReadRAWREC: + case SubghzCustomEventViewReadRAWREC: if(subghz->txrx->rx_key_state != SubGhzRxKeyStateIDLE) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { @@ -199,42 +246,17 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz_rx(subghz, subghz->txrx->frequency); } subghz->state_notifications = SubGhzNotificationStateRX; + subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } else { - string_set(subghz->error_str, "No SD card"); + string_set(subghz->error_str, "Function requires\nan SD card."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } } - return true; break; + case SubghzCustomEventViewReadRAWSave: - if(strcmp( - subghz_protocol_raw_get_last_file_name( - (SubGhzProtocolRAW*)subghz->txrx->protocol_result), - "")) { - string_t temp_str; - string_init_printf( - temp_str, - "%s", - subghz_protocol_raw_get_last_file_name( - (SubGhzProtocolRAW*)subghz->txrx->protocol_result)); - path_extract_filename_no_ext(string_get_cstr(temp_str), temp_str); - strlcpy( - subghz->file_name, - string_get_cstr(temp_str), - strlen(string_get_cstr(temp_str)) + 1); - - //set the path to read the file - string_printf( - temp_str, - "%s/%s%s", - SUBGHZ_APP_PATH_FOLDER, - subghz->file_name, - SUBGHZ_APP_EXTENSION); - subghz_protocol_raw_set_last_file_name( - (SubGhzProtocolRAW*)subghz->txrx->protocol_result, string_get_cstr(temp_str)); - string_clear(temp_str); - + if(subghz_scene_read_raw_update_filename(subghz)) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet); subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index 53b72c1a..a2eb4af2 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -56,6 +56,7 @@ void subghz_scene_add_to_history_callback(SubGhzProtocolCommon* parser, void* co subghz_scene_receiver_update_statusbar(subghz); } string_clear(str_buff); + subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } void subghz_scene_receiver_on_enter(void* context) { @@ -64,6 +65,10 @@ void subghz_scene_receiver_on_enter(void* context) { string_t str_buff; string_init(str_buff); + if(subghz->txrx->rx_key_state == SubGhzRxKeyStateIDLE) { + subghz_history_clean(subghz->txrx->history); + } + //Load history to receiver subghz_receiver_exit(subghz->subghz_receiver); for(uint8_t i = 0; i < subghz_history_get_item(subghz->txrx->history); i++) { @@ -73,6 +78,7 @@ void subghz_scene_receiver_on_enter(void* context) { subghz->subghz_receiver, string_get_cstr(str_buff), subghz_history_get_type_protocol(subghz->txrx->history, i)); + subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } string_clear(str_buff); subghz_scene_receiver_update_statusbar(subghz); @@ -99,20 +105,26 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { case SubghzCustomEventViewReceverBack: + // Stop CC1101 Rx subghz->state_notifications = SubGhzNotificationStateIDLE; if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { subghz_rx_end(subghz); subghz_sleep(subghz); }; - subghz_history_clean(subghz->txrx->history); subghz->txrx->hopper_state = SubGhzHopperStateOFF; subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; subghz->txrx->idx_menu_chosen = 0; subghz_parser_enable_dump(subghz->txrx->parser, NULL, subghz); - scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneStart); + + if(subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) { + subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); + } else { + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneStart); + } return true; break; case SubghzCustomEventViewReceverOK: diff --git a/applications/subghz/scenes/subghz_scene_save_name.c b/applications/subghz/scenes/subghz_scene_save_name.c index 4442d39d..40be8fea 100644 --- a/applications/subghz/scenes/subghz_scene_save_name.c +++ b/applications/subghz/scenes/subghz_scene_save_name.c @@ -20,7 +20,7 @@ void subghz_scene_save_name_on_enter(void* context) { set_random_name(subghz->file_name, sizeof(subghz->file_name)); } else { - memcpy(subghz->file_name_tmp, subghz->file_name, strlen(subghz->file_name) + 1); + strcpy(subghz->file_name_tmp, subghz->file_name); if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == SubghzCustomEventManagerSet) { subghz_get_next_name_file(subghz); @@ -42,8 +42,11 @@ void subghz_scene_save_name_on_enter(void* context) { bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; - - if(event.type == SceneManagerEventTypeCustom) { + if(event.type == SceneManagerEventTypeBack) { + strcpy(subghz->file_name, subghz->file_name_tmp); + scene_manager_previous_scene(subghz->scene_manager); + return true; + } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubghzCustomEventSceneSaveName) { if(strcmp(subghz->file_name, "")) { if(strcmp(subghz->file_name_tmp, "")) { @@ -56,13 +59,15 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { SubghzCustomEventManagerSet) { subghz_protocol_raw_set_last_file_name( (SubGhzProtocolRAW*)subghz->txrx->protocol_result, subghz->file_name); + } else { + subghz_file_name_clear(subghz); } - subghz_file_name_clear(subghz); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); return true; } else { string_set(subghz->error_str, "No name file"); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); return true; } } diff --git a/applications/subghz/scenes/subghz_scene_save_success.c b/applications/subghz/scenes/subghz_scene_save_success.c index 7509abd8..923a06b6 100644 --- a/applications/subghz/scenes/subghz_scene_save_success.c +++ b/applications/subghz/scenes/subghz_scene_save_success.c @@ -26,10 +26,13 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) if(event.event == SubghzCustomEventSceneSaveSuccess) { if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneReceiver)) { + subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWSave; if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneReadRAW)) { - scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneStart); + if(!scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneSaved)) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); + } } } return true; diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index 331b9dc2..ea88baf8 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -19,7 +19,7 @@ bool subghz_scene_set_type_submenu_to_find_protocol(void* context, const char* p subghz->txrx->protocol_result = subghz_parser_get_by_name(subghz->txrx->parser, protocol_name); if(subghz->txrx->protocol_result == NULL) { string_set(subghz->error_str, "Protocol not found"); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); return false; } return true; @@ -177,7 +177,8 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { generated_protocol = true; } else { generated_protocol = false; - string_set(subghz->error_str, "No manufactory key"); + string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } } diff --git a/applications/subghz/scenes/subghz_scene_show_error.c b/applications/subghz/scenes/subghz_scene_show_error.c index d8f2e050..1e450f1e 100644 --- a/applications/subghz/scenes/subghz_scene_show_error.c +++ b/applications/subghz/scenes/subghz_scene_show_error.c @@ -1,31 +1,74 @@ #include "../subghz_i.h" #include "../helpers/subghz_custom_event.h" -void subghz_scene_show_error_popup_callback(void* context) { +void subghz_scene_show_error_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); SubGhz* subghz = context; - view_dispatcher_send_custom_event(subghz->view_dispatcher, SubghzCustomEventSceneShowError); + + if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubghzCustomEventSceneShowErrorOk); + } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubghzCustomEventSceneShowErrorBack); + } } void subghz_scene_show_error_on_enter(void* context) { SubGhz* subghz = context; - // Setup view - Popup* popup = subghz->popup; - popup_set_icon(popup, 32, 12, &I_DolphinFirstStart7_61x51); - popup_set_header(popup, string_get_cstr(subghz->error_str), 64, 8, AlignCenter, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, subghz); - popup_set_callback(popup, subghz_scene_show_error_popup_callback); - popup_enable_timeout(popup); - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewPopup); + widget_add_icon_element(subghz->widget, 0, 0, &I_SDQuestion_35x43); + + widget_add_string_multiline_element( + subghz->widget, + 81, + 24, + AlignCenter, + AlignCenter, + FontSecondary, + string_get_cstr(subghz->error_str)); + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneShowError) == + SubghzCustomEventManagerSet) { + widget_add_button_element( + subghz->widget, GuiButtonTypeRight, "Ok", subghz_scene_show_error_callback, subghz); + } + + widget_add_button_element( + subghz->widget, GuiButtonTypeLeft, "Back", subghz_scene_show_error_callback, subghz); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewWidget); } bool subghz_scene_show_error_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubghzCustomEventSceneShowError) { + if(event.type == SceneManagerEventTypeBack) { + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneShowError) == + SubghzCustomEventManagerSet) { + return false; + } else { scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); + } + return true; + } else if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubghzCustomEventSceneShowErrorOk) { + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneShowError) == + SubghzCustomEventManagerSet) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); + } + return true; + } else if(event.event == SubghzCustomEventSceneShowErrorBack) { + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneShowError) == + SubghzCustomEventManagerSet) { + //exit app + if(!scene_manager_previous_scene(subghz->scene_manager)) { + scene_manager_stop(subghz->scene_manager); + view_dispatcher_stop(subghz->view_dispatcher); + } + } else { + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneStart); + } return true; } } @@ -34,15 +77,8 @@ bool subghz_scene_show_error_on_event(void* context, SceneManagerEvent event) { void subghz_scene_show_error_on_exit(void* context) { SubGhz* subghz = context; - - // Clear view - Popup* popup = subghz->popup; - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - popup_set_callback(popup, NULL); - popup_set_context(popup, NULL); - popup_set_timeout(popup, 0); - popup_disable_timeout(popup); + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneShowError, SubghzCustomEventManagerNoSet); + widget_clear(subghz->widget); string_reset(subghz->error_str); } diff --git a/applications/subghz/scenes/subghz_scene_show_error_sub.c b/applications/subghz/scenes/subghz_scene_show_error_sub.c new file mode 100644 index 00000000..566e6451 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_show_error_sub.c @@ -0,0 +1,48 @@ +#include "../subghz_i.h" +#include "../helpers/subghz_custom_event.h" + +void subghz_scene_show_error_sub_popup_callback(void* context) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubghzCustomEventSceneShowErrorSub); +} + +void subghz_scene_show_error_sub_on_enter(void* context) { + SubGhz* subghz = context; + + // Setup view + Popup* popup = subghz->popup; + popup_set_icon(popup, 32, 12, &I_DolphinFirstStart7_61x51); + popup_set_header(popup, string_get_cstr(subghz->error_str), 64, 8, AlignCenter, AlignBottom); + popup_set_timeout(popup, 1500); + popup_set_context(popup, subghz); + popup_set_callback(popup, subghz_scene_show_error_sub_popup_callback); + popup_enable_timeout(popup); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewPopup); +} + +bool subghz_scene_show_error_sub_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubghzCustomEventSceneShowErrorSub) { + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneStart); + return true; + } + } + return false; +} + +void subghz_scene_show_error_sub_on_exit(void* context) { + SubGhz* subghz = context; + + // Clear view + Popup* popup = subghz->popup; + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + popup_set_callback(popup, NULL); + popup_set_context(popup, NULL); + popup_set_timeout(popup, 0); + popup_disable_timeout(popup); + string_reset(subghz->error_str); +} diff --git a/applications/subghz/scenes/subghz_scene_start.c b/applications/subghz/scenes/subghz_scene_start.c index 640c42ca..454b39f1 100644 --- a/applications/subghz/scenes/subghz_scene_start.c +++ b/applications/subghz/scenes/subghz_scene_start.c @@ -53,8 +53,12 @@ void subghz_scene_start_on_enter(void* context) { bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; - - if(event.type == SceneManagerEventTypeCustom) { + if(event.type == SceneManagerEventTypeBack) { + //exit app + scene_manager_stop(subghz->scene_manager); + view_dispatcher_stop(subghz->view_dispatcher); + return true; + } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexReadRAW) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW); diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c index 16617589..287e1afd 100644 --- a/applications/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -94,7 +94,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { return true; } else if(event.event == SubghzCustomEventViewTransmitterError) { string_set(subghz->error_str, "Protocol not found"); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); } } else if(event.type == SceneManagerEventTypeTick) { if(subghz->state_notifications == SubGhzNotificationStateTX) { diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 5ae24b7b..23599739 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -1,3 +1,8 @@ +/* +* Give up hope, everyone who enters here!!! +* Оставь надежду, всяк сюда входящий!!! +*/ + #include "subghz_i.h" #include @@ -191,13 +196,6 @@ SubGhz* subghz_alloc() { //Init Error_str string_init(subghz->error_str); - subghz_parser_load_keeloq_file(subghz->txrx->parser, "/ext/subghz/keeloq_mfcodes"); - subghz_parser_load_keeloq_file(subghz->txrx->parser, "/ext/subghz/keeloq_mfcodes_user"); - subghz_parser_load_nice_flor_s_file(subghz->txrx->parser, "/ext/subghz/nice_flor_s_rx"); - subghz_parser_load_came_atomo_file(subghz->txrx->parser, "/ext/subghz/came_atomo"); - - //subghz_parser_enable_dump_text(subghz->protocol, subghz_text_callback, subghz); - return subghz; } @@ -285,19 +283,41 @@ void subghz_free(SubGhz* subghz) { int32_t subghz_app(void* p) { SubGhz* subghz = subghz_alloc(); + //Load database + bool load_database = + subghz_parser_load_keeloq_file(subghz->txrx->parser, "/ext/subghz/keeloq_mfcodes"); + subghz_parser_load_keeloq_file(subghz->txrx->parser, "/ext/subghz/keeloq_mfcodes_user"); + subghz_parser_load_nice_flor_s_file(subghz->txrx->parser, "/ext/subghz/nice_flor_s_rx"); + subghz_parser_load_came_atomo_file(subghz->txrx->parser, "/ext/subghz/came_atomo"); + // Check argument and run corresponding scene if(p && subghz_key_load(subghz, p)) { string_t filename; string_init(filename); path_extract_filename_no_ext(p, filename); - strlcpy( - subghz->file_name, string_get_cstr(filename), strlen(string_get_cstr(filename)) + 1); + strcpy(subghz->file_name, string_get_cstr(filename)); string_clear(filename); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); + if((!strcmp(subghz->txrx->protocol_result->name, "RAW"))) { + //Load Raw TX + subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); + } else { + //Load transmitter TX + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); + } } else { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); + if(load_database) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); + } else { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneShowError, SubghzCustomEventManagerSet); + string_set( + subghz->error_str, + "No SD card or\ndatabase found.\nSome app function\nmay be reduced."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + } } furi_hal_power_suppress_charge_enter(); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index ea06aae7..845eac0f 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -286,7 +286,7 @@ bool subghz_get_next_name_file(SubGhz* subghz) { storage_get_next_filename( storage, SUBGHZ_RAW_PATH_FOLDER, subghz->file_name, SUBGHZ_APP_EXTENSION, temp_str); - memcpy(subghz->file_name, string_get_cstr(temp_str), strlen(string_get_cstr(temp_str))); + strcpy(subghz->file_name, string_get_cstr(temp_str)); res = true; } diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index c206f87b..733db844 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -74,6 +74,7 @@ typedef enum { SubGhzRxKeyStateAddKey, SubGhzRxKeyStateExit, SubGhzRxKeyStateRAWLoad, + SubGhzRxKeyStateRAWSave, } SubGhzRxKeyState; struct SubGhzTxRx { diff --git a/applications/subghz/views/subghz_read_raw.c b/applications/subghz/views/subghz_read_raw.c index 993ca914..cfb79ab4 100644 --- a/applications/subghz/views/subghz_read_raw.c +++ b/applications/subghz/views/subghz_read_raw.c @@ -10,6 +10,7 @@ #include #define SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE 100 +#define TAG "SubghzReadRAW" struct SubghzReadRAW { View* view; @@ -89,11 +90,22 @@ void subghz_read_raw_stop_send(SubghzReadRAW* instance) { with_view_model( instance->view, (SubghzReadRAWModel * model) { - if(model->satus == SubghzReadRAWStatusTXRepeat) { - // Start TX + switch(model->satus) { + case SubghzReadRAWStatusTXRepeat: + case SubghzReadRAWStatusLoadKeyTXRepeat: instance->callback(SubghzCustomEventViewReadRAWSendStart, instance->context); - } else { + break; + case SubghzReadRAWStatusTX: model->satus = SubghzReadRAWStatusIDLE; + break; + case SubghzReadRAWStatusLoadKeyTX: + model->satus = SubghzReadRAWStatusLoadKeyIDLE; + break; + + default: + FURI_LOG_W(TAG, "unknown status"); + model->satus = SubghzReadRAWStatusIDLE; + break; } return true; }); @@ -203,6 +215,7 @@ void subghz_read_raw_draw_rssi(Canvas* canvas, SubghzReadRAWModel* model) { } void subghz_read_raw_draw(Canvas* canvas, SubghzReadRAWModel* model) { + uint8_t graphics_mode = 1; canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 5, 8, string_get_cstr(model->frequency_str)); @@ -214,32 +227,47 @@ void subghz_read_raw_draw(Canvas* canvas, SubghzReadRAWModel* model) { canvas_draw_line(canvas, 0, 48, 115, 48); canvas_draw_line(canvas, 115, 14, 115, 48); - if((model->satus == SubghzReadRAWStatusTX) || (model->satus == SubghzReadRAWStatusTXRepeat)) { + switch(model->satus) { + case SubghzReadRAWStatusIDLE: + elements_button_left(canvas, "Erase"); + elements_button_center(canvas, "Send"); + elements_button_right(canvas, "Save"); + break; + case SubghzReadRAWStatusLoadKeyIDLE: + elements_button_left(canvas, "New"); + elements_button_center(canvas, "Send"); + elements_button_right(canvas, "More"); + canvas_draw_str_aligned( + canvas, 58, 28, AlignCenter, AlignTop, string_get_cstr(model->file_name)); + break; + + case SubghzReadRAWStatusTX: + case SubghzReadRAWStatusTXRepeat: + case SubghzReadRAWStatusLoadKeyTX: + case SubghzReadRAWStatusLoadKeyTXRepeat: + graphics_mode = 0; + elements_button_center(canvas, "Send"); + break; + + case SubghzReadRAWStatusStart: + elements_button_left(canvas, "Config"); + elements_button_center(canvas, "REC"); + break; + + default: + elements_button_center(canvas, "Stop"); + break; + } + + if(graphics_mode == 0) { subghz_read_raw_draw_sin(canvas, model); } else { subghz_read_raw_draw_rssi(canvas, model); subghz_read_raw_draw_scale(canvas, model); + canvas_set_font_direction(canvas, CanvasDirectionBottomToTop); + canvas_draw_str(canvas, 126, 40, "RSSI"); + canvas_set_font_direction(canvas, CanvasDirectionLeftToRight); } - - if(model->satus == SubghzReadRAWStatusIDLE) { - elements_button_left(canvas, "Erase"); - elements_button_center(canvas, "Send"); - elements_button_right(canvas, "Save"); - canvas_draw_str_aligned( - canvas, 58, 28, AlignCenter, AlignTop, string_get_cstr(model->file_name)); - } else if(model->satus == SubghzReadRAWStatusStart) { - elements_button_left(canvas, "Config"); - elements_button_center(canvas, "REC"); - } else if( - (model->satus == SubghzReadRAWStatusTX) || (model->satus == SubghzReadRAWStatusTXRepeat)) { - elements_button_center(canvas, "Send"); - } else { - elements_button_center(canvas, "Stop"); - } - - canvas_set_font_direction(canvas, 3); - canvas_draw_str(canvas, 126, 40, "RSSI"); - canvas_set_font_direction(canvas, 0); } bool subghz_read_raw_input(InputEvent* event, void* context) { @@ -255,14 +283,32 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { with_view_model( instance->view, (SubghzReadRAWModel * model) { uint8_t ret = false; - if(model->satus == SubghzReadRAWStatusIDLE) { + switch(model->satus) { + case SubghzReadRAWStatusIDLE: // Start TX instance->callback(SubghzCustomEventViewReadRAWSendStart, instance->context); instance->callback(SubghzCustomEventViewReadRAWVibro, instance->context); model->satus = SubghzReadRAWStatusTXRepeat; ret = true; - } else if(model->satus == SubghzReadRAWStatusTX) { + break; + case SubghzReadRAWStatusTX: + // Start TXRepeat model->satus = SubghzReadRAWStatusTXRepeat; + break; + case SubghzReadRAWStatusLoadKeyIDLE: + // Start Load Key TX + instance->callback(SubghzCustomEventViewReadRAWSendStart, instance->context); + instance->callback(SubghzCustomEventViewReadRAWVibro, instance->context); + model->satus = SubghzReadRAWStatusLoadKeyTXRepeat; + ret = true; + break; + case SubghzReadRAWStatusLoadKeyTX: + // Start Load Key TXRepeat + model->satus = SubghzReadRAWStatusLoadKeyTXRepeat; + break; + + default: + break; } return ret; }); @@ -272,19 +318,40 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { if(model->satus == SubghzReadRAWStatusTXRepeat) { // Stop repeat TX model->satus = SubghzReadRAWStatusTX; + } else if(model->satus == SubghzReadRAWStatusLoadKeyTXRepeat) { + // Stop repeat TX + model->satus = SubghzReadRAWStatusLoadKeyTX; } return false; }); } else if(event->key == InputKeyBack && event->type == InputTypeShort) { with_view_model( instance->view, (SubghzReadRAWModel * model) { - if(model->satus == SubghzReadRAWStatusREC) { + switch(model->satus) { + case SubghzReadRAWStatusREC: //Stop REC instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); model->satus = SubghzReadRAWStatusIDLE; - } else { + break; + case SubghzReadRAWStatusLoadKeyTX: + //Stop TxRx + instance->callback(SubghzCustomEventViewReadRAWTXRXStop, instance->context); + model->satus = SubghzReadRAWStatusLoadKeyIDLE; + break; + case SubghzReadRAWStatusTX: + //Stop TxRx + instance->callback(SubghzCustomEventViewReadRAWTXRXStop, instance->context); + model->satus = SubghzReadRAWStatusIDLE; + break; + case SubghzReadRAWStatusLoadKeyIDLE: //Exit instance->callback(SubghzCustomEventViewReadRAWBack, instance->context); + break; + + default: + //Exit + instance->callback(SubghzCustomEventViewReadRAWBack, instance->context); + break; } return true; }); @@ -294,7 +361,9 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { if(model->satus == SubghzReadRAWStatusStart) { //Config instance->callback(SubghzCustomEventViewReadRAWConfig, instance->context); - } else if(model->satus == SubghzReadRAWStatusIDLE) { + } else if( + (model->satus == SubghzReadRAWStatusIDLE) || + (model->satus == SubghzReadRAWStatusLoadKeyIDLE)) { //Erase model->satus = SubghzReadRAWStatusStart; model->rssi_history_end = false; @@ -308,9 +377,12 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { } else if(event->key == InputKeyRight && event->type == InputTypeShort) { with_view_model( instance->view, (SubghzReadRAWModel * model) { - //Save if(model->satus == SubghzReadRAWStatusIDLE) { + //Save instance->callback(SubghzCustomEventViewReadRAWSave, instance->context); + } else if(model->satus == SubghzReadRAWStatusLoadKeyIDLE) { + //More + instance->callback(SubghzCustomEventViewReadRAWMore, instance->context); } return true; }); @@ -323,9 +395,7 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { model->satus = SubghzReadRAWStatusREC; model->ind_write = 0; model->rssi_history_end = false; - } else if( - (model->satus != SubghzReadRAWStatusTX) && - (model->satus != SubghzReadRAWStatusTXRepeat)) { + } else if(model->satus == SubghzReadRAWStatusREC) { //Stop instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); model->satus = SubghzReadRAWStatusIDLE; @@ -341,7 +411,9 @@ void subghz_read_raw_set_status( SubghzReadRAWStatus satus, const char* file_name) { furi_assert(instance); - if(satus == SubghzReadRAWStatusStart) { + + switch(satus) { + case SubghzReadRAWStatusStart: with_view_model( instance->view, (SubghzReadRAWModel * model) { model->satus = SubghzReadRAWStatusStart; @@ -351,22 +423,42 @@ void subghz_read_raw_set_status( string_set(model->sample_write, "0 spl."); return true; }); - } else if(satus == SubghzReadRAWStatusIDLE) { + break; + case SubghzReadRAWStatusIDLE: with_view_model( instance->view, (SubghzReadRAWModel * model) { model->satus = SubghzReadRAWStatusIDLE; return true; }); - } else if(satus == SubghzReadRAWStatusTX) { + break; + case SubghzReadRAWStatusLoadKeyTX: with_view_model( instance->view, (SubghzReadRAWModel * model) { - model->satus = SubghzReadRAWStatusIDLE; + model->satus = SubghzReadRAWStatusLoadKeyIDLE; model->rssi_history_end = false; model->ind_write = 0; string_set(model->file_name, file_name); string_set(model->sample_write, "RAW"); return true; }); + break; + case SubghzReadRAWStatusSaveKey: + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + model->satus = SubghzReadRAWStatusLoadKeyIDLE; + if(!model->ind_write) { + string_set(model->file_name, file_name); + string_set(model->sample_write, "RAW"); + } else { + string_reset(model->file_name); + } + return true; + }); + break; + + default: + FURI_LOG_W(TAG, "unknown status"); + break; } } @@ -382,7 +474,8 @@ void subghz_read_raw_exit(void* context) { with_view_model( instance->view, (SubghzReadRAWModel * model) { if(model->satus != SubghzReadRAWStatusIDLE && - model->satus != SubghzReadRAWStatusStart) { + model->satus != SubghzReadRAWStatusStart && + model->satus != SubghzReadRAWStatusLoadKeyIDLE) { instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); model->satus = SubghzReadRAWStatusStart; } diff --git a/applications/subghz/views/subghz_read_raw.h b/applications/subghz/views/subghz_read_raw.h index 86b69253..443d0185 100644 --- a/applications/subghz/views/subghz_read_raw.h +++ b/applications/subghz/views/subghz_read_raw.h @@ -13,6 +13,11 @@ typedef enum { SubghzReadRAWStatusREC, SubghzReadRAWStatusTX, SubghzReadRAWStatusTXRepeat, + + SubghzReadRAWStatusLoadKeyIDLE, + SubghzReadRAWStatusLoadKeyTX, + SubghzReadRAWStatusLoadKeyTXRepeat, + SubghzReadRAWStatusSaveKey, } SubghzReadRAWStatus; void subghz_read_raw_set_callback( diff --git a/lib/subghz/subghz_parser.c b/lib/subghz/subghz_parser.c index 93c48cb7..dbb2ffd8 100644 --- a/lib/subghz/subghz_parser.c +++ b/lib/subghz/subghz_parser.c @@ -215,12 +215,15 @@ void subghz_parser_load_came_atomo_file(SubGhzParser* instance, const char* file (SubGhzProtocolCameAtomo*)instance->protocols[SubGhzProtocolTypeCameAtomo], file_name); } -void subghz_parser_load_keeloq_file(SubGhzParser* instance, const char* file_name) { +bool subghz_parser_load_keeloq_file(SubGhzParser* instance, const char* file_name) { + bool ret = false; if (subghz_keystore_load(instance->keystore, file_name)) { FURI_LOG_I(SUBGHZ_PARSER_TAG, "Successfully loaded keeloq keys from %s", file_name); + ret = true; } else { FURI_LOG_W(SUBGHZ_PARSER_TAG, "Failed to load keeloq keysfrom %s", file_name); } + return ret; } void subghz_parser_reset(SubGhzParser* instance) { diff --git a/lib/subghz/subghz_parser.h b/lib/subghz/subghz_parser.h index 7e6c72b8..c5a46dd7 100644 --- a/lib/subghz/subghz_parser.h +++ b/lib/subghz/subghz_parser.h @@ -67,8 +67,9 @@ void subghz_parser_load_came_atomo_file(SubGhzParser* instance, const char* file * * @param instance - SubGhzParser instance * @param file_name - "path/file_name" + * @return bool */ -void subghz_parser_load_keeloq_file(SubGhzParser* instance, const char* file_name); +bool subghz_parser_load_keeloq_file(SubGhzParser* instance, const char* file_name); /** Restarting all parsers *