diff --git a/applications/subghz/helpers/subghz_custom_event.h b/applications/subghz/helpers/subghz_custom_event.h index df833b8d..5a423e6f 100644 --- a/applications/subghz/helpers/subghz_custom_event.h +++ b/applications/subghz/helpers/subghz_custom_event.h @@ -1,6 +1,9 @@ #pragma once typedef enum { + SubghzCustomEventManagerNoSet = 0, + SubghzCustomEventManagerSet, + SubghzCustomEventSceneDeleteSuccess = 100, SubghzCustomEventSceneDelete, SubghzCustomEventSceneReceiverInfoTxStart, @@ -11,15 +14,18 @@ typedef enum { SubghzCustomEventSceneShowError, SubghzCustomEventSceneShowOnlyRX, + SubghzCustomEventSceneNeedSavingNo, + SubghzCustomEventSceneNeedSavingYes, + SubghzCustomEventViewReceverOK, SubghzCustomEventViewReceverConfig, SubghzCustomEventViewReceverBack, - SubghzCustomEventViewSaveRAWBack, - SubghzCustomEventViewSaveRAWIDLE, - SubghzCustomEventViewSaveRAWREC, - SubghzCustomEventViewSaveRAWConfig, - SubghzCustomEventViewSaveRAWMore, + SubghzCustomEventViewReadRAWBack, + SubghzCustomEventViewReadRAWIDLE, + SubghzCustomEventViewReadRAWREC, + SubghzCustomEventViewReadRAWConfig, + SubghzCustomEventViewReadRAWMore, SubghzCustomEventViewTransmitterBack, SubghzCustomEventViewTransmitterSendStart, diff --git a/applications/subghz/scenes/subghz_scene_config.h b/applications/subghz/scenes/subghz_scene_config.h index 0f66e67a..6d89cb74 100644 --- a/applications/subghz/scenes/subghz_scene_config.h +++ b/applications/subghz/scenes/subghz_scene_config.h @@ -17,4 +17,6 @@ ADD_SCENE(subghz, test_carrier, TestCarrier) ADD_SCENE(subghz, test_packet, TestPacket) ADD_SCENE(subghz, set_type, SetType) ADD_SCENE(subghz, frequency_analyzer, FrequencyAnalyzer) -ADD_SCENE(subghz, save_raw, SaveRAW) \ No newline at end of file +ADD_SCENE(subghz, read_raw, ReadRAW) +ADD_SCENE(subghz, read_raw_menu, ReadRAWMenu) +ADD_SCENE(subghz, need_saving, NeedSaving) \ No newline at end of file diff --git a/applications/subghz/scenes/subghz_scene_need_saving.c b/applications/subghz/scenes/subghz_scene_need_saving.c new file mode 100644 index 00000000..c7f83ce0 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_need_saving.c @@ -0,0 +1,63 @@ +#include "../subghz_i.h" +#include "../helpers/subghz_custom_event.h" + +void subghz_scene_need_saving_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, SubghzCustomEventSceneNeedSavingYes); + } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubghzCustomEventSceneNeedSavingNo); + } +} + +void subghz_scene_need_saving_on_enter(void* context) { + SubGhz* subghz = context; + + widget_add_string_multiline_element( + subghz->widget, + 64, + 25, + AlignCenter, + AlignCenter, + FontSecondary, + "There is an unsaved data.\nDo you want to save it?"); + + widget_add_button_element( + subghz->widget, GuiButtonTypeRight, "Save", subghz_scene_need_saving_callback, subghz); + widget_add_button_element( + subghz->widget, GuiButtonTypeLeft, "Delete", subghz_scene_need_saving_callback, subghz); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewWidget); +} + +bool subghz_scene_need_saving_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubghzCustomEventSceneNeedSavingYes) { + subghz->txrx->rx_key_state = SubGhzRxKeyStateNeedSave; + scene_manager_previous_scene(subghz->scene_manager); + return true; + } else if(event.event == SubghzCustomEventSceneNeedSavingNo) { + if(subghz->txrx->rx_key_state == SubGhzRxKeyStateExit) { + subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneStart); + } else { + subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + scene_manager_previous_scene(subghz->scene_manager); + } + + return true; + } + } + return false; +} + +void subghz_scene_need_saving_on_exit(void* context) { + SubGhz* subghz = context; + widget_clear(subghz->widget); +} diff --git a/applications/subghz/scenes/subghz_scene_save_raw.c b/applications/subghz/scenes/subghz_scene_read_raw.c similarity index 61% rename from applications/subghz/scenes/subghz_scene_save_raw.c rename to applications/subghz/scenes/subghz_scene_read_raw.c index 5399c74e..6d4a72d1 100644 --- a/applications/subghz/scenes/subghz_scene_save_raw.c +++ b/applications/subghz/scenes/subghz_scene_read_raw.c @@ -1,9 +1,9 @@ #include "../subghz_i.h" -#include "../views/subghz_save_raw.h" +#include "../views/subghz_read_raw.h" #include #include -static void subghz_scene_save_raw_update_statusbar(void* context) { +static void subghz_scene_read_raw_update_statusbar(void* context) { furi_assert(context); SubGhz* subghz = context; char frequency_str[20]; @@ -25,19 +25,28 @@ static void subghz_scene_save_raw_update_statusbar(void* context) { } else { furi_crash(NULL); } - subghz_save_raw_add_data_statusbar(subghz->subghz_save_raw, frequency_str, preset_str); + + subghz_read_raw_add_data_statusbar(subghz->subghz_read_raw, frequency_str, preset_str); } -void subghz_scene_save_raw_callback(SubghzCustomEvent event, void* context) { +void subghz_scene_read_raw_callback(SubghzCustomEvent event, void* context) { furi_assert(context); SubGhz* subghz = context; view_dispatcher_send_custom_event(subghz->view_dispatcher, event); } -void subghz_scene_save_raw_on_enter(void* context) { +void subghz_scene_read_raw_on_enter(void* context) { SubGhz* subghz = context; - subghz_scene_save_raw_update_statusbar(subghz); - subghz_save_raw_set_callback(subghz->subghz_save_raw, subghz_scene_save_raw_callback, subghz); + + if(subghz->txrx->rx_key_state == SubGhzRxKeyStateNeedSave) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubghzCustomEventViewReadRAWMore); + } else { + subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + } + + subghz_scene_read_raw_update_statusbar(subghz); + subghz_read_raw_set_callback(subghz->subghz_read_raw, subghz_scene_read_raw_callback, subghz); subghz->txrx->protocol_result = subghz_parser_get_by_name(subghz->txrx->parser, "RAW"); furi_assert(subghz->txrx->protocol_result); @@ -45,66 +54,78 @@ void subghz_scene_save_raw_on_enter(void* context) { subghz_worker_set_pair_callback( subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_parser_raw_parse); - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewSaveRAW); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReadRAW); } -bool subghz_scene_save_raw_on_event(void* context, SceneManagerEvent event) { +bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SubghzCustomEventViewSaveRAWBack: + case SubghzCustomEventViewReadRAWBack: if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { subghz_rx_end(subghz); subghz_sleep(subghz); }; subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; - subghz_protocol_save_raw_to_file_stop( + subghz_protocol_raw_save_to_file_stop( (SubGhzProtocolRAW*)subghz->txrx->protocol_result); - scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneStart); subghz->state_notifications = NOTIFICATION_IDLE_STATE; + + 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 SubghzCustomEventViewSaveRAWConfig: - scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneSaveRAW, 1); + case SubghzCustomEventViewReadRAWConfig: + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); return true; break; - case SubghzCustomEventViewSaveRAWIDLE: + case SubghzCustomEventViewReadRAWIDLE: if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { subghz_rx_end(subghz); subghz_sleep(subghz); }; - subghz_protocol_save_raw_to_file_stop( + subghz_protocol_raw_save_to_file_stop( (SubGhzProtocolRAW*)subghz->txrx->protocol_result); subghz->state_notifications = NOTIFICATION_IDLE_STATE; - //send the name of the saved file to the account - subghz_save_raw_set_file_name( - subghz->subghz_save_raw, - subghz_protocol_get_last_file_name( - (SubGhzProtocolRAW*)subghz->txrx->protocol_result)); + + subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; + return true; break; - case SubghzCustomEventViewSaveRAWREC: - if(subghz_protocol_save_raw_to_file_init( - (SubGhzProtocolRAW*)subghz->txrx->protocol_result, - "Raw", - subghz->txrx->frequency, - subghz->txrx->preset)) { - if((subghz->txrx->txrx_state == SubGhzTxRxStateIdle) || - (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { - subghz_begin(subghz, subghz->txrx->preset); - subghz_rx(subghz, subghz->txrx->frequency); - } - subghz->state_notifications = NOTIFICATION_RX_STATE; + case SubghzCustomEventViewReadRAWREC: + + if(subghz->txrx->rx_key_state != SubGhzRxKeyStateIDLE) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { - string_set(subghz->error_str, "No SD card"); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + if(subghz_protocol_raw_save_to_file_init( + (SubGhzProtocolRAW*)subghz->txrx->protocol_result, + "Raw_temp", + subghz->txrx->frequency, + subghz->txrx->preset)) { + if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || + (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { + subghz_begin(subghz, subghz->txrx->preset); + subghz_rx(subghz, subghz->txrx->frequency); + } + subghz->state_notifications = NOTIFICATION_RX_STATE; + } else { + string_set(subghz->error_str, "No SD card"); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); + } } + return true; break; - case SubghzCustomEventViewSaveRAWMore: + case SubghzCustomEventViewReadRAWMore: if(strcmp( subghz_protocol_get_last_file_name( (SubGhzProtocolRAW*)subghz->txrx->protocol_result), @@ -128,7 +149,7 @@ bool subghz_scene_save_raw_on_event(void* context, SceneManagerEvent event) { (SubGhzProtocolRAW*)subghz->txrx->protocol_result, string_get_cstr(temp_str)); string_clear(temp_str); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSavedMenu); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAWMenu); } return true; break; @@ -140,11 +161,11 @@ bool subghz_scene_save_raw_on_event(void* context, SceneManagerEvent event) { switch(subghz->state_notifications) { case NOTIFICATION_RX_STATE: notification_message(subghz->notifications, &sequence_blink_blue_10); - subghz_save_raw_update_sample_write( - subghz->subghz_save_raw, - subghz_save_protocol_raw_get_sample_write( + subghz_read_raw_update_sample_write( + subghz->subghz_read_raw, + subghz_protocol_raw_get_sample_write( (SubGhzProtocolRAW*)subghz->txrx->protocol_result)); - subghz_save_raw_add_data_rssi(subghz->subghz_save_raw, furi_hal_subghz_get_rssi()); + subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, furi_hal_subghz_get_rssi()); break; default: break; @@ -153,7 +174,7 @@ bool subghz_scene_save_raw_on_event(void* context, SceneManagerEvent event) { return false; } -void subghz_scene_save_raw_on_exit(void* context) { +void subghz_scene_read_raw_on_exit(void* context) { SubGhz* subghz = context; //Stop CC1101 diff --git a/applications/subghz/scenes/subghz_scene_read_raw_menu.c b/applications/subghz/scenes/subghz_scene_read_raw_menu.c new file mode 100644 index 00000000..2c6deefc --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_read_raw_menu.c @@ -0,0 +1,72 @@ +#include "../subghz_i.h" + +enum SubmenuIndex { + SubmenuIndexEmulate, + SubmenuIndexEdit, + SubmenuIndexDelete, +}; + +void subghz_scene_read_raw_menu_submenu_callback(void* context, uint32_t index) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, index); +} + +void subghz_scene_read_raw_menu_on_enter(void* context) { + SubGhz* subghz = context; + submenu_add_item( + subghz->submenu, + "Emulate", + SubmenuIndexEmulate, + subghz_scene_read_raw_menu_submenu_callback, + subghz); + + submenu_add_item( + subghz->submenu, + "Save", + SubmenuIndexEdit, + subghz_scene_read_raw_menu_submenu_callback, + subghz); + + submenu_add_item( + subghz->submenu, + "Delete", + SubmenuIndexDelete, + subghz_scene_read_raw_menu_submenu_callback, + subghz); + + submenu_set_selected_item( + subghz->submenu, + scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSavedMenu)); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewMenu); +} + +bool subghz_scene_read_raw_menu_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexEmulate) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReadRAWMenu, SubmenuIndexEmulate); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); + return true; + } else if(event.event == SubmenuIndexDelete) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReadRAWMenu, SubmenuIndexDelete); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDelete); + return true; + } else if(event.event == SubmenuIndexEdit) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReadRAWMenu, SubghzCustomEventManagerSet); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + return true; + } + } + return false; +} + +void subghz_scene_read_raw_menu_on_exit(void* context) { + SubGhz* subghz = context; + submenu_clean(subghz->submenu); + subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; +} diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index 653cdb1a..107381c2 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -87,7 +87,7 @@ void subghz_scene_receiver_on_enter(void* context) { if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { subghz_rx_end(subghz); }; - if((subghz->txrx->txrx_state == SubGhzTxRxStateIdle) || + if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { subghz_begin(subghz, subghz->txrx->preset); subghz_rx(subghz, subghz->txrx->frequency); diff --git a/applications/subghz/scenes/subghz_scene_receiver_config.c b/applications/subghz/scenes/subghz_scene_receiver_config.c index 2a51bee6..4243b09b 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/subghz/scenes/subghz_scene_receiver_config.c @@ -126,7 +126,8 @@ 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, subghz_frequencies_text[value_index]); - if(!scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSaveRAW)) { + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != + SubghzCustomEventManagerSet) { item = variable_item_list_add( subghz->variable_item_list, "Hopping:", @@ -161,5 +162,6 @@ bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent even void subghz_scene_receiver_config_on_exit(void* context) { SubGhz* subghz = context; variable_item_list_clean(subghz->variable_item_list); - scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneSaveRAW, 0); + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerNoSet); } diff --git a/applications/subghz/scenes/subghz_scene_receiver_info.c b/applications/subghz/scenes/subghz_scene_receiver_info.c index 11083300..1e9f100a 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/subghz/scenes/subghz_scene_receiver_info.c @@ -107,7 +107,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) if(!subghz_scene_receiver_info_update_parser(subghz)) { return false; } - if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle || + if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE || subghz->txrx->txrx_state == SubGhzTxRxStateSleep) { if(!subghz_tx_start(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); @@ -122,7 +122,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { subghz_tx_stop(subghz); } - if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { + if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) { subghz_begin(subghz, subghz->txrx->preset); subghz_rx(subghz, subghz->txrx->frequency); } diff --git a/applications/subghz/scenes/subghz_scene_save_name.c b/applications/subghz/scenes/subghz_scene_save_name.c index f0ecd077..6cba3240 100644 --- a/applications/subghz/scenes/subghz_scene_save_name.c +++ b/applications/subghz/scenes/subghz_scene_save_name.c @@ -20,6 +20,10 @@ void subghz_scene_save_name_on_enter(void* context) { dev_name_empty = true; } else { memcpy(subghz->file_name_tmp, subghz->file_name, strlen(subghz->file_name)); + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAWMenu) == + SubghzCustomEventManagerSet) { + subghz_get_next_name_file(subghz); + } } text_input_set_header_text(text_input, "Name signal"); @@ -63,4 +67,6 @@ void subghz_scene_save_name_on_exit(void* context) { // Clear view text_input_clean(subghz->text_input); + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReadRAWMenu, SubghzCustomEventManagerNoSet); } diff --git a/applications/subghz/scenes/subghz_scene_saved_menu.c b/applications/subghz/scenes/subghz_scene_saved_menu.c index 59d7e3e8..a25f8e6f 100644 --- a/applications/subghz/scenes/subghz_scene_saved_menu.c +++ b/applications/subghz/scenes/subghz_scene_saved_menu.c @@ -19,12 +19,14 @@ void subghz_scene_saved_menu_on_enter(void* context) { SubmenuIndexEmulate, subghz_scene_saved_menu_submenu_callback, subghz); + submenu_add_item( subghz->submenu, "Edit name", SubmenuIndexEdit, subghz_scene_saved_menu_submenu_callback, subghz); + submenu_add_item( subghz->submenu, "Delete", diff --git a/applications/subghz/scenes/subghz_scene_start.c b/applications/subghz/scenes/subghz_scene_start.c index e36a514b..fe37d7ae 100644 --- a/applications/subghz/scenes/subghz_scene_start.c +++ b/applications/subghz/scenes/subghz_scene_start.c @@ -6,7 +6,7 @@ enum SubmenuIndex { SubmenuIndexTest, SubmenuIndexAddManualy, SubmenuIndexFrequencyAnalyzer, - SubmenuIndexSaveRAW, + SubmenuIndexReadRAW, }; void subghz_scene_start_submenu_callback(void* context, uint32_t index) { @@ -24,7 +24,7 @@ void subghz_scene_start_on_enter(void* context) { submenu_add_item( subghz->submenu, "Read Raw", - SubmenuIndexSaveRAW, + SubmenuIndexReadRAW, subghz_scene_start_submenu_callback, subghz); submenu_add_item( @@ -54,10 +54,10 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexSaveRAW) { + if(event.event == SubmenuIndexReadRAW) { scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneStart, SubmenuIndexSaveRAW); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveRAW); + subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); return true; } else if(event.event == SubmenuIndexRead) { scene_manager_set_scene_state( diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c index 7dee5bdf..28d49397 100644 --- a/applications/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -79,7 +79,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { subghz_rx_end(subghz); } - if((subghz->txrx->txrx_state == SubGhzTxRxStateIdle) || + if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { if(!subghz_tx_start(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index ff521581..63156717 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -140,12 +140,12 @@ SubGhz* subghz_alloc() { SubGhzViewFrequencyAnalyzer, subghz_frequency_analyzer_get_view(subghz->subghz_frequency_analyzer)); - // Save RAW - subghz->subghz_save_raw = subghz_save_raw_alloc(); + // Read RAW + subghz->subghz_read_raw = subghz_read_raw_alloc(); view_dispatcher_add_view( subghz->view_dispatcher, - SubGhzViewSaveRAW, - subghz_save_raw_get_view(subghz->subghz_save_raw)); + SubGhzViewReadRAW, + subghz_read_raw_get_view(subghz->subghz_read_raw)); // Carrier Test Module subghz->subghz_test_carrier = subghz_test_carrier_alloc(); @@ -174,6 +174,7 @@ SubGhz* subghz_alloc() { subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; subghz->txrx->txrx_state = SubGhzTxRxStateSleep; subghz->txrx->hopper_state = SubGhzHopperStateOFF; + subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; subghz->txrx->history = subghz_history_alloc(); subghz->txrx->worker = subghz_worker_alloc(); subghz->txrx->parser = subghz_parser_alloc(); @@ -234,9 +235,9 @@ void subghz_free(SubGhz* subghz) { view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewFrequencyAnalyzer); subghz_frequency_analyzer_free(subghz->subghz_frequency_analyzer); - // Save RAW - view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewSaveRAW); - subghz_save_raw_free(subghz->subghz_save_raw); + // Read RAW + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewReadRAW); + subghz_read_raw_free(subghz->subghz_read_raw); // Submenu view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewMenu); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 2e3fe6ff..fe8bfff1 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -16,7 +16,7 @@ void subghz_begin(SubGhz* subghz, FuriHalSubGhzPreset preset) { furi_hal_subghz_idle(); furi_hal_subghz_load_preset(preset); hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; } uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency) { @@ -59,7 +59,7 @@ void subghz_idle(SubGhz* subghz) { furi_assert(subghz); furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; } void subghz_rx_end(SubGhz* subghz) { @@ -70,7 +70,7 @@ void subghz_rx_end(SubGhz* subghz) { furi_hal_subghz_stop_async_rx(); } furi_hal_subghz_idle(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; } void subghz_sleep(SubGhz* subghz) { @@ -208,6 +208,30 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { return loaded; } +bool subghz_get_next_name_file(SubGhz* subghz) { + furi_assert(subghz); + + FileWorker* file_worker = file_worker_alloc(false); + string_t temp_str; + string_init(temp_str); + bool res = false; + + if(strcmp(subghz->file_name, "")) { + //get the name of the next free file + file_worker_get_next_filename( + file_worker, 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))); + res = true; + } + + string_clear(temp_str); + file_worker_close(file_worker); + file_worker_free(file_worker); + + return res; +} + bool subghz_save_protocol_to_file(SubGhz* subghz, const char* dev_name) { furi_assert(subghz); furi_assert(subghz->txrx->protocol_result); @@ -466,7 +490,7 @@ void subghz_hopper_update(SubGhz* subghz) { if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { subghz_rx_end(subghz); }; - if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { + if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) { subghz_parser_reset(subghz->txrx->parser); subghz->txrx->frequency = subghz_hopper_frequencies[subghz->txrx->hopper_idx_frequency]; subghz_rx(subghz, subghz->txrx->frequency); diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index 9e7c1f27..70a39f23 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -4,7 +4,7 @@ #include "views/subghz_receiver.h" #include "views/subghz_transmitter.h" #include "views/subghz_frequency_analyzer.h" -#include "views/subghz_save_raw.h" +#include "views/subghz_read_raw.h" #include "views/subghz_test_static.h" #include "views/subghz_test_carrier.h" @@ -47,7 +47,7 @@ extern const uint32_t subghz_frequencies_433_92; /** SubGhzTxRx state */ typedef enum { - SubGhzTxRxStateIdle, + SubGhzTxRxStateIDLE, SubGhzTxRxStateRx, SubGhzTxRxStateTx, SubGhzTxRxStateSleep, @@ -61,21 +61,29 @@ typedef enum { SubGhzHopperStateRSSITimeOut, } SubGhzHopperState; +/** SubGhzRxKeyState state */ +typedef enum { + SubGhzRxKeyStateIDLE, + SubGhzRxKeyStateNoSave, + SubGhzRxKeyStateNeedSave, + SubGhzRxKeyStateAddKey, + SubGhzRxKeyStateExit, +} SubGhzRxKeyState; + struct SubGhzTxRx { SubGhzWorker* worker; SubGhzParser* parser; SubGhzProtocolCommon* protocol_result; - //SubGhzProtocolCommon* protocol_save_raw; SubGhzProtocolCommonEncoder* encoder; uint32_t frequency; FuriHalSubGhzPreset preset; SubGhzHistory* history; uint16_t idx_menu_chosen; SubGhzTxRxState txrx_state; - //bool hopper_runing; SubGhzHopperState hopper_state; uint8_t hopper_timeout; uint8_t hopper_idx_frequency; + SubGhzRxKeyState rx_key_state; }; typedef struct SubGhzTxRx SubGhzTxRx; @@ -102,7 +110,7 @@ struct SubGhz { VariableItemList* variable_item_list; SubghzFrequencyAnalyzer* subghz_frequency_analyzer; - SubghzSaveRAW* subghz_save_raw; + SubghzReadRAW* subghz_read_raw; SubghzTestStatic* subghz_test_static; SubghzTestCarrier* subghz_test_carrier; SubghzTestPacket* subghz_test_packet; @@ -119,7 +127,7 @@ typedef enum { SubGhzViewTransmitter, SubGhzViewVariableItemList, SubGhzViewFrequencyAnalyzer, - SubGhzViewSaveRAW, + SubGhzViewReadRAW, SubGhzViewStatic, SubGhzViewTestCarrier, SubGhzViewTestPacket, @@ -132,6 +140,7 @@ void subghz_sleep(SubGhz* subghz); bool subghz_tx_start(SubGhz* subghz); void subghz_tx_stop(SubGhz* subghz); bool subghz_key_load(SubGhz* subghz, const char* file_path); +bool subghz_get_next_name_file(SubGhz* subghz); bool subghz_save_protocol_to_file(SubGhz* subghz, const char* dev_name); bool subghz_load_protocol_from_file(SubGhz* subghz); bool subghz_rename_file(SubGhz* subghz); diff --git a/applications/subghz/views/subghz_read_raw.c b/applications/subghz/views/subghz_read_raw.c new file mode 100644 index 00000000..7c24654b --- /dev/null +++ b/applications/subghz/views/subghz_read_raw.c @@ -0,0 +1,274 @@ +#include "subghz_read_raw.h" +#include "../subghz_i.h" + +#include +#include +#include +#include +#include +#include + +#include +#define SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE 100 + +typedef enum { + SubghzReadRAWStatusStart, + SubghzReadRAWStatusIDLE, + SubghzReadRAWStatusREC, + //SubghzReadRAWStatusShowName, +} SubghzReadRAWStatus; + +struct SubghzReadRAW { + View* view; + SubghzReadRAWCallback callback; + void* context; +}; + +typedef struct { + string_t frequency_str; + string_t preset_str; + string_t sample_write; + uint8_t* rssi_history; + bool rssi_history_end; + uint8_t ind_write; + SubghzReadRAWStatus satus; +} SubghzReadRAWModel; + +void subghz_read_raw_set_callback( + SubghzReadRAW* subghz_read_raw, + SubghzReadRAWCallback callback, + void* context) { + furi_assert(subghz_read_raw); + furi_assert(callback); + subghz_read_raw->callback = callback; + subghz_read_raw->context = context; +} + +void subghz_read_raw_add_data_statusbar( + SubghzReadRAW* instance, + const char* frequency_str, + const char* preset_str) { + furi_assert(instance); + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + string_set(model->frequency_str, frequency_str); + string_set(model->preset_str, preset_str); + return true; + }); +} + +void subghz_read_raw_add_data_rssi(SubghzReadRAW* instance, float rssi) { + furi_assert(instance); + uint8_t u_rssi = 0; + + if(rssi < -90) { + u_rssi = 0; + } else { + u_rssi = (uint8_t)((rssi + 90) / 2.7); + } + //if(u_rssi > 34) u_rssi = 34; + + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + model->rssi_history[model->ind_write++] = u_rssi; + if(model->ind_write > SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE) { + model->rssi_history_end = true; + model->ind_write = 0; + } + return true; + }); +} + +void subghz_read_raw_update_sample_write(SubghzReadRAW* instance, size_t sample) { + furi_assert(instance); + + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + string_printf(model->sample_write, "%d spl.", sample); + return false; + }); +} + +void subghz_read_raw_draw_rssi(Canvas* canvas, SubghzReadRAWModel* model) { + int ind = 0; + int base = 0; + if(model->rssi_history_end == false) { + for(int i = model->ind_write; i >= 0; i--) { + canvas_draw_line(canvas, i, 47, i, 47 - model->rssi_history[i]); + } + if(model->ind_write > 3) { + canvas_draw_line(canvas, model->ind_write, 47, model->ind_write, 13); + canvas_draw_line(canvas, model->ind_write - 2, 12, model->ind_write + 2, 12); + canvas_draw_line(canvas, model->ind_write - 1, 13, model->ind_write + 1, 13); + } + } else { + base = SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE - model->ind_write; + for(int i = SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE; i >= 0; i--) { + ind = i - base; + if(ind < 0) ind += SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE; + canvas_draw_line(canvas, i, 47, i, 47 - model->rssi_history[ind]); + } + canvas_draw_line( + canvas, SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE, 47, SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE, 13); + canvas_draw_line( + canvas, + SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE - 2, + 12, + SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE + 2, + 12); + canvas_draw_line( + canvas, + SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE - 1, + 13, + SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE + 1, + 13); + } +} + +void subghz_read_raw_draw(Canvas* canvas, SubghzReadRAWModel* model) { + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 5, 8, string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 40, 8, string_get_cstr(model->preset_str)); + canvas_draw_str_aligned( + canvas, 126, 0, AlignRight, AlignTop, string_get_cstr(model->sample_write)); + + canvas_draw_line(canvas, 0, 14, 115, 14); + subghz_read_raw_draw_rssi(canvas, model); + canvas_draw_line(canvas, 0, 48, 115, 48); + canvas_draw_line(canvas, 115, 14, 115, 48); + + if(model->satus == SubghzReadRAWStatusIDLE) { + elements_button_left(canvas, "Config"); + elements_button_center(canvas, "REC"); + elements_button_right(canvas, "More"); + } else if(model->satus == SubghzReadRAWStatusStart) { + elements_button_left(canvas, "Config"); + elements_button_center(canvas, "REC"); + } 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) { + furi_assert(context); + SubghzReadRAW* instance = context; + + if(event->key == InputKeyBack && event->type == InputTypeShort) { + instance->callback(SubghzCustomEventViewReadRAWBack, instance->context); + } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + if(model->satus == SubghzReadRAWStatusIDLE || + model->satus == SubghzReadRAWStatusStart) { + instance->callback(SubghzCustomEventViewReadRAWConfig, instance->context); + } + return true; + }); + } else if(event->key == InputKeyRight && event->type == InputTypeShort) { + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + if(model->satus == SubghzReadRAWStatusIDLE) { + instance->callback(SubghzCustomEventViewReadRAWMore, instance->context); + } + return true; + }); + } else if(event->key == InputKeyOk && event->type == InputTypeShort) { + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + if(model->satus == SubghzReadRAWStatusIDLE || + model->satus == SubghzReadRAWStatusStart) { + instance->callback(SubghzCustomEventViewReadRAWREC, instance->context); + model->satus = SubghzReadRAWStatusREC; + model->ind_write = 0; + model->rssi_history_end = false; + } else { + instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); + model->satus = SubghzReadRAWStatusIDLE; + } + return true; + }); + } + + return true; +} + +void subghz_read_raw_enter(void* context) { + furi_assert(context); + SubghzReadRAW* instance = context; + + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + model->satus = SubghzReadRAWStatusStart; + model->rssi_history = furi_alloc(SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); + model->rssi_history_end = false; + model->ind_write = 0; + string_set(model->sample_write, "0 spl."); + return true; + }); +} + +void subghz_read_raw_exit(void* context) { + furi_assert(context); + SubghzReadRAW* instance = context; + + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + if(model->satus != SubghzReadRAWStatusIDLE && + model->satus != SubghzReadRAWStatusStart) { + instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); + model->satus = SubghzReadRAWStatusStart; + } + string_clean(model->frequency_str); + string_clean(model->preset_str); + string_clean(model->sample_write); + free(model->rssi_history); + return true; + }); +} + +SubghzReadRAW* subghz_read_raw_alloc() { + SubghzReadRAW* instance = furi_alloc(sizeof(SubghzReadRAW)); + + // View allocation and configuration + instance->view = view_alloc(); + view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(SubghzReadRAWModel)); + view_set_context(instance->view, instance); + view_set_draw_callback(instance->view, (ViewDrawCallback)subghz_read_raw_draw); + view_set_input_callback(instance->view, subghz_read_raw_input); + view_set_enter_callback(instance->view, subghz_read_raw_enter); + view_set_exit_callback(instance->view, subghz_read_raw_exit); + + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + string_init(model->frequency_str); + string_init(model->preset_str); + string_init(model->sample_write); + return true; + }); + + return instance; +} + +void subghz_read_raw_free(SubghzReadRAW* instance) { + furi_assert(instance); + + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + string_clear(model->frequency_str); + string_clear(model->preset_str); + string_clear(model->sample_write); + return true; + }); + view_free(instance->view); + free(instance); +} + +View* subghz_read_raw_get_view(SubghzReadRAW* instance) { + furi_assert(instance); + return instance->view; +} \ No newline at end of file diff --git a/applications/subghz/views/subghz_read_raw.h b/applications/subghz/views/subghz_read_raw.h new file mode 100644 index 00000000..d6a2337f --- /dev/null +++ b/applications/subghz/views/subghz_read_raw.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include "../helpers/subghz_custom_event.h" + +typedef struct SubghzReadRAW SubghzReadRAW; + +typedef void (*SubghzReadRAWCallback)(SubghzCustomEvent event, void* context); + +void subghz_read_raw_set_callback( + SubghzReadRAW* subghz_read_raw, + SubghzReadRAWCallback callback, + void* context); + +SubghzReadRAW* subghz_read_raw_alloc(); + +void subghz_read_raw_free(SubghzReadRAW* subghz_static); + +void subghz_read_raw_add_data_statusbar( + SubghzReadRAW* instance, + const char* frequency_str, + const char* preset_str); + +void subghz_read_raw_update_sample_write(SubghzReadRAW* instance, size_t sample); + +void subghz_read_raw_add_data_rssi(SubghzReadRAW* instance, float rssi); + +View* subghz_read_raw_get_view(SubghzReadRAW* subghz_static); diff --git a/applications/subghz/views/subghz_save_raw.c b/applications/subghz/views/subghz_save_raw.c deleted file mode 100644 index b496cef7..00000000 --- a/applications/subghz/views/subghz_save_raw.c +++ /dev/null @@ -1,313 +0,0 @@ -#include "subghz_save_raw.h" -#include "../subghz_i.h" - -#include -#include -#include -#include -#include -#include - -#include -#define SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE 100 - -typedef enum { - SubghzSaveRAWStatusStart, - SubghzSaveRAWStatusIDLE, - SubghzSaveRAWStatusREC, - SubghzSaveRAWStatusShowName, -} SubghzSaveRAWStatus; - -struct SubghzSaveRAW { - View* view; - osTimerId timer; - SubghzSaveRAWCallback callback; - void* context; -}; - -typedef struct { - string_t frequency_str; - string_t preset_str; - string_t sample_write; - string_t file_name; - uint8_t* rssi_history; - bool rssi_history_end; - uint8_t ind_write; - SubghzSaveRAWStatus satus; -} SubghzSaveRAWModel; - -void subghz_save_raw_set_callback( - SubghzSaveRAW* subghz_save_raw, - SubghzSaveRAWCallback callback, - void* context) { - furi_assert(subghz_save_raw); - furi_assert(callback); - subghz_save_raw->callback = callback; - subghz_save_raw->context = context; -} - -void subghz_save_raw_add_data_statusbar( - SubghzSaveRAW* instance, - const char* frequency_str, - const char* preset_str) { - furi_assert(instance); - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - string_set(model->frequency_str, frequency_str); - string_set(model->preset_str, preset_str); - return true; - }); -} - -void subghz_save_raw_set_file_name(SubghzSaveRAW* instance, const char* file_name) { - furi_assert(instance); - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - string_set(model->file_name, file_name); - return true; - }); -} - -static void subghz_save_raw_timer_callback(void* context) { - furi_assert(context); - SubghzSaveRAW* instance = context; - - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - model->satus = SubghzSaveRAWStatusIDLE; - return true; - }); -} - -void subghz_save_raw_add_data_rssi(SubghzSaveRAW* instance, float rssi) { - furi_assert(instance); - uint8_t u_rssi = 0; - - if(rssi < -90) { - u_rssi = 0; - } else { - u_rssi = (uint8_t)((rssi + 90) / 2.7); - } - //if(u_rssi > 34) u_rssi = 34; - - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - model->rssi_history[model->ind_write++] = u_rssi; - if(model->ind_write > SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE) { - model->rssi_history_end = true; - model->ind_write = 0; - } - return true; - }); -} - -void subghz_save_raw_update_sample_write(SubghzSaveRAW* instance, size_t sample) { - furi_assert(instance); - - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - string_printf(model->sample_write, "%d spl.", sample); - return false; - }); -} - -void subghz_save_raw_draw_rssi(Canvas* canvas, SubghzSaveRAWModel* model) { - int ind = 0; - int base = 0; - if(model->rssi_history_end == false) { - for(int i = model->ind_write; i >= 0; i--) { - canvas_draw_line(canvas, i, 47, i, 47 - model->rssi_history[i]); - } - if(model->ind_write > 3) { - canvas_draw_line(canvas, model->ind_write, 47, model->ind_write, 13); - canvas_draw_line(canvas, model->ind_write - 2, 12, model->ind_write + 2, 12); - canvas_draw_line(canvas, model->ind_write - 1, 13, model->ind_write + 1, 13); - } - } else { - base = SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE - model->ind_write; - for(int i = SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE; i >= 0; i--) { - ind = i - base; - if(ind < 0) ind += SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE; - canvas_draw_line(canvas, i, 47, i, 47 - model->rssi_history[ind]); - } - canvas_draw_line( - canvas, SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE, 47, SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE, 13); - canvas_draw_line( - canvas, - SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE - 2, - 12, - SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE + 2, - 12); - canvas_draw_line( - canvas, - SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE - 1, - 13, - SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE + 1, - 13); - } -} - -void subghz_save_raw_draw(Canvas* canvas, SubghzSaveRAWModel* model) { - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - if(model->satus != SubghzSaveRAWStatusShowName) { - canvas_draw_str(canvas, 5, 8, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 40, 8, string_get_cstr(model->preset_str)); - canvas_draw_str_aligned( - canvas, 126, 0, AlignRight, AlignTop, string_get_cstr(model->sample_write)); - } else { - canvas_draw_str_aligned( - canvas, 61, 1, AlignRight, AlignTop, string_get_cstr(model->file_name)); - canvas_draw_str(canvas, 65, 8, "Saved!"); - } - - canvas_draw_line(canvas, 0, 14, 115, 14); - subghz_save_raw_draw_rssi(canvas, model); - canvas_draw_line(canvas, 0, 48, 115, 48); - canvas_draw_line(canvas, 115, 14, 115, 48); - - if(model->satus == SubghzSaveRAWStatusIDLE) { - elements_button_left(canvas, "Config"); - elements_button_center(canvas, "REC"); - elements_button_right(canvas, "More"); - } else if(model->satus == SubghzSaveRAWStatusStart) { - elements_button_left(canvas, "Config"); - elements_button_center(canvas, "REC"); - } 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_save_raw_input(InputEvent* event, void* context) { - furi_assert(context); - SubghzSaveRAW* instance = context; - - if(event->key == InputKeyBack && event->type == InputTypeShort) { - instance->callback(SubghzCustomEventViewSaveRAWBack, instance->context); - } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - if(model->satus == SubghzSaveRAWStatusIDLE || - model->satus == SubghzSaveRAWStatusStart) { - instance->callback(SubghzCustomEventViewSaveRAWConfig, instance->context); - } - return true; - }); - } else if(event->key == InputKeyRight && event->type == InputTypeShort) { - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - if(model->satus == SubghzSaveRAWStatusIDLE) { - instance->callback(SubghzCustomEventViewSaveRAWMore, instance->context); - } - return true; - }); - } else if(event->key == InputKeyOk && event->type == InputTypeShort) { - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - if(model->satus == SubghzSaveRAWStatusIDLE || - model->satus == SubghzSaveRAWStatusStart) { - instance->callback(SubghzCustomEventViewSaveRAWREC, instance->context); - model->satus = SubghzSaveRAWStatusREC; - model->ind_write = 0; - model->rssi_history_end = false; - } else { - instance->callback(SubghzCustomEventViewSaveRAWIDLE, instance->context); - model->satus = SubghzSaveRAWStatusShowName; - osTimerStart(instance->timer, 1024); - } - return true; - }); - } - - if(event->key == InputKeyBack) { - return false; - } - - return true; -} - -void subghz_save_raw_enter(void* context) { - furi_assert(context); - SubghzSaveRAW* instance = context; - - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - model->satus = SubghzSaveRAWStatusStart; - model->rssi_history = furi_alloc(SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); - model->rssi_history_end = false; - model->ind_write = 0; - string_set(model->sample_write, "0 spl."); - return true; - }); -} - -void subghz_save_raw_exit(void* context) { - furi_assert(context); - SubghzSaveRAW* instance = context; - - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - if(model->satus != SubghzSaveRAWStatusIDLE && - model->satus != SubghzSaveRAWStatusStart) { - instance->callback(SubghzCustomEventViewSaveRAWIDLE, instance->context); - model->satus = SubghzSaveRAWStatusStart; - } - string_clean(model->frequency_str); - string_clean(model->preset_str); - string_clean(model->sample_write); - string_clean(model->file_name); - free(model->rssi_history); - return true; - }); -} - -SubghzSaveRAW* subghz_save_raw_alloc() { - SubghzSaveRAW* instance = furi_alloc(sizeof(SubghzSaveRAW)); - - // View allocation and configuration - instance->view = view_alloc(); - view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(SubghzSaveRAWModel)); - view_set_context(instance->view, instance); - view_set_draw_callback(instance->view, (ViewDrawCallback)subghz_save_raw_draw); - view_set_input_callback(instance->view, subghz_save_raw_input); - view_set_enter_callback(instance->view, subghz_save_raw_enter); - view_set_exit_callback(instance->view, subghz_save_raw_exit); - - instance->timer = osTimerNew(subghz_save_raw_timer_callback, osTimerOnce, instance, NULL); - - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - string_init(model->frequency_str); - string_init(model->preset_str); - string_init(model->sample_write); - string_init(model->file_name); - return true; - }); - - return instance; -} - -void subghz_save_raw_free(SubghzSaveRAW* instance) { - furi_assert(instance); - - with_view_model( - instance->view, (SubghzSaveRAWModel * model) { - string_clear(model->frequency_str); - string_clear(model->preset_str); - string_clear(model->sample_write); - string_clear(model->file_name); - return true; - }); - osTimerDelete(instance->timer); - view_free(instance->view); - free(instance); -} - -View* subghz_save_raw_get_view(SubghzSaveRAW* instance) { - furi_assert(instance); - return instance->view; -} \ No newline at end of file diff --git a/applications/subghz/views/subghz_save_raw.h b/applications/subghz/views/subghz_save_raw.h deleted file mode 100644 index 25d86cf9..00000000 --- a/applications/subghz/views/subghz_save_raw.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include "../helpers/subghz_custom_event.h" - -typedef struct SubghzSaveRAW SubghzSaveRAW; - -typedef void (*SubghzSaveRAWCallback)(SubghzCustomEvent event, void* context); - -void subghz_save_raw_set_callback( - SubghzSaveRAW* subghz_save_raw, - SubghzSaveRAWCallback callback, - void* context); - -SubghzSaveRAW* subghz_save_raw_alloc(); - -void subghz_save_raw_free(SubghzSaveRAW* subghz_static); - -void subghz_save_raw_add_data_statusbar( - SubghzSaveRAW* instance, - const char* frequency_str, - const char* preset_str); - -void subghz_save_raw_set_file_name(SubghzSaveRAW* instance, const char* file_name); - -void subghz_save_raw_update_sample_write(SubghzSaveRAW* instance, size_t sample); - -void subghz_save_raw_add_data_rssi(SubghzSaveRAW* instance, float rssi); - -View* subghz_save_raw_get_view(SubghzSaveRAW* subghz_static); diff --git a/lib/subghz/protocols/subghz_protocol_raw.c b/lib/subghz/protocols/subghz_protocol_raw.c index 8d2311c6..7c711e8a 100644 --- a/lib/subghz/protocols/subghz_protocol_raw.c +++ b/lib/subghz/protocols/subghz_protocol_raw.c @@ -111,7 +111,7 @@ void subghz_protocol_raw_parse(SubGhzProtocolRAW* instance, bool level, uint32_t } if(instance->ind_write == SUBGHZ_DOWNLOAD_MAX_SIZE) { - subghz_protocol_save_raw_to_file_write(instance); + subghz_protocol_raw_save_to_file_write(instance); } } } @@ -128,7 +128,7 @@ void subghz_protocol_set_last_file_name(SubGhzProtocolRAW* instance, const char* string_printf(instance->file_name, "%s", name); } -bool subghz_protocol_save_raw_to_file_init( +bool subghz_protocol_raw_save_to_file_init( SubGhzProtocolRAW* instance, const char* dev_name, uint32_t frequency, @@ -150,30 +150,45 @@ bool subghz_protocol_save_raw_to_file_init( if(!file_worker_mkdir(instance->file_worker, SUBGHZ_RAW_PATH_FOLDER)) { break; } - //get the name of the next free file - file_worker_get_next_filename( - instance->file_worker, - SUBGHZ_RAW_PATH_FOLDER, - dev_name, - SUBGHZ_APP_EXTENSION, - temp_str); - - string_set(instance->file_name, temp_str); + string_set(instance->file_name, dev_name); + // First remove subghz device file if it was saved string_printf( - dev_file_name, - "%s/%s%s", - SUBGHZ_RAW_PATH_FOLDER, - string_get_cstr(temp_str), - SUBGHZ_APP_EXTENSION); - // Open file - if(!file_worker_open( - instance->file_worker, - string_get_cstr(dev_file_name), - FSAM_WRITE, - FSOM_CREATE_ALWAYS)) { + dev_file_name, "%s/%s%s", SUBGHZ_APP_PATH_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); + if(!file_worker_remove(instance->file_worker, string_get_cstr(dev_file_name))) { break; } + // Open file + if(!file_worker_open( + instance->file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + break; + } + + // //get the name of the next free file + // file_worker_get_next_filename( + // instance->file_worker, + // SUBGHZ_RAW_PATH_FOLDER, + // dev_name, + // SUBGHZ_APP_EXTENSION, + // temp_str); + + // string_set(instance->file_name, temp_str); + + // string_printf( + // dev_file_name, + // "%s/%s%s", + // SUBGHZ_RAW_PATH_FOLDER, + // string_get_cstr(temp_str), + // SUBGHZ_APP_EXTENSION); + // // Open file + // if(!file_worker_open( + // instance->file_worker, + // string_get_cstr(dev_file_name), + // FSAM_WRITE, + // FSOM_CREATE_ALWAYS)) { + // break; + // } + //Get string frequency preset protocol string_printf( temp_str, @@ -200,11 +215,11 @@ bool subghz_protocol_save_raw_to_file_init( return init; } -void subghz_protocol_save_raw_to_file_stop(SubGhzProtocolRAW* instance) { +void subghz_protocol_raw_save_to_file_stop(SubGhzProtocolRAW* instance) { furi_assert(instance); if(instance->file_is_open == RAWFileIsOpenWrite && instance->ind_write) - subghz_protocol_save_raw_to_file_write(instance); + subghz_protocol_raw_save_to_file_write(instance); if(instance->file_is_open != RAWFileIsOpenClose) { free(instance->upload_raw); instance->upload_raw = NULL; @@ -214,7 +229,7 @@ void subghz_protocol_save_raw_to_file_stop(SubGhzProtocolRAW* instance) { instance->file_is_open = RAWFileIsOpenClose; } -bool subghz_protocol_save_raw_to_file_write(SubGhzProtocolRAW* instance) { +bool subghz_protocol_raw_save_to_file_write(SubGhzProtocolRAW* instance) { furi_assert(instance); string_t temp_str; @@ -252,7 +267,7 @@ bool subghz_protocol_save_raw_to_file_write(SubGhzProtocolRAW* instance) { return is_write; } -size_t subghz_save_protocol_raw_get_sample_write(SubGhzProtocolRAW* instance) { +size_t subghz_protocol_raw_get_sample_write(SubGhzProtocolRAW* instance) { return instance->sample_write + instance->ind_write; } diff --git a/lib/subghz/protocols/subghz_protocol_raw.h b/lib/subghz/protocols/subghz_protocol_raw.h index 58253d01..00c84314 100644 --- a/lib/subghz/protocols/subghz_protocol_raw.h +++ b/lib/subghz/protocols/subghz_protocol_raw.h @@ -49,14 +49,14 @@ const char* subghz_protocol_get_last_file_name(SubGhzProtocolRAW* instance); void subghz_protocol_set_last_file_name(SubGhzProtocolRAW* instance, const char* name); -bool subghz_protocol_save_raw_to_file_init( +bool subghz_protocol_raw_save_to_file_init( SubGhzProtocolRAW* instance, const char* dev_name, uint32_t frequency, FuriHalSubGhzPreset preset); -void subghz_protocol_save_raw_to_file_stop(SubGhzProtocolRAW* instance); -bool subghz_protocol_save_raw_to_file_write(SubGhzProtocolRAW* instance); -size_t subghz_save_protocol_raw_get_sample_write(SubGhzProtocolRAW* instance); +void subghz_protocol_raw_save_to_file_stop(SubGhzProtocolRAW* instance); +bool subghz_protocol_raw_save_to_file_write(SubGhzProtocolRAW* instance); +size_t subghz_protocol_raw_get_sample_write(SubGhzProtocolRAW* instance); bool subghz_protocol_raw_to_load_protocol_from_file( FileWorker* file_worker, diff --git a/lib/subghz/subghz_file_encoder_worker.c b/lib/subghz/subghz_file_encoder_worker.c index 4f2aa074..0e502fdf 100644 --- a/lib/subghz/subghz_file_encoder_worker.c +++ b/lib/subghz/subghz_file_encoder_worker.c @@ -192,8 +192,8 @@ bool subghz_file_encoder_worker_start(SubGhzFileEncoderWorker* instance, const c xStreamBufferReset(instance->stream); string_set(instance->file_path, file_path); instance->worker_running = true; - furi_thread_start(instance->thread); - return true; + bool res = furi_thread_start(instance->thread); + return res; } void subghz_file_encoder_worker_stop(SubGhzFileEncoderWorker* instance) {