Change in osmo-bts[master]: Introduce bts_shutdown FSM

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Thu Jun 18 12:51:35 UTC 2020


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/18903 )


Change subject: Introduce bts_shutdown FSM
......................................................................

Introduce bts_shutdown FSM

Using an FSM here will allow for more complex ordered shutdown
procedures, like power ramp down, waiting for TRX deact asyncrhonously,
etc.

Current commit leaves everything in place already prepared to implement
ramp down, which will be implemented in next commit in the series.

Related: SYS#4920
Change-Id: I8f48f17e61c3b9b86342eaf5b8a2b1ac9758bde5
---
M include/osmo-bts/Makefile.am
M include/osmo-bts/bts.h
A include/osmo-bts/bts_shutdown_fsm.h
M include/osmo-bts/gsm_data.h
M src/common/Makefile.am
M src/common/bts.c
A src/common/bts_shutdown_fsm.c
M src/common/gsm_data.c
M src/common/main.c
M src/osmo-bts-octphy/main.c
M src/osmo-bts-omldummy/bts_model.c
M src/osmo-bts-sysmo/l1_if.c
M src/osmo-bts-sysmo/main.c
M src/osmo-bts-sysmo/oml.c
M src/osmo-bts-trx/l1_if.c
M src/osmo-bts-trx/scheduler_trx.c
M src/osmo-bts-trx/trx_if.c
M src/osmo-bts-virtual/l1_if.c
M src/osmo-bts-virtual/main.c
M src/osmo-bts-virtual/scheduler_virtbts.c
20 files changed, 224 insertions(+), 35 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/03/18903/1

diff --git a/include/osmo-bts/Makefile.am b/include/osmo-bts/Makefile.am
index 4999ab4..310fce2 100644
--- a/include/osmo-bts/Makefile.am
+++ b/include/osmo-bts/Makefile.am
@@ -2,6 +2,7 @@
 	abis.h \
 	bts.h \
 	bts_model.h \
+	bts_shutdown_fsm.h \
 	gsm_data.h \
 	logging.h \
 	measurement.h \
diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h
index 63412f9..6549244 100644
--- a/include/osmo-bts/bts.h
+++ b/include/osmo-bts/bts.h
@@ -28,7 +28,6 @@
 
 int bts_init(struct gsm_bts *bts);
 int bts_trx_init(struct gsm_bts_trx *trx);
-void bts_shutdown(struct gsm_bts *bts, const char *reason);
 
 int bts_link_estab(struct gsm_bts *bts);
 int trx_link_estab(struct gsm_bts_trx *trx);
diff --git a/include/osmo-bts/bts_shutdown_fsm.h b/include/osmo-bts/bts_shutdown_fsm.h
new file mode 100644
index 0000000..1ced7a1
--- /dev/null
+++ b/include/osmo-bts/bts_shutdown_fsm.h
@@ -0,0 +1,41 @@
+/* BTS shutdown FSM */
+
+/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info at sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin at sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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/>.
+ *
+ */
+
+#pragma once
+
+#include <osmocom/core/fsm.h>
+
+/* 3GPP TS 24.008 § 4.1.3.3 GMM mobility management states on the network side */
+enum bts_shutdown_fsm_states {
+	ST_BTS_SHUTDOWN_NONE,
+	ST_BTS_SHUTDOWN_WAIT_RAMP_DOWN_COMPL,
+	ST_BTS_SHUTDOWN_EXIT,
+};
+
+enum bts_shutdown_fsm_events {
+	E_BTS_SHUTDOWN_START,
+};
+
+extern struct osmo_fsm bts_shutdown_fsm;
+
+struct gsm_bts;
+void bts_shutdown(struct gsm_bts *bts, const char *reason);
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h
index 80cc0be..5194850 100644
--- a/include/osmo-bts/gsm_data.h
+++ b/include/osmo-bts/gsm_data.h
@@ -732,6 +732,9 @@
 		char *sock_path;
 	} pcu;
 
+	struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */
+	struct osmo_tdef *T_defs; /* Timer defines */
+
 	void *model_priv; /* Allocated by bts_model, contains model specific data pointer */
 };
 
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 85b7038..2fa5514 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -27,6 +27,7 @@
 	tx_power.c \
 	bts_ctrl_commands.c \
 	bts_ctrl_lookup.c \
+	bts_shutdown_fsm.c \
 	l1sap.c \
 	cbch.c \
 	power_control.c \
diff --git a/src/common/bts.c b/src/common/bts.c
index d8a6ff2..b90bfa4 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -269,39 +269,6 @@
 	return 0;
 }
 
