BadKB: Sync UI and code improvements from OFW PR

This commit is contained in:
Willy-JL
2025-04-03 06:50:04 +01:00
parent 7f46fe5d5c
commit fa359af54e
12 changed files with 122 additions and 67 deletions

View File

@@ -80,6 +80,7 @@
- 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
- Also added `BLE_ID` command, same as `BT_ID`
- Improved UI with better naming and action acknowledgement
- Main Menu: Refined CoverFlow menu style (#379 by @956MB)
- NFC:
- Support MIFARE DESFire Transaction MAC file type, fixes reading some EV2+ cards (by @Willy-JL)

View File

@@ -132,14 +132,14 @@ static void bad_usb_load_settings(BadUsbApp* app) {
if(!loaded) {
furi_string_set(app->keyboard_layout, BAD_USB_SETTINGS_DEFAULT_LAYOUT);
app->interface = BadUsbHidInterfaceUsb;
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->ble.bonding = true;
hid_cfg->ble.pairing = GapPairingPinCodeVerifyYesNo;
hid_cfg->usb.vid = 0;
hid_cfg->usb.pid = 0;
hid_cfg->usb.manuf[0] = '\0';
hid_cfg->usb.product[0] = '\0';
}
}

View File

@@ -6,19 +6,21 @@ enum ConfigIndex {
};
enum ConfigIndexBle {
ConfigIndexBleRemember = ConfigIndexConnection + 1,
ConfigIndexBlePairing,
ConfigIndexBleDeviceName,
ConfigIndexBleMacAddress,
ConfigIndexBleRandomizeMac,
ConfigIndexBleUnpair,
ConfigIndexBlePersistPairing = ConfigIndexConnection + 1,
ConfigIndexBlePairingMode,
ConfigIndexBleSetDeviceName,
ConfigIndexBleSetMacAddress,
ConfigIndexBleRandomizeMacAddress,
ConfigIndexBleRestoreDefaults,
ConfigIndexBleRemovePairing,
};
enum ConfigIndexUsb {
ConfigIndexUsbManufacturer = ConfigIndexConnection + 1,
ConfigIndexUsbProductName,
ConfigIndexUsbVidPid,
ConfigIndexUsbSetManufacturerName = ConfigIndexConnection + 1,
ConfigIndexUsbSetProductName,
ConfigIndexUsbSetVidPid,
ConfigIndexUsbRandomizeVidPid,
ConfigIndexUsbRestoreDefaults,
};
void bad_usb_scene_config_connection_callback(VariableItem* item) {
@@ -32,29 +34,33 @@ void bad_usb_scene_config_connection_callback(VariableItem* item) {
view_dispatcher_send_custom_event(bad_usb->view_dispatcher, ConfigIndexConnection);
}
void bad_usb_scene_config_ble_remember_callback(VariableItem* item) {
void bad_usb_scene_config_ble_persist_pairing_callback(VariableItem* item) {
BadUsbApp* bad_usb = variable_item_get_context(item);
bool value = variable_item_get_current_value_index(item);
const BadUsbHidApi* hid = bad_usb_hid_get_interface(bad_usb->interface);
// Apply to current script config
bad_usb->script_hid_cfg.ble.bonding = value;
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
bad_usb->user_hid_cfg.ble.bonding = value;
variable_item_set_current_value_text(item, value ? "ON" : "OFF");
}
const char* const ble_pairing_names[GapPairingCount] = {
const char* const ble_pairing_mode_names[GapPairingCount] = {
"YesNo",
"PIN Type",
"PIN Y/N",
};
void bad_usb_scene_config_ble_pairing_callback(VariableItem* item) {
void bad_usb_scene_config_ble_pairing_mode_callback(VariableItem* item) {
BadUsbApp* bad_usb = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
const BadUsbHidApi* hid = bad_usb_hid_get_interface(bad_usb->interface);
// Apply to current script config
bad_usb->script_hid_cfg.ble.pairing = index;
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
bad_usb->user_hid_cfg.ble.pairing = index;
variable_item_set_current_value_text(item, ble_pairing_names[index]);
variable_item_set_current_value_text(item, ble_pairing_mode_names[index]);
}
void bad_usb_scene_config_select_callback(void* context, uint32_t index) {
@@ -81,34 +87,42 @@ static void draw_menu(BadUsbApp* bad_usb) {
BleProfileHidParams* ble_hid_cfg = &bad_usb->script_hid_cfg.ble;
item = variable_item_list_add(
var_item_list, "BLE Remember", 2, bad_usb_scene_config_ble_remember_callback, bad_usb);
var_item_list,
"Persist Pairing",
2,
bad_usb_scene_config_ble_persist_pairing_callback,
bad_usb);
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",
"Pairing Mode",
GapPairingCount,
bad_usb_scene_config_ble_pairing_callback,
bad_usb_scene_config_ble_pairing_mode_callback,
bad_usb);
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_set_current_value_text(item, ble_pairing_mode_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, "Set 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, "Set 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, "Randomize MAC Address", 0, NULL, NULL);
variable_item_list_add(var_item_list, "Restore BLE Defaults", 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, "Set Manufacturer Name", 0, NULL, NULL);
variable_item_list_add(var_item_list, "USB Product Name", 0, NULL, NULL);
variable_item_list_add(var_item_list, "Set 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, "Set VID and PID", 0, NULL, NULL);
variable_item_list_add(var_item_list, "Randomize USB VID:PID", 0, NULL, NULL);
variable_item_list_add(var_item_list, "Randomize VID and PID", 0, NULL, NULL);
variable_item_list_add(var_item_list, "Restore USB Defaults", 0, NULL, NULL);
}
}
@@ -132,13 +146,14 @@ bool bad_usb_scene_config_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
scene_manager_set_scene_state(bad_usb->scene_manager, BadUsbSceneConfig, event.event);
consumed = true;
const BadUsbHidApi* hid = bad_usb_hid_get_interface(bad_usb->interface);
switch(event.event) {
case ConfigIndexKeyboardLayout:
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneConfigLayout);
break;
case ConfigIndexConnection:
// Refresh default values for new interface
const BadUsbHidApi* hid = bad_usb_hid_get_interface(bad_usb->interface);
hid->adjust_config(&bad_usb->script_hid_cfg);
// Redraw menu with new interface options
draw_menu(bad_usb);
@@ -148,23 +163,42 @@ bool bad_usb_scene_config_on_event(void* context, SceneManagerEvent event) {
}
if(bad_usb->interface == BadUsbHidInterfaceBle) {
switch(event.event) {
case ConfigIndexBleDeviceName:
case ConfigIndexBleSetDeviceName:
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneConfigBleName);
break;
case ConfigIndexBleMacAddress:
case ConfigIndexBleSetMacAddress:
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneConfigBleMac);
break;
case ConfigIndexBleRandomizeMac:
case ConfigIndexBleRandomizeMacAddress:
// Apply to current script config
furi_hal_random_fill_buf(
bad_usb->script_hid_cfg.ble.mac, sizeof(bad_usb->script_hid_cfg.ble.mac));
bad_usb->script_hid_cfg.ble.mac[sizeof(bad_usb->script_hid_cfg.ble.mac) - 1] |=
0b11 << 6; // Set 2 MSB for Random Static Address
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
memcpy(
bad_usb->user_hid_cfg.ble.mac,
bad_usb->script_hid_cfg.ble.mac,
sizeof(bad_usb->user_hid_cfg.ble.mac));
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneDone);
break;
case ConfigIndexBleUnpair:
case ConfigIndexBleRestoreDefaults:
// Apply to current script config
bad_usb->script_hid_cfg.ble.name[0] = '\0';
memset(
bad_usb->script_hid_cfg.ble.mac, 0, sizeof(bad_usb->script_hid_cfg.ble.mac));
bad_usb->script_hid_cfg.ble.bonding = true;
bad_usb->script_hid_cfg.ble.pairing = GapPairingPinCodeVerifyYesNo;
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
memcpy(
&bad_usb->user_hid_cfg.ble,
&bad_usb->script_hid_cfg.ble,
sizeof(bad_usb->user_hid_cfg.ble));
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneDone);
break;
case ConfigIndexBleRemovePairing:
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneConfirmUnpair);
break;
default:
@@ -172,17 +206,17 @@ bool bad_usb_scene_config_on_event(void* context, SceneManagerEvent event) {
}
} else {
switch(event.event) {
case ConfigIndexUsbManufacturer:
case ConfigIndexUsbSetManufacturerName:
scene_manager_set_scene_state(
bad_usb->scene_manager, BadUsbSceneConfigUsbName, true);
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneConfigUsbName);
break;
case ConfigIndexUsbProductName:
case ConfigIndexUsbSetProductName:
scene_manager_set_scene_state(
bad_usb->scene_manager, BadUsbSceneConfigUsbName, false);
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneConfigUsbName);
break;
case ConfigIndexUsbVidPid:
case ConfigIndexUsbSetVidPid:
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneConfigUsbVidPid);
break;
case ConfigIndexUsbRandomizeVidPid:
@@ -191,9 +225,25 @@ bool bad_usb_scene_config_on_event(void* context, SceneManagerEvent event) {
// Apply to current script config
bad_usb->script_hid_cfg.usb.vid = bad_usb->usb_vidpid_buf[0];
bad_usb->script_hid_cfg.usb.pid = bad_usb->usb_vidpid_buf[1];
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
bad_usb->user_hid_cfg.usb.vid = bad_usb->script_hid_cfg.usb.vid;
bad_usb->user_hid_cfg.usb.pid = bad_usb->script_hid_cfg.usb.pid;
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneDone);
break;
case ConfigIndexUsbRestoreDefaults:
// Apply to current script config
bad_usb->script_hid_cfg.usb.vid = 0;
bad_usb->script_hid_cfg.usb.pid = 0;
bad_usb->script_hid_cfg.usb.manuf[0] = '\0';
bad_usb->script_hid_cfg.usb.product[0] = '\0';
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
memcpy(
&bad_usb->user_hid_cfg.usb,
&bad_usb->script_hid_cfg.usb,
sizeof(bad_usb->user_hid_cfg.usb));
scene_manager_next_scene(bad_usb->scene_manager, BadUsbSceneDone);
break;
default:
break;

