diff options
Diffstat (limited to 'src/common/bts_shutdown_fsm.c')
-rw-r--r-- | src/common/bts_shutdown_fsm.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/src/common/bts_shutdown_fsm.c b/src/common/bts_shutdown_fsm.c index 0ac30789..13a0e1d0 100644 --- a/src/common/bts_shutdown_fsm.c +++ b/src/common/bts_shutdown_fsm.c @@ -1,6 +1,6 @@ /* BTS shutdown FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -29,6 +29,8 @@ #include <osmo-bts/gsm_data.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> +#include <osmo-bts/nm_common_fsm.h> #define X(s) (1 << (s)) @@ -58,6 +60,9 @@ static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data) unsigned int count; switch(event) { case BTS_SHUTDOWN_EV_START: + /* Firt announce to NM objects that we are starting a shutdown procedure: */ + osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_START, NULL); + count = count_trx_operational(bts); if (count) { bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL); @@ -85,7 +90,10 @@ static void st_wait_ramp_down_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t llist_for_each_entry(trx, &bts->trx_list, list) { if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED) continue; - power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb); + if (bts->shutdown_fi_skip_power_ramp) + power_ramp_force(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb); + else + power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb); } } @@ -108,8 +116,15 @@ static void st_wait_ramp_down_compl(struct osmo_fsm_inst *fi, uint32_t event, vo LOGPFSML(fi, LOGL_INFO, "%s Ramping down complete, %u TRX remaining\n", gsm_trx_name(src_trx), remaining); - if (remaining == 0) + if (remaining == 0) { + /* Make sure we end up any remaining ongoing power ramp + * down under target shutdown tx power level, then + * finally transit to next state: + */ + llist_for_each_entry(trx, &bts->trx_list, list) + power_ramp_abort(trx); bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED); + } break; } } @@ -148,8 +163,15 @@ static void st_wait_trx_closed(struct osmo_fsm_inst *fi, uint32_t event, void *d static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { - LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfuly, exiting process\n"); - exit(0); + struct gsm_bts *bts = (struct gsm_bts *)fi->priv; + + osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_FINISH, NULL); + + if (bts->shutdown_fi_exit_proc) { + LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfully, exiting process\n"); + exit(0); + } + bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_NONE); } static struct osmo_fsm_state bts_shutdown_fsm_states[] = { @@ -182,6 +204,8 @@ static struct osmo_fsm_state bts_shutdown_fsm_states[] = { }, [BTS_SHUTDOWN_ST_EXIT] = { .name = "EXIT", + .out_state_mask = + X(BTS_SHUTDOWN_ST_NONE), .onenter = st_exit_on_enter, } }; @@ -189,7 +213,7 @@ static struct osmo_fsm_state bts_shutdown_fsm_states[] = { const struct value_string bts_shutdown_fsm_event_names[] = { OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_START), OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_TRX_RAMP_COMPL), - OSMO_VALUE_STRING(BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED), + OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_TRX_CLOSED), { 0, NULL } }; @@ -224,18 +248,33 @@ static __attribute__((constructor)) void bts_shutdown_fsm_init(void) OSMO_ASSERT(osmo_fsm_register(&bts_shutdown_fsm) == 0); } -void bts_shutdown(struct gsm_bts *bts, const char *reason) +bool bts_shutdown_in_progress(const struct gsm_bts *bts) +{ + const struct osmo_fsm_inst *fi = bts->shutdown_fi; + return fi->state != BTS_SHUTDOWN_ST_NONE; +} + +void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc, bool skip_power_ramp) { struct osmo_fsm_inst *fi = bts->shutdown_fi; - if (fi->state != BTS_SHUTDOWN_ST_NONE) { + if (bts_shutdown_in_progress(bts)) { LOGPFSML(fi, LOGL_NOTICE, "BTS is already being shutdown.\n"); + if (exit_proc) + bts->shutdown_fi_exit_proc = true; return; } - - LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, reason: %s\n", reason); + bts->shutdown_fi_exit_proc = exit_proc; + bts->shutdown_fi_skip_power_ramp = skip_power_ramp; + LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, exit %u, reason: %s\n", + exit_proc, reason); osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_START, NULL); } +void bts_shutdown(struct gsm_bts *bts, const char *reason) +{ + bts_shutdown_ext(bts, reason, true, true); +} + void bts_model_trx_close_cb(struct gsm_bts_trx *trx, int rc) { struct osmo_fsm_inst *fi = trx->bts->shutdown_fi; |