From bb9a4dd758aa496c924a133f1f09020b16048b80 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Thu, 3 Dec 2020 00:12:21 -0500 Subject: [PATCH] fix(split): Use queue/work for peripheral events. * Avoid corruption by using work to process peripheral key position events on the main work thread, like local kscan events are. * FIxes #221 --- app/src/split/bluetooth/central.c | 33 +++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index 2d4d1ed8..1fcdd2aa 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -33,6 +33,29 @@ static struct bt_uuid_128 uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID); static struct bt_gatt_discover_params discover_params; static struct bt_gatt_subscribe_params subscribe_params; +struct zmk_split_peripheral_event { + u32_t position; + u32_t state; + s32_t timestamp; +}; + +K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_split_peripheral_event), 4, 4); + +void peripheral_event_work_callback(struct k_work *work) { + struct zmk_split_peripheral_event ev; + while (k_msgq_get(&peripheral_event_msgq, &ev, K_NO_WAIT) == 0) { + struct position_state_changed *pos_ev = new_position_state_changed(); + pos_ev->position = ev.position; + pos_ev->state = ev.state; + pos_ev->timestamp = ev.timestamp; + + LOG_DBG("Trigger key position state change for %d", ev.position); + ZMK_EVENT_RAISE(pos_ev); + } +} + +K_WORK_DEFINE(peripheral_event_work, peripheral_event_work_callback); + static u8_t split_central_notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, const void *data, u16_t length) { static u8_t position_state[POSITION_STATE_DATA_LEN]; @@ -57,13 +80,11 @@ static u8_t split_central_notify_func(struct bt_conn *conn, struct bt_gatt_subsc if (changed_positions[i] & BIT(j)) { u32_t position = (i * 8) + j; bool pressed = position_state[i] & BIT(j); - struct position_state_changed *pos_ev = new_position_state_changed(); - pos_ev->position = position; - pos_ev->state = pressed; - pos_ev->timestamp = k_uptime_get(); + struct zmk_split_peripheral_event ev = { + .position = position, .state = pressed, .timestamp = k_uptime_get()}; - LOG_DBG("Trigger key position state change for %d", position); - ZMK_EVENT_RAISE(pos_ev); + k_msgq_put(&peripheral_event_msgq, &ev, K_NO_WAIT); + k_work_submit(&peripheral_event_work); } } }