Change in osmo-bsc[master]: Store GPRS MOs directly under BTS SiteMgr object

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
Tue Dec 1 16:29:05 UTC 2020


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


Change subject: Store GPRS MOs directly under BTS SiteMgr object
......................................................................

Store GPRS MOs directly under BTS SiteMgr object

The only real 1-1 relationship between BTS NM objects is the one between
GPRS Cell and BTS (which is actually a BTS cell).
In our current osmo-bts implementation we don't care much since we only
handle 1-cell BTSses, but let's make the data structure organization
more generic.

Implementation notes:
The gsm_bts_sm is moved to its own file, APIs to allocate are added and
the new public object is hooked correctly in the allocation process of
osmo-bsc.

Change-Id: I06461b7784fa2a78de37383406e35beae85fbad8
---
M include/osmocom/bsc/Makefile.am
M include/osmocom/bsc/bts.h
A include/osmocom/bsc/bts_sm.h
M include/osmocom/bsc/gsm_data.h
M src/ipaccess/Makefile.am
M src/osmo-bsc/Makefile.am
M src/osmo-bsc/abis_nm.c
M src/osmo-bsc/bsc_vty.c
M src/osmo-bsc/bts.c
M src/osmo-bsc/bts_ipaccess_nanobts.c
M src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
M src/osmo-bsc/bts_nokia_site.c
A src/osmo-bsc/bts_sm.c
M src/osmo-bsc/gsm_data.c
M src/osmo-bsc/nm_bb_transc_fsm.c
M src/osmo-bsc/nm_bts_fsm.c
M src/osmo-bsc/nm_bts_sm_fsm.c
M src/osmo-bsc/nm_channel_fsm.c
M src/osmo-bsc/osmo_bsc_main.c
M src/osmo-bsc/pcu_sock.c
M src/utils/Makefile.am
M tests/abis/Makefile.am
M tests/acc/Makefile.am
M tests/acc/acc_test.c
M tests/bsc/Makefile.am
M tests/gsm0408/Makefile.am
M tests/gsm0408/gsm0408_test.c
M tests/handover/Makefile.am
M tests/nanobts_omlattr/Makefile.am
M tests/nanobts_omlattr/nanobts_omlattr_test.c
30 files changed, 328 insertions(+), 196 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/23/21423/1

diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am
index 1f066b6..e2d5db8 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -11,6 +11,7 @@
 	bsc_subscr_conn_fsm.h \
 	bss.h \
 	bts.h \
+	bts_sm.h \
 	bts_trx.h \
 	bts_ipaccess_nanobts_omlattr.h \
 	chan_alloc.h \
diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h
index 22839d6..365b473 100644
--- a/include/osmocom/bsc/bts.h
+++ b/include/osmocom/bsc/bts.h
@@ -14,6 +14,7 @@
 
 #include "osmocom/bsc/gsm_data.h"
 #include "osmocom/bsc/bts_trx.h"
+#include "osmocom/bsc/bts_sm.h"
 
 enum bts_counter_id {
 	BTS_CTR_CHREQ_TOTAL,
@@ -197,17 +198,6 @@
 	uint8_t _features_data[MAX_BTS_FEATURES/8];
 };
 
-/* BTS Site Manager */
-struct gsm_bts_sm {
-	struct gsm_abis_mo mo;
-	/* nanoBTS and old versions of osmo-bts behaves this way due to
-	   broken FSMs not following TS 12.21: they never do
-	   Dependency->Offline transition, but they should be OPSTARTed
-	   nevertheless during Dependnecy state to work. This field is
-	   used by all dependent NM objects. */
-	bool peer_has_no_avstate_offline;
-};
-
 /* One BTS */
 struct gsm_bts {
 	/* list header in net->bts_list */
@@ -272,7 +262,7 @@
 	/* CCCH is on C0 */
 	struct gsm_bts_trx *c0;
 
-	struct gsm_bts_sm site_mgr;
+	struct gsm_bts_sm *site_mgr; /* backpointer */
 
 	/* bitmask of all SI that are present/valid in si_buf */
 	uint32_t si_valid;
@@ -354,18 +344,6 @@
 	/* Not entirely sure how ip.access specific this is */
 	struct {
 		enum bts_gprs_mode mode;
-		struct {
-			struct gsm_abis_mo mo;
-			uint16_t nsei;
-			uint8_t timer[7];
-		} nse;
-		struct {
-			struct gsm_abis_mo mo;
-			uint16_t bvci;
-			uint8_t timer[11];
-			struct gprs_rlc_cfg rlc_cfg;
-		} cell;
-		struct gsm_bts_gprs_nsvc nsvc[2];
 		uint8_t rac;
 		uint8_t net_ctrl_ord;
 		bool ctrl_ack_type_use_block;
@@ -574,11 +552,7 @@
 	return &lai;
 }
 
-static inline struct gsm_bts *gsm_bts_sm_get_bts(struct gsm_bts_sm *site_mgr) {
-	return (struct gsm_bts *)container_of(site_mgr, struct gsm_bts, site_mgr);
-}
-
-struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num);
+struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm, uint8_t bts_num);
 
 char *gsm_bts_name(const struct gsm_bts *bts);
 
diff --git a/include/osmocom/bsc/bts_sm.h b/include/osmocom/bsc/bts_sm.h
new file mode 100644
index 0000000..32c7c34
--- /dev/null
+++ b/include/osmocom/bsc/bts_sm.h
@@ -0,0 +1,80 @@
+/* BTS Site Manager */
+
+/* (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 <unistd.h>
+#include <stdint.h>
+
+#include "osmocom/bsc/gsm_data.h"
+
+struct gsm_bts;
+
+struct gsm_gprs_nse {
+	struct gsm_abis_mo mo;
+	uint16_t nsei;
+	uint8_t timer[7];
+};
+
+struct gsm_gprs_cell {
+	struct gsm_abis_mo mo;
+	uint16_t bvci;
+	uint8_t timer[11];
+	struct gprs_rlc_cfg rlc_cfg;
+};
+
+struct gsm_gprs_nsvc {
+	struct gsm_bts *bts;
+	/* data read via VTY config file, to configure the BTS
+	 * via OML from BSC */
+	int id;
+	uint16_t nsvci;
+	uint16_t local_port;	/* on the BTS */
+	struct osmo_sockaddr remote;
+	struct gsm_abis_mo mo;
+};
+
+
+/* BTS Site Manager */
+struct gsm_bts_sm {
+	struct gsm_bts *bts[1]; /* only one bts supported so far */
+	struct gsm_abis_mo mo;
+	/* nanoBTS and old versions of osmo-bts behaves this way due to
+	   broken FSMs not following TS 12.21: they never do
+	   Dependency->Offline transition, but they should be OPSTARTed
+	   nevertheless during Dependnecy state to work. This field is
+	   used by all dependent NM objects. */
+	bool peer_has_no_avstate_offline;
+	struct {
+		struct gsm_gprs_nse nse;
+		struct gsm_gprs_cell cell;
+		struct gsm_gprs_nsvc nsvc[2];
+	} gprs;
+};
+
+static inline struct gsm_bts *gsm_bts_sm_get_bts(struct gsm_bts_sm *site_mgr) {
+	return site_mgr->bts[0];
+}
+
+struct gsm_bts_sm *gsm_bts_sm_alloc(struct gsm_network *net, uint8_t bts_num);
+
+void gsm_bts_sm_mo_reset(struct gsm_bts_sm *bts_sm);
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index a5b5a50..d8f8be2 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -767,17 +767,6 @@
 	struct gsm_abis_mo mo;
 };
 
