Change in osmo-bsc[master]: dissolve libbsc: move all to src/osmo-bsc, link .o files

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/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Thu Jun 7 01:01:42 UTC 2018


Neels Hofmeyr has uploaded this change for review. ( https://gerrit.osmocom.org/9481


Change subject: dissolve libbsc: move all to src/osmo-bsc, link .o files
......................................................................

dissolve libbsc: move all to src/osmo-bsc, link .o files

Move all of libbsc/ into osmo-bsc/, and separate/move some implementations to
allow linking from utils/* and ipaccess/* without pulling in unccessary
dependencies.

Some utilities use gsm_network and gsm_bts structs, which already include data
structures for fairly advanced uses. Move initialization that only osmo-bsc
needs into new bsc_network_init() and bsc_bts_alloc_register() functions, so
that the leaner tools can use the old gsm_* versions without the need to link
everything (e.g. handover and lchan alloc code).

In some instances, there need to be stubs if to cut off linking "just before
the RSL level" and prevent dependencies from creeping in.
- abis_rsl_rcvmsg(): the only program currently interpreting RSL messages is
  osmo-bsc, the utils are merely concerned with OML, if at all.
- paging_flush_bts(): ip.access nanobts models call this when the RSL link is
  dropped. Only osmo-bsc actually needs to do anything there.
- on_gsm_ts_init(): the mechanism to trigger timeslot initialization is related
  to OML, while this action to take on init would pull in RSL dependencies.
utils/ and ipaccess/ each have a stubs.c file to implement these stubs. Tests
implement stubs inline where required.

>From src/utils/, src/ipaccess/ and tests/*/, link in .o files from osmo-bsc/.
In order for this to work, the osmo-bsc subdir must be built before the other
source trees. (An alternative would be to include the .c files as sources, but
that would re-compile them in every source tree. Not a large burden really, but
unless linking .o files gives problems, let's have the quicker build.)

Minor obvious cleanups creep in with this patch, I will not bother to name them
individually now unless code review asks me to.

Rationale:

1) libbsc has been separate to use it for osmo-nitb and osmo-bsc in the old
openbsc.git. This is no longer required, and spreading over libbsc and osmo-bsc
is distracting.

2) Recently, ridiculous linking requirements have made adding new functions
cumbersome, because libbsc has started depending on osmo-bsc/*.c
implementations: on gscon FSM and bssap functions. For example, neither
bs11_config nor ipaccess-config nor bts_test need handover_cfg or BSSMAP
message composition. It makes no sense to link the entire osmo-bsc to it, nor
do we want to keep adding stubs to each linking realm.

Change-Id: I36a586726f5818121abe54d25654819fc451d3bf
---
M configure.ac
M include/osmocom/bsc/Makefile.am
M include/osmocom/bsc/bss.h
M include/osmocom/bsc/chan_alloc.h
D include/osmocom/bsc/common_bsc.h
M include/osmocom/bsc/gsm_data.h
M src/Makefile.am
M src/ipaccess/Makefile.am
M src/ipaccess/ipaccess-config.c
A src/ipaccess/stubs.c
D src/libbsc/Makefile.am
D src/libbsc/bsc_init.c
D src/libbsc/net_init.c
M src/osmo-bsc/Makefile.am
R src/osmo-bsc/a_reset.c
A src/osmo-bsc/abis_bs11.c
R src/osmo-bsc/abis_nm.c
R src/osmo-bsc/abis_nm_ipaccess.c
R src/osmo-bsc/abis_nm_vty.c
R src/osmo-bsc/abis_om2000.c
R src/osmo-bsc/abis_om2000_vty.c
R src/osmo-bsc/abis_rsl.c
R src/osmo-bsc/acc_ramp.c
R src/osmo-bsc/arfcn_range_encode.c
R src/osmo-bsc/bsc_api.c
R src/osmo-bsc/bsc_ctrl_commands.c
R src/osmo-bsc/bsc_ctrl_lookup.c
R src/osmo-bsc/bsc_dyn_ts.c
A src/osmo-bsc/bsc_init.c
R src/osmo-bsc/bsc_rf_ctrl.c
R src/osmo-bsc/bsc_rll.c
R src/osmo-bsc/bsc_subscr_conn_fsm.c
R src/osmo-bsc/bsc_subscriber.c
R src/osmo-bsc/bsc_vty.c
R src/osmo-bsc/bts_ericsson_rbs2000.c
R src/osmo-bsc/bts_init.c
R src/osmo-bsc/bts_ipaccess_nanobts.c
R src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
R src/osmo-bsc/bts_nokia_site.c
R src/osmo-bsc/bts_siemens_bs11.c
R src/osmo-bsc/bts_sysmobts.c
R src/osmo-bsc/bts_unknown.c
R src/osmo-bsc/chan_alloc.c
R src/osmo-bsc/e1_config.c
R src/osmo-bsc/gsm_04_08_utils.c
R src/osmo-bsc/gsm_04_80_utils.c
R src/osmo-bsc/gsm_data.c
R src/osmo-bsc/handover_cfg.c
R src/osmo-bsc/handover_decision.c
R src/osmo-bsc/handover_decision_2.c
R src/osmo-bsc/handover_logic.c
R src/osmo-bsc/handover_vty.c
R src/osmo-bsc/meas_feed.c
R src/osmo-bsc/meas_rep.c
A src/osmo-bsc/net_init.c
R src/osmo-bsc/osmo_bsc_lcls.c
M src/osmo-bsc/osmo_bsc_main.c
R src/osmo-bsc/paging.c
R src/osmo-bsc/pcu_sock.c
R src/osmo-bsc/penalty_timers.c
R src/osmo-bsc/rest_octets.c
R src/osmo-bsc/system_information.c
M src/utils/Makefile.am
M src/utils/bs11_config.c
A src/utils/stubs.c
M tests/abis/Makefile.am
M tests/abis/abis_test.c
M tests/bsc/Makefile.am
M tests/bsc/bsc_test.c
M tests/bssap/Makefile.am
M tests/bssap/bssap_test.c
M tests/channel/Makefile.am
M tests/channel/channel_test.c
M tests/gsm0408/Makefile.am
M tests/gsm0408/gsm0408_test.c
M tests/handover/Makefile.am
M tests/handover/handover_test.c
M tests/nanobts_omlattr/Makefile.am
M tests/nanobts_omlattr/nanobts_omlattr_test.c
M tests/subscr/Makefile.am
80 files changed, 1,118 insertions(+), 935 deletions(-)



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

diff --git a/configure.ac b/configure.ac
index bcf890c..f07c756 100644
--- a/configure.ac
+++ b/configure.ac
@@ -168,7 +168,6 @@
     include/osmocom/Makefile
     include/osmocom/bsc/Makefile
     src/Makefile
-    src/libbsc/Makefile
     src/libfilter/Makefile
     src/osmo-bsc/Makefile
     src/ipaccess/Makefile
diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am
index 0987be9..5fa39eb 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -12,7 +12,6 @@
 	bss.h \
 	bts_ipaccess_nanobts_omlattr.h \
 	chan_alloc.h \
-	common_bsc.h \
 	ctrl.h \
 	debug.h \
 	e1_config.h \
diff --git a/include/osmocom/bsc/bss.h b/include/osmocom/bsc/bss.h
index 9891f5f..ecb68d6 100644
--- a/include/osmocom/bsc/bss.h
+++ b/include/osmocom/bsc/bss.h
@@ -7,7 +7,6 @@
 
 /* start and stop network */
 extern int bsc_network_alloc(void);
-extern int bsc_network_configure(const char *cfg_file);
 extern int bsc_shutdown_net(struct gsm_network *net);
 
 /* register all supported BTS */
diff --git a/include/osmocom/bsc/chan_alloc.h b/include/osmocom/bsc/chan_alloc.h
index 98568a5..f3aec9d 100644
--- a/include/osmocom/bsc/chan_alloc.h
+++ b/include/osmocom/bsc/chan_alloc.h
@@ -45,7 +45,6 @@
 void network_chan_load(struct pchan_load *pl, struct gsm_network *net);
 void bts_update_t3122_chan_load(struct gsm_bts *bts);
 
-bool trx_is_usable(const struct gsm_bts_trx *trx);
 bool ts_is_usable(const struct gsm_bts_trx_ts *ts);
 
 #endif /* _CHAN_ALLOC_H */
diff --git a/include/osmocom/bsc/common_bsc.h b/include/osmocom/bsc/common_bsc.h
deleted file mode 100644
index c23d20c..0000000
--- a/include/osmocom/bsc/common_bsc.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-
-struct gsm_network *bsc_network_init(void *ctx);
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index b1fceb3..a8d1f92 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -997,6 +997,8 @@
 };
 
 
+struct gsm_network *gsm_network_init(void *ctx);
+
 struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num);
 struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
 
@@ -1378,9 +1380,8 @@
 struct gsm_subscriber_connection *msc_subscr_con_allocate(struct gsm_network *network);
 void msc_subscr_con_free(struct gsm_subscriber_connection *conn);
 
-struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net,
-					enum gsm_bts_type type,
-					uint8_t bsic);
+struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type, uint8_t bsic);
+struct gsm_bts *bsc_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type, uint8_t bsic);
 
 void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
 		   uint8_t e1_ts, uint8_t e1_ts_ss);
@@ -1418,4 +1419,8 @@
 void gsm_trx_mark_all_ts_uninitialized(struct gsm_bts_trx *trx);
 void gsm_bts_mark_all_ts_uninitialized(struct gsm_bts *bts);
 
+bool trx_is_usable(const struct gsm_bts_trx *trx);
+
+bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts);
+
 #endif /* _GSM_DATA_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index fc9bf8e..6c63eea 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,15 +19,9 @@
 	$(COVERAGE_LDFLAGS) \
 	$(NULL)
 
-# Libraries
 SUBDIRS = \
-	libbsc \
 	libfilter \
-	$(NULL)
-
-# Programs
-SUBDIRS += \
+	osmo-bsc \
 	utils \
 	ipaccess \
-	osmo-bsc \
 	$(NULL)
diff --git a/src/ipaccess/Makefile.am b/src/ipaccess/Makefile.am
index 0f9045f..2c6282d 100644
--- a/src/ipaccess/Makefile.am
+++ b/src/ipaccess/Makefile.am
@@ -33,31 +33,37 @@
 	$(NULL)
 
 abisip_find_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
 	$(OSMO_LIBS) \
 	$(NULL)
 
 abisip_find_SOURCES = \
 	abisip-find.c \
+	stubs.c \
 	$(NULL)
 
 ipaccess_config_SOURCES = \
 	ipaccess-config.c \
 	ipaccess-firmware.c \
 	network_listen.c \
+	stubs.c \
 	$(NULL)
 
 # FIXME: resolve the bogus dependencies patched around here:
 ipaccess_config_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/abis_nm.o \
+	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts.o \
+	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
+	$(top_builddir)/src/osmo-bsc/net_init.o \
 	$(OSMO_LIBS) \
 	$(NULL)
 
 ipaccess_proxy_SOURCES = \
 	ipaccess-proxy.c \
+	stubs.c \
+	$(top_srcdir)/src/osmo-bsc/gsm_data.c \
 	$(NULL)
 
 ipaccess_proxy_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
 	$(OSMO_LIBS) \
 	$(NULL)
diff --git a/src/ipaccess/ipaccess-config.c b/src/ipaccess/ipaccess-config.c
index 2236063..079bae2 100644
--- a/src/ipaccess/ipaccess-config.c
+++ b/src/ipaccess/ipaccess-config.c
@@ -39,7 +39,6 @@
 #include <osmocom/core/select.h>
 #include <osmocom/core/timer.h>
 #include <osmocom/bsc/ipaccess.h>
-#include <osmocom/bsc/common_bsc.h>
 #include <osmocom/abis/e1_input.h>
 #include <osmocom/bsc/abis_nm.h>
 #include <osmocom/bsc/signal.h>
@@ -54,6 +53,7 @@
 #include <osmocom/core/talloc.h>
 #include <osmocom/abis/abis.h>
 #include <osmocom/gsm/protocol/gsm_12_21.h>
+#include <osmocom/bsc/bss.h>
 
 struct gsm_network *bsc_gsmnet;
 
@@ -873,8 +873,6 @@
 	print_value_string(&ipa_test_strs[0], ARRAY_SIZE(ipa_test_strs));
 }
 
