From a3196ef1623c73ad605c1a4a25bd5b0f361e0e27 Mon Sep 17 00:00:00 2001 From: skiinder Date: Sat, 14 Mar 2026 14:04:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(ble):=20=E6=B7=BB=E5=8A=A0=E8=93=9D?= =?UTF-8?q?=E7=89=99=E5=B9=BF=E6=92=AD=E6=8E=A7=E5=88=B6=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8A=A8=E6=80=81=E5=B9=BF=E5=91=8A=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在CMakeLists.txt中添加ble_adv_ctrl_module.c源文件 - 启用MCU管理器相关配置(CONFIG_MCUMGR等)以支持OTA功能 - 添加CAF模块挂起事件配置(CONFIG_CAF_MODULE_SUSPEND_EVENTS) - 实现ble_adv_ctrl_module模块,根据当前模式类型控制蓝牙广告的挂起/恢复: * BLE模式时恢复广告,允许广播 * USB/2.4G模式时挂起广告,禁止广播 - 模块在启动时默认请求挂起状态,防止模式切换前出现意外广播 - 通过CAF事件系统与ble_adv模块交互,实现广告控制逻辑 --- CMakeLists.txt | 1 + prj.conf | 11 +++- src/modules/ble_adv_ctrl_module.c | 85 +++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/modules/ble_adv_ctrl_module.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b559b5c..54c1498 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ target_sources(app PRIVATE src/events/mode_event.c src/events/usb_hid_event.c src/modules/battery_module.c + src/modules/ble_adv_ctrl_module.c src/modules/ble_bond_module.c src/modules/button_map_module.c src/modules/mode_switch_module.c diff --git a/prj.conf b/prj.conf index ba8e33f..ca7e54f 100644 --- a/prj.conf +++ b/prj.conf @@ -1,12 +1,20 @@ CONFIG_CAF=y CONFIG_HEAP_MEM_POOL_SIZE=2048 CONFIG_LOG=y -CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_ASSERT=y CONFIG_ASSERT_VERBOSE=y CONFIG_RESET_ON_FATAL_ERROR=n CONFIG_FAULT_DUMP=2 +CONFIG_ZCBOR=y +CONFIG_BOOTLOADER_MCUBOOT=y +CONFIG_MCUMGR=y +CONFIG_MCUMGR_TRANSPORT_BT=y +CONFIG_MCUMGR_GRP_IMG=y +CONFIG_MCUMGR_GRP_OS=y +CONFIG_IMG_MANAGER=y +CONFIG_STREAM_FLASH=y + CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y @@ -24,6 +32,7 @@ CONFIG_BT_SETTINGS=y CONFIG_CAF_BLE_STATE=y CONFIG_CAF_BLE_ADV=y +CONFIG_CAF_MODULE_SUSPEND_EVENTS=y CONFIG_CAF_SETTINGS_LOADER=y CONFIG_BT_ADV_PROV_FLAGS=y CONFIG_BT_ADV_PROV_GAP_APPEARANCE=y diff --git a/src/modules/ble_adv_ctrl_module.c b/src/modules/ble_adv_ctrl_module.c new file mode 100644 index 0000000..3e19b0b --- /dev/null +++ b/src/modules/ble_adv_ctrl_module.c @@ -0,0 +1,85 @@ +#include + +#define MODULE ble_adv_ctrl +#include +#include + +#include "mode_event.h" + +#include +LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); + +/* + * 该模块负责把“模式选择”转换成对 ble_adv 的挂起/恢复请求: + * - BLE 模式:恢复 ble_adv,允许广播。 + * - USB/2.4G 模式:挂起 ble_adv,禁止广播。 + * + * 说明: + * - 这里是控制层,不直接操作 bt_le_adv_start/stop; + * - 实际广播执行仍由 CAF 的 ble_adv 模块处理。 + */ +static bool ble_adv_suspended = true; + +static void send_ble_adv_ctrl_req(bool suspend) +{ + if (suspend) { + struct module_suspend_req_event *event = new_module_suspend_req_event(); + + event->sink_module_id = MODULE_ID(ble_adv); + event->src_module_id = MODULE_ID(MODULE); + APP_EVENT_SUBMIT(event); + } else { + struct module_resume_req_event *event = new_module_resume_req_event(); + + event->sink_module_id = MODULE_ID(ble_adv); + event->src_module_id = MODULE_ID(MODULE); + APP_EVENT_SUBMIT(event); + } +} + +static bool handle_mode_event(const struct mode_event *event) +{ + bool new_suspend = (event->mode_type != MODE_TYPE_BLE); + + if (new_suspend == ble_adv_suspended) { + return false; + } + + ble_adv_suspended = new_suspend; + send_ble_adv_ctrl_req(ble_adv_suspended); + + LOG_INF("BLE advertising %s by mode %u", + ble_adv_suspended ? "suspended" : "resumed", + event->mode_type); + + return false; +} + +static bool app_event_handler(const struct app_event_header *aeh) +{ + if (is_module_state_event(aeh)) { + const struct module_state_event *event = cast_module_state_event(aeh); + + if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) { + /* + * 上电默认先请求挂起,避免在 mode_switch 首次采样前出现短暂误广播。 + */ + send_ble_adv_ctrl_req(true); + module_set_state(MODULE_STATE_READY); + } + + return false; + } + + if (is_mode_event(aeh)) { + return handle_mode_event(cast_mode_event(aeh)); + } + + __ASSERT_NO_MSG(false); + return false; +} + +APP_EVENT_LISTENER(MODULE, app_event_handler); +APP_EVENT_SUBSCRIBE(MODULE, module_state_event); +APP_EVENT_SUBSCRIBE(MODULE, mode_event); +