BadKB completely rework connection handling

Proper distinction between user and ID/BT_ID configs
All init and deinit handled centrally in a cleaner way
Moved USB HID config to be handled this way too
Changing config doesn't reload the script file, less error/crash prone
Remember MAC is now serial MAC +2, like bt remote has serial MAC +1
This commit is contained in:
Willy-JL
2023-06-11 21:26:43 +01:00
parent 6b886858c1
commit e1c12282cc
7 changed files with 210 additions and 233 deletions

View File

@@ -89,41 +89,6 @@ static void bad_kb_save_settings(BadKbApp* app) {
furi_record_close(RECORD_STORAGE);
}
void bad_kb_reload_worker(BadKbApp* app) {
bad_kb_script_close(app->bad_kb_script);
app->bad_kb_script = bad_kb_script_open(app->file_path, app->is_bt ? app->bt : NULL, app);
bad_kb_script_set_keyboard_layout(app->bad_kb_script, app->keyboard_layout);
}
int32_t bad_kb_config_switch_mode(BadKbApp* app) {
if(!app->is_bt) furi_hal_bt_stop_advertising();
XTREME_SETTINGS()->bad_bt = app->is_bt;
XTREME_SETTINGS_SAVE();
bad_kb_reload_worker(app);
if(app->is_bt) furi_hal_bt_start_advertising();
bad_kb_config_refresh_menu(app);
return 0;
}
void bad_kb_config_refresh_menu(BadKbApp* app) {
scene_manager_next_scene(app->scene_manager, BadKbSceneConfig);
scene_manager_previous_scene(app->scene_manager);
}
void bad_kb_config_switch_remember_mode(BadKbApp* app) {
if(app->bt_remember) {
furi_hal_bt_set_profile_pairing_method(
FuriHalBtProfileHidKeyboard, GapPairingPinCodeVerifyYesNo);
bt_set_profile_mac_address(app->bt, (uint8_t*)&BAD_KB_BOUND_MAC_ADDRESS);
bt_enable_peer_key_update(app->bt);
} else {
furi_hal_bt_set_profile_pairing_method(FuriHalBtProfileHidKeyboard, GapPairingNone);
bt_set_profile_mac_address(app->bt, app->config.bt_mac);
bt_disable_peer_key_update(app->bt);
}
bad_kb_reload_worker(app);
}
BadKbApp* bad_kb_app_alloc(char* arg) {
BadKbApp* app = malloc(sizeof(BadKbApp));
@@ -165,6 +130,8 @@ BadKbApp* bad_kb_app_alloc(char* arg) {
app->bt->suppress_pin_screen = true;
app->is_bt = XTREME_SETTINGS()->bad_bt;
app->bt_remember = XTREME_SETTINGS()->bad_bt_remember;
memcpy(BAD_KB_BOUND_MAC, furi_hal_version_get_ble_mac(), BAD_KB_MAC_LEN);
BAD_KB_BOUND_MAC[2] += 2;
// Custom Widget
app->widget = widget_alloc();
@@ -193,7 +160,7 @@ BadKbApp* bad_kb_app_alloc(char* arg) {
app->conn_mode = BadKbConnModeNone;
app->conn_init_thread =
furi_thread_alloc_ex("BadKbConnInit", 1024, (FuriThreadCallback)bad_kb_conn_refresh, app);
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);
@@ -247,6 +214,7 @@ void bad_kb_app_free(BadKbApp* app) {
app->conn_init_thread = NULL;
}
bad_kb_conn_reset(app);
if(app->hid_cfg) free(app->hid_cfg);
// Close records
furi_record_close(RECORD_GUI);

View File

@@ -25,5 +25,3 @@ typedef enum {
BadKbAppViewByteInput,
BadKbAppViewTextInput
} BadKbAppView;
void bad_kb_config_switch_remember_mode(BadKbApp* app);

View File

@@ -11,9 +11,13 @@
#include "ducky_script_i.h"
#include <dolphin/dolphin.h>
#include <toolbox/hex.h>
#include <xtreme.h>
#include "../scenes/bad_kb_scene.h"
const uint8_t BAD_KB_BOUND_MAC_ADDRESS[BAD_KB_MAC_LEN] = {0x41, 0x4a, 0xef, 0xb6, 0xa9, 0xd4};
const uint8_t BAD_KB_EMPTY_MAC_ADDRESS[BAD_KB_MAC_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t BAD_KB_EMPTY_MAC[BAD_KB_MAC_LEN] = FURI_HAL_BT_EMPTY_MAC_ADDR;
// Adjusts to serial MAC +2 in app init
uint8_t BAD_KB_BOUND_MAC[BAD_KB_MAC_LEN] = FURI_HAL_BT_EMPTY_MAC_ADDR;
#define TAG "BadKB"
#define WORKER_TAG TAG "Worker"
@@ -305,51 +309,51 @@ static int32_t ducky_parse_line(BadKbScript* bad_kb, FuriString* line) {
}
static bool ducky_set_usb_id(BadKbScript* bad_kb, const char* line) {
if(sscanf(line, "%lX:%lX", &bad_kb->hid_cfg.vid, &bad_kb->hid_cfg.pid) == 2) {
bad_kb->hid_cfg.manuf[0] = '\0';
bad_kb->hid_cfg.product[0] = '\0';
FuriHalUsbHidConfig* cfg = &bad_kb->app->id_config.usb_cfg;
if(sscanf(line, "%lX:%lX", &cfg->vid, &cfg->pid) == 2) {
cfg->manuf[0] = '\0';
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]",
bad_kb->hid_cfg.manuf,
bad_kb->hid_cfg.product);
sscanf(&line[id_len + 1], "%31[^\r\n:]:%31[^\r\n]", cfg->manuf, cfg->product);
}
FURI_LOG_D(
WORKER_TAG,
"set id: %04lX:%04lX mfr:%s product:%s",
bad_kb->hid_cfg.vid,
bad_kb->hid_cfg.pid,
bad_kb->hid_cfg.manuf,
bad_kb->hid_cfg.product);
"set usb id: %04lX:%04lX mfr:%s product:%s",
cfg->vid,
cfg->pid,
cfg->manuf,
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;
size_t line_len = strlen(line);
size_t mac_len = BAD_KB_MAC_LEN * 3;
size_t mac_len = BAD_KB_MAC_LEN * 3; // 2 text chars + separator per byte
if(line_len < mac_len + 1) return false; // MAC + at least 1 char for name
uint8_t mac[BAD_KB_MAC_LEN];
for(size_t i = 0; i < BAD_KB_MAC_LEN; i++) {
char a = line[i * 3];
char b = line[i * 3 + 1];
if((a < 'A' && a > 'F') || (a < '0' && a > '9') || (b < 'A' && b > 'F') ||
(b < '0' && b > '9') || !hex_char_to_uint8(a, b, &mac[i])) {
(b < '0' && b > '9') || !hex_char_to_uint8(a, b, &cfg->bt_mac[i])) {
return false;
}
}
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, line + mac_len);
bt_set_profile_mac_address(bad_kb->bt, mac);
strlcpy(cfg->bt_name, line + mac_len, BAD_KB_NAME_LEN);
FURI_LOG_D(WORKER_TAG, "set bt id: %s", line);
return true;
}
static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) {
static void ducky_script_preload(BadKbScript* bad_kb, File* script_file) {
BadKbApp* app = bad_kb->app;
uint8_t ret = 0;
uint32_t line_len = 0;
@@ -376,81 +380,23 @@ static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) {
}
} while(ret > 0);
const char* line_tmp = furi_string_get_cstr(bad_kb->line);
if(bad_kb->app->switch_mode_thread) {
furi_thread_join(bad_kb->app->switch_mode_thread);
furi_thread_free(bad_kb->app->switch_mode_thread);
bad_kb->app->switch_mode_thread = NULL;
}
// Looking for ID or BT_ID command at first line
bad_kb->set_usb_id = false;
bad_kb->set_bt_id = false;
bad_kb->has_usb_id = strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0;
bad_kb->has_bt_id = strncmp(line_tmp, ducky_cmd_bt_id, strlen(ducky_cmd_bt_id)) == 0;
if(bad_kb->has_usb_id) {
if(bad_kb->bt) {
bad_kb->app->is_bt = false;
bad_kb->app->switch_mode_thread = furi_thread_alloc_ex(
"BadKbSwitchMode",
1024,
(FuriThreadCallback)bad_kb_config_switch_mode,
bad_kb->app);
furi_thread_start(bad_kb->app->switch_mode_thread);
return false;
}
bad_kb->set_usb_id = ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1]);
} else if(bad_kb->has_bt_id) {
if(!bad_kb->bt) {
bad_kb->app->is_bt = true;
bad_kb->app->switch_mode_thread = furi_thread_alloc_ex(
"BadKbSwitchMode",
1024,
(FuriThreadCallback)bad_kb_config_switch_mode,
bad_kb->app);
furi_thread_start(bad_kb->app->switch_mode_thread);
return false;
}
if(!bad_kb->app->bt_remember) {
bad_kb->set_bt_id = ducky_set_bt_id(bad_kb, &line_tmp[strlen(ducky_cmd_bt_id) + 1]);
}
}
bad_kb_config_refresh_menu(bad_kb->app);
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->bt) {
if(!bad_kb->set_bt_id) {
const char* bt_name = bad_kb->app->config.bt_name;
const uint8_t* bt_mac = bad_kb->app->bt_remember ?
(uint8_t*)&BAD_KB_BOUND_MAC_ADDRESS :
bad_kb->app->config.bt_mac;
bool reset_name = strncmp(
bt_name,
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard),
BAD_KB_NAME_LEN);
bool reset_mac = memcmp(
bt_mac,
furi_hal_bt_get_profile_mac_addr(FuriHalBtProfileHidKeyboard),
BAD_KB_MAC_LEN);
if(reset_name && reset_mac) {
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, bt_name);
} else if(reset_name) {
bt_set_profile_adv_name(bad_kb->bt, bt_name);
}
if(reset_mac) {
bt_set_profile_mac_address(bad_kb->bt, bt_mac);
}
}
} else {
if(bad_kb->set_usb_id) {
furi_check(furi_hal_usb_set_config(&usb_hid, &bad_kb->hid_cfg));
} else {
furi_check(furi_hal_usb_set_config(&usb_hid, NULL));
}
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]);
}
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) {
@@ -562,64 +508,68 @@ static uint32_t bad_kb_flags_get(uint32_t flags_mask, uint32_t timeout) {
return flags;
}
int32_t bad_kb_conn_refresh(BadKbApp* app) {
bool bt = app->is_bt;
int32_t bad_kb_conn_apply(BadKbApp* app) {
if(app->is_bt) {
// Shorthands so this bs is readable
BadKbConfig* prev = &app->prev_config;
BadKbConfig* cfg = app->set_bt_id ? &app->id_config : &app->config;
FuriHalBtProfile kbd = FuriHalBtProfileHidKeyboard;
if(app->conn_mode != BadKbConnModeNone) bad_kb_conn_reset(app);
// Save prev config
strcpy(prev->bt_name, furi_hal_bt_get_profile_adv_name(kbd));
memcpy(prev->bt_mac, furi_hal_bt_get_profile_mac_addr(kbd), BAD_KB_MAC_LEN);
prev->bt_mode = furi_hal_bt_get_profile_pairing_method(kbd);
if(bt) {
strcpy(
app->prev_config.bt_name,
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard));
memcpy(
app->prev_config.bt_mac,
furi_hal_bt_get_profile_mac_addr(FuriHalBtProfileHidKeyboard),
BAD_KB_MAC_LEN);
app->prev_config.bt_mode =
furi_hal_bt_get_profile_pairing_method(FuriHalBtProfileHidKeyboard);
// Setup new config
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);
if(strcmp(app->config.bt_name, "") != 0) {
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, app->config.bt_name);
}
furi_hal_bt_set_profile_adv_name(kbd, cfg->bt_name);
if(app->bt_remember) {
furi_hal_bt_set_profile_mac_addr(
FuriHalBtProfileHidKeyboard, (uint8_t*)&BAD_KB_BOUND_MAC_ADDRESS);
furi_hal_bt_set_profile_pairing_method(
FuriHalBtProfileHidKeyboard, GapPairingPinCodeVerifyYesNo);
furi_hal_bt_set_profile_mac_addr(kbd, BAD_KB_BOUND_MAC);
furi_hal_bt_set_profile_pairing_method(kbd, GapPairingPinCodeVerifyYesNo);
} else {
if(memcmp(app->config.bt_mac, (uint8_t*)&BAD_KB_EMPTY_MAC_ADDRESS, BAD_KB_MAC_LEN) !=
0) {
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, app->config.bt_mac);
}
furi_hal_bt_set_profile_pairing_method(FuriHalBtProfileHidKeyboard, GapPairingNone);
furi_hal_bt_set_profile_mac_addr(kbd, cfg->bt_mac);
furi_hal_bt_set_profile_pairing_method(kbd, GapPairingNone);
}
// Set profile, restart BT, adjust defaults
furi_check(bt_set_profile(app->bt, BtProfileHidKeyboard));
// What was empty is now adjusted by furi_hal_bt so save the new defaults
if(strcmp(app->config.bt_name, "") == 0) {
strcpy(
app->config.bt_name,
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard));
}
if(memcmp(app->config.bt_mac, (uint8_t*)&BAD_KB_EMPTY_MAC_ADDRESS, BAD_KB_MAC_LEN) == 0) {
memcpy(
app->config.bt_mac,
furi_hal_bt_get_profile_mac_addr(FuriHalBtProfileHidKeyboard),
BAD_KB_MAC_LEN);
strcpy(app->config.bt_name, furi_hal_bt_get_profile_adv_name(kbd));
}
// Advertise even if BT is off in settings
furi_hal_bt_start_advertising();
// Toggle key callback after since BT restart resets it
if(app->bt_remember) {
bt_enable_peer_key_update(app->bt);
} else {
bt_disable_peer_key_update(app->bt);
}
furi_hal_bt_start_advertising();
app->conn_mode = BadKbConnModeBt;
} else {
// Save prev config (TODO: maybe also restore config context?)
app->prev_config.usb_mode = furi_hal_usb_get_config();
// Unlock RPC connections
furi_hal_usb_unlock();
furi_check(furi_hal_usb_set_config(NULL, NULL));
// Context will apply with set_config only if pointer address is different, so we use a copy
FuriHalUsbHidConfig* hid_cfg = malloc(sizeof(FuriHalUsbHidConfig));
memcpy(
hid_cfg,
app->set_usb_id ? &app->id_config.usb_cfg : &app->config.usb_cfg,
sizeof(FuriHalUsbHidConfig));
furi_check(furi_hal_usb_set_config(&usb_hid, hid_cfg));
if(app->hid_cfg) free(app->hid_cfg);
app->hid_cfg = hid_cfg;
app->conn_mode = BadKbConnModeUsb;
}
@@ -630,6 +580,7 @@ int32_t bad_kb_conn_refresh(BadKbApp* app) {
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_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, app->prev_config.bt_name);
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, app->prev_config.bt_mac);
@@ -645,6 +596,101 @@ void bad_kb_conn_reset(BadKbApp* app) {
app->conn_mode = BadKbConnModeNone;
}
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;
// MAC is adjusted by furi_hal_bt, adjust here too so it matches after applying
const uint8_t* normal_mac = furi_hal_version_get_ble_mac();
uint8_t empty_mac[BAD_KB_MAC_LEN] = FURI_HAL_BT_EMPTY_MAC_ADDR;
uint8_t default_mac[BAD_KB_MAC_LEN] = FURI_HAL_BT_DEFAULT_MAC_ADDR;
if(memcmp(cfg->bt_mac, empty_mac, BAD_KB_MAC_LEN) == 0 ||
memcmp(cfg->bt_mac, normal_mac, BAD_KB_MAC_LEN) == 0 ||
memcmp(cfg->bt_mac, default_mac, BAD_KB_MAC_LEN) == 0) {
memcpy(cfg->bt_mac, normal_mac, BAD_KB_MAC_LEN);
cfg->bt_mac[2]++;
}
if(app->conn_mode != BadKbConnModeBt) {
apply = true;
bad_kb_conn_reset(app);
} else {
apply = apply || strncmp(
cfg->bt_name,
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard),
BAD_KB_NAME_LEN);
apply = apply || memcmp(
app->bt_remember ? BAD_KB_BOUND_MAC : cfg->bt_mac,
furi_hal_bt_get_profile_mac_addr(FuriHalBtProfileHidKeyboard),
BAD_KB_MAC_LEN);
}
} else {
FuriHalUsbHidConfig* cfg = app->set_usb_id ? &app->id_config.usb_cfg :
&app->config.usb_cfg;
if(app->conn_mode != BadKbConnModeUsb) {
apply = true;
bad_kb_conn_reset(app);
} else {
void* ctx;
if(furi_hal_usb_get_config() == &usb_hid &&
(ctx = furi_hal_usb_get_config_context()) != NULL) {
FuriHalUsbHidConfig* cur = ctx;
apply = apply || cfg->vid != cur->vid;
apply = apply || cfg->pid != cur->pid;
apply = apply || strncmp(cfg->manuf, cur->manuf, sizeof(cur->manuf));
apply = apply || strncmp(cfg->product, cur->product, sizeof(cur->product));
} else {
apply = true;
}
}
}
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);
// Update settings
XtremeSettings* xtreme_settings = XTREME_SETTINGS();
if(xtreme_settings->bad_bt != app->is_bt ||
xtreme_settings->bad_bt_remember != app->bt_remember) {
xtreme_settings->bad_bt = app->is_bt;
xtreme_settings->bad_bt_remember = app->bt_remember;
XTREME_SETTINGS_SAVE();
}
}
static int32_t bad_kb_worker(void* context) {
BadKbScript* bad_kb = context;
@@ -658,20 +704,6 @@ static int32_t bad_kb_worker(void* context) {
bad_kb->line_prev = furi_string_alloc();
bad_kb->string_print = furi_string_alloc();
if(bad_kb->app->conn_init_thread) {
furi_thread_join(bad_kb->app->conn_init_thread);
furi_thread_free(bad_kb->app->conn_init_thread);
bad_kb->app->conn_init_thread = NULL;
}
if(bad_kb->bt) {
if(bad_kb->app->conn_mode != BadKbConnModeBt) bad_kb_conn_refresh(bad_kb->app);
bt_set_status_changed_callback(bad_kb->bt, bad_kb_bt_hid_state_callback, bad_kb);
} else {
if(bad_kb->app->conn_mode != BadKbConnModeUsb) bad_kb_conn_refresh(bad_kb->app);
furi_hal_hid_set_state_callback(bad_kb_usb_hid_state_callback, bad_kb);
}
while(1) {
if(worker_state == BadKbStateInit) { // State: initialization
FURI_LOG_D(WORKER_TAG, "init start");
@@ -680,20 +712,10 @@ static int32_t bad_kb_worker(void* context) {
furi_string_get_cstr(bad_kb->file_path),
FSAM_READ,
FSOM_OPEN_EXISTING)) {
if((ducky_script_preload(bad_kb, script_file)) && (bad_kb->st.line_nb > 0)) {
if(bad_kb->bt) {
if(furi_hal_bt_is_connected()) {
worker_state = BadKbStateIdle; // Ready to run
} else {
worker_state = BadKbStateNotConnected; // Not connected
}
} else {
if(furi_hal_hid_is_connected()) {
worker_state = BadKbStateIdle; // Ready to run
} else {
worker_state = BadKbStateNotConnected; // Not connected
}
}
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
} else {
worker_state = BadKbStateScriptError; // Script preload error
}
@@ -989,11 +1011,8 @@ static int32_t bad_kb_worker(void* context) {
}
}
if(bad_kb->bt) {
bt_set_status_changed_callback(bad_kb->bt, NULL, NULL);
} else {
furi_hal_hid_set_state_callback(NULL, NULL);
}
bt_set_status_changed_callback(bad_kb->app->bt, NULL, NULL);
furi_hal_hid_set_state_callback(NULL, NULL);
storage_file_close(script_file);
storage_file_free(script_file);

View File

@@ -61,7 +61,6 @@ struct BadKbState {
typedef struct BadKbApp BadKbApp;
typedef struct {
FuriHalUsbHidConfig hid_cfg;
FuriThread* thread;
BadKbState st;
@@ -84,11 +83,6 @@ typedef struct {
FuriString* string_print;
size_t string_print_pos;
bool set_usb_id;
bool set_bt_id;
bool has_usb_id;
bool has_bt_id;
Bt* bt;
BadKbApp* app;
} BadKbScript;
@@ -112,19 +106,19 @@ BadKbState* bad_kb_script_get_state(BadKbScript* bad_kb);
#define BAD_KB_NAME_LEN FURI_HAL_BT_ADV_NAME_LENGTH
#define BAD_KB_MAC_LEN GAP_MAC_ADDR_SIZE
// this is the MAC address used when we do not forget paired device (BOUND STATE)
extern const uint8_t BAD_KB_BOUND_MAC_ADDRESS[BAD_KB_MAC_LEN];
extern const uint8_t BAD_KB_EMPTY_MAC_ADDRESS[BAD_KB_MAC_LEN];
extern const uint8_t BAD_KB_EMPTY_MAC[BAD_KB_MAC_LEN];
extern uint8_t BAD_KB_BOUND_MAC[BAD_KB_MAC_LEN]; // For remember mode
typedef enum {
BadKbAppErrorNoFiles,
} BadKbAppError;
typedef struct {
GapPairing bt_mode;
char bt_name[BAD_KB_NAME_LEN];
uint8_t bt_mac[BAD_KB_MAC_LEN];
FuriHalUsbInterface* usb_mode;
GapPairing bt_mode;
FuriHalUsbHidConfig usb_cfg;
} BadKbConfig;
typedef enum {
@@ -155,22 +149,26 @@ struct BadKbApp {
Bt* bt;
bool is_bt;
bool bt_remember;
BadKbConfig config;
BadKbConfig prev_config;
BadKbConfig config; // User options (TODO: allow users to change usb cfg)
BadKbConfig id_config; // ID and BT_ID values
BadKbConfig prev_config; // State to restore at exit
bool set_usb_id;
bool set_bt_id;
bool has_usb_id;
bool has_bt_id;
FuriHalUsbHidConfig* hid_cfg;
BadKbConnMode conn_mode;
FuriThread* conn_init_thread;
FuriThread* switch_mode_thread;
};
int32_t bad_kb_config_switch_mode(BadKbApp* app);
void bad_kb_config_refresh_menu(BadKbApp* app);
int32_t bad_kb_conn_refresh(BadKbApp* app);
int32_t bad_kb_conn_apply(BadKbApp* app);
void bad_kb_conn_reset(BadKbApp* app);
void bad_kb_config_refresh(BadKbApp* app);
#ifdef __cplusplus
}
#endif

View File

@@ -23,8 +23,6 @@ void bad_kb_scene_config_connection_callback(VariableItem* item) {
void bad_kb_scene_config_bt_remember_callback(VariableItem* item) {
BadKbApp* bad_kb = variable_item_get_context(item);
bad_kb->bt_remember = variable_item_get_current_value_index(item);
XTREME_SETTINGS()->bad_bt_remember = bad_kb->bt_remember;
XTREME_SETTINGS_SAVE();
variable_item_set_current_value_text(item, bad_kb->bt_remember ? "ON" : "OFF");
view_dispatcher_send_custom_event(bad_kb->view_dispatcher, VarItemListIndexBtRemember);
}
@@ -45,9 +43,9 @@ void bad_kb_scene_config_on_enter(void* context) {
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->bad_kb_script->has_usb_id) {
if(bad_kb->has_usb_id) {
variable_item_set_locked(item, true, "Script has\nID cmd!\nLocked to\nUSB Mode!");
} else if(bad_kb->bad_kb_script->has_bt_id) {
} else if(bad_kb->has_bt_id) {
variable_item_set_locked(item, true, "Script has\nBT_ID cmd!\nLocked to\nBT Mode!");
}
@@ -58,21 +56,21 @@ void bad_kb_scene_config_on_enter(void* context) {
variable_item_set_current_value_text(item, bad_kb->bt_remember ? "ON" : "OFF");
item = variable_item_list_add(var_item_list, "BT Device Name", 0, NULL, bad_kb);
if(bad_kb->bad_kb_script->set_bt_id) {
if(bad_kb->set_bt_id) {
variable_item_set_locked(item, true, "Script has\nBT_ID cmd!\nLocked to\nset Name!");
}
item = variable_item_list_add(var_item_list, "BT MAC Address", 0, NULL, bad_kb);
if(bad_kb->bt_remember) {
variable_item_set_locked(item, true, "Remember\nmust be Off!");
} else if(bad_kb->bad_kb_script->set_bt_id) {
} else if(bad_kb->set_bt_id) {
variable_item_set_locked(item, true, "Script has\nBT_ID cmd!\nLocked to\nset MAC!");
}
item = variable_item_list_add(var_item_list, "Randomize BT MAC", 0, NULL, bad_kb);
if(bad_kb->bt_remember) {
variable_item_set_locked(item, true, "Remember\nmust be Off!");
} else if(bad_kb->bad_kb_script->set_bt_id) {
} else if(bad_kb->set_bt_id) {
variable_item_set_locked(item, true, "Script has\nBT_ID cmd!\nLocked to\nset MAC!");
}
}
@@ -97,14 +95,6 @@ bool bad_kb_scene_config_on_event(void* context, SceneManagerEvent event) {
case VarItemListIndexKeyboardLayout:
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigLayout);
break;
case VarItemListIndexConnection:
bad_kb_config_switch_mode(bad_kb);
break;
case VarItemListIndexBtRemember:
bad_kb_config_switch_remember_mode(bad_kb);
scene_manager_previous_scene(bad_kb->scene_manager);
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfig);
break;
case VarItemListIndexBtDeviceName:
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigName);
break;
@@ -113,7 +103,11 @@ bool bad_kb_scene_config_on_event(void* context, SceneManagerEvent event) {
break;
case VarItemListIndexRandomizeBtMac:
furi_hal_random_fill_buf(bad_kb->config.bt_mac, BAD_KB_MAC_LEN);
bt_set_profile_mac_address(bad_kb->bt, bad_kb->config.bt_mac);
/* fall through */
case VarItemListIndexBtRemember:
/* fall through */
case VarItemListIndexConnection:
bad_kb_config_refresh(bad_kb);
break;
default:
break;

View File

@@ -35,7 +35,7 @@ bool bad_kb_scene_config_mac_on_event(void* context, SceneManagerEvent event) {
consumed = true;
if(event.event == BadKbAppCustomEventByteInputDone) {
memmove(bad_kb->config.bt_mac, bad_kb->bt_mac_buf, BAD_KB_MAC_LEN);
bt_set_profile_mac_address(bad_kb->bt, bad_kb->config.bt_mac);
bad_kb_config_refresh(bad_kb);
}
scene_manager_previous_scene(bad_kb->scene_manager);
}

View File

@@ -33,7 +33,7 @@ bool bad_kb_scene_config_name_on_event(void* context, SceneManagerEvent event) {
consumed = true;
if(event.event == BadKbAppCustomEventTextInputDone) {
strlcpy(bad_kb->config.bt_name, bad_kb->bt_name_buf, BAD_KB_NAME_LEN);
bt_set_profile_adv_name(bad_kb->bt, bad_kb->config.bt_name);
bad_kb_config_refresh(bad_kb);
}
scene_manager_previous_scene(bad_kb->scene_manager);
}