diff --git a/inc/module_lifecycle.h b/inc/module_lifecycle.h index a5cd8c3..8af1efe 100644 --- a/inc/module_lifecycle.h +++ b/inc/module_lifecycle.h @@ -52,7 +52,72 @@ static inline bool module_lifecycle_is_initialized( static inline bool module_lifecycle_reports_stopped_state( const struct module_lifecycle_ctx *ctx) { - return ctx->cfg->mode != ML_MODE_NONE; + return ctx->cfg->mode == ML_MODE_POWER; +} + +static inline bool module_lifecycle_target_allowed( + const struct module_lifecycle_ctx *ctx, + enum module_lifecycle target) +{ + switch (target) { + case LC_RUNNING: + case LC_ERROR: + return true; + + case LC_STOPPED: + return ctx->cfg->mode == ML_MODE_POWER; + + case LC_SUSPENDED: + return ctx->cfg->mode == ML_MODE_SUSPEND; + + case LC_UNINIT: + default: + return false; + } +} + +static inline bool module_lifecycle_path_allowed( + enum module_lifecycle current, + enum module_lifecycle target) +{ + switch (current) { + case LC_UNINIT: + return (target == LC_RUNNING) || (target == LC_STOPPED); + + case LC_RUNNING: + return (target == LC_STOPPED) || (target == LC_SUSPENDED); + + case LC_STOPPED: + case LC_SUSPENDED: + return target == LC_RUNNING; + + case LC_ERROR: + default: + return false; + } +} + +static inline int module_lifecycle_validate_ops( + const struct module_lifecycle_ctx *ctx) +{ + if ((ctx == NULL) || (ctx->cfg == NULL) || (ctx->ops == NULL) || + (ctx->ops->do_init == NULL)) { + return -EINVAL; + } + + switch (ctx->cfg->mode) { + case ML_MODE_NONE: + return 0; + + case ML_MODE_POWER: + case ML_MODE_SUSPEND: + return (ctx->ops->do_start != NULL) && (ctx->ops->do_stop != NULL) ? + 0 : + -EINVAL; + + default: + return -EINVAL; + } } static inline int module_lifecycle_report_state( @@ -65,14 +130,18 @@ static inline int module_lifecycle_report_state( return 0; case LC_STOPPED: - if (!module_lifecycle_reports_stopped_state(ctx)) { - return 0; + if (ctx->cfg->mode != ML_MODE_POWER) { + return -EINVAL; } module_set_state(ctx->cfg->stopped_state); return 0; case LC_SUSPENDED: + if (ctx->cfg->mode != ML_MODE_SUSPEND) { + return -EINVAL; + } + module_set_state(MODULE_STATE_SUSPENDED); return 0; @@ -105,39 +174,56 @@ static inline int module_lifecycle_do_init(struct module_lifecycle_ctx *ctx) return 0; } -static inline int module_lifecycle_do_start(struct module_lifecycle_ctx *ctx, - enum module_lifecycle target) +static inline int module_lifecycle_finish_transition( + struct module_lifecycle_ctx *ctx, + enum module_lifecycle target) { - int err = ctx->ops->do_start(); - - if (err) { - return module_lifecycle_fail(ctx, err); - } - ctx->state = target; return module_lifecycle_report_state(ctx, target); } -static inline int module_lifecycle_do_stop(struct module_lifecycle_ctx *ctx, - enum module_lifecycle target) +static inline int module_lifecycle_start_running(struct module_lifecycle_ctx *ctx) { - int err = ctx->ops->do_stop(); + int err = 0; + + if (ctx->ops->do_start != NULL) { + err = ctx->ops->do_start(); + + if (err) { + return module_lifecycle_fail(ctx, err); + } + } + + return module_lifecycle_finish_transition(ctx, LC_RUNNING); +} + +static inline int module_lifecycle_stop_running( + struct module_lifecycle_ctx *ctx, + enum module_lifecycle target) +{ + int err; + + if (ctx->ops->do_stop == NULL) { + return module_lifecycle_fail(ctx, -EINVAL); + } + + err = ctx->ops->do_stop(); if (err) { return module_lifecycle_fail(ctx, err); } - ctx->state = target; - return module_lifecycle_report_state(ctx, target); + return module_lifecycle_finish_transition(ctx, target); } static inline int module_set_lifecycle(struct module_lifecycle_ctx *ctx, enum module_lifecycle target) { - if ((ctx == NULL) || (ctx->cfg == NULL) || (ctx->ops == NULL) || - (ctx->ops->do_init == NULL) || (ctx->ops->do_start == NULL) || - (ctx->ops->do_stop == NULL)) { - return -EINVAL; + int err; + + err = module_lifecycle_validate_ops(ctx); + if (err) { + return err; } if (ctx->state == LC_ERROR) { @@ -152,53 +238,35 @@ static inline int module_set_lifecycle(struct module_lifecycle_ctx *ctx, return module_lifecycle_fail(ctx, -EIO); } + if (!module_lifecycle_target_allowed(ctx, target) || + !module_lifecycle_path_allowed(ctx->state, target)) { + return -EPERM; + } + switch (ctx->state) { case LC_UNINIT: + err = module_lifecycle_do_init(ctx); + if (err) { + return err; + } + if (target == LC_RUNNING) { - int err = module_lifecycle_do_init(ctx); - - if (err) { - return err; - } - - ctx->state = LC_STOPPED; - return module_lifecycle_do_start(ctx, LC_RUNNING); + return module_lifecycle_start_running(ctx); } - if (target == LC_STOPPED) { - int err = module_lifecycle_do_init(ctx); - - if (err) { - return err; - } - - ctx->state = LC_STOPPED; - return module_lifecycle_report_state(ctx, LC_STOPPED); - } - - break; + return module_lifecycle_finish_transition(ctx, LC_STOPPED); case LC_RUNNING: - if ((target == LC_STOPPED) || (target == LC_SUSPENDED)) { - return module_lifecycle_do_stop(ctx, target); - } - - break; + return module_lifecycle_stop_running(ctx, target); case LC_STOPPED: case LC_SUSPENDED: - if (target == LC_RUNNING) { - return module_lifecycle_do_start(ctx, LC_RUNNING); - } - - break; + return module_lifecycle_start_running(ctx); case LC_ERROR: default: - break; + return -EPERM; } - - return -EPERM; } #endif /* MODULE_LIFECYCLE_H_ */ diff --git a/src/ble_bas_module.c b/src/ble_bas_module.c index 22da91c..ee8a314 100644 --- a/src/ble_bas_module.c +++ b/src/ble_bas_module.c @@ -105,9 +105,7 @@ 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)) { - (void)module_set_lifecycle(&ctx.lc, - ctx.ble_ready ? LC_RUNNING : - LC_STOPPED); + (void)module_set_lifecycle(&ctx.lc, LC_RUNNING); return false; } @@ -115,9 +113,7 @@ static bool app_event_handler(const struct app_event_header *aeh) if (check_state(event, MODULE_ID(ble_state), MODULE_STATE_READY)) { ctx.ble_ready = true; - if (ctx.lc.state == LC_STOPPED) { - (void)module_set_lifecycle(&ctx.lc, LC_RUNNING); - } else if (module_lifecycle_is_running(&ctx.lc)) { + if (module_lifecycle_is_running(&ctx.lc)) { (void)bas_update_level(); } return false; diff --git a/src/ble_hid_module.c b/src/ble_hid_module.c index 18383f8..ab05b76 100644 --- a/src/ble_hid_module.c +++ b/src/ble_hid_module.c @@ -7,7 +7,6 @@ #define MODULE ble_hid_module #include -#include #include #include @@ -57,8 +56,8 @@ 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, + .mode = ML_MODE_NONE, + .stopped_state = MODULE_STATE_OFF, }; static const struct module_lifecycle_ops lifecycle_ops = { @@ -446,22 +445,6 @@ static bool app_event_handler(const struct app_event_header *aeh) 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; } @@ -469,5 +452,3 @@ APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE_EARLY(MODULE, module_state_event); APP_EVENT_SUBSCRIBE(MODULE, hid_tx_report_event); APP_EVENT_SUBSCRIBE_EARLY(MODULE, ble_peer_event); -APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); -APP_EVENT_SUBSCRIBE(MODULE, wake_up_event); diff --git a/src/ble_nus_module.c b/src/ble_nus_module.c index be349f0..526ad7b 100644 --- a/src/ble_nus_module.c +++ b/src/ble_nus_module.c @@ -6,7 +6,6 @@ #define MODULE ble_nus_module #include -#include #include #include @@ -38,8 +37,8 @@ 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, + .mode = ML_MODE_NONE, + .stopped_state = MODULE_STATE_OFF, }; static const struct module_lifecycle_ops lifecycle_ops = { @@ -329,22 +328,6 @@ static bool app_event_handler(const struct app_event_header *aeh) return false; } - if (is_power_down_event(aeh)) { - if (module_lifecycle_is_initialized(&ctx.lc)) { - (void)apply_lifecycle(LC_STOPPED); - } - - return false; - } - - if (is_wake_up_event(aeh)) { - if (module_lifecycle_is_initialized(&ctx.lc)) { - (void)apply_lifecycle(LC_RUNNING); - } - - return false; - } - return false; } @@ -352,5 +335,3 @@ APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE(MODULE, module_state_event); APP_EVENT_SUBSCRIBE(MODULE, proto_tx_event); APP_EVENT_SUBSCRIBE_EARLY(MODULE, ble_peer_event); -APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); -APP_EVENT_SUBSCRIBE(MODULE, wake_up_event); diff --git a/src/mode_policy_module.c b/src/mode_policy_module.c index e2ebb95..4fa2f9d 100644 --- a/src/mode_policy_module.c +++ b/src/mode_policy_module.c @@ -5,7 +5,6 @@ #define MODULE mode_policy_module #include #include -#include #include @@ -24,8 +23,8 @@ 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, + .mode = ML_MODE_NONE, + .stopped_state = MODULE_STATE_OFF, }; static const struct module_lifecycle_ops lifecycle_ops = { @@ -195,27 +194,9 @@ static bool app_event_handler(const struct app_event_header *aeh) 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); diff --git a/src/mode_switch_module.c b/src/mode_switch_module.c index dbd97c3..7c47215 100644 --- a/src/mode_switch_module.c +++ b/src/mode_switch_module.c @@ -201,6 +201,10 @@ static bool app_event_handler(const struct app_event_header *aeh) if (is_wake_up_event(aeh)) { if (module_lifecycle_is_initialized(&ctx.lc)) { (void)module_set_lifecycle(&ctx.lc, LC_RUNNING); + + if (ctx.last_mode != MODE_SWITCH_INVALID) { + submit_mode_switch_event(ctx.last_mode, 0U); + } } return false; diff --git a/src/protocol_module.c b/src/protocol_module.c index fa9d108..66a7f6f 100644 --- a/src/protocol_module.c +++ b/src/protocol_module.c @@ -8,7 +8,6 @@ #define MODULE protocol_module #include -#include #include #include @@ -55,8 +54,8 @@ 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, + .mode = ML_MODE_NONE, + .stopped_state = MODULE_STATE_OFF, }; static const struct module_lifecycle_ops lifecycle_ops = { @@ -544,22 +543,6 @@ static bool app_event_handler(const struct app_event_header *aeh) 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; } @@ -569,5 +552,3 @@ APP_EVENT_SUBSCRIBE(MODULE, hid_led_event); APP_EVENT_SUBSCRIBE(MODULE, module_state_event); APP_EVENT_SUBSCRIBE(MODULE, proto_rx_event); APP_EVENT_SUBSCRIBE(MODULE, proto_transport_state_event); -APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); -APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);