aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2020-07-15 20:53:16 +0200
committerlaforge <laforge@osmocom.org>2020-07-18 21:45:32 +0000
commit388ed5848242f56a207abbc854aa5f2c519ffdb1 (patch)
treecba548f05a765304637cd04924c65ff17c5faef7 /src/osmo-bsc
parent6b23d7183235cce41d16adbeacf574e8551498d9 (diff)
Move struct gsm_bts: gsm_data.* => bts.*
Place all code related to the object into the related file. Having all the data model in one file made sense in early stage of development to make progress quickly, but nowadays it hurts more than helps, due to constantly growing size and more and more bits being added to the model, gaining in complexity. Currently, having lots of different objects mixed up in gsm_data.h is a hole of despair, where nobody can make any sense were to properly put new stuff in, ending up with functions related to same object in different files or with wrong prefixes, declarations of non-existing functions, etc. because people cannot make up their mind on strict relation to objects in the data model. Splitting them in files really helps finding code operating on a specific object and helping with logically splitting in the future. Change-Id: I00c15f5285b5c1a0109279b7ab192d5467a04ece
Diffstat (limited to 'src/osmo-bsc')
-rw-r--r--src/osmo-bsc/Makefile.am1
-rw-r--r--src/osmo-bsc/abis_nm.c9
-rw-r--r--src/osmo-bsc/abis_om2000.c1
-rw-r--r--src/osmo-bsc/abis_om2000_vty.c1
-rw-r--r--src/osmo-bsc/abis_rsl.c2
-rw-r--r--src/osmo-bsc/acc_ramp.c1
-rw-r--r--src/osmo-bsc/assignment_fsm.c1
-rw-r--r--src/osmo-bsc/bsc_ctrl_commands.c1
-rw-r--r--src/osmo-bsc/bsc_init.c19
-rw-r--r--src/osmo-bsc/bsc_rf_ctrl.c1
-rw-r--r--src/osmo-bsc/bsc_vty.c1
-rw-r--r--src/osmo-bsc/bts.c748
-rw-r--r--src/osmo-bsc/bts_ericsson_rbs2000.c1
-rw-r--r--src/osmo-bsc/bts_ipaccess_nanobts.c1
-rw-r--r--src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c2
-rw-r--r--src/osmo-bsc/bts_nokia_site.c1
-rw-r--r--src/osmo-bsc/bts_siemens_bs11.c1
-rw-r--r--src/osmo-bsc/bts_sysmobts.c1
-rw-r--r--src/osmo-bsc/bts_unknown.c1
-rw-r--r--src/osmo-bsc/cbch_scheduler.c1
-rw-r--r--src/osmo-bsc/chan_alloc.c1
-rw-r--r--src/osmo-bsc/codec_pref.c1
-rw-r--r--src/osmo-bsc/e1_config.c1
-rw-r--r--src/osmo-bsc/gsm_04_08_rr.c1
-rw-r--r--src/osmo-bsc/gsm_08_08.c1
-rw-r--r--src/osmo-bsc/gsm_data.c716
-rw-r--r--src/osmo-bsc/handover_decision.c1
-rw-r--r--src/osmo-bsc/handover_decision_2.c1
-rw-r--r--src/osmo-bsc/handover_fsm.c1
-rw-r--r--src/osmo-bsc/handover_logic.c1
-rw-r--r--src/osmo-bsc/handover_vty.c1
-rw-r--r--src/osmo-bsc/lchan_fsm.c2
-rw-r--r--src/osmo-bsc/lchan_rtp_fsm.c1
-rw-r--r--src/osmo-bsc/lchan_select.c1
-rw-r--r--src/osmo-bsc/meas_feed.c1
-rw-r--r--src/osmo-bsc/neighbor_ident_vty.c1
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c1
-rw-r--r--src/osmo-bsc/osmo_bsc_ctrl.c1
-rw-r--r--src/osmo-bsc/osmo_bsc_filter.c1
-rw-r--r--src/osmo-bsc/osmo_bsc_grace.c1
-rw-r--r--src/osmo-bsc/osmo_bsc_main.c1
-rw-r--r--src/osmo-bsc/osmo_bsc_msc.c1
-rw-r--r--src/osmo-bsc/osmo_bsc_sigtran.c1
-rw-r--r--src/osmo-bsc/paging.c1
-rw-r--r--src/osmo-bsc/pcu_sock.c1
-rw-r--r--src/osmo-bsc/rest_octets.c1
-rw-r--r--src/osmo-bsc/smscb.c1
-rw-r--r--src/osmo-bsc/system_information.c1
-rw-r--r--src/osmo-bsc/timeslot_fsm.c1
49 files changed, 813 insertions, 727 deletions
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index 0665af6f3..f66421ac3 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -43,6 +43,7 @@ osmo_bsc_SOURCES = \
bsc_subscr_conn_fsm.c \
bsc_subscriber.c \
bsc_vty.c \
+ bts.c \
bts_ericsson_rbs2000.c \
bts_init.c \
bts_ipaccess_nanobts.c \
diff --git a/src/osmo-bsc/abis_nm.c b/src/osmo-bsc/abis_nm.c
index 8dde8de9f..4ce27f3d9 100644
--- a/src/osmo-bsc/abis_nm.c
+++ b/src/osmo-bsc/abis_nm.c
@@ -48,6 +48,7 @@
#include <osmocom/bsc/signal.h>
#include <osmocom/abis/e1_input.h>
#include <osmocom/bsc/chan_alloc.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/gsm/bts_features.h>
#define OM_ALLOC_SIZE 1024
@@ -853,14 +854,6 @@ bool all_trx_rsl_connected_unlocked(const struct gsm_bts *bts)
return true;
}
-char *get_model_oml_status(const struct gsm_bts *bts)
-{
- if (bts->model->oml_status)
- return bts->model->oml_status(bts);
-
- return "unknown";
-}
-
void abis_nm_queue_send_next(struct gsm_bts *bts)
{
int wait = 0;
diff --git a/src/osmo-bsc/abis_om2000.c b/src/osmo-bsc/abis_om2000.c
index 0aea684c0..1e4ef9783 100644
--- a/src/osmo-bsc/abis_om2000.c
+++ b/src/osmo-bsc/abis_om2000.c
@@ -44,6 +44,7 @@
#include <osmocom/bsc/abis_om2000.h>
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/timeslot_fsm.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/abis/e1_input.h>
/* FIXME: move to libosmocore */
diff --git a/src/osmo-bsc/abis_om2000_vty.c b/src/osmo-bsc/abis_om2000_vty.c
index 222546f87..b00c7ddfe 100644
--- a/src/osmo-bsc/abis_om2000_vty.c
+++ b/src/osmo-bsc/abis_om2000_vty.c
@@ -33,6 +33,7 @@
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/abis_om2000.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/vty.h>
#include <osmocom/vty/vty.h>
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index f6e564b28..1ffdd06a5 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -54,7 +54,7 @@
#include <osmocom/bsc/lchan_rtp_fsm.h>
#include <osmocom/bsc/handover_fsm.h>
#include <osmocom/bsc/smscb.h>
-
+#include <osmocom/bsc/bts.h>
#define RSL_ALLOC_SIZE 1024
#define RSL_ALLOC_HEADROOM 128
diff --git a/src/osmo-bsc/acc_ramp.c b/src/osmo-bsc/acc_ramp.c
index b79c0c2ac..761ab093c 100644
--- a/src/osmo-bsc/acc_ramp.c
+++ b/src/osmo-bsc/acc_ramp.c
@@ -29,6 +29,7 @@
#include <osmocom/bsc/chan_alloc.h>
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/abis_nm.h>
+#include <osmocom/bsc/bts.h>
/*
* Check if an ACC has been permanently barred for a BTS,
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index cd5abc857..ca29daabb 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -34,6 +34,7 @@
#include <osmocom/bsc/gsm_08_08.h>
#include <osmocom/bsc/lchan_select.h>
#include <osmocom/bsc/abis_rsl.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/assignment_fsm.h>
diff --git a/src/osmo-bsc/bsc_ctrl_commands.c b/src/osmo-bsc/bsc_ctrl_commands.c
index 774ded21b..9383167fb 100644
--- a/src/osmo-bsc/bsc_ctrl_commands.c
+++ b/src/osmo-bsc/bsc_ctrl_commands.c
@@ -30,6 +30,7 @@
#include <osmocom/bsc/chan_alloc.h>
#include <osmocom/bsc/osmo_bsc_rf.h>
#include <osmocom/bsc/bsc_msc_data.h>
+#include <osmocom/bsc/bts.h>
CTRL_CMD_DEFINE(net_mcc, "mcc");
static int get_net_mcc(struct ctrl_cmd *cmd, void *_data)
diff --git a/src/osmo-bsc/bsc_init.c b/src/osmo-bsc/bsc_init.c
index 733353352..4fc0ab1bc 100644
--- a/src/osmo-bsc/bsc_init.c
+++ b/src/osmo-bsc/bsc_init.c
@@ -36,6 +36,7 @@
#include <osmocom/bsc/handover_cfg.h>
#include <osmocom/bsc/gsm_04_08_rr.h>
#include <osmocom/bsc/neighbor_ident.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/smscb.h>
#include <osmocom/gsm/protocol/gsm_48_049.h>
@@ -68,24 +69,6 @@ int bsc_shutdown_net(struct gsm_network *net)
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;
diff --git a/src/osmo-bsc/bsc_rf_ctrl.c b/src/osmo-bsc/bsc_rf_ctrl.c
index c72154a02..1e04f21c3 100644
--- a/src/osmo-bsc/bsc_rf_ctrl.c
+++ b/src/osmo-bsc/bsc_rf_ctrl.c
@@ -26,6 +26,7 @@
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/ipaccess.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 36b16a21e..aa08e8b30 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -73,6 +73,7 @@
#include <osmocom/bsc/lchan_select.h>
#include <osmocom/bsc/smscb.h>
#include <osmocom/bsc/osmo_bsc.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
#include <inttypes.h>
diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c
new file mode 100644
index 000000000..71968f640
--- /dev/null
+++ b/src/osmo-bsc/bts.c
@@ -0,0 +1,748 @@
+/* (C) 2008-2018 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2020 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 <osmocom/gsm/abis_nm.h>
+
+#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/bts.h>
+#include <osmocom/bsc/debug.h>
+
+const struct value_string bts_attribute_names[] = {
+ OSMO_VALUE_STRING(BTS_TYPE_VARIANT),
+ OSMO_VALUE_STRING(BTS_SUB_MODEL),
+ OSMO_VALUE_STRING(TRX_PHY_VERSION),
+ { 0, NULL }
+};
+
+enum bts_attribute str2btsattr(const char *s)
+{
+ return get_string_value(bts_attribute_names, s);
+}
+
+const char *btsatttr2str(enum bts_attribute v)
+{
+ return get_value_string(bts_attribute_names, v);
+}
+
+const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
+ { BTS_UNKNOWN, "unknown" },
+ { BTS_OSMO_LITECELL15, "osmo-bts-lc15" },
+ { BTS_OSMO_OCTPHY, "osmo-bts-octphy" },
+ { BTS_OSMO_SYSMO, "osmo-bts-sysmo" },
+ { BTS_OSMO_TRX, "omso-bts-trx" },
+ { 0, NULL }
+};
+
+enum gsm_bts_type_variant str2btsvariant(const char *arg)
+{
+ return get_string_value(osmo_bts_variant_names, arg);
+}
+
+const char *btsvariant2str(enum gsm_bts_type_variant v)
+{
+ return get_value_string(osmo_bts_variant_names, v);
+}
+
+const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = {
+ { GSM_BTS_TYPE_UNKNOWN, "unknown" },
+ { GSM_BTS_TYPE_BS11, "bs11" },
+ { GSM_BTS_TYPE_NANOBTS, "nanobts" },
+ { GSM_BTS_TYPE_RBS2000, "rbs2000" },
+ { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" },
+ { GSM_BTS_TYPE_OSMOBTS, "sysmobts" },
+ { 0, NULL }
+};
+
+const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = {
+ { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" },
+ { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" },
+ { GSM_BTS_TYPE_NANOBTS, "ip.access nanoBTS or compatible" },
+ { GSM_BTS_TYPE_RBS2000, "Ericsson RBS2000 Series" },
+ { GSM_BTS_TYPE_NOKIA_SITE, "Nokia {Metro,Ultra,In}Site" },
+ { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" },
+ { 0, NULL }
+};
+
+enum gsm_bts_type str2btstype(const char *arg)
+{
+ return get_string_value(bts_type_names, arg);
+}
+
+const char *btstype2str(enum gsm_bts_type type)
+{
+ return get_value_string(bts_type_names, type);
+}
+
+static void bts_init_cbch_state(struct bts_smscb_chan_state *cstate, struct gsm_bts *bts)
+{
+ cstate->bts = bts;
+ INIT_LLIST_HEAD(&cstate->messages);
+}
+
+static LLIST_HEAD(bts_models);
+
+struct gsm_bts_model *bts_model_find(enum gsm_bts_type type)
+{
+ struct gsm_bts_model *model;
+
+ llist_for_each_entry(model, &bts_models, list) {
+ if (model->type == type)
+ return model;
+ }
+
+ return NULL;
+}
+
+int gsm_bts_model_register(struct gsm_bts_model *model)
+{
+ if (bts_model_find(model->type))
+ return -EEXIST;
+
+ tlv_def_patch(&model->nm_att_tlvdef, &abis_nm_att_tlvdef);
+ llist_add_tail(&model->list, &bts_models);
+ return 0;
+}
+
+static const struct osmo_stat_item_desc bts_stat_desc[] = {
+ [BTS_STAT_CHAN_LOAD_AVERAGE] = { "chanloadavg", "Channel load average", "%", 16, 0 },
+ [BTS_STAT_CHAN_CCCH_SDCCH4_USED] = { "chan_ccch_sdcch4:used",
+ "Number of CCCH+SDCCH4 channels used", "", 16, 0 },
+ [BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL] = { "chan_ccch_sdcch4:total",
+ "Number of CCCH+SDCCH4 channels total", "", 16, 0 },
+ [BTS_STAT_CHAN_TCH_F_USED] = { "chan_tch_f:used",
+ "Number of TCH/F channels used", "", 16, 0 },
+ [BTS_STAT_CHAN_TCH_F_TOTAL] = { "chan_tch_f:total",
+ "Number of TCH/F channels total", "", 16, 0 },
+ [BTS_STAT_CHAN_TCH_H_USED] = { "chan_tch_h:used",
+ "Number of TCH/H channels used", "", 16, 0 },
+ [BTS_STAT_CHAN_TCH_H_TOTAL] = { "chan_tch_h:total",
+ "Number of TCH/H channels total", "", 16, 0 },
+ [BTS_STAT_CHAN_SDCCH8_USED] = { "chan_sdcch8:used",
+ "Number of SDCCH8 channels used", "", 16, 0 },
+ [BTS_STAT_CHAN_SDCCH8_TOTAL] = { "chan_sdcch8:total",
+ "Number of SDCCH8 channels total", "", 16, 0 },
+ [BTS_STAT_CHAN_TCH_F_PDCH_USED] = { "chan_tch_f_pdch:used",
+ "Number of TCH/F_PDCH channels used", "", 16, 0 },
+ [BTS_STAT_CHAN_TCH_F_PDCH_TOTAL] = { "chan_tch_f_pdch:total",
+ "Number of TCH/F_PDCH channels total", "", 16, 0 },
+ [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED] = { "chan_ccch_sdcch4_cbch:used",
+ "Number of CCCH+SDCCH4+CBCH channels used", "", 16, 0 },
+ [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL] = { "chan_ccch_sdcch4_cbch:total",
+ "Number of CCCH+SDCCH4+CBCH channels total", "", 16, 0 },
+ [BTS_STAT_CHAN_SDCCH8_CBCH_USED] = { "chan_sdcch8_cbch:used",
+ "Number of SDCCH8+CBCH channels used", "", 16, 0 },
+ [BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL] = { "chan_sdcch8_cbch:total",
+ "Number of SDCCH8+CBCH channels total", "", 16, 0 },
+ [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED] = { "chan_tch_f_tch_h_pdch:used",
+ "Number of TCH/F_TCH/H_PDCH channels used", "", 16, 0 },
+ [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL] = { "chan_tch_f_tch_h_pdch:total",
+ "Number of TCH/F_TCH/H_PDCH channels total", "", 16, 0 },
+ [BTS_STAT_T3122] = { "T3122", "T3122 IMMEDIATE ASSIGNMENT REJECT wait indicator",
+ "s", 16, GSM_T3122_DEFAULT },
+ [BTS_STAT_RACH_BUSY] = { "rach_busy",
+ "RACH slots with signal above threshold", "%", 16, 0 },
+ [BTS_STAT_RACH_ACCESS] = { "rach_access",
+ "RACH slots with access bursts in them", "%", 16, 0 },
+ [BTS_STAT_OML_CONNECTED] = { "oml_connected", "Number of OML links connected", "", 16, 0 },
+ [BTS_STAT_RSL_CONNECTED] = { "rsl_connected", "Number of RSL links connected", "", 16, 0 },
+ [BTS_STAT_LCHAN_BORKEN] = { "lchan_borken",
+ "Number of lchans in the BORKEN state", "", 16, 0 },
+ [BTS_STAT_TS_BORKEN] = { "ts_borken",
+ "Number of timeslots in the BORKEN state", "", 16, 0 },
+};
+
+static const struct osmo_stat_item_group_desc bts_statg_desc = {
+ .group_name_prefix = "bts",
+ .group_description = "base transceiver station",
+ .class_id = OSMO_STATS_CLASS_GLOBAL,
+ .num_items = ARRAY_SIZE(bts_stat_desc),
+ .item_desc = bts_stat_desc,
+};
+
+static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
+static const uint8_t bts_cell_timer_default[] =
+ { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
+static const struct gprs_rlc_cfg rlc_cfg_default = {
+ .parameter = {
+ [RLC_T3142] = 20,
+ [RLC_T3169] = 5,
+ [RLC_T3191] = 5,
+ [RLC_T3193] = 160, /* 10ms */
+ [RLC_T3195] = 5,
+ [RLC_N3101] = 10,
+ [RLC_N3103] = 4,
+ [RLC_N3105] = 8,
+ [CV_COUNTDOWN] = 15,
+ [T_DL_TBF_EXT] = 250 * 10, /* ms */
+ [T_UL_TBF_EXT] = 250 * 10, /* ms */
+ },
+ .paging = {
+ .repeat_time = 5 * 50, /* ms */
+ .repeat_count = 3,
+ },
+ .cs_mask = 0x1fff,
+ .initial_cs = 2,
+ .initial_mcs = 6,
+};
+
+/* 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);
+ struct gsm48_multi_rate_conf mr_cfg;
+ int i;
+
+ if (!bts)
+ return NULL;
+
+ bts->nr = bts_num;
+ bts->num_trx = 0;
+ INIT_LLIST_HEAD(&bts->trx_list);
+ bts->network = net;
+
+ bts->ms_max_power = 15; /* dBm */
+
+ gsm_mo_init(&bts->mo, bts, NM_OC_BTS,
+ bts->nr, 0xff, 0xff);
+ gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
+ 0xff, 0xff, 0xff);
+
+ for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
+ bts->gprs.nsvc[i].bts = bts;
+ bts->gprs.nsvc[i].id = i;
+ gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
+ bts->nr, i, 0xff);
+ }
+ memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
+ sizeof(bts->gprs.nse.timer));
+ gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
+ bts->nr, 0xff, 0xff);
+ memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
+ sizeof(bts->gprs.cell.timer));
+ gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
+ bts->nr, 0xff, 0xff);
+ memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
+ sizeof(bts->gprs.cell.rlc_cfg));
+
+ /* 3GPP TS 08.18, chapter 5.4.1: 0 is reserved for signalling */
+ bts->gprs.cell.bvci = 2;
+
+ /* init statistics */
+ bts->bts_ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);
+ if (!bts->bts_ctrs) {
+ talloc_free(bts);
+ return NULL;
+ }
+ bts->bts_statg = osmo_stat_item_group_alloc(bts, &bts_statg_desc, bts->nr);
+
+ /* create our primary TRX */
+ bts->c0 = gsm_bts_trx_alloc(bts);
+ if (!bts->c0) {
+ rate_ctr_group_free(bts->bts_ctrs);
+ osmo_stat_item_group_free(bts->bts_statg);
+ talloc_free(bts);
+ return NULL;
+ }
+ bts->c0->ts[0].pchan_from_config = GSM_PCHAN_CCCH_SDCCH4; /* TODO: really?? */
+
+ bts->ccch_load_ind_thresh = 10; /* 10% of Load: Start sending CCCH LOAD IND */
+ bts->rach_b_thresh = -1;
+ bts->rach_ldavg_slots = -1;
+
+ bts->paging.free_chans_need = -1;
+ INIT_LLIST_HEAD(&bts->paging.pending_requests);
+
+ bts->features.data = &bts->_features_data[0];
+ bts->features.data_len = sizeof(bts->_features_data);
+
+ /* si handling */
+ bts->bcch_change_mark = 1;
+ bts->chan_load_avg = 0;
+
+ /* timer overrides */
+ bts->T3122 = 0; /* not overridden by default */
+ bts->T3113_dynamic = true; /* dynamic by default */
+
+ bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
+ bts->dtxd = false;
+ bts->gprs.ctrl_ack_type_use_block = true; /* use RLC/MAC control block */
+ bts->neigh_list_manual_mode = NL_MODE_AUTOMATIC;
+ bts->early_classmark_allowed_3g = true; /* 3g Early Classmark Sending controlled by bts->early_classmark_allowed param */
+ bts->si_unused_send_empty = true;
+ bts->si_common.cell_sel_par.cell_resel_hyst = 2; /* 4 dB */
+ bts->si_common.cell_sel_par.rxlev_acc_min = 0;
+ bts->si_common.si2quater_neigh_list.arfcn = bts->si_common.data.earfcn_list;
+ bts->si_common.si2quater_neigh_list.meas_bw = bts->si_common.data.meas_bw_list;
+ bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;
+ bts->si_common.si2quater_neigh_list.thresh_hi = 0;
+ osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);
+ bts->si_common.neigh_list.data = bts->si_common.data.neigh_list;
+ bts->si_common.neigh_list.data_len =
+ sizeof(bts->si_common.data.neigh_list);
+ bts->si_common.si5_neigh_list.data = bts->si_common.data.si5_neigh_list;
+ bts->si_common.si5_neigh_list.data_len =
+ sizeof(bts->si_common.data.si5_neigh_list);
+ bts->si_common.cell_alloc.data = bts->si_common.data.cell_alloc;
+ bts->si_common.cell_alloc.data_len =
+ sizeof(bts->si_common.data.cell_alloc);
+ bts->si_common.rach_control.re = 1; /* no re-establishment */
+ bts->si_common.rach_control.tx_integer = 9; /* 12 slots spread - 217/115 slots delay */
+ bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */
+ bts->si_common.rach_control.t2 = 4; /* no emergency calls */
+ bts->si_common.chan_desc.att = 1; /* attachment required */
+ bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */
+ bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */
+ bts->si_common.chan_desc.t3212 = osmo_tdef_get(net->T_defs, 3212, OSMO_TDEF_CUSTOM, -1);
+ gsm_bts_set_radio_link_timeout(bts, 32); /* Use RADIO LINK TIMEOUT of 32 */
+
+ INIT_LLIST_HEAD(&bts->abis_queue);
+ INIT_LLIST_HEAD(&bts->loc_list);
+ INIT_LLIST_HEAD(&bts->local_neighbors);
+ INIT_LLIST_HEAD(&bts->oml_fail_rep);
+
+ /* Enable all codecs by default. These get reset to a more fine grained selection IF a
+ * 'codec-support' config appears in the config file (see bsc_vty.c). */
+ bts->codec = (struct bts_codec_conf){
+ .hr = 1,
+ .efr = 1,
+ .amr = 1,
+ };
+
+ /* Set reasonable defaults for AMR-FR and AMR-HR rate configuration.
+ * (see also 3GPP TS 28.062, Table 7.11.3.1.3-2) */
+ mr_cfg = (struct gsm48_multi_rate_conf) {
+ .m4_75 = 1,
+ .m5_15 = 0,
+ .m5_90 = 1,
+ .m6_70 = 0,
+ .m7_40 = 1,
+ .m7_95 = 0,
+ .m10_2 = 0,
+ .m12_2 = 1
+ };
+ memcpy(bts->mr_full.gsm48_ie, &mr_cfg, sizeof(bts->mr_full.gsm48_ie));
+ bts->mr_full.ms_mode[0].mode = 0;
+ bts->mr_full.ms_mode[1].mode = 2;
+ bts->mr_full.ms_mode[2].mode = 4;
+ bts->mr_full.ms_mode[3].mode = 7;
+ bts->mr_full.bts_mode[0].mode = 0;
+ bts->mr_full.bts_mode[1].mode = 2;
+ bts->mr_full.bts_mode[2].mode = 4;
+ bts->mr_full.bts_mode[3].mode = 7;
+ for (i = 0; i < 3; i++) {
+ bts->mr_full.ms_mode[i].hysteresis = 8;
+ bts->mr_full.ms_mode[i].threshold = 32;
+ bts->mr_full.bts_mode[i].hysteresis = 8;
+ bts->mr_full.bts_mode[i].threshold = 32;
+ }
+ bts->mr_full.num_modes = 4;
+
+ mr_cfg = (struct gsm48_multi_rate_conf) {
+ .m4_75 = 1,
+ .m5_15 = 0,
+ .m5_90 = 1,
+ .m6_70 = 0,
+ .m7_40 = 1,
+ .m7_95 = 0,
+ .m10_2 = 0,
+ .m12_2 = 0
+ };
+ memcpy(bts->mr_half.gsm48_ie, &mr_cfg, sizeof(bts->mr_half.gsm48_ie));
+ bts->mr_half.ms_mode[0].mode = 0;
+ bts->mr_half.ms_mode[1].mode = 2;
+ bts->mr_half.ms_mode[2].mode = 4;
+ bts->mr_half.ms_mode[3].mode = 7;
+ bts->mr_half.bts_mode[0].mode = 0;
+ bts->mr_half.bts_mode[1].mode = 2;
+ bts->mr_half.bts_mode[2].mode = 4;
+ bts->mr_half.bts_mode[3].mode = 7;
+ for (i = 0; i < 3; i++) {
+ bts->mr_half.ms_mode[i].hysteresis = 8;
+ bts->mr_half.ms_mode[i].threshold = 32;
+ bts->mr_half.bts_mode[i].hysteresis = 8;
+ bts->mr_half.bts_mode[i].threshold = 32;
+ }
+ bts->mr_half.num_modes = 3;
+
+ bts_init_cbch_state(&bts->cbch_basic, bts);
+ bts_init_cbch_state(&bts->cbch_extended, bts);
+
+ return bts;
+}
+
+static char ts2str[255];
+
+char *gsm_bts_name(const struct gsm_bts *bts)
+{
+ if (!bts)
+ snprintf(ts2str, sizeof(ts2str), "(bts=NULL)");
+ else
+ snprintf(ts2str, sizeof(ts2str), "(bts=%d)", bts->nr);
+
+ return ts2str;
+}
+
+bool gsm_bts_matches_lai(const struct gsm_bts *bts, const struct osmo_location_area_id *lai)
+{
+ return osmo_plmn_cmp(&lai->plmn, &bts->network->plmn) == 0
+ && lai->lac == bts->location_area_code;
+}
+
+bool gsm_bts_matches_cell_id(const struct gsm_bts *bts, const struct gsm0808_cell_id *cell_id)
+{
+ const union gsm0808_cell_id_u *id = &cell_id->id;
+ if (!bts || !cell_id)
+ return false;
+
+ switch (cell_id->id_discr) {
+ case CELL_IDENT_WHOLE_GLOBAL:
+ return gsm_bts_matches_lai(bts, &id->global.lai)
+ && id->global.cell_identity == bts->cell_identity;
+ case CELL_IDENT_LAC_AND_CI:
+ return id->lac_and_ci.lac == bts->location_area_code
+ && id->lac_and_ci.ci == bts->cell_identity;
+ case CELL_IDENT_CI:
+ return id->ci == bts->cell_identity;
+ case CELL_IDENT_NO_CELL:
+ return false;
+ case CELL_IDENT_LAI_AND_LAC:
+ return gsm_bts_matches_lai(bts, &id->lai_and_lac);
+ case CELL_IDENT_LAC:
+ return id->lac == bts->location_area_code;
+ case CELL_IDENT_BSS:
+ return true;
+ case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
+ case CELL_IDENT_UTRAN_RNC:
+ case CELL_IDENT_UTRAN_LAC_RNC:
+ return false;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static struct gsm_bts_ref *gsm_bts_ref_find(const struct llist_head *list, const struct gsm_bts *bts)
+{
+ struct gsm_bts_ref *ref;
+ if (!bts)
+ return NULL;
+ llist_for_each_entry(ref, list, entry) {
+ if (ref->bts == bts)
+ return ref;
+ }
+ return NULL;
+}
+
+/* Add a BTS reference to the local_neighbors list.
+ * Return 1 if added, 0 if such an entry already existed, and negative on errors. */
+int gsm_bts_local_neighbor_add(struct gsm_bts *bts, struct gsm_bts *neighbor)
+{
+ struct gsm_bts_ref *ref;
+ if (!bts || !neighbor)
+ return -ENOMEM;
+
+ if (bts == neighbor)
+ return -EINVAL;
+
+ /* Already got this entry? */
+ ref = gsm_bts_ref_find(&bts->local_neighbors, neighbor);
+ if (ref)
+ return 0;
+
+ ref = talloc_zero(bts, struct gsm_bts_ref);
+ if (!ref)
+ return -ENOMEM;
+ ref->bts = neighbor;
+ llist_add_tail(&ref->entry, &bts->local_neighbors);
+ return 1;
+}
+
+/* Remove a BTS reference from the local_neighbors list.
+ * Return 1 if removed, 0 if no such entry existed, and negative on errors. */
+int gsm_bts_local_neighbor_del(struct gsm_bts *bts, const struct gsm_bts *neighbor)
+{
+ struct gsm_bts_ref *ref;
+ if (!bts || !neighbor)
+ return -ENOMEM;
+
+ ref = gsm_bts_ref_find(&bts->local_neighbors, neighbor);
+ if (!ref)
+ return 0;
+
+ llist_del(&ref->entry);
+ talloc_free(ref);
+ return 1;
+}
+
+/* return the gsm_lchan for the CBCH (if it exists at all) */
+struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)
+{
+ struct gsm_lchan *lchan = NULL;
+ struct gsm_bts_trx *trx = bts->c0;
+
+ if (trx->ts[0].pchan_from_config == GSM_PCHAN_CCCH_SDCCH4_CBCH)
+ lchan = &trx->ts[0].lchan[2];
+ else {
+ int i;
+ for (i = 0; i < 8; i++) {
+ if (trx->ts[i].pchan_from_config == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
+ lchan = &trx->ts[i].lchan[2];
+ break;
+ }
+ }
+ }
+
+ return lchan;
+}
+
+int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type)
+{
+ struct gsm_bts_model *model;
+
+ model = bts_model_find(type);
+ if (!model)
+ return -EINVAL;
+
+ bts->type = type;
+ bts->model = model;
+
+ if (model->start && !model->started) {
+ int ret = model->start(bts->network);
+ if (ret < 0)
+ return ret;
+
+ model->started = true;
+ }
+
+ switch (bts->type) {
+ case GSM_BTS_TYPE_NANOBTS:
+ case GSM_BTS_TYPE_OSMOBTS:
+ /* Set the default OML Stream ID to 0xff */
+ bts->oml_tei = 0xff;
+ bts->c0->nominal_power = 23;
+ break;
+ case GSM_BTS_TYPE_RBS2000:
+ INIT_LLIST_HEAD(&bts->rbs2000.is.conn_groups);
+ INIT_LLIST_HEAD(&bts->rbs2000.con.conn_groups);
+ break;
+ case GSM_BTS_TYPE_BS11:
+ case GSM_BTS_TYPE_UNKNOWN:
+ case GSM_BTS_TYPE_NOKIA_SITE:
+ /* Set default BTS reset timer */
+ bts->nokia.bts_reset_timer_cnf = 15;
+ case _NUM_GSM_BTS_TYPE:
+ break;
+ }
+
+ return 0;
+}
+
+int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode)
+{
+ if (mode != BTS_GPRS_NONE &&
+ !osmo_bts_has_feature(&bts->model->features, BTS_FEAT_GPRS)) {
+ return 0;
+ }
+ if (mode == BTS_GPRS_EGPRS &&
+ !osmo_bts_has_feature(&bts->model->features, BTS_FEAT_EGPRS)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr)
+{
+ struct gsm_bts_trx *trx;
+
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ if (trx->nr == nr)
+ return trx;
+ }
+ return NULL;
+}
+
+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);
+}
+
+char *get_model_oml_status(const struct gsm_bts *bts)
+{
+ if (bts->model->oml_status)
+ return bts->model->oml_status(bts);
+
+ return "unknown";
+}
+
+/* reset the state of all MO in the BTS */
+void gsm_bts_mo_reset(struct gsm_bts *bts)
+{
+ struct gsm_bts_trx *trx;
+ unsigned int i;
+
+ gsm_abis_mo_reset(&bts->mo);
+ gsm_abis_mo_reset(&bts->site_mgr.mo);
+ for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++)
+ gsm_abis_mo_reset(&bts->gprs.nsvc[i].mo);
+ gsm_abis_mo_reset(&bts->gprs.nse.mo);
+ gsm_abis_mo_reset(&bts->gprs.cell.mo);
+
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ gsm_abis_mo_reset(&trx->mo);
+ gsm_abis_mo_reset(&trx->bb_transc.mo);
+
+ for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
+ struct gsm_bts_trx_ts *ts = &trx->ts[i];
+ gsm_abis_mo_reset(&ts->mo);
+ }
+ }
+}
+
+/* Assume there are only 256 possible bts */
+osmo_static_assert(sizeof(((struct gsm_bts *) 0)->nr) == 1, _bts_nr_is_256);
+static void depends_calc_index_bit(int bts_nr, int *idx, int *bit)
+{
+ *idx = bts_nr / (8 * 4);
+ *bit = bts_nr % (8 * 4);
+}
+
+void bts_depend_mark(struct gsm_bts *bts, int dep)
+{
+ int idx, bit;
+ depends_calc_index_bit(dep, &idx, &bit);
+
+ bts->depends_on[idx] |= 1 << bit;
+}
+
+void bts_depend_clear(struct gsm_bts *bts, int dep)
+{
+ int idx, bit;
+ depends_calc_index_bit(dep, &idx, &bit);
+
+ bts->depends_on[idx] &= ~(1 << bit);
+}
+
+int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)
+{
+ int idx, bit;
+ depends_calc_index_bit(other->nr, &idx, &bit);
+
+ /* Check if there is a depends bit */
+ return (base->depends_on[idx] & (1 << bit)) > 0;
+}
+
+static int bts_is_online(struct gsm_bts *bts)
+{
+ /* TODO: support E1 BTS too */
+ if (!is_ipaccess_bts(bts))
+ return 1;
+
+ if (!bts->oml_link)
+ return 0;
+
+ return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED;
+}
+
+int bts_depend_check(struct gsm_bts *bts)
+{
+ struct gsm_bts *other_bts;
+
+ llist_for_each_entry(other_bts, &bts->network->bts_list, list) {
+ if (!bts_depend_is_depedency(bts, other_bts))
+ continue;
+ if (bts_is_online(other_bts))
+ continue;
+ return 0;
+ }
+ return 1;
+}
+
+/* get the radio link timeout (based on SACCH decode errors, according
+ * to algorithm specified in TS 05.08 section 5.2. A value of -1
+ * indicates we should use an infinitely long timeout, which only works
+ * with OsmoBTS as the BTS implementation */
+int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts)
+{
+ const struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
+
+ if (bts->infinite_radio_link_timeout)
+ return -1;
+ else {
+ /* Encoding as per Table 10.5.21 of TS 04.08 */
+ return (cell_options->radio_link_timeout + 1) << 2;
+ }
+}
+
+/* set the radio link timeout (based on SACCH decode errors, according
+ * to algorithm specified in TS 05.08 Section 5.2. A value of -1
+ * indicates we should use an infinitely long timeout, which only works
+ * with OsmoBTS as the BTS implementation */
+void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value)
+{
+ struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
+
+ if (value < 0)
+ bts->infinite_radio_link_timeout = true;
+ else {
+ bts->infinite_radio_link_timeout = false;
+ /* Encoding as per Table 10.5.21 of TS 04.08 */
+ if (value < 4)
+ value = 4;
+ if (value > 64)
+ value = 64;
+ cell_options->radio_link_timeout = (value >> 2) - 1;
+ }
+}
+
+void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data)
+{
+ struct gsm_bts_trx *trx;
+ llist_for_each_entry(trx, &bts->trx_list, list)
+ gsm_trx_all_ts_dispatch(trx, ts_ev, data);
+}
+
+
+/* Count number of free TS of given pchan type */
+int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
+{
+ struct gsm_bts_trx *trx;
+ int count = 0;
+
+ llist_for_each_entry(trx, &bts->trx_list, list)
+ count += trx_count_free_ts(trx, pchan);
+
+ return count;
+}
diff --git a/src/osmo-bsc/bts_ericsson_rbs2000.c b/src/osmo-bsc/bts_ericsson_rbs2000.c
index 02ef46387..1297b3025 100644
--- a/src/osmo-bsc/bts_ericsson_rbs2000.c
+++ b/src/osmo-bsc/bts_ericsson_rbs2000.c
@@ -29,6 +29,7 @@
#include <osmocom/abis/e1_input.h>
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/timeslot_fsm.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/abis/lapd.h>
diff --git a/src/osmo-bsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c
index 5b603671e..49720e5c2 100644
--- a/src/osmo-bsc/bts_ipaccess_nanobts.c
+++ b/src/osmo-bsc/bts_ipaccess_nanobts.c
@@ -45,6 +45,7 @@
#include <osmocom/bsc/bts_ipaccess_nanobts_omlattr.h>
#include <osmocom/bsc/paging.h>
#include <osmocom/bsc/timeslot_fsm.h>
+#include <osmocom/bsc/bts.h>
static int bts_model_nanobts_start(struct gsm_network *net);
static void bts_model_nanobts_e1line_bind_ops(struct e1inp_line *line);
diff --git a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
index be823ae43..b979cc73d 100644
--- a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
+++ b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
@@ -23,7 +23,7 @@
#include <osmocom/core/msgb.h>
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/abis_nm.h>
-
+#include <osmocom/bsc/bts.h>
struct msgb *nanobts_attr_bts_get(struct gsm_bts *bts)
{
diff --git a/src/osmo-bsc/bts_nokia_site.c b/src/osmo-bsc/bts_nokia_site.c
index 523c9edf3..2b6f91876 100644
--- a/src/osmo-bsc/bts_nokia_site.c
+++ b/src/osmo-bsc/bts_nokia_site.c
@@ -37,6 +37,7 @@
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/timeslot_fsm.h>
#include <osmocom/bsc/system_information.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/core/timer.h>
diff --git a/src/osmo-bsc/bts_siemens_bs11.c b/src/osmo-bsc/bts_siemens_bs11.c
index 057a0e153..c8084214f 100644
--- a/src/osmo-bsc/bts_siemens_bs11.c
+++ b/src/osmo-bsc/bts_siemens_bs11.c
@@ -30,6 +30,7 @@
#include <osmocom/abis/e1_input.h>
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/timeslot_fsm.h>
+#include <osmocom/bsc/bts.h>
static int bts_model_bs11_start(struct gsm_network *net);
diff --git a/src/osmo-bsc/bts_sysmobts.c b/src/osmo-bsc/bts_sysmobts.c
index 6f9dc77cb..df43d76ae 100644
--- a/src/osmo-bsc/bts_sysmobts.c
+++ b/src/osmo-bsc/bts_sysmobts.c
@@ -26,6 +26,7 @@
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/abis_nm.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/abis/e1_input.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/msgb.h>
diff --git a/src/osmo-bsc/bts_unknown.c b/src/osmo-bsc/bts_unknown.c
index b6b56a81b..b5471ce0c 100644
--- a/src/osmo-bsc/bts_unknown.c
+++ b/src/osmo-bsc/bts_unknown.c
@@ -21,6 +21,7 @@
#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/bsc/abis_nm.h>
diff --git a/src/osmo-bsc/cbch_scheduler.c b/src/osmo-bsc/cbch_scheduler.c
index ef93b7a4a..802180419 100644
--- a/src/osmo-bsc/cbch_scheduler.c
+++ b/src/osmo-bsc/cbch_scheduler.c
@@ -28,6 +28,7 @@
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/smscb.h>
#include <osmocom/bsc/abis_rsl.h>
+#include <osmocom/bsc/bts.h>
/* add all pages of given SMSCB so they appear as soon as possible *after* (included) base_idx. */
static int bts_smscb_sched_add_after(struct bts_smscb_page **sched_arr, int sched_arr_size,
diff --git a/src/osmo-bsc/chan_alloc.c b/src/osmo-bsc/chan_alloc.c
index 9b80df3f5..6829251e3 100644
--- a/src/osmo-bsc/chan_alloc.c
+++ b/src/osmo-bsc/chan_alloc.c
@@ -34,6 +34,7 @@
#include <osmocom/bsc/timeslot_fsm.h>
#include <osmocom/bsc/lchan_fsm.h>
#include <osmocom/bsc/gsm_04_08_rr.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/core/talloc.h>
diff --git a/src/osmo-bsc/codec_pref.c b/src/osmo-bsc/codec_pref.c
index 6ec6d05ec..58a7867c5 100644
--- a/src/osmo-bsc/codec_pref.c
+++ b/src/osmo-bsc/codec_pref.c
@@ -27,6 +27,7 @@
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/codec_pref.h>
#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/bts.h>
/* Determine whether a permitted speech value is specifies a half rate or full
* rate codec */
diff --git a/src/osmo-bsc/e1_config.c b/src/osmo-bsc/e1_config.c
index 4389f66c9..9ccbbfd70 100644
--- a/src/osmo-bsc/e1_config.c
+++ b/src/osmo-bsc/e1_config.c
@@ -30,6 +30,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/abis_rsl.h>
+#include <osmocom/bsc/bts.h>
#define SAPI_L2ML 0
#define SAPI_OML 62
diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c
index 07978de30..e54a93719 100644
--- a/src/osmo-bsc/gsm_04_08_rr.c
+++ b/src/osmo-bsc/gsm_04_08_rr.c
@@ -44,6 +44,7 @@
#include <osmocom/bsc/gsm_08_08.h>
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/system_information.h>
+#include <osmocom/bsc/bts.h>
int gsm48_sendmsg(struct msgb *msg)
diff --git a/src/osmo-bsc/gsm_08_08.c b/src/osmo-bsc/gsm_08_08.c
index 2829b67c7..d5915f4f0 100644
--- a/src/osmo-bsc/gsm_08_08.c
+++ b/src/osmo-bsc/gsm_08_08.c
@@ -36,6 +36,7 @@
#include <osmocom/gsm/gsm23236.h>
#include <osmocom/bsc/osmo_bsc_sigtran.h>
+#include <osmocom/bsc/bts.h>
#define LOG_COMPL_L3(pdisc, mtype, loglevel, format, args...) \
LOGP(DRSL, loglevel, "%s %s: " format, gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, mtype), ##args)
diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
index a4f6b7f36..12955929b 100644
--- a/src/osmo-bsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -44,11 +44,10 @@
#include <osmocom/bsc/handover_cfg.h>
#include <osmocom/bsc/timeslot_fsm.h>
#include <osmocom/bsc/lchan_fsm.h>
+#include <osmocom/bsc/bts.h>
void *tall_bsc_ctx = NULL;
-static LLIST_HEAD(bts_models);
-
void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
uint8_t e1_ts, uint8_t e1_ts_ss)
{
@@ -57,49 +56,6 @@ void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
ts->e1_link.e1_ts_ss = e1_ts_ss;
}
-static struct gsm_bts_model *bts_model_find(enum gsm_bts_type type)
-{
- struct gsm_bts_model *model;
-
- llist_for_each_entry(model, &bts_models, list) {
- if (model->type == type)
- return model;
- }
-
- return NULL;
-}
-
-int gsm_bts_model_register(struct gsm_bts_model *model)
-{
- if (bts_model_find(model->type))
- return -EEXIST;
-
- tlv_def_patch(&model->nm_att_tlvdef, &abis_nm_att_tlvdef);
- llist_add_tail(&model->list, &bts_models);
- return 0;
-}
-
-const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = {
- { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" },
- { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" },
- { GSM_BTS_TYPE_NANOBTS, "ip.access nanoBTS or compatible" },
- { GSM_BTS_TYPE_RBS2000, "Ericsson RBS2000 Series" },
- { GSM_BTS_TYPE_NOKIA_SITE, "Nokia {Metro,Ultra,In}Site" },
- { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" },
- { 0, NULL }
-};
-
-struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr)
-{
- struct gsm_bts_trx *trx;
-
- llist_for_each_entry(trx, &bts->trx_list, list) {
- if (trx->nr == nr)
- return trx;
- }
- return NULL;
-}
-
/* Search for a BTS in the given Location Area; optionally start searching
* with start_bts (for continuing to search after the first result) */
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
@@ -149,62 +105,6 @@ const char *bts_gprs_mode_name(enum bts_gprs_mode mode)
return get_value_string(bts_gprs_mode_names, mode);
}
-int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode)
-{
- if (mode != BTS_GPRS_NONE &&
- !osmo_bts_has_feature(&bts->model->features, BTS_FEAT_GPRS)) {
- return 0;
- }
- if (mode == BTS_GPRS_EGPRS &&
- !osmo_bts_has_feature(&bts->model->features, BTS_FEAT_EGPRS)) {
- return 0;
- }
-
- return 1;
-}
-
-int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type)
-{
- struct gsm_bts_model *model;
-
- model = bts_model_find(type);
- if (!model)
- return -EINVAL;
-
- bts->type = type;
- bts->model = model;
-
- if (model->start && !model->started) {
- int ret = model->start(bts->network);
- if (ret < 0)
- return ret;
-
- model->started = true;
- }
-
- switch (bts->type) {
- case GSM_BTS_TYPE_NANOBTS:
- case GSM_BTS_TYPE_OSMOBTS:
- /* Set the default OML Stream ID to 0xff */
- bts->oml_tei = 0xff;
- bts->c0->nominal_power = 23;
- break;
- case GSM_BTS_TYPE_RBS2000:
- INIT_LLIST_HEAD(&bts->rbs2000.is.conn_groups);
- INIT_LLIST_HEAD(&bts->rbs2000.con.conn_groups);
- break;
- case GSM_BTS_TYPE_BS11:
- case GSM_BTS_TYPE_UNKNOWN:
- case GSM_BTS_TYPE_NOKIA_SITE:
- /* Set default BTS reset timer */
- bts->nokia.bts_reset_timer_cnf = 15;
- case _NUM_GSM_BTS_TYPE:
- break;
- }
-
- return 0;
-}
-
struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type,
uint8_t bsic)
{
@@ -248,166 +148,14 @@ void gsm48_ra_id_by_bts(struct gsm48_ra_id *buf, struct gsm_bts *bts)
gsm48_encode_ra(buf, &raid);
}
-/* Assume there are only 256 possible bts */
-osmo_static_assert(sizeof(((struct gsm_bts *) 0)->nr) == 1, _bts_nr_is_256);
-static void depends_calc_index_bit(int bts_nr, int *idx, int *bit)
-{
- *idx = bts_nr / (8 * 4);
- *bit = bts_nr % (8 * 4);
-}
-
-void bts_depend_mark(struct gsm_bts *bts, int dep)
-{
- int idx, bit;
- depends_calc_index_bit(dep, &idx, &bit);
-
- bts->depends_on[idx] |= 1 << bit;
-}
-
-void bts_depend_clear(struct gsm_bts *bts, int dep)
-{
- int idx, bit;
- depends_calc_index_bit(dep, &idx, &bit);
-
- bts->depends_on[idx] &= ~(1 << bit);
-}
-
-int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)
-{
- int idx, bit;
- depends_calc_index_bit(other->nr, &idx, &bit);
-
- /* Check if there is a depends bit */
- return (base->depends_on[idx] & (1 << bit)) > 0;
-}
-
-static int bts_is_online(struct gsm_bts *bts)
-{
- /* TODO: support E1 BTS too */
- if (!is_ipaccess_bts(bts))
- return 1;
-
- if (!bts->oml_link)
- return 0;
-
- return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED;
-}
-
-int bts_depend_check(struct gsm_bts *bts)
-{
- struct gsm_bts *other_bts;
-
- llist_for_each_entry(other_bts, &bts->network->bts_list, list) {
- if (!bts_depend_is_depedency(bts, other_bts))
- continue;
- if (bts_is_online(other_bts))
- continue;
- return 0;
- }
- return 1;
-}
-
-/* get the radio link timeout (based on SACCH decode errors, according
- * to algorithm specified in TS 05.08 section 5.2. A value of -1
- * indicates we should use an infinitely long timeout, which only works
- * with OsmoBTS as the BTS implementation */
-int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts)
-{
- const struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
-
- if (bts->infinite_radio_link_timeout)
- return -1;
- else {
- /* Encoding as per Table 10.5.21 of TS 04.08 */
- return (cell_options->radio_link_timeout + 1) << 2;
- }
-}
-
-/* set the radio link timeout (based on SACCH decode errors, according
- * to algorithm specified in TS 05.08 Section 5.2. A value of -1
- * indicates we should use an infinitely long timeout, which only works
- * with OsmoBTS as the BTS implementation */
-void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value)
-{
- struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
-
- if (value < 0)
- bts->infinite_radio_link_timeout = true;
- else {
- bts->infinite_radio_link_timeout = false;
- /* Encoding as per Table 10.5.21 of TS 04.08 */
- if (value < 4)
- value = 4;
- if (value > 64)
- value = 64;
- cell_options->radio_link_timeout = (value >> 2) - 1;
- }
-}
-
-static const struct osmo_stat_item_desc bts_stat_desc[] = {
- [BTS_STAT_CHAN_LOAD_AVERAGE] = { "chanloadavg", "Channel load average", "%", 16, 0 },
- [BTS_STAT_CHAN_CCCH_SDCCH4_USED] = { "chan_ccch_sdcch4:used",
- "Number of CCCH+SDCCH4 channels used", "", 16, 0 },
- [BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL] = { "chan_ccch_sdcch4:total",
- "Number of CCCH+SDCCH4 channels total", "", 16, 0 },
- [BTS_STAT_CHAN_TCH_F_USED] = { "chan_tch_f:used",
- "Number of TCH/F channels used", "", 16, 0 },
- [BTS_STAT_CHAN_TCH_F_TOTAL] = { "chan_tch_f:total",
- "Number of TCH/F channels total", "", 16, 0 },
- [BTS_STAT_CHAN_TCH_H_USED] = { "chan_tch_h:used",
- "Number of TCH/H channels used", "", 16, 0 },
- [BTS_STAT_CHAN_TCH_H_TOTAL] = { "chan_tch_h:total",
- "Number of TCH/H channels total", "", 16, 0 },
- [BTS_STAT_CHAN_SDCCH8_USED] = { "chan_sdcch8:used",
- "Number of SDCCH8 channels used", "", 16, 0 },
- [BTS_STAT_CHAN_SDCCH8_TOTAL] = { "chan_sdcch8:total",
- "Number of SDCCH8 channels total", "", 16, 0 },
- [BTS_STAT_CHAN_TCH_F_PDCH_USED] = { "chan_tch_f_pdch:used",
- "Number of TCH/F_PDCH channels used", "", 16, 0 },
- [BTS_STAT_CHAN_TCH_F_PDCH_TOTAL] = { "chan_tch_f_pdch:total",
- "Number of TCH/F_PDCH channels total", "", 16, 0 },
- [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED] = { "chan_ccch_sdcch4_cbch:used",
- "Number of CCCH+SDCCH4+CBCH channels used", "", 16, 0 },
- [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL] = { "chan_ccch_sdcch4_cbch:total",
- "Number of CCCH+SDCCH4+CBCH channels total", "", 16, 0 },
- [BTS_STAT_CHAN_SDCCH8_CBCH_USED] = { "chan_sdcch8_cbch:used",
- "Number of SDCCH8+CBCH channels used", "", 16, 0 },
- [BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL] = { "chan_sdcch8_cbch:total",
- "Number of SDCCH8+CBCH channels total", "", 16, 0 },
- [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED] = { "chan_tch_f_tch_h_pdch:used",
- "Number of TCH/F_TCH/H_PDCH channels used", "", 16, 0 },
- [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL] = { "chan_tch_f_tch_h_pdch:total",
- "Number of TCH/F_TCH/H_PDCH channels total", "", 16, 0 },
- [BTS_STAT_T3122] = { "T3122", "T3122 IMMEDIATE ASSIGNMENT REJECT wait indicator",
- "s", 16, GSM_T3122_DEFAULT },
- [BTS_STAT_RACH_BUSY] = { "rach_busy",
- "RACH slots with signal above threshold", "%", 16, 0 },
- [BTS_STAT_RACH_ACCESS] = { "rach_access",
- "RACH slots with access bursts in them", "%", 16, 0 },
- [BTS_STAT_OML_CONNECTED] = { "oml_connected", "Number of OML links connected", "", 16, 0 },
- [BTS_STAT_RSL_CONNECTED] = { "rsl_connected", "Number of RSL links connected", "", 16, 0 },
- [BTS_STAT_LCHAN_BORKEN] = { "lchan_borken",
- "Number of lchans in the BORKEN state", "", 16, 0 },
- [BTS_STAT_TS_BORKEN] = { "ts_borken",
- "Number of timeslots in the BORKEN state", "", 16, 0 },
-};
-
-static const struct osmo_stat_item_group_desc bts_statg_desc = {
- .group_name_prefix = "bts",
- .group_description = "base transceiver station",
- .class_id = OSMO_STATS_CLASS_GLOBAL,
- .num_items = ARRAY_SIZE(bts_stat_desc),
- .item_desc = bts_stat_desc,
-};
-
void gsm_abis_mo_reset(struct gsm_abis_mo *mo)
{
mo->nm_state.operational = NM_OPSTATE_NULL;
mo->nm_state.availability = NM_AVSTATE_POWER_OFF;
}
-static void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
- uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3)
+void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
+ uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3)
{
mo->bts = bts;
mo->obj_class = obj_class;
@@ -417,62 +165,6 @@ static void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
gsm_abis_mo_reset(mo);
}
-const struct value_string bts_attribute_names[] = {
- OSMO_VALUE_STRING(BTS_TYPE_VARIANT),
- OSMO_VALUE_STRING(BTS_SUB_MODEL),
- OSMO_VALUE_STRING(TRX_PHY_VERSION),
- { 0, NULL }
-};
-
-enum bts_attribute str2btsattr(const char *s)
-{
- return get_string_value(bts_attribute_names, s);
-}
-
-const char *btsatttr2str(enum bts_attribute v)
-{
- return get_value_string(bts_attribute_names, v);
-}
-
-const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
- { BTS_UNKNOWN, "unknown" },
- { BTS_OSMO_LITECELL15, "osmo-bts-lc15" },
- { BTS_OSMO_OCTPHY, "osmo-bts-octphy" },
- { BTS_OSMO_SYSMO, "osmo-bts-sysmo" },
- { BTS_OSMO_TRX, "omso-bts-trx" },
- { 0, NULL }
-};
-
-enum gsm_bts_type_variant str2btsvariant(const char *arg)
-{
- return get_string_value(osmo_bts_variant_names, arg);
-}
-
-const char *btsvariant2str(enum gsm_bts_type_variant v)
-{
- return get_value_string(osmo_bts_variant_names, v);
-}
-
-const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = {
- { GSM_BTS_TYPE_UNKNOWN, "unknown" },
- { GSM_BTS_TYPE_BS11, "bs11" },
- { GSM_BTS_TYPE_NANOBTS, "nanobts" },
- { GSM_BTS_TYPE_RBS2000, "rbs2000" },
- { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" },
- { GSM_BTS_TYPE_OSMOBTS, "sysmobts" },
- { 0, NULL }
-};
-
-enum gsm_bts_type str2btstype(const char *arg)
-{
- return get_string_value(bts_type_names, arg);
-}
-
-const char *btstype2str(enum gsm_bts_type type)
-{
- return get_value_string(bts_type_names, type);
-}
-
const struct value_string gsm_chreq_descs[] = {
{ GSM_CHREQ_REASON_EMERG, "emergency call" },
{ GSM_CHREQ_REASON_PAG, "answer to paging" },
@@ -577,44 +269,6 @@ struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num)
return NULL;
}
-bool gsm_bts_matches_lai(const struct gsm_bts *bts, const struct osmo_location_area_id *lai)
-{
- return osmo_plmn_cmp(&lai->plmn, &bts->network->plmn) == 0
- && lai->lac == bts->location_area_code;
-}
-
-bool gsm_bts_matches_cell_id(const struct gsm_bts *bts, const struct gsm0808_cell_id *cell_id)
-{
- const union gsm0808_cell_id_u *id = &cell_id->id;
- if (!bts || !cell_id)
- return false;
-
- switch (cell_id->id_discr) {
- case CELL_IDENT_WHOLE_GLOBAL:
- return gsm_bts_matches_lai(bts, &id->global.lai)
- && id->global.cell_identity == bts->cell_identity;
- case CELL_IDENT_LAC_AND_CI:
- return id->lac_and_ci.lac == bts->location_area_code
- && id->lac_and_ci.ci == bts->cell_identity;
- case CELL_IDENT_CI:
- return id->ci == bts->cell_identity;
- case CELL_IDENT_NO_CELL:
- return false;
- case CELL_IDENT_LAI_AND_LAC:
- return gsm_bts_matches_lai(bts, &id->lai_and_lac);
- case CELL_IDENT_LAC:
- return id->lac == bts->location_area_code;
- case CELL_IDENT_BSS:
- return true;
- case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
- case CELL_IDENT_UTRAN_RNC:
- case CELL_IDENT_UTRAN_LAC_RNC:
- return false;
- default:
- OSMO_ASSERT(false);
- }
-}
-
/* From a list of local BTSes that match the cell_id, return the Nth one, or NULL if there is no such
* match. */
struct gsm_bts *gsm_bts_by_cell_id(const struct gsm_network *net,
@@ -636,59 +290,6 @@ struct gsm_bts *gsm_bts_by_cell_id(const struct gsm_network *net,
return NULL;
}
-struct gsm_bts_ref *gsm_bts_ref_find(const struct llist_head *list, const struct gsm_bts *bts)
-{
- struct gsm_bts_ref *ref;
- if (!bts)
- return NULL;
- llist_for_each_entry(ref, list, entry) {
- if (ref->bts == bts)
- return ref;
- }
- return NULL;
-}
-
-/* Add a BTS reference to the local_neighbors list.
- * Return 1 if added, 0 if such an entry already existed, and negative on errors. */
-int gsm_bts_local_neighbor_add(struct gsm_bts *bts, struct gsm_bts *neighbor)
-{
- struct gsm_bts_ref *ref;
- if (!bts || !neighbor)
- return -ENOMEM;
-
- if (bts == neighbor)
- return -EINVAL;
-
- /* Already got this entry? */
- ref = gsm_bts_ref_find(&bts->local_neighbors, neighbor);
- if (ref)
- return 0;
-
- ref = talloc_zero(bts, struct gsm_bts_ref);
- if (!ref)
- return -ENOMEM;
- ref->bts = neighbor;
- llist_add_tail(&ref->entry, &bts->local_neighbors);
- return 1;
-}
-
-/* Remove a BTS reference from the local_neighbors list.
- * Return 1 if removed, 0 if no such entry existed, and negative on errors. */
-int gsm_bts_local_neighbor_del(struct gsm_bts *bts, const struct gsm_bts *neighbor)
-{
- struct gsm_bts_ref *ref;
- if (!bts || !neighbor)
- return -ENOMEM;
-
- ref = gsm_bts_ref_find(&bts->local_neighbors, neighbor);
- if (!ref)
- return 0;
-
- llist_del(&ref->entry);
- talloc_free(ref);
- return 1;
-}
-
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
{
struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx);
@@ -748,251 +349,6 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
return trx;
}
-
-static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
-static const uint8_t bts_cell_timer_default[] =
- { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
-static const struct gprs_rlc_cfg rlc_cfg_default = {
- .parameter = {
- [RLC_T3142] = 20,
- [RLC_T3169] = 5,
- [RLC_T3191] = 5,
- [RLC_T3193] = 160, /* 10ms */
- [RLC_T3195] = 5,
- [RLC_N3101] = 10,
- [RLC_N3103] = 4,
- [RLC_N3105] = 8,
- [CV_COUNTDOWN] = 15,
- [T_DL_TBF_EXT] = 250 * 10, /* ms */
- [T_UL_TBF_EXT] = 250 * 10, /* ms */
- },
- .paging = {
- .repeat_time = 5 * 50, /* ms */
- .repeat_count = 3,
- },
- .cs_mask = 0x1fff,
- .initial_cs = 2,
- .initial_mcs = 6,
-};
-
-static void bts_init_cbch_state(struct bts_smscb_chan_state *cstate, struct gsm_bts *bts)
-{
- cstate->bts = bts;
- INIT_LLIST_HEAD(&cstate->messages);
-}
-
-/* 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);
- struct gsm48_multi_rate_conf mr_cfg;
- int i;
-
- if (!bts)
- return NULL;
-
- bts->nr = bts_num;
- bts->num_trx = 0;
- INIT_LLIST_HEAD(&bts->trx_list);
- bts->network = net;
-
- bts->ms_max_power = 15; /* dBm */
-
- gsm_mo_init(&bts->mo, bts, NM_OC_BTS,
- bts->nr, 0xff, 0xff);
- gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
- 0xff, 0xff, 0xff);
-
- for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
- bts->gprs.nsvc[i].bts = bts;
- bts->gprs.nsvc[i].id = i;
- gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
- bts->nr, i, 0xff);
- }
- memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
- sizeof(bts->gprs.nse.timer));
- gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
- bts->nr, 0xff, 0xff);
- memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
- sizeof(bts->gprs.cell.timer));
- gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
- bts->nr, 0xff, 0xff);
- memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
- sizeof(bts->gprs.cell.rlc_cfg));
-
- /* 3GPP TS 08.18, chapter 5.4.1: 0 is reserved for signalling */
- bts->gprs.cell.bvci = 2;
-
- /* init statistics */
- bts->bts_ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);
- if (!bts->bts_ctrs) {
- talloc_free(bts);
- return NULL;
- }
- bts->bts_statg = osmo_stat_item_group_alloc(bts, &bts_statg_desc, bts->nr);
-
- /* create our primary TRX */
- bts->c0 = gsm_bts_trx_alloc(bts);
- if (!bts->c0) {
- rate_ctr_group_free(bts->bts_ctrs);
- osmo_stat_item_group_free(bts->bts_statg);
- talloc_free(bts);
- return NULL;
- }
- bts->c0->ts[0].pchan_from_config = GSM_PCHAN_CCCH_SDCCH4; /* TODO: really?? */
-
- bts->ccch_load_ind_thresh = 10; /* 10% of Load: Start sending CCCH LOAD IND */
- bts->rach_b_thresh = -1;
- bts->rach_ldavg_slots = -1;
-
- bts->paging.free_chans_need = -1;
- INIT_LLIST_HEAD(&bts->paging.pending_requests);
-
- bts->features.data = &bts->_features_data[0];
- bts->features.data_len = sizeof(bts->_features_data);
-
- /* si handling */
- bts->bcch_change_mark = 1;
- bts->chan_load_avg = 0;
-
- /* timer overrides */
- bts->T3122 = 0; /* not overridden by default */
- bts->T3113_dynamic = true; /* dynamic by default */
-
- bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
- bts->dtxd = false;
- bts->gprs.ctrl_ack_type_use_block = true; /* use RLC/MAC control block */
- bts->neigh_list_manual_mode = NL_MODE_AUTOMATIC;
- bts->early_classmark_allowed_3g = true; /* 3g Early Classmark Sending controlled by bts->early_classmark_allowed param */
- bts->si_unused_send_empty = true;
- bts->si_common.cell_sel_par.cell_resel_hyst = 2; /* 4 dB */
- bts->si_common.cell_sel_par.rxlev_acc_min = 0;
- bts->si_common.si2quater_neigh_list.arfcn = bts->si_common.data.earfcn_list;
- bts->si_common.si2quater_neigh_list.meas_bw = bts->si_common.data.meas_bw_list;
- bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;
- bts->si_common.si2quater_neigh_list.thresh_hi = 0;
- osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);
- bts->si_common.neigh_list.data = bts->si_common.data.neigh_list;
- bts->si_common.neigh_list.data_len =
- sizeof(bts->si_common.data.neigh_list);
- bts->si_common.si5_neigh_list.data = bts->si_common.data.si5_neigh_list;
- bts->si_common.si5_neigh_list.data_len =
- sizeof(bts->si_common.data.si5_neigh_list);
- bts->si_common.cell_alloc.data = bts->si_common.data.cell_alloc;
- bts->si_common.cell_alloc.data_len =
- sizeof(bts->si_common.data.cell_alloc);
- bts->si_common.rach_control.re = 1; /* no re-establishment */
- bts->si_common.rach_control.tx_integer = 9; /* 12 slots spread - 217/115 slots delay */
- bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */
- bts->si_common.rach_control.t2 = 4; /* no emergency calls */
- bts->si_common.chan_desc.att = 1; /* attachment required */
- bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */
- bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */
- bts->si_common.chan_desc.t3212 = osmo_tdef_get(net->T_defs, 3212, OSMO_TDEF_CUSTOM, -1);
- gsm_bts_set_radio_link_timeout(bts, 32); /* Use RADIO LINK TIMEOUT of 32 */
-
- INIT_LLIST_HEAD(&bts->abis_queue);
- INIT_LLIST_HEAD(&bts->loc_list);
- INIT_LLIST_HEAD(&bts->local_neighbors);
- INIT_LLIST_HEAD(&bts->oml_fail_rep);
-
- /* Enable all codecs by default. These get reset to a more fine grained selection IF a
- * 'codec-support' config appears in the config file (see bsc_vty.c). */
- bts->codec = (struct bts_codec_conf){
- .hr = 1,
- .efr = 1,
- .amr = 1,
- };
-
- /* Set reasonable defaults for AMR-FR and AMR-HR rate configuration.
- * (see also 3GPP TS 28.062, Table 7.11.3.1.3-2) */
- mr_cfg = (struct gsm48_multi_rate_conf) {
- .m4_75 = 1,
- .m5_15 = 0,
- .m5_90 = 1,
- .m6_70 = 0,
- .m7_40 = 1,
- .m7_95 = 0,
- .m10_2 = 0,
- .m12_2 = 1
- };
- memcpy(bts->mr_full.gsm48_ie, &mr_cfg, sizeof(bts->mr_full.gsm48_ie));
- bts->mr_full.ms_mode[0].mode = 0;
- bts->mr_full.ms_mode[1].mode = 2;
- bts->mr_full.ms_mode[2].mode = 4;
- bts->mr_full.ms_mode[3].mode = 7;
- bts->mr_full.bts_mode[0].mode = 0;
- bts->mr_full.bts_mode[1].mode = 2;
- bts->mr_full.bts_mode[2].mode = 4;
- bts->mr_full.bts_mode[3].mode = 7;
- for (i = 0; i < 3; i++) {
- bts->mr_full.ms_mode[i].hysteresis = 8;
- bts->mr_full.ms_mode[i].threshold = 32;
- bts->mr_full.bts_mode[i].hysteresis = 8;
- bts->mr_full.bts_mode[i].threshold = 32;
- }
- bts->mr_full.num_modes = 4;
-
- mr_cfg = (struct gsm48_multi_rate_conf) {
- .m4_75 = 1,
- .m5_15 = 0,
- .m5_90 = 1,
- .m6_70 = 0,
- .m7_40 = 1,
- .m7_95 = 0,
- .m10_2 = 0,
- .m12_2 = 0
- };
- memcpy(bts->mr_half.gsm48_ie, &mr_cfg, sizeof(bts->mr_half.gsm48_ie));
- bts->mr_half.ms_mode[0].mode = 0;
- bts->mr_half.ms_mode[1].mode = 2;
- bts->mr_half.ms_mode[2].mode = 4;
- bts->mr_half.ms_mode[3].mode = 7;
- bts->mr_half.bts_mode[0].mode = 0;
- bts->mr_half.bts_mode[1].mode = 2;
- bts->mr_half.bts_mode[2].mode = 4;
- bts->mr_half.bts_mode[3].mode = 7;
- for (i = 0; i < 3; i++) {
- bts->mr_half.ms_mode[i].hysteresis = 8;
- bts->mr_half.ms_mode[i].threshold = 32;
- bts->mr_half.bts_mode[i].hysteresis = 8;
- bts->mr_half.bts_mode[i].threshold = 32;
- }
- bts->mr_half.num_modes = 3;
-
- bts_init_cbch_state(&bts->cbch_basic, bts);
- bts_init_cbch_state(&bts->cbch_extended, bts);
-
- return bts;
-}
-
-/* reset the state of all MO in the BTS */
-void gsm_bts_mo_reset(struct gsm_bts *bts)
-{
- struct gsm_bts_trx *trx;
- unsigned int i;
-
- gsm_abis_mo_reset(&bts->mo);
- gsm_abis_mo_reset(&bts->site_mgr.mo);
- for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++)
- gsm_abis_mo_reset(&bts->gprs.nsvc[i].mo);
- gsm_abis_mo_reset(&bts->gprs.nse.mo);
- gsm_abis_mo_reset(&bts->gprs.cell.mo);
-
- llist_for_each_entry(trx, &bts->trx_list, list) {
- gsm_abis_mo_reset(&trx->mo);
- gsm_abis_mo_reset(&trx->bb_transc.mo);
-
- for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
- struct gsm_bts_trx_ts *ts = &trx->ts[i];
- gsm_abis_mo_reset(&ts->mo);
- }
- }
-}
-
struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)
{
struct gsm_bts_trx *trx;
@@ -1010,16 +366,6 @@ struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)
static char ts2str[255];
-char *gsm_bts_name(const struct gsm_bts *bts)
-{
- if (!bts)
- snprintf(ts2str, sizeof(ts2str), "(bts=NULL)");
- else
- snprintf(ts2str, sizeof(ts2str), "(bts=%d)", bts->nr);
-
- return ts2str;
-}
-
char *gsm_trx_name(const struct gsm_bts_trx *trx)
{
if (!trx)
@@ -1289,27 +635,6 @@ uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)
return gsm_pchan2chan_nr(lchan->ts->pchan_is, lchan->ts->nr, lchan->nr);
}
-/* return the gsm_lchan for the CBCH (if it exists at all) */
-struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)
-{
- struct gsm_lchan *lchan = NULL;
- struct gsm_bts_trx *trx = bts->c0;
-
- if (trx->ts[0].pchan_from_config == GSM_PCHAN_CCCH_SDCCH4_CBCH)
- lchan = &trx->ts[0].lchan[2];
- else {
- int i;
- for (i = 0; i < 8; i++) {
- if (trx->ts[i].pchan_from_config == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
- lchan = &trx->ts[i].lchan[2];
- break;
- }
- }
- }
-
- return lchan;
-}
-
/* determine logical channel based on TRX and channel number IE */
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
int *rc)
@@ -1392,6 +717,12 @@ bool ts_is_tch(struct gsm_bts_trx_ts *ts)
return pchan_is_tch(ts->pchan_is);
}
+struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {
+ if (!conn || !conn->lchan)
+ return NULL;
+ return conn->lchan->ts->trx->bts;
+}
+
bool trx_is_usable(const struct gsm_bts_trx *trx)
{
/* FIXME: How does this behave for BS-11 ? */
@@ -1417,13 +748,6 @@ void gsm_trx_all_ts_dispatch(struct gsm_bts_trx *trx, uint32_t ts_ev, void *data
}
}
-void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data)
-{
- struct gsm_bts_trx *trx;
- llist_for_each_entry(trx, &bts->trx_list, list)
- gsm_trx_all_ts_dispatch(trx, ts_ev, data);
-}
-
static void _chan_desc_fill_tail(struct gsm48_chan_desc *cd, const struct gsm_lchan *lchan)
{
if (!lchan->ts->hopping.enabled) {
@@ -1458,6 +782,14 @@ void gsm48_lchan2chan_desc_as_configured(struct gsm48_chan_desc *cd,
_chan_desc_fill_tail(cd, lchan);
}
+uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)
+{
+ if (ts->tsc != -1)
+ return ts->tsc;
+ else
+ return ts->trx->bts->bsic & 7;
+}
+
bool nm_is_running(const struct gsm_nm_state *s) {
if (s->operational != NM_OPSTATE_ENABLED)
return false;
@@ -1633,7 +965,7 @@ bool ts_is_capable_of_lchant(struct gsm_bts_trx_ts *ts, enum gsm_chan_t type)
}
}
-static int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)
+int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)
{
struct gsm_bts_trx_ts *ts;
struct gsm_lchan *lchan;
@@ -1681,18 +1013,6 @@ static int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config
return count;
}
-/* Count number of free TS of given pchan type */
-int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
-{
- struct gsm_bts_trx *trx;
- int count = 0;
-
- llist_for_each_entry(trx, &bts->trx_list, list)
- count += trx_count_free_ts(trx, pchan);
-
- return count;
-}
-
bool ts_is_usable(const struct gsm_bts_trx_ts *ts)
{
if (!trx_is_usable(ts->trx)) {
diff --git a/src/osmo-bsc/handover_decision.c b/src/osmo-bsc/handover_decision.c
index 533840024..7eb8f31e0 100644
--- a/src/osmo-bsc/handover_decision.c
+++ b/src/osmo-bsc/handover_decision.c
@@ -34,6 +34,7 @@
#include <osmocom/bsc/handover_fsm.h>
#include <osmocom/bsc/handover_cfg.h>
+#include <osmocom/bsc/bts.h>
/* did we get a RXLEV for a given cell in the given report? */
static int rxlev_for_cell_in_rep(struct gsm_meas_rep *mr,
diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c
index ab507e84c..8caa2e3f4 100644
--- a/src/osmo-bsc/handover_decision_2.c
+++ b/src/osmo-bsc/handover_decision_2.c
@@ -37,6 +37,7 @@
#include <osmocom/bsc/penalty_timers.h>
#include <osmocom/bsc/neighbor_ident.h>
#include <osmocom/bsc/timeslot_fsm.h>
+#include <osmocom/bsc/bts.h>
#define LOGPHOBTS(bts, level, fmt, args...) \
LOGP(DHODEC, level, "(BTS %u) " fmt, bts->nr, ## args)
diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c
index 0b88b27d8..8ed5945c5 100644
--- a/src/osmo-bsc/handover_fsm.c
+++ b/src/osmo-bsc/handover_fsm.c
@@ -43,6 +43,7 @@
#include <osmocom/bsc/osmo_bsc_lcls.h>
#include <osmocom/bsc/codec_pref.h>
#include <osmocom/bsc/gsm_08_08.h>
+#include <osmocom/bsc/bts.h>
#define LOG_FMT_BTS "bts %u lac-ci %u-%u arfcn-bsic %d-%d"
#define LOG_ARGS_BTS(bts) \
diff --git a/src/osmo-bsc/handover_logic.c b/src/osmo-bsc/handover_logic.c
index 5be838340..071228e88 100644
--- a/src/osmo-bsc/handover_logic.c
+++ b/src/osmo-bsc/handover_logic.c
@@ -43,6 +43,7 @@
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
#include <osmocom/bsc/neighbor_ident.h>
#include <osmocom/bsc/abis_nm.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/gsm/gsm0808.h>
#include <osmocom/gsm/gsm0808_utils.h>
diff --git a/src/osmo-bsc/handover_vty.c b/src/osmo-bsc/handover_vty.c
index a418aa7ac..81313e251 100644
--- a/src/osmo-bsc/handover_vty.c
+++ b/src/osmo-bsc/handover_vty.c
@@ -27,6 +27,7 @@
#include <osmocom/bsc/vty.h>
#include <osmocom/bsc/handover_cfg.h>
#include <osmocom/bsc/handover_decision_2.h>
+#include <osmocom/bsc/bts.h>
static struct handover_cfg *ho_cfg_from_vty(struct vty *vty)
{
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index bcf7c4b06..e879059da 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -39,7 +39,7 @@
#include <osmocom/bsc/handover_fsm.h>
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/codec_pref.h>
-
+#include <osmocom/bsc/bts.h>
static struct osmo_fsm lchan_fsm;
diff --git a/src/osmo-bsc/lchan_rtp_fsm.c b/src/osmo-bsc/lchan_rtp_fsm.c
index 4be979002..2def2f5db 100644
--- a/src/osmo-bsc/lchan_rtp_fsm.c
+++ b/src/osmo-bsc/lchan_rtp_fsm.c
@@ -30,6 +30,7 @@
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
#include <osmocom/bsc/abis_rsl.h>
#include <osmocom/bsc/bsc_msc_data.h>
+#include <osmocom/bsc/bts.h>
static struct osmo_fsm lchan_rtp_fsm;
diff --git a/src/osmo-bsc/lchan_select.c b/src/osmo-bsc/lchan_select.c
index d63db22d3..d2dba1bb2 100644
--- a/src/osmo-bsc/lchan_select.c
+++ b/src/osmo-bsc/lchan_select.c
@@ -28,6 +28,7 @@
#include <osmocom/bsc/lchan_fsm.h>
#include <osmocom/bsc/lchan_select.h>
+#include <osmocom/bsc/bts.h>
static struct gsm_lchan *
_lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,
diff --git a/src/osmo-bsc/meas_feed.c b/src/osmo-bsc/meas_feed.c
index f9a362600..889f6efc3 100644
--- a/src/osmo-bsc/meas_feed.c
+++ b/src/osmo-bsc/meas_feed.c
@@ -19,6 +19,7 @@
#include <osmocom/bsc/meas_feed.h>
#include <osmocom/bsc/vty.h>
#include <osmocom/bsc/debug.h>
+#include <osmocom/bsc/bts.h>
struct meas_feed_state {
struct osmo_wqueue wqueue;
diff --git a/src/osmo-bsc/neighbor_ident_vty.c b/src/osmo-bsc/neighbor_ident_vty.c
index 54d6944f5..7feed2a27 100644
--- a/src/osmo-bsc/neighbor_ident_vty.c
+++ b/src/osmo-bsc/neighbor_ident_vty.c
@@ -30,6 +30,7 @@
#include <osmocom/bsc/vty.h>
#include <osmocom/bsc/neighbor_ident.h>
#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/bts.h>
static struct gsm_network *g_net = NULL;
static struct neighbor_ident_list *g_neighbor_cells = NULL;
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index 1cacfe935..bf38d107d 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -33,6 +33,7 @@
#include <osmocom/bsc/codec_pref.h>
#include <osmocom/bsc/abis_rsl.h>
#include <osmocom/bsc/handover_fsm.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm0808.h>
diff --git a/src/osmo-bsc/osmo_bsc_ctrl.c b/src/osmo-bsc/osmo_bsc_ctrl.c
index b94a749bf..5ebe59789 100644
--- a/src/osmo-bsc/osmo_bsc_ctrl.c
+++ b/src/osmo-bsc/osmo_bsc_ctrl.c
@@ -27,6 +27,7 @@
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/a_reset.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/signal.h>
diff --git a/src/osmo-bsc/osmo_bsc_filter.c b/src/osmo-bsc/osmo_bsc_filter.c
index 08c3a5048..f664231e8 100644
--- a/src/osmo-bsc/osmo_bsc_filter.c
+++ b/src/osmo-bsc/osmo_bsc_filter.c
@@ -26,6 +26,7 @@
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/paging.h>
#include <osmocom/bsc/gsm_04_08_rr.h>
+#include <osmocom/bsc/bts.h>
#include <stdlib.h>
diff --git a/src/osmo-bsc/osmo_bsc_grace.c b/src/osmo-bsc/osmo_bsc_grace.c
index 56edee569..a26a716ad 100644
--- a/src/osmo-bsc/osmo_bsc_grace.c
+++ b/src/osmo-bsc/osmo_bsc_grace.c
@@ -25,6 +25,7 @@
#include <osmocom/bsc/paging.h>
#include <osmocom/bsc/signal.h>
#include <osmocom/bsc/lchan_fsm.h>
+#include <osmocom/bsc/bts.h>
int bsc_grace_allow_new_connection(struct gsm_network *network, struct gsm_bts *bts)
{
diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c
index ada60472d..84b44f70d 100644
--- a/src/osmo-bsc/osmo_bsc_main.c
+++ b/src/osmo-bsc/osmo_bsc_main.c
@@ -64,6 +64,7 @@
#include <osmocom/bsc/e1_config.h>
#include <osmocom/bsc/codec_pref.h>
#include <osmocom/bsc/system_information.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/mgcp_client/mgcp_client.h>
diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c
index f2a1e5b0f..5e02b4a39 100644
--- a/src/osmo-bsc/osmo_bsc_msc.c
+++ b/src/osmo-bsc/osmo_bsc_msc.c
@@ -29,6 +29,7 @@
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/osmo_bsc_sigtran.h>
#include <osmocom/bsc/signal.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/socket.h>
diff --git a/src/osmo-bsc/osmo_bsc_sigtran.c b/src/osmo-bsc/osmo_bsc_sigtran.c
index afc6c8d8f..de4be2630 100644
--- a/src/osmo-bsc/osmo_bsc_sigtran.c
+++ b/src/osmo-bsc/osmo_bsc_sigtran.c
@@ -34,6 +34,7 @@
#include <osmocom/bsc/a_reset.h>
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/mgcp_client/mgcp_common.h>
/* A pointer to a list with all involved MSCs
diff --git a/src/osmo-bsc/paging.c b/src/osmo-bsc/paging.c
index 7859c69d0..521598f6f 100644
--- a/src/osmo-bsc/paging.c
+++ b/src/osmo-bsc/paging.c
@@ -53,6 +53,7 @@
#include <osmocom/bsc/gsm_08_08.h>
#include <osmocom/bsc/gsm_04_08_rr.h>
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
+#include <osmocom/bsc/bts.h>
void *tall_paging_ctx = NULL;
diff --git a/src/osmo-bsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c
index 3e0b7bf79..ae4ac8a20 100644
--- a/src/osmo-bsc/pcu_sock.c
+++ b/src/osmo-bsc/pcu_sock.c
@@ -44,6 +44,7 @@
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/abis_rsl.h>
#include <osmocom/bsc/gsm_04_08_rr.h>
+#include <osmocom/bsc/bts.h>
static int pcu_sock_send(struct gsm_bts *bts, struct msgb *msg);
uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx);
diff --git a/src/osmo-bsc/rest_octets.c b/src/osmo-bsc/rest_octets.c
index 0d806f393..7307cb888 100644
--- a/src/osmo-bsc/rest_octets.c
+++ b/src/osmo-bsc/rest_octets.c
@@ -33,6 +33,7 @@
#include <osmocom/bsc/rest_octets.h>
#include <osmocom/bsc/arfcn_range_encode.h>
#include <osmocom/bsc/system_information.h>
+#include <osmocom/bsc/bts.h>
/* generate SI1 rest octets */
int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net)
diff --git a/src/osmo-bsc/smscb.c b/src/osmo-bsc/smscb.c
index 8d48af9fe..436826a25 100644
--- a/src/osmo-bsc/smscb.c
+++ b/src/osmo-bsc/smscb.c
@@ -41,6 +41,7 @@
#include <osmocom/bsc/gsm_04_08_rr.h>
#include <osmocom/bsc/lchan_fsm.h>
#include <osmocom/bsc/abis_rsl.h>
+#include <osmocom/bsc/bts.h>
/*********************************************************************************
* Helper Functions
diff --git a/src/osmo-bsc/system_information.c b/src/osmo-bsc/system_information.c
index b17a909e5..13d0f4673 100644
--- a/src/osmo-bsc/system_information.c
+++ b/src/osmo-bsc/system_information.c
@@ -41,6 +41,7 @@
#include <osmocom/bsc/gsm_04_08_rr.h>
#include <osmocom/bsc/acc_ramp.h>
#include <osmocom/bsc/neighbor_ident.h>
+#include <osmocom/bsc/bts.h>
struct gsm0808_cell_id_list2;
diff --git a/src/osmo-bsc/timeslot_fsm.c b/src/osmo-bsc/timeslot_fsm.c
index 4816dafb5..0aecfaeb2 100644
--- a/src/osmo-bsc/timeslot_fsm.c
+++ b/src/osmo-bsc/timeslot_fsm.c
@@ -28,6 +28,7 @@
#include <osmocom/bsc/lchan_fsm.h>
#include <osmocom/bsc/abis_rsl.h>
#include <osmocom/bsc/pcu_if.h>
+#include <osmocom/bsc/bts.h>
static struct osmo_fsm ts_fsm;