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>
|
||||
#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);
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
|
||||
|
|
|
@ -8,9 +8,12 @@
|
|||
|
||||
#include <zmk/events/position_state_changed.h>
|
||||
#include <zmk/events/sensor_event.h>
|
||||
#include <zmk/split/service.h>
|
||||
|
||||
void zmk_position_state_change_handle(struct zmk_position_state_changed *ev);
|
||||
|
||||
#if ZMK_KEYMAP_HAS_SENSORS
|
||||
void zmk_sensor_event_handle(struct zmk_sensor_event *ev);
|
||||
#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];
|
||||
} __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_released(uint8_t position);
|
||||
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) {
|
||||
return invoke_locally(&binding, event, pressed);
|
||||
} else {
|
||||
return zmk_split_bt_invoke_behavior(source, &binding, event, pressed);
|
||||
return zmk_split_invoke_behavior(source, &binding, event, pressed);
|
||||
}
|
||||
#else
|
||||
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:
|
||||
#if ZMK_BLE_IS_CENTRAL
|
||||
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
|
||||
return invoke_locally(&binding, event, pressed);
|
||||
|
|
|
@ -714,90 +714,25 @@ static struct bt_conn_cb conn_callbacks = {
|
|||
.disconnected = split_central_disconnected,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
void send_split_run_impl(struct zmk_split_run_behavior_payload_wrapper *payload_wrapper) {
|
||||
if (peripherals[payload_wrapper->source].state != PERIPHERAL_SLOT_STATE_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");
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
int err = bt_gatt_write_without_response(
|
||||
peripherals[payload_wrapper.source].conn,
|
||||
peripherals[payload_wrapper.source].run_behavior_handle, &payload_wrapper.payload,
|
||||
peripherals[payload_wrapper->source].conn,
|
||||
peripherals[payload_wrapper->source].run_behavior_handle, &payload_wrapper->payload,
|
||||
sizeof(struct zmk_split_run_behavior_payload), true);
|
||||
|
||||
if (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)
|
||||
|
||||
|
@ -853,9 +788,6 @@ static struct settings_handler ble_central_settings_handler = {
|
|||
#endif // IS_ENABLED(CONFIG_SETTINGS)
|
||||
|
||||
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);
|
||||
|
||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||
|
|
|
@ -7,9 +7,13 @@
|
|||
#include <zephyr/types.h>
|
||||
#include <zephyr/init.h>
|
||||
|
||||
#include <zmk/stdlib.h>
|
||||
#include <zmk/behavior.h>
|
||||
#include <zmk/event_manager.h>
|
||||
#include <zmk/events/position_state_changed.h>
|
||||
#include <zmk/events/sensor_event.h>
|
||||
#include <zmk/split/central.h>
|
||||
#include <zmk/split/service.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
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);
|
||||
}
|
||||
#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