aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/bsc/Makefile.am1
-rw-r--r--include/osmocom/bsc/bts.h634
-rw-r--r--include/osmocom/bsc/gsm_data.h632
-rw-r--r--src/ipaccess/Makefile.am4
-rw-r--r--src/ipaccess/ipaccess-config.c1
-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
-rw-r--r--src/utils/Makefile.am2
-rw-r--r--src/utils/bs11_config.c1
-rw-r--r--tests/abis/Makefile.am1
-rw-r--r--tests/abis/abis_test.c1
-rw-r--r--tests/bsc/Makefile.am1
-rw-r--r--tests/codec_pref/codec_pref_test.c1
-rw-r--r--tests/gsm0408/Makefile.am1
-rw-r--r--tests/gsm0408/gsm0408_test.c1
-rw-r--r--tests/handover/Makefile.am1
-rw-r--r--tests/handover/handover_test.c1
-rw-r--r--tests/nanobts_omlattr/Makefile.am1
-rw-r--r--tests/nanobts_omlattr/nanobts_omlattr_test.c1
66 files changed, 1471 insertions, 1354 deletions
diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am
index 7a296e474..4d2df20de 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -10,6 +10,7 @@ noinst_HEADERS = \
bsc_subscriber.h \
bsc_subscr_conn_fsm.h \
bss.h \
+ bts.h \
bts_ipaccess_nanobts_omlattr.h \
chan_alloc.h \
codec_pref.h \
diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h
new file mode 100644
index 000000000..07d279333
--- /dev/null
+++ b/include/osmocom/bsc/bts.h
@@ -0,0 +1,634 @@
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdbool.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/bitvec.h>
+#include <osmocom/gsm/tlv.h>
+#include <osmocom/gsm/bts_features.h>
+
+#include <osmocom/abis/e1_input.h>
+
+#include "osmocom/bsc/gsm_data.h"
+
+enum bts_counter_id {
+ BTS_CTR_CHREQ_TOTAL,
+ BTS_CTR_CHREQ_SUCCESSFUL,
+ BTS_CTR_CHREQ_NO_CHANNEL,
+ BTS_CTR_CHAN_RF_FAIL,
+ BTS_CTR_CHAN_RLL_ERR,
+ BTS_CTR_BTS_OML_FAIL,
+ BTS_CTR_BTS_RSL_FAIL,
+ BTS_CTR_CODEC_AMR_F,
+ BTS_CTR_CODEC_AMR_H,
+ BTS_CTR_CODEC_EFR,
+ BTS_CTR_CODEC_V1_FR,
+ BTS_CTR_CODEC_V1_HR,
+ BTS_CTR_PAGING_ATTEMPTED,
+ BTS_CTR_PAGING_ALREADY,
+ BTS_CTR_PAGING_RESPONDED,
+ BTS_CTR_PAGING_EXPIRED,
+ BTS_CTR_PAGING_NO_ACTIVE_PAGING,
+ BTS_CTR_PAGING_MSC_FLUSH,
+ BTS_CTR_CHAN_ACT_TOTAL,
+ BTS_CTR_CHAN_ACT_NACK,
+ BTS_CTR_RSL_UNKNOWN,
+ BTS_CTR_RSL_IPA_NACK,
+ BTS_CTR_RSL_DELETE_IND,
+ BTS_CTR_MODE_MODIFY_NACK,
+ BTS_CTR_LCHAN_BORKEN_FROM_UNUSED,
+ BTS_CTR_LCHAN_BORKEN_FROM_WAIT_ACTIV_ACK,
+ BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RF_RELEASE_ACK,
+ BTS_CTR_LCHAN_BORKEN_FROM_BORKEN,
+ BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN,
+ BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK,
+ BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK,
+ BTS_CTR_LCHAN_BORKEN_EV_RF_CHAN_REL_ACK,
+ BTS_CTR_LCHAN_BORKEN_EV_VTY,
+ BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN,
+ BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED,
+ BTS_CTR_TS_BORKEN_FROM_UNUSED,
+ BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_ACT,
+ BTS_CTR_TS_BORKEN_FROM_PDCH,
+ BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_DEACT,
+ BTS_CTR_TS_BORKEN_FROM_IN_USE,
+ BTS_CTR_TS_BORKEN_FROM_BORKEN,
+ BTS_CTR_TS_BORKEN_FROM_UNKNOWN,
+ BTS_CTR_TS_BORKEN_EV_PDCH_ACT_ACK_NACK,
+ BTS_CTR_TS_BORKEN_EV_PDCH_DEACT_ACK_NACK,
+ BTS_CTR_TS_BORKEN_EV_TEARDOWN,
+ BTS_CTR_ASSIGNMENT_ATTEMPTED,
+ BTS_CTR_ASSIGNMENT_COMPLETED,
+ BTS_CTR_ASSIGNMENT_STOPPED,
+ BTS_CTR_ASSIGNMENT_NO_CHANNEL,
+ BTS_CTR_ASSIGNMENT_TIMEOUT,
+ BTS_CTR_ASSIGNMENT_FAILED,
+ BTS_CTR_ASSIGNMENT_ERROR,
+};
+
+static const struct rate_ctr_desc bts_ctr_description[] = {
+ [BTS_CTR_CHREQ_TOTAL] = {"chreq:total", "Received channel requests"},
+ [BTS_CTR_CHREQ_SUCCESSFUL] = {"chreq:successful", "Successful channel requests (immediate assign sent)"},
+ [BTS_CTR_CHREQ_NO_CHANNEL] = {"chreq:no_channel", "Sent to MS no channel available"},
+ [BTS_CTR_CHAN_RF_FAIL] = {"chan:rf_fail", "Received a RF failure indication from BTS"},
+ [BTS_CTR_CHAN_RLL_ERR] = {"chan:rll_err", "Received a RLL failure with T200 cause from BTS"},
+ [BTS_CTR_BTS_OML_FAIL] = {"oml_fail", "Received a TEI down on a OML link"},
+ [BTS_CTR_BTS_RSL_FAIL] = {"rsl_fail", "Received a TEI down on a OML link"},
+ [BTS_CTR_CODEC_AMR_F] = {"codec:amr_f", "Count the usage of AMR/F codec by channel mode requested"},
+ [BTS_CTR_CODEC_AMR_H] = {"codec:amr_h", "Count the usage of AMR/H codec by channel mode requested"},
+ [BTS_CTR_CODEC_EFR] = {"codec:efr", "Count the usage of EFR codec by channel mode requested"},
+ [BTS_CTR_CODEC_V1_FR] = {"codec:fr", "Count the usage of FR codec by channel mode requested"},
+ [BTS_CTR_CODEC_V1_HR] = {"codec:hr", "Count the usage of HR codec by channel mode requested"},
+
+ [BTS_CTR_PAGING_ATTEMPTED] = {"paging:attempted", "Paging attempts for a subscriber"},
+ [BTS_CTR_PAGING_ALREADY] = {"paging:already", "Paging attempts ignored as subscriber was already being paged"},
+ [BTS_CTR_PAGING_RESPONDED] = {"paging:responded", "Paging attempts with successful paging response"},
+ [BTS_CTR_PAGING_EXPIRED] = {"paging:expired", "Paging Request expired because of timeout T3113"},
+ [BTS_CTR_PAGING_NO_ACTIVE_PAGING] = {"paging:no_active_paging", "Paging response without an active paging request (arrived after paging expiration?)"},
+ [BTS_CTR_PAGING_MSC_FLUSH] = {"paging:msc_flush", "Paging flushed due to MSC Reset BSSMAP message"},
+ [BTS_CTR_CHAN_ACT_TOTAL] = {"chan_act:total", "Total number of Channel Activations"},
+ [BTS_CTR_CHAN_ACT_NACK] = {"chan_act:nack", "Number of Channel Activations that the BTS NACKed"},
+ [BTS_CTR_RSL_UNKNOWN] = {"rsl:unknown", "Number of unknown/unsupported RSL messages received from BTS"},
+ [BTS_CTR_RSL_IPA_NACK] = {"rsl:ipa_nack", "Number of IPA (RTP/dyn-PDCH) related NACKs received from BTS"},
+ [BTS_CTR_RSL_DELETE_IND] = {"rsl:delete_ind", "Number of RSL DELETE INDICATION (DL CCCH overload)"},
+ [BTS_CTR_MODE_MODIFY_NACK] = {"chan:mode_modify_nack", "Number of Channel Mode Modify NACKs received from BTS"},
+
+ /* lchan/TS BORKEN state counters */
+ [BTS_CTR_LCHAN_BORKEN_FROM_UNUSED] = {"lchan_borken:from_state:unused", "Transitions from lchan UNUSED state to BORKEN state"},
+ [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_ACTIV_ACK] = {"lchan_borken:from_state:wait_activ_ack", "Transitions from lchan WAIT_ACTIV_ACK state to BORKEN state"},
+ [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RF_RELEASE_ACK] = {"lchan_borken:from_state:wait_rf_release_ack", "Transitions from lchan WAIT_RF_RELEASE_ACK state to BORKEN state"},
+ [BTS_CTR_LCHAN_BORKEN_FROM_BORKEN] = {"lchan_borken:from_state:borken", "Transitions from lchan BORKEN state to BORKEN state"},
+ [BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN] = {"lchan_borken:from_state:unknown", "Transitions from an unknown lchan state to BORKEN state"},
+ [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK] = {"lchan_borken:event:chan_activ_ack", "CHAN_ACTIV_ACK received in the lchan BORKEN state"},
+ [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK] = {"lchan_borken:event:chan_activ_nack", "CHAN_ACTIV_NACK received in the lchan BORKEN state"},
+ [BTS_CTR_LCHAN_BORKEN_EV_RF_CHAN_REL_ACK] = {"lchan_borken:event:rf_chan_rel_ack", "RF_CHAN_REL_ACK received in the lchan BORKEN state"},
+ [BTS_CTR_LCHAN_BORKEN_EV_VTY] = {"lchan_borken:event:vty", "VTY commands received in the lchan BORKEN state"},
+ [BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN] = {"lchan_borken:event:teardown", "lchan in a BORKEN state is shutting down (BTS disconnected?)"},
+ [BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED] = {"ts_borken:from_state:not_initialized", "Transitions from TS NOT_INITIALIZED state to BORKEN state"},
+ [BTS_CTR_TS_BORKEN_FROM_UNUSED] = {"ts_borken:from_state:unused", "Transitions from TS UNUSED state to BORKEN state"},
+ [BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_ACT] = {"ts_borken:from_state:wait_pdch_act", "Transitions from TS WAIT_PDCH_ACT state to BORKEN state"},
+ [BTS_CTR_TS_BORKEN_FROM_PDCH] = {"ts_borken:from_state:pdch", "Transitions from TS PDCH state to BORKEN state"},
+ [BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_DEACT] = {"ts_borken:from_state:wait_pdch_deact", "Transitions from TS WAIT_PDCH_DEACT state to BORKEN state"},
+ [BTS_CTR_TS_BORKEN_FROM_IN_USE] = {"ts_borken:from_state:in_use", "Transitions from TS IN_USE state to BORKEN state"},
+ [BTS_CTR_TS_BORKEN_FROM_BORKEN] = {"ts_borken:from_state:borken", "Transitions from TS BORKEN state to BORKEN state"},
+ [BTS_CTR_TS_BORKEN_FROM_UNKNOWN] = {"ts_borken:from_state:unknown", "Transitions from an unknown TS state to BORKEN state"},
+ [BTS_CTR_TS_BORKEN_EV_PDCH_ACT_ACK_NACK] = {"ts_borken:event:pdch_act_ack_nack", "PDCH_ACT_ACK/NACK received in the TS BORKEN state"},
+ [BTS_CTR_TS_BORKEN_EV_PDCH_DEACT_ACK_NACK] = {"ts_borken:event:pdch_deact_ack_nack", "PDCH_DEACT_ACK/NACK received in the TS BORKEN state"},
+ [BTS_CTR_TS_BORKEN_EV_TEARDOWN] = {"ts_borken:event:teardown", "TS in a BORKEN state is shutting down (BTS disconnected?)"},
+ [BTS_CTR_ASSIGNMENT_ATTEMPTED] = {"assignment:attempted", "Assignment attempts"},
+ [BTS_CTR_ASSIGNMENT_COMPLETED] = {"assignment:completed", "Assignment completed"},
+ [BTS_CTR_ASSIGNMENT_STOPPED] = {"assignment:stopped", "Connection ended during Assignment"},
+ [BTS_CTR_ASSIGNMENT_NO_CHANNEL] = {"assignment:no_channel", "Failure to allocate lchan for Assignment"},
+ [BTS_CTR_ASSIGNMENT_TIMEOUT] = {"assignment:timeout", "Assignment timed out"},
+ [BTS_CTR_ASSIGNMENT_FAILED] = {"assignment:failed", "Received Assignment Failure message"},
+ [BTS_CTR_ASSIGNMENT_ERROR] = {"assignment:error", "Assignment failed for other reason"},
+
+};
+
+static const struct rate_ctr_group_desc bts_ctrg_desc = {
+ "bts",
+ "base transceiver station",
+ OSMO_STATS_CLASS_GLOBAL,
+ ARRAY_SIZE(bts_ctr_description),
+ bts_ctr_description,
+};
+
+enum {
+ BTS_STAT_CHAN_LOAD_AVERAGE,
+ BTS_STAT_CHAN_CCCH_SDCCH4_USED,
+ BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL,
+ BTS_STAT_CHAN_TCH_F_USED,
+ BTS_STAT_CHAN_TCH_F_TOTAL,
+ BTS_STAT_CHAN_TCH_H_USED,
+ BTS_STAT_CHAN_TCH_H_TOTAL,
+ BTS_STAT_CHAN_SDCCH8_USED,
+ BTS_STAT_CHAN_SDCCH8_TOTAL,
+ BTS_STAT_CHAN_TCH_F_PDCH_USED,
+ BTS_STAT_CHAN_TCH_F_PDCH_TOTAL,
+ BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED,
+ BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL,
+ BTS_STAT_CHAN_SDCCH8_CBCH_USED,
+ BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL,
+ BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED,
+ BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL,
+ BTS_STAT_T3122,
+ BTS_STAT_RACH_BUSY,
+ BTS_STAT_RACH_ACCESS,
+ BTS_STAT_OML_CONNECTED,
+ BTS_STAT_RSL_CONNECTED,
+ BTS_STAT_LCHAN_BORKEN,
+ BTS_STAT_TS_BORKEN,
+};
+
+enum gsm_bts_type {
+ GSM_BTS_TYPE_UNKNOWN,
+ GSM_BTS_TYPE_BS11,
+ GSM_BTS_TYPE_NANOBTS,
+ GSM_BTS_TYPE_RBS2000,
+ GSM_BTS_TYPE_NOKIA_SITE,
+ GSM_BTS_TYPE_OSMOBTS,
+ _NUM_GSM_BTS_TYPE
+};
+extern const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1];
+extern const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1];
+
+enum gsm_bts_type_variant {
+ BTS_UNKNOWN,
+ BTS_OSMO_LITECELL15,
+ BTS_OSMO_OCTPHY,
+ BTS_OSMO_SYSMO,
+ BTS_OSMO_TRX,
+ _NUM_BTS_VARIANT
+};
+
+/* Used by OML layer for BTS Attribute reporting */
+enum bts_attribute {
+ BTS_TYPE_VARIANT,
+ BTS_SUB_MODEL,
+ TRX_PHY_VERSION,
+};
+
+struct vty;
+
+struct gsm_bts_model {
+ struct llist_head list;
+
+ enum gsm_bts_type type;
+ enum gsm_bts_type_variant variant;
+ const char *name;
+
+ bool started;
+ int (*start)(struct gsm_network *net);
+ int (*oml_rcvmsg)(struct msgb *msg);
+ char * (*oml_status)(const struct gsm_bts *bts);
+
+ void (*e1line_bind_ops)(struct e1inp_line *line);
+
+ void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);
+ void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);
+ void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts);
+
+ /* Should SI2bis and SI2ter be disabled by default on this BTS model? */
+ bool force_combined_si;
+
+ struct tlv_definition nm_att_tlvdef;
+
+ /* features of a given BTS model set via gsm_bts_model_register() locally */
+ struct bitvec features;
+ uint8_t _features_data[MAX_BTS_FEATURES/8];
+};
+
+/* One BTS */
+struct gsm_bts {
+ /* list header in net->bts_list */
+ struct llist_head list;
+
+ /* Geographical location of the BTS */
+ struct llist_head loc_list;
+
+ /* number of this BTS in network */
+ uint8_t nr;
+ /* human readable name / description */
+ char *description;
+ /* Cell Identity */
+ uint16_t cell_identity;
+ /* location area code of this BTS */
+ uint16_t location_area_code;
+ /* Base Station Identification Code (BSIC), lower 3 bits is BCC,
+ * which is used as TSC for the CCCH */
+ uint8_t bsic;
+ /* type of BTS */
+ enum gsm_bts_type type;
+ enum gsm_bts_type_variant variant;
+ struct gsm_bts_model *model;
+ enum gsm_band band;
+ char version[MAX_VERSION_LENGTH];
+ char sub_model[MAX_VERSION_LENGTH];
+
+ /* features of a given BTS set/reported via OML */
+ struct bitvec features;
+ uint8_t _features_data[MAX_BTS_FEATURES/8];
+
+ /* Connected PCU version (if any) */
+ char pcu_version[MAX_VERSION_LENGTH];
+
+ /* maximum Tx power that the MS is permitted to use in this cell */
+ int ms_max_power;
+
+ /* how do we talk OML with this TRX? */
+ struct gsm_e1_subslot oml_e1_link;
+ uint8_t oml_tei;
+ struct e1inp_sign_link *oml_link;
+ /* Timer to use for deferred drop of OML link, see \ref ipaccess_drop_oml_deferred */
+ struct osmo_timer_list oml_drop_link_timer;
+ /* when OML link was established */
+ time_t uptime;
+
+ /* Abis network management O&M handle */
+ struct abis_nm_h *nmh;
+
+ struct gsm_abis_mo mo;
+
+ /* number of this BTS on given E1 link */
+ uint8_t bts_nr;
+
+ /* DTX features of this BTS */
+ enum gsm48_dtx_mode dtxu;
+ bool dtxd;
+
+ /* paging state and control */
+ struct gsm_bts_paging_state paging;
+
+ /* CCCH is on C0 */
+ struct gsm_bts_trx *c0;
+
+ struct {
+ struct gsm_abis_mo mo;
+ } site_mgr;
+
+ /* bitmask of all SI that are present/valid in si_buf */
+ uint32_t si_valid;
+ /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
+ uint8_t si2q_index; /* distinguish individual SI2quater messages */
+ uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
+ /* buffers where we put the pre-computed SI */
+ sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
+ /* offsets used while generating SI2quater */
+ size_t e_offset;
+ size_t u_offset;
+ /* 3GPP TS 08.58 ยง8.5.1 BCCH INFORMATION. Some nanoBTS fail upon
+ * receival of empty SI disabling unsupported SI. see OS#3707. */
+ bool si_unused_send_empty;
+
+ /* ip.access Unit ID's have Site/BTS/TRX layout */
+ union {
+ struct {
+ uint16_t site_id;
+ uint16_t bts_id;
+ uint32_t flags;
+ uint32_t rsl_ip;
+ } ip_access;
+ struct {
+ struct {
+ struct gsm_abis_mo mo;
+ } cclk;
+ struct {
+ struct gsm_abis_mo mo;
+ } rack;
+ struct gsm_envabtse envabtse[4];
+ } bs11;
+ struct {
+ struct {
+ struct om2k_mo om2k_mo;
+ struct gsm_abis_mo mo;
+ struct llist_head conn_groups;
+ } cf;
+ struct {
+ struct om2k_mo om2k_mo;
+ struct gsm_abis_mo mo;
+ struct llist_head conn_groups;
+ } is;
+ struct {
+ struct om2k_mo om2k_mo;
+ struct gsm_abis_mo mo;
+ struct llist_head conn_groups;
+ } con;
+ struct {
+ struct om2k_mo om2k_mo;
+ struct gsm_abis_mo mo;
+ } dp;
+ struct {
+ struct om2k_mo om2k_mo;
+ struct gsm_abis_mo mo;
+ } tf;
+ struct {
+ struct om2k_mo om2k_mo;
+ struct gsm_abis_mo mo;
+ } mctr;
+ uint32_t use_superchannel:1;
+ struct {
+ uint16_t limit;
+ uint16_t active;
+ } om2k_version[16];
+ } rbs2000;
+ struct {
+ uint8_t bts_type;
+ unsigned int configured:1, /* we sent the config data request */
+ skip_reset:1, /* skip reset at bootstrap */
+ no_loc_rel_cnf:1, /* don't wait for RSL REL CONF */
+ bts_reset_timer_cnf, /* timer for BTS RESET */
+ did_reset:1, /* we received a RESET ACK */
+ wait_reset:2; /* we are waiting for reset to complete */
+ struct osmo_timer_list reset_timer;
+ } nokia;
+ };
+
+ /* Not entirely sure how ip.access specific this is */
+ struct {
+ enum bts_gprs_mode mode;
+ struct {
+ struct gsm_abis_mo mo;
+ uint16_t nsei;
+ uint8_t timer[7];
+ } nse;
+ struct {
+ struct gsm_abis_mo mo;
+ uint16_t bvci;
+ uint8_t timer[11];
+ struct gprs_rlc_cfg rlc_cfg;
+ } cell;
+ struct gsm_bts_gprs_nsvc nsvc[2];
+ uint8_t rac;
+ uint8_t net_ctrl_ord;
+ bool ctrl_ack_type_use_block;
+ bool egprs_pkt_chan_request;
+ } gprs;
+
+ /* threshold (in percent) when BTS shall send CCCH LOAD IND */
+ int ccch_load_ind_thresh;
+
+ /* RACH NM values */
+ int rach_b_thresh;
+ int rach_ldavg_slots;
+
+ /* transceivers */
+ int num_trx;
+ struct llist_head trx_list;
+
+ /* SI related items */
+ int force_combined_si;
+ bool force_combined_si_set;
+ int bcch_change_mark;
+
+ /* Abis NM queue */
+ struct llist_head abis_queue;
+ int abis_nm_pend;
+
+ struct gsm_network *network;
+
+ /* should the channel allocator allocate channels from high TRX to TRX0,
+ * rather than starting from TRX0 and go upwards? */
+ int chan_alloc_reverse;
+
+ enum neigh_list_manual_mode neigh_list_manual_mode;
+ /* parameters from which we build SYSTEM INFORMATION */
+ struct {
+ struct gsm48_rach_control rach_control;
+ uint8_t ncc_permitted;
+ struct gsm48_cell_sel_par cell_sel_par;
+ struct gsm48_si_selection_params cell_ro_sel_par; /* rest octet */
+ struct gsm48_cell_options cell_options;
+ struct gsm48_control_channel_descr chan_desc;
+ struct bitvec neigh_list;
+ struct bitvec cell_alloc;
+ struct bitvec si5_neigh_list;
+ struct osmo_earfcn_si2q si2quater_neigh_list;
+ size_t uarfcn_length; /* index for uarfcn and scramble lists */
+ struct {
+ /* bitmask large enough for all possible ARFCN's */
+ uint8_t neigh_list[1024/8];
+ uint8_t cell_alloc[1024/8];
+ /* If the user wants a different neighbor list in SI5 than in SI2 */
+ uint8_t si5_neigh_list[1024/8];
+ uint8_t meas_bw_list[MAX_EARFCN_LIST];
+ uint16_t earfcn_list[MAX_EARFCN_LIST];
+ uint16_t uarfcn_list[MAX_EARFCN_LIST];
+ uint16_t scramble_list[MAX_EARFCN_LIST];
+ } data;
+ } si_common;
+ bool early_classmark_allowed;
+ bool early_classmark_allowed_3g;
+ /* for testing only: Have an infinitely long radio link timeout */
+ bool infinite_radio_link_timeout;
+
+ /* do we use static (user-defined) system information messages? (bitmask) */
+ uint32_t si_mode_static;
+
+ /* access control class ramping */
+ struct acc_ramp acc_ramp;
+
+ /* exclude the BTS from the global RF Lock handling */
+ int excl_from_rf_lock;
+
+ /* supported codecs beside FR */
+ struct bts_codec_conf codec;
+
+ /* BTS dependencies bit field */
+ uint32_t depends_on[256/(8*4)];
+
+ /* full and half rate multirate config */
+ struct amr_multirate_conf mr_full;
+ struct amr_multirate_conf mr_half;
+
+ /* PCU socket state */
+ char *pcu_sock_path;
+ struct pcu_sock_state *pcu_state;
+
+ struct rate_ctr_group *bts_ctrs;
+ struct osmo_stat_item_group *bts_statg;
+
+ struct handover_cfg *ho;
+
+ /* A list of struct gsm_bts_ref, indicating neighbors of this BTS.
+ * When the si_common neigh_list is in automatic mode, it is populated from this list as well as
+ * gsm_network->neighbor_bss_cells. */
+ struct llist_head local_neighbors;
+
+ /* BTS-specific overrides for timer values from struct gsm_network. */
+ uint8_t T3122; /* ASSIGNMENT REJECT wait indication */
+ bool T3113_dynamic; /* Calculate T3113 timeout dynamically based on BTS channel config and load */
+
+ /* Periodic channel load measurements are used to maintain T3122. */
+ struct load_counter chan_load_samples[7];
+ int chan_load_samples_idx;
+ uint8_t chan_load_avg; /* current channel load average in percent (0 - 100). */
+
+ /* cell broadcast system */
+ struct osmo_timer_list cbch_timer;
+ struct bts_smscb_chan_state cbch_basic;
+ struct bts_smscb_chan_state cbch_extended;
+ struct osmo_timer_list etws_timer; /* when to stop ETWS PN */
+
+ struct llist_head oml_fail_rep;
+};
+
+#define GSM_BTS_SI2Q(bts, i) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
+#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
+#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
+
+/* this actually refers to the IPA transport, not the BTS model */
+static inline int is_ipaccess_bts(const struct gsm_bts *bts)
+{
+ switch (bts->type) {
+ case GSM_BTS_TYPE_NANOBTS:
+ case GSM_BTS_TYPE_OSMOBTS:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static inline int is_sysmobts_v2(const struct gsm_bts *bts)
+{
+ switch (bts->type) {
+ case GSM_BTS_TYPE_OSMOBTS:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static inline int is_siemens_bts(const struct gsm_bts *bts)
+{
+ switch (bts->type) {
+ case GSM_BTS_TYPE_BS11:
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static inline int is_nokia_bts(const struct gsm_bts *bts)
+{
+ switch (bts->type) {
+ case GSM_BTS_TYPE_NOKIA_SITE:
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static inline int is_ericsson_bts(const struct gsm_bts *bts)
+{
+ switch (bts->type) {
+ case GSM_BTS_TYPE_RBS2000:
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static inline int is_e1_bts(const struct gsm_bts *bts)
+{
+ switch (bts->type) {
+ case GSM_BTS_TYPE_BS11:
+ case GSM_BTS_TYPE_RBS2000:
+ case GSM_BTS_TYPE_NOKIA_SITE:
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static inline const struct osmo_location_area_id *bts_lai(struct gsm_bts *bts)
+{
+ static struct osmo_location_area_id lai;
+ lai = (struct osmo_location_area_id){
+ .plmn = bts->network->plmn,
+ .lac = bts->location_area_code,
+ };
+ return &lai;
+}
+
+struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num);
+
+char *gsm_bts_name(const struct gsm_bts *bts);
+
+bool gsm_bts_matches_lai(const struct gsm_bts *bts, const struct osmo_location_area_id *lai);
+bool gsm_bts_matches_cell_id(const struct gsm_bts *bts, const struct gsm0808_cell_id *cell_id);
+
+int gsm_bts_local_neighbor_add(struct gsm_bts *bts, struct gsm_bts *neighbor);
+int gsm_bts_local_neighbor_del(struct gsm_bts *bts, const struct gsm_bts *neighbor);
+
+/* return the gsm_lchan for the CBCH (if it exists at all) */
+struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
+
+int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
+
+struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
+
+int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);
+
+unsigned long long bts_uptime(const struct gsm_bts *bts);
+
+char *get_model_oml_status(const struct gsm_bts *bts);
+/* reset the state of all MO in the BTS */
+void gsm_bts_mo_reset(struct gsm_bts *bts);
+
+/* dependency handling */
+void bts_depend_mark(struct gsm_bts *bts, int dep);
+void bts_depend_clear(struct gsm_bts *bts, int dep);
+int bts_depend_check(struct gsm_bts *bts);
+int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other);
+
+int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts);
+void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value);
+
+void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data);
+
+int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);
+
+int gsm_bts_model_register(struct gsm_bts_model *model);
+struct gsm_bts_model *bts_model_find(enum gsm_bts_type type);
+
+enum gsm_bts_type str2btstype(const char *arg);
+const char *btstype2str(enum gsm_bts_type type);
+
+enum bts_attribute str2btsattr(const char *s);
+const char *btsatttr2str(enum bts_attribute v);
+
+enum gsm_bts_type_variant str2btsvariant(const char *arg);
+const char *btsvariant2str(enum gsm_bts_type_variant v);
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index c35798192..a74e6d982 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -39,6 +39,7 @@ struct mgcp_client_conf;
struct mgcp_client;
struct gsm0808_cell_id;
struct osmo_mgcpc_ep;
+struct gsm_bts;
/** annotations for msgb ownership */
#define __uses
@@ -772,69 +773,8 @@ struct gsm_bts_trx {
struct gsm_bts_trx_ts ts[TRX_NR_TS];
};
-#define GSM_BTS_SI2Q(bts, i) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
-#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
-#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0])
-enum gsm_bts_type {
- GSM_BTS_TYPE_UNKNOWN,
- GSM_BTS_TYPE_BS11,
- GSM_BTS_TYPE_NANOBTS,
- GSM_BTS_TYPE_RBS2000,
- GSM_BTS_TYPE_NOKIA_SITE,
- GSM_BTS_TYPE_OSMOBTS,
- _NUM_GSM_BTS_TYPE
-};
-
-enum gsm_bts_type_variant {
- BTS_UNKNOWN,
- BTS_OSMO_LITECELL15,
- BTS_OSMO_OCTPHY,
- BTS_OSMO_SYSMO,
- BTS_OSMO_TRX,
- _NUM_BTS_VARIANT
-};
-
-/* Used by OML layer for BTS Attribute reporting */
-enum bts_attribute {
- BTS_TYPE_VARIANT,
- BTS_SUB_MODEL,
- TRX_PHY_VERSION,
-};
-
-struct vty;
-
-struct gsm_bts_model {
- struct llist_head list;
-
- enum gsm_bts_type type;
- enum gsm_bts_type_variant variant;
- const char *name;
-
- bool started;
- int (*start)(struct gsm_network *net);
- int (*oml_rcvmsg)(struct msgb *msg);
- char * (*oml_status)(const struct gsm_bts *bts);
-
- void (*e1line_bind_ops)(struct e1inp_line *line);
-
- void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);
- void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);
- void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts);
-
- /* Should SI2bis and SI2ter be disabled by default on this BTS model? */
- bool force_combined_si;
-
- struct tlv_definition nm_att_tlvdef;
-
- /* features of a given BTS model set via gsm_bts_model_register() locally */
- struct bitvec features;
- uint8_t _features_data[MAX_BTS_FEATURES/8];
-};
-
-
-
/*
* This keeps track of the paging status of one BTS. It
* includes a number of pending requests, a back pointer
@@ -1004,280 +944,6 @@ struct bts_oml_fail_rep {
struct msgb *mb;
};
-/* One BTS */
-struct gsm_bts {
- /* list header in net->bts_list */
- struct llist_head list;
-
- /* Geographical location of the BTS */
- struct llist_head loc_list;
-
- /* number of this BTS in network */
- uint8_t nr;
- /* human readable name / description */
- char *description;
- /* Cell Identity */
- uint16_t cell_identity;
- /* location area code of this BTS */
- uint16_t location_area_code;
- /* Base Station Identification Code (BSIC), lower 3 bits is BCC,
- * which is used as TSC for the CCCH */
- uint8_t bsic;
- /* type of BTS */
- enum gsm_bts_type type;
- enum gsm_bts_type_variant variant;
- struct gsm_bts_model *model;
- enum gsm_band band;
- char version[MAX_VERSION_LENGTH];
- char sub_model[MAX_VERSION_LENGTH];
-
- /* features of a given BTS set/reported via OML */
- struct bitvec features;
- uint8_t _features_data[MAX_BTS_FEATURES/8];
-
- /* Connected PCU version (if any) */
- char pcu_version[MAX_VERSION_LENGTH];
-
- /* maximum Tx power that the MS is permitted to use in this cell */
- int ms_max_power;
-
- /* how do we talk OML with this TRX? */
- struct gsm_e1_subslot oml_e1_link;
- uint8_t oml_tei;
- struct e1inp_sign_link *oml_link;
- /* Timer to use for deferred drop of OML link, see \ref ipaccess_drop_oml_deferred */
- struct osmo_timer_list oml_drop_link_timer;
- /* when OML link was established */
- time_t uptime;
-
- /* Abis network management O&M handle */
- struct abis_nm_h *nmh;
-
- struct gsm_abis_mo mo;
-
- /* number of this BTS on given E1 link */
- uint8_t bts_nr;
-
- /* DTX features of this BTS */
- enum gsm48_dtx_mode dtxu;
- bool dtxd;
-
- /* paging state and control */
- struct gsm_bts_paging_state paging;
-
- /* CCCH is on C0 */
- struct gsm_bts_trx *c0;
-
- struct {
- struct gsm_abis_mo mo;
- } site_mgr;
-
- /* bitmask of all SI that are present/valid in si_buf */
- uint32_t si_valid;
- /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
- uint8_t si2q_index; /* distinguish individual SI2quater messages */
- uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
- /* buffers where we put the pre-computed SI */
- sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
- /* offsets used while generating SI2quater */
- size_t e_offset;
- size_t u_offset;
- /* 3GPP TS 08.58 ยง8.5.1 BCCH INFORMATION. Some nanoBTS fail upon
- * receival of empty SI disabling unsupported SI. see OS#3707. */
- bool si_unused_send_empty;
-
- /* ip.access Unit ID's have Site/BTS/TRX layout */
- union {
- struct {
- uint16_t site_id;
- uint16_t bts_id;
- uint32_t flags;
- uint32_t rsl_ip;
- } ip_access;
- struct {
- struct {
- struct gsm_abis_mo mo;
- } cclk;
- struct {
- struct gsm_abis_mo mo;
- } rack;
- struct gsm_envabtse envabtse[4];
- } bs11;
- struct {
- struct {
- struct om2k_mo om2k_mo;
- struct gsm_abis_mo mo;
- struct llist_head conn_groups;
- } cf;
- struct {
- struct om2k_mo om2k_mo;
- struct gsm_abis_mo mo;
- struct llist_head conn_groups;
- } is;
- struct {
- struct om2k_mo om2k_mo;
- struct gsm_abis_mo mo;
- struct llist_head conn_groups;
- } con;
- struct {
- struct om2k_mo om2k_mo;
- struct gsm_abis_mo mo;
- } dp;
- struct {
- struct om2k_mo om2k_mo;
- struct gsm_abis_mo mo;
- } tf;
- struct {
- struct om2k_mo om2k_mo;
- struct gsm_abis_mo mo;
- } mctr;
- uint32_t use_superchannel:1;
- struct {
- uint16_t limit;
- uint16_t active;
- } om2k_version[16];
- } rbs2000;
- struct {
- uint8_t bts_type;
- unsigned int configured:1, /* we sent the config data request */
- skip_reset:1, /* skip reset at bootstrap */
- no_loc_rel_cnf:1, /* don't wait for RSL REL CONF */
- bts_reset_timer_cnf, /* timer for BTS RESET */
- did_reset:1, /* we received a RESET ACK */
- wait_reset:2; /* we are waiting for reset to complete */
- struct osmo_timer_list reset_timer;
- } nokia;
- };
-
- /* Not entirely sure how ip.access specific this is */
- struct {
- enum bts_gprs_mode mode;
- struct {
- struct gsm_abis_mo mo;
- uint16_t nsei;
- uint8_t timer[7];
- } nse;
- struct {
- struct gsm_abis_mo mo;
- uint16_t bvci;
- uint8_t timer[11];
- struct gprs_rlc_cfg rlc_cfg;
- } cell;
- struct gsm_bts_gprs_nsvc nsvc[2];
- uint8_t rac;
- uint8_t net_ctrl_ord;
- bool ctrl_ack_type_use_block;
- bool egprs_pkt_chan_request;
- } gprs;
-
- /* threshold (in percent) when BTS shall send CCCH LOAD IND */
- int ccch_load_ind_thresh;
-
- /* RACH NM values */
- int rach_b_thresh;
- int rach_ldavg_slots;
-
- /* transceivers */
- int num_trx;
- struct llist_head trx_list;
-
- /* SI related items */
- int force_combined_si;
- bool force_combined_si_set;
- int bcch_change_mark;
-
- /* Abis NM queue */
- struct llist_head abis_queue;
- int abis_nm_pend;
-
- struct gsm_network *network;
-
- /* should the channel allocator allocate channels from high TRX to TRX0,
- * rather than starting from TRX0 and go upwards? */
- int chan_alloc_reverse;
-
- enum neigh_list_manual_mode neigh_list_manual_mode;
- /* parameters from which we build SYSTEM INFORMATION */
- struct {
- struct gsm48_rach_control rach_control;
- uint8_t ncc_permitted;
- struct gsm48_cell_sel_par cell_sel_par;
- struct gsm48_si_selection_params cell_ro_sel_par; /* rest octet */
- struct gsm48_cell_options cell_options;
- struct gsm48_control_channel_descr chan_desc;
- struct bitvec neigh_list;
- struct bitvec cell_alloc;
- struct bitvec si5_neigh_list;
- struct osmo_earfcn_si2q si2quater_neigh_list;
- size_t uarfcn_length; /* index for uarfcn and scramble lists */
- struct {
- /* bitmask large enough for all possible ARFCN's */
- uint8_t neigh_list[1024/8];
- uint8_t cell_alloc[1024/8];
- /* If the user wants a different neighbor list in SI5 than in SI2 */
- uint8_t si5_neigh_list[1024/8];
- uint8_t meas_bw_list[MAX_EARFCN_LIST];
- uint16_t earfcn_list[MAX_EARFCN_LIST];
- uint16_t uarfcn_list[MAX_EARFCN_LIST];
- uint16_t scramble_list[MAX_EARFCN_LIST];
- } data;
- } si_common;
- bool early_classmark_allowed;
- bool early_classmark_allowed_3g;
- /* for testing only: Have an infinitely long radio link timeout */
- bool infinite_radio_link_timeout;
-
- /* do we use static (user-defined) system information messages? (bitmask) */
- uint32_t si_mode_static;
-
- /* access control class ramping */
- struct acc_ramp acc_ramp;
-
- /* exclude the BTS from the global RF Lock handling */
- int excl_from_rf_lock;
-
- /* supported codecs beside FR */
- struct bts_codec_conf codec;
-
- /* BTS dependencies bit field */
- uint32_t depends_on[256/(8*4)];
-
- /* full and half rate multirate config */
- struct amr_multirate_conf mr_full;
- struct amr_multirate_conf mr_half;
-
- /* PCU socket state */
- char *pcu_sock_path;
- struct pcu_sock_state *pcu_state;
-
- struct rate_ctr_group *bts_ctrs;
- struct osmo_stat_item_group *bts_statg;
-
- struct handover_cfg *ho;
-
- /* A list of struct gsm_bts_ref, indicating neighbors of this BTS.
- * When the si_common neigh_list is in automatic mode, it is populated from this list as well as
- * gsm_network->neighbor_bss_cells. */
- struct llist_head local_neighbors;
-
- /* BTS-specific overrides for timer values from struct gsm_network. */
- uint8_t T3122; /* ASSIGNMENT REJECT wait indication */
- bool T3113_dynamic; /* Calculate T3113 timeout dynamically based on BTS channel config and load */
-
- /* Periodic channel load measurements are used to maintain T3122. */
- struct load_counter chan_load_samples[7];
- int chan_load_samples_idx;
- uint8_t chan_load_avg; /* current channel load average in percent (0 - 100). */
-
- /* cell broadcast system */
- struct osmo_timer_list cbch_timer;
- struct bts_smscb_chan_state cbch_basic;
- struct bts_smscb_chan_state cbch_extended;
- struct osmo_timer_list etws_timer; /* when to stop ETWS PN */
-
- struct llist_head oml_fail_rep;
-};
-
/* One rejected BTS */
struct gsm_bts_rejected {
/* list header in net->bts_rejected */
@@ -1291,28 +957,14 @@ struct gsm_bts_rejected {
struct gsm_network *gsm_network_init(void *ctx);
-struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num);
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num);
-bool gsm_bts_matches_lai(const struct gsm_bts *bts, const struct osmo_location_area_id *lai);
-bool gsm_bts_matches_cell_id(const struct gsm_bts *bts, const struct gsm0808_cell_id *cell_id);
struct gsm_bts *gsm_bts_by_cell_id(const struct gsm_network *net,
const struct gsm0808_cell_id *cell_id,
int match_idx);
-int gsm_bts_local_neighbor_add(struct gsm_bts *bts, struct gsm_bts *neighbor);
-int gsm_bts_local_neighbor_del(struct gsm_bts *bts, const struct gsm_bts *neighbor);
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num);
-enum gsm_bts_type str2btstype(const char *arg);
-const char *btstype2str(enum gsm_bts_type type);
-
-enum bts_attribute str2btsattr(const char *s);
-const char *btsatttr2str(enum bts_attribute v);
-
-enum gsm_bts_type_variant str2btsvariant(const char *arg);
-const char *btsvariant2str(enum gsm_bts_type_variant v);
-
extern const struct value_string gsm_chreq_descs[];
extern const struct value_string gsm_pchant_names[];
extern const struct value_string gsm_pchant_descs[];
@@ -1323,7 +975,6 @@ static inline const char *gsm_pchan_id(enum gsm_phys_chan_config c)
enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
const char *gsm_lchant_name(enum gsm_chan_t c);
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
-char *gsm_bts_name(const struct gsm_bts *bts);
char *gsm_trx_name(const struct gsm_bts_trx *trx);
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);
char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts);
@@ -1335,6 +986,8 @@ static inline char *gsm_lchan_name(const struct gsm_lchan *lchan)
}
void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
+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);
struct gsm_nm_state *
gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
@@ -1343,9 +996,6 @@ void *
gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
const struct abis_om_obj_inst *obj_inst);
-/* reset the state of all MO in the BTS */
-void gsm_bts_mo_reset(struct gsm_bts *bts);
-
uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
uint8_t ts_nr, uint8_t lchan_nr);
uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan);
@@ -1356,16 +1006,7 @@ void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
const struct gsm_lchan *lchan);
void gsm48_lchan2chan_desc_as_configured(struct gsm48_chan_desc *cd, const struct gsm_lchan *lchan);
-/* return the gsm_lchan for the CBCH (if it exists at all) */
-struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
-
-static inline 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;
-}
+uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts);
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
int *rc);
@@ -1375,164 +1016,11 @@ uint8_t pchan_subslots(enum gsm_phys_chan_config pchan);
bool ts_is_tch(struct gsm_bts_trx_ts *ts);
-static inline struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {
- if (!conn || !conn->lchan)
- return NULL;
- return conn->lchan->ts->trx->bts;
-}
+struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn);
void conn_update_ms_power_class(struct gsm_subscriber_connection *conn, uint8_t power_class);
void lchan_update_ms_power_ctrl_level(struct gsm_lchan *lchan, int ms_power_dbm);
-enum bts_counter_id {
- BTS_CTR_CHREQ_TOTAL,
- BTS_CTR_CHREQ_SUCCESSFUL,
- BTS_CTR_CHREQ_NO_CHANNEL,
- BTS_CTR_CHAN_RF_FAIL,
- BTS_CTR_CHAN_RLL_ERR,
- BTS_CTR_BTS_OML_FAIL,
- BTS_CTR_BTS_RSL_FAIL,
- BTS_CTR_CODEC_AMR_F,
- BTS_CTR_CODEC_AMR_H,
- BTS_CTR_CODEC_EFR,
- BTS_CTR_CODEC_V1_FR,
- BTS_CTR_CODEC_V1_HR,
- BTS_CTR_PAGING_ATTEMPTED,
- BTS_CTR_PAGING_ALREADY,
- BTS_CTR_PAGING_RESPONDED,
- BTS_CTR_PAGING_EXPIRED,
- BTS_CTR_PAGING_NO_ACTIVE_PAGING,
- BTS_CTR_PAGING_MSC_FLUSH,
- BTS_CTR_CHAN_ACT_TOTAL,
- BTS_CTR_CHAN_ACT_NACK,
- BTS_CTR_RSL_UNKNOWN,
- BTS_CTR_RSL_IPA_NACK,
- BTS_CTR_RSL_DELETE_IND,
- BTS_CTR_MODE_MODIFY_NACK,
- BTS_CTR_LCHAN_BORKEN_FROM_UNUSED,
- BTS_CTR_LCHAN_BORKEN_FROM_WAIT_ACTIV_ACK,
- BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RF_RELEASE_ACK,
- BTS_CTR_LCHAN_BORKEN_FROM_BORKEN,
- BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN,
- BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK,
- BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK,
- BTS_CTR_LCHAN_BORKEN_EV_RF_CHAN_REL_ACK,
- BTS_CTR_LCHAN_BORKEN_EV_VTY,
- BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN,
- BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED,
- BTS_CTR_TS_BORKEN_FROM_UNUSED,
- BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_ACT,
- BTS_CTR_TS_BORKEN_FROM_PDCH,
- BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_DEACT,
- BTS_CTR_TS_BORKEN_FROM_IN_USE,
- BTS_CTR_TS_BORKEN_FROM_BORKEN,
- BTS_CTR_TS_BORKEN_FROM_UNKNOWN,
- BTS_CTR_TS_BORKEN_EV_PDCH_ACT_ACK_NACK,
- BTS_CTR_TS_BORKEN_EV_PDCH_DEACT_ACK_NACK,
- BTS_CTR_TS_BORKEN_EV_TEARDOWN,
- BTS_CTR_ASSIGNMENT_ATTEMPTED,
- BTS_CTR_ASSIGNMENT_COMPLETED,
- BTS_CTR_ASSIGNMENT_STOPPED,
- BTS_CTR_ASSIGNMENT_NO_CHANNEL,
- BTS_CTR_ASSIGNMENT_TIMEOUT,
- BTS_CTR_ASSIGNMENT_FAILED,
- BTS_CTR_ASSIGNMENT_ERROR,
-};
-
-static const struct rate_ctr_desc bts_ctr_description[] = {
- [BTS_CTR_CHREQ_TOTAL] = {"chreq:total", "Received channel requests"},
- [BTS_CTR_CHREQ_SUCCESSFUL] = {"chreq:successful", "Successful channel requests (immediate assign sent)"},
- [BTS_CTR_CHREQ_NO_CHANNEL] = {"chreq:no_channel", "Sent to MS no channel available"},
- [BTS_CTR_CHAN_RF_FAIL] = {"chan:rf_fail", "Received a RF failure indication from BTS"},
- [BTS_CTR_CHAN_RLL_ERR] = {"chan:rll_err", "Received a RLL failure with T200 cause from BTS"},
- [BTS_CTR_BTS_OML_FAIL] = {"oml_fail", "Received a TEI down on a OML link"},
- [BTS_CTR_BTS_RSL_FAIL] = {"rsl_fail", "Received a TEI down on a OML link"},
- [BTS_CTR_CODEC_AMR_F] = {"codec:amr_f", "Count the usage of AMR/F codec by channel mode requested"},
- [BTS_CTR_CODEC_AMR_H] = {"codec:amr_h", "Count the usage of AMR/H codec by channel mode requested"},
- [BTS_CTR_CODEC_EFR] = {"codec:efr", "Count the usage of EFR codec by channel mode requested"},
- [BTS_CTR_CODEC_V1_FR] = {"codec:fr", "Count the usage of FR codec by channel mode requested"},
- [BTS_CTR_CODEC_V1_HR] = {"codec:hr", "Count the usage of HR codec by channel mode requested"},
-
- [BTS_CTR_PAGING_ATTEMPTED] = {"paging:attempted", "Paging attempts for a subscriber"},
- [BTS_CTR_PAGING_ALREADY] = {"paging:already", "Paging attempts ignored as subscriber was already being paged"},
- [BTS_CTR_PAGING_RESPONDED] = {"paging:responded", "Paging attempts with successful paging response"},
- [BTS_CTR_PAGING_EXPIRED] = {"paging:expired", "Paging Request expired because of timeout T3113"},
- [BTS_CTR_PAGING_NO_ACTIVE_PAGING] = {"paging:no_active_paging", "Paging response without an active paging request (arrived after paging expiration?)"},
- [BTS_CTR_PAGING_MSC_FLUSH] = {"paging:msc_flush", "Paging flushed due to MSC Reset BSSMAP message"},
- [BTS_CTR_CHAN_ACT_TOTAL] = {"chan_act:total", "Total number of Channel Activations"},
- [BTS_CTR_CHAN_ACT_NACK] = {"chan_act:nack", "Number of Channel Activations that the BTS NACKed"},
- [BTS_CTR_RSL_UNKNOWN] = {"rsl:unknown", "Number of unknown/unsupported RSL messages received from BTS"},
- [BTS_CTR_RSL_IPA_NACK] = {"rsl:ipa_nack", "Number of IPA (RTP/dyn-PDCH) related NACKs received from BTS"},
- [BTS_CTR_RSL_DELETE_IND] = {"rsl:delete_ind", "Number of RSL DELETE INDICATION (DL CCCH overload)"},
- [BTS_CTR_MODE_MODIFY_NACK] = {"chan:mode_modify_nack", "Number of Channel Mode Modify NACKs received from BTS"},
-
- /* lchan/TS BORKEN state counters */
- [BTS_CTR_LCHAN_BORKEN_FROM_UNUSED] = {"lchan_borken:from_state:unused", "Transitions from lchan UNUSED state to BORKEN state"},
- [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_ACTIV_ACK] = {"lchan_borken:from_state:wait_activ_ack", "Transitions from lchan WAIT_ACTIV_ACK state to BORKEN state"},
- [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RF_RELEASE_ACK] = {"lchan_borken:from_state:wait_rf_release_ack", "Transitions from lchan WAIT_RF_RELEASE_ACK state to BORKEN state"},
- [BTS_CTR_LCHAN_BORKEN_FROM_BORKEN] = {"lchan_borken:from_state:borken", "Transitions from lchan BORKEN state to BORKEN state"},
- [BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN] = {"lchan_borken:from_state:unknown", "Transitions from an unknown lchan state to BORKEN state"},
- [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK] = {"lchan_borken:event:chan_activ_ack", "CHAN_ACTIV_ACK received in the lchan BORKEN state"},
- [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK] = {"lchan_borken:event:chan_activ_nack", "CHAN_ACTIV_NACK received in the lchan BORKEN state"},
- [BTS_CTR_LCHAN_BORKEN_EV_RF_CHAN_REL_ACK] = {"lchan_borken:event:rf_chan_rel_ack", "RF_CHAN_REL_ACK received in the lchan BORKEN state"},
- [BTS_CTR_LCHAN_BORKEN_EV_VTY] = {"lchan_borken:event:vty", "VTY commands received in the lchan BORKEN state"},
- [BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN] = {"lchan_borken:event:teardown", "lchan in a BORKEN state is shutting down (BTS disconnected?)"},
- [BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED] = {"ts_borken:from_state:not_initialized", "Transitions from TS NOT_INITIALIZED state to BORKEN state"},
- [BTS_CTR_TS_BORKEN_FROM_UNUSED] = {"ts_borken:from_state:unused", "Transitions from TS UNUSED state to BORKEN state"},
- [BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_ACT] = {"ts_borken:from_state:wait_pdch_act", "Transitions from TS WAIT_PDCH_ACT state to BORKEN state"},
- [BTS_CTR_TS_BORKEN_FROM_PDCH] = {"ts_borken:from_state:pdch", "Transitions from TS PDCH state to BORKEN state"},
- [BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_DEACT] = {"ts_borken:from_state:wait_pdch_deact", "Transitions from TS WAIT_PDCH_DEACT state to BORKEN state"},
- [BTS_CTR_TS_BORKEN_FROM_IN_USE] = {"ts_borken:from_state:in_use", "Transitions from TS IN_USE state to BORKEN state"},
- [BTS_CTR_TS_BORKEN_FROM_BORKEN] = {"ts_borken:from_state:borken", "Transitions from TS BORKEN state to BORKEN state"},
- [BTS_CTR_TS_BORKEN_FROM_UNKNOWN] = {"ts_borken:from_state:unknown", "Transitions from an unknown TS state to BORKEN state"},
- [BTS_CTR_TS_BORKEN_EV_PDCH_ACT_ACK_NACK] = {"ts_borken:event:pdch_act_ack_nack", "PDCH_ACT_ACK/NACK received in the TS BORKEN state"},
- [BTS_CTR_TS_BORKEN_EV_PDCH_DEACT_ACK_NACK] = {"ts_borken:event:pdch_deact_ack_nack", "PDCH_DEACT_ACK/NACK received in the TS BORKEN state"},
- [BTS_CTR_TS_BORKEN_EV_TEARDOWN] = {"ts_borken:event:teardown", "TS in a BORKEN state is shutting down (BTS disconnected?)"},
- [BTS_CTR_ASSIGNMENT_ATTEMPTED] = {"assignment:attempted", "Assignment attempts"},
- [BTS_CTR_ASSIGNMENT_COMPLETED] = {"assignment:completed", "Assignment completed"},
- [BTS_CTR_ASSIGNMENT_STOPPED] = {"assignment:stopped", "Connection ended during Assignment"},
- [BTS_CTR_ASSIGNMENT_NO_CHANNEL] = {"assignment:no_channel", "Failure to allocate lchan for Assignment"},
- [BTS_CTR_ASSIGNMENT_TIMEOUT] = {"assignment:timeout", "Assignment timed out"},
- [BTS_CTR_ASSIGNMENT_FAILED] = {"assignment:failed", "Received Assignment Failure message"},
- [BTS_CTR_ASSIGNMENT_ERROR] = {"assignment:error", "Assignment failed for other reason"},
-
-};
-
-static const struct rate_ctr_group_desc bts_ctrg_desc = {
- "bts",
- "base transceiver station",
- OSMO_STATS_CLASS_GLOBAL,
- ARRAY_SIZE(bts_ctr_description),
- bts_ctr_description,
-};
-
-enum {
- BTS_STAT_CHAN_LOAD_AVERAGE,
- BTS_STAT_CHAN_CCCH_SDCCH4_USED,
- BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL,
- BTS_STAT_CHAN_TCH_F_USED,
- BTS_STAT_CHAN_TCH_F_TOTAL,
- BTS_STAT_CHAN_TCH_H_USED,
- BTS_STAT_CHAN_TCH_H_TOTAL,
- BTS_STAT_CHAN_SDCCH8_USED,
- BTS_STAT_CHAN_SDCCH8_TOTAL,
- BTS_STAT_CHAN_TCH_F_PDCH_USED,
- BTS_STAT_CHAN_TCH_F_PDCH_TOTAL,
- BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED,
- BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL,
- BTS_STAT_CHAN_SDCCH8_CBCH_USED,
- BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL,
- BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED,
- BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL,
- BTS_STAT_T3122,
- BTS_STAT_RACH_BUSY,
- BTS_STAT_RACH_ACCESS,
- BTS_STAT_OML_CONNECTED,
- BTS_STAT_RSL_CONNECTED,
- BTS_STAT_LCHAN_BORKEN,
- BTS_STAT_TS_BORKEN,
-};
-
enum {
BSC_CTR_ASSIGNMENT_ATTEMPTED,
BSC_CTR_ASSIGNMENT_COMPLETED,
@@ -1743,20 +1231,8 @@ struct gsm_audio_support {
ver : 7;
};
-static inline const struct osmo_location_area_id *bts_lai(struct gsm_bts *bts)
-{
- static struct osmo_location_area_id lai;
- lai = (struct osmo_location_area_id){
- .plmn = bts->network->plmn,
- .lac = bts->location_area_code,
- };
- return &lai;
-}
-
extern void talloc_ctx_init(void *ctx_root);
-int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
-
enum gsm_bts_type parse_btstype(const char *arg);
const char *btstype2str(enum gsm_bts_type type);
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
@@ -1764,91 +1240,14 @@ struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
extern void *tall_bsc_ctx;
-/* this actually refers to the IPA transport, not the BTS model */
-static inline int is_ipaccess_bts(const struct gsm_bts *bts)
-{
- switch (bts->type) {
- case GSM_BTS_TYPE_NANOBTS:
- case GSM_BTS_TYPE_OSMOBTS:
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-static inline int is_sysmobts_v2(const struct gsm_bts *bts)
-{
- switch (bts->type) {
- case GSM_BTS_TYPE_OSMOBTS:
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-static inline int is_siemens_bts(const struct gsm_bts *bts)
-{
- switch (bts->type) {
- case GSM_BTS_TYPE_BS11:
- return 1;
- default:
- break;
- }
-
- return 0;
-}
-
-static inline int is_nokia_bts(const struct gsm_bts *bts)
-{
- switch (bts->type) {
- case GSM_BTS_TYPE_NOKIA_SITE:
- return 1;
- default:
- break;
- }
-
- return 0;
-}
-
-static inline int is_ericsson_bts(const struct gsm_bts *bts)
-{
- switch (bts->type) {
- case GSM_BTS_TYPE_RBS2000:
- return 1;
- default:
- break;
- }
-
- return 0;
-}
-
-static inline int is_e1_bts(const struct gsm_bts *bts)
-{
- switch (bts->type) {
- case GSM_BTS_TYPE_BS11:
- case GSM_BTS_TYPE_RBS2000:
- case GSM_BTS_TYPE_NOKIA_SITE:
- return 1;
- default:
- break;
- }
-
- return 0;
-}
-
extern struct gsm_network *bsc_gsmnet;
enum bts_gprs_mode bts_gprs_mode_parse(const char *arg, int *valid);
const char *bts_gprs_mode_name(enum bts_gprs_mode mode);
-int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);
void gsm48_ra_id_by_bts(struct gsm48_ra_id *buf, struct gsm_bts *bts);
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
-int gsm_bts_model_register(struct gsm_bts_model *model);
-
struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *network);
struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type, uint8_t bsic);
@@ -1858,42 +1257,23 @@ void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
uint8_t e1_ts, uint8_t e1_ts_ss);
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, bool locked, const char *reason);
-struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx);
int gsm_bts_set_system_infos(struct gsm_bts *bts);
/* generic E1 line operations for all ISDN-based BTS. */
extern struct e1inp_line_ops bts_isdn_e1inp_line_ops;
-extern const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1];
-extern const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1];
-
-char *get_model_oml_status(const struct gsm_bts *bts);
-
-unsigned long long bts_uptime(const struct gsm_bts *bts);
-
/* control interface handling */
int bsc_base_ctrl_cmds_install(void);
-/* dependency handling */
-void bts_depend_mark(struct gsm_bts *bts, int dep);
-void bts_depend_clear(struct gsm_bts *bts, int dep);
-int bts_depend_check(struct gsm_bts *bts);
-int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other);
-
-int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts);
-void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value);
-
bool trx_is_usable(const struct gsm_bts_trx *trx);
bool ts_is_usable(const struct gsm_bts_trx_ts *ts);
int gsm_lchan_type_by_pchan(enum gsm_phys_chan_config pchan);
enum gsm_phys_chan_config gsm_pchan_by_lchan_type(enum gsm_chan_t type);
-void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data);
void gsm_trx_all_ts_dispatch(struct gsm_bts_trx *trx, uint32_t ts_ev, void *data);
-
-int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);
+int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan);
bool trx_has_valid_pchan_config(const struct gsm_bts_trx *trx);
diff --git a/src/ipaccess/Makefile.am b/src/ipaccess/Makefile.am
index 145ea3989..273530cf5 100644
--- a/src/ipaccess/Makefile.am
+++ b/src/ipaccess/Makefile.am
@@ -46,6 +46,7 @@ ipaccess_config_SOURCES = \
# FIXME: resolve the bogus dependencies patched around here:
ipaccess_config_LDADD = \
+ $(top_builddir)/src/osmo-bsc/bts.o \
$(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 \
@@ -57,9 +58,10 @@ ipaccess_config_LDADD = \
ipaccess_proxy_SOURCES = \
ipaccess-proxy.c \
stubs.c \
- $(top_srcdir)/src/osmo-bsc/gsm_data.c \
$(NULL)
ipaccess_proxy_LDADD = \
+ $(top_builddir)/src/osmo-bsc/bts.o \
+ $(top_builddir)/src/osmo-bsc/gsm_data.o \
$(OSMO_LIBS) \
$(NULL)
diff --git a/src/ipaccess/ipaccess-config.c b/src/ipaccess/ipaccess-config.c
index f7d733231..34ad57f1c 100644
--- a/src/ipaccess/ipaccess-config.c
+++ b/src/ipaccess/ipaccess-config.c
@@ -56,6 +56,7 @@
#include <osmocom/abis/abis.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/bsc/bss.h>
+#include <osmocom/bsc/bts.h>
struct gsm_network *bsc_gsmnet;
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;
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
index e585e0df8..669667971 100644
--- a/src/utils/Makefile.am
+++ b/src/utils/Makefile.am
@@ -48,6 +48,7 @@ bs11_config_SOURCES = \
bs11_config_LDADD = \
$(top_builddir)/src/osmo-bsc/abis_nm.o \
+ $(top_builddir)/src/osmo-bsc/bts.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 \
@@ -117,6 +118,7 @@ meas_json_SOURCES = \
$(NULL)
meas_json_LDADD = \
+ $(top_builddir)/src/osmo-bsc/bts.o \
$(top_builddir)/src/osmo-bsc/gsm_data.o \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
diff --git a/src/utils/bs11_config.c b/src/utils/bs11_config.c
index 11562336c..c43c008bf 100644
--- a/src/utils/bs11_config.c
+++ b/src/utils/bs11_config.c
@@ -39,6 +39,7 @@
#include <osmocom/bsc/debug.h>
#include <osmocom/core/select.h>
#include <osmocom/bsc/rs232.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/core/application.h>
#include <osmocom/core/talloc.h>
#include <osmocom/abis/abis.h>
diff --git a/tests/abis/Makefile.am b/tests/abis/Makefile.am
index 60054d94d..a01f56a29 100644
--- a/tests/abis/Makefile.am
+++ b/tests/abis/Makefile.am
@@ -26,6 +26,7 @@ abis_test_SOURCES = \
abis_test_LDADD = \
$(top_builddir)/src/osmo-bsc/abis_nm.o \
+ $(top_builddir)/src/osmo-bsc/bts.o \
$(top_builddir)/src/osmo-bsc/gsm_data.o \
$(top_builddir)/src/osmo-bsc/net_init.o \
$(LIBOSMOCORE_LIBS) \
diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c
index 43934f364..767a9fbc9 100644
--- a/tests/abis/abis_test.c
+++ b/tests/abis/abis_test.c
@@ -26,6 +26,7 @@
#include <osmocom/gsm/gsm23003.h>
#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/abis_nm.h>
#include <osmocom/bsc/debug.h>
diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am
index b301f9e9c..7ea002e6e 100644
--- a/tests/bsc/Makefile.am
+++ b/tests/bsc/Makefile.am
@@ -37,6 +37,7 @@ bsc_test_LDADD = \
$(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \
$(top_builddir)/src/osmo-bsc/osmo_bsc_filter.o \
$(top_builddir)/src/osmo-bsc/bsc_subscriber.o \
+ $(top_builddir)/src/osmo-bsc/bts.o \
$(top_builddir)/src/osmo-bsc/gsm_data.o \
$(top_builddir)/src/osmo-bsc/handover_cfg.o \
$(top_builddir)/src/osmo-bsc/handover_logic.o \
diff --git a/tests/codec_pref/codec_pref_test.c b/tests/codec_pref/codec_pref_test.c
index f163f35a6..5f4c831d4 100644
--- a/tests/codec_pref/codec_pref_test.c
+++ b/tests/codec_pref/codec_pref_test.c
@@ -20,6 +20,7 @@
*/
#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/osmo_bsc.h>
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/core/application.h>
diff --git a/tests/gsm0408/Makefile.am b/tests/gsm0408/Makefile.am
index aff7c7dd4..21b787341 100644
--- a/tests/gsm0408/Makefile.am
+++ b/tests/gsm0408/Makefile.am
@@ -25,6 +25,7 @@ gsm0408_test_SOURCES = \
gsm0408_test_LDADD = \
$(top_builddir)/src/osmo-bsc/gsm_04_08_rr.o \
$(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \
+ $(top_builddir)/src/osmo-bsc/bts.o \
$(top_builddir)/src/osmo-bsc/gsm_data.o \
$(top_builddir)/src/osmo-bsc/net_init.o \
$(top_builddir)/src/osmo-bsc/rest_octets.o \
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index 5ff9491e9..b3e8b11d3 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -29,6 +29,7 @@
#include <osmocom/bsc/arfcn_range_encode.h>
#include <osmocom/bsc/system_information.h>
#include <osmocom/bsc/abis_rsl.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/core/application.h>
#include <osmocom/core/byteswap.h>
diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am
index 736b44456..571b7a93a 100644
--- a/tests/handover/Makefile.am
+++ b/tests/handover/Makefile.am
@@ -57,6 +57,7 @@ handover_test_LDADD = \
$(top_builddir)/src/osmo-bsc/bsc_subscr_conn_fsm.o \
$(top_builddir)/src/osmo-bsc/bsc_subscriber.o \
$(top_builddir)/src/osmo-bsc/bsc_vty.o \
+ $(top_builddir)/src/osmo-bsc/bts.o \
$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts.o \
$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
$(top_builddir)/src/osmo-bsc/bts_unknown.o \
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index 1a756cda3..edc3219c1 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -47,6 +47,7 @@
#include <osmocom/bsc/lchan_fsm.h>
#include <osmocom/bsc/handover_fsm.h>
#include <osmocom/bsc/bsc_msc_data.h>
+#include <osmocom/bsc/bts.h>
void *ctx;
diff --git a/tests/nanobts_omlattr/Makefile.am b/tests/nanobts_omlattr/Makefile.am
index aa7045e49..93fdbe82b 100644
--- a/tests/nanobts_omlattr/Makefile.am
+++ b/tests/nanobts_omlattr/Makefile.am
@@ -25,6 +25,7 @@ nanobts_omlattr_test_SOURCES = \
nanobts_omlattr_test_LDADD = \
$(top_builddir)/src/osmo-bsc/abis_nm.o \
$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
+ $(top_builddir)/src/osmo-bsc/bts.o \
$(top_builddir)/src/osmo-bsc/gsm_data.o \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
diff --git a/tests/nanobts_omlattr/nanobts_omlattr_test.c b/tests/nanobts_omlattr/nanobts_omlattr_test.c
index a3ba8e006..4180f4a0e 100644
--- a/tests/nanobts_omlattr/nanobts_omlattr_test.c
+++ b/tests/nanobts_omlattr/nanobts_omlattr_test.c
@@ -22,6 +22,7 @@
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/bts_ipaccess_nanobts_omlattr.h>
+#include <osmocom/bsc/bts.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>