aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2020-10-02 17:06:45 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2020-10-02 19:40:11 +0200
commita97941aaca7b12f98633a3a97fd71f48b082d591 (patch)
tree2cd3935823f29c0d818ea40ffe5b6f5fd35e430c
parent396cb163e6f85ef56ed26fbf9bfcdd0edb577457 (diff)
Introduce NM BTS Site Manager FSM
This fixes old behavior mimicing broken behavior in nanoBTS (according to TS 12.21) where BTS Site Mgr NM object was announced as Enabled despite no OPSTART was sent by the BSC. With this new FSM, BTS SiteManager will be announced as Disabled Offline during OML startup conversation, instead of Enabled. The new osmo-bsc OML management FSMs use this change in behavior to find out whether it should use the old broken management states (without Offline state, as per nanoBTS) or use the new state transitions (which allow fixing several race conditions). Change-Id: Iab2d17c45c9642860cd2d5d523c1baae24502243
-rw-r--r--include/osmo-bts/Makefile.am1
-rw-r--r--include/osmo-bts/bts.h3
-rw-r--r--include/osmo-bts/nm_bts_sm_fsm.h40
-rw-r--r--src/common/Makefile.am1
-rw-r--r--src/common/bts.c15
-rw-r--r--src/common/nm_bts_sm_fsm.c152
-rw-r--r--src/common/oml.c2
-rw-r--r--src/osmo-bts-litecell15/oml.c5
-rw-r--r--src/osmo-bts-oc2g/oml.c5
-rw-r--r--src/osmo-bts-octphy/l1_oml.c5
-rw-r--r--src/osmo-bts-omldummy/bts_model.c5
-rw-r--r--src/osmo-bts-sysmo/oml.c5
-rw-r--r--src/osmo-bts-trx/l1_if.c5
-rw-r--r--src/osmo-bts-virtual/bts_model.c5
14 files changed, 236 insertions, 13 deletions
diff --git a/include/osmo-bts/Makefile.am b/include/osmo-bts/Makefile.am
index cdbaa4f9..c03cf3cc 100644
--- a/include/osmo-bts/Makefile.am
+++ b/include/osmo-bts/Makefile.am
@@ -27,4 +27,5 @@ noinst_HEADERS = \
phy_link.h \
dtx_dl_amr_fsm.h \
ta_control.h \
+ nm_bts_sm_fsm.h \
$(NULL)
diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h
index ffaeb577..191feb92 100644
--- a/include/osmo-bts/bts.h
+++ b/include/osmo-bts/bts.h
@@ -145,6 +145,9 @@ struct gsm_bts {
struct gsm_bts_trx *c0;
struct {
+ /* NM BTS Site Manager FSM */
+ struct osmo_fsm_inst *fi;
+ bool opstart_success;
struct gsm_abis_mo mo;
} site_mgr;
diff --git a/include/osmo-bts/nm_bts_sm_fsm.h b/include/osmo-bts/nm_bts_sm_fsm.h
new file mode 100644
index 00000000..552d2891
--- /dev/null
+++ b/include/osmo-bts/nm_bts_sm_fsm.h
@@ -0,0 +1,40 @@
+/* NM BTS Site Manager FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21:
+ GSM 12.21 Objects' Operational state and availability status behaviour during initialization */
+
+/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin@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>
+
+enum nm_bts_sm_op_fsm_states {
+ NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED,
+ NM_BTS_SM_ST_OP_DISABLED_OFFLINE,
+ NM_BTS_SM_ST_OP_ENABLED,
+};
+
+enum nm_bts_sm_op_fsm_events {
+ NM_BTS_SM_EV_SW_ACT,
+ NM_BTS_SM_EV_OPSTART_ACK,
+ NM_BTS_SM_EV_OPSTART_NACK,
+};
+
+extern struct osmo_fsm nm_bts_sm_fsm;
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index e3a72dc8..67243746 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -37,6 +37,7 @@ libbts_a_SOURCES = \
dtx_dl_amr_fsm.c \
scheduler_mframe.c \
ta_control.c \
+ nm_bts_sm_fsm.c \
$(NULL)
libl1sched_a_SOURCES = scheduler.c
diff --git a/src/common/bts.c b/src/common/bts.c
index c900428c..34a6be27 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -52,6 +52,7 @@
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/cbch.h>
#include <osmo-bts/bts_shutdown_fsm.h>
+#include <osmo-bts/nm_bts_sm_fsm.h>
#define MIN_QUAL_RACH 50 /* minimum link quality (in centiBels) for Access Bursts */
#define MIN_QUAL_NORM -5 /* minimum link quality (in centiBels) for Normal Bursts */
@@ -219,10 +220,14 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
LOGL_INFO, NULL);
osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr);
+ bts->site_mgr.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts, bts,
+ LOGL_INFO, NULL);
+ osmo_fsm_inst_update_id_f(bts->site_mgr.fi, "bts_sm%d", bts->nr);
+ gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
+ 0xff, 0xff, 0xff);
+
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,
- 0xff, 0xff, 0xff);
for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
bts->gprs.nsvc[i].bts = bts;
@@ -327,7 +332,7 @@ int bts_init(struct gsm_bts *bts)
bts->radio_link_timeout = 32;
/* Start with the site manager */
- oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
+ oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
/* set BTS to dependency */
oml_mo_state_init(&bts->mo, -1, NM_AVSTATE_DEPENDENCY);
@@ -390,8 +395,8 @@ int bts_link_estab(struct gsm_bts *bts)
LOGP(DSUM, LOGL_INFO, "Main link established, sending NM Status.\n");
- /* BTS and SITE MGR are EANBLED, BTS is DEPENDENCY */
- oml_tx_state_changed(&bts->site_mgr.mo);
+ /* BTS SITE MGR becomes Offline (tx SW ACT Report), BTS is DEPENDENCY */
+ osmo_fsm_inst_dispatch(bts->site_mgr.fi, NM_BTS_SM_EV_SW_ACT, NULL);
oml_tx_state_changed(&bts->mo);
/* those should all be in DEPENDENCY */
diff --git a/src/common/nm_bts_sm_fsm.c b/src/common/nm_bts_sm_fsm.c
new file mode 100644
index 00000000..74f7a8cc
--- /dev/null
+++ b/src/common/nm_bts_sm_fsm.c
@@ -0,0 +1,152 @@
+/* NM BTS Site Manager FSM */
+
+/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin@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 <errno.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/tdef.h>
+#include <osmocom/gsm/protocol/gsm_12_21.h>
+
+#include <osmo-bts/logging.h>
+#include <osmo-bts/gsm_data.h>
+#include <osmo-bts/bts_model.h>
+#include <osmo-bts/bts.h>
+#include <osmo-bts/rsl.h>
+#include <osmo-bts/nm_bts_sm_fsm.h>
+#include <osmo-bts/phy_link.h>
+
+#define X(s) (1 << (s))
+
+#define nm_bts_sm_fsm_state_chg(fi, NEXT_STATE) \
+ osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0)
+
+//////////////////////////
+// FSM STATE ACTIONS
+//////////////////////////
+
+static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
+ bts->site_mgr.opstart_success = false;
+ oml_mo_state_chg(&bts->site_mgr.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
+}
+
+static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
+
+ switch (event) {
+ case NM_BTS_SM_EV_SW_ACT:
+ oml_mo_tx_sw_act_rep(&bts->site_mgr.mo);
+ nm_bts_sm_fsm_state_chg(fi, NM_BTS_SM_ST_OP_DISABLED_OFFLINE);
+ return;
+ default:
+ OSMO_ASSERT(0);
+ }
+}
+
+static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
+ bts->site_mgr.opstart_success = false;
+ oml_mo_state_chg(&bts->site_mgr.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
+}
+
+static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
+
+ switch (event) {
+ case NM_BTS_SM_EV_OPSTART_ACK:
+ bts->site_mgr.opstart_success = true;
+ oml_mo_opstart_ack(&bts->site_mgr.mo);
+ nm_bts_sm_fsm_state_chg(fi, NM_BTS_SM_ST_OP_ENABLED);
+ break; /* check statechg below */
+ case NM_BTS_SM_EV_OPSTART_NACK:
+ bts->site_mgr.opstart_success = false;
+ oml_mo_opstart_nack(&bts->site_mgr.mo, (int)(intptr_t)data);
+ return;
+ default:
+ OSMO_ASSERT(0);
+ }
+}
+
+static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
+ oml_mo_state_chg(&bts->site_mgr.mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
+}
+
+static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+}
+
+static struct osmo_fsm_state nm_bts_sm_fsm_states[] = {
+ [NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED] = {
+ .in_event_mask =
+ X(NM_BTS_SM_EV_SW_ACT),
+ .out_state_mask =
+ X(NM_BTS_SM_ST_OP_DISABLED_OFFLINE),
+ .name = "DISABLED_NOTINSTALLED",
+ .onenter = st_op_disabled_notinstalled_on_enter,
+ .action = st_op_disabled_notinstalled,
+ },
+ [NM_BTS_SM_ST_OP_DISABLED_OFFLINE] = {
+ .in_event_mask =
+ X(NM_BTS_SM_EV_OPSTART_ACK) |
+ X(NM_BTS_SM_EV_OPSTART_NACK),
+ .out_state_mask =
+ X(NM_BTS_SM_ST_OP_ENABLED),
+ .name = "DISABLED_OFFLINE",
+ .onenter = st_op_disabled_offline_on_enter,
+ .action = st_op_disabled_offline,
+ },
+ [NM_BTS_SM_ST_OP_ENABLED] = {
+ .in_event_mask = 0,
+ .out_state_mask = 0,
+ .name = "ENABLED",
+ .onenter = st_op_enabled_on_enter,
+ .action = st_op_enabled,
+ },
+};
+
+const struct value_string nm_bts_sm_fsm_event_names[] = {
+ { NM_BTS_SM_EV_SW_ACT, "SW_ACT" },
+ { NM_BTS_SM_EV_OPSTART_ACK, "OPSTART_ACK" },
+ { NM_BTS_SM_EV_OPSTART_NACK, "OPSTART_NACK" },
+ { 0, NULL }
+};
+
+struct osmo_fsm nm_bts_sm_fsm = {
+ .name = "NM_BTS_SM_OP",
+ .states = nm_bts_sm_fsm_states,
+ .num_states = ARRAY_SIZE(nm_bts_sm_fsm_states),
+ .event_names = nm_bts_sm_fsm_event_names,
+ .log_subsys = DOML,
+};
+
+static __attribute__((constructor)) void nm_bts_sm_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&nm_bts_sm_fsm) == 0);
+}
diff --git a/src/common/oml.c b/src/common/oml.c
index 14fc80f3..fd4aed85 100644
--- a/src/common/oml.c
+++ b/src/common/oml.c
@@ -1621,7 +1621,7 @@ gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
obj = &trx->ts[obj_inst->ts_nr];
break;
case NM_OC_SITE_MANAGER:
- obj = &bts->site_mgr;
+ obj = bts;
break;
case NM_OC_GPRS_NSE:
obj = &bts->gprs.nse;
diff --git a/src/osmo-bts-litecell15/oml.c b/src/osmo-bts-litecell15/oml.c
index 194ba7f7..366e8da6 100644
--- a/src/osmo-bts-litecell15/oml.c
+++ b/src/osmo-bts-litecell15/oml.c
@@ -42,6 +42,7 @@
#include <osmo-bts/phy_link.h>
#include <osmo-bts/handover.h>
#include <osmo-bts/l1sap.h>
+#include <osmo-bts/nm_bts_sm_fsm.h>
#include "l1_if.h"
#include "lc15bts.h"
@@ -1887,6 +1888,9 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
int rc;
switch (mo->obj_class) {
+ case NM_OC_SITE_MANAGER:
+ rc = osmo_fsm_inst_dispatch(bts->site_mgr.fi, NM_BTS_SM_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_RADIO_CARRIER:
rc = trx_init(obj);
break;
@@ -1894,7 +1898,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
rc = ts_opstart(obj);
break;
case NM_OC_BTS:
- case NM_OC_SITE_MANAGER:
case NM_OC_BASEB_TRANSC:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
diff --git a/src/osmo-bts-oc2g/oml.c b/src/osmo-bts-oc2g/oml.c
index 695850c8..798be8f3 100644
--- a/src/osmo-bts-oc2g/oml.c
+++ b/src/osmo-bts-oc2g/oml.c
@@ -42,6 +42,7 @@
#include <osmo-bts/phy_link.h>
#include <osmo-bts/handover.h>
#include <osmo-bts/l1sap.h>
+#include <osmo-bts/nm_bts_sm_fsm.h>
#include "l1_if.h"
#include "oc2gbts.h"
@@ -1896,6 +1897,9 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
int rc;
switch (mo->obj_class) {
+ case NM_OC_SITE_MANAGER:
+ rc = osmo_fsm_inst_dispatch(bts->site_mgr.fi, NM_BTS_SM_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_RADIO_CARRIER:
rc = trx_init(obj);
break;
@@ -1903,7 +1907,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
rc = ts_opstart(obj);
break;
case NM_OC_BTS:
- case NM_OC_SITE_MANAGER:
case NM_OC_BASEB_TRANSC:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c
index 7c203eb7..1d34378f 100644
--- a/src/osmo-bts-octphy/l1_oml.c
+++ b/src/osmo-bts-octphy/l1_oml.c
@@ -38,6 +38,7 @@
#include <osmo-bts/bts.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/l1sap.h>
+#include <osmo-bts/nm_bts_sm_fsm.h>
#include "l1_if.h"
#include "l1_oml.h"
@@ -1766,6 +1767,9 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
struct gsm_bts_trx_ts *ts;
switch (mo->obj_class) {
+ case NM_OC_SITE_MANAGER:
+ rc = osmo_fsm_inst_dispatch(bts->site_mgr.fi, NM_BTS_SM_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_RADIO_CARRIER:
rc = trx_init(obj);
break;
@@ -1774,7 +1778,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
rc = ts_connect_as(ts, ts->pchan, pchan_act_compl_cb, NULL);
break;
case NM_OC_BTS:
- case NM_OC_SITE_MANAGER:
case NM_OC_BASEB_TRANSC:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
diff --git a/src/osmo-bts-omldummy/bts_model.c b/src/osmo-bts-omldummy/bts_model.c
index 01b78d4d..7ac93918 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/nm_bts_sm_fsm.h>
/* TODO: check if dummy method is sufficient, else implement */
int bts_model_lchan_deactivate(struct gsm_lchan *lchan)
@@ -129,6 +130,9 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
uint8_t tn;
switch (mo->obj_class) {
+ case NM_OC_SITE_MANAGER:
+ rc = osmo_fsm_inst_dispatch(bts->site_mgr.fi, NM_BTS_SM_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_RADIO_CARRIER:
trx = (struct gsm_bts_trx*) obj;
/* Mark Dependency TS as Offline (ready to be Opstarted) */
@@ -142,7 +146,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
rc = oml_mo_opstart_ack(mo);
break;
case NM_OC_CHANNEL:
- case NM_OC_SITE_MANAGER:
case NM_OC_BASEB_TRANSC:
case NM_OC_BTS:
case NM_OC_GPRS_NSE:
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index cc53d72f..f58a0e6b 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/nm_bts_sm_fsm.h>
#include "l1_if.h"
#include "femtobts.h"
@@ -1773,6 +1774,9 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
int rc;
switch (mo->obj_class) {
+ case NM_OC_SITE_MANAGER:
+ rc = osmo_fsm_inst_dispatch(bts->site_mgr.fi, NM_BTS_SM_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_RADIO_CARRIER:
rc = trx_init(obj);
break;
@@ -1780,7 +1784,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
rc = ts_opstart(obj);
break;
case NM_OC_BTS:
- case NM_OC_SITE_MANAGER:
case NM_OC_BASEB_TRANSC:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c
index 8ad004e4..c19a1a6c 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -44,6 +44,7 @@
#include <osmo-bts/abis.h>
#include <osmo-bts/scheduler.h>
#include <osmo-bts/pcu_if.h>
+#include <osmo-bts/nm_bts_sm_fsm.h>
#include "l1_if.h"
#include "trx_if.h"
@@ -616,13 +617,15 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
int rc;
switch (mo->obj_class) {
+ case NM_OC_SITE_MANAGER:
+ rc = osmo_fsm_inst_dispatch(bts->site_mgr.fi, NM_BTS_SM_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_RADIO_CARRIER:
/* activate transceiver */
rc = trx_init(obj);
break;
case NM_OC_CHANNEL:
case NM_OC_BTS:
- case NM_OC_SITE_MANAGER:
case NM_OC_BASEB_TRANSC:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
diff --git a/src/osmo-bts-virtual/bts_model.c b/src/osmo-bts-virtual/bts_model.c
index 74ad31d0..47f0ba29 100644
--- a/src/osmo-bts-virtual/bts_model.c
+++ b/src/osmo-bts-virtual/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/nm_bts_sm_fsm.h>
#include "virtual_um.h"
@@ -143,6 +144,9 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
uint8_t tn;
switch (mo->obj_class) {
+ case NM_OC_SITE_MANAGER:
+ rc = osmo_fsm_inst_dispatch(bts->site_mgr.fi, NM_BTS_SM_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_RADIO_CARRIER:
trx = (struct gsm_bts_trx*) obj;
/* Mark Dependency TS as Offline (ready to be Opstarted) */
@@ -156,7 +160,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
rc = oml_mo_opstart_ack(mo);
break;
case NM_OC_CHANNEL:
- case NM_OC_SITE_MANAGER:
case NM_OC_BASEB_TRANSC:
case NM_OC_BTS:
case NM_OC_GPRS_NSE: