From 268b6943629488d5a66661bf58fd4036042abe62 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 26 Feb 2025 04:48:49 +0000 Subject: [PATCH] BadKB: Rewrite BadKB extras on "new" OFW BadUSB structure - Mainly, HID interface abstractions and porting all BadKB options to it - Tying up some loose ends, some things still not ideal but good enough - Can customize BLE MAC address when BLE Remember is enabled - Added BLE_ID command, alias for BT_ID (OFW BadUSB calls everything BLE) --- CHANGELOG.md | 5 + applications/main/bad_kb/bad_kb_app.c | 433 ++++++------------ applications/main/bad_kb/bad_kb_app_i.h | 73 +-- applications/main/bad_kb/bad_kb_paths.h | 8 - applications/main/bad_kb/helpers/bad_kb_hid.c | 321 +++++++++++++ applications/main/bad_kb/helpers/bad_kb_hid.h | 48 ++ .../helpers/{ble_hid.c => ble_hid_profile.c} | 9 +- .../helpers/{ble_hid.h => ble_hid_profile.h} | 2 + .../{ble_hid_svc.c => ble_hid_service.c} | 9 +- .../{ble_hid_svc.h => ble_hid_service.h} | 4 +- .../main/bad_kb/helpers/ducky_script.c | 402 ++++++---------- .../main/bad_kb/helpers/ducky_script.h | 38 +- .../bad_kb/helpers/ducky_script_commands.c | 152 +++--- .../main/bad_kb/helpers/ducky_script_i.h | 15 +- .../bad_kb/helpers/ducky_script_keycodes.c | 23 + .../resources/badusb/Demos/test_mouse.txt | 46 ++ .../main/bad_kb/scenes/bad_kb_scene_config.c | 242 +++++----- .../main/bad_kb/scenes/bad_kb_scene_config.h | 6 +- .../scenes/bad_kb_scene_config_ble_mac.c | 71 +++ .../scenes/bad_kb_scene_config_ble_name.c | 59 +++ .../scenes/bad_kb_scene_config_bt_mac.c | 61 --- .../scenes/bad_kb_scene_config_bt_name.c | 58 --- .../scenes/bad_kb_scene_config_layout.c | 5 +- .../scenes/bad_kb_scene_config_usb_name.c | 51 +-- .../scenes/bad_kb_scene_config_usb_vidpid.c | 32 +- .../scenes/bad_kb_scene_confirm_unpair.c | 49 ++ .../main/bad_kb/scenes/bad_kb_scene_error.c | 4 + .../bad_kb/scenes/bad_kb_scene_file_select.c | 10 +- .../bad_kb/scenes/bad_kb_scene_unpair_done.c | 39 ++ .../main/bad_kb/scenes/bad_kb_scene_work.c | 33 +- applications/main/bad_kb/views/bad_kb_view.c | 39 +- applications/main/bad_kb/views/bad_kb_view.h | 2 + applications/services/bt/bt_service/bt.c | 5 - applications/services/bt/bt_service/bt_i.h | 1 - .../bt_settings_scene_forget_dev_confirm.c | 4 +- assets/icons/BadKb/Bad_BLE_48x22.png | Bin 0 -> 145 bytes targets/f7/api_symbols.csv | 1 + 37 files changed, 1308 insertions(+), 1052 deletions(-) delete mode 100644 applications/main/bad_kb/bad_kb_paths.h create mode 100644 applications/main/bad_kb/helpers/bad_kb_hid.c create mode 100644 applications/main/bad_kb/helpers/bad_kb_hid.h rename applications/main/bad_kb/helpers/{ble_hid.c => ble_hid_profile.c} (98%) rename applications/main/bad_kb/helpers/{ble_hid.h => ble_hid_profile.h} (98%) rename applications/main/bad_kb/helpers/{ble_hid_svc.c => ble_hid_service.c} (98%) rename applications/main/bad_kb/helpers/{ble_hid_svc.h => ble_hid_service.h} (85%) create mode 100644 applications/main/bad_kb/resources/badusb/Demos/test_mouse.txt create mode 100644 applications/main/bad_kb/scenes/bad_kb_scene_config_ble_mac.c create mode 100644 applications/main/bad_kb/scenes/bad_kb_scene_config_ble_name.c delete mode 100644 applications/main/bad_kb/scenes/bad_kb_scene_config_bt_mac.c delete mode 100644 applications/main/bad_kb/scenes/bad_kb_scene_config_bt_name.c create mode 100644 applications/main/bad_kb/scenes/bad_kb_scene_confirm_unpair.c create mode 100644 applications/main/bad_kb/scenes/bad_kb_scene_unpair_done.c create mode 100644 assets/icons/BadKb/Bad_BLE_48x22.png diff --git a/CHANGELOG.md b/CHANGELOG.md index de6f8b50d..5e693c805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ - OFW: JS: New `gui/widget` view, replaces old `widget` module (by @portasynthinca3) - Scripts using `widget` module will need to be updated - Check the `gui.js` example for reference usage +- BadKB: Rewritten BadKB extras on top of "new" OFW BadUSB structure (by @Willy-JL) + - Should be more reliable with BLE, will be easier to keep updated + - Previous settings and pairing will be reset, need to reconfigure and pair again ### Added: - Apps: @@ -33,6 +36,8 @@ - Metroflip: Big refactor with plugins and assets to save RAM, RavKav moved to Calypso parser (by @luu176), unified Calypso parser (by @DocSystem) - Picopass: Added Save SR as legacy from saved menu, fix write key 'retry' when presented with new card (by @bettse) - Pinball0: Prevent tilt before ball is in play, fixed Endless table by making bottom portal extend full width (by @rdefeo) +- BadKB: Rewritten BadKB extras on top of "new" OFW BadUSB structure (by @Willy-JL) + - Additionally, can now customize MAC address when BLE Remember is enabled - NFC: - OFW: Added naming for DESFire cards + fix MF3ICD40 cards unable to be read (by @Demae) - OFW: Enable MFUL sync poller to be provided with passwords (by @GMMan) diff --git a/applications/main/bad_kb/bad_kb_app.c b/applications/main/bad_kb/bad_kb_app.c index aaae95011..9acd8437e 100644 --- a/applications/main/bad_kb/bad_kb_app.c +++ b/applications/main/bad_kb/bad_kb_app.c @@ -3,12 +3,12 @@ #include #include #include -#include -#include -#include "helpers/ducky_script_i.h" +#include -// Adjusts to serial MAC +2 in app init -uint8_t BAD_KB_BOUND_MAC[GAP_MAC_ADDR_SIZE] = {0}; +#define BAD_KB_SETTINGS_PATH BAD_KB_APP_BASE_FOLDER "/.badkb.settings" +#define BAD_KB_SETTINGS_FILE_TYPE "Flipper BadKB Settings File" +#define BAD_KB_SETTINGS_VERSION 1 +#define BAD_KB_SETTINGS_DEFAULT_LAYOUT BAD_KB_APP_PATH_LAYOUT_FOLDER "/en-US.kl" static bool bad_kb_app_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -28,118 +28,158 @@ static void bad_kb_app_tick_event_callback(void* context) { scene_manager_handle_tick_event(app->scene_manager); } -void bad_kb_load_settings(BadKbApp* app) { - furi_string_reset(app->keyboard_layout); - BadKbConfig* cfg = &app->config; - +static void bad_kb_load_settings(BadKbApp* app) { Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* file = flipper_format_file_alloc(storage); - if(flipper_format_file_open_existing(file, BAD_KB_SETTINGS_PATH)) { - FuriString* tmp_str = furi_string_alloc(); - uint32_t tmp_uint = 0; + FlipperFormat* fff = flipper_format_file_alloc(storage); + bool loaded = false; - if(!flipper_format_read_string(file, "Keyboard_Layout", app->keyboard_layout)) { - furi_string_reset(app->keyboard_layout); - flipper_format_rewind(file); - } + BadKbHidConfig* hid_cfg = &app->user_hid_cfg; + FuriString* temp_str = furi_string_alloc(); + uint32_t temp_uint = 0; - if(!flipper_format_read_bool(file, "Is_Bt", &app->is_bt, 1)) { - app->is_bt = false; - flipper_format_rewind(file); - } + if(flipper_format_file_open_existing(fff, BAD_KB_SETTINGS_PATH)) { + do { + if(!flipper_format_read_header(fff, temp_str, &temp_uint)) break; + if((strcmp(furi_string_get_cstr(temp_str), BAD_KB_SETTINGS_FILE_TYPE) != 0) || + (temp_uint != BAD_KB_SETTINGS_VERSION)) + break; - if(!flipper_format_read_bool(file, "Bt_Remember", &cfg->ble.bonding, 1)) { - cfg->ble.bonding = false; - flipper_format_rewind(file); - } + if(flipper_format_read_string(fff, "layout", temp_str)) { + furi_string_set(app->keyboard_layout, temp_str); + FileInfo layout_file_info; + FS_Error file_check_err = storage_common_stat( + storage, furi_string_get_cstr(app->keyboard_layout), &layout_file_info); + if((file_check_err != FSE_OK) || (layout_file_info.size != 256)) { + furi_string_set(app->keyboard_layout, BAD_KB_SETTINGS_DEFAULT_LAYOUT); + } + } else { + furi_string_set(app->keyboard_layout, BAD_KB_SETTINGS_DEFAULT_LAYOUT); + flipper_format_rewind(fff); + } - if(!flipper_format_read_uint32(file, "Bt_Pairing", &tmp_uint, 1)) { - tmp_uint = GapPairingNone; - flipper_format_rewind(file); - } - cfg->ble.pairing = tmp_uint; + if(!flipper_format_read_uint32(fff, "interface", &temp_uint, 1) || + temp_uint >= BadKbHidInterfaceMAX) { + temp_uint = BadKbHidInterfaceUsb; + flipper_format_rewind(fff); + } + app->interface = temp_uint; - if(flipper_format_read_string(file, "Bt_Name", tmp_str)) { - strlcpy(cfg->ble.name, furi_string_get_cstr(tmp_str), sizeof(cfg->ble.name)); - } else { - cfg->ble.name[0] = '\0'; - flipper_format_rewind(file); - } + if(!flipper_format_read_bool(fff, "ble_bonding", &hid_cfg->ble.bonding, 1)) { + hid_cfg->ble.bonding = true; + flipper_format_rewind(fff); + } - if(!flipper_format_read_hex( - file, "Bt_Mac", (uint8_t*)&cfg->ble.mac, sizeof(cfg->ble.mac))) { - memset(cfg->ble.mac, 0, sizeof(cfg->ble.mac)); - flipper_format_rewind(file); - } + if(!flipper_format_read_uint32(fff, "ble_pairing", &temp_uint, 1) || + temp_uint >= GapPairingCount) { + temp_uint = GapPairingPinCodeVerifyYesNo; + flipper_format_rewind(fff); + } + hid_cfg->ble.pairing = temp_uint; - if(flipper_format_read_string(file, "Usb_Manuf", tmp_str)) { - strlcpy(cfg->usb.manuf, furi_string_get_cstr(tmp_str), sizeof(cfg->usb.manuf)); - } else { - cfg->usb.manuf[0] = '\0'; - flipper_format_rewind(file); - } + if(flipper_format_read_string(fff, "ble_name", temp_str)) { + strlcpy( + hid_cfg->ble.name, furi_string_get_cstr(temp_str), sizeof(hid_cfg->ble.name)); + } else { + hid_cfg->ble.name[0] = '\0'; + flipper_format_rewind(fff); + } - if(flipper_format_read_string(file, "Usb_Product", tmp_str)) { - strlcpy(cfg->usb.product, furi_string_get_cstr(tmp_str), sizeof(cfg->usb.product)); - } else { - cfg->usb.product[0] = '\0'; - flipper_format_rewind(file); - } + if(!flipper_format_read_hex( + fff, "ble_mac", hid_cfg->ble.mac, sizeof(hid_cfg->ble.mac))) { + memset(hid_cfg->ble.mac, 0, sizeof(hid_cfg->ble.mac)); + flipper_format_rewind(fff); + } - if(!flipper_format_read_uint32(file, "Usb_Vid", &cfg->usb.vid, 1)) { - cfg->usb.vid = 0; - flipper_format_rewind(file); - } + if(flipper_format_read_string(fff, "usb_manuf", temp_str)) { + strlcpy( + hid_cfg->usb.manuf, + furi_string_get_cstr(temp_str), + sizeof(hid_cfg->usb.manuf)); + } else { + hid_cfg->usb.manuf[0] = '\0'; + flipper_format_rewind(fff); + } - if(!flipper_format_read_uint32(file, "Usb_Pid", &cfg->usb.pid, 1)) { - cfg->usb.pid = 0; - flipper_format_rewind(file); - } + if(flipper_format_read_string(fff, "usb_product", temp_str)) { + strlcpy( + hid_cfg->usb.product, + furi_string_get_cstr(temp_str), + sizeof(hid_cfg->usb.product)); + } else { + hid_cfg->usb.product[0] = '\0'; + flipper_format_rewind(fff); + } - furi_string_free(tmp_str); - flipper_format_file_close(file); - } - flipper_format_free(file); + if(!flipper_format_read_uint32(fff, "usb_vid", &hid_cfg->usb.vid, 1)) { + hid_cfg->usb.vid = 0; + flipper_format_rewind(fff); + } - if(!furi_string_empty(app->keyboard_layout)) { - FileInfo layout_file_info; - FS_Error file_check_err = storage_common_stat( - storage, furi_string_get_cstr(app->keyboard_layout), &layout_file_info); - if(file_check_err != FSE_OK) { - furi_string_reset(app->keyboard_layout); - return; - } - if(layout_file_info.size != 256) { - furi_string_reset(app->keyboard_layout); - } + if(!flipper_format_read_uint32(fff, "usb_pid", &hid_cfg->usb.pid, 1)) { + hid_cfg->usb.pid = 0; + flipper_format_rewind(fff); + } + + loaded = true; + } while(0); } + furi_string_free(temp_str); + + flipper_format_free(fff); furi_record_close(RECORD_STORAGE); + + if(!loaded) { + furi_string_set(app->keyboard_layout, BAD_KB_SETTINGS_DEFAULT_LAYOUT); + app->interface = BadKbHidInterfaceUsb; + hid_cfg->ble.bonding = true; + hid_cfg->ble.pairing = GapPairingPinCodeVerifyYesNo; + hid_cfg->ble.name[0] = '\0'; + memset(hid_cfg->ble.mac, 0, sizeof(hid_cfg->ble.mac)); + hid_cfg->usb.manuf[0] = '\0'; + hid_cfg->usb.product[0] = '\0'; + hid_cfg->usb.vid = 0; + hid_cfg->usb.pid = 0; + } } static void bad_kb_save_settings(BadKbApp* app) { - BadKbConfig* cfg = &app->config; Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* file = flipper_format_file_alloc(storage); - if(flipper_format_file_open_always(file, BAD_KB_SETTINGS_PATH)) { - uint32_t tmp_uint = 0; - flipper_format_write_string(file, "Keyboard_Layout", app->keyboard_layout); - flipper_format_write_bool(file, "Is_Bt", &app->is_bt, 1); - flipper_format_write_bool(file, "Bt_Remember", &cfg->ble.bonding, 1); - tmp_uint = cfg->ble.pairing; - flipper_format_write_uint32(file, "Bt_Pairing", &tmp_uint, 1); - flipper_format_write_string_cstr(file, "Bt_Name", cfg->ble.name); - flipper_format_write_hex(file, "Bt_Mac", (uint8_t*)&cfg->ble.mac, sizeof(cfg->ble.mac)); - flipper_format_write_string_cstr(file, "Usb_Manuf", cfg->usb.manuf); - flipper_format_write_string_cstr(file, "Usb_Product", cfg->usb.product); - flipper_format_write_uint32(file, "Usb_Vid", &cfg->usb.vid, 1); - flipper_format_write_uint32(file, "Usb_Pid", &cfg->usb.pid, 1); - flipper_format_file_close(file); + FlipperFormat* fff = flipper_format_file_alloc(storage); + BadKbHidConfig* hid_cfg = &app->user_hid_cfg; + uint32_t temp_uint = 0; + + if(flipper_format_file_open_always(fff, BAD_KB_SETTINGS_PATH)) { + do { + if(!flipper_format_write_header_cstr( + fff, BAD_KB_SETTINGS_FILE_TYPE, BAD_KB_SETTINGS_VERSION)) + break; + if(!flipper_format_write_string(fff, "layout", app->keyboard_layout)) break; + temp_uint = app->interface; + if(!flipper_format_write_uint32(fff, "interface", &temp_uint, 1)) break; + if(!flipper_format_write_bool(fff, "ble_bonding", &hid_cfg->ble.bonding, 1)) break; + temp_uint = hid_cfg->ble.pairing; + if(!flipper_format_write_uint32(fff, "ble_pairing", &temp_uint, 1)) break; + if(!flipper_format_write_string_cstr(fff, "ble_name", hid_cfg->ble.name)) break; + if(!flipper_format_write_hex( + fff, "ble_mac", (uint8_t*)&hid_cfg->ble.mac, sizeof(hid_cfg->ble.mac))) + break; + if(!flipper_format_write_string_cstr(fff, "usb_manuf", hid_cfg->usb.manuf)) break; + if(!flipper_format_write_string_cstr(fff, "usb_product", hid_cfg->usb.product)) break; + if(!flipper_format_write_uint32(fff, "usb_vid", &hid_cfg->usb.vid, 1)) break; + if(!flipper_format_write_uint32(fff, "usb_pid", &hid_cfg->usb.pid, 1)) break; + } while(0); } - flipper_format_free(file); + + flipper_format_free(fff); furi_record_close(RECORD_STORAGE); } +void bad_kb_set_interface(BadKbApp* app, BadKbHidInterface interface) { + app->interface = interface; + bad_kb_view_set_interface(app->bad_kb_view, interface); +} + void bad_kb_app_show_loading_popup(BadKbApp* app, bool show) { if(show) { // Raise timer priority so that animations can play @@ -151,166 +191,6 @@ void bad_kb_app_show_loading_popup(BadKbApp* app, bool show) { } } -int32_t bad_kb_conn_apply(BadKbApp* app) { - if(app->is_bt) { - // Setup profile config - BadKbConfig* cfg = app->set_bt_id ? &app->id_config : &app->config; - memcpy(&app->cur_ble_cfg, &cfg->ble, sizeof(cfg->ble)); - if(app->cur_ble_cfg.bonding) { - // Hardcode mac for remember mode - // Change in config copy to preserve user choice for non-remember mode - memcpy(app->cur_ble_cfg.mac, BAD_KB_BOUND_MAC, sizeof(BAD_KB_BOUND_MAC)); - } - - // Prepare for new profile - bt_timeout = bt_hid_delays[LevelRssi39_0]; - bt_disconnect(app->bt); - furi_delay_ms(200); - bt_keys_storage_set_storage_path(app->bt, BAD_KB_KEYS_PATH); - - // Set profile - app->ble_hid = bt_profile_start(app->bt, ble_profile_hid, &app->cur_ble_cfg); - furi_check(app->ble_hid); - - // Advertise even if BT is off in settings - furi_hal_bt_start_advertising(); - - app->conn_mode = BadKbConnModeBt; - - } else { - // Unlock RPC connections - furi_hal_usb_unlock(); - - // Context will apply with set_config only if pointer address is different, so we use a copy - FuriHalUsbHidConfig* cur_usb_cfg = malloc(sizeof(FuriHalUsbHidConfig)); - - // Setup new config - BadKbConfig* cfg = app->set_usb_id ? &app->id_config : &app->config; - memcpy(cur_usb_cfg, &cfg->usb, sizeof(cfg->usb)); - - // Set profile - furi_check(furi_hal_usb_set_config(&usb_hid, cur_usb_cfg)); - if(app->cur_usb_cfg) free(app->cur_usb_cfg); - app->cur_usb_cfg = cur_usb_cfg; - - app->conn_mode = BadKbConnModeUsb; - } - - return 0; -} - -void bad_kb_conn_reset(BadKbApp* app) { - if(app->conn_mode == BadKbConnModeBt) { - bt_disconnect(app->bt); - furi_delay_ms(200); - bt_keys_storage_set_default_path(app->bt); - furi_check(bt_profile_restore_default(app->bt)); - } else if(app->conn_mode == BadKbConnModeUsb) { - // TODO: maybe also restore USB context? - furi_check(furi_hal_usb_set_config(app->prev_usb_mode, NULL)); - } - - app->conn_mode = BadKbConnModeNone; -} - -void bad_kb_config_adjust(BadKbConfig* cfg) { - // Avoid empty name - if(cfg->ble.name[0] == '\0') { - snprintf( - cfg->ble.name, sizeof(cfg->ble.name), "Control %s", furi_hal_version_get_name_ptr()); - } - - const uint8_t* normal_mac = furi_hal_version_get_ble_mac(); - uint8_t empty_mac[sizeof(cfg->ble.mac)] = {0}; - uint8_t default_mac[sizeof(cfg->ble.mac)] = {0x6c, 0x7a, 0xd8, 0xac, 0x57, 0x72}; //furi_hal_bt - if(memcmp(cfg->ble.mac, empty_mac, sizeof(cfg->ble.mac)) == 0 || - memcmp(cfg->ble.mac, normal_mac, sizeof(cfg->ble.mac)) == 0 || - memcmp(cfg->ble.mac, default_mac, sizeof(cfg->ble.mac)) == 0) { - memcpy(cfg->ble.mac, normal_mac, sizeof(cfg->ble.mac)); - cfg->ble.mac[2]++; - } - - // Use defaults if vid or pid are unset - if(cfg->usb.vid == 0) cfg->usb.vid = HID_VID_DEFAULT; - if(cfg->usb.pid == 0) cfg->usb.pid = HID_PID_DEFAULT; -} - -void bad_kb_config_refresh(BadKbApp* app) { - bt_set_status_changed_callback(app->bt, NULL, NULL); - furi_hal_hid_set_state_callback(NULL, NULL); - if(app->bad_kb_script) { - furi_thread_flags_set(furi_thread_get_id(app->bad_kb_script->thread), WorkerEvtDisconnect); - } - if(app->conn_init_thread) { - furi_thread_join(app->conn_init_thread); - } - - bool apply = false; - if(app->is_bt) { - BadKbConfig* cfg = app->set_bt_id ? &app->id_config : &app->config; - bad_kb_config_adjust(cfg); - - if(app->conn_mode != BadKbConnModeBt) { - apply = true; - bad_kb_conn_reset(app); - } else { - BleProfileHidParams* cur = &app->cur_ble_cfg; - apply = apply || cfg->ble.bonding != cur->bonding; - apply = apply || cfg->ble.pairing != cur->pairing; - apply = apply || strncmp(cfg->ble.name, cur->name, sizeof(cfg->ble.name)); - apply = apply || memcmp(cfg->ble.mac, cur->mac, sizeof(cfg->ble.mac)); - } - } else { - BadKbConfig* cfg = app->set_usb_id ? &app->id_config : &app->config; - bad_kb_config_adjust(cfg); - - if(app->conn_mode != BadKbConnModeUsb) { - apply = true; - bad_kb_conn_reset(app); - } else { - FuriHalUsbHidConfig* cur = app->cur_usb_cfg; - apply = apply || cfg->usb.vid != cur->vid; - apply = apply || cfg->usb.pid != cur->pid; - apply = apply || strncmp(cfg->usb.manuf, cur->manuf, sizeof(cur->manuf)); - apply = apply || strncmp(cfg->usb.product, cur->product, sizeof(cur->product)); - } - } - - if(apply) { - bad_kb_conn_apply(app); - } - - if(app->bad_kb_script) { - BadKbScript* script = app->bad_kb_script; - script->st.is_bt = app->is_bt; - script->bt = app->is_bt ? app->bt : NULL; - bool connected; - if(app->is_bt) { - bt_set_status_changed_callback(app->bt, bad_kb_bt_hid_state_callback, script); - connected = furi_hal_bt_is_connected(); - } else { - furi_hal_hid_set_state_callback(bad_kb_usb_hid_state_callback, script); - connected = furi_hal_hid_is_connected(); - } - if(connected) { - furi_thread_flags_set(furi_thread_get_id(script->thread), WorkerEvtConnect); - } - } - - // Reload config page - scene_manager_next_scene(app->scene_manager, BadKbSceneConfig); - scene_manager_previous_scene(app->scene_manager); -} - -void reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]) { - uint8_t tmp; - for(size_t i = 0; i < GAP_MAC_ADDR_SIZE / 2; i++) { - tmp = mac_addr[i]; - mac_addr[i] = mac_addr[GAP_MAC_ADDR_SIZE - 1 - i]; - mac_addr[GAP_MAC_ADDR_SIZE - 1 - i] = tmp; - } -} - BadKbApp* bad_kb_app_alloc(char* arg) { BadKbApp* app = malloc(sizeof(BadKbApp)); @@ -329,7 +209,6 @@ BadKbApp* bad_kb_app_alloc(char* arg) { app->dialogs = furi_record_open(RECORD_DIALOGS); app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&bad_kb_scene_handlers, app); view_dispatcher_set_event_callback_context(app->view_dispatcher, app); @@ -340,28 +219,18 @@ BadKbApp* bad_kb_app_alloc(char* arg) { view_dispatcher_set_navigation_event_callback( app->view_dispatcher, bad_kb_app_back_event_callback); - Bt* bt = furi_record_open(RECORD_BT); - app->bt = bt; - app->bt->suppress_pin_screen = true; - bad_kb_config_adjust(&app->config); - - // Save prev config - app->prev_usb_mode = furi_hal_usb_get_config(); - - // Adjust BT remember MAC to be serial MAC +2 - memcpy(BAD_KB_BOUND_MAC, furi_hal_version_get_ble_mac(), sizeof(BAD_KB_BOUND_MAC)); - BAD_KB_BOUND_MAC[2] += 2; - // Custom Widget app->widget = widget_alloc(); view_dispatcher_add_view( app->view_dispatcher, BadKbAppViewWidget, widget_get_view(app->widget)); + // Popup + app->popup = popup_alloc(); + view_dispatcher_add_view(app->view_dispatcher, BadKbAppViewPopup, popup_get_view(app->popup)); + app->var_item_list = variable_item_list_alloc(); view_dispatcher_add_view( - app->view_dispatcher, - BadKbAppViewVarItemList, - variable_item_list_get_view(app->var_item_list)); + app->view_dispatcher, BadKbAppViewConfig, variable_item_list_get_view(app->var_item_list)); app->bad_kb_view = bad_kb_view_alloc(); view_dispatcher_add_view( @@ -381,13 +250,8 @@ BadKbApp* bad_kb_app_alloc(char* arg) { view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - app->conn_mode = BadKbConnModeNone; - app->conn_init_thread = - furi_thread_alloc_ex("BadKbConnInit", 1024, (FuriThreadCallback)bad_kb_conn_apply, 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_set_keyboard_layout(app->bad_kb_script, app->keyboard_layout); + scene_manager_set_scene_state(app->scene_manager, BadKbSceneWork, true); scene_manager_next_scene(app->scene_manager, BadKbSceneWork); } else { furi_string_set(app->file_path, BAD_KB_APP_BASE_FOLDER); @@ -413,8 +277,12 @@ void bad_kb_app_free(BadKbApp* app) { view_dispatcher_remove_view(app->view_dispatcher, BadKbAppViewWidget); widget_free(app->widget); - // Variable item list - view_dispatcher_remove_view(app->view_dispatcher, BadKbAppViewVarItemList); + // Popup + view_dispatcher_remove_view(app->view_dispatcher, BadKbAppViewPopup); + popup_free(app->popup); + + // Config menu + view_dispatcher_remove_view(app->view_dispatcher, BadKbAppViewConfig); variable_item_list_free(app->var_item_list); // Text Input @@ -433,21 +301,10 @@ void bad_kb_app_free(BadKbApp* app) { view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); - // Restore connection config - app->bt->suppress_pin_screen = false; - if(app->conn_init_thread) { - furi_thread_join(app->conn_init_thread); - furi_thread_free(app->conn_init_thread); - app->conn_init_thread = NULL; - } - bad_kb_conn_reset(app); - if(app->cur_usb_cfg) free(app->cur_usb_cfg); - // Close records furi_record_close(RECORD_GUI); furi_record_close(RECORD_NOTIFICATION); furi_record_close(RECORD_DIALOGS); - furi_record_close(RECORD_BT); bad_kb_save_settings(app); diff --git a/applications/main/bad_kb/bad_kb_app_i.h b/applications/main/bad_kb/bad_kb_app_i.h index bc5f00ea4..97b6ff5bf 100644 --- a/applications/main/bad_kb/bad_kb_app_i.h +++ b/applications/main/bad_kb/bad_kb_app_i.h @@ -3,14 +3,12 @@ #include "bad_kb_app.h" #include "scenes/bad_kb_scene.h" #include "helpers/ducky_script.h" -#include "helpers/ble_hid.h" -#include "bad_kb_paths.h" +#include "helpers/bad_kb_hid.h" #include #include #include #include -#include #include #include #include @@ -18,35 +16,19 @@ #include #include #include +#include #include "views/bad_kb_view.h" #include -#define BAD_KB_APP_SCRIPT_EXTENSION ".txt" -#define BAD_KB_APP_LAYOUT_EXTENSION ".kl" - -extern uint8_t BAD_KB_BOUND_MAC[GAP_MAC_ADDR_SIZE]; // For remember mode - -typedef enum BadKbCustomEvent { - BadKbAppCustomEventTextInputDone, - BadKbAppCustomEventByteInputDone, - BadKbCustomEventErrorBack -} BadKbCustomEvent; +#define BAD_KB_APP_BASE_FOLDER EXT_PATH("badusb") +#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" typedef enum { BadKbAppErrorNoFiles, } BadKbAppError; -typedef struct { - BleProfileHidParams ble; - FuriHalUsbHidConfig usb; -} BadKbConfig; - -typedef enum { - BadKbConnModeNone, - BadKbConnModeUsb, - BadKbConnModeBt, -} BadKbConnMode; - struct BadKbApp { Gui* gui; ViewDispatcher* view_dispatcher; @@ -54,13 +36,14 @@ struct BadKbApp { NotificationApp* notifications; DialogsApp* dialogs; Widget* widget; + Popup* popup; VariableItemList* var_item_list; TextInput* text_input; ByteInput* byte_input; Loading* loading; - char bt_name_buf[FURI_HAL_BT_ADV_NAME_LENGTH]; - uint8_t bt_mac_buf[GAP_MAC_ADDR_SIZE]; + char ble_name_buf[FURI_HAL_BT_ADV_NAME_LENGTH]; + uint8_t ble_mac_buf[GAP_MAC_ADDR_SIZE]; char usb_name_buf[HID_MANUF_PRODUCT_NAME_LEN]; uint16_t usb_vidpid_buf[2]; @@ -70,45 +53,21 @@ struct BadKbApp { BadKb* bad_kb_view; BadKbScript* bad_kb_script; - Bt* bt; - bool is_bt; - BadKbConfig config; // User options - BadKbConfig id_config; // ID and BT_ID values - - bool set_bt_id; - bool set_usb_id; - bool has_bt_id; - bool has_usb_id; - - FuriHalBleProfileBase* ble_hid; - FuriHalUsbInterface* prev_usb_mode; - - BleProfileHidParams cur_ble_cfg; - FuriHalUsbHidConfig* cur_usb_cfg; - - BadKbConnMode conn_mode; - FuriThread* conn_init_thread; + BadKbHidInterface interface; + BadKbHidConfig user_hid_cfg; + BadKbHidConfig script_hid_cfg; }; typedef enum { BadKbAppViewWidget, + BadKbAppViewPopup, BadKbAppViewWork, - BadKbAppViewVarItemList, + BadKbAppViewConfig, BadKbAppViewByteInput, BadKbAppViewTextInput, BadKbAppViewLoading, } BadKbAppView; +void bad_kb_set_interface(BadKbApp* app, BadKbHidInterface interface); + void bad_kb_app_show_loading_popup(BadKbApp* app, bool show); - -void bad_kb_load_settings(BadKbApp* app); - -int32_t bad_kb_conn_apply(BadKbApp* app); - -void bad_kb_conn_reset(BadKbApp* app); - -void bad_kb_config_refresh(BadKbApp* app); - -void bad_kb_config_adjust(BadKbConfig* cfg); - -void reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]); diff --git a/applications/main/bad_kb/bad_kb_paths.h b/applications/main/bad_kb/bad_kb_paths.h deleted file mode 100644 index ff569f015..000000000 --- a/applications/main/bad_kb/bad_kb_paths.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include - -#define BAD_KB_APP_BASE_FOLDER EXT_PATH("badusb") -#define BAD_KB_KEYS_PATH BAD_KB_APP_BASE_FOLDER "/.badkb.keys" -#define BAD_KB_SETTINGS_PATH BAD_KB_APP_BASE_FOLDER "/.badkb.settings" -#define BAD_KB_APP_PATH_LAYOUT_FOLDER BAD_KB_APP_BASE_FOLDER "/assets/layouts" diff --git a/applications/main/bad_kb/helpers/bad_kb_hid.c b/applications/main/bad_kb/helpers/bad_kb_hid.c new file mode 100644 index 000000000..067ad0d65 --- /dev/null +++ b/applications/main/bad_kb/helpers/bad_kb_hid.c @@ -0,0 +1,321 @@ +#include "bad_kb_hid.h" +#include "ble_hid_profile.h" +#include +#include +#include + +#define TAG "BadKB HID" + +#define HID_BT_KEYS_STORAGE_NAME ".bt_hid.keys" + +void hid_usb_adjust_config(BadKbHidConfig* hid_cfg) { + if(hid_cfg->usb.vid == 0) hid_cfg->usb.vid = HID_VID_DEFAULT; + if(hid_cfg->usb.pid == 0) hid_cfg->usb.pid = HID_PID_DEFAULT; +} + +void* hid_usb_init(BadKbHidConfig* hid_cfg) { + FuriHalUsbInterface* usb_if_prev = furi_hal_usb_get_config(); + furi_hal_usb_unlock(); + hid_usb_adjust_config(hid_cfg); + furi_check(furi_hal_usb_set_config(&usb_hid, &hid_cfg->usb)); + return usb_if_prev; +} + +void hid_usb_deinit(void* inst) { + FuriHalUsbInterface* usb_if_prev = inst; + furi_check(furi_hal_usb_set_config(usb_if_prev, NULL)); +} + +void hid_usb_set_state_callback(void* inst, HidStateCallback cb, void* context) { + UNUSED(inst); + furi_hal_hid_set_state_callback(cb, context); +} + +bool hid_usb_is_connected(void* inst) { + UNUSED(inst); + return furi_hal_hid_is_connected(); +} + +bool hid_usb_kb_press(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_kb_press(button); +} + +bool hid_usb_kb_release(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_kb_release(button); +} + +bool hid_usb_mouse_press(void* inst, uint8_t button) { + UNUSED(inst); + return furi_hal_hid_mouse_press(button); +} + +bool hid_usb_mouse_release(void* inst, uint8_t button) { + UNUSED(inst); + return furi_hal_hid_mouse_release(button); +} + +bool hid_usb_mouse_scroll(void* inst, int8_t delta) { + UNUSED(inst); + return furi_hal_hid_mouse_scroll(delta); +} + +bool hid_usb_mouse_move(void* inst, int8_t dx, int8_t dy) { + UNUSED(inst); + return furi_hal_hid_mouse_move(dx, dy); +} + +bool hid_usb_mouse_release_all(void* inst) { + UNUSED(inst); + return furi_hal_hid_mouse_release(0); +} + +bool hid_usb_consumer_press(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_consumer_key_press(button); +} + +bool hid_usb_consumer_release(void* inst, uint16_t button) { + UNUSED(inst); + return furi_hal_hid_consumer_key_release(button); +} + +bool hid_usb_release_all(void* inst) { + UNUSED(inst); + bool state = furi_hal_hid_kb_release_all(); + state &= furi_hal_hid_consumer_key_release_all(); + state &= hid_usb_mouse_release_all(inst); + return state; +} + +uint8_t hid_usb_get_led_state(void* inst) { + UNUSED(inst); + return furi_hal_hid_get_led_state(); +} + +static const BadKbHidApi hid_api_usb = { + .adjust_config = hid_usb_adjust_config, + .init = hid_usb_init, + .deinit = hid_usb_deinit, + .set_state_callback = hid_usb_set_state_callback, + .is_connected = hid_usb_is_connected, + + .kb_press = hid_usb_kb_press, + .kb_release = hid_usb_kb_release, + .mouse_press = hid_usb_mouse_press, + .mouse_release = hid_usb_mouse_release, + .mouse_scroll = hid_usb_mouse_scroll, + .mouse_move = hid_usb_mouse_move, + .consumer_press = hid_usb_consumer_press, + .consumer_release = hid_usb_consumer_release, + .release_all = hid_usb_release_all, + .get_led_state = hid_usb_get_led_state, +}; + +typedef struct { + Bt* bt; + FuriHalBleProfileBase* profile; + HidStateCallback state_callback; + void* callback_context; + bool is_connected; +} BleHidInstance; + +static void hid_ble_connection_status_callback(BtStatus status, void* context) { + furi_assert(context); + BleHidInstance* ble_hid = context; + ble_hid->is_connected = (status == BtStatusConnected); + if(ble_hid->state_callback) { + ble_hid->state_callback(ble_hid->is_connected, ble_hid->callback_context); + } +} + +void hid_ble_adjust_config(BadKbHidConfig* hid_cfg) { + const uint8_t* normal_mac = furi_hal_version_get_ble_mac(); + uint8_t empty_mac[GAP_MAC_ADDR_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + uint8_t default_mac[GAP_MAC_ADDR_SIZE] = {0x6c, 0x7a, 0xd8, 0xac, 0x57, 0x72}; // furi_hal_bt + if(memcmp(hid_cfg->ble.mac, empty_mac, sizeof(hid_cfg->ble.mac)) == 0 || + memcmp(hid_cfg->ble.mac, normal_mac, sizeof(hid_cfg->ble.mac)) == 0 || + memcmp(hid_cfg->ble.mac, default_mac, sizeof(hid_cfg->ble.mac)) == 0) { + // Derive badkb MAC from Flipper MAC + memcpy(hid_cfg->ble.mac, normal_mac, sizeof(hid_cfg->ble.mac)); + hid_cfg->ble.mac[2]++; + uint16_t badkb_mac_xor = 0x0002; + hid_cfg->ble.mac[0] ^= badkb_mac_xor; + hid_cfg->ble.mac[1] ^= badkb_mac_xor >> 8; + } + + if(hid_cfg->ble.name[0] == '\0') { + // Derive badkb name from Flipper name + const char* badkb_device_name_prefix = "BadKB"; + snprintf( + hid_cfg->ble.name, + sizeof(hid_cfg->ble.name), + "%s %s", + badkb_device_name_prefix, + furi_hal_version_get_name_ptr()); + } + + if(hid_cfg->ble.pairing >= GapPairingCount) { + hid_cfg->ble.pairing = GapPairingPinCodeVerifyYesNo; + } +} + +void* hid_ble_init(BadKbHidConfig* hid_cfg) { + BleHidInstance* ble_hid = malloc(sizeof(BleHidInstance)); + ble_hid->bt = furi_record_open(RECORD_BT); + ble_hid->bt->suppress_pin_screen = true; + bt_disconnect(ble_hid->bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + + bt_keys_storage_set_storage_path(ble_hid->bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME)); + + hid_ble_adjust_config(hid_cfg); + ble_hid->profile = bt_profile_start(ble_hid->bt, ble_profile_hid, &hid_cfg->ble); + furi_check(ble_hid->profile); + + furi_hal_bt_start_advertising(); + + bt_set_status_changed_callback(ble_hid->bt, hid_ble_connection_status_callback, ble_hid); + + return ble_hid; +} + +void hid_ble_deinit(void* inst) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + + bt_set_status_changed_callback(ble_hid->bt, NULL, NULL); + bt_disconnect(ble_hid->bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + bt_keys_storage_set_default_path(ble_hid->bt); + + furi_check(bt_profile_restore_default(ble_hid->bt)); + ble_hid->bt->suppress_pin_screen = false; + furi_record_close(RECORD_BT); + free(ble_hid); +} + +void hid_ble_set_state_callback(void* inst, HidStateCallback cb, void* context) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + ble_hid->state_callback = cb; + ble_hid->callback_context = context; +} + +bool hid_ble_is_connected(void* inst) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_hid->is_connected; +} + +bool hid_ble_kb_press(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_kb_press(ble_hid->profile, button); +} + +bool hid_ble_kb_release(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_kb_release(ble_hid->profile, button); +} + +bool hid_ble_mouse_press(void* inst, uint8_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_mouse_press(ble_hid->profile, button); +} +bool hid_ble_mouse_release(void* inst, uint8_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_mouse_release(ble_hid->profile, button); +} +bool hid_ble_mouse_scroll(void* inst, int8_t delta) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_mouse_scroll(ble_hid->profile, delta); +} +bool hid_ble_mouse_move(void* inst, int8_t dx, int8_t dy) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_mouse_move(ble_hid->profile, dx, dy); +} + +bool hid_ble_consumer_press(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_consumer_key_press(ble_hid->profile, button); +} + +bool hid_ble_consumer_release(void* inst, uint16_t button) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + return ble_profile_hid_consumer_key_release(ble_hid->profile, button); +} + +bool hid_ble_release_all(void* inst) { + BleHidInstance* ble_hid = inst; + furi_assert(ble_hid); + bool state = ble_profile_hid_kb_release_all(ble_hid->profile); + state &= ble_profile_hid_consumer_key_release_all(ble_hid->profile); + state &= ble_profile_hid_mouse_release_all(ble_hid->profile); + return state; +} + +uint8_t hid_ble_get_led_state(void* inst) { + UNUSED(inst); + FURI_LOG_W(TAG, "hid_ble_get_led_state not implemented"); + return 0; +} + +static const BadKbHidApi hid_api_ble = { + .adjust_config = hid_ble_adjust_config, + .init = hid_ble_init, + .deinit = hid_ble_deinit, + .set_state_callback = hid_ble_set_state_callback, + .is_connected = hid_ble_is_connected, + + .kb_press = hid_ble_kb_press, + .kb_release = hid_ble_kb_release, + .mouse_press = hid_ble_mouse_press, + .mouse_release = hid_ble_mouse_release, + .mouse_scroll = hid_ble_mouse_scroll, + .mouse_move = hid_ble_mouse_move, + .consumer_press = hid_ble_consumer_press, + .consumer_release = hid_ble_consumer_release, + .release_all = hid_ble_release_all, + .get_led_state = hid_ble_get_led_state, +}; + +const BadKbHidApi* bad_kb_hid_get_interface(BadKbHidInterface interface) { + if(interface == BadKbHidInterfaceUsb) { + return &hid_api_usb; + } else { + return &hid_api_ble; + } +} + +void bad_kb_hid_ble_remove_pairing(void) { + Bt* bt = furi_record_open(RECORD_BT); + bt_disconnect(bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + + furi_hal_bt_stop_advertising(); + + bt_keys_storage_set_storage_path(bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME)); + bt_forget_bonded_devices(bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + bt_keys_storage_set_default_path(bt); + + furi_check(bt_profile_restore_default(bt)); + furi_record_close(RECORD_BT); +} diff --git a/applications/main/bad_kb/helpers/bad_kb_hid.h b/applications/main/bad_kb/helpers/bad_kb_hid.h new file mode 100644 index 000000000..39eee30f9 --- /dev/null +++ b/applications/main/bad_kb/helpers/bad_kb_hid.h @@ -0,0 +1,48 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "ble_hid_profile.h" + +typedef enum { + BadKbHidInterfaceUsb, + BadKbHidInterfaceBle, + BadKbHidInterfaceMAX, +} BadKbHidInterface; + +typedef struct { + BleProfileHidParams ble; + FuriHalUsbHidConfig usb; +} BadKbHidConfig; + +typedef struct { + void (*adjust_config)(BadKbHidConfig* hid_cfg); + void* (*init)(BadKbHidConfig* hid_cfg); + void (*deinit)(void* inst); + void (*set_state_callback)(void* inst, HidStateCallback cb, void* context); + bool (*is_connected)(void* inst); + + bool (*kb_press)(void* inst, uint16_t button); + bool (*kb_release)(void* inst, uint16_t button); + bool (*mouse_press)(void* inst, uint8_t button); + bool (*mouse_release)(void* inst, uint8_t button); + bool (*mouse_scroll)(void* inst, int8_t delta); + bool (*mouse_move)(void* inst, int8_t dx, int8_t dy); + bool (*consumer_press)(void* inst, uint16_t button); + bool (*consumer_release)(void* inst, uint16_t button); + bool (*release_all)(void* inst); + uint8_t (*get_led_state)(void* inst); +} BadKbHidApi; + +const BadKbHidApi* bad_kb_hid_get_interface(BadKbHidInterface interface); + +void bad_kb_hid_ble_remove_pairing(void); + +#ifdef __cplusplus +} +#endif diff --git a/applications/main/bad_kb/helpers/ble_hid.c b/applications/main/bad_kb/helpers/ble_hid_profile.c similarity index 98% rename from applications/main/bad_kb/helpers/ble_hid.c rename to applications/main/bad_kb/helpers/ble_hid_profile.c index 2f6dd8c2a..7b9b2e06f 100644 --- a/applications/main/bad_kb/helpers/ble_hid.c +++ b/applications/main/bad_kb/helpers/ble_hid_profile.c @@ -1,9 +1,11 @@ -#include "ble_hid.h" +#include "ble_hid_profile.h" + +// Based on #include #include #include -#include "ble_hid_svc.h" +#include "ble_hid_service.h" #include #include @@ -394,12 +396,13 @@ static GapConfig template_config = { }; static void ble_profile_hid_get_config(GapConfig* config, FuriHalBleProfileParams profile_params) { + furi_check(profile_params); BleProfileHidParams* hid_profile_params = profile_params; furi_check(config); memcpy(config, &template_config, sizeof(GapConfig)); - // Set mac address + // Set MAC address memcpy(config->mac_address, hid_profile_params->mac, sizeof(config->mac_address)); // Set advertise name diff --git a/applications/main/bad_kb/helpers/ble_hid.h b/applications/main/bad_kb/helpers/ble_hid_profile.h similarity index 98% rename from applications/main/bad_kb/helpers/ble_hid.h rename to applications/main/bad_kb/helpers/ble_hid_profile.h index 717625354..2302aa581 100644 --- a/applications/main/bad_kb/helpers/ble_hid.h +++ b/applications/main/bad_kb/helpers/ble_hid_profile.h @@ -1,5 +1,7 @@ #pragma once +// Based on + #include #ifdef __cplusplus diff --git a/applications/main/bad_kb/helpers/ble_hid_svc.c b/applications/main/bad_kb/helpers/ble_hid_service.c similarity index 98% rename from applications/main/bad_kb/helpers/ble_hid_svc.c rename to applications/main/bad_kb/helpers/ble_hid_service.c index 024e25a78..b546368dd 100644 --- a/applications/main/bad_kb/helpers/ble_hid_svc.c +++ b/applications/main/bad_kb/helpers/ble_hid_service.c @@ -1,5 +1,8 @@ -#include "ble_hid_svc.h" -#include "app_common.h" +#include "ble_hid_service.h" + +// Based on + +#include "app_common.h" // IWYU pragma: keep #include #include #include @@ -170,7 +173,7 @@ static BleEventAckStatus ble_svc_hid_event_handler(void* event, void* context) { return ret; } -BleServiceHid* ble_svc_hid_start() { +BleServiceHid* ble_svc_hid_start(void) { BleServiceHid* hid_svc = malloc(sizeof(BleServiceHid)); // Register event handler diff --git a/applications/main/bad_kb/helpers/ble_hid_svc.h b/applications/main/bad_kb/helpers/ble_hid_service.h similarity index 85% rename from applications/main/bad_kb/helpers/ble_hid_svc.h rename to applications/main/bad_kb/helpers/ble_hid_service.h index c6e3059cd..e1ac3b0be 100644 --- a/applications/main/bad_kb/helpers/ble_hid_svc.h +++ b/applications/main/bad_kb/helpers/ble_hid_service.h @@ -1,5 +1,7 @@ #pragma once +// Based on + #include #include @@ -9,7 +11,7 @@ extern "C" { typedef struct BleServiceHid BleServiceHid; -BleServiceHid* ble_svc_hid_start(); +BleServiceHid* ble_svc_hid_start(void); void ble_svc_hid_stop(BleServiceHid* service); diff --git a/applications/main/bad_kb/helpers/ducky_script.c b/applications/main/bad_kb/helpers/ducky_script.c index 64b78d9eb..e226093b7 100644 --- a/applications/main/bad_kb/helpers/ducky_script.c +++ b/applications/main/bad_kb/helpers/ducky_script.c @@ -1,17 +1,13 @@ -#include "../bad_kb_app_i.h" #include #include #include #include #include #include -#include -#include "ble_hid.h" #include #include "ducky_script.h" #include "ducky_script_i.h" #include -#include #define TAG "BadKb" @@ -20,46 +16,17 @@ #define BADKB_ASCII_TO_KEY(script, x) \ (((uint8_t)x < 128) ? (script->layout[(uint8_t)x]) : HID_KEYBOARD_NONE) -// Delays for waiting between HID key press and key release -const uint8_t bt_hid_delays[LevelRssiNum] = { - 60, // LevelRssi122_100 - 55, // LevelRssi99_80 - 50, // LevelRssi79_60 - 47, // LevelRssi59_40 - 34, // LevelRssi39_0 -}; - -uint8_t bt_timeout = 0; - -static LevelRssiRange bt_remote_rssi_range(Bt* bt) { - uint8_t rssi; - - if(!bt_remote_rssi(bt, &rssi)) return LevelRssiError; - - if(rssi <= 39) - return LevelRssi39_0; - else if(rssi <= 59) - return LevelRssi59_40; - else if(rssi <= 79) - return LevelRssi79_60; - else if(rssi <= 99) - return LevelRssi99_80; - else if(rssi <= 122) - return LevelRssi122_100; - - return LevelRssiError; -} - -static inline void update_bt_timeout(Bt* bt) { - LevelRssiRange r = bt_remote_rssi_range(bt); - if(r < LevelRssiNum) { - bt_timeout = bt_hid_delays[r]; - FURI_LOG_D(WORKER_TAG, "BLE Key timeout : %u", bt_timeout); - } -} +typedef enum { + WorkerEvtStartStop = (1 << 0), + WorkerEvtPauseResume = (1 << 1), + WorkerEvtEnd = (1 << 2), + WorkerEvtConnect = (1 << 3), + WorkerEvtDisconnect = (1 << 4), +} WorkerEvtFlags; static const char ducky_cmd_id[] = {"ID"}; static const char ducky_cmd_bt_id[] = {"BT_ID"}; +static const char ducky_cmd_ble_id[] = {"BLE_ID"}; static const uint8_t numpad_keys[10] = { HID_KEYPAD_0, @@ -83,7 +50,7 @@ uint32_t ducky_get_command_len(const char* line) { } bool ducky_is_line_end(const char chr) { - return ((chr == ' ') || (chr == '\0') || (chr == '\r') || (chr == '\n')); + return (chr == ' ') || (chr == '\0') || (chr == '\r') || (chr == '\n'); } uint16_t ducky_get_keycode(BadKbScript* bad_kb, const char* param, bool accept_chars) { @@ -93,7 +60,7 @@ uint16_t ducky_get_keycode(BadKbScript* bad_kb, const char* param, bool accept_c } if((accept_chars) && (strlen(param) > 0)) { - return (BADKB_ASCII_TO_KEY(bad_kb, param[0]) & 0xFF); + return BADKB_ASCII_TO_KEY(bad_kb, param[0]) & 0xFF; } return 0; } @@ -107,23 +74,10 @@ bool ducky_get_number(const char* param, uint32_t* val) { return false; } -uint8_t furi_hal_bt_hid_get_led_state() { - // FIXME - return 0; -} - void ducky_numlock_on(BadKbScript* bad_kb) { - if(bad_kb->bt) { - if((furi_hal_bt_hid_get_led_state() & HID_KB_LED_NUM) == 0) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, HID_KEYBOARD_LOCK_NUM_LOCK); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release(bad_kb->app->ble_hid, HID_KEYBOARD_LOCK_NUM_LOCK); - } - } else { - if((furi_hal_hid_get_led_state() & HID_KB_LED_NUM) == 0) { - furi_hal_hid_kb_press(HID_KEYBOARD_LOCK_NUM_LOCK); - furi_hal_hid_kb_release(HID_KEYBOARD_LOCK_NUM_LOCK); - } + if((bad_kb->hid->get_led_state(bad_kb->hid_inst) & HID_KB_LED_NUM) == 0) { + bad_kb->hid->kb_press(bad_kb->hid_inst, HID_KEYBOARD_LOCK_NUM_LOCK); + bad_kb->hid->kb_release(bad_kb->hid_inst, HID_KEYBOARD_LOCK_NUM_LOCK); } } @@ -131,14 +85,8 @@ bool ducky_numpad_press(BadKbScript* bad_kb, const char num) { if((num < '0') || (num > '9')) return false; uint16_t key = numpad_keys[num - '0']; - if(bad_kb->bt) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, key); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release(bad_kb->app->ble_hid, key); - } else { - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release(key); - } + bad_kb->hid->kb_press(bad_kb->hid_inst, key); + bad_kb->hid->kb_release(bad_kb->hid_inst, key); return true; } @@ -147,11 +95,7 @@ bool ducky_altchar(BadKbScript* bad_kb, const char* charcode) { uint8_t i = 0; bool state = false; - if(bad_kb->bt) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, KEY_MOD_LEFT_ALT); - } else { - furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT); - } + bad_kb->hid->kb_press(bad_kb->hid_inst, KEY_MOD_LEFT_ALT); while(!ducky_is_line_end(charcode[i])) { state = ducky_numpad_press(bad_kb, charcode[i]); @@ -159,11 +103,7 @@ bool ducky_altchar(BadKbScript* bad_kb, const char* charcode) { i++; } - if(bad_kb->bt) { - ble_profile_hid_kb_release(bad_kb->app->ble_hid, KEY_MOD_LEFT_ALT); - } else { - furi_hal_hid_kb_release(KEY_MOD_LEFT_ALT); - } + bad_kb->hid->kb_release(bad_kb->hid_inst, KEY_MOD_LEFT_ALT); return state; } @@ -204,24 +144,12 @@ bool ducky_string(BadKbScript* bad_kb, const char* param) { if(param[i] != '\n') { uint16_t keycode = BADKB_ASCII_TO_KEY(bad_kb, param[i]); if(keycode != HID_KEYBOARD_NONE) { - if(bad_kb->bt) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, keycode); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release(bad_kb->app->ble_hid, keycode); - } else { - furi_hal_hid_kb_press(keycode); - furi_hal_hid_kb_release(keycode); - } + bad_kb->hid->kb_press(bad_kb->hid_inst, keycode); + bad_kb->hid->kb_release(bad_kb->hid_inst, keycode); } } else { - if(bad_kb->bt) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, HID_KEYBOARD_RETURN); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release(bad_kb->app->ble_hid, HID_KEYBOARD_RETURN); - } else { - furi_hal_hid_kb_press(HID_KEYBOARD_RETURN); - furi_hal_hid_kb_release(HID_KEYBOARD_RETURN); - } + bad_kb->hid->kb_press(bad_kb->hid_inst, HID_KEYBOARD_RETURN); + bad_kb->hid->kb_release(bad_kb->hid_inst, HID_KEYBOARD_RETURN); } i++; } @@ -239,24 +167,12 @@ static bool ducky_string_next(BadKbScript* bad_kb) { if(print_char != '\n') { uint16_t keycode = BADKB_ASCII_TO_KEY(bad_kb, print_char); if(keycode != HID_KEYBOARD_NONE) { - if(bad_kb->bt) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, keycode); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release(bad_kb->app->ble_hid, keycode); - } else { - furi_hal_hid_kb_press(keycode); - furi_hal_hid_kb_release(keycode); - } + bad_kb->hid->kb_press(bad_kb->hid_inst, keycode); + bad_kb->hid->kb_release(bad_kb->hid_inst, keycode); } } else { - if(bad_kb->bt) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, HID_KEYBOARD_RETURN); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release(bad_kb->app->ble_hid, HID_KEYBOARD_RETURN); - } else { - furi_hal_hid_kb_press(HID_KEYBOARD_RETURN); - furi_hal_hid_kb_release(HID_KEYBOARD_RETURN); - } + bad_kb->hid->kb_press(bad_kb->hid_inst, HID_KEYBOARD_RETURN); + bad_kb->hid->kb_release(bad_kb->hid_inst, HID_KEYBOARD_RETURN); } bad_kb->string_print_pos++; @@ -279,8 +195,16 @@ static int32_t ducky_parse_line(BadKbScript* bad_kb, FuriString* line) { return cmd_result; } + // Mouse Keys + uint16_t key = ducky_get_mouse_keycode_by_name(line_tmp); + if(key != HID_MOUSE_INVALID) { + bad_kb->hid->mouse_press(bad_kb->hid_inst, key); + bad_kb->hid->mouse_release(bad_kb->hid_inst, key); + return 0; + } + // Special keys + modifiers - uint16_t key = ducky_get_keycode(bad_kb, line_tmp, false); + key = ducky_get_keycode(bad_kb, line_tmp, false); if(key == HID_KEYBOARD_NONE) { return ducky_error(bad_kb, "No keycode defined for %s", line_tmp); } @@ -290,71 +214,73 @@ static int32_t ducky_parse_line(BadKbScript* bad_kb, FuriString* line) { // ducky_get_command_len() returns 0 without space, so check for != 1 if(offset != 1 && line_len > offset) { // It's also a key combination - key |= ducky_get_keycode(bad_kb, line_tmp + offset, true); + line_tmp = &line_tmp[offset]; + key |= ducky_get_keycode(bad_kb, line_tmp, true); } } - if(bad_kb->bt) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, key); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release(bad_kb->app->ble_hid, key); - } else { - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release(key); - } + bad_kb->hid->kb_press(bad_kb->hid_inst, key); + bad_kb->hid->kb_release(bad_kb->hid_inst, key); return 0; } static bool ducky_set_usb_id(BadKbScript* bad_kb, const char* line) { - FuriHalUsbHidConfig* cfg = &bad_kb->app->id_config.usb; + FuriHalUsbHidConfig* usb_hid_cfg = &bad_kb->hid_cfg->usb; - if(sscanf(line, "%lX:%lX", &cfg->vid, &cfg->pid) == 2) { - cfg->manuf[0] = '\0'; - cfg->product[0] = '\0'; + if(sscanf(line, "%lX:%lX", &usb_hid_cfg->vid, &usb_hid_cfg->pid) == 2) { + usb_hid_cfg->manuf[0] = '\0'; + usb_hid_cfg->product[0] = '\0'; uint8_t id_len = ducky_get_command_len(line); if(!ducky_is_line_end(line[id_len + 1])) { - sscanf(&line[id_len + 1], "%31[^\r\n:]:%31[^\r\n]", cfg->manuf, cfg->product); + sscanf( + &line[id_len + 1], + "%31[^\r\n:]:%31[^\r\n]", + usb_hid_cfg->manuf, + usb_hid_cfg->product); } FURI_LOG_D( WORKER_TAG, - "set usb id: %04lX:%04lX mfr:%s product:%s", - cfg->vid, - cfg->pid, - cfg->manuf, - cfg->product); + "set id: %04lX:%04lX mfr:%s product:%s", + usb_hid_cfg->vid, + usb_hid_cfg->pid, + usb_hid_cfg->manuf, + usb_hid_cfg->product); return true; } return false; } -static bool ducky_set_bt_id(BadKbScript* bad_kb, const char* line) { - BadKbConfig* cfg = &bad_kb->app->id_config; +static bool ducky_set_ble_id(BadKbScript* bad_kb, const char* line) { + BleProfileHidParams* ble_hid_cfg = &bad_kb->hid_cfg->ble; size_t line_len = strlen(line); - size_t mac_len = sizeof(cfg->ble.mac) * 3; // 2 text chars + separator per byte + size_t mac_len = sizeof(ble_hid_cfg->mac) * 3; // 2 hex chars + separator per byte if(line_len < mac_len + 1) return false; // MAC + at least 1 char for name - for(size_t i = 0; i < sizeof(cfg->ble.mac); 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, &cfg->ble.mac[i])) { + for(size_t i = 0; i < sizeof(ble_hid_cfg->mac); i++) { + const char* hex_byte = &line[i * 3]; + if(sscanf(hex_byte, "%02hhX", &ble_hid_cfg->mac[sizeof(ble_hid_cfg->mac) - 1 - i]) != 1) { return false; } } - reverse_mac_addr(cfg->ble.mac); - strlcpy(cfg->ble.name, line + mac_len, sizeof(cfg->ble.name)); - FURI_LOG_D(WORKER_TAG, "set bt id: %s", line); - - // Can't set bonding and pairing via BT_ID, sync with user choice instead - cfg->ble.bonding = bad_kb->app->config.ble.bonding; - cfg->ble.pairing = bad_kb->app->config.ble.pairing; + strlcpy(ble_hid_cfg->name, line + mac_len, sizeof(ble_hid_cfg->name)); + FURI_LOG_D(WORKER_TAG, "set ble id: %s", line); return true; } -static void ducky_script_preload(BadKbScript* bad_kb, File* script_file) { - BadKbApp* app = bad_kb->app; +static void bad_kb_hid_state_callback(bool state, void* context) { + furi_assert(context); + BadKbScript* bad_kb = context; + + if(state == true) { + furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtConnect); + } else { + furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtDisconnect); + } +} + +static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) { uint8_t ret = 0; uint32_t line_len = 0; @@ -381,24 +307,36 @@ static void ducky_script_preload(BadKbScript* bad_kb, File* script_file) { } } while(ret > 0); - // Looking for ID or BT_ID command at first line - const char* line_tmp = furi_string_get_cstr(bad_kb->line); - app->set_usb_id = false; - app->set_bt_id = false; - app->has_usb_id = strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0; - app->has_bt_id = strncmp(line_tmp, ducky_cmd_bt_id, strlen(ducky_cmd_bt_id)) == 0; + if(bad_kb->load_id_cfg) { + const char* line_tmp = furi_string_get_cstr(bad_kb->line); + BadKbHidInterface interface = *bad_kb->interface; + // Look for ID/BLE_ID/BT_ID command on first line + if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) { + if(ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1])) { + interface = BadKbHidInterfaceUsb; + } + } else if( + strncmp(line_tmp, ducky_cmd_ble_id, strlen(ducky_cmd_ble_id)) == 0 || + strncmp(line_tmp, ducky_cmd_bt_id, strlen(ducky_cmd_bt_id)) == 0) { + if(ducky_set_ble_id(bad_kb, &line_tmp[ducky_get_command_len(line_tmp) + 1])) { + interface = BadKbHidInterfaceBle; + } + } - // Auto-switch to mode chosen with ID/BT_ID, can override manually in config screen - if(app->has_usb_id) { - app->is_bt = false; - app->set_usb_id = ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1]); - } else if(app->has_bt_id) { - app->is_bt = true; - app->set_bt_id = ducky_set_bt_id(bad_kb, &line_tmp[strlen(ducky_cmd_bt_id) + 1]); + // Auto-switch based on ID/BLE_ID/BT_ID command, user can override manually after + if(interface != *bad_kb->interface) { + *bad_kb->interface = interface; + bad_kb->hid = bad_kb_hid_get_interface(*bad_kb->interface); + } } + bad_kb->hid_inst = bad_kb->hid->init(bad_kb->hid_cfg); + bad_kb->hid->set_state_callback(bad_kb->hid_inst, bad_kb_hid_state_callback, bad_kb); + storage_file_seek(script_file, 0, true); furi_string_reset(bad_kb->line); + + return true; } static int32_t ducky_script_execute_next(BadKbScript* bad_kb, File* script_file) { @@ -418,7 +356,7 @@ static int32_t ducky_script_execute_next(BadKbScript* bad_kb, File* script_file) FURI_LOG_E(WORKER_TAG, "Unknown command at line %zu", bad_kb->st.line_cur - 1U); return SCRIPT_STATE_ERROR; } else { - return (delay_val + bad_kb->defdelay); + return delay_val + bad_kb->defdelay; } } @@ -457,7 +395,7 @@ static int32_t ducky_script_execute_next(BadKbScript* bad_kb, File* script_file) FURI_LOG_E(WORKER_TAG, "Unknown command at line %zu", bad_kb->st.line_cur); return SCRIPT_STATE_ERROR; } else { - return (delay_val + bad_kb->defdelay); + return delay_val + bad_kb->defdelay; } } else { furi_string_push_back(bad_kb->line, bad_kb->file_buf[i]); @@ -470,33 +408,6 @@ static int32_t ducky_script_execute_next(BadKbScript* bad_kb, File* script_file) return 0; } -void bad_kb_bt_hid_state_callback(BtStatus status, void* context) { - furi_assert(context); - BadKbScript* bad_kb = context; - bool state = (status == BtStatusConnected); - - if(state == true) { - LevelRssiRange r = bt_remote_rssi_range(bad_kb->bt); - if(r != LevelRssiError) { - bt_timeout = bt_hid_delays[r]; - } - furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtConnect); - } else { - furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtDisconnect); - } -} - -void bad_kb_usb_hid_state_callback(bool state, void* context) { - furi_assert(context); - BadKbScript* bad_kb = context; - - if(state == true) { - furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtConnect); - } else { - furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtDisconnect); - } -} - static uint32_t bad_kb_flags_get(uint32_t flags_mask, uint32_t timeout) { uint32_t flags = furi_thread_flags_get(); furi_check((flags & FuriFlagError) == 0); @@ -534,10 +445,12 @@ static int32_t bad_kb_worker(void* context) { furi_string_get_cstr(bad_kb->file_path), FSAM_READ, FSOM_OPEN_EXISTING)) { - ducky_script_preload(bad_kb, script_file); - if(bad_kb->st.line_nb > 0) { - bad_kb_config_refresh(bad_kb->app); - worker_state = BadKbStateNotConnected; // Refresh will set connected flag + if((ducky_script_preload(bad_kb, script_file)) && (bad_kb->st.line_nb > 0)) { + if(bad_kb->hid->is_connected(bad_kb->hid_inst)) { + worker_state = BadKbStateIdle; // Ready to run + } else { + worker_state = BadKbStateNotConnected; // USB not connected + } } else { worker_state = BadKbStateScriptError; // Script preload error } @@ -569,8 +482,7 @@ static int32_t bad_kb_worker(void* context) { start = 0; FURI_LOG_D(WORKER_TAG, "idle wait"); uint32_t flags = bad_kb_flags_get( - WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtConnect | WorkerEvtDisconnect, - FuriWaitForever); + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtDisconnect, FuriWaitForever); FURI_LOG_D(WORKER_TAG, "idle flags: %lu", flags); if(flags & WorkerEvtEnd) { @@ -587,7 +499,6 @@ static int32_t bad_kb_worker(void* context) { bad_kb->key_hold_nb = 0; bad_kb->file_end = false; storage_file_seek(script_file, 0, true); - bad_kb_script_set_keyboard_layout(bad_kb, bad_kb->keyboard_layout); worker_state = BadKbStateRunning; bad_kb->st.elapsed = 0; } else if(flags & WorkerEvtDisconnect) { @@ -599,8 +510,7 @@ static int32_t bad_kb_worker(void* context) { start = 0; FURI_LOG_D(WORKER_TAG, "will run wait"); uint32_t flags = bad_kb_flags_get( - WorkerEvtEnd | WorkerEvtConnect | WorkerEvtDisconnect | WorkerEvtStartStop, - FuriWaitForever); + WorkerEvtEnd | WorkerEvtConnect | WorkerEvtStartStop, FuriWaitForever); FURI_LOG_D(WORKER_TAG, "will run flags: %lu", flags); if(flags & WorkerEvtEnd) { @@ -620,7 +530,7 @@ static int32_t bad_kb_worker(void* context) { flags = furi_thread_flags_wait( WorkerEvtEnd | WorkerEvtDisconnect | WorkerEvtStartStop, FuriFlagWaitAny | FuriFlagNoClear, - bad_kb->bt ? 3000 : 1500); + 1500); if(flags == (unsigned)FuriFlagErrorTimeout) { // If nothing happened - start script execution worker_state = BadKbStateRunning; @@ -629,10 +539,6 @@ static int32_t bad_kb_worker(void* context) { worker_state = BadKbStateIdle; furi_thread_flags_clear(WorkerEvtStartStop); } - if(bad_kb->bt) { - update_bt_timeout(bad_kb->bt); - } - bad_kb_script_set_keyboard_layout(bad_kb, bad_kb->keyboard_layout); } else if(flags & WorkerEvtStartStop) { // Cancel scheduled execution worker_state = BadKbStateNotConnected; } @@ -642,8 +548,7 @@ static int32_t bad_kb_worker(void* context) { FURI_LOG_D(WORKER_TAG, "running"); uint16_t delay_cur = (delay_val > 100) ? (100) : (delay_val); uint32_t flags = furi_thread_flags_wait( - WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtConnect | - WorkerEvtDisconnect, + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur); FURI_LOG_D(WORKER_TAG, "running flags: %lu", flags); @@ -654,18 +559,10 @@ static int32_t bad_kb_worker(void* context) { break; } else if(flags & WorkerEvtStartStop) { worker_state = BadKbStateIdle; // Stop executing script - if(bad_kb->bt) { - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->release_all(bad_kb->hid_inst); } else if(flags & WorkerEvtDisconnect) { worker_state = BadKbStateNotConnected; // Disconnected - if(bad_kb->bt) { - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->release_all(bad_kb->hid_inst); } else if(flags & WorkerEvtPauseResume) { pause_state = BadKbStateRunning; worker_state = BadKbStatePaused; // Pause @@ -687,20 +584,12 @@ static int32_t bad_kb_worker(void* context) { delay_val = 0; worker_state = BadKbStateScriptError; bad_kb->st.state = worker_state; - if(bad_kb->bt) { - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->release_all(bad_kb->hid_inst); } else if(delay_val == SCRIPT_STATE_END) { // End of script delay_val = 0; worker_state = BadKbStateIdle; bad_kb->st.state = BadKbStateDone; - if(bad_kb->bt) { - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->release_all(bad_kb->hid_inst); bad_kb->st.elapsed += (furi_get_tick() - start); continue; } else if(delay_val == SCRIPT_STATE_STRING_START) { // Start printing string with delays @@ -721,8 +610,7 @@ static int32_t bad_kb_worker(void* context) { start = 0; FURI_LOG_D(WORKER_TAG, "button wait"); uint32_t flags = bad_kb_flags_get( - WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtConnect | - WorkerEvtDisconnect, + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect, FuriWaitForever); FURI_LOG_D(WORKER_TAG, "button flags: %lu", flags); if(!(flags & FuriFlagError)) { @@ -733,11 +621,7 @@ static int32_t bad_kb_worker(void* context) { worker_state = BadKbStateRunning; } else if(flags & WorkerEvtDisconnect) { worker_state = BadKbStateNotConnected; // Disconnected - if(bad_kb->bt) { - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->release_all(bad_kb->hid_inst); } bad_kb->st.state = worker_state; continue; @@ -746,8 +630,7 @@ static int32_t bad_kb_worker(void* context) { start = 0; FURI_LOG_D(WORKER_TAG, "paused wait"); uint32_t flags = bad_kb_flags_get( - WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtConnect | - WorkerEvtDisconnect, + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect, FuriWaitForever); FURI_LOG_D(WORKER_TAG, "paused flags: %lu", flags); if(!(flags & FuriFlagError)) { @@ -756,19 +639,11 @@ static int32_t bad_kb_worker(void* context) { } else if(flags & WorkerEvtStartStop) { worker_state = BadKbStateIdle; // Stop executing script bad_kb->st.state = worker_state; - if(bad_kb->bt) { - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->release_all(bad_kb->hid_inst); } else if(flags & WorkerEvtDisconnect) { worker_state = BadKbStateNotConnected; // Disconnected bad_kb->st.state = worker_state; - if(bad_kb->bt) { - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->release_all(bad_kb->hid_inst); } else if(flags & WorkerEvtPauseResume) { if(pause_state == BadKbStateRunning) { if(delay_val > 0) { @@ -791,8 +666,7 @@ static int32_t bad_kb_worker(void* context) { uint32_t delay = (bad_kb->stringdelay == 0) ? bad_kb->defstringdelay : bad_kb->stringdelay; uint32_t flags = bad_kb_flags_get( - WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtConnect | - WorkerEvtDisconnect, + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect, delay); FURI_LOG_D(WORKER_TAG, "delay flags: %lu", flags); @@ -801,18 +675,10 @@ static int32_t bad_kb_worker(void* context) { break; } else if(flags & WorkerEvtStartStop) { worker_state = BadKbStateIdle; // Stop executing script - if(bad_kb->bt) { - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->release_all(bad_kb->hid_inst); } else if(flags & WorkerEvtDisconnect) { worker_state = BadKbStateNotConnected; // Disconnected - if(bad_kb->bt) { - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->release_all(bad_kb->hid_inst); } else if(flags & WorkerEvtPauseResume) { pause_state = BadKbStateStringDelay; worker_state = BadKbStatePaused; // Pause @@ -844,16 +710,13 @@ static int32_t bad_kb_worker(void* context) { break; } } - if(bad_kb->bt) { - update_bt_timeout(bad_kb->bt); - } if(start) { bad_kb->st.elapsed += (furi_get_tick() - start); } } - bt_set_status_changed_callback(bad_kb->app->bt, NULL, NULL); - furi_hal_hid_set_state_callback(NULL, NULL); + bad_kb->hid->set_state_callback(bad_kb->hid_inst, NULL, NULL); + bad_kb->hid->deinit(bad_kb->hid_inst); storage_file_close(script_file); storage_file_free(script_file); @@ -868,26 +731,28 @@ static int32_t bad_kb_worker(void* context) { static void bad_kb_script_set_default_keyboard_layout(BadKbScript* bad_kb) { furi_assert(bad_kb); - furi_string_set_str(bad_kb->keyboard_layout, ""); memset(bad_kb->layout, HID_KEYBOARD_NONE, sizeof(bad_kb->layout)); memcpy(bad_kb->layout, hid_asciimap, MIN(sizeof(hid_asciimap), sizeof(bad_kb->layout))); } -BadKbScript* bad_kb_script_open(FuriString* file_path, Bt* bt, BadKbApp* app) { +BadKbScript* bad_kb_script_open( + FuriString* file_path, + BadKbHidInterface* interface, + BadKbHidConfig* hid_cfg, + bool load_id_cfg) { 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(); bad_kb_script_set_default_keyboard_layout(bad_kb); bad_kb->st.state = BadKbStateInit; bad_kb->st.error[0] = '\0'; - bad_kb->st.is_bt = !!bt; - - bad_kb->bt = bt; + bad_kb->interface = interface; + bad_kb->hid_cfg = hid_cfg; + bad_kb->load_id_cfg = load_id_cfg; + bad_kb->hid = bad_kb_hid_get_interface(*bad_kb->interface); bad_kb->thread = furi_thread_alloc_ex("BadKbWorker", 2048, bad_kb_worker, bad_kb); furi_thread_start(bad_kb->thread); @@ -896,12 +761,10 @@ BadKbScript* bad_kb_script_open(FuriString* file_path, Bt* bt, BadKbApp* app) { void bad_kb_script_close(BadKbScript* bad_kb) { furi_assert(bad_kb); - furi_record_close(RECORD_STORAGE); furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtEnd); furi_thread_join(bad_kb->thread); furi_thread_free(bad_kb->thread); furi_string_free(bad_kb->file_path); - furi_string_free(bad_kb->keyboard_layout); free(bad_kb); } @@ -915,7 +778,6 @@ void bad_kb_script_set_keyboard_layout(BadKbScript* bad_kb, FuriString* layout_p File* layout_file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); if(!furi_string_empty(layout_path)) { //-V1051 - furi_string_set(bad_kb->keyboard_layout, layout_path); if(storage_file_open( layout_file, furi_string_get_cstr(layout_path), FSAM_READ, FSOM_OPEN_EXISTING)) { uint16_t layout[128]; diff --git a/applications/main/bad_kb/helpers/ducky_script.h b/applications/main/bad_kb/helpers/ducky_script.h index 28c931bc6..2a9fb902d 100644 --- a/applications/main/bad_kb/helpers/ducky_script.h +++ b/applications/main/bad_kb/helpers/ducky_script.h @@ -6,31 +6,7 @@ extern "C" { #include #include -#include - -#include "../bad_kb_app.h" - -typedef enum { - LevelRssi122_100, - LevelRssi99_80, - LevelRssi79_60, - LevelRssi59_40, - LevelRssi39_0, - LevelRssiNum, - LevelRssiError = 0xFF, -} LevelRssiRange; - -extern const uint8_t bt_hid_delays[LevelRssiNum]; - -extern uint8_t bt_timeout; - -typedef enum { - WorkerEvtStartStop = (1 << 0), - WorkerEvtPauseResume = (1 << 1), - WorkerEvtEnd = (1 << 2), - WorkerEvtConnect = (1 << 3), - WorkerEvtDisconnect = (1 << 4), -} WorkerEvtFlags; +#include "bad_kb_hid.h" typedef enum { BadKbStateInit, @@ -49,8 +25,6 @@ typedef enum { typedef struct { BadKbWorkerState state; - bool is_bt; - uint32_t pin; size_t line_cur; size_t line_nb; uint32_t delay_remain; @@ -61,7 +35,11 @@ typedef struct { typedef struct BadKbScript BadKbScript; -BadKbScript* bad_kb_script_open(FuriString* file_path, Bt* bt, BadKbApp* app); +BadKbScript* bad_kb_script_open( + FuriString* file_path, + BadKbHidInterface* interface, + BadKbHidConfig* hid_cfg, + bool load_id_cfg); void bad_kb_script_close(BadKbScript* bad_kb); @@ -77,10 +55,6 @@ void bad_kb_script_pause_resume(BadKbScript* bad_kb); BadKbState* bad_kb_script_get_state(BadKbScript* bad_kb); -void bad_kb_bt_hid_state_callback(BtStatus status, void* context); - -void bad_kb_usb_hid_state_callback(bool state, void* context); - #ifdef __cplusplus } #endif diff --git a/applications/main/bad_kb/helpers/ducky_script_commands.c b/applications/main/bad_kb/helpers/ducky_script_commands.c index 6dfb4b683..a1b17c9b0 100644 --- a/applications/main/bad_kb/helpers/ducky_script_commands.c +++ b/applications/main/bad_kb/helpers/ducky_script_commands.c @@ -1,7 +1,5 @@ -#include "../bad_kb_app_i.h" #include -#include -#include "ble_hid.h" +#include #include "ducky_script.h" #include "ducky_script_i.h" @@ -95,17 +93,9 @@ static int32_t ducky_fnc_sysrq(BadKbScript* bad_kb, const char* line, int32_t pa line = &line[ducky_get_command_len(line) + 1]; uint16_t key = ducky_get_keycode(bad_kb, line, true); - if(bad_kb->bt) { - ble_profile_hid_kb_press( - bad_kb->app->ble_hid, KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); - ble_profile_hid_kb_press(bad_kb->app->ble_hid, key); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release_all(bad_kb->app->ble_hid); - } else { - furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release_all(); - } + bad_kb->hid->kb_press(bad_kb->hid_inst, KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); + bad_kb->hid->kb_press(bad_kb->hid_inst, key); + bad_kb->hid->release_all(bad_kb->hid_inst); return 0; } @@ -135,42 +125,58 @@ static int32_t ducky_fnc_altstring(BadKbScript* bad_kb, const char* line, int32_ static int32_t ducky_fnc_hold(BadKbScript* bad_kb, const char* line, int32_t param) { UNUSED(param); - line = &line[ducky_get_command_len(line) + 1]; - uint16_t key = ducky_get_keycode(bad_kb, line, true); - if(key == HID_KEYBOARD_NONE) { - return ducky_error(bad_kb, "No keycode defined for %s", line); - } - bad_kb->key_hold_nb++; + if(bad_kb->key_hold_nb > (HID_KB_MAX_KEYS - 1)) { - return ducky_error(bad_kb, "Too many keys are hold"); + return ducky_error(bad_kb, "Too many keys are held"); } - if(bad_kb->bt) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, key); - } else { - furi_hal_hid_kb_press(key); + + // Handle Mouse Keys here + uint16_t key = ducky_get_mouse_keycode_by_name(line); + if(key != HID_MOUSE_NONE) { + bad_kb->key_hold_nb++; + bad_kb->hid->mouse_press(bad_kb->hid_inst, key); + return 0; } - return 0; + + // Handle Keyboard keys here + key = ducky_get_keycode(bad_kb, line, true); + if(key != HID_KEYBOARD_NONE) { + bad_kb->key_hold_nb++; + bad_kb->hid->kb_press(bad_kb->hid_inst, key); + return 0; + } + + // keyboard and mouse were none + return ducky_error(bad_kb, "Unknown keycode for %s", line); } static int32_t ducky_fnc_release(BadKbScript* bad_kb, const char* line, int32_t param) { UNUSED(param); - line = &line[ducky_get_command_len(line) + 1]; - uint16_t key = ducky_get_keycode(bad_kb, line, true); - if(key == HID_KEYBOARD_NONE) { - return ducky_error(bad_kb, "No keycode defined for %s", line); - } + if(bad_kb->key_hold_nb == 0) { - return ducky_error(bad_kb, "No keys are hold"); + return ducky_error(bad_kb, "No keys are held"); } - bad_kb->key_hold_nb--; - if(bad_kb->bt) { - ble_profile_hid_kb_release(bad_kb->app->ble_hid, key); - } else { - furi_hal_hid_kb_release(key); + + // Handle Mouse Keys here + uint16_t key = ducky_get_mouse_keycode_by_name(line); + if(key != HID_MOUSE_NONE) { + bad_kb->key_hold_nb--; + bad_kb->hid->mouse_release(bad_kb->hid_inst, key); + return 0; } - return 0; + + //Handle Keyboard Keys here + key = ducky_get_keycode(bad_kb, line, true); + if(key != HID_KEYBOARD_NONE) { + bad_kb->key_hold_nb--; + bad_kb->hid->kb_release(bad_kb->hid_inst, key); + return 0; + } + + // keyboard and mouse were none + return ducky_error(bad_kb, "No keycode defined for %s", line); } static int32_t ducky_fnc_media(BadKbScript* bad_kb, const char* line, int32_t param) { @@ -181,14 +187,8 @@ static int32_t ducky_fnc_media(BadKbScript* bad_kb, const char* line, int32_t pa if(key == HID_CONSUMER_UNASSIGNED) { return ducky_error(bad_kb, "No keycode defined for %s", line); } - if(bad_kb->bt) { - ble_profile_hid_kb_press(bad_kb->app->ble_hid, key); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release(bad_kb->app->ble_hid, key); - } else { - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release(key); - } + bad_kb->hid->consumer_press(bad_kb->hid_inst, key); + bad_kb->hid->consumer_release(bad_kb->hid_inst, key); return 0; } @@ -201,18 +201,10 @@ static int32_t ducky_fnc_globe(BadKbScript* bad_kb, const char* line, int32_t pa return ducky_error(bad_kb, "No keycode defined for %s", line); } - if(bad_kb->bt) { - ble_profile_hid_consumer_key_press(bad_kb->app->ble_hid, HID_CONSUMER_FN_GLOBE); - ble_profile_hid_kb_press(bad_kb->app->ble_hid, key); - furi_delay_ms(bt_timeout); - ble_profile_hid_kb_release(bad_kb->app->ble_hid, key); - ble_profile_hid_consumer_key_release(bad_kb->app->ble_hid, HID_CONSUMER_FN_GLOBE); - } else { - furi_hal_hid_consumer_key_press(HID_CONSUMER_FN_GLOBE); - furi_hal_hid_kb_press(key); - furi_hal_hid_kb_release(key); - furi_hal_hid_consumer_key_release(HID_CONSUMER_FN_GLOBE); - } + bad_kb->hid->consumer_press(bad_kb->hid_inst, HID_CONSUMER_FN_GLOBE); + bad_kb->hid->kb_press(bad_kb->hid_inst, key); + bad_kb->hid->kb_release(bad_kb->hid_inst, key); + bad_kb->hid->consumer_release(bad_kb->hid_inst, HID_CONSUMER_FN_GLOBE); return 0; } @@ -224,10 +216,48 @@ static int32_t ducky_fnc_waitforbutton(BadKbScript* bad_kb, const char* line, in return SCRIPT_STATE_WAIT_FOR_BTN; } +static int32_t ducky_fnc_mouse_scroll(BadKbScript* bad_kb, const char* line, int32_t param) { + UNUSED(param); + + line = &line[strcspn(line, " ") + 1]; + int32_t mouse_scroll_dist = 0; + + if(strint_to_int32(line, NULL, &mouse_scroll_dist, 10) != StrintParseNoError) { + return ducky_error(bad_kb, "Invalid Number %s", line); + } + + bad_kb->hid->mouse_scroll(bad_kb->hid_inst, mouse_scroll_dist); + + return 0; +} + +static int32_t ducky_fnc_mouse_move(BadKbScript* bad_kb, const char* line, int32_t param) { + UNUSED(param); + + line = &line[strcspn(line, " ") + 1]; + int32_t mouse_move_x = 0; + int32_t mouse_move_y = 0; + + if(strint_to_int32(line, NULL, &mouse_move_x, 10) != StrintParseNoError) { + return ducky_error(bad_kb, "Invalid Number %s", line); + } + + line = &line[strcspn(line, " ") + 1]; + + if(strint_to_int32(line, NULL, &mouse_move_y, 10) != StrintParseNoError) { + return ducky_error(bad_kb, "Invalid Number %s", line); + } + + bad_kb->hid->mouse_move(bad_kb->hid_inst, mouse_move_x, mouse_move_y); + + return 0; +} + static const DuckyCmd ducky_commands[] = { {"REM", NULL, -1}, {"ID", NULL, -1}, {"BT_ID", NULL, -1}, + {"BLE_ID", NULL, -1}, {"DELAY", ducky_fnc_delay, -1}, {"STRING", ducky_fnc_string, 0}, {"STRINGLN", ducky_fnc_string, 1}, @@ -247,6 +277,10 @@ static const DuckyCmd ducky_commands[] = { {"WAIT_FOR_BUTTON_PRESS", ducky_fnc_waitforbutton, -1}, {"MEDIA", ducky_fnc_media, -1}, {"GLOBE", ducky_fnc_globe, -1}, + {"MOUSEMOVE", ducky_fnc_mouse_move, -1}, + {"MOUSE_MOVE", ducky_fnc_mouse_move, -1}, + {"MOUSESCROLL", ducky_fnc_mouse_scroll, -1}, + {"MOUSE_SCROLL", ducky_fnc_mouse_scroll, -1}, }; #define TAG "BadKb" @@ -266,7 +300,7 @@ int32_t ducky_execute_cmd(BadKbScript* bad_kb, const char* line) { if(ducky_commands[i].callback == NULL) { return 0; } else { - return ((ducky_commands[i].callback)(bad_kb, line, ducky_commands[i].param)); + return (ducky_commands[i].callback)(bad_kb, line, ducky_commands[i].param); } } } diff --git a/applications/main/bad_kb/helpers/ducky_script_i.h b/applications/main/bad_kb/helpers/ducky_script_i.h index d4d5fab39..963a99861 100644 --- a/applications/main/bad_kb/helpers/ducky_script_i.h +++ b/applications/main/bad_kb/helpers/ducky_script_i.h @@ -7,6 +7,7 @@ extern "C" { #include #include #include "ducky_script.h" +#include "bad_kb_hid.h" #define SCRIPT_STATE_ERROR (-1) #define SCRIPT_STATE_END (-2) @@ -17,12 +18,19 @@ extern "C" { #define FILE_BUFFER_LEN 16 +#define HID_MOUSE_INVALID 0 +#define HID_MOUSE_NONE 0 + struct BadKbScript { + BadKbHidInterface* interface; + BadKbHidConfig* hid_cfg; + bool load_id_cfg; + const BadKbHidApi* hid; + void* hid_inst; FuriThread* thread; BadKbState st; FuriString* file_path; - FuriString* keyboard_layout; uint8_t file_buf[FILE_BUFFER_LEN + 1]; uint8_t buf_start; uint8_t buf_len; @@ -40,9 +48,6 @@ struct BadKbScript { FuriString* string_print; size_t string_print_pos; - - Bt* bt; - BadKbApp* app; }; uint16_t ducky_get_keycode(BadKbScript* bad_kb, const char* param, bool accept_chars); @@ -55,6 +60,8 @@ uint16_t ducky_get_keycode_by_name(const char* param); uint16_t ducky_get_media_keycode_by_name(const char* param); +uint8_t ducky_get_mouse_keycode_by_name(const char* param); + bool ducky_get_number(const char* param, uint32_t* val); void ducky_numlock_on(BadKbScript* bad_kb); diff --git a/applications/main/bad_kb/helpers/ducky_script_keycodes.c b/applications/main/bad_kb/helpers/ducky_script_keycodes.c index 290618c13..7dd2e4d16 100644 --- a/applications/main/bad_kb/helpers/ducky_script_keycodes.c +++ b/applications/main/bad_kb/helpers/ducky_script_keycodes.c @@ -108,6 +108,17 @@ static const DuckyKey ducky_media_keys[] = { {"BRIGHT_DOWN", HID_CONSUMER_BRIGHTNESS_DECREMENT}, }; +static const DuckyKey ducky_mouse_keys[] = { + {"LEFTCLICK", HID_MOUSE_BTN_LEFT}, + {"LEFT_CLICK", HID_MOUSE_BTN_LEFT}, + {"RIGHTCLICK", HID_MOUSE_BTN_RIGHT}, + {"RIGHT_CLICK", HID_MOUSE_BTN_RIGHT}, + {"MIDDLECLICK", HID_MOUSE_BTN_WHEEL}, + {"MIDDLE_CLICK", HID_MOUSE_BTN_WHEEL}, + {"WHEELCLICK", HID_MOUSE_BTN_WHEEL}, + {"WHEEL_CLICK", HID_MOUSE_BTN_WHEEL}, +}; + uint16_t ducky_get_keycode_by_name(const char* param) { for(size_t i = 0; i < COUNT_OF(ducky_keys); i++) { size_t key_cmd_len = strlen(ducky_keys[i].name); @@ -131,3 +142,15 @@ uint16_t ducky_get_media_keycode_by_name(const char* param) { return HID_CONSUMER_UNASSIGNED; } + +uint8_t ducky_get_mouse_keycode_by_name(const char* param) { + for(size_t i = 0; i < COUNT_OF(ducky_mouse_keys); i++) { + size_t key_cmd_len = strlen(ducky_mouse_keys[i].name); + if((strncmp(param, ducky_mouse_keys[i].name, key_cmd_len) == 0) && + (ducky_is_line_end(param[key_cmd_len]))) { + return ducky_mouse_keys[i].keycode; + } + } + + return HID_MOUSE_INVALID; +} diff --git a/applications/main/bad_kb/resources/badusb/Demos/test_mouse.txt b/applications/main/bad_kb/resources/badusb/Demos/test_mouse.txt new file mode 100644 index 000000000..97391cf17 --- /dev/null +++ b/applications/main/bad_kb/resources/badusb/Demos/test_mouse.txt @@ -0,0 +1,46 @@ +ID 1234:abcd Generic:USB Keyboard +REM Declare ourselves as a generic usb keyboard +REM You can override this to use something else +REM Check the `lsusb` command to know your own devices IDs + +DEFAULT_DELAY 200 +DEFAULT_STRING_DELAY 100 + +DELAY 1000 + +REM Test all mouse functions +LEFTCLICK +RIGHTCLICK +MIDDLECLICK + +DELAY 1000 + +MOUSEMOVE -10 0 +REPEAT 20 +MOUSEMOVE 0 10 +REPEAT 20 +MOUSEMOVE 10 0 +REPEAT 20 +MOUSEMOVE 0 -10 +REPEAT 20 + +DELAY 1000 + +MOUSESCROLL -50 +MOUSESCROLL 50 + +DELAY 1000 + +REM Verify Mouse hold working +HOLD LEFTCLICK +DELAY 2000 +RELEASE LEFTCLICK + +DELAY 1000 + +REM Verify KB hold working +HOLD M +DELAY 2000 +RELEASE M + +ENTER \ No newline at end of file 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 b92f361a7..6665f660d 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config.c @@ -1,125 +1,127 @@ #include "../bad_kb_app_i.h" -enum VarItemListIndex { - VarItemListIndexKeyboardLayout, - VarItemListIndexConnection, +enum ConfigIndex { + ConfigIndexKeyboardLayout, + ConfigIndexConnection, }; -enum VarItemListIndexBt { - VarItemListIndexBtRemember = VarItemListIndexConnection + 1, - VarItemListIndexBtPairing, - VarItemListIndexBtDeviceName, - VarItemListIndexBtMacAddress, - VarItemListIndexBtRandomizeMac, +enum ConfigIndexBle { + ConfigIndexBleRemember = ConfigIndexConnection + 1, + ConfigIndexBlePairing, + ConfigIndexBleDeviceName, + ConfigIndexBleMacAddress, + ConfigIndexBleRandomizeMac, + ConfigIndexBleUnpair, }; -enum VarItemListIndexUsb { - VarItemListIndexUsbManufacturer = VarItemListIndexConnection + 1, - VarItemListIndexUsbProductName, - VarItemListIndexUsbVidPid, - VarItemListIndexUsbRandomizeVidPid, +enum ConfigIndexUsb { + ConfigIndexUsbManufacturer = ConfigIndexConnection + 1, + ConfigIndexUsbProductName, + ConfigIndexUsbVidPid, + ConfigIndexUsbRandomizeVidPid, }; 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); - variable_item_set_current_value_text(item, bad_kb->is_bt ? "BT" : "USB"); - view_dispatcher_send_custom_event(bad_kb->view_dispatcher, VarItemListIndexConnection); + bad_kb_set_interface( + bad_kb, + bad_kb->interface == BadKbHidInterfaceBle ? BadKbHidInterfaceUsb : BadKbHidInterfaceBle); + variable_item_set_current_value_text( + item, bad_kb->interface == BadKbHidInterfaceBle ? "BLE" : "USB"); + view_dispatcher_send_custom_event(bad_kb->view_dispatcher, ConfigIndexConnection); } -void bad_kb_scene_config_bt_remember_callback(VariableItem* item) { +void bad_kb_scene_config_ble_remember_callback(VariableItem* item) { BadKbApp* bad_kb = variable_item_get_context(item); bool value = variable_item_get_current_value_index(item); - // Set user config and remember - bad_kb->config.ble.bonding = value; - // Apply to ID config so its temporarily overridden (currently can't set bonding with BT_ID anyway) - if(bad_kb->set_bt_id) { - bad_kb->id_config.ble.bonding = value; - } + // Apply to current script config + bad_kb->script_hid_cfg.ble.bonding = value; + // Set in user config to save in settings file + bad_kb->user_hid_cfg.ble.bonding = value; variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - view_dispatcher_send_custom_event(bad_kb->view_dispatcher, VarItemListIndexBtRemember); } -const char* const bt_pairing_names[GapPairingCount] = { +const char* const ble_pairing_names[GapPairingCount] = { "YesNo", "PIN Type", "PIN Y/N", }; -void bad_kb_scene_config_bt_pairing_callback(VariableItem* item) { +void bad_kb_scene_config_ble_pairing_callback(VariableItem* item) { BadKbApp* bad_kb = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); - // Set user config and remember - bad_kb->config.ble.pairing = index; - // Apply to ID config so its temporarily overridden (currently can't set pairing with BT_ID anyway) - if(bad_kb->set_bt_id) { - bad_kb->id_config.ble.pairing = index; - } - variable_item_set_current_value_text(item, bt_pairing_names[index]); - view_dispatcher_send_custom_event(bad_kb->view_dispatcher, VarItemListIndexBtPairing); + // Apply to current script config + bad_kb->script_hid_cfg.ble.pairing = index; + // Set in user config to save in settings file + bad_kb->user_hid_cfg.ble.pairing = index; + variable_item_set_current_value_text(item, ble_pairing_names[index]); } -void bad_kb_scene_config_var_item_list_callback(void* context, uint32_t index) { +void bad_kb_scene_config_select_callback(void* context, uint32_t index) { BadKbApp* bad_kb = context; + view_dispatcher_send_custom_event(bad_kb->view_dispatcher, index); } +static void draw_menu(BadKbApp* bad_kb) { + VariableItemList* var_item_list = bad_kb->var_item_list; + VariableItem* item; + + variable_item_list_reset(var_item_list); + + variable_item_list_add(var_item_list, "Keyboard Layout (global)", 0, NULL, NULL); + + item = variable_item_list_add( + var_item_list, "Connection", 2, bad_kb_scene_config_connection_callback, bad_kb); + variable_item_set_current_value_index(item, bad_kb->interface == BadKbHidInterfaceBle); + variable_item_set_current_value_text( + item, bad_kb->interface == BadKbHidInterfaceBle ? "BLE" : "USB"); + + if(bad_kb->interface == BadKbHidInterfaceBle) { + BleProfileHidParams* ble_hid_cfg = &bad_kb->script_hid_cfg.ble; + + item = variable_item_list_add( + var_item_list, "BLE Remember", 2, bad_kb_scene_config_ble_remember_callback, bad_kb); + variable_item_set_current_value_index(item, ble_hid_cfg->bonding); + variable_item_set_current_value_text(item, ble_hid_cfg->bonding ? "ON" : "OFF"); + + item = variable_item_list_add( + var_item_list, + "BLE Pairing", + GapPairingCount, + bad_kb_scene_config_ble_pairing_callback, + bad_kb); + variable_item_set_current_value_index(item, ble_hid_cfg->pairing); + variable_item_set_current_value_text(item, ble_pairing_names[ble_hid_cfg->pairing]); + + variable_item_list_add(var_item_list, "BLE Device Name", 0, NULL, NULL); + + variable_item_list_add(var_item_list, "BLE MAC Address", 0, NULL, NULL); + + variable_item_list_add(var_item_list, "Randomize BLE MAC", 0, NULL, NULL); + + variable_item_list_add(var_item_list, "Remove BLE Pairing", 0, NULL, NULL); + } else { + variable_item_list_add(var_item_list, "USB Manufacturer", 0, NULL, NULL); + + variable_item_list_add(var_item_list, "USB Product Name", 0, NULL, NULL); + + variable_item_list_add(var_item_list, "USB VID and PID", 0, NULL, NULL); + + variable_item_list_add(var_item_list, "Randomize USB VID:PID", 0, NULL, NULL); + } +} + void bad_kb_scene_config_on_enter(void* context) { BadKbApp* bad_kb = context; VariableItemList* var_item_list = bad_kb->var_item_list; - VariableItem* item; - - item = variable_item_list_add(var_item_list, "Keyboard layout", 0, NULL, bad_kb); - - item = variable_item_list_add( - var_item_list, "Connection", 2, bad_kb_scene_config_connection_callback, bad_kb); - variable_item_set_current_value_index(item, bad_kb->is_bt); - variable_item_set_current_value_text(item, bad_kb->is_bt ? "BT" : "USB"); - - if(bad_kb->is_bt) { - BadKbConfig* cfg = bad_kb->set_bt_id ? &bad_kb->id_config : &bad_kb->config; - - item = variable_item_list_add( - var_item_list, "BT Remember", 2, bad_kb_scene_config_bt_remember_callback, bad_kb); - variable_item_set_current_value_index(item, cfg->ble.bonding); - variable_item_set_current_value_text(item, cfg->ble.bonding ? "ON" : "OFF"); - - item = variable_item_list_add( - var_item_list, - "BT Pairing", - GapPairingCount, - bad_kb_scene_config_bt_pairing_callback, - bad_kb); - variable_item_set_current_value_index(item, cfg->ble.pairing); - variable_item_set_current_value_text(item, bt_pairing_names[cfg->ble.pairing]); - - item = variable_item_list_add(var_item_list, "BT Device Name", 0, NULL, bad_kb); - - item = variable_item_list_add(var_item_list, "BT MAC Address", 0, NULL, bad_kb); - if(cfg->ble.bonding) { - variable_item_set_locked(item, true, "Remember\nmust be Off!"); - } - - item = variable_item_list_add(var_item_list, "Randomize BT MAC", 0, NULL, bad_kb); - if(cfg->ble.bonding) { - variable_item_set_locked(item, true, "Remember\nmust be Off!"); - } - } else { - item = variable_item_list_add(var_item_list, "USB Manufacturer", 0, NULL, bad_kb); - - item = variable_item_list_add(var_item_list, "USB Product Name", 0, NULL, bad_kb); - - item = variable_item_list_add(var_item_list, "USB VID and PID", 0, NULL, bad_kb); - - item = variable_item_list_add(var_item_list, "Randomize USB VID:PID", 0, NULL, bad_kb); - } variable_item_list_set_enter_callback( - var_item_list, bad_kb_scene_config_var_item_list_callback, bad_kb); - + var_item_list, bad_kb_scene_config_select_callback, bad_kb); + draw_menu(bad_kb); variable_item_list_set_selected_item( var_item_list, scene_manager_get_scene_state(bad_kb->scene_manager, BadKbSceneConfig)); - view_dispatcher_switch_to_view(bad_kb->view_dispatcher, BadKbAppViewVarItemList); + view_dispatcher_switch_to_view(bad_kb->view_dispatcher, BadKbAppViewConfig); } bool bad_kb_scene_config_on_event(void* context, SceneManagerEvent event) { @@ -130,71 +132,67 @@ bool bad_kb_scene_config_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state(bad_kb->scene_manager, BadKbSceneConfig, event.event); consumed = true; switch(event.event) { - case VarItemListIndexKeyboardLayout: + case ConfigIndexKeyboardLayout: scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigLayout); break; - case VarItemListIndexConnection: - bad_kb_config_refresh(bad_kb); + case ConfigIndexConnection: + // Refresh default values for new interface + const BadKbHidApi* hid = bad_kb_hid_get_interface(bad_kb->interface); + hid->adjust_config(&bad_kb->script_hid_cfg); + // Redraw menu with new interface options + draw_menu(bad_kb); break; default: break; } - if(bad_kb->is_bt) { + if(bad_kb->interface == BadKbHidInterfaceBle) { switch(event.event) { - case VarItemListIndexBtRemember: - bad_kb_config_refresh(bad_kb); + case ConfigIndexBleDeviceName: + scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigBleName); break; - case VarItemListIndexBtPairing: - bad_kb_config_refresh(bad_kb); + case ConfigIndexBleMacAddress: + scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigBleMac); break; - case VarItemListIndexBtDeviceName: - scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigBtName); + case ConfigIndexBleRandomizeMac: + // Apply to current script config + furi_hal_random_fill_buf( + bad_kb->script_hid_cfg.ble.mac, sizeof(bad_kb->script_hid_cfg.ble.mac)); + // Set in user config to save in settings file + memcpy( + bad_kb->user_hid_cfg.ble.mac, + bad_kb->script_hid_cfg.ble.mac, + sizeof(bad_kb->user_hid_cfg.ble.mac)); break; - case VarItemListIndexBtMacAddress: - scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigBtMac); - break; - case VarItemListIndexBtRandomizeMac: - // Set user config and remember - furi_hal_random_fill_buf(bad_kb->config.ble.mac, sizeof(bad_kb->config.ble.mac)); - // Apply to ID config so its temporarily overridden - if(bad_kb->set_bt_id) { - memcpy( - bad_kb->id_config.ble.mac, - bad_kb->config.ble.mac, - sizeof(bad_kb->id_config.ble.mac)); - } - bad_kb_config_refresh(bad_kb); + case ConfigIndexBleUnpair: + scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfirmUnpair); break; default: break; } } else { switch(event.event) { - case VarItemListIndexUsbManufacturer: + case ConfigIndexUsbManufacturer: scene_manager_set_scene_state( bad_kb->scene_manager, BadKbSceneConfigUsbName, true); scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigUsbName); break; - case VarItemListIndexUsbProductName: + case ConfigIndexUsbProductName: scene_manager_set_scene_state( bad_kb->scene_manager, BadKbSceneConfigUsbName, false); scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigUsbName); break; - case VarItemListIndexUsbVidPid: + case ConfigIndexUsbVidPid: scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigUsbVidPid); break; - case VarItemListIndexUsbRandomizeVidPid: + case ConfigIndexUsbRandomizeVidPid: furi_hal_random_fill_buf( (void*)bad_kb->usb_vidpid_buf, sizeof(bad_kb->usb_vidpid_buf)); - // Set user config and remember - bad_kb->config.usb.vid = bad_kb->usb_vidpid_buf[0]; - bad_kb->config.usb.pid = bad_kb->usb_vidpid_buf[1]; - // Apply to ID config so its temporarily overridden - if(bad_kb->set_usb_id) { - bad_kb->id_config.usb.vid = bad_kb->config.usb.vid; - bad_kb->id_config.usb.pid = bad_kb->config.usb.pid; - } - bad_kb_config_refresh(bad_kb); + // Apply to current script config + bad_kb->script_hid_cfg.usb.vid = bad_kb->usb_vidpid_buf[0]; + bad_kb->script_hid_cfg.usb.pid = bad_kb->usb_vidpid_buf[1]; + // Set in user config to save in settings file + bad_kb->user_hid_cfg.usb.vid = bad_kb->script_hid_cfg.usb.vid; + bad_kb->user_hid_cfg.usb.pid = bad_kb->script_hid_cfg.usb.pid; break; default: break; diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config.h b/applications/main/bad_kb/scenes/bad_kb_scene_config.h index 034a898a4..2faae438d 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config.h +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config.h @@ -3,7 +3,9 @@ ADD_SCENE(bad_kb, work, Work) ADD_SCENE(bad_kb, error, Error) ADD_SCENE(bad_kb, config, Config) ADD_SCENE(bad_kb, config_layout, ConfigLayout) -ADD_SCENE(bad_kb, config_bt_name, ConfigBtName) -ADD_SCENE(bad_kb, config_bt_mac, ConfigBtMac) +ADD_SCENE(bad_kb, config_ble_name, ConfigBleName) +ADD_SCENE(bad_kb, config_ble_mac, ConfigBleMac) ADD_SCENE(bad_kb, config_usb_name, ConfigUsbName) ADD_SCENE(bad_kb, config_usb_vidpid, ConfigUsbVidPid) +ADD_SCENE(bad_kb, confirm_unpair, ConfirmUnpair) +ADD_SCENE(bad_kb, unpair_done, UnpairDone) diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_ble_mac.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_ble_mac.c new file mode 100644 index 000000000..006e473b4 --- /dev/null +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_ble_mac.c @@ -0,0 +1,71 @@ +#include "../bad_kb_app_i.h" + +enum ByteInputResult { + ByteInputResultOk, +}; + +static void reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]) { + uint8_t tmp; + for(size_t i = 0; i < GAP_MAC_ADDR_SIZE / 2; i++) { + tmp = mac_addr[i]; + mac_addr[i] = mac_addr[GAP_MAC_ADDR_SIZE - 1 - i]; + mac_addr[GAP_MAC_ADDR_SIZE - 1 - i] = tmp; + } +} + +void bad_kb_scene_config_ble_mac_byte_input_callback(void* context) { + BadKbApp* bad_kb = context; + + view_dispatcher_send_custom_event(bad_kb->view_dispatcher, ByteInputResultOk); +} + +void bad_kb_scene_config_ble_mac_on_enter(void* context) { + BadKbApp* bad_kb = context; + ByteInput* byte_input = bad_kb->byte_input; + + memcpy(bad_kb->ble_mac_buf, bad_kb->script_hid_cfg.ble.mac, sizeof(bad_kb->ble_mac_buf)); + reverse_mac_addr(bad_kb->ble_mac_buf); + byte_input_set_header_text(byte_input, "Set BLE MAC address"); + + byte_input_set_result_callback( + byte_input, + bad_kb_scene_config_ble_mac_byte_input_callback, + NULL, + bad_kb, + bad_kb->ble_mac_buf, + sizeof(bad_kb->ble_mac_buf)); + + view_dispatcher_switch_to_view(bad_kb->view_dispatcher, BadKbAppViewByteInput); +} + +bool bad_kb_scene_config_ble_mac_on_event(void* context, SceneManagerEvent event) { + BadKbApp* bad_kb = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == ByteInputResultOk) { + reverse_mac_addr(bad_kb->ble_mac_buf); + // Apply to current script config + memcpy( + bad_kb->script_hid_cfg.ble.mac, + bad_kb->ble_mac_buf, + sizeof(bad_kb->script_hid_cfg.ble.mac)); + // Set in user config to save in settings file + memcpy( + bad_kb->user_hid_cfg.ble.mac, + bad_kb->ble_mac_buf, + sizeof(bad_kb->user_hid_cfg.ble.mac)); + } + scene_manager_previous_scene(bad_kb->scene_manager); + } + return consumed; +} + +void bad_kb_scene_config_ble_mac_on_exit(void* context) { + BadKbApp* bad_kb = context; + ByteInput* byte_input = bad_kb->byte_input; + + byte_input_set_result_callback(byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(byte_input, ""); +} diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_ble_name.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_ble_name.c new file mode 100644 index 000000000..f5acb8c50 --- /dev/null +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_ble_name.c @@ -0,0 +1,59 @@ +#include "../bad_kb_app_i.h" + +enum TextInputResult { + TextInputResultOk, +}; + +static void bad_kb_scene_config_ble_name_text_input_callback(void* context) { + BadKbApp* bad_kb = context; + + view_dispatcher_send_custom_event(bad_kb->view_dispatcher, TextInputResultOk); +} + +void bad_kb_scene_config_ble_name_on_enter(void* context) { + BadKbApp* bad_kb = context; + TextInput* text_input = bad_kb->text_input; + + strlcpy(bad_kb->ble_name_buf, bad_kb->script_hid_cfg.ble.name, sizeof(bad_kb->ble_name_buf)); + text_input_set_header_text(text_input, "Set BLE device name"); + + text_input_set_result_callback( + text_input, + bad_kb_scene_config_ble_name_text_input_callback, + bad_kb, + bad_kb->ble_name_buf, + sizeof(bad_kb->ble_name_buf), + true); + + view_dispatcher_switch_to_view(bad_kb->view_dispatcher, BadKbAppViewTextInput); +} + +bool bad_kb_scene_config_ble_name_on_event(void* context, SceneManagerEvent event) { + BadKbApp* bad_kb = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == TextInputResultOk) { + // Apply to current script config + strlcpy( + bad_kb->script_hid_cfg.ble.name, + bad_kb->ble_name_buf, + sizeof(bad_kb->script_hid_cfg.ble.name)); + // Set in user config to save in settings file + strlcpy( + bad_kb->user_hid_cfg.ble.name, + bad_kb->ble_name_buf, + sizeof(bad_kb->user_hid_cfg.ble.name)); + } + scene_manager_previous_scene(bad_kb->scene_manager); + } + return consumed; +} + +void bad_kb_scene_config_ble_name_on_exit(void* context) { + BadKbApp* bad_kb = context; + TextInput* text_input = bad_kb->text_input; + + text_input_reset(text_input); +} diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_mac.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_mac.c deleted file mode 100644 index d80a874c7..000000000 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_mac.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "../bad_kb_app_i.h" - -void bad_kb_scene_config_bt_mac_byte_input_callback(void* context) { - BadKbApp* bad_kb = context; - - view_dispatcher_send_custom_event(bad_kb->view_dispatcher, BadKbAppCustomEventByteInputDone); -} - -void bad_kb_scene_config_bt_mac_on_enter(void* context) { - BadKbApp* bad_kb = context; - ByteInput* byte_input = bad_kb->byte_input; - - memcpy( - bad_kb->bt_mac_buf, - bad_kb->set_bt_id ? bad_kb->id_config.ble.mac : bad_kb->config.ble.mac, - sizeof(bad_kb->bt_mac_buf)); - reverse_mac_addr(bad_kb->bt_mac_buf); - byte_input_set_header_text(byte_input, "Set BT MAC address"); - - byte_input_set_result_callback( - byte_input, - bad_kb_scene_config_bt_mac_byte_input_callback, - NULL, - bad_kb, - bad_kb->bt_mac_buf, - sizeof(bad_kb->bt_mac_buf)); - - view_dispatcher_switch_to_view(bad_kb->view_dispatcher, BadKbAppViewByteInput); -} - -bool bad_kb_scene_config_bt_mac_on_event(void* context, SceneManagerEvent event) { - BadKbApp* bad_kb = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - consumed = true; - if(event.event == BadKbAppCustomEventByteInputDone) { - reverse_mac_addr(bad_kb->bt_mac_buf); - // Set user config and remember - memcpy(bad_kb->config.ble.mac, bad_kb->bt_mac_buf, sizeof(bad_kb->config.ble.mac)); - // Apply to ID config so its temporarily overridden - if(bad_kb->set_bt_id) { - memcpy( - bad_kb->id_config.ble.mac, - bad_kb->bt_mac_buf, - sizeof(bad_kb->id_config.ble.mac)); - } - bad_kb_config_refresh(bad_kb); - } - scene_manager_previous_scene(bad_kb->scene_manager); - } - return consumed; -} - -void bad_kb_scene_config_bt_mac_on_exit(void* context) { - BadKbApp* bad_kb = context; - ByteInput* byte_input = bad_kb->byte_input; - - byte_input_set_result_callback(byte_input, NULL, NULL, NULL, NULL, 0); - byte_input_set_header_text(byte_input, ""); -} diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_name.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_name.c deleted file mode 100644 index 67a92c6bf..000000000 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt_name.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../bad_kb_app_i.h" - -static void bad_kb_scene_config_bt_name_text_input_callback(void* context) { - BadKbApp* bad_kb = context; - - view_dispatcher_send_custom_event(bad_kb->view_dispatcher, BadKbAppCustomEventTextInputDone); -} - -void bad_kb_scene_config_bt_name_on_enter(void* context) { - BadKbApp* bad_kb = context; - TextInput* text_input = bad_kb->text_input; - - strlcpy( - bad_kb->bt_name_buf, - bad_kb->set_bt_id ? bad_kb->id_config.ble.name : bad_kb->config.ble.name, - sizeof(bad_kb->bt_name_buf)); - text_input_set_header_text(text_input, "Set BT device name"); - - text_input_set_result_callback( - text_input, - bad_kb_scene_config_bt_name_text_input_callback, - bad_kb, - bad_kb->bt_name_buf, - sizeof(bad_kb->bt_name_buf), - true); - - view_dispatcher_switch_to_view(bad_kb->view_dispatcher, BadKbAppViewTextInput); -} - -bool bad_kb_scene_config_bt_name_on_event(void* context, SceneManagerEvent event) { - BadKbApp* bad_kb = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - consumed = true; - if(event.event == BadKbAppCustomEventTextInputDone) { - // Set user config and remember - strlcpy(bad_kb->config.ble.name, bad_kb->bt_name_buf, sizeof(bad_kb->config.ble.name)); - // Apply to ID config so its temporarily overridden - if(bad_kb->set_bt_id) { - strlcpy( - bad_kb->id_config.ble.name, - bad_kb->bt_name_buf, - sizeof(bad_kb->id_config.ble.name)); - } - bad_kb_config_refresh(bad_kb); - } - scene_manager_previous_scene(bad_kb->scene_manager); - } - return consumed; -} - -void bad_kb_scene_config_bt_name_on_exit(void* context) { - BadKbApp* bad_kb = context; - TextInput* text_input = bad_kb->text_input; - - text_input_reset(text_input); -} diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_layout.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_layout.c index 5e655c54b..141635dd1 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_layout.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_layout.c @@ -29,9 +29,8 @@ static bool bad_kb_layout_select(BadKbApp* bad_kb) { void bad_kb_scene_config_layout_on_enter(void* context) { BadKbApp* bad_kb = context; - if(bad_kb_layout_select(bad_kb)) { - bad_kb_script_set_keyboard_layout(bad_kb->bad_kb_script, bad_kb->keyboard_layout); - } + bad_kb_layout_select(bad_kb); + scene_manager_previous_scene(bad_kb->scene_manager); } diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_name.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_name.c index 0cd9da1c8..d7b3ebd5c 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_name.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_name.c @@ -1,9 +1,13 @@ #include "../bad_kb_app_i.h" +enum TextInputResult { + TextInputResultOk, +}; + static void bad_kb_scene_config_usb_name_text_input_callback(void* context) { BadKbApp* bad_kb = context; - view_dispatcher_send_custom_event(bad_kb->view_dispatcher, BadKbAppCustomEventTextInputDone); + view_dispatcher_send_custom_event(bad_kb->view_dispatcher, TextInputResultOk); } void bad_kb_scene_config_usb_name_on_enter(void* context) { @@ -12,14 +16,12 @@ void bad_kb_scene_config_usb_name_on_enter(void* context) { if(scene_manager_get_scene_state(bad_kb->scene_manager, BadKbSceneConfigUsbName)) { strlcpy( - bad_kb->usb_name_buf, - bad_kb->set_usb_id ? bad_kb->id_config.usb.manuf : bad_kb->config.usb.manuf, - sizeof(bad_kb->usb_name_buf)); + bad_kb->usb_name_buf, bad_kb->script_hid_cfg.usb.manuf, sizeof(bad_kb->usb_name_buf)); text_input_set_header_text(text_input, "Set USB manufacturer name"); } else { strlcpy( bad_kb->usb_name_buf, - bad_kb->set_usb_id ? bad_kb->id_config.usb.product : bad_kb->config.usb.product, + bad_kb->script_hid_cfg.usb.product, sizeof(bad_kb->usb_name_buf)); text_input_set_header_text(text_input, "Set USB product name"); } @@ -41,35 +43,30 @@ bool bad_kb_scene_config_usb_name_on_event(void* context, SceneManagerEvent even if(event.type == SceneManagerEventTypeCustom) { consumed = true; - if(event.event == BadKbAppCustomEventTextInputDone) { + if(event.event == TextInputResultOk) { if(scene_manager_get_scene_state(bad_kb->scene_manager, BadKbSceneConfigUsbName)) { - // Set user config and remember + // Apply to current script config strlcpy( - bad_kb->config.usb.manuf, + bad_kb->script_hid_cfg.usb.manuf, bad_kb->usb_name_buf, - sizeof(bad_kb->config.usb.manuf)); - // Apply to ID config so its temporarily overridden - if(bad_kb->set_usb_id) { - strlcpy( - bad_kb->id_config.usb.manuf, - bad_kb->usb_name_buf, - sizeof(bad_kb->id_config.usb.manuf)); - } + sizeof(bad_kb->script_hid_cfg.usb.manuf)); + // Set in user config to save in settings file + strlcpy( + bad_kb->user_hid_cfg.usb.manuf, + bad_kb->usb_name_buf, + sizeof(bad_kb->user_hid_cfg.usb.manuf)); } else { - // Set user config and remember + // Apply to current script config strlcpy( - bad_kb->config.usb.product, + bad_kb->script_hid_cfg.usb.product, bad_kb->usb_name_buf, - sizeof(bad_kb->config.usb.product)); - // Apply to ID config so its temporarily overridden - if(bad_kb->set_usb_id) { - strlcpy( - bad_kb->id_config.usb.product, - bad_kb->usb_name_buf, - sizeof(bad_kb->id_config.usb.product)); - } + sizeof(bad_kb->script_hid_cfg.usb.product)); + // Set in user config to save in settings file + strlcpy( + bad_kb->user_hid_cfg.usb.product, + bad_kb->usb_name_buf, + sizeof(bad_kb->user_hid_cfg.usb.product)); } - bad_kb_config_refresh(bad_kb); } scene_manager_previous_scene(bad_kb->scene_manager); } diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_vidpid.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_vidpid.c index 43b131465..b4c6293ae 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_vidpid.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb_vidpid.c @@ -1,22 +1,21 @@ #include "../bad_kb_app_i.h" +enum ByteInputResult { + ByteInputResultOk, +}; + void bad_kb_scene_config_usb_vidpid_byte_input_callback(void* context) { BadKbApp* bad_kb = context; - view_dispatcher_send_custom_event(bad_kb->view_dispatcher, BadKbAppCustomEventByteInputDone); + view_dispatcher_send_custom_event(bad_kb->view_dispatcher, ByteInputResultOk); } void bad_kb_scene_config_usb_vidpid_on_enter(void* context) { BadKbApp* bad_kb = context; ByteInput* byte_input = bad_kb->byte_input; - if(bad_kb->set_usb_id) { - bad_kb->usb_vidpid_buf[0] = __REVSH(bad_kb->id_config.usb.vid); - bad_kb->usb_vidpid_buf[1] = __REVSH(bad_kb->id_config.usb.pid); - } else { - bad_kb->usb_vidpid_buf[0] = __REVSH(bad_kb->config.usb.vid); - bad_kb->usb_vidpid_buf[1] = __REVSH(bad_kb->config.usb.pid); - } + bad_kb->usb_vidpid_buf[0] = __REVSH(bad_kb->script_hid_cfg.usb.vid); + bad_kb->usb_vidpid_buf[1] = __REVSH(bad_kb->script_hid_cfg.usb.pid); byte_input_set_header_text(byte_input, "Set USB VID:PID"); byte_input_set_result_callback( @@ -36,16 +35,13 @@ bool bad_kb_scene_config_usb_vidpid_on_event(void* context, SceneManagerEvent ev if(event.type == SceneManagerEventTypeCustom) { consumed = true; - if(event.event == BadKbAppCustomEventByteInputDone) { - // Set user config and remember - bad_kb->config.usb.vid = __REVSH(bad_kb->usb_vidpid_buf[0]); - bad_kb->config.usb.pid = __REVSH(bad_kb->usb_vidpid_buf[1]); - // Apply to ID config so its temporarily overridden - if(bad_kb->set_usb_id) { - bad_kb->id_config.usb.vid = bad_kb->config.usb.vid; - bad_kb->id_config.usb.pid = bad_kb->config.usb.pid; - } - bad_kb_config_refresh(bad_kb); + if(event.event == ByteInputResultOk) { + // Apply to current script config + bad_kb->script_hid_cfg.usb.vid = __REVSH(bad_kb->usb_vidpid_buf[0]); + bad_kb->script_hid_cfg.usb.pid = __REVSH(bad_kb->usb_vidpid_buf[1]); + // Set in user config to save in settings file + bad_kb->user_hid_cfg.usb.vid = bad_kb->script_hid_cfg.usb.vid; + bad_kb->user_hid_cfg.usb.pid = bad_kb->script_hid_cfg.usb.pid; } scene_manager_previous_scene(bad_kb->scene_manager); } diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_confirm_unpair.c b/applications/main/bad_kb/scenes/bad_kb_scene_confirm_unpair.c new file mode 100644 index 000000000..d9c57d1a9 --- /dev/null +++ b/applications/main/bad_kb/scenes/bad_kb_scene_confirm_unpair.c @@ -0,0 +1,49 @@ +#include "../bad_kb_app_i.h" + +void bad_kb_scene_confirm_unpair_widget_callback( + GuiButtonType type, + InputType input_type, + void* context) { + UNUSED(input_type); + SceneManagerEvent event = {.type = SceneManagerEventTypeCustom, .event = type}; + bad_kb_scene_confirm_unpair_on_event(context, event); +} + +void bad_kb_scene_confirm_unpair_on_enter(void* context) { + BadKbApp* bad_kb = context; + Widget* widget = bad_kb->widget; + + widget_add_button_element( + widget, GuiButtonTypeLeft, "Cancel", bad_kb_scene_confirm_unpair_widget_callback, context); + widget_add_button_element( + widget, GuiButtonTypeRight, "Unpair", bad_kb_scene_confirm_unpair_widget_callback, context); + + widget_add_text_box_element( + widget, 0, 0, 128, 64, AlignCenter, AlignTop, "\e#Unpair the Device?\e#\n", false); + + view_dispatcher_switch_to_view(bad_kb->view_dispatcher, BadKbAppViewWidget); +} + +bool bad_kb_scene_confirm_unpair_on_event(void* context, SceneManagerEvent event) { + BadKbApp* bad_kb = context; + SceneManager* scene_manager = bad_kb->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + if(event.event == GuiButtonTypeRight) { + scene_manager_next_scene(scene_manager, BadKbSceneUnpairDone); + } else if(event.event == GuiButtonTypeLeft) { + scene_manager_previous_scene(scene_manager); + } + } + + return consumed; +} + +void bad_kb_scene_confirm_unpair_on_exit(void* context) { + BadKbApp* bad_kb = context; + Widget* widget = bad_kb->widget; + + widget_reset(widget); +} diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_error.c b/applications/main/bad_kb/scenes/bad_kb_scene_error.c index b0edac36c..5df6344f1 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_error.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_error.c @@ -1,5 +1,9 @@ #include "../bad_kb_app_i.h" +typedef enum { + BadKbCustomEventErrorBack, +} BadKbCustomEvent; + static void bad_kb_scene_error_event_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); 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 cefb6f1de..6f3e32267 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 @@ -25,11 +25,6 @@ static bool bad_kb_file_select(BadKbApp* bad_kb) { furi_record_close(RECORD_DIALOGS); if(res == DialogMessageButtonRight) { storage_common_migrate(storage, EXT_PATH("badkb"), BAD_KB_APP_BASE_FOLDER); - if(bad_kb->conn_init_thread) { - furi_thread_join(bad_kb->conn_init_thread); - } - bad_kb_load_settings(bad_kb); - bad_kb_config_adjust(&bad_kb->config); } } storage_simply_mkdir(storage, BAD_KB_APP_BASE_FOLDER); @@ -58,10 +53,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); - bad_kb_script_set_keyboard_layout(bad_kb->bad_kb_script, bad_kb->keyboard_layout); - + scene_manager_set_scene_state(bad_kb->scene_manager, BadKbSceneWork, true); scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneWork); } else { view_dispatcher_stop(bad_kb->view_dispatcher); diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_unpair_done.c b/applications/main/bad_kb/scenes/bad_kb_scene_unpair_done.c new file mode 100644 index 000000000..ace7f90b6 --- /dev/null +++ b/applications/main/bad_kb/scenes/bad_kb_scene_unpair_done.c @@ -0,0 +1,39 @@ +#include "../bad_kb_app_i.h" + +static void bad_kb_scene_unpair_done_popup_callback(void* context) { + BadKbApp* bad_kb = context; + scene_manager_search_and_switch_to_previous_scene(bad_kb->scene_manager, BadKbSceneConfig); +} + +void bad_kb_scene_unpair_done_on_enter(void* context) { + BadKbApp* bad_kb = context; + Popup* popup = bad_kb->popup; + + bad_kb_hid_ble_remove_pairing(); + + popup_set_icon(popup, 48, 4, &I_DolphinDone_80x58); + popup_set_header(popup, "Done", 20, 19, AlignLeft, AlignBottom); + popup_set_callback(popup, bad_kb_scene_unpair_done_popup_callback); + popup_set_context(popup, bad_kb); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(bad_kb->view_dispatcher, BadKbAppViewPopup); +} + +bool bad_kb_scene_unpair_done_on_event(void* context, SceneManagerEvent event) { + BadKbApp* bad_kb = context; + UNUSED(bad_kb); + UNUSED(event); + bool consumed = false; + + return consumed; +} + +void bad_kb_scene_unpair_done_on_exit(void* context) { + BadKbApp* bad_kb = context; + Popup* popup = bad_kb->popup; + UNUSED(popup); + + popup_reset(popup); +} diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_work.c b/applications/main/bad_kb/scenes/bad_kb_scene_work.c index f2e1fd2da..5d568b1ef 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_work.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_work.c @@ -17,6 +17,9 @@ bool bad_kb_scene_work_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == InputKeyLeft) { if(bad_kb_view_is_idle_state(app->bad_kb_view)) { + bad_kb_script_close(app->bad_kb_script); + app->bad_kb_script = NULL; + scene_manager_next_scene(app->scene_manager, BadKbSceneConfig); } consumed = true; @@ -24,11 +27,23 @@ bool bad_kb_scene_work_on_event(void* context, SceneManagerEvent event) { bad_kb_script_start_stop(app->bad_kb_script); consumed = true; } else if(event.event == InputKeyRight) { - bad_kb_script_pause_resume(app->bad_kb_script); + if(bad_kb_view_is_idle_state(app->bad_kb_view)) { + bad_kb_set_interface( + app, + app->interface == BadKbHidInterfaceBle ? BadKbHidInterfaceUsb : + BadKbHidInterfaceBle); + bad_kb_script_close(app->bad_kb_script); + app->bad_kb_script = bad_kb_script_open( + app->file_path, &app->interface, &app->script_hid_cfg, false); + bad_kb_script_set_keyboard_layout(app->bad_kb_script, app->keyboard_layout); + } else { + bad_kb_script_pause_resume(app->bad_kb_script); + } consumed = true; } } else if(event.type == SceneManagerEventTypeTick) { bad_kb_view_set_state(app->bad_kb_view, bad_kb_script_get_state(app->bad_kb_script)); + bad_kb_view_set_interface(app->bad_kb_view, app->interface); } return consumed; } @@ -36,6 +51,22 @@ bool bad_kb_scene_work_on_event(void* context, SceneManagerEvent event) { void bad_kb_scene_work_on_enter(void* context) { BadKbApp* app = context; + bad_kb_view_set_interface(app->bad_kb_view, app->interface); + + // Opening script the first time: + // - copy user settings as base config + // - load ID/BLE_ID/BT_ID config if present + // Then disable this until next script selected so user can customize options + bool first_script_load = scene_manager_get_scene_state(app->scene_manager, BadKbSceneWork); + if(first_script_load) { + memcpy(&app->script_hid_cfg, &app->user_hid_cfg, sizeof(app->script_hid_cfg)); + scene_manager_set_scene_state(app->scene_manager, BadKbSceneWork, false); + } + // Interface and config are passed as pointers as ID/BLE_ID/BT_ID config can modify them + app->bad_kb_script = bad_kb_script_open( + app->file_path, &app->interface, &app->script_hid_cfg, first_script_load); + bad_kb_script_set_keyboard_layout(app->bad_kb_script, app->keyboard_layout); + FuriString* file_name; file_name = furi_string_alloc(); path_extract_filename(app->file_path, file_name, true); diff --git a/applications/main/bad_kb/views/bad_kb_view.c b/applications/main/bad_kb/views/bad_kb_view.c index 72064190a..869d8713b 100644 --- a/applications/main/bad_kb/views/bad_kb_view.c +++ b/applications/main/bad_kb/views/bad_kb_view.c @@ -1,4 +1,3 @@ -#include "../bad_kb_app_i.h" #include "bad_kb_view.h" #include "../helpers/ducky_script.h" #include @@ -20,17 +19,14 @@ typedef struct { BadKbState state; bool pause_wait; uint8_t anim_frame; + BadKbHidInterface interface; + Bt* bt; } BadKbModel; static void bad_kb_draw_callback(Canvas* canvas, void* _model) { BadKbModel* model = _model; - BadKbWorkerState state = model->state.state; - FuriString* disp_str = furi_string_alloc_set( - state == BadKbStateInit ? "( . . . )" : - model->state.is_bt ? "(BT) " : - "(USB) "); - furi_string_cat_str(disp_str, model->file_name); + FuriString* disp_str = furi_string_alloc_set(model->file_name); elements_string_fit_width(canvas, disp_str, 128 - 2); canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 2, 8, furi_string_get_cstr(disp_str)); @@ -40,8 +36,8 @@ static void bad_kb_draw_callback(Canvas* canvas, void* _model) { } else { furi_string_printf(disp_str, "(%s)", model->layout); } - if(model->state.pin) { - furi_string_cat_printf(disp_str, " PIN: %ld", model->state.pin); + if(model->interface == BadKbHidInterfaceBle && model->bt->pin_code) { + furi_string_cat_printf(disp_str, " PIN: %ld", model->bt->pin_code); } else { uint32_t e = model->state.elapsed; furi_string_cat_printf(disp_str, " %02lu:%02lu.%ld", e / 60 / 1000, e / 1000, e % 1000); @@ -52,12 +48,19 @@ static void bad_kb_draw_callback(Canvas* canvas, void* _model) { furi_string_reset(disp_str); - canvas_draw_icon(canvas, 22, 24, &I_UsbTree_48x22); + if(model->interface == BadKbHidInterfaceBle) { + canvas_draw_icon(canvas, 22, 24, &I_Bad_BLE_48x22); + } else { + canvas_draw_icon(canvas, 22, 24, &I_UsbTree_48x22); + } + + BadKbWorkerState state = model->state.state; if((state == BadKbStateIdle) || (state == BadKbStateDone) || (state == BadKbStateNotConnected)) { elements_button_center(canvas, "Run"); elements_button_left(canvas, "Config"); + elements_button_right(canvas, model->interface == BadKbHidInterfaceBle ? "USB" : "BLE"); } else if((state == BadKbStateRunning) || (state == BadKbStateDelay)) { elements_button_center(canvas, "Stop"); if(!model->pause_wait) { @@ -220,11 +223,15 @@ BadKb* bad_kb_view_alloc(void) { view_set_draw_callback(bad_kb->view, bad_kb_draw_callback); view_set_input_callback(bad_kb->view, bad_kb_input_callback); + with_view_model( + bad_kb->view, BadKbModel * model, { model->bt = furi_record_open(RECORD_BT); }, true); + return bad_kb; } void bad_kb_view_free(BadKb* bad_kb) { furi_assert(bad_kb); + furi_record_close(RECORD_BT); view_free(bad_kb->view); free(bad_kb); } @@ -262,14 +269,6 @@ void bad_kb_view_set_layout(BadKb* bad_kb, const char* layout) { void bad_kb_view_set_state(BadKb* bad_kb, BadKbState* st) { furi_assert(st); - uint32_t pin = 0; - if(bad_kb->context != NULL) { - BadKbApp* app = bad_kb->context; - if(app->bt != NULL) { - pin = app->bt->pin; - } - } - st->pin = pin; with_view_model( bad_kb->view, BadKbModel * model, @@ -283,6 +282,10 @@ void bad_kb_view_set_state(BadKb* bad_kb, BadKbState* st) { true); } +void bad_kb_view_set_interface(BadKb* bad_kb, BadKbHidInterface interface) { + with_view_model(bad_kb->view, BadKbModel * model, { model->interface = interface; }, true); +} + bool bad_kb_view_is_idle_state(BadKb* bad_kb) { bool is_idle = false; with_view_model( diff --git a/applications/main/bad_kb/views/bad_kb_view.h b/applications/main/bad_kb/views/bad_kb_view.h index 427862eb3..6f7669226 100644 --- a/applications/main/bad_kb/views/bad_kb_view.h +++ b/applications/main/bad_kb/views/bad_kb_view.h @@ -20,4 +20,6 @@ void bad_kb_view_set_layout(BadKb* bad_kb, const char* layout); void bad_kb_view_set_state(BadKb* bad_kb, BadKbState* st); +void bad_kb_view_set_interface(BadKb* bad_kb, BadKbHidInterface interface); + bool bad_kb_view_is_idle_state(BadKb* bad_kb); diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index a2bb29e11..a99568da5 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -186,8 +186,6 @@ Bt* bt_alloc(void) { // API evnent bt->api_event = furi_event_flag_alloc(); - bt->pin = 0; - return bt; } @@ -264,7 +262,6 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { furi_assert(context); Bt* bt = context; bool ret = false; - bt->pin = 0; bool do_update_status = false; bool current_profile_is_serial = furi_hal_bt_check_profile_type(bt->current_profile, ble_profile_serial); @@ -303,14 +300,12 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { do_update_status = true; ret = true; } else if(event.type == GapEventTypePinCodeShow) { - bt->pin = event.data.pin_code; BtMessage message = { .type = BtMessageTypePinCodeShow, .data.pin_code = event.data.pin_code}; furi_check( furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); ret = true; } else if(event.type == GapEventTypePinCodeVerify) { - bt->pin = event.data.pin_code; ret = bt_pin_code_verify_event_handler(bt, event.data.pin_code); } else if(event.type == GapEventTypeUpdateMTU) { bt->max_packet_size = event.data.max_packet_size; diff --git a/applications/services/bt/bt_service/bt_i.h b/applications/services/bt/bt_service/bt_i.h index e5578ff22..2ee5e971a 100644 --- a/applications/services/bt/bt_service/bt_i.h +++ b/applications/services/bt/bt_service/bt_i.h @@ -87,6 +87,5 @@ struct Bt { BtStatusChangedCallback status_changed_cb; void* status_changed_ctx; - uint32_t pin; bool suppress_pin_screen; }; diff --git a/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_confirm.c b/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_confirm.c index cfc945751..86088e28c 100644 --- a/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_confirm.c +++ b/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_confirm.c @@ -1,6 +1,6 @@ #include "../bt_settings_app.h" #include -#include +#include void bt_settings_scene_forget_dev_confirm_dialog_callback(DialogExResult result, void* context) { furi_assert(context); @@ -35,7 +35,7 @@ bool bt_settings_scene_forget_dev_confirm_on_event(void* context, SceneManagerEv // also remove keys for apps const char* keys_paths[] = { - BAD_KB_KEYS_PATH, + EXT_PATH("apps_data/bad_kb/.bt_hid.keys"), EXT_PATH("apps_data/hid_ble/.bt_hid.keys"), EXT_PATH("apps_data/air_mouse/.bt_hid.keys"), EXT_PATH("apps_data/vgm_air_mouse/.bt_hid.keys"), diff --git a/assets/icons/BadKb/Bad_BLE_48x22.png b/assets/icons/BadKb/Bad_BLE_48x22.png new file mode 100644 index 0000000000000000000000000000000000000000..5f6fa6f4694972b23d9d0a219f404f16c18f6403 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^20$#v2qYNR^(cYp2u~Nskcv6JXAQX;3mdKI;Vst091lAb^rhX literal 0 HcmV?d00001 diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index b95f47832..eee586718 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -3949,6 +3949,7 @@ Variable,+,I_Auth_62x31,const Icon, Variable,+,I_BLE_Pairing_128x64,const Icon, Variable,+,I_BLE_beacon_7x8,const Icon, Variable,+,I_Background_128x11,const Icon, +Variable,+,I_Bad_BLE_48x22,const Icon, Variable,+,I_BatteryBody_52x28,const Icon, Variable,+,I_Battery_16x16,const Icon, Variable,+,I_Battery_25x8,const Icon,