Update subbrute --nobuild

This commit is contained in:
Willy-JL
2023-08-31 23:26:26 +02:00
parent 14e6768d14
commit 9f840e95f3
22 changed files with 587 additions and 363 deletions

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2022 Der Skythe Copyright (c) 2023 DerSkythe
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,64 +0,0 @@
#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);
}
}

View File

@@ -1,15 +0,0 @@
#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);

View File

@@ -0,0 +1,83 @@
//#include "../../../lib/subghz/protocols/protocol_items.h"
//#include "../../../firmware//targets/f7/furi_hal/furi_hal_subghz.h"
#include <furi/core/check.h>
//#include "../../../furi/core/check.h"
// furi/core/check.h
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
#include <applications/main/subghz/helpers/subghz_types.h>
#include <lib/subghz/devices/devices.h>
#include "subbrute_radio_device_loader.h"
#define TAG "SubBruteRadioDeviceLoader"
static void subbrute_radio_device_loader_power_on() {
uint8_t attempts = 5;
while(--attempts > 0) {
if(furi_hal_power_enable_otg()) {
break;
}
}
if(attempts == 0) {
if(furi_hal_power_get_usb_voltage() < 4.5f) {
FURI_LOG_E(
TAG,
"Error power otg enable. BQ2589 check otg fault = %d",
furi_hal_power_check_otg_fault() ? 1 : 0);
}
}
}
static void subbrute_radio_device_loader_power_off() {
if(furi_hal_power_is_otg_enabled()) {
furi_hal_power_disable_otg();
}
}
bool subbrute_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) {
subbrute_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) {
subbrute_radio_device_loader_power_off();
}
return is_connect;
}
const SubGhzDevice* subbrute_radio_device_loader_set(
const SubGhzDevice* current_radio_device,
SubGhzRadioDeviceType radio_device_type) {
const SubGhzDevice* radio_device;
if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 &&
subbrute_radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) {
subbrute_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 {
subbrute_radio_device_loader_end(current_radio_device);
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
}
return radio_device;
}
void subbrute_radio_device_loader_end(const SubGhzDevice* radio_device) {
furi_assert(radio_device);
subbrute_radio_device_loader_power_off();
if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) {
subghz_devices_end(radio_device);
}
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include <lib/subghz/devices/devices.h>
#include <applications/main/subghz/helpers/subghz_types.h>
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
#include "subghz/helpers/subghz_types.h"
const SubGhzDevice* subbrute_radio_device_loader_set(
const SubGhzDevice* current_radio_device,
SubGhzRadioDeviceType radio_device_type);
void subbrute_radio_device_loader_end(const SubGhzDevice* radio_device);

View File

