forked from kofal.net/zmk
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:
committed by
Pete Johanson
parent
3936298260
commit
718500543b
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user