<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/19287">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Move struct gsm_bts: gsm_data.* => bts.*<br><br>Place all code related to the object into the related file.<br><br>Having all the data model in one file made sense in early stage of<br>development to make progress quickly, but nowadays it hurts more than<br>helps, due to constantly growing size and more and more bits being<br>added to the model, gaining in complexity.<br><br>Currently, having lots of different objects mixed up in gsm_data.h is a hole<br>of despair, where nobody can make any sense were to properly put new stuff<br>in, ending up with functions related to same object in different files<br>or with wrong prefixes, declarations of non-existing functions, etc.<br>because people cannot make up their mind on strict relation to objects<br>in the data model.<br>Splitting them in files really helps finding code operating on a<br>specific object and helping with logically splitting in the future.<br><br>Change-Id: I00c15f5285b5c1a0109279b7ab192d5467a04ece<br>---<br>M include/osmocom/bsc/Makefile.am<br>A include/osmocom/bsc/bts.h<br>M include/osmocom/bsc/gsm_data.h<br>M src/ipaccess/Makefile.am<br>M src/ipaccess/ipaccess-config.c<br>M src/osmo-bsc/Makefile.am<br>M src/osmo-bsc/abis_nm.c<br>M src/osmo-bsc/abis_om2000.c<br>M src/osmo-bsc/abis_om2000_vty.c<br>M src/osmo-bsc/abis_rsl.c<br>M src/osmo-bsc/acc_ramp.c<br>M src/osmo-bsc/assignment_fsm.c<br>M src/osmo-bsc/bsc_ctrl_commands.c<br>M src/osmo-bsc/bsc_init.c<br>M src/osmo-bsc/bsc_rf_ctrl.c<br>M src/osmo-bsc/bsc_vty.c<br>A src/osmo-bsc/bts.c<br>M src/osmo-bsc/bts_ericsson_rbs2000.c<br>M src/osmo-bsc/bts_ipaccess_nanobts.c<br>M src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c<br>M src/osmo-bsc/bts_nokia_site.c<br>M src/osmo-bsc/bts_siemens_bs11.c<br>M src/osmo-bsc/bts_sysmobts.c<br>M src/osmo-bsc/bts_unknown.c<br>M src/osmo-bsc/cbch_scheduler.c<br>M src/osmo-bsc/chan_alloc.c<br>M src/osmo-bsc/codec_pref.c<br>M src/osmo-bsc/e1_config.c<br>M src/osmo-bsc/gsm_04_08_rr.c<br>M src/osmo-bsc/gsm_08_08.c<br>M src/osmo-bsc/gsm_data.c<br>M src/osmo-bsc/handover_decision.c<br>M src/osmo-bsc/handover_decision_2.c<br>M src/osmo-bsc/handover_fsm.c<br>M src/osmo-bsc/handover_logic.c<br>M src/osmo-bsc/handover_vty.c<br>M src/osmo-bsc/lchan_fsm.c<br>M src/osmo-bsc/lchan_rtp_fsm.c<br>M src/osmo-bsc/lchan_select.c<br>M src/osmo-bsc/meas_feed.c<br>M src/osmo-bsc/neighbor_ident_vty.c<br>M src/osmo-bsc/osmo_bsc_bssap.c<br>M src/osmo-bsc/osmo_bsc_ctrl.c<br>M src/osmo-bsc/osmo_bsc_filter.c<br>M src/osmo-bsc/osmo_bsc_grace.c<br>M src/osmo-bsc/osmo_bsc_main.c<br>M src/osmo-bsc/osmo_bsc_msc.c<br>M src/osmo-bsc/osmo_bsc_sigtran.c<br>M src/osmo-bsc/paging.c<br>M src/osmo-bsc/pcu_sock.c<br>M src/osmo-bsc/rest_octets.c<br>M src/osmo-bsc/smscb.c<br>M src/osmo-bsc/system_information.c<br>M src/osmo-bsc/timeslot_fsm.c<br>M src/utils/Makefile.am<br>M src/utils/bs11_config.c<br>M tests/abis/Makefile.am<br>M tests/abis/abis_test.c<br>M tests/bsc/Makefile.am<br>M tests/codec_pref/codec_pref_test.c<br>M tests/gsm0408/Makefile.am<br>M tests/gsm0408/gsm0408_test.c<br>M tests/handover/Makefile.am<br>M tests/handover/handover_test.c<br>M tests/nanobts_omlattr/Makefile.am<br>M tests/nanobts_omlattr/nanobts_omlattr_test.c<br>66 files changed, 1,471 insertions(+), 1,354 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am</span><br><span>index 7a296e4..4d2df20 100644</span><br><span>--- a/include/osmocom/bsc/Makefile.am</span><br><span>+++ b/include/osmocom/bsc/Makefile.am</span><br><span>@@ -10,6 +10,7 @@</span><br><span>    bsc_subscriber.h \</span><br><span>   bsc_subscr_conn_fsm.h \</span><br><span>      bss.h \</span><br><span style="color: hsl(120, 100%, 40%);">+       bts.h \</span><br><span>      bts_ipaccess_nanobts_omlattr.h \</span><br><span>     chan_alloc.h \</span><br><span>       codec_pref.h \</span><br><span>diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h</span><br><span>new file mode 100644</span><br><span>index 0000000..07d2793</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/bsc/bts.h</span><br><span>@@ -0,0 +1,634 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/types.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/bitvec.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/tlv.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/bts_features.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/abis/e1_input.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "osmocom/bsc/gsm_data.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum bts_counter_id {</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_CTR_CHREQ_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_CTR_CHREQ_SUCCESSFUL,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_CHREQ_NO_CHANNEL,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_CHAN_RF_FAIL,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_CTR_CHAN_RLL_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_CTR_BTS_OML_FAIL,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_CTR_BTS_RSL_FAIL,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_CTR_CODEC_AMR_F,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_CTR_CODEC_AMR_H,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_CTR_CODEC_EFR,</span><br><span style="color: hsl(120, 100%, 40%);">+    BTS_CTR_CODEC_V1_FR,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_CTR_CODEC_V1_HR,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_CTR_PAGING_ATTEMPTED,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_PAGING_ALREADY,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_PAGING_RESPONDED,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_PAGING_EXPIRED,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_PAGING_NO_ACTIVE_PAGING,</span><br><span style="color: hsl(120, 100%, 40%);">+      BTS_CTR_PAGING_MSC_FLUSH,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_CHAN_ACT_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_CHAN_ACT_NACK,</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_CTR_RSL_UNKNOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_CTR_RSL_IPA_NACK,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_CTR_RSL_DELETE_IND,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_MODE_MODIFY_NACK,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_LCHAN_BORKEN_FROM_UNUSED,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_LCHAN_BORKEN_FROM_WAIT_ACTIV_ACK,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RF_RELEASE_ACK,</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_CTR_LCHAN_BORKEN_FROM_BORKEN,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+    BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK,</span><br><span style="color: hsl(120, 100%, 40%);">+      BTS_CTR_LCHAN_BORKEN_EV_RF_CHAN_REL_ACK,</span><br><span style="color: hsl(120, 100%, 40%);">+      BTS_CTR_LCHAN_BORKEN_EV_VTY,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_TS_BORKEN_FROM_UNUSED,</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_ACT,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_CTR_TS_BORKEN_FROM_PDCH,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_DEACT,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_TS_BORKEN_FROM_IN_USE,</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_CTR_TS_BORKEN_FROM_BORKEN,</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_CTR_TS_BORKEN_FROM_UNKNOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_TS_BORKEN_EV_PDCH_ACT_ACK_NACK,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_CTR_TS_BORKEN_EV_PDCH_DEACT_ACK_NACK,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_CTR_TS_BORKEN_EV_TEARDOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_CTR_ASSIGNMENT_ATTEMPTED,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_CTR_ASSIGNMENT_COMPLETED,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_CTR_ASSIGNMENT_STOPPED,</span><br><span style="color: hsl(120, 100%, 40%);">+   BTS_CTR_ASSIGNMENT_NO_CHANNEL,</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_CTR_ASSIGNMENT_TIMEOUT,</span><br><span style="color: hsl(120, 100%, 40%);">+   BTS_CTR_ASSIGNMENT_FAILED,</span><br><span style="color: hsl(120, 100%, 40%);">+    BTS_CTR_ASSIGNMENT_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct rate_ctr_desc bts_ctr_description[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_CTR_CHREQ_TOTAL] =                 {"chreq:total", "Received channel requests"},</span><br><span style="color: hsl(120, 100%, 40%);">+     [BTS_CTR_CHREQ_SUCCESSFUL] =            {"chreq:successful", "Successful channel requests (immediate assign sent)"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_CTR_CHREQ_NO_CHANNEL] =            {"chreq:no_channel", "Sent to MS no channel available"},</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_CTR_CHAN_RF_FAIL] =                {"chan:rf_fail", "Received a RF failure indication from BTS"},</span><br><span style="color: hsl(120, 100%, 40%);">+    [BTS_CTR_CHAN_RLL_ERR] =                {"chan:rll_err", "Received a RLL failure with T200 cause from BTS"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_CTR_BTS_OML_FAIL] =                {"oml_fail", "Received a TEI down on a OML link"},</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_CTR_BTS_RSL_FAIL] =                {"rsl_fail", "Received a TEI down on a OML link"},</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_CTR_CODEC_AMR_F] =                 {"codec:amr_f", "Count the usage of AMR/F codec by channel mode requested"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_CTR_CODEC_AMR_H] =                 {"codec:amr_h", "Count the usage of AMR/H codec by channel mode requested"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_CTR_CODEC_EFR] =                   {"codec:efr", "Count the usage of EFR codec by channel mode requested"},</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_CTR_CODEC_V1_FR] =                 {"codec:fr", "Count the usage of FR codec by channel mode requested"},</span><br><span style="color: hsl(120, 100%, 40%);">+    [BTS_CTR_CODEC_V1_HR] =                 {"codec:hr", "Count the usage of HR codec by channel mode requested"},</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_CTR_PAGING_ATTEMPTED] =            {"paging:attempted", "Paging attempts for a subscriber"},</span><br><span style="color: hsl(120, 100%, 40%);">+ [BTS_CTR_PAGING_ALREADY] =              {"paging:already", "Paging attempts ignored as subscriber was already being paged"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_CTR_PAGING_RESPONDED] =            {"paging:responded", "Paging attempts with successful paging response"},</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_CTR_PAGING_EXPIRED] =              {"paging:expired", "Paging Request expired because of timeout T3113"},</span><br><span style="color: hsl(120, 100%, 40%);">+    [BTS_CTR_PAGING_NO_ACTIVE_PAGING] =     {"paging:no_active_paging", "Paging response without an active paging request (arrived after paging expiration?)"},</span><br><span style="color: hsl(120, 100%, 40%);">+       [BTS_CTR_PAGING_MSC_FLUSH] =            {"paging:msc_flush", "Paging flushed due to MSC Reset BSSMAP message"},</span><br><span style="color: hsl(120, 100%, 40%);">+   [BTS_CTR_CHAN_ACT_TOTAL] =              {"chan_act:total", "Total number of Channel Activations"},</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_CTR_CHAN_ACT_NACK] =               {"chan_act:nack", "Number of Channel Activations that the BTS NACKed"},</span><br><span style="color: hsl(120, 100%, 40%);">+   [BTS_CTR_RSL_UNKNOWN] =                 {"rsl:unknown", "Number of unknown/unsupported RSL messages received from BTS"},</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_CTR_RSL_IPA_NACK] =                {"rsl:ipa_nack", "Number of IPA (RTP/dyn-PDCH) related NACKs received from BTS"},</span><br><span style="color: hsl(120, 100%, 40%);">+ [BTS_CTR_RSL_DELETE_IND] =              {"rsl:delete_ind", "Number of RSL DELETE INDICATION (DL CCCH overload)"},</span><br><span style="color: hsl(120, 100%, 40%);">+ [BTS_CTR_MODE_MODIFY_NACK] =            {"chan:mode_modify_nack", "Number of Channel Mode Modify NACKs received from BTS"},</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* lchan/TS BORKEN state counters */</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_CTR_LCHAN_BORKEN_FROM_UNUSED] =              {"lchan_borken:from_state:unused", "Transitions from lchan UNUSED state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [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"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [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"},</span><br><span style="color: hsl(120, 100%, 40%);">+    [BTS_CTR_LCHAN_BORKEN_FROM_BORKEN] =              {"lchan_borken:from_state:borken", "Transitions from lchan BORKEN state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN] =             {"lchan_borken:from_state:unknown", "Transitions from an unknown lchan state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+ [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK] =        {"lchan_borken:event:chan_activ_ack", "CHAN_ACTIV_ACK received in the lchan BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+     [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK] =       {"lchan_borken:event:chan_activ_nack", "CHAN_ACTIV_NACK received in the lchan BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+   [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"},</span><br><span style="color: hsl(120, 100%, 40%);">+   [BTS_CTR_LCHAN_BORKEN_EV_VTY] =                   {"lchan_borken:event:vty", "VTY commands received in the lchan BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN] =              {"lchan_borken:event:teardown", "lchan in a BORKEN state is shutting down (BTS disconnected?)"},</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED] =   {"ts_borken:from_state:not_initialized", "Transitions from TS NOT_INITIALIZED state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+       [BTS_CTR_TS_BORKEN_FROM_UNUSED] =            {"ts_borken:from_state:unused", "Transitions from TS UNUSED state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+ [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"},</span><br><span style="color: hsl(120, 100%, 40%);">+   [BTS_CTR_TS_BORKEN_FROM_PDCH] =              {"ts_borken:from_state:pdch", "Transitions from TS PDCH state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+     [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"},</span><br><span style="color: hsl(120, 100%, 40%);">+       [BTS_CTR_TS_BORKEN_FROM_IN_USE] =            {"ts_borken:from_state:in_use", "Transitions from TS IN_USE state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+ [BTS_CTR_TS_BORKEN_FROM_BORKEN] =            {"ts_borken:from_state:borken", "Transitions from TS BORKEN state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+ [BTS_CTR_TS_BORKEN_FROM_UNKNOWN] =           {"ts_borken:from_state:unknown", "Transitions from an unknown TS state to BORKEN state"},</span><br><span style="color: hsl(120, 100%, 40%);">+    [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"},</span><br><span style="color: hsl(120, 100%, 40%);">+  [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"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_CTR_TS_BORKEN_EV_TEARDOWN] =            {"ts_borken:event:teardown", "TS in a BORKEN state is shutting down (BTS disconnected?)"},</span><br><span style="color: hsl(120, 100%, 40%);">+   [BTS_CTR_ASSIGNMENT_ATTEMPTED] =             {"assignment:attempted", "Assignment attempts"},</span><br><span style="color: hsl(120, 100%, 40%);">+     [BTS_CTR_ASSIGNMENT_COMPLETED] =             {"assignment:completed", "Assignment completed"},</span><br><span style="color: hsl(120, 100%, 40%);">+    [BTS_CTR_ASSIGNMENT_STOPPED] =               {"assignment:stopped", "Connection ended during Assignment"},</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_CTR_ASSIGNMENT_NO_CHANNEL] =            {"assignment:no_channel", "Failure to allocate lchan for Assignment"},</span><br><span style="color: hsl(120, 100%, 40%);">+       [BTS_CTR_ASSIGNMENT_TIMEOUT] =               {"assignment:timeout", "Assignment timed out"},</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_CTR_ASSIGNMENT_FAILED] =                {"assignment:failed", "Received Assignment Failure message"},</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_CTR_ASSIGNMENT_ERROR] =                 {"assignment:error", "Assignment failed for other reason"},</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct rate_ctr_group_desc bts_ctrg_desc = {</span><br><span style="color: hsl(120, 100%, 40%);">+       "bts",</span><br><span style="color: hsl(120, 100%, 40%);">+      "base transceiver station",</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_STATS_CLASS_GLOBAL,</span><br><span style="color: hsl(120, 100%, 40%);">+      ARRAY_SIZE(bts_ctr_description),</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_ctr_description,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum {</span><br><span style="color: hsl(120, 100%, 40%);">+    BTS_STAT_CHAN_LOAD_AVERAGE,</span><br><span style="color: hsl(120, 100%, 40%);">+   BTS_STAT_CHAN_CCCH_SDCCH4_USED,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+      BTS_STAT_CHAN_TCH_F_USED,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_STAT_CHAN_TCH_F_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+    BTS_STAT_CHAN_TCH_H_USED,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_STAT_CHAN_TCH_H_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+    BTS_STAT_CHAN_SDCCH8_USED,</span><br><span style="color: hsl(120, 100%, 40%);">+    BTS_STAT_CHAN_SDCCH8_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+   BTS_STAT_CHAN_TCH_F_PDCH_USED,</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_STAT_CHAN_TCH_F_PDCH_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_STAT_CHAN_SDCCH8_CBCH_USED,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+      BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_STAT_T3122,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_STAT_RACH_BUSY,</span><br><span style="color: hsl(120, 100%, 40%);">+   BTS_STAT_RACH_ACCESS,</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_STAT_OML_CONNECTED,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_STAT_RSL_CONNECTED,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_STAT_LCHAN_BORKEN,</span><br><span style="color: hsl(120, 100%, 40%);">+        BTS_STAT_TS_BORKEN,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum gsm_bts_type {</span><br><span style="color: hsl(120, 100%, 40%);">+        GSM_BTS_TYPE_UNKNOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM_BTS_TYPE_BS11,</span><br><span style="color: hsl(120, 100%, 40%);">+    GSM_BTS_TYPE_NANOBTS,</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM_BTS_TYPE_RBS2000,</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM_BTS_TYPE_NOKIA_SITE,</span><br><span style="color: hsl(120, 100%, 40%);">+      GSM_BTS_TYPE_OSMOBTS,</span><br><span style="color: hsl(120, 100%, 40%);">+ _NUM_GSM_BTS_TYPE</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+extern const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1];</span><br><span style="color: hsl(120, 100%, 40%);">+extern const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum gsm_bts_type_variant {</span><br><span style="color: hsl(120, 100%, 40%);">+    BTS_UNKNOWN,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_OSMO_LITECELL15,</span><br><span style="color: hsl(120, 100%, 40%);">+  BTS_OSMO_OCTPHY,</span><br><span style="color: hsl(120, 100%, 40%);">+      BTS_OSMO_SYSMO,</span><br><span style="color: hsl(120, 100%, 40%);">+       BTS_OSMO_TRX,</span><br><span style="color: hsl(120, 100%, 40%);">+ _NUM_BTS_VARIANT</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Used by OML layer for BTS Attribute reporting */</span><br><span style="color: hsl(120, 100%, 40%);">+enum bts_attribute {</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_TYPE_VARIANT,</span><br><span style="color: hsl(120, 100%, 40%);">+     BTS_SUB_MODEL,</span><br><span style="color: hsl(120, 100%, 40%);">+        TRX_PHY_VERSION,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct vty;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts_model {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     enum gsm_bts_type type;</span><br><span style="color: hsl(120, 100%, 40%);">+       enum gsm_bts_type_variant variant;</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *name;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   bool started;</span><br><span style="color: hsl(120, 100%, 40%);">+ int (*start)(struct gsm_network *net);</span><br><span style="color: hsl(120, 100%, 40%);">+        int (*oml_rcvmsg)(struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  char * (*oml_status)(const struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    void (*e1line_bind_ops)(struct e1inp_line *line);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+       void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);</span><br><span style="color: hsl(120, 100%, 40%);">+   void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Should SI2bis and SI2ter be disabled by default on this BTS model? */</span><br><span style="color: hsl(120, 100%, 40%);">+      bool force_combined_si;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     struct tlv_definition nm_att_tlvdef;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* features of a given BTS model set via gsm_bts_model_register() locally */</span><br><span style="color: hsl(120, 100%, 40%);">+  struct bitvec features;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t _features_data[MAX_BTS_FEATURES/8];</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* One BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts {</span><br><span style="color: hsl(120, 100%, 40%);">+    /* list header in net->bts_list */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Geographical location of the BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+        struct llist_head loc_list;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* number of this BTS in network */</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t nr;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* human readable name / description */</span><br><span style="color: hsl(120, 100%, 40%);">+       char *description;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Cell Identity */</span><br><span style="color: hsl(120, 100%, 40%);">+   uint16_t cell_identity;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* location area code of this BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+  uint16_t location_area_code;</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Base Station Identification Code (BSIC), lower 3 bits is BCC,</span><br><span style="color: hsl(120, 100%, 40%);">+       * which is used as TSC for the CCCH */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t bsic;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* type of BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+     enum gsm_bts_type type;</span><br><span style="color: hsl(120, 100%, 40%);">+       enum gsm_bts_type_variant variant;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_bts_model *model;</span><br><span style="color: hsl(120, 100%, 40%);">+  enum gsm_band band;</span><br><span style="color: hsl(120, 100%, 40%);">+   char version[MAX_VERSION_LENGTH];</span><br><span style="color: hsl(120, 100%, 40%);">+     char sub_model[MAX_VERSION_LENGTH];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* features of a given BTS set/reported via OML */</span><br><span style="color: hsl(120, 100%, 40%);">+    struct bitvec features;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t _features_data[MAX_BTS_FEATURES/8];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Connected PCU version (if any) */</span><br><span style="color: hsl(120, 100%, 40%);">+  char pcu_version[MAX_VERSION_LENGTH];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* maximum Tx power that the MS is permitted to use in this cell */</span><br><span style="color: hsl(120, 100%, 40%);">+   int ms_max_power;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* how do we talk OML with this TRX? */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_e1_subslot oml_e1_link;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t oml_tei;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct e1inp_sign_link *oml_link;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Timer to use for deferred drop of OML link, see \ref ipaccess_drop_oml_deferred */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_timer_list oml_drop_link_timer;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* when OML link was established */</span><br><span style="color: hsl(120, 100%, 40%);">+   time_t uptime;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Abis network management O&M handle */</span><br><span style="color: hsl(120, 100%, 40%);">+  struct abis_nm_h *nmh;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* number of this BTS on given E1 link */</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t bts_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* DTX features of this BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+        enum gsm48_dtx_mode dtxu;</span><br><span style="color: hsl(120, 100%, 40%);">+     bool dtxd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* paging state and control */</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm_bts_paging_state paging;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* CCCH is on C0 */</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_bts_trx *c0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+        } site_mgr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* bitmask of all SI that are present/valid in si_buf */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t si_valid;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t si2q_index; /* distinguish individual SI2quater messages */</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */</span><br><span style="color: hsl(120, 100%, 40%);">+      /* buffers where we put the pre-computed SI */</span><br><span style="color: hsl(120, 100%, 40%);">+        sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];</span><br><span style="color: hsl(120, 100%, 40%);">+        /* offsets used while generating SI2quater */</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t e_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t u_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* 3GPP TS 08.58 ยง8.5.1 BCCH INFORMATION. Some nanoBTS fail upon</span><br><span style="color: hsl(120, 100%, 40%);">+      * receival of empty SI disabling unsupported SI. see OS#3707. */</span><br><span style="color: hsl(120, 100%, 40%);">+     bool si_unused_send_empty;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* ip.access Unit ID's have Site/BTS/TRX layout */</span><br><span style="color: hsl(120, 100%, 40%);">+        union {</span><br><span style="color: hsl(120, 100%, 40%);">+               struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      uint16_t site_id;</span><br><span style="color: hsl(120, 100%, 40%);">+                     uint16_t bts_id;</span><br><span style="color: hsl(120, 100%, 40%);">+                      uint32_t flags;</span><br><span style="color: hsl(120, 100%, 40%);">+                       uint32_t rsl_ip;</span><br><span style="color: hsl(120, 100%, 40%);">+              } ip_access;</span><br><span style="color: hsl(120, 100%, 40%);">+          struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                              struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                        } cclk;</span><br><span style="color: hsl(120, 100%, 40%);">+                       struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                              struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                        } rack;</span><br><span style="color: hsl(120, 100%, 40%);">+                       struct gsm_envabtse envabtse[4];</span><br><span style="color: hsl(120, 100%, 40%);">+              } bs11;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                              struct om2k_mo om2k_mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                               struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct llist_head conn_groups;</span><br><span style="color: hsl(120, 100%, 40%);">+                        } cf;</span><br><span style="color: hsl(120, 100%, 40%);">+                 struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                              struct om2k_mo om2k_mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                               struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct llist_head conn_groups;</span><br><span style="color: hsl(120, 100%, 40%);">+                        } is;</span><br><span style="color: hsl(120, 100%, 40%);">+                 struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                              struct om2k_mo om2k_mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                               struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct llist_head conn_groups;</span><br><span style="color: hsl(120, 100%, 40%);">+                        } con;</span><br><span style="color: hsl(120, 100%, 40%);">+                        struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                              struct om2k_mo om2k_mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                               struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                        } dp;</span><br><span style="color: hsl(120, 100%, 40%);">+                 struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                              struct om2k_mo om2k_mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                               struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                        } tf;</span><br><span style="color: hsl(120, 100%, 40%);">+                 struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                              struct om2k_mo om2k_mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                               struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                        } mctr;</span><br><span style="color: hsl(120, 100%, 40%);">+                       uint32_t use_superchannel:1;</span><br><span style="color: hsl(120, 100%, 40%);">+                  struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                              uint16_t limit;</span><br><span style="color: hsl(120, 100%, 40%);">+                               uint16_t active;</span><br><span style="color: hsl(120, 100%, 40%);">+                      } om2k_version[16];</span><br><span style="color: hsl(120, 100%, 40%);">+           } rbs2000;</span><br><span style="color: hsl(120, 100%, 40%);">+            struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      uint8_t bts_type;</span><br><span style="color: hsl(120, 100%, 40%);">+                     unsigned int configured:1,      /* we sent the config data request */</span><br><span style="color: hsl(120, 100%, 40%);">+                         skip_reset:1,           /* skip reset at bootstrap */</span><br><span style="color: hsl(120, 100%, 40%);">+                         no_loc_rel_cnf:1,       /* don't wait for RSL REL CONF */</span><br><span style="color: hsl(120, 100%, 40%);">+                         bts_reset_timer_cnf,    /* timer for BTS RESET */</span><br><span style="color: hsl(120, 100%, 40%);">+                             did_reset:1,            /* we received a RESET ACK */</span><br><span style="color: hsl(120, 100%, 40%);">+                         wait_reset:2;           /* we are waiting for reset to complete */</span><br><span style="color: hsl(120, 100%, 40%);">+                    struct osmo_timer_list reset_timer;</span><br><span style="color: hsl(120, 100%, 40%);">+           } nokia;</span><br><span style="color: hsl(120, 100%, 40%);">+      };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Not entirely sure how ip.access specific this is */</span><br><span style="color: hsl(120, 100%, 40%);">+        struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              enum bts_gprs_mode mode;</span><br><span style="color: hsl(120, 100%, 40%);">+              struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint16_t nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint8_t timer[7];</span><br><span style="color: hsl(120, 100%, 40%);">+             } nse;</span><br><span style="color: hsl(120, 100%, 40%);">+                struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      struct gsm_abis_mo mo;</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint16_t bvci;</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint8_t timer[11];</span><br><span style="color: hsl(120, 100%, 40%);">+                    struct gprs_rlc_cfg rlc_cfg;</span><br><span style="color: hsl(120, 100%, 40%);">+          } cell;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct gsm_bts_gprs_nsvc nsvc[2];</span><br><span style="color: hsl(120, 100%, 40%);">+             uint8_t rac;</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t net_ctrl_ord;</span><br><span style="color: hsl(120, 100%, 40%);">+         bool ctrl_ack_type_use_block;</span><br><span style="color: hsl(120, 100%, 40%);">+         bool egprs_pkt_chan_request;</span><br><span style="color: hsl(120, 100%, 40%);">+  } gprs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* threshold (in percent) when BTS shall send CCCH LOAD IND */</span><br><span style="color: hsl(120, 100%, 40%);">+        int ccch_load_ind_thresh;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* RACH NM values */</span><br><span style="color: hsl(120, 100%, 40%);">+  int rach_b_thresh;</span><br><span style="color: hsl(120, 100%, 40%);">+    int rach_ldavg_slots;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* transceivers */</span><br><span style="color: hsl(120, 100%, 40%);">+    int num_trx;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct llist_head trx_list;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* SI related items */</span><br><span style="color: hsl(120, 100%, 40%);">+        int force_combined_si;</span><br><span style="color: hsl(120, 100%, 40%);">+        bool force_combined_si_set;</span><br><span style="color: hsl(120, 100%, 40%);">+   int bcch_change_mark;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Abis NM queue */</span><br><span style="color: hsl(120, 100%, 40%);">+   struct llist_head abis_queue;</span><br><span style="color: hsl(120, 100%, 40%);">+ int abis_nm_pend;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_network *network;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* should the channel allocator allocate channels from high TRX to TRX0,</span><br><span style="color: hsl(120, 100%, 40%);">+       * rather than starting from TRX0 and go upwards? */</span><br><span style="color: hsl(120, 100%, 40%);">+  int chan_alloc_reverse;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     enum neigh_list_manual_mode neigh_list_manual_mode;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* parameters from which we build SYSTEM INFORMATION */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              struct gsm48_rach_control rach_control;</span><br><span style="color: hsl(120, 100%, 40%);">+               uint8_t ncc_permitted;</span><br><span style="color: hsl(120, 100%, 40%);">+                struct gsm48_cell_sel_par cell_sel_par;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct gsm48_si_selection_params cell_ro_sel_par; /* rest octet */</span><br><span style="color: hsl(120, 100%, 40%);">+            struct gsm48_cell_options cell_options;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct gsm48_control_channel_descr chan_desc;</span><br><span style="color: hsl(120, 100%, 40%);">+         struct bitvec neigh_list;</span><br><span style="color: hsl(120, 100%, 40%);">+             struct bitvec cell_alloc;</span><br><span style="color: hsl(120, 100%, 40%);">+             struct bitvec si5_neigh_list;</span><br><span style="color: hsl(120, 100%, 40%);">+         struct osmo_earfcn_si2q si2quater_neigh_list;</span><br><span style="color: hsl(120, 100%, 40%);">+         size_t uarfcn_length; /* index for uarfcn and scramble lists */</span><br><span style="color: hsl(120, 100%, 40%);">+               struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* bitmask large enough for all possible ARFCN's */</span><br><span style="color: hsl(120, 100%, 40%);">+                       uint8_t neigh_list[1024/8];</span><br><span style="color: hsl(120, 100%, 40%);">+                   uint8_t cell_alloc[1024/8];</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* If the user wants a different neighbor list in SI5 than in SI2 */</span><br><span style="color: hsl(120, 100%, 40%);">+                  uint8_t si5_neigh_list[1024/8];</span><br><span style="color: hsl(120, 100%, 40%);">+                       uint8_t meas_bw_list[MAX_EARFCN_LIST];</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint16_t earfcn_list[MAX_EARFCN_LIST];</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint16_t uarfcn_list[MAX_EARFCN_LIST];</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint16_t scramble_list[MAX_EARFCN_LIST];</span><br><span style="color: hsl(120, 100%, 40%);">+              } data;</span><br><span style="color: hsl(120, 100%, 40%);">+       } si_common;</span><br><span style="color: hsl(120, 100%, 40%);">+  bool early_classmark_allowed;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool early_classmark_allowed_3g;</span><br><span style="color: hsl(120, 100%, 40%);">+      /* for testing only: Have an infinitely long radio link timeout */</span><br><span style="color: hsl(120, 100%, 40%);">+    bool infinite_radio_link_timeout;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* do we use static (user-defined) system information messages? (bitmask) */</span><br><span style="color: hsl(120, 100%, 40%);">+  uint32_t si_mode_static;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* access control class ramping */</span><br><span style="color: hsl(120, 100%, 40%);">+    struct acc_ramp acc_ramp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* exclude the BTS from the global RF Lock handling */</span><br><span style="color: hsl(120, 100%, 40%);">+        int excl_from_rf_lock;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* supported codecs beside FR */</span><br><span style="color: hsl(120, 100%, 40%);">+      struct bts_codec_conf codec;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* BTS dependencies bit field */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t depends_on[256/(8*4)];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* full and half rate multirate config */</span><br><span style="color: hsl(120, 100%, 40%);">+     struct amr_multirate_conf mr_full;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct amr_multirate_conf mr_half;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* PCU socket state */</span><br><span style="color: hsl(120, 100%, 40%);">+        char *pcu_sock_path;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct pcu_sock_state *pcu_state;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   struct rate_ctr_group *bts_ctrs;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_stat_item_group *bts_statg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     struct handover_cfg *ho;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* A list of struct gsm_bts_ref, indicating neighbors of this BTS.</span><br><span style="color: hsl(120, 100%, 40%);">+     * When the si_common neigh_list is in automatic mode, it is populated from this list as well as</span><br><span style="color: hsl(120, 100%, 40%);">+       * gsm_network->neighbor_bss_cells. */</span><br><span style="color: hsl(120, 100%, 40%);">+     struct llist_head local_neighbors;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* BTS-specific overrides for timer values from struct gsm_network. */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t T3122;  /* ASSIGNMENT REJECT wait indication */</span><br><span style="color: hsl(120, 100%, 40%);">+       bool T3113_dynamic; /* Calculate T3113 timeout dynamically based on BTS channel config and load */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Periodic channel load measurements are used to maintain T3122. */</span><br><span style="color: hsl(120, 100%, 40%);">+  struct load_counter chan_load_samples[7];</span><br><span style="color: hsl(120, 100%, 40%);">+     int chan_load_samples_idx;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t chan_load_avg; /* current channel load average in percent (0 - 100). */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* cell broadcast system */</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_timer_list cbch_timer;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct bts_smscb_chan_state cbch_basic;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct bts_smscb_chan_state cbch_extended;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_timer_list etws_timer;      /* when to stop ETWS PN */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  struct llist_head oml_fail_rep;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define GSM_BTS_SI2Q(bts, i)   (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])</span><br><span style="color: hsl(120, 100%, 40%);">+#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))</span><br><span style="color: hsl(120, 100%, 40%);">+#define GSM_BTS_SI(bts, i)     (void *)((bts)->si_buf[i][0])</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* this actually refers to the IPA transport, not the BTS model */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int is_ipaccess_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (bts->type) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BTS_TYPE_NANOBTS:</span><br><span style="color: hsl(120, 100%, 40%);">+    case GSM_BTS_TYPE_OSMOBTS:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int is_sysmobts_v2(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (bts->type) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BTS_TYPE_OSMOBTS:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int is_siemens_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (bts->type) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BTS_TYPE_BS11:</span><br><span style="color: hsl(120, 100%, 40%);">+               return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int is_nokia_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (bts->type) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BTS_TYPE_NOKIA_SITE:</span><br><span style="color: hsl(120, 100%, 40%);">+         return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int is_ericsson_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (bts->type) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BTS_TYPE_RBS2000:</span><br><span style="color: hsl(120, 100%, 40%);">+            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int is_e1_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (bts->type) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BTS_TYPE_BS11:</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BTS_TYPE_RBS2000:</span><br><span style="color: hsl(120, 100%, 40%);">+    case GSM_BTS_TYPE_NOKIA_SITE:</span><br><span style="color: hsl(120, 100%, 40%);">+         return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline const struct osmo_location_area_id *bts_lai(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     static struct osmo_location_area_id lai;</span><br><span style="color: hsl(120, 100%, 40%);">+      lai = (struct osmo_location_area_id){</span><br><span style="color: hsl(120, 100%, 40%);">+         .plmn = bts->network->plmn,</span><br><span style="color: hsl(120, 100%, 40%);">+             .lac = bts->location_area_code,</span><br><span style="color: hsl(120, 100%, 40%);">+    };</span><br><span style="color: hsl(120, 100%, 40%);">+    return &lai;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+char *gsm_bts_name(const struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool gsm_bts_matches_lai(const struct gsm_bts *bts, const struct osmo_location_area_id *lai);</span><br><span style="color: hsl(120, 100%, 40%);">+bool gsm_bts_matches_cell_id(const struct gsm_bts *bts, const struct gsm0808_cell_id *cell_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_bts_local_neighbor_add(struct gsm_bts *bts, struct gsm_bts *neighbor);</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_bts_local_neighbor_del(struct gsm_bts *bts, const struct gsm_bts *neighbor);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* return the gsm_lchan for the CBCH (if it exists at all) */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+unsigned long long bts_uptime(const struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+char *get_model_oml_status(const struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+/* reset the state of all MO in the BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_bts_mo_reset(struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* dependency handling */</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_depend_mark(struct gsm_bts *bts, int dep);</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_depend_clear(struct gsm_bts *bts, int dep);</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_depend_check(struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_bts_model_register(struct gsm_bts_model *model);</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts_model *bts_model_find(enum gsm_bts_type type);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum gsm_bts_type str2btstype(const char *arg);</span><br><span style="color: hsl(120, 100%, 40%);">+const char *btstype2str(enum gsm_bts_type type);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum bts_attribute str2btsattr(const char *s);</span><br><span style="color: hsl(120, 100%, 40%);">+const char *btsatttr2str(enum bts_attribute v);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum gsm_bts_type_variant str2btsvariant(const char *arg);</span><br><span style="color: hsl(120, 100%, 40%);">+const char *btsvariant2str(enum gsm_bts_type_variant v);</span><br><span>diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h</span><br><span>index c357981..a74e6d9 100644</span><br><span>--- a/include/osmocom/bsc/gsm_data.h</span><br><span>+++ b/include/osmocom/bsc/gsm_data.h</span><br><span>@@ -39,6 +39,7 @@</span><br><span> struct mgcp_client;</span><br><span> struct gsm0808_cell_id;</span><br><span> struct osmo_mgcpc_ep;</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts;</span><br><span> </span><br><span> /** annotations for msgb ownership */</span><br><span> #define __uses</span><br><span>@@ -772,69 +773,8 @@</span><br><span>     struct gsm_bts_trx_ts ts[TRX_NR_TS];</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define GSM_BTS_SI2Q(bts, i)   (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])</span><br><span style="color: hsl(0, 100%, 40%);">-#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))</span><br><span style="color: hsl(0, 100%, 40%);">-#define GSM_BTS_SI(bts, i)     (void *)((bts)->si_buf[i][0])</span><br><span> #define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0])</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum gsm_bts_type {</span><br><span style="color: hsl(0, 100%, 40%);">-     GSM_BTS_TYPE_UNKNOWN,</span><br><span style="color: hsl(0, 100%, 40%);">-   GSM_BTS_TYPE_BS11,</span><br><span style="color: hsl(0, 100%, 40%);">-      GSM_BTS_TYPE_NANOBTS,</span><br><span style="color: hsl(0, 100%, 40%);">-   GSM_BTS_TYPE_RBS2000,</span><br><span style="color: hsl(0, 100%, 40%);">-   GSM_BTS_TYPE_NOKIA_SITE,</span><br><span style="color: hsl(0, 100%, 40%);">-        GSM_BTS_TYPE_OSMOBTS,</span><br><span style="color: hsl(0, 100%, 40%);">-   _NUM_GSM_BTS_TYPE</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum gsm_bts_type_variant {</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_UNKNOWN,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_OSMO_LITECELL15,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_OSMO_OCTPHY,</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS_OSMO_SYSMO,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_OSMO_TRX,</span><br><span style="color: hsl(0, 100%, 40%);">-   _NUM_BTS_VARIANT</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Used by OML layer for BTS Attribute reporting */</span><br><span style="color: hsl(0, 100%, 40%);">-enum bts_attribute {</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_TYPE_VARIANT,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_SUB_MODEL,</span><br><span style="color: hsl(0, 100%, 40%);">-  TRX_PHY_VERSION,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct vty;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_bts_model {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct llist_head list;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- enum gsm_bts_type type;</span><br><span style="color: hsl(0, 100%, 40%);">- enum gsm_bts_type_variant variant;</span><br><span style="color: hsl(0, 100%, 40%);">-      const char *name;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       bool started;</span><br><span style="color: hsl(0, 100%, 40%);">-   int (*start)(struct gsm_network *net);</span><br><span style="color: hsl(0, 100%, 40%);">-  int (*oml_rcvmsg)(struct msgb *msg);</span><br><span style="color: hsl(0, 100%, 40%);">-    char * (*oml_status)(const struct gsm_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        void (*e1line_bind_ops)(struct e1inp_line *line);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">- void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);</span><br><span style="color: hsl(0, 100%, 40%);">-     void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* Should SI2bis and SI2ter be disabled by default on this BTS model? */</span><br><span style="color: hsl(0, 100%, 40%);">-        bool force_combined_si;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- struct tlv_definition nm_att_tlvdef;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* features of a given BTS model set via gsm_bts_model_register() locally */</span><br><span style="color: hsl(0, 100%, 40%);">-    struct bitvec features;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t _features_data[MAX_BTS_FEATURES/8];</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /*</span><br><span>  * This keeps track of the paging status of one BTS. It</span><br><span>  * includes a number of pending requests, a back pointer</span><br><span>@@ -1004,280 +944,6 @@</span><br><span>  struct msgb *mb;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* One BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_bts {</span><br><span style="color: hsl(0, 100%, 40%);">- /* list header in net->bts_list */</span><br><span style="color: hsl(0, 100%, 40%);">-   struct llist_head list;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Geographical location of the BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-  struct llist_head loc_list;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* number of this BTS in network */</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t nr;</span><br><span style="color: hsl(0, 100%, 40%);">-     /* human readable name / description */</span><br><span style="color: hsl(0, 100%, 40%);">- char *description;</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Cell Identity */</span><br><span style="color: hsl(0, 100%, 40%);">-     uint16_t cell_identity;</span><br><span style="color: hsl(0, 100%, 40%);">- /* location area code of this BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-    uint16_t location_area_code;</span><br><span style="color: hsl(0, 100%, 40%);">-    /* Base Station Identification Code (BSIC), lower 3 bits is BCC,</span><br><span style="color: hsl(0, 100%, 40%);">-         * which is used as TSC for the CCCH */</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t bsic;</span><br><span style="color: hsl(0, 100%, 40%);">-   /* type of BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-       enum gsm_bts_type type;</span><br><span style="color: hsl(0, 100%, 40%);">- enum gsm_bts_type_variant variant;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gsm_bts_model *model;</span><br><span style="color: hsl(0, 100%, 40%);">-    enum gsm_band band;</span><br><span style="color: hsl(0, 100%, 40%);">-     char version[MAX_VERSION_LENGTH];</span><br><span style="color: hsl(0, 100%, 40%);">-       char sub_model[MAX_VERSION_LENGTH];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* features of a given BTS set/reported via OML */</span><br><span style="color: hsl(0, 100%, 40%);">-      struct bitvec features;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t _features_data[MAX_BTS_FEATURES/8];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Connected PCU version (if any) */</span><br><span style="color: hsl(0, 100%, 40%);">-    char pcu_version[MAX_VERSION_LENGTH];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* maximum Tx power that the MS is permitted to use in this cell */</span><br><span style="color: hsl(0, 100%, 40%);">-     int ms_max_power;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* how do we talk OML with this TRX? */</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_e1_subslot oml_e1_link;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t oml_tei;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct e1inp_sign_link *oml_link;</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Timer to use for deferred drop of OML link, see \ref ipaccess_drop_oml_deferred */</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_timer_list oml_drop_link_timer;</span><br><span style="color: hsl(0, 100%, 40%);">-     /* when OML link was established */</span><br><span style="color: hsl(0, 100%, 40%);">-     time_t uptime;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* Abis network management O&M handle */</span><br><span style="color: hsl(0, 100%, 40%);">-    struct abis_nm_h *nmh;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* number of this BTS on given E1 link */</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t bts_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* DTX features of this BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-  enum gsm48_dtx_mode dtxu;</span><br><span style="color: hsl(0, 100%, 40%);">-       bool dtxd;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* paging state and control */</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gsm_bts_paging_state paging;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* CCCH is on C0 */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gsm_bts_trx *c0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-  } site_mgr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* bitmask of all SI that are present/valid in si_buf */</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t si_valid;</span><br><span style="color: hsl(0, 100%, 40%);">-      /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */</span><br><span style="color: hsl(0, 100%, 40%);">-   uint8_t si2q_index; /* distinguish individual SI2quater messages */</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */</span><br><span style="color: hsl(0, 100%, 40%);">-        /* buffers where we put the pre-computed SI */</span><br><span style="color: hsl(0, 100%, 40%);">-  sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];</span><br><span style="color: hsl(0, 100%, 40%);">-  /* offsets used while generating SI2quater */</span><br><span style="color: hsl(0, 100%, 40%);">-   size_t e_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-        size_t u_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-        /* 3GPP TS 08.58 ยง8.5.1 BCCH INFORMATION. Some nanoBTS fail upon</span><br><span style="color: hsl(0, 100%, 40%);">-        * receival of empty SI disabling unsupported SI. see OS#3707. */</span><br><span style="color: hsl(0, 100%, 40%);">-       bool si_unused_send_empty;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* ip.access Unit ID's have Site/BTS/TRX layout */</span><br><span style="color: hsl(0, 100%, 40%);">-  union {</span><br><span style="color: hsl(0, 100%, 40%);">-         struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                        uint16_t site_id;</span><br><span style="color: hsl(0, 100%, 40%);">-                       uint16_t bts_id;</span><br><span style="color: hsl(0, 100%, 40%);">-                        uint32_t flags;</span><br><span style="color: hsl(0, 100%, 40%);">-                 uint32_t rsl_ip;</span><br><span style="color: hsl(0, 100%, 40%);">-                } ip_access;</span><br><span style="color: hsl(0, 100%, 40%);">-            struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                  } cclk;</span><br><span style="color: hsl(0, 100%, 40%);">-                 struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                  } rack;</span><br><span style="color: hsl(0, 100%, 40%);">-                 struct gsm_envabtse envabtse[4];</span><br><span style="color: hsl(0, 100%, 40%);">-                } bs11;</span><br><span style="color: hsl(0, 100%, 40%);">-         struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct om2k_mo om2k_mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                          struct llist_head conn_groups;</span><br><span style="color: hsl(0, 100%, 40%);">-                  } cf;</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct om2k_mo om2k_mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                          struct llist_head conn_groups;</span><br><span style="color: hsl(0, 100%, 40%);">-                  } is;</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct om2k_mo om2k_mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                          struct llist_head conn_groups;</span><br><span style="color: hsl(0, 100%, 40%);">-                  } con;</span><br><span style="color: hsl(0, 100%, 40%);">-                  struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct om2k_mo om2k_mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                  } dp;</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct om2k_mo om2k_mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                  } tf;</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                                struct om2k_mo om2k_mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                  } mctr;</span><br><span style="color: hsl(0, 100%, 40%);">-                 uint32_t use_superchannel:1;</span><br><span style="color: hsl(0, 100%, 40%);">-                    struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                                uint16_t limit;</span><br><span style="color: hsl(0, 100%, 40%);">-                         uint16_t active;</span><br><span style="color: hsl(0, 100%, 40%);">-                        } om2k_version[16];</span><br><span style="color: hsl(0, 100%, 40%);">-             } rbs2000;</span><br><span style="color: hsl(0, 100%, 40%);">-              struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                        uint8_t bts_type;</span><br><span style="color: hsl(0, 100%, 40%);">-                       unsigned int configured:1,      /* we sent the config data request */</span><br><span style="color: hsl(0, 100%, 40%);">-                           skip_reset:1,           /* skip reset at bootstrap */</span><br><span style="color: hsl(0, 100%, 40%);">-                           no_loc_rel_cnf:1,       /* don't wait for RSL REL CONF */</span><br><span style="color: hsl(0, 100%, 40%);">-                           bts_reset_timer_cnf,    /* timer for BTS RESET */</span><br><span style="color: hsl(0, 100%, 40%);">-                               did_reset:1,            /* we received a RESET ACK */</span><br><span style="color: hsl(0, 100%, 40%);">-                           wait_reset:2;           /* we are waiting for reset to complete */</span><br><span style="color: hsl(0, 100%, 40%);">-                      struct osmo_timer_list reset_timer;</span><br><span style="color: hsl(0, 100%, 40%);">-             } nokia;</span><br><span style="color: hsl(0, 100%, 40%);">-        };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Not entirely sure how ip.access specific this is */</span><br><span style="color: hsl(0, 100%, 40%);">-  struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                enum bts_gprs_mode mode;</span><br><span style="color: hsl(0, 100%, 40%);">-                struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                  uint16_t nsei;</span><br><span style="color: hsl(0, 100%, 40%);">-                  uint8_t timer[7];</span><br><span style="color: hsl(0, 100%, 40%);">-               } nse;</span><br><span style="color: hsl(0, 100%, 40%);">-          struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct gsm_abis_mo mo;</span><br><span style="color: hsl(0, 100%, 40%);">-                  uint16_t bvci;</span><br><span style="color: hsl(0, 100%, 40%);">-                  uint8_t timer[11];</span><br><span style="color: hsl(0, 100%, 40%);">-                      struct gprs_rlc_cfg rlc_cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-            } cell;</span><br><span style="color: hsl(0, 100%, 40%);">-         struct gsm_bts_gprs_nsvc nsvc[2];</span><br><span style="color: hsl(0, 100%, 40%);">-               uint8_t rac;</span><br><span style="color: hsl(0, 100%, 40%);">-            uint8_t net_ctrl_ord;</span><br><span style="color: hsl(0, 100%, 40%);">-           bool ctrl_ack_type_use_block;</span><br><span style="color: hsl(0, 100%, 40%);">-           bool egprs_pkt_chan_request;</span><br><span style="color: hsl(0, 100%, 40%);">-    } gprs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* threshold (in percent) when BTS shall send CCCH LOAD IND */</span><br><span style="color: hsl(0, 100%, 40%);">-  int ccch_load_ind_thresh;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* RACH NM values */</span><br><span style="color: hsl(0, 100%, 40%);">-    int rach_b_thresh;</span><br><span style="color: hsl(0, 100%, 40%);">-      int rach_ldavg_slots;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* transceivers */</span><br><span style="color: hsl(0, 100%, 40%);">-      int num_trx;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct llist_head trx_list;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* SI related items */</span><br><span style="color: hsl(0, 100%, 40%);">-  int force_combined_si;</span><br><span style="color: hsl(0, 100%, 40%);">-  bool force_combined_si_set;</span><br><span style="color: hsl(0, 100%, 40%);">-     int bcch_change_mark;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Abis NM queue */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct llist_head abis_queue;</span><br><span style="color: hsl(0, 100%, 40%);">-   int abis_nm_pend;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gsm_network *network;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* should the channel allocator allocate channels from high TRX to TRX0,</span><br><span style="color: hsl(0, 100%, 40%);">-         * rather than starting from TRX0 and go upwards? */</span><br><span style="color: hsl(0, 100%, 40%);">-    int chan_alloc_reverse;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- enum neigh_list_manual_mode neigh_list_manual_mode;</span><br><span style="color: hsl(0, 100%, 40%);">-     /* parameters from which we build SYSTEM INFORMATION */</span><br><span style="color: hsl(0, 100%, 40%);">- struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                struct gsm48_rach_control rach_control;</span><br><span style="color: hsl(0, 100%, 40%);">-         uint8_t ncc_permitted;</span><br><span style="color: hsl(0, 100%, 40%);">-          struct gsm48_cell_sel_par cell_sel_par;</span><br><span style="color: hsl(0, 100%, 40%);">-         struct gsm48_si_selection_params cell_ro_sel_par; /* rest octet */</span><br><span style="color: hsl(0, 100%, 40%);">-              struct gsm48_cell_options cell_options;</span><br><span style="color: hsl(0, 100%, 40%);">-         struct gsm48_control_channel_descr chan_desc;</span><br><span style="color: hsl(0, 100%, 40%);">-           struct bitvec neigh_list;</span><br><span style="color: hsl(0, 100%, 40%);">-               struct bitvec cell_alloc;</span><br><span style="color: hsl(0, 100%, 40%);">-               struct bitvec si5_neigh_list;</span><br><span style="color: hsl(0, 100%, 40%);">-           struct osmo_earfcn_si2q si2quater_neigh_list;</span><br><span style="color: hsl(0, 100%, 40%);">-           size_t uarfcn_length; /* index for uarfcn and scramble lists */</span><br><span style="color: hsl(0, 100%, 40%);">-         struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* bitmask large enough for all possible ARFCN's */</span><br><span style="color: hsl(0, 100%, 40%);">-                 uint8_t neigh_list[1024/8];</span><br><span style="color: hsl(0, 100%, 40%);">-                     uint8_t cell_alloc[1024/8];</span><br><span style="color: hsl(0, 100%, 40%);">-                     /* If the user wants a different neighbor list in SI5 than in SI2 */</span><br><span style="color: hsl(0, 100%, 40%);">-                    uint8_t si5_neigh_list[1024/8];</span><br><span style="color: hsl(0, 100%, 40%);">-                 uint8_t meas_bw_list[MAX_EARFCN_LIST];</span><br><span style="color: hsl(0, 100%, 40%);">-                  uint16_t earfcn_list[MAX_EARFCN_LIST];</span><br><span style="color: hsl(0, 100%, 40%);">-                  uint16_t uarfcn_list[MAX_EARFCN_LIST];</span><br><span style="color: hsl(0, 100%, 40%);">-                  uint16_t scramble_list[MAX_EARFCN_LIST];</span><br><span style="color: hsl(0, 100%, 40%);">-                } data;</span><br><span style="color: hsl(0, 100%, 40%);">- } si_common;</span><br><span style="color: hsl(0, 100%, 40%);">-    bool early_classmark_allowed;</span><br><span style="color: hsl(0, 100%, 40%);">-   bool early_classmark_allowed_3g;</span><br><span style="color: hsl(0, 100%, 40%);">-        /* for testing only: Have an infinitely long radio link timeout */</span><br><span style="color: hsl(0, 100%, 40%);">-      bool infinite_radio_link_timeout;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* do we use static (user-defined) system information messages? (bitmask) */</span><br><span style="color: hsl(0, 100%, 40%);">-    uint32_t si_mode_static;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* access control class ramping */</span><br><span style="color: hsl(0, 100%, 40%);">-      struct acc_ramp acc_ramp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* exclude the BTS from the global RF Lock handling */</span><br><span style="color: hsl(0, 100%, 40%);">-  int excl_from_rf_lock;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* supported codecs beside FR */</span><br><span style="color: hsl(0, 100%, 40%);">-        struct bts_codec_conf codec;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* BTS dependencies bit field */</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t depends_on[256/(8*4)];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* full and half rate multirate config */</span><br><span style="color: hsl(0, 100%, 40%);">-       struct amr_multirate_conf mr_full;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct amr_multirate_conf mr_half;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* PCU socket state */</span><br><span style="color: hsl(0, 100%, 40%);">-  char *pcu_sock_path;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct pcu_sock_state *pcu_state;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       struct rate_ctr_group *bts_ctrs;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct osmo_stat_item_group *bts_statg;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- struct handover_cfg *ho;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* A list of struct gsm_bts_ref, indicating neighbors of this BTS.</span><br><span style="color: hsl(0, 100%, 40%);">-       * When the si_common neigh_list is in automatic mode, it is populated from this list as well as</span><br><span style="color: hsl(0, 100%, 40%);">-         * gsm_network->neighbor_bss_cells. */</span><br><span style="color: hsl(0, 100%, 40%);">-       struct llist_head local_neighbors;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* BTS-specific overrides for timer values from struct gsm_network. */</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t T3122;  /* ASSIGNMENT REJECT wait indication */</span><br><span style="color: hsl(0, 100%, 40%);">- bool T3113_dynamic; /* Calculate T3113 timeout dynamically based on BTS channel config and load */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Periodic channel load measurements are used to maintain T3122. */</span><br><span style="color: hsl(0, 100%, 40%);">-    struct load_counter chan_load_samples[7];</span><br><span style="color: hsl(0, 100%, 40%);">-       int chan_load_samples_idx;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t chan_load_avg; /* current channel load average in percent (0 - 100). */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* cell broadcast system */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct osmo_timer_list cbch_timer;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct bts_smscb_chan_state cbch_basic;</span><br><span style="color: hsl(0, 100%, 40%);">- struct bts_smscb_chan_state cbch_extended;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct osmo_timer_list etws_timer;      /* when to stop ETWS PN */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      struct llist_head oml_fail_rep;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* One rejected BTS */</span><br><span> struct gsm_bts_rejected {</span><br><span>     /* list header in net->bts_rejected */</span><br><span>@@ -1291,28 +957,14 @@</span><br><span> </span><br><span> struct gsm_network *gsm_network_init(void *ctx);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num);</span><br><span> struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num);</span><br><span style="color: hsl(0, 100%, 40%);">-bool gsm_bts_matches_lai(const struct gsm_bts *bts, const struct osmo_location_area_id *lai);</span><br><span style="color: hsl(0, 100%, 40%);">-bool gsm_bts_matches_cell_id(const struct gsm_bts *bts, const struct gsm0808_cell_id *cell_id);</span><br><span> struct gsm_bts *gsm_bts_by_cell_id(const struct gsm_network *net,</span><br><span>                                 const struct gsm0808_cell_id *cell_id,</span><br><span>                               int match_idx);</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_bts_local_neighbor_add(struct gsm_bts *bts, struct gsm_bts *neighbor);</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_bts_local_neighbor_del(struct gsm_bts *bts, const struct gsm_bts *neighbor);</span><br><span> </span><br><span> struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);</span><br><span> struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum gsm_bts_type str2btstype(const char *arg);</span><br><span style="color: hsl(0, 100%, 40%);">-const char *btstype2str(enum gsm_bts_type type);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum bts_attribute str2btsattr(const char *s);</span><br><span style="color: hsl(0, 100%, 40%);">-const char *btsatttr2str(enum bts_attribute v);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum gsm_bts_type_variant str2btsvariant(const char *arg);</span><br><span style="color: hsl(0, 100%, 40%);">-const char *btsvariant2str(enum gsm_bts_type_variant v);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> extern const struct value_string gsm_chreq_descs[];</span><br><span> extern const struct value_string gsm_pchant_names[];</span><br><span> extern const struct value_string gsm_pchant_descs[];</span><br><span>@@ -1323,7 +975,6 @@</span><br><span> enum gsm_phys_chan_config gsm_pchan_parse(const char *name);</span><br><span> const char *gsm_lchant_name(enum gsm_chan_t c);</span><br><span> const char *gsm_chreq_name(enum gsm_chreq_reason_t c);</span><br><span style="color: hsl(0, 100%, 40%);">-char *gsm_bts_name(const struct gsm_bts *bts);</span><br><span> char *gsm_trx_name(const struct gsm_bts_trx *trx);</span><br><span> char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);</span><br><span> char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts);</span><br><span>@@ -1335,6 +986,8 @@</span><br><span> }</span><br><span> </span><br><span> void gsm_abis_mo_reset(struct gsm_abis_mo *mo);</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+                 uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3);</span><br><span> </span><br><span> struct gsm_nm_state *</span><br><span> gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,</span><br><span>@@ -1343,9 +996,6 @@</span><br><span> gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,</span><br><span>          const struct abis_om_obj_inst *obj_inst);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* reset the state of all MO in the BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-void gsm_bts_mo_reset(struct gsm_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,</span><br><span>                          uint8_t ts_nr, uint8_t lchan_nr);</span><br><span> uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan);</span><br><span>@@ -1356,16 +1006,7 @@</span><br><span>                       const struct gsm_lchan *lchan);</span><br><span> void gsm48_lchan2chan_desc_as_configured(struct gsm48_chan_desc *cd, const struct gsm_lchan *lchan);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* return the gsm_lchan for the CBCH (if it exists at all) */</span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static inline uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   if (ts->tsc != -1)</span><br><span style="color: hsl(0, 100%, 40%);">-           return ts->tsc;</span><br><span style="color: hsl(0, 100%, 40%);">-      else</span><br><span style="color: hsl(0, 100%, 40%);">-            return ts->trx->bts->bsic & 7;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts);</span><br><span> </span><br><span> struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,</span><br><span>                                  int *rc);</span><br><span>@@ -1375,164 +1016,11 @@</span><br><span> bool ts_is_tch(struct gsm_bts_trx_ts *ts);</span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static inline struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!conn || !conn->lchan)</span><br><span style="color: hsl(0, 100%, 40%);">-           return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    return conn->lchan->ts->trx->bts;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn);</span><br><span> </span><br><span> void conn_update_ms_power_class(struct gsm_subscriber_connection *conn, uint8_t power_class);</span><br><span> void lchan_update_ms_power_ctrl_level(struct gsm_lchan *lchan, int ms_power_dbm);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum bts_counter_id {</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS_CTR_CHREQ_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_CTR_CHREQ_SUCCESSFUL,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_CHREQ_NO_CHANNEL,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_CHAN_RF_FAIL,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_CTR_CHAN_RLL_ERR,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_CTR_BTS_OML_FAIL,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_CTR_BTS_RSL_FAIL,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_CTR_CODEC_AMR_F,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_CTR_CODEC_AMR_H,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_CTR_CODEC_EFR,</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS_CTR_CODEC_V1_FR,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_CTR_CODEC_V1_HR,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_CTR_PAGING_ATTEMPTED,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_PAGING_ALREADY,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_CTR_PAGING_RESPONDED,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_PAGING_EXPIRED,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_CTR_PAGING_NO_ACTIVE_PAGING,</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS_CTR_PAGING_MSC_FLUSH,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_CHAN_ACT_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_CTR_CHAN_ACT_NACK,</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_CTR_RSL_UNKNOWN,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_CTR_RSL_IPA_NACK,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_CTR_RSL_DELETE_IND,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_CTR_MODE_MODIFY_NACK,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_LCHAN_BORKEN_FROM_UNUSED,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_LCHAN_BORKEN_FROM_WAIT_ACTIV_ACK,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RF_RELEASE_ACK,</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_CTR_LCHAN_BORKEN_FROM_BORKEN,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN,</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK,</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS_CTR_LCHAN_BORKEN_EV_RF_CHAN_REL_ACK,</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS_CTR_LCHAN_BORKEN_EV_VTY,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_CTR_TS_BORKEN_FROM_UNUSED,</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_ACT,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_CTR_TS_BORKEN_FROM_PDCH,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_DEACT,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_CTR_TS_BORKEN_FROM_IN_USE,</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_CTR_TS_BORKEN_FROM_BORKEN,</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_CTR_TS_BORKEN_FROM_UNKNOWN,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_CTR_TS_BORKEN_EV_PDCH_ACT_ACK_NACK,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_CTR_TS_BORKEN_EV_PDCH_DEACT_ACK_NACK,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_CTR_TS_BORKEN_EV_TEARDOWN,</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_CTR_ASSIGNMENT_ATTEMPTED,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_CTR_ASSIGNMENT_COMPLETED,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_CTR_ASSIGNMENT_STOPPED,</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS_CTR_ASSIGNMENT_NO_CHANNEL,</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_CTR_ASSIGNMENT_TIMEOUT,</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS_CTR_ASSIGNMENT_FAILED,</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS_CTR_ASSIGNMENT_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const struct rate_ctr_desc bts_ctr_description[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_CTR_CHREQ_TOTAL] =                 {"chreq:total", "Received channel requests"},</span><br><span style="color: hsl(0, 100%, 40%);">-       [BTS_CTR_CHREQ_SUCCESSFUL] =            {"chreq:successful", "Successful channel requests (immediate assign sent)"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [BTS_CTR_CHREQ_NO_CHANNEL] =            {"chreq:no_channel", "Sent to MS no channel available"},</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_CTR_CHAN_RF_FAIL] =                {"chan:rf_fail", "Received a RF failure indication from BTS"},</span><br><span style="color: hsl(0, 100%, 40%);">-      [BTS_CTR_CHAN_RLL_ERR] =                {"chan:rll_err", "Received a RLL failure with T200 cause from BTS"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [BTS_CTR_BTS_OML_FAIL] =                {"oml_fail", "Received a TEI down on a OML link"},</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_CTR_BTS_RSL_FAIL] =                {"rsl_fail", "Received a TEI down on a OML link"},</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_CTR_CODEC_AMR_F] =                 {"codec:amr_f", "Count the usage of AMR/F codec by channel mode requested"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [BTS_CTR_CODEC_AMR_H] =                 {"codec:amr_h", "Count the usage of AMR/H codec by channel mode requested"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [BTS_CTR_CODEC_EFR] =                   {"codec:efr", "Count the usage of EFR codec by channel mode requested"},</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_CTR_CODEC_V1_FR] =                 {"codec:fr", "Count the usage of FR codec by channel mode requested"},</span><br><span style="color: hsl(0, 100%, 40%);">-      [BTS_CTR_CODEC_V1_HR] =                 {"codec:hr", "Count the usage of HR codec by channel mode requested"},</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      [BTS_CTR_PAGING_ATTEMPTED] =            {"paging:attempted", "Paging attempts for a subscriber"},</span><br><span style="color: hsl(0, 100%, 40%);">-   [BTS_CTR_PAGING_ALREADY] =              {"paging:already", "Paging attempts ignored as subscriber was already being paged"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [BTS_CTR_PAGING_RESPONDED] =            {"paging:responded", "Paging attempts with successful paging response"},</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_CTR_PAGING_EXPIRED] =              {"paging:expired", "Paging Request expired because of timeout T3113"},</span><br><span style="color: hsl(0, 100%, 40%);">-      [BTS_CTR_PAGING_NO_ACTIVE_PAGING] =     {"paging:no_active_paging", "Paging response without an active paging request (arrived after paging expiration?)"},</span><br><span style="color: hsl(0, 100%, 40%);">- [BTS_CTR_PAGING_MSC_FLUSH] =            {"paging:msc_flush", "Paging flushed due to MSC Reset BSSMAP message"},</span><br><span style="color: hsl(0, 100%, 40%);">-     [BTS_CTR_CHAN_ACT_TOTAL] =              {"chan_act:total", "Total number of Channel Activations"},</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_CTR_CHAN_ACT_NACK] =               {"chan_act:nack", "Number of Channel Activations that the BTS NACKed"},</span><br><span style="color: hsl(0, 100%, 40%);">-     [BTS_CTR_RSL_UNKNOWN] =                 {"rsl:unknown", "Number of unknown/unsupported RSL messages received from BTS"},</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_CTR_RSL_IPA_NACK] =                {"rsl:ipa_nack", "Number of IPA (RTP/dyn-PDCH) related NACKs received from BTS"},</span><br><span style="color: hsl(0, 100%, 40%);">-   [BTS_CTR_RSL_DELETE_IND] =              {"rsl:delete_ind", "Number of RSL DELETE INDICATION (DL CCCH overload)"},</span><br><span style="color: hsl(0, 100%, 40%);">-   [BTS_CTR_MODE_MODIFY_NACK] =            {"chan:mode_modify_nack", "Number of Channel Mode Modify NACKs received from BTS"},</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* lchan/TS BORKEN state counters */</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_CTR_LCHAN_BORKEN_FROM_UNUSED] =              {"lchan_borken:from_state:unused", "Transitions from lchan UNUSED state to BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [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"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [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"},</span><br><span style="color: hsl(0, 100%, 40%);">-      [BTS_CTR_LCHAN_BORKEN_FROM_BORKEN] =              {"lchan_borken:from_state:borken", "Transitions from lchan BORKEN state to BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN] =             {"lchan_borken:from_state:unknown", "Transitions from an unknown lchan state to BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-   [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK] =        {"lchan_borken:event:chan_activ_ack", "CHAN_ACTIV_ACK received in the lchan BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-       [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK] =       {"lchan_borken:event:chan_activ_nack", "CHAN_ACTIV_NACK received in the lchan BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-     [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"},</span><br><span style="color: hsl(0, 100%, 40%);">-     [BTS_CTR_LCHAN_BORKEN_EV_VTY] =                   {"lchan_borken:event:vty", "VTY commands received in the lchan BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN] =              {"lchan_borken:event:teardown", "lchan in a BORKEN state is shutting down (BTS disconnected?)"},</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED] =   {"ts_borken:from_state:not_initialized", "Transitions from TS NOT_INITIALIZED state to BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">- [BTS_CTR_TS_BORKEN_FROM_UNUSED] =            {"ts_borken:from_state:unused", "Transitions from TS UNUSED state to BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-   [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"},</span><br><span style="color: hsl(0, 100%, 40%);">-     [BTS_CTR_TS_BORKEN_FROM_PDCH] =              {"ts_borken:from_state:pdch", "Transitions from TS PDCH state to BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-       [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"},</span><br><span style="color: hsl(0, 100%, 40%);">- [BTS_CTR_TS_BORKEN_FROM_IN_USE] =            {"ts_borken:from_state:in_use", "Transitions from TS IN_USE state to BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-   [BTS_CTR_TS_BORKEN_FROM_BORKEN] =            {"ts_borken:from_state:borken", "Transitions from TS BORKEN state to BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-   [BTS_CTR_TS_BORKEN_FROM_UNKNOWN] =           {"ts_borken:from_state:unknown", "Transitions from an unknown TS state to BORKEN state"},</span><br><span style="color: hsl(0, 100%, 40%);">-      [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"},</span><br><span style="color: hsl(0, 100%, 40%);">-    [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"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [BTS_CTR_TS_BORKEN_EV_TEARDOWN] =            {"ts_borken:event:teardown", "TS in a BORKEN state is shutting down (BTS disconnected?)"},</span><br><span style="color: hsl(0, 100%, 40%);">-     [BTS_CTR_ASSIGNMENT_ATTEMPTED] =             {"assignment:attempted", "Assignment attempts"},</span><br><span style="color: hsl(0, 100%, 40%);">-       [BTS_CTR_ASSIGNMENT_COMPLETED] =             {"assignment:completed", "Assignment completed"},</span><br><span style="color: hsl(0, 100%, 40%);">-      [BTS_CTR_ASSIGNMENT_STOPPED] =               {"assignment:stopped", "Connection ended during Assignment"},</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_CTR_ASSIGNMENT_NO_CHANNEL] =            {"assignment:no_channel", "Failure to allocate lchan for Assignment"},</span><br><span style="color: hsl(0, 100%, 40%);">- [BTS_CTR_ASSIGNMENT_TIMEOUT] =               {"assignment:timeout", "Assignment timed out"},</span><br><span style="color: hsl(0, 100%, 40%);">-        [BTS_CTR_ASSIGNMENT_FAILED] =                {"assignment:failed", "Received Assignment Failure message"},</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_CTR_ASSIGNMENT_ERROR] =                 {"assignment:error", "Assignment failed for other reason"},</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const struct rate_ctr_group_desc bts_ctrg_desc = {</span><br><span style="color: hsl(0, 100%, 40%);">- "bts",</span><br><span style="color: hsl(0, 100%, 40%);">-        "base transceiver station",</span><br><span style="color: hsl(0, 100%, 40%);">-   OSMO_STATS_CLASS_GLOBAL,</span><br><span style="color: hsl(0, 100%, 40%);">-        ARRAY_SIZE(bts_ctr_description),</span><br><span style="color: hsl(0, 100%, 40%);">-        bts_ctr_description,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_STAT_CHAN_LOAD_AVERAGE,</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS_STAT_CHAN_CCCH_SDCCH4_USED,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS_STAT_CHAN_TCH_F_USED,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_STAT_CHAN_TCH_F_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS_STAT_CHAN_TCH_H_USED,</span><br><span style="color: hsl(0, 100%, 40%);">-       BTS_STAT_CHAN_TCH_H_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS_STAT_CHAN_SDCCH8_USED,</span><br><span style="color: hsl(0, 100%, 40%);">-      BTS_STAT_CHAN_SDCCH8_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS_STAT_CHAN_TCH_F_PDCH_USED,</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_STAT_CHAN_TCH_F_PDCH_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_STAT_CHAN_SDCCH8_CBCH_USED,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">-        BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED,</span><br><span style="color: hsl(0, 100%, 40%);">-    BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_STAT_T3122,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_STAT_RACH_BUSY,</span><br><span style="color: hsl(0, 100%, 40%);">-     BTS_STAT_RACH_ACCESS,</span><br><span style="color: hsl(0, 100%, 40%);">-   BTS_STAT_OML_CONNECTED,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_STAT_RSL_CONNECTED,</span><br><span style="color: hsl(0, 100%, 40%);">- BTS_STAT_LCHAN_BORKEN,</span><br><span style="color: hsl(0, 100%, 40%);">-  BTS_STAT_TS_BORKEN,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> enum {</span><br><span>      BSC_CTR_ASSIGNMENT_ATTEMPTED,</span><br><span>        BSC_CTR_ASSIGNMENT_COMPLETED,</span><br><span>@@ -1743,20 +1231,8 @@</span><br><span>                 ver : 7;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static inline const struct osmo_location_area_id *bts_lai(struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     static struct osmo_location_area_id lai;</span><br><span style="color: hsl(0, 100%, 40%);">-        lai = (struct osmo_location_area_id){</span><br><span style="color: hsl(0, 100%, 40%);">-           .plmn = bts->network->plmn,</span><br><span style="color: hsl(0, 100%, 40%);">-               .lac = bts->location_area_code,</span><br><span style="color: hsl(0, 100%, 40%);">-      };</span><br><span style="color: hsl(0, 100%, 40%);">-      return &lai;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> extern void talloc_ctx_init(void *ctx_root);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> enum gsm_bts_type parse_btstype(const char *arg);</span><br><span> const char *btstype2str(enum gsm_bts_type type);</span><br><span> struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,</span><br><span>@@ -1764,91 +1240,14 @@</span><br><span> </span><br><span> extern void *tall_bsc_ctx;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* this actually refers to the IPA transport, not the BTS model */</span><br><span style="color: hsl(0, 100%, 40%);">-static inline int is_ipaccess_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (bts->type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_BTS_TYPE_NANOBTS:</span><br><span style="color: hsl(0, 100%, 40%);">-      case GSM_BTS_TYPE_OSMOBTS:</span><br><span style="color: hsl(0, 100%, 40%);">-              return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static inline int is_sysmobts_v2(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  switch (bts->type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_BTS_TYPE_OSMOBTS:</span><br><span style="color: hsl(0, 100%, 40%);">-              return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static inline int is_siemens_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  switch (bts->type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_BTS_TYPE_BS11:</span><br><span style="color: hsl(0, 100%, 40%);">-         return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static inline int is_nokia_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (bts->type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_BTS_TYPE_NOKIA_SITE:</span><br><span style="color: hsl(0, 100%, 40%);">-           return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static inline int is_ericsson_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- switch (bts->type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_BTS_TYPE_RBS2000:</span><br><span style="color: hsl(0, 100%, 40%);">-              return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static inline int is_e1_bts(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (bts->type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_BTS_TYPE_BS11:</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_BTS_TYPE_RBS2000:</span><br><span style="color: hsl(0, 100%, 40%);">-      case GSM_BTS_TYPE_NOKIA_SITE:</span><br><span style="color: hsl(0, 100%, 40%);">-           return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> extern struct gsm_network *bsc_gsmnet;</span><br><span> </span><br><span> enum bts_gprs_mode bts_gprs_mode_parse(const char *arg, int *valid);</span><br><span> const char *bts_gprs_mode_name(enum bts_gprs_mode mode);</span><br><span style="color: hsl(0, 100%, 40%);">-int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);</span><br><span> </span><br><span> void gsm48_ra_id_by_bts(struct gsm48_ra_id *buf, struct gsm_bts *bts);</span><br><span> void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_bts_model_register(struct gsm_bts_model *model);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *network);</span><br><span> </span><br><span> struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type, uint8_t bsic);</span><br><span>@@ -1858,42 +1257,23 @@</span><br><span>                    uint8_t e1_ts, uint8_t e1_ts_ss);</span><br><span> </span><br><span> void gsm_trx_lock_rf(struct gsm_bts_trx *trx, bool locked, const char *reason);</span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);</span><br><span> int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx);</span><br><span> int gsm_bts_set_system_infos(struct gsm_bts *bts);</span><br><span> </span><br><span> /* generic E1 line operations for all ISDN-based BTS. */</span><br><span> extern struct e1inp_line_ops bts_isdn_e1inp_line_ops;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-extern const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1];</span><br><span style="color: hsl(0, 100%, 40%);">-extern const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-char *get_model_oml_status(const struct gsm_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-unsigned long long bts_uptime(const struct gsm_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* control interface handling */</span><br><span> int bsc_base_ctrl_cmds_install(void);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* dependency handling */</span><br><span style="color: hsl(0, 100%, 40%);">-void bts_depend_mark(struct gsm_bts *bts, int dep);</span><br><span style="color: hsl(0, 100%, 40%);">-void bts_depend_clear(struct gsm_bts *bts, int dep);</span><br><span style="color: hsl(0, 100%, 40%);">-int bts_depend_check(struct gsm_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts);</span><br><span style="color: hsl(0, 100%, 40%);">-void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> bool trx_is_usable(const struct gsm_bts_trx *trx);</span><br><span> bool ts_is_usable(const struct gsm_bts_trx_ts *ts);</span><br><span> </span><br><span> int gsm_lchan_type_by_pchan(enum gsm_phys_chan_config pchan);</span><br><span> enum gsm_phys_chan_config gsm_pchan_by_lchan_type(enum gsm_chan_t type);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data);</span><br><span> void gsm_trx_all_ts_dispatch(struct gsm_bts_trx *trx, uint32_t ts_ev, void *data);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan);</span><br><span> </span><br><span> bool trx_has_valid_pchan_config(const struct gsm_bts_trx *trx);</span><br><span> </span><br><span>diff --git a/src/ipaccess/Makefile.am b/src/ipaccess/Makefile.am</span><br><span>index 145ea39..273530c 100644</span><br><span>--- a/src/ipaccess/Makefile.am</span><br><span>+++ b/src/ipaccess/Makefile.am</span><br><span>@@ -46,6 +46,7 @@</span><br><span> </span><br><span> # FIXME: resolve the bogus dependencies patched around here:</span><br><span> ipaccess_config_LDADD = \</span><br><span style="color: hsl(120, 100%, 40%);">+       $(top_builddir)/src/osmo-bsc/bts.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/abis_nm.o \</span><br><span>     $(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \</span><br><span>@@ -57,9 +58,10 @@</span><br><span> ipaccess_proxy_SOURCES = \</span><br><span>     ipaccess-proxy.c \</span><br><span>   stubs.c \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_srcdir)/src/osmo-bsc/gsm_data.c \</span><br><span>      $(NULL)</span><br><span> </span><br><span> ipaccess_proxy_LDADD = \</span><br><span style="color: hsl(120, 100%, 40%);">+       $(top_builddir)/src/osmo-bsc/bts.o \</span><br><span style="color: hsl(120, 100%, 40%);">+  $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span>    $(OSMO_LIBS) \</span><br><span>       $(NULL)</span><br><span>diff --git a/src/ipaccess/ipaccess-config.c b/src/ipaccess/ipaccess-config.c</span><br><span>index f7d7332..34ad57f 100644</span><br><span>--- a/src/ipaccess/ipaccess-config.c</span><br><span>+++ b/src/ipaccess/ipaccess-config.c</span><br><span>@@ -56,6 +56,7 @@</span><br><span> #include <osmocom/abis/abis.h></span><br><span> #include <osmocom/gsm/protocol/gsm_12_21.h></span><br><span> #include <osmocom/bsc/bss.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> struct gsm_network *bsc_gsmnet;</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am</span><br><span>index 0665af6..f66421a 100644</span><br><span>--- a/src/osmo-bsc/Makefile.am</span><br><span>+++ b/src/osmo-bsc/Makefile.am</span><br><span>@@ -43,6 +43,7 @@</span><br><span>  bsc_subscr_conn_fsm.c \</span><br><span>      bsc_subscriber.c \</span><br><span>   bsc_vty.c \</span><br><span style="color: hsl(120, 100%, 40%);">+   bts.c \</span><br><span>      bts_ericsson_rbs2000.c \</span><br><span>     bts_init.c \</span><br><span>         bts_ipaccess_nanobts.c \</span><br><span>diff --git a/src/osmo-bsc/abis_nm.c b/src/osmo-bsc/abis_nm.c</span><br><span>index 8dde8de..4ce27f3 100644</span><br><span>--- a/src/osmo-bsc/abis_nm.c</span><br><span>+++ b/src/osmo-bsc/abis_nm.c</span><br><span>@@ -48,6 +48,7 @@</span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/abis/e1_input.h></span><br><span> #include <osmocom/bsc/chan_alloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/gsm/bts_features.h></span><br><span> </span><br><span> #define OM_ALLOC_SIZE             1024</span><br><span>@@ -853,14 +854,6 @@</span><br><span>  return true;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-char *get_model_oml_status(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     if (bts->model->oml_status)</span><br><span style="color: hsl(0, 100%, 40%);">-               return bts->model->oml_status(bts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return "unknown";</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> void abis_nm_queue_send_next(struct gsm_bts *bts)</span><br><span> {</span><br><span>       int wait = 0;</span><br><span>diff --git a/src/osmo-bsc/abis_om2000.c b/src/osmo-bsc/abis_om2000.c</span><br><span>index 0aea684..1e4ef97 100644</span><br><span>--- a/src/osmo-bsc/abis_om2000.c</span><br><span>+++ b/src/osmo-bsc/abis_om2000.c</span><br><span>@@ -44,6 +44,7 @@</span><br><span> #include <osmocom/bsc/abis_om2000.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/abis/e1_input.h></span><br><span> </span><br><span> /* FIXME: move to libosmocore */</span><br><span>diff --git a/src/osmo-bsc/abis_om2000_vty.c b/src/osmo-bsc/abis_om2000_vty.c</span><br><span>index 222546f..b00c7dd 100644</span><br><span>--- a/src/osmo-bsc/abis_om2000_vty.c</span><br><span>+++ b/src/osmo-bsc/abis_om2000_vty.c</span><br><span>@@ -33,6 +33,7 @@</span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/abis_om2000.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/bsc/vty.h></span><br><span> </span><br><span> #include <osmocom/vty/vty.h></span><br><span>diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c</span><br><span>index f6e564b..1ffdd06 100644</span><br><span>--- a/src/osmo-bsc/abis_rsl.c</span><br><span>+++ b/src/osmo-bsc/abis_rsl.c</span><br><span>@@ -54,7 +54,7 @@</span><br><span> #include <osmocom/bsc/lchan_rtp_fsm.h></span><br><span> #include <osmocom/bsc/handover_fsm.h></span><br><span> #include <osmocom/bsc/smscb.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #define RSL_ALLOC_SIZE              1024</span><br><span> #define RSL_ALLOC_HEADROOM      128</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/acc_ramp.c b/src/osmo-bsc/acc_ramp.c</span><br><span>index b79c0c2..761ab09 100644</span><br><span>--- a/src/osmo-bsc/acc_ramp.c</span><br><span>+++ b/src/osmo-bsc/acc_ramp.c</span><br><span>@@ -29,6 +29,7 @@</span><br><span> #include <osmocom/bsc/chan_alloc.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/abis_nm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> /*</span><br><span>  * Check if an ACC has been permanently barred for a BTS,</span><br><span>diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c</span><br><span>index cd5abc8..ca29daa 100644</span><br><span>--- a/src/osmo-bsc/assignment_fsm.c</span><br><span>+++ b/src/osmo-bsc/assignment_fsm.c</span><br><span>@@ -34,6 +34,7 @@</span><br><span> #include <osmocom/bsc/gsm_08_08.h></span><br><span> #include <osmocom/bsc/lchan_select.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/bsc/assignment_fsm.h></span><br><span> </span><br><span>diff --git a/src/osmo-bsc/bsc_ctrl_commands.c b/src/osmo-bsc/bsc_ctrl_commands.c</span><br><span>index 774ded2..9383167 100644</span><br><span>--- a/src/osmo-bsc/bsc_ctrl_commands.c</span><br><span>+++ b/src/osmo-bsc/bsc_ctrl_commands.c</span><br><span>@@ -30,6 +30,7 @@</span><br><span> #include <osmocom/bsc/chan_alloc.h></span><br><span> #include <osmocom/bsc/osmo_bsc_rf.h></span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> CTRL_CMD_DEFINE(net_mcc, "mcc");</span><br><span> static int get_net_mcc(struct ctrl_cmd *cmd, void *_data)</span><br><span>diff --git a/src/osmo-bsc/bsc_init.c b/src/osmo-bsc/bsc_init.c</span><br><span>index 7333533..4fc0ab1 100644</span><br><span>--- a/src/osmo-bsc/bsc_init.c</span><br><span>+++ b/src/osmo-bsc/bsc_init.c</span><br><span>@@ -36,6 +36,7 @@</span><br><span> #include <osmocom/bsc/handover_cfg.h></span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/bsc/smscb.h></span><br><span> #include <osmocom/gsm/protocol/gsm_48_049.h></span><br><span>@@ -68,24 +69,6 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-unsigned long long bts_uptime(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct timespec tp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!bts->uptime || !bts->oml_link) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DNM, LOGL_ERROR, "BTS %u OML link uptime unavailable\n", bts->nr);</span><br><span style="color: hsl(0, 100%, 40%);">-            return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DNM, LOGL_ERROR, "BTS %u uptime computation failure: %s\n", bts->nr, strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-                return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* monotonic clock helps to ensure that the conversion is valid */</span><br><span style="color: hsl(0, 100%, 40%);">-      return difftime(tp.tv_sec, bts->uptime);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static int rsl_si(struct gsm_bts_trx *trx, enum osmo_sysinfo_type i, int si_len)</span><br><span> {</span><br><span>        struct gsm_bts *bts = trx->bts;</span><br><span>diff --git a/src/osmo-bsc/bsc_rf_ctrl.c b/src/osmo-bsc/bsc_rf_ctrl.c</span><br><span>index c72154a..1e04f21 100644</span><br><span>--- a/src/osmo-bsc/bsc_rf_ctrl.c</span><br><span>+++ b/src/osmo-bsc/bsc_rf_ctrl.c</span><br><span>@@ -26,6 +26,7 @@</span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span> #include <osmocom/bsc/ipaccess.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/utils.h></span><br><span>diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c</span><br><span>index 36b16a2..aa08e8b 100644</span><br><span>--- a/src/osmo-bsc/bsc_vty.c</span><br><span>+++ b/src/osmo-bsc/bsc_vty.c</span><br><span>@@ -73,6 +73,7 @@</span><br><span> #include <osmocom/bsc/lchan_select.h></span><br><span> #include <osmocom/bsc/smscb.h></span><br><span> #include <osmocom/bsc/osmo_bsc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h></span><br><span> </span><br><span> #include <inttypes.h></span><br><span>diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c</span><br><span>new file mode 100644</span><br><span>index 0000000..71968f6</span><br><span>--- /dev/null</span><br><span>+++ b/src/osmo-bsc/bts.c</span><br><span>@@ -0,0 +1,748 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2008-2018 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/abis_nm.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/debug.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct value_string bts_attribute_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_VALUE_STRING(BTS_TYPE_VARIANT),</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_VALUE_STRING(BTS_SUB_MODEL),</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_VALUE_STRING(TRX_PHY_VERSION),</span><br><span style="color: hsl(120, 100%, 40%);">+   { 0, NULL }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum bts_attribute str2btsattr(const char *s)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return get_string_value(bts_attribute_names, s);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const char *btsatttr2str(enum bts_attribute v)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return get_value_string(bts_attribute_names, v);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {</span><br><span style="color: hsl(120, 100%, 40%);">+     { BTS_UNKNOWN,          "unknown" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { BTS_OSMO_LITECELL15,  "osmo-bts-lc15" },</span><br><span style="color: hsl(120, 100%, 40%);">+  { BTS_OSMO_OCTPHY,      "osmo-bts-octphy" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { BTS_OSMO_SYSMO,       "osmo-bts-sysmo" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BTS_OSMO_TRX,         "omso-bts-trx" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { 0, NULL }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum gsm_bts_type_variant str2btsvariant(const char *arg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return get_string_value(osmo_bts_variant_names, arg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const char *btsvariant2str(enum gsm_bts_type_variant v)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return get_value_string(osmo_bts_variant_names, v);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { GSM_BTS_TYPE_UNKNOWN,         "unknown" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { GSM_BTS_TYPE_BS11,            "bs11" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { GSM_BTS_TYPE_NANOBTS,         "nanobts" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { GSM_BTS_TYPE_RBS2000,         "rbs2000" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { GSM_BTS_TYPE_NOKIA_SITE,      "nokia_site" },</span><br><span style="color: hsl(120, 100%, 40%);">+     { GSM_BTS_TYPE_OSMOBTS,         "sysmobts" },</span><br><span style="color: hsl(120, 100%, 40%);">+       { 0, NULL }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = {</span><br><span style="color: hsl(120, 100%, 40%);">+  { GSM_BTS_TYPE_UNKNOWN,         "Unknown BTS Type" },</span><br><span style="color: hsl(120, 100%, 40%);">+       { GSM_BTS_TYPE_BS11,            "Siemens BTS (BS-11 or compatible)" },</span><br><span style="color: hsl(120, 100%, 40%);">+      { GSM_BTS_TYPE_NANOBTS,         "ip.access nanoBTS or compatible" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { GSM_BTS_TYPE_RBS2000,         "Ericsson RBS2000 Series" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { GSM_BTS_TYPE_NOKIA_SITE,      "Nokia {Metro,Ultra,In}Site" },</span><br><span style="color: hsl(120, 100%, 40%);">+     { GSM_BTS_TYPE_OSMOBTS,         "sysmocom sysmoBTS" },</span><br><span style="color: hsl(120, 100%, 40%);">+      { 0,                            NULL }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum gsm_bts_type str2btstype(const char *arg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return get_string_value(bts_type_names, arg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const char *btstype2str(enum gsm_bts_type type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return get_value_string(bts_type_names, type);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void bts_init_cbch_state(struct bts_smscb_chan_state *cstate, struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     cstate->bts = bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&cstate->messages);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static LLIST_HEAD(bts_models);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts_model *bts_model_find(enum gsm_bts_type type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_bts_model *model;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        llist_for_each_entry(model, &bts_models, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (model->type == type)</span><br><span style="color: hsl(120, 100%, 40%);">+                   return model;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_bts_model_register(struct gsm_bts_model *model)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bts_model_find(model->type))</span><br><span style="color: hsl(120, 100%, 40%);">+           return -EEXIST;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     tlv_def_patch(&model->nm_att_tlvdef, &abis_nm_att_tlvdef);</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_add_tail(&model->list, &bts_models);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct osmo_stat_item_desc bts_stat_desc[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+   [BTS_STAT_CHAN_LOAD_AVERAGE] =                  { "chanloadavg", "Channel load average", "%", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_STAT_CHAN_CCCH_SDCCH4_USED] =              { "chan_ccch_sdcch4:used",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    "Number of CCCH+SDCCH4 channels used", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+     [BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL] =             { "chan_ccch_sdcch4:total",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   "Number of CCCH+SDCCH4 channels total", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+    [BTS_STAT_CHAN_TCH_F_USED] =                    { "chan_tch_f:used",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                          "Number of TCH/F channels used", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+   [BTS_STAT_CHAN_TCH_F_TOTAL] =                   { "chan_tch_f:total",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         "Number of TCH/F channels total", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_STAT_CHAN_TCH_H_USED] =                    { "chan_tch_h:used",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                          "Number of TCH/H channels used", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+   [BTS_STAT_CHAN_TCH_H_TOTAL] =                   { "chan_tch_h:total",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         "Number of TCH/H channels total", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_STAT_CHAN_SDCCH8_USED] =                   { "chan_sdcch8:used",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         "Number of SDCCH8 channels used", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_STAT_CHAN_SDCCH8_TOTAL] =                  { "chan_sdcch8:total",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        "Number of SDCCH8 channels total", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BTS_STAT_CHAN_TCH_F_PDCH_USED] =               { "chan_tch_f_pdch:used",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     "Number of TCH/F_PDCH channels used", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+      [BTS_STAT_CHAN_TCH_F_PDCH_TOTAL] =              { "chan_tch_f_pdch:total",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    "Number of TCH/F_PDCH channels total", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+     [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED] =         { "chan_ccch_sdcch4_cbch:used",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                       "Number of CCCH+SDCCH4+CBCH channels used", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL] =        { "chan_ccch_sdcch4_cbch:total",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      "Number of CCCH+SDCCH4+CBCH channels total", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+       [BTS_STAT_CHAN_SDCCH8_CBCH_USED] =              { "chan_sdcch8_cbch:used",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    "Number of SDCCH8+CBCH channels used", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+     [BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL] =             { "chan_sdcch8_cbch:total",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   "Number of SDCCH8+CBCH channels total", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+    [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED] =         { "chan_tch_f_tch_h_pdch:used",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                       "Number of TCH/F_TCH/H_PDCH channels used", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL] =        { "chan_tch_f_tch_h_pdch:total",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      "Number of TCH/F_TCH/H_PDCH channels total", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+       [BTS_STAT_T3122] =                              { "T3122", "T3122 IMMEDIATE ASSIGNMENT REJECT wait indicator",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      "s", 16, GSM_T3122_DEFAULT },</span><br><span style="color: hsl(120, 100%, 40%);">+     [BTS_STAT_RACH_BUSY] =                          { "rach_busy",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        "RACH slots with signal above threshold", "%", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BTS_STAT_RACH_ACCESS] =                        { "rach_access",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      "RACH slots with access bursts in them", "%", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+  [BTS_STAT_OML_CONNECTED] =                      { "oml_connected", "Number of OML links connected", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_STAT_RSL_CONNECTED] =                      { "rsl_connected", "Number of RSL links connected", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        [BTS_STAT_LCHAN_BORKEN] =                       { "lchan_borken",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     "Number of lchans in the BORKEN state", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+    [BTS_STAT_TS_BORKEN] =                          { "ts_borken",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        "Number of timeslots in the BORKEN state", "", 16, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct osmo_stat_item_group_desc bts_statg_desc = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .group_name_prefix = "bts",</span><br><span style="color: hsl(120, 100%, 40%);">+ .group_description = "base transceiver station",</span><br><span style="color: hsl(120, 100%, 40%);">+    .class_id = OSMO_STATS_CLASS_GLOBAL,</span><br><span style="color: hsl(120, 100%, 40%);">+  .num_items = ARRAY_SIZE(bts_stat_desc),</span><br><span style="color: hsl(120, 100%, 40%);">+       .item_desc = bts_stat_desc,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };</span><br><span style="color: hsl(120, 100%, 40%);">+static const uint8_t bts_cell_timer_default[] =</span><br><span style="color: hsl(120, 100%, 40%);">+                         { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct gprs_rlc_cfg rlc_cfg_default = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .parameter = {</span><br><span style="color: hsl(120, 100%, 40%);">+                [RLC_T3142] = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+             [RLC_T3169] = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+              [RLC_T3191] = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+              [RLC_T3193] = 160, /* 10ms */</span><br><span style="color: hsl(120, 100%, 40%);">+         [RLC_T3195] = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+              [RLC_N3101] = 10,</span><br><span style="color: hsl(120, 100%, 40%);">+             [RLC_N3103] = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+              [RLC_N3105] = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+              [CV_COUNTDOWN] = 15,</span><br><span style="color: hsl(120, 100%, 40%);">+          [T_DL_TBF_EXT] = 250 * 10, /* ms */</span><br><span style="color: hsl(120, 100%, 40%);">+           [T_UL_TBF_EXT] = 250 * 10, /* ms */</span><br><span style="color: hsl(120, 100%, 40%);">+   },</span><br><span style="color: hsl(120, 100%, 40%);">+    .paging = {</span><br><span style="color: hsl(120, 100%, 40%);">+           .repeat_time = 5 * 50, /* ms */</span><br><span style="color: hsl(120, 100%, 40%);">+               .repeat_count = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+    },</span><br><span style="color: hsl(120, 100%, 40%);">+    .cs_mask = 0x1fff,</span><br><span style="color: hsl(120, 100%, 40%);">+    .initial_cs = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+      .initial_mcs = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Initialize those parts that don't require osmo-bsc specific dependencies.</span><br><span style="color: hsl(120, 100%, 40%);">+ * This part is shared among the thin programs in osmo-bsc/src/utils/.</span><br><span style="color: hsl(120, 100%, 40%);">+ * osmo-bsc requires further initialization that pulls in more dependencies (see</span><br><span style="color: hsl(120, 100%, 40%);">+ * bsc_bts_alloc_register()). */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gsm_bts *bts = talloc_zero(net, struct gsm_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm48_multi_rate_conf mr_cfg;</span><br><span style="color: hsl(120, 100%, 40%);">+  int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts)</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->nr = bts_num;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->num_trx = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  INIT_LLIST_HEAD(&bts->trx_list);</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->network = net;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->ms_max_power = 15;      /* dBm */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   gsm_mo_init(&bts->mo, bts, NM_OC_BTS,</span><br><span style="color: hsl(120, 100%, 40%);">+                  bts->nr, 0xff, 0xff);</span><br><span style="color: hsl(120, 100%, 40%);">+      gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,</span><br><span style="color: hsl(120, 100%, 40%);">+                        0xff, 0xff, 0xff);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+              bts->gprs.nsvc[i].bts = bts;</span><br><span style="color: hsl(120, 100%, 40%);">+               bts->gprs.nsvc[i].id = i;</span><br><span style="color: hsl(120, 100%, 40%);">+          gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,</span><br><span style="color: hsl(120, 100%, 40%);">+                               bts->nr, i, 0xff);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,</span><br><span style="color: hsl(120, 100%, 40%);">+            sizeof(bts->gprs.nse.timer));</span><br><span style="color: hsl(120, 100%, 40%);">+      gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,</span><br><span style="color: hsl(120, 100%, 40%);">+                    bts->nr, 0xff, 0xff);</span><br><span style="color: hsl(120, 100%, 40%);">+      memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,</span><br><span style="color: hsl(120, 100%, 40%);">+          sizeof(bts->gprs.cell.timer));</span><br><span style="color: hsl(120, 100%, 40%);">+     gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,</span><br><span style="color: hsl(120, 100%, 40%);">+                  bts->nr, 0xff, 0xff);</span><br><span style="color: hsl(120, 100%, 40%);">+      memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,</span><br><span style="color: hsl(120, 100%, 40%);">+          sizeof(bts->gprs.cell.rlc_cfg));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 3GPP TS 08.18, chapter 5.4.1: 0 is reserved for signalling */</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->gprs.cell.bvci = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* init statistics */</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->bts_ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!bts->bts_ctrs) {</span><br><span style="color: hsl(120, 100%, 40%);">+              talloc_free(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->bts_statg = osmo_stat_item_group_alloc(bts, &bts_statg_desc, bts->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* create our primary TRX */</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->c0 = gsm_bts_trx_alloc(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!bts->c0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            rate_ctr_group_free(bts->bts_ctrs);</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_stat_item_group_free(bts->bts_statg);</span><br><span style="color: hsl(120, 100%, 40%);">+         talloc_free(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->c0->ts[0].pchan_from_config = GSM_PCHAN_CCCH_SDCCH4; /* TODO: really?? */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->ccch_load_ind_thresh = 10; /* 10% of Load: Start sending CCCH LOAD IND */</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->rach_b_thresh = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+   bts->rach_ldavg_slots = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->paging.free_chans_need = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+  INIT_LLIST_HEAD(&bts->paging.pending_requests);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->features.data = &bts->_features_data[0];</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->features.data_len = sizeof(bts->_features_data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* si handling */</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->bcch_change_mark = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->chan_load_avg = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* timer overrides */</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->T3122 = 0; /* not overridden by default */</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->T3113_dynamic = true; /* dynamic by default */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;</span><br><span style="color: hsl(120, 100%, 40%);">+   bts->dtxd = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->gprs.ctrl_ack_type_use_block = true; /* use RLC/MAC control block */</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->neigh_list_manual_mode = NL_MODE_AUTOMATIC;</span><br><span style="color: hsl(120, 100%, 40%);">+   bts->early_classmark_allowed_3g = true; /* 3g Early Classmark Sending controlled by bts->early_classmark_allowed param */</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->si_unused_send_empty = true;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->si_common.cell_sel_par.cell_resel_hyst = 2; /* 4 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->si_common.cell_sel_par.rxlev_acc_min = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->si_common.si2quater_neigh_list.arfcn = bts->si_common.data.earfcn_list;</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->si_common.si2quater_neigh_list.meas_bw = bts->si_common.data.meas_bw_list;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->si_common.si2quater_neigh_list.thresh_hi = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->si_common.neigh_list.data = bts->si_common.data.neigh_list;</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->si_common.neigh_list.data_len =</span><br><span style="color: hsl(120, 100%, 40%);">+                               sizeof(bts->si_common.data.neigh_list);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->si_common.si5_neigh_list.data = bts->si_common.data.si5_neigh_list;</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->si_common.si5_neigh_list.data_len =</span><br><span style="color: hsl(120, 100%, 40%);">+                           sizeof(bts->si_common.data.si5_neigh_list);</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->si_common.cell_alloc.data = bts->si_common.data.cell_alloc;</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->si_common.cell_alloc.data_len =</span><br><span style="color: hsl(120, 100%, 40%);">+                               sizeof(bts->si_common.data.cell_alloc);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->si_common.rach_control.re = 1; /* no re-establishment */</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->si_common.rach_control.tx_integer = 9;  /* 12 slots spread - 217/115 slots delay */</span><br><span style="color: hsl(120, 100%, 40%);">+   bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->si_common.rach_control.t2 = 4; /* no emergency calls */</span><br><span style="color: hsl(120, 100%, 40%);">+       bts->si_common.chan_desc.att = 1; /* attachment required */</span><br><span style="color: hsl(120, 100%, 40%);">+        bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->si_common.chan_desc.t3212 = osmo_tdef_get(net->T_defs, 3212, OSMO_TDEF_CUSTOM, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+        gsm_bts_set_radio_link_timeout(bts, 32); /* Use RADIO LINK TIMEOUT of 32 */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&bts->abis_queue);</span><br><span style="color: hsl(120, 100%, 40%);">+     INIT_LLIST_HEAD(&bts->loc_list);</span><br><span style="color: hsl(120, 100%, 40%);">+       INIT_LLIST_HEAD(&bts->local_neighbors);</span><br><span style="color: hsl(120, 100%, 40%);">+        INIT_LLIST_HEAD(&bts->oml_fail_rep);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Enable all codecs by default. These get reset to a more fine grained selection IF a</span><br><span style="color: hsl(120, 100%, 40%);">+         * 'codec-support' config appears in the config file (see bsc_vty.c). */</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->codec = (struct bts_codec_conf){</span><br><span style="color: hsl(120, 100%, 40%);">+              .hr = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+              .efr = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+             .amr = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+     };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Set reasonable defaults for AMR-FR and AMR-HR rate configuration.</span><br><span style="color: hsl(120, 100%, 40%);">+   * (see also 3GPP TS 28.062, Table 7.11.3.1.3-2) */</span><br><span style="color: hsl(120, 100%, 40%);">+   mr_cfg = (struct gsm48_multi_rate_conf) {</span><br><span style="color: hsl(120, 100%, 40%);">+             .m4_75 = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m5_15 = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m5_90 = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m6_70 = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m7_40 = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m7_95 = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m10_2 = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m12_2 = 1</span><br><span style="color: hsl(120, 100%, 40%);">+    };</span><br><span style="color: hsl(120, 100%, 40%);">+    memcpy(bts->mr_full.gsm48_ie, &mr_cfg, sizeof(bts->mr_full.gsm48_ie));</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->mr_full.ms_mode[0].mode = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->mr_full.ms_mode[1].mode = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->mr_full.ms_mode[2].mode = 4;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->mr_full.ms_mode[3].mode = 7;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->mr_full.bts_mode[0].mode = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->mr_full.bts_mode[1].mode = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->mr_full.bts_mode[2].mode = 4;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->mr_full.bts_mode[3].mode = 7;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < 3; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          bts->mr_full.ms_mode[i].hysteresis = 8;</span><br><span style="color: hsl(120, 100%, 40%);">+            bts->mr_full.ms_mode[i].threshold = 32;</span><br><span style="color: hsl(120, 100%, 40%);">+            bts->mr_full.bts_mode[i].hysteresis = 8;</span><br><span style="color: hsl(120, 100%, 40%);">+           bts->mr_full.bts_mode[i].threshold = 32;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->mr_full.num_modes = 4;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      mr_cfg = (struct gsm48_multi_rate_conf) {</span><br><span style="color: hsl(120, 100%, 40%);">+             .m4_75 = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m5_15 = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m5_90 = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m6_70 = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m7_40 = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m7_95 = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m10_2 = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+           .m12_2 = 0</span><br><span style="color: hsl(120, 100%, 40%);">+    };</span><br><span style="color: hsl(120, 100%, 40%);">+    memcpy(bts->mr_half.gsm48_ie, &mr_cfg, sizeof(bts->mr_half.gsm48_ie));</span><br><span style="color: hsl(120, 100%, 40%);">+      bts->mr_half.ms_mode[0].mode = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->mr_half.ms_mode[1].mode = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->mr_half.ms_mode[2].mode = 4;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->mr_half.ms_mode[3].mode = 7;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->mr_half.bts_mode[0].mode = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->mr_half.bts_mode[1].mode = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->mr_half.bts_mode[2].mode = 4;</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->mr_half.bts_mode[3].mode = 7;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < 3; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          bts->mr_half.ms_mode[i].hysteresis = 8;</span><br><span style="color: hsl(120, 100%, 40%);">+            bts->mr_half.ms_mode[i].threshold = 32;</span><br><span style="color: hsl(120, 100%, 40%);">+            bts->mr_half.bts_mode[i].hysteresis = 8;</span><br><span style="color: hsl(120, 100%, 40%);">+           bts->mr_half.bts_mode[i].threshold = 32;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->mr_half.num_modes = 3;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bts_init_cbch_state(&bts->cbch_basic, bts);</span><br><span style="color: hsl(120, 100%, 40%);">+    bts_init_cbch_state(&bts->cbch_extended, bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return bts;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static char ts2str[255];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+char *gsm_bts_name(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!bts)</span><br><span style="color: hsl(120, 100%, 40%);">+             snprintf(ts2str, sizeof(ts2str), "(bts=NULL)");</span><br><span style="color: hsl(120, 100%, 40%);">+     else</span><br><span style="color: hsl(120, 100%, 40%);">+          snprintf(ts2str, sizeof(ts2str), "(bts=%d)", bts->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return ts2str;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool gsm_bts_matches_lai(const struct gsm_bts *bts, const struct osmo_location_area_id *lai)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  return osmo_plmn_cmp(&lai->plmn, &bts->network->plmn) == 0</span><br><span style="color: hsl(120, 100%, 40%);">+           && lai->lac == bts->location_area_code;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool gsm_bts_matches_cell_id(const struct gsm_bts *bts, const struct gsm0808_cell_id *cell_id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const union gsm0808_cell_id_u *id = &cell_id->id;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts || !cell_id)</span><br><span style="color: hsl(120, 100%, 40%);">+         return false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (cell_id->id_discr) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case CELL_IDENT_WHOLE_GLOBAL:</span><br><span style="color: hsl(120, 100%, 40%);">+         return gsm_bts_matches_lai(bts, &id->global.lai)</span><br><span style="color: hsl(120, 100%, 40%);">+                       && id->global.cell_identity == bts->cell_identity;</span><br><span style="color: hsl(120, 100%, 40%);">+      case CELL_IDENT_LAC_AND_CI:</span><br><span style="color: hsl(120, 100%, 40%);">+           return id->lac_and_ci.lac == bts->location_area_code</span><br><span style="color: hsl(120, 100%, 40%);">+                    && id->lac_and_ci.ci == bts->cell_identity;</span><br><span style="color: hsl(120, 100%, 40%);">+     case CELL_IDENT_CI:</span><br><span style="color: hsl(120, 100%, 40%);">+           return id->ci == bts->cell_identity;</span><br><span style="color: hsl(120, 100%, 40%);">+    case CELL_IDENT_NO_CELL:</span><br><span style="color: hsl(120, 100%, 40%);">+              return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ case CELL_IDENT_LAI_AND_LAC:</span><br><span style="color: hsl(120, 100%, 40%);">+          return gsm_bts_matches_lai(bts, &id->lai_and_lac);</span><br><span style="color: hsl(120, 100%, 40%);">+     case CELL_IDENT_LAC:</span><br><span style="color: hsl(120, 100%, 40%);">+          return id->lac == bts->location_area_code;</span><br><span style="color: hsl(120, 100%, 40%);">+      case CELL_IDENT_BSS:</span><br><span style="color: hsl(120, 100%, 40%);">+          return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  case CELL_IDENT_UTRAN_PLMN_LAC_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+   case CELL_IDENT_UTRAN_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+    case CELL_IDENT_UTRAN_LAC_RNC:</span><br><span style="color: hsl(120, 100%, 40%);">+                return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct gsm_bts_ref *gsm_bts_ref_find(const struct llist_head *list, const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_bts_ref *ref;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts)</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  llist_for_each_entry(ref, list, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (ref->bts == bts)</span><br><span style="color: hsl(120, 100%, 40%);">+                       return ref;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Add a BTS reference to the local_neighbors list.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Return 1 if added, 0 if such an entry already existed, and negative on errors. */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_bts_local_neighbor_add(struct gsm_bts *bts, struct gsm_bts *neighbor)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm_bts_ref *ref;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts || !neighbor)</span><br><span style="color: hsl(120, 100%, 40%);">+                return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (bts == neighbor)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Already got this entry? */</span><br><span style="color: hsl(120, 100%, 40%);">+ ref = gsm_bts_ref_find(&bts->local_neighbors, neighbor);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ref)</span><br><span style="color: hsl(120, 100%, 40%);">+              return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ref = talloc_zero(bts, struct gsm_bts_ref);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!ref)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+       ref->bts = neighbor;</span><br><span style="color: hsl(120, 100%, 40%);">+       llist_add_tail(&ref->entry, &bts->local_neighbors);</span><br><span style="color: hsl(120, 100%, 40%);">+     return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Remove a BTS reference from the local_neighbors list.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Return 1 if removed, 0 if no such entry existed, and negative on errors. */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_bts_local_neighbor_del(struct gsm_bts *bts, const struct gsm_bts *neighbor)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_bts_ref *ref;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bts || !neighbor)</span><br><span style="color: hsl(120, 100%, 40%);">+                return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ref = gsm_bts_ref_find(&bts->local_neighbors, neighbor);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!ref)</span><br><span style="color: hsl(120, 100%, 40%);">+             return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   llist_del(&ref->entry);</span><br><span style="color: hsl(120, 100%, 40%);">+        talloc_free(ref);</span><br><span style="color: hsl(120, 100%, 40%);">+     return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* return the gsm_lchan for the CBCH (if it exists at all) */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gsm_lchan *lchan = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_bts_trx *trx = bts->c0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (trx->ts[0].pchan_from_config == GSM_PCHAN_CCCH_SDCCH4_CBCH)</span><br><span style="color: hsl(120, 100%, 40%);">+            lchan = &trx->ts[0].lchan[2];</span><br><span style="color: hsl(120, 100%, 40%);">+  else {</span><br><span style="color: hsl(120, 100%, 40%);">+                int i;</span><br><span style="color: hsl(120, 100%, 40%);">+                for (i = 0; i < 8; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (trx->ts[i].pchan_from_config == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               lchan = &trx->ts[i].lchan[2];</span><br><span style="color: hsl(120, 100%, 40%);">+                          break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_bts_model *model;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        model = bts_model_find(type);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!model)</span><br><span style="color: hsl(120, 100%, 40%);">+           return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     bts->type = type;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts->model = model;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (model->start && !model->started) {</span><br><span style="color: hsl(120, 100%, 40%);">+          int ret = model->start(bts->network);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ret < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                       return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         model->started = true;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (bts->type) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BTS_TYPE_NANOBTS:</span><br><span style="color: hsl(120, 100%, 40%);">+    case GSM_BTS_TYPE_OSMOBTS:</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Set the default OML Stream ID to 0xff */</span><br><span style="color: hsl(120, 100%, 40%);">+           bts->oml_tei = 0xff;</span><br><span style="color: hsl(120, 100%, 40%);">+               bts->c0->nominal_power = 23;</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM_BTS_TYPE_RBS2000:</span><br><span style="color: hsl(120, 100%, 40%);">+            INIT_LLIST_HEAD(&bts->rbs2000.is.conn_groups);</span><br><span style="color: hsl(120, 100%, 40%);">+         INIT_LLIST_HEAD(&bts->rbs2000.con.conn_groups);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM_BTS_TYPE_BS11:</span><br><span style="color: hsl(120, 100%, 40%);">+       case GSM_BTS_TYPE_UNKNOWN:</span><br><span style="color: hsl(120, 100%, 40%);">+    case GSM_BTS_TYPE_NOKIA_SITE:</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Set default BTS reset timer */</span><br><span style="color: hsl(120, 100%, 40%);">+             bts->nokia.bts_reset_timer_cnf = 15;</span><br><span style="color: hsl(120, 100%, 40%);">+       case _NUM_GSM_BTS_TYPE:</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (mode != BTS_GPRS_NONE &&</span><br><span style="color: hsl(120, 100%, 40%);">+      !osmo_bts_has_feature(&bts->model->features, BTS_FEAT_GPRS)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (mode == BTS_GPRS_EGPRS &&</span><br><span style="color: hsl(120, 100%, 40%);">+     !osmo_bts_has_feature(&bts->model->features, BTS_FEAT_EGPRS)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_bts_trx *trx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    llist_for_each_entry(trx, &bts->trx_list, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (trx->nr == nr)</span><br><span style="color: hsl(120, 100%, 40%);">+                 return trx;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+unsigned long long bts_uptime(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct timespec tp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!bts->uptime || !bts->oml_link) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DNM, LOGL_ERROR, "BTS %u OML link uptime unavailable\n", bts->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+          return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DNM, LOGL_ERROR, "BTS %u uptime computation failure: %s\n", bts->nr, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+              return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* monotonic clock helps to ensure that the conversion is valid */</span><br><span style="color: hsl(120, 100%, 40%);">+    return difftime(tp.tv_sec, bts->uptime);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+char *get_model_oml_status(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if (bts->model->oml_status)</span><br><span style="color: hsl(120, 100%, 40%);">+             return bts->model->oml_status(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return "unknown";</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* reset the state of all MO in the BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_bts_mo_reset(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_bts_trx *trx;</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     gsm_abis_mo_reset(&bts->mo);</span><br><span style="color: hsl(120, 100%, 40%);">+   gsm_abis_mo_reset(&bts->site_mgr.mo);</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++)</span><br><span style="color: hsl(120, 100%, 40%);">+                gsm_abis_mo_reset(&bts->gprs.nsvc[i].mo);</span><br><span style="color: hsl(120, 100%, 40%);">+      gsm_abis_mo_reset(&bts->gprs.nse.mo);</span><br><span style="color: hsl(120, 100%, 40%);">+  gsm_abis_mo_reset(&bts->gprs.cell.mo);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       llist_for_each_entry(trx, &bts->trx_list, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+              gsm_abis_mo_reset(&trx->mo);</span><br><span style="color: hsl(120, 100%, 40%);">+           gsm_abis_mo_reset(&trx->bb_transc.mo);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct gsm_bts_trx_ts *ts = &trx->ts[i];</span><br><span style="color: hsl(120, 100%, 40%);">+                       gsm_abis_mo_reset(&ts->mo);</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Assume there are only 256 possible bts */</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_static_assert(sizeof(((struct gsm_bts *) 0)->nr) == 1, _bts_nr_is_256);</span><br><span style="color: hsl(120, 100%, 40%);">+static void depends_calc_index_bit(int bts_nr, int *idx, int *bit)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  *idx = bts_nr / (8 * 4);</span><br><span style="color: hsl(120, 100%, 40%);">+      *bit = bts_nr % (8 * 4);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_depend_mark(struct gsm_bts *bts, int dep)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  int idx, bit;</span><br><span style="color: hsl(120, 100%, 40%);">+ depends_calc_index_bit(dep, &idx, &bit);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->depends_on[idx] |= 1 << bit;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void bts_depend_clear(struct gsm_bts *bts, int dep)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int idx, bit;</span><br><span style="color: hsl(120, 100%, 40%);">+ depends_calc_index_bit(dep, &idx, &bit);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    bts->depends_on[idx] &= ~(1 << bit);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int idx, bit;</span><br><span style="color: hsl(120, 100%, 40%);">+ depends_calc_index_bit(other->nr, &idx, &bit);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Check if there is a depends bit */</span><br><span style="color: hsl(120, 100%, 40%);">+ return (base->depends_on[idx] & (1 << bit)) > 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int bts_is_online(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       /* TODO: support E1 BTS too */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!is_ipaccess_bts(bts))</span><br><span style="color: hsl(120, 100%, 40%);">+            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!bts->oml_link)</span><br><span style="color: hsl(120, 100%, 40%);">+                return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_depend_check(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_bts *other_bts;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  llist_for_each_entry(other_bts, &bts->network->bts_list, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!bts_depend_is_depedency(bts, other_bts))</span><br><span style="color: hsl(120, 100%, 40%);">+                 continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (bts_is_online(other_bts))</span><br><span style="color: hsl(120, 100%, 40%);">+                 continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* get the radio link timeout (based on SACCH decode errors, according</span><br><span style="color: hsl(120, 100%, 40%);">+ * to algorithm specified in TS 05.08 section 5.2.  A value of -1</span><br><span style="color: hsl(120, 100%, 40%);">+ * indicates we should use an infinitely long timeout, which only works</span><br><span style="color: hsl(120, 100%, 40%);">+ * with OsmoBTS as the BTS implementation */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    const struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (bts->infinite_radio_link_timeout)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    else {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Encoding as per Table 10.5.21 of TS 04.08 */</span><br><span style="color: hsl(120, 100%, 40%);">+               return (cell_options->radio_link_timeout + 1) << 2;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* set the radio link timeout (based on SACCH decode errors, according</span><br><span style="color: hsl(120, 100%, 40%);">+ * to algorithm specified in TS 05.08 Section 5.2.  A value of -1</span><br><span style="color: hsl(120, 100%, 40%);">+ * indicates we should use an infinitely long timeout, which only works</span><br><span style="color: hsl(120, 100%, 40%);">+ * with OsmoBTS as the BTS implementation */</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (value < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+             bts->infinite_radio_link_timeout = true;</span><br><span style="color: hsl(120, 100%, 40%);">+   else {</span><br><span style="color: hsl(120, 100%, 40%);">+                bts->infinite_radio_link_timeout = false;</span><br><span style="color: hsl(120, 100%, 40%);">+          /* Encoding as per Table 10.5.21 of TS 04.08 */</span><br><span style="color: hsl(120, 100%, 40%);">+               if (value < 4)</span><br><span style="color: hsl(120, 100%, 40%);">+                     value = 4;</span><br><span style="color: hsl(120, 100%, 40%);">+            if (value > 64)</span><br><span style="color: hsl(120, 100%, 40%);">+                    value = 64;</span><br><span style="color: hsl(120, 100%, 40%);">+           cell_options->radio_link_timeout = (value >> 2) - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_bts_trx *trx;</span><br><span style="color: hsl(120, 100%, 40%);">+      llist_for_each_entry(trx, &bts->trx_list, list)</span><br><span style="color: hsl(120, 100%, 40%);">+                gsm_trx_all_ts_dispatch(trx, ts_ev, data);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Count number of free TS of given pchan type */</span><br><span style="color: hsl(120, 100%, 40%);">+int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm_bts_trx *trx;</span><br><span style="color: hsl(120, 100%, 40%);">+      int count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      llist_for_each_entry(trx, &bts->trx_list, list)</span><br><span style="color: hsl(120, 100%, 40%);">+                count += trx_count_free_ts(trx, pchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return count;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/osmo-bsc/bts_ericsson_rbs2000.c b/src/osmo-bsc/bts_ericsson_rbs2000.c</span><br><span>index 02ef463..1297b30 100644</span><br><span>--- a/src/osmo-bsc/bts_ericsson_rbs2000.c</span><br><span>+++ b/src/osmo-bsc/bts_ericsson_rbs2000.c</span><br><span>@@ -29,6 +29,7 @@</span><br><span> #include <osmocom/abis/e1_input.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/abis/lapd.h></span><br><span> </span><br><span>diff --git a/src/osmo-bsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c</span><br><span>index 5b60367..49720e5 100644</span><br><span>--- a/src/osmo-bsc/bts_ipaccess_nanobts.c</span><br><span>+++ b/src/osmo-bsc/bts_ipaccess_nanobts.c</span><br><span>@@ -45,6 +45,7 @@</span><br><span> #include <osmocom/bsc/bts_ipaccess_nanobts_omlattr.h></span><br><span> #include <osmocom/bsc/paging.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> static int bts_model_nanobts_start(struct gsm_network *net);</span><br><span> static void bts_model_nanobts_e1line_bind_ops(struct e1inp_line *line);</span><br><span>diff --git a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c</span><br><span>index be823ae..b979cc7 100644</span><br><span>--- a/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c</span><br><span>+++ b/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c</span><br><span>@@ -23,7 +23,7 @@</span><br><span> #include <osmocom/core/msgb.h></span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span> #include <osmocom/bsc/abis_nm.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> struct msgb *nanobts_attr_bts_get(struct gsm_bts *bts)</span><br><span> {</span><br><span>diff --git a/src/osmo-bsc/bts_nokia_site.c b/src/osmo-bsc/bts_nokia_site.c</span><br><span>index 523c9ed..2b6f918 100644</span><br><span>--- a/src/osmo-bsc/bts_nokia_site.c</span><br><span>+++ b/src/osmo-bsc/bts_nokia_site.c</span><br><span>@@ -37,6 +37,7 @@</span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> #include <osmocom/bsc/system_information.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/core/timer.h></span><br><span> </span><br><span>diff --git a/src/osmo-bsc/bts_siemens_bs11.c b/src/osmo-bsc/bts_siemens_bs11.c</span><br><span>index 057a0e1..c808421 100644</span><br><span>--- a/src/osmo-bsc/bts_siemens_bs11.c</span><br><span>+++ b/src/osmo-bsc/bts_siemens_bs11.c</span><br><span>@@ -30,6 +30,7 @@</span><br><span> #include <osmocom/abis/e1_input.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> static int bts_model_bs11_start(struct gsm_network *net);</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/bts_sysmobts.c b/src/osmo-bsc/bts_sysmobts.c</span><br><span>index 6f9dc77..df43d76 100644</span><br><span>--- a/src/osmo-bsc/bts_sysmobts.c</span><br><span>+++ b/src/osmo-bsc/bts_sysmobts.c</span><br><span>@@ -26,6 +26,7 @@</span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/abis_nm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/abis/e1_input.h></span><br><span> #include <osmocom/gsm/tlv.h></span><br><span> #include <osmocom/core/msgb.h></span><br><span>diff --git a/src/osmo-bsc/bts_unknown.c b/src/osmo-bsc/bts_unknown.c</span><br><span>index b6b56a8..b5471ce 100644</span><br><span>--- a/src/osmo-bsc/bts_unknown.c</span><br><span>+++ b/src/osmo-bsc/bts_unknown.c</span><br><span>@@ -21,6 +21,7 @@</span><br><span> </span><br><span> </span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/gsm/tlv.h></span><br><span> #include <osmocom/bsc/abis_nm.h></span><br><span> </span><br><span>diff --git a/src/osmo-bsc/cbch_scheduler.c b/src/osmo-bsc/cbch_scheduler.c</span><br><span>index ef93b7a..8021804 100644</span><br><span>--- a/src/osmo-bsc/cbch_scheduler.c</span><br><span>+++ b/src/osmo-bsc/cbch_scheduler.c</span><br><span>@@ -28,6 +28,7 @@</span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span> #include <osmocom/bsc/smscb.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> /* add all pages of given SMSCB so they appear as soon as possible *after* (included) base_idx. */</span><br><span> static int bts_smscb_sched_add_after(struct bts_smscb_page **sched_arr, int sched_arr_size,</span><br><span>diff --git a/src/osmo-bsc/chan_alloc.c b/src/osmo-bsc/chan_alloc.c</span><br><span>index 9b80df3..6829251 100644</span><br><span>--- a/src/osmo-bsc/chan_alloc.c</span><br><span>+++ b/src/osmo-bsc/chan_alloc.c</span><br><span>@@ -34,6 +34,7 @@</span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span> </span><br><span>diff --git a/src/osmo-bsc/codec_pref.c b/src/osmo-bsc/codec_pref.c</span><br><span>index 6ec6d05..58a7867 100644</span><br><span>--- a/src/osmo-bsc/codec_pref.c</span><br><span>+++ b/src/osmo-bsc/codec_pref.c</span><br><span>@@ -27,6 +27,7 @@</span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span> #include <osmocom/bsc/codec_pref.h></span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> /* Determine whether a permitted speech value is specifies a half rate or full</span><br><span>  * rate codec */</span><br><span>diff --git a/src/osmo-bsc/e1_config.c b/src/osmo-bsc/e1_config.c</span><br><span>index 4389f66..9ccbbfd 100644</span><br><span>--- a/src/osmo-bsc/e1_config.c</span><br><span>+++ b/src/osmo-bsc/e1_config.c</span><br><span>@@ -30,6 +30,7 @@</span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #define SAPI_L2ML   0</span><br><span> #define SAPI_OML   62</span><br><span>diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c</span><br><span>index 07978de..e54a937 100644</span><br><span>--- a/src/osmo-bsc/gsm_04_08_rr.c</span><br><span>+++ b/src/osmo-bsc/gsm_04_08_rr.c</span><br><span>@@ -44,6 +44,7 @@</span><br><span> #include <osmocom/bsc/gsm_08_08.h></span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span> #include <osmocom/bsc/system_information.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> </span><br><span> int gsm48_sendmsg(struct msgb *msg)</span><br><span>diff --git a/src/osmo-bsc/gsm_08_08.c b/src/osmo-bsc/gsm_08_08.c</span><br><span>index 2829b67..d5915f4 100644</span><br><span>--- a/src/osmo-bsc/gsm_08_08.c</span><br><span>+++ b/src/osmo-bsc/gsm_08_08.c</span><br><span>@@ -36,6 +36,7 @@</span><br><span> #include <osmocom/gsm/gsm23236.h></span><br><span> </span><br><span> #include <osmocom/bsc/osmo_bsc_sigtran.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #define LOG_COMPL_L3(pdisc, mtype, loglevel, format, args...) \</span><br><span>         LOGP(DRSL, loglevel, "%s %s: " format, gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, mtype), ##args)</span><br><span>diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c</span><br><span>index a4f6b7f..1295592 100644</span><br><span>--- a/src/osmo-bsc/gsm_data.c</span><br><span>+++ b/src/osmo-bsc/gsm_data.c</span><br><span>@@ -44,11 +44,10 @@</span><br><span> #include <osmocom/bsc/handover_cfg.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> void *tall_bsc_ctx = NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static LLIST_HEAD(bts_models);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,</span><br><span>              uint8_t e1_ts, uint8_t e1_ts_ss)</span><br><span> {</span><br><span>@@ -57,49 +56,6 @@</span><br><span>        ts->e1_link.e1_ts_ss = e1_ts_ss;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct gsm_bts_model *bts_model_find(enum gsm_bts_type type)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gsm_bts_model *model;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    llist_for_each_entry(model, &bts_models, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (model->type == type)</span><br><span style="color: hsl(0, 100%, 40%);">-                     return model;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_bts_model_register(struct gsm_bts_model *model)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   if (bts_model_find(model->type))</span><br><span style="color: hsl(0, 100%, 40%);">-             return -EEXIST;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- tlv_def_patch(&model->nm_att_tlvdef, &abis_nm_att_tlvdef);</span><br><span style="color: hsl(0, 100%, 40%);">-   llist_add_tail(&model->list, &bts_models);</span><br><span style="color: hsl(0, 100%, 40%);">-   return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = {</span><br><span style="color: hsl(0, 100%, 40%);">-     { GSM_BTS_TYPE_UNKNOWN,         "Unknown BTS Type" },</span><br><span style="color: hsl(0, 100%, 40%);">- { GSM_BTS_TYPE_BS11,            "Siemens BTS (BS-11 or compatible)" },</span><br><span style="color: hsl(0, 100%, 40%);">-        { GSM_BTS_TYPE_NANOBTS,         "ip.access nanoBTS or compatible" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { GSM_BTS_TYPE_RBS2000,         "Ericsson RBS2000 Series" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { GSM_BTS_TYPE_NOKIA_SITE,      "Nokia {Metro,Ultra,In}Site" },</span><br><span style="color: hsl(0, 100%, 40%);">-       { GSM_BTS_TYPE_OSMOBTS,         "sysmocom sysmoBTS" },</span><br><span style="color: hsl(0, 100%, 40%);">-        { 0,                            NULL }</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gsm_bts_trx *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        llist_for_each_entry(trx, &bts->trx_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-                if (trx->nr == nr)</span><br><span style="color: hsl(0, 100%, 40%);">-                   return trx;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Search for a BTS in the given Location Area; optionally start searching</span><br><span>  * with start_bts (for continuing to search after the first result) */</span><br><span> struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,</span><br><span>@@ -149,62 +105,6 @@</span><br><span>    return get_value_string(bts_gprs_mode_names, mode);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  if (mode != BTS_GPRS_NONE &&</span><br><span style="color: hsl(0, 100%, 40%);">-        !osmo_bts_has_feature(&bts->model->features, BTS_FEAT_GPRS)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (mode == BTS_GPRS_EGPRS &&</span><br><span style="color: hsl(0, 100%, 40%);">-       !osmo_bts_has_feature(&bts->model->features, BTS_FEAT_EGPRS)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gsm_bts_model *model;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    model = bts_model_find(type);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!model)</span><br><span style="color: hsl(0, 100%, 40%);">-             return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- bts->type = type;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->model = model;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (model->start && !model->started) {</span><br><span style="color: hsl(0, 100%, 40%);">-            int ret = model->start(bts->network);</span><br><span style="color: hsl(0, 100%, 40%);">-             if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                 return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             model->started = true;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (bts->type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_BTS_TYPE_NANOBTS:</span><br><span style="color: hsl(0, 100%, 40%);">-      case GSM_BTS_TYPE_OSMOBTS:</span><br><span style="color: hsl(0, 100%, 40%);">-              /* Set the default OML Stream ID to 0xff */</span><br><span style="color: hsl(0, 100%, 40%);">-             bts->oml_tei = 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-         bts->c0->nominal_power = 23;</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case GSM_BTS_TYPE_RBS2000:</span><br><span style="color: hsl(0, 100%, 40%);">-              INIT_LLIST_HEAD(&bts->rbs2000.is.conn_groups);</span><br><span style="color: hsl(0, 100%, 40%);">-           INIT_LLIST_HEAD(&bts->rbs2000.con.conn_groups);</span><br><span style="color: hsl(0, 100%, 40%);">-          break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case GSM_BTS_TYPE_BS11:</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_BTS_TYPE_UNKNOWN:</span><br><span style="color: hsl(0, 100%, 40%);">-      case GSM_BTS_TYPE_NOKIA_SITE:</span><br><span style="color: hsl(0, 100%, 40%);">-           /* Set default BTS reset timer */</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->nokia.bts_reset_timer_cnf = 15;</span><br><span style="color: hsl(0, 100%, 40%);">- case _NUM_GSM_BTS_TYPE:</span><br><span style="color: hsl(0, 100%, 40%);">-         break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type,</span><br><span>                                        uint8_t bsic)</span><br><span> {</span><br><span>@@ -248,166 +148,14 @@</span><br><span>  gsm48_encode_ra(buf, &raid);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Assume there are only 256 possible bts */</span><br><span style="color: hsl(0, 100%, 40%);">-osmo_static_assert(sizeof(((struct gsm_bts *) 0)->nr) == 1, _bts_nr_is_256);</span><br><span style="color: hsl(0, 100%, 40%);">-static void depends_calc_index_bit(int bts_nr, int *idx, int *bit)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- *idx = bts_nr / (8 * 4);</span><br><span style="color: hsl(0, 100%, 40%);">-        *bit = bts_nr % (8 * 4);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void bts_depend_mark(struct gsm_bts *bts, int dep)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    int idx, bit;</span><br><span style="color: hsl(0, 100%, 40%);">-   depends_calc_index_bit(dep, &idx, &bit);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->depends_on[idx] |= 1 << bit;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void bts_depend_clear(struct gsm_bts *bts, int dep)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int idx, bit;</span><br><span style="color: hsl(0, 100%, 40%);">-   depends_calc_index_bit(dep, &idx, &bit);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->depends_on[idx] &= ~(1 << bit);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     int idx, bit;</span><br><span style="color: hsl(0, 100%, 40%);">-   depends_calc_index_bit(other->nr, &idx, &bit);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Check if there is a depends bit */</span><br><span style="color: hsl(0, 100%, 40%);">-   return (base->depends_on[idx] & (1 << bit)) > 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int bts_is_online(struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- /* TODO: support E1 BTS too */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!is_ipaccess_bts(bts))</span><br><span style="color: hsl(0, 100%, 40%);">-              return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!bts->oml_link)</span><br><span style="color: hsl(0, 100%, 40%);">-          return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int bts_depend_check(struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gsm_bts *other_bts;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      llist_for_each_entry(other_bts, &bts->network->bts_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-              if (!bts_depend_is_depedency(bts, other_bts))</span><br><span style="color: hsl(0, 100%, 40%);">-                   continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               if (bts_is_online(other_bts))</span><br><span style="color: hsl(0, 100%, 40%);">-                   continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* get the radio link timeout (based on SACCH decode errors, according</span><br><span style="color: hsl(0, 100%, 40%);">- * to algorithm specified in TS 05.08 section 5.2.  A value of -1</span><br><span style="color: hsl(0, 100%, 40%);">- * indicates we should use an infinitely long timeout, which only works</span><br><span style="color: hsl(0, 100%, 40%);">- * with OsmoBTS as the BTS implementation */</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      const struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (bts->infinite_radio_link_timeout)</span><br><span style="color: hsl(0, 100%, 40%);">-                return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      else {</span><br><span style="color: hsl(0, 100%, 40%);">-          /* Encoding as per Table 10.5.21 of TS 04.08 */</span><br><span style="color: hsl(0, 100%, 40%);">-         return (cell_options->radio_link_timeout + 1) << 2;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* set the radio link timeout (based on SACCH decode errors, according</span><br><span style="color: hsl(0, 100%, 40%);">- * to algorithm specified in TS 05.08 Section 5.2.  A value of -1</span><br><span style="color: hsl(0, 100%, 40%);">- * indicates we should use an infinitely long timeout, which only works</span><br><span style="color: hsl(0, 100%, 40%);">- * with OsmoBTS as the BTS implementation */</span><br><span style="color: hsl(0, 100%, 40%);">-void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (value < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->infinite_radio_link_timeout = true;</span><br><span style="color: hsl(0, 100%, 40%);">-     else {</span><br><span style="color: hsl(0, 100%, 40%);">-          bts->infinite_radio_link_timeout = false;</span><br><span style="color: hsl(0, 100%, 40%);">-            /* Encoding as per Table 10.5.21 of TS 04.08 */</span><br><span style="color: hsl(0, 100%, 40%);">-         if (value < 4)</span><br><span style="color: hsl(0, 100%, 40%);">-                       value = 4;</span><br><span style="color: hsl(0, 100%, 40%);">-              if (value > 64)</span><br><span style="color: hsl(0, 100%, 40%);">-                      value = 64;</span><br><span style="color: hsl(0, 100%, 40%);">-             cell_options->radio_link_timeout = (value >> 2) - 1;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const struct osmo_stat_item_desc bts_stat_desc[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-   [BTS_STAT_CHAN_LOAD_AVERAGE] =                  { "chanloadavg", "Channel load average", "%", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_STAT_CHAN_CCCH_SDCCH4_USED] =              { "chan_ccch_sdcch4:used",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                      "Number of CCCH+SDCCH4 channels used", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-       [BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL] =             { "chan_ccch_sdcch4:total",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                     "Number of CCCH+SDCCH4 channels total", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-      [BTS_STAT_CHAN_TCH_F_USED] =                    { "chan_tch_f:used",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                    "Number of TCH/F channels used", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-     [BTS_STAT_CHAN_TCH_F_TOTAL] =                   { "chan_tch_f:total",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                   "Number of TCH/F channels total", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_STAT_CHAN_TCH_H_USED] =                    { "chan_tch_h:used",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                    "Number of TCH/H channels used", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-     [BTS_STAT_CHAN_TCH_H_TOTAL] =                   { "chan_tch_h:total",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                   "Number of TCH/H channels total", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_STAT_CHAN_SDCCH8_USED] =                   { "chan_sdcch8:used",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                   "Number of SDCCH8 channels used", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_STAT_CHAN_SDCCH8_TOTAL] =                  { "chan_sdcch8:total",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                          "Number of SDCCH8 channels total", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-   [BTS_STAT_CHAN_TCH_F_PDCH_USED] =               { "chan_tch_f_pdch:used",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                       "Number of TCH/F_PDCH channels used", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-        [BTS_STAT_CHAN_TCH_F_PDCH_TOTAL] =              { "chan_tch_f_pdch:total",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                      "Number of TCH/F_PDCH channels total", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-       [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED] =         { "chan_ccch_sdcch4_cbch:used",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                         "Number of CCCH+SDCCH4+CBCH channels used", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL] =        { "chan_ccch_sdcch4_cbch:total",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                        "Number of CCCH+SDCCH4+CBCH channels total", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">- [BTS_STAT_CHAN_SDCCH8_CBCH_USED] =              { "chan_sdcch8_cbch:used",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                      "Number of SDCCH8+CBCH channels used", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-       [BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL] =             { "chan_sdcch8_cbch:total",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                     "Number of SDCCH8+CBCH channels total", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-      [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED] =         { "chan_tch_f_tch_h_pdch:used",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                         "Number of TCH/F_TCH/H_PDCH channels used", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL] =        { "chan_tch_f_tch_h_pdch:total",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                        "Number of TCH/F_TCH/H_PDCH channels total", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">- [BTS_STAT_T3122] =                              { "T3122", "T3122 IMMEDIATE ASSIGNMENT REJECT wait indicator",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                        "s", 16, GSM_T3122_DEFAULT },</span><br><span style="color: hsl(0, 100%, 40%);">-       [BTS_STAT_RACH_BUSY] =                          { "rach_busy",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                          "RACH slots with signal above threshold", "%", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-   [BTS_STAT_RACH_ACCESS] =                        { "rach_access",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                        "RACH slots with access bursts in them", "%", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-    [BTS_STAT_OML_CONNECTED] =                      { "oml_connected", "Number of OML links connected", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_STAT_RSL_CONNECTED] =                      { "rsl_connected", "Number of RSL links connected", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-  [BTS_STAT_LCHAN_BORKEN] =                       { "lchan_borken",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                       "Number of lchans in the BORKEN state", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-      [BTS_STAT_TS_BORKEN] =                          { "ts_borken",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                          "Number of timeslots in the BORKEN state", "", 16, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const struct osmo_stat_item_group_desc bts_statg_desc = {</span><br><span style="color: hsl(0, 100%, 40%);">- .group_name_prefix = "bts",</span><br><span style="color: hsl(0, 100%, 40%);">-   .group_description = "base transceiver station",</span><br><span style="color: hsl(0, 100%, 40%);">-      .class_id = OSMO_STATS_CLASS_GLOBAL,</span><br><span style="color: hsl(0, 100%, 40%);">-    .num_items = ARRAY_SIZE(bts_stat_desc),</span><br><span style="color: hsl(0, 100%, 40%);">- .item_desc = bts_stat_desc,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> void gsm_abis_mo_reset(struct gsm_abis_mo *mo)</span><br><span> {</span><br><span>         mo->nm_state.operational = NM_OPSTATE_NULL;</span><br><span>       mo->nm_state.availability = NM_AVSTATE_POWER_OFF;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,</span><br><span style="color: hsl(0, 100%, 40%);">-                       uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3)</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3)</span><br><span> {</span><br><span>         mo->bts = bts;</span><br><span>    mo->obj_class = obj_class;</span><br><span>@@ -417,62 +165,6 @@</span><br><span>         gsm_abis_mo_reset(mo);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-const struct value_string bts_attribute_names[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_VALUE_STRING(BTS_TYPE_VARIANT),</span><br><span style="color: hsl(0, 100%, 40%);">-    OSMO_VALUE_STRING(BTS_SUB_MODEL),</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_VALUE_STRING(TRX_PHY_VERSION),</span><br><span style="color: hsl(0, 100%, 40%);">-     { 0, NULL }</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum bts_attribute str2btsattr(const char *s)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     return get_string_value(bts_attribute_names, s);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const char *btsatttr2str(enum bts_attribute v)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        return get_value_string(bts_attribute_names, v);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {</span><br><span style="color: hsl(0, 100%, 40%);">-     { BTS_UNKNOWN,          "unknown" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { BTS_OSMO_LITECELL15,  "osmo-bts-lc15" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { BTS_OSMO_OCTPHY,      "osmo-bts-octphy" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { BTS_OSMO_SYSMO,       "osmo-bts-sysmo" },</span><br><span style="color: hsl(0, 100%, 40%);">-   { BTS_OSMO_TRX,         "omso-bts-trx" },</span><br><span style="color: hsl(0, 100%, 40%);">-     { 0, NULL }</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum gsm_bts_type_variant str2btsvariant(const char *arg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return get_string_value(osmo_bts_variant_names, arg);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const char *btsvariant2str(enum gsm_bts_type_variant v)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return get_value_string(osmo_bts_variant_names, v);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = {</span><br><span style="color: hsl(0, 100%, 40%);">- { GSM_BTS_TYPE_UNKNOWN,         "unknown" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { GSM_BTS_TYPE_BS11,            "bs11" },</span><br><span style="color: hsl(0, 100%, 40%);">-     { GSM_BTS_TYPE_NANOBTS,         "nanobts" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { GSM_BTS_TYPE_RBS2000,         "rbs2000" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { GSM_BTS_TYPE_NOKIA_SITE,      "nokia_site" },</span><br><span style="color: hsl(0, 100%, 40%);">-       { GSM_BTS_TYPE_OSMOBTS,         "sysmobts" },</span><br><span style="color: hsl(0, 100%, 40%);">- { 0, NULL }</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum gsm_bts_type str2btstype(const char *arg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    return get_string_value(bts_type_names, arg);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const char *btstype2str(enum gsm_bts_type type)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return get_value_string(bts_type_names, type);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> const struct value_string gsm_chreq_descs[] = {</span><br><span>   { GSM_CHREQ_REASON_EMERG,       "emergency call" },</span><br><span>        { GSM_CHREQ_REASON_PAG,         "answer to paging" },</span><br><span>@@ -577,44 +269,6 @@</span><br><span>       return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-bool gsm_bts_matches_lai(const struct gsm_bts *bts, const struct osmo_location_area_id *lai)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      return osmo_plmn_cmp(&lai->plmn, &bts->network->plmn) == 0</span><br><span style="color: hsl(0, 100%, 40%);">-             && lai->lac == bts->location_area_code;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-bool gsm_bts_matches_cell_id(const struct gsm_bts *bts, const struct gsm0808_cell_id *cell_id)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   const union gsm0808_cell_id_u *id = &cell_id->id;</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!bts || !cell_id)</span><br><span style="color: hsl(0, 100%, 40%);">-           return false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   switch (cell_id->id_discr) {</span><br><span style="color: hsl(0, 100%, 40%);">- case CELL_IDENT_WHOLE_GLOBAL:</span><br><span style="color: hsl(0, 100%, 40%);">-           return gsm_bts_matches_lai(bts, &id->global.lai)</span><br><span style="color: hsl(0, 100%, 40%);">-                 && id->global.cell_identity == bts->cell_identity;</span><br><span style="color: hsl(0, 100%, 40%);">-        case CELL_IDENT_LAC_AND_CI:</span><br><span style="color: hsl(0, 100%, 40%);">-             return id->lac_and_ci.lac == bts->location_area_code</span><br><span style="color: hsl(0, 100%, 40%);">-                      && id->lac_and_ci.ci == bts->cell_identity;</span><br><span style="color: hsl(0, 100%, 40%);">-       case CELL_IDENT_CI:</span><br><span style="color: hsl(0, 100%, 40%);">-             return id->ci == bts->cell_identity;</span><br><span style="color: hsl(0, 100%, 40%);">-      case CELL_IDENT_NO_CELL:</span><br><span style="color: hsl(0, 100%, 40%);">-                return false;</span><br><span style="color: hsl(0, 100%, 40%);">-   case CELL_IDENT_LAI_AND_LAC:</span><br><span style="color: hsl(0, 100%, 40%);">-            return gsm_bts_matches_lai(bts, &id->lai_and_lac);</span><br><span style="color: hsl(0, 100%, 40%);">-       case CELL_IDENT_LAC:</span><br><span style="color: hsl(0, 100%, 40%);">-            return id->lac == bts->location_area_code;</span><br><span style="color: hsl(0, 100%, 40%);">-        case CELL_IDENT_BSS:</span><br><span style="color: hsl(0, 100%, 40%);">-            return true;</span><br><span style="color: hsl(0, 100%, 40%);">-    case CELL_IDENT_UTRAN_PLMN_LAC_RNC:</span><br><span style="color: hsl(0, 100%, 40%);">-     case CELL_IDENT_UTRAN_RNC:</span><br><span style="color: hsl(0, 100%, 40%);">-      case CELL_IDENT_UTRAN_LAC_RNC:</span><br><span style="color: hsl(0, 100%, 40%);">-          return false;</span><br><span style="color: hsl(0, 100%, 40%);">-   default:</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(false);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* From a list of local BTSes that match the cell_id, return the Nth one, or NULL if there is no such</span><br><span>  * match. */</span><br><span> struct gsm_bts *gsm_bts_by_cell_id(const struct gsm_network *net,</span><br><span>@@ -636,59 +290,6 @@</span><br><span>      return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_bts_ref *gsm_bts_ref_find(const struct llist_head *list, const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gsm_bts_ref *ref;</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!bts)</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    llist_for_each_entry(ref, list, entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-                if (ref->bts == bts)</span><br><span style="color: hsl(0, 100%, 40%);">-                 return ref;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Add a BTS reference to the local_neighbors list.</span><br><span style="color: hsl(0, 100%, 40%);">- * Return 1 if added, 0 if such an entry already existed, and negative on errors. */</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_bts_local_neighbor_add(struct gsm_bts *bts, struct gsm_bts *neighbor)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gsm_bts_ref *ref;</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!bts || !neighbor)</span><br><span style="color: hsl(0, 100%, 40%);">-          return -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (bts == neighbor)</span><br><span style="color: hsl(0, 100%, 40%);">-            return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Already got this entry? */</span><br><span style="color: hsl(0, 100%, 40%);">-   ref = gsm_bts_ref_find(&bts->local_neighbors, neighbor);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ref)</span><br><span style="color: hsl(0, 100%, 40%);">-                return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ref = talloc_zero(bts, struct gsm_bts_ref);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!ref)</span><br><span style="color: hsl(0, 100%, 40%);">-               return -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">- ref->bts = neighbor;</span><br><span style="color: hsl(0, 100%, 40%);">- llist_add_tail(&ref->entry, &bts->local_neighbors);</span><br><span style="color: hsl(0, 100%, 40%);">-       return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Remove a BTS reference from the local_neighbors list.</span><br><span style="color: hsl(0, 100%, 40%);">- * Return 1 if removed, 0 if no such entry existed, and negative on errors. */</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_bts_local_neighbor_del(struct gsm_bts *bts, const struct gsm_bts *neighbor)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gsm_bts_ref *ref;</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!bts || !neighbor)</span><br><span style="color: hsl(0, 100%, 40%);">-          return -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ref = gsm_bts_ref_find(&bts->local_neighbors, neighbor);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ref)</span><br><span style="color: hsl(0, 100%, 40%);">-               return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       llist_del(&ref->entry);</span><br><span style="color: hsl(0, 100%, 40%);">-  talloc_free(ref);</span><br><span style="color: hsl(0, 100%, 40%);">-       return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)</span><br><span> {</span><br><span>        struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx);</span><br><span>@@ -748,251 +349,6 @@</span><br><span>      return trx;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };</span><br><span style="color: hsl(0, 100%, 40%);">-static const uint8_t bts_cell_timer_default[] =</span><br><span style="color: hsl(0, 100%, 40%);">-                            { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };</span><br><span style="color: hsl(0, 100%, 40%);">-static const struct gprs_rlc_cfg rlc_cfg_default = {</span><br><span style="color: hsl(0, 100%, 40%);">-     .parameter = {</span><br><span style="color: hsl(0, 100%, 40%);">-          [RLC_T3142] = 20,</span><br><span style="color: hsl(0, 100%, 40%);">-               [RLC_T3169] = 5,</span><br><span style="color: hsl(0, 100%, 40%);">-                [RLC_T3191] = 5,</span><br><span style="color: hsl(0, 100%, 40%);">-                [RLC_T3193] = 160, /* 10ms */</span><br><span style="color: hsl(0, 100%, 40%);">-           [RLC_T3195] = 5,</span><br><span style="color: hsl(0, 100%, 40%);">-                [RLC_N3101] = 10,</span><br><span style="color: hsl(0, 100%, 40%);">-               [RLC_N3103] = 4,</span><br><span style="color: hsl(0, 100%, 40%);">-                [RLC_N3105] = 8,</span><br><span style="color: hsl(0, 100%, 40%);">-                [CV_COUNTDOWN] = 15,</span><br><span style="color: hsl(0, 100%, 40%);">-            [T_DL_TBF_EXT] = 250 * 10, /* ms */</span><br><span style="color: hsl(0, 100%, 40%);">-             [T_UL_TBF_EXT] = 250 * 10, /* ms */</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(0, 100%, 40%);">-      .paging = {</span><br><span style="color: hsl(0, 100%, 40%);">-             .repeat_time = 5 * 50, /* ms */</span><br><span style="color: hsl(0, 100%, 40%);">-         .repeat_count = 3,</span><br><span style="color: hsl(0, 100%, 40%);">-      },</span><br><span style="color: hsl(0, 100%, 40%);">-      .cs_mask = 0x1fff,</span><br><span style="color: hsl(0, 100%, 40%);">-      .initial_cs = 2,</span><br><span style="color: hsl(0, 100%, 40%);">-        .initial_mcs = 6,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void bts_init_cbch_state(struct bts_smscb_chan_state *cstate, struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   cstate->bts = bts;</span><br><span style="color: hsl(0, 100%, 40%);">-   INIT_LLIST_HEAD(&cstate->messages);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Initialize those parts that don't require osmo-bsc specific dependencies.</span><br><span style="color: hsl(0, 100%, 40%);">- * This part is shared among the thin programs in osmo-bsc/src/utils/.</span><br><span style="color: hsl(0, 100%, 40%);">- * osmo-bsc requires further initialization that pulls in more dependencies (see</span><br><span style="color: hsl(0, 100%, 40%);">- * bsc_bts_alloc_register()). */</span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gsm_bts *bts = talloc_zero(net, struct gsm_bts);</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm48_multi_rate_conf mr_cfg;</span><br><span style="color: hsl(0, 100%, 40%);">-    int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!bts)</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->nr = bts_num;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->num_trx = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    INIT_LLIST_HEAD(&bts->trx_list);</span><br><span style="color: hsl(0, 100%, 40%);">- bts->network = net;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->ms_max_power = 15;      /* dBm */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       gsm_mo_init(&bts->mo, bts, NM_OC_BTS,</span><br><span style="color: hsl(0, 100%, 40%);">-                    bts->nr, 0xff, 0xff);</span><br><span style="color: hsl(0, 100%, 40%);">-        gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,</span><br><span style="color: hsl(0, 100%, 40%);">-                  0xff, 0xff, 0xff);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                bts->gprs.nsvc[i].bts = bts;</span><br><span style="color: hsl(0, 100%, 40%);">-         bts->gprs.nsvc[i].id = i;</span><br><span style="color: hsl(0, 100%, 40%);">-            gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,</span><br><span style="color: hsl(0, 100%, 40%);">-                         bts->nr, i, 0xff);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,</span><br><span style="color: hsl(0, 100%, 40%);">-              sizeof(bts->gprs.nse.timer));</span><br><span style="color: hsl(0, 100%, 40%);">-        gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,</span><br><span style="color: hsl(0, 100%, 40%);">-                      bts->nr, 0xff, 0xff);</span><br><span style="color: hsl(0, 100%, 40%);">-        memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,</span><br><span style="color: hsl(0, 100%, 40%);">-            sizeof(bts->gprs.cell.timer));</span><br><span style="color: hsl(0, 100%, 40%);">-       gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,</span><br><span style="color: hsl(0, 100%, 40%);">-                    bts->nr, 0xff, 0xff);</span><br><span style="color: hsl(0, 100%, 40%);">-        memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,</span><br><span style="color: hsl(0, 100%, 40%);">-            sizeof(bts->gprs.cell.rlc_cfg));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* 3GPP TS 08.18, chapter 5.4.1: 0 is reserved for signalling */</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->gprs.cell.bvci = 2;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* init statistics */</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->bts_ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!bts->bts_ctrs) {</span><br><span style="color: hsl(0, 100%, 40%);">-                talloc_free(bts);</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       bts->bts_statg = osmo_stat_item_group_alloc(bts, &bts_statg_desc, bts->nr);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* create our primary TRX */</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->c0 = gsm_bts_trx_alloc(bts);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!bts->c0) {</span><br><span style="color: hsl(0, 100%, 40%);">-              rate_ctr_group_free(bts->bts_ctrs);</span><br><span style="color: hsl(0, 100%, 40%);">-          osmo_stat_item_group_free(bts->bts_statg);</span><br><span style="color: hsl(0, 100%, 40%);">-           talloc_free(bts);</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       bts->c0->ts[0].pchan_from_config = GSM_PCHAN_CCCH_SDCCH4; /* TODO: really?? */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->ccch_load_ind_thresh = 10; /* 10% of Load: Start sending CCCH LOAD IND */</span><br><span style="color: hsl(0, 100%, 40%);">-       bts->rach_b_thresh = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-     bts->rach_ldavg_slots = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->paging.free_chans_need = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-    INIT_LLIST_HEAD(&bts->paging.pending_requests);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->features.data = &bts->_features_data[0];</span><br><span style="color: hsl(0, 100%, 40%);">- bts->features.data_len = sizeof(bts->_features_data);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* si handling */</span><br><span style="color: hsl(0, 100%, 40%);">-       bts->bcch_change_mark = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->chan_load_avg = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* timer overrides */</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->T3122 = 0; /* not overridden by default */</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->T3113_dynamic = true; /* dynamic by default */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;</span><br><span style="color: hsl(0, 100%, 40%);">-     bts->dtxd = false;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->gprs.ctrl_ack_type_use_block = true; /* use RLC/MAC control block */</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->neigh_list_manual_mode = NL_MODE_AUTOMATIC;</span><br><span style="color: hsl(0, 100%, 40%);">-     bts->early_classmark_allowed_3g = true; /* 3g Early Classmark Sending controlled by bts->early_classmark_allowed param */</span><br><span style="color: hsl(0, 100%, 40%);">- bts->si_unused_send_empty = true;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->si_common.cell_sel_par.cell_resel_hyst = 2; /* 4 dB */</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->si_common.cell_sel_par.rxlev_acc_min = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       bts->si_common.si2quater_neigh_list.arfcn = bts->si_common.data.earfcn_list;</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->si_common.si2quater_neigh_list.meas_bw = bts->si_common.data.meas_bw_list;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->si_common.si2quater_neigh_list.thresh_hi = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-   osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->si_common.neigh_list.data = bts->si_common.data.neigh_list;</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->si_common.neigh_list.data_len =</span><br><span style="color: hsl(0, 100%, 40%);">-                         sizeof(bts->si_common.data.neigh_list);</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->si_common.si5_neigh_list.data = bts->si_common.data.si5_neigh_list;</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->si_common.si5_neigh_list.data_len =</span><br><span style="color: hsl(0, 100%, 40%);">-                             sizeof(bts->si_common.data.si5_neigh_list);</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->si_common.cell_alloc.data = bts->si_common.data.cell_alloc;</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->si_common.cell_alloc.data_len =</span><br><span style="color: hsl(0, 100%, 40%);">-                         sizeof(bts->si_common.data.cell_alloc);</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->si_common.rach_control.re = 1; /* no re-establishment */</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->si_common.rach_control.tx_integer = 9;  /* 12 slots spread - 217/115 slots delay */</span><br><span style="color: hsl(0, 100%, 40%);">-     bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->si_common.rach_control.t2 = 4; /* no emergency calls */</span><br><span style="color: hsl(0, 100%, 40%);">- bts->si_common.chan_desc.att = 1; /* attachment required */</span><br><span style="color: hsl(0, 100%, 40%);">-  bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */</span><br><span style="color: hsl(0, 100%, 40%);">-      bts->si_common.chan_desc.t3212 = osmo_tdef_get(net->T_defs, 3212, OSMO_TDEF_CUSTOM, -1);</span><br><span style="color: hsl(0, 100%, 40%);">-  gsm_bts_set_radio_link_timeout(bts, 32); /* Use RADIO LINK TIMEOUT of 32 */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     INIT_LLIST_HEAD(&bts->abis_queue);</span><br><span style="color: hsl(0, 100%, 40%);">-       INIT_LLIST_HEAD(&bts->loc_list);</span><br><span style="color: hsl(0, 100%, 40%);">- INIT_LLIST_HEAD(&bts->local_neighbors);</span><br><span style="color: hsl(0, 100%, 40%);">-  INIT_LLIST_HEAD(&bts->oml_fail_rep);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Enable all codecs by default. These get reset to a more fine grained selection IF a</span><br><span style="color: hsl(0, 100%, 40%);">-   * 'codec-support' config appears in the config file (see bsc_vty.c). */</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->codec = (struct bts_codec_conf){</span><br><span style="color: hsl(0, 100%, 40%);">-                .hr = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-                .efr = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-               .amr = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-       };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Set reasonable defaults for AMR-FR and AMR-HR rate configuration.</span><br><span style="color: hsl(0, 100%, 40%);">-     * (see also 3GPP TS 28.062, Table 7.11.3.1.3-2) */</span><br><span style="color: hsl(0, 100%, 40%);">-     mr_cfg = (struct gsm48_multi_rate_conf) {</span><br><span style="color: hsl(0, 100%, 40%);">-               .m4_75 = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m5_15 = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m5_90 = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m6_70 = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m7_40 = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m7_95 = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m10_2 = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m12_2 = 1</span><br><span style="color: hsl(0, 100%, 40%);">-      };</span><br><span style="color: hsl(0, 100%, 40%);">-      memcpy(bts->mr_full.gsm48_ie, &mr_cfg, sizeof(bts->mr_full.gsm48_ie));</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->mr_full.ms_mode[0].mode = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->mr_full.ms_mode[1].mode = 2;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->mr_full.ms_mode[2].mode = 4;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->mr_full.ms_mode[3].mode = 7;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->mr_full.bts_mode[0].mode = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->mr_full.bts_mode[1].mode = 2;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->mr_full.bts_mode[2].mode = 4;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->mr_full.bts_mode[3].mode = 7;</span><br><span style="color: hsl(0, 100%, 40%);">-   for (i = 0; i < 3; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-            bts->mr_full.ms_mode[i].hysteresis = 8;</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->mr_full.ms_mode[i].threshold = 32;</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->mr_full.bts_mode[i].hysteresis = 8;</span><br><span style="color: hsl(0, 100%, 40%);">-             bts->mr_full.bts_mode[i].threshold = 32;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       bts->mr_full.num_modes = 4;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  mr_cfg = (struct gsm48_multi_rate_conf) {</span><br><span style="color: hsl(0, 100%, 40%);">-               .m4_75 = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m5_15 = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m5_90 = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m6_70 = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m7_40 = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m7_95 = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m10_2 = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-             .m12_2 = 0</span><br><span style="color: hsl(0, 100%, 40%);">-      };</span><br><span style="color: hsl(0, 100%, 40%);">-      memcpy(bts->mr_half.gsm48_ie, &mr_cfg, sizeof(bts->mr_half.gsm48_ie));</span><br><span style="color: hsl(0, 100%, 40%);">-        bts->mr_half.ms_mode[0].mode = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->mr_half.ms_mode[1].mode = 2;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->mr_half.ms_mode[2].mode = 4;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->mr_half.ms_mode[3].mode = 7;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->mr_half.bts_mode[0].mode = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->mr_half.bts_mode[1].mode = 2;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->mr_half.bts_mode[2].mode = 4;</span><br><span style="color: hsl(0, 100%, 40%);">-   bts->mr_half.bts_mode[3].mode = 7;</span><br><span style="color: hsl(0, 100%, 40%);">-   for (i = 0; i < 3; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-            bts->mr_half.ms_mode[i].hysteresis = 8;</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->mr_half.ms_mode[i].threshold = 32;</span><br><span style="color: hsl(0, 100%, 40%);">-              bts->mr_half.bts_mode[i].hysteresis = 8;</span><br><span style="color: hsl(0, 100%, 40%);">-             bts->mr_half.bts_mode[i].threshold = 32;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       bts->mr_half.num_modes = 3;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bts_init_cbch_state(&bts->cbch_basic, bts);</span><br><span style="color: hsl(0, 100%, 40%);">-      bts_init_cbch_state(&bts->cbch_extended, bts);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return bts;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* reset the state of all MO in the BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-void gsm_bts_mo_reset(struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gsm_bts_trx *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-        unsigned int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_abis_mo_reset(&bts->mo);</span><br><span style="color: hsl(0, 100%, 40%);">-     gsm_abis_mo_reset(&bts->site_mgr.mo);</span><br><span style="color: hsl(0, 100%, 40%);">-    for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++)</span><br><span style="color: hsl(0, 100%, 40%);">-          gsm_abis_mo_reset(&bts->gprs.nsvc[i].mo);</span><br><span style="color: hsl(0, 100%, 40%);">-        gsm_abis_mo_reset(&bts->gprs.nse.mo);</span><br><span style="color: hsl(0, 100%, 40%);">-    gsm_abis_mo_reset(&bts->gprs.cell.mo);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   llist_for_each_entry(trx, &bts->trx_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-                gsm_abis_mo_reset(&trx->mo);</span><br><span style="color: hsl(0, 100%, 40%);">-             gsm_abis_mo_reset(&trx->bb_transc.mo);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-           for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       struct gsm_bts_trx_ts *ts = &trx->ts[i];</span><br><span style="color: hsl(0, 100%, 40%);">-                 gsm_abis_mo_reset(&ts->mo);</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)</span><br><span> {</span><br><span>   struct gsm_bts_trx *trx;</span><br><span>@@ -1010,16 +366,6 @@</span><br><span> </span><br><span> static char ts2str[255];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-char *gsm_bts_name(const struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!bts)</span><br><span style="color: hsl(0, 100%, 40%);">-               snprintf(ts2str, sizeof(ts2str), "(bts=NULL)");</span><br><span style="color: hsl(0, 100%, 40%);">-       else</span><br><span style="color: hsl(0, 100%, 40%);">-            snprintf(ts2str, sizeof(ts2str), "(bts=%d)", bts->nr);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return ts2str;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> char *gsm_trx_name(const struct gsm_bts_trx *trx)</span><br><span> {</span><br><span>    if (!trx)</span><br><span>@@ -1289,27 +635,6 @@</span><br><span>    return gsm_pchan2chan_nr(lchan->ts->pchan_is, lchan->ts->nr, lchan->nr);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* return the gsm_lchan for the CBCH (if it exists at all) */</span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gsm_lchan *lchan = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_bts_trx *trx = bts->c0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (trx->ts[0].pchan_from_config == GSM_PCHAN_CCCH_SDCCH4_CBCH)</span><br><span style="color: hsl(0, 100%, 40%);">-              lchan = &trx->ts[0].lchan[2];</span><br><span style="color: hsl(0, 100%, 40%);">-    else {</span><br><span style="color: hsl(0, 100%, 40%);">-          int i;</span><br><span style="color: hsl(0, 100%, 40%);">-          for (i = 0; i < 8; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    if (trx->ts[i].pchan_from_config == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         lchan = &trx->ts[i].lchan[2];</span><br><span style="color: hsl(0, 100%, 40%);">-                            break;</span><br><span style="color: hsl(0, 100%, 40%);">-                  }</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return lchan;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* determine logical channel based on TRX and channel number IE */</span><br><span> struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,</span><br><span>                                    int *rc)</span><br><span>@@ -1392,6 +717,12 @@</span><br><span>  return pchan_is_tch(ts->pchan_is);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!conn || !conn->lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+         return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  return conn->lchan->ts->trx->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> bool trx_is_usable(const struct gsm_bts_trx *trx)</span><br><span> {</span><br><span>         /* FIXME: How does this behave for BS-11 ? */</span><br><span>@@ -1417,13 +748,6 @@</span><br><span>        }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct gsm_bts_trx *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-        llist_for_each_entry(trx, &bts->trx_list, list)</span><br><span style="color: hsl(0, 100%, 40%);">-          gsm_trx_all_ts_dispatch(trx, ts_ev, data);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void _chan_desc_fill_tail(struct gsm48_chan_desc *cd, const struct gsm_lchan *lchan)</span><br><span> {</span><br><span>      if (!lchan->ts->hopping.enabled) {</span><br><span>@@ -1458,6 +782,14 @@</span><br><span>     _chan_desc_fill_tail(cd, lchan);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (ts->tsc != -1)</span><br><span style="color: hsl(120, 100%, 40%);">+         return ts->tsc;</span><br><span style="color: hsl(120, 100%, 40%);">+    else</span><br><span style="color: hsl(120, 100%, 40%);">+          return ts->trx->bts->bsic & 7;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> bool nm_is_running(const struct gsm_nm_state *s) {</span><br><span>       if (s->operational != NM_OPSTATE_ENABLED)</span><br><span>                 return false;</span><br><span>@@ -1633,7 +965,7 @@</span><br><span>         }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)</span><br><span> {</span><br><span>       struct gsm_bts_trx_ts *ts;</span><br><span>   struct gsm_lchan *lchan;</span><br><span>@@ -1681,18 +1013,6 @@</span><br><span>    return count;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Count number of free TS of given pchan type */</span><br><span style="color: hsl(0, 100%, 40%);">-int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gsm_bts_trx *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-        int count = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  llist_for_each_entry(trx, &bts->trx_list, list)</span><br><span style="color: hsl(0, 100%, 40%);">-          count += trx_count_free_ts(trx, pchan);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return count;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> bool ts_is_usable(const struct gsm_bts_trx_ts *ts)</span><br><span> {</span><br><span>    if (!trx_is_usable(ts->trx)) {</span><br><span>diff --git a/src/osmo-bsc/handover_decision.c b/src/osmo-bsc/handover_decision.c</span><br><span>index 5338400..7eb8f31 100644</span><br><span>--- a/src/osmo-bsc/handover_decision.c</span><br><span>+++ b/src/osmo-bsc/handover_decision.c</span><br><span>@@ -34,6 +34,7 @@</span><br><span> </span><br><span> #include <osmocom/bsc/handover_fsm.h></span><br><span> #include <osmocom/bsc/handover_cfg.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> /* did we get a RXLEV for a given cell in the given report? */</span><br><span> static int rxlev_for_cell_in_rep(struct gsm_meas_rep *mr,</span><br><span>diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c</span><br><span>index ab507e8..8caa2e3 100644</span><br><span>--- a/src/osmo-bsc/handover_decision_2.c</span><br><span>+++ b/src/osmo-bsc/handover_decision_2.c</span><br><span>@@ -37,6 +37,7 @@</span><br><span> #include <osmocom/bsc/penalty_timers.h></span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #define LOGPHOBTS(bts, level, fmt, args...) \</span><br><span>       LOGP(DHODEC, level, "(BTS %u) " fmt, bts->nr, ## args)</span><br><span>diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c</span><br><span>index 0b88b27..8ed5945 100644</span><br><span>--- a/src/osmo-bsc/handover_fsm.c</span><br><span>+++ b/src/osmo-bsc/handover_fsm.c</span><br><span>@@ -43,6 +43,7 @@</span><br><span> #include <osmocom/bsc/osmo_bsc_lcls.h></span><br><span> #include <osmocom/bsc/codec_pref.h></span><br><span> #include <osmocom/bsc/gsm_08_08.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #define LOG_FMT_BTS "bts %u lac-ci %u-%u arfcn-bsic %d-%d"</span><br><span> #define LOG_ARGS_BTS(bts) \</span><br><span>diff --git a/src/osmo-bsc/handover_logic.c b/src/osmo-bsc/handover_logic.c</span><br><span>index 5be8383..071228e 100644</span><br><span>--- a/src/osmo-bsc/handover_logic.c</span><br><span>+++ b/src/osmo-bsc/handover_logic.c</span><br><span>@@ -43,6 +43,7 @@</span><br><span> #include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span> #include <osmocom/bsc/abis_nm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/gsm/gsm0808.h></span><br><span> #include <osmocom/gsm/gsm0808_utils.h></span><br><span> </span><br><span>diff --git a/src/osmo-bsc/handover_vty.c b/src/osmo-bsc/handover_vty.c</span><br><span>index a418aa7..81313e2 100644</span><br><span>--- a/src/osmo-bsc/handover_vty.c</span><br><span>+++ b/src/osmo-bsc/handover_vty.c</span><br><span>@@ -27,6 +27,7 @@</span><br><span> #include <osmocom/bsc/vty.h></span><br><span> #include <osmocom/bsc/handover_cfg.h></span><br><span> #include <osmocom/bsc/handover_decision_2.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> static struct handover_cfg *ho_cfg_from_vty(struct vty *vty)</span><br><span> {</span><br><span>diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c</span><br><span>index bcf7c4b..e879059 100644</span><br><span>--- a/src/osmo-bsc/lchan_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_fsm.c</span><br><span>@@ -39,7 +39,7 @@</span><br><span> #include <osmocom/bsc/handover_fsm.h></span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span> #include <osmocom/bsc/codec_pref.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> static struct osmo_fsm lchan_fsm;</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/lchan_rtp_fsm.c b/src/osmo-bsc/lchan_rtp_fsm.c</span><br><span>index 4be9790..2def2f5 100644</span><br><span>--- a/src/osmo-bsc/lchan_rtp_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_rtp_fsm.c</span><br><span>@@ -30,6 +30,7 @@</span><br><span> #include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> static struct osmo_fsm lchan_rtp_fsm;</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/lchan_select.c b/src/osmo-bsc/lchan_select.c</span><br><span>index d63db22..d2dba1b 100644</span><br><span>--- a/src/osmo-bsc/lchan_select.c</span><br><span>+++ b/src/osmo-bsc/lchan_select.c</span><br><span>@@ -28,6 +28,7 @@</span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span> </span><br><span> #include <osmocom/bsc/lchan_select.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> static struct gsm_lchan *</span><br><span> _lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,</span><br><span>diff --git a/src/osmo-bsc/meas_feed.c b/src/osmo-bsc/meas_feed.c</span><br><span>index f9a3626..889f6ef 100644</span><br><span>--- a/src/osmo-bsc/meas_feed.c</span><br><span>+++ b/src/osmo-bsc/meas_feed.c</span><br><span>@@ -19,6 +19,7 @@</span><br><span> #include <osmocom/bsc/meas_feed.h></span><br><span> #include <osmocom/bsc/vty.h></span><br><span> #include <osmocom/bsc/debug.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> struct meas_feed_state {</span><br><span>   struct osmo_wqueue wqueue;</span><br><span>diff --git a/src/osmo-bsc/neighbor_ident_vty.c b/src/osmo-bsc/neighbor_ident_vty.c</span><br><span>index 54d6944..7feed2a 100644</span><br><span>--- a/src/osmo-bsc/neighbor_ident_vty.c</span><br><span>+++ b/src/osmo-bsc/neighbor_ident_vty.c</span><br><span>@@ -30,6 +30,7 @@</span><br><span> #include <osmocom/bsc/vty.h></span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> static struct gsm_network *g_net = NULL;</span><br><span> static struct neighbor_ident_list *g_neighbor_cells = NULL;</span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c</span><br><span>index 1cacfe9..bf38d10 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_bssap.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_bssap.c</span><br><span>@@ -33,6 +33,7 @@</span><br><span> #include <osmocom/bsc/codec_pref.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span> #include <osmocom/bsc/handover_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/gsm/protocol/gsm_08_08.h></span><br><span> #include <osmocom/gsm/gsm0808.h></span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_ctrl.c b/src/osmo-bsc/osmo_bsc_ctrl.c</span><br><span>index b94a749..5ebe597 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_ctrl.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_ctrl.c</span><br><span>@@ -27,6 +27,7 @@</span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/a_reset.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/core/linuxlist.h></span><br><span> #include <osmocom/core/signal.h></span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_filter.c b/src/osmo-bsc/osmo_bsc_filter.c</span><br><span>index 08c3a50..f664231 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_filter.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_filter.c</span><br><span>@@ -26,6 +26,7 @@</span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/bsc/paging.h></span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <stdlib.h></span><br><span> </span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_grace.c b/src/osmo-bsc/osmo_bsc_grace.c</span><br><span>index 56edee5..a26a716 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_grace.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_grace.c</span><br><span>@@ -25,6 +25,7 @@</span><br><span> #include <osmocom/bsc/paging.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> int bsc_grace_allow_new_connection(struct gsm_network *network, struct gsm_bts *bts)</span><br><span> {</span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c</span><br><span>index ada6047..84b44f7 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_main.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_main.c</span><br><span>@@ -64,6 +64,7 @@</span><br><span> #include <osmocom/bsc/e1_config.h></span><br><span> #include <osmocom/bsc/codec_pref.h></span><br><span> #include <osmocom/bsc/system_information.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/mgcp_client/mgcp_client.h></span><br><span> </span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c</span><br><span>index f2a1e5b..5e02b4a 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_msc.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_msc.c</span><br><span>@@ -29,6 +29,7 @@</span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span> #include <osmocom/bsc/osmo_bsc_sigtran.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/socket.h></span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_sigtran.c b/src/osmo-bsc/osmo_bsc_sigtran.c</span><br><span>index afc6c8d..de4be26 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_sigtran.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_sigtran.c</span><br><span>@@ -34,6 +34,7 @@</span><br><span> #include <osmocom/bsc/a_reset.h></span><br><span> #include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/mgcp_client/mgcp_common.h></span><br><span> </span><br><span> /* A pointer to a list with all involved MSCs</span><br><span>diff --git a/src/osmo-bsc/paging.c b/src/osmo-bsc/paging.c</span><br><span>index 7859c69..521598f 100644</span><br><span>--- a/src/osmo-bsc/paging.c</span><br><span>+++ b/src/osmo-bsc/paging.c</span><br><span>@@ -53,6 +53,7 @@</span><br><span> #include <osmocom/bsc/gsm_08_08.h></span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span> #include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> void *tall_paging_ctx = NULL;</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c</span><br><span>index 3e0b7bf..ae4ac8a 100644</span><br><span>--- a/src/osmo-bsc/pcu_sock.c</span><br><span>+++ b/src/osmo-bsc/pcu_sock.c</span><br><span>@@ -44,6 +44,7 @@</span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> static int pcu_sock_send(struct gsm_bts *bts, struct msgb *msg);</span><br><span> uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx);</span><br><span>diff --git a/src/osmo-bsc/rest_octets.c b/src/osmo-bsc/rest_octets.c</span><br><span>index 0d806f3..7307cb8 100644</span><br><span>--- a/src/osmo-bsc/rest_octets.c</span><br><span>+++ b/src/osmo-bsc/rest_octets.c</span><br><span>@@ -33,6 +33,7 @@</span><br><span> #include <osmocom/bsc/rest_octets.h></span><br><span> #include <osmocom/bsc/arfcn_range_encode.h></span><br><span> #include <osmocom/bsc/system_information.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> /* generate SI1 rest octets */</span><br><span> int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net)</span><br><span>diff --git a/src/osmo-bsc/smscb.c b/src/osmo-bsc/smscb.c</span><br><span>index 8d48af9..436826a 100644</span><br><span>--- a/src/osmo-bsc/smscb.c</span><br><span>+++ b/src/osmo-bsc/smscb.c</span><br><span>@@ -41,6 +41,7 @@</span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> /*********************************************************************************</span><br><span>  * Helper Functions</span><br><span>diff --git a/src/osmo-bsc/system_information.c b/src/osmo-bsc/system_information.c</span><br><span>index b17a909..13d0f46 100644</span><br><span>--- a/src/osmo-bsc/system_information.c</span><br><span>+++ b/src/osmo-bsc/system_information.c</span><br><span>@@ -41,6 +41,7 @@</span><br><span> #include <osmocom/bsc/gsm_04_08_rr.h></span><br><span> #include <osmocom/bsc/acc_ramp.h></span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> struct gsm0808_cell_id_list2;</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/timeslot_fsm.c b/src/osmo-bsc/timeslot_fsm.c</span><br><span>index 4816daf..0aecfae 100644</span><br><span>--- a/src/osmo-bsc/timeslot_fsm.c</span><br><span>+++ b/src/osmo-bsc/timeslot_fsm.c</span><br><span>@@ -28,6 +28,7 @@</span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span> #include <osmocom/bsc/pcu_if.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> static struct osmo_fsm ts_fsm;</span><br><span> </span><br><span>diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am</span><br><span>index e585e0d..6696679 100644</span><br><span>--- a/src/utils/Makefile.am</span><br><span>+++ b/src/utils/Makefile.am</span><br><span>@@ -48,6 +48,7 @@</span><br><span> </span><br><span> bs11_config_LDADD = \</span><br><span>         $(top_builddir)/src/osmo-bsc/abis_nm.o \</span><br><span style="color: hsl(120, 100%, 40%);">+      $(top_builddir)/src/osmo-bsc/bts.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/bts_siemens_bs11.o \</span><br><span>    $(top_builddir)/src/osmo-bsc/e1_config.o \</span><br><span>   $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span>@@ -117,6 +118,7 @@</span><br><span>      $(NULL)</span><br><span> </span><br><span> meas_json_LDADD = \</span><br><span style="color: hsl(120, 100%, 40%);">+    $(top_builddir)/src/osmo-bsc/bts.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span>    $(LIBOSMOCORE_LIBS) \</span><br><span>        $(LIBOSMOGSM_LIBS) \</span><br><span>diff --git a/src/utils/bs11_config.c b/src/utils/bs11_config.c</span><br><span>index 1156233..c43c008 100644</span><br><span>--- a/src/utils/bs11_config.c</span><br><span>+++ b/src/utils/bs11_config.c</span><br><span>@@ -39,6 +39,7 @@</span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/core/select.h></span><br><span> #include <osmocom/bsc/rs232.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/core/application.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/abis/abis.h></span><br><span>diff --git a/tests/abis/Makefile.am b/tests/abis/Makefile.am</span><br><span>index 60054d9..a01f56a 100644</span><br><span>--- a/tests/abis/Makefile.am</span><br><span>+++ b/tests/abis/Makefile.am</span><br><span>@@ -26,6 +26,7 @@</span><br><span> </span><br><span> abis_test_LDADD = \</span><br><span>         $(top_builddir)/src/osmo-bsc/abis_nm.o \</span><br><span style="color: hsl(120, 100%, 40%);">+      $(top_builddir)/src/osmo-bsc/bts.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span>    $(top_builddir)/src/osmo-bsc/net_init.o \</span><br><span>    $(LIBOSMOCORE_LIBS) \</span><br><span>diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c</span><br><span>index 43934f3..767a9fb 100644</span><br><span>--- a/tests/abis/abis_test.c</span><br><span>+++ b/tests/abis/abis_test.c</span><br><span>@@ -26,6 +26,7 @@</span><br><span> #include <osmocom/gsm/gsm23003.h></span><br><span> </span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/bsc/abis_nm.h></span><br><span> #include <osmocom/bsc/debug.h></span><br><span> </span><br><span>diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am</span><br><span>index b301f9e..7ea002e 100644</span><br><span>--- a/tests/bsc/Makefile.am</span><br><span>+++ b/tests/bsc/Makefile.am</span><br><span>@@ -37,6 +37,7 @@</span><br><span>      $(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \</span><br><span>  $(top_builddir)/src/osmo-bsc/osmo_bsc_filter.o \</span><br><span>     $(top_builddir)/src/osmo-bsc/bsc_subscriber.o \</span><br><span style="color: hsl(120, 100%, 40%);">+       $(top_builddir)/src/osmo-bsc/bts.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span>    $(top_builddir)/src/osmo-bsc/handover_cfg.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/handover_logic.o \</span><br><span>diff --git a/tests/codec_pref/codec_pref_test.c b/tests/codec_pref/codec_pref_test.c</span><br><span>index f163f35..5f4c831 100644</span><br><span>--- a/tests/codec_pref/codec_pref_test.c</span><br><span>+++ b/tests/codec_pref/codec_pref_test.c</span><br><span>@@ -20,6 +20,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/bsc/osmo_bsc.h></span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span> #include <osmocom/core/application.h></span><br><span>diff --git a/tests/gsm0408/Makefile.am b/tests/gsm0408/Makefile.am</span><br><span>index aff7c7d..21b7873 100644</span><br><span>--- a/tests/gsm0408/Makefile.am</span><br><span>+++ b/tests/gsm0408/Makefile.am</span><br><span>@@ -25,6 +25,7 @@</span><br><span> gsm0408_test_LDADD = \</span><br><span>   $(top_builddir)/src/osmo-bsc/gsm_04_08_rr.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \</span><br><span style="color: hsl(120, 100%, 40%);">+   $(top_builddir)/src/osmo-bsc/bts.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span>    $(top_builddir)/src/osmo-bsc/net_init.o \</span><br><span>    $(top_builddir)/src/osmo-bsc/rest_octets.o \</span><br><span>diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c</span><br><span>index 5ff9491..b3e8b11 100644</span><br><span>--- a/tests/gsm0408/gsm0408_test.c</span><br><span>+++ b/tests/gsm0408/gsm0408_test.c</span><br><span>@@ -29,6 +29,7 @@</span><br><span> #include <osmocom/bsc/arfcn_range_encode.h></span><br><span> #include <osmocom/bsc/system_information.h></span><br><span> #include <osmocom/bsc/abis_rsl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/core/application.h></span><br><span> #include <osmocom/core/byteswap.h></span><br><span>diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am</span><br><span>index 736b444..571b7a9 100644</span><br><span>--- a/tests/handover/Makefile.am</span><br><span>+++ b/tests/handover/Makefile.am</span><br><span>@@ -57,6 +57,7 @@</span><br><span>       $(top_builddir)/src/osmo-bsc/bsc_subscr_conn_fsm.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/bsc_subscriber.o \</span><br><span>      $(top_builddir)/src/osmo-bsc/bsc_vty.o \</span><br><span style="color: hsl(120, 100%, 40%);">+      $(top_builddir)/src/osmo-bsc/bts.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \</span><br><span>        $(top_builddir)/src/osmo-bsc/bts_unknown.o \</span><br><span>diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c</span><br><span>index 1a756cd..edc3219 100644</span><br><span>--- a/tests/handover/handover_test.c</span><br><span>+++ b/tests/handover/handover_test.c</span><br><span>@@ -47,6 +47,7 @@</span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span> #include <osmocom/bsc/handover_fsm.h></span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> void *ctx;</span><br><span> </span><br><span>diff --git a/tests/nanobts_omlattr/Makefile.am b/tests/nanobts_omlattr/Makefile.am</span><br><span>index aa7045e..93fdbe8 100644</span><br><span>--- a/tests/nanobts_omlattr/Makefile.am</span><br><span>+++ b/tests/nanobts_omlattr/Makefile.am</span><br><span>@@ -25,6 +25,7 @@</span><br><span> nanobts_omlattr_test_LDADD = \</span><br><span>     $(top_builddir)/src/osmo-bsc/abis_nm.o \</span><br><span>     $(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(top_builddir)/src/osmo-bsc/bts.o \</span><br><span>         $(top_builddir)/src/osmo-bsc/gsm_data.o \</span><br><span>    $(LIBOSMOCORE_LIBS) \</span><br><span>        $(LIBOSMOGSM_LIBS) \</span><br><span>diff --git a/tests/nanobts_omlattr/nanobts_omlattr_test.c b/tests/nanobts_omlattr/nanobts_omlattr_test.c</span><br><span>index a3ba8e0..4180f4a 100644</span><br><span>--- a/tests/nanobts_omlattr/nanobts_omlattr_test.c</span><br><span>+++ b/tests/nanobts_omlattr/nanobts_omlattr_test.c</span><br><span>@@ -22,6 +22,7 @@</span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span> #include <osmocom/bsc/bts_ipaccess_nanobts_omlattr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/utils.h></span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/19287">change 19287</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-bsc/+/19287"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I00c15f5285b5c1a0109279b7ab192d5467a04ece </div>
<div style="display:none"> Gerrit-Change-Number: 19287 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Hoernchen <ewild@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: lynxis lazus <lynxis@fe80.eu> </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>