@@ -59,7 +59,7 @@ void subbrute_worker_free(SubBruteWorker* instance) {
furi_thread_free(instance->thread); furi_thread_free(instance->thread);
subghz_devices_sleep(instance->radio_device); subghz_devices_sleep(instance->radio_device);
radio_device_loader_end(instance->radio_device); subbrute_radio_device_loader_end(instance->radio_device);
free(instance); free(instance);
} }
@@ -85,7 +85,7 @@ bool subbrute_worker_init_default_attack(
SubBruteAttacks attack_type, SubBruteAttacks attack_type,
uint64_t step, uint64_t step,
const SubBruteProtocol* protocol, const SubBruteProtocol* protocol,
uint8_t extra_repeats) { uint8_t repeats) {
furi_assert(instance); furi_assert(instance);
if(instance->worker_running) { if(instance->worker_running) {
@@ -100,7 +100,7 @@ bool subbrute_worker_init_default_attack(
instance->step = step; instance->step = step;
instance->bits = protocol->bits; instance->bits = protocol->bits;
instance->te = protocol->te; instance->te = protocol->te;
instance->repeat = protocol->repeat + extra_repeats; instance->repeat = repeats;
instance->load_index = 0; instance->load_index = 0;
instance->file_key = 0; instance->file_key = 0;
instance->two_bytes = false; instance->two_bytes = false;
@@ -133,7 +133,7 @@ bool subbrute_worker_init_file_attack(
uint8_t load_index, uint8_t load_index,
uint64_t file_key, uint64_t file_key,
SubBruteProtocol* protocol, SubBruteProtocol* protocol,
uint8_t extra_repeats, uint8_t repeats,
bool two_bytes) { bool two_bytes) {
furi_assert(instance); furi_assert(instance);
@@ -150,7 +150,7 @@ bool subbrute_worker_init_file_attack(
instance->bits = protocol->bits; instance->bits = protocol->bits;
instance->te = protocol->te; instance->te = protocol->te;
instance->load_index = load_index; instance->load_index = load_index;
instance->repeat = protocol->repeat + extra_repeats; instance->repeat = repeats;
instance->file_key = file_key; instance->file_key = file_key;
instance->two_bytes = two_bytes; instance->two_bytes = two_bytes;
@@ -490,6 +490,7 @@ bool subbrute_worker_is_tx_allowed(SubBruteWorker* instance, uint32_t value) {
bool res = false; bool res = false;
if(!subghz_devices_is_frequency_valid(instance->radio_device, value)) { if(!subghz_devices_is_frequency_valid(instance->radio_device, value)) {
return false;
} else { } else {
subghz_devices_set_frequency(instance->radio_device, value); subghz_devices_set_frequency(instance->radio_device, value);
res = subghz_devices_set_tx(instance->radio_device); res = subghz_devices_set_tx(instance->radio_device);

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include "../subbrute_protocols.h" #include "../subbrute_protocols.h"
#include "radio_device_loader.h" #include "subbrute_radio_device_loader.h"
typedef enum { typedef enum {
SubBruteWorkerStateIDLE, SubBruteWorkerStateIDLE,
@@ -24,14 +24,14 @@ bool subbrute_worker_init_default_attack(
SubBruteAttacks attack_type, SubBruteAttacks attack_type,
uint64_t step, uint64_t step,
const SubBruteProtocol* protocol, const SubBruteProtocol* protocol,
uint8_t extra_repeats); uint8_t repeats);
bool subbrute_worker_init_file_attack( bool subbrute_worker_init_file_attack(
SubBruteWorker* instance, SubBruteWorker* instance,
uint64_t step, uint64_t step,
uint8_t load_index, uint8_t load_index,
uint64_t file_key, uint64_t file_key,
SubBruteProtocol* protocol, SubBruteProtocol* protocol,
uint8_t extra_repeats, uint8_t repeats,
bool two_bytes); bool two_bytes);
bool subbrute_worker_start(SubBruteWorker* instance); bool subbrute_worker_start(SubBruteWorker* instance);
void subbrute_worker_stop(SubBruteWorker* instance); void subbrute_worker_stop(SubBruteWorker* instance);

View File

@@ -36,10 +36,13 @@ void subbrute_scene_load_file_on_enter(void* context) {
load_result = load_result =
subbrute_device_load_from_file(instance->device, furi_string_get_cstr(load_path)); subbrute_device_load_from_file(instance->device, furi_string_get_cstr(load_path));
if(load_result == SubBruteFileResultOk) { if(load_result == SubBruteFileResultOk) {
uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main); instance->settings->last_index = SubBruteAttackLoadFile;
subbrute_settings_set_repeats(
instance->settings, subbrute_main_view_get_extra_repeats(instance->view_main));
uint8_t extra_repeats = subbrute_settings_get_current_repeats(instance->settings);
load_result = subbrute_device_attack_set( load_result = subbrute_device_attack_set(
instance->device, SubBruteAttackLoadFile, extra_repeats); instance->device, instance->settings->last_index, extra_repeats);
if(load_result == SubBruteFileResultOk) { if(load_result == SubBruteFileResultOk) {
if(!subbrute_worker_init_file_attack( if(!subbrute_worker_init_file_attack(
instance->worker, instance->worker,
@@ -58,6 +61,7 @@ void subbrute_scene_load_file_on_enter(void* context) {
} }
if(load_result == SubBruteFileResultOk) { if(load_result == SubBruteFileResultOk) {
subbrute_settings_save(instance->settings);
scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadSelect); scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadSelect);
} else { } else {
FURI_LOG_E(TAG, "Returned error: %d", load_result); FURI_LOG_E(TAG, "Returned error: %d", load_result);

View File

@@ -21,7 +21,12 @@ void subbrute_scene_load_select_on_enter(void* context) {
instance->current_view = SubBruteViewMain; instance->current_view = SubBruteViewMain;
subbrute_main_view_set_callback(view, subbrute_scene_load_select_callback, instance); subbrute_main_view_set_callback(view, subbrute_scene_load_select_callback, instance);
subbrute_main_view_set_index( subbrute_main_view_set_index(
view, 7, true, instance->device->two_bytes, instance->device->key_from_file); view,
7,
instance->settings->repeat_values,
true,
instance->device->two_bytes,
instance->device->key_from_file);
view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view); view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
} }
@@ -46,7 +51,12 @@ bool subbrute_scene_load_select_on_event(void* context, SceneManagerEvent event)
instance->device->current_step = 0; instance->device->current_step = 0;
instance->device->bit_index = subbrute_main_view_get_index(instance->view_main); instance->device->bit_index = subbrute_main_view_get_index(instance->view_main);
instance->device->two_bytes = subbrute_main_view_get_two_bytes(instance->view_main); instance->device->two_bytes = subbrute_main_view_get_two_bytes(instance->view_main);
uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main);
instance->settings->last_index = instance->device->attack;
subbrute_settings_set_repeats(
instance->settings, subbrute_main_view_get_extra_repeats(instance->view_main));
uint8_t total_repeats = subbrute_settings_get_current_repeats(instance->settings);
instance->device->max_value = subbrute_protocol_calc_max_value( instance->device->max_value = subbrute_protocol_calc_max_value(
instance->device->attack, instance->device->attack,
instance->device->bit_index, instance->device->bit_index,
@@ -58,10 +68,11 @@ bool subbrute_scene_load_select_on_event(void* context, SceneManagerEvent event)
instance->device->bit_index, instance->device->bit_index,
instance->device->key_from_file, instance->device->key_from_file,
instance->device->file_protocol_info, instance->device->file_protocol_info,
extra_repeats, total_repeats,
instance->device->two_bytes)) { instance->device->two_bytes)) {
furi_crash("Invalid attack set!"); furi_crash("Invalid attack set!");
} }
subbrute_settings_save(instance->settings);
scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack);
/*#endif*/ /*#endif*/
consumed = true; consumed = true;

View File

@@ -12,7 +12,7 @@
enum SubBruteVarListIndex { enum SubBruteVarListIndex {
SubBruteVarListIndexTimeDelay, SubBruteVarListIndexTimeDelay,
SubBruteVarListIndexRepeat_or_OnExtra, SubBruteVarListIndexRepeatOrOnExtra,
SubBruteVarListIndexTe, SubBruteVarListIndexTe,
}; };
@@ -255,7 +255,7 @@ static void setup_extra_enter_callback(void* context, uint32_t index) {
furi_assert(context); furi_assert(context);
SubBruteState* instance = context; SubBruteState* instance = context;
if(index == SubBruteVarListIndexRepeat_or_OnExtra) { if(index == SubBruteVarListIndexRepeatOrOnExtra) {
subbrute_scene_setup_extra_init_var_list(instance, true); subbrute_scene_setup_extra_init_var_list(instance, true);
} }
} }

View File

@@ -7,9 +7,6 @@ void subbrute_scene_start_callback(SubBruteCustomEvent event, void* context) {
furi_assert(context); furi_assert(context);
SubBruteState* instance = (SubBruteState*)context; SubBruteState* instance = (SubBruteState*)context;
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_scene_start_callback");
#endif
view_dispatcher_send_custom_event(instance->view_dispatcher, event); view_dispatcher_send_custom_event(instance->view_dispatcher, event);
} }
@@ -23,22 +20,22 @@ void subbrute_scene_start_on_enter(void* context) {
instance->current_view = SubBruteViewMain; instance->current_view = SubBruteViewMain;
subbrute_main_view_set_callback(view, subbrute_scene_start_callback, instance); subbrute_main_view_set_callback(view, subbrute_scene_start_callback, instance);
instance->device->attack = instance->settings->last_index;
subbrute_main_view_set_index( subbrute_main_view_set_index(
view, instance->device->attack, false, instance->device->two_bytes, 0); view,
instance->settings->last_index,
instance->settings->repeat_values,
false,
instance->device->two_bytes,
0);
view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view); view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
// TODO: DELETE IT
#ifdef SUBBRUTE_FAST_TRACK
scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadFile);
#endif
} }
void subbrute_scene_start_on_exit(void* context) { void subbrute_scene_start_on_exit(void* context) {
UNUSED(context); furi_assert(context);
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "subbrute_scene_start_on_exit");
#endif
} }
bool subbrute_scene_start_on_event(void* context, SceneManagerEvent event) { bool subbrute_scene_start_on_event(void* context, SceneManagerEvent event) {
@@ -55,19 +52,23 @@ bool subbrute_scene_start_on_event(void* context, SceneManagerEvent event) {
event.event == SubBruteCustomEventTypeLoadFile ? "true" : "false"); event.event == SubBruteCustomEventTypeLoadFile ? "true" : "false");
#endif #endif
if(event.event == SubBruteCustomEventTypeMenuSelected) { if(event.event == SubBruteCustomEventTypeMenuSelected) {
SubBruteAttacks attack = subbrute_main_view_get_index(instance->view_main); instance->settings->last_index = subbrute_main_view_get_index(instance->view_main);
uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main); subbrute_settings_set_repeats(
instance->settings, subbrute_main_view_get_extra_repeats(instance->view_main));
uint8_t total_repeats = subbrute_settings_get_current_repeats(instance->settings);
if((subbrute_device_attack_set(instance->device, attack, extra_repeats) != if((subbrute_device_attack_set(
instance->device, instance->settings->last_index, total_repeats) !=
SubBruteFileResultOk) || SubBruteFileResultOk) ||
(!subbrute_worker_init_default_attack( (!subbrute_worker_init_default_attack(
instance->worker, instance->worker,
attack, instance->settings->last_index,
instance->device->current_step, instance->device->current_step,
instance->device->protocol_info, instance->device->protocol_info,
instance->device->extra_repeats))) { instance->device->extra_repeats))) {
furi_crash("Invalid attack set!"); furi_crash("Invalid attack set!");
} }
subbrute_settings_save(instance->settings);
scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack);
consumed = true; consumed = true;
@@ -80,6 +81,11 @@ bool subbrute_scene_start_on_event(void* context, SceneManagerEvent event) {
} }
} else if(event.type == SceneManagerEventTypeBack) { } else if(event.type == SceneManagerEventTypeBack) {
//exit app //exit app
instance->settings->last_index = subbrute_main_view_get_index(instance->view_main);
subbrute_settings_set_repeats(
instance->settings, subbrute_main_view_get_extra_repeats(instance->view_main));
subbrute_settings_save(instance->settings);
scene_manager_stop(instance->scene_manager); scene_manager_stop(instance->scene_manager);
view_dispatcher_stop(instance->view_dispatcher); view_dispatcher_stop(instance->view_dispatcher);
consumed = true; consumed = true;

View File

@@ -1,5 +1,4 @@
#include "subbrute_i.h" #include "subbrute_i.h"
#include "subbrute_custom_event.h"
#include "scenes/subbrute_scene.h" #include "scenes/subbrute_scene.h"
#define TAG "SubBruteApp" #define TAG "SubBruteApp"
@@ -51,8 +50,8 @@ SubBruteState* subbrute_alloc() {
subghz_devices_init(); subghz_devices_init();
// init radio device // init radio device
instance->radio_device = instance->radio_device = subbrute_radio_device_loader_set(
radio_device_loader_set(instance->radio_device, SubGhzRadioDeviceTypeExternalCC1101); instance->radio_device, SubGhzRadioDeviceTypeExternalCC1101);
subghz_devices_reset(instance->radio_device); subghz_devices_reset(instance->radio_device);
subghz_devices_idle(instance->radio_device); subghz_devices_idle(instance->radio_device);
@@ -106,6 +105,8 @@ SubBruteState* subbrute_alloc() {
SubBruteViewAttack, SubBruteViewAttack,
subbrute_attack_view_get_view(instance->view_attack)); subbrute_attack_view_get_view(instance->view_attack));
instance->settings = subbrute_settings_alloc();
subbrute_settings_load(instance->settings);
//instance->flipper_format = flipper_format_string_alloc(); //instance->flipper_format = flipper_format_string_alloc();
//instance->environment = subghz_environment_alloc(); //instance->environment = subghz_environment_alloc();
@@ -127,9 +128,11 @@ void subbrute_free(SubBruteState* instance) {
// SubBruteDevice // SubBruteDevice
subbrute_device_free(instance->device); subbrute_device_free(instance->device);
subghz_devices_deinit(); subghz_devices_deinit();
//subbrute_settings_save(instance->settings);
subbrute_settings_free(instance->settings);
// 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);

View File

@@ -1,9 +1,6 @@
#include "subbrute_device.h" #include "subbrute_device.h"
#include <stdint.h>
#include <storage/storage.h> #include <storage/storage.h>
#include <lib/toolbox/stream/stream.h>
#include <lib/flipper_format/flipper_format.h>
#include <lib/flipper_format/flipper_format_i.h> #include <lib/flipper_format/flipper_format_i.h>
#include <lib/subghz/subghz_protocol_registry.h> #include <lib/subghz/subghz_protocol_registry.h>
@@ -24,11 +21,11 @@ SubBruteDevice* subbrute_device_alloc(const SubGhzDevice* radio_device) {
instance->radio_device = radio_device; 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
subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433);
#endif //#endif
return instance; return instance;
} }
@@ -386,6 +383,7 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
FURI_LOG_D(TAG, "Loaded successfully"); FURI_LOG_D(TAG, "Loaded successfully");
#endif #endif
} else { } else {
FURI_LOG_E(TAG, "Load failed!");
subbrute_device_free_protocol_info(instance); subbrute_device_free_protocol_info(instance);
} }

View File

@@ -5,16 +5,12 @@
#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" #include "helpers/subbrute_radio_device_loader.h"
#define SUBBRUTE_TEXT_STORE_SIZE 256
#define SUBBRUTE_MAX_LEN_NAME 64 #define SUBBRUTE_MAX_LEN_NAME 64
#define SUBBRUTE_PATH EXT_PATH("subghz") #define SUBBRUTE_PATH EXT_PATH("subghz")
#define SUBBRUTE_FILE_EXT ".sub" #define SUBBRUTE_FILE_EXT ".sub"
#define SUBBRUTE_PAYLOAD_SIZE 16
typedef enum { typedef enum {
SubBruteFileResultUnknown, SubBruteFileResultUnknown,
SubBruteFileResultOk, SubBruteFileResultOk,
@@ -54,11 +50,12 @@ typedef struct {
uint64_t key_from_file; uint64_t key_from_file;
uint64_t current_key_from_file; uint64_t current_key_from_file;
bool two_bytes; bool two_bytes;
// Index of group to bruteforce in loaded file // Index of group to bruteforce in loaded file
uint8_t bit_index; uint8_t bit_index;
} SubBruteDevice; } SubBruteDevice;
SubBruteDevice* subbrute_device_alloc(const SubGhzDevice* radio_device;); 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);

View File

@@ -27,11 +27,12 @@
#include "subbrute.h" #include "subbrute.h"
#include "subbrute_device.h" #include "subbrute_device.h"
#include "subbrute_settings.h"
#include "helpers/subbrute_worker.h" #include "helpers/subbrute_worker.h"
#include "views/subbrute_attack_view.h" #include "views/subbrute_attack_view.h"
#include "views/subbrute_main_view.h" #include "views/subbrute_main_view.h"
#define SUBBRUTEFORCER_VER "Sub-GHz BruteForcer 3.7" #define SUBBRUTEFORCER_VER "Sub-GHz BruteForcer 3.9"
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
//#define SUBBRUTE_FAST_TRACK false //#define SUBBRUTE_FAST_TRACK false
@@ -78,6 +79,8 @@ struct SubBruteState {
SubBruteDevice* device; SubBruteDevice* device;
// SubBruteWorker // SubBruteWorker
SubBruteWorker* worker; SubBruteWorker* worker;
// Last used settings
SubBruteSettings* settings;
}; };
void subbrute_show_loading_popup(void* context, bool show); void subbrute_show_loading_popup(void* context, bool show);

View File

@@ -1,6 +1,5 @@
#include "subbrute_protocols.h" #include "subbrute_protocols.h"
#include "math.h" #include "math.h"
#include <string.h>
#define TAG "SubBruteProtocols" #define TAG "SubBruteProtocols"

View File

@@ -5,6 +5,8 @@
#include <core/string.h> #include <core/string.h>
#include <toolbox/stream/stream.h> #include <toolbox/stream/stream.h>
#define SUBBRUTE_PROTOCOL_MAX_REPEATS 9
typedef enum { typedef enum {
CAMEFileProtocol, CAMEFileProtocol,
NICEFileProtocol, NICEFileProtocol,

View File

@@ -0,0 +1,147 @@
#include "subbrute_settings.h"
#include "subbrute_i.h"
#define TAG "SubBruteSettings"
#define SUBBRUTE_SETTINGS_FILE_TYPE "Sub-GHz BruteForcer Settings File"
#define SUBBRUTE_SETTINGS_FILE_VERSION 1
#define SUBBRUTE_SETTINGS_PATH EXT_PATH("subghz-bruteforcer.settings")
#define SUBBRUTE_FIELD_LAST_INDEX "LastIndex"
#define SUBBRUTE_FIELD_REPEAT_VALUES "RepeatValue"
SubBruteSettings* subbrute_settings_alloc(void) {
SubBruteSettings* instance = malloc(sizeof(SubBruteSettings));
return instance;
}
void subbrute_settings_free(SubBruteSettings* instance) {
furi_assert(instance);
free(instance);
}
void subbrute_settings_load(SubBruteSettings* instance) {
furi_assert(instance);
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
uint32_t temp_last_index = 0;
uint8_t temp_repeat_values[SubBruteAttackTotalCount] = {0};
bool was_read_last_index = false;
bool was_read_repeat_values = false;
if(FSE_OK == storage_sd_status(storage) && SUBBRUTE_SETTINGS_PATH &&
flipper_format_file_open_existing(fff_data_file, SUBBRUTE_SETTINGS_PATH)) {
was_read_last_index = flipper_format_read_uint32(
fff_data_file, SUBBRUTE_FIELD_LAST_INDEX, (uint32_t*)&temp_last_index, 1);
was_read_repeat_values = flipper_format_read_hex(
fff_data_file,
SUBBRUTE_FIELD_REPEAT_VALUES,
temp_repeat_values,
SubBruteAttackTotalCount);
} else {
FURI_LOG_E(TAG, "Error open file %s", SUBBRUTE_SETTINGS_PATH);
}
if(was_read_last_index && temp_last_index < SubBruteAttackTotalCount) {
instance->last_index = temp_last_index;
} else {
FURI_LOG_W(TAG, "Last used index not found or can't be used!");
instance->last_index = (uint32_t)SubBruteAttackCAME12bit433;
}
if(was_read_repeat_values) {
for(size_t i = 0; i < SubBruteAttackTotalCount; i++) {
uint8_t protocol_count = subbrute_protocol_repeats_count(i);
uint8_t max_protocol_count = protocol_count * 3;
if(temp_repeat_values[i] < protocol_count) {
instance->repeat_values[i] = protocol_count;
} else if(temp_repeat_values[i] > max_protocol_count) {
instance->repeat_values[i] = max_protocol_count;
} else {
instance->repeat_values[i] = temp_repeat_values[i];
}
}
} else {
FURI_LOG_W(TAG, "Last used repeat values can't be used!");
for(size_t i = 0; i < SubBruteAttackTotalCount; i++) {
instance->repeat_values[i] = subbrute_protocol_repeats_count(i);
}
}
flipper_format_file_close(fff_data_file);
flipper_format_free(fff_data_file);
furi_record_close(RECORD_STORAGE);
}
bool subbrute_settings_save(SubBruteSettings* instance) {
furi_assert(instance);
bool saved = false;
Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* file = flipper_format_file_alloc(storage);
do {
if(FSE_OK != storage_sd_status(storage)) {
break;
}
// Open file
if(!flipper_format_file_open_always(file, SUBBRUTE_SETTINGS_PATH)) {
break;
}
// Write header
if(!flipper_format_write_header_cstr(
file, SUBBRUTE_SETTINGS_FILE_TYPE, SUBBRUTE_SETTINGS_FILE_VERSION)) {
break;
}
if(!flipper_format_insert_or_update_uint32(
file, SUBBRUTE_FIELD_LAST_INDEX, &instance->last_index, 1)) {
break;
}
if(!flipper_format_insert_or_update_hex(
file,
SUBBRUTE_FIELD_REPEAT_VALUES,
instance->repeat_values,
SubBruteAttackTotalCount)) {
break;
}
saved = true;
break;
} while(true);
if(!saved) {
FURI_LOG_E(TAG, "Error save file %s", SUBBRUTE_SETTINGS_PATH);
}
flipper_format_file_close(file);
flipper_format_free(file);
furi_record_close(RECORD_STORAGE);
return saved;
}
void subbrute_settings_set_value(SubBruteSettings* instance, SubBruteAttacks index, uint8_t value) {
furi_assert(instance);
instance->repeat_values[index] = value;
}
uint8_t subbrute_settings_get_value(SubBruteSettings* instance, SubBruteAttacks index) {
furi_assert(instance);
return instance->repeat_values[index];
}
void subbrute_settings_set_repeats(SubBruteSettings* instance, const uint8_t* repeated_values) {
furi_assert(instance);
for(size_t i = 0; i < SubBruteAttackTotalCount; i++) {
instance->repeat_values[i] = repeated_values[i];
}
}
uint8_t subbrute_settings_get_current_repeats(SubBruteSettings* instance) {
furi_assert(instance);
return instance->repeat_values[instance->last_index];
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include <furi_hal.h>
#include <stdint.h>
#include <stdbool.h>
#include <storage/storage.h>
#include "subbrute_protocols.h"
typedef struct {
uint8_t repeat_values[SubBruteAttackTotalCount];
uint32_t last_index;
} SubBruteSettings;
SubBruteSettings* subbrute_settings_alloc(void);
void subbrute_settings_free(SubBruteSettings* instance);
void subbrute_settings_load(SubBruteSettings* instance);
bool subbrute_settings_save(SubBruteSettings* instance);
void subbrute_settings_set_value(SubBruteSettings* instance, SubBruteAttacks index, uint8_t value);
uint8_t subbrute_settings_get_value(SubBruteSettings* instance, SubBruteAttacks index);
void subbrute_settings_set_repeats(SubBruteSettings* instance, const uint8_t* repeated_values);
uint8_t subbrute_settings_get_current_repeats(SubBruteSettings* instance);

View File

@@ -1,13 +1,12 @@
#include "subbrute_attack_view.h" #include "subbrute_attack_view.h"
#include "../subbrute_i.h" #include "../subbrute_i.h"
#include "../subbrute_protocols.h"
#include "../helpers/gui_top_buttons.h" #include "../helpers/gui_top_buttons.h"
#include <input/input.h> #include <input/input.h>
#include <gui/elements.h> #include <gui/elements.h>
#include <gui/icon.h>
#include <gui/icon_animation.h> #include <gui/icon_animation.h>
#include <subghz_bruteforcer_icons.h> #include "subghz_bruteforcer_icons.h"
#include <assets_icons.h>
#define TAG "SubBruteAttackView" #define TAG "SubBruteAttackView"
@@ -26,7 +25,7 @@ typedef struct {
SubBruteAttacks attack_type; SubBruteAttacks attack_type;
uint64_t max_value; uint64_t max_value;
uint64_t current_step; uint64_t current_step;
uint8_t extra_repeats; uint8_t repeat_count;
bool is_attacking; bool is_attacking;
IconAnimation* icon; IconAnimation* icon;
} SubBruteAttackViewModel; } SubBruteAttackViewModel;
@@ -126,10 +125,10 @@ bool subbrute_attack_view_input(InputEvent* event, void* context) {
model->current_step = instance->current_step; model->current_step = instance->current_step;
model->is_attacking = instance->is_attacking; model->is_attacking = instance->is_attacking;
}, },
true); update);
} }
return true; return update;
} }
SubBruteAttackView* subbrute_attack_view_alloc() { SubBruteAttackView* subbrute_attack_view_alloc() {
@@ -236,7 +235,7 @@ void subbrute_attack_view_init_values(
model->attack_type = index; model->attack_type = index;
model->current_step = current_step; model->current_step = current_step;
model->is_attacking = is_attacking; model->is_attacking = is_attacking;
model->extra_repeats = extra_repeats; model->repeat_count = extra_repeats;
if(is_attacking) { if(is_attacking) {
icon_animation_start(model->icon); icon_animation_start(model->icon);
} else { } else {
@@ -308,7 +307,7 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) {
buffer, buffer,
sizeof(buffer), sizeof(buffer),
"x%d", "x%d",
model->extra_repeats); // + subbrute_protocol_repeats_count(model->attack_type)); model->repeat_count); // + subbrute_protocol_repeats_count(model->attack_type));
canvas_draw_str_aligned(canvas, 60, 6, AlignCenter, AlignCenter, buffer); canvas_draw_str_aligned(canvas, 60, 6, AlignCenter, AlignCenter, buffer);
elements_button_left(canvas, "-1"); elements_button_left(canvas, "-1");
@@ -335,7 +334,7 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) {
buffer, buffer,
sizeof(buffer), sizeof(buffer),
"x%d", "x%d",
model->extra_repeats); // + subbrute_protocol_repeats_count(model->attack_type)); model->repeat_count); // + subbrute_protocol_repeats_count(model->attack_type));
canvas_draw_str(canvas, 4, y - 8, buffer); canvas_draw_str(canvas, 4, y - 8, buffer);
canvas_draw_str(canvas, 4, y - 1, "repeats"); canvas_draw_str(canvas, 4, y - 1, "repeats");

View File

@@ -1,11 +1,9 @@
#include "subbrute_main_view.h" #include "subbrute_main_view.h"
#include "../subbrute_i.h" #include "../subbrute_i.h"
#include "../subbrute_protocols.h"
#include "../helpers/gui_top_buttons.h" #include "../helpers/gui_top_buttons.h"
#include <input/input.h> #include <input/input.h>
#include <gui/elements.h> #include <gui/elements.h>
#include <gui/icon.h>
#define STATUS_BAR_Y_SHIFT 14 #define STATUS_BAR_Y_SHIFT 14
#define TAG "SubBruteMainView" #define TAG "SubBruteMainView"
@@ -29,13 +27,13 @@ struct SubBruteMainView {
bool is_select_byte; bool is_select_byte;
bool two_bytes; bool two_bytes;
uint64_t key_from_file; uint64_t key_from_file;
uint8_t extra_repeats; uint8_t repeat_values[SubBruteAttackTotalCount];
uint8_t window_position; uint8_t window_position;
}; };
typedef struct { typedef struct {
uint8_t index; uint8_t index;
uint8_t extra_repeats; uint8_t repeat_values[SubBruteAttackTotalCount];
uint8_t window_position; uint8_t window_position;
bool is_select_byte; bool is_select_byte;
bool two_bytes; bool two_bytes;
@@ -110,227 +108,252 @@ void subbrute_main_view_center_displayed_key(
canvas_set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
} }
void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { void subbrute_main_view_draw_is_byte_selected(Canvas* canvas, SubBruteMainViewModel* model) {
#ifdef FURI_DEBUG
//FURI_LOG_D(TAG, "key_from_file: %s", model->key_from_file);
#endif
//char msg_index[18];
//snprintf(msg_index, sizeof(msg_index), "Field index: %d", model->index);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, 64, 17, AlignCenter, AlignTop, "Please select values to calc:");
subbrute_main_view_center_displayed_key(
canvas, model->key_from_file, model->index, model->two_bytes);
//const char* line = furi_string_get_cstr(menu_items);
//canvas_set_font(canvas, FontSecondary);
//canvas_draw_str_aligned(
// canvas, 64, 37, AlignCenter, AlignTop, furi_string_get_cstr(menu_items));
elements_button_center(canvas, "Select");
if(model->index > 0) {
elements_button_left(canvas, " ");
}
if(model->index < 7) {
elements_button_right(canvas, " ");
}
// Switch to another mode
if(model->two_bytes) {
elements_button_top_left(canvas, "One byte");
} else {
elements_button_top_left(canvas, "Two bytes");
}
}
void subbrute_main_view_draw_is_ordinary_selected(Canvas* canvas, SubBruteMainViewModel* model) {
uint16_t screen_width = canvas_width(canvas); uint16_t screen_width = canvas_width(canvas);
uint16_t screen_height = canvas_height(canvas); uint16_t screen_height = canvas_height(canvas);
if(model->is_select_byte) { // Title
#ifdef FURI_DEBUG canvas_set_font(canvas, FontPrimary);
//FURI_LOG_D(TAG, "key_from_file: %s", model->key_from_file); canvas_draw_box(canvas, 0, 0, canvas_width(canvas), STATUS_BAR_Y_SHIFT);
#endif canvas_invert_color(canvas);
//char msg_index[18]; canvas_draw_str_aligned(canvas, 64, 3, AlignCenter, AlignTop, SUBBRUTEFORCER_VER);
//snprintf(msg_index, sizeof(msg_index), "Field index: %d", model->index); canvas_invert_color(canvas);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, 64, 17, AlignCenter, AlignTop, "Please select values to calc:");
subbrute_main_view_center_displayed_key( // Menu
canvas, model->key_from_file, model->index, model->two_bytes); canvas_set_color(canvas, ColorBlack);
//const char* line = furi_string_get_cstr(menu_items); canvas_set_font(canvas, FontSecondary);
//canvas_set_font(canvas, FontSecondary); const uint8_t item_height = 16;
//canvas_draw_str_aligned( const uint8_t string_height_offset = 9;
// canvas, 64, 37, AlignCenter, AlignTop, furi_string_get_cstr(menu_items));
elements_button_center(canvas, "Select");
if(model->index > 0) {
elements_button_left(canvas, " ");
}
if(model->index < 7) {
elements_button_right(canvas, " ");
}
// Switch to another mode
if(model->two_bytes) {
elements_button_top_left(canvas, "One byte");
} else {
elements_button_top_left(canvas, "Two bytes");
}
} else {
// Title
canvas_set_font(canvas, FontPrimary);
canvas_draw_box(canvas, 0, 0, canvas_width(canvas), STATUS_BAR_Y_SHIFT);
canvas_invert_color(canvas);
canvas_draw_str_aligned(canvas, 64, 3, AlignCenter, AlignTop, SUBBRUTEFORCER_VER);
canvas_invert_color(canvas);
// Menu
canvas_set_color(canvas, ColorBlack);
canvas_set_font(canvas, FontSecondary);
const uint8_t item_height = 16;
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
//FURI_LOG_D(TAG, "window_position: %d, index: %d", model->window_position, model->index); //FURI_LOG_D(TAG, "window_position: %d, index: %d", model->window_position, model->index);
#endif #endif
for(uint8_t position = 0; position < SubBruteAttackTotalCount; ++position) { for(size_t position = 0; position < SubBruteAttackTotalCount; ++position) {
uint8_t item_position = position - model->window_position; uint8_t item_position = position - model->window_position;
if(item_position < ITEMS_ON_SCREEN) { if(item_position < ITEMS_ON_SCREEN) {
if(model->index == position) { if(model->index == position) {
canvas_draw_str_aligned( canvas_draw_str_aligned(
canvas, canvas,
3, 3,
9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, string_height_offset + (item_position * item_height) + STATUS_BAR_Y_SHIFT,
AlignLeft, AlignLeft,
AlignCenter, AlignCenter,
subbrute_protocol_name(position)); subbrute_protocol_name(position));
if(model->extra_repeats > 0) { elements_frame(
canvas, 1, 1 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, 124, 15);
} else {
canvas_draw_str_aligned(
canvas,
4,
string_height_offset + (item_position * item_height) + STATUS_BAR_Y_SHIFT,
AlignLeft,
AlignCenter,
subbrute_protocol_name(position));
}
uint8_t current_repeat_count = model->repeat_values[position];
uint8_t min_repeat_count = subbrute_protocol_repeats_count(position);
if(current_repeat_count > min_repeat_count) {
#ifdef FW_ORIGIN_Official #ifdef FW_ORIGIN_Official
canvas_set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
#else #else
canvas_set_font(canvas, FontBatteryPercent); canvas_set_font(canvas, FontBatteryPercent);
#endif #endif
char buffer[10]; char buffer[10];
snprintf( snprintf(buffer, sizeof(buffer), "x%d", current_repeat_count);
buffer, uint8_t temp_x_offset_repeats =
sizeof(buffer), current_repeat_count <= SUBBRUTE_PROTOCOL_MAX_REPEATS ? 15 : 18;
"x%d",
model->extra_repeats + subbrute_protocol_repeats_count(model->index));
uint8_t temp_x_offset_repeats = 18;
if(model->extra_repeats + subbrute_protocol_repeats_count(model->index) <
10) {
temp_x_offset_repeats = 15;
}
canvas_draw_str_aligned(
canvas,
screen_width - temp_x_offset_repeats,
9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT,
AlignLeft,
AlignCenter,
buffer);
canvas_set_font(canvas, FontSecondary);
}
elements_frame( canvas_draw_str_aligned(
canvas, 1, 1 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, 124, 15); canvas,
} else { screen_width - temp_x_offset_repeats,
canvas_draw_str_aligned( string_height_offset + (item_position * item_height) + STATUS_BAR_Y_SHIFT,
canvas, AlignLeft,
4, AlignCenter,
9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, buffer);
AlignLeft, canvas_set_font(canvas, FontSecondary);
AlignCenter,
subbrute_protocol_name(position));
}
} }
} }
elements_scrollbar_pos(
canvas,
screen_width,
STATUS_BAR_Y_SHIFT + 2,
screen_height - STATUS_BAR_Y_SHIFT,
model->index,
SubBruteAttackTotalCount);
} }
elements_scrollbar_pos(
canvas,
screen_width,
STATUS_BAR_Y_SHIFT + 2,
screen_height - STATUS_BAR_Y_SHIFT,
model->index,
SubBruteAttackTotalCount);
}
void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) {
if(model->is_select_byte) {
subbrute_main_view_draw_is_byte_selected(canvas, model);
} else {
subbrute_main_view_draw_is_ordinary_selected(canvas, model);
}
}
bool subbrute_main_view_input_file_protocol(InputEvent* event, SubBruteMainView* instance) {
bool updated = false;
if(event->key == InputKeyLeft) {
if((instance->index > 0 && !instance->two_bytes) ||
(instance->two_bytes && instance->index > 1)) {
instance->index--;
}
updated = true;
} else if(event->key == InputKeyRight) {
if(instance->index < 7) {
instance->index++;
}
updated = true;
} else if(event->key == InputKeyUp) {
instance->two_bytes = !instance->two_bytes;
// Because index is changing
if(instance->two_bytes && instance->index < 7) {
instance->index++;
}
// instance->callback(
// instance->two_bytes ? SubBruteCustomEventTypeChangeStepUp :
// SubBruteCustomEventTypeChangeStepDown,
// instance->context);
updated = true;
} else if(event->key == InputKeyOk) {
instance->callback(SubBruteCustomEventTypeIndexSelected, instance->context);
updated = true;
}
return updated;
}
bool subbrute_main_view_input_ordinary_protocol(
InputEvent* event,
SubBruteMainView* instance,
bool is_short) {
const uint8_t min_value = 0;
const uint8_t correct_total = SubBruteAttackTotalCount - 1;
uint8_t index = instance->index;
uint8_t min_repeats = subbrute_protocol_repeats_count(index);
uint8_t max_repeats = min_repeats * 3;
uint8_t current_repeats = instance->repeat_values[index];
bool updated = false;
if(event->key == InputKeyUp && is_short) {
if(index == min_value) {
instance->index = correct_total;
} else {
instance->index = CLAMP(index - 1, correct_total, min_value);
}
//instance->repeat_values = 0;
updated = true;
} else if(event->key == InputKeyDown && is_short) {
if(index == correct_total) {
instance->index = min_value;
} else {
instance->index = CLAMP(index + 1, correct_total, min_value);
}
//instance->repeat_values = 0;
updated = true;
} else if(event->key == InputKeyLeft && is_short) {
instance->repeat_values[index] = CLAMP(current_repeats - 1, max_repeats, min_repeats);
updated = true;
} else if(event->key == InputKeyRight && is_short) {
instance->repeat_values[index] = CLAMP(current_repeats + 1, max_repeats, min_repeats);
updated = true;
} else if(event->key == InputKeyOk && is_short) {
if(index == SubBruteAttackLoadFile) {
instance->callback(SubBruteCustomEventTypeLoadFile, instance->context);
} else {
instance->callback(SubBruteCustomEventTypeMenuSelected, instance->context);
}
updated = true;
}
if(updated) {
instance->window_position = instance->index;
if(instance->window_position > 0) {
instance->window_position -= 1;
}
if(SubBruteAttackTotalCount <= ITEMS_ON_SCREEN) {
instance->window_position = 0;
} else {
if(instance->window_position >= (SubBruteAttackTotalCount - ITEMS_ON_SCREEN)) {
instance->window_position = (SubBruteAttackTotalCount - ITEMS_ON_SCREEN);
}
}
}
return updated;
} }
bool subbrute_main_view_input(InputEvent* event, void* context) { bool subbrute_main_view_input(InputEvent* event, void* context) {
furi_assert(event); furi_assert(event);
furi_assert(context); furi_assert(context);
SubBruteMainView* instance = context;
if(event->key == InputKeyBack && event->type == InputTypeShort) { if(event->key == InputKeyBack && event->type == InputTypeShort) {
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
FURI_LOG_I(TAG, "InputKey: BACK"); FURI_LOG_I(TAG, "InputKey: BACK");
#endif #endif
instance->callback(SubBruteCustomEventTypeBackPressed, instance->context);
return false; return false;
} }
SubBruteMainView* instance = context;
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
FURI_LOG_D(TAG, "InputKey: %d, extra_repeats: %d", event->key, instance->extra_repeats); FURI_LOG_D(
TAG,
"InputKey: %d, extra_repeats: %d",
event->key,
instance->repeat_values[instance->index]);
#endif #endif
const uint8_t min_value = 0;
const uint8_t correct_total = SubBruteAttackTotalCount - 1;
uint8_t max_repeats = 14 - subbrute_protocol_repeats_count(instance->index);
bool updated = false; bool updated = false;
bool consumed = false;
bool is_short = (event->type == InputTypeShort) || (event->type == InputTypeRepeat); bool is_short = (event->type == InputTypeShort) || (event->type == InputTypeRepeat);
if(!instance->is_select_byte) { if(instance->is_select_byte) {
if(event->key == InputKeyUp && is_short) { if(is_short) {
if(instance->index == min_value) { updated = subbrute_main_view_input_file_protocol(event, instance);
instance->index = correct_total;
} else {
instance->index = CLAMP(instance->index - 1, correct_total, min_value);
}
instance->extra_repeats = 0;
updated = true;
consumed = true;
} else if(event->key == InputKeyDown && is_short) {
if(instance->index == correct_total) {
instance->index = min_value;
} else {
instance->index = CLAMP(instance->index + 1, correct_total, min_value);
}
instance->extra_repeats = 0;
updated = true;
consumed = true;
} else if(event->key == InputKeyLeft && is_short) {
instance->extra_repeats = CLAMP(instance->extra_repeats - 1, max_repeats, 0);
updated = true;
consumed = true;
} else if(event->key == InputKeyRight && is_short) {
instance->extra_repeats = CLAMP(instance->extra_repeats + 1, max_repeats, 0);
updated = true;
consumed = true;
} else if(event->key == InputKeyOk && is_short) {
if(instance->index == SubBruteAttackLoadFile) {
instance->callback(SubBruteCustomEventTypeLoadFile, instance->context);
} else {
instance->callback(SubBruteCustomEventTypeMenuSelected, instance->context);
}
consumed = true;
updated = true;
}
if(updated) {
instance->window_position = instance->index;
if(instance->window_position > 0) {
instance->window_position -= 1;
}
if(SubBruteAttackTotalCount <= ITEMS_ON_SCREEN) {
instance->window_position = 0;
} else {
if(instance->window_position >= (SubBruteAttackTotalCount - ITEMS_ON_SCREEN)) {
instance->window_position = (SubBruteAttackTotalCount - ITEMS_ON_SCREEN);
}
}
}
} else if(is_short) {
if(event->key == InputKeyLeft) {
if((instance->index > 0 && !instance->two_bytes) ||
(instance->two_bytes && instance->index > 1)) {
instance->index--;
}
updated = true;
consumed = true;
} else if(event->key == InputKeyRight) {
if(instance->index < 7) {
instance->index++;
}
updated = true;
consumed = true;
} else if(event->key == InputKeyUp) {
instance->two_bytes = !instance->two_bytes;
// Because index is changing
if(instance->two_bytes && instance->index < 7) {
instance->index++;
}
// instance->callback(
// instance->two_bytes ? SubBruteCustomEventTypeChangeStepUp :
// SubBruteCustomEventTypeChangeStepDown,
// instance->context);
updated = true;
consumed = true;
} else if(event->key == InputKeyOk) {
instance->callback(SubBruteCustomEventTypeIndexSelected, instance->context);
consumed = true;
updated = true;
} }
} else {
updated = subbrute_main_view_input_ordinary_protocol(event, instance, is_short);
} }
if(updated) { if(updated) {
@@ -343,28 +366,20 @@ bool subbrute_main_view_input(InputEvent* event, void* context) {
model->key_from_file = instance->key_from_file; model->key_from_file = instance->key_from_file;
model->is_select_byte = instance->is_select_byte; model->is_select_byte = instance->is_select_byte;
model->two_bytes = instance->two_bytes; model->two_bytes = instance->two_bytes;
model->extra_repeats = instance->extra_repeats; model->repeat_values[model->index] = instance->repeat_values[instance->index];
}, },
true); true);
} }
return consumed; return updated;
} }
void subbrute_main_view_enter(void* context) { void subbrute_main_view_enter(void* context) {
furi_assert(context); furi_assert(context);
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_main_view_enter");
#endif
} }
void subbrute_main_view_exit(void* context) { void subbrute_main_view_exit(void* context) {
furi_assert(context); furi_assert(context);
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_main_view_exit");
#endif
} }
SubBruteMainView* subbrute_main_view_alloc() { SubBruteMainView* subbrute_main_view_alloc() {
@@ -382,7 +397,7 @@ SubBruteMainView* subbrute_main_view_alloc() {
instance->key_from_file = 0; instance->key_from_file = 0;
instance->is_select_byte = false; instance->is_select_byte = false;
instance->two_bytes = false; instance->two_bytes = false;
instance->extra_repeats = 0;
with_view_model( with_view_model(
instance->view, instance->view,
SubBruteMainViewModel * model, SubBruteMainViewModel * model,
@@ -392,7 +407,6 @@ SubBruteMainView* subbrute_main_view_alloc() {
model->key_from_file = instance->key_from_file; model->key_from_file = instance->key_from_file;
model->is_select_byte = instance->is_select_byte; model->is_select_byte = instance->is_select_byte;
model->two_bytes = instance->two_bytes; model->two_bytes = instance->two_bytes;
model->extra_repeats = instance->extra_repeats;
}, },
true); true);
@@ -414,6 +428,7 @@ View* subbrute_main_view_get_view(SubBruteMainView* instance) {
void subbrute_main_view_set_index( void subbrute_main_view_set_index(
SubBruteMainView* instance, SubBruteMainView* instance,
uint8_t idx, uint8_t idx,
const uint8_t* repeats,
bool is_select_byte, bool is_select_byte,
bool two_bytes, bool two_bytes,
uint64_t key_from_file) { uint64_t key_from_file) {
@@ -422,6 +437,9 @@ void subbrute_main_view_set_index(
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Set index: %d, is_select_byte: %d", idx, is_select_byte); FURI_LOG_I(TAG, "Set index: %d, is_select_byte: %d", idx, is_select_byte);
#endif #endif
for(size_t i = 0; i < SubBruteAttackTotalCount; i++) {
instance->repeat_values[i] = repeats[i];
}
instance->is_select_byte = is_select_byte; instance->is_select_byte = is_select_byte;
instance->two_bytes = two_bytes; instance->two_bytes = two_bytes;
instance->key_from_file = key_from_file; instance->key_from_file = key_from_file;
@@ -433,12 +451,8 @@ void subbrute_main_view_set_index(
instance->window_position -= 1; instance->window_position -= 1;
} }
if(SubBruteAttackTotalCount <= ITEMS_ON_SCREEN) { if(instance->window_position >= (SubBruteAttackTotalCount - ITEMS_ON_SCREEN)) {
instance->window_position = 0; instance->window_position = (SubBruteAttackTotalCount - ITEMS_ON_SCREEN);
} else {
if(instance->window_position >= (SubBruteAttackTotalCount - ITEMS_ON_SCREEN)) {
instance->window_position = (SubBruteAttackTotalCount - ITEMS_ON_SCREEN);
}
} }
} }
@@ -451,7 +465,9 @@ void subbrute_main_view_set_index(
model->key_from_file = instance->key_from_file; model->key_from_file = instance->key_from_file;
model->is_select_byte = instance->is_select_byte; model->is_select_byte = instance->is_select_byte;
model->two_bytes = instance->two_bytes; model->two_bytes = instance->two_bytes;
model->extra_repeats = instance->extra_repeats; for(size_t i = 0; i < SubBruteAttackTotalCount; i++) {
model->repeat_values[i] = repeats[i];
}
}, },
true); true);
} }
@@ -461,9 +477,9 @@ SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance) {
return instance->index; return instance->index;
} }
uint8_t subbrute_main_view_get_extra_repeats(SubBruteMainView* instance) { const uint8_t* subbrute_main_view_get_extra_repeats(SubBruteMainView* instance) {
furi_assert(instance); furi_assert(instance);
return instance->extra_repeats; return instance->repeat_values;
} }
bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance) { bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance) {

View File

@@ -20,11 +20,12 @@ View* subbrute_main_view_get_view(SubBruteMainView* instance);
void subbrute_main_view_set_index( void subbrute_main_view_set_index(
SubBruteMainView* instance, SubBruteMainView* instance,
uint8_t idx, uint8_t idx,
const uint8_t* repeats,
bool is_select_byte, bool is_select_byte,
bool two_bytes, bool two_bytes,
uint64_t file_key); uint64_t key_from_file);
SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance); SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance);
uint8_t subbrute_main_view_get_extra_repeats(SubBruteMainView* instance); const uint8_t* subbrute_main_view_get_extra_repeats(SubBruteMainView* instance);
bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance); bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance);
void subbrute_attack_view_enter(void* context); void subbrute_attack_view_enter(void* context);
void subbrute_attack_view_exit(void* context); void subbrute_attack_view_exit(void* context);