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); +