-extern void bts_model_nanobts_init();
-
 static const struct log_info_cat log_categories[] = {
 	[DNM] = {
 		.name = "DNM",
@@ -898,6 +896,7 @@
 	int rc, option_index = 0, stream_id = 0xff;
 
 	tall_ctx_config = talloc_named_const(NULL, 0, "ipaccess-config");
+	tall_bsc_ctx = tall_ctx_config;
 	msgb_talloc_ctx_init(tall_ctx_config, 0);
 
 	osmo_init_logging2(tall_ctx_config, &log_info);
@@ -1034,7 +1033,7 @@
 
 	libosmo_abis_init(tall_ctx_config);
 
-	bsc_gsmnet = bsc_network_init(tall_bsc_ctx);
+	bsc_gsmnet = gsm_network_init(tall_ctx_config);
 	if (!bsc_gsmnet)
 		exit(1);
 
diff --git a/src/ipaccess/stubs.c b/src/ipaccess/stubs.c
new file mode 100644
index 0000000..c52d52b
--- /dev/null
+++ b/src/ipaccess/stubs.c
@@ -0,0 +1,43 @@
+/* Stubs required for linking */
+
+/* (C) 2018 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 <stdbool.h>
+struct gsm_bts;
+struct gsm_bts_trx_ts;
+struct msgb;
+struct bsc_msc_data;
+
+bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts)
+{
+	/* No TS init required here. */
+	return true;
+}
+
+int abis_rsl_rcvmsg(struct msgb *msg)
+{
+	/* No RSL handling here */
+	return 0;
+}
+
+void paging_flush_bts(struct gsm_bts *bts, struct bsc_msc_data *msc)
+{
+	/* No paging flushing */
+}
diff --git a/src/libbsc/Makefile.am b/src/libbsc/Makefile.am
deleted file mode 100644
index 2e44729..0000000
--- a/src/libbsc/Makefile.am
+++ /dev/null
@@ -1,70 +0,0 @@
-AM_CPPFLAGS = \
-	$(all_includes) \
-	-I$(top_srcdir)/include \
-	-I$(top_builddir) \
-	$(NULL)
-
-AM_CFLAGS = \
-	-Wall \
-	$(LIBOSMOCORE_CFLAGS) \
-	$(LIBOSMOGSM_CFLAGS) \
-	$(LIBOSMOVTY_CFLAGS) \
-	$(LIBOSMOABIS_CFLAGS) \
-	$(LIBOSMOMGCP_CFLAGS) \
-	$(LIBOSMOSIGTRAN_CFLAGS) \
-	$(COVERAGE_CFLAGS) \
-	$(LIBOSMOMGCPCLIENT_CFLAGS) \
-	$(NULL)
-
-noinst_LIBRARIES = \
-	libbsc.a \
-	$(NULL)
-
-libbsc_a_SOURCES = \
-	abis_nm.c \
-	abis_nm_vty.c \
-	abis_om2000.c \
-	abis_om2000_vty.c \
-	abis_rsl.c \
-	a_reset.c \
-	acc_ramp.c \
-	bsc_rll.c \
-	bsc_subscriber.c \
-	paging.c \
-	bts_ericsson_rbs2000.c \
-	bts_ipaccess_nanobts.c \
-	bts_siemens_bs11.c \
-	bts_nokia_site.c \
-	bts_unknown.c \
-	bts_sysmobts.c \
-	chan_alloc.c \
-	gsm_data.c \
-	handover_decision.c \
-	handover_logic.c \
-	meas_rep.c \
-	pcu_sock.c \
-	rest_octets.c \
-	system_information.c \
-	e1_config.c \
-	bsc_api.c \
-	bsc_vty.c \
-	gsm_04_08_utils.c \
-	gsm_04_80_utils.c \
-	bsc_init.c \
-	bts_init.c \
-	bsc_rf_ctrl.c \
-	arfcn_range_encode.c \
-	bsc_ctrl_commands.c \
-	bsc_ctrl_lookup.c \
-	net_init.c \
-	bsc_dyn_ts.c \
-	bts_ipaccess_nanobts_omlattr.c \
-	handover_vty.c \
-	handover_cfg.c \
-	penalty_timers.c \
-	handover_decision_2.c \
-	bsc_subscr_conn_fsm.c \
-	meas_feed.c \
-	osmo_bsc_lcls.c \
-	$(NULL)
-
diff --git a/src/libbsc/bsc_init.c b/src/libbsc/bsc_init.c
deleted file mode 100644
index 508a7f4..0000000
--- a/src/libbsc/bsc_init.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/* A hackish minimal BSC (+MSC +HLR) implementation */
-
-/* (C) 2008-2018 by Harald Welte <laforge at gnumonks.org>
- * (C) 2009 by Holger Hans Peter Freyther <zecke at selfish.org>
- * 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/bsc/gsm_data.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/bsc/abis_rsl.h>
-#include <osmocom/bsc/abis_nm.h>
-#include <osmocom/bsc/debug.h>
-#include <osmocom/bsc/misdn.h>
-#include <osmocom/vty/telnet_interface.h>
-#include <osmocom/vty/ports.h>
-#include <osmocom/bsc/system_information.h>
-#include <osmocom/bsc/paging.h>
-#include <osmocom/bsc/signal.h>
-#include <osmocom/bsc/chan_alloc.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/bsc/ipaccess.h>
-#include <osmocom/gsm/sysinfo.h>
-#include <osmocom/bsc/e1_config.h>
-#include <osmocom/bsc/common_bsc.h>
-#include <osmocom/bsc/pcu_if.h>
-
-#include <time.h>
-#include <limits.h>
-#include <stdbool.h>
-
-/* Callback function for NACK on the OML NM */
-static int oml_msg_nack(struct nm_nack_signal_data *nack)
-{
-	if (nack->mt == NM_MT_GET_ATTR_NACK) {
-		LOGP(DNM, LOGL_ERROR, "BTS%u does not support Get Attributes "
-		     "OML message.\n", nack->bts->nr);
-		return 0;
-	}
-
-	if (nack->mt == NM_MT_SET_BTS_ATTR_NACK)
-		LOGP(DNM, LOGL_ERROR, "Failed to set BTS attributes. That is fatal. "
-		     "Was the bts type and frequency properly specified?\n");
-	else
-		LOGP(DNM, LOGL_ERROR, "Got %s NACK going to drop the OML links.\n",
-		     abis_nm_nack_name(nack->mt));
-
-	if (!nack->bts) {
-		LOGP(DNM, LOGL_ERROR, "Unknown bts. Can not drop it.\n");
-		return 0;
-	}
-
-	if (is_ipaccess_bts(nack->bts))
-		ipaccess_drop_oml(nack->bts);
-
-	return 0;
-}
-
-/* Callback function to be called every time we receive a signal from NM */
-static int nm_sig_cb(unsigned int subsys, unsigned int signal,
-		     void *handler_data, void *signal_data)
-{
-	struct nm_nack_signal_data *nack;
-
-	switch (signal) {
-	case S_NM_NACK:
-		nack = signal_data;
-		return oml_msg_nack(nack);
-	default:
-		break;
-	}
-	return 0;
-}
-
-int bsc_shutdown_net(struct gsm_network *net)
-{
-	struct gsm_bts *bts;
-
-	llist_for_each_entry(bts, &net->bts_list, list) {
-		LOGP(DNM, LOGL_NOTICE, "shutting down OML for BTS %u\n", bts->nr);
-		osmo_signal_dispatch(SS_L_GLOBAL, S_GLOBAL_BTS_CLOSE_OM, bts);
-	}
-
-	return 0;
-}
-
-unsigned long long bts_uptime(const struct gsm_bts *bts)
-{
-	struct timespec tp;
-
-	if (!bts->uptime || !bts->oml_link) {
-		LOGP(DNM, LOGL_ERROR, "BTS %u OML link uptime unavailable\n", bts->nr);
-		return 0;
-	}
-
-	if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) {
-		LOGP(DNM, LOGL_ERROR, "BTS %u uptime computation failure: %s\n", bts->nr, strerror(errno));
-		return 0;
-	}
-
-	/* monotonic clock helps to ensure that the conversion is valid */
-	return difftime(tp.tv_sec, bts->uptime);
-}
-
-static int rsl_si(struct gsm_bts_trx *trx, enum osmo_sysinfo_type i, int si_len)
-{
-	struct gsm_bts *bts = trx->bts;
-	int rc, j;
-
-	if (si_len) {
-		DEBUGP(DRR, "SI%s: %s\n", get_value_string(osmo_sitype_strs, i),
-			osmo_hexdump(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN));
-	} else
-		DEBUGP(DRR, "SI%s: OFF\n", get_value_string(osmo_sitype_strs, i));
-
-	switch (i) {
-	case SYSINFO_TYPE_5:
-	case SYSINFO_TYPE_5bis:
-	case SYSINFO_TYPE_5ter:
-	case SYSINFO_TYPE_6:
-		rc = rsl_sacch_filling(trx, osmo_sitype2rsl(i),
-				       si_len ? GSM_BTS_SI(bts, i) : NULL, si_len);
-		break;
-	case SYSINFO_TYPE_2quater:
-		if (si_len == 0) {
-			rc = rsl_bcch_info(trx, i, NULL, 0);
-			break;
-		}
-		rc = 0;
-		for (j = 0; j <= bts->si2q_count; j++)
-			rc = rsl_bcch_info(trx, i, (const uint8_t *)GSM_BTS_SI2Q(bts, j), GSM_MACBLOCK_LEN);
-		break;
-	default:
-		rc = rsl_bcch_info(trx, i, si_len ? GSM_BTS_SI(bts, i) : NULL, si_len);
-		break;
-	}
-
-	return rc;
-}
-
-/* set all system information types for a TRX */
-int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx)
-{
-	int i, rc;
-	struct gsm_bts *bts = trx->bts;
-	uint8_t gen_si[_MAX_SYSINFO_TYPE], n_si = 0, n;
-	int si_len[_MAX_SYSINFO_TYPE];
-
-	bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
-			ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
-	bts->si_common.cell_sel_par.neci = bts->network->neci;
-
-	/* Zero/forget the state of the dynamically computed SIs, leeping the static ones */
-	bts->si_valid = bts->si_mode_static;
-
-	/* First, we determine which of the SI messages we actually need */
-
-	if (trx == bts->c0) {
-		/* 1...4 are always present on a C0 TRX */
-		gen_si[n_si++] = SYSINFO_TYPE_1;
-		gen_si[n_si++] = SYSINFO_TYPE_2;
-		gen_si[n_si++] = SYSINFO_TYPE_2bis;
-		gen_si[n_si++] = SYSINFO_TYPE_2ter;
-		gen_si[n_si++] = SYSINFO_TYPE_2quater;
-		gen_si[n_si++] = SYSINFO_TYPE_3;
-		gen_si[n_si++] = SYSINFO_TYPE_4;
-
-		/* 13 is always present on a C0 TRX of a GPRS BTS */
-		if (bts->gprs.mode != BTS_GPRS_NONE)
-			gen_si[n_si++] = SYSINFO_TYPE_13;
-	}
-
-	/* 5 and 6 are always present on every TRX */
-	gen_si[n_si++] = SYSINFO_TYPE_5;
-	gen_si[n_si++] = SYSINFO_TYPE_5bis;
-	gen_si[n_si++] = SYSINFO_TYPE_5ter;
-	gen_si[n_si++] = SYSINFO_TYPE_6;
-
-	/* Second, we generate the selected SI via RSL */
-
-	for (n = 0; n < n_si; n++) {
-		i = gen_si[n];
-		/* Only generate SI if this SI is not in "static" (user-defined) mode */
-		if (!(bts->si_mode_static & (1 << i))) {
-			/* Set SI as being valid. gsm_generate_si() might unset
-			 * it, if SI is not required. */
-			bts->si_valid |= (1 << i);
-			rc = gsm_generate_si(bts, i);
-			if (rc < 0)
-				goto err_out;
-			si_len[i] = rc;
-		} else {
-			if (i == SYSINFO_TYPE_5 || i == SYSINFO_TYPE_5bis
-			 || i == SYSINFO_TYPE_5ter)
-				si_len[i] = 18;
-			else if (i == SYSINFO_TYPE_6)
-				si_len[i] = 11;
-			else
-				si_len[i] = 23;
-		}
-	}
-
-	/* Third, we send the selected SI via RSL */
-
-	for (n = 0; n < n_si; n++) {
-		i = gen_si[n];
-		/* if we don't currently have this SI, we send a zero-length
-		 * RSL BCCH FILLING / SACCH FILLING * in order to deactivate
-		 * the SI, in case it might have previously been active */
-		if (!GSM_BTS_HAS_SI(bts, i))
-			rc = rsl_si(trx, i, 0);
-		else
-			rc = rsl_si(trx, i, si_len[i]);
-		if (rc < 0)
-			return rc;
-	}
-
-	/* Make sure the PCU is aware (in case anything GPRS related has
-	 * changed in SI */
-	pcu_info_update(bts);
-
-	return 0;
-err_out:
-	LOGP(DRR, LOGL_ERROR, "Cannot generate SI%s for BTS %u: error <%s>, "
-	     "most likely a problem with neighbor cell list generation\n",
-	     get_value_string(osmo_sitype_strs, i), bts->nr, strerror(-rc));
-	return rc;
-}
-
-/* set all system information types for a BTS */
-int gsm_bts_set_system_infos(struct gsm_bts *bts)
-{
-	struct gsm_bts_trx *trx;
-
-	/* Generate a new ID */
-	bts->bcch_change_mark += 1;
-	bts->bcch_change_mark %= 0x7;
-
-	llist_for_each_entry(trx, &bts->trx_list, list) {
-		int rc;
-
-		rc = gsm_bts_trx_set_system_infos(trx);
-		if (rc != 0)
-			return rc;
-	}
-
-	return 0;
-}
-
-/* Produce a MA as specified in 10.5.2.21 */
-static int generate_ma_for_ts(struct gsm_bts_trx_ts *ts)
-{
-	/* we have three bitvecs: the per-timeslot ARFCNs, the cell chan ARFCNs
-	 * and the MA */
-	struct bitvec *cell_chan = &ts->trx->bts->si_common.cell_alloc;
-	struct bitvec *ts_arfcn = &ts->hopping.arfcns;
-	struct bitvec *ma = &ts->hopping.ma;
-	unsigned int num_cell_arfcns, bitnum, n_chan;
-	int i;
-
-	/* re-set the MA to all-zero */
-	ma->cur_bit = 0;
-	ts->hopping.ma_len = 0;
-	memset(ma->data, 0, ma->data_len);
-
-	if (!ts->hopping.enabled)
-		return 0;
-
-	/* count the number of ARFCNs in the cell channel allocation */
-	num_cell_arfcns = 0;
-	for (i = 0; i < 1024; i++) {
-		if (bitvec_get_bit_pos(cell_chan, i))
-			num_cell_arfcns++;
-	}
-
-	/* pad it to octet-aligned number of bits */
-	ts->hopping.ma_len = num_cell_arfcns / 8;
-	if (num_cell_arfcns % 8)
-		ts->hopping.ma_len++;
-
-	n_chan = 0;
-	for (i = 0; i < 1024; i++) {
-		if (!bitvec_get_bit_pos(cell_chan, i))
-			continue;
-		/* set the corresponding bit in the MA */
-		bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
-		if (bitvec_get_bit_pos(ts_arfcn, i))
-			bitvec_set_bit_pos(ma, bitnum, 1);
-		else
-			bitvec_set_bit_pos(ma, bitnum, 0);
-		n_chan++;
-	}
-
-	/* ARFCN 0 is special: It is coded last in the bitmask */
-	if (bitvec_get_bit_pos(cell_chan, 0)) {
-		n_chan++;
-		/* set the corresponding bit in the MA */
-		bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
-		if (bitvec_get_bit_pos(ts_arfcn, 0))
-			bitvec_set_bit_pos(ma, bitnum, 1);
-		else
-			bitvec_set_bit_pos(ma, bitnum, 0);
-	}
-
-	return 0;
-}
-
-static void bootstrap_rsl(struct gsm_bts_trx *trx)
-{
-	unsigned int i;
-
-	LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
-		"on ARFCN %u using MCC-MNC %s LAC=%u CID=%u BSIC=%u\n",
-		trx->bts->nr, trx->nr, trx->arfcn,
-		osmo_plmn_name(&bsc_gsmnet->plmn),
-		trx->bts->location_area_code,
-		trx->bts->cell_identity, trx->bts->bsic);
-
-	if (trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE) {
-		rsl_nokia_si_begin(trx);
-	}
-
-	/*
-	 * Trigger ACC ramping before sending system information to BTS.
-	 * This ensures that RACH control in system information is configured correctly.
-	 * TRX 0 should be usable and unlocked, otherwise starting ACC ramping is pointless.
-	 */
-	if (trx_is_usable(trx) && trx->mo.nm_state.administrative == NM_STATE_UNLOCKED)
-		acc_ramp_trigger(&trx->bts->acc_ramp);
-
-	gsm_bts_trx_set_system_infos(trx);
-
-	if (trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE) {
-		/* channel unspecific, power reduction in 2 dB steps */
-		rsl_bs_power_control(trx, 0xFF, trx->max_power_red / 2);
-		rsl_nokia_si_end(trx);
-	}
-
-	for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
-		struct gsm_bts_trx_ts *ts = &trx->ts[i];
-		generate_ma_for_ts(ts);
-		gsm_ts_check_init(ts);
-	}
-}
-
-/* Callback function to be called every time we receive a signal from INPUT */
-static int inp_sig_cb(unsigned int subsys, unsigned int signal,
-		      void *handler_data, void *signal_data)
-{
-	struct input_signal_data *isd = signal_data;
-	struct gsm_bts_trx *trx = isd->trx;
-	int ts_no, lchan_no;
-	/* N. B: we rely on attribute order when parsing response in abis_nm_rx_get_attr_resp() */
-	const uint8_t bts_attr[] = { NM_ATT_MANUF_ID, NM_ATT_SW_CONFIG, };
-	const uint8_t trx_attr[] = { NM_ATT_MANUF_STATE, NM_ATT_SW_CONFIG, };
-
-	/* we should not request more attributes than we're ready to handle */
-	OSMO_ASSERT(sizeof(bts_attr) < MAX_BTS_ATTR);
-	OSMO_ASSERT(sizeof(trx_attr) < MAX_BTS_ATTR);
-
-	if (subsys != SS_L_INPUT)
-		return -EINVAL;
-
-	LOGP(DLMI, LOGL_DEBUG, "%s(): Input signal '%s' received\n", __func__,
-		get_value_string(e1inp_signal_names, signal));
-	switch (signal) {
-	case S_L_INP_TEI_UP:
-		if (isd->link_type == E1INP_SIGN_OML) {
-			/* TODO: this is required for the Nokia BTS, hopping is configured
-			   during OML, other MA is not set.  */
-			struct gsm_bts_trx *cur_trx;
-			/* was static in system_information.c */
-			extern int generate_cell_chan_list(uint8_t *chan_list, struct gsm_bts *bts);
-			uint8_t ca[20];
-			/* has to be called before generate_ma_for_ts to
-			  set bts->si_common.cell_alloc */
-			generate_cell_chan_list(ca, trx->bts);
-
-			/* Request generic BTS-level attributes */
-			abis_nm_get_attr(trx->bts, NM_OC_BTS, 0xFF, 0xFF, 0xFF, bts_attr, sizeof(bts_attr));
-
-			llist_for_each_entry(cur_trx, &trx->bts->trx_list, list) {
-				int i;
-				/* Request TRX-level attributes */
-				abis_nm_get_attr(cur_trx->bts, NM_OC_BASEB_TRANSC, 0, cur_trx->nr, 0xFF,
-						 trx_attr, sizeof(trx_attr));
-				for (i = 0; i < ARRAY_SIZE(cur_trx->ts); i++)
-					generate_ma_for_ts(&cur_trx->ts[i]);
-			}
-		}
-		if (isd->link_type == E1INP_SIGN_RSL)
-			bootstrap_rsl(trx);
-		break;
-	case S_L_INP_TEI_DN:
-		LOGP(DLMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", isd->link_type, trx);
-
-		if (isd->link_type == E1INP_SIGN_OML)
-			rate_ctr_inc(&trx->bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL]);
-		else if (isd->link_type == E1INP_SIGN_RSL) {
-			rate_ctr_inc(&trx->bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL]);
-			acc_ramp_abort(&trx->bts->acc_ramp);
-		}
-
-		/*
-		 * free all allocated channels. change the nm_state so the
-		 * trx and trx_ts becomes unusable and chan_alloc.c can not
-		 * allocate from it.
-		 */
-		for (ts_no = 0; ts_no < ARRAY_SIZE(trx->ts); ++ts_no) {
-			struct gsm_bts_trx_ts *ts = &trx->ts[ts_no];
-
-			for (lchan_no = 0; lchan_no < ARRAY_SIZE(ts->lchan); ++lchan_no) {
-				if (ts->lchan[lchan_no].state != LCHAN_S_NONE)
-					lchan_free(&ts->lchan[lchan_no]);
-				lchan_reset(&ts->lchan[lchan_no]);
-			}
-		}
-
-		gsm_bts_mo_reset(trx->bts);
-
-		abis_nm_clear_queue(trx->bts);
-		break;
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-static int bootstrap_bts(struct gsm_bts *bts)
-{
-	int i, n;
-
-	if (!bts->model)
-		return -EFAULT;
-
-	if (bts->model->start && !bts->model->started) {
-		int ret = bts->model->start(bts->network);
-		if (ret < 0)
-			return ret;
-
-		bts->model->started = true;
-	}
-
-	/* FIXME: What about secondary TRX of a BTS?  What about a BTS that has TRX
-	 * in different bands? Why is 'band' a parameter of the BTS and not of the TRX? */
-	switch (bts->band) {
-	case GSM_BAND_1800:
-		if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
-			LOGP(DNM, LOGL_ERROR, "GSM1800 channel must be between 512-885.\n");
-			return -EINVAL;
-		}
-		break;
-	case GSM_BAND_1900:
-		if (bts->c0->arfcn < 512 || bts->c0->arfcn > 810) {
-			LOGP(DNM, LOGL_ERROR, "GSM1900 channel must be between 512-810.\n");
-			return -EINVAL;
-		}
-		break;
-	case GSM_BAND_900:
-		if ((bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
-		    bts->c0->arfcn > 1023)  {
-			LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 0-124, 955-1023.\n");
-			return -EINVAL;
-		}
-		break;
-	case GSM_BAND_850:
-		if (bts->c0->arfcn < 128 || bts->c0->arfcn > 251) {
-			LOGP(DNM, LOGL_ERROR, "GSM850 channel must be between 128-251.\n");
-			return -EINVAL;
-		}
-		break;
-	default:
-		LOGP(DNM, LOGL_ERROR, "Unsupported frequency band.\n");
-		return -EINVAL;
-	}
-
-	/* Control Channel Description is set from vty/config */
-
-	/* T3212 is set from vty/config */
-
-	/* Set ccch config by looking at ts config */
-	for (n=0, i=0; i<8; i++)
-		n += bts->c0->ts[i].pchan == GSM_PCHAN_CCCH ? 1 : 0;
-
-	/* Indicate R99 MSC in SI3 */
-	bts->si_common.chan_desc.mscr = 1;
-
-	switch (n) {
-	case 0:
-		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
-		/* Limit reserved block to 2 on combined channel according to
-		   3GPP TS 44.018 Table 10.5.2.11.1 */
-		if (bts->si_common.chan_desc.bs_ag_blks_res > 2) {
-			LOGP(DNM, LOGL_NOTICE, "CCCH is combined with SDCCHs, "
-			     "reducing BS-AG-BLKS-RES value %d -> 2\n",
-			     bts->si_common.chan_desc.bs_ag_blks_res);
-			bts->si_common.chan_desc.bs_ag_blks_res = 2;
-		}
-		break;
-	case 1:
-		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_NC;
-		break;
-	case 2:
-		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_2_NC;
-		break;
-	case 3:
-		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_3_NC;
-		break;
-	case 4:
-		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_4_NC;
-		break;
-	default:
-		LOGP(DNM, LOGL_ERROR, "Unsupported CCCH timeslot configuration\n");
-		return -EINVAL;
-	}
-
-	bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
-
-	bts->si_common.cell_sel_par.acs = 0;
-
-	bts->si_common.ncc_permitted = 0xff;
-
-	bts->chan_load_samples_idx = 0;
-
-	/* ACC ramping is initialized from vty/config */
-
-	/* Initialize the BTS state */
-	gsm_bts_mo_reset(bts);
-
-	return 0;
-}
-
-int bsc_network_alloc(void)
-{
-	/* initialize our data structures */
-	bsc_gsmnet = bsc_network_init(tall_bsc_ctx);
-	if (!bsc_gsmnet)
-		return -ENOMEM;
-
-	return 0;
-}
-
-int bsc_network_configure(const char *config_file)
-{
-	struct gsm_bts *bts;
-	int rc;
-
-	rc = vty_read_config_file(config_file, NULL);
-	if (rc < 0) {
-		LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
-		return rc;
-	}
-
-	/* start telnet after reading config for vty_get_bind_addr() */
-	rc = telnet_init_dynif(tall_bsc_ctx, bsc_gsmnet, vty_get_bind_addr(),
-			       OSMO_VTY_PORT_NITB_BSC);
-	if (rc < 0)
-		return rc;
-
-	osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);
-	osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
-
-	llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
-		rc = bootstrap_bts(bts);
-		if (rc < 0) {
-			LOGP(DNM, LOGL_FATAL, "Error bootstrapping BTS\n");
-			return rc;
-		}
-		rc = e1_reconfig_bts(bts);
-		if (rc < 0) {
-			LOGP(DNM, LOGL_FATAL, "Error enabling E1 input driver\n");
-			return rc;
-		}
-	}
-
-	return 0;
-}
diff --git a/src/libbsc/net_init.c b/src/libbsc/net_init.c
deleted file mode 100644
index f03a2e1..0000000
--- a/src/libbsc/net_init.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/* (C) 2008-2010 by Harald Welte <laforge at gnumonks.org>
- *
- * 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/bsc/osmo_bsc.h>
-#include <osmocom/bsc/bsc_msc_data.h>
-#include <osmocom/bsc/gsm_04_08_utils.h>
-#include <osmocom/bsc/handover_cfg.h>
-#include <osmocom/bsc/chan_alloc.h>
-#include <osmocom/bsc/common_bsc.h>
-
-/* XXX hard-coded for now */
-#define T3122_CHAN_LOAD_SAMPLE_INTERVAL 1 /* in seconds */
-
-static void update_t3122_chan_load_timer(void *data)
-{
-	struct gsm_network *net = data;
-	struct gsm_bts *bts;
-
-	llist_for_each_entry(bts, &net->bts_list, list)
-		bts_update_t3122_chan_load(bts);
-
-	/* Keep this timer ticking. */
-	osmo_timer_schedule(&net->t3122_chan_load_timer, T3122_CHAN_LOAD_SAMPLE_INTERVAL, 0);
-}
-
-struct gsm_network *bsc_network_init(void *ctx)
-{
-	struct gsm_network *net;
-
-	net = talloc_zero(ctx, struct gsm_network);
-	if (!net)
-		return NULL;
-
-	net->plmn = (struct osmo_plmn_id){
-		.mcc = 1,
-		.mnc = 1,
-	};
-
-	net->dyn_ts_allow_tch_f = true;
-
-	/* Permit a compile-time default of A5/3 and A5/1 */
-	net->a5_encryption_mask = (1 << 3) | (1 << 1);
-
-	/* Use 30 min periodic update interval as sane default */
-	net->t3212 = 5;
-
-	INIT_LLIST_HEAD(&net->subscr_conns);
-
-	net->bsc_subscribers = talloc_zero(net, struct llist_head);
-	INIT_LLIST_HEAD(net->bsc_subscribers);
-
-	net->bsc_data = talloc_zero(net, struct osmo_bsc_data);
-	if (!net->bsc_data) {
-		talloc_free(net);
-		return NULL;
-	}
-
-	/* Init back pointer */
-	net->bsc_data->auto_off_timeout = -1;
-	net->bsc_data->network = net;
-	INIT_LLIST_HEAD(&net->bsc_data->mscs);
-
-	net->num_bts = 0;
-	net->T3101 = GSM_T3101_DEFAULT;
-	net->T3103 = GSM_T3103_DEFAULT;
-	net->T3105 = GSM_T3105_DEFAULT;
-	net->T3107 = GSM_T3107_DEFAULT;
-	net->T3109 = GSM_T3109_DEFAULT;
-	net->T3111 = GSM_T3111_DEFAULT;
-	net->T3113 = GSM_T3113_DEFAULT;
-	net->T3115 = GSM_T3115_DEFAULT;
-	net->T3117 = GSM_T3117_DEFAULT;
-	net->T3119 = GSM_T3119_DEFAULT;
-	net->T3122 = GSM_T3122_DEFAULT;
-	net->T3141 = GSM_T3141_DEFAULT;
-
-	net->ho = ho_cfg_init(net, NULL);
-	net->hodec2.congestion_check_interval_s = HO_CFG_CONGESTION_CHECK_DEFAULT;
-
-	INIT_LLIST_HEAD(&net->bts_list);
-
-	/*
-	 * At present all BTS in the network share one channel load timeout.
-	 * If this becomes a problem for networks with a lot of BTS, this
-	 * code could be refactored to run the timeout individually per BTS.
-	 */
-	osmo_timer_setup(&net->t3122_chan_load_timer, update_t3122_chan_load_timer, net);
-	osmo_timer_schedule(&net->t3122_chan_load_timer, T3122_CHAN_LOAD_SAMPLE_INTERVAL, 0);
-
-	/* init statistics */
-	net->bsc_ctrs = rate_ctr_group_alloc(net, &bsc_ctrg_desc, 0);
-	if (!net->bsc_ctrs) {
-		talloc_free(net);
-		return NULL;
-	}
-
-	gsm_net_update_ctype(net);
-
-	return net;
-}
-
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index cc96743..a459a92 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -26,21 +26,65 @@
 	$(NULL)
 
 osmo_bsc_SOURCES = \
