aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am8
-rw-r--r--src/ipaccess/Makefile.am12
-rw-r--r--src/ipaccess/ipaccess-config.c7
-rw-r--r--src/ipaccess/stubs.c43
-rw-r--r--src/libbsc/Makefile.am70
-rw-r--r--src/libbsc/bsc_init.c591
-rw-r--r--src/osmo-bsc/Makefile.am58
-rw-r--r--src/osmo-bsc/a_reset.c (renamed from src/libbsc/a_reset.c)0
-rw-r--r--src/osmo-bsc/abis_bs11.c21
-rw-r--r--src/osmo-bsc/abis_nm.c (renamed from src/libbsc/abis_nm.c)7
-rw-r--r--src/osmo-bsc/abis_nm_ipaccess.c (renamed from src/libbsc/abis_nm_ipaccess.c)2
-rw-r--r--src/osmo-bsc/abis_nm_vty.c (renamed from src/libbsc/abis_nm_vty.c)0
-rw-r--r--src/osmo-bsc/abis_om2000.c (renamed from src/libbsc/abis_om2000.c)0
-rw-r--r--src/osmo-bsc/abis_om2000_vty.c (renamed from src/libbsc/abis_om2000_vty.c)0
-rw-r--r--src/osmo-bsc/abis_rsl.c (renamed from src/libbsc/abis_rsl.c)32
-rw-r--r--src/osmo-bsc/acc_ramp.c (renamed from src/libbsc/acc_ramp.c)0
-rw-r--r--src/osmo-bsc/arfcn_range_encode.c (renamed from src/libbsc/arfcn_range_encode.c)0
-rw-r--r--src/osmo-bsc/bsc_api.c (renamed from src/libbsc/bsc_api.c)0
-rw-r--r--src/osmo-bsc/bsc_ctrl_commands.c (renamed from src/libbsc/bsc_ctrl_commands.c)0
-rw-r--r--src/osmo-bsc/bsc_ctrl_lookup.c (renamed from src/libbsc/bsc_ctrl_lookup.c)0
-rw-r--r--src/osmo-bsc/bsc_dyn_ts.c (renamed from src/libbsc/bsc_dyn_ts.c)0
-rw-r--r--src/osmo-bsc/bsc_init.c288
-rw-r--r--src/osmo-bsc/bsc_rf_ctrl.c (renamed from src/libbsc/bsc_rf_ctrl.c)0
-rw-r--r--src/osmo-bsc/bsc_rll.c (renamed from src/libbsc/bsc_rll.c)0
-rw-r--r--src/osmo-bsc/bsc_subscr_conn_fsm.c (renamed from src/libbsc/bsc_subscr_conn_fsm.c)0
-rw-r--r--src/osmo-bsc/bsc_subscriber.c (renamed from src/libbsc/bsc_subscriber.c)0
-rw-r--r--src/osmo-bsc/bsc_vty.c (renamed from src/libbsc/bsc_vty.c)2
-rw-r--r--src/osmo-bsc/bts_ericsson_rbs2000.c (renamed from src/libbsc/bts_ericsson_rbs2000.c)0
-rw-r--r--src/osmo-bsc/bts_init.c (renamed from src/libbsc/bts_init.c)0
-rw-r--r--src/osmo-bsc/bts_ipaccess_nanobts.c (renamed from src/libbsc/bts_ipaccess_nanobts.c)0
-rw-r--r--src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c (renamed from src/libbsc/bts_ipaccess_nanobts_omlattr.c)0
-rw-r--r--src/osmo-bsc/bts_nokia_site.c (renamed from src/libbsc/bts_nokia_site.c)0
-rw-r--r--src/osmo-bsc/bts_siemens_bs11.c (renamed from src/libbsc/bts_siemens_bs11.c)0
-rw-r--r--src/osmo-bsc/bts_sysmobts.c (renamed from src/libbsc/bts_sysmobts.c)0
-rw-r--r--src/osmo-bsc/bts_unknown.c (renamed from src/libbsc/bts_unknown.c)0
-rw-r--r--src/osmo-bsc/chan_alloc.c (renamed from src/libbsc/chan_alloc.c)12
-rw-r--r--src/osmo-bsc/e1_config.c (renamed from src/libbsc/e1_config.c)0
-rw-r--r--src/osmo-bsc/gsm_04_08_utils.c (renamed from src/libbsc/gsm_04_08_utils.c)20
-rw-r--r--src/osmo-bsc/gsm_04_80_utils.c (renamed from src/libbsc/gsm_04_80_utils.c)0
-rw-r--r--src/osmo-bsc/gsm_data.c (renamed from src/libbsc/gsm_data.c)75
-rw-r--r--src/osmo-bsc/handover_cfg.c (renamed from src/libbsc/handover_cfg.c)0
-rw-r--r--src/osmo-bsc/handover_decision.c (renamed from src/libbsc/handover_decision.c)0
-rw-r--r--src/osmo-bsc/handover_decision_2.c (renamed from src/libbsc/handover_decision_2.c)0
-rw-r--r--src/osmo-bsc/handover_logic.c (renamed from src/libbsc/handover_logic.c)0
-rw-r--r--src/osmo-bsc/handover_vty.c (renamed from src/libbsc/handover_vty.c)0
-rw-r--r--src/osmo-bsc/meas_feed.c (renamed from src/libbsc/meas_feed.c)0
-rw-r--r--src/osmo-bsc/meas_rep.c (renamed from src/libbsc/meas_rep.c)0
-rw-r--r--src/osmo-bsc/net_init.c (renamed from src/libbsc/net_init.c)60
-rw-r--r--src/osmo-bsc/osmo_bsc_lcls.c (renamed from src/libbsc/osmo_bsc_lcls.c)0
-rw-r--r--src/osmo-bsc/osmo_bsc_main.c369
-rw-r--r--src/osmo-bsc/paging.c (renamed from src/libbsc/paging.c)0
-rw-r--r--src/osmo-bsc/pcu_sock.c (renamed from src/libbsc/pcu_sock.c)0
-rw-r--r--src/osmo-bsc/penalty_timers.c (renamed from src/libbsc/penalty_timers.c)0
-rw-r--r--src/osmo-bsc/rest_octets.c (renamed from src/libbsc/rest_octets.c)0
-rw-r--r--src/osmo-bsc/system_information.c (renamed from src/libbsc/system_information.c)0
-rw-r--r--src/utils/Makefile.am13
-rw-r--r--src/utils/bs11_config.c3
-rw-r--r--src/utils/stubs.c36
58 files changed, 914 insertions, 815 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index fc9bf8e1a..6c63eead8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,15 +19,9 @@ AM_LDFLAGS = \
$(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 0f9045fd0..2c6282d11 100644
--- a/src/ipaccess/Makefile.am
+++ b/src/ipaccess/Makefile.am
@@ -33,31 +33,37 @@ bin_PROGRAMS = \
$(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 223606373..079bae2b9 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 @@ static void print_options(void)
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 main(int argc, char **argv)
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 @@ int main(int argc, char **argv)
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 000000000..c52d52b77
--- /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@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 2e447292f..000000000
--- 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 508a7f410..000000000
--- 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@gnumonks.org>
- * (C) 2009 by Holger Hans Peter Freyther <zecke@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/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index cc9674396..a459a928b 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -26,21 +26,65 @@ bin_PROGRAMS = \
$(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
index b8f8c8cbd..b8f8c8cbd 100644
--- a/src/libbsc/a_reset.c
+++ b/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 000000000..8b721fa77
--- /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@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
index ea94d3766..9dc1f62cb 100644
--- a/src/libbsc/abis_nm.c
+++ b/src/osmo-bsc/abis_nm.c
@@ -164,13 +164,6 @@ static int abis_nm_sendmsg_direct(struct gsm_bts *bts, struct msgb *msg)
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
index b8225383a..964b92e26 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
index 3019eb828..3019eb828 100644
--- a/src/libbsc/abis_nm_vty.c
+++ b/src/osmo-bsc/abis_nm_vty.c
diff --git a/src/libbsc/abis_om2000.c b/src/osmo-bsc/abis_om2000.c
index d533ea198..d533ea198 100644
--- a/src/libbsc/abis_om2000.c
+++ b/src/osmo-bsc/abis_om2000.c
diff --git a/src/libbsc/abis_om2000_vty.c b/src/osmo-bsc/abis_om2000_vty.c
index faf39c106..faf39c106 100644
--- a/src/libbsc/abis_om2000_vty.c
+++ b/src/osmo-bsc/abis_om2000_vty.c
diff --git a/src/libbsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 48cc39f87..7bbde47d7 100644
--- a/src/libbsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -3033,38 +3033,8 @@ int rsl_direct_rf_release(struct gsm_lchan *lchan)
}
/* 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
index ac9f02da1..ac9f02da1 100644
--- a/src/libbsc/acc_ramp.c
+++ b/src/osmo-bsc/acc_ramp.c
diff --git a/src/libbsc/arfcn_range_encode.c b/src/osmo-bsc/arfcn_range_encode.c
index 84f9f635f..84f9f635f 100644
--- a/src/libbsc/arfcn_range_encode.c
+++ b/src/osmo-bsc/arfcn_range_encode.c
diff --git a/src/libbsc/bsc_api.c b/src/osmo-bsc/bsc_api.c
index 8ae781e96..8ae781e96 100644
--- a/src/libbsc/bsc_api.c
+++ b/src/osmo-bsc/bsc_api.c
diff --git a/src/libbsc/bsc_ctrl_commands.c b/src/osmo-bsc/bsc_ctrl_commands.c
index 171feaff0..171feaff0 100644
--- a/src/libbsc/bsc_ctrl_commands.c
+++ b/src/osmo-bsc/bsc_ctrl_commands.c
diff --git a/src/libbsc/bsc_ctrl_lookup.c b/src/osmo-bsc/bsc_ctrl_lookup.c
index 38d1ba4ea..38d1ba4ea 100644
--- a/src/libbsc/bsc_ctrl_lookup.c
+++ b/src/osmo-bsc/bsc_ctrl_lookup.c
diff --git a/src/libbsc/bsc_dyn_ts.c b/src/osmo-bsc/bsc_dyn_ts.c
index ed7caed7f..ed7caed7f 100644
--- a/src/libbsc/bsc_dyn_ts.c
+++ b/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 000000000..b6bd41025
--- /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@gnumonks.org>
+ * (C) 2009 by Holger Hans Peter Freyther <zecke@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
index f4a21b53a..f4a21b53a 100644
--- a/src/libbsc/bsc_rf_ctrl.c
+++ b/src/osmo-bsc/bsc_rf_ctrl.c
diff --git a/src/libbsc/bsc_rll.c b/src/osmo-bsc/bsc_rll.c
index ebf9b8856..ebf9b8856 100644
--- a/src/libbsc/bsc_rll.c
+++ b/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
index bafe14589..bafe14589 100644
--- a/src/libbsc/bsc_subscr_conn_fsm.c
+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c
diff --git a/src/libbsc/bsc_subscriber.c b/src/osmo-bsc/bsc_subscriber.c
index d9d90baa9..d9d90baa9 100644
--- a/src/libbsc/bsc_subscriber.c
+++ b/src/osmo-bsc/bsc_subscriber.c
diff --git a/src/libbsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 757a8a1cf..5d0feb663 100644
--- a/src/libbsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -1945,7 +1945,7 @@ DEFUN(cfg_bts,
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
index 9c8b90ee2..9c8b90ee2 100644
--- a/src/libbsc/bts_ericsson_rbs2000.c
+++ b/src/osmo-bsc/bts_ericsson_rbs2000.c
diff --git a/src/libbsc/bts_init.c b/src/osmo-bsc/bts_init.c
index 18f1ed4c8..18f1ed4c8 100644
--- a/src/libbsc/bts_init.c
+++ b/src/osmo-bsc/bts_init.c
diff --git a/src/libbsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c
index 843f264ae..843f264ae 100644
--- a/src/libbsc/bts_ipaccess_nanobts.c
+++ b/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
index 1a8d9b07b..1a8d9b07b 100644
--- a/src/libbsc/bts_ipaccess_nanobts_omlattr.c
+++ b/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
index 4a24c3931..4a24c3931 100644
--- a/src/libbsc/bts_nokia_site.c
+++ b/src/osmo-bsc/bts_nokia_site.c
diff --git a/src/libbsc/bts_siemens_bs11.c b/src/osmo-bsc/bts_siemens_bs11.c
index 2d2351702..2d2351702 100644
--- a/src/libbsc/bts_siemens_bs11.c
+++ b/src/osmo-bsc/bts_siemens_bs11.c
diff --git a/src/libbsc/bts_sysmobts.c b/src/osmo-bsc/bts_sysmobts.c
index 91d1118c5..91d1118c5 100644
--- a/src/libbsc/bts_sysmobts.c
+++ b/src/osmo-bsc/bts_sysmobts.c
diff --git a/src/libbsc/bts_unknown.c b/src/osmo-bsc/bts_unknown.c
index 5ecf875c1..5ecf875c1 100644
--- a/src/libbsc/bts_unknown.c
+++ b/src/osmo-bsc/bts_unknown.c
diff --git a/src/libbsc/chan_alloc.c b/src/osmo-bsc/chan_alloc.c
index 4eccff0df..a24fbea94 100644
--- a/src/libbsc/chan_alloc.c
+++ b/src/osmo-bsc/chan_alloc.c
@@ -65,18 +65,6 @@ bool ts_is_usable(const struct gsm_bts_trx_ts *ts)
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
index e7398ed9c..e7398ed9c 100644
--- a/src/libbsc/e1_config.c
+++ b/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
index f30640fb1..5bfdf97ff 100644
--- a/src/libbsc/gsm_04_08_utils.c
+++ b/src/osmo-bsc/gsm_04_08_utils.c
@@ -302,26 +302,6 @@ static void gsm48_cell_desc(struct gsm48_cell_desc *cd,
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
index d67f3c568..d67f3c568 100644
--- a/src/libbsc/gsm_04_80_utils.c
+++ b/src/osmo-bsc/gsm_04_80_utils.c
diff --git a/src/libbsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
index ea2aea064..0f062d25a 100644
--- a/src/libbsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -648,6 +648,10 @@ static const struct gprs_rlc_cfg rlc_cfg_default = {
.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 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num)
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 @@ bool ts_is_tch(struct gsm_bts_trx_ts *ts)
{
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
index 14f5d8e84..14f5d8e84 100644
--- a/src/libbsc/handover_cfg.c
+++ b/src/osmo-bsc/handover_cfg.c
diff --git a/src/libbsc/handover_decision.c b/src/osmo-bsc/handover_decision.c
index 887c2993f..887c2993f 100644
--- a/src/libbsc/handover_decision.c
+++ b/src/osmo-bsc/handover_decision.c
diff --git a/src/libbsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c
index 7ac54df95..7ac54df95 100644
--- a/src/libbsc/handover_decision_2.c
+++ b/src/osmo-bsc/handover_decision_2.c
diff --git a/src/libbsc/handover_logic.c b/src/osmo-bsc/handover_logic.c
index 960bf6993..960bf6993 100644
--- a/src/libbsc/handover_logic.c
+++ b/src/osmo-bsc/handover_logic.c
diff --git a/src/libbsc/handover_vty.c b/src/osmo-bsc/handover_vty.c
index 51e448e03..51e448e03 100644
--- a/src/libbsc/handover_vty.c
+++ b/src/osmo-bsc/handover_vty.c
diff --git a/src/libbsc/meas_feed.c b/src/osmo-bsc/meas_feed.c
index 2e80754d4..2e80754d4 100644
--- a/src/libbsc/meas_feed.c
+++ b/src/osmo-bsc/meas_feed.c
diff --git a/src/libbsc/meas_rep.c b/src/osmo-bsc/meas_rep.c
index 73d9a1f21..73d9a1f21 100644
--- a/src/libbsc/meas_rep.c
+++ b/src/osmo-bsc/meas_rep.c
diff --git a/src/libbsc/net_init.c b/src/osmo-bsc/net_init.c
index f03a2e12f..db84e2a53 100644
--- a/src/libbsc/net_init.c
+++ b/src/osmo-bsc/net_init.c
@@ -22,28 +22,13 @@
#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)
+/* 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;
-
- net = talloc_zero(ctx, struct gsm_network);
+ struct gsm_network *net = talloc_zero(ctx, struct gsm_network);
if (!net)
return NULL;
@@ -65,17 +50,7 @@ struct gsm_network *bsc_network_init(void *ctx)
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);
-
+ INIT_LLIST_HEAD(&net->bts_list);
net->num_bts = 0;
net->T3101 = GSM_T3101_DEFAULT;
net->T3103 = GSM_T3103_DEFAULT;
@@ -90,28 +65,5 @@ struct gsm_network *bsc_network_init(void *ctx)
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/libbsc/osmo_bsc_lcls.c b/src/osmo-bsc/osmo_bsc_lcls.c
index c2b076090..c2b076090 100644
--- a/src/libbsc/osmo_bsc_lcls.c
+++ b/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 fefc04180..5c6a872b4 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 @@ static void handle_options(int argc, char **argv)
}
}
+/* 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
index d6bff2a42..d6bff2a42 100644
--- a/src/libbsc/paging.c
+++ b/src/osmo-bsc/paging.c
diff --git a/src/libbsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c
index 64422c724..64422c724 100644
--- a/src/libbsc/pcu_sock.c
+++ b/src/osmo-bsc/pcu_sock.c
diff --git a/src/libbsc/penalty_timers.c b/src/osmo-bsc/penalty_timers.c
index b80fec946..b80fec946 100644
--- a/src/libbsc/penalty_timers.c
+++ b/src/osmo-bsc/penalty_timers.c
diff --git a/src/libbsc/rest_octets.c b/src/osmo-bsc/rest_octets.c
index 9f2b4c0ab..9f2b4c0ab 100644
--- a/src/libbsc/rest_octets.c
+++ b/src/osmo-bsc/rest_octets.c
diff --git a/src/libbsc/system_information.c b/src/osmo-bsc/system_information.c
index d99153f24..d99153f24 100644
--- a/src/libbsc/system_information.c
+++ b/src/osmo-bsc/system_information.c
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
index 6e21ccc78..543344b53 100644
--- a/src/utils/Makefile.am
+++ b/src/utils/Makefile.am
@@ -46,15 +46,18 @@ endif
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 @@ osmo_meas_udp2db_CFLAGS = \
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 8d4de0152..ae307c796 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 @@ int main(int argc, char **argv)
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 000000000..624797fde
--- /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@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;
+}