Files
blinky/src/mode_policy_module.c

161 lines
3.6 KiB
C
Raw Normal View History

#include <stdbool.h>
#include <app_event_manager.h>
#define MODULE mode_policy_module
#include <caf/events/module_state_event.h>
#include <caf/events/module_suspend_event.h>
#include <caf/events/power_event.h>
#include <zephyr/logging/log.h>
#include "module_lifecycle.h"
#include "mode_switch_event.h"
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
struct mode_policy_module_ctx {
struct module_lifecycle_ctx lc;
bool ble_adv_suspended;
bool usb_enabled;
};
static int do_init(void);
static int do_start(void);
static int do_stop(void);
static const struct module_lifecycle_cfg lifecycle_cfg = {
.mode = ML_MODE_POWER,
.stopped_state = MODULE_STATE_STANDBY,
};
static const struct module_lifecycle_ops lifecycle_ops = {
.do_init = do_init,
.do_start = do_start,
.do_stop = do_stop,
};
static struct mode_policy_module_ctx ctx = {
.lc = {
.state = LC_UNINIT,
.cfg = &lifecycle_cfg,
.ops = &lifecycle_ops,
},
.ble_adv_suspended = true,
};
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);
}
}
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 != ctx.ble_adv_suspended) {
ctx.ble_adv_suspended = should_suspend_ble_adv;
broadcast_ble_adv_req(should_suspend_ble_adv);
}
if (should_enable_usb != ctx.usb_enabled) {
ctx.usb_enabled = should_enable_usb;
if (ctx.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);
}
}
}
static int do_init(void)
{
ctx.ble_adv_suspended = true;
ctx.usb_enabled = false;
return 0;
}
static int do_start(void)
{
if (module_lifecycle_is_running(&ctx.lc)) {
return 0;
}
return 0;
}
static int do_stop(void)
{
return 0;
}
static bool app_event_handler(const struct app_event_header *aeh)
{
if (is_mode_switch_event(aeh)) {
const struct mode_switch_event *event = cast_mode_switch_event(aeh);
if (module_lifecycle_is_running(&ctx.lc)) {
apply_mode_policy(event->mode);
}
return false;
}
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)) {
(void)module_set_lifecycle(&ctx.lc, LC_RUNNING);
}
return false;
}
if (is_power_down_event(aeh)) {
if (module_lifecycle_is_initialized(&ctx.lc)) {
(void)module_set_lifecycle(&ctx.lc, LC_STOPPED);
}
return false;
}
if (is_wake_up_event(aeh)) {
if (module_lifecycle_is_initialized(&ctx.lc)) {
(void)module_set_lifecycle(&ctx.lc, LC_RUNNING);
}
return false;
}
return false;
}
APP_EVENT_LISTENER(MODULE, app_event_handler);
APP_EVENT_SUBSCRIBE(MODULE, mode_switch_event);
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event);
APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);