-struct gsm_bts_gprs_nsvc {
-	struct gsm_bts *bts;
-	/* data read via VTY config file, to configure the BTS
-	 * via OML from BSC */
-	int id;
-	uint16_t nsvci;
-	uint16_t local_port;	/* on the BTS */
-	struct osmo_sockaddr remote;
-	struct gsm_abis_mo mo;
-};
-
 enum gprs_rlc_par {
 	RLC_T3142,
 	RLC_T3169,
diff --git a/src/ipaccess/Makefile.am b/src/ipaccess/Makefile.am
index 1574a8b..c489e0a 100644
--- a/src/ipaccess/Makefile.am
+++ b/src/ipaccess/Makefile.am
@@ -47,6 +47,7 @@
 # FIXME: resolve the bogus dependencies patched around here:
 ipaccess_config_LDADD = \
 	$(top_builddir)/src/osmo-bsc/bts.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/abis_nm.o \
 	$(top_builddir)/src/osmo-bsc/acc.o \
@@ -72,6 +73,7 @@
 	$(top_builddir)/src/osmo-bsc/abis_nm.o \
 	$(top_builddir)/src/osmo-bsc/acc.o \
 	$(top_builddir)/src/osmo-bsc/bts.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/gsm_data.o \
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index 5739885..89f869d 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -52,6 +52,7 @@
 	bts_ipaccess_nanobts_omlattr.c \
 	bts_nokia_site.c \
 	bts_siemens_bs11.c \
+	bts_sm.c \
 	bts_sysmobts.c \
 	bts_unknown.c \
 	chan_alloc.c \
diff --git a/src/osmo-bsc/abis_nm.c b/src/osmo-bsc/abis_nm.c
index 73dc2d0..4d245e5 100644
--- a/src/osmo-bsc/abis_nm.c
+++ b/src/osmo-bsc/abis_nm.c
@@ -863,14 +863,14 @@
 		return false;
 
 	if (bts->gprs.mode != BTS_GPRS_NONE) {
-		if (bts->gprs.cell.mo.nm_state.administrative == NM_STATE_LOCKED)
+		if (bts->site_mgr->gprs.cell.mo.nm_state.administrative == NM_STATE_LOCKED)
 			return false;
 
-		if (bts->gprs.nse.mo.nm_state.administrative == NM_STATE_LOCKED)
+		if (bts->site_mgr->gprs.nse.mo.nm_state.administrative == NM_STATE_LOCKED)
 			return false;
 
-		if (bts->gprs.nsvc[0].mo.nm_state.administrative == NM_STATE_LOCKED &&
-		    bts->gprs.nsvc[1].mo.nm_state.administrative == NM_STATE_LOCKED)
+		if (bts->site_mgr->gprs.nsvc[0].mo.nm_state.administrative == NM_STATE_LOCKED &&
+		    bts->site_mgr->gprs.nsvc[1].mo.nm_state.administrative == NM_STATE_LOCKED)
 			return false;
 	}
 
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 846339d..3ee4c49 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -463,17 +463,17 @@
 	vty_out(vty, "  NM State: ");
 	net_dump_nmstate(vty, &bts->mo.nm_state);
 	vty_out(vty, "  Site Mgr NM State: ");
-	net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
+	net_dump_nmstate(vty, &bts->site_mgr->mo.nm_state);
 
 	if (bts->gprs.mode != BTS_GPRS_NONE) {
 		vty_out(vty, "  GPRS NSE: ");
-		net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
+		net_dump_nmstate(vty, &bts->site_mgr->gprs.nse.mo.nm_state);
 		vty_out(vty, "  GPRS CELL: ");
-		net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
+		net_dump_nmstate(vty, &bts->site_mgr->gprs.cell.mo.nm_state);
 		vty_out(vty, "  GPRS NSVC0: ");
-		net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
+		net_dump_nmstate(vty, &bts->site_mgr->gprs.nsvc[0].mo.nm_state);
 		vty_out(vty, "  GPRS NSVC1: ");
-		net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
+		net_dump_nmstate(vty, &bts->site_mgr->gprs.nsvc[1].mo.nm_state);
 	} else
 		vty_out(vty, "  GPRS: not configured%s", VTY_NEWLINE);
 
@@ -740,6 +740,7 @@
 static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
 {
 	unsigned int i;
+	struct gsm_bts_sm *bts_sm = bts->site_mgr;
 	vty_out(vty, "  gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
 		VTY_NEWLINE);
 	if (bts->gprs.mode == BTS_GPRS_NONE)
@@ -751,21 +752,21 @@
 		bts->gprs.net_ctrl_ord, VTY_NEWLINE);
 	if (!bts->gprs.ctrl_ack_type_use_block)
 		vty_out(vty, "  gprs control-ack-type-rach%s", VTY_NEWLINE);
-	vty_out(vty, "  gprs cell bvci %u%s", bts->gprs.cell.bvci,
+	vty_out(vty, "  gprs cell bvci %u%s", bts_sm->gprs.cell.bvci,
 		VTY_NEWLINE);
-	for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
+	for (i = 0; i < ARRAY_SIZE(bts_sm->gprs.cell.timer); i++)
 		vty_out(vty, "  gprs cell timer %s %u%s",
 			get_value_string(gprs_bssgp_cfg_strs, i),
-			bts->gprs.cell.timer[i], VTY_NEWLINE);
-	vty_out(vty, "  gprs nsei %u%s", bts->gprs.nse.nsei,
+			bts_sm->gprs.cell.timer[i], VTY_NEWLINE);
+	vty_out(vty, "  gprs nsei %u%s", bts_sm->gprs.nse.nsei,
 		VTY_NEWLINE);
-	for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
+	for (i = 0; i < ARRAY_SIZE(bts_sm->gprs.nse.timer); i++)
 		vty_out(vty, "  gprs ns timer %s %u%s",
 			get_value_string(gprs_ns_timer_strs, i),
-			bts->gprs.nse.timer[i], VTY_NEWLINE);
-	for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
-		struct gsm_bts_gprs_nsvc *nsvc =
-					&bts->gprs.nsvc[i];
+			bts_sm->gprs.nse.timer[i], VTY_NEWLINE);
+	for (i = 0; i < ARRAY_SIZE(bts_sm->gprs.nsvc); i++) {
+		struct gsm_gprs_nsvc *nsvc =
+					&bts_sm->gprs.nsvc[i];
 		struct osmo_sockaddr_str remote = {};
 		uint16_t port;
 
@@ -3173,7 +3174,7 @@
 
 	GPRS_CHECK_ENABLED(bts);
 
-	bts->gprs.cell.bvci = atoi(argv[0]);
+	bts->site_mgr->gprs.cell.bvci = atoi(argv[0]);
 
 	return CMD_SUCCESS;
 }
@@ -3190,7 +3191,7 @@
 
 	GPRS_CHECK_ENABLED(bts);
 
-	bts->gprs.nse.nsei = atoi(argv[0]);
+	bts->site_mgr->gprs.nse.nsei = atoi(argv[0]);
 
 	return CMD_SUCCESS;
 }
