diff --git a/applications/external/subghz_bruteforcer/helpers/radio_device_loader.c b/applications/external/subghz_bruteforcer/helpers/radio_device_loader.c new file mode 100644 index 000000000..d2cffde58 --- /dev/null +++ b/applications/external/subghz_bruteforcer/helpers/radio_device_loader.c @@ -0,0 +1,64 @@ +#include "radio_device_loader.h" + +#include +#include + +static void radio_device_loader_power_on() { + uint8_t attempts = 0; + while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { + furi_hal_power_enable_otg(); + //CC1101 power-up time + furi_delay_ms(10); + } +} + +static void radio_device_loader_power_off() { + if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg(); +} + +bool radio_device_loader_is_connect_external(const char* name) { + bool is_connect = false; + bool is_otg_enabled = furi_hal_power_is_otg_enabled(); + + if(!is_otg_enabled) { + radio_device_loader_power_on(); + } + + const SubGhzDevice* device = subghz_devices_get_by_name(name); + if(device) { + is_connect = subghz_devices_is_connect(device); + } + + if(!is_otg_enabled) { + radio_device_loader_power_off(); + } + return is_connect; +} + +const SubGhzDevice* radio_device_loader_set( + const SubGhzDevice* current_radio_device, + SubGhzRadioDeviceType radio_device_type) { + const SubGhzDevice* radio_device; + + if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 && + radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) { + radio_device_loader_power_on(); + radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME); + subghz_devices_begin(radio_device); + } else if(current_radio_device == NULL) { + radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); + } else { + radio_device_loader_end(current_radio_device); + radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); + } + + return radio_device; +} + +void radio_device_loader_end(const SubGhzDevice* radio_device) { + furi_assert(radio_device); + radio_device_loader_power_off(); + if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) { + subghz_devices_end(radio_device); + } +} \ No newline at end of file diff --git a/applications/external/subghz_bruteforcer/helpers/radio_device_loader.h b/applications/external/subghz_bruteforcer/helpers/radio_device_loader.h new file mode 100644 index 000000000..bee4e2c36 --- /dev/null +++ b/applications/external/subghz_bruteforcer/helpers/radio_device_loader.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +/** SubGhzRadioDeviceType */ +typedef enum { + SubGhzRadioDeviceTypeInternal, + SubGhzRadioDeviceTypeExternalCC1101, +} SubGhzRadioDeviceType; + +const SubGhzDevice* radio_device_loader_set( + const SubGhzDevice* current_radio_device, + SubGhzRadioDeviceType radio_device_type); + +void radio_device_loader_end(const SubGhzDevice* radio_device); \ No newline at end of file diff --git a/applications/external/subghz_bruteforcer/helpers/subbrute_worker.c b/applications/external/subghz_bruteforcer/helpers/subbrute_worker.c index ef622482f..fb17e15a6 100644 --- a/applications/external/subghz_bruteforcer/helpers/subbrute_worker.c +++ b/applications/external/subghz_bruteforcer/helpers/subbrute_worker.c @@ -9,7 +9,7 @@ #define SUBBRUTE_TX_TIMEOUT 6 #define SUBBRUTE_MANUAL_TRANSMIT_INTERVAL 250 -SubBruteWorker* subbrute_worker_alloc() { +SubBruteWorker* subbrute_worker_alloc(const SubGhzDevice* radio_device) { SubBruteWorker* instance = malloc(sizeof(SubBruteWorker)); instance->state = SubBruteWorkerStateIDLE; @@ -37,6 +37,8 @@ SubBruteWorker* subbrute_worker_alloc() { instance->transmit_mode = false; + instance->radio_device = radio_device; + return instance; } @@ -56,6 +58,9 @@ void subbrute_worker_free(SubBruteWorker* instance) { furi_thread_free(instance->thread); + subghz_devices_sleep(instance->radio_device); + radio_device_loader_end(instance->radio_device); + free(instance); } @@ -206,9 +211,7 @@ void subbrute_worker_stop(SubBruteWorker* instance) { instance->worker_running = false; furi_thread_join(instance->thread); - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_idle(); - furi_hal_subghz_sleep(); + subghz_devices_idle(instance->radio_device); } bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t step) { @@ -320,20 +323,24 @@ void subbrute_worker_subghz_transmit(SubBruteWorker* instance, FlipperFormat* fl instance->transmitter = subghz_transmitter_alloc_init(instance->environment, instance->protocol_name); subghz_transmitter_deserialize(instance->transmitter, flipper_format); - furi_hal_subghz_reset(); - furi_hal_subghz_idle(); - furi_hal_subghz_load_preset(instance->preset); - furi_hal_subghz_set_frequency_and_path(instance->frequency); - furi_hal_subghz_start_async_tx(subghz_transmitter_yield, instance->transmitter); - while(!furi_hal_subghz_is_async_tx_complete()) { - furi_delay_ms(timeout); + subghz_devices_reset(instance->radio_device); + subghz_devices_idle(instance->radio_device); + subghz_devices_load_preset(instance->radio_device, instance->preset, NULL); + subghz_devices_set_frequency( + instance->radio_device, instance->frequency); // TODO is freq valid check + + if(subghz_devices_set_tx(instance->radio_device)) { + subghz_devices_start_async_tx( + instance->radio_device, subghz_transmitter_yield, instance->transmitter); + while(!subghz_devices_is_async_complete_tx(instance->radio_device)) { + furi_delay_ms(timeout); + } + subghz_devices_stop_async_tx(instance->radio_device); } - furi_hal_subghz_stop_async_tx(); - //furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_idle(); - //furi_hal_subghz_sleep(); + subghz_devices_idle(instance->radio_device); + subghz_transmitter_stop(instance->transmitter); subghz_transmitter_free(instance->transmitter); instance->transmitter = NULL; @@ -456,4 +463,18 @@ void subbrute_worker_timeout_dec(SubBruteWorker* instance) { if(instance->tx_timeout_ms > 0) { instance->tx_timeout_ms--; } +} + +bool subbrute_worker_is_tx_allowed(SubBruteWorker* instance, uint32_t value) { + furi_assert(instance); + bool res = false; + + if(!subghz_devices_is_frequency_valid(instance->radio_device, value)) { + } else { + subghz_devices_set_frequency(instance->radio_device, value); + res = subghz_devices_set_tx(instance->radio_device); + subghz_devices_idle(instance->radio_device); + } + + return res; } \ No newline at end of file diff --git a/applications/external/subghz_bruteforcer/helpers/subbrute_worker.h b/applications/external/subghz_bruteforcer/helpers/subbrute_worker.h index f7c32dd4b..ef3a5eba8 100644 --- a/applications/external/subghz_bruteforcer/helpers/subbrute_worker.h +++ b/applications/external/subghz_bruteforcer/helpers/subbrute_worker.h @@ -1,6 +1,7 @@ #pragma once #include "../subbrute_protocols.h" +#include "radio_device_loader.h" typedef enum { SubBruteWorkerStateIDLE, @@ -13,7 +14,7 @@ typedef void (*SubBruteWorkerCallback)(void* context, SubBruteWorkerState state) typedef struct SubBruteWorker SubBruteWorker; -SubBruteWorker* subbrute_worker_alloc(); +SubBruteWorker* subbrute_worker_alloc(const SubGhzDevice* radio_device); void subbrute_worker_free(SubBruteWorker* instance); uint64_t subbrute_worker_get_step(SubBruteWorker* instance); bool subbrute_worker_set_step(SubBruteWorker* instance, uint64_t step); @@ -46,3 +47,5 @@ uint8_t subbrute_worker_get_timeout(SubBruteWorker* instance); void subbrute_worker_timeout_inc(SubBruteWorker* instance); void subbrute_worker_timeout_dec(SubBruteWorker* instance); + +bool subbrute_worker_is_tx_allowed(SubBruteWorker* instance, uint32_t value); \ No newline at end of file diff --git a/applications/external/subghz_bruteforcer/helpers/subbrute_worker_private.h b/applications/external/subghz_bruteforcer/helpers/subbrute_worker_private.h index a660ca731..7268389db 100644 --- a/applications/external/subghz_bruteforcer/helpers/subbrute_worker_private.h +++ b/applications/external/subghz_bruteforcer/helpers/subbrute_worker_private.h @@ -22,6 +22,7 @@ struct SubBruteWorker { SubGhzTransmitter* transmitter; const char* protocol_name; uint8_t tx_timeout_ms; + const SubGhzDevice* radio_device; // Initiated values SubBruteAttacks attack; // Attack state diff --git a/applications/external/subghz_bruteforcer/subbrute.c b/applications/external/subghz_bruteforcer/subbrute.c index f47c75943..75506f2c2 100644 --- a/applications/external/subghz_bruteforcer/subbrute.c +++ b/applications/external/subghz_bruteforcer/subbrute.c @@ -49,11 +49,20 @@ SubBruteState* subbrute_alloc() { // Notifications instance->notifications = furi_record_open(RECORD_NOTIFICATION); + subghz_devices_init(); + + // init radio device + instance->radio_device = + radio_device_loader_set(instance->radio_device, SubGhzRadioDeviceTypeExternalCC1101); + + subghz_devices_reset(instance->radio_device); + subghz_devices_idle(instance->radio_device); + // Devices - instance->device = subbrute_device_alloc(); + instance->device = subbrute_device_alloc(instance->radio_device); // SubBruteWorker - instance->worker = subbrute_worker_alloc(); + instance->worker = subbrute_worker_alloc(instance->radio_device); // TextInput instance->text_input = text_input_alloc(); @@ -95,7 +104,7 @@ SubBruteState* subbrute_alloc() { //instance->environment = subghz_environment_alloc(); // Uncomment to enable Debug pin output on PIN 17(1W) - //furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton); + // subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_ibutton); return instance; } @@ -104,7 +113,7 @@ void subbrute_free(SubBruteState* instance) { furi_assert(instance); // Uncomment to enable Debug pin output on PIN 17(1W) - //furi_hal_subghz_set_async_mirror_pin(NULL); + // subghz_devices_set_async_mirror_pin(instance->radio_device, NULL); // SubBruteWorker subbrute_worker_stop(instance->worker); @@ -113,6 +122,8 @@ void subbrute_free(SubBruteState* instance) { // SubBruteDevice subbrute_device_free(instance->device); + subghz_devices_deinit(); + // Notifications notification_message(instance->notifications, &sequence_blink_stop); furi_record_close(RECORD_NOTIFICATION); @@ -179,6 +190,7 @@ void subbrute_popup_closed_callback(void* context) { // ENTRYPOINT int32_t subbrute_app(void* p) { UNUSED(p); + furi_hal_power_suppress_charge_enter(); dolphin_deed(DolphinDeedPluginStart); SubBruteState* instance = subbrute_alloc(); @@ -186,26 +198,11 @@ int32_t subbrute_app(void* p) { instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen); scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart); - // Enable power for External CC1101 if it is connected - furi_hal_subghz_enable_ext_power(); - // Auto switch to internal radio if external radio is not available - furi_delay_ms(15); - if(!furi_hal_subghz_check_radio()) { - furi_hal_subghz_select_radio_type(SubGhzRadioInternal); - furi_hal_subghz_init_radio_type(SubGhzRadioInternal); - } - - furi_hal_power_suppress_charge_enter(); - notification_message(instance->notifications, &sequence_display_backlight_on); view_dispatcher_run(instance->view_dispatcher); - furi_hal_power_suppress_charge_exit(); - // Disable power for External CC1101 if it was enabled and module is connected - furi_hal_subghz_disable_ext_power(); - // Reinit SPI handles for internal radio / nfc - furi_hal_subghz_init_radio_type(SubGhzRadioInternal); subbrute_free(instance); + furi_hal_power_suppress_charge_exit(); return 0; } diff --git a/applications/external/subghz_bruteforcer/subbrute_device.c b/applications/external/subghz_bruteforcer/subbrute_device.c index 192b8bfa0..01ed74b36 100644 --- a/applications/external/subghz_bruteforcer/subbrute_device.c +++ b/applications/external/subghz_bruteforcer/subbrute_device.c @@ -9,7 +9,7 @@ #define TAG "SubBruteDevice" -SubBruteDevice* subbrute_device_alloc() { +SubBruteDevice* subbrute_device_alloc(const SubGhzDevice* radio_device) { SubBruteDevice* instance = malloc(sizeof(SubBruteDevice)); instance->current_step = 0; @@ -22,6 +22,8 @@ SubBruteDevice* subbrute_device_alloc() { subghz_environment_set_protocol_registry( instance->environment, (void*)&subghz_protocol_registry); + instance->radio_device = radio_device; + #ifdef FURI_DEBUG subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile); #else @@ -152,7 +154,7 @@ SubBruteFileResult subbrute_device_attack_set( // For non-file types we didn't set SubGhzProtocolDecoderBase instance->receiver = subghz_receiver_alloc_init(instance->environment); subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); - furi_hal_subghz_reset(); + // furi_hal_subghz_reset(); // TODO Is this necessary? uint8_t protocol_check_result = SubBruteFileResultProtocolNotFound; #ifdef FURI_DEBUG @@ -241,7 +243,7 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil instance->receiver = subghz_receiver_alloc_init(instance->environment); subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); - furi_hal_subghz_reset(); + // furi_hal_subghz_reset(); // TODO Is this necessary? do { if(!flipper_format_file_open_existing(fff_data_file, file_path)) { @@ -261,11 +263,22 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil result = SubBruteFileResultMissingOrIncorrectFrequency; break; } - instance->file_protocol_info->frequency = temp_data32; - if(!furi_hal_subghz_is_tx_allowed(instance->file_protocol_info->frequency)) { + + if(!subghz_devices_is_frequency_valid(instance->radio_device, temp_data32)) { + FURI_LOG_E(TAG, "Unsupported radio device frequency"); + result = SubBruteFileResultMissingOrIncorrectFrequency; + break; + } + + instance->file_protocol_info->frequency = + subghz_devices_set_frequency(instance->radio_device, temp_data32); + + if(!subghz_devices_set_tx(instance->radio_device)) { + subghz_devices_idle(instance->radio_device); result = SubBruteFileResultFrequencyNotAllowed; break; } + subghz_devices_idle(instance->radio_device); // Preset if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) { diff --git a/applications/external/subghz_bruteforcer/subbrute_device.h b/applications/external/subghz_bruteforcer/subbrute_device.h index 7ff650e93..8b91222ee 100644 --- a/applications/external/subghz_bruteforcer/subbrute_device.h +++ b/applications/external/subghz_bruteforcer/subbrute_device.h @@ -5,6 +5,7 @@ #include #include #include +#include "helpers/radio_device_loader.h" #define SUBBRUTE_TEXT_STORE_SIZE 256 @@ -42,6 +43,7 @@ typedef struct { SubGhzReceiver* receiver; SubGhzProtocolDecoderBase* decoder_result; SubGhzEnvironment* environment; + const SubGhzDevice* radio_device; // Attack state SubBruteAttacks attack; @@ -56,7 +58,7 @@ typedef struct { uint8_t bit_index; } SubBruteDevice; -SubBruteDevice* subbrute_device_alloc(); +SubBruteDevice* subbrute_device_alloc(const SubGhzDevice* radio_device;); void subbrute_device_free(SubBruteDevice* instance); bool subbrute_device_save_file(SubBruteDevice* instance, const char* key_name); diff --git a/applications/external/subghz_bruteforcer/subbrute_i.h b/applications/external/subghz_bruteforcer/subbrute_i.h index 9f1bd57d4..6f8f3ac09 100644 --- a/applications/external/subghz_bruteforcer/subbrute_i.h +++ b/applications/external/subghz_bruteforcer/subbrute_i.h @@ -56,6 +56,7 @@ struct SubBruteState { Popup* popup; Widget* widget; DialogsApp* dialogs; + const SubGhzDevice* radio_device; // Text store char text_store[SUBBRUTE_MAX_LEN_NAME];