-static void shutdown_timer_cb(void *data)
-{
-	fprintf(stderr, "Shutdown timer expired\n");
-	exit(42);
-}
-
-static struct osmo_timer_list shutdown_timer = {
-	.cb = &shutdown_timer_cb,
-};
-
-void bts_shutdown(struct gsm_bts *bts, const char *reason)
-{
-	struct gsm_bts_trx *trx;
-
-	if (osmo_timer_pending(&shutdown_timer)) {
-		LOGP(DOML, LOGL_NOTICE,
-			"BTS is already being shutdown.\n");
-		return;
-	}
-
-	LOGP(DOML, LOGL_NOTICE, "Shutting down BTS %u, Reason %s\n",
-		bts->nr, reason);
-
-	llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
-		bts_model_trx_deact_rf(trx);
-		bts_model_trx_close(trx);
-	}
-
-	/* schedule a timer to make sure select loop logic can run again
-	 * to dispatch any pending primitives */
-	osmo_timer_schedule(&shutdown_timer, 3, 0);
-}
-
 /* main link is established, send status report */
 int bts_link_estab(struct gsm_bts *bts)
 {
diff --git a/src/common/bts_shutdown_fsm.c b/src/common/bts_shutdown_fsm.c
new file mode 100644
index 0000000..c8aa0ff
--- /dev/null
+++ b/src/common/bts_shutdown_fsm.c
@@ -0,0 +1,145 @@
+/* BTS shutdown FSM */
+
+/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info at sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin at sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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/>.
+ *
+ */
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/tdef.h>
+
+#include <osmo-bts/bts_shutdown_fsm.h>
+#include <osmo-bts/logging.h>
+#include <osmo-bts/gsm_data.h>
+#include <osmo-bts/bts_model.h>
+
+#define X(s) (1 << (s))
+
+static const struct osmo_tdef_state_timeout bts_shutdown_fsm_timeouts[32] = {
+	[ST_BTS_SHUTDOWN_NONE] = { },
+	[ST_BTS_SHUTDOWN_WAIT_RAMP_DOWN_COMPL] = { .T = -1 },
+	[ST_BTS_SHUTDOWN_EXIT] = { .T = -2 },
+};
+
+#define bts_shutdown_fsm_state_chg(fi, NEXT_STATE) \
+	osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, bts_shutdown_fsm_timeouts, ((struct gsm_bts *)fi->priv)->T_defs, -1)
+
+static void st_bts_shutdown_none(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch(event) {
+	case E_BTS_SHUTDOWN_START:
+		bts_shutdown_fsm_state_chg(fi, ST_BTS_SHUTDOWN_WAIT_RAMP_DOWN_COMPL);
+		break;
+	}
+}
+
+static void st_bts_shutdown_wait_ramp_down_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+	/* TODO: here power ramp down will be started on all TRX, prior to changing state */
+}
+
+static void st_bts_shutdown_wait_ramp_down_compl(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	/* TODO: In here once we have ramp down implemented we'll transit to
+	   regular exit. For now we simply wait for state timeout
+	   bts_shutdown_fsm_state_chg(fi, ST_BTS_SHUTDOWN_EXIT);
+	*/
+}
+
+static void st_bts_shutdown_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+	struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
+	struct gsm_bts_trx *trx;
+	llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
+		bts_model_trx_deact_rf(trx);
+		bts_model_trx_close(trx);
+	}
+	/* There's yet no way to get confirmation from lower layers regarding
+	   state. Allow a few seconds of select() loop and timeout timer will
+	   exit later */
+}
+
+static struct osmo_fsm_state bts_shutdown_fsm_states[] = {
+	[ST_BTS_SHUTDOWN_NONE] = {
+		.in_event_mask =
+			X(E_BTS_SHUTDOWN_START),
+		.out_state_mask = X(ST_BTS_SHUTDOWN_WAIT_RAMP_DOWN_COMPL),
+		.name = "None",
+		.action = st_bts_shutdown_none,
+	},
+	[ST_BTS_SHUTDOWN_WAIT_RAMP_DOWN_COMPL] = {
+		.in_event_mask = 0,
+		.out_state_mask =
+			X(ST_BTS_SHUTDOWN_EXIT),
+		.name = "WaitRampDownComplete",
+		.onenter = st_bts_shutdown_wait_ramp_down_compl_on_enter,
+		.action = st_bts_shutdown_wait_ramp_down_compl,
+	},
+	[ST_BTS_SHUTDOWN_EXIT] = {
+		.name = "Exit",
+		.onenter = st_bts_shutdown_exit_on_enter,
+	}
+};
+
+const struct value_string bts_shutdown_fsm_event_names[] = {
+	OSMO_VALUE_STRING(E_BTS_SHUTDOWN_START),
+	{ 0, NULL }
+};
+
+int bts_shutdown_fsm_timer_cb(struct osmo_fsm_inst *fi)
+{
+	switch (fi->state) {
+	case ST_BTS_SHUTDOWN_WAIT_RAMP_DOWN_COMPL:
+		LOGPFSML(fi, LOGL_ERROR, "Timer expired waiting for ramp down complete\n");
+		bts_shutdown_fsm_state_chg(fi, ST_BTS_SHUTDOWN_EXIT);
+		break;
+	case ST_BTS_SHUTDOWN_EXIT:
+		LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfuly, exiting process\n");
+		exit(0);
+		break;
+	default:
+		OSMO_ASSERT(false);
+	}
+	return 0;
+}
+
+struct osmo_fsm bts_shutdown_fsm = {
+	.name = "BTS_SHUTDOWN",
+	.states = bts_shutdown_fsm_states,
+	.num_states = ARRAY_SIZE(bts_shutdown_fsm_states),
+	.event_names = bts_shutdown_fsm_event_names,
+	.log_subsys = DOML,
+	.timer_cb = bts_shutdown_fsm_timer_cb,
+};
+
+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)
+{
+	struct osmo_fsm_inst *fi = bts->shutdown_fi;
+	if (fi->state != ST_BTS_SHUTDOWN_NONE) {
+		LOGPFSML(fi, LOGL_NOTICE, "BTS is already being shutdown.\n");
+		return;
+	}
+
+	LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, reason: %s\n", reason);
+	osmo_fsm_inst_dispatch(fi, E_BTS_SHUTDOWN_START, NULL);
+}
diff --git a/src/common/gsm_data.c b/src/common/gsm_data.c
index c680001..5591af1 100644
--- a/src/common/gsm_data.c
+++ b/src/common/gsm_data.c
@@ -28,12 +28,22 @@
 
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/talloc.h>
+#include <osmocom/core/statistics.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/tdef.h>
+
 #include <osmocom/gsm/gsm_utils.h>
 #include <osmocom/gsm/abis_nm.h>
