1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-13 05:06:30 +04:00

SubGhz: moving "txrx" entity to a separate file

This commit is contained in:
gid9798
2023-05-09 12:07:36 +03:00
parent ee85541d2a
commit b99d309feb
20 changed files with 1161 additions and 1080 deletions

View File

@@ -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->setting;
instance->trigger_level = subghz->last_settings->frequency_analyzer_trigger;
//instance->trigger_level = SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD;
return instance;

View File

@@ -87,12 +87,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_txtx_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_txtx_get_fff_data(subghz->txrx), "File_name", file_name)) {
FURI_LOG_E(TAG, "Missing File_name");
break;
}
@@ -193,7 +194,7 @@ void subghz_scene_decode_raw_on_enter(void* context) {
}
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);
@@ -208,7 +209,7 @@ 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;
@@ -227,8 +228,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);

View File

@@ -48,7 +48,8 @@ bool subghz_scene_need_saving_on_event(void* context, SceneManagerEvent event) {
} else if(event.event == SubGhzCustomEventSceneExit) {
if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateExit) {
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0);
subghz_preset_init(
subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0);
scene_manager_search_and_switch_to_previous_scene(
subghz->scene_manager, SubGhzSceneStart);
} else {

View File

@@ -13,12 +13,13 @@ bool subghz_scene_read_raw_update_filename(SubGhz* subghz) {
//set the path to read the file
FuriString* temp_str = furi_string_alloc();
do {
if(!flipper_format_rewind(subghz->txrx->fff_data)) {
if(!flipper_format_rewind(subghz_txtx_get_fff_data(subghz->txrx))) {
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(
subghz_txtx_get_fff_data(subghz->txrx), "File_name", temp_str)) {
FURI_LOG_E(TAG, "Missing File_name");
break;
}
@@ -127,7 +128,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SubGhzCustomEventViewReadRAWBack:
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
//Stop save file
subghz_protocol_raw_save_to_file_stop(
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result);
@@ -141,13 +142,14 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
//Restore default setting
if(subghz->raw_send_only) {
subghz_preset_init(
subghz,
subghz->txrx,
"AM650",
subghz_setting_get_default_frequency(subghz->setting),
subghz_setting_get_default_frequency(subghz->txrx->setting),
NULL,
0);
} else {
subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0);
subghz_preset_init(
subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0);
}
if(!scene_manager_search_and_switch_to_previous_scene(
subghz->scene_manager, SubGhzSceneSaved)) {
@@ -162,7 +164,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
break;
case SubGhzCustomEventViewReadRAWTXRXStop:
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
subghz->state_notifications = SubGhzNotificationStateIDLE;
consumed = true;
break;
@@ -212,8 +214,8 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
//start send
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_txrx_stop(subghz);
if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) {
subghz_txrx_stop(subghz->txrx);
if(!subghz_tx_start(subghz->txrx, subghz_txtx_get_fff_data(subghz->txrx))) {
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateBack);
subghz_read_raw_set_status(
subghz->subghz_read_raw,
@@ -245,13 +247,13 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
case SubGhzCustomEventViewReadRAWSendStop:
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
subghz_read_raw_stop_send(subghz->subghz_read_raw);
consumed = true;
break;
case SubGhzCustomEventViewReadRAWIDLE:
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
size_t spl_count = subghz_protocol_raw_get_sample_write(
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result);
@@ -262,7 +264,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
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_txtx_get_fff_data(subghz->txrx), furi_string_get_cstr(temp_str));
furi_string_free(temp_str);
if(spl_count > 0) {
@@ -286,12 +288,13 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
RAW_FILE_NAME,
subghz->txrx->preset)) {
DOLPHIN_DEED(DolphinDeedSubGhzRawRec);
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
subghz_begin(
subghz,
subghz->txrx,
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->setting,
furi_string_get_cstr(subghz->txrx->preset->name)));
subghz_rx(subghz->txrx, subghz->txrx->preset->frequency);
subghz->state_notifications = SubGhzNotificationStateRx;
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateAddKey);
@@ -355,7 +358,7 @@ void subghz_scene_read_raw_on_exit(void* context) {
SubGhz* subghz = context;
//Stop CC1101
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
subghz->state_notifications = SubGhzNotificationStateIDLE;
notification_message(subghz->notifications, &sequence_reset_rgb);

View File

@@ -122,7 +122,7 @@ void subghz_scene_receiver_on_enter(void* context) {
FuriString* item_time = furi_string_alloc();
if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateIDLE) {
subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0);
subghz_preset_init(subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0);
subghz_history_reset(subghz->txrx->history);
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart);
}
@@ -154,7 +154,7 @@ void subghz_scene_receiver_on_enter(void* context) {
// 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) {
if(subghz->ignore_starline == true) {
SubGhzProtocolDecoderBase* protocoldecoderbase = NULL;
protocoldecoderbase =
subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, "Star Line");
@@ -163,7 +163,7 @@ void subghz_scene_receiver_on_enter(void* context) {
protocoldecoderbase, NULL, subghz->txrx->receiver);
}
}
if(subghz->txrx->ignore_auto_alarms == true) {
if(subghz->ignore_auto_alarms == true) {
SubGhzProtocolDecoderBase* protocoldecoderbase = NULL;
protocoldecoderbase =
subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, "KIA Seed");
@@ -179,7 +179,7 @@ void subghz_scene_receiver_on_enter(void* context) {
protocoldecoderbase, NULL, subghz->txrx->receiver);
}
}
if(subghz->txrx->ignore_magellan == true) {
if(subghz->ignore_magellan == true) {
SubGhzProtocolDecoderBase* protocoldecoderbase = NULL;
protocoldecoderbase =
subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, "Magellan");
@@ -190,13 +190,13 @@ void subghz_scene_receiver_on_enter(void* context) {
}
subghz->state_notifications = SubGhzNotificationStateRx;
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
subghz_begin(
subghz,
subghz->txrx,
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->setting, furi_string_get_cstr(subghz->txrx->preset->name)));
subghz_rx(subghz->txrx, subghz->txrx->preset->frequency);
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(
@@ -214,9 +214,9 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
case SubGhzCustomEventViewReceiverBack:
// Stop CC1101 Rx
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_txrx_stop(subghz);
subghz_hopper_set_state(subghz, SubGhzHopperStateOFF);
subghz->txrx->idx_menu_chosen = 0;
subghz_txrx_stop(subghz->txrx);
subghz_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF);
subghz->idx_menu_chosen = 0;
subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz);
if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateAddKey) {
@@ -224,7 +224,8 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
} else {
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0);
subghz_preset_init(
subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0);
scene_manager_search_and_switch_to_previous_scene(
subghz->scene_manager, SubGhzSceneStart);
}
@@ -232,17 +233,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->txrx->history, subghz->idx_menu_chosen);
subghz_view_receiver_delete_element_callback(subghz->subghz_receiver);
subghz_scene_receiver_update_statusbar(subghz);
@@ -250,8 +249,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);
@@ -269,8 +267,8 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
break;
}
} else if(event.type == SceneManagerEventTypeTick) {
if(subghz_hopper_get_state(subghz) != SubGhzHopperStateOFF) {
subghz_hopper_update(subghz);
if(subghz_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF) {
subghz_hopper_update(subghz->txrx);
subghz_scene_receiver_update_statusbar(subghz);
}

View File

@@ -93,12 +93,12 @@ uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void*
furi_assert(context);
SubGhz* subghz = context;
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(subghz->txrx->setting); i++) {
if(value == subghz_setting_get_frequency(subghz->txrx->setting, i)) {
index = i;
break;
} else {
index = subghz_setting_get_frequency_default_index(subghz->setting);
index = subghz_setting_get_frequency_default_index(subghz->txrx->setting);
}
}
return index;
@@ -108,12 +108,12 @@ 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)) {
for(uint8_t i = 0; i < subghz_setting_get_preset_count(subghz->txrx->setting); i++) {
if(!strcmp(subghz_setting_get_preset_name(subghz->txrx->setting, i), preset_name)) {
index = i;
break;
} else {
// index = subghz_setting_get_frequency_default_index(subghz->setting);
// index = subghz_setting_get_frequency_default_index(subghz->txrx->setting);
}
}
return index;
@@ -143,37 +143,39 @@ 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);
if(subghz_hopper_get_state(subghz) == SubGhzHopperStateOFF) {
if(subghz_hopper_get_state(subghz->txrx) == SubGhzHopperStateOFF) {
char text_buf[10] = {0};
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);
subghz_setting_get_frequency(subghz->txrx->setting, index) / 1000000,
(subghz_setting_get_frequency(subghz->txrx->setting, index) % 1000000) / 10000);
variable_item_set_current_value_text(item, text_buf);
subghz->txrx->preset->frequency = subghz_setting_get_frequency(subghz->setting, index);
subghz->txrx->preset->frequency =
subghz_setting_get_frequency(subghz->txrx->setting, index);
subghz->last_settings->frequency = subghz->txrx->preset->frequency;
subghz_setting_set_default_frequency(subghz->setting, subghz->txrx->preset->frequency);
subghz_setting_set_default_frequency(
subghz->txrx->setting, subghz->txrx->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(subghz->txrx->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);
const char* preset_name = subghz_setting_get_preset_name(subghz->txrx->setting, index);
variable_item_set_current_value_text(item, preset_name);
//subghz->last_settings->preset = index;
subghz_preset_init(
subghz,
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));
subghz_setting_get_preset_data(subghz->txrx->setting, index),
subghz_setting_get_preset_data_size(subghz->txrx->setting, index));
}
static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) {
@@ -187,17 +189,18 @@ static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item)
text_buf,
sizeof(text_buf),
"%lu.%02lu",
subghz_setting_get_default_frequency(subghz->setting) / 1000000,
(subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000);
subghz_setting_get_default_frequency(subghz->txrx->setting) / 1000000,
(subghz_setting_get_default_frequency(subghz->txrx->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);
subghz->txrx->preset->frequency =
subghz_setting_get_default_frequency(subghz->txrx->setting);
variable_item_set_current_value_index(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
subghz_setting_get_frequency_default_index(subghz->setting));
subghz_setting_get_frequency_default_index(subghz->txrx->setting));
} else {
variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state(
@@ -206,10 +209,10 @@ static void subghz_scene_receiver_config_set_hopping_running(VariableItem* 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));
subghz_setting_get_frequency_default_index(subghz->txrx->setting));
}
subghz_hopper_set_state(subghz, hopping_value[index]);
subghz_hopper_set_state(subghz->txrx, hopping_value[index]);
}
static void subghz_scene_receiver_config_set_speaker(VariableItem* item) {
@@ -217,7 +220,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_speaker_set_state(subghz, speaker_value[index]);
subghz_speaker_set_state(subghz->txrx, speaker_value[index]);
}
static void subghz_scene_receiver_config_set_bin_raw(VariableItem* item) {
@@ -242,7 +245,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 +253,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 +261,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) {
@@ -278,7 +281,7 @@ void subghz_scene_receiver_config_on_enter(void* context) {
item = variable_item_list_add(
subghz->variable_item_list,
"Frequency:",
subghz_setting_get_frequency_count(subghz->setting),
subghz_setting_get_frequency_count(subghz->txrx->setting),
subghz_scene_receiver_config_set_frequency,
subghz);
value_index =
@@ -291,21 +294,21 @@ void subghz_scene_receiver_config_on_enter(void* context) {
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);
subghz_setting_get_frequency(subghz->txrx->setting, value_index) / 1000000,
(subghz_setting_get_frequency(subghz->txrx->setting, value_index) % 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(subghz->txrx->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);
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(subghz->txrx->setting, value_index));
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerSet) {
@@ -317,7 +320,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_hopper_get_state(subghz), hopping_value, HOPPING_COUNT, subghz);
subghz_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]);
}
@@ -344,7 +347,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 +358,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 +369,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]);
}
@@ -379,7 +382,7 @@ void subghz_scene_receiver_config_on_enter(void* context) {
subghz_scene_receiver_config_set_speaker,
subghz);
value_index =
value_index_uint32(subghz_speaker_get_state(subghz), speaker_value, SPEAKER_COUNT);
value_index_uint32(subghz_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]);