-	osmo_bsc_main.c \
-	osmo_bsc_vty.c \
+	a_reset.c \
+	abis_nm.c \
+	abis_nm_vty.c \
+	abis_om2000.c \
+	abis_om2000_vty.c \
+	abis_rsl.c \
+	acc_ramp.c \
+	arfcn_range_encode.c \
+	bsc_api.c \
+	bsc_ctrl_commands.c \
+	bsc_ctrl_lookup.c \
+	bsc_dyn_ts.c \
+	bsc_init.c \
+	bsc_rf_ctrl.c \
+	bsc_rll.c \
+	bsc_subscr_conn_fsm.c \
+	bsc_subscriber.c \
+	bsc_vty.c \
+	bts_ericsson_rbs2000.c \
+	bts_init.c \
+	bts_ipaccess_nanobts.c \
+	bts_ipaccess_nanobts_omlattr.c \
+	bts_nokia_site.c \
+	bts_siemens_bs11.c \
+	bts_sysmobts.c \
+	bts_unknown.c \
+	chan_alloc.c \
+	e1_config.c \
+	gsm_04_08_utils.c \
+	gsm_04_80_utils.c \
+	gsm_data.c \
+	handover_cfg.c \
+	handover_decision.c \
+	handover_decision_2.c \
+	handover_logic.c \
+	handover_vty.c \
+	meas_feed.c \
+	meas_rep.c \
+	net_init.c \
 	osmo_bsc_api.c \
