diff --git a/applications/main/bad_kb/bad_kb_app.c b/applications/main/bad_kb/bad_kb_app.c index 13a9f867c..7fcf02b7c 100644 --- a/applications/main/bad_kb/bad_kb_app.c +++ b/applications/main/bad_kb/bad_kb_app.c @@ -100,19 +100,19 @@ static void bad_kb_save_settings(BadKbApp* app) { void bad_kb_reload_worker(BadKbApp* app) { bad_kb_script_close(app->bad_kb_script); - app->bad_kb_script = bad_kb_script_open(app->file_path, app->is_bt ? app->bt : NULL); + app->bad_kb_script = bad_kb_script_open(app->file_path, app->is_bt ? app->bt : NULL, app); bad_kb_script_set_keyboard_layout(app->bad_kb_script, app->keyboard_layout); } -void bad_kb_config_switch_mode(BadKbApp* app) { - scene_manager_previous_scene(app->scene_manager); - if(app->is_bt) { - furi_hal_bt_start_advertising(); - } else { - furi_hal_bt_stop_advertising(); - } - scene_manager_next_scene(app->scene_manager, BadKbSceneConfig); +int32_t bad_kb_config_switch_mode(BadKbApp* app) { + if(!app->is_bt) furi_hal_bt_stop_advertising(); + XTREME_SETTINGS()->bad_bt = app->is_bt; + XTREME_SETTINGS_SAVE(); bad_kb_reload_worker(app); + if(app->is_bt) furi_hal_bt_start_advertising(); + scene_manager_next_scene(app->scene_manager, BadKbSceneConfig); + scene_manager_previous_scene(app->scene_manager); + return 0; } void bad_kb_config_switch_remember_mode(BadKbApp* app) { @@ -269,7 +269,7 @@ BadKbApp* bad_kb_app_alloc(char* arg) { "BadKbConnInit", 1024, (FuriThreadCallback)bad_kb_connection_init, app); furi_thread_start(app->conn_init_thread); if(!furi_string_empty(app->file_path)) { - app->bad_kb_script = bad_kb_script_open(app->file_path, app->is_bt ? app->bt : NULL); + app->bad_kb_script = bad_kb_script_open(app->file_path, app->is_bt ? app->bt : NULL, app); bad_kb_script_set_keyboard_layout(app->bad_kb_script, app->keyboard_layout); scene_manager_next_scene(app->scene_manager, BadKbSceneWork); } else { diff --git a/applications/main/bad_kb/bad_kb_app.h b/applications/main/bad_kb/bad_kb_app.h index 2da40a21f..923ba7780 100644 --- a/applications/main/bad_kb/bad_kb_app.h +++ b/applications/main/bad_kb/bad_kb_app.h @@ -6,67 +6,21 @@ #include #include -#include #include #include #include -#include -#include -#include -#include -#include "views/bad_kb_view.h" #define BAD_KB_APP_BASE_FOLDER EXT_PATH("badkb") #define BAD_KB_APP_PATH_LAYOUT_FOLDER BAD_KB_APP_BASE_FOLDER "/assets/layouts" #define BAD_KB_APP_SCRIPT_EXTENSION ".txt" #define BAD_KB_APP_LAYOUT_EXTENSION ".kl" -#define BAD_KB_ADV_NAME_MAX_LEN FURI_HAL_BT_ADV_NAME_LENGTH -#define BAD_KB_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE - -typedef enum { - BadKbAppErrorNoFiles, - BadKbAppErrorCloseRpc, -} BadKbAppError; - typedef enum BadKbCustomEvent { BadKbAppCustomEventTextEditResult, BadKbAppCustomEventByteInputDone, BadKbCustomEventErrorBack } BadKbCustomEvent; -typedef struct { - char bt_name[BAD_KB_ADV_NAME_MAX_LEN + 1]; - uint8_t bt_mac[BAD_KB_MAC_ADDRESS_LEN]; - FuriHalUsbInterface* usb_mode; - GapPairing bt_mode; -} BadKbConfig; - -typedef struct { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - NotificationApp* notifications; - DialogsApp* dialogs; - Widget* widget; - VariableItemList* var_item_list; - TextInput* text_input; - ByteInput* byte_input; - - BadKbAppError error; - FuriString* file_path; - FuriString* keyboard_layout; - BadKb* bad_kb_view; - BadKbScript* bad_kb_script; - - Bt* bt; - bool is_bt; - bool bt_remember; - BadKbConfig config; - BadKbConfig prev_config; - FuriThread* conn_init_thread; -} BadKbApp; - typedef enum { BadKbAppViewError, BadKbAppViewWork, @@ -75,8 +29,6 @@ typedef enum { BadKbAppViewConfigName } BadKbAppView; -void bad_kb_config_switch_mode(BadKbApp* app); - void bad_kb_config_switch_remember_mode(BadKbApp* app); int32_t bad_kb_connection_init(BadKbApp* app); diff --git a/applications/main/bad_kb/helpers/ducky_script.c b/applications/main/bad_kb/helpers/ducky_script.c index 6b212a68d..216afb7b5 100644 --- a/applications/main/bad_kb/helpers/ducky_script.c +++ b/applications/main/bad_kb/helpers/ducky_script.c @@ -10,6 +10,7 @@ #include "ducky_script.h" #include "ducky_script_i.h" #include +#include #define TAG "BadKB" #define WORKER_TAG TAG "Worker" @@ -67,6 +68,7 @@ typedef enum { } WorkerEvtFlags; static const char ducky_cmd_id[] = {"ID"}; +static const char ducky_cmd_bt_id[] = {"BT_ID"}; static const uint8_t numpad_keys[10] = { HID_KEYPAD_0, @@ -327,6 +329,28 @@ static bool ducky_set_usb_id(BadKbScript* bad_kb, const char* line) { return false; } +static bool ducky_set_bt_id(BadKbScript* bad_kb, const char* line) { + size_t line_len = strlen(line); + size_t mac_len = BAD_KB_MAC_ADDRESS_LEN * 3; + if(line_len < mac_len + 1) return false; // MAC + at least 1 char for name + + uint8_t mac[BAD_KB_MAC_ADDRESS_LEN]; + for(size_t i = 0; i < BAD_KB_MAC_ADDRESS_LEN; i++) { + char a = line[i * 3]; + char b = line[i * 3 + 1]; + if((a < 'A' && a > 'F') || (a < '0' && a > '9') || (b < 'A' && b > 'F') || (b < '0' && b > '9') || !hex_char_to_uint8(a, b, &mac[i])) { + return false; + } + } + + strncpy(bad_kb->app->config.bt_name, line + mac_len, BAD_KB_ADV_NAME_MAX_LEN); + memcpy(bad_kb->app->config.bt_mac, mac, BAD_KB_MAC_ADDRESS_LEN); + + furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, bad_kb->app->config.bt_name); + bt_set_profile_mac_address(bad_kb->bt, bad_kb->app->config.bt_mac); + return true; +} + static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) { uint8_t ret = 0; uint32_t line_len = 0; @@ -354,20 +378,35 @@ static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) { } } while(ret > 0); - if(!bad_kb->bt) { - const char* line_tmp = furi_string_get_cstr(bad_kb->line); - bool id_set = false; // Looking for ID command at first line - if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) { - id_set = ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1]); + const char* line_tmp = furi_string_get_cstr(bad_kb->line); + // Looking for ID or BT_ID command at first line + if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) { + if(bad_kb->bt) { + bad_kb->app->is_bt = false; + FuriThread* thread = furi_thread_alloc_ex( + "BadKbSwitchMode", 1024, (FuriThreadCallback)bad_kb_config_switch_mode, bad_kb->app); + furi_thread_start(thread); + return false; } - - if(id_set) { + if(ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1])) { furi_check(furi_hal_usb_set_config(&usb_hid, &bad_kb->hid_cfg)); } else { furi_check(furi_hal_usb_set_config(&usb_hid, NULL)); } + } else if(strncmp(line_tmp, ducky_cmd_bt_id, strlen(ducky_cmd_bt_id)) == 0) { + if(!bad_kb->bt) { + bad_kb->app->is_bt = true; + FuriThread* thread = furi_thread_alloc_ex( + "BadKbSwitchMode", 1024, (FuriThreadCallback)bad_kb_config_switch_mode, bad_kb->app); + furi_thread_start(thread); + return false; + } + if(!bad_kb->app->bt_remember) { + ducky_set_bt_id(bad_kb, &line_tmp[strlen(ducky_cmd_bt_id) + 1]); + } } + storage_file_seek(script_file, 0, true); furi_string_reset(bad_kb->line); @@ -766,10 +805,11 @@ static void bad_kb_script_set_default_keyboard_layout(BadKbScript* bad_kb) { memcpy(bad_kb->layout, hid_asciimap, MIN(sizeof(hid_asciimap), sizeof(bad_kb->layout))); } -BadKbScript* bad_kb_script_open(FuriString* file_path, Bt* bt) { +BadKbScript* bad_kb_script_open(FuriString* file_path, Bt* bt, BadKbApp* app) { furi_assert(file_path); BadKbScript* bad_kb = malloc(sizeof(BadKbScript)); + bad_kb->app = app; bad_kb->file_path = furi_string_alloc(); furi_string_set(bad_kb->file_path, file_path); bad_kb->keyboard_layout = furi_string_alloc(); diff --git a/applications/main/bad_kb/helpers/ducky_script.h b/applications/main/bad_kb/helpers/ducky_script.h index 6f5e03e0b..56ef3286e 100644 --- a/applications/main/bad_kb/helpers/ducky_script.h +++ b/applications/main/bad_kb/helpers/ducky_script.h @@ -8,6 +8,13 @@ extern "C" { #include #include +#include +#include +#include +#include +#include +#include "../views/bad_kb_view.h" + #define FILE_BUFFER_LEN 16 typedef enum { @@ -38,7 +45,7 @@ typedef enum { BadKbStateFileError, } BadKbWorkerState; -typedef struct { +struct BadKbState { BadKbWorkerState state; bool is_bt; uint32_t pin; @@ -47,7 +54,9 @@ typedef struct { uint32_t delay_remain; uint16_t error_line; char error[64]; -} BadKbState; +}; + +typedef struct BadKbApp BadKbApp; typedef struct { FuriHalUsbHidConfig hid_cfg; @@ -74,9 +83,10 @@ typedef struct { size_t string_print_pos; Bt* bt; + BadKbApp* app; } BadKbScript; -BadKbScript* bad_kb_script_open(FuriString* file_path, Bt* bt); +BadKbScript* bad_kb_script_open(FuriString* file_path, Bt* bt, BadKbApp* app); void bad_kb_script_close(BadKbScript* bad_kb); @@ -90,6 +100,48 @@ void bad_kb_script_toggle(BadKbScript* bad_kb); BadKbState* bad_kb_script_get_state(BadKbScript* bad_kb); +#define BAD_KB_ADV_NAME_MAX_LEN FURI_HAL_BT_ADV_NAME_LENGTH +#define BAD_KB_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE + +typedef enum { + BadKbAppErrorNoFiles, + BadKbAppErrorCloseRpc, +} BadKbAppError; + +typedef struct { + char bt_name[BAD_KB_ADV_NAME_MAX_LEN + 1]; + uint8_t bt_mac[BAD_KB_MAC_ADDRESS_LEN]; + FuriHalUsbInterface* usb_mode; + GapPairing bt_mode; +} BadKbConfig; + +struct BadKbApp { + Gui* gui; + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + NotificationApp* notifications; + DialogsApp* dialogs; + Widget* widget; + VariableItemList* var_item_list; + TextInput* text_input; + ByteInput* byte_input; + + BadKbAppError error; + FuriString* file_path; + FuriString* keyboard_layout; + BadKb* bad_kb_view; + BadKbScript* bad_kb_script; + + Bt* bt; + bool is_bt; + bool bt_remember; + BadKbConfig config; + BadKbConfig prev_config; + FuriThread* conn_init_thread; +}; + +int32_t bad_kb_config_switch_mode(BadKbApp* app); + #ifdef __cplusplus } #endif diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config.c b/applications/main/bad_kb/scenes/bad_kb_scene_config.c index dbf62e96e..3f16a4c48 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config.c @@ -1,4 +1,5 @@ #include "../bad_kb_app.h" +#include "../helpers/ducky_script.h" #include "furi_hal_power.h" #include "furi_hal_usb.h" #include @@ -15,8 +16,6 @@ enum VarItemListIndex { void bad_kb_scene_config_connection_callback(VariableItem* item) { BadKbApp* bad_kb = variable_item_get_context(item); bad_kb->is_bt = variable_item_get_current_value_index(item); - XTREME_SETTINGS()->bad_bt = bad_kb->is_bt; - XTREME_SETTINGS_SAVE(); variable_item_set_current_value_text(item, bad_kb->is_bt ? "BT" : "USB"); view_dispatcher_send_custom_event(bad_kb->view_dispatcher, VarItemListIndexConnection); } diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_file_select.c b/applications/main/bad_kb/scenes/bad_kb_scene_file_select.c index d14624447..3a8c0748d 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_file_select.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_file_select.c @@ -29,7 +29,7 @@ void bad_kb_scene_file_select_on_enter(void* context) { if(bad_kb_file_select(bad_kb)) { bad_kb->bad_kb_script = - bad_kb_script_open(bad_kb->file_path, bad_kb->is_bt ? bad_kb->bt : NULL); + bad_kb_script_open(bad_kb->file_path, bad_kb->is_bt ? bad_kb->bt : NULL, bad_kb); bad_kb_script_set_keyboard_layout(bad_kb->bad_kb_script, bad_kb->keyboard_layout); scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneWork); diff --git a/applications/main/bad_kb/views/bad_kb_view.c b/applications/main/bad_kb/views/bad_kb_view.c index a05cbb282..95ffe3e4a 100644 --- a/applications/main/bad_kb/views/bad_kb_view.c +++ b/applications/main/bad_kb/views/bad_kb_view.c @@ -8,12 +8,6 @@ #define MAX_NAME_LEN 64 -struct BadKb { - View* view; - BadKbButtonCallback callback; - void* context; -}; - typedef struct { char file_name[MAX_NAME_LEN]; char layout[MAX_NAME_LEN]; diff --git a/applications/main/bad_kb/views/bad_kb_view.h b/applications/main/bad_kb/views/bad_kb_view.h index d8f2559bb..797fafb69 100644 --- a/applications/main/bad_kb/views/bad_kb_view.h +++ b/applications/main/bad_kb/views/bad_kb_view.h @@ -1,11 +1,17 @@ #pragma once #include -#include "../helpers/ducky_script.h" -typedef struct BadKb BadKb; typedef void (*BadKbButtonCallback)(InputKey key, void* context); +typedef struct { + View* view; + BadKbButtonCallback callback; + void* context; +} BadKb; + +typedef struct BadKbState BadKbState; + BadKb* bad_kb_alloc(); void bad_kb_free(BadKb* bad_kb);