diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 1492be16..ee6d8759 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -63,27 +63,34 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) target_sources(app PRIVATE src/combo.c) target_sources(app PRIVATE src/behavior_queue.c) target_sources(app PRIVATE src/conditional_layer.c) + target_sources(app PRIVATE src/endpoints.c) + target_sources(app PRIVATE src/hid_listener.c) target_sources(app PRIVATE src/keymap.c) + + target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/behaviors/behavior_bt.c) + + if (CONFIG_ZMK_BLE) + target_sources(app PRIVATE src/ble.c) + target_sources(app PRIVATE src/hog.c) + endif() endif() + target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/behaviors/behavior_rgb_underglow.c) target_sources_ifdef(CONFIG_ZMK_BACKLIGHT app PRIVATE src/behaviors/behavior_backlight.c) -target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/behaviors/behavior_bt.c) -target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/battery.c) + if (CONFIG_ZMK_SPLIT_BLE AND (NOT CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)) - target_sources(app PRIVATE src/split_listener.c) - target_sources(app PRIVATE src/split/bluetooth/service.c) + target_sources(app PRIVATE src/split_listener.c) + target_sources(app PRIVATE src/split/bluetooth/service.c) + target_sources(app PRIVATE src/split/bluetooth/peripheral.c) endif() if (CONFIG_ZMK_SPLIT_BLE AND CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) - target_sources(app PRIVATE src/split/bluetooth/central.c) + target_sources(app PRIVATE src/split/bluetooth/central.c) endif() target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/usb.c) target_sources_ifdef(CONFIG_ZMK_USB app PRIVATE src/usb_hid.c) -target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/hog.c) target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/rgb_underglow.c) target_sources_ifdef(CONFIG_ZMK_BACKLIGHT app PRIVATE src/backlight.c) -target_sources(app PRIVATE src/endpoints.c) -target_sources(app PRIVATE src/hid_listener.c) target_sources(app PRIVATE src/main.c) add_subdirectory(src/display/) diff --git a/app/src/ble.c b/app/src/ble.c index aecf6023..131b39b4 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -36,14 +36,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include -#define IS_HOST_PERIPHERAL \ - (!IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)) -#define IS_SPLIT_PERIPHERAL \ - (IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)) - -#define DO_PASSKEY_ENTRY (IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) && !IS_SPLIT_PERIPHERAL) - -#if DO_PASSKEY_ENTRY +#if IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) #include #define PASSKEY_DIGITS 6 @@ -52,7 +45,7 @@ static struct bt_conn *auth_passkey_entry_conn; static uint8_t passkey_entries[PASSKEY_DIGITS] = {}; static uint8_t passkey_digit = 0; -#endif +#endif /* IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) */ #if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) #define PROFILE_COUNT (CONFIG_BT_MAX_PAIRED - 1) @@ -81,20 +74,12 @@ static uint8_t active_profile; BUILD_ASSERT(DEVICE_NAME_LEN <= 16, "ERROR: BLE device name is too long. Max length: 16"); static const struct bt_data zmk_ble_ad[] = { -#if IS_HOST_PERIPHERAL BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE, 0xC1, 0x03), -#endif BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), - BT_DATA_BYTES(BT_DATA_UUID16_SOME, -#if IS_HOST_PERIPHERAL - 0x12, 0x18, /* HID Service */ -#endif - 0x0f, 0x18 /* Battery Service */ + BT_DATA_BYTES(BT_DATA_UUID16_SOME, 0x12, 0x18, /* HID Service */ + 0x0f, 0x18 /* Battery Service */ ), -#if IS_SPLIT_PERIPHERAL - BT_DATA_BYTES(BT_DATA_UUID128_ALL, ZMK_SPLIT_BT_SERVICE_UUID) -#endif }; #if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) @@ -473,7 +458,7 @@ static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey) { } */ -#if DO_PASSKEY_ENTRY +#if IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) static void auth_passkey_entry(struct bt_conn *conn) { char addr[BT_ADDR_LE_STR_LEN]; @@ -492,7 +477,7 @@ static void auth_cancel(struct bt_conn *conn) { bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); -#if DO_PASSKEY_ENTRY +#if IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) if (auth_passkey_entry_conn) { bt_conn_unref(auth_passkey_entry_conn); auth_passkey_entry_conn = NULL; @@ -504,7 +489,6 @@ static void auth_cancel(struct bt_conn *conn) { LOG_DBG("Pairing cancelled: %s", log_strdup(addr)); } -#if IS_HOST_PERIPHERAL static enum bt_security_err auth_pairing_accept(struct bt_conn *conn, const struct bt_conn_pairing_feat *const feat) { struct bt_conn_info info; @@ -518,7 +502,6 @@ static enum bt_security_err auth_pairing_accept(struct bt_conn *conn, return BT_SECURITY_ERR_SUCCESS; }; -#endif /* IS_HOST_PERIPHERAL */ static void auth_pairing_complete(struct bt_conn *conn, bool bonded) { struct bt_conn_info info; @@ -533,26 +516,22 @@ static void auth_pairing_complete(struct bt_conn *conn, bool bonded) { return; } -#if IS_HOST_PERIPHERAL if (!zmk_ble_active_profile_is_open()) { LOG_ERR("Pairing completed but current profile is not open: %s", log_strdup(addr)); bt_unpair(BT_ID_DEFAULT, dst); return; } -#endif /* IS_HOST_PERIPHERAL */ set_profile_address(active_profile, dst); update_advertising(); }; static struct bt_conn_auth_cb zmk_ble_auth_cb_display = { -#if IS_HOST_PERIPHERAL .pairing_accept = auth_pairing_accept, -#endif /* IS_HOST_PERIPHERAL */ .pairing_complete = auth_pairing_complete, // .passkey_display = auth_passkey_display, -#if DO_PASSKEY_ENTRY +#if IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) .passkey_entry = auth_passkey_entry, #endif .cancel = auth_cancel, @@ -595,9 +574,7 @@ static int zmk_ble_init(const struct device *_arg) { #if IS_ENABLED(CONFIG_ZMK_BLE_CLEAR_BONDS_ON_START) LOG_WRN("Clearing all existing BLE bond information from the keyboard"); - for (int i = 0; i < 10; i++) { - bt_unpair(i, NULL); - } + bt_unpair(BT_ID_DEFAULT, NULL); for (int i = 0; i < ZMK_BLE_PROFILE_COUNT; i++) { char setting_name[15]; @@ -618,21 +595,7 @@ static int zmk_ble_init(const struct device *_arg) { return 0; } -int zmk_ble_unpair_all() { - int resp = 0; - for (int i = BT_ID_DEFAULT; i < CONFIG_BT_ID_MAX; i++) { - - int err = bt_unpair(BT_ID_DEFAULT, NULL); - if (err) { - resp = err; - LOG_ERR("Failed to unpair devices (err %d)", err); - } - } - - return resp; -}; - -#if DO_PASSKEY_ENTRY +#if IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) static bool zmk_ble_numeric_usage_to_value(const zmk_key_t key, const zmk_key_t one, const zmk_key_t zero, uint32_t *value) { @@ -705,6 +668,6 @@ static int zmk_ble_listener(const zmk_event_t *eh) { ZMK_LISTENER(zmk_ble, zmk_ble_listener); ZMK_SUBSCRIPTION(zmk_ble, zmk_keycode_state_changed); -#endif /* DO_PASSKEY_ENTRY */ +#endif /* IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) */ SYS_INIT(zmk_ble_init, APPLICATION, CONFIG_ZMK_BLE_INIT_PRIORITY); diff --git a/app/src/split/bluetooth/peripheral.c b/app/src/split/bluetooth/peripheral.c new file mode 100644 index 00000000..13b75ba7 --- /dev/null +++ b/app/src/split/bluetooth/peripheral.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if IS_ENABLED(CONFIG_SETTINGS) + +#include + +#endif + +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include + +static const struct bt_data zmk_ble_ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_SOME, 0x0f, 0x18 /* Battery Service */ + ), + BT_DATA_BYTES(BT_DATA_UUID128_ALL, ZMK_SPLIT_BT_SERVICE_UUID)}; + +static int start_advertising() { + return bt_le_adv_start(BT_LE_ADV_CONN, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0); +}; + +static void disconnected(struct bt_conn *conn, uint8_t reason) { + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + LOG_DBG("Disconnected from %s (reason 0x%02x)", log_strdup(addr), reason); +} + +static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) { + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (!err) { + LOG_DBG("Security changed: %s level %u", log_strdup(addr), level); + } else { + LOG_ERR("Security failed: %s level %u err %d", log_strdup(addr), level, err); + } +} + +static void le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, + uint16_t timeout) { + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + LOG_DBG("%s: interval %d latency %d timeout %d", log_strdup(addr), interval, latency, timeout); +} + +static struct bt_conn_cb conn_callbacks = { + .disconnected = disconnected, + .security_changed = security_changed, + .le_param_updated = le_param_updated, +}; + +static int zmk_peripheral_ble_init(const struct device *_arg) { + int err = bt_enable(NULL); + + if (err) { + LOG_ERR("BLUETOOTH FAILED (%d)", err); + return err; + } + +#if IS_ENABLED(CONFIG_SETTINGS) + settings_subsys_init(); + + settings_load_subtree("ble"); + settings_load_subtree("bt"); +#endif + +#if IS_ENABLED(CONFIG_ZMK_BLE_CLEAR_BONDS_ON_START) + LOG_WRN("Clearing all existing BLE bond information from the keyboard"); + + bt_unpair(BT_ID_DEFAULT, NULL); +#endif + + bt_conn_cb_register(&conn_callbacks); + + start_advertising(); + + return 0; +} + +SYS_INIT(zmk_peripheral_ble_init, APPLICATION, CONFIG_ZMK_BLE_INIT_PRIORITY);