+	osmo_bsc_audio.c \
+	osmo_bsc_bssap.c \
+	osmo_bsc_ctrl.c \
+	osmo_bsc_filter.c \
 	osmo_bsc_grace.c \
+	osmo_bsc_lcls.c \
+	osmo_bsc_main.c \
 	osmo_bsc_msc.c \
 	osmo_bsc_sigtran.c \
-	osmo_bsc_filter.c \
-	osmo_bsc_bssap.c \
-	osmo_bsc_audio.c \
-	osmo_bsc_ctrl.c \
+	osmo_bsc_vty.c \
+	paging.c \
+	pcu_sock.c \
+	penalty_timers.c \
+	rest_octets.c \
+	system_information.c \
 	$(NULL)
 
 osmo_bsc_LDADD = \
 	$(top_builddir)/src/libfilter/libfilter.a \
-	$(top_builddir)/src/libbsc/libbsc.a \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
 	$(LIBOSMOVTY_LIBS) \
diff --git a/src/libbsc/a_reset.c b/src/osmo-bsc/a_reset.c
similarity index 100%
rename from src/libbsc/a_reset.c
rename to src/osmo-bsc/a_reset.c
diff --git a/src/osmo-bsc/abis_bs11.c b/src/osmo-bsc/abis_bs11.c
new file mode 100644
index 0000000..8b721fa
--- /dev/null
+++ b/src/osmo-bsc/abis_bs11.c
@@ -0,0 +1,21 @@
+/* Siemens BS11 specific Abis implementations */
+
+/* (C) 2008-2018 by Harald Welte <laforge at gnumonks.org>
+ *
+ * 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/>.
+ *
+ */
+
diff --git a/src/libbsc/abis_nm.c b/src/osmo-bsc/abis_nm.c
similarity index 99%
rename from src/libbsc/abis_nm.c
rename to src/osmo-bsc/abis_nm.c
index ea94d37..9dc1f62 100644
--- a/src/libbsc/abis_nm.c
+++ b/src/osmo-bsc/abis_nm.c
@@ -164,13 +164,6 @@
 
 static int abis_nm_rcvmsg_sw(struct msgb *mb);
 
-bool nm_is_running(const struct gsm_nm_state *s) {
-	return (s->operational == NM_OPSTATE_ENABLED) && (
-		(s->availability == NM_AVSTATE_OK) ||
-		(s->availability == 0xff)
-	);
-}
-
 /* Update the administrative state of a given object in our in-memory data
  * structures and send an event to the higher layer */
 static int update_admstate(struct gsm_bts *bts, uint8_t obj_class,
diff --git a/src/libbsc/abis_nm_ipaccess.c b/src/osmo-bsc/abis_nm_ipaccess.c
similarity index 98%
rename from src/libbsc/abis_nm_ipaccess.c
rename to src/osmo-bsc/abis_nm_ipaccess.c
index b822538..964b92e 100644
--- a/src/libbsc/abis_nm_ipaccess.c
+++ b/src/osmo-bsc/abis_nm_ipaccess.c
@@ -20,6 +20,8 @@
  *
  */
 
+#include <stdint.h>
+
 /* A list of all the 'embedded' attributes of ip.access */
 enum ipa_embedded_att {
 	IPA_ATT_ARFCN_WHITELIST		= 0x01,
diff --git a/src/libbsc/abis_nm_vty.c b/src/osmo-bsc/abis_nm_vty.c
similarity index 100%
rename from src/libbsc/abis_nm_vty.c
rename to src/osmo-bsc/abis_nm_vty.c
diff --git a/src/libbsc/abis_om2000.c b/src/osmo-bsc/abis_om2000.c
similarity index 100%
rename from src/libbsc/abis_om2000.c
rename to src/osmo-bsc/abis_om2000.c
diff --git a/src/libbsc/abis_om2000_vty.c b/src/osmo-bsc/abis_om2000_vty.c
similarity index 100%
rename from src/libbsc/abis_om2000_vty.c
rename to src/osmo-bsc/abis_om2000_vty.c
diff --git a/src/libbsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
similarity index 98%
rename from src/libbsc/abis_rsl.c
rename to src/osmo-bsc/abis_rsl.c
index 48cc39f..7bbde47 100644
--- a/src/libbsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -3033,38 +3033,8 @@
 }
 
 /* Initial timeslot actions when a timeslot first comes into operation. */
-static bool gsm_ts_init(struct gsm_bts_trx_ts *ts)
+bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts)
 {
 	dyn_ts_init(ts);
 	return true;
 }