@@ -3211,7 +3212,7 @@
 
 	GPRS_CHECK_ENABLED(bts);
 
-	bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
+	bts->site_mgr->gprs.nsvc[idx].nsvci = atoi(argv[1]);
 
 	return CMD_SUCCESS;
 }
@@ -3231,7 +3232,7 @@
 
 	GPRS_CHECK_ENABLED(bts);
 
-	bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
+	bts->site_mgr->gprs.nsvc[idx].local_port = atoi(argv[1]);
 
 	return CMD_SUCCESS;
 }
@@ -3252,7 +3253,7 @@
 	GPRS_CHECK_ENABLED(bts);
 
 	/* sockaddr_in and sockaddr_in6 have the port at the same position */
-	bts->gprs.nsvc[idx].remote.u.sin.sin_port = htons(atoi(argv[1]));
+	bts->site_mgr->gprs.nsvc[idx].remote.u.sin.sin_port = htons(atoi(argv[1]));
 
 	return CMD_SUCCESS;
 }
@@ -3281,13 +3282,13 @@
 	}
 
 	/* Can't use osmo_sockaddr_str_to_sockaddr() because the port would be overriden */
-	bts->gprs.nsvc[idx].remote.u.sas.ss_family = remote.af;
+	bts->site_mgr->gprs.nsvc[idx].remote.u.sas.ss_family = remote.af;
 	switch (remote.af) {
 	case AF_INET:
-		osmo_sockaddr_str_to_in_addr(&remote, &bts->gprs.nsvc[idx].remote.u.sin.sin_addr);
+		osmo_sockaddr_str_to_in_addr(&remote, &bts->site_mgr->gprs.nsvc[idx].remote.u.sin.sin_addr);
 		break;
 	case AF_INET6:
-		osmo_sockaddr_str_to_in6_addr(&remote, &bts->gprs.nsvc[idx].remote.u.sin6.sin6_addr);
+		osmo_sockaddr_str_to_in6_addr(&remote, &bts->site_mgr->gprs.nsvc[idx].remote.u.sin6.sin6_addr);
 		break;
 	}
 
@@ -3321,10 +3322,10 @@
 
 	GPRS_CHECK_ENABLED(bts);
 
-	if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
+	if (idx < 0 || idx >= ARRAY_SIZE(bts->site_mgr->gprs.nse.timer))
 		return CMD_WARNING;
 
-	bts->gprs.nse.timer[idx] = val;
+	bts->site_mgr->gprs.nse.timer[idx] = val;
 
 	return CMD_SUCCESS;
 }
@@ -3357,10 +3358,10 @@
 
 	GPRS_CHECK_ENABLED(bts);
 
-	if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
+	if (idx < 0 || idx >= ARRAY_SIZE(bts->site_mgr->gprs.cell.timer))
 		return CMD_WARNING;
 
-	bts->gprs.cell.timer[idx] = val;
+	bts->site_mgr->gprs.cell.timer[idx] = val;
 
 	return CMD_SUCCESS;
 }
diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c
index 065b8ab..b7d64c6 100644
--- a/src/osmo-bsc/bts.c
+++ b/src/osmo-bsc/bts.c
@@ -121,38 +121,9 @@
 	return 0;
 }
 
-static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
-static const uint8_t bts_cell_timer_default[] =
-				{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
-static const struct gprs_rlc_cfg rlc_cfg_default = {
-	.parameter = {
-		[RLC_T3142] = 20,
-		[RLC_T3169] = 5,
-		[RLC_T3191] = 5,
-		[RLC_T3193] = 160, /* 10ms */
-		[RLC_T3195] = 5,
-		[RLC_N3101] = 10,
-		[RLC_N3103] = 4,
-		[RLC_N3105] = 8,
-		[CV_COUNTDOWN] = 15,
-		[T_DL_TBF_EXT] = 250 * 10, /* ms */
-		[T_UL_TBF_EXT] = 250 * 10, /* ms */
-	},
-	.paging = {
-		.repeat_time = 5 * 50, /* ms */
-		.repeat_count = 3,
-	},
-	.cs_mask = 0x1fff,
-	.initial_cs = 2,
-	.initial_mcs = 6,
-};
-
 static int gsm_bts_talloc_destructor(struct gsm_bts *bts)
 {
-	if (bts->site_mgr.mo.fi) {
-		osmo_fsm_inst_free(bts->site_mgr.mo.fi);
-		bts->site_mgr.mo.fi = NULL;
-	}
+	bts->site_mgr->bts[0] = NULL;
 	if (bts->mo.fi) {
 		osmo_fsm_inst_free(bts->mo.fi);
 		bts->mo.fi = NULL;
@@ -164,9 +135,9 @@
  * This part is shared among the thin programs in osmo-bsc/src/utils/.
  * osmo-bsc requires further initialization that pulls in more dependencies (see
  * bsc_bts_alloc_register()). */
-struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num)
+struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm, uint8_t bts_num)
 {
-	struct gsm_bts *bts = talloc_zero(net, struct gsm_bts);
+	struct gsm_bts *bts = talloc_zero(bts_sm, struct gsm_bts);
 	struct gsm48_multi_rate_conf mr_cfg;
 	int i;
 
@@ -182,36 +153,13 @@
 
 	bts->ms_max_power = 15;	/* dBm */
 
-	bts->site_mgr.mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts, &bts->site_mgr,
-						  LOGL_INFO, NULL);
-	osmo_fsm_inst_update_id_f(bts->site_mgr.mo.fi, "bts_sm");
-	gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
+	bts->site_mgr = bts_sm;
 
 	bts->mo.fi = osmo_fsm_inst_alloc(&nm_bts_fsm, bts, bts,
 					      LOGL_INFO, NULL);
 	osmo_fsm_inst_update_id_f(bts->mo.fi, "bts%d", bts->nr);
 	gsm_mo_init(&bts->mo, bts, NM_OC_BTS, bts->nr, 0xff, 0xff);
 
-	for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
-		bts->gprs.nsvc[i].bts = bts;
-		bts->gprs.nsvc[i].id = i;
-		gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
-				bts->nr, i, 0xff);
-	}
-	memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
-		sizeof(bts->gprs.nse.timer));
-	gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
-			bts->nr, 0xff, 0xff);
-	memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
-		sizeof(bts->gprs.cell.timer));
-	gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
-			bts->nr, 0xff, 0xff);
-	memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
-		sizeof(bts->gprs.cell.rlc_cfg));
-
-	/* 3GPP TS 08.18, chapter 5.4.1: 0 is reserved for signalling */
-	bts->gprs.cell.bvci = 2;
-
 	/* init statistics */
 	bts->bts_ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);
 	if (!bts->bts_ctrs) {
@@ -589,11 +537,6 @@
 	unsigned int i;
 
 	gsm_abis_mo_reset(&bts->mo);
-	gsm_abis_mo_reset(&bts->site_mgr.mo);
-	for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++)
-		gsm_abis_mo_reset(&bts->gprs.nsvc[i].mo);
-	gsm_abis_mo_reset(&bts->gprs.nse.mo);
-	gsm_abis_mo_reset(&bts->gprs.cell.mo);
 
 	llist_for_each_entry(trx, &bts->trx_list, list) {
 		gsm_abis_mo_reset(&trx->mo);
diff --git a/src/osmo-bsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c
index f9dc8b3..49ae5db 100644
--- a/src/osmo-bsc/bts_ipaccess_nanobts.c
+++ b/src/osmo-bsc/bts_ipaccess_nanobts.c
@@ -133,7 +133,7 @@
 	struct gsm_bts_trx *trx;
 	struct gsm_bts_bb_trx *bb_transc;
 	struct gsm_bts_trx_ts *ts;
-	struct gsm_bts_gprs_nsvc *nsvc;
+	struct gsm_gprs_nsvc *nsvc;
 
 	struct msgb *msgb;
 
@@ -174,7 +174,8 @@
 		osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_STATE_CHG_REP, nsd);
 		break;
 	case NM_OC_GPRS_NSE:
