[FL-2047] SubGhz: New GUI ReadRAW view (#832)
* SubGhz: GUI RAW Read view * SubGhz: GUI Read RAW refactoring * SubGhz: fix bug wrong frequency of the allowed transmission * GUI Read RAW refactoring * SubGhz: fix set the default frequency * SubGhz: fix save filename when returning from another menu * SubGhz: fix Send and Back button behavior Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									01f08f99b1
								
							
						
					
					
						commit
						a13f87fedb
					
				| @ -14,8 +14,8 @@ typedef enum { | ||||
|     SubghzCustomEventSceneShowError, | ||||
|     SubghzCustomEventSceneShowOnlyRX, | ||||
| 
 | ||||
|     SubghzCustomEventSceneNeedSavingNo, | ||||
|     SubghzCustomEventSceneNeedSavingYes, | ||||
|     SubghzCustomEventSceneExit, | ||||
|     SubghzCustomEventSceneStay, | ||||
| 
 | ||||
|     SubghzCustomEventViewReceverOK, | ||||
|     SubghzCustomEventViewReceverConfig, | ||||
| @ -25,7 +25,10 @@ typedef enum { | ||||
|     SubghzCustomEventViewReadRAWIDLE, | ||||
|     SubghzCustomEventViewReadRAWREC, | ||||
|     SubghzCustomEventViewReadRAWConfig, | ||||
|     SubghzCustomEventViewReadRAWMore, | ||||
|     SubghzCustomEventViewReadRAWErase, | ||||
|     SubghzCustomEventViewReadRAWSendStart, | ||||
|     SubghzCustomEventViewReadRAWSendStop, | ||||
|     SubghzCustomEventViewReadRAWSave, | ||||
| 
 | ||||
|     SubghzCustomEventViewTransmitterBack, | ||||
|     SubghzCustomEventViewTransmitterSendStart, | ||||
|  | ||||
| @ -18,5 +18,4 @@ 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, read_raw_menu, ReadRAWMenu) | ||||
| ADD_SCENE(subghz, need_saving, NeedSaving) | ||||
| @ -6,42 +6,46 @@ void subghz_scene_need_saving_callback(GuiButtonType result, InputType type, voi | ||||
|     SubGhz* subghz = context; | ||||
| 
 | ||||
|     if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { | ||||
|         view_dispatcher_send_custom_event( | ||||
|             subghz->view_dispatcher, SubghzCustomEventSceneNeedSavingYes); | ||||
|         view_dispatcher_send_custom_event(subghz->view_dispatcher, SubghzCustomEventSceneStay); | ||||
|     } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { | ||||
|         view_dispatcher_send_custom_event( | ||||
|             subghz->view_dispatcher, SubghzCustomEventSceneNeedSavingNo); | ||||
|         view_dispatcher_send_custom_event(subghz->view_dispatcher, SubghzCustomEventSceneExit); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void subghz_scene_need_saving_on_enter(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
| 
 | ||||
|     widget_add_string_multiline_element( | ||||
|         subghz->widget, 64, 13, AlignCenter, AlignCenter, FontPrimary, "Exit to Gub-Ghz menu?"); | ||||
|     widget_add_string_multiline_element( | ||||
|         subghz->widget, | ||||
|         64, | ||||
|         25, | ||||
|         32, | ||||
|         AlignCenter, | ||||
|         AlignCenter, | ||||
|         FontSecondary, | ||||
|         "There is an unsaved data.\nDo you want to save it?"); | ||||
|         "All unsaved will be\nlost."); | ||||
| 
 | ||||
|     widget_add_button_element( | ||||
|         subghz->widget, GuiButtonTypeRight, "Save", subghz_scene_need_saving_callback, subghz); | ||||
|         subghz->widget, GuiButtonTypeRight, "Stay", subghz_scene_need_saving_callback, subghz); | ||||
|     widget_add_button_element( | ||||
|         subghz->widget, GuiButtonTypeLeft, "Delete", subghz_scene_need_saving_callback, subghz); | ||||
|         subghz->widget, GuiButtonTypeLeft, "Exit", 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; | ||||
|     if(event.type == SceneManagerEventTypeBack) { | ||||
|         subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; | ||||
|         scene_manager_previous_scene(subghz->scene_manager); | ||||
|         return true; | ||||
|     } else if(event.type == SceneManagerEventTypeCustom) { | ||||
|         if(event.event == SubghzCustomEventSceneStay) { | ||||
|             subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; | ||||
|             scene_manager_previous_scene(subghz->scene_manager); | ||||
|             return true; | ||||
|         } else if(event.event == SubghzCustomEventSceneNeedSavingNo) { | ||||
|         } else if(event.event == SubghzCustomEventSceneExit) { | ||||
|             if(subghz->txrx->rx_key_state == SubGhzRxKeyStateExit) { | ||||
|                 subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; | ||||
|                 scene_manager_search_and_switch_to_previous_scene( | ||||
|  | ||||
| @ -2,6 +2,9 @@ | ||||
| #include "../views/subghz_read_raw.h" | ||||
| #include <lib/subghz/protocols/subghz_protocol_raw.h> | ||||
| #include <lib/subghz/subghz_parser.h> | ||||
| #include <lib/toolbox/path.h> | ||||
| 
 | ||||
| #define RAW_FILE_NAME "Raw_temp" | ||||
| 
 | ||||
| static void subghz_scene_read_raw_update_statusbar(void* context) { | ||||
|     furi_assert(context); | ||||
| @ -27,13 +30,20 @@ void subghz_scene_read_raw_callback(SubghzCustomEvent event, void* context) { | ||||
|     view_dispatcher_send_custom_event(subghz->view_dispatcher, event); | ||||
| } | ||||
| 
 | ||||
| void subghz_scene_read_raw_callback_end_tx(void* context) { | ||||
|     furi_assert(context); | ||||
|     SubGhz* subghz = context; | ||||
|     view_dispatcher_send_custom_event( | ||||
|         subghz->view_dispatcher, SubghzCustomEventViewReadRAWSendStop); | ||||
| } | ||||
| 
 | ||||
| void subghz_scene_read_raw_on_enter(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
| 
 | ||||
|     if(subghz->txrx->rx_key_state == SubGhzRxKeyStateNeedSave) { | ||||
|         view_dispatcher_send_custom_event( | ||||
|             subghz->view_dispatcher, SubghzCustomEventViewReadRAWMore); | ||||
|     if(subghz->txrx->rx_key_state == SubGhzRxKeyStateBack) { | ||||
|         subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusIDLE); | ||||
|     } else { | ||||
|         subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusStart); | ||||
|         subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; | ||||
|     } | ||||
| 
 | ||||
| @ -46,6 +56,11 @@ void subghz_scene_read_raw_on_enter(void* context) { | ||||
|     subghz_worker_set_pair_callback( | ||||
|         subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_parser_raw_parse); | ||||
| 
 | ||||
|     subghz_protocol_raw_file_encoder_worker_set_callback_end( | ||||
|         (SubGhzProtocolRAW*)subghz->txrx->protocol_result, | ||||
|         subghz_scene_read_raw_callback_end_tx, | ||||
|         subghz); | ||||
| 
 | ||||
|     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReadRAW); | ||||
| } | ||||
| 
 | ||||
| @ -54,20 +69,29 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         switch(event.event) { | ||||
|         case SubghzCustomEventViewReadRAWBack: | ||||
|             //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->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; | ||||
|             subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; | ||||
|             //Stop save file
 | ||||
|             subghz_protocol_raw_save_to_file_stop( | ||||
|                 (SubGhzProtocolRAW*)subghz->txrx->protocol_result); | ||||
|             subghz->state_notifications = SubGhzNotificationStateIDLE; | ||||
| 
 | ||||
|             if(subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) { | ||||
|             //needed save?
 | ||||
|             if((subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) || | ||||
|                (subghz->txrx->rx_key_state == SubGhzRxKeyStateBack)) { | ||||
|                 subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; | ||||
|                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); | ||||
|             } else { | ||||
|                 //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); | ||||
|             } | ||||
| @ -80,6 +104,63 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { | ||||
|             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); | ||||
|             return true; | ||||
|             break; | ||||
|         case SubghzCustomEventViewReadRAWErase: | ||||
|             subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; | ||||
|             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); | ||||
|                 //start send
 | ||||
|                 subghz->state_notifications = SubGhzNotificationStateIDLE; | ||||
|                 if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { | ||||
|                     subghz_rx_end(subghz); | ||||
|                 } | ||||
|                 if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || | ||||
|                    (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { | ||||
|                     if(!subghz_tx_start(subghz)) { | ||||
|                         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) { | ||||
|                 subghz_tx_stop(subghz); | ||||
|                 subghz_sleep(subghz); | ||||
|             } | ||||
|             subghz_read_raw_stop_send(subghz->subghz_read_raw); | ||||
|             return true; | ||||
|             break; | ||||
|         case SubghzCustomEventViewReadRAWIDLE: | ||||
|             if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { | ||||
|                 subghz_rx_end(subghz); | ||||
| @ -101,7 +182,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { | ||||
|                 subghz_get_preset_name(subghz, subghz->error_str); | ||||
|                 if(subghz_protocol_raw_save_to_file_init( | ||||
|                        (SubGhzProtocolRAW*)subghz->txrx->protocol_result, | ||||
|                        "Raw_temp", | ||||
|                        RAW_FILE_NAME, | ||||
|                        subghz->txrx->frequency, | ||||
|                        string_get_cstr(subghz->error_str))) { | ||||
|                     if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || | ||||
| @ -118,21 +199,25 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
|             return true; | ||||
|             break; | ||||
|         case SubghzCustomEventViewReadRAWMore: | ||||
|         case SubghzCustomEventViewReadRAWSave: | ||||
|             if(strcmp( | ||||
|                    subghz_protocol_raw_get_last_file_name( | ||||
|                        (SubGhzProtocolRAW*)subghz->txrx->protocol_result), | ||||
|                    "")) { | ||||
|                 strlcpy( | ||||
|                     subghz->file_name, | ||||
|                     subghz_protocol_raw_get_last_file_name( | ||||
|                         (SubGhzProtocolRAW*)subghz->txrx->protocol_result), | ||||
|                     strlen(subghz_protocol_raw_get_last_file_name( | ||||
|                         (SubGhzProtocolRAW*)subghz->txrx->protocol_result)) + | ||||
|                         1); | ||||
|                 //set the path to read the file
 | ||||
|                 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, | ||||
| @ -142,7 +227,10 @@ bool subghz_scene_read_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, SubGhzSceneReadRAWMenu); | ||||
|                 scene_manager_set_scene_state( | ||||
|                     subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet); | ||||
|                 subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; | ||||
|                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); | ||||
|             } | ||||
|             return true; | ||||
|             break; | ||||
| @ -160,6 +248,10 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { | ||||
|                     (SubGhzProtocolRAW*)subghz->txrx->protocol_result)); | ||||
|             subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, furi_hal_subghz_get_rssi()); | ||||
|             break; | ||||
|         case SubGhzNotificationStateTX: | ||||
|             notification_message(subghz->notifications, &sequence_blink_green_10); | ||||
|             subghz_read_raw_update_sin(subghz->subghz_read_raw); | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|  | ||||
| @ -1,72 +0,0 @@ | ||||
| #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; | ||||
| } | ||||
| @ -2,6 +2,7 @@ | ||||
| #include <lib/toolbox/random_name.h> | ||||
| #include "file-worker.h" | ||||
| #include "../helpers/subghz_custom_event.h" | ||||
| #include <lib/subghz/protocols/subghz_protocol_raw.h> | ||||
| 
 | ||||
| void subghz_scene_save_name_text_input_callback(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
| @ -20,7 +21,7 @@ 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) + 1); | ||||
|         if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAWMenu) == | ||||
|         if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == | ||||
|            SubghzCustomEventManagerSet) { | ||||
|             subghz_get_next_name_file(subghz); | ||||
|         } | ||||
| @ -49,6 +50,11 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { | ||||
|                     subghz_save_protocol_to_file(subghz, subghz->file_name); | ||||
|                 } | ||||
| 
 | ||||
|                 if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == | ||||
|                    SubghzCustomEventManagerSet) { | ||||
|                     subghz_protocol_raw_set_last_file_name( | ||||
|                         (SubGhzProtocolRAW*)subghz->txrx->protocol_result, subghz->file_name); | ||||
|                 } | ||||
|                 subghz_file_name_clear(subghz); | ||||
|                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); | ||||
|                 return true; | ||||
| @ -68,5 +74,5 @@ 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); | ||||
|         subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerNoSet); | ||||
| } | ||||
|  | ||||
| @ -26,8 +26,11 @@ 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)) { | ||||
|                 scene_manager_search_and_switch_to_previous_scene( | ||||
|                     subghz->scene_manager, SubGhzSceneStart); | ||||
|                 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); | ||||
|                 } | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
| @ -23,7 +23,7 @@ void subghz_scene_start_on_enter(void* context) { | ||||
|         subghz->submenu, "Read", SubmenuIndexRead, subghz_scene_start_submenu_callback, subghz); | ||||
|     submenu_add_item( | ||||
|         subghz->submenu, | ||||
|         "Read Raw", | ||||
|         "Read RAW", | ||||
|         SubmenuIndexReadRAW, | ||||
|         subghz_scene_start_submenu_callback, | ||||
|         subghz); | ||||
| @ -57,6 +57,7 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { | ||||
|         if(event.event == SubmenuIndexReadRAW) { | ||||
|             scene_manager_set_scene_state( | ||||
|                 subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW); | ||||
|             subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; | ||||
|             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); | ||||
|             return true; | ||||
|         } else if(event.event == SubmenuIndexRead) { | ||||
|  | ||||
| @ -70,6 +70,7 @@ typedef enum { | ||||
|     SubGhzRxKeyStateIDLE, | ||||
|     SubGhzRxKeyStateNoSave, | ||||
|     SubGhzRxKeyStateNeedSave, | ||||
|     SubGhzRxKeyStateBack, | ||||
|     SubGhzRxKeyStateAddKey, | ||||
|     SubGhzRxKeyStateExit, | ||||
| } SubGhzRxKeyState; | ||||
|  | ||||
| @ -11,13 +11,6 @@ | ||||
| #include <assets_icons.h> | ||||
| #define SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE 100 | ||||
| 
 | ||||
| typedef enum { | ||||
|     SubghzReadRAWStatusStart, | ||||
|     SubghzReadRAWStatusIDLE, | ||||
|     SubghzReadRAWStatusREC, | ||||
|     //SubghzReadRAWStatusShowName,
 | ||||
| } SubghzReadRAWStatus; | ||||
| 
 | ||||
| struct SubghzReadRAW { | ||||
|     View* view; | ||||
|     SubghzReadRAWCallback callback; | ||||
| @ -31,6 +24,7 @@ typedef struct { | ||||
|     uint8_t* rssi_history; | ||||
|     bool rssi_history_end; | ||||
|     uint8_t ind_write; | ||||
|     uint8_t ind_sin; | ||||
|     SubghzReadRAWStatus satus; | ||||
| } SubghzReadRAWModel; | ||||
| 
 | ||||
| @ -89,6 +83,88 @@ void subghz_read_raw_update_sample_write(SubghzReadRAW* instance, size_t sample) | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void subghz_read_raw_stop_send(SubghzReadRAW* instance) { | ||||
|     furi_assert(instance); | ||||
| 
 | ||||
|     with_view_model( | ||||
|         instance->view, (SubghzReadRAWModel * model) { | ||||
|             if(model->satus == SubghzReadRAWStatusTXRepeat) { | ||||
|                 // Start TX
 | ||||
|                 instance->callback(SubghzCustomEventViewReadRAWSendStart, instance->context); | ||||
|             } else { | ||||
|                 model->satus = SubghzReadRAWStatusIDLE; | ||||
|             } | ||||
|             return true; | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void subghz_read_raw_update_sin(SubghzReadRAW* instance) { | ||||
|     furi_assert(instance); | ||||
|     with_view_model( | ||||
|         instance->view, (SubghzReadRAWModel * model) { | ||||
|             if(model->ind_sin++ > 62) { | ||||
|                 model->ind_sin = 0; | ||||
|             } | ||||
|             return true; | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| static int8_t subghz_read_raw_tab_sin(uint8_t x) { | ||||
|     const uint8_t tab_sin[64] = {0,   3,   6,   9,   12,  16,  19,  22,  25,  28,  31,  34,  37, | ||||
|                                  40,  43,  46,  49,  51,  54,  57,  60,  63,  65,  68,  71,  73, | ||||
|                                  76,  78,  81,  83,  85,  88,  90,  92,  94,  96,  98,  100, 102, | ||||
|                                  104, 106, 107, 109, 111, 112, 113, 115, 116, 117, 118, 120, 121, | ||||
|                                  122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127}; | ||||
| 
 | ||||
|     int8_t r = tab_sin[((x & 0x40) ? -x - 1 : x) & 0x3f]; | ||||
|     if(x & 0x80) return -r; | ||||
|     return r; | ||||
| } | ||||
| 
 | ||||
| void subghz_read_raw_draw_sin(Canvas* canvas, SubghzReadRAWModel* model) { | ||||
| #define SUBGHZ_RAW_SIN_AMPLITUDE 11 | ||||
|     for(int i = 114; i > 0; i--) { | ||||
|         canvas_draw_line( | ||||
|             canvas, | ||||
|             i, | ||||
|             32 - subghz_read_raw_tab_sin(i + model->ind_sin * 16) / SUBGHZ_RAW_SIN_AMPLITUDE, | ||||
|             i + 1, | ||||
|             32 + subghz_read_raw_tab_sin((i + model->ind_sin * 16 + 1) * 2) / | ||||
|                      SUBGHZ_RAW_SIN_AMPLITUDE); | ||||
|         canvas_draw_line( | ||||
|             canvas, | ||||
|             i + 1, | ||||
|             32 - subghz_read_raw_tab_sin((i + model->ind_sin * 16)) / SUBGHZ_RAW_SIN_AMPLITUDE, | ||||
|             i + 2, | ||||
|             32 + subghz_read_raw_tab_sin((i + model->ind_sin * 16 + 1) * 2) / | ||||
|                      SUBGHZ_RAW_SIN_AMPLITUDE); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void subghz_read_raw_draw_scale(Canvas* canvas, SubghzReadRAWModel* model) { | ||||
| #define SUBGHZ_RAW_TOP_SCALE 14 | ||||
| #define SUBGHZ_RAW_END_SCALE 115 | ||||
| 
 | ||||
|     if(model->rssi_history_end == false) { | ||||
|         for(int i = SUBGHZ_RAW_END_SCALE; i > 0; i -= 15) { | ||||
|             canvas_draw_line(canvas, i, SUBGHZ_RAW_TOP_SCALE, i, SUBGHZ_RAW_TOP_SCALE + 4); | ||||
|             canvas_draw_line(canvas, i - 5, SUBGHZ_RAW_TOP_SCALE, i - 5, SUBGHZ_RAW_TOP_SCALE + 2); | ||||
|             canvas_draw_line( | ||||
|                 canvas, i - 10, SUBGHZ_RAW_TOP_SCALE, i - 10, SUBGHZ_RAW_TOP_SCALE + 2); | ||||
|         } | ||||
|     } else { | ||||
|         for(int i = SUBGHZ_RAW_END_SCALE - model->ind_write % 15; i > -15; i -= 15) { | ||||
|             canvas_draw_line(canvas, i, SUBGHZ_RAW_TOP_SCALE, i, SUBGHZ_RAW_TOP_SCALE + 4); | ||||
|             if(SUBGHZ_RAW_END_SCALE > i + 5) | ||||
|                 canvas_draw_line( | ||||
|                     canvas, i + 5, SUBGHZ_RAW_TOP_SCALE, i + 5, SUBGHZ_RAW_TOP_SCALE + 2); | ||||
|             if(SUBGHZ_RAW_END_SCALE > i + 10) | ||||
|                 canvas_draw_line( | ||||
|                     canvas, i + 10, SUBGHZ_RAW_TOP_SCALE, i + 10, SUBGHZ_RAW_TOP_SCALE + 2); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void subghz_read_raw_draw_rssi(Canvas* canvas, SubghzReadRAWModel* model) { | ||||
|     int ind = 0; | ||||
|     int base = 0; | ||||
| @ -134,17 +210,26 @@ void subghz_read_raw_draw(Canvas* canvas, SubghzReadRAWModel* model) { | ||||
|         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); | ||||
|     subghz_read_raw_draw_scale(canvas, model); | ||||
| 
 | ||||
|     if((model->satus == SubghzReadRAWStatusTX) || (model->satus == SubghzReadRAWStatusTXRepeat)) { | ||||
|         subghz_read_raw_draw_sin(canvas, model); | ||||
|     } else { | ||||
|         subghz_read_raw_draw_rssi(canvas, model); | ||||
|     } | ||||
| 
 | ||||
|     if(model->satus == SubghzReadRAWStatusIDLE) { | ||||
|         elements_button_left(canvas, "Config"); | ||||
|         elements_button_center(canvas, "REC"); | ||||
|         elements_button_right(canvas, "More"); | ||||
|         elements_button_left(canvas, "Erase"); | ||||
|         elements_button_center(canvas, "Send"); | ||||
|         elements_button_right(canvas, "Save"); | ||||
|     } 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"); | ||||
|     } | ||||
| @ -158,35 +243,83 @@ 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); | ||||
|     if(event->key == InputKeyOk && event->type == InputTypePress) { | ||||
|         with_view_model( | ||||
|             instance->view, (SubghzReadRAWModel * model) { | ||||
|                 uint8_t ret = false; | ||||
|                 if(model->satus == SubghzReadRAWStatusIDLE) { | ||||
|                     // Start TX
 | ||||
|                     instance->callback(SubghzCustomEventViewReadRAWSendStart, instance->context); | ||||
|                     model->satus = SubghzReadRAWStatusTXRepeat; | ||||
|                     ret = true; | ||||
|                 } else if(model->satus == SubghzReadRAWStatusTX) { | ||||
|                     model->satus = SubghzReadRAWStatusTXRepeat; | ||||
|                 } | ||||
|                 return ret; | ||||
|             }); | ||||
|     } else if(event->key == InputKeyOk && event->type == InputTypeRelease) { | ||||
|         with_view_model( | ||||
|             instance->view, (SubghzReadRAWModel * model) { | ||||
|                 if(model->satus == SubghzReadRAWStatusTXRepeat) { | ||||
|                     // Stop repeat TX
 | ||||
|                     model->satus = SubghzReadRAWStatusTX; | ||||
|                 } | ||||
|                 return false; | ||||
|             }); | ||||
|     } else if(event->key == InputKeyBack && event->type == InputTypeShort) { | ||||
|         with_view_model( | ||||
|             instance->view, (SubghzReadRAWModel * model) { | ||||
|                 if(model->satus == SubghzReadRAWStatusREC) { | ||||
|                     //Stop REC
 | ||||
|                     instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); | ||||
|                     model->satus = SubghzReadRAWStatusIDLE; | ||||
|                 } else { | ||||
|                     //Exit
 | ||||
|                     instance->callback(SubghzCustomEventViewReadRAWBack, instance->context); | ||||
|                 } | ||||
|                 return true; | ||||
|             }); | ||||
| 
 | ||||
|     } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { | ||||
|         with_view_model( | ||||
|             instance->view, (SubghzReadRAWModel * model) { | ||||
|                 if(model->satus == SubghzReadRAWStatusIDLE || | ||||
|                    model->satus == SubghzReadRAWStatusStart) { | ||||
|                 if(model->satus == SubghzReadRAWStatusStart) { | ||||
|                     //Config
 | ||||
|                     instance->callback(SubghzCustomEventViewReadRAWConfig, instance->context); | ||||
|                 } | ||||
| 
 | ||||
|                 if(model->satus == SubghzReadRAWStatusIDLE) { | ||||
|                     //Erase
 | ||||
|                     model->satus = SubghzReadRAWStatusStart; | ||||
|                     model->rssi_history_end = false; | ||||
|                     model->ind_write = 0; | ||||
|                     string_set(model->sample_write, "0 spl."); | ||||
|                     instance->callback(SubghzCustomEventViewReadRAWErase, instance->context); | ||||
|                 } | ||||
|                 return true; | ||||
|             }); | ||||
|     } else if(event->key == InputKeyRight && event->type == InputTypeShort) { | ||||
|         with_view_model( | ||||
|             instance->view, (SubghzReadRAWModel * model) { | ||||
|                 //Save
 | ||||
|                 if(model->satus == SubghzReadRAWStatusIDLE) { | ||||
|                     instance->callback(SubghzCustomEventViewReadRAWMore, instance->context); | ||||
|                     instance->callback(SubghzCustomEventViewReadRAWSave, 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) { | ||||
|                 if(model->satus == SubghzReadRAWStatusStart) { | ||||
|                     //Record
 | ||||
|                     instance->callback(SubghzCustomEventViewReadRAWREC, instance->context); | ||||
|                     model->satus = SubghzReadRAWStatusREC; | ||||
|                     model->ind_write = 0; | ||||
|                     model->rssi_history_end = false; | ||||
|                 } else { | ||||
|                 } else if( | ||||
|                     (model->satus != SubghzReadRAWStatusTX) && | ||||
|                     (model->satus != SubghzReadRAWStatusTXRepeat)) { | ||||
|                     //Stop
 | ||||
|                     instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); | ||||
|                     model->satus = SubghzReadRAWStatusIDLE; | ||||
|                 } | ||||
| @ -197,19 +330,29 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void subghz_read_raw_set_status(SubghzReadRAW* instance, SubghzReadRAWStatus satus) { | ||||
|     furi_assert(instance); | ||||
|     if(satus == SubghzReadRAWStatusStart) { | ||||
|         with_view_model( | ||||
|             instance->view, (SubghzReadRAWModel * model) { | ||||
|                 model->satus = SubghzReadRAWStatusStart; | ||||
|                 model->rssi_history_end = false; | ||||
|                 model->ind_write = 0; | ||||
|                 string_set(model->sample_write, "0 spl."); | ||||
|                 return true; | ||||
|             }); | ||||
|     } else if(satus == SubghzReadRAWStatusIDLE) { | ||||
|         with_view_model( | ||||
|             instance->view, (SubghzReadRAWModel * model) { | ||||
|                 model->satus = SubghzReadRAWStatusIDLE; | ||||
|                 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; | ||||
|         }); | ||||
|     //SubghzReadRAW* instance = context;
 | ||||
| } | ||||
| 
 | ||||
| void subghz_read_raw_exit(void* context) { | ||||
| @ -223,10 +366,6 @@ void subghz_read_raw_exit(void* context) { | ||||
|                 instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); | ||||
|                 model->satus = SubghzReadRAWStatusStart; | ||||
|             } | ||||
|             string_reset(model->frequency_str); | ||||
|             string_reset(model->preset_str); | ||||
|             string_reset(model->sample_write); | ||||
|             free(model->rssi_history); | ||||
|             return true; | ||||
|         }); | ||||
| } | ||||
| @ -248,6 +387,7 @@ SubghzReadRAW* subghz_read_raw_alloc() { | ||||
|             string_init(model->frequency_str); | ||||
|             string_init(model->preset_str); | ||||
|             string_init(model->sample_write); | ||||
|             model->rssi_history = furi_alloc(SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); | ||||
|             return true; | ||||
|         }); | ||||
| 
 | ||||
| @ -262,6 +402,7 @@ void subghz_read_raw_free(SubghzReadRAW* instance) { | ||||
|             string_clear(model->frequency_str); | ||||
|             string_clear(model->preset_str); | ||||
|             string_clear(model->sample_write); | ||||
|             free(model->rssi_history); | ||||
|             return true; | ||||
|         }); | ||||
|     view_free(instance->view); | ||||
|  | ||||
| @ -7,6 +7,14 @@ typedef struct SubghzReadRAW SubghzReadRAW; | ||||
| 
 | ||||
| typedef void (*SubghzReadRAWCallback)(SubghzCustomEvent event, void* context); | ||||
| 
 | ||||
| typedef enum { | ||||
|     SubghzReadRAWStatusStart, | ||||
|     SubghzReadRAWStatusIDLE, | ||||
|     SubghzReadRAWStatusREC, | ||||
|     SubghzReadRAWStatusTX, | ||||
|     SubghzReadRAWStatusTXRepeat, | ||||
| } SubghzReadRAWStatus; | ||||
| 
 | ||||
| void subghz_read_raw_set_callback( | ||||
|     SubghzReadRAW* subghz_read_raw, | ||||
|     SubghzReadRAWCallback callback, | ||||
| @ -23,6 +31,12 @@ void subghz_read_raw_add_data_statusbar( | ||||
| 
 | ||||
| void subghz_read_raw_update_sample_write(SubghzReadRAW* instance, size_t sample); | ||||
| 
 | ||||
| void subghz_read_raw_stop_send(SubghzReadRAW* instance); | ||||
| 
 | ||||
| void subghz_read_raw_update_sin(SubghzReadRAW* instance); | ||||
| 
 | ||||
| void subghz_read_raw_add_data_rssi(SubghzReadRAW* instance, float rssi); | ||||
| 
 | ||||
| void subghz_read_raw_set_status(SubghzReadRAW* instance, SubghzReadRAWStatus satus); | ||||
| 
 | ||||
| View* subghz_read_raw_get_view(SubghzReadRAW* subghz_static); | ||||
|  | ||||
| @ -469,7 +469,7 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { | ||||
|     case FuriHalVersionRegionEuRu: | ||||
|         //433,05..434,79; 868,15..868,55
 | ||||
|         if(!(value >= 433050000 && value <= 434790000) && | ||||
|            !(value >= 868150000 && value <= 8680550000)) { | ||||
|            !(value >= 868150000 && value <= 868550000)) { | ||||
|         } else { | ||||
|             txrx = true; | ||||
|         } | ||||
|  | ||||
| @ -469,7 +469,7 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { | ||||
|     case FuriHalVersionRegionEuRu: | ||||
|         //433,05..434,79; 868,15..868,55
 | ||||
|         if(!(value >= 433050000 && value <= 434790000) && | ||||
|            !(value >= 868150000 && value <= 8680550000)) { | ||||
|            !(value >= 868150000 && value <= 868550000)) { | ||||
|         } else { | ||||
|             txrx = true; | ||||
|         } | ||||
|  | ||||
| @ -17,6 +17,8 @@ struct SubGhzProtocolRAW { | ||||
|     string_t file_name; | ||||
|     size_t sample_write; | ||||
|     bool last_level; | ||||
|     SubGhzProtocolRAWCallbackEnd callback_end; | ||||
|     void* context_end; | ||||
| }; | ||||
| 
 | ||||
| typedef enum { | ||||
| @ -65,6 +67,22 @@ void subghz_protocol_raw_free(SubGhzProtocolRAW* instance) { | ||||
|     free(instance); | ||||
| } | ||||
| 
 | ||||
| void subghz_protocol_raw_file_encoder_worker_callback_end(void* context) { | ||||
|     furi_assert(context); | ||||
|     SubGhzProtocolRAW* instance = context; | ||||
|     if(instance->callback_end) instance->callback_end(instance->context_end); | ||||
| } | ||||
| 
 | ||||
| void subghz_protocol_raw_file_encoder_worker_set_callback_end( | ||||
|     SubGhzProtocolRAW* instance, | ||||
|     SubGhzProtocolRAWCallbackEnd callback_end, | ||||
|     void* context_end) { | ||||
|     furi_assert(instance); | ||||
|     furi_assert(callback_end); | ||||
|     instance->callback_end = callback_end; | ||||
|     instance->context_end = context_end; | ||||
| } | ||||
| 
 | ||||
| void subghz_protocol_raw_file_encoder_worker_stop(void* context) { | ||||
|     furi_assert(context); | ||||
|     SubGhzProtocolRAW* instance = context; | ||||
| @ -90,10 +108,17 @@ bool subghz_protocol_raw_send_key( | ||||
|         //the worker needs a file in order to open and read part of the file
 | ||||
|         osDelay(100); | ||||
|         instance->file_is_open = RAWFileIsOpenRead; | ||||
|         //Forwarding UPLOAD to common encoder
 | ||||
|         subghz_protocol_encoder_common_set_callback( | ||||
|             encoder, subghz_file_encoder_worker_get_level_duration, instance->file_worker_encoder); | ||||
|         //forced stop of transmission
 | ||||
|         subghz_protocol_encoder_common_set_callback_end( | ||||
|             encoder, subghz_protocol_raw_file_encoder_worker_stop, instance); | ||||
|         //file transfer complete callback
 | ||||
|         subghz_file_encoder_worker_callback_end( | ||||
|             instance->file_worker_encoder, | ||||
|             subghz_protocol_raw_file_encoder_worker_callback_end, | ||||
|             instance); | ||||
| 
 | ||||
|         loaded = true; | ||||
|     } else { | ||||
| @ -187,7 +212,8 @@ bool subghz_protocol_raw_save_to_file_init( | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         if(!flipper_file_write_string_cstr(instance->flipper_file, "Protocol", instance->common.name)) { | ||||
|         if(!flipper_file_write_string_cstr( | ||||
|                instance->flipper_file, "Protocol", instance->common.name)) { | ||||
|             FURI_LOG_E(TAG, "Unable to add Protocol"); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
| @ -2,6 +2,8 @@ | ||||
| 
 | ||||
| #include "subghz_protocol_common.h" | ||||
| 
 | ||||
| typedef void (*SubGhzProtocolRAWCallbackEnd)(void* context); | ||||
| 
 | ||||
| typedef struct SubGhzProtocolRAW SubGhzProtocolRAW; | ||||
| 
 | ||||
| /** Allocate SubGhzProtocolRAW
 | ||||
| @ -16,6 +18,11 @@ SubGhzProtocolRAW* subghz_protocol_raw_alloc(); | ||||
|  */ | ||||
| void subghz_protocol_raw_free(SubGhzProtocolRAW* instance); | ||||
| 
 | ||||
| void subghz_protocol_raw_file_encoder_worker_set_callback_end( | ||||
|     SubGhzProtocolRAW* instance, | ||||
|     SubGhzProtocolRAWCallbackEnd callback_end, | ||||
|     void* context_end); | ||||
| 
 | ||||
| /** Reset internal state
 | ||||
|  * @param instance - SubGhzProtocolRAW instance | ||||
|  */ | ||||
|  | ||||
| @ -16,12 +16,26 @@ struct SubGhzFileEncoderWorker { | ||||
|     FlipperFile* flipper_file; | ||||
| 
 | ||||
|     volatile bool worker_running; | ||||
|     volatile bool worker_stoping; | ||||
|     bool level; | ||||
|     int32_t duration; | ||||
|     string_t str_data; | ||||
|     string_t file_path; | ||||
| 
 | ||||
|     SubGhzFileEncoderWorkerCallbackEnd callback_end; | ||||
|     void* context_end; | ||||
| }; | ||||
| 
 | ||||
| void subghz_file_encoder_worker_callback_end( | ||||
|     SubGhzFileEncoderWorker* instance, | ||||
|     SubGhzFileEncoderWorkerCallbackEnd callback_end, | ||||
|     void* context_end) { | ||||
|     furi_assert(instance); | ||||
|     furi_assert(callback_end); | ||||
|     instance->callback_end = callback_end; | ||||
|     instance->context_end = context_end; | ||||
| } | ||||
| 
 | ||||
| void subghz_file_encoder_worker_add_livel_duration( | ||||
|     SubGhzFileEncoderWorker* instance, | ||||
|     int32_t duration) { | ||||
| @ -89,6 +103,7 @@ LevelDuration subghz_file_encoder_worker_get_level_duration(void* context) { | ||||
|         } else if(duration == 0) { | ||||
|             level_duration = level_duration_reset(); | ||||
|             FURI_LOG_I(TAG, "Stop transmission"); | ||||
|             instance->worker_stoping = true; | ||||
|         } | ||||
|         return level_duration; | ||||
|     } else { | ||||
| @ -111,9 +126,7 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { | ||||
|         if(!flipper_file_open_existing( | ||||
|                instance->flipper_file, string_get_cstr(instance->file_path))) { | ||||
|             FURI_LOG_E( | ||||
|                 TAG, | ||||
|                 "Unable to open file for read: %s", | ||||
|                 string_get_cstr(instance->file_path)); | ||||
|                 TAG, "Unable to open file for read: %s", string_get_cstr(instance->file_path)); | ||||
|             break; | ||||
|         } | ||||
|         if(!flipper_file_read_string(instance->flipper_file, "Protocol", instance->str_data)) { | ||||
| @ -124,6 +137,7 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { | ||||
|         //skip the end of the previous line "\n"
 | ||||
|         storage_file_seek(file, 1, false); | ||||
|         res = true; | ||||
|         instance->worker_stoping = false; | ||||
|         FURI_LOG_I(TAG, "Start transmission"); | ||||
|     } while(0); | ||||
| 
 | ||||
| @ -152,7 +166,11 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { | ||||
|     } | ||||
|     //waiting for the end of the transfer
 | ||||
|     FURI_LOG_I(TAG, "End read file"); | ||||
| 
 | ||||
|     while(instance->worker_running) { | ||||
|         if(instance->worker_stoping) { | ||||
|             if(instance->callback_end) instance->callback_end(instance->context_end); | ||||
|         } | ||||
|         osDelay(50); | ||||
|     } | ||||
|     flipper_file_close(instance->flipper_file); | ||||
| @ -177,6 +195,7 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { | ||||
|     string_init(instance->str_data); | ||||
|     string_init(instance->file_path); | ||||
|     instance->level = false; | ||||
|     instance->worker_stoping = true; | ||||
| 
 | ||||
|     return instance; | ||||
| } | ||||
|  | ||||
| @ -2,8 +2,20 @@ | ||||
| 
 | ||||
| #include <furi-hal.h> | ||||
| 
 | ||||
| typedef void (*SubGhzFileEncoderWorkerCallbackEnd)(void* context); | ||||
| 
 | ||||
| typedef struct SubGhzFileEncoderWorker SubGhzFileEncoderWorker; | ||||
| 
 | ||||
| /** End callback SubGhzWorker
 | ||||
|  *  | ||||
|  * @param instance SubGhzFileEncoderWorker instance | ||||
|  * @param callback SubGhzFileEncoderWorkerCallbackEnd callback | ||||
|  */ | ||||
| void subghz_file_encoder_worker_callback_end( | ||||
|     SubGhzFileEncoderWorker* instance, | ||||
|     SubGhzFileEncoderWorkerCallbackEnd callback_end, | ||||
|     void* context_end); | ||||
| 
 | ||||
| /** Allocate SubGhzFileEncoderWorker
 | ||||
|  *  | ||||
|  * @return SubGhzFileEncoderWorker*  | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Skorpionm
						Skorpionm