feat(split): Use directed advertising.
* Split centrals to scan with their identity so they receive direct advertising packets. * Split peripherals to use direct advertising if they have an existing bond to a split central.
This commit is contained in:
parent
3936298260
commit
718500543b
3 changed files with 45 additions and 4 deletions
app/src/split/bluetooth
|
@ -14,6 +14,7 @@ config ZMK_SPLIT_ROLE_CENTRAL
|
|||
select BT_CENTRAL
|
||||
select BT_GATT_CLIENT
|
||||
select BT_GATT_AUTO_DISCOVER_CCC
|
||||
select BT_SCAN_WITH_IDENTITY
|
||||
|
||||
if ZMK_SPLIT_ROLE_CENTRAL
|
||||
|
||||
|
|
|
@ -511,8 +511,10 @@ static void split_central_device_found(const bt_addr_le_t *addr, int8_t rssi, ui
|
|||
LOG_DBG("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i", dev, type, ad->len, rssi);
|
||||
|
||||
/* We're only interested in connectable events */
|
||||
if (type == BT_GAP_ADV_TYPE_ADV_IND || type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
|
||||
if (type == BT_GAP_ADV_TYPE_ADV_IND) {
|
||||
bt_data_parse(ad, split_central_eir_parse, (void *)addr);
|
||||
} else if (type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
|
||||
split_central_eir_found(addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,15 +43,49 @@ static const struct bt_data zmk_ble_ad[] = {
|
|||
|
||||
static bool is_connected = false;
|
||||
|
||||
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 each_bond(const struct bt_bond_info *info, void *user_data) {
|
||||
bt_addr_le_t *addr = (bt_addr_le_t *)user_data;
|
||||
|
||||
if (bt_addr_le_cmp(&info->addr, BT_ADDR_LE_NONE) != 0) {
|
||||
bt_addr_le_copy(addr, &info->addr);
|
||||
}
|
||||
}
|
||||
|
||||
static int start_advertising(bool low_duty) {
|
||||
bt_addr_le_t central_addr = bt_addr_le_none;
|
||||
|
||||
bt_foreach_bond(BT_ID_DEFAULT, each_bond, ¢ral_addr);
|
||||
|
||||
if (bt_addr_le_cmp(¢ral_addr, BT_ADDR_LE_NONE) != 0) {
|
||||
struct bt_le_adv_param adv_param = low_duty ? *BT_LE_ADV_CONN_DIR_LOW_DUTY(¢ral_addr)
|
||||
: *BT_LE_ADV_CONN_DIR(¢ral_addr);
|
||||
return bt_le_adv_start(&adv_param, NULL, 0, NULL, 0);
|
||||
} else {
|
||||
return bt_le_adv_start(BT_LE_ADV_CONN, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0);
|
||||
}
|
||||
};
|
||||
|
||||
static bool low_duty_advertising = false;
|
||||
|
||||
static void advertising_cb(struct k_work *work) {
|
||||
const int err = start_advertising(low_duty_advertising);
|
||||
if (err < 0) {
|
||||
LOG_ERR("Failed to start advertising (%d)", err);
|
||||
}
|
||||
}
|
||||
|
||||
K_WORK_DEFINE(advertising_work, advertising_cb);
|
||||
|
||||
static void connected(struct bt_conn *conn, uint8_t err) {
|
||||
is_connected = (err == 0);
|
||||
|
||||
ZMK_EVENT_RAISE(new_zmk_split_peripheral_status_changed(
|
||||
(struct zmk_split_peripheral_status_changed){.connected = is_connected}));
|
||||
|
||||
if (err == BT_HCI_ERR_ADV_TIMEOUT) {
|
||||
low_duty_advertising = true;
|
||||
k_work_submit(&advertising_work);
|
||||
}
|
||||
}
|
||||
|
||||
static void disconnected(struct bt_conn *conn, uint8_t reason) {
|
||||
|
@ -65,6 +99,9 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) {
|
|||
|
||||
ZMK_EVENT_RAISE(new_zmk_split_peripheral_status_changed(
|
||||
(struct zmk_split_peripheral_status_changed){.connected = is_connected}));
|
||||
|
||||
low_duty_advertising = false;
|
||||
k_work_submit(&advertising_work);
|
||||
}
|
||||
|
||||
static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) {
|
||||
|
@ -119,7 +156,8 @@ static int zmk_peripheral_ble_init(const struct device *_arg) {
|
|||
#else
|
||||
bt_conn_cb_register(&conn_callbacks);
|
||||
|
||||
start_advertising();
|
||||
low_duty_advertising = false;
|
||||
k_work_submit(&advertising_work);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue