diff --git a/applications/main/bad_kb/bad_kb_app.c b/applications/main/bad_kb/bad_kb_app.c index e1219ffc4..2934a50c2 100644 --- a/applications/main/bad_kb/bad_kb_app.c +++ b/applications/main/bad_kb/bad_kb_app.c @@ -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); } diff --git a/applications/main/bad_kb/bad_kb_app.h b/applications/main/bad_kb/bad_kb_app.h index e75a94651..af64be253 100644 --- a/applications/main/bad_kb/bad_kb_app.h +++ b/applications/main/bad_kb/bad_kb_app.h @@ -6,8 +6,6 @@ extern "C" { typedef struct BadKbApp BadKbApp; -void bad_kb_set_name(BadKbApp* app, const char* fmt, ...); - #ifdef __cplusplus } #endif diff --git a/applications/main/bad_kb/bad_kb_app_i.h b/applications/main/bad_kb/bad_kb_app_i.h index 38cae44c5..b7194ac3c 100644 --- a/applications/main/bad_kb/bad_kb_app_i.h +++ b/applications/main/bad_kb/bad_kb_app_i.h @@ -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 { diff --git a/applications/main/bad_kb/bad_kb_script.c b/applications/main/bad_kb/bad_kb_script.c index 99622ff7c..b91f36b9f 100644 --- a/applications/main/bad_kb/bad_kb_script.c +++ b/applications/main/bad_kb/bad_kb_script.c @@ -11,6 +11,8 @@ #include +#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; diff --git a/applications/main/bad_kb/bad_kb_script.h b/applications/main/bad_kb/bad_kb_script.h index 0ea701eb8..a724971ec 100644 --- a/applications/main/bad_kb/bad_kb_script.h +++ b/applications/main/bad_kb/bad_kb_script.h @@ -7,6 +7,8 @@ extern "C" { #include #include +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); diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_bt.c index 4412f0796..70dde9e16 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_bt.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_bt.c @@ -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"); } } diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_mac.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_mac.c index 4463d1c40..d7027537a 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_mac.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_mac.c @@ -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); } diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb.c b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb.c index 232ef8796..d3ff35fc8 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_config_usb.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_config_usb.c @@ -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); } } diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_file_select.c b/applications/main/bad_kb/scenes/bad_kb_scene_file_select.c index bb2ddf6ca..ba238f390 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_file_select.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_file_select.c @@ -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); } } diff --git a/applications/main/bad_kb/scenes/bad_kb_scene_work.c b/applications/main/bad_kb/scenes/bad_kb_scene_work.c index 165ee0289..e962f9132 100644 --- a/applications/main/bad_kb/scenes/bad_kb_scene_work.c +++ b/applications/main/bad_kb/scenes/bad_kb_scene_work.c @@ -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) { diff --git a/applications/main/bad_kb/views/bad_kb_view.c b/applications/main/bad_kb/views/bad_kb_view.c index 1ffe58e9c..26ec90809 100644 --- a/applications/main/bad_kb/views/bad_kb_view.c +++ b/applications/main/bad_kb/views/bad_kb_view.c @@ -1,5 +1,6 @@ #include "bad_kb_view.h" #include "../bad_kb_script.h" +#include "../bad_kb_app_i.h" #include #include #include @@ -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; +} diff --git a/applications/main/bad_kb/views/bad_kb_view.h b/applications/main/bad_kb/views/bad_kb_view.h index 24fdf4792..f16814bb4 100644 --- a/applications/main/bad_kb/views/bad_kb_view.h +++ b/applications/main/bad_kb/views/bad_kb_view.h @@ -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); diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols.c index 0350785e7..47027d9d8 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_protocols.c @@ -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); diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index e72f1255c..31a43f637 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -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); } diff --git a/applications/services/bt/bt_service/bt.h b/applications/services/bt/bt_service/bt.h index a79c227f7..eb762dbf4 100644 --- a/applications/services/bt/bt_service/bt.h +++ b/applications/services/bt/bt_service/bt.h @@ -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); diff --git a/applications/services/bt/bt_service/bt_i.h b/applications/services/bt/bt_service/bt_i.h index c8a0e9965..41e5bcd8c 100644 --- a/applications/services/bt/bt_service/bt_i.h +++ b/applications/services/bt/bt_service/bt_i.h @@ -76,4 +76,6 @@ struct Bt { FuriEventFlag* api_event; BtStatusChangedCallback status_changed_cb; void* status_changed_ctx; + uint32_t pin; + bool suppress_pin_screen; }; diff --git a/applications/services/xtreme/settings.c b/applications/services/xtreme/settings.c index 8036c8d58..881ab8950 100644 --- a/applications/services/xtreme/settings.c +++ b/applications/services/xtreme/settings.c @@ -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 diff --git a/applications/services/xtreme/settings.h b/applications/services/xtreme/settings.h index b870235ec..87f64bb54 100644 --- a/applications/services/xtreme/settings.h +++ b/applications/services/xtreme/settings.h @@ -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; diff --git a/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_confirm.c b/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_confirm.c index 31921b9f3..c912f2e5d 100644 --- a/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_confirm.c +++ b/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_confirm.c @@ -1,5 +1,6 @@ #include "../bt_settings_app.h" #include +#include 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; } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 8075414e2..99448036e 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -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]" diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index 83944b4b5..ebf27b369 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -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(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index d2ce57c4d..198bb4454 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -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) {