refactor(split): move central split run out of Bluetooth directory
This commit is contained in:
parent
264bdfbe14
commit
07bc3b6a9e
6 changed files with 102 additions and 85 deletions
|
@ -8,7 +8,7 @@
|
||||||
#include <zmk/hid_indicators_types.h>
|
#include <zmk/hid_indicators_types.h>
|
||||||
#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
|
#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
|
||||||
|
|
||||||
int zmk_split_bt_invoke_behavior(uint8_t source, struct zmk_behavior_binding *binding,
|
int zmk_split_invoke_behavior(uint8_t source, struct zmk_behavior_binding *binding,
|
||||||
struct zmk_behavior_binding_event event, bool state);
|
struct zmk_behavior_binding_event event, bool state);
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
|
#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
|
||||||
|
|
|
@ -8,9 +8,12 @@
|
||||||
|
|
||||||
#include <zmk/events/position_state_changed.h>
|
#include <zmk/events/position_state_changed.h>
|
||||||
#include <zmk/events/sensor_event.h>
|
#include <zmk/events/sensor_event.h>
|
||||||
|
#include <zmk/split/service.h>
|
||||||
|
|
||||||
void zmk_position_state_change_handle(struct zmk_position_state_changed *ev);
|
void zmk_position_state_change_handle(struct zmk_position_state_changed *ev);
|
||||||
|
|
||||||
#if ZMK_KEYMAP_HAS_SENSORS
|
#if ZMK_KEYMAP_HAS_SENSORS
|
||||||
void zmk_sensor_event_handle(struct zmk_sensor_event *ev);
|
void zmk_sensor_event_handle(struct zmk_sensor_event *ev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void send_split_run_impl(struct zmk_split_run_behavior_payload_wrapper *payload_wrapper);
|
||||||
|
|
|
@ -31,6 +31,11 @@ struct zmk_split_run_behavior_payload {
|
||||||
char behavior_dev[ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN];
|
char behavior_dev[ZMK_SPLIT_RUN_BEHAVIOR_DEV_LEN];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct zmk_split_run_behavior_payload_wrapper {
|
||||||
|
uint8_t source;
|
||||||
|
struct zmk_split_run_behavior_payload payload;
|
||||||
|
};
|
||||||
|
|
||||||
int zmk_split_position_pressed(uint8_t position);
|
int zmk_split_position_pressed(uint8_t position);
|
||||||
int zmk_split_position_released(uint8_t position);
|
int zmk_split_position_released(uint8_t position);
|
||||||
int zmk_split_sensor_triggered(uint8_t sensor_index,
|
int zmk_split_sensor_triggered(uint8_t sensor_index,
|
||||||
|
|
|
@ -214,7 +214,7 @@ int zmk_keymap_apply_position_state(uint8_t source, int layer, uint32_t position
|
||||||
if (source == ZMK_POSITION_STATE_CHANGE_SOURCE_LOCAL) {
|
if (source == ZMK_POSITION_STATE_CHANGE_SOURCE_LOCAL) {
|
||||||
return invoke_locally(&binding, event, pressed);
|
return invoke_locally(&binding, event, pressed);
|
||||||
} else {
|
} else {
|
||||||
return zmk_split_bt_invoke_behavior(source, &binding, event, pressed);
|
return zmk_split_invoke_behavior(source, &binding, event, pressed);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return invoke_locally(&binding, event, pressed);
|
return invoke_locally(&binding, event, pressed);
|
||||||
|
@ -222,7 +222,7 @@ int zmk_keymap_apply_position_state(uint8_t source, int layer, uint32_t position
|
||||||
case BEHAVIOR_LOCALITY_GLOBAL:
|
case BEHAVIOR_LOCALITY_GLOBAL:
|
||||||
#if ZMK_BLE_IS_CENTRAL
|
#if ZMK_BLE_IS_CENTRAL
|
||||||
for (int i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT; i++) {
|
for (int i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT; i++) {
|
||||||
zmk_split_bt_invoke_behavior(i, &binding, event, pressed);
|
zmk_split_invoke_behavior(i, &binding, event, pressed);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return invoke_locally(&binding, event, pressed);
|
return invoke_locally(&binding, event, pressed);
|
||||||
|
|
|
@ -714,90 +714,25 @@ static struct bt_conn_cb conn_callbacks = {
|
||||||
.disconnected = split_central_disconnected,
|
.disconnected = split_central_disconnected,
|
||||||
};
|
};
|
||||||
|
|
||||||
K_THREAD_STACK_DEFINE(split_central_split_run_q_stack,
|
void send_split_run_impl(struct zmk_split_run_behavior_payload_wrapper *payload_wrapper) {
|
||||||
CONFIG_ZMK_SPLIT_BLE_CENTRAL_SPLIT_RUN_STACK_SIZE);
|
if (peripherals[payload_wrapper->source].state != PERIPHERAL_SLOT_STATE_CONNECTED) {
|
||||||
|
|
||||||
struct k_work_q split_central_split_run_q;
|
|
||||||
|
|
||||||
struct zmk_split_run_behavior_payload_wrapper {
|
|
||||||
uint8_t source;
|
|
||||||
struct zmk_split_run_behavior_payload payload;
|
|
||||||
};
|
|
||||||
|
|
||||||
K_MSGQ_DEFINE(zmk_split_central_split_run_msgq,
|
|
||||||
sizeof(struct zmk_split_run_behavior_payload_wrapper),
|
|
||||||
CONFIG_ZMK_SPLIT_BLE_CENTRAL_SPLIT_RUN_QUEUE_SIZE, 4);
|
|
||||||
|
|
||||||
void split_central_split_run_callback(struct k_work *work) {
|
|
||||||
struct zmk_split_run_behavior_payload_wrapper payload_wrapper;
|
|
||||||
|
|
||||||
LOG_DBG("");
|
|
||||||
|
|
||||||
while (k_msgq_get(&zmk_split_central_split_run_msgq, &payload_wrapper, K_NO_WAIT) == 0) {
|
|
||||||
if (peripherals[payload_wrapper.source].state != PERIPHERAL_SLOT_STATE_CONNECTED) {
|
|
||||||
LOG_ERR("Source not connected");
|
LOG_ERR("Source not connected");
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
if (!peripherals[payload_wrapper.source].run_behavior_handle) {
|
if (!peripherals[payload_wrapper->source].run_behavior_handle) {
|
||||||
LOG_ERR("Run behavior handle not found");
|
LOG_ERR("Run behavior handle not found");
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = bt_gatt_write_without_response(
|
int err = bt_gatt_write_without_response(
|
||||||
peripherals[payload_wrapper.source].conn,
|
peripherals[payload_wrapper->source].conn,
|
||||||
peripherals[payload_wrapper.source].run_behavior_handle, &payload_wrapper.payload,
|
peripherals[payload_wrapper->source].run_behavior_handle, &payload_wrapper->payload,
|
||||||
sizeof(struct zmk_split_run_behavior_payload), true);
|
sizeof(struct zmk_split_run_behavior_payload), true);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_ERR("Failed to write the behavior characteristic (err %d)", err);
|
LOG_ERR("Failed to write the behavior characteristic (err %d)", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
K_WORK_DEFINE(split_central_split_run_work, split_central_split_run_callback);
|
|
||||||
|
|
||||||
static int
|
|
||||||
split_bt_invoke_behavior_payload(struct zmk_split_run_behavior_payload_wrapper payload_wrapper) {
|
|
||||||
LOG_DBG("");
|
|
||||||
|
|
||||||
int err = k_msgq_put(&zmk_split_central_split_run_msgq, &payload_wrapper, K_MSEC(100));
|
|
||||||
if (err) {
|
|
||||||
switch (err) {
|
|
||||||
case -EAGAIN: {
|
|
||||||
LOG_WRN("Consumer message queue full, popping first message and queueing again");
|
|
||||||
struct zmk_split_run_behavior_payload_wrapper discarded_report;
|
|
||||||
k_msgq_get(&zmk_split_central_split_run_msgq, &discarded_report, K_NO_WAIT);
|
|
||||||
return split_bt_invoke_behavior_payload(payload_wrapper);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
LOG_WRN("Failed to queue behavior to send (%d)", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
k_work_submit_to_queue(&split_central_split_run_q, &split_central_split_run_work);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
int zmk_split_bt_invoke_behavior(uint8_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 ? 1 : 0,
|
|
||||||
}};
|
|
||||||
const size_t payload_dev_size = sizeof(payload.behavior_dev);
|
|
||||||
if (strlcpy(payload.behavior_dev, binding->behavior_dev, payload_dev_size) >=
|
|
||||||
payload_dev_size) {
|
|
||||||
LOG_ERR("Truncated behavior label %s to %s before invoking peripheral behavior",
|
|
||||||
binding->behavior_dev, payload.behavior_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct zmk_split_run_behavior_payload_wrapper wrapper = {.source = source, .payload = payload};
|
|
||||||
return split_bt_invoke_behavior_payload(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
|
#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
|
||||||
|
|
||||||
|
@ -853,9 +788,6 @@ static struct settings_handler ble_central_settings_handler = {
|
||||||
#endif // IS_ENABLED(CONFIG_SETTINGS)
|
#endif // IS_ENABLED(CONFIG_SETTINGS)
|
||||||
|
|
||||||
static int zmk_split_bt_central_init(void) {
|
static int zmk_split_bt_central_init(void) {
|
||||||
k_work_queue_start(&split_central_split_run_q, split_central_split_run_q_stack,
|
|
||||||
K_THREAD_STACK_SIZEOF(split_central_split_run_q_stack),
|
|
||||||
CONFIG_ZMK_BLE_THREAD_PRIORITY, NULL);
|
|
||||||
bt_conn_cb_register(&conn_callbacks);
|
bt_conn_cb_register(&conn_callbacks);
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||||
|
|
|
@ -7,9 +7,13 @@
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <zephyr/init.h>
|
#include <zephyr/init.h>
|
||||||
|
|
||||||
|
#include <zmk/stdlib.h>
|
||||||
|
#include <zmk/behavior.h>
|
||||||
#include <zmk/event_manager.h>
|
#include <zmk/event_manager.h>
|
||||||
#include <zmk/events/position_state_changed.h>
|
#include <zmk/events/position_state_changed.h>
|
||||||
#include <zmk/events/sensor_event.h>
|
#include <zmk/events/sensor_event.h>
|
||||||
|
#include <zmk/split/central.h>
|
||||||
|
#include <zmk/split/service.h>
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
@ -51,3 +55,76 @@ void zmk_sensor_event_handle(struct zmk_sensor_event *ev) {
|
||||||
k_work_submit(&peripheral_sensor_event_work);
|
k_work_submit(&peripheral_sensor_event_work);
|
||||||
}
|
}
|
||||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||||
|
|
||||||
|
K_THREAD_STACK_DEFINE(split_central_split_run_q_stack,
|
||||||
|
CONFIG_ZMK_SPLIT_BLE_CENTRAL_SPLIT_RUN_STACK_SIZE);
|
||||||
|
|
||||||
|
struct k_work_q split_central_split_run_q;
|
||||||
|
|
||||||
|
K_MSGQ_DEFINE(zmk_split_central_split_run_msgq,
|
||||||
|
sizeof(struct zmk_split_run_behavior_payload_wrapper),
|
||||||
|
CONFIG_ZMK_SPLIT_BLE_CENTRAL_SPLIT_RUN_QUEUE_SIZE, 4);
|
||||||
|
|
||||||
|
void split_central_split_run_callback(struct k_work *work) {
|
||||||
|
struct zmk_split_run_behavior_payload_wrapper payload_wrapper;
|
||||||
|
|
||||||
|
LOG_DBG("");
|
||||||
|
|
||||||
|
while (k_msgq_get(&zmk_split_central_split_run_msgq, &payload_wrapper, K_NO_WAIT) == 0) {
|
||||||
|
send_split_run_impl(&payload_wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
K_WORK_DEFINE(split_central_split_run_work, split_central_split_run_callback);
|
||||||
|
|
||||||
|
static int
|
||||||
|
split_invoke_behavior_payload(struct zmk_split_run_behavior_payload_wrapper payload_wrapper) {
|
||||||
|
LOG_DBG("");
|
||||||
|
|
||||||
|
int err = k_msgq_put(&zmk_split_central_split_run_msgq, &payload_wrapper, K_MSEC(100));
|
||||||
|
if (err) {
|
||||||
|
switch (err) {
|
||||||
|
case -EAGAIN: {
|
||||||
|
LOG_WRN("Consumer message queue full, popping first message and queueing again");
|
||||||
|
struct zmk_split_run_behavior_payload_wrapper discarded_report;
|
||||||
|
k_msgq_get(&zmk_split_central_split_run_msgq, &discarded_report, K_NO_WAIT);
|
||||||
|
return split_invoke_behavior_payload(payload_wrapper);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
LOG_WRN("Failed to queue behavior to send (%d)", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
k_work_submit_to_queue(&split_central_split_run_q, &split_central_split_run_work);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
int zmk_split_invoke_behavior(uint8_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 ? 1 : 0,
|
||||||
|
}};
|
||||||
|
const size_t payload_dev_size = sizeof(payload.behavior_dev);
|
||||||
|
if (strlcpy(payload.behavior_dev, binding->behavior_dev, payload_dev_size) >=
|
||||||
|
payload_dev_size) {
|
||||||
|
LOG_ERR("Truncated behavior label %s to %s before invoking peripheral behavior",
|
||||||
|
binding->behavior_dev, payload.behavior_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct zmk_split_run_behavior_payload_wrapper wrapper = {.source = source, .payload = payload};
|
||||||
|
return split_invoke_behavior_payload(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zmk_split_central_init(void) {
|
||||||
|
k_work_queue_start(&split_central_split_run_q, split_central_split_run_q_stack,
|
||||||
|
K_THREAD_STACK_SIZEOF(split_central_split_run_q_stack),
|
||||||
|
CONFIG_ZMK_BLE_THREAD_PRIORITY, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_INIT(zmk_split_central_init, APPLICATION, CONFIG_ZMK_BLE_INIT_PRIORITY);
|
||||||
|
|
Loading…
Add table
Reference in a new issue