diff --git a/applications/debug/unit_tests/subghz/subghz_test.c b/applications/debug/unit_tests/subghz/subghz_test.c index c7e9c96f1..f1ab92653 100644 --- a/applications/debug/unit_tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/subghz/subghz_test.c @@ -407,7 +407,7 @@ MU_TEST(subghz_decoder_ido_test) { "Test decoder " SUBGHZ_PROTOCOL_IDO_NAME " error\r\n"); } -MU_TEST(subghz_decoder_keelog_test) { +MU_TEST(subghz_decoder_keeloq_test) { mu_assert( subghz_decoder_test( EXT_PATH("unit_tests/subghz/doorhan_raw.sub"), SUBGHZ_PROTOCOL_KEELOQ_NAME), @@ -676,7 +676,7 @@ MU_TEST(subghz_encoder_nice_flo_test) { "Test encoder " SUBGHZ_PROTOCOL_NICE_FLO_NAME " error\r\n"); } -MU_TEST(subghz_encoder_keelog_test) { +MU_TEST(subghz_encoder_keeloq_test) { mu_assert( subghz_encoder_test(EXT_PATH("unit_tests/subghz/doorhan.sub")), "Test encoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n"); @@ -813,7 +813,7 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_decoder_gate_tx_test); MU_RUN_TEST(subghz_decoder_hormann_hsm_test); MU_RUN_TEST(subghz_decoder_ido_test); - MU_RUN_TEST(subghz_decoder_keelog_test); + MU_RUN_TEST(subghz_decoder_keeloq_test); MU_RUN_TEST(subghz_decoder_kia_seed_test); MU_RUN_TEST(subghz_decoder_nero_radio_test); MU_RUN_TEST(subghz_decoder_nero_sketch_test); @@ -852,7 +852,7 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_came_twee_test); MU_RUN_TEST(subghz_encoder_gate_tx_test); MU_RUN_TEST(subghz_encoder_nice_flo_test); - MU_RUN_TEST(subghz_encoder_keelog_test); + MU_RUN_TEST(subghz_encoder_keeloq_test); MU_RUN_TEST(subghz_encoder_linear_test); MU_RUN_TEST(subghz_encoder_linear_delta3_test); MU_RUN_TEST(subghz_encoder_megacode_test); diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index ad49bf09b..cd163a653 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -36,12 +36,12 @@ typedef enum { SubmenuIndexCAME24bit868, SubmenuIndexCAMETwee, SubmenuIndexCAMESpace, - SubmenuIndexPricenton, + SubmenuIndexPricenton433, SubmenuIndexPricenton315, SubmenuIndexBETT_433, SubmenuIndexLinear_300_00, - SubmenuIndexNeroSketch, - SubmenuIndexNeroRadio, + SubmenuIndexNeroSketch, //Deleted in OFW + SubmenuIndexNeroRadio, //Deleted in OFW SubmenuIndexGateTX, SubmenuIndexDoorHan_315_00, SubmenuIndexDoorHan_433_92, diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c index ab90547cb..6fec29565 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -278,7 +278,7 @@ SubGhzFrequencyAnalyzerWorker* subghz_frequency_analyzer_worker_alloc(void* cont furi_thread_set_callback(instance->thread, subghz_frequency_analyzer_worker_thread); SubGhz* subghz = context; - instance->setting = subghz->setting; + instance->setting = subghz_txrx_get_setting(subghz->txrx); instance->trigger_level = subghz->last_settings->frequency_analyzer_trigger; //instance->trigger_level = SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD; return instance; diff --git a/applications/main/subghz/helpers/subghz_threshold_rssi.c b/applications/main/subghz/helpers/subghz_threshold_rssi.c new file mode 100644 index 000000000..04a06bc17 --- /dev/null +++ b/applications/main/subghz/helpers/subghz_threshold_rssi.c @@ -0,0 +1,60 @@ +#include "subghz_threshold_rssi.h" +#include +#include "../subghz_i.h" + +#define TAG "SubGhzThresholdRssi" +#define THRESHOLD_RSSI_LOW_COUNT 10 + +struct SubGhzThresholdRssi { + float threshold_rssi; + uint8_t threshold_rssi_low_count; +}; + +SubGhzThresholdRssi* subghz_threshold_rssi_alloc(void) { + SubGhzThresholdRssi* instance = malloc(sizeof(SubGhzThresholdRssi)); + instance->threshold_rssi = SUBGHZ_RAW_THRESHOLD_MIN; + instance->threshold_rssi_low_count = THRESHOLD_RSSI_LOW_COUNT; + return instance; +} + +void subghz_threshold_rssi_free(SubGhzThresholdRssi* instance) { + furi_assert(instance); + free(instance); +} + +void subghz_threshold_rssi_set(SubGhzThresholdRssi* instance, float rssi) { + furi_assert(instance); + instance->threshold_rssi = rssi; +} + +float subghz_threshold_rssi_get(SubGhzThresholdRssi* instance) { + furi_assert(instance); + return instance->threshold_rssi; +} + +SubGhzThresholdRssiData subghz_threshold_get_rssi_data(SubGhzThresholdRssi* instance) { + furi_assert(instance); + float rssi = furi_hal_subghz_get_rssi(); + SubGhzThresholdRssiData ret = {.rssi = rssi, .is_above = false}; + + if(float_is_equal(instance->threshold_rssi, SUBGHZ_RAW_THRESHOLD_MIN)) { + ret.is_above = true; + } else { + if(rssi < instance->threshold_rssi) { + instance->threshold_rssi_low_count++; + if(instance->threshold_rssi_low_count > THRESHOLD_RSSI_LOW_COUNT) { + instance->threshold_rssi_low_count = THRESHOLD_RSSI_LOW_COUNT; + } + ret.is_above = false; + } else { + instance->threshold_rssi_low_count = 0; + } + + if(instance->threshold_rssi_low_count == THRESHOLD_RSSI_LOW_COUNT) { + ret.is_above = false; + } else { + ret.is_above = true; + } + } + return ret; +} diff --git a/applications/main/subghz/helpers/subghz_threshold_rssi.h b/applications/main/subghz/helpers/subghz_threshold_rssi.h new file mode 100644 index 000000000..e28092acb --- /dev/null +++ b/applications/main/subghz/helpers/subghz_threshold_rssi.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +typedef struct { + float rssi; /**< Current RSSI */ + bool is_above; /**< Exceeded threshold level */ +} SubGhzThresholdRssiData; + +typedef struct SubGhzThresholdRssi SubGhzThresholdRssi; + +/** Allocate SubGhzThresholdRssi + * + * @return SubGhzThresholdRssi* + */ +SubGhzThresholdRssi* subghz_threshold_rssi_alloc(void); + +/** Free SubGhzThresholdRssi + * + * @param instance Pointer to a SubGhzThresholdRssi + */ +void subghz_threshold_rssi_free(SubGhzThresholdRssi* instance); + +/** Set threshold + * + * @param instance Pointer to a SubGhzThresholdRssi + * @param rssi RSSI threshold + */ +void subghz_threshold_rssi_set(SubGhzThresholdRssi* instance, float rssi); + +/** Get threshold + * + * @param instance Pointer to a SubGhzThresholdRssi + * @return float RSSI threshold + */ +float subghz_threshold_rssi_get(SubGhzThresholdRssi* instance); + +/** Check threshold + * + * @param instance Pointer to a SubGhzThresholdRssi + * @return SubGhzThresholdRssiData + */ +SubGhzThresholdRssiData subghz_threshold_get_rssi_data(SubGhzThresholdRssi* instance); diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c new file mode 100644 index 000000000..c1f519ba0 --- /dev/null +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -0,0 +1,563 @@ +#include "subghz_txrx_i.h" +#include + +#define TAG "SubGhz" + +SubGhzTxRx* subghz_txrx_alloc() { + SubGhzTxRx* instance = malloc(sizeof(SubGhzTxRx)); + instance->setting = subghz_setting_alloc(); + subghz_setting_load(instance->setting, EXT_PATH("subghz/assets/setting_user")); + + instance->preset = malloc(sizeof(SubGhzRadioPreset)); + instance->preset->name = furi_string_alloc(); + subghz_txrx_set_preset( + instance, "AM650", subghz_setting_get_default_frequency(instance->setting), NULL, 0); + + instance->txrx_state = SubGhzTxRxStateSleep; + + subghz_txrx_hopper_set_state(instance, SubGhzHopperStateOFF); + subghz_txrx_speaker_set_state(instance, SubGhzSpeakerStateDisable); + subghz_txrx_set_debug_pin_state(instance, false); + + instance->worker = subghz_worker_alloc(); + instance->fff_data = flipper_format_string_alloc(); + + instance->environment = subghz_environment_alloc(); + instance->is_database_loaded = subghz_environment_load_keystore( + instance->environment, EXT_PATH("subghz/assets/keeloq_mfcodes")); + subghz_environment_load_keystore( + instance->environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user")); + subghz_environment_set_came_atomo_rainbow_table_file_name( + instance->environment, EXT_PATH("subghz/assets/came_atomo")); + subghz_environment_set_alutech_at_4n_rainbow_table_file_name( + instance->environment, EXT_PATH("subghz/assets/alutech_at_4n")); + subghz_environment_set_nice_flor_s_rainbow_table_file_name( + instance->environment, EXT_PATH("subghz/assets/nice_flor_s")); + subghz_environment_set_protocol_registry( + instance->environment, (void*)&subghz_protocol_registry); + instance->receiver = subghz_receiver_alloc_init(instance->environment); + + subghz_worker_set_overrun_callback( + instance->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); + subghz_worker_set_pair_callback( + instance->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode); + subghz_worker_set_context(instance->worker, instance->receiver); + + return instance; +} + +void subghz_txrx_free(SubGhzTxRx* instance) { + furi_assert(instance); + + subghz_worker_free(instance->worker); + subghz_receiver_free(instance->receiver); + subghz_environment_free(instance->environment); + flipper_format_free(instance->fff_data); + furi_string_free(instance->preset->name); + subghz_setting_free(instance->setting); + free(instance->preset); + free(instance); +} + +bool subghz_txrx_is_database_loaded(SubGhzTxRx* instance) { + furi_assert(instance); + return instance->is_database_loaded; +} + +void subghz_txrx_set_preset( + SubGhzTxRx* instance, + const char* preset_name, + uint32_t frequency, + uint8_t* preset_data, + size_t preset_data_size) { + furi_assert(instance); + furi_string_set(instance->preset->name, preset_name); + SubGhzRadioPreset* preset = instance->preset; + preset->frequency = frequency; + preset->data = preset_data; + preset->data_size = preset_data_size; +} + +const char* subghz_txrx_get_preset_name(SubGhzTxRx* instance, const char* preset) { + UNUSED(instance); + const char* preset_name = ""; + if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) { + preset_name = "AM270"; + } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) { + preset_name = "AM650"; + } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { + preset_name = "FM238"; + } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { + preset_name = "FM476"; + } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { + preset_name = "CUSTOM"; + } else { + FURI_LOG_E(TAG, "Unknown preset"); + } + return preset_name; +} + +SubGhzRadioPreset subghz_txrx_get_preset(SubGhzTxRx* instance) { + furi_assert(instance); + return *instance->preset; +} + +void subghz_txrx_get_frequency_and_modulation( + SubGhzTxRx* instance, + FuriString* frequency, + FuriString* modulation, + bool long_name) { + furi_assert(instance); + SubGhzRadioPreset* preset = instance->preset; + if(frequency != NULL) { + furi_string_printf( + frequency, + "%03ld.%02ld", + preset->frequency / 1000000 % 1000, + preset->frequency / 10000 % 100); + } + if(modulation != NULL) { + if(long_name) { + furi_string_printf(modulation, "%s", furi_string_get_cstr(preset->name)); + } else { + furi_string_printf(modulation, "%.2s", furi_string_get_cstr(preset->name)); + } + } +} + +static void subghz_txrx_begin(SubGhzTxRx* instance, uint8_t* preset_data) { + furi_assert(instance); + furi_hal_subghz_reset(); + furi_hal_subghz_idle(); + furi_hal_subghz_load_custom_preset(preset_data); + furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); + instance->txrx_state = SubGhzTxRxStateIDLE; +} + +static uint32_t subghz_txrx_rx(SubGhzTxRx* instance, uint32_t frequency) { + furi_assert(instance); + if(!furi_hal_subghz_is_frequency_valid(frequency)) { + furi_crash("SubGhz: Incorrect RX frequency."); + } + furi_assert( + instance->txrx_state != SubGhzTxRxStateRx && instance->txrx_state != SubGhzTxRxStateSleep); + + furi_hal_subghz_idle(); + uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); + furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_subghz_flush_rx(); + subghz_txrx_speaker_on(instance); + furi_hal_subghz_rx(); + + furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, instance->worker); + subghz_worker_start(instance->worker); + instance->txrx_state = SubGhzTxRxStateRx; + return value; +} + +static void subghz_txrx_idle(SubGhzTxRx* instance) { + furi_assert(instance); + furi_assert(instance->txrx_state != SubGhzTxRxStateSleep); + furi_hal_subghz_idle(); + subghz_txrx_speaker_off(instance); + instance->txrx_state = SubGhzTxRxStateIDLE; +} + +static void subghz_txrx_rx_end(SubGhzTxRx* instance) { + furi_assert(instance); + furi_assert(instance->txrx_state == SubGhzTxRxStateRx); + + if(subghz_worker_is_running(instance->worker)) { + subghz_worker_stop(instance->worker); + furi_hal_subghz_stop_async_rx(); + } + furi_hal_subghz_idle(); + subghz_txrx_speaker_off(instance); + instance->txrx_state = SubGhzTxRxStateIDLE; +} + +void subghz_txrx_sleep(SubGhzTxRx* instance) { + furi_assert(instance); + furi_hal_subghz_sleep(); + instance->txrx_state = SubGhzTxRxStateSleep; +} + +static bool subghz_txrx_tx(SubGhzTxRx* instance, uint32_t frequency) { + furi_assert(instance); + if(!furi_hal_subghz_is_frequency_valid(frequency)) { + furi_crash("SubGhz: Incorrect TX frequency."); + } + furi_assert(instance->txrx_state != SubGhzTxRxStateSleep); + furi_hal_subghz_idle(); + furi_hal_subghz_set_frequency_and_path(frequency); + furi_hal_gpio_write(furi_hal_subghz.cc1101_g0_pin, false); + furi_hal_gpio_init( + furi_hal_subghz.cc1101_g0_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + bool ret = furi_hal_subghz_tx(); + if(ret) { + subghz_txrx_speaker_on(instance); + instance->txrx_state = SubGhzTxRxStateTx; + } + + return ret; +} + +SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat* flipper_format) { + furi_assert(instance); + furi_assert(flipper_format); + + subghz_txrx_stop(instance); + + SubGhzTxRxStartTxState ret = SubGhzTxRxStartTxStateErrorParserOthers; + FuriString* temp_str = furi_string_alloc(); + uint32_t repeat = 200; + do { + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + if(!flipper_format_read_string(flipper_format, "Protocol", temp_str)) { + FURI_LOG_E(TAG, "Missing Protocol"); + break; + } + if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) { + FURI_LOG_E(TAG, "Unable Repeat"); + break; + } + ret = SubGhzTxRxStartTxStateOk; + + SubGhzRadioPreset* preset = instance->preset; + instance->transmitter = + subghz_transmitter_alloc_init(instance->environment, furi_string_get_cstr(temp_str)); + + if(instance->transmitter) { + if(subghz_transmitter_deserialize(instance->transmitter, flipper_format) == + SubGhzProtocolStatusOk) { + if(strcmp(furi_string_get_cstr(preset->name), "") != 0) { + subghz_txrx_begin( + instance, + subghz_setting_get_preset_data_by_name( + instance->setting, furi_string_get_cstr(preset->name))); + if(preset->frequency) { + if(!subghz_txrx_tx(instance, preset->frequency)) { + FURI_LOG_E(TAG, "Only Rx"); + ret = SubGhzTxRxStartTxStateErrorOnlyRx; + } + } else { + ret = SubGhzTxRxStartTxStateErrorParserOthers; + } + + } else { + FURI_LOG_E( + TAG, "Unknown name preset \" %s \"", furi_string_get_cstr(preset->name)); + ret = SubGhzTxRxStartTxStateErrorParserOthers; + } + + if(ret == SubGhzTxRxStartTxStateOk) { + //Start TX + furi_hal_subghz_start_async_tx( + subghz_transmitter_yield, instance->transmitter); + } + } else { + ret = SubGhzTxRxStartTxStateErrorParserOthers; + } + } else { + ret = SubGhzTxRxStartTxStateErrorParserOthers; + } + if(ret != SubGhzTxRxStartTxStateOk) { + subghz_transmitter_free(instance->transmitter); + if(instance->txrx_state != SubGhzTxRxStateIDLE) { + subghz_txrx_idle(instance); + } + } + + } while(false); + furi_string_free(temp_str); + return ret; +} + +void subghz_txrx_rx_start(SubGhzTxRx* instance) { + furi_assert(instance); + subghz_txrx_stop(instance); + subghz_txrx_begin( + instance, + subghz_setting_get_preset_data_by_name( + subghz_txrx_get_setting(instance), furi_string_get_cstr(instance->preset->name))); + subghz_txrx_rx(instance, instance->preset->frequency); +} + +void subghz_txrx_set_need_save_callback( + SubGhzTxRx* instance, + SubGhzTxRxNeedSaveCallback callback, + void* context) { + furi_assert(instance); + instance->need_save_callback = callback; + instance->need_save_context = context; +} + +static void subghz_txrx_tx_stop(SubGhzTxRx* instance) { + furi_assert(instance); + furi_assert(instance->txrx_state == SubGhzTxRxStateTx); + //Stop TX + furi_hal_subghz_stop_async_tx(); + subghz_transmitter_stop(instance->transmitter); + subghz_transmitter_free(instance->transmitter); + + //if protocol dynamic then we save the last upload + if(instance->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) { + if(instance->need_save_callback) { + instance->need_save_callback(instance->need_save_context); + } + } + subghz_txrx_idle(instance); + subghz_txrx_speaker_off(instance); + //Todo: Show message + // notification_message(notifications, &sequence_reset_red); +} + +FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance) { + furi_assert(instance); + return instance->fff_data; +} + +SubGhzSetting* subghz_txrx_get_setting(SubGhzTxRx* instance) { + furi_assert(instance); + return instance->setting; +} + +void subghz_txrx_stop(SubGhzTxRx* instance) { + furi_assert(instance); + + switch(instance->txrx_state) { + case SubGhzTxRxStateTx: + subghz_txrx_tx_stop(instance); + subghz_txrx_speaker_unmute(instance); + break; + case SubGhzTxRxStateRx: + subghz_txrx_rx_end(instance); + subghz_txrx_speaker_mute(instance); + break; + + default: + break; + } +} + +void subghz_txrx_hopper_update(SubGhzTxRx* instance) { + furi_assert(instance); + + switch(instance->hopper_state) { + case SubGhzHopperStateOFF: + case SubGhzHopperStatePause: + return; + case SubGhzHopperStateRSSITimeOut: + if(instance->hopper_timeout != 0) { + instance->hopper_timeout--; + return; + } + break; + default: + break; + } + float rssi = -127.0f; + if(instance->hopper_state != SubGhzHopperStateRSSITimeOut) { + // See RSSI Calculation timings in CC1101 17.3 RSSI + rssi = furi_hal_subghz_get_rssi(); + + // Stay if RSSI is high enough + if(rssi > -90.0f) { + instance->hopper_timeout = 10; + instance->hopper_state = SubGhzHopperStateRSSITimeOut; + return; + } + } else { + instance->hopper_state = SubGhzHopperStateRunning; + } + // Select next frequency + if(instance->hopper_idx_frequency < + subghz_setting_get_hopper_frequency_count(instance->setting) - 1) { + instance->hopper_idx_frequency++; + } else { + instance->hopper_idx_frequency = 0; + } + + if(instance->txrx_state == SubGhzTxRxStateRx) { + subghz_txrx_rx_end(instance); + }; + if(instance->txrx_state == SubGhzTxRxStateIDLE) { + subghz_receiver_reset(instance->receiver); + instance->preset->frequency = + subghz_setting_get_hopper_frequency(instance->setting, instance->hopper_idx_frequency); + subghz_txrx_rx(instance, instance->preset->frequency); + } +} + +SubGhzHopperState subghz_txrx_hopper_get_state(SubGhzTxRx* instance) { + furi_assert(instance); + return instance->hopper_state; +} + +void subghz_txrx_hopper_set_state(SubGhzTxRx* instance, SubGhzHopperState state) { + furi_assert(instance); + instance->hopper_state = state; +} + +void subghz_txrx_hopper_unpause(SubGhzTxRx* instance) { + furi_assert(instance); + if(instance->hopper_state == SubGhzHopperStatePause) { + instance->hopper_state = SubGhzHopperStateRunning; + } +} + +void subghz_txrx_hopper_pause(SubGhzTxRx* instance) { + furi_assert(instance); + if(instance->hopper_state == SubGhzHopperStateRunning) { + instance->hopper_state = SubGhzHopperStatePause; + } +} + +void subghz_txrx_speaker_on(SubGhzTxRx* instance) { + furi_assert(instance); + if(instance->debug_pin_state) { + furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton); + } + + if(instance->speaker_state == SubGhzSpeakerStateEnable) { + if(furi_hal_speaker_acquire(30)) { + if(!instance->debug_pin_state) { + furi_hal_subghz_set_async_mirror_pin(&gpio_speaker); + } + } else { + instance->speaker_state = SubGhzSpeakerStateDisable; + } + } +} + +void subghz_txrx_speaker_off(SubGhzTxRx* instance) { + furi_assert(instance); + if(instance->debug_pin_state) { + furi_hal_subghz_set_async_mirror_pin(NULL); + } + if(instance->speaker_state != SubGhzSpeakerStateDisable) { + if(furi_hal_speaker_is_mine()) { + if(!instance->debug_pin_state) { + furi_hal_subghz_set_async_mirror_pin(NULL); + } + furi_hal_speaker_release(); + if(instance->speaker_state == SubGhzSpeakerStateShutdown) + instance->speaker_state = SubGhzSpeakerStateDisable; + } + } +} + +void subghz_txrx_speaker_mute(SubGhzTxRx* instance) { + furi_assert(instance); + if(instance->debug_pin_state) { + furi_hal_subghz_set_async_mirror_pin(NULL); + } + if(instance->speaker_state == SubGhzSpeakerStateEnable) { + if(furi_hal_speaker_is_mine()) { + if(!instance->debug_pin_state) { + furi_hal_subghz_set_async_mirror_pin(NULL); + } + } + } +} + +void subghz_txrx_speaker_unmute(SubGhzTxRx* instance) { + furi_assert(instance); + if(instance->debug_pin_state) { + furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton); + } + if(instance->speaker_state == SubGhzSpeakerStateEnable) { + if(furi_hal_speaker_is_mine()) { + if(!instance->debug_pin_state) { + furi_hal_subghz_set_async_mirror_pin(&gpio_speaker); + } + } + } +} + +void subghz_txrx_speaker_set_state(SubGhzTxRx* instance, SubGhzSpeakerState state) { + furi_assert(instance); + instance->speaker_state = state; +} + +SubGhzSpeakerState subghz_txrx_speaker_get_state(SubGhzTxRx* instance) { + furi_assert(instance); + return instance->speaker_state; +} + +bool subghz_txrx_load_decoder_by_name_protocol(SubGhzTxRx* instance, const char* name_protocol) { + furi_assert(instance); + furi_assert(name_protocol); + bool res = false; + instance->decoder_result = + subghz_receiver_search_decoder_base_by_name(instance->receiver, name_protocol); + if(instance->decoder_result) { + res = true; + } + return res; +} + +SubGhzProtocolDecoderBase* subghz_txrx_get_decoder(SubGhzTxRx* instance) { + furi_assert(instance); + return instance->decoder_result; +} + +bool subghz_txrx_protocol_is_serializable(SubGhzTxRx* instance) { + furi_assert(instance); + return ( + (instance->decoder_result->protocol->flag & SubGhzProtocolFlag_Save) == + SubGhzProtocolFlag_Save); +} + +bool subghz_txrx_protocol_is_transmittable(SubGhzTxRx* instance, bool check_type) { + furi_assert(instance); + const SubGhzProtocol* protocol = instance->decoder_result->protocol; + if(check_type) { + return ( + ((protocol->flag & SubGhzProtocolFlag_Send) == SubGhzProtocolFlag_Send) && + protocol->encoder->deserialize && protocol->type == SubGhzProtocolTypeStatic); + } + return ( + ((protocol->flag & SubGhzProtocolFlag_Send) == SubGhzProtocolFlag_Send) && + protocol->encoder->deserialize); +} + +void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag filter) { + furi_assert(instance); + subghz_receiver_set_filter(instance->receiver, filter); +} + +void subghz_txrx_set_rx_calback( + SubGhzTxRx* instance, + SubGhzReceiverCallback callback, + void* context) { + subghz_receiver_set_rx_callback(instance->receiver, callback, context); +} + +void subghz_txrx_set_raw_file_encoder_worker_callback_end( + SubGhzTxRx* instance, + SubGhzProtocolEncoderRAWCallbackEnd callback, + void* context) { + subghz_protocol_raw_file_encoder_worker_set_callback_end( + (SubGhzProtocolEncoderRAW*)subghz_transmitter_get_protocol_instance(instance->transmitter), + callback, + context); +} + +void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state) { + furi_assert(instance); + instance->debug_pin_state = state; +} + +bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance) { + furi_assert(instance); + return instance->debug_pin_state; +} + +SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) { + furi_assert(instance); + return instance->receiver; +} \ No newline at end of file diff --git a/applications/main/subghz/helpers/subghz_txrx.h b/applications/main/subghz/helpers/subghz_txrx.h new file mode 100644 index 000000000..fd7c024b8 --- /dev/null +++ b/applications/main/subghz/helpers/subghz_txrx.h @@ -0,0 +1,296 @@ +#pragma once + +#include "subghz_types.h" + +#include +#include +#include +#include +#include + +typedef struct SubGhzTxRx SubGhzTxRx; + +typedef void (*SubGhzTxRxNeedSaveCallback)(void* context); + +typedef enum { + SubGhzTxRxStartTxStateOk, + SubGhzTxRxStartTxStateErrorOnlyRx, + SubGhzTxRxStartTxStateErrorParserOthers, +} SubGhzTxRxStartTxState; + +/** + * Allocate SubGhzTxRx + * + * @return SubGhzTxRx* pointer to SubGhzTxRx + */ +SubGhzTxRx* subghz_txrx_alloc(); + +/** + * Free SubGhzTxRx + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_free(SubGhzTxRx* instance); + +/** + * Check if the database is loaded + * + * @param instance Pointer to a SubGhzTxRx + * @return bool True if the database is loaded + */ +bool subghz_txrx_is_database_loaded(SubGhzTxRx* instance); + +/** + * Set preset + * + * @param instance Pointer to a SubGhzTxRx + * @param preset_name Name of preset + * @param frequency Frequency in Hz + * @param preset_data Data of preset + * @param preset_data_size Size of preset data + */ +void subghz_txrx_set_preset( + SubGhzTxRx* instance, + const char* preset_name, + uint32_t frequency, + uint8_t* preset_data, + size_t preset_data_size); + +/** + * Get name of preset + * + * @param instance Pointer to a SubGhzTxRx + * @param preset String of preset + * @return const char* Name of preset + */ +const char* subghz_txrx_get_preset_name(SubGhzTxRx* instance, const char* preset); + +/** + * Get of preset + * + * @param instance Pointer to a SubGhzTxRx + * @return SubGhzRadioPreset Preset + */ +SubGhzRadioPreset subghz_txrx_get_preset(SubGhzTxRx* instance); + +/** + * Get string frequency and modulation + * + * @param instance Pointer to a SubGhzTxRx + * @param frequency Pointer to a string frequency + * @param modulation Pointer to a string modulation + */ +void subghz_txrx_get_frequency_and_modulation( + SubGhzTxRx* instance, + FuriString* frequency, + FuriString* modulation, + bool long_name); + +/** + * Start TX CC1101 + * + * @param instance Pointer to a SubGhzTxRx + * @param flipper_format Pointer to a FlipperFormat + * @return SubGhzTxRxStartTxState + */ +SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat* flipper_format); + +/** + * Start RX CC1101 + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_rx_start(SubGhzTxRx* instance); + +/** + * Stop TX/RX CC1101 + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_stop(SubGhzTxRx* instance); + +/** + * Set sleep mode CC1101 + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_sleep(SubGhzTxRx* instance); + +/** + * Update frequency CC1101 in automatic mode (hopper) + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_hopper_update(SubGhzTxRx* instance); + +/** + * Get state hopper + * + * @param instance Pointer to a SubGhzTxRx + * @return SubGhzHopperState + */ +SubGhzHopperState subghz_txrx_hopper_get_state(SubGhzTxRx* instance); + +/** + * Set state hopper + * + * @param instance Pointer to a SubGhzTxRx + * @param state State hopper + */ +void subghz_txrx_hopper_set_state(SubGhzTxRx* instance, SubGhzHopperState state); + +/** + * Unpause hopper + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_hopper_unpause(SubGhzTxRx* instance); + +/** + * Set pause hopper + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_hopper_pause(SubGhzTxRx* instance); + +/** + * Speaker on + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_speaker_on(SubGhzTxRx* instance); + +/** + * Speaker off + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_speaker_off(SubGhzTxRx* instance); + +/** + * Speaker mute + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_speaker_mute(SubGhzTxRx* instance); + +/** + * Speaker unmute + * + * @param instance Pointer to a SubGhzTxRx + */ +void subghz_txrx_speaker_unmute(SubGhzTxRx* instance); + +/** + * Set state speaker + * + * @param instance Pointer to a SubGhzTxRx + * @param state State speaker + */ +void subghz_txrx_speaker_set_state(SubGhzTxRx* instance, SubGhzSpeakerState state); + +/** + * Get state speaker + * + * @param instance Pointer to a SubGhzTxRx + * @return SubGhzSpeakerState + */ +SubGhzSpeakerState subghz_txrx_speaker_get_state(SubGhzTxRx* instance); + +/** + * load decoder by name protocol + * + * @param instance Pointer to a SubGhzTxRx + * @param name_protocol Name protocol + * @return bool True if the decoder is loaded + */ +bool subghz_txrx_load_decoder_by_name_protocol(SubGhzTxRx* instance, const char* name_protocol); + +/** + * Get decoder + * + * @param instance Pointer to a SubGhzTxRx + * @return SubGhzProtocolDecoderBase* Pointer to a SubGhzProtocolDecoderBase + */ +SubGhzProtocolDecoderBase* subghz_txrx_get_decoder(SubGhzTxRx* instance); + +/** + * Set callback for save data + * + * @param instance Pointer to a SubGhzTxRx + * @param callback Callback for save data + * @param context Context for callback + */ +void subghz_txrx_set_need_save_callback( + SubGhzTxRx* instance, + SubGhzTxRxNeedSaveCallback callback, + void* context); + +/** + * Get pointer to a load data key + * + * @param instance Pointer to a SubGhzTxRx + * @return FlipperFormat* + */ +FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance); + +/** + * Get pointer to a SugGhzSetting + * + * @param instance Pointer to a SubGhzTxRx + * @return SubGhzSetting* + */ +SubGhzSetting* subghz_txrx_get_setting(SubGhzTxRx* instance); + +/** + * Is it possible to save this protocol + * + * @param instance Pointer to a SubGhzTxRx + * @return bool True if it is possible to save this protocol + */ +bool subghz_txrx_protocol_is_serializable(SubGhzTxRx* instance); + +/** + * Is it possible to send this protocol + * + * @param instance Pointer to a SubGhzTxRx + * @return bool True if it is possible to send this protocol + */ +bool subghz_txrx_protocol_is_transmittable(SubGhzTxRx* instance, bool check_type); + +/** + * Set filter, what types of decoder to use + * + * @param instance Pointer to a SubGhzTxRx + * @param filter Filter + */ +void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag filter); + +/** + * Set callback for receive data + * + * @param instance Pointer to a SubGhzTxRx + * @param callback Callback for receive data + * @param context Context for callback + */ +void subghz_txrx_set_rx_calback( + SubGhzTxRx* instance, + SubGhzReceiverCallback callback, + void* context); + +/** + * Set callback for Raw decoder, end of data transfer + * + * @param instance Pointer to a SubGhzTxRx + * @param callback Callback for Raw decoder, end of data transfer + * @param context Context for callback + */ +void subghz_txrx_set_raw_file_encoder_worker_callback_end( + SubGhzTxRx* instance, + SubGhzProtocolEncoderRAWCallbackEnd callback, + void* context); + +void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state); +bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance); + +SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c new file mode 100644 index 000000000..0631c7c15 --- /dev/null +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -0,0 +1,346 @@ +#include "subghz_txrx_i.h" +#include "subghz_txrx_create_protocol_key.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define TAG "SubGhzCreateProtocolKey" + +bool subghz_txrx_gen_data_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + const char* protocol_name, + uint64_t key, + uint32_t bit) { + furi_assert(context); + SubGhzTxRx* instance = context; + + bool res = false; + + subghz_txrx_set_preset(instance, preset_name, frequency, NULL, 0); + instance->decoder_result = + subghz_receiver_search_decoder_base_by_name(instance->receiver, protocol_name); + + if(instance->decoder_result == NULL) { + //TODO: Error + // furi_string_set(error_str, "Protocol not\nfound!"); + // scene_manager_next_scene(scene_manager, SubGhzSceneShowErrorSub); + FURI_LOG_E(TAG, "Protocol not found!"); + return false; + } + + do { + Stream* fff_data_stream = flipper_format_get_raw_stream(instance->fff_data); + stream_clean(fff_data_stream); + if(subghz_protocol_decoder_base_serialize( + instance->decoder_result, instance->fff_data, instance->preset) != + SubGhzProtocolStatusOk) { + FURI_LOG_E(TAG, "Unable to serialize"); + break; + } + if(!flipper_format_update_uint32(instance->fff_data, "Bit", &bit, 1)) { + FURI_LOG_E(TAG, "Unable to update Bit"); + break; + } + + uint8_t key_data[sizeof(uint64_t)] = {0}; + for(size_t i = 0; i < sizeof(uint64_t); i++) { + key_data[sizeof(uint64_t) - i - 1] = (key >> (i * 8)) & 0xFF; + } + if(!flipper_format_update_hex(instance->fff_data, "Key", key_data, sizeof(uint64_t))) { + FURI_LOG_E(TAG, "Unable to update Key"); + break; + } + res = true; + } while(false); + return res; +} + +bool subghz_txrx_gen_data_protocol_and_te( + SubGhzTxRx* instance, + const char* preset_name, + uint32_t frequency, + const char* protocol_name, + uint64_t key, + uint32_t bit, + uint32_t te) { + furi_assert(instance); + bool ret = false; + if(subghz_txrx_gen_data_protocol(instance, preset_name, frequency, protocol_name, key, bit)) { + if(!flipper_format_update_uint32(instance->fff_data, "TE", (uint32_t*)&te, 1)) { + FURI_LOG_E(TAG, "Unable to update Te"); + } else { + ret = true; + } + } + return ret; +} + +bool subghz_txrx_gen_keeloq_protocol( //TODO lead to a general appearance + SubGhzTxRx* instance, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt, + const char* manufacture_name) { + furi_assert(instance); + + bool res = false; + + instance->transmitter = + subghz_transmitter_alloc_init(instance->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); + subghz_txrx_set_preset(instance, preset_name, frequency, NULL, 0); + + if(instance->transmitter && + subghz_protocol_keeloq_create_data( + subghz_transmitter_get_protocol_instance(instance->transmitter), + instance->fff_data, + serial, + btn, + cnt, + manufacture_name, + instance->preset)) { + flipper_format_write_string_cstr(instance->fff_data, "Manufacture", manufacture_name); + res = true; + } + subghz_transmitter_free(instance->transmitter); + return res; +} + +bool subghz_txrx_gen_keeloq_bft_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt, + uint32_t seed, + const char* manufacture_name) { + SubGhzTxRx* txrx = context; + + bool res = false; + + txrx->transmitter = + subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); + subghz_txrx_set_preset(txrx, preset_name, frequency, NULL, 0); + + if(txrx->transmitter && subghz_protocol_keeloq_bft_create_data( + subghz_transmitter_get_protocol_instance(txrx->transmitter), + txrx->fff_data, + serial, + btn, + cnt, + seed, + manufacture_name, + txrx->preset)) { + res = true; + } + + if(res) { + uint8_t seed_data[sizeof(uint32_t)] = {0}; + for(size_t i = 0; i < sizeof(uint32_t); i++) { + seed_data[sizeof(uint32_t) - i - 1] = (seed >> i * 8) & 0xFF; + } + + flipper_format_write_hex(txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); + + flipper_format_write_string_cstr(txrx->fff_data, "Manufacture", "BFT"); + } + + subghz_transmitter_free(txrx->transmitter); + + return res; +} + +bool subghz_txrx_gen_nice_flor_s_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt, + bool nice_one) { + SubGhzTxRx* txrx = context; + + bool res = false; + + txrx->transmitter = + subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME); + subghz_txrx_set_preset(txrx, preset_name, frequency, NULL, 0); + + if(txrx->transmitter && subghz_protocol_nice_flor_s_create_data( + subghz_transmitter_get_protocol_instance(txrx->transmitter), + txrx->fff_data, + serial, + btn, + cnt, + txrx->preset, + nice_one)) { + res = true; + } + + subghz_transmitter_free(txrx->transmitter); + + return res; +} + +bool subghz_txrx_gen_faac_slh_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt, + uint32_t seed, + const char* manufacture_name) { + SubGhzTxRx* txrx = context; + + bool res = false; + + txrx->transmitter = + subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_FAAC_SLH_NAME); + subghz_txrx_set_preset(txrx, preset_name, frequency, NULL, 0); + + if(txrx->transmitter && subghz_protocol_faac_slh_create_data( + subghz_transmitter_get_protocol_instance(txrx->transmitter), + txrx->fff_data, + serial, + btn, + cnt, + seed, + manufacture_name, + txrx->preset)) { + res = true; + } + + if(res) { + uint8_t seed_data[sizeof(uint32_t)] = {0}; + for(size_t i = 0; i < sizeof(uint32_t); i++) { + seed_data[sizeof(uint32_t) - i - 1] = (seed >> i * 8) & 0xFF; + } + + flipper_format_write_hex(txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); + } + + subghz_transmitter_free(txrx->transmitter); + + return res; +} + +bool subghz_txrx_gen_alutech_at_4n_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt) { + SubGhzTxRx* txrx = context; + + bool res = false; + + txrx->transmitter = + subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME); + subghz_txrx_set_preset(txrx, preset_name, frequency, NULL, 0); + + if(txrx->transmitter && subghz_protocol_alutech_at_4n_create_data( + subghz_transmitter_get_protocol_instance(txrx->transmitter), + txrx->fff_data, + serial, + btn, + cnt, + txrx->preset)) { + res = true; + } + + subghz_transmitter_free(txrx->transmitter); + + return res; +} + +bool subghz_txrx_gen_somfy_telis_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt) { + SubGhzTxRx* txrx = context; + + bool res = false; + + txrx->transmitter = + subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME); + subghz_txrx_set_preset(txrx, preset_name, frequency, NULL, 0); + + if(txrx->transmitter && subghz_protocol_somfy_telis_create_data( + subghz_transmitter_get_protocol_instance(txrx->transmitter), + txrx->fff_data, + serial, + btn, + cnt, + txrx->preset)) { + res = true; + } + + subghz_transmitter_free(txrx->transmitter); + + return res; +} + +bool subghz_txrx_gen_secplus_v2_protocol( + SubGhzTxRx* instance, + const char* name_preset, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint32_t cnt) { + furi_assert(instance); + + bool ret = false; + instance->transmitter = + subghz_transmitter_alloc_init(instance->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME); + subghz_txrx_set_preset(instance, name_preset, frequency, NULL, 0); + if(instance->transmitter) { + subghz_protocol_secplus_v2_create_data( + subghz_transmitter_get_protocol_instance(instance->transmitter), + instance->fff_data, + serial, + btn, + cnt, + instance->preset); + ret = true; + } + return ret; +} + +bool subghz_txrx_gen_secplus_v1_protocol( + SubGhzTxRx* instance, + const char* name_preset, + uint32_t frequency) { + furi_assert(instance); + + bool ret = false; + uint32_t serial = (uint32_t)rand(); + while(!subghz_protocol_secplus_v1_check_fixed(serial)) { + serial = (uint32_t)rand(); + } + if(subghz_txrx_gen_data_protocol( + instance, + name_preset, + frequency, + SUBGHZ_PROTOCOL_SECPLUS_V1_NAME, + (uint64_t)serial << 32 | 0xE6000000, + 42)) { + ret = true; + } + return ret; +} \ No newline at end of file diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h new file mode 100644 index 000000000..a5fa2a802 --- /dev/null +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h @@ -0,0 +1,141 @@ +#pragma once +#include "subghz_types.h" +#include "subghz_txrx.h" + +/** + * Generate data for protocol + * + * @param instance Pointer to a SubGhzTxRx + * @param preset_name Name of preset + * @param frequency Frequency in Hz + * @param protocol_name Name of protocol + * @param key Key + * @param bit Bit + * @return bool True if success + */ +bool subghz_txrx_gen_data_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + const char* protocol_name, + uint64_t key, + uint32_t bit); + +/** + * Generate data for protocol and te + * + * @param instance Pointer to a SubGhzTxRx + * @param preset_name Name of preset + * @param frequency Frequency in Hz + * @param protocol_name Name of protocol + * @param key Key + * @param bit Bit + * @param te Te + * @return bool True if success + */ +bool subghz_txrx_gen_data_protocol_and_te( + SubGhzTxRx* instance, + const char* preset_name, + uint32_t frequency, + const char* protocol_name, + uint64_t key, + uint32_t bit, + uint32_t te); + +/** + * Generate data Keeloq protocol + * + * @param instance Pointer to a SubGhzTxRx + * @param preset_name Name of preset + * @param frequency Frequency in Hz + * @param serial Serial number + * @param btn Button + * @param cnt Counter + * @param manufacture_name Name of Keeloq sysmem + * @return bool True if success + */ +bool subghz_txrx_gen_keeloq_protocol( + SubGhzTxRx* instance, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt, + const char* manufacture_name); + +bool subghz_txrx_gen_keeloq_bft_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt, + uint32_t seed, + const char* manufacture_name); + +bool subghz_txrx_gen_nice_flor_s_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt, + bool nice_one); + +bool subghz_txrx_gen_faac_slh_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt, + uint32_t seed, + const char* manufacture_name); + +bool subghz_txrx_gen_alutech_at_4n_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt); + +bool subghz_txrx_gen_somfy_telis_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt); + +/** + * Generate data SecPlus v2 protocol + * + * @param instance Pointer to a SubGhzTxRx + * @param name_preset Name of preset + * @param frequency Frequency in Hz + * @param serial Serial number + * @param btn Button + * @param cnt Counter + * @return bool True if success + */ +bool subghz_txrx_gen_secplus_v2_protocol( + SubGhzTxRx* instance, + const char* name_preset, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint32_t cnt); + +/** + * Generate data SecPlus v1 protocol + * + * @param instance Pointer to a SubGhzTxRx + * @param name_preset Name of preset + * @param frequency Frequency in Hz + * @return bool True if success + */ +bool subghz_txrx_gen_secplus_v1_protocol( + SubGhzTxRx* instance, + const char* name_preset, + uint32_t frequency); \ No newline at end of file diff --git a/applications/main/subghz/helpers/subghz_txrx_i.h b/applications/main/subghz/helpers/subghz_txrx_i.h new file mode 100644 index 000000000..680d27158 --- /dev/null +++ b/applications/main/subghz/helpers/subghz_txrx_i.h @@ -0,0 +1,29 @@ + +#pragma once +#include "subghz_txrx.h" + +struct SubGhzTxRx { + SubGhzWorker* worker; + + SubGhzEnvironment* environment; + SubGhzReceiver* receiver; + SubGhzTransmitter* transmitter; + SubGhzProtocolDecoderBase* decoder_result; + FlipperFormat* fff_data; + + SubGhzRadioPreset* preset; + SubGhzSetting* setting; + + uint8_t hopper_timeout; + uint8_t hopper_idx_frequency; + bool is_database_loaded; + SubGhzHopperState hopper_state; + + SubGhzTxRxState txrx_state; + SubGhzSpeakerState speaker_state; + + SubGhzTxRxNeedSaveCallback need_save_callback; + void* need_save_context; + + bool debug_pin_state; +}; \ No newline at end of file diff --git a/applications/main/subghz/helpers/subghz_types.h b/applications/main/subghz/helpers/subghz_types.h index 3c5982427..700049237 100644 --- a/applications/main/subghz/helpers/subghz_types.h +++ b/applications/main/subghz/helpers/subghz_types.h @@ -80,6 +80,13 @@ typedef enum { SubGhzViewIdTestPacket, } SubGhzViewId; +/** SubGhz load type file */ +typedef enum { + SubGhzLoadTypeFileNoLoad, + SubGhzLoadTypeFileKey, + SubGhzLoadTypeFileRaw, +} SubGhzLoadTypeFile; + typedef enum { SubGhzViewReceiverModeLive, SubGhzViewReceiverModeFile, diff --git a/applications/main/subghz/scenes/subghz_scene_decode_raw.c b/applications/main/subghz/scenes/subghz_scene_decode_raw.c index b9f2d236b..54c729cc3 100644 --- a/applications/main/subghz/scenes/subghz_scene_decode_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_decode_raw.c @@ -7,29 +7,15 @@ #define TAG "SubGhzDecodeRaw" #define SAMPLES_TO_READ_PER_TICK 400 -// TODO: -// [X] Remember RAW file after decoding -// [X] Decode in tick events instead of on_enter -// [X] Make "Config" label optional in subghz_view_receiver_draw (../views/receiver.c) -// [X] Make "Scanning..." label optional in subghz_view_receiver_draw (../views/receiver.c) -// [X] Add Decoding logo -// [ ] Design nicer Decoding logo -// [X] Check progress in stream_buffer, instead of raw stream -// [X] Blink led while decoding -// [X] Stop rx blink (blue, fast) on history item view -// [X] Don't reparse file on back -// [X] Fix: RX animation+LED returning from decoded detail view -// [X] Find good value for SAMPLES_TO_READ_PER_TICK -// [X] Fix: read errors (slow flash) after aborting decode read - static void subghz_scene_receiver_update_statusbar(void* context) { SubGhz* subghz = context; FuriString* history_stat_str = furi_string_alloc(); - if(!subghz_history_get_text_space_left(subghz->txrx->history, history_stat_str)) { + if(!subghz_history_get_text_space_left(subghz->history, history_stat_str)) { FuriString* frequency_str = furi_string_alloc(); FuriString* modulation_str = furi_string_alloc(); - subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + subghz_txrx_get_frequency_and_modulation( + subghz->txrx, frequency_str, modulation_str, false); subghz_view_receiver_add_data_statusbar( subghz->subghz_receiver, @@ -60,21 +46,22 @@ static void subghz_scene_add_to_history_callback( SubGhz* subghz = context; FuriString* item_name = furi_string_alloc(); FuriString* item_time = furi_string_alloc(); - uint16_t idx = subghz_history_get_item(subghz->txrx->history); + uint16_t idx = subghz_history_get_item(subghz->history); + SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); - if(subghz_history_add_to_history(subghz->txrx->history, decoder_base, subghz->txrx->preset)) { + if(subghz_history_add_to_history(subghz->history, decoder_base, &preset)) { furi_string_reset(item_name); furi_string_reset(item_time); subghz->state_notifications = SubGhzNotificationStateRxDone; - subghz_history_get_text_item_menu(subghz->txrx->history, item_name, idx); - subghz_history_get_time_item_menu(subghz->txrx->history, item_time, idx); + subghz_history_get_text_item_menu(subghz->history, item_name, idx); + subghz_history_get_time_item_menu(subghz->history, item_time, idx); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, furi_string_get_cstr(item_name), furi_string_get_cstr(item_time), - subghz_history_get_type_protocol(subghz->txrx->history, idx)); + subghz_history_get_type_protocol(subghz->history, idx)); subghz_scene_receiver_update_statusbar(subghz); } @@ -87,12 +74,13 @@ bool subghz_scene_decode_raw_start(SubGhz* subghz) { FuriString* file_name = furi_string_alloc(); bool success = false; do { - if(!flipper_format_rewind(subghz->txrx->fff_data)) { + if(!flipper_format_rewind(subghz_txrx_get_fff_data(subghz->txrx))) { FURI_LOG_E(TAG, "Rewind error"); break; } - if(!flipper_format_read_string(subghz->txrx->fff_data, "File_name", file_name)) { + if(!flipper_format_read_string( + subghz_txrx_get_fff_data(subghz->txrx), "File_name", file_name)) { FURI_LOG_E(TAG, "Missing File_name"); break; } @@ -123,14 +111,14 @@ bool subghz_scene_decode_raw_start(SubGhz* subghz) { bool subghz_scene_decode_raw_next(SubGhz* subghz) { LevelDuration level_duration; - + SubGhzReceiver* receiver = subghz_txrx_get_receiver(subghz->txrx); for(uint32_t read = SAMPLES_TO_READ_PER_TICK; read > 0; --read) { level_duration = subghz_file_encoder_worker_get_level_duration(subghz->decode_raw_file_worker_encoder); if(!level_duration_is_reset(level_duration)) { bool level = level_duration_get_level(level_duration); uint32_t duration = level_duration_get_duration(level_duration); - subghz_receiver_decode(subghz->txrx->receiver, level, duration); + subghz_receiver_decode(receiver, level, duration); } else { subghz->decode_raw_state = SubGhzDecodeRawStateLoaded; subghz->state_notifications = SubGhzNotificationStateIDLE; @@ -159,19 +147,17 @@ void subghz_scene_decode_raw_on_enter(void* context) { FuriString* item_name = furi_string_alloc(); FuriString* item_time = furi_string_alloc(); - subghz_view_receiver_set_lock(subghz->subghz_receiver, subghz->lock); subghz_view_receiver_set_mode(subghz->subghz_receiver, SubGhzViewReceiverModeFile); subghz_view_receiver_set_callback( subghz->subghz_receiver, subghz_scene_decode_raw_callback, subghz); - subghz_receiver_set_rx_callback( - subghz->txrx->receiver, subghz_scene_add_to_history_callback, subghz); + subghz_txrx_set_rx_calback(subghz->txrx, subghz_scene_add_to_history_callback, subghz); - subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable); + subghz_txrx_receiver_set_filter(subghz->txrx, SubGhzProtocolFlag_Decodable); if(subghz->decode_raw_state == SubGhzDecodeRawStateStart) { //Decode RAW to history - subghz_history_reset(subghz->txrx->history); + subghz_history_reset(subghz->history); if(subghz_scene_decode_raw_start(subghz)) { subghz->decode_raw_state = SubGhzDecodeRawStateLoading; subghz->state_notifications = SubGhzNotificationStateRx; @@ -179,20 +165,20 @@ void subghz_scene_decode_raw_on_enter(void* context) { } else { //Load history to receiver subghz_view_receiver_exit(subghz->subghz_receiver); - for(uint8_t i = 0; i < subghz_history_get_item(subghz->txrx->history); i++) { + for(uint8_t i = 0; i < subghz_history_get_item(subghz->history); i++) { furi_string_reset(item_name); furi_string_reset(item_time); - subghz_history_get_text_item_menu(subghz->txrx->history, item_name, i); - subghz_history_get_time_item_menu(subghz->txrx->history, item_time, i); + subghz_history_get_text_item_menu(subghz->history, item_name, i); + subghz_history_get_time_item_menu(subghz->history, item_time, i); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, furi_string_get_cstr(item_name), furi_string_get_cstr(item_time), - subghz_history_get_type_protocol(subghz->txrx->history, i)); + subghz_history_get_type_protocol(subghz->history, i)); } furi_string_free(item_name); furi_string_free(item_time); - subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); + subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->idx_menu_chosen); } subghz_scene_receiver_update_statusbar(subghz); @@ -207,11 +193,11 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) { switch(event.event) { case SubGhzCustomEventViewReceiverBack: subghz->decode_raw_state = SubGhzDecodeRawStateStart; - subghz->txrx->idx_menu_chosen = 0; + subghz->idx_menu_chosen = 0; subghz->in_decoder_scene = false; subghz->in_decoder_scene_skip = false; - subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz); + subghz_txrx_set_rx_calback(subghz->txrx, NULL, subghz); if(subghz_file_encoder_worker_is_running(subghz->decode_raw_file_worker_encoder)) { subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder); @@ -226,8 +212,7 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) { consumed = true; break; case SubGhzCustomEventViewReceiverOK: - subghz->txrx->idx_menu_chosen = - subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + subghz->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); subghz->state_notifications = SubGhzNotificationStateIDLE; subghz->in_decoder_scene = true; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo); @@ -241,10 +226,6 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) { notification_message(subghz->notifications, &sequence_display_backlight_off); consumed = true; break; - case SubGhzCustomEventViewReceiverUnlock: - subghz->lock = SubGhzLockOff; - consumed = true; - break; default: break; } diff --git a/applications/main/subghz/scenes/subghz_scene_delete.c b/applications/main/subghz/scenes/subghz_scene_delete.c index 4cad14bbf..3fc4be069 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete.c +++ b/applications/main/subghz/scenes/subghz_scene_delete.c @@ -15,7 +15,7 @@ void subghz_scene_delete_on_enter(void* context) { FuriString* modulation_str = furi_string_alloc(); FuriString* text = furi_string_alloc(); - subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, modulation_str, false); widget_add_string_element( subghz->widget, 78, @@ -33,7 +33,7 @@ void subghz_scene_delete_on_enter(void* context) { AlignTop, FontSecondary, furi_string_get_cstr(modulation_str)); - subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, text); + subghz_protocol_decoder_base_get_string(subghz_txrx_get_decoder(subghz->txrx), text); widget_add_string_multiline_element( subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(text)); diff --git a/applications/main/subghz/scenes/subghz_scene_delete_raw.c b/applications/main/subghz/scenes/subghz_scene_delete_raw.c index ee7983dfd..ada0f4c5c 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_delete_raw.c @@ -30,7 +30,7 @@ void subghz_scene_delete_raw_on_enter(void* context) { widget_add_string_element( subghz->widget, 38, 25, AlignLeft, AlignTop, FontSecondary, "RAW signal"); - subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, modulation_str, false); widget_add_string_element( subghz->widget, 35, diff --git a/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c b/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c index b6b9e18a7..9daa42eaa 100644 --- a/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c @@ -62,7 +62,7 @@ static void subghz_scene_receiver_config_set_debug_pin(VariableItem* item) { variable_item_set_current_value_text(item, debug_pin_text[index]); - subghz->txrx->debug_pin_state = index == 1; + subghz_txrx_set_debug_pin_state(subghz->txrx, index == 1); } static void subghz_scene_receiver_config_set_debug_counter(VariableItem* item) { @@ -163,7 +163,7 @@ void subghz_scene_ext_module_settings_on_enter(void* context) { DEBUG_P_COUNT, subghz_scene_receiver_config_set_debug_pin, subghz); - value_index_dpin = subghz->txrx->debug_pin_state; + value_index_dpin = subghz_txrx_get_debug_pin_state(subghz->txrx); variable_item_set_current_value_index(item, value_index_dpin); variable_item_set_current_value_text(item, debug_pin_text[value_index_dpin]); variable_item_set_locked( diff --git a/applications/main/subghz/scenes/subghz_scene_need_saving.c b/applications/main/subghz/scenes/subghz_scene_need_saving.c index 5c6b9cc39..8259b6e82 100644 --- a/applications/main/subghz/scenes/subghz_scene_need_saving.c +++ b/applications/main/subghz/scenes/subghz_scene_need_saving.c @@ -37,22 +37,24 @@ void subghz_scene_need_saving_on_enter(void* context) { bool subghz_scene_need_saving_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeBack) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateBack); scene_manager_previous_scene(subghz->scene_manager); return true; } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneStay) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateBack); scene_manager_previous_scene(subghz->scene_manager); return true; } else if(event.event == SubGhzCustomEventSceneExit) { - if(subghz->txrx->rx_key_state == SubGhzRxKeyStateExit) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; - subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0); + SubGhzRxKeyState state = subghz_rx_key_state_get(subghz); + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); + + if(state == SubGhzRxKeyStateExit) { + subghz_txrx_set_preset( + subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0); scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); } else { - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; scene_manager_previous_scene(subghz->scene_manager); } diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index e3eb5bdd1..92fcfe125 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -7,19 +7,19 @@ #define RAW_FILE_NAME "RAW_" #define TAG "SubGhzSceneReadRAW" -#define RAW_THRESHOLD_RSSI_LOW_COUNT 10 bool subghz_scene_read_raw_update_filename(SubGhz* subghz) { bool ret = false; //set the path to read the file FuriString* temp_str = furi_string_alloc(); do { - if(!flipper_format_rewind(subghz->txrx->fff_data)) { + FlipperFormat* fff_data = subghz_txrx_get_fff_data(subghz->txrx); + if(!flipper_format_rewind(fff_data)) { FURI_LOG_E(TAG, "Rewind error"); break; } - if(!flipper_format_read_string(subghz->txrx->fff_data, "File_name", temp_str)) { + if(!flipper_format_read_string(fff_data, "File_name", temp_str)) { FURI_LOG_E(TAG, "Missing File_name"); break; } @@ -41,10 +41,9 @@ static void subghz_scene_read_raw_update_statusbar(void* context) { FuriString* modulation_str = furi_string_alloc(); #ifdef SUBGHZ_EXT_PRESET_NAME - subghz_get_frequency_modulation(subghz, frequency_str, NULL); - furi_string_printf(modulation_str, "%s", furi_string_get_cstr(subghz->txrx->preset->name)); + subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, modulation_str, true); #else - subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, modulation_str, false); #endif subghz_read_raw_add_data_statusbar( subghz->subghz_read_raw, @@ -72,10 +71,11 @@ void subghz_scene_read_raw_on_enter(void* context) { SubGhz* subghz = context; FuriString* file_name = furi_string_alloc(); - switch(subghz->txrx->rx_key_state) { + float threshold_rssi = subghz_threshold_rssi_get(subghz->threshold_rssi); + switch(subghz_rx_key_state_get(subghz)) { case SubGhzRxKeyStateBack: subghz_read_raw_set_status( - subghz->subghz_read_raw, SubGhzReadRAWStatusIDLE, "", subghz->txrx->raw_threshold_rssi); + subghz->subghz_read_raw, SubGhzReadRAWStatusIDLE, "", threshold_rssi); break; case SubGhzRxKeyStateRAWLoad: path_extract_filename(subghz->file_path, file_name, true); @@ -83,8 +83,7 @@ void subghz_scene_read_raw_on_enter(void* context) { subghz->subghz_read_raw, SubGhzReadRAWStatusLoadKeyTX, furi_string_get_cstr(file_name), - subghz->txrx->raw_threshold_rssi); - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + threshold_rssi); break; case SubGhzRxKeyStateRAWSave: path_extract_filename(subghz->file_path, file_name, true); @@ -92,30 +91,27 @@ void subghz_scene_read_raw_on_enter(void* context) { subghz->subghz_read_raw, SubGhzReadRAWStatusSaveKey, furi_string_get_cstr(file_name), - subghz->txrx->raw_threshold_rssi); - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + threshold_rssi); break; default: subghz_read_raw_set_status( - subghz->subghz_read_raw, - SubGhzReadRAWStatusStart, - "", - subghz->txrx->raw_threshold_rssi); - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + subghz->subghz_read_raw, SubGhzReadRAWStatusStart, "", threshold_rssi); break; } + + if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateBack) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); + } furi_string_free(file_name); subghz_scene_read_raw_update_statusbar(subghz); //set callback view raw subghz_read_raw_set_callback(subghz->subghz_read_raw, subghz_scene_read_raw_callback, subghz); - subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name( - subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME); - furi_assert(subghz->txrx->decoder_result); + furi_check(subghz_txrx_load_decoder_by_name_protocol(subghz->txrx, SUBGHZ_PROTOCOL_RAW_NAME)); //set filter RAW feed - subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_RAW); + subghz_txrx_receiver_set_filter(subghz->txrx, SubGhzProtocolFlag_RAW); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReadRAW); // Start sending immediately with favorites @@ -135,39 +131,28 @@ void subghz_scene_read_raw_on_enter(void* context) { bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; bool consumed = false; + SubGhzProtocolDecoderRAW* decoder_raw = + (SubGhzProtocolDecoderRAW*)subghz_txrx_get_decoder(subghz->txrx); if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { case SubGhzCustomEventViewReadRAWBack: - //Stop TX - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_tx_stop(subghz); - subghz_sleep(subghz); - } - //Stop RX - if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz); - subghz_sleep(subghz); - } + + subghz_txrx_stop(subghz->txrx); //Stop save file - subghz_protocol_raw_save_to_file_stop( - (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result); + subghz_protocol_raw_save_to_file_stop(decoder_raw); subghz->state_notifications = SubGhzNotificationStateIDLE; //needed save? - if((subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) || - (subghz->txrx->rx_key_state == SubGhzRxKeyStateBack)) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; + if((subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateAddKey) || + (subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateBack)) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateExit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { //Restore default setting if(subghz->raw_send_only) { - subghz_preset_init( - subghz, - "AM650", - subghz_setting_get_default_frequency(subghz->setting), - NULL, - 0); + subghz_set_default_preset(subghz); } else { - subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0); + subghz_txrx_set_preset( + subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0); } if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneSaved)) { @@ -182,16 +167,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { break; case SubGhzCustomEventViewReadRAWTXRXStop: - //Stop TX - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_tx_stop(subghz); - subghz_sleep(subghz); - } - //Stop RX - if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz); - subghz_sleep(subghz); - } + subghz_txrx_stop(subghz->txrx); subghz->state_notifications = SubGhzNotificationStateIDLE; consumed = true; break; @@ -204,13 +180,13 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { break; case SubGhzCustomEventViewReadRAWErase: - if(subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) { + if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateAddKey) { if(subghz_scene_read_raw_update_filename(subghz)) { furi_string_set(subghz->file_path_tmp, subghz->file_path); subghz_delete_file(subghz); } } - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); notification_message(subghz->notifications, &sequence_reset_rgb); consumed = true; break; @@ -220,7 +196,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { if(subghz_scene_read_raw_update_filename(subghz)) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSet); - subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateRAWLoad); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneMoreRAW); consumed = true; } else { @@ -240,33 +216,22 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { if(subghz_file_available(subghz) && subghz_scene_read_raw_update_filename(subghz)) { //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, subghz->txrx->fff_data)) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; - subghz_read_raw_set_status( - subghz->subghz_read_raw, - SubGhzReadRAWStatusIDLE, - "", - subghz->txrx->raw_threshold_rssi); - } else { - if(scene_manager_has_previous_scene( - subghz->scene_manager, SubGhzSceneSaved) || - !scene_manager_has_previous_scene( - subghz->scene_manager, SubGhzSceneStart)) { - DOLPHIN_DEED(DolphinDeedSubGhzSend); - } - // set callback end tx - subghz_protocol_raw_file_encoder_worker_set_callback_end( - (SubGhzProtocolEncoderRAW*)subghz_transmitter_get_protocol_instance( - subghz->txrx->transmitter), - subghz_scene_read_raw_callback_end_tx, - subghz); - subghz->state_notifications = SubGhzNotificationStateTx; + if(!subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx))) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateBack); + subghz_read_raw_set_status( + subghz->subghz_read_raw, + SubGhzReadRAWStatusIDLE, + "", + subghz_threshold_rssi_get(subghz->threshold_rssi)); + } else { + if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneSaved) || + !scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneStart)) { + DOLPHIN_DEED(DolphinDeedSubGhzSend); } + // set callback end tx + subghz_txrx_set_raw_file_encoder_worker_callback_end( + subghz->txrx, subghz_scene_read_raw_callback_end_tx, subghz); + subghz->state_notifications = SubGhzNotificationStateTx; } } else { if(!scene_manager_search_and_switch_to_previous_scene( @@ -280,11 +245,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReadRAWSendStop: subghz->state_notifications = SubGhzNotificationStateIDLE; - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_speaker_unmute(subghz); - subghz_tx_stop(subghz); - subghz_sleep(subghz); - } + subghz_txrx_stop(subghz->txrx); subghz_read_raw_stop_send(subghz->subghz_read_raw); // Exit / stop with favorites @@ -297,22 +258,16 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { break; case SubGhzCustomEventViewReadRAWIDLE: - if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz); - subghz_sleep(subghz); - } + subghz_txrx_stop(subghz->txrx); + size_t spl_count = subghz_protocol_raw_get_sample_write(decoder_raw); - size_t spl_count = subghz_protocol_raw_get_sample_write( - (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result); - - subghz_protocol_raw_save_to_file_stop( - (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result); + subghz_protocol_raw_save_to_file_stop(decoder_raw); FuriString* temp_str = furi_string_alloc(); furi_string_printf( temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, RAW_FILE_NAME, SUBGHZ_APP_EXTENSION); subghz_protocol_raw_gen_fff_data( - subghz->txrx->fff_data, furi_string_get_cstr(temp_str)); + subghz_txrx_get_fff_data(subghz->txrx), furi_string_get_cstr(temp_str)); furi_string_free(temp_str); if(spl_count > 0) { @@ -322,32 +277,21 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { } subghz->state_notifications = SubGhzNotificationStateIDLE; - subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateAddKey); consumed = true; break; case SubGhzCustomEventViewReadRAWREC: - if(subghz->txrx->rx_key_state != SubGhzRxKeyStateIDLE) { + if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateIDLE) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { - subghz->txrx->raw_threshold_rssi_low_count = RAW_THRESHOLD_RSSI_LOW_COUNT; - if(subghz_protocol_raw_save_to_file_init( - (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result, - RAW_FILE_NAME, - subghz->txrx->preset)) { + SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); + if(subghz_protocol_raw_save_to_file_init(decoder_raw, RAW_FILE_NAME, &preset)) { DOLPHIN_DEED(DolphinDeedSubGhzRawRec); - if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || - (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { - subghz_begin( - subghz, - subghz_setting_get_preset_data_by_name( - subghz->setting, - furi_string_get_cstr(subghz->txrx->preset->name))); - subghz_rx(subghz, subghz->txrx->preset->frequency); - } + subghz_txrx_rx_start(subghz->txrx); subghz->state_notifications = SubGhzNotificationStateRx; - subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateAddKey); } else { furi_string_set(subghz->error_str, "Function requires\nan SD card."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); @@ -360,7 +304,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { if(subghz_file_available(subghz) && subghz_scene_read_raw_update_filename(subghz)) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSetRAW); - subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateBack); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); } else { if(!scene_manager_search_and_switch_to_previous_scene( @@ -379,41 +323,15 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { switch(subghz->state_notifications) { case SubGhzNotificationStateRx: notification_message(subghz->notifications, &sequence_blink_cyan_10); + subghz_read_raw_update_sample_write( - subghz->subghz_read_raw, - subghz_protocol_raw_get_sample_write( - (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result)); - - float rssi = furi_hal_subghz_get_rssi(); - - if(float_is_equal(subghz->txrx->raw_threshold_rssi, SUBGHZ_RAW_THRESHOLD_MIN)) { - subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, rssi, true); - subghz_protocol_raw_save_to_file_pause( - (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result, false); - } else { - if(rssi < subghz->txrx->raw_threshold_rssi) { - subghz->txrx->raw_threshold_rssi_low_count++; - if(subghz->txrx->raw_threshold_rssi_low_count > RAW_THRESHOLD_RSSI_LOW_COUNT) { - subghz->txrx->raw_threshold_rssi_low_count = RAW_THRESHOLD_RSSI_LOW_COUNT; - } - subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, rssi, false); - } else { - subghz->txrx->raw_threshold_rssi_low_count = 0; - } - - if(subghz->txrx->raw_threshold_rssi_low_count == RAW_THRESHOLD_RSSI_LOW_COUNT) { - subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, rssi, false); - subghz_protocol_raw_save_to_file_pause( - (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result, true); - subghz_speaker_mute(subghz); - } else { - subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, rssi, true); - subghz_protocol_raw_save_to_file_pause( - (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result, false); - subghz_speaker_unmute(subghz); - } - } + subghz->subghz_read_raw, subghz_protocol_raw_get_sample_write(decoder_raw)); + SubGhzThresholdRssiData ret_rssi = + subghz_threshold_get_rssi_data(subghz->threshold_rssi); + subghz_read_raw_add_data_rssi( + subghz->subghz_read_raw, ret_rssi.rssi, ret_rssi.is_above); + subghz_protocol_raw_save_to_file_pause(decoder_raw, !ret_rssi.is_above); break; case SubGhzNotificationStateTx: notification_message(subghz->notifications, &sequence_blink_magenta_10); @@ -430,13 +348,10 @@ void subghz_scene_read_raw_on_exit(void* context) { SubGhz* subghz = context; //Stop CC1101 - if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz); - subghz_sleep(subghz); - } + subghz_txrx_stop(subghz->txrx); subghz->state_notifications = SubGhzNotificationStateIDLE; notification_message(subghz->notifications, &sequence_reset_rgb); //filter restoration - subghz_receiver_set_filter(subghz->txrx->receiver, subghz->txrx->filter); + subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); } diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index fd8d9b70e..9987449cd 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -40,23 +40,28 @@ const NotificationSequence subghz_sequence_rx_locked = { static void subghz_scene_receiver_update_statusbar(void* context) { SubGhz* subghz = context; FuriString* history_stat_str = furi_string_alloc(); - if(!subghz_history_get_text_space_left(subghz->txrx->history, history_stat_str)) { + if(!subghz_history_get_text_space_left(subghz->history, history_stat_str)) { FuriString* frequency_str = furi_string_alloc(); FuriString* modulation_str = furi_string_alloc(); #ifdef SUBGHZ_EXT_PRESET_NAME - if(subghz_history_get_last_index(subghz->txrx->history) > 0) { - subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + if(subghz_history_get_last_index(subghz->history) > 0) { + subghz_txrx_get_frequency_and_modulation( + subghz->txrx, frequency_str, modulation_str, false); } else { - subghz_get_frequency_modulation(subghz, frequency_str, NULL); + FuriString* temp_str = furi_string_alloc(); + + subghz_txrx_get_frequency_and_modulation(subghz->txrx, frequency_str, temp_str, true); furi_string_printf( modulation_str, "%s Mod: %s", furi_hal_subghz_get_radio_type() ? "Ext" : "Int", - furi_string_get_cstr(subghz->txrx->preset->name)); + furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); } #else - subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + subghz_txrx_get_frequency_and_modulation( + subghz->txrx, frequency_str, modulation_str, false); #endif subghz_view_receiver_add_data_statusbar( @@ -86,127 +91,105 @@ static void subghz_scene_add_to_history_callback( SubGhzProtocolDecoderBase* decoder_base, void* context) { furi_assert(context); - SubGhz* subghz = context; - + SubGhzHistory* history = subghz->history; FuriString* item_name = furi_string_alloc(); FuriString* item_time = furi_string_alloc(); - uint16_t idx = subghz_history_get_item(subghz->txrx->history); + uint16_t idx = subghz_history_get_item(history); - if(subghz_history_add_to_history(subghz->txrx->history, decoder_base, subghz->txrx->preset)) { + SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); + if(subghz_history_add_to_history(history, decoder_base, &preset)) { furi_string_reset(item_name); furi_string_reset(item_time); subghz->state_notifications = SubGhzNotificationStateRxDone; - subghz_history_get_text_item_menu(subghz->txrx->history, item_name, idx); - subghz_history_get_time_item_menu(subghz->txrx->history, item_time, idx); + subghz_history_get_text_item_menu(history, item_name, idx); + subghz_history_get_time_item_menu(history, item_time, idx); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, furi_string_get_cstr(item_name), furi_string_get_cstr(item_time), - subghz_history_get_type_protocol(subghz->txrx->history, idx)); + subghz_history_get_type_protocol(history, idx)); subghz_scene_receiver_update_statusbar(subghz); } subghz_receiver_reset(receiver); furi_string_free(item_name); furi_string_free(item_time); - subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateAddKey); } void subghz_scene_receiver_on_enter(void* context) { SubGhz* subghz = context; + SubGhzHistory* history = subghz->history; FuriString* item_name = furi_string_alloc(); FuriString* item_time = furi_string_alloc(); - if(subghz->txrx->rx_key_state == SubGhzRxKeyStateIDLE) { - subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0); - subghz_history_reset(subghz->txrx->history); - subghz->txrx->rx_key_state = SubGhzRxKeyStateStart; + if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateIDLE) { + subghz_txrx_set_preset(subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0); + subghz_history_reset(history); + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); } - subghz_view_receiver_set_lock(subghz->subghz_receiver, subghz->lock); + subghz_view_receiver_set_lock(subghz->subghz_receiver, subghz_is_locked(subghz)); subghz_view_receiver_set_mode(subghz->subghz_receiver, SubGhzViewReceiverModeLive); //Load history to receiver subghz_view_receiver_exit(subghz->subghz_receiver); - for(uint8_t i = 0; i < subghz_history_get_item(subghz->txrx->history); i++) { + for(uint8_t i = 0; i < subghz_history_get_item(history); i++) { furi_string_reset(item_name); furi_string_reset(item_time); - subghz_history_get_text_item_menu(subghz->txrx->history, item_name, i); - subghz_history_get_time_item_menu(subghz->txrx->history, item_time, i); + subghz_history_get_text_item_menu(history, item_name, i); + subghz_history_get_time_item_menu(history, item_time, i); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, furi_string_get_cstr(item_name), furi_string_get_cstr(item_time), - subghz_history_get_type_protocol(subghz->txrx->history, i)); - subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; + subghz_history_get_type_protocol(history, i)); + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateAddKey); } furi_string_free(item_name); furi_string_free(item_time); subghz_scene_receiver_update_statusbar(subghz); subghz_view_receiver_set_callback( subghz->subghz_receiver, subghz_scene_receiver_callback, subghz); - subghz_receiver_set_rx_callback( - subghz->txrx->receiver, subghz_scene_add_to_history_callback, subghz); + subghz_txrx_set_rx_calback(subghz->txrx, subghz_scene_add_to_history_callback, subghz); // TODO: Replace with proper solution based on protocol flags, remove kostily and velosipedy from here // Needs to be done after subghz refactoring merge!!! - if(subghz->txrx->ignore_starline == true) { - SubGhzProtocolDecoderBase* protocoldecoderbase = NULL; - protocoldecoderbase = - subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, "Star Line"); - if(protocoldecoderbase) { + if(subghz->ignore_starline == true) { + if(subghz_txrx_load_decoder_by_name_protocol(subghz->txrx, "Star Line")) { subghz_protocol_decoder_base_set_decoder_callback( - protocoldecoderbase, NULL, subghz->txrx->receiver); + subghz_txrx_get_decoder(subghz->txrx), NULL, NULL); } } - if(subghz->txrx->ignore_auto_alarms == true) { - SubGhzProtocolDecoderBase* protocoldecoderbase = NULL; - protocoldecoderbase = - subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, "KIA Seed"); - if(protocoldecoderbase) { + if(subghz->ignore_auto_alarms == true) { + if(subghz_txrx_load_decoder_by_name_protocol(subghz->txrx, "KIA Seed")) { subghz_protocol_decoder_base_set_decoder_callback( - protocoldecoderbase, NULL, subghz->txrx->receiver); + subghz_txrx_get_decoder(subghz->txrx), NULL, NULL); } - protocoldecoderbase = NULL; - protocoldecoderbase = - subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, "Scher-Khan"); - if(protocoldecoderbase) { + + if(subghz_txrx_load_decoder_by_name_protocol(subghz->txrx, "Scher-Khan")) { subghz_protocol_decoder_base_set_decoder_callback( - protocoldecoderbase, NULL, subghz->txrx->receiver); + subghz_txrx_get_decoder(subghz->txrx), NULL, NULL); } } - if(subghz->txrx->ignore_magellan == true) { - SubGhzProtocolDecoderBase* protocoldecoderbase = NULL; - protocoldecoderbase = - subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, "Magellan"); - if(protocoldecoderbase) { + if(subghz->ignore_magellan == true) { + if(subghz_txrx_load_decoder_by_name_protocol(subghz->txrx, "Magellan")) { subghz_protocol_decoder_base_set_decoder_callback( - protocoldecoderbase, NULL, subghz->txrx->receiver); + subghz_txrx_get_decoder(subghz->txrx), NULL, NULL); } } subghz->state_notifications = SubGhzNotificationStateRx; - if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz); - } - if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || - (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { - subghz_begin( - subghz, - subghz_setting_get_preset_data_by_name( - subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name))); - subghz_rx(subghz, subghz->txrx->preset->frequency); - } - subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); + subghz_txrx_rx_start(subghz->txrx); + subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->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); + furi_check( + subghz_txrx_load_decoder_by_name_protocol(subghz->txrx, SUBGHZ_PROTOCOL_BIN_RAW_NAME)); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReceiver); } @@ -219,20 +202,18 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReceiverBack: // Stop CC1101 Rx subghz->state_notifications = SubGhzNotificationStateIDLE; - if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz); - subghz_sleep(subghz); - } - subghz->txrx->hopper_state = SubGhzHopperStateOFF; - subghz->txrx->idx_menu_chosen = 0; - subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz); + subghz_txrx_stop(subghz->txrx); + subghz_txrx_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF); + subghz->idx_menu_chosen = 0; + subghz_txrx_set_rx_calback(subghz->txrx, NULL, subghz); - if(subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; + if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateAddKey) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateExit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; - subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0); + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); + subghz_txrx_set_preset( + subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0); scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); } @@ -240,17 +221,15 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { break; case SubGhzCustomEventViewReceiverOK: // Show file info, scene: receiver_info - subghz->txrx->idx_menu_chosen = - subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + subghz->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo); DOLPHIN_DEED(DolphinDeedSubGhzReceiverInfo); consumed = true; break; case SubGhzCustomEventViewReceiverDeleteItem: - subghz->txrx->idx_menu_chosen = - subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + subghz->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); - subghz_history_delete_item(subghz->txrx->history, subghz->txrx->idx_menu_chosen); + subghz_history_delete_item(subghz->history, subghz->idx_menu_chosen); subghz_view_receiver_delete_element_callback(subghz->subghz_receiver); subghz_scene_receiver_update_statusbar(subghz); @@ -258,8 +237,7 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { break; case SubGhzCustomEventViewReceiverConfig: subghz->state_notifications = SubGhzNotificationStateIDLE; - subghz->txrx->idx_menu_chosen = - subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + subghz->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); scene_manager_set_scene_state( subghz->scene_manager, SubGhzViewIdReceiver, SubGhzCustomEventManagerSet); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); @@ -270,30 +248,31 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { consumed = true; break; case SubGhzCustomEventViewReceiverUnlock: - subghz->lock = SubGhzLockOff; + subghz_unlock(subghz); consumed = true; break; default: break; } } else if(event.type == SceneManagerEventTypeTick) { - if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { - subghz_hopper_update(subghz); + if(subghz_txrx_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF) { + subghz_txrx_hopper_update(subghz->txrx); subghz_scene_receiver_update_statusbar(subghz); } //get RSSI - float rssi = furi_hal_subghz_get_rssi(); - subghz_receiver_rssi(subghz->subghz_receiver, rssi); + SubGhzThresholdRssiData ret_rssi = subghz_threshold_get_rssi_data(subghz->threshold_rssi); + + subghz_receiver_rssi(subghz->subghz_receiver, ret_rssi.rssi); subghz_protocol_decoder_bin_raw_data_input_rssi( - (SubGhzProtocolDecoderBinRAW*)subghz->txrx->decoder_result, rssi); + (SubGhzProtocolDecoderBinRAW*)subghz_txrx_get_decoder(subghz->txrx), ret_rssi.rssi); switch(subghz->state_notifications) { case SubGhzNotificationStateRx: notification_message(subghz->notifications, &sequence_blink_cyan_10); break; case SubGhzNotificationStateRxDone: - if(subghz->lock != SubGhzLockOn) { + if(!subghz_is_locked(subghz)) { notification_message(subghz->notifications, &subghz_sequence_rx); } else { notification_message(subghz->notifications, &subghz_sequence_rx_locked); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index 68c5b4b7a..29d55c03a 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -92,13 +92,15 @@ const char* const magellan_text[MAGELLAN_COUNT] = { uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) { furi_assert(context); SubGhz* subghz = context; + SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); + uint8_t index = 0; - for(uint8_t i = 0; i < subghz_setting_get_frequency_count(subghz->setting); i++) { - if(value == subghz_setting_get_frequency(subghz->setting, i)) { + for(uint8_t i = 0; i < subghz_setting_get_frequency_count(setting); i++) { + if(value == subghz_setting_get_frequency(setting, i)) { index = i; break; } else { - index = subghz_setting_get_frequency_default_index(subghz->setting); + index = subghz_setting_get_frequency_default_index(setting); } } return index; @@ -108,12 +110,14 @@ uint8_t subghz_scene_receiver_config_next_preset(const char* preset_name, void* furi_assert(context); SubGhz* subghz = context; uint8_t index = 0; - for(uint8_t i = 0; i < subghz_setting_get_preset_count(subghz->setting); i++) { - if(!strcmp(subghz_setting_get_preset_name(subghz->setting, i), preset_name)) { + SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); + + for(uint8_t i = 0; i < subghz_setting_get_preset_count(setting); i++) { + if(!strcmp(subghz_setting_get_preset_name(setting, i), preset_name)) { index = i; break; } else { - // index = subghz_setting_get_frequency_default_index(subghz->setting); + // index = subghz_setting_get_frequency_default_index(setting); } } return index; @@ -142,74 +146,90 @@ uint8_t subghz_scene_receiver_config_hopper_value_index( static void subghz_scene_receiver_config_set_frequency(VariableItem* item) { SubGhz* subghz = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); + SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); - if(subghz->txrx->hopper_state == SubGhzHopperStateOFF) { + if(subghz_txrx_hopper_get_state(subghz->txrx) == SubGhzHopperStateOFF) { char text_buf[10] = {0}; + uint32_t frequency = subghz_setting_get_frequency(setting, index); + SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); + snprintf( text_buf, sizeof(text_buf), "%lu.%02lu", - subghz_setting_get_frequency(subghz->setting, index) / 1000000, - (subghz_setting_get_frequency(subghz->setting, index) % 1000000) / 10000); + frequency / 1000000, + (frequency % 1000000) / 10000); variable_item_set_current_value_text(item, text_buf); - subghz->txrx->preset->frequency = subghz_setting_get_frequency(subghz->setting, index); - subghz->last_settings->frequency = subghz->txrx->preset->frequency; - subghz_setting_set_default_frequency(subghz->setting, subghz->txrx->preset->frequency); + subghz_txrx_set_preset( + subghz->txrx, + furi_string_get_cstr(preset.name), + frequency, + preset.data, + preset.data_size); + + preset = subghz_txrx_get_preset(subghz->txrx); + + subghz->last_settings->frequency = preset.frequency; + subghz_setting_set_default_frequency(setting, preset.frequency); } else { variable_item_set_current_value_index( - item, subghz_setting_get_frequency_default_index(subghz->setting)); + item, subghz_setting_get_frequency_default_index(setting)); } } static void subghz_scene_receiver_config_set_preset(VariableItem* item) { SubGhz* subghz = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); - const char* preset_name = subghz_setting_get_preset_name(subghz->setting, index); + SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); + + const char* preset_name = subghz_setting_get_preset_name(setting, index); variable_item_set_current_value_text(item, preset_name); //subghz->last_settings->preset = index; - - subghz_preset_init( - subghz, + SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); + subghz_txrx_set_preset( + subghz->txrx, preset_name, - subghz->txrx->preset->frequency, - subghz_setting_get_preset_data(subghz->setting, index), - subghz_setting_get_preset_data_size(subghz->setting, index)); + preset.frequency, + subghz_setting_get_preset_data(setting, index), + subghz_setting_get_preset_data_size(setting, index)); } static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) { SubGhz* subghz = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); + SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); + VariableItem* frequency_item = (VariableItem*)scene_manager_get_scene_state( + subghz->scene_manager, SubGhzSceneReceiverConfig); variable_item_set_current_value_text(item, hopping_text[index]); if(hopping_value[index] == SubGhzHopperStateOFF) { char text_buf[10] = {0}; + uint32_t frequency = subghz_setting_get_default_frequency(setting); + SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); + snprintf( text_buf, sizeof(text_buf), "%lu.%02lu", - subghz_setting_get_default_frequency(subghz->setting) / 1000000, - (subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000); - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - subghz->scene_manager, SubGhzSceneReceiverConfig), - text_buf); - subghz->txrx->preset->frequency = subghz_setting_get_default_frequency(subghz->setting); + frequency / 1000000, + (frequency % 1000000) / 10000); + variable_item_set_current_value_text(frequency_item, text_buf); + + subghz_txrx_set_preset( + subghz->txrx, + furi_string_get_cstr(preset.name), + frequency, + preset.data, + preset.data_size); variable_item_set_current_value_index( - (VariableItem*)scene_manager_get_scene_state( - subghz->scene_manager, SubGhzSceneReceiverConfig), - subghz_setting_get_frequency_default_index(subghz->setting)); + frequency_item, subghz_setting_get_frequency_default_index(setting)); } else { - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - subghz->scene_manager, SubGhzSceneReceiverConfig), - " -----"); + variable_item_set_current_value_text(frequency_item, " -----"); variable_item_set_current_value_index( - (VariableItem*)scene_manager_get_scene_state( - subghz->scene_manager, SubGhzSceneReceiverConfig), - subghz_setting_get_frequency_default_index(subghz->setting)); + frequency_item, subghz_setting_get_frequency_default_index(setting)); } - subghz->txrx->hopper_state = hopping_value[index]; + subghz_txrx_hopper_set_state(subghz->txrx, hopping_value[index]); } static void subghz_scene_receiver_config_set_speaker(VariableItem* item) { @@ -217,7 +237,7 @@ static void subghz_scene_receiver_config_set_speaker(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, speaker_text[index]); - subghz->txrx->speaker_state = speaker_value[index]; + subghz_txrx_speaker_set_state(subghz->txrx, speaker_value[index]); } static void subghz_scene_receiver_config_set_bin_raw(VariableItem* item) { @@ -225,8 +245,8 @@ static void subghz_scene_receiver_config_set_bin_raw(VariableItem* 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); + subghz->filter = bin_raw_value[index]; + subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); } static void subghz_scene_receiver_config_set_raw_threshold_rssi(VariableItem* item) { @@ -234,7 +254,7 @@ static void subghz_scene_receiver_config_set_raw_threshold_rssi(VariableItem* it uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, raw_threshold_rssi_text[index]); - subghz->txrx->raw_threshold_rssi = raw_threshold_rssi_value[index]; + subghz_threshold_rssi_set(subghz->threshold_rssi, raw_threshold_rssi_value[index]); } static void subghz_scene_receiver_config_set_starline(VariableItem* item) { @@ -242,7 +262,7 @@ static void subghz_scene_receiver_config_set_starline(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, starline_text[index]); - subghz->txrx->ignore_starline = (index == 1); + subghz->ignore_starline = (index == 1); } static void subghz_scene_receiver_config_set_auto_alarms(VariableItem* item) { @@ -250,7 +270,7 @@ static void subghz_scene_receiver_config_set_auto_alarms(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, auto_alarms_text[index]); - subghz->txrx->ignore_auto_alarms = (index == 1); + subghz->ignore_auto_alarms = (index == 1); } static void subghz_scene_receiver_config_set_magellan(VariableItem* item) { @@ -258,7 +278,7 @@ static void subghz_scene_receiver_config_set_magellan(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, magellan_text[index]); - subghz->txrx->ignore_magellan = (index == 1); + subghz->ignore_magellan = (index == 1); } static void subghz_scene_receiver_config_var_list_enter_callback(void* context, uint32_t index) { @@ -274,38 +294,40 @@ void subghz_scene_receiver_config_on_enter(void* context) { SubGhz* subghz = context; VariableItem* item; uint8_t value_index; + SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); + SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); item = variable_item_list_add( subghz->variable_item_list, "Frequency:", - subghz_setting_get_frequency_count(subghz->setting), + subghz_setting_get_frequency_count(setting), subghz_scene_receiver_config_set_frequency, subghz); - value_index = - subghz_scene_receiver_config_next_frequency(subghz->txrx->preset->frequency, subghz); + value_index = subghz_scene_receiver_config_next_frequency(preset.frequency, subghz); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig, (uint32_t)item); variable_item_set_current_value_index(item, value_index); char text_buf[10] = {0}; + uint32_t frequency = subghz_setting_get_frequency(setting, value_index); snprintf( text_buf, sizeof(text_buf), "%lu.%02lu", - subghz_setting_get_frequency(subghz->setting, value_index) / 1000000, - (subghz_setting_get_frequency(subghz->setting, value_index) % 1000000) / 10000); + frequency / 1000000, + (frequency % 1000000) / 10000); variable_item_set_current_value_text(item, text_buf); item = variable_item_list_add( subghz->variable_item_list, "Modulation:", - subghz_setting_get_preset_count(subghz->setting), + subghz_setting_get_preset_count(setting), subghz_scene_receiver_config_set_preset, subghz); - value_index = subghz_scene_receiver_config_next_preset( - furi_string_get_cstr(subghz->txrx->preset->name), subghz); + value_index = + subghz_scene_receiver_config_next_preset(furi_string_get_cstr(preset.name), subghz); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text( - item, subghz_setting_get_preset_name(subghz->setting, value_index)); + item, subghz_setting_get_preset_name(setting, value_index)); if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerSet) { @@ -317,7 +339,7 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz_scene_receiver_config_set_hopping_running, subghz); value_index = subghz_scene_receiver_config_hopper_value_index( - subghz->txrx->hopper_state, hopping_value, HOPPING_COUNT, subghz); + subghz_txrx_hopper_get_state(subghz->txrx), hopping_value, HOPPING_COUNT, subghz); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, hopping_text[value_index]); } @@ -330,7 +352,7 @@ void subghz_scene_receiver_config_on_enter(void* context) { 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); + value_index = value_index_uint32(subghz->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]); } @@ -344,7 +366,7 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz_scene_receiver_config_set_starline, subghz); - value_index = subghz->txrx->ignore_starline; + value_index = subghz->ignore_starline; variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, starline_text[value_index]); @@ -355,7 +377,7 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz_scene_receiver_config_set_auto_alarms, subghz); - value_index = subghz->txrx->ignore_auto_alarms; + value_index = subghz->ignore_auto_alarms; variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, auto_alarms_text[value_index]); @@ -366,7 +388,7 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz_scene_receiver_config_set_magellan, subghz); - value_index = subghz->txrx->ignore_magellan; + value_index = subghz->ignore_magellan; variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, magellan_text[value_index]); } @@ -378,7 +400,8 @@ void subghz_scene_receiver_config_on_enter(void* context) { SPEAKER_COUNT, subghz_scene_receiver_config_set_speaker, subghz); - value_index = value_index_uint32(subghz->txrx->speaker_state, speaker_value, SPEAKER_COUNT); + value_index = value_index_uint32( + subghz_txrx_speaker_get_state(subghz->txrx), speaker_value, SPEAKER_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, speaker_text[value_index]); @@ -400,7 +423,9 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz_scene_receiver_config_set_raw_threshold_rssi, subghz); value_index = value_index_float( - subghz->txrx->raw_threshold_rssi, raw_threshold_rssi_value, RAW_THRESHOLD_RSSI_COUNT); + subghz_threshold_rssi_get(subghz->threshold_rssi), + raw_threshold_rssi_value, + RAW_THRESHOLD_RSSI_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, raw_threshold_rssi_text[value_index]); } @@ -413,7 +438,7 @@ bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent even if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneSettingLock) { - subghz->lock = SubGhzLockOn; + subghz_lock(subghz); scene_manager_previous_scene(subghz->scene_manager); consumed = true; } diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index a108132c0..370638931 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -23,20 +23,19 @@ void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, v static bool subghz_scene_receiver_info_update_parser(void* context) { SubGhz* subghz = context; - subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name( - subghz->txrx->receiver, - subghz_history_get_protocol_name(subghz->txrx->history, subghz->txrx->idx_menu_chosen)); - if(subghz->txrx->decoder_result) { - //todo we are trying to deserialize without checking for errors, since it is assumed that we just received this chignal + if(subghz_txrx_load_decoder_by_name_protocol( + subghz->txrx, + subghz_history_get_protocol_name(subghz->history, subghz->idx_menu_chosen))) { + //todo we are trying to deserialize without checking for errors, since it is assumed that we just received this signal subghz_protocol_decoder_base_deserialize( - subghz->txrx->decoder_result, - subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen)); + subghz_txrx_get_decoder(subghz->txrx), + subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen)); SubGhzRadioPreset* preset = - subghz_history_get_radio_preset(subghz->txrx->history, subghz->txrx->idx_menu_chosen); - subghz_preset_init( - subghz, + subghz_history_get_radio_preset(subghz->history, subghz->idx_menu_chosen); + subghz_txrx_set_preset( + subghz->txrx, furi_string_get_cstr(preset->name), preset->frequency, preset->data, @@ -53,7 +52,8 @@ void subghz_scene_receiver_info_draw_widget(SubGhz* subghz) { FuriString* modulation_str = furi_string_alloc(); FuriString* text = furi_string_alloc(); - subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + subghz_txrx_get_frequency_and_modulation( + subghz->txrx, frequency_str, modulation_str, false); widget_add_string_element( subghz->widget, 78, @@ -71,7 +71,7 @@ void subghz_scene_receiver_info_draw_widget(SubGhz* subghz) { AlignTop, FontSecondary, furi_string_get_cstr(modulation_str)); - subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, text); + subghz_protocol_decoder_base_get_string(subghz_txrx_get_decoder(subghz->txrx), text); widget_add_string_multiline_element( subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(text)); @@ -79,8 +79,7 @@ void subghz_scene_receiver_info_draw_widget(SubGhz* subghz) { furi_string_free(modulation_str); furi_string_free(text); - if((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Save) == - SubGhzProtocolFlag_Save) { + if(subghz_txrx_protocol_is_serializable(subghz->txrx)) { widget_add_button_element( subghz->widget, GuiButtonTypeRight, @@ -89,9 +88,7 @@ void subghz_scene_receiver_info_draw_widget(SubGhz* subghz) { subghz); } // Removed static check - if(((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Send) == - SubGhzProtocolFlag_Send) && - subghz->txrx->decoder_result->protocol->encoder->deserialize) { + if(subghz_txrx_protocol_is_transmittable(subghz->txrx, false)) { widget_add_button_element( subghz->widget, GuiButtonTypeCenter, @@ -121,40 +118,19 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneReceiverInfoTxStart) { - //CC1101 Stop RX -> Start TX - if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { - subghz->txrx->hopper_state = SubGhzHopperStatePause; - } - if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz); - } if(!subghz_scene_receiver_info_update_parser(subghz)) { return false; } - if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE || - subghz->txrx->txrx_state == SubGhzTxRxStateSleep) { - if(!subghz_tx_start( - subghz, - subghz_history_get_raw_data( - subghz->txrx->history, subghz->txrx->idx_menu_chosen))) { - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_tx_stop(subghz); - } - if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) { - subghz_begin( - subghz, - subghz_setting_get_preset_data_by_name( - subghz->setting, - furi_string_get_cstr(subghz->txrx->preset->name))); - subghz_rx(subghz, subghz->txrx->preset->frequency); - } - if(subghz->txrx->hopper_state == SubGhzHopperStatePause) { - subghz->txrx->hopper_state = SubGhzHopperStateRunning; - } - subghz->state_notifications = SubGhzNotificationStateRx; - } else { - subghz->state_notifications = SubGhzNotificationStateTx; - } + //CC1101 Stop RX -> Start TX + subghz_txrx_hopper_pause(subghz->txrx); + if(!subghz_tx_start( + subghz, + subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen))) { + subghz_txrx_rx_start(subghz->txrx); + subghz_txrx_hopper_unpause(subghz->txrx); + subghz->state_notifications = SubGhzNotificationStateRx; + } else { + subghz->state_notifications = SubGhzNotificationStateTx; } return true; } else if(event.event == SubGhzCustomEventSceneReceiverInfoTxStop) { @@ -164,37 +140,25 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) widget_reset(subghz->widget); subghz_scene_receiver_info_draw_widget(subghz); - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_tx_stop(subghz); - } + subghz_txrx_stop(subghz->txrx); if(!subghz->in_decoder_scene) { - if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) { - subghz_begin( - subghz, - subghz_setting_get_preset_data_by_name( - subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name))); - subghz_rx(subghz, subghz->txrx->preset->frequency); - } - if(subghz->txrx->hopper_state == SubGhzHopperStatePause) { - subghz->txrx->hopper_state = SubGhzHopperStateRunning; - } + subghz_txrx_rx_start(subghz->txrx); + + subghz_txrx_hopper_unpause(subghz->txrx); subghz->state_notifications = SubGhzNotificationStateRx; } return true; } else if(event.event == SubGhzCustomEventSceneReceiverInfoSave) { //CC1101 Stop RX -> Save subghz->state_notifications = SubGhzNotificationStateIDLE; - subghz->txrx->hopper_state = SubGhzHopperStateOFF; - if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz); - subghz_sleep(subghz); - } + subghz_txrx_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF); + + subghz_txrx_stop(subghz->txrx); if(!subghz_scene_receiver_info_update_parser(subghz)) { return false; } - if((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Save) == - SubGhzProtocolFlag_Save) { + if(subghz_txrx_protocol_is_serializable(subghz->txrx)) { subghz_file_name_clear(subghz); if(subghz->in_decoder_scene) { @@ -205,8 +169,8 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) return true; } } else if(event.type == SceneManagerEventTypeTick) { - if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { - subghz_hopper_update(subghz); + if(subghz_txrx_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF) { + subghz_txrx_hopper_update(subghz->txrx); } switch(subghz->state_notifications) { case SubGhzNotificationStateTx: diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index 13379490b..8a52cf2a9 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -9,6 +9,7 @@ typedef enum { SubGhzRpcStateIdle, SubGhzRpcStateLoaded, + SubGhzRpcStateTx, } SubGhzRpcState; void subghz_scene_rpc_on_enter(void* context) { @@ -43,9 +44,9 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { view_dispatcher_stop(subghz->view_dispatcher); } else if(event.event == SubGhzCustomEventSceneRpcButtonPress) { bool result = false; - if((subghz->txrx->txrx_state == SubGhzTxRxStateSleep) && - (state == SubGhzRpcStateLoaded)) { - result = subghz_tx_start(subghz, subghz->txrx->fff_data); + if((state == SubGhzRpcStateLoaded)) { + result = subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); + state = SubGhzRpcStateTx; if(result) subghz_blink_start(subghz); } if(!result) { @@ -57,10 +58,10 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventButtonPress, result); } else if(event.event == SubGhzCustomEventSceneRpcButtonRelease) { bool result = false; - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { + if(state == SubGhzRpcStateTx) { + subghz_txrx_stop(subghz->txrx); subghz_blink_stop(subghz); - subghz_tx_stop(subghz); - subghz_sleep(subghz); + state = SubGhzRpcStateIdle; result = true; } rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventButtonRelease, result); @@ -98,9 +99,9 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { void subghz_scene_rpc_on_exit(void* context) { SubGhz* subghz = context; - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_tx_stop(subghz); - subghz_sleep(subghz); + SubGhzRpcState state = scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneRpc); + if(state != SubGhzRpcStateIdle) { + subghz_txrx_stop(subghz->txrx); subghz_blink_stop(subghz); } diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 2bb13f184..b0c3a1b12 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -57,15 +57,16 @@ void subghz_scene_save_name_on_enter(void* context) { if(!subghz_path_is_file(subghz->file_path)) { char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0}; if(furi_hal_subghz_get_timestamp_file_names()) { - if(subghz->txrx->decoder_result != 0x0) { - if(subghz->txrx->decoder_result != NULL) { - if(strlen(subghz->txrx->decoder_result->protocol->name) != 0) { + SubGhzProtocolDecoderBase* decoder_result = subghz_txrx_get_decoder(subghz->txrx); + if(decoder_result != 0x0) { + if(decoder_result != NULL) { + if(strlen(decoder_result->protocol->name) != 0) { if(scene_manager_has_previous_scene( subghz->scene_manager, SubGhzSceneSetType)) { subghz_scene_save_name_get_timefilename(file_name, "S", true); } else { subghz_scene_save_name_get_timefilename( - file_name, subghz->txrx->decoder_result->protocol->name, false); + file_name, decoder_result->protocol->name, false); } } else { @@ -146,7 +147,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { SubGhzCustomEventManagerNoSet) { subghz_save_protocol_to_file( subghz, - subghz->txrx->fff_data, + subghz_txrx_get_fff_data(subghz->txrx), furi_string_get_cstr(subghz->file_path)); scene_manager_set_scene_state( subghz->scene_manager, @@ -155,8 +156,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { } else { subghz_save_protocol_to_file( subghz, - subghz_history_get_raw_data( - subghz->txrx->history, subghz->txrx->idx_menu_chosen), + subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen), furi_string_get_cstr(subghz->file_path)); } } @@ -164,7 +164,8 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { subghz_protocol_raw_gen_fff_data( - subghz->txrx->fff_data, furi_string_get_cstr(subghz->file_path)); + subghz_txrx_get_fff_data(subghz->txrx), + furi_string_get_cstr(subghz->file_path)); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); } else { diff --git a/applications/main/subghz/scenes/subghz_scene_save_success.c b/applications/main/subghz/scenes/subghz_scene_save_success.c index 107dc7b7d..9033f694b 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_success.c +++ b/applications/main/subghz/scenes/subghz_scene_save_success.c @@ -28,10 +28,10 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) if(!subghz->in_decoder_scene) { if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneReceiver)) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWSave; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateRAWSave); if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneReadRAW)) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneSaved)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); @@ -40,8 +40,8 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) } } else { subghz->decode_raw_state = SubGhzDecodeRawStateStart; - subghz->txrx->idx_menu_chosen = 0; - subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz); + subghz->idx_menu_chosen = 0; + subghz_txrx_set_rx_calback(subghz->txrx, NULL, subghz); if(subghz_file_encoder_worker_is_running(subghz->decode_raw_file_worker_encoder)) { subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder); diff --git a/applications/main/subghz/scenes/subghz_scene_saved.c b/applications/main/subghz/scenes/subghz_scene_saved.c index 62ade3508..8b198e339 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved.c +++ b/applications/main/subghz/scenes/subghz_scene_saved.c @@ -4,8 +4,8 @@ void subghz_scene_saved_on_enter(void* context) { SubGhz* subghz = context; if(subghz_load_protocol_from_file(subghz)) { - if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; + if(subghz_get_load_type_file(subghz) == SubGhzLoadTypeFileRaw) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateRAWLoad); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); } else { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSavedMenu); diff --git a/applications/main/subghz/scenes/subghz_scene_set_cnt.c b/applications/main/subghz/scenes/subghz_scene_set_cnt.c index 62ef581ff..4faff7bbb 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_cnt.c +++ b/applications/main/subghz/scenes/subghz_scene_set_cnt.c @@ -24,7 +24,7 @@ void subghz_scene_set_cnt_on_enter(void* context) { subghz_scene_set_cnt_byte_input_callback, NULL, subghz, - subghz->txrx->secure_data->cnt, + subghz->secure_data->cnt, 2); break; case SubmenuIndexFaacSLH_433: @@ -35,7 +35,7 @@ void subghz_scene_set_cnt_on_enter(void* context) { subghz_scene_set_cnt_byte_input_callback, NULL, subghz, - subghz->txrx->secure_data->cnt, + subghz->secure_data->cnt, 3); break; default: diff --git a/applications/main/subghz/scenes/subghz_scene_set_fix.c b/applications/main/subghz/scenes/subghz_scene_set_fix.c index 01431dac6..7564fb24d 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_fix.c +++ b/applications/main/subghz/scenes/subghz_scene_set_fix.c @@ -19,7 +19,7 @@ void subghz_scene_set_fix_on_enter(void* context) { subghz_scene_set_fix_byte_input_callback, NULL, subghz, - subghz->txrx->secure_data->fix, + subghz->secure_data->fix, 4); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); } diff --git a/applications/main/subghz/scenes/subghz_scene_set_seed.c b/applications/main/subghz/scenes/subghz_scene_set_seed.c index aa2a270f3..e6850d1e3 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_seed.c +++ b/applications/main/subghz/scenes/subghz_scene_set_seed.c @@ -1,6 +1,5 @@ #include "../subghz_i.h" -#include -#include +#include "../helpers/subghz_txrx_create_protocol_key.h" #define TAG "SubGhzSetSeed" @@ -21,7 +20,7 @@ void subghz_scene_set_seed_on_enter(void* context) { subghz_scene_set_seed_byte_input_callback, NULL, subghz, - subghz->txrx->secure_data->seed, + subghz->secure_data->seed, 4); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); } @@ -38,46 +37,23 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { switch(state) { case SubmenuIndexBFTClone: - fix_part = subghz->txrx->secure_data->fix[0] << 24 | - subghz->txrx->secure_data->fix[1] << 16 | - subghz->txrx->secure_data->fix[2] << 8 | - subghz->txrx->secure_data->fix[3]; + fix_part = subghz->secure_data->fix[0] << 24 | subghz->secure_data->fix[1] << 16 | + subghz->secure_data->fix[2] << 8 | subghz->secure_data->fix[3]; - cnt = subghz->txrx->secure_data->cnt[0] << 8 | subghz->txrx->secure_data->cnt[1]; + cnt = subghz->secure_data->cnt[0] << 8 | subghz->secure_data->cnt[1]; - seed = subghz->txrx->secure_data->seed[0] << 24 | - subghz->txrx->secure_data->seed[1] << 16 | - subghz->txrx->secure_data->seed[2] << 8 | - subghz->txrx->secure_data->seed[3]; + seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 | + subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3]; - subghz->txrx->transmitter = - subghz_transmitter_alloc_init(subghz->txrx->environment, "KeeLoq"); - if(subghz->txrx->transmitter) { - subghz_preset_init(subghz, "AM650", 433920000, NULL, 0); - subghz_protocol_keeloq_bft_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - fix_part & 0x0FFFFFFF, - fix_part >> 28, - cnt, - seed, - "BFT", - subghz->txrx->preset); - - uint8_t seed_data[sizeof(uint32_t)] = {0}; - for(size_t i = 0; i < sizeof(uint32_t); i++) { - seed_data[sizeof(uint32_t) - i - 1] = (seed >> i * 8) & 0xFF; - } - - flipper_format_write_hex( - subghz->txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); - - flipper_format_write_string_cstr(subghz->txrx->fff_data, "Manufacture", "BFT"); - - generated_protocol = true; - } - - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_keeloq_bft_protocol( + subghz->txrx, + "AM650", + 433920000, + fix_part & 0x0FFFFFFF, + fix_part >> 28, + cnt, + seed, + "BFT"); if(!generated_protocol) { furi_string_set( @@ -88,53 +64,37 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { break; case SubmenuIndexFaacSLH_433: case SubmenuIndexFaacSLH_868: - fix_part = subghz->txrx->secure_data->fix[0] << 24 | - subghz->txrx->secure_data->fix[1] << 16 | - subghz->txrx->secure_data->fix[2] << 8 | - subghz->txrx->secure_data->fix[3]; + fix_part = subghz->secure_data->fix[0] << 24 | subghz->secure_data->fix[1] << 16 | + subghz->secure_data->fix[2] << 8 | subghz->secure_data->fix[3]; - cnt = subghz->txrx->secure_data->cnt[0] << 16 | - subghz->txrx->secure_data->cnt[1] << 8 | subghz->txrx->secure_data->cnt[2]; + cnt = subghz->secure_data->cnt[0] << 16 | subghz->secure_data->cnt[1] << 8 | + subghz->secure_data->cnt[2]; - seed = subghz->txrx->secure_data->seed[0] << 24 | - subghz->txrx->secure_data->seed[1] << 16 | - subghz->txrx->secure_data->seed[2] << 8 | - subghz->txrx->secure_data->seed[3]; + seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 | + subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3]; - subghz->txrx->transmitter = - subghz_transmitter_alloc_init(subghz->txrx->environment, "Faac SLH"); - if(subghz->txrx->transmitter) { - SubGhzCustomEvent state = - scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType); - - if(state == SubmenuIndexFaacSLH_433) { - subghz_preset_init(subghz, "AM650", 433920000, NULL, 0); - } else if(state == SubmenuIndexFaacSLH_868) { - subghz_preset_init(subghz, "AM650", 868350000, NULL, 0); - } - subghz_protocol_faac_slh_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, + if(state == SubmenuIndexFaacSLH_433) { + generated_protocol = subghz_txrx_gen_faac_slh_protocol( + subghz->txrx, + "AM650", + 433920000, fix_part >> 4, fix_part & 0xf, (cnt & 0xFFFFF), seed, - "FAAC_SLH", - subghz->txrx->preset); - // RogueMaster dont steal! - uint8_t seed_data[sizeof(uint32_t)] = {0}; - for(size_t i = 0; i < sizeof(uint32_t); i++) { - seed_data[sizeof(uint32_t) - i - 1] = (seed >> i * 8) & 0xFF; - } - - flipper_format_write_hex( - subghz->txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); - - generated_protocol = true; + "FAAC_SLH"); + } else if(state == SubmenuIndexFaacSLH_868) { + generated_protocol = subghz_txrx_gen_faac_slh_protocol( + subghz->txrx, + "AM650", + 868350000, + fix_part >> 4, + fix_part & 0xf, + (cnt & 0xFFFFF), + seed, + "FAAC_SLH"); } - subghz_transmitter_free(subghz->txrx->transmitter); - if(!generated_protocol) { furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index e871a6439..ef53006da 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -1,102 +1,10 @@ #include "../subghz_i.h" -#include -#include -#include -#include -#include +#include "../helpers/subghz_txrx_create_protocol_key.h" #include -#include -#include #include #define TAG "SubGhzSetType" -bool subghz_scene_set_type_submenu_gen_data_protocol( - void* context, - const char* protocol_name, - uint64_t key, - uint32_t bit, - uint32_t frequency, - const char* preset_name) { - furi_assert(context); - SubGhz* subghz = context; - - bool res = false; - - subghz_preset_init(subghz, preset_name, frequency, NULL, 0); - subghz->txrx->decoder_result = - subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, protocol_name); - - if(subghz->txrx->decoder_result == NULL) { - furi_string_set(subghz->error_str, "Protocol not\nfound!"); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); - return false; - } - - do { - Stream* fff_data_stream = flipper_format_get_raw_stream(subghz->txrx->fff_data); - stream_clean(fff_data_stream); - if(subghz_protocol_decoder_base_serialize( - subghz->txrx->decoder_result, subghz->txrx->fff_data, subghz->txrx->preset) != - SubGhzProtocolStatusOk) { - FURI_LOG_E(TAG, "Unable to serialize"); - break; - } - if(!flipper_format_update_uint32(subghz->txrx->fff_data, "Bit", &bit, 1)) { - FURI_LOG_E(TAG, "Unable to update Bit"); - break; - } - - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (key >> (i * 8)) & 0xFF; - } - if(!flipper_format_update_hex(subghz->txrx->fff_data, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to update Key"); - break; - } - res = true; - } while(false); - return res; -} - -bool subghz_scene_set_type_submenu_gen_data_keeloq( - void* context, - const char* preset_name, - uint32_t frequency, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - const char* manufacture_name) { - SubGhz* subghz = context; - - bool res = false; - - subghz->txrx->transmitter = - subghz_transmitter_alloc_init(subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); - subghz_preset_init(subghz, preset_name, frequency, NULL, 0); - - if(subghz->txrx->transmitter && - subghz_protocol_keeloq_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - serial, - btn, - cnt, - manufacture_name, - subghz->txrx->preset)) { - flipper_format_write_string_cstr(subghz->txrx->fff_data, "Manufacture", manufacture_name); - res = true; - } - - subghz_transmitter_free(subghz->txrx->transmitter); - if(!res) { - furi_string_set(subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } - return res; -} - void subghz_scene_set_type_submenu_callback(void* context, uint32_t index) { SubGhz* subghz = context; view_dispatcher_send_custom_event(subghz->view_dispatcher, index); @@ -306,7 +214,7 @@ void subghz_scene_set_type_on_enter(void* context) { submenu_add_item( subghz->submenu, "Princeton 433MHz", - SubmenuIndexPricenton, + SubmenuIndexPricenton433, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( @@ -385,8 +293,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { bool generated_protocol = false; if(event.type == SceneManagerEventTypeCustom) { - //ToDo Fix - uint32_t key = subghz_random_serial(); + uint32_t key = (uint32_t)rand(); switch(event.event) { case SubmenuIndexFaacSLH_868: scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix); @@ -397,258 +304,246 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { case SubmenuIndexBFTClone: scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix); break; - case SubmenuIndexPricenton: + case SubmenuIndexPricenton433: key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 433920000, "AM650")) { - uint32_t te = 400; - flipper_format_update_uint32(subghz->txrx->fff_data, "TE", (uint32_t*)&te, 1); - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol_and_te( + subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 400); break; case SubmenuIndexPricenton315: key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 315000000, "AM650")) { - uint32_t te = 400; - flipper_format_update_uint32(subghz->txrx->fff_data, "TE", (uint32_t*)&te, 1); - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol_and_te( + subghz->txrx, "AM650", 315000000, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 400); break; case SubmenuIndexNiceFlo12bit: key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4 - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 12, 433920000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 12); break; case SubmenuIndexNiceFlo24bit: key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 24, 433920000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 24); break; case SubmenuIndexCAME12bit: key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4 - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_CAME_NAME, key, 12, 433920000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12); break; case SubmenuIndexCAME24bit: key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_CAME_NAME, key, 24, 433920000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 24); break; case SubmenuIndexCAME12bit868: key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4 - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_CAME_NAME, key, 12, 868350000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 868350000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12); break; case SubmenuIndexCAME24bit868: key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_CAME_NAME, key, 24, 868350000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 868350000, SUBGHZ_PROTOCOL_CAME_NAME, key, 24); break; case SubmenuIndexLinear_300_00: key = (key & 0x3FF); - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_LINEAR_NAME, key, 10, 300000000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 300000000, SUBGHZ_PROTOCOL_LINEAR_NAME, key, 10); break; case SubmenuIndexBETT_433: key = (key & 0x0000FFF0); - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_BETT_NAME, key, 18, 433920000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_BETT_NAME, key, 18); break; case SubmenuIndexCAMETwee: key = (key & 0x0FFFFFF0); key = 0x003FFF7200000000 | (key ^ 0xE0E0E0EE); - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_CAME_TWEE_NAME, key, 54, 433920000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_TWEE_NAME, key, 54); break; - // case SubmenuIndexNeroSketch: - // /* code */ - // break; - // case SubmenuIndexNeroRadio: - // /* code */ - // break; case SubmenuIndexGateTX: key = (key & 0x00F0FF00) | 0xF << 16 | 0x40; //btn 0xF, 0xC, 0xA, 0x6 (?) uint64_t rev_key = subghz_protocol_blocks_reverse_key(key, 24); - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, SUBGHZ_PROTOCOL_GATE_TX_NAME, rev_key, 24, 433920000, "AM650")) { - generated_protocol = true; - } + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_GATE_TX_NAME, rev_key, 24); break; case SubmenuIndexBeninca433: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, - "AM650", - 433920000, - (key & 0x000FFF00) | 0x00800080, - 0x1, - 0x0005, - "Beninca")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, + "AM650", + 433920000, + (key & 0x000FFF00) | 0x00800080, + 0x1, + 0x0005, + "Beninca"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexBeninca868: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, - "AM650", - 868350000, - (key & 0x000FFF00) | 0x00800080, - 0x1, - 0x0005, - "Beninca")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, + "AM650", + 868350000, + (key & 0x000FFF00) | 0x00800080, + 0x1, + 0x0005, + "Beninca"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexAllmatic433: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, - "AM650", - 433920000, - (key & 0x00FFFF00) | 0x01000011, - 0xC, - 0x0005, - "Beninca")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, + "AM650", + 433920000, + (key & 0x00FFFF00) | 0x01000011, + 0xC, + 0x0005, + "Beninca"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexAllmatic868: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, - "AM650", - 868350000, - (key & 0x00FFFF00) | 0x01000011, - 0xC, - 0x0005, - "Beninca")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, + "AM650", + 868350000, + (key & 0x00FFFF00) | 0x01000011, + 0xC, + 0x0005, + "Beninca"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexElmesElectronic: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, - "AM650", - 433920000, - (key & 0x00FFFFFF) | 0x02000000, - 0x2, - 0x0003, - "Elmes_Poland")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, + "AM650", + 433920000, + (key & 0x00FFFFFF) | 0x02000000, + 0x2, + 0x0003, + "Elmes_Poland"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexANMotorsAT4: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, - "AM650", - 433920000, - (key & 0x000FFFFF) | 0x04700000, - 0x2, - 0x0021, - "AN-Motors")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, + "AM650", + 433920000, + (key & 0x000FFFFF) | 0x04700000, + 0x2, + 0x0021, + "AN-Motors"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexAprimatic: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, - "AM650", - 433920000, - (key & 0x000FFFFF) | 0x00600000, - 0x4, - 0x0003, - "Aprimatic")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, + "AM650", + 433920000, + (key & 0x000FFFFF) | 0x00600000, + 0x4, + 0x0003, + "Aprimatic"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexGibidi433: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Gibidi")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Gibidi"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexGSN: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "AM650", 433920000, key & 0x0FFFFFFF, 0x2, 0x0003, "GSN")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "AM650", 433920000, key & 0x0FFFFFFF, 0x2, 0x0003, "GSN"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexIronLogic: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "AM650", 433920000, key & 0x00FFFFF0, 0x4, 0x0005, "IronLogic")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "AM650", 433920000, key & 0x00FFFFF0, 0x4, 0x0005, "IronLogic"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexSommer_FM_434: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "FM476", 434420000, key & 0x0FFFFFFF, 0x4, 0x0003, "Sommer(fsk476)")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "FM476", 434420000, key & 0x0FFFFFFF, 0x4, 0x0003, "Sommer(fsk476)"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexSommer_FM_868: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "FM476", 868800000, key & 0x0FFFFFFF, 0x4, 0x0003, "Sommer(fsk476)")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "FM476", 868800000, key & 0x0FFFFFFF, 0x4, 0x0003, "Sommer(fsk476)"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexDTMNeo433: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "AM650", 433920000, key & 0x000FFFFF, 0x2, 0x0005, "DTM_Neo")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "AM650", 433920000, key & 0x000FFFFF, 0x2, 0x0005, "DTM_Neo"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexCAMESpace: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Came_Space")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Came_Space"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexBFTMitto: - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); - subghz_preset_init(subghz, "AM650", 433920000, NULL, 0); - if(subghz->txrx->transmitter) { - subghz_protocol_keeloq_bft_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - key & 0x000FFFFF, - 0x2, - 0x0002, - key & 0x000FFFFF, - "BFT", - subghz->txrx->preset); - - uint8_t seed_data[sizeof(uint32_t)] = {0}; - for(size_t i = 0; i < sizeof(uint32_t); i++) { - seed_data[sizeof(uint32_t) - i - 1] = ((key & 0x000FFFFF) >> i * 8) & 0xFF; - } - - flipper_format_write_hex( - subghz->txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); - - flipper_format_write_string_cstr(subghz->txrx->fff_data, "Manufacture", "BFT"); - - generated_protocol = true; - } else { - generated_protocol = false; - } - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_keeloq_bft_protocol( + subghz->txrx, + "AM650", + 433920000, + key & 0x000FFFFF, + 0x2, + 0x0002, + key & 0x000FFFFF, + "BFT"); if(!generated_protocol) { furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); @@ -656,22 +551,8 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { } break; case SubmenuIndexAlutechAT4N: - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME); - subghz_preset_init(subghz, "AM650", 433920000, NULL, 0); - if(subghz->txrx->transmitter) { - subghz_protocol_alutech_at_4n_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - (key & 0x000FFFFF) | 0x00100000, - 0x44, - 0x0003, - subghz->txrx->preset); - generated_protocol = true; - } else { - generated_protocol = false; - } - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_alutech_at_4n_protocol( + subghz->txrx, "AM650", 433920000, (key & 0x000FFFFF) | 0x00100000, 0x44, 0x0003); if(!generated_protocol) { furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); @@ -679,58 +560,30 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { } break; case SubmenuIndexSomfyTelis: - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME); - subghz_preset_init(subghz, "AM650", 433920000, NULL, 0); - if(subghz->txrx->transmitter) { - subghz_protocol_somfy_telis_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - key & 0x00FFFFFF, - 0x2, - 0x0003, - subghz->txrx->preset); - generated_protocol = true; - } else { - generated_protocol = false; - } - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_somfy_telis_protocol( + subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003); + break; + case SubmenuIndexDoorHan_433_92: + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "AM650", 433920000, key & 0x0FFFFFFF, 0x2, 0x0003, "DoorHan"); if(!generated_protocol) { furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; - case SubmenuIndexDoorHan_433_92: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "AM650", 433920000, key & 0x0FFFFFFF, 0x2, 0x0003, "DoorHan")) { - generated_protocol = true; - } - break; case SubmenuIndexDoorHan_315_00: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "AM650", 315000000, key & 0x0FFFFFFF, 0x2, 0x0003, "DoorHan")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "AM650", 315000000, key & 0x0FFFFFFF, 0x2, 0x0003, "DoorHan"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexNiceFlorS_433_92: - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME); - subghz_preset_init(subghz, "AM650", 433920000, NULL, 0); - if(subghz->txrx->transmitter) { - subghz_protocol_nice_flor_s_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - key & 0x0FFFFFFF, - 0x1, - 0x0003, - subghz->txrx->preset, - false); - generated_protocol = true; - } else { - generated_protocol = false; - } - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_nice_flor_s_protocol( + subghz->txrx, "AM650", 433920000, key & 0x0FFFFFFF, 0x1, 0x0003, false); if(!generated_protocol) { furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); @@ -738,23 +591,8 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { } break; case SubmenuIndexNiceOne_433_92: - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME); - subghz_preset_init(subghz, "AM650", 433920000, NULL, 0); - if(subghz->txrx->transmitter) { - subghz_protocol_nice_flor_s_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - key & 0x0FFFFFFF, - 0x1, - 0x0003, - subghz->txrx->preset, - true); - generated_protocol = true; - } else { - generated_protocol = false; - } - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_nice_flor_s_protocol( + subghz->txrx, "AM650", 433920000, key & 0x0FFFFFFF, 0x1, 0x0003, true); if(!generated_protocol) { furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); @@ -762,124 +600,41 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { } break; case SubmenuIndexNiceSmilo_433_92: - if(subghz_scene_set_type_submenu_gen_data_keeloq( - subghz, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "NICE_Smilo")) { - generated_protocol = true; + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "NICE_Smilo"); + if(!generated_protocol) { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } break; case SubmenuIndexLiftMaster_315_00: - while(!subghz_protocol_secplus_v1_check_fixed(key)) { - key = subghz_random_serial(); - } - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_SECPLUS_V1_NAME, - (uint64_t)key << 32 | 0xE6000000, - 42, - 315000000, - "AM650")) { - generated_protocol = true; - } + generated_protocol = + subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, "AM650", 315000000); break; case SubmenuIndexLiftMaster_390_00: - while(!subghz_protocol_secplus_v1_check_fixed(key)) { - key = subghz_random_serial(); - } - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_SECPLUS_V1_NAME, - (uint64_t)key << 32 | 0xE6000000, - 42, - 390000000, - "AM650")) { - generated_protocol = true; - } + generated_protocol = + subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, "AM650", 390000000); break; case SubmenuIndexLiftMaster_433_00: - while(!subghz_protocol_secplus_v1_check_fixed(key)) { - key = subghz_random_serial(); - } - if(subghz_scene_set_type_submenu_gen_data_protocol( - subghz, - SUBGHZ_PROTOCOL_SECPLUS_V1_NAME, - (uint64_t)key << 32 | 0xE6000000, - 42, - 433920000, - "AM650")) { - generated_protocol = true; - } + generated_protocol = + subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, "AM650", 433920000); break; case SubmenuIndexSecPlus_v2_310_00: - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME); - subghz_preset_init(subghz, "AM650", 310000000, NULL, 0); - if(subghz->txrx->transmitter) { - subghz_protocol_secplus_v2_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - key, - 0x68, - 0xE500000, - subghz->txrx->preset); - generated_protocol = true; - } else { - generated_protocol = false; - } - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_secplus_v2_protocol( + subghz->txrx, "AM650", 310000000, key, 0x68, 0xE500000); break; case SubmenuIndexSecPlus_v2_315_00: - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME); - subghz_preset_init(subghz, "AM650", 315000000, NULL, 0); - if(subghz->txrx->transmitter) { - subghz_protocol_secplus_v2_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - key, - 0x68, - 0xE500000, - subghz->txrx->preset); - generated_protocol = true; - } else { - generated_protocol = false; - } - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_secplus_v2_protocol( + subghz->txrx, "AM650", 315000000, key, 0x68, 0xE500000); break; case SubmenuIndexSecPlus_v2_390_00: - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME); - subghz_preset_init(subghz, "AM650", 390000000, NULL, 0); - if(subghz->txrx->transmitter) { - subghz_protocol_secplus_v2_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - key, - 0x68, - 0xE500000, - subghz->txrx->preset); - generated_protocol = true; - } else { - generated_protocol = false; - } - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_secplus_v2_protocol( + subghz->txrx, "AM650", 390000000, key, 0x68, 0xE500000); break; case SubmenuIndexSecPlus_v2_433_00: - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME); - subghz_preset_init(subghz, "AM650", 433920000, NULL, 0); - if(subghz->txrx->transmitter) { - subghz_protocol_secplus_v2_create_data( - subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter), - subghz->txrx->fff_data, - key, - 0x68, - 0xE500000, - subghz->txrx->preset); - generated_protocol = true; - } else { - generated_protocol = false; - } - subghz_transmitter_free(subghz->txrx->transmitter); + generated_protocol = subghz_txrx_gen_secplus_v2_protocol( + subghz->txrx, "AM650", 433920000, key, 0x68, 0xE500000); break; default: return false; diff --git a/applications/main/subghz/scenes/subghz_scene_start.c b/applications/main/subghz/scenes/subghz_scene_start.c index e3c70aaf6..78b99c691 100644 --- a/applications/main/subghz/scenes/subghz_scene_start.c +++ b/applications/main/subghz/scenes/subghz_scene_start.c @@ -97,7 +97,7 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubmenuIndexReadRAW) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneStart, SubmenuIndexReadRAW); - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); return true; } else if(event.event == SubmenuIndexRead) { diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 77601c08a..12f23cf11 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -16,29 +16,25 @@ void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) { bool subghz_scene_transmitter_update_data_show(void* context) { SubGhz* subghz = context; bool ret = false; - if(subghz->txrx->decoder_result) { + SubGhzProtocolDecoderBase* decoder = subghz_txrx_get_decoder(subghz->txrx); + + if(decoder) { FuriString* key_str = furi_string_alloc(); FuriString* frequency_str = furi_string_alloc(); FuriString* modulation_str = furi_string_alloc(); - bool show_button = false; - if(subghz_protocol_decoder_base_deserialize( - subghz->txrx->decoder_result, subghz->txrx->fff_data) == SubGhzProtocolStatusOk) { - subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, key_str); + decoder, subghz_txrx_get_fff_data(subghz->txrx)) == SubGhzProtocolStatusOk) { + subghz_protocol_decoder_base_get_string(decoder, key_str); - if((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Send) == - SubGhzProtocolFlag_Send) { - show_button = true; - } - - subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + subghz_txrx_get_frequency_and_modulation( + subghz->txrx, frequency_str, modulation_str, false); subghz_view_transmitter_add_data_to_show( subghz->subghz_transmitter, furi_string_get_cstr(key_str), furi_string_get_cstr(frequency_str), furi_string_get_cstr(modulation_str), - show_button); + subghz_txrx_protocol_is_transmittable(subghz->txrx, false)); ret = true; } furi_string_free(frequency_str); @@ -94,40 +90,23 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventViewTransmitterSendStart) { 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, subghz->txrx->fff_data)) { - subghz->state_notifications = SubGhzNotificationStateTx; - subghz_scene_transmitter_update_data_show(subghz); - DOLPHIN_DEED(DolphinDeedSubGhzSend); - } + + if(subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx))) { + subghz->state_notifications = SubGhzNotificationStateTx; + subghz_scene_transmitter_update_data_show(subghz); + DOLPHIN_DEED(DolphinDeedSubGhzSend); } return true; } else if(event.event == SubGhzCustomEventViewTransmitterSendStop) { subghz->state_notifications = SubGhzNotificationStateIDLE; - if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { - subghz_tx_stop(subghz); - subghz_sleep(subghz); - } + subghz_txrx_stop(subghz->txrx); if(subghz_custom_btn_get() != 0) { subghz_custom_btn_set(0); uint8_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult(); furi_hal_subghz_set_rolling_counter_mult(0); // Calling restore! - 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, subghz->txrx->fff_data)) { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); - } - } - subghz_tx_stop(subghz); - subghz_sleep(subghz); + subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); + subghz_txrx_stop(subghz->txrx); furi_hal_subghz_set_rolling_counter_mult(tmp_counter); } if(subghz->fav_timeout) { diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index fa6e10b7a..7fdfc80fd 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -53,16 +53,6 @@ static void subghz_rpc_command_callback(RpcAppSystemEvent event, void* context) } } -void subghz_blink_start(SubGhz* instance) { - furi_assert(instance); - notification_message(instance->notifications, &sequence_blink_start_magenta); -} - -void subghz_blink_stop(SubGhz* instance) { - furi_assert(instance); - notification_message(instance->notifications, &sequence_blink_stop); -} - SubGhz* subghz_alloc(bool alloc_for_tx_only) { SubGhz* subghz = malloc(sizeof(SubGhz)); @@ -182,10 +172,15 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz_test_static_get_view(subghz->subghz_test_static)); #endif - //init setting - subghz->setting = subghz_setting_alloc(); + //init threshold rssi + subghz->threshold_rssi = subghz_threshold_rssi_alloc(); - subghz_setting_load(subghz->setting, EXT_PATH("subghz/assets/setting_user")); + //init TxRx & Protocol & History & KeyBoard + subghz_unlock(subghz); + + subghz->txrx = subghz_txrx_alloc(); + + SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); // Custom Presets load without using config file if(!alloc_for_tx_only) { @@ -195,7 +190,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { (const char*)"Custom_preset_data", (const char*)"02 0D 0B 06 08 32 07 04 14 00 13 02 12 04 11 83 10 67 15 24 18 18 19 16 1D 91 1C 00 1B 07 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"); flipper_format_rewind(temp_fm_preset); - subghz_setting_load_custom_preset(subghz->setting, (const char*)"FM95", temp_fm_preset); + subghz_setting_load_custom_preset(setting, (const char*)"FM95", temp_fm_preset); flipper_format_free(temp_fm_preset); @@ -206,7 +201,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { (const char*)"Custom_preset_data", (const char*)"02 0D 03 47 08 32 0B 06 15 32 14 00 13 00 12 00 11 32 10 A7 18 18 19 1D 1D 92 1C 00 1B 04 20 FB 22 17 21 B6 00 00 00 12 0E 34 60 C5 C1 C0"); flipper_format_rewind(temp_fm_preset2); - subghz_setting_load_custom_preset(subghz->setting, (const char*)"FM15k", temp_fm_preset2); + subghz_setting_load_custom_preset(setting, (const char*)"FM15k", temp_fm_preset2); flipper_format_free(temp_fm_preset2); @@ -217,7 +212,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { (const char*)"Custom_preset_data", (const char*)"02 0D 07 04 08 32 0B 06 10 64 11 93 12 0C 13 02 14 00 15 15 18 18 19 16 1B 07 1C 00 1D 91 20 FB 21 56 22 10 00 00 C0 00 00 00 00 00 00 00"); flipper_format_rewind(temp_fm_preset3); - subghz_setting_load_custom_preset(subghz->setting, (const char*)"Pagers", temp_fm_preset3); + subghz_setting_load_custom_preset(setting, (const char*)"Pagers", temp_fm_preset3); flipper_format_free(temp_fm_preset3); @@ -228,7 +223,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { (const char*)"Custom_preset_data", (const char*)"02 0D 0B 06 08 32 07 04 14 00 13 02 12 04 11 36 10 69 15 32 18 18 19 16 1D 91 1C 00 1B 07 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"); flipper_format_rewind(temp_fm_preset4); - subghz_setting_load_custom_preset(subghz->setting, (const char*)"HND_1", temp_fm_preset4); + subghz_setting_load_custom_preset(setting, (const char*)"HND_1", temp_fm_preset4); flipper_format_free(temp_fm_preset4); @@ -238,7 +233,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { (const char*)"Custom_preset_data", (const char*)"02 0D 0B 06 08 32 07 04 14 00 13 02 12 07 11 36 10 E9 15 32 18 18 19 16 1D 92 1C 40 1B 03 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"); flipper_format_rewind(temp_fm_preset5); - subghz_setting_load_custom_preset(subghz->setting, (const char*)"HND_2", temp_fm_preset5); + subghz_setting_load_custom_preset(setting, (const char*)"HND_2", temp_fm_preset5); flipper_format_free(temp_fm_preset5); } @@ -255,52 +250,24 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz->last_settings->frequency, subghz->last_settings->preset); #endif - subghz_setting_set_default_frequency(subghz->setting, subghz->last_settings->frequency); + subghz_setting_set_default_frequency(setting, subghz->last_settings->frequency); } - //init Worker & Protocol & History & KeyBoard - subghz->lock = SubGhzLockOff; - subghz->txrx = malloc(sizeof(SubGhzTxRx)); - subghz->txrx->preset = malloc(sizeof(SubGhzRadioPreset)); - subghz->txrx->preset->name = furi_string_alloc(); + if(!alloc_for_tx_only) { - subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0); - } else { - subghz_preset_init( - subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); + subghz_txrx_set_preset(subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0); } - subghz->txrx->txrx_state = SubGhzTxRxStateSleep; - subghz->txrx->hopper_state = SubGhzHopperStateOFF; - subghz->txrx->speaker_state = SubGhzSpeakerStateDisable; - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; - subghz->txrx->debug_pin_state = false; + + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); + if(!alloc_for_tx_only) { - subghz->txrx->history = subghz_history_alloc(); + subghz->history = subghz_history_alloc(); } - subghz->txrx->raw_threshold_rssi = SUBGHZ_RAW_THRESHOLD_MIN; - subghz->txrx->worker = subghz_worker_alloc(); + subghz->secure_data = malloc(sizeof(SecureData)); - subghz->txrx->fff_data = flipper_format_string_alloc(); - subghz->txrx->secure_data = malloc(sizeof(SecureData)); - - subghz->txrx->environment = subghz_environment_alloc(); - subghz_environment_set_came_atomo_rainbow_table_file_name( - subghz->txrx->environment, EXT_PATH("subghz/assets/came_atomo")); - subghz_environment_set_alutech_at_4n_rainbow_table_file_name( - subghz->txrx->environment, EXT_PATH("subghz/assets/alutech_at_4n")); - subghz_environment_set_nice_flor_s_rainbow_table_file_name( - subghz->txrx->environment, EXT_PATH("subghz/assets/nice_flor_s")); - subghz_environment_set_protocol_registry( - subghz->txrx->environment, (void*)&subghz_protocol_registry); - subghz->txrx->receiver = subghz_receiver_alloc_init(subghz->txrx->environment); - subghz->txrx->filter = SubGhzProtocolFlag_Decodable; - subghz_receiver_set_filter(subghz->txrx->receiver, subghz->txrx->filter); - - subghz_worker_set_overrun_callback( - subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); - subghz_worker_set_pair_callback( - subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode); - subghz_worker_set_context(subghz->txrx->worker, subghz->txrx->receiver); + subghz->filter = SubGhzProtocolFlag_Decodable; + subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); + subghz_txrx_set_need_save_callback(subghz->txrx, subghz_save_to_file, subghz); //Init Error_str subghz->error_str = furi_string_alloc(); @@ -318,7 +285,9 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { subghz->rpc_ctx = NULL; } - subghz_speaker_off(subghz); + subghz_txrx_speaker_off(subghz->txrx); + subghz_txrx_stop(subghz->txrx); + subghz_txrx_sleep(subghz->txrx); #if FURI_DEBUG // Packet Test @@ -388,27 +357,19 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { furi_record_close(RECORD_GUI); subghz->gui = NULL; - //setting - subghz_setting_free(subghz->setting); + subghz_last_settings_free(subghz->last_settings); + + // threshold rssi + subghz_threshold_rssi_free(subghz->threshold_rssi); + if(!alloc_for_tx_only) { - subghz_last_settings_free(subghz->last_settings); + subghz_history_free(subghz->history); } - //Worker & Protocol & History - subghz_receiver_free(subghz->txrx->receiver); + free(subghz->secure_data); - subghz_environment_free(subghz->txrx->environment); - - subghz_worker_free(subghz->txrx->worker); - - flipper_format_free(subghz->txrx->fff_data); - if(!alloc_for_tx_only) { - subghz_history_free(subghz->txrx->history); - } - furi_string_free(subghz->txrx->preset->name); - free(subghz->txrx->preset); - free(subghz->txrx->secure_data); - free(subghz->txrx); + //TxRx + subghz_txrx_free(subghz->txrx); //Error string furi_string_free(subghz->error_str); @@ -441,12 +402,6 @@ int32_t subghz_app(char* p) { subghz->raw_send_only = false; } - //Load database - bool load_database = subghz_environment_load_keystore( - subghz->txrx->environment, EXT_PATH("subghz/assets/keeloq_mfcodes")); - subghz_environment_load_keystore( - subghz->txrx->environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user")); - // Call enable power for external module furi_hal_subghz_enable_ext_power(); @@ -475,9 +430,9 @@ int32_t subghz_app(char* p) { furi_string_set(subghz->file_path, (const char*)p); subghz->fav_timeout = is_favorite; - if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) { + if(subghz_get_load_type_file(subghz) == SubGhzLoadTypeFileRaw) { //Load Raw TX - subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateRAWLoad); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); } else { //Load transmitter TX @@ -493,7 +448,7 @@ int32_t subghz_app(char* p) { view_dispatcher_attach_to_gui( subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); - if(load_database) { + if(subghz_txrx_is_database_loaded(subghz->txrx)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); } else { scene_manager_set_scene_state( diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index d21bdac41..70812ed11 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -18,214 +18,42 @@ #define TAG "SubGhz" -void subghz_preset_init( - void* context, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size) { - furi_assert(context); - SubGhz* subghz = context; - furi_string_set(subghz->txrx->preset->name, preset_name); - subghz->txrx->preset->frequency = frequency; - subghz->txrx->preset->data = preset_data; - subghz->txrx->preset->data_size = preset_data_size; -} - -bool subghz_set_preset(SubGhz* subghz, const char* preset) { - if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) { - furi_string_set(subghz->txrx->preset->name, "AM270"); - } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) { - furi_string_set(subghz->txrx->preset->name, "AM650"); - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { - furi_string_set(subghz->txrx->preset->name, "FM238"); - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { - furi_string_set(subghz->txrx->preset->name, "FM476"); - } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { - furi_string_set(subghz->txrx->preset->name, "CUSTOM"); - } else { - FURI_LOG_E(TAG, "Unknown preset"); - return false; - } - return true; -} - -void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, FuriString* modulation) { +void subghz_set_default_preset(SubGhz* subghz) { furi_assert(subghz); - if(frequency != NULL) { - furi_string_printf( - frequency, - "%03ld.%02ld", - subghz->txrx->preset->frequency / 1000000 % 1000, - subghz->txrx->preset->frequency / 10000 % 100); - } - if(modulation != NULL) { - furi_string_printf(modulation, "%.2s", furi_string_get_cstr(subghz->txrx->preset->name)); - } + subghz_txrx_set_preset( + subghz->txrx, + "AM650", + subghz_setting_get_default_frequency(subghz_txrx_get_setting(subghz->txrx)), + NULL, + 0); } -void subghz_begin(SubGhz* subghz, uint8_t* preset_data) { +void subghz_blink_start(SubGhz* subghz) { furi_assert(subghz); - furi_hal_subghz_reset(); - furi_hal_subghz_idle(); - furi_hal_subghz_load_custom_preset(preset_data); - furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); - subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; + notification_message(subghz->notifications, &sequence_blink_stop); + notification_message(subghz->notifications, &sequence_blink_start_magenta); } -uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency) { +void subghz_blink_stop(SubGhz* subghz) { furi_assert(subghz); - if(!furi_hal_subghz_is_frequency_valid(frequency)) { - furi_crash("SubGhz: Incorrect RX frequency."); - } - furi_assert( - subghz->txrx->txrx_state != SubGhzTxRxStateRx && - subghz->txrx->txrx_state != SubGhzTxRxStateSleep); - - furi_hal_subghz_idle(); - uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); - furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); - furi_hal_subghz_flush_rx(); - subghz_speaker_on(subghz); - furi_hal_subghz_rx(); - - furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, subghz->txrx->worker); - subghz_worker_start(subghz->txrx->worker); - subghz->txrx->txrx_state = SubGhzTxRxStateRx; - return value; -} - -static bool subghz_tx(SubGhz* subghz, uint32_t frequency) { - furi_assert(subghz); - if(!furi_hal_subghz_is_frequency_valid(frequency)) { - furi_crash("SubGhz: Incorrect TX frequency."); - } - furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); - furi_hal_subghz_idle(); - furi_hal_subghz_set_frequency_and_path(frequency); - furi_hal_gpio_write(furi_hal_subghz.cc1101_g0_pin, false); - furi_hal_gpio_init( - furi_hal_subghz.cc1101_g0_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - bool ret = furi_hal_subghz_tx(); - if(ret) { - subghz_speaker_on(subghz); - subghz->txrx->txrx_state = SubGhzTxRxStateTx; - } - return ret; -} - -void subghz_idle(SubGhz* subghz) { - furi_assert(subghz); - furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); - furi_hal_subghz_idle(); - subghz_speaker_off(subghz); - subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; -} - -void subghz_rx_end(SubGhz* subghz) { - furi_assert(subghz); - furi_assert(subghz->txrx->txrx_state == SubGhzTxRxStateRx); - - if(subghz_worker_is_running(subghz->txrx->worker)) { - subghz_worker_stop(subghz->txrx->worker); - furi_hal_subghz_stop_async_rx(); - } - furi_hal_subghz_idle(); - subghz_speaker_off(subghz); - subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; -} - -void subghz_sleep(SubGhz* subghz) { - furi_assert(subghz); - furi_hal_subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateSleep; + notification_message(subghz->notifications, &sequence_blink_stop); } bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) { - furi_assert(subghz); + switch(subghz_txrx_tx_start(subghz->txrx, flipper_format)) { + case SubGhzTxRxStartTxStateErrorParserOthers: + dialog_message_show_storage_error( + subghz->dialogs, "Error in protocol\nparameters\ndescription"); + break; + case SubGhzTxRxStartTxStateErrorOnlyRx: + subghz_dialog_message_show_only_rx(subghz); + break; - bool ret = false; - FuriString* temp_str = furi_string_alloc(); - uint32_t repeat = 200; - do { - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_string(flipper_format, "Protocol", temp_str)) { - FURI_LOG_E(TAG, "Missing Protocol"); - break; - } - if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) { - FURI_LOG_E(TAG, "Unable Repeat"); - break; - } - - subghz->txrx->transmitter = subghz_transmitter_alloc_init( - subghz->txrx->environment, furi_string_get_cstr(temp_str)); - - if(subghz->txrx->transmitter) { - if(subghz_transmitter_deserialize(subghz->txrx->transmitter, flipper_format) == - SubGhzProtocolStatusOk) { - if(strcmp(furi_string_get_cstr(subghz->txrx->preset->name), "") != 0) { - subghz_begin( - subghz, - subghz_setting_get_preset_data_by_name( - subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name))); - } else { - FURI_LOG_E( - TAG, - "Unknown name preset \" %s \"", - furi_string_get_cstr(subghz->txrx->preset->name)); - subghz_begin( - subghz, subghz_setting_get_preset_data_by_name(subghz->setting, "AM650")); - } - if(subghz->txrx->preset->frequency) { - ret = subghz_tx(subghz, subghz->txrx->preset->frequency); - } else { - ret = subghz_tx(subghz, 433920000); - } - if(ret) { - //Start TX - furi_hal_subghz_start_async_tx( - subghz_transmitter_yield, subghz->txrx->transmitter); - } else { - subghz_dialog_message_show_only_rx(subghz); - } - } else { - dialog_message_show_storage_error( - subghz->dialogs, "Error in protocol\nparameters\ndescription"); - } - } - if(!ret) { - subghz_transmitter_free(subghz->txrx->transmitter); - if(subghz->txrx->txrx_state != SubGhzTxRxStateSleep) { - subghz_idle(subghz); - } - } - - } while(false); - furi_string_free(temp_str); - return ret; -} - -void subghz_tx_stop(SubGhz* subghz) { - furi_assert(subghz); - furi_assert(subghz->txrx->txrx_state == SubGhzTxRxStateTx); - //Stop TX - furi_hal_subghz_stop_async_tx(); - subghz_transmitter_stop(subghz->txrx->transmitter); - subghz_transmitter_free(subghz->txrx->transmitter); - - //if protocol dynamic then we save the last upload - if((subghz->txrx->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) && - (subghz_path_is_file(subghz->file_path))) { - subghz_save_protocol_to_file( - subghz, subghz->txrx->fff_data, furi_string_get_cstr(subghz->file_path)); + default: + return true; + break; } - subghz_idle(subghz); - subghz_speaker_off(subghz); - notification_message(subghz->notifications, &sequence_reset_red); + return false; } void subghz_dialog_message_show_only_rx(SubGhz* subghz) { @@ -250,7 +78,8 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - Stream* fff_data_stream = flipper_format_get_raw_stream(subghz->txrx->fff_data); + Stream* fff_data_stream = + flipper_format_get_raw_stream(subghz_txrx_get_fff_data(subghz->txrx)); SubGhzLoadKeyState load_key_state = SubGhzLoadKeyStateParseErr; FuriString* temp_str = furi_string_alloc(); @@ -276,6 +105,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { break; } + //Load frequency if(!flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) { FURI_LOG_E(TAG, "Missing Frequency"); break; @@ -291,58 +121,62 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { load_key_state = SubGhzLoadKeyStateOnlyRx; break; } - subghz->txrx->preset->frequency = temp_data32; + //Load preset if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) { FURI_LOG_E(TAG, "Missing Preset"); break; } - if(!subghz_set_preset(subghz, furi_string_get_cstr(temp_str))) { + furi_string_set_str( + temp_str, subghz_txrx_get_preset_name(subghz->txrx, furi_string_get_cstr(temp_str))); + if(!strcmp(furi_string_get_cstr(temp_str), "")) { break; } + SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); - if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!strcmp(furi_string_get_cstr(temp_str), "CUSTOM")) { //Todo add Custom_preset_module //delete preset if it already exists - subghz_setting_delete_custom_preset( - subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name)); + subghz_setting_delete_custom_preset(setting, furi_string_get_cstr(temp_str)); //load custom preset from file if(!subghz_setting_load_custom_preset( - subghz->setting, - furi_string_get_cstr(subghz->txrx->preset->name), - fff_data_file)) { + setting, furi_string_get_cstr(temp_str), fff_data_file)) { FURI_LOG_E(TAG, "Missing Custom preset"); break; } } - size_t preset_index = subghz_setting_get_inx_preset_by_name( - subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name)); - subghz_preset_init( - subghz, - furi_string_get_cstr(subghz->txrx->preset->name), - subghz->txrx->preset->frequency, - subghz_setting_get_preset_data(subghz->setting, preset_index), - subghz_setting_get_preset_data_size(subghz->setting, preset_index)); + size_t preset_index = + subghz_setting_get_inx_preset_by_name(setting, furi_string_get_cstr(temp_str)); + subghz_txrx_set_preset( + subghz->txrx, + furi_string_get_cstr(temp_str), + temp_data32, + subghz_setting_get_preset_data(setting, preset_index), + subghz_setting_get_preset_data_size(setting, preset_index)); + //Load protocol if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) { FURI_LOG_E(TAG, "Missing Protocol"); break; } + + FlipperFormat* fff_data = subghz_txrx_get_fff_data(subghz->txrx); if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) { //if RAW - subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, file_path); + subghz->load_type_file = SubGhzLoadTypeFileRaw; + subghz_protocol_raw_gen_fff_data(fff_data, file_path); } else { + subghz->load_type_file = SubGhzLoadTypeFileKey; stream_copy_full( flipper_format_get_raw_stream(fff_data_file), - flipper_format_get_raw_stream(subghz->txrx->fff_data)); + flipper_format_get_raw_stream(fff_data)); } - subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name( - subghz->txrx->receiver, furi_string_get_cstr(temp_str)); - if(subghz->txrx->decoder_result) { + if(subghz_txrx_load_decoder_by_name_protocol( + subghz->txrx, furi_string_get_cstr(temp_str))) { SubGhzProtocolStatus status = subghz_protocol_decoder_base_deserialize( - subghz->txrx->decoder_result, subghz->txrx->fff_data); + subghz_txrx_get_decoder(subghz->txrx), fff_data); if(status != SubGhzProtocolStatusOk) { load_key_state = SubGhzLoadKeyStateProtocolDescriptionErr; break; @@ -387,6 +221,11 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { } } +SubGhzLoadTypeFile subghz_get_load_type_file(SubGhz* subghz) { + furi_assert(subghz); + return subghz->load_type_file; +} + bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { furi_assert(subghz); @@ -468,6 +307,17 @@ bool subghz_save_protocol_to_file( return saved; } +void subghz_save_to_file(void* context) { + furi_assert(context); + SubGhz* subghz = context; + if(subghz_path_is_file(subghz->file_path)) { + subghz_save_protocol_to_file( + subghz, + subghz_txrx_get_fff_data(subghz->txrx), + furi_string_get_cstr(subghz->file_path)); + } +} + bool subghz_load_protocol_from_file(SubGhz* subghz) { furi_assert(subghz); @@ -551,113 +401,27 @@ bool subghz_path_is_file(FuriString* path) { return furi_string_end_with(path, SUBGHZ_APP_EXTENSION); } -uint32_t subghz_random_serial(void) { - return (uint32_t)rand(); -} - -void subghz_hopper_update(SubGhz* subghz) { +void subghz_lock(SubGhz* subghz) { furi_assert(subghz); - - switch(subghz->txrx->hopper_state) { - case SubGhzHopperStateOFF: - case SubGhzHopperStatePause: - return; - case SubGhzHopperStateRSSITimeOut: - if(subghz->txrx->hopper_timeout != 0) { - subghz->txrx->hopper_timeout--; - return; - } - break; - default: - break; - } - float rssi = -127.0f; - if(subghz->txrx->hopper_state != SubGhzHopperStateRSSITimeOut) { - // See RSSI Calculation timings in CC1101 17.3 RSSI - rssi = furi_hal_subghz_get_rssi(); - - // Stay if RSSI is high enough - if(rssi > -90.0f) { - subghz->txrx->hopper_timeout = 10; - subghz->txrx->hopper_state = SubGhzHopperStateRSSITimeOut; - return; - } - } else { - subghz->txrx->hopper_state = SubGhzHopperStateRunning; - } - // Select next frequency - if(subghz->txrx->hopper_idx_frequency < - subghz_setting_get_hopper_frequency_count(subghz->setting) - 1) { - subghz->txrx->hopper_idx_frequency++; - } else { - subghz->txrx->hopper_idx_frequency = 0; - } - - if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz); - } - if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) { - subghz_receiver_reset(subghz->txrx->receiver); - subghz->txrx->preset->frequency = subghz_setting_get_hopper_frequency( - subghz->setting, subghz->txrx->hopper_idx_frequency); - subghz_rx(subghz, subghz->txrx->preset->frequency); - } + subghz->lock = SubGhzLockOn; } -void subghz_speaker_on(SubGhz* subghz) { - if(subghz->txrx->debug_pin_state) { - furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton); - } - - if(subghz->txrx->speaker_state == SubGhzSpeakerStateEnable) { - if(furi_hal_speaker_acquire(30)) { - if(!subghz->txrx->debug_pin_state) { - furi_hal_subghz_set_async_mirror_pin(&gpio_speaker); - } - } else { - subghz->txrx->speaker_state = SubGhzSpeakerStateDisable; - } - } +void subghz_unlock(SubGhz* subghz) { + furi_assert(subghz); + subghz->lock = SubGhzLockOff; } -void subghz_speaker_off(SubGhz* subghz) { - if(subghz->txrx->debug_pin_state) { - furi_hal_subghz_set_async_mirror_pin(NULL); - } - if(subghz->txrx->speaker_state != SubGhzSpeakerStateDisable) { - if(furi_hal_speaker_is_mine()) { - if(!subghz->txrx->debug_pin_state) { - furi_hal_subghz_set_async_mirror_pin(NULL); - } - furi_hal_speaker_release(); - if(subghz->txrx->speaker_state == SubGhzSpeakerStateShutdown) - subghz->txrx->speaker_state = SubGhzSpeakerStateDisable; - } - } +bool subghz_is_locked(SubGhz* subghz) { + furi_assert(subghz); + return (subghz->lock == SubGhzLockOn); } -void subghz_speaker_mute(SubGhz* subghz) { - if(subghz->txrx->debug_pin_state) { - furi_hal_subghz_set_async_mirror_pin(NULL); - } - if(subghz->txrx->speaker_state == SubGhzSpeakerStateEnable) { - if(furi_hal_speaker_is_mine()) { - if(!subghz->txrx->debug_pin_state) { - furi_hal_subghz_set_async_mirror_pin(NULL); - } - } - } +void subghz_rx_key_state_set(SubGhz* subghz, SubGhzRxKeyState state) { + furi_assert(subghz); + subghz->rx_key_state = state; } -void subghz_speaker_unmute(SubGhz* subghz) { - if(subghz->txrx->debug_pin_state) { - furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton); - } - if(subghz->txrx->speaker_state == SubGhzSpeakerStateEnable) { - if(furi_hal_speaker_is_mine()) { - if(!subghz->txrx->debug_pin_state) { - furi_hal_subghz_set_async_mirror_pin(&gpio_speaker); - } - } - } +SubGhzRxKeyState subghz_rx_key_state_get(SubGhz* subghz) { + furi_assert(subghz); + return subghz->rx_key_state; } diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index 37318580f..f1b063457 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -41,6 +41,10 @@ #include "rpc/rpc_app.h" +#include "helpers/subghz_threshold_rssi.h" + +#include "helpers/subghz_txrx.h" + #define SUBGHZ_MAX_LEN_NAME 64 #define SUBGHZ_EXT_PRESET_NAME true @@ -56,38 +60,6 @@ typedef enum { SubGhzDecodeRawStateLoaded, } SubGhzDecodeRawState; -struct SubGhzTxRx { - SubGhzWorker* worker; - - SubGhzEnvironment* environment; - SubGhzReceiver* receiver; - SubGhzTransmitter* transmitter; - SubGhzProtocolFlag filter; - SubGhzProtocolDecoderBase* decoder_result; - FlipperFormat* fff_data; - SecureData* secure_data; - - SubGhzRadioPreset* preset; - SubGhzHistory* history; - uint16_t idx_menu_chosen; - SubGhzTxRxState txrx_state; - SubGhzHopperState hopper_state; - SubGhzSpeakerState speaker_state; - bool ignore_starline; - bool ignore_auto_alarms; - bool ignore_magellan; - uint8_t hopper_timeout; - uint8_t hopper_idx_frequency; - SubGhzRxKeyState rx_key_state; - - bool debug_pin_state; - - float raw_threshold_rssi; - uint8_t raw_threshold_rssi_low_count; -}; - -typedef struct SubGhzTxRx SubGhzTxRx; - struct SubGhz { Gui* gui; NotificationApp* notifications; @@ -120,60 +92,65 @@ struct SubGhz { SubGhzTestStatic* subghz_test_static; SubGhzTestPacket* subghz_test_packet; #endif - FuriString* error_str; - SubGhzSetting* setting; SubGhzLastSettings* last_settings; + + SubGhzProtocolFlag filter; + FuriString* error_str; SubGhzLock lock; bool in_decoder_scene; bool in_decoder_scene_skip; + bool ignore_starline; + bool ignore_auto_alarms; + bool ignore_magellan; + + SecureData* secure_data; + SubGhzDecodeRawState decode_raw_state; SubGhzFileEncoderWorker* decode_raw_file_worker_encoder; + SubGhzThresholdRssi* threshold_rssi; + SubGhzRxKeyState rx_key_state; + SubGhzHistory* history; + + uint16_t idx_menu_chosen; + SubGhzLoadTypeFile load_type_file; + bool fav_timeout; FuriTimer* fav_timer; void* rpc_ctx; }; -void subghz_preset_init( - void* context, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size); -bool subghz_set_preset(SubGhz* subghz, const char* preset); -void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, FuriString* modulation); -void subghz_begin(SubGhz* subghz, uint8_t* preset_data); -uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency); -void subghz_rx_end(SubGhz* subghz); -void subghz_sleep(SubGhz* subghz); - -void subghz_blink_start(SubGhz* instance); -void subghz_blink_stop(SubGhz* instance); +void subghz_set_default_preset(SubGhz* subghz); +void subghz_blink_start(SubGhz* subghz); +void subghz_blink_stop(SubGhz* subghz); bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format); -void subghz_tx_stop(SubGhz* subghz); void subghz_dialog_message_show_only_rx(SubGhz* subghz); + bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog); bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len); bool subghz_save_protocol_to_file( SubGhz* subghz, FlipperFormat* flipper_format, const char* dev_file_name); +void subghz_save_to_file(void* context); bool subghz_load_protocol_from_file(SubGhz* subghz); bool subghz_rename_file(SubGhz* subghz); bool subghz_file_available(SubGhz* subghz); bool subghz_delete_file(SubGhz* subghz); void subghz_file_name_clear(SubGhz* subghz); bool subghz_path_is_file(FuriString* path); -uint32_t subghz_random_serial(void); -void subghz_hopper_update(SubGhz* subghz); -void subghz_speaker_on(SubGhz* subghz); -void subghz_speaker_off(SubGhz* subghz); -void subghz_speaker_mute(SubGhz* subghz); -void subghz_speaker_unmute(SubGhz* subghz); +SubGhzLoadTypeFile subghz_get_load_type_file(SubGhz* subghz); + +void subghz_lock(SubGhz* subghz); +void subghz_unlock(SubGhz* subghz); +bool subghz_is_locked(SubGhz* subghz); + +void subghz_rx_key_state_set(SubGhz* subghz, SubGhzRxKeyState state); +SubGhzRxKeyState subghz_rx_key_state_get(SubGhz* subghz); extern const NotificationSequence subghz_sequence_rx; extern const NotificationSequence subghz_sequence_rx_locked; diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index bcc7181f0..20afe8c12 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -51,7 +51,7 @@ typedef enum { } SubGhzViewReceiverBarShow; struct SubGhzViewReceiver { - SubGhzLock lock; + bool lock; uint8_t lock_count; FuriTimer* timer; View* view; @@ -97,10 +97,10 @@ void subghz_receiver_rssi(SubGhzViewReceiver* instance, float rssi) { true); } -void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLock lock) { +void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, bool lock) { furi_assert(subghz_receiver); subghz_receiver->lock_count = 0; - if(lock == SubGhzLockOn) { + if(lock == true) { subghz_receiver->lock = lock; with_view_model( subghz_receiver->view, @@ -399,7 +399,7 @@ static void subghz_view_receiver_timer_callback(void* context) { subghz_receiver->callback( SubGhzCustomEventViewReceiverOffDisplay, subghz_receiver->context); } else { - subghz_receiver->lock = SubGhzLockOff; + subghz_receiver->lock = false; subghz_receiver->callback(SubGhzCustomEventViewReceiverUnlock, subghz_receiver->context); } subghz_receiver->lock_count = 0; @@ -409,7 +409,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { furi_assert(context); SubGhzViewReceiver* subghz_receiver = context; - if(subghz_receiver->lock == SubGhzLockOn) { + if(subghz_receiver->lock == true) { with_view_model( subghz_receiver->view, SubGhzViewReceiverModel * model, @@ -429,7 +429,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { SubGhzViewReceiverModel * model, { model->bar_show = SubGhzViewReceiverBarShowUnlock; }, true); - //subghz_receiver->lock = SubGhzLockOff; + //subghz_receiver->lock = false; furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(650)); } @@ -554,7 +554,7 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() { // View allocation and configuration subghz_receiver->view = view_alloc(); - subghz_receiver->lock = SubGhzLockOff; + subghz_receiver->lock = false; subghz_receiver->lock_count = 0; view_allocate_model( subghz_receiver->view, ViewModelTypeLocking, sizeof(SubGhzViewReceiverModel)); diff --git a/applications/main/subghz/views/receiver.h b/applications/main/subghz/views/receiver.h index f5ec86b4b..54c1b3e7d 100644 --- a/applications/main/subghz/views/receiver.h +++ b/applications/main/subghz/views/receiver.h @@ -14,7 +14,7 @@ void subghz_view_receiver_set_mode( 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, bool keyboard); void subghz_view_receiver_set_callback( SubGhzViewReceiver* subghz_receiver, diff --git a/lib/subghz/protocols/alutech_at_4n.c b/lib/subghz/protocols/alutech_at_4n.c index 20dae49c1..47cf37d6b 100644 --- a/lib/subghz/protocols/alutech_at_4n.c +++ b/lib/subghz/protocols/alutech_at_4n.c @@ -429,10 +429,8 @@ static bool subghz_protocol_encoder_alutech_at_4n_get_upload( if((custom_btn_id == 0) && (original_btn_num != 0)) { btn = original_btn_num; } - //gen new key - if(subghz_protocol_alutech_at_4n_gen_data(instance, btn)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { + // Gen new key + if(!subghz_protocol_alutech_at_4n_gen_data(instance, btn)) { return false; } diff --git a/lib/subghz/protocols/keeloq_common.c b/lib/subghz/protocols/keeloq_common.c index 1d2d04457..a9a2238dd 100644 --- a/lib/subghz/protocols/keeloq_common.c +++ b/lib/subghz/protocols/keeloq_common.c @@ -23,7 +23,7 @@ inline uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const } /** Simple Learning Decrypt - * @param data - keelog encrypt data + * @param data - keeloq encrypt data * @param key - manufacture (64bit) * @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter */ diff --git a/lib/subghz/protocols/kinggates_stylo_4k.c b/lib/subghz/protocols/kinggates_stylo_4k.c index a9127d2b1..c5d21bcb0 100644 --- a/lib/subghz/protocols/kinggates_stylo_4k.c +++ b/lib/subghz/protocols/kinggates_stylo_4k.c @@ -197,9 +197,7 @@ static bool subghz_protocol_encoder_kinggates_stylo_4k_get_upload( furi_assert(instance); // Gen new key - if(subghz_protocol_kinggates_stylo_4k_gen_data(instance, btn)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { + if(!subghz_protocol_kinggates_stylo_4k_gen_data(instance, btn)) { return false; } diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index dd860a61d..4074d757b 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -208,10 +208,8 @@ static bool subghz_protocol_encoder_somfy_keytis_get_upload( uint8_t btn) { furi_assert(instance); - //gen new key - if(subghz_protocol_somfy_keytis_gen_data(instance, btn)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { + // Gen new key + if(!subghz_protocol_somfy_keytis_gen_data(instance, btn)) { return false; } diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 047efb688..57c6c510b 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -254,10 +254,8 @@ static bool subghz_protocol_encoder_somfy_telis_get_upload( uint8_t btn) { furi_assert(instance); - //gen new key - if(subghz_protocol_somfy_telis_gen_data(instance, btn, false)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { + // Gen new key + if(!subghz_protocol_somfy_telis_gen_data(instance, btn, false)) { return false; } diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index 181dee643..cb9b26760 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -237,10 +237,8 @@ static bool subghz_protocol_encoder_star_line_get_upload( uint8_t btn) { furi_assert(instance); - //gen new key - if(subghz_protocol_star_line_gen_data(instance, btn)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { + // Gen new key + if(!subghz_protocol_star_line_gen_data(instance, btn)) { return false; }