View File

@@ -25,18 +25,18 @@ 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));
subghz_history_get_protocol_name(subghz->txrx->history, subghz->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
subghz_protocol_decoder_base_deserialize(
subghz->txrx->decoder_result,
subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
subghz_history_get_raw_data(subghz->txrx->history, subghz->idx_menu_chosen));
SubGhzRadioPreset* preset =
subghz_history_get_radio_preset(subghz->txrx->history, subghz->txrx->idx_menu_chosen);
subghz_history_get_radio_preset(subghz->txrx->history, subghz->idx_menu_chosen);
subghz_preset_init(
subghz,
subghz->txrx,
furi_string_get_cstr(preset->name),
preset->frequency,
preset->data,
@@ -122,25 +122,24 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubGhzCustomEventSceneReceiverInfoTxStart) {
//CC1101 Stop RX -> Start TX
subghz_subghz_hopper_set_pause(subghz);
subghz_subghz_hopper_set_pause(subghz->txrx);
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
if(!subghz_scene_receiver_info_update_parser(subghz)) {
return false;
}
if(!subghz_tx_start(
subghz,
subghz_history_get_raw_data(
subghz->txrx->history, subghz->txrx->idx_menu_chosen))) {
subghz_txrx_stop(subghz);
subghz->txrx,
subghz_history_get_raw_data(subghz->txrx->history, subghz->idx_menu_chosen))) {
subghz_txrx_stop(subghz->txrx);
subghz_begin(
subghz,
subghz->txrx,
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_hopper_remove_pause(subghz);
subghz->txrx->setting, furi_string_get_cstr(subghz->txrx->preset->name)));
subghz_rx(subghz->txrx, subghz->txrx->preset->frequency);
subghz_hopper_remove_pause(subghz->txrx);
subghz->state_notifications = SubGhzNotificationStateRx;
} else {
subghz->state_notifications = SubGhzNotificationStateTx;
@@ -153,24 +152,24 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
widget_reset(subghz->widget);
subghz_scene_receiver_info_draw_widget(subghz);
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
if(!subghz->in_decoder_scene) {
subghz_begin(
subghz,
subghz->txrx,
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->setting, furi_string_get_cstr(subghz->txrx->preset->name)));
subghz_rx(subghz->txrx, subghz->txrx->preset->frequency);
subghz_hopper_remove_pause(subghz);
subghz_hopper_remove_pause(subghz->txrx);
subghz->state_notifications = SubGhzNotificationStateRx;
}
return true;
} else if(event.event == SubGhzCustomEventSceneReceiverInfoSave) {
//CC1101 Stop RX -> Save
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_hopper_set_state(subghz, SubGhzHopperStateOFF);
subghz_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF);
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
if(!subghz_scene_receiver_info_update_parser(subghz)) {
return false;
}
@@ -187,8 +186,8 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
return true;
}
} else if(event.type == SceneManagerEventTypeTick) {
if(subghz_hopper_get_state(subghz) != SubGhzHopperStateOFF) {
subghz_hopper_update(subghz);
if(subghz_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF) {
subghz_hopper_update(subghz->txrx);
}
switch(subghz->state_notifications) {
case SubGhzNotificationStateTx:

View File

@@ -42,9 +42,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_get_state(subghz) == SubGhzTxRxStateSleep) &&
if((subghz_txrx_get_state(subghz->txrx) == SubGhzTxRxStateSleep) &&
(state == SubGhzRpcStateLoaded)) {
result = subghz_tx_start(subghz, subghz->txrx->fff_data);
result = subghz_tx_start(subghz->txrx, subghz_txtx_get_fff_data(subghz->txrx));
if(result) subghz_blink_start(subghz);
}
if(!result) {
@@ -56,8 +56,8 @@ 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_get_state(subghz) == SubGhzTxRxStateTx) {
subghz_txrx_stop(subghz);
if(subghz_txrx_get_state(subghz->txrx) == SubGhzTxRxStateTx) {
subghz_txrx_stop(subghz->txrx);
subghz_blink_stop(subghz);
result = true;
}
@@ -96,8 +96,8 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
void subghz_scene_rpc_on_exit(void* context) {
SubGhz* subghz = context;
if(subghz_txrx_get_state(subghz) == SubGhzTxRxStateTx) {
subghz_txrx_stop(subghz);
if(subghz_txrx_get_state(subghz->txrx) == SubGhzTxRxStateTx) {
subghz_txrx_stop(subghz->txrx);
subghz_blink_stop(subghz);
}

View File

@@ -146,7 +146,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
SubGhzCustomEventManagerNoSet) {
subghz_save_protocol_to_file(
subghz,
subghz->txrx->fff_data,
subghz_txtx_get_fff_data(subghz->txrx),
furi_string_get_cstr(subghz->file_path));
scene_manager_set_scene_state(
subghz->scene_manager,
@@ -156,7 +156,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
subghz_save_protocol_to_file(
subghz,
subghz_history_get_raw_data(
subghz->txrx->history, subghz->txrx->idx_menu_chosen),
subghz->txrx->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_txtx_get_fff_data(subghz->txrx),
furi_string_get_cstr(subghz->file_path));
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet);
} else {

View File

@@ -39,7 +39,7 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event)
}
} else {
subghz->decode_raw_state = SubGhzDecodeRawStateStart;
subghz->txrx->idx_menu_chosen = 0;
subghz->idx_menu_chosen = 0;
subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz);
if(subghz_file_encoder_worker_is_running(subghz->decode_raw_file_worker_encoder)) {

View File

@@ -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:

View File

@@ -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);
}

View File

@@ -19,7 +19,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);
}
@@ -36,20 +36,16 @@ 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];
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq_bft(
subghz,
subghz->txrx,
"AM650",
433920000,
fix_part & 0x0FFFFFFF,
@@ -67,22 +63,18 @@ 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];
if(state == SubmenuIndexFaacSLH_433) {
generated_protocol = subghz_scene_set_type_submenu_gen_data_faac_slh(
subghz,
subghz->txrx,
"AM650",
433920000,
fix_part >> 4,
@@ -92,7 +84,7 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
"FAAC_SLH");
} else if(state == SubmenuIndexFaacSLH_868) {
generated_protocol = subghz_scene_set_type_submenu_gen_data_faac_slh(
subghz,
subghz->txrx,
"AM650",
868350000,
fix_part >> 4,

View File

@@ -292,7 +292,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
bool generated_protocol = false;
if(event.type == SceneManagerEventTypeCustom) {
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);
@@ -306,68 +306,68 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
case SubmenuIndexPricenton433:
key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8
generated_protocol = subghz_gen_data_protocol_and_te(
subghz, "AM650", 433920000, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 400);
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 400);
break;
case SubmenuIndexPricenton315:
key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8
generated_protocol = subghz_gen_data_protocol_and_te(
subghz, "AM650", 315000000, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 400);
subghz->txrx, "AM650", 315000000, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 400);
break;
case SubmenuIndexNiceFlo12bit:
key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 12);
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 12);
break;
case SubmenuIndexNiceFlo24bit:
key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 24);
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 24);
break;
case SubmenuIndexCAME12bit:
key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12);
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12);
break;
case SubmenuIndexCAME24bit:
key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 24);
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 24);
break;
case SubmenuIndexCAME12bit868:
key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 868350000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12);
subghz->txrx, "AM650", 868350000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12);
break;
case SubmenuIndexCAME24bit868:
key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 868350000, SUBGHZ_PROTOCOL_CAME_NAME, key, 24);
subghz->txrx, "AM650", 868350000, SUBGHZ_PROTOCOL_CAME_NAME, key, 24);
break;
case SubmenuIndexLinear_300_00:
key = (key & 0x3FF);
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 300000000, SUBGHZ_PROTOCOL_LINEAR_NAME, key, 10);
subghz->txrx, "AM650", 300000000, SUBGHZ_PROTOCOL_LINEAR_NAME, key, 10);
break;
case SubmenuIndexBETT_433:
key = (key & 0x0000FFF0);
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 433920000, SUBGHZ_PROTOCOL_BETT_NAME, key, 18);
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_BETT_NAME, key, 18);
break;
case SubmenuIndexCAMETwee:
key = (key & 0x0FFFFFF0);
key = 0x003FFF7200000000 | (key ^ 0xE0E0E0EE);
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_TWEE_NAME, key, 54);
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_TWEE_NAME, key, 54);
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);
generated_protocol = subghz_gen_data_protocol(
subghz, "AM650", 433920000, SUBGHZ_PROTOCOL_GATE_TX_NAME, rev_key, 24);
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_GATE_TX_NAME, rev_key, 24);
break;
case SubmenuIndexBeninca433:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz,
subghz->txrx,
"AM650",
433920000,
(key & 0x000FFF00) | 0x00800080,
@@ -382,7 +382,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexBeninca868:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz,
subghz->txrx,
"AM650",
868350000,
(key & 0x000FFF00) | 0x00800080,
@@ -397,7 +397,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexAllmatic433:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz,
subghz->txrx,
"AM650",
433920000,
(key & 0x00FFFF00) | 0x01000011,
@@ -412,7 +412,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexAllmatic868:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz,
subghz->txrx,
"AM650",
868350000,
(key & 0x00FFFF00) | 0x01000011,
@@ -427,7 +427,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexElmesElectronic:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz,
subghz->txrx,
"AM650",
433920000,
(key & 0x00FFFFFF) | 0x02000000,
@@ -442,7 +442,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexANMotorsAT4:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz,
subghz->txrx,
"AM650",
433920000,
(key & 0x000FFFFF) | 0x04700000,
@@ -457,7 +457,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexAprimatic:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz,
subghz->txrx,
"AM650",
433920000,
(key & 0x000FFFFF) | 0x00600000,
@@ -472,7 +472,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexGibidi433:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Gibidi");
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.");
@@ -481,7 +481,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexGSN:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "AM650", 433920000, key & 0x0FFFFFFF, 0x2, 0x0003, "GSN");
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.");
@@ -490,7 +490,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexIronLogic:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "AM650", 433920000, key & 0x00FFFFF0, 0x4, 0x0005, "IronLogic");
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.");
@@ -499,7 +499,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexSommer_FM_434:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "FM476", 434420000, key & 0x0FFFFFFF, 0x4, 0x0003, "Sommer(fsk476)");
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.");
@@ -508,7 +508,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexSommer_FM_868:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "FM476", 868800000, key & 0x0FFFFFFF, 0x4, 0x0003, "Sommer(fsk476)");
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.");
@@ -517,7 +517,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexDTMNeo433:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "AM650", 433920000, key & 0x000FFFFF, 0x2, 0x0005, "DTM_Neo");
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.");
@@ -526,7 +526,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexCAMESpace:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Came_Space");
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.");
@@ -535,7 +535,14 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexBFTMitto:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq_bft(
subghz, "AM650", 433920000, key & 0x000FFFFF, 0x2, 0x0002, key & 0x000FFFFF, "BFT");
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.");
@@ -544,7 +551,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexAlutechAT4N:
generated_protocol = subghz_scene_set_type_submenu_gen_data_alutech_at_4n(
subghz, "AM650", 433920000, (key & 0x000FFFFF) | 0x00100000, 0x44, 0x0003);
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.");
@@ -553,7 +560,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexSomfyTelis:
generated_protocol = subghz_scene_set_type_submenu_gen_data_somfy_telis(
subghz, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003);
subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003);
if(!generated_protocol) { //TODO does not use databases
furi_string_set(
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
@@ -562,7 +569,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexDoorHan_433_92:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "AM650", 433920000, key & 0x0FFFFFFF, 0x2, 0x0003, "DoorHan");
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.");
@@ -571,7 +578,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexDoorHan_315_00:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "AM650", 315000000, key & 0x0FFFFFFF, 0x2, 0x0003, "DoorHan");
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.");
@@ -580,7 +587,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexNiceFlorS_433_92:
generated_protocol = subghz_scene_set_type_submenu_gen_data_nice_flor(
subghz, "AM650", 433920000, key & 0x0FFFFFFF, 0x1, 0x0003, false);
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.");
@@ -589,7 +596,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexNiceOne_433_92:
generated_protocol = subghz_scene_set_type_submenu_gen_data_nice_flor(
subghz, "AM650", 433920000, key & 0x0FFFFFFF, 0x1, 0x0003, true);
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.");
@@ -598,7 +605,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexNiceSmilo_433_92:
generated_protocol = subghz_scene_set_type_submenu_gen_data_keeloq(
subghz, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "NICE_Smilo");
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.");
@@ -606,29 +613,29 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
}
break;
case SubmenuIndexLiftMaster_315_00:
generated_protocol = subghz_gen_secplus_v1_protocol(subghz, "AM650", 315000000);
generated_protocol = subghz_gen_secplus_v1_protocol(subghz->txrx, "AM650", 315000000);
break;
case SubmenuIndexLiftMaster_390_00:
generated_protocol = subghz_gen_secplus_v1_protocol(subghz, "AM650", 390000000);
generated_protocol = subghz_gen_secplus_v1_protocol(subghz->txrx, "AM650", 390000000);
break;
case SubmenuIndexLiftMaster_433_00:
generated_protocol = subghz_gen_secplus_v1_protocol(subghz, "AM650", 433920000);
generated_protocol = subghz_gen_secplus_v1_protocol(subghz->txrx, "AM650", 433920000);
break;
case SubmenuIndexSecPlus_v2_310_00:
generated_protocol =
subghz_gen_secplus_v2_protocol(subghz, "AM650", 310000000, key, 0x68, 0xE500000);
generated_protocol = subghz_gen_secplus_v2_protocol(
subghz->txrx, "AM650", 310000000, key, 0x68, 0xE500000);
break;
case SubmenuIndexSecPlus_v2_315_00:
generated_protocol =
subghz_gen_secplus_v2_protocol(subghz, "AM650", 315000000, key, 0x68, 0xE500000);
generated_protocol = subghz_gen_secplus_v2_protocol(
subghz->txrx, "AM650", 315000000, key, 0x68, 0xE500000);
break;
case SubmenuIndexSecPlus_v2_390_00:
generated_protocol =
subghz_gen_secplus_v2_protocol(subghz, "AM650", 390000000, key, 0x68, 0xE500000);
generated_protocol = subghz_gen_secplus_v2_protocol(
subghz->txrx, "AM650", 390000000, key, 0x68, 0xE500000);
break;
case SubmenuIndexSecPlus_v2_433_00:
generated_protocol =
subghz_gen_secplus_v2_protocol(subghz, "AM650", 433920000, key, 0x68, 0xE500000);
generated_protocol = subghz_gen_secplus_v2_protocol(
subghz->txrx, "AM650", 433920000, key, 0x68, 0xE500000);
break;
default:
return false;

