summaryrefslogtreecommitdiff
path: root/app/src/split/bluetooth/central.c
diff options
context:
space:
mode:
authorPete Johanson <peter@peterjohanson.com>2020-12-20 09:49:42 -0500
committerNick Van Doorn <nick@nv.delivery>2021-11-26 09:59:03 -0800
commit4e4faca67015df3a3e1bf1b9937265f465c5093d (patch)
tree65557196f4bd4d22532bbda17cb531b468cb8af2 /app/src/split/bluetooth/central.c
parent67d30762529bee82236446d43b98858072f8afd0 (diff)
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.
Diffstat (limited to 'app/src/split/bluetooth/central.c')
-rw-r--r--app/src/split/bluetooth/central.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c
index 9a7f01b..5ac4f83 100644
--- a/app/src/split/bluetooth/central.c
+++ b/app/src/split/bluetooth/central.c
@@ -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);