SubGhz: add protocol BinRAW (binarization of data quantized by the minimum correlated duration) (#2322)
* SubGhz: add protocol DataRAW (binarization of data quantized by the minimum correlated duration) * SubGhz: fix name history * SubGhz: add encoder Data_RAW protocol * SubGhz: decreasing the size of the LevelDuration structure * SubGhz: history, added check that there is free RAM * SubGhz: checking for free memory, support to pass without gap * SubGhz: add running average to average the result, auto cut noise at the end of a burst * SubGhz: support for repeating sequences * SubGhz: fix secplus_v2 decoder * SubGhz: bin_RAW fix add history * SubGhz: add debug * SubGhz: debug refactoring * FURI_LOG: add FURI_LOG_RAW_x formatted string output like printf * SubGhz: fix new FURI_LOG metod * FURI_LOG: fix unit test * SubGhz: add enable/disable BinRAW protocol decoding * SubGhz: fix PVS * SubGhz: forcibly turn off the speaker when exiting SubGhz * SubGhz: adaptive adjustment to the noise level Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									71871949ec
								
							
						
					
					
						commit
						163be139eb
					
				| @ -70,7 +70,7 @@ void minunit_print_progress() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void minunit_print_fail(const char* str) { | void minunit_print_fail(const char* str) { | ||||||
|     printf(FURI_LOG_CLR_E "%s\r\n" FURI_LOG_CLR_RESET, str); |     printf(_FURI_LOG_CLR_E "%s\r\n" _FURI_LOG_CLR_RESET, str); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void unit_tests_cli(Cli* cli, FuriString* args, void* context) { | void unit_tests_cli(Cli* cli, FuriString* args, void* context) { | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ App( | |||||||
|     ], |     ], | ||||||
|     provides=["subghz_start"], |     provides=["subghz_start"], | ||||||
|     icon="A_Sub1ghz_14", |     icon="A_Sub1ghz_14", | ||||||
|     stack_size=2 * 1024, |     stack_size=3 * 1024, | ||||||
|     order=10, |     order=10, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -411,5 +411,5 @@ void subghz_scene_read_raw_on_exit(void* context) { | |||||||
|     notification_message(subghz->notifications, &sequence_reset_rgb); |     notification_message(subghz->notifications, &sequence_reset_rgb); | ||||||
| 
 | 
 | ||||||
|     //filter restoration
 |     //filter restoration
 | ||||||
|     subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable); |     subghz_receiver_set_filter(subghz->txrx->receiver, subghz->txrx->filter); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #include "../subghz_i.h" | #include "../subghz_i.h" | ||||||
| #include "../views/receiver.h" | #include "../views/receiver.h" | ||||||
| #include <dolphin/dolphin.h> | #include <dolphin/dolphin.h> | ||||||
|  | #include <lib/subghz/protocols/bin_raw.h> | ||||||
| 
 | 
 | ||||||
| static const NotificationSequence subghs_sequence_rx = { | static const NotificationSequence subghs_sequence_rx = { | ||||||
|     &message_green_255, |     &message_green_255, | ||||||
| @ -143,6 +144,11 @@ void subghz_scene_receiver_on_enter(void* context) { | |||||||
|     } |     } | ||||||
|     subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); |     subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); | ||||||
| 
 | 
 | ||||||
|  |     //to use a universal decoder, we are looking for a link to it
 | ||||||
|  |     subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name( | ||||||
|  |         subghz->txrx->receiver, SUBGHZ_PROTOCOL_BIN_RAW_NAME); | ||||||
|  |     furi_assert(subghz->txrx->decoder_result); | ||||||
|  | 
 | ||||||
|     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReceiver); |     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReceiver); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -208,6 +214,13 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { | |||||||
|             subghz_hopper_update(subghz); |             subghz_hopper_update(subghz); | ||||||
|             subghz_scene_receiver_update_statusbar(subghz); |             subghz_scene_receiver_update_statusbar(subghz); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         //get RSSI
 | ||||||
|  |         float rssi = furi_hal_subghz_get_rssi(); | ||||||
|  |         subghz_receiver_rssi(subghz->subghz_receiver, rssi); | ||||||
|  |         subghz_protocol_decoder_bin_raw_data_input_rssi( | ||||||
|  |             (SubGhzProtocolDecoderBinRAW*)subghz->txrx->decoder_result, rssi); | ||||||
|  | 
 | ||||||
|         switch(subghz->state_notifications) { |         switch(subghz->state_notifications) { | ||||||
|         case SubGhzNotificationStateRx: |         case SubGhzNotificationStateRx: | ||||||
|             notification_message(subghz->notifications, &sequence_blink_cyan_10); |             notification_message(subghz->notifications, &sequence_blink_cyan_10); | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ enum SubGhzSettingIndex { | |||||||
|     SubGhzSettingIndexFrequency, |     SubGhzSettingIndexFrequency, | ||||||
|     SubGhzSettingIndexHopping, |     SubGhzSettingIndexHopping, | ||||||
|     SubGhzSettingIndexModulation, |     SubGhzSettingIndexModulation, | ||||||
|  |     SubGhzSettingIndexBinRAW, | ||||||
|     SubGhzSettingIndexSound, |     SubGhzSettingIndexSound, | ||||||
|     SubGhzSettingIndexLock, |     SubGhzSettingIndexLock, | ||||||
|     SubGhzSettingIndexRAWThesholdRSSI, |     SubGhzSettingIndexRAWThesholdRSSI, | ||||||
| @ -58,6 +59,15 @@ const uint32_t speaker_value[SPEAKER_COUNT] = { | |||||||
|     SubGhzSpeakerStateShutdown, |     SubGhzSpeakerStateShutdown, | ||||||
|     SubGhzSpeakerStateEnable, |     SubGhzSpeakerStateEnable, | ||||||
| }; | }; | ||||||
|  | #define BIN_RAW_COUNT 2 | ||||||
|  | const char* const bin_raw_text[BIN_RAW_COUNT] = { | ||||||
|  |     "OFF", | ||||||
|  |     "ON", | ||||||
|  | }; | ||||||
|  | const uint32_t bin_raw_value[BIN_RAW_COUNT] = { | ||||||
|  |     SubGhzProtocolFlag_Decodable, | ||||||
|  |     SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_BinRAW, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) { | uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) { | ||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
| @ -186,6 +196,15 @@ static void subghz_scene_receiver_config_set_speaker(VariableItem* item) { | |||||||
|     subghz->txrx->speaker_state = speaker_value[index]; |     subghz->txrx->speaker_state = speaker_value[index]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void subghz_scene_receiver_config_set_bin_raw(VariableItem* item) { | ||||||
|  |     SubGhz* subghz = variable_item_get_context(item); | ||||||
|  |     uint8_t index = variable_item_get_current_value_index(item); | ||||||
|  | 
 | ||||||
|  |     variable_item_set_current_value_text(item, bin_raw_text[index]); | ||||||
|  |     subghz->txrx->filter = bin_raw_value[index]; | ||||||
|  |     subghz_receiver_set_filter(subghz->txrx->receiver, subghz->txrx->filter); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void subghz_scene_receiver_config_set_raw_threshold_rssi(VariableItem* item) { | static void subghz_scene_receiver_config_set_raw_threshold_rssi(VariableItem* item) { | ||||||
|     SubGhz* subghz = variable_item_get_context(item); |     SubGhz* subghz = variable_item_get_context(item); | ||||||
|     uint8_t index = variable_item_get_current_value_index(item); |     uint8_t index = variable_item_get_current_value_index(item); | ||||||
| @ -254,6 +273,19 @@ void subghz_scene_receiver_config_on_enter(void* context) { | |||||||
|     variable_item_set_current_value_text( |     variable_item_set_current_value_text( | ||||||
|         item, subghz_setting_get_preset_name(subghz->setting, value_index)); |         item, subghz_setting_get_preset_name(subghz->setting, value_index)); | ||||||
| 
 | 
 | ||||||
|  |     if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != | ||||||
|  |        SubGhzCustomEventManagerSet) { | ||||||
|  |         item = variable_item_list_add( | ||||||
|  |             subghz->variable_item_list, | ||||||
|  |             "Bin_RAW:", | ||||||
|  |             BIN_RAW_COUNT, | ||||||
|  |             subghz_scene_receiver_config_set_bin_raw, | ||||||
|  |             subghz); | ||||||
|  |         value_index = value_index_uint32(subghz->txrx->filter, bin_raw_value, BIN_RAW_COUNT); | ||||||
|  |         variable_item_set_current_value_index(item, value_index); | ||||||
|  |         variable_item_set_current_value_text(item, bin_raw_text[value_index]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     item = variable_item_list_add( |     item = variable_item_list_add( | ||||||
|         subghz->variable_item_list, |         subghz->variable_item_list, | ||||||
|         "Sound:", |         "Sound:", | ||||||
|  | |||||||
| @ -194,7 +194,8 @@ SubGhz* subghz_alloc() { | |||||||
|     subghz_environment_set_protocol_registry( |     subghz_environment_set_protocol_registry( | ||||||
|         subghz->txrx->environment, (void*)&subghz_protocol_registry); |         subghz->txrx->environment, (void*)&subghz_protocol_registry); | ||||||
|     subghz->txrx->receiver = subghz_receiver_alloc_init(subghz->txrx->environment); |     subghz->txrx->receiver = subghz_receiver_alloc_init(subghz->txrx->environment); | ||||||
|     subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable); |     subghz->txrx->filter = SubGhzProtocolFlag_Decodable; | ||||||
|  |     subghz_receiver_set_filter(subghz->txrx->receiver, subghz->txrx->filter); | ||||||
| 
 | 
 | ||||||
|     subghz_worker_set_overrun_callback( |     subghz_worker_set_overrun_callback( | ||||||
|         subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); |         subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); | ||||||
| @ -218,6 +219,8 @@ void subghz_free(SubGhz* subghz) { | |||||||
|         subghz->rpc_ctx = NULL; |         subghz->rpc_ctx = NULL; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     subghz_speaker_off(subghz); | ||||||
|  | 
 | ||||||
|     // Packet Test
 |     // Packet Test
 | ||||||
|     view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTestPacket); |     view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTestPacket); | ||||||
|     subghz_test_packet_free(subghz->subghz_test_packet); |     subghz_test_packet_free(subghz->subghz_test_packet); | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| 
 | 
 | ||||||
| #define SUBGHZ_HISTORY_MAX 50 | #define SUBGHZ_HISTORY_MAX 50 | ||||||
|  | #define SUBGHZ_HISTORY_FREE_HEAP 20480 | ||||||
| #define TAG "SubGhzHistory" | #define TAG "SubGhzHistory" | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| @ -121,6 +122,10 @@ FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx | |||||||
| } | } | ||||||
| bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output) { | bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output) { | ||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
|  |     if(memmgr_get_free_heap() < SUBGHZ_HISTORY_FREE_HEAP) { | ||||||
|  |         if(output != NULL) furi_string_printf(output, "    Free heap LOW"); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|     if(instance->last_index_write == SUBGHZ_HISTORY_MAX) { |     if(instance->last_index_write == SUBGHZ_HISTORY_MAX) { | ||||||
|         if(output != NULL) furi_string_printf(output, "   Memory is FULL"); |         if(output != NULL) furi_string_printf(output, "   Memory is FULL"); | ||||||
|         return true; |         return true; | ||||||
| @ -142,6 +147,7 @@ bool subghz_history_add_to_history( | |||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
| 
 | 
 | ||||||
|  |     if(memmgr_get_free_heap() < SUBGHZ_HISTORY_FREE_HEAP) return false; | ||||||
|     if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return false; |     if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return false; | ||||||
| 
 | 
 | ||||||
|     SubGhzProtocolDecoderBase* decoder_base = context; |     SubGhzProtocolDecoderBase* decoder_base = context; | ||||||
| @ -200,13 +206,13 @@ bool subghz_history_add_to_history( | |||||||
|         } |         } | ||||||
|         uint8_t key_data[sizeof(uint64_t)] = {0}; |         uint8_t key_data[sizeof(uint64_t)] = {0}; | ||||||
|         if(!flipper_format_read_hex(item->flipper_string, "Key", key_data, sizeof(uint64_t))) { |         if(!flipper_format_read_hex(item->flipper_string, "Key", key_data, sizeof(uint64_t))) { | ||||||
|             FURI_LOG_E(TAG, "Missing Key"); |             FURI_LOG_D(TAG, "No Key"); | ||||||
|             break; |  | ||||||
|         } |         } | ||||||
|         uint64_t data = 0; |         uint64_t data = 0; | ||||||
|         for(uint8_t i = 0; i < sizeof(uint64_t); i++) { |         for(uint8_t i = 0; i < sizeof(uint64_t); i++) { | ||||||
|             data = (data << 8) | key_data[i]; |             data = (data << 8) | key_data[i]; | ||||||
|         } |         } | ||||||
|  |         if(data != 0) { | ||||||
|             if(!(uint32_t)(data >> 32)) { |             if(!(uint32_t)(data >> 32)) { | ||||||
|                 furi_string_printf( |                 furi_string_printf( | ||||||
|                     item->item_str, |                     item->item_str, | ||||||
| @ -221,6 +227,10 @@ bool subghz_history_add_to_history( | |||||||
|                     (uint32_t)(data >> 32), |                     (uint32_t)(data >> 32), | ||||||
|                     (uint32_t)(data & 0xFFFFFFFF)); |                     (uint32_t)(data & 0xFFFFFFFF)); | ||||||
|             } |             } | ||||||
|  |         } else { | ||||||
|  |             furi_string_printf(item->item_str, "%s", furi_string_get_cstr(instance->tmp_string)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|     } while(false); |     } while(false); | ||||||
| 
 | 
 | ||||||
|     furi_string_free(text); |     furi_string_free(text); | ||||||
|  | |||||||
| @ -45,6 +45,7 @@ struct SubGhzTxRx { | |||||||
|     SubGhzEnvironment* environment; |     SubGhzEnvironment* environment; | ||||||
|     SubGhzReceiver* receiver; |     SubGhzReceiver* receiver; | ||||||
|     SubGhzTransmitter* transmitter; |     SubGhzTransmitter* transmitter; | ||||||
|  |     SubGhzProtocolFlag filter; | ||||||
|     SubGhzProtocolDecoderBase* decoder_result; |     SubGhzProtocolDecoderBase* decoder_result; | ||||||
|     FlipperFormat* fff_data; |     FlipperFormat* fff_data; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -12,6 +12,8 @@ | |||||||
| #define MENU_ITEMS 4u | #define MENU_ITEMS 4u | ||||||
| #define UNLOCK_CNT 3 | #define UNLOCK_CNT 3 | ||||||
| 
 | 
 | ||||||
|  | #define SUBGHZ_RAW_TRESHOLD_MIN -90.0f | ||||||
|  | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     FuriString* item_str; |     FuriString* item_str; | ||||||
|     uint8_t type; |     uint8_t type; | ||||||
| @ -59,8 +61,24 @@ typedef struct { | |||||||
|     uint16_t list_offset; |     uint16_t list_offset; | ||||||
|     uint16_t history_item; |     uint16_t history_item; | ||||||
|     SubGhzViewReceiverBarShow bar_show; |     SubGhzViewReceiverBarShow bar_show; | ||||||
|  |     uint8_t u_rssi; | ||||||
| } SubGhzViewReceiverModel; | } SubGhzViewReceiverModel; | ||||||
| 
 | 
 | ||||||
|  | void subghz_receiver_rssi(SubGhzViewReceiver* instance, float rssi) { | ||||||
|  |     furi_assert(instance); | ||||||
|  |     with_view_model( | ||||||
|  |         instance->view, | ||||||
|  |         SubGhzViewReceiverModel * model, | ||||||
|  |         { | ||||||
|  |             if(rssi < SUBGHZ_RAW_TRESHOLD_MIN) { | ||||||
|  |                 model->u_rssi = 0; | ||||||
|  |             } else { | ||||||
|  |                 model->u_rssi = (uint8_t)(rssi - SUBGHZ_RAW_TRESHOLD_MIN); | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLock lock) { | void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLock lock) { | ||||||
|     furi_assert(subghz_receiver); |     furi_assert(subghz_receiver); | ||||||
|     subghz_receiver->lock_count = 0; |     subghz_receiver->lock_count = 0; | ||||||
| @ -168,13 +186,22 @@ static void subghz_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool s | |||||||
|     canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11); |     canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void subghz_view_rssi_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { | ||||||
|  |     for(uint8_t i = 1; i < model->u_rssi; i++) { | ||||||
|  |         if(i % 5) { | ||||||
|  |             canvas_draw_dot(canvas, 46 + i, 50); | ||||||
|  |             canvas_draw_dot(canvas, 47 + i, 51); | ||||||
|  |             canvas_draw_dot(canvas, 46 + i, 52); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { | void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
|     canvas_set_font(canvas, FontSecondary); |     canvas_set_font(canvas, FontSecondary); | ||||||
| 
 | 
 | ||||||
|     elements_button_left(canvas, "Config"); |     elements_button_left(canvas, "Config"); | ||||||
|     canvas_draw_line(canvas, 46, 51, 125, 51); |  | ||||||
| 
 | 
 | ||||||
|     bool scrollbar = model->history_item > 4; |     bool scrollbar = model->history_item > 4; | ||||||
|     FuriString* str_buff; |     FuriString* str_buff; | ||||||
| @ -206,11 +233,11 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { | |||||||
|     if(model->history_item == 0) { |     if(model->history_item == 0) { | ||||||
|         canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52); |         canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52); | ||||||
|         canvas_set_font(canvas, FontPrimary); |         canvas_set_font(canvas, FontPrimary); | ||||||
|         canvas_draw_str(canvas, 63, 46, "Scanning..."); |         canvas_draw_str(canvas, 63, 44, "Scanning..."); | ||||||
|         canvas_draw_line(canvas, 46, 51, 125, 51); |  | ||||||
|         canvas_set_font(canvas, FontSecondary); |         canvas_set_font(canvas, FontSecondary); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     subghz_view_rssi_draw(canvas, model); | ||||||
|     switch(model->bar_show) { |     switch(model->bar_show) { | ||||||
|     case SubGhzViewReceiverBarShowLock: |     case SubGhzViewReceiverBarShowLock: | ||||||
|         canvas_draw_icon(canvas, 64, 55, &I_Lock_7x8); |         canvas_draw_icon(canvas, 64, 55, &I_Lock_7x8); | ||||||
|  | |||||||
| @ -8,6 +8,8 @@ typedef struct SubGhzViewReceiver SubGhzViewReceiver; | |||||||
| 
 | 
 | ||||||
| typedef void (*SubGhzViewReceiverCallback)(SubGhzCustomEvent event, void* context); | typedef void (*SubGhzViewReceiverCallback)(SubGhzCustomEvent event, void* context); | ||||||
| 
 | 
 | ||||||
|  | void subghz_receiver_rssi(SubGhzViewReceiver* instance, float rssi); | ||||||
|  | 
 | ||||||
| void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLock keyboard); | void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLock keyboard); | ||||||
| 
 | 
 | ||||||
| void subghz_view_receiver_set_callback( | void subghz_view_receiver_set_callback( | ||||||
|  | |||||||
| @ -79,7 +79,6 @@ void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, uint8_t rssi, uint8_t x | |||||||
| void subghz_frequency_analyzer_draw_log_rssi(Canvas* canvas, uint8_t rssi, uint8_t x, uint8_t y) { | void subghz_frequency_analyzer_draw_log_rssi(Canvas* canvas, uint8_t rssi, uint8_t x, uint8_t y) { | ||||||
|     uint8_t column_height = 6; |     uint8_t column_height = 6; | ||||||
|     if(rssi) { |     if(rssi) { | ||||||
|         //rssi = rssi
 |  | ||||||
|         if(rssi > 54) rssi = 54; |         if(rssi > 54) rssi = 54; | ||||||
|         for(uint8_t i = 1; i < rssi; i++) { |         for(uint8_t i = 1; i < rssi; i++) { | ||||||
|             if(i % 5) { |             if(i % 5) { | ||||||
|  | |||||||
| @ -84,9 +84,10 @@ void subghz_view_transmitter_draw(Canvas* canvas, SubGhzViewTransmitterModel* mo | |||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
|     canvas_set_font(canvas, FontSecondary); |     canvas_set_font(canvas, FontSecondary); | ||||||
|     elements_multiline_text(canvas, 0, 8, furi_string_get_cstr(model->key_str)); |     elements_multiline_text_aligned( | ||||||
|     canvas_draw_str(canvas, 78, 8, furi_string_get_cstr(model->frequency_str)); |         canvas, 0, 0, AlignLeft, AlignTop, furi_string_get_cstr(model->key_str)); | ||||||
|     canvas_draw_str(canvas, 113, 8, furi_string_get_cstr(model->preset_str)); |     canvas_draw_str(canvas, 78, 7, furi_string_get_cstr(model->frequency_str)); | ||||||
|  |     canvas_draw_str(canvas, 113, 7, furi_string_get_cstr(model->preset_str)); | ||||||
|     if(model->show_button) subghz_view_transmitter_button_right(canvas, "Send"); |     if(model->show_button) subghz_view_transmitter_button_right(canvas, "Send"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1409,6 +1409,7 @@ Function,+,furi_kernel_unlock,int32_t, | |||||||
| Function,+,furi_log_get_level,FuriLogLevel, | Function,+,furi_log_get_level,FuriLogLevel, | ||||||
| Function,-,furi_log_init,void, | Function,-,furi_log_init,void, | ||||||
| Function,+,furi_log_print_format,void,"FuriLogLevel, const char*, const char*, ..." | Function,+,furi_log_print_format,void,"FuriLogLevel, const char*, const char*, ..." | ||||||
|  | Function,+,furi_log_print_raw_format,void,"FuriLogLevel, const char*, ..." | ||||||
| Function,+,furi_log_set_level,void,FuriLogLevel | Function,+,furi_log_set_level,void,FuriLogLevel | ||||||
| Function,-,furi_log_set_puts,void,FuriLogPuts | Function,-,furi_log_set_puts,void,FuriLogPuts | ||||||
| Function,-,furi_log_set_timestamp,void,FuriLogTimestamp | Function,-,furi_log_set_timestamp,void,FuriLogTimestamp | ||||||
| @ -2599,7 +2600,7 @@ Function,+,subghz_protocol_blocks_crc8le,uint8_t,"const uint8_t[], size_t, uint8 | |||||||
| Function,+,subghz_protocol_blocks_get_bit_array,_Bool,"uint8_t[], size_t" | Function,+,subghz_protocol_blocks_get_bit_array,_Bool,"uint8_t[], size_t" | ||||||
| Function,+,subghz_protocol_blocks_get_hash_data,uint8_t,"SubGhzBlockDecoder*, size_t" | Function,+,subghz_protocol_blocks_get_hash_data,uint8_t,"SubGhzBlockDecoder*, size_t" | ||||||
| Function,+,subghz_protocol_blocks_get_parity,uint8_t,"uint64_t, uint8_t" | Function,+,subghz_protocol_blocks_get_parity,uint8_t,"uint64_t, uint8_t" | ||||||
| Function,+,subghz_protocol_blocks_get_upload,size_t,"uint8_t[], size_t, LevelDuration*, size_t, uint32_t" | Function,+,subghz_protocol_blocks_get_upload_from_bit_array,size_t,"uint8_t[], size_t, LevelDuration*, size_t, uint32_t, SubGhzProtocolBlockAlignBit" | ||||||
| Function,+,subghz_protocol_blocks_lfsr_digest16,uint16_t,"const uint8_t[], size_t, uint16_t, uint16_t" | Function,+,subghz_protocol_blocks_lfsr_digest16,uint16_t,"const uint8_t[], size_t, uint16_t, uint16_t" | ||||||
| Function,+,subghz_protocol_blocks_lfsr_digest8,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t" | Function,+,subghz_protocol_blocks_lfsr_digest8,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t" | ||||||
| Function,+,subghz_protocol_blocks_lfsr_digest8_reflect,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t" | Function,+,subghz_protocol_blocks_lfsr_digest8_reflect,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t" | ||||||
|  | |||||||
| 
 | 
| @ -28,27 +28,27 @@ void furi_log_print_format(FuriLogLevel level, const char* tag, const char* form | |||||||
|         FuriString* string; |         FuriString* string; | ||||||
|         string = furi_string_alloc(); |         string = furi_string_alloc(); | ||||||
| 
 | 
 | ||||||
|         const char* color = FURI_LOG_CLR_RESET; |         const char* color = _FURI_LOG_CLR_RESET; | ||||||
|         const char* log_letter = " "; |         const char* log_letter = " "; | ||||||
|         switch(level) { |         switch(level) { | ||||||
|         case FuriLogLevelError: |         case FuriLogLevelError: | ||||||
|             color = FURI_LOG_CLR_E; |             color = _FURI_LOG_CLR_E; | ||||||
|             log_letter = "E"; |             log_letter = "E"; | ||||||
|             break; |             break; | ||||||
|         case FuriLogLevelWarn: |         case FuriLogLevelWarn: | ||||||
|             color = FURI_LOG_CLR_W; |             color = _FURI_LOG_CLR_W; | ||||||
|             log_letter = "W"; |             log_letter = "W"; | ||||||
|             break; |             break; | ||||||
|         case FuriLogLevelInfo: |         case FuriLogLevelInfo: | ||||||
|             color = FURI_LOG_CLR_I; |             color = _FURI_LOG_CLR_I; | ||||||
|             log_letter = "I"; |             log_letter = "I"; | ||||||
|             break; |             break; | ||||||
|         case FuriLogLevelDebug: |         case FuriLogLevelDebug: | ||||||
|             color = FURI_LOG_CLR_D; |             color = _FURI_LOG_CLR_D; | ||||||
|             log_letter = "D"; |             log_letter = "D"; | ||||||
|             break; |             break; | ||||||
|         case FuriLogLevelTrace: |         case FuriLogLevelTrace: | ||||||
|             color = FURI_LOG_CLR_T; |             color = _FURI_LOG_CLR_T; | ||||||
|             log_letter = "T"; |             log_letter = "T"; | ||||||
|             break; |             break; | ||||||
|         default: |         default: | ||||||
| @ -58,7 +58,7 @@ void furi_log_print_format(FuriLogLevel level, const char* tag, const char* form | |||||||
|         // Timestamp
 |         // Timestamp
 | ||||||
|         furi_string_printf( |         furi_string_printf( | ||||||
|             string, |             string, | ||||||
|             "%lu %s[%s][%s] " FURI_LOG_CLR_RESET, |             "%lu %s[%s][%s] " _FURI_LOG_CLR_RESET, | ||||||
|             furi_log.timestamp(), |             furi_log.timestamp(), | ||||||
|             color, |             color, | ||||||
|             log_letter, |             log_letter, | ||||||
| @ -80,6 +80,23 @@ void furi_log_print_format(FuriLogLevel level, const char* tag, const char* form | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void furi_log_print_raw_format(FuriLogLevel level, const char* format, ...) { | ||||||
|  |     if(level <= furi_log.log_level && | ||||||
|  |        furi_mutex_acquire(furi_log.mutex, FuriWaitForever) == FuriStatusOk) { | ||||||
|  |         FuriString* string; | ||||||
|  |         string = furi_string_alloc(); | ||||||
|  |         va_list args; | ||||||
|  |         va_start(args, format); | ||||||
|  |         furi_string_vprintf(string, format, args); | ||||||
|  |         va_end(args); | ||||||
|  | 
 | ||||||
|  |         furi_log.puts(furi_string_get_cstr(string)); | ||||||
|  |         furi_string_free(string); | ||||||
|  | 
 | ||||||
|  |         furi_mutex_release(furi_log.mutex); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void furi_log_set_level(FuriLogLevel level) { | void furi_log_set_level(FuriLogLevel level) { | ||||||
|     if(level == FuriLogLevelDefault) { |     if(level == FuriLogLevelDefault) { | ||||||
|         level = FURI_LOG_LEVEL_DEFAULT; |         level = FURI_LOG_LEVEL_DEFAULT; | ||||||
|  | |||||||
| @ -22,21 +22,21 @@ typedef enum { | |||||||
|     FuriLogLevelTrace = 6, |     FuriLogLevelTrace = 6, | ||||||
| } FuriLogLevel; | } FuriLogLevel; | ||||||
| 
 | 
 | ||||||
| #define FURI_LOG_CLR(clr) "\033[0;" clr "m" | #define _FURI_LOG_CLR(clr) "\033[0;" clr "m" | ||||||
| #define FURI_LOG_CLR_RESET "\033[0m" | #define _FURI_LOG_CLR_RESET "\033[0m" | ||||||
| 
 | 
 | ||||||
| #define FURI_LOG_CLR_BLACK "30" | #define _FURI_LOG_CLR_BLACK "30" | ||||||
| #define FURI_LOG_CLR_RED "31" | #define _FURI_LOG_CLR_RED "31" | ||||||
| #define FURI_LOG_CLR_GREEN "32" | #define _FURI_LOG_CLR_GREEN "32" | ||||||
| #define FURI_LOG_CLR_BROWN "33" | #define _FURI_LOG_CLR_BROWN "33" | ||||||
| #define FURI_LOG_CLR_BLUE "34" | #define _FURI_LOG_CLR_BLUE "34" | ||||||
| #define FURI_LOG_CLR_PURPLE "35" | #define _FURI_LOG_CLR_PURPLE "35" | ||||||
| 
 | 
 | ||||||
| #define FURI_LOG_CLR_E FURI_LOG_CLR(FURI_LOG_CLR_RED) | #define _FURI_LOG_CLR_E _FURI_LOG_CLR(_FURI_LOG_CLR_RED) | ||||||
| #define FURI_LOG_CLR_W FURI_LOG_CLR(FURI_LOG_CLR_BROWN) | #define _FURI_LOG_CLR_W _FURI_LOG_CLR(_FURI_LOG_CLR_BROWN) | ||||||
| #define FURI_LOG_CLR_I FURI_LOG_CLR(FURI_LOG_CLR_GREEN) | #define _FURI_LOG_CLR_I _FURI_LOG_CLR(_FURI_LOG_CLR_GREEN) | ||||||
| #define FURI_LOG_CLR_D FURI_LOG_CLR(FURI_LOG_CLR_BLUE) | #define _FURI_LOG_CLR_D _FURI_LOG_CLR(_FURI_LOG_CLR_BLUE) | ||||||
| #define FURI_LOG_CLR_T FURI_LOG_CLR(FURI_LOG_CLR_PURPLE) | #define _FURI_LOG_CLR_T _FURI_LOG_CLR(_FURI_LOG_CLR_PURPLE) | ||||||
| 
 | 
 | ||||||
| typedef void (*FuriLogPuts)(const char* data); | typedef void (*FuriLogPuts)(const char* data); | ||||||
| typedef uint32_t (*FuriLogTimestamp)(void); | typedef uint32_t (*FuriLogTimestamp)(void); | ||||||
| @ -54,6 +54,15 @@ void furi_log_init(); | |||||||
| void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...) | void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...) | ||||||
|     _ATTRIBUTE((__format__(__printf__, 3, 4))); |     _ATTRIBUTE((__format__(__printf__, 3, 4))); | ||||||
| 
 | 
 | ||||||
|  | /** Print log record
 | ||||||
|  |  *  | ||||||
|  |  * @param level  | ||||||
|  |  * @param format  | ||||||
|  |  * @param ...  | ||||||
|  |  */ | ||||||
|  | void furi_log_print_raw_format(FuriLogLevel level, const char* format, ...) | ||||||
|  |     _ATTRIBUTE((__format__(__printf__, 2, 3))); | ||||||
|  | 
 | ||||||
| /** Set log level
 | /** Set log level
 | ||||||
|  * |  * | ||||||
|  * @param[in]  level  The level |  * @param[in]  level  The level | ||||||
| @ -95,6 +104,22 @@ void furi_log_set_timestamp(FuriLogTimestamp timestamp); | |||||||
| #define FURI_LOG_T(tag, format, ...) \ | #define FURI_LOG_T(tag, format, ...) \ | ||||||
|     furi_log_print_format(FuriLogLevelTrace, tag, format, ##__VA_ARGS__) |     furi_log_print_format(FuriLogLevelTrace, tag, format, ##__VA_ARGS__) | ||||||
| 
 | 
 | ||||||
|  | /** Log methods
 | ||||||
|  |  * | ||||||
|  |  * @param      format  The raw format  | ||||||
|  |  * @param      ...     VA Args | ||||||
|  |  */ | ||||||
|  | #define FURI_LOG_RAW_E(format, ...) \ | ||||||
|  |     furi_log_print_raw_format(FuriLogLevelError, format, ##__VA_ARGS__) | ||||||
|  | #define FURI_LOG_RAW_W(format, ...) \ | ||||||
|  |     furi_log_print_raw_format(FuriLogLevelWarn, format, ##__VA_ARGS__) | ||||||
|  | #define FURI_LOG_RAW_I(format, ...) \ | ||||||
|  |     furi_log_print_raw_format(FuriLogLevelInfo, format, ##__VA_ARGS__) | ||||||
|  | #define FURI_LOG_RAW_D(format, ...) \ | ||||||
|  |     furi_log_print_raw_format(FuriLogLevelDebug, format, ##__VA_ARGS__) | ||||||
|  | #define FURI_LOG_RAW_T(format, ...) \ | ||||||
|  |     furi_log_print_raw_format(FuriLogLevelTrace, format, ##__VA_ARGS__) | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -2,6 +2,8 @@ | |||||||
| #include "math.h" | #include "math.h" | ||||||
| #include <core/check.h> | #include <core/check.h> | ||||||
| 
 | 
 | ||||||
|  | #include "furi.h" | ||||||
|  | 
 | ||||||
| #define TAG "SubGhzBlockEncoder" | #define TAG "SubGhzBlockEncoder" | ||||||
| 
 | 
 | ||||||
| void subghz_protocol_blocks_set_bit_array( | void subghz_protocol_blocks_set_bit_array( | ||||||
| @ -17,21 +19,32 @@ bool subghz_protocol_blocks_get_bit_array(uint8_t data_array[], size_t read_inde | |||||||
|     return bit_read(data_array[read_index_bit >> 3], 7 - (read_index_bit & 0x7)); |     return bit_read(data_array[read_index_bit >> 3], 7 - (read_index_bit & 0x7)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| size_t subghz_protocol_blocks_get_upload( | size_t subghz_protocol_blocks_get_upload_from_bit_array( | ||||||
|     uint8_t data_array[], |     uint8_t data_array[], | ||||||
|     size_t count_bit_data_array, |     size_t count_bit_data_array, | ||||||
|     LevelDuration* upload, |     LevelDuration* upload, | ||||||
|     size_t max_size_upload, |     size_t max_size_upload, | ||||||
|     uint32_t duration_bit) { |     uint32_t duration_bit, | ||||||
|     size_t index_bit = 0; |     SubGhzProtocolBlockAlignBit align_bit) { | ||||||
|  |     size_t bias_bit = 0; | ||||||
|     size_t size_upload = 0; |     size_t size_upload = 0; | ||||||
|     uint32_t duration = duration_bit; |     uint32_t duration = duration_bit; | ||||||
|  | 
 | ||||||
|  |     if(align_bit == SubGhzProtocolBlockAlignBitRight) { | ||||||
|  |         if(count_bit_data_array & 0x7) { | ||||||
|  |             bias_bit = 8 - (count_bit_data_array & 0x7); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     size_t index_bit = bias_bit; | ||||||
|  | 
 | ||||||
|     bool last_bit = subghz_protocol_blocks_get_bit_array(data_array, index_bit++); |     bool last_bit = subghz_protocol_blocks_get_bit_array(data_array, index_bit++); | ||||||
|     for(size_t i = 1; i < count_bit_data_array; i++) { |     for(size_t i = 1 + bias_bit; i < count_bit_data_array + bias_bit; i++) { | ||||||
|         if(last_bit == subghz_protocol_blocks_get_bit_array(data_array, index_bit)) { |         if(last_bit == subghz_protocol_blocks_get_bit_array(data_array, index_bit)) { | ||||||
|             duration += duration_bit; |             duration += duration_bit; | ||||||
|         } else { |         } else { | ||||||
|             furi_assert(max_size_upload > size_upload); |             if(size_upload > max_size_upload) { | ||||||
|  |                 furi_crash("SubGhz: Encoder buffer overflow"); | ||||||
|  |             } | ||||||
|             upload[size_upload++] = level_duration_make( |             upload[size_upload++] = level_duration_make( | ||||||
|                 subghz_protocol_blocks_get_bit_array(data_array, index_bit - 1), duration); |                 subghz_protocol_blocks_get_bit_array(data_array, index_bit - 1), duration); | ||||||
|             last_bit = !last_bit; |             last_bit = !last_bit; | ||||||
|  | |||||||
| @ -19,6 +19,11 @@ typedef struct { | |||||||
| 
 | 
 | ||||||
| } SubGhzProtocolBlockEncoder; | } SubGhzProtocolBlockEncoder; | ||||||
| 
 | 
 | ||||||
|  | typedef enum { | ||||||
|  |     SubGhzProtocolBlockAlignBitLeft, | ||||||
|  |     SubGhzProtocolBlockAlignBitRight, | ||||||
|  | } SubGhzProtocolBlockAlignBit; | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Set data bit when encoding HEX array. |  * Set data bit when encoding HEX array. | ||||||
|  * @param bit_value The value of the bit to be set |  * @param bit_value The value of the bit to be set | ||||||
| @ -47,13 +52,15 @@ bool subghz_protocol_blocks_get_bit_array(uint8_t data_array[], size_t read_inde | |||||||
|  * @param upload Pointer to a LevelDuration |  * @param upload Pointer to a LevelDuration | ||||||
|  * @param max_size_upload upload size, check not to overflow |  * @param max_size_upload upload size, check not to overflow | ||||||
|  * @param duration_bit duration 1 bit |  * @param duration_bit duration 1 bit | ||||||
|  |  * @param align_bit alignment of useful bits in an array | ||||||
|  */ |  */ | ||||||
| size_t subghz_protocol_blocks_get_upload( | size_t subghz_protocol_blocks_get_upload_from_bit_array( | ||||||
|     uint8_t data_array[], |     uint8_t data_array[], | ||||||
|     size_t count_bit_data_array, |     size_t count_bit_data_array, | ||||||
|     LevelDuration* upload, |     LevelDuration* upload, | ||||||
|     size_t max_size_upload, |     size_t max_size_upload, | ||||||
|     uint32_t duration_bit); |     uint32_t duration_bit, | ||||||
|  |     SubGhzProtocolBlockAlignBit align_bit); | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
|  | |||||||
| @ -100,7 +100,7 @@ bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperForma | |||||||
|             FURI_LOG_E(TAG, "Missing Bit"); |             FURI_LOG_E(TAG, "Missing Bit"); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         instance->data_count_bit = (uint8_t)temp_data; |         instance->data_count_bit = (uint16_t)temp_data; | ||||||
| 
 | 
 | ||||||
|         uint8_t key_data[sizeof(uint64_t)] = {0}; |         uint8_t key_data[sizeof(uint64_t)] = {0}; | ||||||
|         if(!flipper_format_read_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { |         if(!flipper_format_read_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ struct SubGhzBlockGeneric { | |||||||
|     const char* protocol_name; |     const char* protocol_name; | ||||||
|     uint64_t data; |     uint64_t data; | ||||||
|     uint32_t serial; |     uint32_t serial; | ||||||
|     uint8_t data_count_bit; |     uint16_t data_count_bit; | ||||||
|     uint8_t btn; |     uint8_t btn; | ||||||
|     uint32_t cnt; |     uint32_t cnt; | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										1120
									
								
								lib/subghz/protocols/bin_raw.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1120
									
								
								lib/subghz/protocols/bin_raw.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										111
									
								
								lib/subghz/protocols/bin_raw.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								lib/subghz/protocols/bin_raw.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "base.h" | ||||||
|  | 
 | ||||||
|  | #define SUBGHZ_PROTOCOL_BIN_RAW_NAME "BinRAW" | ||||||
|  | 
 | ||||||
|  | typedef struct SubGhzProtocolDecoderBinRAW SubGhzProtocolDecoderBinRAW; | ||||||
|  | typedef struct SubGhzProtocolEncoderBinRAW SubGhzProtocolEncoderBinRAW; | ||||||
|  | 
 | ||||||
|  | extern const SubGhzProtocolDecoder subghz_protocol_bin_raw_decoder; | ||||||
|  | extern const SubGhzProtocolEncoder subghz_protocol_bin_raw_encoder; | ||||||
|  | extern const SubGhzProtocol subghz_protocol_bin_raw; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Allocate SubGhzProtocolEncoderBinRAW. | ||||||
|  |  * @param environment Pointer to a SubGhzEnvironment instance | ||||||
|  |  * @return SubGhzProtocolEncoderBinRAW* pointer to a SubGhzProtocolEncoderBinRAW instance | ||||||
|  |  */ | ||||||
|  | void* subghz_protocol_encoder_bin_raw_alloc(SubGhzEnvironment* environment); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Free SubGhzProtocolEncoderBinRAW. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_encoder_bin_raw_free(void* context); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Deserialize and generating an upload to send. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance | ||||||
|  |  * @param flipper_format Pointer to a FlipperFormat instance | ||||||
|  |  * @return true On success | ||||||
|  |  */ | ||||||
|  | bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Forced transmission stop. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_encoder_bin_raw_stop(void* context); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Getting the level and duration of the upload to be loaded into DMA. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance | ||||||
|  |  * @return LevelDuration  | ||||||
|  |  */ | ||||||
|  | LevelDuration subghz_protocol_encoder_bin_raw_yield(void* context); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Allocate SubGhzProtocolDecoderBinRAW. | ||||||
|  |  * @param environment Pointer to a SubGhzEnvironment instance | ||||||
|  |  * @return SubGhzProtocolDecoderBinRAW* pointer to a SubGhzProtocolDecoderBinRAW instance | ||||||
|  |  */ | ||||||
|  | void* subghz_protocol_decoder_bin_raw_alloc(SubGhzEnvironment* environment); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Free SubGhzProtocolDecoderBinRAW. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_decoder_bin_raw_free(void* context); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Reset decoder SubGhzProtocolDecoderBinRAW. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_decoder_bin_raw_reset(void* context); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Parse a raw sequence of levels and durations received from the air. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance | ||||||
|  |  * @param level Signal level true-high false-low | ||||||
|  |  * @param duration Duration of this level in, us | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_decoder_bin_raw_feed(void* context, bool level, uint32_t duration); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Getting the hash sum of the last randomly received parcel. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance | ||||||
|  |  * @return hash Hash sum | ||||||
|  |  */ | ||||||
|  | uint8_t subghz_protocol_decoder_bin_raw_get_hash_data(void* context); | ||||||
|  | 
 | ||||||
|  | void subghz_protocol_decoder_bin_raw_data_input_rssi( | ||||||
|  |     SubGhzProtocolDecoderBinRAW* instance, | ||||||
|  |     float rssi); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Serialize data SubGhzProtocolDecoderBinRAW. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance | ||||||
|  |  * @param flipper_format Pointer to a FlipperFormat instance | ||||||
|  |  * @param preset The modulation on which the signal was received, SubGhzRadioPreset | ||||||
|  |  * @return true On success | ||||||
|  |  */ | ||||||
|  | bool subghz_protocol_decoder_bin_raw_serialize( | ||||||
|  |     void* context, | ||||||
|  |     FlipperFormat* flipper_format, | ||||||
|  |     SubGhzRadioPreset* preset); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Deserialize data SubGhzProtocolDecoderBinRAW. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance | ||||||
|  |  * @param flipper_format Pointer to a FlipperFormat instance | ||||||
|  |  * @return true On success | ||||||
|  |  */ | ||||||
|  | bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Getting a textual representation of the received data. | ||||||
|  |  * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance | ||||||
|  |  * @param output Resulting text | ||||||
|  |  */ | ||||||
|  | void subghz_protocol_decoder_bin_raw_get_string(void* context, FuriString* output); | ||||||
| @ -196,12 +196,13 @@ static bool | |||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     instance->encoder.size_upload = subghz_protocol_blocks_get_upload( |     instance->encoder.size_upload = subghz_protocol_blocks_get_upload_from_bit_array( | ||||||
|         upload_hex_data, |         upload_hex_data, | ||||||
|         upload_hex_count_bit, |         upload_hex_count_bit, | ||||||
|         instance->encoder.upload, |         instance->encoder.upload, | ||||||
|         instance->encoder.size_upload, |         instance->encoder.size_upload, | ||||||
|         subghz_protocol_chamb_code_const.te_short); |         subghz_protocol_chamb_code_const.te_short, | ||||||
|  |         SubGhzProtocolBlockAlignBitLeft); | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  | |||||||
| @ -42,6 +42,7 @@ const SubGhzProtocol* subghz_protocol_registry_items[] = { | |||||||
|     &subghz_protocol_dooya, |     &subghz_protocol_dooya, | ||||||
|     &subghz_protocol_alutech_at_4n, |     &subghz_protocol_alutech_at_4n, | ||||||
|     &subghz_protocol_kinggates_stylo_4k, |     &subghz_protocol_kinggates_stylo_4k, | ||||||
|  |     &subghz_protocol_bin_raw, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const SubGhzProtocolRegistry subghz_protocol_registry = { | const SubGhzProtocolRegistry subghz_protocol_registry = { | ||||||
|  | |||||||
| @ -42,5 +42,6 @@ | |||||||
| #include "dooya.h" | #include "dooya.h" | ||||||
| #include "alutech_at_4n.h" | #include "alutech_at_4n.h" | ||||||
| #include "kinggates_stylo_4k.h" | #include "kinggates_stylo_4k.h" | ||||||
|  | #include "bin_raw.h" | ||||||
| 
 | 
 | ||||||
| extern const SubGhzProtocolRegistry subghz_protocol_registry; | extern const SubGhzProtocolRegistry subghz_protocol_registry; | ||||||
|  | |||||||
| @ -261,16 +261,16 @@ static bool | |||||||
|     data = order << 4 | invert; |     data = order << 4 | invert; | ||||||
|     int k = 0; |     int k = 0; | ||||||
|     for(int i = 6; i >= 0; i -= 2) { |     for(int i = 6; i >= 0; i -= 2) { | ||||||
|         roll_array[k++] = (data >> i) & 0x03; |         roll_array[k] = (data >> i) & 0x03; | ||||||
|         if(roll_array[k] == 3) { |         if(roll_array[k++] == 3) { | ||||||
|             FURI_LOG_E(TAG, "Roll_Array FAIL"); |             FURI_LOG_E(TAG, "Roll_Array FAIL"); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for(int i = 8; i >= 0; i -= 2) { |     for(int i = 8; i >= 0; i -= 2) { | ||||||
|         roll_array[k++] = (p[2] >> i) & 0x03; |         roll_array[k] = (p[2] >> i) & 0x03; | ||||||
|         if(roll_array[k] == 3) { |         if(roll_array[k++] == 3) { | ||||||
|             FURI_LOG_E(TAG, "Roll_Array FAIL"); |             FURI_LOG_E(TAG, "Roll_Array FAIL"); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -64,7 +64,7 @@ void subghz_receiver_decode(SubGhzReceiver* instance, bool level, uint32_t durat | |||||||
| 
 | 
 | ||||||
|     for |     for | ||||||
|         M_EACH(slot, instance->slots, SubGhzReceiverSlotArray_t) { |         M_EACH(slot, instance->slots, SubGhzReceiverSlotArray_t) { | ||||||
|             if((slot->base->protocol->flag & instance->filter) == instance->filter) { |             if((slot->base->protocol->flag & instance->filter) != 0) { | ||||||
|                 slot->base->protocol->decoder->feed(slot->base, level, duration); |                 slot->base->protocol->decoder->feed(slot->base, level, duration); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -90,6 +90,7 @@ typedef enum { | |||||||
|     SubGhzProtocolFlag_Save = (1 << 7), |     SubGhzProtocolFlag_Save = (1 << 7), | ||||||
|     SubGhzProtocolFlag_Load = (1 << 8), |     SubGhzProtocolFlag_Load = (1 << 8), | ||||||
|     SubGhzProtocolFlag_Send = (1 << 9), |     SubGhzProtocolFlag_Send = (1 << 9), | ||||||
|  |     SubGhzProtocolFlag_BinRAW = (1 << 10), | ||||||
| } SubGhzProtocolFlag; | } SubGhzProtocolFlag; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|  | |||||||
| @ -13,8 +13,8 @@ | |||||||
| #define LEVEL_DURATION_RESERVED 0x800000U | #define LEVEL_DURATION_RESERVED 0x800000U | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint32_t level; |     uint32_t duration : 30; | ||||||
|     uint32_t duration; |     uint8_t level : 2; | ||||||
| } LevelDuration; | } LevelDuration; | ||||||
| 
 | 
 | ||||||
| static inline LevelDuration level_duration_make(bool level, uint32_t duration) { | static inline LevelDuration level_duration_make(bool level, uint32_t duration) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Skorpionm
						Skorpionm