-
-/* Trigger initial timeslot actions iff both OML and RSL are setup. */
-void gsm_ts_check_init(struct gsm_bts_trx_ts *ts)
-{
-	struct gsm_bts *bts = ts->trx->bts;
-	if (bts->model->oml_is_ts_ready
-	    && !bts->model->oml_is_ts_ready(ts))
-		return;
-	if (!ts->trx->rsl_link)
-		return;
-	if (ts->initialized)
-		return;
-	ts->initialized = gsm_ts_init(ts);
-}
-
-void gsm_trx_mark_all_ts_uninitialized(struct gsm_bts_trx *trx)
-{
-	int i;
-	for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
-		struct gsm_bts_trx_ts *ts = &trx->ts[i];
-		ts->initialized = false;
-	}
-}
-
-void gsm_bts_mark_all_ts_uninitialized(struct gsm_bts *bts)
-{
-	struct gsm_bts_trx *trx;
-	llist_for_each_entry(trx, &bts->trx_list, list)
-		gsm_trx_mark_all_ts_uninitialized(trx);
-}
diff --git a/src/libbsc/acc_ramp.c b/src/osmo-bsc/acc_ramp.c
similarity index 100%
rename from src/libbsc/acc_ramp.c
rename to src/osmo-bsc/acc_ramp.c
diff --git a/src/libbsc/arfcn_range_encode.c b/src/osmo-bsc/arfcn_range_encode.c
similarity index 100%
rename from src/libbsc/arfcn_range_encode.c
rename to src/osmo-bsc/arfcn_range_encode.c
diff --git a/src/libbsc/bsc_api.c b/src/osmo-bsc/bsc_api.c
similarity index 100%
rename from src/libbsc/bsc_api.c
rename to src/osmo-bsc/bsc_api.c
diff --git a/src/libbsc/bsc_ctrl_commands.c b/src/osmo-bsc/bsc_ctrl_commands.c
similarity index 100%
rename from src/libbsc/bsc_ctrl_commands.c
rename to src/osmo-bsc/bsc_ctrl_commands.c
diff --git a/src/libbsc/bsc_ctrl_lookup.c b/src/osmo-bsc/bsc_ctrl_lookup.c
similarity index 100%
rename from src/libbsc/bsc_ctrl_lookup.c
rename to src/osmo-bsc/bsc_ctrl_lookup.c
diff --git a/src/libbsc/bsc_dyn_ts.c b/src/osmo-bsc/bsc_dyn_ts.c
similarity index 100%
rename from src/libbsc/bsc_dyn_ts.c
rename to src/osmo-bsc/bsc_dyn_ts.c
diff --git a/src/osmo-bsc/bsc_init.c b/src/osmo-bsc/bsc_init.c
new file mode 100644
index 0000000..b6bd410
--- /dev/null
+++ b/src/osmo-bsc/bsc_init.c
@@ -0,0 +1,288 @@
+/* A hackish minimal BSC (+MSC +HLR) implementation */
+
+/* (C) 2008-2018 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2009 by Holger Hans Peter Freyther <zecke at selfish.org>
+ * 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/bsc/gsm_data.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/bsc/abis_rsl.h>
+#include <osmocom/bsc/debug.h>
+#include <osmocom/bsc/misdn.h>
+#include <osmocom/bsc/system_information.h>
+#include <osmocom/bsc/paging.h>
+#include <osmocom/bsc/signal.h>
+#include <osmocom/bsc/chan_alloc.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/bsc/ipaccess.h>
+#include <osmocom/gsm/sysinfo.h>
+#include <osmocom/bsc/pcu_if.h>
+#include <osmocom/bsc/bsc_msc_data.h>
+#include <osmocom/bsc/handover_cfg.h>
+#include <osmocom/bsc/gsm_04_08_utils.h>
+
+#include <time.h>
+#include <limits.h>
+#include <stdbool.h>
+
+int bsc_shutdown_net(struct gsm_network *net)
+{
+	struct gsm_bts *bts;
+
+	llist_for_each_entry(bts, &net->bts_list, list) {
+		LOGP(DNM, LOGL_NOTICE, "shutting down OML for BTS %u\n", bts->nr);
+		osmo_signal_dispatch(SS_L_GLOBAL, S_GLOBAL_BTS_CLOSE_OM, bts);
+	}
+
+	return 0;
+}
+
+unsigned long long bts_uptime(const struct gsm_bts *bts)
+{
+	struct timespec tp;
+
+	if (!bts->uptime || !bts->oml_link) {
+		LOGP(DNM, LOGL_ERROR, "BTS %u OML link uptime unavailable\n", bts->nr);
+		return 0;
+	}
+
+	if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) {
+		LOGP(DNM, LOGL_ERROR, "BTS %u uptime computation failure: %s\n", bts->nr, strerror(errno));
+		return 0;
+	}
+
+	/* monotonic clock helps to ensure that the conversion is valid */
+	return difftime(tp.tv_sec, bts->uptime);
+}
+
+static int rsl_si(struct gsm_bts_trx *trx, enum osmo_sysinfo_type i, int si_len)
+{
+	struct gsm_bts *bts = trx->bts;
+	int rc, j;
+
+	if (si_len) {
+		DEBUGP(DRR, "SI%s: %s\n", get_value_string(osmo_sitype_strs, i),
+			osmo_hexdump(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN));
+	} else
+		DEBUGP(DRR, "SI%s: OFF\n", get_value_string(osmo_sitype_strs, i));
+
+	switch (i) {
+	case SYSINFO_TYPE_5:
+	case SYSINFO_TYPE_5bis:
+	case SYSINFO_TYPE_5ter:
+	case SYSINFO_TYPE_6:
+		rc = rsl_sacch_filling(trx, osmo_sitype2rsl(i),
+				       si_len ? GSM_BTS_SI(bts, i) : NULL, si_len);
+		break;
+	case SYSINFO_TYPE_2quater:
+		if (si_len == 0) {
+			rc = rsl_bcch_info(trx, i, NULL, 0);
+			break;
+		}
+		rc = 0;
+		for (j = 0; j <= bts->si2q_count; j++)
+			rc = rsl_bcch_info(trx, i, (const uint8_t *)GSM_BTS_SI2Q(bts, j), GSM_MACBLOCK_LEN);
+		break;
+	default:
+		rc = rsl_bcch_info(trx, i, si_len ? GSM_BTS_SI(bts, i) : NULL, si_len);
+		break;
+	}
+
+	return rc;
+}
+
+/* set all system information types for a TRX */
+int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx)
+{
+	int i, rc;
+	struct gsm_bts *bts = trx->bts;
+	uint8_t gen_si[_MAX_SYSINFO_TYPE], n_si = 0, n;
+	int si_len[_MAX_SYSINFO_TYPE];
+
+	bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
+			ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
+	bts->si_common.cell_sel_par.neci = bts->network->neci;
+
+	/* Zero/forget the state of the dynamically computed SIs, leeping the static ones */
+	bts->si_valid = bts->si_mode_static;
+
+	/* First, we determine which of the SI messages we actually need */
+
+	if (trx == bts->c0) {
+		/* 1...4 are always present on a C0 TRX */
+		gen_si[n_si++] = SYSINFO_TYPE_1;
+		gen_si[n_si++] = SYSINFO_TYPE_2;
+		gen_si[n_si++] = SYSINFO_TYPE_2bis;
+		gen_si[n_si++] = SYSINFO_TYPE_2ter;
+		gen_si[n_si++] = SYSINFO_TYPE_2quater;
+		gen_si[n_si++] = SYSINFO_TYPE_3;
+		gen_si[n_si++] = SYSINFO_TYPE_4;
+
+		/* 13 is always present on a C0 TRX of a GPRS BTS */
+		if (bts->gprs.mode != BTS_GPRS_NONE)
+			gen_si[n_si++] = SYSINFO_TYPE_13;
+	}
+
+	/* 5 and 6 are always present on every TRX */
+	gen_si[n_si++] = SYSINFO_TYPE_5;
+	gen_si[n_si++] = SYSINFO_TYPE_5bis;
+	gen_si[n_si++] = SYSINFO_TYPE_5ter;
+	gen_si[n_si++] = SYSINFO_TYPE_6;
+
+	/* Second, we generate the selected SI via RSL */
+
+	for (n = 0; n < n_si; n++) {
+		i = gen_si[n];
+		/* Only generate SI if this SI is not in "static" (user-defined) mode */
+		if (!(bts->si_mode_static & (1 << i))) {
+			/* Set SI as being valid. gsm_generate_si() might unset
+			 * it, if SI is not required. */
+			bts->si_valid |= (1 << i);
+			rc = gsm_generate_si(bts, i);
+			if (rc < 0)
+				goto err_out;
+			si_len[i] = rc;
+		} else {
+			if (i == SYSINFO_TYPE_5 || i == SYSINFO_TYPE_5bis
+			 || i == SYSINFO_TYPE_5ter)
+				si_len[i] = 18;
+			else if (i == SYSINFO_TYPE_6)
+				si_len[i] = 11;
+			else
+				si_len[i] = 23;
+		}
+	}
+
+	/* Third, we send the selected SI via RSL */
+
+	for (n = 0; n < n_si; n++) {
+		i = gen_si[n];
+		/* if we don't currently have this SI, we send a zero-length
+		 * RSL BCCH FILLING / SACCH FILLING * in order to deactivate
+		 * the SI, in case it might have previously been active */
+		if (!GSM_BTS_HAS_SI(bts, i))
+			rc = rsl_si(trx, i, 0);
+		else
+			rc = rsl_si(trx, i, si_len[i]);
+		if (rc < 0)
+			return rc;
+	}
+
+	/* Make sure the PCU is aware (in case anything GPRS related has
+	 * changed in SI */
+	pcu_info_update(bts);
+
+	return 0;
+err_out:
+	LOGP(DRR, LOGL_ERROR, "Cannot generate SI%s for BTS %u: error <%s>, "
+	     "most likely a problem with neighbor cell list generation\n",
+	     get_value_string(osmo_sitype_strs, i), bts->nr, strerror(-rc));
+	return rc;
+}
+
+/* set all system information types for a BTS */
+int gsm_bts_set_system_infos(struct gsm_bts *bts)
+{
+	struct gsm_bts_trx *trx;
+
+	/* Generate a new ID */
+	bts->bcch_change_mark += 1;
+	bts->bcch_change_mark %= 0x7;
+
+	llist_for_each_entry(trx, &bts->trx_list, list) {
+		int rc;
+
+		rc = gsm_bts_trx_set_system_infos(trx);
+		if (rc != 0)
+			return rc;
+	}
+
+	return 0;
+}
+
+/* XXX hard-coded for now */
+#define T3122_CHAN_LOAD_SAMPLE_INTERVAL 1 /* in seconds */
+
+static void update_t3122_chan_load_timer(void *data)
+{
+	struct gsm_network *net = data;
+	struct gsm_bts *bts;
+
+	llist_for_each_entry(bts, &net->bts_list, list)
+		bts_update_t3122_chan_load(bts);
+
+	/* Keep this timer ticking. */
+	osmo_timer_schedule(&net->t3122_chan_load_timer, T3122_CHAN_LOAD_SAMPLE_INTERVAL, 0);
+}
+
+static struct gsm_network *bsc_network_init(void *ctx)
+{
+	struct gsm_network *net = gsm_network_init(ctx);
+
+	net->bsc_data = talloc_zero(net, struct osmo_bsc_data);
+	if (!net->bsc_data) {
+		talloc_free(net);
+		return NULL;
+	}
+
+	/* Init back pointer */
+	net->bsc_data->auto_off_timeout = -1;
+	net->bsc_data->network = net;
+	INIT_LLIST_HEAD(&net->bsc_data->mscs);
+
+	net->ho = ho_cfg_init(net, NULL);
+	net->hodec2.congestion_check_interval_s = HO_CFG_CONGESTION_CHECK_DEFAULT;
+
+	/* init statistics */
+	net->bsc_ctrs = rate_ctr_group_alloc(net, &bsc_ctrg_desc, 0);
+	if (!net->bsc_ctrs) {
+		talloc_free(net);
+		return NULL;
+	}
+
+	gsm_net_update_ctype(net);
+
+	/*
+	 * At present all BTS in the network share one channel load timeout.
+	 * If this becomes a problem for networks with a lot of BTS, this
+	 * code could be refactored to run the timeout individually per BTS.
+	 */
+	osmo_timer_setup(&net->t3122_chan_load_timer, update_t3122_chan_load_timer, net);
+	osmo_timer_schedule(&net->t3122_chan_load_timer, T3122_CHAN_LOAD_SAMPLE_INTERVAL, 0);
+
+	return net;
+}
+
+int bsc_network_alloc(void)
+{
+	/* initialize our data structures */
+	bsc_gsmnet = bsc_network_init(tall_bsc_ctx);
+	if (!bsc_gsmnet)
+		return -ENOMEM;
+
+	return 0;
+}
+
+struct gsm_bts *bsc_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type, uint8_t bsic)
+{
+	struct gsm_bts *bts = gsm_bts_alloc_register(net, type, bsic);
+
+	bts->ho = ho_cfg_init(bts, net->ho);
+
+	return bts;
+}
diff --git a/src/libbsc/bsc_rf_ctrl.c b/src/osmo-bsc/bsc_rf_ctrl.c
similarity index 100%
rename from src/libbsc/bsc_rf_ctrl.c
rename to src/osmo-bsc/bsc_rf_ctrl.c
diff --git a/src/libbsc/bsc_rll.c b/src/osmo-bsc/bsc_rll.c
similarity index 100%
rename from src/libbsc/bsc_rll.c
rename to src/osmo-bsc/bsc_rll.c
diff --git a/src/libbsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c
similarity index 100%
rename from src/libbsc/bsc_subscr_conn_fsm.c
rename to src/osmo-bsc/bsc_subscr_conn_fsm.c
diff --git a/src/libbsc/bsc_subscriber.c b/src/osmo-bsc/bsc_subscriber.c
similarity index 100%
rename from src/libbsc/bsc_subscriber.c
rename to src/osmo-bsc/bsc_subscriber.c
diff --git a/src/libbsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
similarity index 99%
rename from src/libbsc/bsc_vty.c
rename to src/osmo-bsc/bsc_vty.c
index 757a8a1..5d0feb6 100644
--- a/src/libbsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -1945,7 +1945,7 @@
 		return CMD_WARNING;
 	} else if (bts_nr == gsmnet->num_bts) {
 		/* allocate a new one */
-		bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
+		bts = bsc_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
 					     HARDCODED_BSIC);
 		/*
 		 * Initalize bts->acc_ramp here. Else we could segfault while
diff --git a/src/libbsc/bts_ericsson_rbs2000.c b/src/osmo-bsc/bts_ericsson_rbs2000.c
similarity index 100%
rename from src/libbsc/bts_ericsson_rbs2000.c
rename to src/osmo-bsc/bts_ericsson_rbs2000.c
diff --git a/src/libbsc/bts_init.c b/src/osmo-bsc/bts_init.c
similarity index 100%
rename from src/libbsc/bts_init.c
rename to src/osmo-bsc/bts_init.c
diff --git a/src/libbsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c
similarity index 100%
rename from src/libbsc/bts_ipaccess_nanobts.c
rename to src/osmo-bsc/bts_ipaccess_nanobts.c
diff --git a/src/libbsc/bts_ipaccess_nanobts_omlattr.c b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
similarity index 100%
rename from src/libbsc/bts_ipaccess_nanobts_omlattr.c
rename to src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
diff --git a/src/libbsc/bts_nokia_site.c b/src/osmo-bsc/bts_nokia_site.c
similarity index 100%
rename from src/libbsc/bts_nokia_site.c
rename to src/osmo-bsc/bts_nokia_site.c
diff --git a/src/libbsc/bts_siemens_bs11.c b/src/osmo-bsc/bts_siemens_bs11.c
similarity index 100%
rename from src/libbsc/bts_siemens_bs11.c
rename to src/osmo-bsc/bts_siemens_bs11.c
diff --git a/src/libbsc/bts_sysmobts.c b/src/osmo-bsc/bts_sysmobts.c
similarity index 100%
rename from src/libbsc/bts_sysmobts.c
rename to src/osmo-bsc/bts_sysmobts.c
diff --git a/src/libbsc/bts_unknown.c b/src/osmo-bsc/bts_unknown.c
similarity index 100%
rename from src/libbsc/bts_unknown.c
rename to src/osmo-bsc/bts_unknown.c
diff --git a/src/libbsc/chan_alloc.c b/src/osmo-bsc/chan_alloc.c
similarity index 98%
rename from src/libbsc/chan_alloc.c
rename to src/osmo-bsc/chan_alloc.c
index 4eccff0..a24fbea 100644
--- a/src/libbsc/chan_alloc.c
+++ b/src/osmo-bsc/chan_alloc.c
@@ -65,18 +65,6 @@
 	return true;
 }
 
-bool trx_is_usable(const struct gsm_bts_trx *trx)
-{
-	/* FIXME: How does this behave for BS-11 ? */
-	if (is_ipaccess_bts(trx->bts)) {
-		if (!nm_is_running(&trx->mo.nm_state) ||
-		    !nm_is_running(&trx->bb_transc.mo.nm_state))
-			return false;
-	}
-
-	return true;
-}
-
 static int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)
 {
 	struct gsm_bts_trx_ts *ts;
diff --git a/src/libbsc/e1_config.c b/src/osmo-bsc/e1_config.c
similarity index 100%
rename from src/libbsc/e1_config.c
rename to src/osmo-bsc/e1_config.c
diff --git a/src/libbsc/gsm_04_08_utils.c b/src/osmo-bsc/gsm_04_08_utils.c
similarity index 97%
rename from src/libbsc/gsm_04_08_utils.c
rename to src/osmo-bsc/gsm_04_08_utils.c
index f30640f..5bfdf97 100644
--- a/src/libbsc/gsm_04_08_utils.c
+++ b/src/osmo-bsc/gsm_04_08_utils.c
@@ -302,26 +302,6 @@
 	cd->arfcn_lo = bts->c0->arfcn & 0xff;
 }
 
-void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
-			   const struct gsm_lchan *lchan)
-{
-	uint16_t arfcn = lchan->ts->trx->arfcn & 0x3ff;
-
-	cd->chan_nr = gsm_lchan2chan_nr(lchan);
-	if (!lchan->ts->hopping.enabled) {
-		cd->h0.tsc = gsm_ts_tsc(lchan->ts);
-		cd->h0.h = 0;
-		cd->h0.arfcn_high = arfcn >> 8;
-		cd->h0.arfcn_low = arfcn & 0xff;
-	} else {
-		cd->h1.tsc = gsm_ts_tsc(lchan->ts);
-		cd->h1.h = 1;
-		cd->h1.maio_high = lchan->ts->hopping.maio >> 2;
-		cd->h1.maio_low = lchan->ts->hopping.maio & 0x03;
-		cd->h1.hsn = lchan->ts->hopping.hsn;
-	}
-}
-
 /*! \brief Encode a TS 04.08 multirate config LV according to 10.5.2.21aa
  *  \param[out] lv caller-allocated buffer of 7 bytes. First octet is IS length
  *  \param[in] mr multi-rate configuration to encode
diff --git a/src/libbsc/gsm_04_80_utils.c b/src/osmo-bsc/gsm_04_80_utils.c
similarity index 100%
rename from src/libbsc/gsm_04_80_utils.c
rename to src/osmo-bsc/gsm_04_80_utils.c
diff --git a/src/libbsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
similarity index 93%
rename from src/libbsc/gsm_data.c
rename to src/osmo-bsc/gsm_data.c
index ea2aea0..0f062d2 100644
--- a/src/libbsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -648,6 +648,10 @@
 	.initial_mcs = 6,
 };
 
+/* Initialize those parts that don't require osmo-bsc specific dependencies.
+ * 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 *bts = talloc_zero(net, struct gsm_bts);
@@ -716,8 +720,6 @@
 	bts->bcch_change_mark = 1;
 	bts->chan_load_avg = 0;
 
-	bts->ho = ho_cfg_init(bts, net->ho);
-
 	/* timer overrides */
 	bts->T3122 = 0; /* not overriden by default */
 
@@ -1232,3 +1234,72 @@
 {
 	return pchan_is_tch(ts_pchan(ts));
 }
