2026-04-10 19:28:20 +08:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
|
|
#include <app_event_manager.h>
|
|
|
|
|
|
2026-04-15 15:13:44 +08:00
|
|
|
#define MODULE mode_policy_module
|
2026-04-10 19:28:20 +08:00
|
|
|
#include <caf/events/module_state_event.h>
|
|
|
|
|
#include <caf/events/module_suspend_event.h>
|
2026-04-15 15:13:44 +08:00
|
|
|
#include <caf/events/power_event.h>
|
2026-04-10 19:28:20 +08:00
|
|
|
|
|
|
|
|
#include <zephyr/logging/log.h>
|
|
|
|
|
|
|
|
|
|
#include "mode_switch_event.h"
|
|
|
|
|
|
|
|
|
|
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
|
|
|
|
|
|
|
|
|
static bool initialized;
|
|
|
|
|
static bool running;
|
|
|
|
|
static bool ble_adv_suspended = true;
|
2026-04-15 15:13:44 +08:00
|
|
|
static bool usb_enabled;
|
2026-04-10 19:28:20 +08:00
|
|
|
|
|
|
|
|
static void broadcast_ble_adv_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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 15:13:44 +08:00
|
|
|
static void apply_mode_policy(enum mode_switch_mode mode)
|
|
|
|
|
{
|
|
|
|
|
bool should_suspend_ble_adv = (mode != MODE_SWITCH_BLE);
|
|
|
|
|
bool should_enable_usb = (mode == MODE_SWITCH_USB);
|
|
|
|
|
|
|
|
|
|
if (should_suspend_ble_adv != ble_adv_suspended) {
|
|
|
|
|
ble_adv_suspended = should_suspend_ble_adv;
|
|
|
|
|
broadcast_ble_adv_req(should_suspend_ble_adv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (should_enable_usb != usb_enabled) {
|
|
|
|
|
usb_enabled = should_enable_usb;
|
|
|
|
|
if (usb_enabled) {
|
|
|
|
|
struct module_resume_req_event *event =
|
|
|
|
|
new_module_resume_req_event();
|
|
|
|
|
|
|
|
|
|
event->sink_module_id = MODULE_ID(usb_device_module);
|
|
|
|
|
event->src_module_id = MODULE_ID(MODULE);
|
|
|
|
|
APP_EVENT_SUBMIT(event);
|
|
|
|
|
} else {
|
|
|
|
|
struct module_suspend_req_event *event =
|
|
|
|
|
new_module_suspend_req_event();
|
|
|
|
|
|
|
|
|
|
event->sink_module_id = MODULE_ID(usb_device_module);
|
|
|
|
|
event->src_module_id = MODULE_ID(MODULE);
|
|
|
|
|
APP_EVENT_SUBMIT(event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-10 19:28:20 +08:00
|
|
|
static int module_init(void)
|
|
|
|
|
{
|
|
|
|
|
ble_adv_suspended = true;
|
2026-04-15 15:13:44 +08:00
|
|
|
usb_enabled = false;
|
2026-04-10 19:28:20 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int module_start(void)
|
|
|
|
|
{
|
|
|
|
|
if (running) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
running = true;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void module_pause(void)
|
|
|
|
|
{
|
|
|
|
|
running = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool app_event_handler(const struct app_event_header *aeh)
|
|
|
|
|
{
|
|
|
|
|
if (is_mode_switch_event(aeh)) {
|
2026-04-15 15:13:44 +08:00
|
|
|
const struct mode_switch_event *event = cast_mode_switch_event(aeh);
|
|
|
|
|
|
|
|
|
|
if (running) {
|
|
|
|
|
apply_mode_policy(event->mode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
2026-04-10 19:28:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)) {
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
if (!initialized) {
|
|
|
|
|
err = module_init();
|
|
|
|
|
if (err) {
|
|
|
|
|
module_set_state(MODULE_STATE_ERROR);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initialized = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = module_start();
|
|
|
|
|
if (err) {
|
|
|
|
|
module_set_state(MODULE_STATE_ERROR);
|
|
|
|
|
} else {
|
|
|
|
|
module_set_state(MODULE_STATE_READY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 15:13:44 +08:00
|
|
|
if (is_power_down_event(aeh)) {
|
|
|
|
|
if (initialized) {
|
|
|
|
|
module_pause();
|
|
|
|
|
module_set_state(MODULE_STATE_STANDBY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_wake_up_event(aeh)) {
|
|
|
|
|
if (initialized) {
|
|
|
|
|
int err = module_start();
|
|
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
|
module_set_state(MODULE_STATE_ERROR);
|
|
|
|
|
} else {
|
|
|
|
|
module_set_state(MODULE_STATE_READY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-10 19:28:20 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
|
|
|
|
APP_EVENT_SUBSCRIBE(MODULE, mode_switch_event);
|
|
|
|
|
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
2026-04-15 15:13:44 +08:00
|
|
|
APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event);
|
|
|
|
|
APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);
|