mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-30 16:56:41 +03:00
231 lines
8.2 KiB
C
231 lines
8.2 KiB
C
|
#include "subbrute.h"
|
||
|
|
||
|
#include "scene/subbrute_scene_load_file.h"
|
||
|
#include "scene/subbrute_scene_select_field.h"
|
||
|
#include "scene/subbrute_scene_run_attack.h"
|
||
|
#include "scene/subbrute_scene_entrypoint.h"
|
||
|
|
||
|
static void draw_callback(Canvas* const canvas, void* ctx) {
|
||
|
SubBruteState* subbrute_state = (SubBruteState*)acquire_mutex((ValueMutex*)ctx, 100);
|
||
|
|
||
|
if(subbrute_state == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Draw correct Canvas
|
||
|
switch(subbrute_state->current_scene) {
|
||
|
case NoneScene:
|
||
|
case SceneSelectFile:
|
||
|
subbrute_scene_load_file_on_draw(canvas, subbrute_state);
|
||
|
break;
|
||
|
case SceneSelectField:
|
||
|
subbrute_scene_select_field_on_draw(canvas, subbrute_state);
|
||
|
break;
|
||
|
case SceneAttack:
|
||
|
subbrute_scene_run_attack_on_draw(canvas, subbrute_state);
|
||
|
break;
|
||
|
case SceneEntryPoint:
|
||
|
subbrute_scene_entrypoint_on_draw(canvas, subbrute_state);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
release_mutex((ValueMutex*)ctx, subbrute_state);
|
||
|
}
|
||
|
|
||
|
void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||
|
furi_assert(event_queue);
|
||
|
|
||
|
SubBruteEvent event = {
|
||
|
.evt_type = EventTypeKey, .key = input_event->key, .input_type = input_event->type};
|
||
|
furi_message_queue_put(event_queue, &event, 100);
|
||
|
}
|
||
|
|
||
|
static void timer_callback(FuriMessageQueue* event_queue) {
|
||
|
furi_assert(event_queue);
|
||
|
SubBruteEvent event = {
|
||
|
.evt_type = EventTypeTick, .key = InputKeyUp, .input_type = InputTypeRelease};
|
||
|
furi_message_queue_put(event_queue, &event, 100);
|
||
|
}
|
||
|
|
||
|
SubBruteState* subbrute_alloc() {
|
||
|
SubBruteState* subbrute = malloc(sizeof(SubBruteState));
|
||
|
|
||
|
string_init(subbrute->protocol);
|
||
|
string_init(subbrute->preset);
|
||
|
string_init(subbrute->file_path);
|
||
|
string_init(subbrute->file_path_tmp);
|
||
|
string_init_set(subbrute->notification_msg, "");
|
||
|
string_init(subbrute->candidate);
|
||
|
string_init(subbrute->flipper_format_string);
|
||
|
|
||
|
subbrute->previous_scene = NoneScene;
|
||
|
subbrute->current_scene = SceneSelectFile;
|
||
|
subbrute->is_running = true;
|
||
|
subbrute->is_attacking = false;
|
||
|
subbrute->key_index = 0;
|
||
|
subbrute->notify = furi_record_open(RECORD_NOTIFICATION);
|
||
|
|
||
|
//Dialog
|
||
|
subbrute->dialogs = furi_record_open(RECORD_DIALOGS);
|
||
|
|
||
|
subbrute->flipper_format = flipper_format_string_alloc();
|
||
|
subbrute->environment = subghz_environment_alloc();
|
||
|
subbrute->receiver = subghz_receiver_alloc_init(subbrute->environment);
|
||
|
subghz_receiver_set_filter(subbrute->receiver, SubGhzProtocolFlag_Decodable);
|
||
|
|
||
|
return subbrute;
|
||
|
}
|
||
|
|
||
|
void subbrute_free(SubBruteState* subbrute) {
|
||
|
//Dialog
|
||
|
furi_record_close(RECORD_DIALOGS);
|
||
|
notification_message(subbrute->notify, &sequence_blink_stop);
|
||
|
|
||
|
string_clear(subbrute->preset);
|
||
|
string_clear(subbrute->candidate);
|
||
|
|
||
|
// Path strings
|
||
|
string_clear(subbrute->file_path);
|
||
|
string_clear(subbrute->file_path_tmp);
|
||
|
string_clear(subbrute->notification_msg);
|
||
|
string_clear(subbrute->candidate);
|
||
|
string_clear(subbrute->flipper_format_string);
|
||
|
|
||
|
// The rest
|
||
|
free(subbrute);
|
||
|
}
|
||
|
|
||
|
// ENTRYPOINT
|
||
|
int32_t subbrute_start(void* p) {
|
||
|
UNUSED(p);
|
||
|
// Input
|
||
|
FURI_LOG_I(TAG, "Initializing input");
|
||
|
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(SubBruteEvent));
|
||
|
SubBruteState* subbrute_state = subbrute_alloc();
|
||
|
ValueMutex subbrute_state_mutex;
|
||
|
|
||
|
// Mutex
|
||
|
FURI_LOG_I(TAG, "Initializing flipfrid mutex");
|
||
|
if(!init_mutex(&subbrute_state_mutex, subbrute_state, sizeof(SubBruteState))) {
|
||
|
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
||
|
furi_message_queue_free(event_queue);
|
||
|
free(subbrute_state);
|
||
|
}
|
||
|
|
||
|
// Configure view port
|
||
|
FURI_LOG_I(TAG, "Initializing viewport");
|
||
|
ViewPort* view_port = view_port_alloc();
|
||
|
view_port_draw_callback_set(view_port, draw_callback, &subbrute_state_mutex);
|
||
|
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||
|
|
||
|
// Configure timer
|
||
|
FURI_LOG_I(TAG, "Initializing timer");
|
||
|
FuriTimer* timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, event_queue);
|
||
|
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10); // 10 times per second
|
||
|
|
||
|
// Register view port in GUI
|
||
|
FURI_LOG_I(TAG, "Initializing gui");
|
||
|
Gui* gui = (Gui*)furi_record_open(RECORD_GUI);
|
||
|
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||
|
|
||
|
subbrute_state->current_scene = SceneEntryPoint;
|
||
|
|
||
|
// Init values
|
||
|
SubBruteEvent event;
|
||
|
while(subbrute_state->is_running) {
|
||
|
// Get next event
|
||
|
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 25);
|
||
|
if(event_status == FuriStatusOk) {
|
||
|
if(event.evt_type == EventTypeKey) {
|
||
|
//Handle event key
|
||
|
FURI_LOG_D(TAG, "EVENT ###");
|
||
|
switch(subbrute_state->current_scene) {
|
||
|
case SceneSelectFile:
|
||
|
subbrute_scene_load_file_on_event(event, subbrute_state);
|
||
|
break;
|
||
|
case SceneSelectField:
|
||
|
subbrute_scene_select_field_on_event(event, subbrute_state);
|
||
|
break;
|
||
|
case SceneAttack:
|
||
|
subbrute_scene_run_attack_on_event(event, subbrute_state);
|
||
|
break;
|
||
|
case NoneScene:
|
||
|
case SceneEntryPoint:
|
||
|
subbrute_scene_entrypoint_on_event(event, subbrute_state);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} else if(event.evt_type == EventTypeTick) {
|
||
|
//Handle event tick
|
||
|
if(subbrute_state->current_scene != subbrute_state->previous_scene) {
|
||
|
// Trigger Exit Scene
|
||
|
switch(subbrute_state->previous_scene) {
|
||
|
case SceneSelectFile:
|
||
|
subbrute_scene_load_file_on_exit(subbrute_state);
|
||
|
break;
|
||
|
case SceneSelectField:
|
||
|
subbrute_scene_select_field_on_exit(subbrute_state);
|
||
|
break;
|
||
|
case SceneAttack:
|
||
|
subbrute_scene_run_attack_on_exit(subbrute_state);
|
||
|
break;
|
||
|
case SceneEntryPoint:
|
||
|
subbrute_scene_entrypoint_on_exit(subbrute_state);
|
||
|
break;
|
||
|
case NoneScene:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Trigger Entry Scene
|
||
|
switch(subbrute_state->current_scene) {
|
||
|
case NoneScene:
|
||
|
case SceneSelectFile:
|
||
|
subbrute_scene_load_file_on_enter(subbrute_state);
|
||
|
break;
|
||
|
case SceneSelectField:
|
||
|
subbrute_scene_select_field_on_enter(subbrute_state);
|
||
|
break;
|
||
|
case SceneAttack:
|
||
|
subbrute_scene_run_attack_on_enter(subbrute_state);
|
||
|
break;
|
||
|
case SceneEntryPoint:
|
||
|
subbrute_scene_entrypoint_on_enter(subbrute_state);
|
||
|
break;
|
||
|
}
|
||
|
subbrute_state->previous_scene = subbrute_state->current_scene;
|
||
|
}
|
||
|
|
||
|
// Trigger Tick Scene
|
||
|
switch(subbrute_state->current_scene) {
|
||
|
case NoneScene:
|
||
|
case SceneSelectFile:
|
||
|
subbrute_scene_load_file_on_tick(subbrute_state);
|
||
|
break;
|
||
|
case SceneSelectField:
|
||
|
subbrute_scene_select_field_on_tick(subbrute_state);
|
||
|
break;
|
||
|
case SceneAttack:
|
||
|
subbrute_scene_run_attack_on_tick(subbrute_state);
|
||
|
break;
|
||
|
case SceneEntryPoint:
|
||
|
subbrute_scene_entrypoint_on_tick(subbrute_state);
|
||
|
break;
|
||
|
}
|
||
|
view_port_update(view_port);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Cleanup
|
||
|
furi_timer_stop(timer);
|
||
|
furi_timer_free(timer);
|
||
|
|
||
|
FURI_LOG_I(TAG, "Cleaning up");
|
||
|
gui_remove_view_port(gui, view_port);
|
||
|
view_port_free(view_port);
|
||
|
furi_message_queue_free(event_queue);
|
||
|
furi_record_close(RECORD_GUI);
|
||
|
subbrute_free(subbrute_state);
|
||
|
|
||
|
return 0;
|
||
|
}
|