-		bts = container_of(obj, struct gsm_bts, gprs.nse);
+		bts_sm = container_of(obj, struct gsm_bts_sm, gprs.nse);
+		bts = bts_sm->bts[0];
 		if (bts->gprs.mode == BTS_GPRS_NONE)
 			break;
 		if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
@@ -190,7 +191,8 @@
 		}
 		break;
 	case NM_OC_GPRS_CELL:
-		bts = container_of(obj, struct gsm_bts, gprs.cell);
+		bts_sm = container_of(obj, struct gsm_bts_sm, gprs.cell);
+		bts = bts_sm->bts[0];
 		if (bts->gprs.mode == BTS_GPRS_NONE)
 			break;
 		if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
@@ -258,7 +260,7 @@
 
 	switch (foh->obj_class) {
 	case NM_OC_SITE_MANAGER:
-		osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SW_ACT_REP, NULL);
+		osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SW_ACT_REP, NULL);
 		break;
 	case NM_OC_BTS:
 		osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_SW_ACT_REP, NULL);
@@ -306,7 +308,7 @@
 
 	switch (foh->obj_class) {
 	case NM_OC_SITE_MANAGER:
-		osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_ACK, NULL);
+		osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OPSTART_ACK, NULL);
 		break;
 	case NM_OC_BTS:
 		osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL);
@@ -339,7 +341,7 @@
 
 	switch (foh->obj_class) {
 	case NM_OC_SITE_MANAGER:
-		osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_NACK, NULL);
+		osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OPSTART_NACK, NULL);
 		break;
 	case NM_OC_BTS:
 		osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL);
@@ -522,7 +524,7 @@
 		}
 	}
 
-	osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OML_DOWN, NULL);
+	osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OML_DOWN, NULL);
 	osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OML_DOWN, NULL);
 	gsm_bts_all_ts_dispatch(bts, TS_EV_OML_DOWN, NULL);
 
diff --git a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
index 6d64a4b..6a7de53 100644
--- a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
+++ b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
@@ -105,18 +105,19 @@
 {
 	struct msgb *msgb;
 	uint8_t buf[256];
+	struct gsm_bts_sm *bts_sm = bts->site_mgr;
 	msgb = msgb_alloc(1024, "nanobts_attr_bts");
 	if (!msgb)
 		return NULL;
 
 	/* NSEI 925 */
-	buf[0] = bts->gprs.nse.nsei >> 8;
-	buf[1] = bts->gprs.nse.nsei & 0xff;
+	buf[0] = bts_sm->gprs.nse.nsei >> 8;
+	buf[1] = bts_sm->gprs.nse.nsei & 0xff;
 	msgb_tl16v_put(msgb, NM_ATT_IPACC_NSEI, 2, buf);
 
 	/* all timers in seconds */
-	OSMO_ASSERT(ARRAY_SIZE(bts->gprs.nse.timer) < sizeof(buf));
-	memcpy(buf, bts->gprs.nse.timer, ARRAY_SIZE(bts->gprs.nse.timer));
+	OSMO_ASSERT(ARRAY_SIZE(bts_sm->gprs.nse.timer) < sizeof(buf));
+	memcpy(buf, bts_sm->gprs.nse.timer, ARRAY_SIZE(bts_sm->gprs.nse.timer));
 	msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_CFG, 7, buf);
 
 	/* all timers in seconds */
@@ -132,8 +133,8 @@
 	buf[9] = 10;	/* capability update timer (T5) */
 	buf[10] = 3;	/* capability update retries */
 
-	OSMO_ASSERT(ARRAY_SIZE(bts->gprs.cell.timer) < sizeof(buf));
-	memcpy(buf, bts->gprs.cell.timer, ARRAY_SIZE(bts->gprs.cell.timer));
+	OSMO_ASSERT(ARRAY_SIZE(bts_sm->gprs.cell.timer) < sizeof(buf));
+	memcpy(buf, bts_sm->gprs.cell.timer, ARRAY_SIZE(bts_sm->gprs.cell.timer));
 	msgb_tl16v_put(msgb, NM_ATT_IPACC_BSSGP_CFG, 11, buf);
 
 	return msgb;