+
+bool trx_is_usable(const struct gsm_bts_trx *trx)
+{
+	/* FIXME: How does this behave for BS-11 ? */
+	if (is_ipaccess_bts(trx->bts)) {
+		if (!nm_is_running(&trx->mo.nm_state) ||
+		    !nm_is_running(&trx->bb_transc.mo.nm_state))
+			return false;
+	}
+
+	return true;
+}
+
+void gsm_trx_mark_all_ts_uninitialized(struct gsm_bts_trx *trx)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
+		struct gsm_bts_trx_ts *ts = &trx->ts[i];
+		ts->initialized = false;
+	}
+}
+
+void gsm_bts_mark_all_ts_uninitialized(struct gsm_bts *bts)
+{
+	struct gsm_bts_trx *trx;
+	llist_for_each_entry(trx, &bts->trx_list, list)
+		gsm_trx_mark_all_ts_uninitialized(trx);
+}
+
+/* Trigger initial timeslot actions iff both OML and RSL are setup. */
+void gsm_ts_check_init(struct gsm_bts_trx_ts *ts)
+{
+	struct gsm_bts *bts = ts->trx->bts;
+	if (bts->model->oml_is_ts_ready
+	    && !bts->model->oml_is_ts_ready(ts))
+		return;
+	if (!ts->trx->rsl_link)
+		return;
+	if (ts->initialized)
+		return;
+	ts->initialized = on_gsm_ts_init(ts);
+}
+
+void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
+			   const struct gsm_lchan *lchan)
+{
+	uint16_t arfcn = lchan->ts->trx->arfcn & 0x3ff;
+
+	cd->chan_nr = gsm_lchan2chan_nr(lchan);
+	if (!lchan->ts->hopping.enabled) {
+		cd->h0.tsc = gsm_ts_tsc(lchan->ts);
+		cd->h0.h = 0;
+		cd->h0.arfcn_high = arfcn >> 8;
+		cd->h0.arfcn_low = arfcn & 0xff;
+	} else {
+		cd->h1.tsc = gsm_ts_tsc(lchan->ts);
+		cd->h1.h = 1;
+		cd->h1.maio_high = lchan->ts->hopping.maio >> 2;
+		cd->h1.maio_low = lchan->ts->hopping.maio & 0x03;
+		cd->h1.hsn = lchan->ts->hopping.hsn;
+	}
+}
+
+bool nm_is_running(const struct gsm_nm_state *s) {
+	return (s->operational == NM_OPSTATE_ENABLED) && (
+		(s->availability == NM_AVSTATE_OK) ||
+		(s->availability == 0xff)
+	);
+}
diff --git a/src/libbsc/handover_cfg.c b/src/osmo-bsc/handover_cfg.c
similarity index 100%
rename from src/libbsc/handover_cfg.c
rename to src/osmo-bsc/handover_cfg.c
diff --git a/src/libbsc/handover_decision.c b/src/osmo-bsc/handover_decision.c
similarity index 100%
rename from src/libbsc/handover_decision.c
rename to src/osmo-bsc/handover_decision.c
diff --git a/src/libbsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c
similarity index 100%
rename from src/libbsc/handover_decision_2.c
rename to src/osmo-bsc/handover_decision_2.c
diff --git a/src/libbsc/handover_logic.c b/src/osmo-bsc/handover_logic.c
similarity index 100%
rename from src/libbsc/handover_logic.c
rename to src/osmo-bsc/handover_logic.c
diff --git a/src/libbsc/handover_vty.c b/src/osmo-bsc/handover_vty.c
similarity index 100%
rename from src/libbsc/handover_vty.c
rename to src/osmo-bsc/handover_vty.c
diff --git a/src/libbsc/meas_feed.c b/src/osmo-bsc/meas_feed.c
similarity index 100%
rename from src/libbsc/meas_feed.c
rename to src/osmo-bsc/meas_feed.c
diff --git a/src/libbsc/meas_rep.c b/src/osmo-bsc/meas_rep.c
similarity index 100%
rename from src/libbsc/meas_rep.c
rename to src/osmo-bsc/meas_rep.c
diff --git a/src/osmo-bsc/net_init.c b/src/osmo-bsc/net_init.c
new file mode 100644
index 0000000..db84e2a
--- /dev/null
+++ b/src/osmo-bsc/net_init.c
@@ -0,0 +1,69 @@
+/* (C) 2008-2010 by Harald Welte <laforge at gnumonks.org>
+ *
+ * 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/bsc/osmo_bsc.h>
+#include <osmocom/bsc/bsc_msc_data.h>
+#include <osmocom/bsc/gsm_04_08_utils.h>
+#include <osmocom/bsc/handover_cfg.h>
+#include <osmocom/bsc/chan_alloc.h>
+
+/* Initialize the bare minimum of struct gsm_network, minimizing required dependencies.
+ * 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_network_init()). */
+struct gsm_network *gsm_network_init(void *ctx)
+{
+	struct gsm_network *net = talloc_zero(ctx, struct gsm_network);
+	if (!net)
+		return NULL;
+
+	net->plmn = (struct osmo_plmn_id){
+		.mcc = 1,
+		.mnc = 1,
+	};
+
+	net->dyn_ts_allow_tch_f = true;
+
+	/* Permit a compile-time default of A5/3 and A5/1 */
+	net->a5_encryption_mask = (1 << 3) | (1 << 1);
+
+	/* Use 30 min periodic update interval as sane default */
+	net->t3212 = 5;
+
+	INIT_LLIST_HEAD(&net->subscr_conns);
+
+	net->bsc_subscribers = talloc_zero(net, struct llist_head);
+	INIT_LLIST_HEAD(net->bsc_subscribers);
+
+	INIT_LLIST_HEAD(&net->bts_list);
+	net->num_bts = 0;
+	net->T3101 = GSM_T3101_DEFAULT;
+	net->T3103 = GSM_T3103_DEFAULT;
+	net->T3105 = GSM_T3105_DEFAULT;
+	net->T3107 = GSM_T3107_DEFAULT;
+	net->T3109 = GSM_T3109_DEFAULT;
+	net->T3111 = GSM_T3111_DEFAULT;
+	net->T3113 = GSM_T3113_DEFAULT;
+	net->T3115 = GSM_T3115_DEFAULT;
+	net->T3117 = GSM_T3117_DEFAULT;
+	net->T3119 = GSM_T3119_DEFAULT;
+	net->T3122 = GSM_T3122_DEFAULT;
+	net->T3141 = GSM_T3141_DEFAULT;
+
+	return net;
+}
diff --git a/src/libbsc/osmo_bsc_lcls.c b/src/osmo-bsc/osmo_bsc_lcls.c
similarity index 100%
rename from src/libbsc/osmo_bsc_lcls.c
rename to src/osmo-bsc/osmo_bsc_lcls.c
diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c
index fefc041..5c6a872 100644
--- a/src/osmo-bsc/osmo_bsc_main.c
+++ b/src/osmo-bsc/osmo_bsc_main.c
@@ -42,9 +42,15 @@
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/stats.h>
 #include <osmocom/gsm/protocol/gsm_12_21.h>
+#include <osmocom/vty/telnet_interface.h>
+#include <osmocom/vty/ports.h>
 
 #include <osmocom/abis/abis.h>
 #include <osmocom/bsc/abis_om2000.h>
+#include <osmocom/bsc/abis_nm.h>
+#include <osmocom/bsc/abis_rsl.h>
+#include <osmocom/bsc/chan_alloc.h>
+#include <osmocom/bsc/e1_config.h>
 
 #include <osmocom/mgcp_client/mgcp_client.h>
 
@@ -147,6 +153,369 @@
 	}
 }
 