View File

@@ -23,7 +23,8 @@ bool subghz_scene_transmitter_update_data_show(void* context) {
bool show_button = false;
if(subghz_protocol_decoder_base_deserialize(
subghz->txrx->decoder_result, subghz->txrx->fff_data) == SubGhzProtocolStatusOk) {
subghz->txrx->decoder_result, subghz_txtx_get_fff_data(subghz->txrx)) ==
SubGhzProtocolStatusOk) {
subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, key_str);
if((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Send) ==
@@ -70,8 +71,8 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubGhzCustomEventViewTransmitterSendStart) {
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_txrx_stop(subghz);
if(subghz_tx_start(subghz, subghz->txrx->fff_data)) {
subghz_txrx_stop(subghz->txrx);
if(subghz_tx_start(subghz->txrx, subghz_txtx_get_fff_data(subghz->txrx))) {
subghz->state_notifications = SubGhzNotificationStateTx;
subghz_scene_transmitter_update_data_show(subghz);
DOLPHIN_DEED(DolphinDeedSubGhzSend);
@@ -79,19 +80,19 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
return true;
} else if(event.event == SubGhzCustomEventViewTransmitterSendStop) {
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz_txrx_stop(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!
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) {
if(!subghz_tx_start(subghz->txrx, subghz_txtx_get_fff_data(subghz->txrx))) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
}
subghz_txrx_stop(subghz);
subghz_txrx_stop(subghz->txrx);
furi_hal_subghz_set_rolling_counter_mult(tmp_counter);
}
return true;

View File

@@ -180,10 +180,11 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
subghz_test_static_get_view(subghz->subghz_test_static));
#endif
subghz->txrx = malloc(sizeof(SubGhzTxRx));
//init setting
subghz->setting = subghz_setting_alloc();
subghz->txrx->setting = subghz_setting_alloc();
subghz_setting_load(subghz->setting, EXT_PATH("subghz/assets/setting_user"));
subghz_setting_load(subghz->txrx->setting, EXT_PATH("subghz/assets/setting_user"));
// Custom Presets load without using config file
if(!alloc_for_tx_only) {
@@ -193,7 +194,8 @@ 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(
subghz->txrx->setting, (const char*)"FM95", temp_fm_preset);
flipper_format_free(temp_fm_preset);
@@ -204,7 +206,8 @@ 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(
subghz->txrx->setting, (const char*)"FM15k", temp_fm_preset2);
flipper_format_free(temp_fm_preset2);
@@ -215,7 +218,8 @@ 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(
subghz->txrx->setting, (const char*)"Pagers", temp_fm_preset3);
flipper_format_free(temp_fm_preset3);
@@ -226,7 +230,8 @@ 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(
subghz->txrx->setting, (const char*)"HND_1", temp_fm_preset4);
flipper_format_free(temp_fm_preset4);
@@ -236,7 +241,8 @@ 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(
subghz->txrx->setting, (const char*)"HND_2", temp_fm_preset5);
flipper_format_free(temp_fm_preset5);
}
@@ -253,7 +259,8 @@ 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(
subghz->txrx->setting, subghz->last_settings->frequency);
}
//init threshold rssi
@@ -261,18 +268,22 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
//init Worker & Protocol & History & KeyBoard
subghz_unlock(subghz);
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);
subghz_preset_init(subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0);
} else {
subghz_preset_init(
subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0);
subghz->txrx,
"AM650",
subghz_setting_get_default_frequency(subghz->txrx->setting),
NULL,
0);
}
subghz->txrx->txrx_state = SubGhzTxRxStateSleep;
subghz_hopper_set_state(subghz, SubGhzHopperStateOFF);
subghz_speaker_set_state(subghz, SubGhzSpeakerStateDisable);
subghz_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF);
subghz_speaker_set_state(subghz->txrx, SubGhzSpeakerStateDisable);
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
subghz->txrx->debug_pin_state = false;
if(!alloc_for_tx_only) {
@@ -282,7 +293,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
subghz->txrx->worker = subghz_worker_alloc();
subghz->txrx->fff_data = flipper_format_string_alloc();
subghz->txrx->secure_data = malloc(sizeof(SecureData));
subghz->secure_data = malloc(sizeof(SecureData));
subghz->txrx->environment = subghz_environment_alloc();
subghz_environment_set_came_atomo_rainbow_table_file_name(
@@ -303,6 +314,8 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode);
subghz_worker_set_context(subghz->txrx->worker, subghz->txrx->receiver);
subghz_txrx_need_save_callback_set(subghz->txrx, subghz_save_to_file, subghz);
//Init Error_str
subghz->error_str = furi_string_alloc();
@@ -319,7 +332,7 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) {
subghz->rpc_ctx = NULL;
}
subghz_speaker_off(subghz);
subghz_speaker_off(subghz->txrx);
#if FURI_DEBUG
// Packet Test
@@ -390,7 +403,7 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) {
subghz->gui = NULL;
// setting
subghz_setting_free(subghz->setting);
subghz_setting_free(subghz->txrx->setting);
if(!alloc_for_tx_only) {
subghz_last_settings_free(subghz->last_settings);
}
@@ -412,7 +425,7 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) {
}
furi_string_free(subghz->txrx->preset->name);
free(subghz->txrx->preset);
free(subghz->txrx->secure_data);
free(subghz->secure_data);
free(subghz->txrx);
//Error string