View File

@@ -8,4 +8,4 @@ ADD_SCENE(bad_usb, config_ble_mac, ConfigBleMac)
ADD_SCENE(bad_usb, config_usb_name, ConfigUsbName)
ADD_SCENE(bad_usb, config_usb_vidpid, ConfigUsbVidPid)
ADD_SCENE(bad_usb, confirm_unpair, ConfirmUnpair)
ADD_SCENE(bad_usb, unpair_done, UnpairDone)
ADD_SCENE(bad_usb, done, Done)

View File

@@ -45,12 +45,14 @@ bool bad_usb_scene_config_ble_mac_on_event(void* context, SceneManagerEvent even
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
if(event.event == ByteInputResultOk) {
const BadUsbHidApi* hid = bad_usb_hid_get_interface(bad_usb->interface);
reverse_mac_addr(bad_usb->ble_mac_buf);
// Apply to current script config
memcpy(
bad_usb->script_hid_cfg.ble.mac,
bad_usb->ble_mac_buf,
sizeof(bad_usb->script_hid_cfg.ble.mac));
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
memcpy(
bad_usb->user_hid_cfg.ble.mac,

View File

@@ -36,11 +36,13 @@ bool bad_usb_scene_config_ble_name_on_event(void* context, SceneManagerEvent eve
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
if(event.event == TextInputResultOk) {
const BadUsbHidApi* hid = bad_usb_hid_get_interface(bad_usb->interface);
// Apply to current script config
strlcpy(
bad_usb->script_hid_cfg.ble.name,
bad_usb->ble_name_buf,
sizeof(bad_usb->script_hid_cfg.ble.name));
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
strlcpy(
bad_usb->user_hid_cfg.ble.name,

View File

@@ -46,12 +46,14 @@ bool bad_usb_scene_config_usb_name_on_event(void* context, SceneManagerEvent eve
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
if(event.event == TextInputResultOk) {
const BadUsbHidApi* hid = bad_usb_hid_get_interface(bad_usb->interface);
if(scene_manager_get_scene_state(bad_usb->scene_manager, BadUsbSceneConfigUsbName)) {
// Apply to current script config
strlcpy(
bad_usb->script_hid_cfg.usb.manuf,
bad_usb->usb_name_buf,
sizeof(bad_usb->script_hid_cfg.usb.manuf));
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
strlcpy(
bad_usb->user_hid_cfg.usb.manuf,
@@ -63,6 +65,7 @@ bool bad_usb_scene_config_usb_name_on_event(void* context, SceneManagerEvent eve
bad_usb->script_hid_cfg.usb.product,
bad_usb->usb_name_buf,
sizeof(bad_usb->script_hid_cfg.usb.product));
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
strlcpy(
bad_usb->user_hid_cfg.usb.product,

View File

@@ -14,8 +14,8 @@ void bad_usb_scene_config_usb_vidpid_on_enter(void* context) {
BadUsbApp* bad_usb = context;
ByteInput* byte_input = bad_usb->byte_input;
bad_usb->usb_vidpid_buf[0] = __REVSH(bad_usb->script_hid_cfg.usb.vid);
bad_usb->usb_vidpid_buf[1] = __REVSH(bad_usb->script_hid_cfg.usb.pid);
bad_usb->usb_vidpid_buf[0] = __builtin_bswap16(bad_usb->script_hid_cfg.usb.vid);
bad_usb->usb_vidpid_buf[1] = __builtin_bswap16(bad_usb->script_hid_cfg.usb.pid);
byte_input_set_header_text(byte_input, "Set USB VID:PID");
byte_input_set_result_callback(
@@ -36,9 +36,11 @@ bool bad_usb_scene_config_usb_vidpid_on_event(void* context, SceneManagerEvent e
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
if(event.event == ByteInputResultOk) {
const BadUsbHidApi* hid = bad_usb_hid_get_interface(bad_usb->interface);
// Apply to current script config
bad_usb->script_hid_cfg.usb.vid = __REVSH(bad_usb->usb_vidpid_buf[0]);
bad_usb->script_hid_cfg.usb.pid = __REVSH(bad_usb->usb_vidpid_buf[1]);
bad_usb->script_hid_cfg.usb.vid = __builtin_bswap16(bad_usb->usb_vidpid_buf[0]);
bad_usb->script_hid_cfg.usb.pid = __builtin_bswap16(bad_usb->usb_vidpid_buf[1]);
hid->adjust_config(&bad_usb->script_hid_cfg);
// Set in user config to save in settings file
bad_usb->user_hid_cfg.usb.vid = bad_usb->script_hid_cfg.usb.vid;
bad_usb->user_hid_cfg.usb.pid = bad_usb->script_hid_cfg.usb.pid;

View File

@@ -36,7 +36,8 @@ bool bad_usb_scene_confirm_unpair_on_event(void* context, SceneManagerEvent even
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
if(event.event == GuiButtonTypeRight) {
scene_manager_next_scene(scene_manager, BadUsbSceneUnpairDone);
bad_usb_hid_ble_remove_pairing();
scene_manager_next_scene(scene_manager, BadUsbSceneDone);
} else if(event.event == GuiButtonTypeLeft) {
scene_manager_previous_scene(scene_manager);
}

View File

@@ -1,19 +1,17 @@
#include "../bad_usb_app_i.h"
static void bad_usb_scene_unpair_done_popup_callback(void* context) {
static void bad_usb_scene_done_popup_callback(void* context) {
BadUsbApp* bad_usb = context;
scene_manager_search_and_switch_to_previous_scene(bad_usb->scene_manager, BadUsbSceneConfig);
}
void bad_usb_scene_unpair_done_on_enter(void* context) {
void bad_usb_scene_done_on_enter(void* context) {
BadUsbApp* bad_usb = context;
Popup* popup = bad_usb->popup;
bad_usb_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_usb_scene_unpair_done_popup_callback);
popup_set_callback(popup, bad_usb_scene_done_popup_callback);
popup_set_context(popup, bad_usb);
popup_set_timeout(popup, 1500);
popup_enable_timeout(popup);
@@ -21,7 +19,7 @@ void bad_usb_scene_unpair_done_on_enter(void* context) {
view_dispatcher_switch_to_view(bad_usb->view_dispatcher, BadUsbAppViewPopup);
}
bool bad_usb_scene_unpair_done_on_event(void* context, SceneManagerEvent event) {
bool bad_usb_scene_done_on_event(void* context, SceneManagerEvent event) {
BadUsbApp* bad_usb = context;
UNUSED(bad_usb);
UNUSED(event);
@@ -30,7 +28,7 @@ bool bad_usb_scene_unpair_done_on_event(void* context, SceneManagerEvent event)
return consumed;
}
void bad_usb_scene_unpair_done_on_exit(void* context) {
void bad_usb_scene_done_on_exit(void* context) {
BadUsbApp* bad_usb = context;
Popup* popup = bad_usb->popup;
UNUSED(popup);

View File

@@ -20,6 +20,7 @@ bool bad_usb_scene_work_on_event(void* context, SceneManagerEvent event) {
bad_usb_script_close(app->bad_usb_script);
app->bad_usb_script = NULL;
scene_manager_set_scene_state(app->scene_manager, BadUsbSceneConfig, 0);
scene_manager_next_scene(app->scene_manager, BadUsbSceneConfig);
}
consumed = true;

View File

@@ -9,12 +9,12 @@
#include <usb_hid.h>
#include <ble/ble.h>
#define HID_INFO_BASE_USB_SPECIFICATION (0x0101)
#define HID_INFO_COUNTRY_CODE (0x00)
#define BLE_PROFILE_HID_INFO_FLAG_REMOTE_WAKE_MSK (0x01)
#define HID_INFO_BASE_USB_SPECIFICATION (0x0101)
#define HID_INFO_COUNTRY_CODE (0x00)
#define BLE_PROFILE_HID_INFO_FLAG_REMOTE_WAKE_MSK (0x01)
#define BLE_PROFILE_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK (0x02)
#define BLE_PROFILE_HID_KB_MAX_KEYS (6)
#define BLE_PROFILE_HID_KB_MAX_KEYS (6)
#define BLE_PROFILE_CONSUMER_MAX_KEYS (1)
// Report ids cant be 0
@@ -380,10 +380,11 @@ bool ble_profile_hid_mouse_scroll(FuriHalBleProfileBase* profile, int8_t delta)
#define CONNECTION_INTERVAL_MAX (0x24)
static GapConfig template_config = {
.adv_service = {
.UUID_Type = UUID_TYPE_16,
.Service_UUID_16 = HUMAN_INTERFACE_DEVICE_SERVICE_UUID,
},
.adv_service =
{
.UUID_Type = UUID_TYPE_16,
.Service_UUID_16 = HUMAN_INTERFACE_DEVICE_SERVICE_UUID,
},
.appearance_char = GAP_APPEARANCE_KEYBOARD,
.bonding_mode = true,
.pairing_method = GapPairingPinCodeVerifyYesNo,
@@ -412,23 +413,17 @@ static void ble_profile_hid_get_config(GapConfig* config, FuriHalBleProfileParam
}
// Set advertise name
memset(config->adv_name, 0, sizeof(config->adv_name));
const char* clicker_str = "Control";
if(hid_profile_params && hid_profile_params->device_name_prefix) {
clicker_str = hid_profile_params->device_name_prefix;
}
// We don't have Flipper in BLE name, use printf instead of replace
FuriString* name = furi_string_alloc_printf(
snprintf(
config->adv_name,
sizeof(config->adv_name),
"%c%s %s",
furi_hal_version_get_ble_local_device_name_ptr()[0],
clicker_str,
furi_hal_version_get_ble_local_device_name_ptr() + 1);
if(furi_string_size(name) >= sizeof(config->adv_name)) {
furi_string_left(name, sizeof(config->adv_name) - 1);
}
memcpy(config->adv_name, furi_string_get_cstr(name), furi_string_size(name));
furi_string_free(name);
furi_hal_version_get_name_ptr());
}
static const FuriHalBleProfileTemplate profile_callbacks = {