@@ -143,6 +144,7 @@
 {
 	struct msgb *msgb;
 	uint8_t buf[256];
+	struct gsm_bts_sm *bts_sm = bts->site_mgr;
 	msgb = msgb_alloc(1024, "nanobts_attr_bts");
 	if (!msgb)
 		return NULL;
@@ -156,8 +158,8 @@
 	msgb_tl16v_put(msgb, NM_ATT_IPACC_GPRS_PAGING_CFG, 2, buf);
 
 	/* BVCI 925 */
-	buf[0] = bts->gprs.cell.bvci >> 8;
-	buf[1] = bts->gprs.cell.bvci & 0xff;
+	buf[0] = bts_sm->gprs.cell.bvci >> 8;
+	buf[1] = bts_sm->gprs.cell.bvci & 0xff;
 	msgb_tl16v_put(msgb, NM_ATT_IPACC_BVCI, 2, buf);
 
 	/* all timers in seconds, unless otherwise stated */
@@ -202,16 +204,17 @@
 {
 	struct msgb *msgb;
 	uint8_t buf[256];
+	struct gsm_bts_sm *bts_sm = bts->site_mgr;
 	msgb = msgb_alloc(1024, "nanobts_attr_bts");
 	if (!msgb)
 		return NULL;
 
 	/* 925 */
-	buf[0] = bts->gprs.nsvc[0].nsvci >> 8;
-	buf[1] = bts->gprs.nsvc[0].nsvci & 0xff;
+	buf[0] = bts_sm->gprs.nsvc[0].nsvci >> 8;
+	buf[1] = bts_sm->gprs.nsvc[0].nsvci & 0xff;
 	msgb_tl16v_put(msgb, NM_ATT_IPACC_NSVCI, 2, buf);
 
-	switch (bts->gprs.nsvc->remote.u.sa.sa_family) {
+	switch (bts_sm->gprs.nsvc->remote.u.sa.sa_family) {
 	case AF_INET6:
 		/* all fields are encoded in network byte order */
 		/* protocol family */
@@ -219,20 +222,20 @@
 		/* padding */
 		buf[1] = 0x00;
 		/* local udp port */
-		osmo_store16be(bts->gprs.nsvc[0].local_port, &buf[2]);
+		osmo_store16be(bts_sm->gprs.nsvc[0].local_port, &buf[2]);
 		/* remote udp port */
-		memcpy(&buf[4], &bts->gprs.nsvc[0].remote.u.sin6.sin6_port, sizeof(uint16_t));
+		memcpy(&buf[4], &bts_sm->gprs.nsvc[0].remote.u.sin6.sin6_port, sizeof(uint16_t));
 		/* remote ip address */
-		memcpy(&buf[6], &bts->gprs.nsvc[0].remote.u.sin6.sin6_addr, sizeof(struct in6_addr));
+		memcpy(&buf[6], &bts_sm->gprs.nsvc[0].remote.u.sin6.sin6_addr, sizeof(struct in6_addr));
 		msgb_tl16v_put(msgb, NM_ATT_OSMO_NS_LINK_CFG, 6 + sizeof(struct in6_addr), buf);
 		break;
 	case AF_INET:
 		/* remote udp port */
-		memcpy(&buf[0], &bts->gprs.nsvc[0].remote.u.sin.sin_port, sizeof(uint16_t));
+		memcpy(&buf[0], &bts_sm->gprs.nsvc[0].remote.u.sin.sin_port, sizeof(uint16_t));
 		/* remote ip address */
-		memcpy(&buf[2], &bts->gprs.nsvc[0].remote.u.sin.sin_addr, sizeof(struct in_addr));
+		memcpy(&buf[2], &bts_sm->gprs.nsvc[0].remote.u.sin.sin_addr, sizeof(struct in_addr));
 		/* local udp port */
-		osmo_store16be(bts->gprs.nsvc[0].local_port, &buf[6]);
+		osmo_store16be(bts_sm->gprs.nsvc[0].local_port, &buf[6]);
 		msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_LINK_CFG, 8, buf);
 		break;
 	default:
diff --git a/src/osmo-bsc/bts_nokia_site.c b/src/osmo-bsc/bts_nokia_site.c
index 2b6f918..3820ead 100644
--- a/src/osmo-bsc/bts_nokia_site.c
+++ b/src/osmo-bsc/bts_nokia_site.c
@@ -1452,7 +1452,7 @@
 	struct gsm_bts_trx *trx;
 
 	mo_ok(&bts->mo);
-	mo_ok(&bts->site_mgr.mo);
+	mo_ok(&bts->site_mgr->mo);
 
 	llist_for_each_entry(trx, &bts->trx_list, list) {
 		int i;
diff --git a/src/osmo-bsc/bts_sm.c b/src/osmo-bsc/bts_sm.c
new file mode 100644
index 0000000..96acff8
--- /dev/null
+++ b/src/osmo-bsc/bts_sm.c
@@ -0,0 +1,119 @@
+/* (C) 2008-2018 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2020 by sysmocom s.f.m.c. GmbH <info 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 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/>.
+ *
+ */
+
+#include <osmocom/gsm/abis_nm.h>
+
+#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/bts.h>
+#include <osmocom/bsc/debug.h>
+#include <osmocom/bsc/nm_common_fsm.h>
+
+static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
+static const uint8_t bts_cell_timer_default[] =
+				{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
+static const struct gprs_rlc_cfg rlc_cfg_default = {
+	.parameter = {
+		[RLC_T3142] = 20,
+		[RLC_T3169] = 5,
+		[RLC_T3191] = 5,
+		[RLC_T3193] = 160, /* 10ms */
+		[RLC_T3195] = 5,
+		[RLC_N3101] = 10,
+		[RLC_N3103] = 4,
+		[RLC_N3105] = 8,
+		[CV_COUNTDOWN] = 15,
+		[T_DL_TBF_EXT] = 250 * 10, /* ms */
+		[T_UL_TBF_EXT] = 250 * 10, /* ms */
+	},
+	.paging = {
+		.repeat_time = 5 * 50, /* ms */
+		.repeat_count = 3,
+	},
+	.cs_mask = 0x1fff,
+	.initial_cs = 2,
+	.initial_mcs = 6,
+};
+
+static int gsm_bts_sm_talloc_destructor(struct gsm_bts_sm *bts_sm)
+{
+	if (bts_sm->mo.fi) {
+		osmo_fsm_inst_free(bts_sm->mo.fi);
+		bts_sm->mo.fi = NULL;
+	}
+	return 0;
+}
+
+struct gsm_bts_sm *gsm_bts_sm_alloc(struct gsm_network *net, uint8_t bts_num)
+{
+	struct gsm_bts_sm *bts_sm = talloc_zero(net, struct gsm_bts_sm);
+	struct gsm_bts *bts;
+	int i;
+	if (!bts_sm)
+		return NULL;
+
+	talloc_set_destructor(bts_sm, gsm_bts_sm_talloc_destructor);
+	bts_sm->mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts_sm, bts_sm,
+					    LOGL_INFO, NULL);
+	osmo_fsm_inst_update_id_f(bts_sm->mo.fi, "bts_sm");
+
+	bts = gsm_bts_alloc(net, bts_sm, bts_num);
+	if (!bts) {
+		talloc_free(bts_sm);
+		return NULL;
+	}
+	bts_sm->bts[0] = bts;
+
+	gsm_mo_init(&bts_sm->mo, bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
+
+	for (i = 0; i < ARRAY_SIZE(bts_sm->gprs.nsvc); i++) {
+		bts_sm->gprs.nsvc[i].bts = bts;
+		bts_sm->gprs.nsvc[i].id = i;
+		gsm_mo_init(&bts_sm->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
+				bts->nr, i, 0xff);
+	}
+	memcpy(&bts_sm->gprs.nse.timer, bts_nse_timer_default,
+		sizeof(bts_sm->gprs.nse.timer));
+	gsm_mo_init(&bts_sm->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
+			bts->nr, 0xff, 0xff);
+	memcpy(&bts_sm->gprs.cell.timer, bts_cell_timer_default,
+		sizeof(bts_sm->gprs.cell.timer));
+	gsm_mo_init(&bts_sm->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
+			bts->nr, 0xff, 0xff);
+	memcpy(&bts_sm->gprs.cell.rlc_cfg, &rlc_cfg_default,
+		sizeof(bts_sm->gprs.cell.rlc_cfg));
+
+	/* 3GPP TS 08.18, chapter 5.4.1: 0 is reserved for signalling */
+	bts_sm->gprs.cell.bvci = 2;
+
+	return bts_sm;
+}
+
+void gsm_bts_sm_mo_reset(struct gsm_bts_sm *bts_sm)
+{
+	int i;
+	gsm_abis_mo_reset(&bts_sm->mo);
+
+	for (i = 0; i < ARRAY_SIZE(bts_sm->gprs.nsvc); i++)
+		gsm_abis_mo_reset(&bts_sm->gprs.nsvc[i].mo);
+	gsm_abis_mo_reset(&bts_sm->gprs.nse.mo);
+	gsm_abis_mo_reset(&bts_sm->gprs.cell.mo);
+
+	gsm_bts_mo_reset(bts_sm->bts[0]);
+}
diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
index 22616f3..3087c0c 100644
--- a/src/osmo-bsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -110,14 +110,16 @@
 					uint8_t bsic)
 {
 	struct gsm_bts_model *model = bts_model_find(type);
+	struct gsm_bts_sm *bts_sm;
 	struct gsm_bts *bts;
 
 	if (!model && type != GSM_BTS_TYPE_UNKNOWN)
 		return NULL;
 
-	bts = gsm_bts_alloc(net, net->num_bts);
-	if (!bts)
+	bts_sm = gsm_bts_sm_alloc(net, net->num_bts);
+	if (!bts_sm)
 		return NULL;
+	bts = bts_sm->bts[0];
 
 	net->num_bts++;
 
@@ -378,7 +380,7 @@
 		mo = &trx->ts[obj_inst->ts_nr].mo;
 		break;
 	case NM_OC_SITE_MANAGER:
-		mo = &bts->site_mgr.mo;
+		mo = &bts->site_mgr->mo;
 		break;
 	case NM_OC_BS11:
 		switch (obj_inst->bts_nr) {
@@ -410,15 +412,15 @@
 		mo = &bts->bs11.envabtse[obj_inst->trx_nr].mo;
 		break;
 	case NM_OC_GPRS_NSE:
-		mo = &bts->gprs.nse.mo;
+		mo = &bts->site_mgr->gprs.nse.mo;
 		break;
 	case NM_OC_GPRS_CELL:
-		mo = &bts->gprs.cell.mo;
+		mo = &bts->site_mgr->gprs.cell.mo;
 		break;
 	case NM_OC_GPRS_NSVC:
-		if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc))
+		if (obj_inst->trx_nr >= ARRAY_SIZE(bts->site_mgr->gprs.nsvc))
 			return NULL;
-		mo = &bts->gprs.nsvc[obj_inst->trx_nr].mo;
+		mo = &bts->site_mgr->gprs.nsvc[obj_inst->trx_nr].mo;
 		break;
 	}
 	return mo;
@@ -474,18 +476,18 @@
 		obj = &trx->ts[obj_inst->ts_nr];
 		break;
 	case NM_OC_SITE_MANAGER:
-		obj = &bts->site_mgr;
+		obj = bts->site_mgr;
 		break;
 	case NM_OC_GPRS_NSE:
-		obj = &bts->gprs.nse;
+		obj = &bts->site_mgr->gprs.nse;
 		break;
 	case NM_OC_GPRS_CELL:
-		obj = &bts->gprs.cell;
+		obj = &bts->site_mgr->gprs.cell;
 		break;
 	case NM_OC_GPRS_NSVC:
-		if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc))
+		if (obj_inst->trx_nr >= ARRAY_SIZE(bts->site_mgr->gprs.nsvc))
 			return NULL;
-		obj = &bts->gprs.nsvc[obj_inst->trx_nr];
+		obj = &bts->site_mgr->gprs.nsvc[obj_inst->trx_nr];
 		break;
 	}
 	return obj;