View File

@@ -18,38 +18,6 @@
#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) {
furi_assert(subghz);
if(frequency != NULL) {
@@ -64,195 +32,6 @@ void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, Furi
}
}
void subghz_begin(SubGhz* subghz, uint8_t* preset_data) {
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;
}
uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency) {
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;
}
bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) {
furi_assert(subghz);
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));
}
subghz_idle(subghz);
subghz_speaker_off(subghz);
notification_message(subghz->notifications, &sequence_reset_red);
}
void subghz_txrx_stop(SubGhz* subghz) {
furi_assert(subghz);
switch(subghz->txrx->txrx_state) {
case SubGhzTxRxStateTx:
subghz_tx_stop(subghz);
subghz_speaker_unmute(subghz);
subghz_sleep(subghz);
break;
case SubGhzTxRxStateRx:
subghz_rx_end(subghz);
subghz_speaker_mute(subghz);
subghz_sleep(subghz);
break;
default:
break;
}
}
SubGhzTxRxState subghz_txrx_get_state(SubGhz* subghz) {
furi_assert(subghz);
return subghz->txrx->txrx_state;
}
void subghz_dialog_message_show_only_rx(SubGhz* subghz) {
DialogsApp* dialogs = subghz->dialogs;
DialogMessage* message = dialog_message_alloc();
@@ -275,7 +54,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_txtx_get_fff_data(subghz->txrx));
SubGhzLoadKeyState load_key_state = SubGhzLoadKeyStateParseErr;
FuriString* temp_str = furi_string_alloc();
@@ -301,6 +81,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;
@@ -316,14 +97,15 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
load_key_state = SubGhzLoadKeyStateOnlyRx;
break;
}
subghz->txrx->preset->frequency = temp_data32;
//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))) {
if(!subghz_set_preset(subghz->txrx, furi_string_get_cstr(temp_str))) {
break;
}
@@ -331,10 +113,11 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
//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_txrx_get_setting(subghz->txrx),
furi_string_get_cstr(subghz->txrx->preset->name));
//load custom preset from file
if(!subghz_setting_load_custom_preset(
subghz->setting,
subghz_txrx_get_setting(subghz->txrx),
furi_string_get_cstr(subghz->txrx->preset->name),
fff_data_file)) {
FURI_LOG_E(TAG, "Missing Custom preset");
@@ -342,34 +125,37 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
}
}
size_t preset_index = subghz_setting_get_inx_preset_by_name(
subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name));
subghz_txrx_get_setting(subghz->txrx),
furi_string_get_cstr(subghz->txrx->preset->name));
subghz_preset_init(
subghz,
subghz->txrx,
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));
temp_data32,
subghz_setting_get_preset_data(subghz_txrx_get_setting(subghz->txrx), preset_index),
subghz_setting_get_preset_data_size(
subghz_txrx_get_setting(subghz->txrx), preset_index));
//Load protocol
if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) {
FURI_LOG_E(TAG, "Missing Protocol");
break;
}
if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) {
//if RAW
subghz->txrx->load_type_file = SubGhzLoadTypeFileRaw;
subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, file_path);
subghz->load_type_file = SubGhzLoadTypeFileRaw;
subghz_protocol_raw_gen_fff_data(subghz_txtx_get_fff_data(subghz->txrx), file_path);
} else {
subghz->txrx->load_type_file = SubGhzLoadTypeFileKey;
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(subghz_txtx_get_fff_data(subghz->txrx)));
}
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) {
SubGhzProtocolStatus status = subghz_protocol_decoder_base_deserialize(
subghz->txrx->decoder_result, subghz->txrx->fff_data);
subghz->txrx->decoder_result, subghz_txtx_get_fff_data(subghz->txrx));
if(status != SubGhzProtocolStatusOk) {
load_key_state = SubGhzLoadKeyStateProtocolDescriptionErr;
break;
@@ -416,7 +202,7 @@ 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->txrx->load_type_file;
return subghz->load_type_file;
}
bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) {
@@ -460,6 +246,17 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) {
return res;
}
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_txtx_get_fff_data(subghz->txrx),
furi_string_get_cstr(subghz->file_path));
}
}
bool subghz_save_protocol_to_file(
SubGhz* subghz,
FlipperFormat* flipper_format,
@@ -583,151 +380,6 @@ 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) {
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);
}
}
SubGhzHopperState subghz_hopper_get_state(SubGhz* subghz) {
furi_assert(subghz);
return subghz->txrx->hopper_state;
}
void subghz_hopper_set_state(SubGhz* subghz, SubGhzHopperState state) {
furi_assert(subghz);
subghz->txrx->hopper_state = state;
}
void subghz_hopper_remove_pause(SubGhz* subghz) {
furi_assert(subghz);
if(subghz->txrx->hopper_state == SubGhzHopperStatePause) {
subghz->txrx->hopper_state = SubGhzHopperStateRunning;
}
}
void subghz_subghz_hopper_set_pause(SubGhz* subghz) {
furi_assert(subghz);
if(subghz->txrx->hopper_state == SubGhzHopperStateOFF) {
subghz->txrx->hopper_state = SubGhzHopperStatePause;
}
}
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_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;
}
}
}
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_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);
}
}
}
}
void subghz_speaker_set_state(SubGhz* subghz, SubGhzSpeakerState state) {
furi_assert(subghz);
subghz->txrx->speaker_state = state;
}
SubGhzSpeakerState subghz_speaker_get_state(SubGhz* subghz) {
furi_assert(subghz);
return subghz->txrx->speaker_state;
}
void subghz_lock(SubGhz* subghz) {
furi_assert(subghz);
subghz->lock = SubGhzLockOn;
@@ -752,344 +404,3 @@ SubGhzRxKeyState subghz_rx_key_state_get(SubGhz* subghz) {
furi_assert(subghz);
return subghz->rx_key_state;
}
//#############Create new Key##############
#include <lib/subghz/protocols/protocol_items.h>
#include <lib/subghz/protocols/keeloq.h>
#include <lib/subghz/protocols/nice_flor_s.h>
#include <lib/subghz/protocols/secplus_v1.h>
#include <lib/subghz/protocols/secplus_v2.h>
bool subghz_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);
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_gen_data_protocol_and_te(
SubGhz* subghz,
const char* preset_name,
uint32_t frequency,
const char* protocol_name,
uint64_t key,
uint32_t bit,
uint32_t te) {
furi_assert(subghz);
bool ret = false;
if(subghz_gen_data_protocol(subghz, preset_name, frequency, protocol_name, key, bit)) {
if(!flipper_format_update_uint32(subghz->txrx->fff_data, "TE", (uint32_t*)&te, 1)) {
FURI_LOG_E(TAG, "Unable to update Te");
} else {
ret = true;
}
}
return ret;
}
bool subghz_scene_set_type_submenu_gen_data_keeloq( //TODO rename
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);
return res;
}
bool subghz_scene_set_type_submenu_gen_data_keeloq_bft( //TODO rename
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) {
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_bft_create_data(
subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter),
subghz->txrx->fff_data,
serial,
btn,
cnt,
seed,
manufacture_name,
subghz->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(subghz->txrx->fff_data, "Seed", seed_data, sizeof(uint32_t));
flipper_format_write_string_cstr(subghz->txrx->fff_data, "Manufacture", "BFT");
}
subghz_transmitter_free(subghz->txrx->transmitter);
return res;
}
bool subghz_scene_set_type_submenu_gen_data_nice_flor( //TODO rename
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
bool nice_one) {
SubGhz* subghz = context;
bool res = false;
subghz->txrx->transmitter =
subghz_transmitter_alloc_init(subghz->txrx->environment, SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME);
subghz_preset_init(subghz, preset_name, frequency, 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,
serial,
btn,
cnt,
subghz->txrx->preset,
nice_one)) {
res = true;
}
subghz_transmitter_free(subghz->txrx->transmitter);
return res;
}
bool subghz_scene_set_type_submenu_gen_data_faac_slh( //TODO rename
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) {
SubGhz* subghz = context;
bool res = false;
subghz->txrx->transmitter =
subghz_transmitter_alloc_init(subghz->txrx->environment, SUBGHZ_PROTOCOL_FAAC_SLH_NAME);
subghz_preset_init(subghz, preset_name, frequency, NULL, 0);
if(subghz->txrx->transmitter &&
subghz_protocol_faac_slh_create_data(
subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter),
subghz->txrx->fff_data,
serial,
btn,
cnt,
seed,
manufacture_name,
subghz->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(subghz->txrx->fff_data, "Seed", seed_data, sizeof(uint32_t));
}
subghz_transmitter_free(subghz->txrx->transmitter);
return res;
}
bool subghz_scene_set_type_submenu_gen_data_alutech_at_4n( //TODO rename
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt) {
SubGhz* subghz = context;
bool res = false;
subghz->txrx->transmitter = subghz_transmitter_alloc_init(
subghz->txrx->environment, SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME);
subghz_preset_init(subghz, preset_name, frequency, 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,
serial,
btn,
cnt,
subghz->txrx->preset)) {
res = true;
}
subghz_transmitter_free(subghz->txrx->transmitter);
return res;
}
bool subghz_scene_set_type_submenu_gen_data_somfy_telis( //TODO rename
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt) {
SubGhz* subghz = context;
bool res = false;
subghz->txrx->transmitter =
subghz_transmitter_alloc_init(subghz->txrx->environment, SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME);
subghz_preset_init(subghz, preset_name, frequency, NULL, 0);
if(subghz->txrx->transmitter &&
subghz_protocol_somfy_telis_create_data(
subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter),
subghz->txrx->fff_data,
serial,
btn,
cnt,
subghz->txrx->preset)) {
res = true;
}
subghz_transmitter_free(subghz->txrx->transmitter);
return res;
}
bool subghz_gen_secplus_v2_protocol(
SubGhz* subghz,
const char* name_preset,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint32_t cnt) {
furi_assert(subghz);
bool ret = false;
subghz->txrx->transmitter =
subghz_transmitter_alloc_init(subghz->txrx->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME);
subghz_preset_init(subghz, name_preset, frequency, NULL, 0);
if(subghz->txrx->transmitter) {
subghz_protocol_secplus_v2_create_data(
subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter),
subghz->txrx->fff_data,
serial,
btn,
cnt,
subghz->txrx->preset);
ret = true;
}
return ret;
}
bool subghz_gen_secplus_v1_protocol(SubGhz* subghz, const char* name_preset, uint32_t frequency) {
furi_assert(subghz);
bool ret = false;
uint32_t serial = subghz_random_serial();
while(!subghz_protocol_secplus_v1_check_fixed(serial)) {
serial = subghz_random_serial();
}
if(subghz_gen_data_protocol(
subghz,
name_preset,
frequency,
SUBGHZ_PROTOCOL_SECPLUS_V1_NAME,
(uint64_t)serial << 32 | 0xE6000000,
42)) {
ret = true;
}
return ret;
}

