[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, |     SubghzCustomEventSceneShowError, | ||||||
|     SubghzCustomEventSceneShowOnlyRX, |     SubghzCustomEventSceneShowOnlyRX, | ||||||
| 
 | 
 | ||||||
|     SubghzCustomEventSceneNeedSavingNo, |     SubghzCustomEventSceneExit, | ||||||
|     SubghzCustomEventSceneNeedSavingYes, |     SubghzCustomEventSceneStay, | ||||||
| 
 | 
 | ||||||
|     SubghzCustomEventViewReceverOK, |     SubghzCustomEventViewReceverOK, | ||||||
|     SubghzCustomEventViewReceverConfig, |     SubghzCustomEventViewReceverConfig, | ||||||
| @ -25,7 +25,10 @@ typedef enum { | |||||||
|     SubghzCustomEventViewReadRAWIDLE, |     SubghzCustomEventViewReadRAWIDLE, | ||||||
|     SubghzCustomEventViewReadRAWREC, |     SubghzCustomEventViewReadRAWREC, | ||||||
|     SubghzCustomEventViewReadRAWConfig, |     SubghzCustomEventViewReadRAWConfig, | ||||||
|     SubghzCustomEventViewReadRAWMore, |     SubghzCustomEventViewReadRAWErase, | ||||||
|  |     SubghzCustomEventViewReadRAWSendStart, | ||||||
|  |     SubghzCustomEventViewReadRAWSendStop, | ||||||
|  |     SubghzCustomEventViewReadRAWSave, | ||||||
| 
 | 
 | ||||||
|     SubghzCustomEventViewTransmitterBack, |     SubghzCustomEventViewTransmitterBack, | ||||||
|     SubghzCustomEventViewTransmitterSendStart, |     SubghzCustomEventViewTransmitterSendStart, | ||||||
|  | |||||||
| @ -18,5 +18,4 @@ ADD_SCENE(subghz, test_packet, TestPacket) | |||||||
| ADD_SCENE(subghz, set_type, SetType) | ADD_SCENE(subghz, set_type, SetType) | ||||||
| ADD_SCENE(subghz, frequency_analyzer, FrequencyAnalyzer) | ADD_SCENE(subghz, frequency_analyzer, FrequencyAnalyzer) | ||||||
| ADD_SCENE(subghz, read_raw, ReadRAW) | ADD_SCENE(subghz, read_raw, ReadRAW) | ||||||
| ADD_SCENE(subghz, read_raw_menu, ReadRAWMenu) |  | ||||||
| ADD_SCENE(subghz, need_saving, NeedSaving) | ADD_SCENE(subghz, need_saving, NeedSaving) | ||||||
| @ -6,42 +6,46 @@ void subghz_scene_need_saving_callback(GuiButtonType result, InputType type, voi | |||||||
|     SubGhz* subghz = context; |     SubGhz* subghz = context; | ||||||
| 
 | 
 | ||||||
|     if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { |     if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { | ||||||
|         view_dispatcher_send_custom_event( |         view_dispatcher_send_custom_event(subghz->view_dispatcher, SubghzCustomEventSceneStay); | ||||||
|             subghz->view_dispatcher, SubghzCustomEventSceneNeedSavingYes); |  | ||||||
|     } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { |     } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { | ||||||
|         view_dispatcher_send_custom_event( |         view_dispatcher_send_custom_event(subghz->view_dispatcher, SubghzCustomEventSceneExit); | ||||||
|             subghz->view_dispatcher, SubghzCustomEventSceneNeedSavingNo); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void subghz_scene_need_saving_on_enter(void* context) { | void subghz_scene_need_saving_on_enter(void* context) { | ||||||
|     SubGhz* subghz = 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( |     widget_add_string_multiline_element( | ||||||
|         subghz->widget, |         subghz->widget, | ||||||
|         64, |         64, | ||||||
|         25, |         32, | ||||||
|         AlignCenter, |         AlignCenter, | ||||||
|         AlignCenter, |         AlignCenter, | ||||||
|         FontSecondary, |         FontSecondary, | ||||||
|         "There is an unsaved data.\nDo you want to save it?"); |         "All unsaved will be\nlost."); | ||||||
| 
 | 
 | ||||||
|     widget_add_button_element( |     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( |     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); |     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewWidget); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool subghz_scene_need_saving_on_event(void* context, SceneManagerEvent event) { | bool subghz_scene_need_saving_on_event(void* context, SceneManagerEvent event) { | ||||||
|     SubGhz* subghz = context; |     SubGhz* subghz = context; | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeBack) { | ||||||
|         if(event.event == SubghzCustomEventSceneNeedSavingYes) { |         subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; | ||||||
|             subghz->txrx->rx_key_state = SubGhzRxKeyStateNeedSave; |  | ||||||
|         scene_manager_previous_scene(subghz->scene_manager); |         scene_manager_previous_scene(subghz->scene_manager); | ||||||
|         return true; |         return true; | ||||||
|         } else if(event.event == SubghzCustomEventSceneNeedSavingNo) { |     } 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 == SubghzCustomEventSceneExit) { | ||||||
|             if(subghz->txrx->rx_key_state == SubGhzRxKeyStateExit) { |             if(subghz->txrx->rx_key_state == SubGhzRxKeyStateExit) { | ||||||
|                 subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; |                 subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; | ||||||
|                 scene_manager_search_and_switch_to_previous_scene( |                 scene_manager_search_and_switch_to_previous_scene( | ||||||
|  | |||||||
| @ -2,6 +2,9 @@ | |||||||
| #include "../views/subghz_read_raw.h" | #include "../views/subghz_read_raw.h" | ||||||
| #include <lib/subghz/protocols/subghz_protocol_raw.h> | #include <lib/subghz/protocols/subghz_protocol_raw.h> | ||||||
| #include <lib/subghz/subghz_parser.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) { | static void subghz_scene_read_raw_update_statusbar(void* context) { | ||||||
|     furi_assert(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); |     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) { | void subghz_scene_read_raw_on_enter(void* context) { | ||||||
|     SubGhz* subghz = context; |     SubGhz* subghz = context; | ||||||
| 
 | 
 | ||||||
|     if(subghz->txrx->rx_key_state == SubGhzRxKeyStateNeedSave) { |     if(subghz->txrx->rx_key_state == SubGhzRxKeyStateBack) { | ||||||
|         view_dispatcher_send_custom_event( |         subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusIDLE); | ||||||
|             subghz->view_dispatcher, SubghzCustomEventViewReadRAWMore); |  | ||||||
|     } else { |     } else { | ||||||
|  |         subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusStart); | ||||||
|         subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; |         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_worker_set_pair_callback( | ||||||
|         subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_parser_raw_parse); |         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); |     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) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|         switch(event.event) { |         switch(event.event) { | ||||||
|         case SubghzCustomEventViewReadRAWBack: |         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) { |             if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { | ||||||
|                 subghz_rx_end(subghz); |                 subghz_rx_end(subghz); | ||||||
|                 subghz_sleep(subghz); |                 subghz_sleep(subghz); | ||||||
|             }; |             }; | ||||||
|             subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; |             //Stop save file
 | ||||||
|             subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; |  | ||||||
|             subghz_protocol_raw_save_to_file_stop( |             subghz_protocol_raw_save_to_file_stop( | ||||||
|                 (SubGhzProtocolRAW*)subghz->txrx->protocol_result); |                 (SubGhzProtocolRAW*)subghz->txrx->protocol_result); | ||||||
|             subghz->state_notifications = SubGhzNotificationStateIDLE; |             subghz->state_notifications = SubGhzNotificationStateIDLE; | ||||||
| 
 |             //needed save?
 | ||||||
|             if(subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) { |             if((subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) || | ||||||
|  |                (subghz->txrx->rx_key_state == SubGhzRxKeyStateBack)) { | ||||||
|                 subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; |                 subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; | ||||||
|                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); |                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); | ||||||
|             } else { |             } 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( |                 scene_manager_search_and_switch_to_previous_scene( | ||||||
|                     subghz->scene_manager, SubGhzSceneStart); |                     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); |             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); | ||||||
|             return true; |             return true; | ||||||
|             break; |             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: |         case SubghzCustomEventViewReadRAWIDLE: | ||||||
|             if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { |             if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { | ||||||
|                 subghz_rx_end(subghz); |                 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); |                 subghz_get_preset_name(subghz, subghz->error_str); | ||||||
|                 if(subghz_protocol_raw_save_to_file_init( |                 if(subghz_protocol_raw_save_to_file_init( | ||||||
|                        (SubGhzProtocolRAW*)subghz->txrx->protocol_result, |                        (SubGhzProtocolRAW*)subghz->txrx->protocol_result, | ||||||
|                        "Raw_temp", |                        RAW_FILE_NAME, | ||||||
|                        subghz->txrx->frequency, |                        subghz->txrx->frequency, | ||||||
|                        string_get_cstr(subghz->error_str))) { |                        string_get_cstr(subghz->error_str))) { | ||||||
|                     if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || |                     if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || | ||||||
| @ -118,21 +199,25 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { | |||||||
| 
 | 
 | ||||||
|             return true; |             return true; | ||||||
|             break; |             break; | ||||||
|         case SubghzCustomEventViewReadRAWMore: |         case SubghzCustomEventViewReadRAWSave: | ||||||
|             if(strcmp( |             if(strcmp( | ||||||
|                    subghz_protocol_raw_get_last_file_name( |                    subghz_protocol_raw_get_last_file_name( | ||||||
|                        (SubGhzProtocolRAW*)subghz->txrx->protocol_result), |                        (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_t temp_str; | ||||||
|                 string_init_printf( |                 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, |                     temp_str, | ||||||
|                     "%s/%s%s", |                     "%s/%s%s", | ||||||
|                     SUBGHZ_APP_PATH_FOLDER, |                     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)); |                     (SubGhzProtocolRAW*)subghz->txrx->protocol_result, string_get_cstr(temp_str)); | ||||||
|                 string_clear(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; |             return true; | ||||||
|             break; |             break; | ||||||
| @ -160,6 +248,10 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { | |||||||
|                     (SubGhzProtocolRAW*)subghz->txrx->protocol_result)); |                     (SubGhzProtocolRAW*)subghz->txrx->protocol_result)); | ||||||
|             subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, furi_hal_subghz_get_rssi()); |             subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, furi_hal_subghz_get_rssi()); | ||||||
|             break; |             break; | ||||||
|  |         case SubGhzNotificationStateTX: | ||||||
|  |             notification_message(subghz->notifications, &sequence_blink_green_10); | ||||||
|  |             subghz_read_raw_update_sin(subghz->subghz_read_raw); | ||||||
|  |             break; | ||||||
|         default: |         default: | ||||||
|             break; |             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 <lib/toolbox/random_name.h> | ||||||
| #include "file-worker.h" | #include "file-worker.h" | ||||||
| #include "../helpers/subghz_custom_event.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) { | void subghz_scene_save_name_text_input_callback(void* context) { | ||||||
|     SubGhz* subghz = context; |     SubGhz* subghz = context; | ||||||
| @ -20,7 +21,7 @@ void subghz_scene_save_name_on_enter(void* context) { | |||||||
|         dev_name_empty = true; |         dev_name_empty = true; | ||||||
|     } else { |     } else { | ||||||
|         memcpy(subghz->file_name_tmp, subghz->file_name, strlen(subghz->file_name) + 1); |         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) { |            SubghzCustomEventManagerSet) { | ||||||
|             subghz_get_next_name_file(subghz); |             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); |                     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); |                 subghz_file_name_clear(subghz); | ||||||
|                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); |                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); | ||||||
|                 return true; |                 return true; | ||||||
| @ -68,5 +74,5 @@ void subghz_scene_save_name_on_exit(void* context) { | |||||||
|     // Clear view
 |     // Clear view
 | ||||||
|     text_input_clean(subghz->text_input); |     text_input_clean(subghz->text_input); | ||||||
|     scene_manager_set_scene_state( |     scene_manager_set_scene_state( | ||||||
|         subghz->scene_manager, SubGhzSceneReadRAWMenu, SubghzCustomEventManagerNoSet); |         subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerNoSet); | ||||||
| } | } | ||||||
|  | |||||||
| @ -26,9 +26,12 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) | |||||||
|         if(event.event == SubghzCustomEventSceneSaveSuccess) { |         if(event.event == SubghzCustomEventSceneSaveSuccess) { | ||||||
|             if(!scene_manager_search_and_switch_to_previous_scene( |             if(!scene_manager_search_and_switch_to_previous_scene( | ||||||
|                    subghz->scene_manager, SubGhzSceneReceiver)) { |                    subghz->scene_manager, SubGhzSceneReceiver)) { | ||||||
|  |                 if(!scene_manager_search_and_switch_to_previous_scene( | ||||||
|  |                        subghz->scene_manager, SubGhzSceneReadRAW)) { | ||||||
|                     scene_manager_search_and_switch_to_previous_scene( |                     scene_manager_search_and_switch_to_previous_scene( | ||||||
|                         subghz->scene_manager, SubGhzSceneStart); |                         subghz->scene_manager, SubGhzSceneStart); | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ void subghz_scene_start_on_enter(void* context) { | |||||||
|         subghz->submenu, "Read", SubmenuIndexRead, subghz_scene_start_submenu_callback, subghz); |         subghz->submenu, "Read", SubmenuIndexRead, subghz_scene_start_submenu_callback, subghz); | ||||||
|     submenu_add_item( |     submenu_add_item( | ||||||
|         subghz->submenu, |         subghz->submenu, | ||||||
|         "Read Raw", |         "Read RAW", | ||||||
|         SubmenuIndexReadRAW, |         SubmenuIndexReadRAW, | ||||||
|         subghz_scene_start_submenu_callback, |         subghz_scene_start_submenu_callback, | ||||||
|         subghz); |         subghz); | ||||||
| @ -57,6 +57,7 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { | |||||||
|         if(event.event == SubmenuIndexReadRAW) { |         if(event.event == SubmenuIndexReadRAW) { | ||||||
|             scene_manager_set_scene_state( |             scene_manager_set_scene_state( | ||||||
|                 subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW); |                 subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW); | ||||||
|  |             subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; | ||||||
|             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); |             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); | ||||||
|             return true; |             return true; | ||||||
|         } else if(event.event == SubmenuIndexRead) { |         } else if(event.event == SubmenuIndexRead) { | ||||||
|  | |||||||
| @ -70,6 +70,7 @@ typedef enum { | |||||||
|     SubGhzRxKeyStateIDLE, |     SubGhzRxKeyStateIDLE, | ||||||
|     SubGhzRxKeyStateNoSave, |     SubGhzRxKeyStateNoSave, | ||||||
|     SubGhzRxKeyStateNeedSave, |     SubGhzRxKeyStateNeedSave, | ||||||
|  |     SubGhzRxKeyStateBack, | ||||||
|     SubGhzRxKeyStateAddKey, |     SubGhzRxKeyStateAddKey, | ||||||
|     SubGhzRxKeyStateExit, |     SubGhzRxKeyStateExit, | ||||||
| } SubGhzRxKeyState; | } SubGhzRxKeyState; | ||||||
|  | |||||||
| @ -11,13 +11,6 @@ | |||||||
| #include <assets_icons.h> | #include <assets_icons.h> | ||||||
| #define SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE 100 | #define SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE 100 | ||||||
| 
 | 
 | ||||||
| typedef enum { |  | ||||||
|     SubghzReadRAWStatusStart, |  | ||||||
|     SubghzReadRAWStatusIDLE, |  | ||||||
|     SubghzReadRAWStatusREC, |  | ||||||
|     //SubghzReadRAWStatusShowName,
 |  | ||||||
| } SubghzReadRAWStatus; |  | ||||||
| 
 |  | ||||||
| struct SubghzReadRAW { | struct SubghzReadRAW { | ||||||
|     View* view; |     View* view; | ||||||
|     SubghzReadRAWCallback callback; |     SubghzReadRAWCallback callback; | ||||||
| @ -31,6 +24,7 @@ typedef struct { | |||||||
|     uint8_t* rssi_history; |     uint8_t* rssi_history; | ||||||
|     bool rssi_history_end; |     bool rssi_history_end; | ||||||
|     uint8_t ind_write; |     uint8_t ind_write; | ||||||
|  |     uint8_t ind_sin; | ||||||
|     SubghzReadRAWStatus satus; |     SubghzReadRAWStatus satus; | ||||||
| } SubghzReadRAWModel; | } 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) { | void subghz_read_raw_draw_rssi(Canvas* canvas, SubghzReadRAWModel* model) { | ||||||
|     int ind = 0; |     int ind = 0; | ||||||
|     int base = 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, 126, 0, AlignRight, AlignTop, string_get_cstr(model->sample_write)); | ||||||
| 
 | 
 | ||||||
|     canvas_draw_line(canvas, 0, 14, 115, 14); |     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, 0, 48, 115, 48); | ||||||
|     canvas_draw_line(canvas, 115, 14, 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) { |     if(model->satus == SubghzReadRAWStatusIDLE) { | ||||||
|         elements_button_left(canvas, "Config"); |         elements_button_left(canvas, "Erase"); | ||||||
|         elements_button_center(canvas, "REC"); |         elements_button_center(canvas, "Send"); | ||||||
|         elements_button_right(canvas, "More"); |         elements_button_right(canvas, "Save"); | ||||||
|     } else if(model->satus == SubghzReadRAWStatusStart) { |     } else if(model->satus == SubghzReadRAWStatusStart) { | ||||||
|         elements_button_left(canvas, "Config"); |         elements_button_left(canvas, "Config"); | ||||||
|         elements_button_center(canvas, "REC"); |         elements_button_center(canvas, "REC"); | ||||||
|  |     } else if( | ||||||
|  |         (model->satus == SubghzReadRAWStatusTX) || (model->satus == SubghzReadRAWStatusTXRepeat)) { | ||||||
|  |         elements_button_center(canvas, "Send"); | ||||||
|     } else { |     } else { | ||||||
|         elements_button_center(canvas, "Stop"); |         elements_button_center(canvas, "Stop"); | ||||||
|     } |     } | ||||||
| @ -158,35 +243,83 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { | |||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
|     SubghzReadRAW* instance = context; |     SubghzReadRAW* instance = context; | ||||||
| 
 | 
 | ||||||
|     if(event->key == InputKeyBack && event->type == InputTypeShort) { |     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); |                     instance->callback(SubghzCustomEventViewReadRAWBack, instance->context); | ||||||
|  |                 } | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|     } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { |     } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { | ||||||
|         with_view_model( |         with_view_model( | ||||||
|             instance->view, (SubghzReadRAWModel * model) { |             instance->view, (SubghzReadRAWModel * model) { | ||||||
|                 if(model->satus == SubghzReadRAWStatusIDLE || |                 if(model->satus == SubghzReadRAWStatusStart) { | ||||||
|                    model->satus == SubghzReadRAWStatusStart) { |                     //Config
 | ||||||
|                     instance->callback(SubghzCustomEventViewReadRAWConfig, instance->context); |                     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; |                 return true; | ||||||
|             }); |             }); | ||||||
|     } else if(event->key == InputKeyRight && event->type == InputTypeShort) { |     } else if(event->key == InputKeyRight && event->type == InputTypeShort) { | ||||||
|         with_view_model( |         with_view_model( | ||||||
|             instance->view, (SubghzReadRAWModel * model) { |             instance->view, (SubghzReadRAWModel * model) { | ||||||
|  |                 //Save
 | ||||||
|                 if(model->satus == SubghzReadRAWStatusIDLE) { |                 if(model->satus == SubghzReadRAWStatusIDLE) { | ||||||
|                     instance->callback(SubghzCustomEventViewReadRAWMore, instance->context); |                     instance->callback(SubghzCustomEventViewReadRAWSave, instance->context); | ||||||
|                 } |                 } | ||||||
|                 return true; |                 return true; | ||||||
|             }); |             }); | ||||||
|     } else if(event->key == InputKeyOk && event->type == InputTypeShort) { |     } else if(event->key == InputKeyOk && event->type == InputTypeShort) { | ||||||
|         with_view_model( |         with_view_model( | ||||||
|             instance->view, (SubghzReadRAWModel * model) { |             instance->view, (SubghzReadRAWModel * model) { | ||||||
|                 if(model->satus == SubghzReadRAWStatusIDLE || |                 if(model->satus == SubghzReadRAWStatusStart) { | ||||||
|                    model->satus == SubghzReadRAWStatusStart) { |                     //Record
 | ||||||
|                     instance->callback(SubghzCustomEventViewReadRAWREC, instance->context); |                     instance->callback(SubghzCustomEventViewReadRAWREC, instance->context); | ||||||
|                     model->satus = SubghzReadRAWStatusREC; |                     model->satus = SubghzReadRAWStatusREC; | ||||||
|                     model->ind_write = 0; |                     model->ind_write = 0; | ||||||
|                     model->rssi_history_end = false; |                     model->rssi_history_end = false; | ||||||
|                 } else { |                 } else if( | ||||||
|  |                     (model->satus != SubghzReadRAWStatusTX) && | ||||||
|  |                     (model->satus != SubghzReadRAWStatusTXRepeat)) { | ||||||
|  |                     //Stop
 | ||||||
|                     instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); |                     instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); | ||||||
|                     model->satus = SubghzReadRAWStatusIDLE; |                     model->satus = SubghzReadRAWStatusIDLE; | ||||||
|                 } |                 } | ||||||
| @ -197,19 +330,29 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void subghz_read_raw_enter(void* context) { | void subghz_read_raw_set_status(SubghzReadRAW* instance, SubghzReadRAWStatus satus) { | ||||||
|     furi_assert(context); |     furi_assert(instance); | ||||||
|     SubghzReadRAW* instance = context; |     if(satus == SubghzReadRAWStatusStart) { | ||||||
| 
 |  | ||||||
|         with_view_model( |         with_view_model( | ||||||
|             instance->view, (SubghzReadRAWModel * model) { |             instance->view, (SubghzReadRAWModel * model) { | ||||||
|                 model->satus = SubghzReadRAWStatusStart; |                 model->satus = SubghzReadRAWStatusStart; | ||||||
|             model->rssi_history = furi_alloc(SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); |  | ||||||
|                 model->rssi_history_end = false; |                 model->rssi_history_end = false; | ||||||
|                 model->ind_write = 0; |                 model->ind_write = 0; | ||||||
|                 string_set(model->sample_write, "0 spl."); |                 string_set(model->sample_write, "0 spl."); | ||||||
|                 return true; |                 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;
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void subghz_read_raw_exit(void* context) { | void subghz_read_raw_exit(void* context) { | ||||||
| @ -223,10 +366,6 @@ void subghz_read_raw_exit(void* context) { | |||||||
|                 instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); |                 instance->callback(SubghzCustomEventViewReadRAWIDLE, instance->context); | ||||||
|                 model->satus = SubghzReadRAWStatusStart; |                 model->satus = SubghzReadRAWStatusStart; | ||||||
|             } |             } | ||||||
|             string_reset(model->frequency_str); |  | ||||||
|             string_reset(model->preset_str); |  | ||||||
|             string_reset(model->sample_write); |  | ||||||
|             free(model->rssi_history); |  | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| } | } | ||||||
| @ -248,6 +387,7 @@ SubghzReadRAW* subghz_read_raw_alloc() { | |||||||
|             string_init(model->frequency_str); |             string_init(model->frequency_str); | ||||||
|             string_init(model->preset_str); |             string_init(model->preset_str); | ||||||
|             string_init(model->sample_write); |             string_init(model->sample_write); | ||||||
|  |             model->rssi_history = furi_alloc(SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
| @ -262,6 +402,7 @@ void subghz_read_raw_free(SubghzReadRAW* instance) { | |||||||
|             string_clear(model->frequency_str); |             string_clear(model->frequency_str); | ||||||
|             string_clear(model->preset_str); |             string_clear(model->preset_str); | ||||||
|             string_clear(model->sample_write); |             string_clear(model->sample_write); | ||||||
|  |             free(model->rssi_history); | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
|     view_free(instance->view); |     view_free(instance->view); | ||||||
|  | |||||||
| @ -7,6 +7,14 @@ typedef struct SubghzReadRAW SubghzReadRAW; | |||||||
| 
 | 
 | ||||||
| typedef void (*SubghzReadRAWCallback)(SubghzCustomEvent event, void* context); | typedef void (*SubghzReadRAWCallback)(SubghzCustomEvent event, void* context); | ||||||
| 
 | 
 | ||||||
|  | typedef enum { | ||||||
|  |     SubghzReadRAWStatusStart, | ||||||
|  |     SubghzReadRAWStatusIDLE, | ||||||
|  |     SubghzReadRAWStatusREC, | ||||||
|  |     SubghzReadRAWStatusTX, | ||||||
|  |     SubghzReadRAWStatusTXRepeat, | ||||||
|  | } SubghzReadRAWStatus; | ||||||
|  | 
 | ||||||
| void subghz_read_raw_set_callback( | void subghz_read_raw_set_callback( | ||||||
|     SubghzReadRAW* subghz_read_raw, |     SubghzReadRAW* subghz_read_raw, | ||||||
|     SubghzReadRAWCallback callback, |     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_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_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); | 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: |     case FuriHalVersionRegionEuRu: | ||||||
|         //433,05..434,79; 868,15..868,55
 |         //433,05..434,79; 868,15..868,55
 | ||||||
|         if(!(value >= 433050000 && value <= 434790000) && |         if(!(value >= 433050000 && value <= 434790000) && | ||||||
|            !(value >= 868150000 && value <= 8680550000)) { |            !(value >= 868150000 && value <= 868550000)) { | ||||||
|         } else { |         } else { | ||||||
|             txrx = true; |             txrx = true; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -469,7 +469,7 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { | |||||||
|     case FuriHalVersionRegionEuRu: |     case FuriHalVersionRegionEuRu: | ||||||
|         //433,05..434,79; 868,15..868,55
 |         //433,05..434,79; 868,15..868,55
 | ||||||
|         if(!(value >= 433050000 && value <= 434790000) && |         if(!(value >= 433050000 && value <= 434790000) && | ||||||
|            !(value >= 868150000 && value <= 8680550000)) { |            !(value >= 868150000 && value <= 868550000)) { | ||||||
|         } else { |         } else { | ||||||
|             txrx = true; |             txrx = true; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -17,6 +17,8 @@ struct SubGhzProtocolRAW { | |||||||
|     string_t file_name; |     string_t file_name; | ||||||
|     size_t sample_write; |     size_t sample_write; | ||||||
|     bool last_level; |     bool last_level; | ||||||
|  |     SubGhzProtocolRAWCallbackEnd callback_end; | ||||||
|  |     void* context_end; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
| @ -65,6 +67,22 @@ void subghz_protocol_raw_free(SubGhzProtocolRAW* instance) { | |||||||
|     free(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) { | void subghz_protocol_raw_file_encoder_worker_stop(void* context) { | ||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
|     SubGhzProtocolRAW* instance = 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
 |         //the worker needs a file in order to open and read part of the file
 | ||||||
|         osDelay(100); |         osDelay(100); | ||||||
|         instance->file_is_open = RAWFileIsOpenRead; |         instance->file_is_open = RAWFileIsOpenRead; | ||||||
|  |         //Forwarding UPLOAD to common encoder
 | ||||||
|         subghz_protocol_encoder_common_set_callback( |         subghz_protocol_encoder_common_set_callback( | ||||||
|             encoder, subghz_file_encoder_worker_get_level_duration, instance->file_worker_encoder); |             encoder, subghz_file_encoder_worker_get_level_duration, instance->file_worker_encoder); | ||||||
|  |         //forced stop of transmission
 | ||||||
|         subghz_protocol_encoder_common_set_callback_end( |         subghz_protocol_encoder_common_set_callback_end( | ||||||
|             encoder, subghz_protocol_raw_file_encoder_worker_stop, instance); |             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; |         loaded = true; | ||||||
|     } else { |     } else { | ||||||
| @ -187,7 +212,8 @@ bool subghz_protocol_raw_save_to_file_init( | |||||||
|             break; |             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"); |             FURI_LOG_E(TAG, "Unable to add Protocol"); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -2,6 +2,8 @@ | |||||||
| 
 | 
 | ||||||
| #include "subghz_protocol_common.h" | #include "subghz_protocol_common.h" | ||||||
| 
 | 
 | ||||||
|  | typedef void (*SubGhzProtocolRAWCallbackEnd)(void* context); | ||||||
|  | 
 | ||||||
| typedef struct SubGhzProtocolRAW SubGhzProtocolRAW; | typedef struct SubGhzProtocolRAW SubGhzProtocolRAW; | ||||||
| 
 | 
 | ||||||
| /** Allocate SubGhzProtocolRAW
 | /** Allocate SubGhzProtocolRAW
 | ||||||
| @ -16,6 +18,11 @@ SubGhzProtocolRAW* subghz_protocol_raw_alloc(); | |||||||
|  */ |  */ | ||||||
| void subghz_protocol_raw_free(SubGhzProtocolRAW* instance); | 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
 | /** Reset internal state
 | ||||||
|  * @param instance - SubGhzProtocolRAW instance |  * @param instance - SubGhzProtocolRAW instance | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -16,12 +16,26 @@ struct SubGhzFileEncoderWorker { | |||||||
|     FlipperFile* flipper_file; |     FlipperFile* flipper_file; | ||||||
| 
 | 
 | ||||||
|     volatile bool worker_running; |     volatile bool worker_running; | ||||||
|  |     volatile bool worker_stoping; | ||||||
|     bool level; |     bool level; | ||||||
|     int32_t duration; |     int32_t duration; | ||||||
|     string_t str_data; |     string_t str_data; | ||||||
|     string_t file_path; |     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( | void subghz_file_encoder_worker_add_livel_duration( | ||||||
|     SubGhzFileEncoderWorker* instance, |     SubGhzFileEncoderWorker* instance, | ||||||
|     int32_t duration) { |     int32_t duration) { | ||||||
| @ -89,6 +103,7 @@ LevelDuration subghz_file_encoder_worker_get_level_duration(void* context) { | |||||||
|         } else if(duration == 0) { |         } else if(duration == 0) { | ||||||
|             level_duration = level_duration_reset(); |             level_duration = level_duration_reset(); | ||||||
|             FURI_LOG_I(TAG, "Stop transmission"); |             FURI_LOG_I(TAG, "Stop transmission"); | ||||||
|  |             instance->worker_stoping = true; | ||||||
|         } |         } | ||||||
|         return level_duration; |         return level_duration; | ||||||
|     } else { |     } else { | ||||||
| @ -111,9 +126,7 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { | |||||||
|         if(!flipper_file_open_existing( |         if(!flipper_file_open_existing( | ||||||
|                instance->flipper_file, string_get_cstr(instance->file_path))) { |                instance->flipper_file, string_get_cstr(instance->file_path))) { | ||||||
|             FURI_LOG_E( |             FURI_LOG_E( | ||||||
|                 TAG, |                 TAG, "Unable to open file for read: %s", string_get_cstr(instance->file_path)); | ||||||
|                 "Unable to open file for read: %s", |  | ||||||
|                 string_get_cstr(instance->file_path)); |  | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         if(!flipper_file_read_string(instance->flipper_file, "Protocol", instance->str_data)) { |         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"
 |         //skip the end of the previous line "\n"
 | ||||||
|         storage_file_seek(file, 1, false); |         storage_file_seek(file, 1, false); | ||||||
|         res = true; |         res = true; | ||||||
|  |         instance->worker_stoping = false; | ||||||
|         FURI_LOG_I(TAG, "Start transmission"); |         FURI_LOG_I(TAG, "Start transmission"); | ||||||
|     } while(0); |     } while(0); | ||||||
| 
 | 
 | ||||||
| @ -152,7 +166,11 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { | |||||||
|     } |     } | ||||||
|     //waiting for the end of the transfer
 |     //waiting for the end of the transfer
 | ||||||
|     FURI_LOG_I(TAG, "End read file"); |     FURI_LOG_I(TAG, "End read file"); | ||||||
|  | 
 | ||||||
|     while(instance->worker_running) { |     while(instance->worker_running) { | ||||||
|  |         if(instance->worker_stoping) { | ||||||
|  |             if(instance->callback_end) instance->callback_end(instance->context_end); | ||||||
|  |         } | ||||||
|         osDelay(50); |         osDelay(50); | ||||||
|     } |     } | ||||||
|     flipper_file_close(instance->flipper_file); |     flipper_file_close(instance->flipper_file); | ||||||
| @ -177,6 +195,7 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { | |||||||
|     string_init(instance->str_data); |     string_init(instance->str_data); | ||||||
|     string_init(instance->file_path); |     string_init(instance->file_path); | ||||||
|     instance->level = false; |     instance->level = false; | ||||||
|  |     instance->worker_stoping = true; | ||||||
| 
 | 
 | ||||||
|     return instance; |     return instance; | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,8 +2,20 @@ | |||||||
| 
 | 
 | ||||||
| #include <furi-hal.h> | #include <furi-hal.h> | ||||||
| 
 | 
 | ||||||
|  | typedef void (*SubGhzFileEncoderWorkerCallbackEnd)(void* context); | ||||||
|  | 
 | ||||||
| typedef struct SubGhzFileEncoderWorker SubGhzFileEncoderWorker; | 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
 | /** Allocate SubGhzFileEncoderWorker
 | ||||||
|  *  |  *  | ||||||
|  * @return SubGhzFileEncoderWorker*  |  * @return SubGhzFileEncoderWorker*  | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Skorpionm
						Skorpionm