mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2025-02-17 13:58:32 +00:00
Merge pull request #461 from gid9798/subghz_refactoring_step_by_step
SubGhz app refactoring
This commit is contained in:
commit
02610abd40
41 changed files with 2245 additions and 1512 deletions
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
60
applications/main/subghz/helpers/subghz_threshold_rssi.c
Normal file
60
applications/main/subghz/helpers/subghz_threshold_rssi.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "subghz_threshold_rssi.h"
|
||||
#include <float_tools.h>
|
||||
#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;
|
||||
}
|
43
applications/main/subghz/helpers/subghz_threshold_rssi.h
Normal file
43
applications/main/subghz/helpers/subghz_threshold_rssi.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
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);
|
563
applications/main/subghz/helpers/subghz_txrx.c
Normal file
563
applications/main/subghz/helpers/subghz_txrx.c
Normal file
|
@ -0,0 +1,563 @@
|
|||
#include "subghz_txrx_i.h"
|
||||
#include <lib/subghz/protocols/protocol_items.h>
|
||||
|
||||
#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;
|
||||
}
|
296
applications/main/subghz/helpers/subghz_txrx.h
Normal file
296
applications/main/subghz/helpers/subghz_txrx.h
Normal file
|
@ -0,0 +1,296 @@
|
|||
#pragma once
|
||||
|
||||
#include "subghz_types.h"
|
||||
|
||||
#include <lib/subghz/subghz_worker.h>
|
||||
#include <lib/subghz/subghz_setting.h>
|
||||
#include <lib/subghz/receiver.h>
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/protocols/raw.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,346 @@
|
|||
#include "subghz_txrx_i.h"
|
||||
#include "subghz_txrx_create_protocol_key.h"
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/protocols/protocol_items.h>
|
||||
#include <lib/subghz/protocols/keeloq.h>
|
||||
#include <lib/subghz/protocols/secplus_v1.h>
|
||||
#include <lib/subghz/protocols/secplus_v2.h>
|
||||
#include <lib/subghz/protocols/nice_flor_s.h>
|
||||
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <lib/toolbox/stream/stream.h>
|
||||
#include <lib/subghz/protocols/raw.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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);
|
29
applications/main/subghz/helpers/subghz_txrx_i.h
Normal file
29
applications/main/subghz/helpers/subghz_txrx_i.h
Normal file
|
@ -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;
|
||||
};
|
|
@ -80,6 +80,13 @@ typedef enum {
|
|||
SubGhzViewIdTestPacket,
|
||||
} SubGhzViewId;
|
||||
|
||||
/** SubGhz load type file */
|
||||
typedef enum {
|
||||
SubGhzLoadTypeFileNoLoad,
|
||||
SubGhzLoadTypeFileKey,
|
||||
SubGhzLoadTypeFileRaw,
|
||||
} SubGhzLoadTypeFile;
|
||||
|
||||
typedef enum {
|
||||
SubGhzViewReceiverModeLive,
|
||||
SubGhzViewReceiverModeFile,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
@ -164,7 +164,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]);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,69 +91,55 @@ 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);
|
||||
}
|
||||
|
||||
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)) {
|
||||
|
@ -169,16 +154,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;
|
||||
|
@ -191,13 +167,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;
|
||||
|
@ -207,7 +183,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 {
|
||||
|
@ -227,33 +203,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(
|
||||
|
@ -267,32 +232,22 @@ 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);
|
||||
consumed = true;
|
||||
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) {
|
||||
|
@ -302,32 +257,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);
|
||||
|
@ -340,7 +284,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(
|
||||
|
@ -359,41 +303,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);
|
||||
|
@ -410,13 +328,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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
typedef enum {
|
||||
SubGhzRpcStateIdle,
|
||||
SubGhzRpcStateLoaded,
|
||||
SubGhzRpcStateTx,
|
||||
} SubGhzRpcState;
|
||||
|
||||
void subghz_scene_rpc_on_enter(void* context) {
|
||||
|
@ -42,9 +43,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) {
|
||||
|
@ -56,10 +57,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);
|
||||
|
@ -97,9 +98,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -27,10 +27,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);
|
||||
|
@ -39,8 +39,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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "../subghz_i.h"
|
||||
#include <lib/subghz/protocols/faac_slh.h>
|
||||
#include <lib/subghz/protocols/keeloq.h>
|
||||
#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.");
|
||||
|
|
|
@ -1,102 +1,10 @@
|
|||
#include "../subghz_i.h"
|
||||
#include <lib/subghz/protocols/keeloq.h>
|
||||
#include <lib/subghz/protocols/nice_flor_s.h>
|
||||
#include <lib/subghz/protocols/faac_slh.h>
|
||||
#include <lib/subghz/protocols/secplus_v1.h>
|
||||
#include <lib/subghz/protocols/secplus_v2.h>
|
||||
#include "../helpers/subghz_txrx_create_protocol_key.h"
|
||||
#include <lib/subghz/blocks/math.h>
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <lib/toolbox/stream/stream.h>
|
||||
#include <lib/subghz/protocols/protocol_items.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -93,7 +93,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) {
|
||||
|
|
|
@ -15,29 +15,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);
|
||||
|
@ -70,40 +66,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);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -51,16 +51,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));
|
||||
|
||||
|
@ -180,10 +170,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) {
|
||||
|
@ -193,7 +188,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);
|
||||
|
||||
|
@ -204,7 +199,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);
|
||||
|
||||
|
@ -215,7 +210,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);
|
||||
|
||||
|
@ -226,7 +221,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);
|
||||
|
||||
|
@ -236,7 +231,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);
|
||||
}
|
||||
|
@ -253,52 +248,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();
|
||||
|
@ -316,7 +283,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
|
||||
|
@ -386,27 +355,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);
|
||||
|
@ -439,12 +400,6 @@ int32_t subghz_app(void* 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();
|
||||
|
||||
|
@ -471,9 +426,9 @@ int32_t subghz_app(void* p) {
|
|||
if(subghz_key_load(subghz, p, true)) {
|
||||
furi_string_set(subghz->file_path, (const char*)p);
|
||||
|
||||
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
|
||||
|
@ -489,7 +444,7 @@ int32_t subghz_app(void* 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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,57 +92,62 @@ 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;
|
||||
|
||||
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;
|
||||
|
|
|
@ -49,7 +49,7 @@ typedef enum {
|
|||
} SubGhzViewReceiverBarShow;
|
||||
|
||||
struct SubGhzViewReceiver {
|
||||
SubGhzLock lock;
|
||||
bool lock;
|
||||
uint8_t lock_count;
|
||||
FuriTimer* timer;
|
||||
View* view;
|
||||
|
@ -95,10 +95,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,
|
||||
|
@ -394,7 +394,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;
|
||||
|
@ -404,7 +404,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,
|
||||
|
@ -424,7 +424,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));
|
||||
}
|
||||
|
||||
|
@ -549,7 +549,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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue