BadKB fixes and BT improvements (#143)

This commit is contained in:
WillyJL
2023-03-04 00:22:04 +00:00
committed by GitHub
22 changed files with 347 additions and 205 deletions
+21 -17
View File
@@ -72,17 +72,6 @@ static void bad_kb_save_settings(BadKbApp* app) {
storage_file_free(settings_file);
}
void bad_kb_set_name(BadKbApp* app, const char* fmt, ...) {
furi_assert(app);
va_list args;
va_start(args, fmt);
vsnprintf(app->name, BAD_KB_ADV_NAME_MAX_LEN, fmt, args);
va_end(args);
}
BadKbApp* bad_kb_app_alloc(char* arg) {
BadKbApp* app = malloc(sizeof(BadKbApp));
@@ -113,14 +102,19 @@ BadKbApp* bad_kb_app_alloc(char* arg) {
view_dispatcher_set_navigation_event_callback(
app->view_dispatcher, bad_kb_app_back_event_callback);
app->connection_init = false;
Bt* bt = furi_record_open(RECORD_BT);
app->bt = bt;
app->bt->suppress_pin_screen = true;
app->is_bt = XTREME_SETTINGS()->bad_bt;
const char* adv_name = bt_get_profile_adv_name(bt);
app->bt_remember = XTREME_SETTINGS()->bad_bt_remember;
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);
const uint8_t* mac_addr = bt_get_profile_mac_address(bt);
// 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);
@@ -156,8 +150,12 @@ BadKbApp* bad_kb_app_alloc(char* arg) {
if(furi_hal_usb_is_locked()) {
app->error = BadKbAppErrorCloseRpc;
app->conn_init_thread = NULL;
scene_manager_next_scene(app->scene_manager, BadKbSceneError);
} else {
app->conn_init_thread = furi_thread_alloc_ex(
"BadKbConnInit", 512, (FuriThreadCallback)bad_kb_connection_init, app);
furi_thread_start(app->conn_init_thread);
if(!furi_string_empty(app->file_path)) {
app->bad_kb_script = bad_kb_script_open(app->file_path, app->is_bt ? app->bt : NULL);
bad_kb_script_set_keyboard_layout(app->bad_kb_script, app->keyboard_layout);
@@ -205,16 +203,16 @@ void bad_kb_app_free(BadKbApp* app) {
view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager);
// restores bt config
// BtProfile have already been switched to the previous one
// so we directly modify the right profile
bad_kb_connection_deinit(app->bt);
// Restore bt config
// BtProfile has already been switched to the previous one
// So we directly modify the right profile
if(strcmp(app->bt_old_config.name, app->name) != 0) {
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, app->bt_old_config.name);
}
if(memcmp(app->bt_old_config.mac, app->mac, BAD_KB_MAC_ADDRESS_LEN) != 0) {
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, app->bt_old_config.mac);
}
app->bt->suppress_pin_screen = false;
// Close records
furi_record_close(RECORD_GUI);
@@ -227,6 +225,12 @@ void bad_kb_app_free(BadKbApp* app) {
furi_string_free(app->file_path);
furi_string_free(app->keyboard_layout);
if(app->conn_init_thread) {
furi_thread_join(app->conn_init_thread);
furi_thread_free(app->conn_init_thread);
}
bad_kb_connection_deinit(app);
free(app);
}
-2
View File
@@ -6,8 +6,6 @@ extern "C" {
typedef struct BadKbApp BadKbApp;
void bad_kb_set_name(BadKbApp* app, const char* fmt, ...);
#ifdef __cplusplus
}
#endif
+13 -4
View File
@@ -18,12 +18,17 @@
#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
// this is the MAC address used when we do not forget paired device (BOUND STATE)
#define BAD_KB_BOUND_MAC_ADDRESS {0x41, 0x4a, 0xef, 0xb6, 0xa9, 0xd4};
typedef enum {
BadKbAppErrorNoFiles,
BadKbAppErrorCloseRpc,
@@ -36,12 +41,9 @@ typedef enum BadKbCustomEvent {
} BadKbCustomEvent;
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 +61,7 @@ struct BadKbApp {
ByteInput* byte_input;
uint8_t mac[BAD_KB_MAC_ADDRESS_LEN];
char name[BAD_KB_ADV_NAME_MAX_LEN + 1];
bool bt_remember; // weither we remember paired devices or not
BadKbBtConfig bt_old_config;
BadKbAppError error;
@@ -68,6 +71,12 @@ struct BadKbApp {
BadKbScript* bad_kb_script;
bool is_bt;
bool connection_init;
FuriHalUsbInterface* usb_prev_mode;
GapPairing bt_prev_mode;
FuriThread* conn_init_thread;
};
typedef enum {
+153 -110
View File
@@ -11,6 +11,8 @@
#include <bt/bt_service/bt.h>
#include "bad_kb_app_i.h"
#define HID_BT_KEYS_STORAGE_PATH EXT_PATH("apps/Tools/.bt_hid.keys")
#define TAG "BadKB"
@@ -41,12 +43,6 @@ typedef enum {
LevelRssiError = 0xFF,
} LevelRssiRange;
typedef enum {
BadKbConnectionModeNone,
BadKbConnectionModeUsb,
BadKbConnectionModeBt,
} BadKbConnectionMode;
/**
* Delays for waiting between HID key press and key release
*/
@@ -65,6 +61,7 @@ struct BadKbScript {
FuriString* keyboard_layout;
uint32_t defdelay;
uint16_t layout[128];
uint32_t stringdelay;
FuriThread* thread;
uint8_t file_buf[FILE_BUFFER_LEN + 1];
uint8_t buf_start;
@@ -148,6 +145,8 @@ static const char ducky_cmd_delay[] = {"DELAY "};
static const char ducky_cmd_string[] = {"STRING "};
static const char ducky_cmd_defdelay_1[] = {"DEFAULT_DELAY "};
static const char ducky_cmd_defdelay_2[] = {"DEFAULTDELAY "};
static const char ducky_cmd_stringdelay_1[] = {"STRINGDELAY "};
static const char ducky_cmd_stringdelay_2[] = {"STRING_DELAY "};
static const char ducky_cmd_repeat[] = {"REPEAT "};
static const char ducky_cmd_sysrq[] = {"SYSRQ "};
@@ -170,27 +169,22 @@ static const uint8_t numpad_keys[10] = {
HID_KEYPAD_9,
};
BadKbConnectionMode connection_mode = BadKbConnectionModeNone;
FuriHalUsbInterface* usb_mode_prev = NULL;
GapPairing bt_mode_prev = GapPairingNone;
bool bt_connected = false;
bool usb_connected = false;
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;
@@ -304,6 +298,7 @@ static bool ducky_altstring(BadKbScript* bad_kb, const char* param) {
static bool ducky_string(BadKbScript* bad_kb, const char* param) {
uint32_t i = 0;
while(param[i] != '\0') {
uint16_t keycode = BADKB_ASCII_TO_KEY(bad_kb, param[i]);
if(keycode != HID_KEYBOARD_NONE) {
@@ -315,9 +310,13 @@ static bool ducky_string(BadKbScript* bad_kb, const char* param) {
furi_hal_hid_kb_press(keycode);
furi_hal_hid_kb_release(keycode);
}
if(bad_kb->stringdelay > 0) {
furi_delay_ms(bad_kb->stringdelay);
}
}
i++;
}
bad_kb->stringdelay = 0;
return true;
}
@@ -379,6 +378,19 @@ static int32_t
snprintf(error, error_len, "Invalid number %s", line_tmp);
}
return (state) ? (0) : SCRIPT_STATE_ERROR;
} else if(
(strncmp(line_tmp, ducky_cmd_stringdelay_1, strlen(ducky_cmd_stringdelay_1)) == 0) ||
(strncmp(line_tmp, ducky_cmd_stringdelay_2, strlen(ducky_cmd_stringdelay_2)) == 0)) {
//STRINGDELAY, finally it's here
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
state = ducky_get_number(line_tmp, &bad_kb->stringdelay);
if((state) && (bad_kb->stringdelay > 0)) {
return state;
}
if(error != NULL) {
snprintf(error, error_len, "Invalid number %s", line_tmp);
}
return SCRIPT_STATE_ERROR;
} else if(strncmp(line_tmp, ducky_cmd_string, strlen(ducky_cmd_string)) == 0) {
// STRING
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
@@ -607,10 +619,8 @@ static void bad_kb_bt_hid_state_callback(BtStatus status, void* context) {
if(r != LevelRssiError) {
bt_timeout = bt_hid_delays[r];
}
bt_connected = true;
furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtConnect);
} else {
bt_connected = false;
furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtDisconnect);
}
}
@@ -620,83 +630,116 @@ static void bad_kb_usb_hid_state_callback(bool state, void* context) {
BadKbScript* bad_kb = context;
if(state == true) {
usb_connected = true;
furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtConnect);
} else {
usb_connected = false;
furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtDisconnect);
}
}
void bad_kb_bt_init(Bt* bt) {
bt_timeout = bt_hid_delays[LevelRssi39_0];
bt_disconnect(bt);
furi_delay_ms(200);
bt_keys_storage_set_storage_path(bt, HID_BT_KEYS_STORAGE_PATH);
furi_assert(bt_set_profile(bt, BtProfileHidKeyboard));
bt_mode_prev = bt_get_profile_pairing_method(bt);
bt_set_profile_pairing_method(bt, GapPairingNone);
furi_hal_bt_start_advertising();
// disable peer key adding to bt SRAM storage
bt_disable_peer_key_update(bt);
connection_mode = BadKbConnectionModeBt;
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);
bad_kb_script_set_keyboard_layout(app->bad_kb_script, app->keyboard_layout);
}
void bad_kb_bt_deinit(Bt* bt) {
// release all keys
// bt_hid_hold_while_keyboard_buffer_full(6, 3000);
void bad_kb_config_switch_mode(BadKbApp* app) {
scene_manager_previous_scene(app->scene_manager);
if(app->is_bt) {
furi_hal_bt_start_advertising();
scene_manager_next_scene(app->scene_manager, BadKbSceneConfigBt);
} else {
furi_hal_bt_stop_advertising();
scene_manager_next_scene(app->scene_manager, BadKbSceneConfigUsb);
}
bad_kb_reload_worker(app);
}
// stop ble
bt_disconnect(bt);
void bad_kb_config_switch_remember_mode(BadKbApp* app) {
if(app->bt_remember) {
// 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);
}
bad_kb_reload_worker(app);
}
// Wait 2nd core to update nvm storage
furi_delay_ms(200);
int32_t bad_kb_connection_init(BadKbApp* app) {
app->usb_prev_mode = furi_hal_usb_get_config();
furi_hal_usb_set_config(NULL, NULL);
bt_keys_storage_set_default_path(bt);
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_APP_PATH_BOUND_KEYS_FILE);
app->bt_prev_mode = furi_hal_bt_get_profile_pairing_method(FuriHalBtProfileHidKeyboard);
if(app->bt_remember) {
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_pairing_method(bt, bt_mode_prev);
bt_set_profile(app->bt, BtProfileHidKeyboard);
if(app->is_bt) {
furi_hal_bt_start_advertising();
if(app->bt_remember) {
bt_enable_peer_key_update(app->bt);
} else {
bt_disable_peer_key_update(app->bt); // disable peer key adding to bt SRAM storage
}
} else {
furi_hal_bt_stop_advertising();
}
app->connection_init = true;
return 0;
}
void bad_kb_connection_deinit(BadKbApp* app) {
if(!app->connection_init) return;
furi_hal_usb_set_config(app->usb_prev_mode, NULL);
// bt_hid_hold_while_keyboard_buffer_full(6, 3000); // release all keys
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);
if(app->bt_remember) {
// 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);
}
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(bt, BtProfileSerial);
// starts saving peer keys (bounded devices)
bt_enable_peer_key_update(bt);
connection_mode = BadKbConnectionModeNone;
bt_set_profile(app->bt, BtProfileSerial);
furi_hal_bt_set_profile_pairing_method(FuriHalBtProfileHidKeyboard, app->bt_prev_mode);
}
void bad_kb_usb_init() {
usb_mode_prev = furi_hal_usb_get_config();
connection_mode = BadKbConnectionModeUsb;
}
void bad_kb_usb_deinit() {
furi_hal_usb_set_config(usb_mode_prev, NULL);
connection_mode = BadKbConnectionModeNone;
}
void bad_kb_connection_init(Bt* bt) {
if(connection_mode != BadKbConnectionModeNone) return;
if(bt) {
bad_kb_bt_init(bt);
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);
if(flags == 0) {
flags = furi_thread_flags_wait(flags_mask, FuriFlagWaitAny, timeout);
furi_check(((flags & FuriFlagError) == 0) || (flags == (unsigned)FuriFlagErrorTimeout));
} else {
bad_kb_usb_init();
}
}
void bad_kb_connection_deinit(Bt* bt) {
if(connection_mode == BadKbConnectionModeNone) return;
if(connection_mode == BadKbConnectionModeBt) {
bad_kb_bt_deinit(bt);
} else {
bad_kb_usb_deinit();
uint32_t state = furi_thread_flags_clear(flags);
furi_check((state & FuriFlagError) == 0);
}
return flags;
}
static int32_t bad_kb_worker(void* context) {
@@ -705,8 +748,6 @@ static int32_t bad_kb_worker(void* context) {
BadKbWorkerState worker_state = BadKbStateInit;
int32_t delay_val = 0;
bad_kb_connection_init(bad_kb->bt);
if(bad_kb->bt) {
bt_set_status_changed_callback(bad_kb->bt, bad_kb_bt_hid_state_callback, bad_kb);
} else {
@@ -727,7 +768,11 @@ static int32_t bad_kb_worker(void* context) {
FSOM_OPEN_EXISTING)) {
if((ducky_script_preload(bad_kb, script_file)) && (bad_kb->st.line_nb > 0)) {
if(bad_kb->bt) {
worker_state = BadKbStateNotConnected; // Ready to run
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
@@ -745,30 +790,20 @@ static int32_t bad_kb_worker(void* context) {
bad_kb->st.state = worker_state;
} else if(worker_state == BadKbStateNotConnected) { // State: Not connected
if((bad_kb->bt && bt_connected) || (!bad_kb->bt && usb_connected)) {
uint32_t flags = bad_kb_flags_get(
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle, FuriWaitForever);
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtConnect) {
worker_state = BadKbStateIdle; // Ready to run
} else {
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle,
FuriFlagWaitAny,
FuriWaitForever);
furi_check((flags & FuriFlagError) == 0);
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtConnect) {
worker_state = BadKbStateIdle; // Ready to run
} else if(flags & WorkerEvtToggle) {
worker_state = BadKbStateWillRun; // Will run when connected
}
} else if(flags & WorkerEvtToggle) {
worker_state = BadKbStateWillRun; // Will run when connected
}
bad_kb->st.state = worker_state;
} else if(worker_state == BadKbStateIdle) { // State: ready to start
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect,
FuriFlagWaitAny,
FuriWaitForever);
furi_check((flags & FuriFlagError) == 0);
uint32_t flags = bad_kb_flags_get(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriWaitForever);
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtToggle) { // Start executing script
@@ -777,6 +812,7 @@ static int32_t bad_kb_worker(void* context) {
bad_kb->buf_len = 0;
bad_kb->st.line_cur = 0;
bad_kb->defdelay = 0;
bad_kb->stringdelay = 0;
bad_kb->repeat_cnt = 0;
bad_kb->file_end = false;
storage_file_seek(script_file, 0, true);
@@ -788,11 +824,8 @@ static int32_t bad_kb_worker(void* context) {
bad_kb->st.state = worker_state;
} else if(worker_state == BadKbStateWillRun) { // State: start on connection
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle,
FuriFlagWaitAny,
FuriWaitForever);
furi_check((flags & FuriFlagError) == 0);
uint32_t flags = bad_kb_flags_get(
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle, FuriWaitForever);
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtConnect) { // Start executing script
@@ -801,16 +834,26 @@ static int32_t bad_kb_worker(void* context) {
bad_kb->buf_len = 0;
bad_kb->st.line_cur = 0;
bad_kb->defdelay = 0;
bad_kb->stringdelay = 0;
bad_kb->repeat_cnt = 0;
bad_kb->file_end = false;
storage_file_seek(script_file, 0, true);
// extra time for PC to recognize Flipper as keyboard
furi_thread_flags_wait(0, FuriFlagWaitAny, 1500);
flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtDisconnect | WorkerEvtToggle,
FuriFlagWaitAny | FuriFlagNoClear,
1500);
if(flags == (unsigned)FuriFlagErrorTimeout) {
// If nothing happened - start script execution
worker_state = BadKbStateRunning;
} else if(flags & WorkerEvtToggle) {
worker_state = BadKbStateIdle;
furi_thread_flags_clear(WorkerEvtToggle);
}
if(bad_kb->bt) {
update_bt_timeout(bad_kb->bt);
}
bad_kb_script_set_keyboard_layout(bad_kb, bad_kb->keyboard_layout);
worker_state = BadKbStateRunning;
} else if(flags & WorkerEvtToggle) { // Cancel scheduled execution
worker_state = BadKbStateNotConnected;
}
@@ -875,9 +918,8 @@ static int32_t bad_kb_worker(void* context) {
} else if(
(worker_state == BadKbStateFileError) ||
(worker_state == BadKbStateScriptError)) { // State: error
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd, FuriFlagWaitAny, FuriWaitForever); // Waiting for exit command
furi_check((flags & FuriFlagError) == 0);
uint32_t flags =
bad_kb_flags_get(WorkerEvtEnd, FuriWaitForever); // Waiting for exit command
if(flags & WorkerEvtEnd) {
break;
}
@@ -921,6 +963,7 @@ BadKbScript* bad_kb_script_open(FuriString* file_path, Bt* bt) {
bad_kb->st.state = BadKbStateInit;
bad_kb->st.error[0] = '\0';
bad_kb->st.is_bt = !!bt;
bad_kb->bt = bt;
+10 -2
View File
@@ -7,6 +7,8 @@ extern "C" {
#include <furi.h>
#include <bt/bt_service/bt_i.h>
typedef struct BadKbApp BadKbApp;
typedef struct BadKbScript BadKbScript;
typedef enum {
@@ -23,6 +25,8 @@ typedef enum {
typedef struct {
BadKbWorkerState state;
bool is_bt;
uint32_t pin;
uint16_t line_cur;
uint16_t line_nb;
uint32_t delay_remain;
@@ -30,9 +34,13 @@ typedef struct {
char error[64];
} BadKbState;
void bad_kb_connection_init(Bt* bt);
void bad_kb_config_switch_mode(BadKbApp* app);
void bad_kb_connection_deinit(Bt* bt);
void bad_kb_config_switch_remember_mode(BadKbApp* app);
int32_t bad_kb_connection_init(BadKbApp* app);
void bad_kb_connection_deinit(BadKbApp* app);
BadKbScript* bad_kb_script_open(FuriString* file_path, Bt* bt);
@@ -5,6 +5,7 @@
enum VarItemListIndex {
VarItemListIndexConnection,
VarItemListIndexRemember,
VarItemListIndexKeyboardLayout,
VarItemListIndexAdvertisementName,
VarItemListIndexMacAddress,
@@ -19,6 +20,15 @@ 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->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, VarItemListIndexRemember);
}
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 +44,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, "Remember", 2, bad_kb_scene_config_bt_bounding_callback, bad_kb);
variable_item_set_current_value_index(item, bad_kb->bt_remember);
variable_item_set_current_value_text(item, bad_kb->bt_remember ? "ON" : "OFF");
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->bt_remember) {
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);
@@ -56,23 +74,15 @@ bool bad_kb_scene_config_bt_on_event(void* context, SceneManagerEvent event) {
if(event.event == VarItemListIndexKeyboardLayout) {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigLayout);
} else if(event.event == VarItemListIndexConnection) {
bad_kb_script_close(bad_kb->bad_kb_script);
bad_kb_connection_deinit(bad_kb->bt);
bad_kb->bad_kb_script =
bad_kb_script_open(bad_kb->file_path, bad_kb->is_bt ? bad_kb->bt : NULL);
bad_kb_script_set_keyboard_layout(bad_kb->bad_kb_script, bad_kb->keyboard_layout);
bad_kb_config_switch_mode(bad_kb);
} else if(event.event == VarItemListIndexRemember) {
bad_kb_config_switch_remember_mode(bad_kb);
scene_manager_previous_scene(bad_kb->scene_manager);
if(bad_kb->is_bt) {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigBt);
} else {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigUsb);
}
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigBt);
} else if(event.event == VarItemListIndexAdvertisementName) {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigName);
} else if(event.event == VarItemListIndexMacAddress) {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigMac);
// } else {
// furi_crash("Unknown key type");
}
}
@@ -2,14 +2,14 @@
#define TAG "BadKbConfigMac"
static uint8_t* reverse_mac_addr(uint8_t* mac) {
static uint8_t* reverse_mac_addr(uint8_t* mac, uint8_t* out) {
uint8_t tmp;
for(int i = 0; i < 3; i++) {
tmp = mac[i];
mac[i] = mac[5 - i];
mac[5 - i] = tmp;
out[i] = mac[5 - i];
out[5 - i] = tmp;
}
return mac;
return out;
}
void bad_kb_scene_config_mac_byte_input_callback(void* context) {
@@ -29,7 +29,7 @@ void bad_kb_scene_config_mac_on_enter(void* context) {
bad_kb_scene_config_mac_byte_input_callback,
NULL,
bad_kb,
reverse_mac_addr(bad_kb->mac),
reverse_mac_addr(bad_kb->mac, bad_kb->mac),
GAP_MAC_ADDR_SIZE);
view_dispatcher_switch_to_view(bad_kb->view_dispatcher, BadKbAppViewConfigMac);
}
@@ -40,7 +40,8 @@ bool bad_kb_scene_config_mac_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == BadKbAppCustomEventByteInputDone) {
bt_set_profile_mac_address(bad_kb->bt, reverse_mac_addr(bad_kb->mac));
uint8_t mac[GAP_MAC_ADDR_SIZE];
bt_set_profile_mac_address(bad_kb->bt, reverse_mac_addr(bad_kb->mac, mac));
scene_manager_previous_scene(bad_kb->scene_manager);
consumed = true;
}
@@ -54,4 +55,7 @@ void bad_kb_scene_config_mac_on_exit(void* context) {
// Clear view
byte_input_set_result_callback(bad_kb->byte_input, NULL, NULL, NULL, NULL, 0);
byte_input_set_header_text(bad_kb->byte_input, "");
// reverse back addr (in case it didn't get modified)
reverse_mac_addr(bad_kb->mac, bad_kb->mac);
}
@@ -50,19 +50,7 @@ bool bad_kb_scene_config_usb_on_event(void* context, SceneManagerEvent event) {
if(event.event == VarItemListIndexKeyboardLayout) {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigLayout);
} else if(event.event == VarItemListIndexConnection) {
bad_kb_script_close(bad_kb->bad_kb_script);
bad_kb_connection_deinit(bad_kb->bt);
bad_kb->bad_kb_script =
bad_kb_script_open(bad_kb->file_path, bad_kb->is_bt ? bad_kb->bt : NULL);
bad_kb_script_set_keyboard_layout(bad_kb->bad_kb_script, bad_kb->keyboard_layout);
scene_manager_previous_scene(bad_kb->scene_manager);
if(bad_kb->is_bt) {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigBt);
} else {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneConfigUsb);
}
// } else {
// furi_crash("Unknown key type");
bad_kb_config_switch_mode(bad_kb);
}
}
@@ -22,7 +22,6 @@ static bool bad_kb_file_select(BadKbApp* bad_kb) {
void bad_kb_scene_file_select_on_enter(void* context) {
BadKbApp* bad_kb = context;
furi_hal_usb_disable();
if(bad_kb->bad_kb_script) {
bad_kb_script_close(bad_kb->bad_kb_script);
bad_kb->bad_kb_script = NULL;
@@ -35,7 +34,6 @@ void bad_kb_scene_file_select_on_enter(void* context) {
scene_manager_next_scene(bad_kb->scene_manager, BadKbSceneWork);
} else {
furi_hal_usb_enable();
view_dispatcher_stop(bad_kb->view_dispatcher);
}
}
@@ -16,10 +16,12 @@ bool bad_kb_scene_work_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == InputKeyLeft) {
if(app->is_bt) {
scene_manager_next_scene(app->scene_manager, BadKbSceneConfigBt);
} else {
scene_manager_next_scene(app->scene_manager, BadKbSceneConfigUsb);
if(bad_kb_is_idle_state(app->bad_kb_view)) {
if(app->is_bt) {
scene_manager_next_scene(app->scene_manager, BadKbSceneConfigBt);
} else {
scene_manager_next_scene(app->scene_manager, BadKbSceneConfigUsb);
}
}
consumed = true;
} else if(event.event == InputKeyOk) {
+31 -7
View File
@@ -1,5 +1,6 @@
#include "bad_kb_view.h"
#include "../bad_kb_script.h"
#include "../bad_kb_app_i.h"
#include <toolbox/path.h>
#include <gui/elements.h>
#include <assets_icons.h>
@@ -24,7 +25,8 @@ static void bad_kb_draw_callback(Canvas* canvas, void* _model) {
BadKbModel* model = _model;
FuriString* disp_str;
disp_str = furi_string_alloc_set(model->file_name);
disp_str = furi_string_alloc_set(model->state.is_bt ? "(BT) " : "(USB) ");
furi_string_cat_str(disp_str, 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));
@@ -38,6 +40,9 @@ static void bad_kb_draw_callback(Canvas* canvas, void* _model) {
furi_string_push_back(disp_str, model->layout[i]);
furi_string_push_back(disp_str, ')');
}
if(model->state.pin) {
furi_string_cat_printf(disp_str, " PIN: %ld", model->state.pin);
}
elements_string_fit_width(canvas, disp_str, 128 - 2);
canvas_draw_str(
canvas, 2, 8 + canvas_current_font_height(canvas), furi_string_get_cstr(disp_str));
@@ -51,19 +56,15 @@ static void bad_kb_draw_callback(Canvas* canvas, void* _model) {
if(XTREME_ASSETS()->is_nsfw) {
elements_button_center(canvas, "Cum");
} else {
elements_button_center(canvas, "Start");
elements_button_center(canvas, "Run");
}
elements_button_left(canvas, "Config");
} else if((model->state.state == BadKbStateRunning) || (model->state.state == BadKbStateDelay)) {
elements_button_center(canvas, "Stop");
} else if(model->state.state == BadKbStateWillRun) {
elements_button_center(canvas, "Cancel");
}
if((model->state.state == BadKbStateNotConnected) || (model->state.state == BadKbStateIdle) ||
(model->state.state == BadKbStateDone)) {
elements_button_left(canvas, "Config");
}
if(model->state.state == BadKbStateNotConnected) {
canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18);
canvas_set_font(canvas, FontPrimary);
@@ -214,6 +215,14 @@ void bad_kb_set_layout(BadKb* bad_kb, const char* layout) {
void bad_kb_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,
@@ -223,3 +232,18 @@ void bad_kb_set_state(BadKb* bad_kb, BadKbState* st) {
},
true);
}
bool bad_kb_is_idle_state(BadKb* bad_kb) {
bool is_idle = false;
with_view_model(
bad_kb->view,
BadKbModel * model,
{
if((model->state.state == BadKbStateIdle) || (model->state.state == BadKbStateDone) ||
(model->state.state == BadKbStateNotConnected)) {
is_idle = true;
}
},
false);
return is_idle;
}
@@ -19,3 +19,5 @@ void bad_kb_set_file_name(BadKb* bad_kb, const char* name);
void bad_kb_set_layout(BadKb* bad_kb, const char* layout);
void bad_kb_set_state(BadKb* bad_kb, BadKbState* st);
bool bad_kb_is_idle_state(BadKb* bad_kb);
@@ -8,6 +8,14 @@ static void xtreme_app_scene_protocols_bad_bk_mode_changed(VariableItem* item) {
app->save_settings = true;
}
static void xtreme_app_scene_protocols_bad_bt_remember_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item);
bool value = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, value ? "ON" : "OFF");
XTREME_SETTINGS()->bad_bt_remember = value;
app->save_settings = true;
}
static void xtreme_app_scene_protocols_subghz_extend_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item);
app->subghz_extend = variable_item_get_current_value_index(item);
@@ -33,6 +41,15 @@ void xtreme_app_scene_protocols_on_enter(void* context) {
variable_item_set_current_value_index(item, xtreme_settings->bad_bt);
variable_item_set_current_value_text(item, xtreme_settings->bad_bt ? "BT" : "USB");
item = variable_item_list_add(
var_item_list,
"Bad BT Remember",
2,
xtreme_app_scene_protocols_bad_bt_remember_changed,
app);
variable_item_set_current_value_index(item, xtreme_settings->bad_bt_remember);
variable_item_set_current_value_text(item, xtreme_settings->bad_bt_remember ? "ON" : "OFF");
item = variable_item_list_add(
var_item_list, "SubGHz Extend", 2, xtreme_app_scene_protocols_subghz_extend_changed, app);
variable_item_set_current_value_index(item, app->subghz_extend);
+14 -7
View File
@@ -61,8 +61,11 @@ static ViewPort* bt_pin_code_view_port_alloc(Bt* bt) {
}
static void bt_pin_code_show(Bt* bt, uint32_t pin_code) {
furi_assert(bt);
bt->pin_code = pin_code;
notification_message(bt->notification, &sequence_display_backlight_on);
if(bt->suppress_pin_screen) return;
gui_view_port_send_to_front(bt->gui, bt->pin_code_view_port);
view_port_enabled_set(bt->pin_code_view_port, true);
}
@@ -76,10 +79,10 @@ static void bt_pin_code_hide(Bt* bt) {
static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) {
furi_assert(bt);
if(bt_get_profile_pairing_method(bt) == GapPairingNone) return true;
bt->pin_code = pin;
notification_message(bt->notification, &sequence_display_backlight_on);
if(bt->suppress_pin_screen) return true;
FuriString* pin_str;
dialog_message_set_icon(bt->dialog_message, XTREME_ASSETS()->I_BLE_Pairing_128x64, 0, 0);
pin_str = furi_string_alloc_printf("Verify code\n%06lu", pin);
@@ -154,6 +157,8 @@ Bt* bt_alloc() {
// API evnent
bt->api_event = furi_event_flag_alloc();
bt->pin = 0;
return bt;
}
@@ -219,6 +224,7 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) {
furi_assert(context);
Bt* bt = context;
bool ret = false;
bt->pin = 0;
if(event.type == GapEventTypeConnected) {
// Update status bar
@@ -275,12 +281,14 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) {
furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk);
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;
@@ -419,17 +427,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;
}
@@ -451,6 +457,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);
}
+1 -1
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);
@@ -76,4 +76,6 @@ struct Bt {
FuriEventFlag* api_event;
BtStatusChangedCallback status_changed_cb;
void* status_changed_ctx;
uint32_t pin;
bool suppress_pin_screen;
};
+1
View File
@@ -39,6 +39,7 @@ void XTREME_SETTINGS_LOAD() {
xtreme_settings->bar_borders = true; // ON
xtreme_settings->bar_background = false; // OFF
xtreme_settings->bad_bt = false; // USB
xtreme_settings->bad_bt_remember = false; // OFF
xtreme_settings->butthurt_timer = 43200; // 12 H
xtreme_settings->sort_dirs_first = true; // ON
xtreme_settings->dark_mode = false; // OFF
+2 -1
View File
@@ -11,7 +11,7 @@
#define MAX_PACK_NAME_LEN 32
#define XTREME_SETTINGS_VERSION (4)
#define XTREME_SETTINGS_VERSION (5)
#define XTREME_SETTINGS_PATH INT_PATH(XTREME_SETTINGS_FILE_NAME)
#define XTREME_SETTINGS_MAGIC (0x69)
@@ -28,6 +28,7 @@ typedef struct {
bool bar_borders;
bool bar_background;
bool bad_bt;
bool bad_bt_remember;
int32_t butthurt_timer;
bool sort_dirs_first;
bool dark_mode;
@@ -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;
}
+1 -1
View File
@@ -593,7 +593,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
593 Function + bt_get_profile_pairing_method GapPairing Bt*
594 Function + bt_keys_storage_set_default_path void Bt*
595 Function + bt_keys_storage_set_storage_path void Bt*, const char*
596 Function + bt_remote_rssi _Bool Bt*, BtRssi* Bt*, uint8_t*
597 Function + bt_set_profile _Bool Bt*, BtProfile
598 Function + bt_set_profile_adv_name void Bt*, const char*, ...
599 Function + bt_set_profile_mac_address void Bt*, const uint8_t[6]
+10 -8
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,
@@ -515,16 +517,16 @@ bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) {
gap->advertise_timer = furi_timer_alloc(gap_advetise_timer_callback, FuriTimerTypeOnce, NULL);
// Initialization of GATT & GAP layer
gap->service.adv_name = config->adv_name;
FURI_LOG_I(TAG, "Advertising name: %s", &(gap->service.adv_name[1]));
FURI_LOG_I(
FURI_LOG_D(TAG, "Advertising name: %s", &(gap->service.adv_name[1]));
FURI_LOG_D(
TAG,
"MAC @ : %02X:%02X:%02X:%02X:%02X:%02X",
config->mac_address[0],
config->mac_address[1],
config->mac_address[2],
config->mac_address[3],
config->mac_address[5],
config->mac_address[4],
config->mac_address[5]);
config->mac_address[3],
config->mac_address[2],
config->mac_address[1],
config->mac_address[0]);
gap_init_svc(gap);
// Initialization of the BLE Services
SVCCTL_Init();
+23 -7
View File
@@ -209,6 +209,12 @@ bool furi_hal_bt_start_app(FuriHalBtProfile profile, GapEventCallback event_cb,
profile_config[profile].config.mac_address,
furi_hal_version_get_ble_mac(),
sizeof(profile_config[profile].config.mac_address));
// Set advertise name
strlcpy(
profile_config[profile].config.adv_name,
furi_hal_version_get_ble_local_device_name_ptr(),
FURI_HAL_VERSION_DEVICE_NAME_LENGTH);
config->adv_service_uuid |= furi_hal_version_get_hw_color();
} else if(profile == FuriHalBtProfileHidKeyboard) {
// Change MAC address for HID profile
@@ -218,8 +224,11 @@ bool furi_hal_bt_start_app(FuriHalBtProfile profile, GapEventCallback event_cb,
}
// Change name Flipper -> Control
if(strlen(&config->adv_name[1]) == 0) {
const char* clicker_str = "Control";
memcpy(&config->adv_name[1], clicker_str, strlen(clicker_str));
snprintf(
&config->adv_name[1],
strlen("Control ") + FURI_HAL_VERSION_DEVICE_NAME_LENGTH,
"Control %s",
furi_hal_version_get_ble_local_device_name_ptr());
}
}
if(!gap_init(config, event_cb, context)) {
@@ -470,11 +479,18 @@ void furi_hal_bt_set_profile_adv_name(
furi_assert(profile < FuriHalBtProfileNumber);
furi_assert(name);
profile_config[profile].config.adv_name[0] = 0x09;
memcpy(
&(profile_config[profile].config.adv_name[1]),
name,
FURI_HAL_VERSION_DEVICE_NAME_LENGTH - 1);
if(strlen(name) == 0) {
memset(
&(profile_config[profile].config.adv_name[1]),
0,
strlen(&(profile_config[profile].config.adv_name[1])));
} else {
profile_config[profile].config.adv_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;
memcpy(
&(profile_config[profile].config.adv_name[1]),
name,
FURI_HAL_VERSION_DEVICE_NAME_LENGTH - 1);
}
}
const char* furi_hal_bt_get_profile_adv_name(FuriHalBtProfile profile) {