View File

@@ -43,6 +43,8 @@
#include "helpers/subghz_threshold_rssi.h"
#include "subghz_radio.h"
#define SUBGHZ_MAX_LEN_NAME 64
#define SUBGHZ_EXT_PRESET_NAME true
@@ -58,40 +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;
uint8_t hopper_timeout;
uint8_t hopper_idx_frequency;
SubGhzHopperState hopper_state;
SubGhzSpeakerState speaker_state;
SubGhzTxRxState txrx_state;
bool ignore_starline;
bool ignore_auto_alarms;
bool ignore_magellan;
SubGhzLoadTypeFile load_type_file;
bool debug_pin_state;
};
typedef struct SubGhzTxRx SubGhzTxRx;
struct SubGhz {
Gui* gui;
NotificationApp* notifications;
@@ -124,7 +92,6 @@ struct SubGhz {
SubGhzTestStatic* subghz_test_static;
SubGhzTestPacket* subghz_test_packet;
#endif
SubGhzSetting* setting;
SubGhzLastSettings* last_settings;
FuriString* error_str;
@@ -133,33 +100,29 @@ struct SubGhz {
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;
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);
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);
@@ -167,27 +130,15 @@ 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);
void subghz_speaker_set_state(SubGhz* subghz, SubGhzSpeakerState state);
SubGhzSpeakerState subghz_speaker_get_state(SubGhz* subghz);
void subghz_txrx_stop(SubGhz* subghz);
SubGhzTxRxState subghz_txrx_get_state(SubGhz* subghz);
SubGhzHopperState subghz_hopper_get_state(SubGhz* subghz);
void subghz_hopper_set_state(SubGhz* subghz, SubGhzHopperState state);
void subghz_hopper_remove_pause(SubGhz* subghz);
void subghz_subghz_hopper_set_pause(SubGhz* subghz);
void subghz_lock(SubGhz* subghz);
void subghz_unlock(SubGhz* subghz);
@@ -198,87 +149,5 @@ SubGhzLoadTypeFile subghz_get_load_type_file(SubGhz* subghz);
void subghz_rx_key_state_set(SubGhz* subghz, SubGhzRxKeyState state);
SubGhzRxKeyState subghz_rx_key_state_get(SubGhz* subghz);
//#############Create new Key##############
bool subghz_gen_data_protocol(
void* context,
const char* preset_name,
uint32_t frequency,
const char* protocol_name,
uint64_t key,
uint32_t bit);
bool subghz_gen_data_protocol_and_te(
SubGhz* subghz,
const char* preset_name,
uint32_t frequency,
const char* protocol_name,
uint64_t key,
uint32_t bit,
uint32_t te);
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);
bool subghz_scene_set_type_submenu_gen_data_keeloq_bft( //TODO rename
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_scene_set_type_submenu_gen_data_nice_flor( //TODO rename
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
bool nice_one);
bool subghz_scene_set_type_submenu_gen_data_faac_slh( //TODO rename
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_scene_set_type_submenu_gen_data_alutech_at_4n( //TODO rename
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt);
bool subghz_scene_set_type_submenu_gen_data_somfy_telis( //TODO rename
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt);
bool subghz_gen_secplus_v2_protocol(
SubGhz* subghz,
const char* name_preset,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint32_t cnt);
bool subghz_gen_secplus_v1_protocol(SubGhz* subghz, const char* name_preset, uint32_t frequency);
extern const NotificationSequence subghz_sequence_rx;
extern const NotificationSequence subghz_sequence_rx_locked;

View File

@@ -0,0 +1,723 @@
#include "subghz_radio.h"
#define TAG "SubGhz"
void subghz_preset_init(
SubGhzTxRx* txrx,
const char* preset_name,
uint32_t frequency,
uint8_t* preset_data,
size_t preset_data_size) {
furi_assert(txrx);
furi_string_set(txrx->preset->name, preset_name);
txrx->preset->frequency = frequency;
txrx->preset->data = preset_data;
txrx->preset->data_size = preset_data_size;
}
bool subghz_set_preset(SubGhzTxRx* txrx, const char* preset) {
if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) {
furi_string_set(txrx->preset->name, "AM270");
} else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) {
furi_string_set(txrx->preset->name, "AM650");
} else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) {
furi_string_set(txrx->preset->name, "FM238");
} else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) {
furi_string_set(txrx->preset->name, "FM476");
} else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) {
furi_string_set(txrx->preset->name, "CUSTOM");
} else {
FURI_LOG_E(TAG, "Unknown preset");
return false;
}
return true;
}
void subghz_begin(SubGhzTxRx* txrx, uint8_t* preset_data) {
furi_assert(txrx);
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);
txrx->txrx_state = SubGhzTxRxStateIDLE;
}
uint32_t subghz_rx(SubGhzTxRx* txrx, uint32_t frequency) {
furi_assert(txrx);
if(!furi_hal_subghz_is_frequency_valid(frequency)) {
furi_crash("SubGhz: Incorrect RX frequency.");
}
furi_assert(txrx->txrx_state != SubGhzTxRxStateRx && 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(txrx);
furi_hal_subghz_rx();
furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, txrx->worker);
subghz_worker_start(txrx->worker);
txrx->txrx_state = SubGhzTxRxStateRx;
return value;
}
static void subghz_idle(SubGhzTxRx* txrx) {
furi_assert(txrx);
furi_assert(txrx->txrx_state != SubGhzTxRxStateSleep);
furi_hal_subghz_idle();
subghz_speaker_off(txrx);
txrx->txrx_state = SubGhzTxRxStateIDLE;
}
static void subghz_rx_end(SubGhzTxRx* txrx) {
furi_assert(txrx);
furi_assert(txrx->txrx_state == SubGhzTxRxStateRx);
if(subghz_worker_is_running(txrx->worker)) {
subghz_worker_stop(txrx->worker);
furi_hal_subghz_stop_async_rx();
}
furi_hal_subghz_idle();
subghz_speaker_off(txrx);
txrx->txrx_state = SubGhzTxRxStateIDLE;
}
// static void subghz_sleep(SubGhzTxRx* txrx) {
// furi_assert(txrx);
// furi_hal_subghz_sleep();
// txrx->txrx_state = SubGhzTxRxStateSleep;
// }
static bool subghz_tx(SubGhzTxRx* txrx, uint32_t frequency) {
furi_assert(txrx);
if(!furi_hal_subghz_is_frequency_valid(frequency)) {
furi_crash("SubGhz: Incorrect TX frequency.");
}
furi_assert(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(txrx);
txrx->txrx_state = SubGhzTxRxStateTx;
}
return ret;
}
bool subghz_tx_start(SubGhzTxRx* txrx, FlipperFormat* flipper_format) {
furi_assert(txrx);
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;
}
txrx->transmitter =
subghz_transmitter_alloc_init(txrx->environment, furi_string_get_cstr(temp_str));
if(txrx->transmitter) {
if(subghz_transmitter_deserialize(txrx->transmitter, flipper_format) ==
SubGhzProtocolStatusOk) {
if(strcmp(furi_string_get_cstr(txrx->preset->name), "") != 0) {
subghz_begin(
txrx,
subghz_setting_get_preset_data_by_name(
txrx->setting, furi_string_get_cstr(txrx->preset->name)));
} else {
FURI_LOG_E(
TAG,
"Unknown name preset \" %s \"",
furi_string_get_cstr(txrx->preset->name));
subghz_begin(
txrx, subghz_setting_get_preset_data_by_name(txrx->setting, "AM650"));
}
if(txrx->preset->frequency) {
ret = subghz_tx(txrx, txrx->preset->frequency);
} else {
ret = subghz_tx(txrx, 433920000);
}
if(ret) {
//Start TX
furi_hal_subghz_start_async_tx(subghz_transmitter_yield, txrx->transmitter);
} else {
//Todo: Show error
//subghz_dialog_message_show_only_rx(subghz);
}
} else {
//Todo: Show error
// dialog_message_show_storage_error(
// dialogs, "Error in protocol\nparameters\ndescription");
}
}
if(!ret) {
subghz_transmitter_free(txrx->transmitter);
if(txrx->txrx_state != SubGhzTxRxStateSleep) {
subghz_idle(txrx);
}
}
} while(false);
furi_string_free(temp_str);
return ret;
}
void subghz_txrx_need_save_callback_set(
SubGhzTxRx* txrx,
SubGhzTxRxNeedSaveCallback callback,
void* context) {
furi_assert(txrx);
txrx->need_save_callback = callback;
txrx->need_save_context = context;
}
static void subghz_tx_stop(SubGhzTxRx* txrx) {
furi_assert(txrx);
furi_assert(txrx->txrx_state == SubGhzTxRxStateTx);
//Stop TX
furi_hal_subghz_stop_async_tx();
subghz_transmitter_stop(txrx->transmitter);
subghz_transmitter_free(txrx->transmitter);
//if protocol dynamic then we save the last upload
if(txrx->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) {
if(txrx->need_save_callback) {
txrx->need_save_callback(txrx->need_save_context);
}
}
subghz_idle(txrx);
subghz_speaker_off(txrx);
//Todo: Show message
// notification_message(notifications, &sequence_reset_red);
}
FlipperFormat* subghz_txtx_get_fff_data(SubGhzTxRx* txrx) {
furi_assert(txrx);
return txrx->fff_data;
}
SubGhzSetting* subghz_txrx_get_setting(SubGhzTxRx* txrx) {
furi_assert(txrx);
return txrx->setting;
}
void subghz_txrx_stop(SubGhzTxRx* txrx) {
furi_assert(txrx);
switch(txrx->txrx_state) {
case SubGhzTxRxStateTx:
subghz_tx_stop(txrx);
subghz_speaker_unmute(txrx);
//subghz_sleep(txrx);
break;
case SubGhzTxRxStateRx:
subghz_rx_end(txrx);
subghz_speaker_mute(txrx);
//subghz_sleep(txrx);
break;
default:
break;
}
}
SubGhzTxRxState subghz_txrx_get_state(SubGhzTxRx* txrx) {
furi_assert(txrx);
return txrx->txrx_state;
}
void subghz_hopper_update(SubGhzTxRx* txrx) {
furi_assert(txrx);
switch(txrx->hopper_state) {
case SubGhzHopperStateOFF:
case SubGhzHopperStatePause:
return;
case SubGhzHopperStateRSSITimeOut:
if(txrx->hopper_timeout != 0) {
txrx->hopper_timeout--;
return;
}
break;
default:
break;
}
float rssi = -127.0f;
if(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) {
txrx->hopper_timeout = 10;
txrx->hopper_state = SubGhzHopperStateRSSITimeOut;
return;
}
} else {
txrx->hopper_state = SubGhzHopperStateRunning;
}
// Select next frequency
if(txrx->hopper_idx_frequency < subghz_setting_get_hopper_frequency_count(txrx->setting) - 1) {
txrx->hopper_idx_frequency++;
} else {
txrx->hopper_idx_frequency = 0;
}
if(txrx->txrx_state == SubGhzTxRxStateRx) {
subghz_rx_end(txrx);
};
if(txrx->txrx_state == SubGhzTxRxStateIDLE) {
subghz_receiver_reset(txrx->receiver);
txrx->preset->frequency =
subghz_setting_get_hopper_frequency(txrx->setting, txrx->hopper_idx_frequency);
subghz_rx(txrx, txrx->preset->frequency);
}
}
SubGhzHopperState subghz_hopper_get_state(SubGhzTxRx* txrx) {
furi_assert(txrx);
return txrx->hopper_state;
}
void subghz_hopper_set_state(SubGhzTxRx* txrx, SubGhzHopperState state) {
furi_assert(txrx);
txrx->hopper_state = state;
}
void subghz_hopper_remove_pause(SubGhzTxRx* txrx) {
furi_assert(txrx);
if(txrx->hopper_state == SubGhzHopperStatePause) {
txrx->hopper_state = SubGhzHopperStateRunning;
}
}
void subghz_subghz_hopper_set_pause(SubGhzTxRx* txrx) {
furi_assert(txrx);
if(txrx->hopper_state == SubGhzHopperStateRunning) {
txrx->hopper_state = SubGhzHopperStatePause;
}
}
void subghz_speaker_on(SubGhzTxRx* txrx) {
furi_assert(txrx);
if(txrx->debug_pin_state) {
furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton);
}
if(txrx->speaker_state == SubGhzSpeakerStateEnable) {
if(furi_hal_speaker_acquire(30)) {
if(!txrx->debug_pin_state) {
furi_hal_subghz_set_async_mirror_pin(&gpio_speaker);
}
} else {
txrx->speaker_state = SubGhzSpeakerStateDisable;
}
}
}
void subghz_speaker_off(SubGhzTxRx* txrx) {
furi_assert(txrx);
if(txrx->debug_pin_state) {
furi_hal_subghz_set_async_mirror_pin(NULL);
}
if(txrx->speaker_state != SubGhzSpeakerStateDisable) {
if(furi_hal_speaker_is_mine()) {
if(!txrx->debug_pin_state) {
furi_hal_subghz_set_async_mirror_pin(NULL);
}
furi_hal_speaker_release();
if(txrx->speaker_state == SubGhzSpeakerStateShutdown)
txrx->speaker_state = SubGhzSpeakerStateDisable;
}
}
}
void subghz_speaker_mute(SubGhzTxRx* txrx) {
furi_assert(txrx);
if(txrx->debug_pin_state) {
furi_hal_subghz_set_async_mirror_pin(NULL);
}
if(txrx->speaker_state == SubGhzSpeakerStateEnable) {
if(furi_hal_speaker_is_mine()) {
if(!txrx->debug_pin_state) {
furi_hal_subghz_set_async_mirror_pin(NULL);
}
}
}
}
void subghz_speaker_unmute(SubGhzTxRx* txrx) {
furi_assert(txrx);
if(txrx->debug_pin_state) {
furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton);
}
if(txrx->speaker_state == SubGhzSpeakerStateEnable) {
if(furi_hal_speaker_is_mine()) {
if(!txrx->debug_pin_state) {
furi_hal_subghz_set_async_mirror_pin(&gpio_speaker);
}
}
}
}
void subghz_speaker_set_state(SubGhzTxRx* txrx, SubGhzSpeakerState state) {
furi_assert(txrx);
txrx->speaker_state = state;
}
SubGhzSpeakerState subghz_speaker_get_state(SubGhzTxRx* txrx) {
furi_assert(txrx);
return txrx->speaker_state;
}
//#############Create new Key##############
#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>
bool subghz_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* txrx = context;
bool res = false;
subghz_preset_init(txrx, preset_name, frequency, NULL, 0);
txrx->decoder_result =
subghz_receiver_search_decoder_base_by_name(txrx->receiver, protocol_name);
if(txrx->decoder_result == NULL) {
//TODO: Error
// furi_string_set(error_str, "Protocol not\nfound!");
// scene_manager_next_scene(scene_manager, SubGhzSceneShowErrorSub);
return false;
}
do {
Stream* fff_data_stream = flipper_format_get_raw_stream(txrx->fff_data);
stream_clean(fff_data_stream);
if(subghz_protocol_decoder_base_serialize(
txrx->decoder_result, txrx->fff_data, txrx->preset) != SubGhzProtocolStatusOk) {
FURI_LOG_E(TAG, "Unable to serialize");
break;
}
if(!flipper_format_update_uint32(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(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_gen_data_protocol_and_te(
SubGhzTxRx* txrx,
const char* preset_name,
uint32_t frequency,
const char* protocol_name,
uint64_t key,
uint32_t bit,
uint32_t te) {
furi_assert(txrx);
bool ret = false;
if(subghz_gen_data_protocol(txrx, preset_name, frequency, protocol_name, key, bit)) {
if(!flipper_format_update_uint32(txrx->fff_data, "TE", (uint32_t*)&te, 1)) {
FURI_LOG_E(TAG, "Unable to update Te");
} else {
ret = true;
}
}
return ret;
}
bool subghz_scene_set_type_submenu_gen_data_keeloq( //TODO rename
SubGhzTxRx* txrx,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
const char* manufacture_name) {
furi_assert(txrx);
bool res = false;
txrx->transmitter =
subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME);
subghz_preset_init(txrx, preset_name, frequency, NULL, 0);
if(txrx->transmitter && subghz_protocol_keeloq_create_data(
subghz_transmitter_get_protocol_instance(txrx->transmitter),
txrx->fff_data,
serial,
btn,
cnt,
manufacture_name,
txrx->preset)) {
flipper_format_write_string_cstr(txrx->fff_data, "Manufacture", manufacture_name);
res = true;
}
subghz_transmitter_free(txrx->transmitter);
return res;
}
bool subghz_scene_set_type_submenu_gen_data_keeloq_bft( //TODO rename
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_preset_init(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_scene_set_type_submenu_gen_data_nice_flor( //TODO rename
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_preset_init(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_scene_set_type_submenu_gen_data_faac_slh( //TODO rename
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_preset_init(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_scene_set_type_submenu_gen_data_alutech_at_4n( //TODO rename
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_preset_init(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_scene_set_type_submenu_gen_data_somfy_telis( //TODO rename
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_preset_init(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_gen_secplus_v2_protocol(
SubGhzTxRx* txrx,
const char* name_preset,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint32_t cnt) {
furi_assert(txrx);
bool ret = false;
txrx->transmitter =
subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_SECPLUS_V2_NAME);
subghz_preset_init(txrx, name_preset, frequency, NULL, 0);
if(txrx->transmitter) {
subghz_protocol_secplus_v2_create_data(
subghz_transmitter_get_protocol_instance(txrx->transmitter),
txrx->fff_data,
serial,
btn,
cnt,
txrx->preset);
ret = true;
}
return ret;
}
bool subghz_gen_secplus_v1_protocol(SubGhzTxRx* txrx, const char* name_preset, uint32_t frequency) {
furi_assert(txrx);
bool ret = false;
uint32_t serial = (uint32_t)rand();
while(!subghz_protocol_secplus_v1_check_fixed(serial)) {
serial = (uint32_t)rand();
}
if(subghz_gen_data_protocol(
txrx,
name_preset,
frequency,
SUBGHZ_PROTOCOL_SECPLUS_V1_NAME,
(uint64_t)serial << 32 | 0xE6000000,
42)) {
ret = true;
}
return ret;
}

View File

@@ -0,0 +1,160 @@
#pragma once
//#include "subghz_i.h"
#include "helpers/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 "subghz_history.h"
typedef void (*SubGhzTxRxNeedSaveCallback)(void* context);
struct SubGhzTxRx {
SubGhzWorker* worker;
SubGhzEnvironment* environment;
SubGhzReceiver* receiver;
SubGhzTransmitter* transmitter;
SubGhzProtocolFlag filter;
SubGhzProtocolDecoderBase* decoder_result;
FlipperFormat* fff_data;
SubGhzRadioPreset* preset;
SubGhzHistory* history;
SubGhzSetting* setting;
uint8_t hopper_timeout;
uint8_t hopper_idx_frequency;
SubGhzHopperState hopper_state;
SubGhzTxRxState txrx_state;
SubGhzSpeakerState speaker_state;
SubGhzTxRxNeedSaveCallback need_save_callback;
void* need_save_context;
bool debug_pin_state;
};
typedef struct SubGhzTxRx SubGhzTxRx;
void subghz_preset_init(
SubGhzTxRx* txrx,
const char* preset_name,
uint32_t frequency,
uint8_t* preset_data,
size_t preset_data_size);
bool subghz_set_preset(SubGhzTxRx* txrx, const char* preset);
void subghz_begin(SubGhzTxRx* txrx, uint8_t* preset_data);
uint32_t subghz_rx(SubGhzTxRx* txrx, uint32_t frequency);
bool subghz_tx_start(SubGhzTxRx* txrx, FlipperFormat* flipper_format);
//void subghz_rx_end(SubGhzTxRx* txrx); //depricated
//void subghz_sleep(SubGhzTxRx* txrx);
void subghz_txrx_stop(SubGhzTxRx* txrx);
SubGhzTxRxState subghz_txrx_get_state(SubGhzTxRx* txrx);
void subghz_hopper_update(SubGhzTxRx* txrx);
SubGhzHopperState subghz_hopper_get_state(SubGhzTxRx* txrx);
void subghz_hopper_set_state(SubGhzTxRx* txrx, SubGhzHopperState state);
void subghz_hopper_remove_pause(SubGhzTxRx* txrx);
void subghz_subghz_hopper_set_pause(SubGhzTxRx* txrx);
void subghz_speaker_on(SubGhzTxRx* txrx);
void subghz_speaker_off(SubGhzTxRx* txrx);
void subghz_speaker_mute(SubGhzTxRx* txrx);
void subghz_speaker_unmute(SubGhzTxRx* txrx);
void subghz_speaker_set_state(SubGhzTxRx* txrx, SubGhzSpeakerState state);
SubGhzSpeakerState subghz_speaker_get_state(SubGhzTxRx* txrx);
void subghz_txrx_need_save_callback_set(
SubGhzTxRx* txrx,
SubGhzTxRxNeedSaveCallback callback,
void* context);
FlipperFormat* subghz_txtx_get_fff_data(SubGhzTxRx* txrx);
SubGhzSetting* subghz_txrx_get_setting(SubGhzTxRx* txrx);
//#############Create new Key##############
bool subghz_gen_data_protocol(
void* context,
const char* preset_name,
uint32_t frequency,
const char* protocol_name,
uint64_t key,
uint32_t bit);
bool subghz_gen_data_protocol_and_te(
SubGhzTxRx* txrx,
const char* preset_name,
uint32_t frequency,
const char* protocol_name,
uint64_t key,
uint32_t bit,
uint32_t te);
bool subghz_scene_set_type_submenu_gen_data_keeloq(
SubGhzTxRx* txrx,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
const char* manufacture_name);
bool subghz_scene_set_type_submenu_gen_data_keeloq_bft( //TODO rename
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_scene_set_type_submenu_gen_data_nice_flor( //TODO rename
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
bool nice_one);
bool subghz_scene_set_type_submenu_gen_data_faac_slh( //TODO rename
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_scene_set_type_submenu_gen_data_alutech_at_4n( //TODO rename
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt);
bool subghz_scene_set_type_submenu_gen_data_somfy_telis( //TODO rename
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt);
bool subghz_gen_secplus_v2_protocol(
SubGhzTxRx* txrx,
const char* name_preset,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint32_t cnt);
bool subghz_gen_secplus_v1_protocol(SubGhzTxRx* txrx, const char* name_preset, uint32_t frequency);