gid9798 2 лет назад
Родитель
Сommit
c191d66cd7

+ 64 - 0
helpers/radio_device_loader.c

@@ -0,0 +1,64 @@
+#include "radio_device_loader.h"
+
+#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
+#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
+
+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);
+    }
+}

+ 15 - 0
helpers/radio_device_loader.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include <lib/subghz/devices/devices.h>
+
+/** 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);

+ 53 - 16
helpers/subbrute_worker.c

@@ -9,7 +9,7 @@
 #define SUBBRUTE_TX_TIMEOUT 6
 #define SUBBRUTE_TX_TIMEOUT 6
 #define SUBBRUTE_MANUAL_TRANSMIT_INTERVAL 250
 #define SUBBRUTE_MANUAL_TRANSMIT_INTERVAL 250
 
 
-SubBruteWorker* subbrute_worker_alloc() {
+SubBruteWorker* subbrute_worker_alloc(const SubGhzDevice* radio_device) {
     SubBruteWorker* instance = malloc(sizeof(SubBruteWorker));
     SubBruteWorker* instance = malloc(sizeof(SubBruteWorker));
 
 
     instance->state = SubBruteWorkerStateIDLE;
     instance->state = SubBruteWorkerStateIDLE;
@@ -37,6 +37,8 @@ SubBruteWorker* subbrute_worker_alloc() {
 
 
     instance->transmit_mode = false;
     instance->transmit_mode = false;
 
 
+    instance->radio_device = radio_device;
+
     return instance;
     return instance;
 }
 }
 
 
@@ -56,6 +58,9 @@ void subbrute_worker_free(SubBruteWorker* instance) {
 
 
     furi_thread_free(instance->thread);
     furi_thread_free(instance->thread);
 
 
+    subghz_devices_sleep(instance->radio_device);
+    radio_device_loader_end(instance->radio_device);
+
     free(instance);
     free(instance);
 }
 }
 
 
@@ -206,9 +211,10 @@ void subbrute_worker_stop(SubBruteWorker* instance) {
     instance->worker_running = false;
     instance->worker_running = false;
     furi_thread_join(instance->thread);
     furi_thread_join(instance->thread);
 
 
-    furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate);
-    furi_hal_subghz_idle();
-    furi_hal_subghz_sleep();
+    // 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) {
 bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t step) {
@@ -320,20 +326,37 @@ void subbrute_worker_subghz_transmit(SubBruteWorker* instance, FlipperFormat* fl
     instance->transmitter =
     instance->transmitter =
         subghz_transmitter_alloc_init(instance->environment, instance->protocol_name);
         subghz_transmitter_alloc_init(instance->environment, instance->protocol_name);
     subghz_transmitter_deserialize(instance->transmitter, flipper_format);
     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);
+    // 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);
+    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();
+    // while(!furi_hal_subghz_is_async_tx_complete()) {
+    //     furi_delay_ms(timeout);
+    // }
+    // 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_stop(instance->transmitter);
     subghz_transmitter_free(instance->transmitter);
     subghz_transmitter_free(instance->transmitter);
     instance->transmitter = NULL;
     instance->transmitter = NULL;
@@ -456,4 +479,18 @@ void subbrute_worker_timeout_dec(SubBruteWorker* instance) {
     if(instance->tx_timeout_ms > 0) {
     if(instance->tx_timeout_ms > 0) {
         instance->tx_timeout_ms--;
         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;
 }
 }

+ 4 - 1
helpers/subbrute_worker.h

@@ -1,6 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "../subbrute_protocols.h"
 #include "../subbrute_protocols.h"
+#include "radio_device_loader.h"
 
 
 typedef enum {
 typedef enum {
     SubBruteWorkerStateIDLE,
     SubBruteWorkerStateIDLE,
@@ -13,7 +14,7 @@ typedef void (*SubBruteWorkerCallback)(void* context, SubBruteWorkerState state)
 
 
 typedef struct SubBruteWorker SubBruteWorker;
 typedef struct SubBruteWorker SubBruteWorker;
 
 
-SubBruteWorker* subbrute_worker_alloc();
+SubBruteWorker* subbrute_worker_alloc(const SubGhzDevice* radio_device);
 void subbrute_worker_free(SubBruteWorker* instance);
 void subbrute_worker_free(SubBruteWorker* instance);
 uint64_t subbrute_worker_get_step(SubBruteWorker* instance);
 uint64_t subbrute_worker_get_step(SubBruteWorker* instance);
 bool subbrute_worker_set_step(SubBruteWorker* instance, uint64_t step);
 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_inc(SubBruteWorker* instance);
 
 
 void subbrute_worker_timeout_dec(SubBruteWorker* instance);
 void subbrute_worker_timeout_dec(SubBruteWorker* instance);
+
+bool subbrute_worker_is_tx_allowed(SubBruteWorker* instance, uint32_t value);

+ 1 - 0
helpers/subbrute_worker_private.h

@@ -22,6 +22,7 @@ struct SubBruteWorker {
     SubGhzTransmitter* transmitter;
     SubGhzTransmitter* transmitter;
     const char* protocol_name;
     const char* protocol_name;
     uint8_t tx_timeout_ms;
     uint8_t tx_timeout_ms;
+    const SubGhzDevice* radio_device;
 
 
     // Initiated values
     // Initiated values
     SubBruteAttacks attack; // Attack state
     SubBruteAttacks attack; // Attack state

+ 19 - 20
subbrute.c

@@ -48,11 +48,20 @@ SubBruteState* subbrute_alloc() {
     // Notifications
     // Notifications
     instance->notifications = furi_record_open(RECORD_NOTIFICATION);
     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
     // Devices
-    instance->device = subbrute_device_alloc();
+    instance->device = subbrute_device_alloc(instance->radio_device);
 
 
     // SubBruteWorker
     // SubBruteWorker
-    instance->worker = subbrute_worker_alloc();
+    instance->worker = subbrute_worker_alloc(instance->radio_device);
 
 
     // TextInput
     // TextInput
     instance->text_input = text_input_alloc();
     instance->text_input = text_input_alloc();
@@ -94,7 +103,8 @@ SubBruteState* subbrute_alloc() {
     //instance->environment = subghz_environment_alloc();
     //instance->environment = subghz_environment_alloc();
 
 
     // Uncomment to enable Debug pin output on PIN 17(1W)
     // Uncomment to enable Debug pin output on PIN 17(1W)
-    //furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton);
+    // //furi_hal_subghz_set_async_mirror_pin(&gpio_ibutton);
+    // subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_ibutton);
 
 
     return instance;
     return instance;
 }
 }
@@ -103,7 +113,8 @@ void subbrute_free(SubBruteState* instance) {
     furi_assert(instance);
     furi_assert(instance);
 
 
     // Uncomment to enable Debug pin output on PIN 17(1W)
     // Uncomment to enable Debug pin output on PIN 17(1W)
-    //furi_hal_subghz_set_async_mirror_pin(NULL);
+    // //furi_hal_subghz_set_async_mirror_pin(NULL);
+    // subghz_devices_set_async_mirror_pin(instance->radio_device, NULL);
 
 
     // SubBruteWorker
     // SubBruteWorker
     subbrute_worker_stop(instance->worker);
     subbrute_worker_stop(instance->worker);
@@ -112,6 +123,8 @@ void subbrute_free(SubBruteState* instance) {
     // SubBruteDevice
     // SubBruteDevice
     subbrute_device_free(instance->device);
     subbrute_device_free(instance->device);
 
 
+    subghz_devices_deinit();
+
     // Notifications
     // Notifications
     notification_message(instance->notifications, &sequence_blink_stop);
     notification_message(instance->notifications, &sequence_blink_stop);
     furi_record_close(RECORD_NOTIFICATION);
     furi_record_close(RECORD_NOTIFICATION);
@@ -178,32 +191,18 @@ void subbrute_popup_closed_callback(void* context) {
 // ENTRYPOINT
 // ENTRYPOINT
 int32_t subbrute_app(void* p) {
 int32_t subbrute_app(void* p) {
     UNUSED(p);
     UNUSED(p);
+    furi_hal_power_suppress_charge_enter();
 
 
     SubBruteState* instance = subbrute_alloc();
     SubBruteState* instance = subbrute_alloc();
     view_dispatcher_attach_to_gui(
     view_dispatcher_attach_to_gui(
         instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen);
         instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen);
     scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
     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);
     notification_message(instance->notifications, &sequence_display_backlight_on);
     view_dispatcher_run(instance->view_dispatcher);
     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);
     subbrute_free(instance);
 
 
+    furi_hal_power_suppress_charge_exit();
     return 0;
     return 0;
 }
 }

+ 23 - 5
subbrute_device.c

@@ -9,7 +9,7 @@
 
 
 #define TAG "SubBruteDevice"
 #define TAG "SubBruteDevice"
 
 
-SubBruteDevice* subbrute_device_alloc() {
+SubBruteDevice* subbrute_device_alloc(const SubGhzDevice* radio_device) {
     SubBruteDevice* instance = malloc(sizeof(SubBruteDevice));
     SubBruteDevice* instance = malloc(sizeof(SubBruteDevice));
 
 
     instance->current_step = 0;
     instance->current_step = 0;
@@ -22,6 +22,8 @@ SubBruteDevice* subbrute_device_alloc() {
     subghz_environment_set_protocol_registry(
     subghz_environment_set_protocol_registry(
         instance->environment, (void*)&subghz_protocol_registry);
         instance->environment, (void*)&subghz_protocol_registry);
 
 
+    instance->radio_device = radio_device;
+
 #ifdef FURI_DEBUG
 #ifdef FURI_DEBUG
     subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile);
     subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile);
 #else
 #else
@@ -152,7 +154,7 @@ SubBruteFileResult subbrute_device_attack_set(
     // For non-file types we didn't set SubGhzProtocolDecoderBase
     // For non-file types we didn't set SubGhzProtocolDecoderBase
     instance->receiver = subghz_receiver_alloc_init(instance->environment);
     instance->receiver = subghz_receiver_alloc_init(instance->environment);
     subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable);
     subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable);
-    furi_hal_subghz_reset();
+    // furi_hal_subghz_reset(); // XXX
 
 
     uint8_t protocol_check_result = SubBruteFileResultProtocolNotFound;
     uint8_t protocol_check_result = SubBruteFileResultProtocolNotFound;
 #ifdef FURI_DEBUG
 #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);
     instance->receiver = subghz_receiver_alloc_init(instance->environment);
     subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable);
     subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable);
-    furi_hal_subghz_reset();
+    // furi_hal_subghz_reset(); // XXX
 
 
     do {
     do {
         if(!flipper_format_file_open_existing(fff_data_file, file_path)) {
         if(!flipper_format_file_open_existing(fff_data_file, file_path)) {
@@ -261,11 +263,27 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
             result = SubBruteFileResultMissingOrIncorrectFrequency;
             result = SubBruteFileResultMissingOrIncorrectFrequency;
             break;
             break;
         }
         }
-        instance->file_protocol_info->frequency = temp_data32;
-        if(!furi_hal_subghz_is_tx_allowed(instance->file_protocol_info->frequency)) {
+        // instance->file_protocol_info->frequency = temp_data32;
+        // if(!furi_hal_subghz_is_tx_allowed(instance->file_protocol_info->frequency)) {
+        //     result = SubBruteFileResultFrequencyNotAllowed;
+        //     break;
+        // }
+
+        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;
             result = SubBruteFileResultFrequencyNotAllowed;
             break;
             break;
         }
         }
+        subghz_devices_idle(instance->radio_device);
 
 
         // Preset
         // Preset
         if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) {
         if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) {

+ 3 - 1
subbrute_device.h

@@ -5,6 +5,7 @@
 #include <lib/subghz/transmitter.h>
 #include <lib/subghz/transmitter.h>
 #include <lib/subghz/receiver.h>
 #include <lib/subghz/receiver.h>
 #include <lib/subghz/environment.h>
 #include <lib/subghz/environment.h>
+#include "helpers/radio_device_loader.h"
 
 
 #define SUBBRUTE_TEXT_STORE_SIZE 256
 #define SUBBRUTE_TEXT_STORE_SIZE 256
 
 
@@ -42,6 +43,7 @@ typedef struct {
     SubGhzReceiver* receiver;
     SubGhzReceiver* receiver;
     SubGhzProtocolDecoderBase* decoder_result;
     SubGhzProtocolDecoderBase* decoder_result;
     SubGhzEnvironment* environment;
     SubGhzEnvironment* environment;
+    const SubGhzDevice* radio_device;
 
 
     // Attack state
     // Attack state
     SubBruteAttacks attack;
     SubBruteAttacks attack;
@@ -56,7 +58,7 @@ typedef struct {
     uint8_t bit_index;
     uint8_t bit_index;
 } SubBruteDevice;
 } SubBruteDevice;
 
 
-SubBruteDevice* subbrute_device_alloc();
+SubBruteDevice* subbrute_device_alloc(const SubGhzDevice* radio_device;);
 void subbrute_device_free(SubBruteDevice* instance);
 void subbrute_device_free(SubBruteDevice* instance);
 
 
 bool subbrute_device_save_file(SubBruteDevice* instance, const char* key_name);
 bool subbrute_device_save_file(SubBruteDevice* instance, const char* key_name);

+ 1 - 0
subbrute_i.h

@@ -56,6 +56,7 @@ struct SubBruteState {
     Popup* popup;
     Popup* popup;
     Widget* widget;
     Widget* widget;
     DialogsApp* dialogs;
     DialogsApp* dialogs;
+    const SubGhzDevice* radio_device;
 
 
     // Text store
     // Text store
     char text_store[SUBBRUTE_MAX_LEN_NAME];
     char text_store[SUBBRUTE_MAX_LEN_NAME];