diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 60c502fcd..20d1a03ca 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -96,6 +96,7 @@ target_sources_ifdef(CONFIG_ZMK_BATTERY_REPORTING app PRIVATE src/battery.c) target_sources_ifdef(CONFIG_ZMK_HID_INDICATORS app PRIVATE src/events/hid_indicators_changed.c) target_sources_ifdef(CONFIG_ZMK_SPLIT app PRIVATE src/events/split_peripheral_status_changed.c) +target_sources_ifdef(CONFIG_ZMK_SPLIT app PRIVATE src/events/split_transport_changed.c) add_subdirectory_ifdef(CONFIG_ZMK_SPLIT src/split) target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/usb.c) diff --git a/app/include/zmk/events/split_transport_changed.h b/app/include/zmk/events/split_transport_changed.h new file mode 100644 index 000000000..1e55b23ef --- /dev/null +++ b/app/include/zmk/events/split_transport_changed.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include +#include + +struct zmk_split_transport_changed { + uint32_t addr; + struct zmk_split_transport_status status; +}; + +ZMK_EVENT_DECLARE(zmk_split_transport_changed) \ No newline at end of file diff --git a/app/include/zmk/split/central.h b/app/include/zmk/split/central.h index ff971bfc6..cde066867 100644 --- a/app/include/zmk/split/central.h +++ b/app/include/zmk/split/central.h @@ -46,3 +46,7 @@ int zmk_split_central_update_hid_indicator(zmk_hid_indicators_t indicators); int zmk_split_central_get_peripheral_battery_level(uint8_t source, uint8_t *level); #endif // IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING) + +bool zmk_split_transport_get_available(uint32_t addr); + +uint32_t zmk_split_get_transport_addr_at_index(uint8_t index); \ No newline at end of file diff --git a/app/include/zmk/split/peripheral.h b/app/include/zmk/split/peripheral.h index 6fb2301cb..6ab9eae33 100644 --- a/app/include/zmk/split/peripheral.h +++ b/app/include/zmk/split/peripheral.h @@ -9,3 +9,7 @@ #include int zmk_split_peripheral_report_event(const struct zmk_split_transport_peripheral_event *event); + +bool zmk_split_transport_get_available(uint32_t addr); + +uint32_t zmk_split_get_transport_addr_at_index(uint8_t index); \ No newline at end of file diff --git a/app/src/events/split_transport_changed.c b/app/src/events/split_transport_changed.c new file mode 100644 index 000000000..a7d451ebf --- /dev/null +++ b/app/src/events/split_transport_changed.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +ZMK_EVENT_IMPL(zmk_split_transport_changed); \ No newline at end of file diff --git a/app/src/split/central.c b/app/src/split/central.c index e2b806437..aaa9cdb94 100644 --- a/app/src/split/central.c +++ b/app/src/split/central.c @@ -19,6 +19,8 @@ #include #include +#include + LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); const struct zmk_split_transport_central *active_transport; @@ -198,6 +200,8 @@ static int select_first_available_transport(void) { static int transport_status_changed_cb(const struct zmk_split_transport_central *central, struct zmk_split_transport_status status) { + raise_zmk_split_transport_changed( + (struct zmk_split_transport_changed){.addr = (uint32_t)central, .status = status}); if (central == active_transport) { LOG_DBG("Central at %p changed status: enabled %d, available %d, connections %d", central, status.enabled, status.available, status.connections); @@ -212,6 +216,26 @@ static int transport_status_changed_cb(const struct zmk_split_transport_central return 0; } +bool zmk_split_transport_get_available(uint32_t addr) { + STRUCT_SECTION_FOREACH(zmk_split_transport_central, t) { + if ((uint32_t)t == addr) { + return t->api->get_status().available; + } + } + + return 0; +} + +uint32_t zmk_split_get_transport_addr_at_index(uint8_t index) { + struct zmk_split_transport_central *t; + ptrdiff_t count; + STRUCT_SECTION_COUNT(zmk_split_transport_central, &count); + if ((ptrdiff_t)index > count) + return 0; + STRUCT_SECTION_GET(zmk_split_transport_central, index, &t); + return (uint32_t)t; +} + static int central_init(void) { STRUCT_SECTION_FOREACH(zmk_split_transport_central, t) { if (!t->api->set_status_callback) { diff --git a/app/src/split/peripheral.c b/app/src/split/peripheral.c index e9317bb8b..7ee29f66f 100644 --- a/app/src/split/peripheral.c +++ b/app/src/split/peripheral.c @@ -18,6 +18,8 @@ #include #include +#include + #if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) #include #endif @@ -55,13 +57,14 @@ int zmk_split_transport_peripheral_command_handler( if (err) { LOG_ERR("Failed to invoke behavior %s: %d", binding.behavior_dev, err); } + return err; } case ZMK_SPLIT_TRANSPORT_CENTRAL_CMD_TYPE_SET_PHYSICAL_LAYOUT: { - zmk_physical_layouts_select(cmd.data.set_physical_layout.layout_idx); + return zmk_physical_layouts_select(cmd.data.set_physical_layout.layout_idx); } #if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS) case ZMK_SPLIT_TRANSPORT_CENTRAL_CMD_TYPE_SET_HID_INDICATORS: { - raise_zmk_hid_indicators_changed((struct zmk_hid_indicators_changed){ + return raise_zmk_hid_indicators_changed((struct zmk_hid_indicators_changed){ .indicators = cmd.data.set_hid_indicators.indicators}); } #endif @@ -115,6 +118,8 @@ static int select_first_available_transport(void) { static int transport_status_changed_cb(const struct zmk_split_transport_peripheral *p, struct zmk_split_transport_status status) { + raise_zmk_split_transport_changed( + (struct zmk_split_transport_changed){.addr = (uint32_t)p, .status = status}); if (p == active_transport) { LOG_DBG("Peripheral at %p changed status: enabled %d, available %d, connections %d", p, status.enabled, status.available, status.connections); @@ -130,6 +135,26 @@ static int transport_status_changed_cb(const struct zmk_split_transport_peripher return 0; } +bool zmk_split_transport_get_available(uint32_t addr) { + STRUCT_SECTION_FOREACH(zmk_split_transport_peripheral, t) { + if ((uint32_t)t == addr) { + return t->api->get_status().available; + } + } + + return 0; +} + +uint32_t zmk_split_get_transport_addr_at_index(uint8_t index) { + struct zmk_split_transport_peripheral *t; + ptrdiff_t count; + STRUCT_SECTION_COUNT(zmk_split_transport_peripheral, &count); + if ((ptrdiff_t)index > count) + return 0; + STRUCT_SECTION_GET(zmk_split_transport_peripheral, index, &t); + return (uint32_t)t; +} + static int peripheral_init(void) { STRUCT_SECTION_FOREACH(zmk_split_transport_peripheral, t) { if (!t->api->set_status_callback) {