Adds bonding toggle in badkb, allowing to remember paired devices, but MAC address cannot be modified in this state (V1)

This commit is contained in:
yocvito
2023-02-28 19:27:15 +01:00
parent fb08674a99
commit 48641ef6f6
10 changed files with 96 additions and 29 deletions

View File

@@ -107,10 +107,12 @@ BadKbApp* bad_kb_app_alloc(char* arg) {
Bt* bt = furi_record_open(RECORD_BT);
app->bt = bt;
app->is_bt = XTREME_SETTINGS()->bad_bt;
app->bonding = BondingForgetDevices;
const char* adv_name = furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard);
memcpy(app->name, adv_name, BAD_KB_ADV_NAME_MAX_LEN);
memcpy(app->bt_old_config.name, adv_name, BAD_KB_ADV_NAME_MAX_LEN);
// need to be done before bt init (where mac address get modified if bounding is activated)
const uint8_t* mac_addr = furi_hal_bt_get_profile_mac_addr(FuriHalBtProfileHidKeyboard);
memcpy(app->mac, mac_addr, BAD_KB_MAC_ADDRESS_LEN);
memcpy(app->bt_old_config.mac, mac_addr, BAD_KB_MAC_ADDRESS_LEN);

View File

@@ -18,11 +18,16 @@
#define BAD_KB_APP_BASE_FOLDER ANY_PATH("badkb")
#define BAD_KB_APP_PATH_LAYOUT_FOLDER BAD_KB_APP_BASE_FOLDER "/assets/layouts"
#define BAD_KB_APP_PATH_BOUND_KEYS_FOLDER EXT_PATH("badkb/.bt_keys")
#define BAD_KB_APP_PATH_BOUND_KEYS_FILE BAD_KB_APP_PATH_BOUND_KEYS_FOLDER "/.devices.keys"
#define BAD_KB_APP_SCRIPT_EXTENSION ".txt"
#define BAD_KB_APP_LAYOUT_EXTENSION ".kl"
#define BAD_KB_MAC_ADDRESS_LEN 6 // need replace with MAC size maccro
#define BAD_KB_ADV_NAME_MAX_LEN 18
#define BAD_KB_MAC_ADDRESS_LEN 6 // need replace with MAC size maccro
#define BAD_KB_ADV_NAME_MAX_LEN 18
// this is the MAC address used when we do not forget paired device (BOUND STATE)
#define BAD_KB_BOUND_MAC_ADDRESS { 0x41, 0x4a, 0xef, 0xbe, 0xad, 0xde };
typedef enum {
BadKbAppErrorNoFiles,
@@ -35,13 +40,14 @@ typedef enum BadKbCustomEvent {
BadKbCustomEventErrorBack
} BadKbCustomEvent;
#define BondingForgetDevices false
#define BondingRememberDevices true
typedef struct {
//uint8_t bounded_mac[BAD_KB_MAC_ADDRESS_LEN];
uint8_t mac[BAD_KB_MAC_ADDRESS_LEN];
char name[BAD_KB_ADV_NAME_MAX_LEN + 1];
// number of bt keys before starting the app (all keys added in
// the bt keys file then will be removed)
uint16_t n_keys;
} BadKbBtConfig;
struct BadKbApp {
@@ -59,6 +65,7 @@ struct BadKbApp {
ByteInput* byte_input;
uint8_t mac[BAD_KB_MAC_ADDRESS_LEN];
char name[BAD_KB_ADV_NAME_MAX_LEN + 1];
bool bonding; // weither we remember paired devices or not
BadKbBtConfig bt_old_config;
BadKbAppError error;

View File

@@ -169,19 +169,19 @@ static const uint8_t numpad_keys[10] = {
uint8_t bt_timeout = 0;
static LevelRssiRange bt_remote_rssi_range(Bt* bt) {
BtRssi rssi_data = {0};
uint8_t rssi;
if(!bt_remote_rssi(bt, &rssi_data)) return LevelRssiError;
if(!bt_remote_rssi(bt, &rssi)) return LevelRssiError;
if(rssi_data.rssi <= 39)
if(rssi <= 39)
return LevelRssi39_0;
else if(rssi_data.rssi <= 59)
else if(rssi <= 59)
return LevelRssi59_40;
else if(rssi_data.rssi <= 79)
else if(rssi <= 79)
return LevelRssi79_60;
else if(rssi_data.rssi <= 99)
else if(rssi <= 99)
return LevelRssi99_80;
else if(rssi_data.rssi <= 122)
else if(rssi <= 122)
return LevelRssi122_100;
return LevelRssiError;
@@ -629,6 +629,23 @@ void bad_kb_config_switch_mode(BadKbApp* app) {
}
}
void bad_kb_config_switch_bonding_mode(BadKbApp *app) {
if (app->bonding) {
// set bouding mac
uint8_t mac[6] = BAD_KB_BOUND_MAC_ADDRESS;
furi_hal_bt_set_profile_pairing_method(FuriHalBtProfileHidKeyboard, GapPairingPinCodeVerifyYesNo);
bt_set_profile_mac_address(app->bt, mac); // this also restart bt
// enable keys storage
bt_enable_peer_key_update(app->bt);
} else {
// set back user defined mac address
furi_hal_bt_set_profile_pairing_method(FuriHalBtProfileHidKeyboard, GapPairingNone);
bt_set_profile_mac_address(app->bt, app->mac);
// disable key storage
bt_disable_peer_key_update(app->bt);
}
}
void bad_kb_connection_init(BadKbApp* app) {
app->usb_prev_mode = furi_hal_usb_get_config();
furi_hal_usb_set_config(NULL, NULL);
@@ -636,13 +653,22 @@ void bad_kb_connection_init(BadKbApp* app) {
bt_timeout = bt_hid_delays[LevelRssi39_0];
bt_disconnect(app->bt);
// furi_delay_ms(200);
bt_keys_storage_set_storage_path(app->bt, HID_BT_KEYS_STORAGE_PATH);
bt_keys_storage_set_storage_path(app->bt, BAD_KB_APP_PATH_BOUND_KEYS_FILE);
app->bt_prev_mode = furi_hal_bt_get_profile_pairing_method(FuriHalBtProfileHidKeyboard);
if (app->bonding) { // usefull if bounding become an XTREME setting
uint8_t mac[6] = BAD_KB_BOUND_MAC_ADDRESS;
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, mac);
// using GapPairingNone breaks bounding between devices
furi_hal_bt_set_profile_pairing_method(FuriHalBtProfileHidKeyboard, GapPairingPinCodeVerifyYesNo);
} else {
furi_hal_bt_set_profile_pairing_method(FuriHalBtProfileHidKeyboard, GapPairingNone);
}
bt_set_profile(app->bt, BtProfileHidKeyboard);
app->bt_prev_mode = bt_get_profile_pairing_method(app->bt);
bt_set_profile_pairing_method(app->bt, GapPairingNone);
bt_disable_peer_key_update(app->bt); // disable peer key adding to bt SRAM storage
if(app->is_bt) {
furi_hal_bt_start_advertising();
if (!app->bonding)
bt_disable_peer_key_update(app->bt); // disable peer key adding to bt SRAM storage
} else {
furi_hal_bt_stop_advertising();
}
@@ -659,11 +685,16 @@ void bad_kb_connection_deinit(BadKbApp* app) {
bt_disconnect(app->bt); // stop ble
// furi_delay_ms(200); // Wait 2nd core to update nvm storage
bt_keys_storage_set_default_path(app->bt);
bt_set_profile_pairing_method(app->bt, app->bt_prev_mode);
if (app->bonding) {
// hal primitives doesn't restarts ble, that's what we want cuz we are shutting down
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, app->mac);
}else {
bt_enable_peer_key_update(app->bt); // starts saving peer keys (bounded devices)
}
// fails if ble radio stack isn't ready when switching profile
// if it happens, maybe we should increase the delay after bt_disconnect
bt_set_profile(app->bt, BtProfileSerial);
bt_enable_peer_key_update(app->bt); // starts saving peer keys (bounded devices)
furi_hal_bt_set_profile_pairing_method(FuriHalBtProfileHidKeyboard, app->bt_prev_mode);
}
static int32_t bad_kb_worker(void* context) {

View File

@@ -36,6 +36,8 @@ typedef struct {
void bad_kb_config_switch_mode(BadKbApp* app);
void bad_kb_config_switch_bonding_mode(BadKbApp *app);
void bad_kb_connection_init(BadKbApp* app);
void bad_kb_connection_deinit(BadKbApp* app);

View File

@@ -5,6 +5,7 @@
enum VarItemListIndex {
VarItemListIndexConnection,
VarItemListIndexBonding,
VarItemListIndexKeyboardLayout,
VarItemListIndexAdvertisementName,
VarItemListIndexMacAddress,
@@ -19,6 +20,13 @@ void bad_kb_scene_config_bt_connection_callback(VariableItem* item) {
view_dispatcher_send_custom_event(bad_kb->view_dispatcher, VarItemListIndexConnection);
}
void bad_kb_scene_config_bt_bounding_callback(VariableItem* item) {
BadKbApp* bad_kb = variable_item_get_context(item);
bad_kb->bonding = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, bad_kb->bonding ? "Remember" : "Forget");
view_dispatcher_send_custom_event(bad_kb->view_dispatcher, VarItemListIndexBonding);
}
void bad_kb_scene_config_bt_var_item_list_callback(void* context, uint32_t index) {
BadKbApp* bad_kb = context;
view_dispatcher_send_custom_event(bad_kb->view_dispatcher, index);
@@ -34,11 +42,19 @@ void bad_kb_scene_config_bt_on_enter(void* context) {
variable_item_set_current_value_index(item, bad_kb->is_bt);
variable_item_set_current_value_text(item, bad_kb->is_bt ? "BT" : "USB");
item = variable_item_list_add(
var_item_list, "Bonding", 2, bad_kb_scene_config_bt_bounding_callback, bad_kb);
variable_item_set_current_value_index(item, bad_kb->bonding);
variable_item_set_current_value_text(item, bad_kb->bonding ? "Remember" : "Forget");
item = variable_item_list_add(var_item_list, "Keyboard layout", 0, NULL, bad_kb);
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);
// this doesn't update instantly when toggling between Bounding modes
if (!bad_kb->bonding) {
item = variable_item_list_add(var_item_list, "BT MAC address", 0, NULL, bad_kb);
}
variable_item_list_set_enter_callback(
var_item_list, bad_kb_scene_config_bt_var_item_list_callback, bad_kb);
@@ -57,6 +73,8 @@ bool bad_kb_scene_config_bt_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigLayout);
} else if(event.event == VarItemListIndexConnection) {
bad_kb_config_switch_mode(bad_kb);
} else if (event.event == VarItemListIndexBonding) {
bad_kb_config_switch_bonding_mode(bad_kb);
} else if(event.event == VarItemListIndexAdvertisementName) {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigName);
} else if(event.event == VarItemListIndexMacAddress) {

View File

@@ -424,17 +424,15 @@ const uint8_t* bt_get_profile_mac_address(Bt* bt) {
return furi_hal_bt_get_profile_mac_addr(get_hal_bt_profile(bt->profile));
}
bool bt_remote_rssi(Bt* bt, BtRssi* rssi) {
bool bt_remote_rssi(Bt* bt, uint8_t* rssi) {
furi_assert(bt);
UNUSED(rssi);
uint8_t rssi_val;
uint32_t since = furi_hal_bt_get_conn_rssi(&rssi_val);
if(since == 0) return false;
rssi->rssi = rssi_val;
rssi->since = since;
*rssi = rssi_val;
return true;
}
@@ -456,6 +454,7 @@ void bt_disable_peer_key_update(Bt* bt) {
}
void bt_enable_peer_key_update(Bt* bt) {
furi_assert(bt);
furi_hal_bt_set_key_storage_change_callback(bt_on_key_storage_change_callback, bt);
}

View File

@@ -47,7 +47,7 @@ const char* bt_get_profile_adv_name(Bt* bt);
void bt_set_profile_mac_address(Bt* bt, const uint8_t mac[6]);
const uint8_t* bt_get_profile_mac_address(Bt* bt);
bool bt_remote_rssi(Bt* bt, BtRssi* rssi);
bool bt_remote_rssi(Bt* bt, uint8_t* rssi);
void bt_set_profile_pairing_method(Bt* bt, GapPairing pairing_method);
GapPairing bt_get_profile_pairing_method(Bt* bt);

View File

@@ -1,5 +1,6 @@
#include "../bt_settings_app.h"
#include <furi_hal_bt.h>
#include <applications/main/bad_kb/bad_kb_app_i.h>
void bt_settings_scene_forget_dev_confirm_dialog_callback(DialogExResult result, void* context) {
furi_assert(context);
@@ -30,6 +31,11 @@ bool bt_settings_scene_forget_dev_confirm_on_event(void* context, SceneManagerEv
consumed = scene_manager_previous_scene(app->scene_manager);
} else if(event.event == DialogExResultRight) {
bt_forget_bonded_devices(app->bt);
// also removes keys of badkb bonded devices
bt_keys_storage_set_storage_path(app->bt, BAD_KB_APP_PATH_BOUND_KEYS_FILE);
bt_forget_bonded_devices(app->bt);
bt_keys_storage_set_default_path(app->bt);
scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneForgetDevSuccess);
consumed = true;
}

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,14.1,,
Version,+,15.0,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
@@ -589,7 +589,7 @@ Function,+,bt_get_profile_mac_address,const uint8_t*,Bt*
Function,+,bt_get_profile_pairing_method,GapPairing,Bt*
Function,+,bt_keys_storage_set_default_path,void,Bt*
Function,+,bt_keys_storage_set_storage_path,void,"Bt*, const char*"
Function,+,bt_remote_rssi,_Bool,"Bt*, BtRssi*"
Function,+,bt_remote_rssi,_Bool,"Bt*, uint8_t*"
Function,+,bt_set_profile,_Bool,"Bt*, BtProfile"
Function,+,bt_set_profile_adv_name,void,"Bt*, const char*, ..."
Function,+,bt_set_profile_mac_address,void,"Bt*, const uint8_t[6]"
1 entry status name type params
2 Version + 14.1 15.0
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/cli/cli.h
5 Header + applications/services/cli/cli_vcp.h
589 Function + bt_get_profile_pairing_method GapPairing Bt*
590 Function + bt_keys_storage_set_default_path void Bt*
591 Function + bt_keys_storage_set_storage_path void Bt*, const char*
592 Function + bt_remote_rssi _Bool Bt*, BtRssi* Bt*, uint8_t*
593 Function + bt_set_profile _Bool Bt*, BtProfile
594 Function + bt_set_profile_adv_name void Bt*, const char*, ...
595 Function + bt_set_profile_mac_address void Bt*, const uint8_t[6]

View File

@@ -373,6 +373,7 @@ static void gap_init_svc(Gap* gap) {
bool keypress_supported = false;
uint8_t conf_mitm = CFG_MITM_PROTECTION;
uint8_t conf_used_fixed_pin = CFG_USED_FIXED_PIN;
bool conf_bonding = gap->config->bonding_mode;
if(gap->config->pairing_method == GapPairingPinCodeShow) {
aci_gap_set_io_capability(IO_CAP_DISPLAY_ONLY);
} else if(gap->config->pairing_method == GapPairingPinCodeVerifyYesNo) {
@@ -382,6 +383,7 @@ static void gap_init_svc(Gap* gap) {
// Just works pairing method (IOS accept it, it seems android and linux doesn't)
conf_mitm = 0;
conf_used_fixed_pin = 0;
conf_bonding = false;
// if just works isn't supported, we want the numeric comparaison method
aci_gap_set_io_capability(IO_CAP_DISPLAY_YES_NO);
keypress_supported = true;
@@ -389,7 +391,7 @@ static void gap_init_svc(Gap* gap) {
// Setup authentication
aci_gap_set_authentication_requirement(
gap->config->bonding_mode,
conf_bonding,
conf_mitm,
CFG_SC_SUPPORT,
keypress_supported,