Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing: split input test #2762

Merged
merged 5 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/module/drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ add_subdirectory_ifdef(CONFIG_GPIO gpio)
add_subdirectory_ifdef(CONFIG_KSCAN kscan)
add_subdirectory_ifdef(CONFIG_SENSOR sensor)
add_subdirectory_ifdef(CONFIG_DISPLAY display)
add_subdirectory_ifdef(CONFIG_INPUT input)
1 change: 1 addition & 0 deletions app/module/drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ rsource "gpio/Kconfig"
rsource "kscan/Kconfig"
rsource "sensor/Kconfig"
rsource "display/Kconfig"
rsource "input/Kconfig"
6 changes: 6 additions & 0 deletions app/module/drivers/input/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2020-2023 The ZMK Contributors
# SPDX-License-Identifier: MIT

zephyr_library_amend()

zephyr_library_sources_ifdef(CONFIG_ZMK_INPUT_MOCK input_mock.c)
9 changes: 9 additions & 0 deletions app/module/drivers/input/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

if INPUT

config ZMK_INPUT_MOCK
bool "Input Mock"
default y
depends on DT_HAS_ZMK_INPUT_MOCK_ENABLED

endif
87 changes: 87 additions & 0 deletions app/module/drivers/input/input_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/

#define DT_DRV_COMPAT zmk_input_mock

#include <stdlib.h>
#include <zephyr/device.h>
#include <zephyr/input/input.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

struct input_mock_config {
uint16_t startup_delay;
uint16_t event_period;
bool exit_after;
const uint32_t *events;
size_t events_len;
};

struct input_mock_data {
size_t event_index;
struct k_work_delayable work;
const struct device *dev;
};

static void input_mock_work_cb(struct k_work *work) {
struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work);
struct input_mock_data *data = CONTAINER_OF(dwork, struct input_mock_data, work);

const struct device *dev = data->dev;

const struct input_mock_config *cfg = dev->config;

data->event_index++;

size_t base_idx = data->event_index * 4;

if (base_idx >= cfg->events_len) {
if (cfg->exit_after) {
exit(0);
} else {
return;
}
}

input_report(dev, cfg->events[base_idx], cfg->events[base_idx + 1], cfg->events[base_idx + 2],
cfg->events[base_idx + 3], K_NO_WAIT);

k_work_schedule(&data->work, K_MSEC(cfg->event_period));
}

int input_mock_init(const struct device *dev) {
struct input_mock_data *drv_data = dev->data;
const struct input_mock_config *drv_cfg = dev->config;

drv_data->dev = dev;
drv_data->event_index = -1;

k_work_init_delayable(&drv_data->work, input_mock_work_cb);

k_work_schedule(&drv_data->work, K_MSEC(drv_cfg->startup_delay));

return 0;
}

#define GET_EVENT(n, inst) \
{}

#define INPUT_MOCK_INST(n) \
struct input_mock_data input_mock_data_##n = {}; \
const uint32_t mock_data_##n[] = DT_INST_PROP(n, events); \
const struct input_mock_config input_mock_cfg_##n = { \
.events = mock_data_##n, \
.events_len = DT_INST_PROP_LEN(n, events), \
.startup_delay = DT_INST_PROP(n, event_startup_delay), \
.event_period = DT_INST_PROP(n, event_period), \
.exit_after = DT_INST_PROP(n, exit_after), \
}; \
DEVICE_DT_INST_DEFINE(n, input_mock_init, NULL, &input_mock_data_##n, &input_mock_cfg_##n, \
POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL);

