Skip to content

Commit

Permalink
feat(ble): handle BLE disconnection request
Browse files Browse the repository at this point in the history
- added switch `CONFIG_ZMK_HANDLE_BLE_DISCONNECTION`
- fix KinesisCorporation/Adv360-Pro-ZMK#172
  • Loading branch information
cvcore committed Jul 31, 2023
1 parent 4b5ecbc commit 06023f9
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 9 deletions.
4 changes: 4 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ config ZMK_BLE_PASSKEY_ENTRY
bool "Experimental: Requiring typing passkey from host to pair BLE connection"
default n

config ZMK_HANDLE_BLE_DISCONNECTION
bool "Experimental: Respect user disconnection request from computer"
default n

config BT_PERIPHERAL_PREF_MIN_INT
default 6

Expand Down
55 changes: 46 additions & 9 deletions app/src/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/event_manager.h>
#include <zmk/events/ble_active_profile_changed.h>

#if IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION)
#include <zmk/activity.h>
#include <zmk/events/keycode_state_changed.h>
#endif /* IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION) */

#if IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY)
#include <zmk/events/keycode_state_changed.h>

Expand Down Expand Up @@ -68,6 +73,10 @@ enum advertising_type {
static struct zmk_ble_profile profiles[ZMK_BLE_PROFILE_COUNT];
static uint8_t active_profile;

#if IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION)
bool active_profile_seeking_connection = true;
#endif

#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)

Expand Down Expand Up @@ -173,15 +182,23 @@ int update_advertising() {

if (zmk_ble_active_profile_is_open()) {
desired_adv = ZMK_ADV_CONN;
} else if (!zmk_ble_active_profile_is_connected()) {
desired_adv = ZMK_ADV_CONN;
// Need to fix directed advertising for privacy centrals. See
// https://github.com/zephyrproject-rtos/zephyr/pull/14984 char
// addr_str[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(zmk_ble_active_profile_addr(), addr_str,
// sizeof(addr_str));

// LOG_DBG("Directed advertising to %s", addr_str);
// desired_adv = ZMK_ADV_DIR;
} else {
#if IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION)
if (!zmk_ble_active_profile_is_connected() && active_profile_seeking_connection) {
desired_adv = ZMK_ADV_CONN;
}
#else
if (!zmk_ble_active_profile_is_connected()) {
desired_adv = ZMK_ADV_CONN;
// Need to fix directed advertising for privacy centrals. See
// https://github.com/zephyrproject-rtos/zephyr/pull/14984 char
// addr_str[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(zmk_ble_active_profile_addr(),
// addr_str, sizeof(addr_str));

// LOG_DBG("Directed advertising to %s", addr_str);
// desired_adv = ZMK_ADV_DIR;
}
#endif /* IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION) */
}
LOG_DBG("advertising from %d to %d", advertising_status, desired_adv);

Expand Down Expand Up @@ -268,6 +285,9 @@ int zmk_ble_prof_select(uint8_t index) {
active_profile = index;
ble_save_profile();

#if IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION)
active_profile_seeking_connection = true;
#endif
update_advertising();

raise_profile_changed_event();
Expand Down Expand Up @@ -406,6 +426,9 @@ static void connected(struct bt_conn *conn, uint8_t err) {
update_advertising();

if (is_conn_active_profile(conn)) {
#if IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION)
active_profile_seeking_connection = false;
#endif
LOG_DBG("Active profile connected");
k_work_submit(&raise_profile_changed_event_work);
}
Expand Down Expand Up @@ -694,4 +717,18 @@ ZMK_LISTENER(zmk_ble, zmk_ble_listener);
ZMK_SUBSCRIPTION(zmk_ble, zmk_keycode_state_changed);
#endif /* IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) */

#if IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION)
/* Restart BLE advertsing after user key press */
static int ble_keypress_listener(const zmk_event_t *eh) {
if (as_zmk_keycode_state_changed(eh) != NULL && !active_profile_seeking_connection &&
!zmk_ble_active_profile_is_connected()) {
active_profile_seeking_connection = true;
k_work_submit(&update_advertising_work);
}
return 0;
}
ZMK_LISTENER(ble_keypress, ble_keypress_listener);
ZMK_SUBSCRIPTION(ble_keypress, zmk_keycode_state_changed);
#endif /* IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION) */

SYS_INIT(zmk_ble_init, APPLICATION, CONFIG_ZMK_BLE_INIT_PRIORITY);
1 change: 1 addition & 0 deletions docs/docs/config/system.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ for more information on configuring Bluetooth.
| `CONFIG_ZMK_BLE_THREAD_PRIORITY` | int | Priority of the BLE notify thread | 5 |
| `CONFIG_ZMK_BLE_THREAD_STACK_SIZE` | int | Stack size of the BLE notify thread | 512 |
| `CONFIG_ZMK_BLE_PASSKEY_ENTRY` | bool | Experimental: require typing passkey from host to pair BLE connection | n |
| `CONFIG_ZMK_HANDLE_BLE_DISCONNECTION` | bool | Experimental: respect user BLE disconnection request from computer | n |

Note that `CONFIG_BT_MAX_CONN` and `CONFIG_BT_MAX_PAIRED` should be set to the same value. On a split keyboard they should only be set for the central and must be set to one greater than the desired number of bluetooth profiles.

Expand Down

0 comments on commit 06023f9

Please sign in to comment.