feat(ble): 添加蓝牙广播控制模块实现动态广告管理

- 在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模块交互,实现广告控制逻辑
This commit is contained in:
2026-03-14 14:04:59 +08:00
parent e893ddded6
commit a3196ef162
3 changed files with 96 additions and 1 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,85 @@
#include <app_event_manager.h>
#define MODULE ble_adv_ctrl
#include <caf/events/module_state_event.h>
#include <caf/events/module_suspend_event.h>
#include "mode_event.h"
#include <zephyr/logging/log.h>
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);