DT_INST_FOREACH_STATUS_OKAY(INPUT_MOCK_INST)
6 changes: 6 additions & 0 deletions app/module/drivers/kscan/kscan_mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ static int kscan_mock_configure(const struct device *dev, kscan_callback_t callb
struct k_work_delayable *d_work = k_work_delayable_from_work(work); \
struct kscan_mock_data *data = CONTAINER_OF(d_work, struct kscan_mock_data, work); \
const struct kscan_mock_config_##n *cfg = data->dev->config; \
if (data->event_index >= DT_INST_PROP_LEN(n, events)) { \
if (cfg->exit_after) \
exit(0); \
else \
return; \
} \
uint32_t ev = cfg->events[data->event_index]; \
LOG_DBG("ev %u row %d column %d state %d\n", ev, ZMK_MOCK_ROW(ev), ZMK_MOCK_COL(ev), \
ZMK_MOCK_IS_PRESS(ev)); \
Expand Down
21 changes: 21 additions & 0 deletions app/module/dts/bindings/input/zmk,input-mock.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright (c) 2024 The ZMK Contributors
# SPDX-License-Identifier: MIT

description: |
Allows defining a mock input driver that simulates periodic input events.

compatible: "zmk,input-mock"

properties:
event-startup-delay:
type: int
default: 0
description: Milliseconds to delay before starting generating the events
event-period:
type: int
description: Milliseconds between each generated event
events:
type: array
description: List of tuples of (type, code, value, sync)
exit-after:
type: boolean
3 changes: 2 additions & 1 deletion app/src/split/bluetooth/central.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn,

LOG_DBG("[ATTRIBUTE] handle %u", attr->handle);
switch (params->type) {
case BT_GATT_DISCOVER_CHARACTERISTIC:
case BT_GATT_DISCOVER_CHARACTERISTIC: {
const struct bt_uuid *chrc_uuid = ((struct bt_gatt_chrc *)attr->user_data)->uuid;

if (bt_uuid_cmp(chrc_uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID)) ==
Expand Down Expand Up @@ -665,6 +665,7 @@ static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn,
#endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) */
}
break;
}
case BT_GATT_DISCOVER_STD_CHAR_DESC:
#if IS_ENABLED(CONFIG_ZMK_INPUT_SPLIT)
if (bt_uuid_cmp(slot->discover_params.uuid, BT_UUID_GATT_CCC) == 0) {
Expand Down
73 changes: 65 additions & 8 deletions app/tests/ble/central/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static bool skip_set_security_on_connect = false;
static bool skip_discovery_on_connect = false;
static bool read_directly_on_discovery = false;
static bool write_hid_indicators_on_discovery = false;
static bool subscribe_to_pointer_report = false;
static int32_t wait_on_start = 0;

static void ble_central_native_posix_options(void) {
Expand Down Expand Up @@ -74,6 +75,11 @@ static void ble_central_native_posix_options(void) {
.type = 'b',
.dest = (void *)&read_hid_report_on_connect,
.descript = "Read the peripheral HID report after connecting"},
{.is_switch = true,
.option = "subscribe_to_pointer_report",
.type = 'b',
.dest = (void *)&subscribe_to_pointer_report,
.descript = "Subscribe to peripheral mouse HID report after connecting"},
{.is_switch = true,
.option = "skip_discovery_on_connect",
.type = 'b',
Expand Down Expand Up @@ -110,6 +116,8 @@ static struct bt_conn *default_conn;
static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
static struct bt_gatt_discover_params discover_params;
static struct bt_gatt_subscribe_params subscribe_params;
static struct bt_gatt_subscribe_params consumer_subscribe_params;
static struct bt_gatt_subscribe_params pointer_subscribe_params;

static uint8_t notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length) {
Expand Down Expand Up @@ -167,6 +175,28 @@ static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *at
discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);

err = bt_gatt_discover(conn, &discover_params);
if (err) {
LOG_DBG("[Discover failed] (err %d)", err);
}
} else if (!consumer_subscribe_params.value_handle) {
memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
discover_params.uuid = &uuid.uuid;
discover_params.start_handle = attr->handle + 2;
discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
consumer_subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);

err = bt_gatt_discover(conn, &discover_params);
if (err) {
LOG_DBG("[Discover failed] (err %d)", err);
}
} else if (subscribe_to_pointer_report && !pointer_subscribe_params.value_handle) {
memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
discover_params.uuid = &uuid.uuid;
discover_params.start_handle = attr->handle + 2;
discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
pointer_subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);

err = bt_gatt_discover(conn, &discover_params);
if (err) {
LOG_DBG("[Discover failed] (err %d)", err);
Expand All @@ -182,18 +212,45 @@ static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *at
return BT_GATT_ITER_CONTINUE;
}
} else if (discover_params.type == BT_GATT_DISCOVER_DESCRIPTOR) {
subscribe_params.notify = notify_func;
subscribe_params.value = BT_GATT_CCC_NOTIFY;
subscribe_params.ccc_handle = attr->handle;
if (!subscribe_params.ccc_handle) {

err = bt_gatt_subscribe(conn, &subscribe_params);
if (err && err != -EALREADY) {
LOG_DBG("[Subscribe failed] (err %d)", err);
subscribe_params.notify = notify_func;
subscribe_params.value = BT_GATT_CCC_NOTIFY;
subscribe_params.ccc_handle = attr->handle;

err = bt_gatt_subscribe(conn, &subscribe_params);
if (err && err != -EALREADY) {
LOG_DBG("[Subscribe failed] (err %d)", err);
} else {
LOG_DBG("[SUBSCRIBED]");
}
} else if (!consumer_subscribe_params.ccc_handle) {

consumer_subscribe_params.notify = notify_func;
consumer_subscribe_params.value = BT_GATT_CCC_NOTIFY;
consumer_subscribe_params.ccc_handle = attr->handle;

err = bt_gatt_subscribe(conn, &consumer_subscribe_params);
if (err && err != -EALREADY) {
LOG_DBG("[Subscribe failed] (err %d)", err);
} else {
LOG_DBG("[CONSUMER SUBSCRIBED]");
}
} else {
LOG_DBG("[SUBSCRIBED]");
pointer_subscribe_params.notify = notify_func;
pointer_subscribe_params.value = BT_GATT_CCC_NOTIFY;
pointer_subscribe_params.ccc_handle = attr->handle;

err = bt_gatt_subscribe(conn, &pointer_subscribe_params);
if (err && err != -EALREADY) {
LOG_DBG("[Subscribe failed] (err %d)", err);
} else {
LOG_DBG("[MOUSE SUBSCRIBED]");
}
}

find_next_hids_report = write_hid_indicators_on_discovery;
find_next_hids_report = !consumer_subscribe_params.ccc_handle ||
write_hid_indicators_on_discovery || subscribe_to_pointer_report;
}

if (find_next_hids_report) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 23
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
profile 1 <dbg> ble_central: discover_func: [SUBSCRIBED]
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 32
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 34
profile 1 <dbg> ble_central: discover_func: [CONSUMER SUBSCRIBED]
profile 1 <dbg> ble_central: notify_func: payload
profile 1 00 00 04 00 00 00 00 00 |........
profile 1 <dbg> ble_central: notify_func: payload
profile 1 00 00 00 00 00 00 00 00 |........
profile 1 <dbg> ble_central: notify_func: payload
profile 1 00 00 00 00 00 00 00 00 |........
5 changes: 3 additions & 2 deletions app/tests/ble/profiles/bond-to-cleared-profile/snapshot.log
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 23
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
profile 1 <dbg> ble_central: discover_func: [SUBSCRIBED]
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 32
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 34
profile 1 <dbg> ble_central: discover_func: [CONSUMER SUBSCRIBED]
profile 1 <dbg> ble_central: notify_func: payload
profile 1 00 00 04 00 00 00 00 00 |........
profile 1 <dbg> ble_central: notify_func: payload
profile 1 00 00 00 00 00 00 00 00 |........
profile 1 <dbg> ble_central: notify_func: payload
profile 1 00 00 00 00 00 00 00 00 |........
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
<dbg> ble_central: discover_func: [SUBSCRIBED]
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 32
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 34
<dbg> ble_central: discover_func: [CONSUMER SUBSCRIBED]
<dbg> ble_central: notify_func: payload
00 00 04 00 00 00 00 00 |........
<dbg> ble_central: notify_func: payload
Expand All @@ -21,5 +24,3 @@
00 00 05 00 00 00 00 00 |........
<dbg> ble_central: notify_func: payload
00 00 00 00 00 00 00 00 |........
<dbg> ble_central: notify_func: payload
00 00 00 00 00 00 00 00 |........
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 23
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
profile 0 <dbg> ble_central: discover_func: [SUBSCRIBED]
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 32
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 34
profile 0 <dbg> ble_central: discover_func: [CONSUMER SUBSCRIBED]
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 04 00 00 00 00 00 |........
profile 0 <dbg> ble_central: notify_func: payload
Expand All @@ -32,9 +35,10 @@ profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 23
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
profile 1 <dbg> ble_central: discover_func: [SUBSCRIBED]
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 32
profile 1 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 34
profile 1 <dbg> ble_central: discover_func: [CONSUMER SUBSCRIBED]
profile 1 <dbg> ble_central: notify_func: payload
profile 1 00 00 05 00 00 00 00 00 |........
profile 1 <dbg> ble_central: notify_func: payload
profile 1 00 00 00 00 00 00 00 00 |........
profile 1 <dbg> ble_central: notify_func: payload
profile 1 00 00 00 00 00 00 00 00 |........
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
<dbg> ble_central: discover_func: [SUBSCRIBED]
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 32
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 34
<dbg> ble_central: discover_func: [CONSUMER SUBSCRIBED]
<dbg> ble_central: notify_func: payload
00 00 04 00 00 00 00 00 |........
<dbg> ble_central: notify_func: payload
Expand All @@ -30,5 +33,3 @@
00 00 05 00 00 00 00 00 |........
<dbg> ble_central: notify_func: payload
00 00 00 00 00 00 00 00 |........
<dbg> ble_central: notify_func: payload
00 00 00 00 00 00 00 00 |........
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
<dbg> ble_central: discover_func: [SUBSCRIBED]
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 32
<dbg> ble_central: discover_func: [ATTRIBUTE] handle 34
<dbg> ble_central: discover_func: [CONSUMER SUBSCRIBED]
<dbg> ble_central: notify_func: payload
00 00 04 00 00 00 00 00 |........
<dbg> ble_central: notify_func: payload
Expand All @@ -29,5 +32,3 @@
00 00 05 00 00 00 00 00 |........
<dbg> ble_central: notify_func: payload
00 00 00 00 00 00 00 00 |........
<dbg> ble_central: notify_func: payload
00 00 00 00 00 00 00 00 |........
3 changes: 3 additions & 0 deletions app/tests/ble/split/basic/snapshot.log
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 23
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
profile 0 <dbg> ble_central: discover_func: [SUBSCRIBED]
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 32
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 34
profile 0 <dbg> ble_central: discover_func: [CONSUMER SUBSCRIBED]
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 04 00 00 00 00 00 |........
profile 0 <dbg> ble_central: notify_func: payload
Expand Down
3 changes: 3 additions & 0 deletions app/tests/ble/split/multiple-peripherals/snapshot.log
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 23
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 28
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 30
profile 0 <dbg> ble_central: discover_func: [SUBSCRIBED]
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 32
profile 0 <dbg> ble_central: discover_func: [ATTRIBUTE] handle 34
profile 0 <dbg> ble_central: discover_func: [CONSUMER SUBSCRIBED]
profile 0 <dbg> ble_central: notify_func: payload
profile 0 00 00 05 00 00 00 00 00 |........
profile 0 <dbg> ble_central: notify_func: payload
Expand Down
Loading
Loading