forked from kofal.net/zmk
feature(split): behavior locality support.
* GATT characteristic allowing passng data + behavior label to invoke the behavior on the peripheral side. * Behaviors have a locality setting to specify where they run. * Build reset/power/RGB on peripheral.
This commit is contained in:
@@ -18,7 +18,9 @@
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#include <zmk/ble.h>
|
||||
#include <zmk/behavior.h>
|
||||
#include <zmk/split/bluetooth/uuid.h>
|
||||
#include <zmk/split/bluetooth/service.h>
|
||||
#include <zmk/event_manager.h>
|
||||
#include <zmk/events/position_state_changed.h>
|
||||
#include <init.h>
|
||||
@@ -33,6 +35,7 @@ static const struct bt_uuid_128 split_service_uuid = BT_UUID_INIT_128(ZMK_SPLIT_
|
||||
static struct bt_gatt_discover_params discover_params;
|
||||
static struct bt_gatt_subscribe_params subscribe_params;
|
||||
static struct bt_gatt_discover_params sub_discover_params;
|
||||
static uint16_t run_behavior_handle;
|
||||
|
||||
K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_position_state_changed),
|
||||
CONFIG_ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE, 4);
|
||||
@@ -72,8 +75,10 @@ static uint8_t split_central_notify_func(struct bt_conn *conn,
|
||||
if (changed_positions[i] & BIT(j)) {
|
||||
uint32_t position = (i * 8) + j;
|
||||
bool pressed = position_state[i] & BIT(j);
|
||||
struct zmk_position_state_changed ev = {
|
||||
.position = position, .state = pressed, .timestamp = k_uptime_get()};
|
||||
struct zmk_position_state_changed ev = {.source = bt_conn_get_dst(conn),
|
||||
.position = position,
|
||||
.state = pressed,
|
||||
.timestamp = k_uptime_get()};
|
||||
|
||||
k_msgq_put(&peripheral_event_msgq, &ev, K_NO_WAIT);
|
||||
k_work_submit(&peripheral_event_work);
|
||||
@@ -124,9 +129,28 @@ static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn,
|
||||
subscribe_params.disc_params = &sub_discover_params;
|
||||
subscribe_params.end_handle = discover_params.end_handle;
|
||||
subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
|
||||
|
||||
err = bt_gatt_discover(conn, &discover_params);
|
||||
if (err) {
|
||||
LOG_ERR("Discover failed (err %d)", err);
|
||||
}
|
||||
} else if (!bt_uuid_cmp(discover_params.uuid,
|
||||
BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_RUN_BEHAVIOR_UUID))) {
|
||||
run_behavior_handle = bt_gatt_attr_value_handle(attr);
|
||||
} else {
|
||||
subscribe_params.notify = split_central_notify_func;
|
||||
subscribe_params.value = BT_GATT_CCC_NOTIFY;
|
||||
split_central_subscribe(conn);
|
||||
|
||||
memcpy(&uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_RUN_BEHAVIOR_UUID), sizeof(uuid));
|
||||
discover_params.uuid = &uuid.uuid;
|
||||
discover_params.start_handle = attr->handle + 1;
|
||||
discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
|
||||
|
||||
err = bt_gatt_discover(conn, &discover_params);
|
||||
if (err) {
|
||||
LOG_ERR("Discover failed (err %d)", err);
|
||||
}
|
||||
}
|
||||
|
||||
return subscribe_params.value_handle ? BT_GATT_ITER_STOP : BT_GATT_ITER_CONTINUE;
|
||||
@@ -340,6 +364,27 @@ static struct bt_conn_cb conn_callbacks = {
|
||||
.disconnected = split_central_disconnected,
|
||||
};
|
||||
|
||||
int zmk_split_bt_invoke_behavior(const bt_addr_le_t *source, struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event, bool state) {
|
||||
struct zmk_split_run_behavior_payload payload = {.data = {
|
||||
.param1 = binding->param1,
|
||||
.param2 = binding->param2,
|
||||
.position = event.position,
|
||||
.state = state,
|
||||
}};
|
||||
strncpy(payload.behavior_dev, binding->behavior_dev, ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN - 1);
|
||||
payload.behavior_dev[ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN - 1] = '\0';
|
||||
|
||||
int err = bt_gatt_write_without_response(default_conn, run_behavior_handle, &payload,
|
||||
sizeof(struct zmk_split_run_behavior_payload), true);
|
||||
|
||||
if (err) {
|
||||
LOG_ERR("Failed to write the behavior characteristic (err %d)", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
};
|
||||
|
||||
int zmk_split_bt_central_init(const struct device *_arg) {
|
||||
bt_conn_cb_register(&conn_callbacks);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user