diff --git a/src/osmo-bsc/nm_bb_transc_fsm.c b/src/osmo-bsc/nm_bb_transc_fsm.c
index c29f53d..e7132e8 100644
--- a/src/osmo-bsc/nm_bb_transc_fsm.c
+++ b/src/osmo-bsc/nm_bb_transc_fsm.c
@@ -113,7 +113,7 @@
 	struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
 	struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
 
-	if (trx->bts->site_mgr.peer_has_no_avstate_offline) {
+	if (trx->bts->site_mgr->peer_has_no_avstate_offline) {
 		nm_bb_transc_fsm_state_chg(fi, NM_BB_TRANSC_ST_OP_DISABLED_OFFLINE);
 		return;
 	}
@@ -187,7 +187,7 @@
 		case NM_AVSTATE_DEPENDENCY:
 			/* There's no point in moving back to Dependency, since it's broken
 			   and it acts actually as if it was in Offline state */
-			if (!trx->bts->site_mgr.peer_has_no_avstate_offline) {
+			if (!trx->bts->site_mgr->peer_has_no_avstate_offline) {
 				nm_bb_transc_fsm_state_chg(fi, NM_BB_TRANSC_ST_OP_DISABLED_DEPENDENCY);
 			} else {
 				/* Moreover, in nanoBTS we need to check here for tx
diff --git a/src/osmo-bsc/nm_bts_fsm.c b/src/osmo-bsc/nm_bts_fsm.c
index 5f47fdc..6c577bd 100644
--- a/src/osmo-bsc/nm_bts_fsm.c
+++ b/src/osmo-bsc/nm_bts_fsm.c
@@ -119,7 +119,7 @@
 	/* nanoBTS is broken, doesn't follow TS 12.21. Opstart MUST be sent
 	   during Dependency, so we simply move to OFFLINE state here to avoid
 	   duplicating code */
-	if (bts->site_mgr.peer_has_no_avstate_offline) {
+	if (bts->site_mgr->peer_has_no_avstate_offline) {
 		nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_DISABLED_OFFLINE);
 		return;
 	}
@@ -202,7 +202,7 @@
 		case NM_AVSTATE_DEPENDENCY:
 			/* There's no point in moving back to Dependency, since it's broken
 			   and it acts actually as if it was in Offline state */
-			if (!bts->site_mgr.peer_has_no_avstate_offline) {
+			if (!bts->site_mgr->peer_has_no_avstate_offline) {
 				nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_DISABLED_DEPENDENCY);
 			} else {
 				/* Moreover, in nanoBTS we need to check here for tx
diff --git a/src/osmo-bsc/nm_bts_sm_fsm.c b/src/osmo-bsc/nm_bts_sm_fsm.c
index ce9e15b..e5b5a3c 100644
--- a/src/osmo-bsc/nm_bts_sm_fsm.c
+++ b/src/osmo-bsc/nm_bts_sm_fsm.c
@@ -78,7 +78,7 @@
 					 "have your .cfg with 'type nanobts'. Otherwise, you probably "
 					 "are using an old osmo-bts; automatically adjusting OML "
 					 "behavior to be backward-compatible.\n");
-				bts->site_mgr.peer_has_no_avstate_offline = true;
+				site_mgr->peer_has_no_avstate_offline = true;
 			}
 			nm_bts_sm_fsm_state_chg(fi, NM_BTS_SM_ST_OP_ENABLED);
 			return;
diff --git a/src/osmo-bsc/nm_channel_fsm.c b/src/osmo-bsc/nm_channel_fsm.c
index 676c471..620051a 100644
--- a/src/osmo-bsc/nm_channel_fsm.c
+++ b/src/osmo-bsc/nm_channel_fsm.c
@@ -125,7 +125,7 @@
 {
 	struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv;
 
-	if (ts->trx->bts->site_mgr.peer_has_no_avstate_offline) {
+	if (ts->trx->bts->site_mgr->peer_has_no_avstate_offline) {
 		nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_DISABLED_OFFLINE);
 		return;
 	}
@@ -208,7 +208,7 @@
 		case NM_AVSTATE_DEPENDENCY:
 			/* There's no point in moving back to Dependency, since it's broken
 			   and it acts actually as if it was in Offline state */
-			if (!ts->trx->bts->site_mgr.peer_has_no_avstate_offline) {
+			if (!ts->trx->bts->site_mgr->peer_has_no_avstate_offline) {
 				nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_DISABLED_DEPENDENCY);
 			} else {
 				/* Moreover, in nanoBTS we need to check here for tx
diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c
index cc02c71..3be8593 100644
--- a/src/osmo-bsc/osmo_bsc_main.c
+++ b/src/osmo-bsc/osmo_bsc_main.c
@@ -424,7 +424,7 @@
 				osmo_timer_del(&trx->bts->cbch_timer);
 		}
 
-		gsm_bts_mo_reset(trx->bts);
+		gsm_bts_sm_mo_reset(trx->bts->site_mgr);
 
 		abis_nm_clear_queue(trx->bts);
 		break;
@@ -529,7 +529,7 @@
 	/* ACC ramping is initialized from vty/config */
 
 	/* Initialize the BTS state */
-	gsm_bts_mo_reset(bts);
+	gsm_bts_sm_mo_reset(bts->site_mgr);
 
 	return 0;
 }
diff --git a/src/osmo-bsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c
index 541fc84..3ffee3c 100644
--- a/src/osmo-bsc/pcu_sock.c
+++ b/src/osmo-bsc/pcu_sock.c
@@ -46,6 +46,7 @@
 #include <osmocom/bsc/abis_rsl.h>
 #include <osmocom/bsc/gsm_04_08_rr.h>
 #include <osmocom/bsc/bts.h>
+#include <osmocom/bsc/bts_sm.h>
 
 static int pcu_sock_send(struct gsm_bts *bts, struct msgb *msg);
 uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx);
@@ -115,17 +116,21 @@
 	struct gsm_pcu_if *pcu_prim;
 	struct gsm_pcu_if_info_ind *info_ind;
 	struct gprs_rlc_cfg *rlcc;
-	struct gsm_bts_gprs_nsvc *nsvc;
+	struct gsm_bts_sm *bts_sm;
+	struct gsm_gprs_nsvc *nsvc;
 	struct gsm_bts_trx *trx;
 	struct gsm_bts_trx_ts *ts;
 	int i, tn;
 
 	OSMO_ASSERT(bts);
 	OSMO_ASSERT(bts->network);
+	OSMO_ASSERT(bts->site_mgr);
+
+	bts_sm = bts->site_mgr;
 
 	LOGP(DPCU, LOGL_INFO, "Sending info for BTS %d\n",bts->nr);
 
-	rlcc = &bts->gprs.cell.rlc_cfg;
+	rlcc = &bts_sm->gprs.cell.rlc_cfg;
 
 	msg = pcu_msgb_alloc(PCU_IF_MSG_INFO_IND, bts->nr);
 	if (!msg)
@@ -147,15 +152,15 @@
 	info_ind->rac = bts->gprs.rac;
 
 	/* NSE */
-	info_ind->nsei = bts->gprs.nse.nsei;
-	memcpy(info_ind->nse_timer, bts->gprs.nse.timer, 7);
-	memcpy(info_ind->cell_timer, bts->gprs.cell.timer, 11);
+	info_ind->nsei = bts_sm->gprs.nse.nsei;
+	memcpy(info_ind->nse_timer, bts_sm->gprs.nse.timer, 7);
+	memcpy(info_ind->cell_timer, bts_sm->gprs.cell.timer, 11);
 
 	/* cell attributes */
 	info_ind->cell_id = bts->cell_identity;
 	info_ind->repeat_time = rlcc->paging.repeat_time;
 	info_ind->repeat_count = rlcc->paging.repeat_count;
-	info_ind->bvci = bts->gprs.cell.bvci;
+	info_ind->bvci = bts_sm->gprs.cell.bvci;
 	info_ind->t3142 = rlcc->parameter[RLC_T3142];
 	info_ind->t3169 = rlcc->parameter[RLC_T3169];
 	info_ind->t3191 = rlcc->parameter[RLC_T3191];
@@ -202,7 +207,7 @@
 
 	/* NSVC */
 	for (i = 0; i < ARRAY_SIZE(info_ind->nsvci); i++) {
-		nsvc = &bts->gprs.nsvc[i];
+		nsvc = &bts->site_mgr->gprs.nsvc[i];
 
 		info_ind->nsvci[i] = nsvc->nsvci;
 		info_ind->local_port[i] = nsvc->local_port;
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
index 65fd8fa..dfc68c5 100644
--- a/src/utils/Makefile.am
+++ b/src/utils/Makefile.am
@@ -50,6 +50,7 @@
 	$(top_builddir)/src/osmo-bsc/abis_nm.o \
 	$(top_builddir)/src/osmo-bsc/acc.o \
 	$(top_builddir)/src/osmo-bsc/bts.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/bts_siemens_bs11.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
@@ -130,6 +131,7 @@
 	$(top_builddir)/src/osmo-bsc/abis_nm.o \
 	$(top_builddir)/src/osmo-bsc/acc.o \
 	$(top_builddir)/src/osmo-bsc/bts.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/gsm_data.o \
diff --git a/tests/abis/Makefile.am b/tests/abis/Makefile.am
index d7d53b7..681e35a 100644
--- a/tests/abis/Makefile.am
+++ b/tests/abis/Makefile.am
@@ -29,6 +29,7 @@
 	$(top_builddir)/src/osmo-bsc/acc.o \
 	$(top_builddir)/src/osmo-bsc/bts.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/gsm_data.o \
 	$(top_builddir)/src/osmo-bsc/net_init.o \
diff --git a/tests/acc/Makefile.am b/tests/acc/Makefile.am
index b1315e3..1536365 100644
--- a/tests/acc/Makefile.am
+++ b/tests/acc/Makefile.am
@@ -28,6 +28,7 @@
 	$(top_builddir)/src/osmo-bsc/abis_nm.o \
 	$(top_builddir)/src/osmo-bsc/acc.o \
 	$(top_builddir)/src/osmo-bsc/bts.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/gsm_data.o \
diff --git a/tests/acc/acc_test.c b/tests/acc/acc_test.c
index 81b9e8d..73757c7 100644
--- a/tests/acc/acc_test.c
+++ b/tests/acc/acc_test.c
@@ -44,7 +44,8 @@
 #define bts_init(net) _bts_init(net, __func__)
 static inline struct gsm_bts *_bts_init(struct gsm_network *net, const char *msg)
 {
-	struct gsm_bts *bts = gsm_bts_alloc(net, 0);
+	struct gsm_bts_sm *bts_sm = gsm_bts_sm_alloc(net, 0);
+	struct gsm_bts *bts = bts_sm->bts[0];
 	if (!bts) {
 		fprintf(stderr, "BTS allocation failure in %s()\n", msg);
 		exit(1);
@@ -66,7 +67,7 @@
 	if (osmo_timer_pending(&bts->acc_ramp.step_timer))
 		osmo_timer_del(&bts->acc_ramp.step_timer);
 	/* no need to llist_del(&bts->list), we never registered the bts there. */
-	talloc_free(bts);
+	talloc_free(bts->site_mgr);
 	fprintf(stderr, "BTS deallocated OK in %s()\n", msg);
 }
 
diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am
index f040cbc..02842eb 100644
--- a/tests/bsc/Makefile.am
+++ b/tests/bsc/Makefile.am
@@ -39,6 +39,7 @@
 	$(top_builddir)/src/osmo-bsc/osmo_bsc_filter.o \
 	$(top_builddir)/src/osmo-bsc/bsc_subscriber.o \
 	$(top_builddir)/src/osmo-bsc/bts.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/gsm_data.o \
diff --git a/tests/gsm0408/Makefile.am b/tests/gsm0408/Makefile.am
index de38747..c04a5ae 100644
--- a/tests/gsm0408/Makefile.am
+++ b/tests/gsm0408/Makefile.am
@@ -29,6 +29,7 @@
 	$(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \
 	$(top_builddir)/src/osmo-bsc/bts.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/gsm_data.o \
 	$(top_builddir)/src/osmo-bsc/net_init.o \
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index 8ee29f7..c23b262 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -123,7 +123,8 @@
 #define bts_init(net) _bts_init(net, __func__)
 static inline struct gsm_bts *_bts_init(struct gsm_network *net, const char *msg)
 {
-	struct gsm_bts *bts = gsm_bts_alloc(net, 0);
+	struct gsm_bts_sm *bts_sm = gsm_bts_sm_alloc(net, 0);
+	struct gsm_bts *bts = bts_sm->bts[0];
 	if (!bts) {
 		printf("BTS allocation failure in %s()\n", msg);
 		exit(1);
@@ -143,7 +144,7 @@
 	if (osmo_timer_pending(&bts->acc_mgr.rotate_timer))
 		osmo_timer_del(&bts->acc_mgr.rotate_timer);
 	/* no need to llist_del(&bts->list), we never registered the bts there. */
-	talloc_free(bts);
+	talloc_free(bts->site_mgr);
 	printf("BTS deallocated OK in %s()\n", msg);
 }
 
diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am
index 42bb937..02fcdc1 100644
--- a/tests/handover/Makefile.am
+++ b/tests/handover/Makefile.am
@@ -58,6 +58,7 @@
 	$(top_builddir)/src/osmo-bsc/bsc_subscriber.o \
 	$(top_builddir)/src/osmo-bsc/bsc_vty.o \
 	$(top_builddir)/src/osmo-bsc/bts.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
diff --git a/tests/nanobts_omlattr/Makefile.am b/tests/nanobts_omlattr/Makefile.am
index 3dd7f2f..29097b8 100644
--- a/tests/nanobts_omlattr/Makefile.am
+++ b/tests/nanobts_omlattr/Makefile.am
@@ -27,6 +27,7 @@
 	$(top_builddir)/src/osmo-bsc/acc.o \
 	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
 	$(top_builddir)/src/osmo-bsc/bts.o \
+	$(top_builddir)/src/osmo-bsc/bts_sm.o \
 	$(top_builddir)/src/osmo-bsc/bts_trx.o \
 	$(top_builddir)/src/osmo-bsc/gsm_data.o \
 	$(top_builddir)/src/osmo-bsc/nm_common_fsm.o \
diff --git a/tests/nanobts_omlattr/nanobts_omlattr_test.c b/tests/nanobts_omlattr/nanobts_omlattr_test.c
index da220c1..eb74832 100644
--- a/tests/nanobts_omlattr/nanobts_omlattr_test.c
+++ b/tests/nanobts_omlattr/nanobts_omlattr_test.c
@@ -243,7 +243,7 @@
 	};
 
 	/* Parameters needed to test nanobts_attr_nse_get() */
-	bts->gprs.nse.nsei = 101;
+	bts->site_mgr->gprs.nse.nsei = 101;
 	uint8_t attr_nse_expected[] =
 	    { 0x9d, 0x00, 0x02, 0x00, 0x65, 0xa0, 0x00, 0x07, 0x03, 0x03, 0x03,
 		0x03, 0x1e, 0x03, 0x0a, 0xa1, 0x00, 0x0b, 0x03, 0x03, 0x03,
@@ -253,7 +253,7 @@
 
 	/* Parameters needed to test nanobts_attr_cell_get() */
 	bts->gprs.rac = 0x00;
-	bts->gprs.cell.bvci = 2;
+	bts->site_mgr->gprs.cell.bvci = 2;
 	bts->gprs.mode = BTS_GPRS_GPRS;
 	uint8_t attr_cell_expected[] =
 	    { 0x9a, 0x00, 0x01, 0x00, 0x9c, 0x00, 0x02, 0x05, 0x03, 0x9e, 0x00,
@@ -266,9 +266,9 @@
 	/* Parameters needed to test nanobts_attr_nscv_get() */
 	struct osmo_sockaddr_str addr;
 	osmo_sockaddr_str_from_str(&addr, "10.9.1.101", 23000);
-	osmo_sockaddr_str_to_sockaddr(&addr, &bts->gprs.nsvc[0].remote.u.sas);
-	bts->gprs.nsvc[0].nsvci = 0x65;
-	bts->gprs.nsvc[0].local_port = 0x5a3c;
+	osmo_sockaddr_str_to_sockaddr(&addr, &bts->site_mgr->gprs.nsvc[0].remote.u.sas);
+	bts->site_mgr->gprs.nsvc[0].nsvci = 0x65;
+	bts->site_mgr->gprs.nsvc[0].local_port = 0x5a3c;
 	uint8_t attr_nscv_expected[] =
 	    { 0x9f, 0x00, 0x02, 0x00, 0x65, 0xa2, 0x00, 0x08, 0x59, 0xd8, 0x0a,
 		0x09, 0x01, 0x65, 0x5a, 0x3c
@@ -291,9 +291,9 @@
 	/* NSVC IPv6 test */
 	struct osmo_sockaddr_str addr6;
 	osmo_sockaddr_str_from_str(&addr6, "fd00:5678:9012:3456:7890:1234:5678:9012", 23010);
-	osmo_sockaddr_str_to_sockaddr(&addr6, &bts->gprs.nsvc[0].remote.u.sas);
-	bts->gprs.nsvc[0].nsvci = 0x65;
-	bts->gprs.nsvc[0].local_port = 0x5a3c;
+	osmo_sockaddr_str_to_sockaddr(&addr6, &bts->site_mgr->gprs.nsvc[0].remote.u.sas);
+	bts->site_mgr->gprs.nsvc[0].nsvci = 0x65;
+	bts->site_mgr->gprs.nsvc[0].local_port = 0x5a3c;
 	uint8_t attr_nscv6_expected[] =
 	      /*                             |- oml attr  |-16bit length */
 	    { 0x9f, 0x00, 0x02, 0x00, 0x65, 0xfd, 0x00, 0x16,

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

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I06461b7784fa2a78de37383406e35beae85fbad8
Gerrit-Change-Number: 21423
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/20201201/5e97e693/attachment.htm>


More information about the gerrit-log mailing list