Skip to content

Commit

Permalink
feat(ble): Add the ability to enable and disable advertising
Browse files Browse the repository at this point in the history
Currently advertising cannot be disabled, In some circumstances it may be desirable to disable advertising to the host e.g. seeking consistency between an endpoint switch and percieved board behaviour

Update behavior_bt.c

Revert "Update behavior_bt.c"

This reverts commit d822523.
  • Loading branch information
ReFil committed Oct 10, 2024
1 parent 022ede9 commit ac43a1b
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 7 deletions.
6 changes: 6 additions & 0 deletions app/include/dt-bindings/zmk/bt.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#define BT_SEL_CMD 3
#define BT_CLR_ALL_CMD 4
#define BT_DISC_CMD 5
#define BT_ADV_OFF_CMD 6
#define BT_ADV_ON_CMD 7
#define BT_ADV_TOG_CMD 8

/*
Note: Some future commands will include additional parameters, so we
Expand All @@ -22,3 +25,6 @@ defines these aliases up front.
#define BT_SEL BT_SEL_CMD
#define BT_CLR_ALL BT_CLR_ALL_CMD 0
#define BT_DISC BT_DISC_CMD
#define ADV_OFF BT_ADV_OFF_CMD 0
#define ADV_ON BT_ADV_ON_CMD 0
#define ADV_TOG BT_ADV_TOG_CMD 0
9 changes: 9 additions & 0 deletions app/include/zmk/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
#define ZMK_BLE_PROFILE_COUNT CONFIG_BT_MAX_PAIRED
#endif

enum advertising_type {
ZMK_ADV_NONE,
ZMK_ADV_DIR,
ZMK_ADV_CONN,
};

void zmk_ble_clear_bonds(void);
int zmk_ble_prof_next(void);
int zmk_ble_prof_prev(void);
Expand All @@ -41,6 +47,9 @@ int zmk_ble_unpair_all(void);

int zmk_ble_set_device_name(char *name);

void zmk_ble_adv_mode_set(bool mode);
enum advertising_type zmk_ble_adv_mode_get();

#if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
int zmk_ble_put_peripheral_addr(const bt_addr_le_t *addr);
#endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) */
24 changes: 24 additions & 0 deletions app/src/behaviors/behavior_bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ static const struct behavior_parameter_value_metadata no_arg_values[] = {
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
.value = BT_CLR_CMD,
},
{
.display_name = "Disconnect All and Stop Advertising",
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
.value = BT_ADV_OFF_CMD,
},
{
.display_name = "Start Advertising",
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
.value = BT_ADV_ON_CMD,
},
{
.display_name = "Toggle Advertising",
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
.value = BT_ADV_TOG_CMD,
},
};

static const struct behavior_parameter_metadata_set no_args_set = {
Expand Down Expand Up @@ -105,6 +120,15 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
return 0;
case BT_DISC_CMD:
return zmk_ble_prof_disconnect(binding->param2);
case BT_ADV_ON_CMD:
zmk_ble_adv_mode_set(true);
return 0;
case BT_ADV_OFF_CMD:
zmk_ble_adv_mode_set(false);
return 0;
case BT_ADV_TOG_CMD:
zmk_ble_adv_mode_set((zmk_ble_adv_mode_get() == ZMK_ADV_CONN) ? false : true);
return 0;
default:
LOG_ERR("Unknown BT command: %d", binding->param1);
}
Expand Down
36 changes: 29 additions & 7 deletions app/src/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,7 @@ RING_BUF_DECLARE(passkey_entries, PASSKEY_DIGITS);

#endif /* IS_ENABLED(CONFIG_ZMK_BLE_PASSKEY_ENTRY) */

enum advertising_type {
ZMK_ADV_NONE,
ZMK_ADV_DIR,
ZMK_ADV_CONN,
} advertising_status;
enum advertising_type advertising_status;

#define CURR_ADV(adv) (adv << 4)

Expand All @@ -63,6 +59,8 @@ enum advertising_type {
static struct zmk_ble_profile profiles[ZMK_BLE_PROFILE_COUNT];
static uint8_t active_profile;

static bool permit_adv = true;

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

Expand Down Expand Up @@ -167,9 +165,9 @@ int update_advertising(void) {
struct bt_conn *conn;
enum advertising_type desired_adv = ZMK_ADV_NONE;

if (zmk_ble_active_profile_is_open()) {
if (permit_adv && zmk_ble_active_profile_is_open()) {
desired_adv = ZMK_ADV_CONN;
} else if (!zmk_ble_active_profile_is_connected()) {
} else if (permit_adv && !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
Expand Down Expand Up @@ -210,6 +208,30 @@ static void update_advertising_callback(struct k_work *work) { update_advertisin

K_WORK_DEFINE(update_advertising_work, update_advertising_callback);

void zmk_ble_adv_mode_set(bool mode) {
if (mode) {
if (advertising_status != ZMK_ADV_CONN) {
permit_adv = true;
LOG_DBG("Enabling adv");
}
update_advertising();
} else {
if (advertising_status != ZMK_ADV_NONE) {
permit_adv = false;
LOG_DBG("Disabling adv and disconnecting");
for (int i = 0; i < ZMK_BLE_PROFILE_COUNT; i++) {
int err = zmk_ble_prof_disconnect(i);
if (err) {
LOG_DBG("Failed to disconnect profile %d : %d", i, err);
}
}
update_advertising();
}
}
}

enum advertising_type zmk_ble_adv_mode_get() { return advertising_status; }

static void clear_profile_bond(uint8_t profile) {
if (bt_addr_le_cmp(&profiles[profile].peer, BT_ADDR_LE_ANY)) {
bt_unpair(BT_ID_DEFAULT, &profiles[profile].peer);
Expand Down
3 changes: 3 additions & 0 deletions docs/docs/keymaps/behaviors/bluetooth.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ Here is a table describing the command for each define:
| `BT_PRV` | Switch to the previous profile, cycling through to the last one when the beginning is reached. |
| `BT_SEL` | Select the 0-indexed profile by number; must include a number as an argument in the keymap to work correctly, e.g. `BT_SEL 0`. |
| `BT_DISC` | Disconnect from the 0-indexed profile by number, if it's currently connected and inactive; must include a number as an argument in the keymap to work correctly, e.g. `BT_DISC 0`. |
| `ADV_OFF` | Disconnect from all profiles and disable advertising (The device will not show up as connectable on host devices) |
| `ADV_ON` | Enable Bluetooth advertising, the device will show up as connectable |
| `ADV_TOG` | Toggle advertising on and off |

:::note[Selected profile persistence]
The profile that is selected by the `BT_SEL`/`BT_PRV`/`BT_NXT` actions will be saved to flash storage and hence persist across restarts and firmware flashes.
Expand Down

0 comments on commit ac43a1b

Please sign in to comment.