-#include <osmocom/core/statistics.h>
 #include <osmocom/codec/ecu.h>
 
 #include <osmo-bts/gsm_data.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
+
+static struct osmo_tdef bts_T_defs[] = {
+	{ .T=-1, .default_val=1, .desc="Grace time for ramp down complete during shutdown (s)" },
+	{ .T=-2, .default_val=3, .desc="Grace time for proper ordered shutdown of transceivers (s)" },
+	{}
+};
 
 void gsm_abis_mo_reset(struct gsm_abis_mo *mo)
 {
@@ -266,6 +276,7 @@
 
 struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
 {
+	char bts_name[32];
 	struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
 	int i;
 
@@ -277,6 +288,12 @@
 	INIT_LLIST_HEAD(&bts->trx_list);
 	bts->ms_max_power = 15;	/* dBm */
 
+	bts->T_defs = bts_T_defs;
+	osmo_tdefs_reset(bts->T_defs);
+	snprintf(bts_name, sizeof(bts_name), "bts%d", bts->nr);
+	bts->shutdown_fi = osmo_fsm_inst_alloc(&bts_shutdown_fsm, bts, bts,
+					       LOGL_INFO, bts_name);
+
 	gsm_mo_init(&bts->mo, bts, NM_OC_BTS,
 			bts->nr, 0xff, 0xff);
 	gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
diff --git a/src/common/main.c b/src/common/main.c
index 6d8088c..1ce91cf 100644
--- a/src/common/main.c
+++ b/src/common/main.c
@@ -42,6 +42,7 @@
 #include <osmocom/core/gsmtap.h>
 
 #include <osmo-bts/gsm_data.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 #include <osmo-bts/phy_link.h>
 #include <osmo-bts/logging.h>
 #include <osmo-bts/abis.h>
diff --git a/src/osmo-bts-octphy/main.c b/src/osmo-bts-octphy/main.c
index 928a4c8..d9d4e7c 100644
--- a/src/osmo-bts-octphy/main.c
+++ b/src/osmo-bts-octphy/main.c
@@ -45,6 +45,7 @@
 #include <osmo-bts/bts.h>
 #include <osmo-bts/vty.h>
 #include <osmo-bts/l1sap.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 
 #include "l1_if.h"
 
diff --git a/src/osmo-bts-omldummy/bts_model.c b/src/osmo-bts-omldummy/bts_model.c
index c011401..f85c62b 100644
--- a/src/osmo-bts-omldummy/bts_model.c
+++ b/src/osmo-bts-omldummy/bts_model.c
@@ -34,6 +34,7 @@
 #include <osmo-bts/bts_model.h>
 #include <osmo-bts/handover.h>
 #include <osmo-bts/l1sap.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 
 /* TODO: check if dummy method is sufficient, else implement */
 int bts_model_lchan_deactivate(struct gsm_lchan *lchan)
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 2e5e5b6..192ba2d 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -51,6 +51,7 @@
 #include <osmo-bts/msg_utils.h>
 #include <osmo-bts/dtx_dl_amr_fsm.h>
 #include <osmo-bts/tx_power.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 
 #include <sysmocom/femtobts/superfemto.h>
 #include <sysmocom/femtobts/gsml1prim.h>
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c
index 51a14c7..6aedbfc 100644
--- a/src/osmo-bts-sysmo/main.c
+++ b/src/osmo-bts-sysmo/main.c
@@ -46,6 +46,7 @@
 #include <osmo-bts/bts_model.h>
 #include <osmo-bts/pcu_if.h>
 #include <osmo-bts/l1sap.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 
 #define SYSMOBTS_RF_LOCK_PATH	"/var/lock/bts_rf_lock"
 
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index c3bf8b6..d51e4e8 100644
--- a/src/osmo-bts-sysmo/oml.c
+++ b/src/osmo-bts-sysmo/oml.c
@@ -39,6 +39,7 @@
 #include <osmo-bts/phy_link.h>
 #include <osmo-bts/handover.h>
 #include <osmo-bts/l1sap.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 
 #include "l1_if.h"
 #include "femtobts.h"
diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c
index ea3dcfa..f068659 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -41,6 +41,7 @@
 #include <osmo-bts/amr.h>
 #include <osmo-bts/abis.h>
 #include <osmo-bts/scheduler.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 
 #include "l1_if.h"
 #include "trx_if.h"
diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c
index d4a38b6..bd04e18 100644
--- a/src/osmo-bts-trx/scheduler_trx.c
+++ b/src/osmo-bts-trx/scheduler_trx.c
@@ -43,6 +43,7 @@
 #include <osmo-bts/l1sap.h>
 #include <osmo-bts/scheduler.h>
 #include <osmo-bts/scheduler_backend.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 
 #include "l1_if.h"
 #include "trx_if.h"
diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index 1953f71..d59c293 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -44,6 +44,7 @@
 #include <osmo-bts/logging.h>
 #include <osmo-bts/bts.h>
 #include <osmo-bts/scheduler.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 
 #include "l1_if.h"
 #include "trx_if.h"
diff --git a/src/osmo-bts-virtual/l1_if.c b/src/osmo-bts-virtual/l1_if.c
index 8e84579..5f6f0c7 100644
--- a/src/osmo-bts-virtual/l1_if.c
+++ b/src/osmo-bts-virtual/l1_if.c
@@ -42,6 +42,8 @@
 #include <osmo-bts/amr.h>
 #include <osmo-bts/abis.h>
 #include <osmo-bts/scheduler.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
+
 #include "virtual_um.h"
 
 extern int vbts_sched_start(struct gsm_bts *bts);
diff --git a/src/osmo-bts-virtual/main.c b/src/osmo-bts-virtual/main.c
index fb5d357..7602a9d 100644
--- a/src/osmo-bts-virtual/main.c
+++ b/src/osmo-bts-virtual/main.c
@@ -46,6 +46,8 @@
 #include <osmo-bts/bts_model.h>
 #include <osmo-bts/l1sap.h>
 #include <osmo-bts/phy_link.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
+
 #include "virtual_um.h"
 #include "l1_if.h"
 
diff --git a/src/osmo-bts-virtual/scheduler_virtbts.c b/src/osmo-bts-virtual/scheduler_virtbts.c
index d3fdf1a..d45c729 100644
--- a/src/osmo-bts-virtual/scheduler_virtbts.c
+++ b/src/osmo-bts-virtual/scheduler_virtbts.c
@@ -42,6 +42,8 @@
 #include <osmo-bts/amr.h>
 #include <osmo-bts/scheduler.h>
 #include <osmo-bts/scheduler_backend.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
+
 #include "virtual_um.h"
 #include "l1_if.h"
 

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/18903
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I8f48f17e61c3b9b86342eaf5b8a2b1ac9758bde5
Gerrit-Change-Number: 18903
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200618/5b20bfd9/attachment.htm>


More information about the gerrit-log mailing list