aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/bts_shutdown_fsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/bts_shutdown_fsm.c')
-rw-r--r--src/common/bts_shutdown_fsm.c61
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;