+/* Callback function for NACK on the OML NM */
+static int oml_msg_nack(struct nm_nack_signal_data *nack)
+{
+	if (nack->mt == NM_MT_GET_ATTR_NACK) {
+		LOGP(DNM, LOGL_ERROR, "BTS%u does not support Get Attributes "
+		     "OML message.\n", nack->bts->nr);
+		return 0;
+	}
+
+	if (nack->mt == NM_MT_SET_BTS_ATTR_NACK)
+		LOGP(DNM, LOGL_ERROR, "Failed to set BTS attributes. That is fatal. "
+		     "Was the bts type and frequency properly specified?\n");
+	else
+		LOGP(DNM, LOGL_ERROR, "Got %s NACK going to drop the OML links.\n",
+		     abis_nm_nack_name(nack->mt));
+
+	if (!nack->bts) {
+		LOGP(DNM, LOGL_ERROR, "Unknown bts. Can not drop it.\n");
+		return 0;
+	}
+
+	if (is_ipaccess_bts(nack->bts))
+		ipaccess_drop_oml(nack->bts);
+
+	return 0;
+}
+
+/* Callback function to be called every time we receive a signal from NM */
+static int nm_sig_cb(unsigned int subsys, unsigned int signal,
+		     void *handler_data, void *signal_data)
+{
+	struct nm_nack_signal_data *nack;
+
+	switch (signal) {
+	case S_NM_NACK:
+		nack = signal_data;
+		return oml_msg_nack(nack);
+	default:
+		break;
+	}
+	return 0;
+}
+
+/* Produce a MA as specified in 10.5.2.21 */
+static int generate_ma_for_ts(struct gsm_bts_trx_ts *ts)
+{
+	/* we have three bitvecs: the per-timeslot ARFCNs, the cell chan ARFCNs
+	 * and the MA */
+	struct bitvec *cell_chan = &ts->trx->bts->si_common.cell_alloc;
+	struct bitvec *ts_arfcn = &ts->hopping.arfcns;
+	struct bitvec *ma = &ts->hopping.ma;
+	unsigned int num_cell_arfcns, bitnum, n_chan;
+	int i;
+
+	/* re-set the MA to all-zero */
+	ma->cur_bit = 0;
+	ts->hopping.ma_len = 0;
+	memset(ma->data, 0, ma->data_len);
+
+	if (!ts->hopping.enabled)
+		return 0;
+
+	/* count the number of ARFCNs in the cell channel allocation */
+	num_cell_arfcns = 0;
+	for (i = 0; i < 1024; i++) {
+		if (bitvec_get_bit_pos(cell_chan, i))
+			num_cell_arfcns++;
+	}
+
+	/* pad it to octet-aligned number of bits */
+	ts->hopping.ma_len = num_cell_arfcns / 8;
+	if (num_cell_arfcns % 8)
+		ts->hopping.ma_len++;
+
+	n_chan = 0;
+	for (i = 0; i < 1024; i++) {
+		if (!bitvec_get_bit_pos(cell_chan, i))
+			continue;
+		/* set the corresponding bit in the MA */
+		bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
+		if (bitvec_get_bit_pos(ts_arfcn, i))
+			bitvec_set_bit_pos(ma, bitnum, 1);
+		else
+			bitvec_set_bit_pos(ma, bitnum, 0);
+		n_chan++;
+	}
+
+	/* ARFCN 0 is special: It is coded last in the bitmask */
+	if (bitvec_get_bit_pos(cell_chan, 0)) {
+		n_chan++;
+		/* set the corresponding bit in the MA */
+		bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
+		if (bitvec_get_bit_pos(ts_arfcn, 0))
+			bitvec_set_bit_pos(ma, bitnum, 1);
+		else
+			bitvec_set_bit_pos(ma, bitnum, 0);
+	}
+
+	return 0;
+}
+
+static void bootstrap_rsl(struct gsm_bts_trx *trx)
+{
+	unsigned int i;
+
+	LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
+		"on ARFCN %u using MCC-MNC %s LAC=%u CID=%u BSIC=%u\n",
+		trx->bts->nr, trx->nr, trx->arfcn,
+		osmo_plmn_name(&bsc_gsmnet->plmn),
+		trx->bts->location_area_code,
+		trx->bts->cell_identity, trx->bts->bsic);
+
+	if (trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE) {
+		rsl_nokia_si_begin(trx);
+	}
+
+	/*
+	 * Trigger ACC ramping before sending system information to BTS.
+	 * This ensures that RACH control in system information is configured correctly.
+	 * TRX 0 should be usable and unlocked, otherwise starting ACC ramping is pointless.
+	 */
+	if (trx_is_usable(trx) && trx->mo.nm_state.administrative == NM_STATE_UNLOCKED)
+		acc_ramp_trigger(&trx->bts->acc_ramp);
+
+	gsm_bts_trx_set_system_infos(trx);
+
+	if (trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE) {
+		/* channel unspecific, power reduction in 2 dB steps */
+		rsl_bs_power_control(trx, 0xFF, trx->max_power_red / 2);
+		rsl_nokia_si_end(trx);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
+		struct gsm_bts_trx_ts *ts = &trx->ts[i];
+		generate_ma_for_ts(ts);
+		gsm_ts_check_init(ts);
+	}
+}
+
+/* Callback function to be called every time we receive a signal from INPUT */
+static int inp_sig_cb(unsigned int subsys, unsigned int signal,
+		      void *handler_data, void *signal_data)
+{
+	struct input_signal_data *isd = signal_data;
+	struct gsm_bts_trx *trx = isd->trx;
+	int ts_no, lchan_no;
+	/* N. B: we rely on attribute order when parsing response in abis_nm_rx_get_attr_resp() */
+	const uint8_t bts_attr[] = { NM_ATT_MANUF_ID, NM_ATT_SW_CONFIG, };
+	const uint8_t trx_attr[] = { NM_ATT_MANUF_STATE, NM_ATT_SW_CONFIG, };
+
+	/* we should not request more attributes than we're ready to handle */
+	OSMO_ASSERT(sizeof(bts_attr) < MAX_BTS_ATTR);
+	OSMO_ASSERT(sizeof(trx_attr) < MAX_BTS_ATTR);
+
+	if (subsys != SS_L_INPUT)
+		return -EINVAL;
+
+	LOGP(DLMI, LOGL_DEBUG, "%s(): Input signal '%s' received\n", __func__,
+		get_value_string(e1inp_signal_names, signal));
+	switch (signal) {
+	case S_L_INP_TEI_UP:
+		if (isd->link_type == E1INP_SIGN_OML) {
+			/* TODO: this is required for the Nokia BTS, hopping is configured
+			   during OML, other MA is not set.  */
+			struct gsm_bts_trx *cur_trx;
+			/* was static in system_information.c */
+			extern int generate_cell_chan_list(uint8_t *chan_list, struct gsm_bts *bts);
+			uint8_t ca[20];
+			/* has to be called before generate_ma_for_ts to
+			  set bts->si_common.cell_alloc */
+			generate_cell_chan_list(ca, trx->bts);
+
+			/* Request generic BTS-level attributes */
+			abis_nm_get_attr(trx->bts, NM_OC_BTS, 0xFF, 0xFF, 0xFF, bts_attr, sizeof(bts_attr));
+
+			llist_for_each_entry(cur_trx, &trx->bts->trx_list, list) {
+				int i;
+				/* Request TRX-level attributes */
+				abis_nm_get_attr(cur_trx->bts, NM_OC_BASEB_TRANSC, 0, cur_trx->nr, 0xFF,
+						 trx_attr, sizeof(trx_attr));
+				for (i = 0; i < ARRAY_SIZE(cur_trx->ts); i++)
+					generate_ma_for_ts(&cur_trx->ts[i]);
+			}
+		}
+		if (isd->link_type == E1INP_SIGN_RSL)
+			bootstrap_rsl(trx);
+		break;
+	case S_L_INP_TEI_DN:
+		LOGP(DLMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", isd->link_type, trx);
+
+		if (isd->link_type == E1INP_SIGN_OML)
+			rate_ctr_inc(&trx->bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL]);
+		else if (isd->link_type == E1INP_SIGN_RSL) {
+			rate_ctr_inc(&trx->bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL]);
+			acc_ramp_abort(&trx->bts->acc_ramp);
+		}
+
+		/*
+		 * free all allocated channels. change the nm_state so the
+		 * trx and trx_ts becomes unusable and chan_alloc.c can not
+		 * allocate from it.
+		 */
+		for (ts_no = 0; ts_no < ARRAY_SIZE(trx->ts); ++ts_no) {
+			struct gsm_bts_trx_ts *ts = &trx->ts[ts_no];
+
+			for (lchan_no = 0; lchan_no < ARRAY_SIZE(ts->lchan); ++lchan_no) {
+				if (ts->lchan[lchan_no].state != LCHAN_S_NONE)
+					lchan_free(&ts->lchan[lchan_no]);
+				lchan_reset(&ts->lchan[lchan_no]);
+			}
+		}
+
+		gsm_bts_mo_reset(trx->bts);
+
+		abis_nm_clear_queue(trx->bts);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int bootstrap_bts(struct gsm_bts *bts)
+{
+	int i, n;
+
+	if (!bts->model)
+		return -EFAULT;
+
+	if (bts->model->start && !bts->model->started) {
+		int ret = bts->model->start(bts->network);
+		if (ret < 0)
+			return ret;
+
+		bts->model->started = true;
+	}
+
+	/* FIXME: What about secondary TRX of a BTS?  What about a BTS that has TRX
+	 * in different bands? Why is 'band' a parameter of the BTS and not of the TRX? */
+	switch (bts->band) {
+	case GSM_BAND_1800:
+		if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
+			LOGP(DNM, LOGL_ERROR, "GSM1800 channel must be between 512-885.\n");
+			return -EINVAL;
+		}
+		break;
+	case GSM_BAND_1900:
+		if (bts->c0->arfcn < 512 || bts->c0->arfcn > 810) {
+			LOGP(DNM, LOGL_ERROR, "GSM1900 channel must be between 512-810.\n");
+			return -EINVAL;
+		}
+		break;
+	case GSM_BAND_900:
+		if ((bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
+		    bts->c0->arfcn > 1023)  {
+			LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 0-124, 955-1023.\n");
+			return -EINVAL;
+		}
+		break;
+	case GSM_BAND_850:
+		if (bts->c0->arfcn < 128 || bts->c0->arfcn > 251) {
+			LOGP(DNM, LOGL_ERROR, "GSM850 channel must be between 128-251.\n");
+			return -EINVAL;
+		}
+		break;
+	default:
+		LOGP(DNM, LOGL_ERROR, "Unsupported frequency band.\n");
+		return -EINVAL;
+	}
+
+	/* Control Channel Description is set from vty/config */
+
+	/* T3212 is set from vty/config */
+
+	/* Set ccch config by looking at ts config */
+	for (n=0, i=0; i<8; i++)
+		n += bts->c0->ts[i].pchan == GSM_PCHAN_CCCH ? 1 : 0;
+
+	/* Indicate R99 MSC in SI3 */
+	bts->si_common.chan_desc.mscr = 1;
+
+	switch (n) {
+	case 0:
+		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
+		/* Limit reserved block to 2 on combined channel according to
+		   3GPP TS 44.018 Table 10.5.2.11.1 */
+		if (bts->si_common.chan_desc.bs_ag_blks_res > 2) {
+			LOGP(DNM, LOGL_NOTICE, "CCCH is combined with SDCCHs, "
+			     "reducing BS-AG-BLKS-RES value %d -> 2\n",
+			     bts->si_common.chan_desc.bs_ag_blks_res);
+			bts->si_common.chan_desc.bs_ag_blks_res = 2;
+		}
+		break;
+	case 1:
+		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_NC;
+		break;
+	case 2:
+		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_2_NC;
+		break;
+	case 3:
+		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_3_NC;
+		break;
+	case 4:
+		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_4_NC;
+		break;
+	default:
+		LOGP(DNM, LOGL_ERROR, "Unsupported CCCH timeslot configuration\n");
+		return -EINVAL;
+	}
+
+	bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
+
+	bts->si_common.cell_sel_par.acs = 0;
+
+	bts->si_common.ncc_permitted = 0xff;
+
+	bts->chan_load_samples_idx = 0;
+
+	/* ACC ramping is initialized from vty/config */
+
+	/* Initialize the BTS state */
+	gsm_bts_mo_reset(bts);
+
+	return 0;
+}
+
+static int bsc_network_configure(const char *config_file)
+{
+	struct gsm_bts *bts;
+	int rc;
+
+	rc = vty_read_config_file(config_file, NULL);
+	if (rc < 0) {
+		LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
+		return rc;
+	}
+
+	/* start telnet after reading config for vty_get_bind_addr() */
+	rc = telnet_init_dynif(tall_bsc_ctx, bsc_gsmnet, vty_get_bind_addr(),
+			       OSMO_VTY_PORT_NITB_BSC);
+	if (rc < 0)
+		return rc;
+
+	osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);
+	osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
+
+	llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
+		rc = bootstrap_bts(bts);
+		if (rc < 0) {
+			LOGP(DNM, LOGL_FATAL, "Error bootstrapping BTS\n");
+			return rc;
+		}
+		rc = e1_reconfig_bts(bts);
+		if (rc < 0) {
+			LOGP(DNM, LOGL_FATAL, "Error enabling E1 input driver\n");
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
 static int bsc_vty_go_parent(struct vty *vty)
 {
 	switch (vty->node) {
diff --git a/src/libbsc/paging.c b/src/osmo-bsc/paging.c
similarity index 100%
rename from src/libbsc/paging.c
rename to src/osmo-bsc/paging.c
diff --git a/src/libbsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c
similarity index 100%
rename from src/libbsc/pcu_sock.c
rename to src/osmo-bsc/pcu_sock.c
diff --git a/src/libbsc/penalty_timers.c b/src/osmo-bsc/penalty_timers.c
similarity index 100%
rename from src/libbsc/penalty_timers.c
rename to src/osmo-bsc/penalty_timers.c
diff --git a/src/libbsc/rest_octets.c b/src/osmo-bsc/rest_octets.c
similarity index 100%
rename from src/libbsc/rest_octets.c
rename to src/osmo-bsc/rest_octets.c
diff --git a/src/libbsc/system_information.c b/src/osmo-bsc/system_information.c
similarity index 100%
rename from src/libbsc/system_information.c
rename to src/osmo-bsc/system_information.c
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
index 6e21ccc..543344b 100644
--- a/src/utils/Makefile.am
+++ b/src/utils/Makefile.am
@@ -46,15 +46,18 @@
 
 bs11_config_SOURCES = \
 	bs11_config.c \
+	stubs.c \
 	$(NULL)
 
 bs11_config_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/abis_nm.o \
+	$(top_builddir)/src/osmo-bsc/bts_siemens_bs11.o \
+	$(top_builddir)/src/osmo-bsc/e1_config.o \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
+	$(top_builddir)/src/osmo-bsc/net_init.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
-	$(LIBOSMOSIGTRAN_LIBS) \
-	$(LIBOSMOMGCPCLIENT_LIBS) \
 	$(NULL)
 
 isdnsync_SOURCES = \
@@ -114,12 +117,14 @@
 
 meas_json_SOURCES = \
 	meas_json.c \
+	stubs.c \
 	$(NULL)
 
 meas_json_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
+	$(LIBOSMOABIS_LIBS) \
 	$(NULL)
 
 meas_json_CFLAGS = \
diff --git a/src/utils/bs11_config.c b/src/utils/bs11_config.c
index 8d4de01..ae307c7 100644
--- a/src/utils/bs11_config.c
+++ b/src/utils/bs11_config.c
@@ -32,7 +32,6 @@
 
 #include <sys/stat.h>
 
-#include <osmocom/bsc/common_bsc.h>
 #include <osmocom/bsc/abis_nm.h>
 #include <osmocom/core/msgb.h>
 #include <osmocom/core/utils.h>
@@ -915,7 +914,7 @@
 	handle_options(argc, argv);
 	bts_model_bs11_init();
 
-	gsmnet = bsc_network_init(tall_bs11cfg_ctx);
+	gsmnet = gsm_network_init(tall_bs11cfg_ctx);
 	if (!gsmnet) {
 		fprintf(stderr, "Unable to allocate gsm network\n");
 		exit(1);
diff --git a/src/utils/stubs.c b/src/utils/stubs.c
new file mode 100644
index 0000000..624797f
--- /dev/null
+++ b/src/utils/stubs.c
@@ -0,0 +1,36 @@
+/* Stubs required for linking */
+
+/* (C) 2018 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 <stdbool.h>
+struct gsm_bts_trx_ts;
+struct msgb;
+
+bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts)
+{
+	/* No TS init required here. */
+	return true;
+}
+
+int abis_rsl_rcvmsg(struct msgb *msg)
+{
+	/* No RSL handling here */
+	return 0;
+}
diff --git a/tests/abis/Makefile.am b/tests/abis/Makefile.am
index 8dc829f..60054d9 100644
--- a/tests/abis/Makefile.am
+++ b/tests/abis/Makefile.am
@@ -25,7 +25,9 @@
 	$(NULL)
 
 abis_test_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/abis_nm.o \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
+	$(top_builddir)/src/osmo-bsc/net_init.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c
index faf9ea5..c6f29f5 100644
--- a/tests/abis/abis_test.c
+++ b/tests/abis/abis_test.c
@@ -186,3 +186,5 @@
 struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *net) {
 	OSMO_ASSERT(0);
 }
+
+bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts) { return true; }
diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am
index a436c27..a930629 100644
--- a/tests/bsc/Makefile.am
+++ b/tests/bsc/Makefile.am
@@ -28,11 +28,28 @@
 
 bsc_test_SOURCES = \
 	bsc_test.c \
-	$(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c \
 	$(NULL)
 
 bsc_test_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/abis_nm.o \
+	$(top_builddir)/src/osmo-bsc/abis_rsl.o \
+	$(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \
+	$(top_builddir)/src/osmo-bsc/bsc_api.o \
+	$(top_builddir)/src/osmo-bsc/bsc_dyn_ts.o \
+	$(top_builddir)/src/osmo-bsc/osmo_bsc_filter.o \
+	$(top_builddir)/src/osmo-bsc/bsc_rll.o \
+	$(top_builddir)/src/osmo-bsc/bsc_subscriber.o \
+	$(top_builddir)/src/osmo-bsc/chan_alloc.o \
+	$(top_builddir)/src/osmo-bsc/gsm_04_08_utils.o \
+	$(top_builddir)/src/osmo-bsc/gsm_04_80_utils.o \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
+	$(top_builddir)/src/osmo-bsc/handover_cfg.o \
+	$(top_builddir)/src/osmo-bsc/handover_logic.o \
+	$(top_builddir)/src/osmo-bsc/net_init.o \
+	$(top_builddir)/src/osmo-bsc/paging.o \
+	$(top_builddir)/src/osmo-bsc/pcu_sock.o \
+	$(top_builddir)/src/osmo-bsc/rest_octets.o \
+	$(top_builddir)/src/osmo-bsc/system_information.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
 	$(LIBOSMOVTY_LIBS) \
diff --git a/tests/bsc/bsc_test.c b/tests/bsc/bsc_test.c
index 106b08b..183fddf 100644
--- a/tests/bsc/bsc_test.c
+++ b/tests/bsc/bsc_test.c
@@ -30,7 +30,6 @@
 #include <osmocom/bsc/osmo_bsc.h>
 #include <osmocom/bsc/bsc_msc_data.h>
 #include <osmocom/bsc/gsm_04_80.h>
-#include <osmocom/bsc/common_bsc.h>
 
 #include <osmocom/core/application.h>
 #include <osmocom/core/backtrace.h>
@@ -124,7 +123,7 @@
 {
 	int i;
 
-	struct gsm_network *net = bsc_network_init(ctx);
+	struct gsm_network *net = gsm_network_init(ctx);
 	struct gsm_bts *bts = gsm_bts_alloc(net, 0);
 	struct bsc_msc_data *msc;
 	struct gsm_subscriber_connection *conn;
@@ -162,7 +161,7 @@
 			/* override timezone of msg coming from the BSC */
 			/* FIXME: no test for this case is defined in
 			 * test_scan_defs[], so this is never used. */
-			result = bsc_scan_bts_msg(conn, msg);
+			//result = bsc_scan_bts_msg(conn, msg);
 			break;
 		default:
 			abort();
diff --git a/tests/bssap/Makefile.am b/tests/bssap/Makefile.am
index 30a9246..fad6318 100644
--- a/tests/bssap/Makefile.am
+++ b/tests/bssap/Makefile.am
@@ -25,14 +25,9 @@
 
 bssap_test_SOURCES = \
 	bssap_test.c \
-	$(top_srcdir)/src/osmo-bsc/osmo_bsc_bssap.c \
-	$(top_srcdir)/src/osmo-bsc/osmo_bsc_sigtran.c \
-	$(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c \
-	$(top_srcdir)/src/osmo-bsc/osmo_bsc_grace.c \
 	$(NULL)
 
 bssap_test_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
@@ -41,6 +36,30 @@
 	$(NULL)
 
 bssap_test_LDFLAGS = \
+	$(top_builddir)/src/osmo-bsc/a_reset.o \
+	$(top_builddir)/src/osmo-bsc/abis_rsl.o \
+	$(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \
+	$(top_builddir)/src/osmo-bsc/bsc_api.o \
+	$(top_builddir)/src/osmo-bsc/bsc_dyn_ts.o \
+	$(top_builddir)/src/osmo-bsc/bsc_init.o \
+	$(top_builddir)/src/osmo-bsc/bsc_rll.o \
+	$(top_builddir)/src/osmo-bsc/bsc_subscriber.o \
+	$(top_builddir)/src/osmo-bsc/chan_alloc.o \
+	$(top_builddir)/src/osmo-bsc/gsm_04_08_utils.o \
+	$(top_builddir)/src/osmo-bsc/gsm_04_80_utils.o \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
+	$(top_builddir)/src/osmo-bsc/handover_cfg.o \
+	$(top_builddir)/src/osmo-bsc/handover_logic.o \
+	$(top_builddir)/src/osmo-bsc/net_init.o \
+	$(top_builddir)/src/osmo-bsc/osmo_bsc_api.o \
+	$(top_builddir)/src/osmo-bsc/osmo_bsc_bssap.o \
+	$(top_builddir)/src/osmo-bsc/osmo_bsc_filter.o \
+	$(top_builddir)/src/osmo-bsc/osmo_bsc_grace.o \
+	$(top_builddir)/src/osmo-bsc/osmo_bsc_sigtran.o \
+	$(top_builddir)/src/osmo-bsc/paging.o \
+	$(top_builddir)/src/osmo-bsc/pcu_sock.o \
+	$(top_builddir)/src/osmo-bsc/rest_octets.o \
+	$(top_builddir)/src/osmo-bsc/system_information.o \
 	-Wl,--wrap=bsc_grace_paging_request \
 	$(NULL)
 
diff --git a/tests/bssap/bssap_test.c b/tests/bssap/bssap_test.c
index c9e7075..bb23241 100644
--- a/tests/bssap/bssap_test.c
+++ b/tests/bssap/bssap_test.c
@@ -24,8 +24,8 @@
 #include <osmocom/bsc/signal.h>
 #include <osmocom/bsc/bsc_subscriber.h>
 #include <osmocom/bsc/bsc_msc_data.h>
-#include <osmocom/bsc/common_bsc.h>
 #include <osmocom/bsc/osmo_bsc_rf.h>
+#include <osmocom/bsc/bss.h>
 
 struct msgb *msgb_from_hex(const char *label, uint16_t size, const char *hex)
 {
@@ -80,7 +80,7 @@
 	},
 };
 
-struct gsm_network *bsc_gsmnet;
+struct gsm_network *bsc_gsmnet = NULL;
 
 void test_cell_identifier()
 {
@@ -89,7 +89,7 @@
 	struct bsc_msc_data *msc;
 	struct gsm_bts *bts;
 
-	bsc_gsmnet = bsc_network_init(NULL);
+	bsc_network_alloc();
 	bsc_gsmnet->bsc_data->rf_ctrl = talloc_zero(NULL, struct osmo_bsc_rf);
 	bsc_gsmnet->bsc_data->rf_ctrl->policy = S_RF_ON;
 
@@ -160,3 +160,26 @@
 int bsc_sccplite_rx_ctrl(struct osmo_ss7_asp *asp, struct msgb *msg) {
 	OSMO_ASSERT(0);
 }
+
+int bsc_sccplite_rx_mgcp(struct osmo_ss7_asp *asp, struct msgb *msg) {
+	OSMO_ASSERT(0);
+}
+
+int bsc_sccplite_rx_mgcp(struct osmo_ss7_asp *asp, struct msgb *msg) {
+	OSMO_ASSERT(0);
+}
+
+int bsc_msg_filter_initial(struct gsm48_hdr *hdr48, size_t hdr48_len,
+			struct bsc_filter_request *req,
+			int *con_type,
+			char **imsi, struct bsc_filter_reject_cause *cause)
+{ return 0; }
+
+int bsc_msg_filter_data(struct gsm48_hdr *hdr48, size_t len,
+		struct bsc_filter_request *req,
+		struct bsc_filter_state *state,
+		struct bsc_filter_reject_cause *cause)
+{ return 0; }
+
+struct llist_head *bsc_access_lists(void)
+{ return NULL; }
diff --git a/tests/channel/Makefile.am b/tests/channel/Makefile.am
index f641f60..26c6cff 100644
--- a/tests/channel/Makefile.am
+++ b/tests/channel/Makefile.am
@@ -24,7 +24,8 @@
 	$(NULL)
 
 channel_test_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
+	$(top_builddir)/src/osmo-bsc/net_init.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
diff --git a/tests/channel/channel_test.c b/tests/channel/channel_test.c
index e8f6cd9..4c2f9cd 100644
--- a/tests/channel/channel_test.c
+++ b/tests/channel/channel_test.c
@@ -25,10 +25,11 @@
 #include <osmocom/core/application.h>
 #include <osmocom/core/select.h>
 
-#include <osmocom/bsc/common_bsc.h>
 #include <osmocom/bsc/abis_rsl.h>
 #include <osmocom/bsc/debug.h>
 
+void *ctx = NULL;
+
 void test_bts_debug_print(void)
 {
 	struct gsm_network *network;
@@ -38,7 +39,7 @@
 	printf("Testing the lchan printing:");
 
 	/* Create a dummy network */
-	network = bsc_network_init(tall_bsc_ctx);
+	network = gsm_network_init(ctx);
 	if (!network)
 		exit(1);
 	/* Add a BTS with some reasonanbly non-zero id */
@@ -98,7 +99,8 @@
 
 int main(int argc, char **argv)
 {
-	osmo_init_logging2(NULL, &log_info);
+	ctx = talloc_named_const(NULL, 0, "channel_test");
+	osmo_init_logging2(ctx, &log_info);
 
 	test_dyn_ts_subslots();
 	test_bts_debug_print();
@@ -106,19 +108,4 @@
 	return EXIT_SUCCESS;
 }
 
-void sms_alloc() {}
-void sms_free() {}
-void gsm48_secure_channel() {}
-void vty_out() {}
-
-void ipa_client_conn_clear_queue() {}
-void ipa_client_conn_close() {}
-void ipa_client_conn_create() {}
-void ipa_client_conn_destroy() {}
-void ipa_client_conn_open() {}
-void ipa_client_conn_send() {}
-void ipa_msg_push_header() {}
-void ipaccess_bts_handle_ccm() {}
-struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *network) { return NULL; }
-
-struct tlv_definition nm_att_tlvdef;
+bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts) { return true; }
diff --git a/tests/gsm0408/Makefile.am b/tests/gsm0408/Makefile.am
index 9a74d44..6d10b9f 100644
--- a/tests/gsm0408/Makefile.am
+++ b/tests/gsm0408/Makefile.am
@@ -23,7 +23,11 @@
 	$(NULL)
 
 gsm0408_test_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
+	$(top_builddir)/src/osmo-bsc/net_init.o \
+	$(top_builddir)/src/osmo-bsc/rest_octets.o \
+	$(top_builddir)/src/osmo-bsc/system_information.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index a934806..9552fb1 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -24,7 +24,6 @@
 #include <stdbool.h>
 #include <arpa/inet.h>
 
-#include <osmocom/bsc/common_bsc.h>
 #include <osmocom/bsc/gsm_data.h>
 #include <osmocom/bsc/debug.h>
 #include <osmocom/bsc/arfcn_range_encode.h>
@@ -817,7 +816,7 @@
 	osmo_init_logging2(tall_bsc_ctx, &log_info);
 	log_set_log_level(osmo_stderr_target, LOGL_INFO);
 
-	net = bsc_network_init(tall_bsc_ctx);
+	net = gsm_network_init(tall_bsc_ctx);
 	if (!net) {
 		printf("Network init failure.\n");
 		return EXIT_FAILURE;
@@ -848,3 +847,8 @@
 struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *net) {
 	OSMO_ASSERT(0);
 }
+
+bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts)
+{
+	return true;
+}
diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am
index 957bbee..9cb77ea 100644
--- a/tests/handover/Makefile.am
+++ b/tests/handover/Makefile.am
@@ -34,7 +34,34 @@
 	$(NULL)
 
 handover_test_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/a_reset.o \
+	$(top_builddir)/src/osmo-bsc/abis_nm.o \
+	$(top_builddir)/src/osmo-bsc/abis_rsl.o \
+	$(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \
+	$(top_builddir)/src/osmo-bsc/bsc_api.o \
+	$(top_builddir)/src/osmo-bsc/bsc_dyn_ts.o \
+	$(top_builddir)/src/osmo-bsc/bsc_init.o \
+	$(top_builddir)/src/osmo-bsc/bsc_rll.o \
+	$(top_builddir)/src/osmo-bsc/bsc_subscr_conn_fsm.o \
+	$(top_builddir)/src/osmo-bsc/bsc_subscriber.o \
+	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts.o \
+	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
+	$(top_builddir)/src/osmo-bsc/bts_sysmobts.o \
+	$(top_builddir)/src/osmo-bsc/chan_alloc.o \
+	$(top_builddir)/src/osmo-bsc/gsm_04_08_utils.o \
+	$(top_builddir)/src/osmo-bsc/gsm_04_80_utils.o \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
+	$(top_builddir)/src/osmo-bsc/handover_cfg.o \
+	$(top_builddir)/src/osmo-bsc/handover_decision.o \
+	$(top_builddir)/src/osmo-bsc/handover_decision_2.o \
+	$(top_builddir)/src/osmo-bsc/handover_logic.o \
+	$(top_builddir)/src/osmo-bsc/meas_rep.o \
+	$(top_builddir)/src/osmo-bsc/net_init.o \
+	$(top_builddir)/src/osmo-bsc/paging.o \
+	$(top_builddir)/src/osmo-bsc/pcu_sock.o \
+	$(top_builddir)/src/osmo-bsc/penalty_timers.o \
+	$(top_builddir)/src/osmo-bsc/rest_octets.o \
+	$(top_builddir)/src/osmo-bsc/system_information.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index 82afbe5..26074a2 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -37,7 +37,6 @@
 #include <osmocom/bsc/system_information.h>
 #include <osmocom/bsc/handover_cfg.h>
 #include <osmocom/bsc/handover_decision_2.h>
-#include <osmocom/bsc/common_bsc.h>
 #include <osmocom/bsc/bss.h>
 #include <osmocom/bsc/bsc_api.h>
 #include <osmocom/bsc/osmo_bsc.h>
@@ -202,7 +201,7 @@
 	struct e1inp_sign_link *rsl_link;
 	int i;
 
-	bts = gsm_bts_alloc_register(bsc_gsmnet, GSM_BTS_TYPE_OSMOBTS, 0x3f);
+	bts = bsc_bts_alloc_register(bsc_gsmnet, GSM_BTS_TYPE_OSMOBTS, 0x3f);
 	if (!bts) {
 		printf("No resource for bts1\n");
 		return NULL;
@@ -1347,8 +1346,8 @@
 	struct gsm_lchan *lchan[256];
 	int lchan_num = 0;
 	int i;
-	int algorithm;
 	struct bsc_api bsc_api = {};
+	int algorithm;
 	int test_case_i;
 	int last_test_i;
 
@@ -1373,8 +1372,7 @@
 	log_set_print_category_hex(osmo_stderr_target, 0);
 	log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_BASENAME);
 
-	/* Create a dummy network */
-	bsc_gsmnet = bsc_network_init(ctx);
+	bsc_network_alloc();
 	if (!bsc_gsmnet)
 		exit(1);
 
diff --git a/tests/nanobts_omlattr/Makefile.am b/tests/nanobts_omlattr/Makefile.am
index c2b2c3b..aa7045e 100644
--- a/tests/nanobts_omlattr/Makefile.am
+++ b/tests/nanobts_omlattr/Makefile.am
@@ -23,7 +23,9 @@
 	$(NULL)
 
 nanobts_omlattr_test_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/abis_nm.o \
+	$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
+	$(top_builddir)/src/osmo-bsc/gsm_data.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
diff --git a/tests/nanobts_omlattr/nanobts_omlattr_test.c b/tests/nanobts_omlattr/nanobts_omlattr_test.c
index 8e8626d..72dabe5 100644
--- a/tests/nanobts_omlattr/nanobts_omlattr_test.c
+++ b/tests/nanobts_omlattr/nanobts_omlattr_test.c
@@ -305,3 +305,6 @@
 struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *net) {
 	OSMO_ASSERT(0);
 }
+
+bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts)
+{ return true; }
diff --git a/tests/subscr/Makefile.am b/tests/subscr/Makefile.am
index 8d14ebf..e56d142 100644
--- a/tests/subscr/Makefile.am
+++ b/tests/subscr/Makefile.am
@@ -31,7 +31,7 @@
 	$(NULL)
 
 bsc_subscr_test_LDADD = \
-	$(top_builddir)/src/libbsc/libbsc.a \
+	$(top_builddir)/src/osmo-bsc/bsc_subscriber.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
 	$(LIBOSMOGSM_LIBS) \

-- 
To view, visit https://gerrit.osmocom.org/9481
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I36a586726f5818121abe54d25654819fc451d3bf
Gerrit-Change-Number: 9481
Gerrit-PatchSet: 1
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180607/e7aeb274/attachment.htm>


More information about the gerrit-log mailing list