[FL-1758] SubGhz refactoring part 1 (#689)
* SubGhz: refactoring * WeGet: Add support for outputting formatted lines, events center button pressed, center button released * Variable Item: slightly changed the display of data on the screen * SubGhz: add show errors, add show preset, refactoring * SubGhz: refactoring transmitter * SubGhz: removed unused modules * SubGhz: Add FuriHalSubGhzPresetOok270Async setting menu * SubGhz: fix annotation * SubGhz: add support Nero Radio Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		@@ -1,10 +1,12 @@
 | 
			
		||||
ADD_SCENE(subghz, start, Start)
 | 
			
		||||
ADD_SCENE(subghz, receiver, Receiver)
 | 
			
		||||
ADD_SCENE(subghz, receiver_config, ReceiverConfig)
 | 
			
		||||
ADD_SCENE(subghz, receiver_info, ReceiverInfo)
 | 
			
		||||
ADD_SCENE(subghz, save_name, SaveName)
 | 
			
		||||
ADD_SCENE(subghz, save_success, SaveSuccess)
 | 
			
		||||
ADD_SCENE(subghz, saved, Saved)
 | 
			
		||||
ADD_SCENE(subghz, transmitter, Transmitter)
 | 
			
		||||
ADD_SCENE(subghz, no_man, NoMan)
 | 
			
		||||
ADD_SCENE(subghz, show_error, ShowError)
 | 
			
		||||
ADD_SCENE(subghz, test, Test)
 | 
			
		||||
ADD_SCENE(subghz, test_static, TestStatic)
 | 
			
		||||
ADD_SCENE(subghz, test_carrier, TestCarrier)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,21 +1,102 @@
 | 
			
		||||
#include "../subghz_i.h"
 | 
			
		||||
#include "../views/subghz_receiver.h"
 | 
			
		||||
 | 
			
		||||
static void subghz_scene_receiver_update_statusbar(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    char frequency_str[20];
 | 
			
		||||
    char preset_str[10];
 | 
			
		||||
    string_t history_stat_str;
 | 
			
		||||
    string_init(history_stat_str);
 | 
			
		||||
    if(!subghz_history_get_text_space_left(subghz->txrx->history, history_stat_str)) {
 | 
			
		||||
        snprintf(
 | 
			
		||||
            frequency_str,
 | 
			
		||||
            sizeof(frequency_str),
 | 
			
		||||
            "%03ld.%02ld",
 | 
			
		||||
            subghz->txrx->frequency / 1000000 % 1000,
 | 
			
		||||
            subghz->txrx->frequency / 10000 % 100);
 | 
			
		||||
        if(subghz->txrx->preset == FuriHalSubGhzPresetOok650Async ||
 | 
			
		||||
           subghz->txrx->preset == FuriHalSubGhzPresetOok270Async) {
 | 
			
		||||
            snprintf(preset_str, sizeof(preset_str), "AM");
 | 
			
		||||
        } else if(subghz->txrx->preset == FuriHalSubGhzPreset2FSKAsync) {
 | 
			
		||||
            snprintf(preset_str, sizeof(preset_str), "FM");
 | 
			
		||||
        } else {
 | 
			
		||||
            furi_check(0);
 | 
			
		||||
        }
 | 
			
		||||
        subghz_receiver_add_data_statusbar(
 | 
			
		||||
            subghz->subghz_receiver, frequency_str, preset_str, string_get_cstr(history_stat_str));
 | 
			
		||||
    } else {
 | 
			
		||||
        subghz_receiver_add_data_statusbar(
 | 
			
		||||
            subghz->subghz_receiver, string_get_cstr(history_stat_str), "", "");
 | 
			
		||||
        subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
    }
 | 
			
		||||
    string_clear(history_stat_str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void subghz_scene_receiver_callback(SubghzReceverEvent event, void* context) {
 | 
			
		||||
    furi_assert(context);
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    view_dispatcher_send_custom_event(subghz->view_dispatcher, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void subghz_scene_add_to_history_callback(SubGhzProtocolCommon* parser, void* context) {
 | 
			
		||||
    furi_assert(context);
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    string_t str_buff;
 | 
			
		||||
    string_init(str_buff);
 | 
			
		||||
 | 
			
		||||
    if(subghz_history_add_to_history(
 | 
			
		||||
           subghz->txrx->history, parser, subghz->txrx->frequency, subghz->txrx->preset)) {
 | 
			
		||||
        subghz_protocol_reset(subghz->txrx->protocol);
 | 
			
		||||
        string_clean(str_buff);
 | 
			
		||||
        subghz_history_get_text_item_menu(
 | 
			
		||||
            subghz->txrx->history, str_buff, subghz_history_get_item(subghz->txrx->history) - 1);
 | 
			
		||||
        subghz_receiver_add_item_to_menu(
 | 
			
		||||
            subghz->subghz_receiver,
 | 
			
		||||
            string_get_cstr(str_buff),
 | 
			
		||||
            subghz_history_get_type_protocol(
 | 
			
		||||
                subghz->txrx->history, subghz_history_get_item(subghz->txrx->history) - 1));
 | 
			
		||||
        subghz_scene_receiver_update_statusbar(subghz);
 | 
			
		||||
    }
 | 
			
		||||
    string_clear(str_buff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void subghz_scene_receiver_on_enter(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    SubghzReceiver* subghz_receiver = subghz->subghz_receiver;
 | 
			
		||||
 | 
			
		||||
    subghz_receiver_set_callback(subghz_receiver, subghz_scene_receiver_callback, subghz);
 | 
			
		||||
    string_t str_buff;
 | 
			
		||||
    string_init(str_buff);
 | 
			
		||||
 | 
			
		||||
    //Load history to receiver
 | 
			
		||||
    subghz_receiver_exit(subghz->subghz_receiver);
 | 
			
		||||
    for(uint8_t i = 0; i < subghz_history_get_item(subghz->txrx->history); i++) {
 | 
			
		||||
        string_clean(str_buff);
 | 
			
		||||
        subghz_history_get_text_item_menu(subghz->txrx->history, str_buff, i);
 | 
			
		||||
        subghz_receiver_add_item_to_menu(
 | 
			
		||||
            subghz->subghz_receiver,
 | 
			
		||||
            string_get_cstr(str_buff),
 | 
			
		||||
            subghz_history_get_type_protocol(subghz->txrx->history, i));
 | 
			
		||||
    }
 | 
			
		||||
    string_clear(str_buff);
 | 
			
		||||
    subghz_scene_receiver_update_statusbar(subghz);
 | 
			
		||||
    subghz_receiver_set_callback(subghz->subghz_receiver, subghz_scene_receiver_callback, subghz);
 | 
			
		||||
    subghz_protocol_enable_dump(
 | 
			
		||||
        subghz->txrx->protocol, subghz_scene_add_to_history_callback, subghz);
 | 
			
		||||
 | 
			
		||||
    subghz_receiver_set_protocol(subghz_receiver, subghz->protocol_result, subghz->protocol);
 | 
			
		||||
    subghz_receiver_set_worker(subghz_receiver, subghz->worker);
 | 
			
		||||
    subghz->state_notifications = NOTIFICATION_RX_STATE;
 | 
			
		||||
    if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
 | 
			
		||||
        subghz_rx_end(subghz->txrx->worker);
 | 
			
		||||
        //subghz_sleep();
 | 
			
		||||
        subghz->txrx->txrx_state = SubGhzTxRxStateIdle;
 | 
			
		||||
    };
 | 
			
		||||
    if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) {
 | 
			
		||||
        subghz_begin(subghz->txrx->preset);
 | 
			
		||||
        subghz_rx(subghz->txrx->worker, subghz->txrx->frequency);
 | 
			
		||||
        subghz->txrx->txrx_state = SubGhzTxRxStateRx;
 | 
			
		||||
    }
 | 
			
		||||
    if(subghz->txrx->idx_menu_chosen != 0) {
 | 
			
		||||
        subghz_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReceiver);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -24,51 +105,43 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event
 | 
			
		||||
 | 
			
		||||
    if(event.type == SceneManagerEventTypeCustom) {
 | 
			
		||||
        switch(event.event) {
 | 
			
		||||
        case SubghzReceverEventSave:
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
            subghz->frequency = subghz_receiver_get_frequency(subghz->subghz_receiver);
 | 
			
		||||
            subghz->preset = subghz_receiver_get_preset(subghz->subghz_receiver);
 | 
			
		||||
            subghz->protocol_result = subghz_receiver_get_protocol(subghz->subghz_receiver);
 | 
			
		||||
            scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
 | 
			
		||||
            return true;
 | 
			
		||||
            break;
 | 
			
		||||
        case SubghzReceverEventBack:
 | 
			
		||||
            scene_manager_previous_scene(subghz->scene_manager);
 | 
			
		||||
            // Stop CC1101 Rx
 | 
			
		||||
            if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
 | 
			
		||||
                subghz_rx_end(subghz->txrx->worker);
 | 
			
		||||
                subghz_sleep();
 | 
			
		||||
                subghz->txrx->txrx_state = SubGhzTxRxStateIdle;
 | 
			
		||||
            };
 | 
			
		||||
            subghz_history_clean(subghz->txrx->history);
 | 
			
		||||
            subghz->txrx->hopper_state = SubGhzHopperStateOFF;
 | 
			
		||||
            subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92];
 | 
			
		||||
            subghz->txrx->preset = FuriHalSubGhzPresetOok650Async;
 | 
			
		||||
            subghz->txrx->idx_menu_chosen = 0;
 | 
			
		||||
            subghz_protocol_enable_dump(subghz->txrx->protocol, NULL, subghz);
 | 
			
		||||
            scene_manager_search_and_switch_to_previous_scene(
 | 
			
		||||
                subghz->scene_manager, SubGhzSceneStart);
 | 
			
		||||
            return true;
 | 
			
		||||
            break;
 | 
			
		||||
        case SubghzReceverEventSendStart:
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_TX_STATE;
 | 
			
		||||
            subghz->frequency = subghz_receiver_get_frequency(subghz->subghz_receiver);
 | 
			
		||||
            subghz->preset = subghz_receiver_get_preset(subghz->subghz_receiver);
 | 
			
		||||
            subghz->protocol_result = subghz_receiver_get_protocol(subghz->subghz_receiver);
 | 
			
		||||
            subghz_transmitter_tx_start(subghz);
 | 
			
		||||
            return true;
 | 
			
		||||
            break;
 | 
			
		||||
        case SubghzReceverEventSendStop:
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
            subghz_transmitter_tx_stop(subghz);
 | 
			
		||||
            return true;
 | 
			
		||||
            break;
 | 
			
		||||
        case SubghzReceverEventMain:
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_RX_STATE;
 | 
			
		||||
        case SubghzReceverEventOK:
 | 
			
		||||
            subghz->txrx->idx_menu_chosen = subghz_receiver_get_idx_menu(subghz->subghz_receiver);
 | 
			
		||||
            scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo);
 | 
			
		||||
            return true;
 | 
			
		||||
            break;
 | 
			
		||||
        case SubghzReceverEventConfig:
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
            return true;
 | 
			
		||||
            break;
 | 
			
		||||
        case SubghzReceverEventSendHistoryFull:
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
            scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig);
 | 
			
		||||
            return true;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    } else if(event.type == SceneManagerEventTypeTick) {
 | 
			
		||||
        if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) {
 | 
			
		||||
            subghz_hopper_update(subghz->txrx);
 | 
			
		||||
            subghz_scene_receiver_update_statusbar(subghz);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch(subghz->state_notifications) {
 | 
			
		||||
        case NOTIFICATION_TX_STATE:
 | 
			
		||||
            notification_message(subghz->notifications, &sequence_blink_red_10);
 | 
			
		||||
            break;
 | 
			
		||||
        case NOTIFICATION_RX_STATE:
 | 
			
		||||
            notification_message(subghz->notifications, &sequence_blink_blue_10);
 | 
			
		||||
            break;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										156
									
								
								applications/subghz/scenes/subghz_scene_receiver_config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								applications/subghz/scenes/subghz_scene_receiver_config.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,156 @@
 | 
			
		||||
#include "../subghz_i.h"
 | 
			
		||||
 | 
			
		||||
#define PRESET_COUNT 3
 | 
			
		||||
const char* const preset_text[PRESET_COUNT] = {
 | 
			
		||||
    "AM270",
 | 
			
		||||
    "AM650",
 | 
			
		||||
    "FM",
 | 
			
		||||
};
 | 
			
		||||
const uint32_t preset_value[PRESET_COUNT] = {
 | 
			
		||||
    FuriHalSubGhzPresetOok270Async, /** OOK, bandwidth 270kHz, asynchronous */
 | 
			
		||||
    FuriHalSubGhzPresetOok650Async, /** OOK, bandwidth 650kHz, asynchronous */
 | 
			
		||||
    FuriHalSubGhzPreset2FSKAsync, /** FM, asynchronous */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define HOPPING_COUNT 2
 | 
			
		||||
const char* const hopping_text[HOPPING_COUNT] = {
 | 
			
		||||
    "OFF",
 | 
			
		||||
    "ON",
 | 
			
		||||
};
 | 
			
		||||
const uint32_t hopping_value[HOPPING_COUNT] = {
 | 
			
		||||
    SubGhzHopperStateOFF,
 | 
			
		||||
    SubGhzHopperStateRunnig,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
uint8_t subghz_scene_receiver_config_uint32_value_index(
 | 
			
		||||
    const uint32_t value,
 | 
			
		||||
    const uint32_t values[],
 | 
			
		||||
    uint8_t values_count) {
 | 
			
		||||
    int64_t last_value = INT64_MIN;
 | 
			
		||||
    uint8_t index = 0;
 | 
			
		||||
    for(uint8_t i = 0; i < values_count; i++) {
 | 
			
		||||
        if((value >= last_value) && (value <= values[i])) {
 | 
			
		||||
            index = i;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        last_value = values[i];
 | 
			
		||||
    }
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t subghz_scene_receiver_config_hopper_value_index(
 | 
			
		||||
    const uint32_t value,
 | 
			
		||||
    const uint32_t values[],
 | 
			
		||||
    uint8_t values_count,
 | 
			
		||||
    void* context) {
 | 
			
		||||
    furi_assert(context);
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
 | 
			
		||||
    if(value == values[0]) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    } else {
 | 
			
		||||
        variable_item_set_current_value_text(
 | 
			
		||||
            (VariableItem*)scene_manager_get_scene_state(
 | 
			
		||||
                subghz->scene_manager, SubGhzSceneReceiverConfig),
 | 
			
		||||
            " -----");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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->txrx->hopper_state == SubGhzHopperStateOFF) {
 | 
			
		||||
        variable_item_set_current_value_text(item, subghz_frequencies_text[index]);
 | 
			
		||||
        subghz->txrx->frequency = subghz_frequencies[index];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
    variable_item_set_current_value_text(item, preset_text[index]);
 | 
			
		||||
    subghz->txrx->preset = preset_value[index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void subghz_scene_receiver_config_set_hopping_runing(VariableItem* item) {
 | 
			
		||||
    SubGhz* subghz = variable_item_get_context(item);
 | 
			
		||||
    uint8_t index = variable_item_get_current_value_index(item);
 | 
			
		||||
 | 
			
		||||
    variable_item_set_current_value_text(item, hopping_text[index]);
 | 
			
		||||
    if(hopping_value[index] == SubGhzHopperStateOFF) {
 | 
			
		||||
        variable_item_set_current_value_text(
 | 
			
		||||
            (VariableItem*)scene_manager_get_scene_state(
 | 
			
		||||
                subghz->scene_manager, SubGhzSceneReceiverConfig),
 | 
			
		||||
            subghz_frequencies_text[subghz_frequencies_433_92]);
 | 
			
		||||
        subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92];
 | 
			
		||||
    } else {
 | 
			
		||||
        variable_item_set_current_value_text(
 | 
			
		||||
            (VariableItem*)scene_manager_get_scene_state(
 | 
			
		||||
                subghz->scene_manager, SubGhzSceneReceiverConfig),
 | 
			
		||||
            " -----");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    subghz->txrx->hopper_state = hopping_value[index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void subghz_scene_receiver_config_callback(SubghzReceverEvent event, void* context) {
 | 
			
		||||
    furi_assert(context);
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    view_dispatcher_send_custom_event(subghz->view_dispatcher, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void subghz_scene_receiver_config_on_enter(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    VariableItem* item;
 | 
			
		||||
    uint8_t value_index;
 | 
			
		||||
 | 
			
		||||
    item = variable_item_list_add(
 | 
			
		||||
        subghz->variable_item_list,
 | 
			
		||||
        "Frequency:",
 | 
			
		||||
        subghz_frequencies_count,
 | 
			
		||||
        subghz_scene_receiver_config_set_frequency,
 | 
			
		||||
        subghz);
 | 
			
		||||
    value_index = subghz_scene_receiver_config_uint32_value_index(
 | 
			
		||||
        subghz->txrx->frequency, subghz_frequencies, subghz_frequencies_count);
 | 
			
		||||
    scene_manager_set_scene_state(
 | 
			
		||||
        subghz->scene_manager, SubGhzSceneReceiverConfig, (uint32_t)item);
 | 
			
		||||
    variable_item_set_current_value_index(item, value_index);
 | 
			
		||||
    variable_item_set_current_value_text(item, subghz_frequencies_text[value_index]);
 | 
			
		||||
 | 
			
		||||
    item = variable_item_list_add(
 | 
			
		||||
        subghz->variable_item_list,
 | 
			
		||||
        "Hopping:",
 | 
			
		||||
        HOPPING_COUNT,
 | 
			
		||||
        subghz_scene_receiver_config_set_hopping_runing,
 | 
			
		||||
        subghz);
 | 
			
		||||
    value_index = subghz_scene_receiver_config_hopper_value_index(
 | 
			
		||||
        subghz->txrx->hopper_state, 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]);
 | 
			
		||||
 | 
			
		||||
    item = variable_item_list_add(
 | 
			
		||||
        subghz->variable_item_list,
 | 
			
		||||
        "Modulation:",
 | 
			
		||||
        PRESET_COUNT,
 | 
			
		||||
        subghz_scene_receiver_config_set_preset,
 | 
			
		||||
        subghz);
 | 
			
		||||
    value_index = subghz_scene_receiver_config_uint32_value_index(
 | 
			
		||||
        subghz->txrx->preset, preset_value, PRESET_COUNT);
 | 
			
		||||
    variable_item_set_current_value_index(item, value_index);
 | 
			
		||||
    variable_item_set_current_value_text(item, preset_text[value_index]);
 | 
			
		||||
 | 
			
		||||
    view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewVariableItemList);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent event) {
 | 
			
		||||
    //SubGhz* subghz = context;
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void subghz_scene_receiver_config_on_exit(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    variable_item_list_clean(subghz->variable_item_list);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										163
									
								
								applications/subghz/scenes/subghz_scene_receiver_info.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								applications/subghz/scenes/subghz_scene_receiver_info.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
#include "../subghz_i.h"
 | 
			
		||||
 | 
			
		||||
void subghz_scene_receiver_info_callback(GuiButtonType result, void* context) {
 | 
			
		||||
    furi_assert(context);
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    view_dispatcher_send_custom_event(subghz->view_dispatcher, result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool subghz_scene_receiver_info_update_parser(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    subghz->txrx->protocol_result = subghz_protocol_get_by_name(
 | 
			
		||||
        subghz->txrx->protocol,
 | 
			
		||||
        subghz_history_get_name(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
 | 
			
		||||
 | 
			
		||||
    if(subghz->txrx->protocol_result->to_load_protocol != NULL) {
 | 
			
		||||
        subghz->txrx->protocol_result->to_load_protocol(
 | 
			
		||||
            subghz->txrx->protocol_result,
 | 
			
		||||
            subghz_history_get_raw_data(subghz->txrx->history, subghz->txrx->idx_menu_chosen));
 | 
			
		||||
        subghz->txrx->frequency =
 | 
			
		||||
            subghz_history_get_frequency(subghz->txrx->history, subghz->txrx->idx_menu_chosen);
 | 
			
		||||
        subghz->txrx->preset =
 | 
			
		||||
            subghz_history_get_preset(subghz->txrx->history, subghz->txrx->idx_menu_chosen);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void subghz_scene_receiver_info_on_enter(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
 | 
			
		||||
    if(subghz_scene_receiver_info_update_parser(subghz)) {
 | 
			
		||||
        char buffer_str[16];
 | 
			
		||||
        snprintf(
 | 
			
		||||
            buffer_str,
 | 
			
		||||
            sizeof(buffer_str),
 | 
			
		||||
            "%03ld.%02ld",
 | 
			
		||||
            subghz->txrx->frequency / 1000000 % 1000,
 | 
			
		||||
            subghz->txrx->frequency / 10000 % 100);
 | 
			
		||||
        widget_add_string_element(
 | 
			
		||||
            subghz->widget, 78, 0, AlignLeft, AlignTop, FontSecondary, buffer_str);
 | 
			
		||||
        if(subghz->txrx->preset == FuriHalSubGhzPresetOok650Async ||
 | 
			
		||||
           subghz->txrx->preset == FuriHalSubGhzPresetOok270Async) {
 | 
			
		||||
            snprintf(buffer_str, sizeof(buffer_str), "AM");
 | 
			
		||||
        } else if(subghz->txrx->preset == FuriHalSubGhzPreset2FSKAsync) {
 | 
			
		||||
            snprintf(buffer_str, sizeof(buffer_str), "FM");
 | 
			
		||||
        } else {
 | 
			
		||||
            furi_check(0);
 | 
			
		||||
        }
 | 
			
		||||
        widget_add_string_element(
 | 
			
		||||
            subghz->widget, 113, 0, AlignLeft, AlignTop, FontSecondary, buffer_str);
 | 
			
		||||
        string_t text;
 | 
			
		||||
        string_init(text);
 | 
			
		||||
        subghz->txrx->protocol_result->to_string(subghz->txrx->protocol_result, text);
 | 
			
		||||
        widget_add_string_multi_element(
 | 
			
		||||
            subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, string_get_cstr(text));
 | 
			
		||||
        string_clear(text);
 | 
			
		||||
 | 
			
		||||
        if(subghz->txrx->protocol_result && subghz->txrx->protocol_result->to_save_string &&
 | 
			
		||||
           strcmp(subghz->txrx->protocol_result->name, "KeeLoq")) {
 | 
			
		||||
            widget_add_button_element(
 | 
			
		||||
                subghz->widget,
 | 
			
		||||
                GuiButtonTypeRight,
 | 
			
		||||
                "Save",
 | 
			
		||||
                subghz_scene_receiver_info_callback,
 | 
			
		||||
                subghz);
 | 
			
		||||
            widget_add_button_element(
 | 
			
		||||
                subghz->widget,
 | 
			
		||||
                GuiButtonTypeCenter,
 | 
			
		||||
                "Send",
 | 
			
		||||
                subghz_scene_receiver_info_callback,
 | 
			
		||||
                subghz);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        widget_add_icon_element(subghz->widget, 32, 12, &I_DolphinFirstStart7_61x51);
 | 
			
		||||
        widget_add_string_element(
 | 
			
		||||
            subghz->widget, 13, 8, AlignLeft, AlignBottom, FontSecondary, "Error history parse.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewWidget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    if(event.type == SceneManagerEventTypeCustom) {
 | 
			
		||||
        if(event.event == GuiButtonTypeCenterPress) {
 | 
			
		||||
            //CC1101 Stop RX -> Start TX
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_TX_STATE;
 | 
			
		||||
            if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) {
 | 
			
		||||
                subghz->txrx->hopper_state = SubGhzHopperStatePause;
 | 
			
		||||
            }
 | 
			
		||||
            if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
 | 
			
		||||
                subghz_rx_end(subghz->txrx->worker);
 | 
			
		||||
                //subghz_sleep();
 | 
			
		||||
                subghz->txrx->txrx_state = SubGhzTxRxStateIdle;
 | 
			
		||||
            }
 | 
			
		||||
            if(!subghz_scene_receiver_info_update_parser(subghz)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) {
 | 
			
		||||
                subghz_tx_start(subghz);
 | 
			
		||||
                subghz->txrx->txrx_state = SubGhzTxRxStateTx;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if(event.event == GuiButtonTypeCenterRelease) {
 | 
			
		||||
            //CC1101 Stop Tx -> Start RX
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
            if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
 | 
			
		||||
                subghz_tx_stop(subghz);
 | 
			
		||||
                subghz->txrx->txrx_state = SubGhzTxRxStateIdle;
 | 
			
		||||
            }
 | 
			
		||||
            if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) {
 | 
			
		||||
                subghz_begin(subghz->txrx->preset);
 | 
			
		||||
                subghz_rx(subghz->txrx->worker, subghz->txrx->frequency);
 | 
			
		||||
                subghz->txrx->txrx_state = SubGhzTxRxStateRx;
 | 
			
		||||
            }
 | 
			
		||||
            if(subghz->txrx->hopper_state == SubGhzHopperStatePause) {
 | 
			
		||||
                subghz->txrx->hopper_state = SubGhzHopperStateRunnig;
 | 
			
		||||
            }
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_RX_STATE;
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if(event.event == GuiButtonTypeRight) {
 | 
			
		||||
            //CC1101 Stop RX -> Save
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
            if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) {
 | 
			
		||||
                subghz->txrx->hopper_state = SubGhzHopperStateOFF;
 | 
			
		||||
            }
 | 
			
		||||
            if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
 | 
			
		||||
                subghz_rx_end(subghz->txrx->worker);
 | 
			
		||||
                subghz_sleep();
 | 
			
		||||
                subghz->txrx->txrx_state = SubGhzTxRxStateIdle;
 | 
			
		||||
            }
 | 
			
		||||
            if(!subghz_scene_receiver_info_update_parser(subghz)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            if(subghz->txrx->protocol_result && subghz->txrx->protocol_result->to_save_string &&
 | 
			
		||||
               strcmp(subghz->txrx->protocol_result->name, "KeeLoq")) {
 | 
			
		||||
                scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    } else if(event.type == SceneManagerEventTypeTick) {
 | 
			
		||||
        if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) {
 | 
			
		||||
            subghz_hopper_update(subghz->txrx);
 | 
			
		||||
        }
 | 
			
		||||
        switch(subghz->state_notifications) {
 | 
			
		||||
        case NOTIFICATION_TX_STATE:
 | 
			
		||||
            notification_message(subghz->notifications, &sequence_blink_red_10);
 | 
			
		||||
            break;
 | 
			
		||||
        case NOTIFICATION_RX_STATE:
 | 
			
		||||
            notification_message(subghz->notifications, &sequence_blink_blue_10);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void subghz_scene_receiver_info_on_exit(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    widget_clear(subghz->widget);
 | 
			
		||||
}
 | 
			
		||||
@@ -35,11 +35,13 @@ const bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent even
 | 
			
		||||
 | 
			
		||||
    if(event.type == SceneManagerEventTypeCustom) {
 | 
			
		||||
        if(event.event == SCENE_SAVE_NAME_CUSTOM_EVENT) {
 | 
			
		||||
            if(subghz_save_protocol_to_file(subghz, subghz->text_store)) {
 | 
			
		||||
            if(strcmp(subghz->text_store, "") &&
 | 
			
		||||
               subghz_save_protocol_to_file(subghz, subghz->text_store)) {
 | 
			
		||||
                scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess);
 | 
			
		||||
                return true;
 | 
			
		||||
            } else {
 | 
			
		||||
                //Error save
 | 
			
		||||
                string_set(subghz->error_str, "No name file");
 | 
			
		||||
                scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -8,15 +8,18 @@ enum SubmenuIndex {
 | 
			
		||||
    SubmenuIndexCAME12bit,
 | 
			
		||||
    SubmenuIndexCAME24bit,
 | 
			
		||||
    SubmenuIndexNeroSketch,
 | 
			
		||||
    SubmenuIndexNeroRadio,
 | 
			
		||||
    SubmenuIndexGateTX,
 | 
			
		||||
    SubmenuIndexDoorHan,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool subghz_scene_set_type_submenu_to_find_protocol(void* context, const char* protocol_name) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    subghz->protocol_result = subghz_protocol_get_by_name(subghz->protocol, protocol_name);
 | 
			
		||||
    if(subghz->protocol_result == NULL) {
 | 
			
		||||
        //show error
 | 
			
		||||
    subghz->txrx->protocol_result =
 | 
			
		||||
        subghz_protocol_get_by_name(subghz->txrx->protocol, protocol_name);
 | 
			
		||||
    if(subghz->txrx->protocol_result == NULL) {
 | 
			
		||||
        string_set(subghz->error_str, "Protocol not found");
 | 
			
		||||
        scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
@@ -62,6 +65,8 @@ const void subghz_scene_set_type_on_enter(void* context) {
 | 
			
		||||
        subghz);
 | 
			
		||||
    // submenu_add_item(
 | 
			
		||||
    //     subghz->submenu, "Nero Sketch", SubmenuIndexNeroSketch, subghz_scene_set_type_submenu_callback, subghz);
 | 
			
		||||
    // submenu_add_item(
 | 
			
		||||
    //     subghz->submenu, "Nero Radio", SubmenuIndexNeroRadio, subghz_scene_set_type_submenu_callback, subghz);
 | 
			
		||||
    submenu_add_item(
 | 
			
		||||
        subghz->submenu,
 | 
			
		||||
        "Gate TX_433",
 | 
			
		||||
@@ -90,81 +95,86 @@ const bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event
 | 
			
		||||
        switch(event.event) {
 | 
			
		||||
        case SubmenuIndexPricenton:
 | 
			
		||||
            if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "Princeton")) {
 | 
			
		||||
                subghz->protocol_result->code_last_count_bit = 24;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_count_bit = 24;
 | 
			
		||||
                key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8
 | 
			
		||||
                subghz->protocol_result->code_last_found = key;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_found = key;
 | 
			
		||||
                generated_protocol = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SubmenuIndexNiceFlo12bit:
 | 
			
		||||
            if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "Nice FLO")) {
 | 
			
		||||
                subghz->protocol_result->code_last_count_bit = 12;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_count_bit = 12;
 | 
			
		||||
                key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4
 | 
			
		||||
                subghz->protocol_result->code_last_found = key;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_found = key;
 | 
			
		||||
                generated_protocol = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SubmenuIndexNiceFlo24bit:
 | 
			
		||||
            if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "Nice FLO")) {
 | 
			
		||||
                subghz->protocol_result->code_last_count_bit = 24;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_count_bit = 24;
 | 
			
		||||
                key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8
 | 
			
		||||
                subghz->protocol_result->code_last_found = key;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_found = key;
 | 
			
		||||
                generated_protocol = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SubmenuIndexCAME12bit:
 | 
			
		||||
            if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "CAME")) {
 | 
			
		||||
                subghz->protocol_result->code_last_count_bit = 12;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_count_bit = 12;
 | 
			
		||||
                key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4
 | 
			
		||||
                subghz->protocol_result->code_last_found = key;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_found = key;
 | 
			
		||||
                generated_protocol = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SubmenuIndexCAME24bit:
 | 
			
		||||
            if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "CAME")) {
 | 
			
		||||
                subghz->protocol_result->code_last_count_bit = 24;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_count_bit = 24;
 | 
			
		||||
                key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8
 | 
			
		||||
                subghz->protocol_result->code_last_found = key;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_found = key;
 | 
			
		||||
                generated_protocol = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        // case SubmenuIndexNeroSketch:
 | 
			
		||||
        //     /* code */
 | 
			
		||||
        //     break;
 | 
			
		||||
        // case SubmenuIndexNeroRadio:
 | 
			
		||||
        //     /* code */
 | 
			
		||||
        //     break;
 | 
			
		||||
        case SubmenuIndexGateTX:
 | 
			
		||||
            if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "GateTX")) {
 | 
			
		||||
                subghz->protocol_result->code_last_count_bit = 24;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_count_bit = 24;
 | 
			
		||||
                key = (key & 0x00F0FFFF) | 0xF << 16; //btn 0xF, 0xC, 0xA, 0x6
 | 
			
		||||
                subghz->protocol_result->code_last_found = subghz_protocol_common_reverse_key(
 | 
			
		||||
                    key, subghz->protocol_result->code_last_count_bit);
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_found =
 | 
			
		||||
                    subghz_protocol_common_reverse_key(
 | 
			
		||||
                        key, subghz->txrx->protocol_result->code_last_count_bit);
 | 
			
		||||
                generated_protocol = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SubmenuIndexDoorHan:
 | 
			
		||||
            if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "KeeLoq")) {
 | 
			
		||||
                subghz->protocol_result->code_last_count_bit = 64;
 | 
			
		||||
                subghz->protocol_result->serial = key & 0x0FFFFFFF;
 | 
			
		||||
                subghz->protocol_result->btn = 0x2; //btn 0x1, 0x2, 0x4, 0x8
 | 
			
		||||
                subghz->protocol_result->cnt = 0x0003;
 | 
			
		||||
                subghz->txrx->protocol_result->code_last_count_bit = 64;
 | 
			
		||||
                subghz->txrx->protocol_result->serial = key & 0x0FFFFFFF;
 | 
			
		||||
                subghz->txrx->protocol_result->btn = 0x2; //btn 0x1, 0x2, 0x4, 0x8
 | 
			
		||||
                subghz->txrx->protocol_result->cnt = 0x0003;
 | 
			
		||||
                if(subghz_protocol_keeloq_set_manufacture_name(
 | 
			
		||||
                       subghz->protocol_result, "DoorHan")) {
 | 
			
		||||
                    subghz->protocol_result->code_last_found =
 | 
			
		||||
                        subghz_protocol_keeloq_gen_key(subghz->protocol_result);
 | 
			
		||||
                       subghz->txrx->protocol_result, "DoorHan")) {
 | 
			
		||||
                    subghz->txrx->protocol_result->code_last_found =
 | 
			
		||||
                        subghz_protocol_keeloq_gen_key(subghz->txrx->protocol_result);
 | 
			
		||||
                    generated_protocol = true;
 | 
			
		||||
                } else {
 | 
			
		||||
                    generated_protocol = false;
 | 
			
		||||
                    scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNoMan);
 | 
			
		||||
                    string_set(subghz->error_str, "No manufactory key");
 | 
			
		||||
                    scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            return false;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(generated_protocol) {
 | 
			
		||||
            subghz->frequency = subghz_frequencies[subghz_frequencies_433_92];
 | 
			
		||||
            subghz->preset = FuriHalSubGhzPresetOok650Async;
 | 
			
		||||
            subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92];
 | 
			
		||||
            subghz->txrx->preset = FuriHalSubGhzPresetOok650Async;
 | 
			
		||||
            scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,26 +2,26 @@
 | 
			
		||||
 | 
			
		||||
#define SCENE_NO_MAN_CUSTOM_EVENT (11UL)
 | 
			
		||||
 | 
			
		||||
void subghz_scene_no_man_popup_callback(void* context) {
 | 
			
		||||
void subghz_scene_show_error_popup_callback(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    view_dispatcher_send_custom_event(subghz->view_dispatcher, SCENE_NO_MAN_CUSTOM_EVENT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void subghz_scene_no_man_on_enter(void* context) {
 | 
			
		||||
const void subghz_scene_show_error_on_enter(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
 | 
			
		||||
    // Setup view
 | 
			
		||||
    Popup* popup = subghz->popup;
 | 
			
		||||
    popup_set_icon(popup, 32, 12, &I_DolphinFirstStart7_61x51);
 | 
			
		||||
    popup_set_header(popup, "No manufactory key", 13, 8, AlignLeft, AlignBottom);
 | 
			
		||||
    popup_set_header(popup, string_get_cstr(subghz->error_str), 64, 8, AlignCenter, AlignBottom);
 | 
			
		||||
    popup_set_timeout(popup, 1500);
 | 
			
		||||
    popup_set_context(popup, subghz);
 | 
			
		||||
    popup_set_callback(popup, subghz_scene_no_man_popup_callback);
 | 
			
		||||
    popup_set_callback(popup, subghz_scene_show_error_popup_callback);
 | 
			
		||||
    popup_enable_timeout(popup);
 | 
			
		||||
    view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewPopup);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const bool subghz_scene_no_man_on_event(void* context, SceneManagerEvent event) {
 | 
			
		||||
const bool subghz_scene_show_error_on_event(void* context, SceneManagerEvent event) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    if(event.type == SceneManagerEventTypeCustom) {
 | 
			
		||||
        if(event.event == SCENE_NO_MAN_CUSTOM_EVENT) {
 | 
			
		||||
@@ -33,7 +33,7 @@ const bool subghz_scene_no_man_on_event(void* context, SceneManagerEvent event)
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void subghz_scene_no_man_on_exit(void* context) {
 | 
			
		||||
const void subghz_scene_show_error_on_exit(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
 | 
			
		||||
    // Clear view
 | 
			
		||||
@@ -45,4 +45,5 @@ const void subghz_scene_no_man_on_exit(void* context) {
 | 
			
		||||
    popup_set_context(popup, NULL);
 | 
			
		||||
    popup_set_timeout(popup, 0);
 | 
			
		||||
    popup_disable_timeout(popup);
 | 
			
		||||
    string_clean(subghz->error_str);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
#include "../subghz_i.h"
 | 
			
		||||
#include "../views/subghz_transmitter.h"
 | 
			
		||||
#include <lib/subghz/protocols/subghz_protocol_keeloq.h>
 | 
			
		||||
 | 
			
		||||
void subghz_scene_transmitter_callback(SubghzTransmitterEvent event, void* context) {
 | 
			
		||||
    furi_assert(context);
 | 
			
		||||
@@ -7,42 +8,90 @@ void subghz_scene_transmitter_callback(SubghzTransmitterEvent event, void* conte
 | 
			
		||||
    view_dispatcher_send_custom_event(subghz->view_dispatcher, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void subghz_scene_transmitter_update_data_show(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
 | 
			
		||||
    if(subghz->txrx->protocol_result && subghz->txrx->protocol_result->get_upload_protocol) {
 | 
			
		||||
        string_t key_str;
 | 
			
		||||
        string_init(key_str);
 | 
			
		||||
        char frequency_str[10];
 | 
			
		||||
        char preset_str[6];
 | 
			
		||||
        uint8_t show_button = 0;
 | 
			
		||||
        subghz->txrx->protocol_result->to_string(subghz->txrx->protocol_result, key_str);
 | 
			
		||||
 | 
			
		||||
        if((!strcmp(subghz->txrx->protocol_result->name, "KeeLoq")) &&
 | 
			
		||||
           (!strcmp(
 | 
			
		||||
               subghz_protocol_keeloq_get_manufacture_name(subghz->txrx->protocol_result),
 | 
			
		||||
               "Unknown"))) {
 | 
			
		||||
            show_button = 0;
 | 
			
		||||
        } else {
 | 
			
		||||
            show_button = 1;
 | 
			
		||||
        }
 | 
			
		||||
        snprintf(
 | 
			
		||||
            frequency_str,
 | 
			
		||||
            sizeof(frequency_str),
 | 
			
		||||
            "%03ld.%02ld",
 | 
			
		||||
            subghz->txrx->frequency / 1000000 % 1000,
 | 
			
		||||
            subghz->txrx->frequency / 10000 % 100);
 | 
			
		||||
        if(subghz->txrx->preset == FuriHalSubGhzPresetOok650Async ||
 | 
			
		||||
           subghz->txrx->preset == FuriHalSubGhzPresetOok270Async) {
 | 
			
		||||
            snprintf(preset_str, sizeof(preset_str), "AM");
 | 
			
		||||
        } else if(subghz->txrx->preset == FuriHalSubGhzPreset2FSKAsync) {
 | 
			
		||||
            snprintf(preset_str, sizeof(preset_str), "FM");
 | 
			
		||||
        } else {
 | 
			
		||||
            furi_check(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        subghz_transmitter_add_data_to_show(
 | 
			
		||||
            subghz->subghz_transmitter,
 | 
			
		||||
            string_get_cstr(key_str),
 | 
			
		||||
            frequency_str,
 | 
			
		||||
            preset_str,
 | 
			
		||||
            show_button);
 | 
			
		||||
        string_clear(key_str);
 | 
			
		||||
    } else {
 | 
			
		||||
        string_set(subghz->error_str, "Protocol not found");
 | 
			
		||||
        scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void subghz_scene_transmitter_on_enter(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    SubghzTransmitter* subghz_transmitter = subghz->subghz_transmitter;
 | 
			
		||||
 | 
			
		||||
    subghz_transmitter_set_callback(subghz_transmitter, subghz_scene_transmitter_callback, subghz);
 | 
			
		||||
    subghz_transmitter_set_protocol(subghz_transmitter, subghz->protocol_result);
 | 
			
		||||
    subghz_transmitter_set_frequency_preset(subghz_transmitter, subghz->frequency, subghz->preset);
 | 
			
		||||
 | 
			
		||||
    view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTransmitter);
 | 
			
		||||
 | 
			
		||||
    subghz_transmitter_set_callback(
 | 
			
		||||
        subghz->subghz_transmitter, subghz_scene_transmitter_callback, subghz);
 | 
			
		||||
    subghz_scene_transmitter_update_data_show(subghz);
 | 
			
		||||
    subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
    view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTransmitter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
 | 
			
		||||
    if(event.type == SceneManagerEventTypeCustom) {
 | 
			
		||||
        if(event.event == SubghzTransmitterEventSendStart) {
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_TX_STATE;
 | 
			
		||||
            subghz_transmitter_tx_start(subghz);
 | 
			
		||||
            if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
 | 
			
		||||
                subghz_rx_end(subghz->txrx->worker);
 | 
			
		||||
                subghz->txrx->txrx_state = SubGhzTxRxStateIdle;
 | 
			
		||||
            }
 | 
			
		||||
            if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) {
 | 
			
		||||
                subghz_tx_start(subghz);
 | 
			
		||||
                subghz_scene_transmitter_update_data_show(subghz);
 | 
			
		||||
                subghz->txrx->txrx_state = SubGhzTxRxStateTx;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if(event.event == SubghzTransmitterEventSendStop) {
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
            subghz_transmitter_tx_stop(subghz);
 | 
			
		||||
            subghz_sleep();
 | 
			
		||||
            if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
 | 
			
		||||
                subghz_tx_stop(subghz);
 | 
			
		||||
                subghz_sleep();
 | 
			
		||||
                subghz->txrx->txrx_state = SubGhzTxRxStateIdle;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if(event.event == SubghzTransmitterEventBack) {
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
            scene_manager_search_and_switch_to_previous_scene(
 | 
			
		||||
                subghz->scene_manager, SubGhzSceneStart);
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if(event.event == SubghzTransmitterEventNoMan) {
 | 
			
		||||
            subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
            scene_manager_search_and_switch_to_previous_scene(
 | 
			
		||||
                subghz->scene_manager, SubGhzSceneNoMan);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    } else if(event.type == SceneManagerEventTypeTick) {
 | 
			
		||||
        if(subghz->state_notifications == NOTIFICATION_TX_STATE) {
 | 
			
		||||
@@ -55,7 +104,6 @@ const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent ev
 | 
			
		||||
 | 
			
		||||
const void subghz_scene_transmitter_on_exit(void* context) {
 | 
			
		||||
    SubGhz* subghz = context;
 | 
			
		||||
    SubghzTransmitter* subghz_transmitter = subghz->subghz_transmitter;
 | 
			
		||||
    subghz_transmitter_set_callback(subghz_transmitter, NULL, subghz);
 | 
			
		||||
 | 
			
		||||
    subghz->state_notifications = NOTIFICATION_IDLE_STATE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user