Change in osmo-bts[master]: Move gsm_bts code gsm-data.* => bts.*

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Wed Jul 8 15:41:49 UTC 2020


pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/19123 )

Change subject: Move gsm_bts code gsm-data.* => bts.*
......................................................................

Move gsm_bts code gsm-data.* => bts.*

bts.h refers to struct gsm_bts object, but we still had a bunch of stuff
in bulky gsm_data.* from old days. Let's move stuff where it belongs to
start clean up of gsm_data.

Change-Id: I0a4219e3f64f625ee8b364bf408b8d2bcc8085c5
---
M include/osmo-bts/bts.h
M include/osmo-bts/gsm_data.h
M src/common/bts.c
M src/common/bts_shutdown_fsm.c
M src/common/gsm_data.c
M src/common/load_indication.c
M src/common/msg_utils.c
M src/common/scheduler.c
M src/common/sysinfo.c
M src/osmo-bts-octphy/l1_if.c
M src/osmo-bts-sysmo/sysmobts_vty.c
M src/osmo-bts-trx/trx_vty.c
12 files changed, 479 insertions(+), 487 deletions(-)

Approvals:
  Jenkins Builder: Verified
  Hoernchen: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved
  fixeria: Looks good to me, but someone else must approve



diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h
index 63412f9..cb8787f 100644
--- a/include/osmo-bts/bts.h
+++ b/include/osmo-bts/bts.h
@@ -24,8 +24,299 @@
 	BTS_CTR_AGCH_DELETED,
 };
 
+/* Used by OML layer for BTS Attribute reporting */
+enum bts_attribute {
+	BTS_TYPE_VARIANT,
+	BTS_SUB_MODEL,
+	TRX_PHY_VERSION,
+};
+const char *btsatttr2str(enum bts_attribute v);
+
+enum gsm_bts_type_variant {
+	BTS_UNKNOWN,
+	BTS_OSMO_LITECELL15,
+        BTS_OSMO_OC2G,
+	BTS_OSMO_OCTPHY,
+	BTS_OSMO_SYSMO,
+	BTS_OSMO_TRX,
+	BTS_OSMO_VIRTUAL,
+	BTS_OSMO_OMLDUMMY,
+	_NUM_BTS_VARIANT
+};
+const char *btsvariant2str(enum gsm_bts_type_variant v);
+
+/* TODO: add a brief description of this flag */
+#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP		(1 << 0)
+/* When this flag is set then the measurement data is included in
+ * (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
+ * measurement data is passed using a separate MPH INFO MEAS IND.
+ * (See also ticket: OS#2977) */
+#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB		(1 << 1)
+
+/* BTS implementation flags (internal use, not exposed via OML) */
+#define bts_internal_flag_get(bts, flag) \
+	((bts->flags & (typeof(bts->flags)) flag) != 0)
+#define bts_internal_flag_set(bts, flag) \
+	bts->flags |= (typeof(bts->flags)) flag
+
+struct gsm_bts_gprs_nsvc {
+	struct gsm_bts *bts;
+	/* data read via VTY config file, to configure the BTS
+	 * via OML from BSC */
+	int id;
+	uint16_t nsvci;
+	uint16_t local_port;	/* on the BTS */
+	uint16_t remote_port;	/* on the SGSN */
+	uint32_t remote_ip;	/* on the SGSN */
+
+	struct gsm_abis_mo mo;
+};
+
+struct gprs_rlc_cfg {
+	uint16_t parameter[_NUM_RLC_PAR];
+	struct {
+		uint16_t repeat_time; /* ms */
+		uint8_t repeat_count;
+	} paging;
+	uint32_t cs_mask; /* bitmask of gprs_cs */
+	uint8_t initial_cs;
+	uint8_t initial_mcs;
+};
+
+struct bts_smscb_state {
+	struct llist_head queue; /* list of struct smscb_msg */
+	int queue_len;
+	struct rate_ctr_group *ctrs;
+	struct smscb_msg *cur_msg; /* current SMS-CB */
+	struct smscb_msg *default_msg; /* default broadcast message; NULL if none */
+};
+
+/* One BTS */
+struct gsm_bts {
+	/* list header in net->bts_list */
+	struct llist_head list;
+
+	/* number of the BTS in network */
+	uint8_t nr;
+	/* human readable name / description */
+	char *description;
+	/* Cell Identity */
+	uint16_t cell_identity;
+	/* location area code of this BTS */
+	uint16_t location_area_code;
+	/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
+	 * which is used as TSC for the CCCH */
+	uint8_t bsic;
+	/* type of BTS */
+	enum gsm_bts_type_variant variant;
+	enum gsm_band band;
+	char version[MAX_VERSION_LENGTH];
+	char sub_model[MAX_VERSION_LENGTH];
+
+	/* public features of a given BTS (set/reported via OML) */
+	struct bitvec *features;
+	/* implementation flags of a given BTS (not exposed via OML) */
+	uint16_t flags;
+
+	/* Connected PCU version (if any) */
+	char pcu_version[MAX_VERSION_LENGTH];
+
+	/* maximum Tx power that the MS is permitted to use in this cell */
+	int ms_max_power;
+
+	/* how do we talk OML with this TRX? */
+	struct e1inp_sign_link *oml_link;
+	struct timespec oml_conn_established_timestamp;
+
+	/* Abis network management O&M handle */
+	struct gsm_abis_mo mo;
+
+	/* number of this BTS on given E1 link */
+	uint8_t bts_nr;
+
+	/* DTX features of this BTS */
+	bool dtxd;
+
+	/* CCCH is on C0 */
+	struct gsm_bts_trx *c0;
+
+	struct {
+		struct gsm_abis_mo mo;
+	} site_mgr;
+
+	/* bitmask of all SI that are present/valid in si_buf */
+	uint32_t si_valid;
+	/* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
+	uint8_t si2q_index; /* distinguish individual SI2quater messages */
+	uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
+	/* buffers where we put the pre-computed SI */
+	sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
+	/* offsets used while generating SI2quater */
+	size_t e_offset;
+	size_t u_offset;
+	/* decoded SI3 rest octets - *unmodified* as received from BSC */
+	struct osmo_gsm48_si_ro_info si3_ro_decoded;
+	/* is SI3 GPRS Indicator currently disabled due to lack of PCU connection? */
+	bool si3_gprs_ind_disabled;
+
+	/* ip.access Unit ID's have Site/BTS/TRX layout */
+	union {
+		struct {
+			uint16_t site_id;
+			uint16_t bts_id;
+			uint32_t flags;
+			uint32_t rsl_ip;
+		} ip_access;
+	};
+
+	/* Not entirely sure how ip.access specific this is */
+	struct {
+		struct {
+			struct gsm_abis_mo mo;
+			uint16_t nsei;
+			uint8_t timer[7];
+		} nse;
+		struct {
+			struct gsm_abis_mo mo;
+			uint16_t bvci;
+			uint8_t timer[11];
+			struct gprs_rlc_cfg rlc_cfg;
+		} cell;
+		struct gsm_bts_gprs_nsvc nsvc[2];
+		uint8_t rac;
+	} gprs;
+
+	/* transceivers */
+	int num_trx;
+	struct llist_head trx_list;
+
+	struct rate_ctr_group *ctrs;
+	bool supp_meas_toa256;
+
+	struct {
+		/* Interference Boundaries for OML */
+		int16_t boundary[6];
+		uint8_t intave;
+	} interference;
+	unsigned int t200_ms[7];
+	unsigned int t3105_ms;
+	struct {
+		uint8_t overload_period;
+		struct {
+			/* Input parameters from OML */
+			uint8_t load_ind_thresh;	/* percent */
+			uint8_t load_ind_period;	/* seconds */
+			/* Internal data */
+			struct osmo_timer_list timer;
+			unsigned int pch_total;
+			unsigned int pch_used;
+		} ccch;
+		struct {
+			/* Input parameters from OML */
+			int16_t busy_thresh;		/* in dBm */
+			uint16_t averaging_slots;
+			/* Internal data */
+			unsigned int total;	/* total nr */
+			unsigned int busy;	/* above busy_thresh */
+			unsigned int access;	/* access bursts */
+		} rach;
+	} load;
+	uint8_t ny1;
+	uint8_t max_ta;
+
+	/* AGCH queuing */
+	struct {
+		struct llist_head queue;
+		int length;
+		int max_length;
+
+		int thresh_level;	/* Cleanup threshold in percent of max len */
+		int low_level;		/* Low water mark in percent of max len */
+		int high_level;		/* High water mark in percent of max len */
+
+		/* TODO: Use a rate counter group instead */
+		uint64_t dropped_msgs;
+		uint64_t merged_msgs;
+		uint64_t rejected_msgs;
+		uint64_t agch_msgs;
+		uint64_t pch_msgs;
+	} agch_queue;
+
+	struct {
+		uint8_t *prim_notif;	/* ETWS primary notification (NULL if none) */
+		ssize_t prim_notif_len;	/* Length of prim_notif; expected 56 bytes */
+		uint8_t page_size;
+		uint8_t num_pages;	/* total number of pages */
+		uint8_t next_page;	/* next page number to be sent */
+		bool pni;		/* Primary Notification Identifier */
+	} etws;
+
+	struct paging_state *paging_state;
+	char *bsc_oml_host;
+	struct llist_head oml_queue;
+	unsigned int rtp_jitter_buf_ms;
+	bool rtp_jitter_adaptive;
+
+	uint16_t rtp_port_range_start;
+	uint16_t rtp_port_range_end;
+	uint16_t rtp_port_range_next;
+	int rtp_ip_dscp;
+
+	struct {
+		uint8_t ciphers;	/* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
+	} support;
+	struct {
+		uint8_t tc4_ctr;
+	} si;
+	struct gsm_time gsm_time;
+	/* frame number statistics (FN in PH-RTS.ind vs. PH-DATA.ind */
+	struct {
+		int32_t min;		/* minimum observed */
+		int32_t max;		/* maximum observed */
+		int32_t avg256;		/* accumulator */
+		uint32_t avg_count;	/* number of samples accumulated in avg256 */
+		uint32_t avg_window;	/* number of averages in avg_count */
+	} fn_stats;
+	/* Radio Link Timeout counter. -1 disables timeout for
+	 * lab/measurement purpose */
+	int radio_link_timeout;
+
+	int ul_power_target;		/* Uplink Rx power target */
+
+	/* used by the sysmoBTS to adjust band */
+	uint8_t auto_band;
+
+	/* State for SMSCB (Cell Broadcast) for BASIC and EXTENDED channel */
+	struct bts_smscb_state smscb_basic;
+	struct bts_smscb_state smscb_extended;
+	int smscb_queue_tgt_len; /* ideal/target queue length */
+	int smscb_queue_max_len; /* maximum queue length */
+	int smscb_queue_hyst; /* hysteresis for CBCH load indications */
+
+	int16_t min_qual_rach;	/* minimum link quality (in centiBels) for Access Bursts */
+	int16_t min_qual_norm;	/* minimum link quality (in centiBels) for Normal Bursts */
+	uint16_t max_ber10k_rach;	/* Maximum permitted RACH BER in 0.01% */
+
+	struct {
+		char *sock_path;
+	} pcu;
+
+	struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */
+	struct osmo_tdef *T_defs; /* Timer defines */
+
+	void *model_priv; /* Allocated by bts_model, contains model specific data pointer */
+};
+
+extern const struct value_string bts_impl_flag_desc[];
 extern void *tall_bts_ctx;
 
+#define GSM_BTS_SI2Q(bts, i)   (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
+#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
+#define GSM_BTS_SI(bts, i)     (void *)((bts)->si_buf[i][0])
+
+struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num);
+struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
+
 int bts_init(struct gsm_bts *bts);
 int bts_trx_init(struct gsm_bts_trx *trx);
 void bts_shutdown(struct gsm_bts *bts, const char *reason);
@@ -39,7 +330,7 @@
 int bts_agch_max_queue_length(int T, int bcch_conf);
 int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
 		      int is_ag_res);
-
+int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher);
 uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time);
 void regenerate_si3_restoctets(struct gsm_bts *bts);
 uint8_t *lchan_sacch_get(struct gsm_lchan *lchan);
@@ -60,4 +351,7 @@
 
 int32_t bts_get_avg_fn_advance(struct gsm_bts *bts);
 
+/* return the gsm_lchan for the CBCH (if it exists at all) */
+struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
+
 #endif /* _BTS_H */
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h
index 2e8ff46..0bb7761 100644
--- a/include/osmo-bts/gsm_data.h
+++ b/include/osmo-bts/gsm_data.h
@@ -386,59 +386,8 @@
 	struct gsm_bts_trx_ts ts[TRX_NR_TS];
 };
 
-#define GSM_BTS_SI2Q(bts, i)   (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
-#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
-#define GSM_BTS_SI(bts, i)     (void *)((bts)->si_buf[i][0])
 #define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0])
 
-enum gsm_bts_type_variant {
-	BTS_UNKNOWN,
-	BTS_OSMO_LITECELL15,
-        BTS_OSMO_OC2G,
-	BTS_OSMO_OCTPHY,
-	BTS_OSMO_SYSMO,
-	BTS_OSMO_TRX,
-	BTS_OSMO_VIRTUAL,
-	BTS_OSMO_OMLDUMMY,
-	_NUM_BTS_VARIANT
-};
-
-/* Used by OML layer for BTS Attribute reporting */
-enum bts_attribute {
-	BTS_TYPE_VARIANT,
-	BTS_SUB_MODEL,
-	TRX_PHY_VERSION,
-};
-
-/* BTS implementation flags (internal use, not exposed via OML) */
-#define bts_internal_flag_get(bts, flag) \
-	((bts->flags & (typeof(bts->flags)) flag) != 0)
-#define bts_internal_flag_set(bts, flag) \
-	bts->flags |= (typeof(bts->flags)) flag
-
-/* TODO: add a brief description of this flag */
-#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP		(1 << 0)
-/* When this flag is set then the measurement data is included in
- * (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
- * measurement data is passed using a separate MPH INFO MEAS IND.
- * (See also ticket: OS#2977) */
-#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB		(1 << 1)
-
-extern const struct value_string bts_impl_flag_desc[];
-
-struct gsm_bts_gprs_nsvc {
-	struct gsm_bts *bts;
-	/* data read via VTY config file, to configure the BTS
-	 * via OML from BSC */
-	int id;
-	uint16_t nsvci;
-	uint16_t local_port;	/* on the BTS */
-	uint16_t remote_port;	/* on the SGSN */
-	uint32_t remote_ip;	/* on the SGSN */
-
-	struct gsm_abis_mo mo;
-};
-
 enum gprs_rlc_par {
 	RLC_T3142,
 	RLC_T3169,
@@ -471,257 +420,13 @@
 	_NUM_GRPS_CS
 };
 
-struct gprs_rlc_cfg {
-	uint16_t parameter[_NUM_RLC_PAR];
-	struct {
-		uint16_t repeat_time; /* ms */
-		uint8_t repeat_count;
-	} paging;
-	uint32_t cs_mask; /* bitmask of gprs_cs */
-	uint8_t initial_cs;
-	uint8_t initial_mcs;
-};
-
-struct bts_smscb_state {
-	struct llist_head queue; /* list of struct smscb_msg */
-	int queue_len;
-	struct rate_ctr_group *ctrs;
-	struct smscb_msg *cur_msg; /* current SMS-CB */
-	struct smscb_msg *default_msg; /* default broadcast message; NULL if none */
-};
-
 /* The amount of time within which a sudden disconnect of a newly established
  * OML connection will cause a special warning to be logged. */
 #define OSMO_BTS_OML_CONN_EARLY_DISCONNECT 10	 /* in seconds */
 
-/* One BTS */
-struct gsm_bts {
-	/* list header in net->bts_list */
-	struct llist_head list;
-
-	/* number of the BTS in network */
-	uint8_t nr;
-	/* human readable name / description */
-	char *description;
-	/* Cell Identity */
-	uint16_t cell_identity;
-	/* location area code of this BTS */
-	uint16_t location_area_code;
-	/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
-	 * which is used as TSC for the CCCH */
-	uint8_t bsic;
-	/* type of BTS */
-	enum gsm_bts_type_variant variant;
-	enum gsm_band band;
-	char version[MAX_VERSION_LENGTH];
-	char sub_model[MAX_VERSION_LENGTH];
-
-	/* public features of a given BTS (set/reported via OML) */
-	struct bitvec *features;
-	/* implementation flags of a given BTS (not exposed via OML) */
-	uint16_t flags;
-
-	/* Connected PCU version (if any) */
-	char pcu_version[MAX_VERSION_LENGTH];
-
-	/* maximum Tx power that the MS is permitted to use in this cell */
-	int ms_max_power;
-
-	/* how do we talk OML with this TRX? */
-	struct e1inp_sign_link *oml_link;
-	struct timespec oml_conn_established_timestamp;
-
-	/* Abis network management O&M handle */
-	struct gsm_abis_mo mo;
-
-	/* number of this BTS on given E1 link */
-	uint8_t bts_nr;
-
-	/* DTX features of this BTS */
-	bool dtxd;
-
-	/* CCCH is on C0 */
-	struct gsm_bts_trx *c0;
-
-	struct {
-		struct gsm_abis_mo mo;
-	} site_mgr;
-
-	/* bitmask of all SI that are present/valid in si_buf */
-	uint32_t si_valid;
-	/* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
-	uint8_t si2q_index; /* distinguish individual SI2quater messages */
-	uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
-	/* buffers where we put the pre-computed SI */
-	sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
-	/* offsets used while generating SI2quater */
-	size_t e_offset;
-	size_t u_offset;
-	/* decoded SI3 rest octets - *unmodified* as received from BSC */
-	struct osmo_gsm48_si_ro_info si3_ro_decoded;
-	/* is SI3 GPRS Indicator currently disabled due to lack of PCU connection? */
-	bool si3_gprs_ind_disabled;
-
-	/* ip.access Unit ID's have Site/BTS/TRX layout */
-	union {
-		struct {
-			uint16_t site_id;
-			uint16_t bts_id;
-			uint32_t flags;
-			uint32_t rsl_ip;
-		} ip_access;
-	};
-
-	/* Not entirely sure how ip.access specific this is */
-	struct {
-		struct {
-			struct gsm_abis_mo mo;
-			uint16_t nsei;
-			uint8_t timer[7];
-		} nse;
-		struct {
-			struct gsm_abis_mo mo;
-			uint16_t bvci;
-			uint8_t timer[11];
-			struct gprs_rlc_cfg rlc_cfg;
-		} cell;
-		struct gsm_bts_gprs_nsvc nsvc[2];
-		uint8_t rac;
-	} gprs;
-
-	/* transceivers */
-	int num_trx;
-	struct llist_head trx_list;
-
-	struct rate_ctr_group *ctrs;
-	bool supp_meas_toa256;
-
-	struct {
-		/* Interference Boundaries for OML */
-		int16_t boundary[6];
-		uint8_t intave;
-	} interference;
-	unsigned int t200_ms[7];
-	unsigned int t3105_ms;
-	struct {
-		uint8_t overload_period;
-		struct {
-			/* Input parameters from OML */
-			uint8_t load_ind_thresh;	/* percent */
-			uint8_t load_ind_period;	/* seconds */
-			/* Internal data */
-			struct osmo_timer_list timer;
-			unsigned int pch_total;
-			unsigned int pch_used;
-		} ccch;
-		struct {
-			/* Input parameters from OML */
-			int16_t busy_thresh;		/* in dBm */
-			uint16_t averaging_slots;
-			/* Internal data */
-			unsigned int total;	/* total nr */
-			unsigned int busy;	/* above busy_thresh */
-			unsigned int access;	/* access bursts */
-		} rach;
-	} load;
-	uint8_t ny1;
-	uint8_t max_ta;
-
-	/* AGCH queuing */
-	struct {
-		struct llist_head queue;
-		int length;
-		int max_length;
-
-		int thresh_level;	/* Cleanup threshold in percent of max len */
-		int low_level;		/* Low water mark in percent of max len */
-		int high_level;		/* High water mark in percent of max len */
-
-		/* TODO: Use a rate counter group instead */
-		uint64_t dropped_msgs;
-		uint64_t merged_msgs;
-		uint64_t rejected_msgs;
-		uint64_t agch_msgs;
-		uint64_t pch_msgs;
-	} agch_queue;
-
-	struct {
-		uint8_t *prim_notif;	/* ETWS primary notification (NULL if none) */
-		ssize_t prim_notif_len;	/* Length of prim_notif; expected 56 bytes */
-		uint8_t page_size;
-		uint8_t num_pages;	/* total number of pages */
-		uint8_t next_page;	/* next page number to be sent */
-		bool pni;		/* Primary Notification Identifier */
-	} etws;
-
-	struct paging_state *paging_state;
-	char *bsc_oml_host;
-	struct llist_head oml_queue;
-	unsigned int rtp_jitter_buf_ms;
-	bool rtp_jitter_adaptive;
-
-	uint16_t rtp_port_range_start;
-	uint16_t rtp_port_range_end;
-	uint16_t rtp_port_range_next;
-	int rtp_ip_dscp;
-
-	struct {
-		uint8_t ciphers;	/* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
-	} support;
-	struct {
-		uint8_t tc4_ctr;
-	} si;
-	struct gsm_time gsm_time;
-	/* frame number statistics (FN in PH-RTS.ind vs. PH-DATA.ind */
-	struct {
-		int32_t min;		/* minimum observed */
-		int32_t max;		/* maximum observed */
-		int32_t avg256;		/* accumulator */
-		uint32_t avg_count;	/* number of samples accumulated in avg256 */
-		uint32_t avg_window;	/* number of averages in avg_count */
-	} fn_stats;
-	/* Radio Link Timeout counter. -1 disables timeout for
-	 * lab/measurement purpose */
-	int radio_link_timeout;
-
-	int ul_power_target;		/* Uplink Rx power target */
-
-	/* used by the sysmoBTS to adjust band */
-	uint8_t auto_band;
-
-	/* State for SMSCB (Cell Broadcast) for BASIC and EXTENDED channel */
-	struct bts_smscb_state smscb_basic;
-	struct bts_smscb_state smscb_extended;
-	int smscb_queue_tgt_len; /* ideal/target queue length */
-	int smscb_queue_max_len; /* maximum queue length */
-	int smscb_queue_hyst; /* hysteresis for CBCH load indications */
-
-	int16_t min_qual_rach;	/* minimum link quality (in centiBels) for Access Bursts */
-	int16_t min_qual_norm;	/* minimum link quality (in centiBels) for Normal Bursts */
-	uint16_t max_ber10k_rach;	/* Maximum permitted RACH BER in 0.01% */
-
-	struct {
-		char *sock_path;
-	} pcu;
-
-	struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */
-	struct osmo_tdef *T_defs; /* Timer defines */
-
-	void *model_priv; /* Allocated by bts_model, contains model specific data pointer */
-};
-
-
-struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num);
-struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
-
 struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
 struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num);
 
-enum bts_attribute str2btsattr(const char *s);
-const char *btsatttr2str(enum bts_attribute v);
-
-enum gsm_bts_type_variant str2btsvariant(const char *arg);
-const char *btsvariant2str(enum gsm_bts_type_variant v);
 
 extern const struct value_string gsm_pchant_names[13];
 extern const struct value_string gsm_pchant_descs[13];
@@ -743,18 +448,9 @@
 uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
 				   enum gsm_phys_chan_config as_pchan);
 
-/* return the gsm_lchan for the CBCH (if it exists at all) */
-struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
-
 #define BSIC2BCC(bsic) ((bsic) & 0x3)
 
-static inline uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)
-{
-	if (ts->tsc != -1)
-		return ts->tsc;
-	else
-		return ts->trx->bts->bsic & 7;
-}
+uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts);
 
 struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
 				   int *rc);
@@ -773,10 +469,6 @@
 /* cipher code */
 #define CIPHER_A5(x) (1 << (x-1))
 
-int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher);
-
 bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);
 
-int bts_model_check_cm_mode(enum gsm_phys_chan_config pchan, enum gsm48_chan_mode cm);
-
 #endif /* _GSM_DATA_H */
diff --git a/src/common/bts.c b/src/common/bts.c
index dccb098..2f6a700 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -32,6 +32,7 @@
 #include <osmocom/core/timer.h>
 #include <osmocom/core/msgb.h>
 #include <osmocom/core/talloc.h>
+#include <osmocom/core/tdef.h>
 #include <osmocom/core/stats.h>
 #include <osmocom/core/rate_ctr.h>
 #include <osmocom/gsm/protocol/gsm_12_21.h>
@@ -50,6 +51,7 @@
 #include <osmo-bts/signal.h>
 #include <osmo-bts/dtx_dl_amr_fsm.h>
 #include <osmo-bts/cbch.h>
+#include <osmo-bts/bts_shutdown_fsm.h>
 
 #define MIN_QUAL_RACH	 50 /* minimum link quality (in centiBels) for Access Bursts */
 #define MIN_QUAL_NORM	 -5 /* minimum link quality (in centiBels) for Normal Bursts */
@@ -122,6 +124,152 @@
 	cbch_ctr_desc
 };
 
+static struct osmo_tdef bts_T_defs[] = {
+	/* T-1: FIXME: Ideally should be dynamically calculated per trx at
+	 * shutdown start based on params below, and highest trx value taken:
+	 * + VTY's power-ramp step-interval.
+	 * + Amount of steps needed (taking into account how many dB each step moves).
+	 * + Extra time to get response back for each step.
+	 * For now we simply give 5 mins, which should be enough for any
+	 * acceptable setup, while still ensuring will timeout at some point if
+	 * something fails in the ramp down procedure.
+	 */
+	{ .T=-1, .default_val=300, .desc="Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s)" },
+	{ .T=-2, .default_val=3, .desc="Time after which osmo-bts exits if requesting transceivers to stop during shut down process does not finish (s)" },
+	{}
+};
+
+static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
+static const uint8_t bts_cell_timer_default[] =
+				{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
+static const struct gprs_rlc_cfg rlc_cfg_default = {
+	.parameter = {
+		[RLC_T3142] = 20,
+		[RLC_T3169] = 5,
+		[RLC_T3191] = 5,
+		[RLC_T3193] = 160, /* 10ms */
+		[RLC_T3195] = 5,
+		[RLC_N3101] = 10,
+		[RLC_N3103] = 4,
+		[RLC_N3105] = 8,
+		[CV_COUNTDOWN] = 15,
+		[T_DL_TBF_EXT] = 250 * 10, /* ms */
+		[T_UL_TBF_EXT] = 250 * 10, /* ms */
+	},
+	.paging = {
+		.repeat_time = 5 * 50, /* ms */
+		.repeat_count = 3,
+	},
+	.cs_mask = 0x1fff,
+	.initial_cs = 2,
+	.initial_mcs = 6,
+};
+
+const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
+	{ BTS_UNKNOWN,		"unknown" },
+	{ BTS_OSMO_LITECELL15,	"osmo-bts-lc15" },
+	{ BTS_OSMO_OC2G,	"osmo-bts-oc2g" },
+	{ BTS_OSMO_OCTPHY,	"osmo-bts-octphy" },
+	{ BTS_OSMO_SYSMO,	"osmo-bts-sysmo" },
+	{ BTS_OSMO_TRX,		"osmo-bts-trx" },
+	{ BTS_OSMO_VIRTUAL,	"osmo-bts-virtual" },
+	{ BTS_OSMO_OMLDUMMY,	"osmo-bts-omldummy" },
+	{ 0, NULL }
+};
+
+const char *btsvariant2str(enum gsm_bts_type_variant v)
+{
+	return get_value_string(osmo_bts_variant_names, v);
+}
+
+const struct value_string bts_attribute_names[] = {
+	OSMO_VALUE_STRING(BTS_TYPE_VARIANT),
+	OSMO_VALUE_STRING(BTS_SUB_MODEL),
+	OSMO_VALUE_STRING(TRX_PHY_VERSION),
+	{ 0, NULL }
+};
+
+const char *btsatttr2str(enum bts_attribute v)
+{
+	return get_value_string(bts_attribute_names, v);
+}
+
+const struct value_string bts_impl_flag_desc[] = {
+	{ BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP,	"DSP/HW based MS Power Control Loop" },
+	{ BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB,	"Measurement and Payload data combined" },
+	{ 0, NULL }
+};
+
+struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
+{
+	struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
+	int i;
+
+	if (!bts)
+		return NULL;
+
+	bts->nr = bts_num;
+	bts->num_trx = 0;
+	INIT_LLIST_HEAD(&bts->trx_list);
+	bts->ms_max_power = 15;	/* dBm */
+
+	bts->T_defs = bts_T_defs;
+	osmo_tdefs_reset(bts->T_defs);
+	bts->shutdown_fi = osmo_fsm_inst_alloc(&bts_shutdown_fsm, bts, bts,
+					       LOGL_INFO, NULL);
+	osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr);
+
+	gsm_mo_init(&bts->mo, bts, NM_OC_BTS,
+			bts->nr, 0xff, 0xff);
+	gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
+			0xff, 0xff, 0xff);
+
+	for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
+		bts->gprs.nsvc[i].bts = bts;
+		bts->gprs.nsvc[i].id = i;
+		gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
+				bts->nr, i, 0xff);
+	}
+	memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
+		sizeof(bts->gprs.nse.timer));
+	gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
+			bts->nr, 0xff, 0xff);
+	memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
+		sizeof(bts->gprs.cell.timer));
+	gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
+			bts->nr, 0xff, 0xff);
+	memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
+		sizeof(bts->gprs.cell.rlc_cfg));
+
+	/* create our primary TRX. It will be initialized during bts_init() */
+	bts->c0 = gsm_bts_trx_alloc(bts);
+	if (!bts->c0) {
+		talloc_free(bts);
+		return NULL;
+	}
+	bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4;
+
+	bts->features = bitvec_alloc(MAX_BTS_FEATURES / 8, bts);
+	OSMO_ASSERT(bts->features != NULL);
+
+	return bts;
+}
+
+struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num)
+{
+	struct gsm_bts *bts;
+
+	if (num >= net->num_bts)
+		return NULL;
+
+	llist_for_each_entry(bts, &net->bts_list, list) {
+		if (bts->nr == num)
+			return bts;
+	}
+
+	return NULL;
+}
+
 /* Initialize the BTS data structures, called before config
  * file reading */
 int bts_init(struct gsm_bts *bts)
@@ -817,3 +965,24 @@
 
 	return 0;
 }
+
+/* return the gsm_lchan for the CBCH (if it exists at all) */
+struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)
+{
+	struct gsm_lchan *lchan = NULL;
+	struct gsm_bts_trx *trx = bts->c0;
+
+	if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
+		lchan = &trx->ts[0].lchan[2];
+	else {
+		int i;
+		for (i = 0; i < 8; i++) {
+			if (trx->ts[i].pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
+				lchan = &trx->ts[i].lchan[2];
+				break;
+			}
+		}
+	}
+
+	return lchan;
+}
diff --git a/src/common/bts_shutdown_fsm.c b/src/common/bts_shutdown_fsm.c
index d55b1cd..c81a4ab 100644
--- a/src/common/bts_shutdown_fsm.c
+++ b/src/common/bts_shutdown_fsm.c
@@ -28,6 +28,7 @@
 #include <osmo-bts/logging.h>
 #include <osmo-bts/gsm_data.h>
 #include <osmo-bts/bts_model.h>
+#include <osmo-bts/bts.h>
 
 #define X(s) (1 << (s))
 
diff --git a/src/common/gsm_data.c b/src/common/gsm_data.c
index 57f33ae..c63793c 100644
--- a/src/common/gsm_data.c
+++ b/src/common/gsm_data.c
@@ -30,74 +30,13 @@
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/statistics.h>
 #include <osmocom/core/fsm.h>
-#include <osmocom/core/tdef.h>
 
 #include <osmocom/gsm/gsm_utils.h>
 #include <osmocom/gsm/abis_nm.h>
 #include <osmocom/codec/ecu.h>
 
 #include <osmo-bts/gsm_data.h>
-#include <osmo-bts/bts_shutdown_fsm.h>
-
-static struct osmo_tdef bts_T_defs[] = {
-	/* T-1: FIXME: Ideally should be dynamically calculated per trx at
-	 * shutdown start based on params below, and highest trx value taken:
-	 * + VTY's power-ramp step-interval.
-	 * + Amount of steps needed (taking into account how many dB each step moves).
-	 * + Extra time to get response back for each step.
-	 * For now we simply give 5 mins, which should be enough for any
-	 * acceptable setup, while still ensuring will timeout at some point if
-	 * something fails in the ramp down procedure.
-	 */
-	{ .T=-1, .default_val=300, .desc="Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s)" },
-	{ .T=-2, .default_val=3, .desc="Time after which osmo-bts exits if requesting transceivers to stop during shut down process does not finish (s)" },
-	{}
-};
-
-const struct value_string bts_attribute_names[] = {
-	OSMO_VALUE_STRING(BTS_TYPE_VARIANT),
-	OSMO_VALUE_STRING(BTS_SUB_MODEL),
-	OSMO_VALUE_STRING(TRX_PHY_VERSION),
-	{ 0, NULL }
-};
-
-enum bts_attribute str2btsattr(const char *s)
-{
-	return get_string_value(bts_attribute_names, s);
-}
-
-const char *btsatttr2str(enum bts_attribute v)
-{
-	return get_value_string(bts_attribute_names, v);
-}
-
-const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
-	{ BTS_UNKNOWN,		"unknown" },
-	{ BTS_OSMO_LITECELL15,	"osmo-bts-lc15" },
-	{ BTS_OSMO_OC2G,	"osmo-bts-oc2g" },
-	{ BTS_OSMO_OCTPHY,	"osmo-bts-octphy" },
-	{ BTS_OSMO_SYSMO,	"osmo-bts-sysmo" },
-	{ BTS_OSMO_TRX,		"osmo-bts-trx" },
-	{ BTS_OSMO_VIRTUAL,	"osmo-bts-virtual" },
-	{ BTS_OSMO_OMLDUMMY,	"osmo-bts-omldummy" },
-	{ 0, NULL }
-};
-
-enum gsm_bts_type_variant str2btsvariant(const char *arg)
-{
-	return get_string_value(osmo_bts_variant_names, arg);
-}
-
-const char *btsvariant2str(enum gsm_bts_type_variant v)
-{
-	return get_value_string(osmo_bts_variant_names, v);
-}
-
-const struct value_string bts_impl_flag_desc[] = {
-	{ BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP,	"DSP/HW based MS Power Control Loop" },
-	{ BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB,	"Measurement and Payload data combined" },
-	{ 0, NULL }
-};
+#include <osmo-bts/bts.h>
 
 const struct value_string gsm_pchant_names[13] = {
 	{ GSM_PCHAN_NONE,	"NONE" },
@@ -164,21 +103,6 @@
 	return get_value_string(lchan_s_names, s);
 }
 
-struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num)
-{
-	struct gsm_bts *bts;
-
-	if (num >= net->num_bts)
-		return NULL;
-
-	llist_for_each_entry(bts, &net->bts_list, list) {
-		if (bts->nr == num)
-			return bts;
-	}
-
-	return NULL;
-}
-
 struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
 {
 	struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx);
@@ -233,88 +157,6 @@
 	return trx;
 }
 
-
-static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
-static const uint8_t bts_cell_timer_default[] =
-				{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
-static const struct gprs_rlc_cfg rlc_cfg_default = {
-	.parameter = {
-		[RLC_T3142] = 20,
-		[RLC_T3169] = 5,
-		[RLC_T3191] = 5,
-		[RLC_T3193] = 160, /* 10ms */
-		[RLC_T3195] = 5,
-		[RLC_N3101] = 10,
-		[RLC_N3103] = 4,
-		[RLC_N3105] = 8,
-		[CV_COUNTDOWN] = 15,
-		[T_DL_TBF_EXT] = 250 * 10, /* ms */
-		[T_UL_TBF_EXT] = 250 * 10, /* ms */
-	},
-	.paging = {
-		.repeat_time = 5 * 50, /* ms */
-		.repeat_count = 3,
-	},
-	.cs_mask = 0x1fff,
-	.initial_cs = 2,
-	.initial_mcs = 6,
-};
-
-struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
-{
-	struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
-	int i;
-
-	if (!bts)
-		return NULL;
-
-	bts->nr = bts_num;
-	bts->num_trx = 0;
-	INIT_LLIST_HEAD(&bts->trx_list);
-	bts->ms_max_power = 15;	/* dBm */
-
-	bts->T_defs = bts_T_defs;
-	osmo_tdefs_reset(bts->T_defs);
-	bts->shutdown_fi = osmo_fsm_inst_alloc(&bts_shutdown_fsm, bts, bts,
-					       LOGL_INFO, NULL);
-	osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr);
-
-	gsm_mo_init(&bts->mo, bts, NM_OC_BTS,
-			bts->nr, 0xff, 0xff);
-	gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
-			0xff, 0xff, 0xff);
-
-	for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
-		bts->gprs.nsvc[i].bts = bts;
-		bts->gprs.nsvc[i].id = i;
-		gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
-				bts->nr, i, 0xff);
-	}
-	memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
-		sizeof(bts->gprs.nse.timer));
-	gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
-			bts->nr, 0xff, 0xff);
-	memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
-		sizeof(bts->gprs.cell.timer));
-	gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
-			bts->nr, 0xff, 0xff);
-	memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
-		sizeof(bts->gprs.cell.rlc_cfg));
-
-	/* create our primary TRX. It will be initialized during bts_init() */
-	bts->c0 = gsm_bts_trx_alloc(bts);
-	if (!bts->c0) {
-		talloc_free(bts);
-		return NULL;
-	}
-	bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4;
-
-	bts->features = bitvec_alloc(MAX_BTS_FEATURES / 8, bts);
-	OSMO_ASSERT(bts->features != NULL);
-
-	return bts;
-}
-
 struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)
 {
 	struct gsm_bts_trx *trx;
@@ -499,25 +341,12 @@
 	return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr);
 }
 
-/* return the gsm_lchan for the CBCH (if it exists at all) */
-struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)
+uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)
 {
-	struct gsm_lchan *lchan = NULL;
-	struct gsm_bts_trx *trx = bts->c0;
-
-	if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
-		lchan = &trx->ts[0].lchan[2];
-	else {
-		int i;
-		for (i = 0; i < 8; i++) {
-			if (trx->ts[i].pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
-				lchan = &trx->ts[i].lchan[2];
-				break;
-			}
-		}
-	}
-
-	return lchan;
+	if (ts->tsc != -1)
+		return ts->tsc;
+	else
+		return ts->trx->bts->bsic & 7;
 }
 
 /* determine logical channel based on TRX and channel number IE */
diff --git a/src/common/load_indication.c b/src/common/load_indication.c
index 8d9b56f..c9b2645 100644
--- a/src/common/load_indication.c
+++ b/src/common/load_indication.c
@@ -27,6 +27,7 @@
 #include <osmo-bts/gsm_data.h>
 #include <osmo-bts/rsl.h>
 #include <osmo-bts/paging.h>
+#include <osmo-bts/bts.h>
 
 static void reset_load_counters(struct gsm_bts *bts)
 {
diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c
index 52b0566..1817849 100644
--- a/src/common/msg_utils.c
+++ b/src/common/msg_utils.c
@@ -23,6 +23,7 @@
 #include <osmo-bts/oml.h>
 #include <osmo-bts/amr.h>
 #include <osmo-bts/rsl.h>
+#include <osmo-bts/bts.h>
 
 #include <osmocom/gsm/protocol/ipaccess.h>
 #include <osmocom/gsm/protocol/gsm_12_21.h>
diff --git a/src/common/scheduler.c b/src/common/scheduler.c
index 3068918..7375a1a 100644
--- a/src/common/scheduler.c
+++ b/src/common/scheduler.c
@@ -42,6 +42,7 @@
 #include <osmo-bts/l1sap.h>
 #include <osmo-bts/scheduler.h>
 #include <osmo-bts/scheduler_backend.h>
+#include <osmo-bts/bts.h>
 
 extern void *tall_bts_ctx;
 
diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c
index f5bc3c8..4a86c4e 100644
--- a/src/common/sysinfo.c
+++ b/src/common/sysinfo.c
@@ -25,6 +25,7 @@
 #include <osmo-bts/logging.h>
 #include <osmo-bts/gsm_data.h>
 #include <osmo-bts/pcu_if.h>
+#include <osmo-bts/bts.h>
 
 /* properly increment SI2q index and return SI2q data for scheduling */
 static inline uint8_t *get_si2q_inc_index(struct gsm_bts *bts)
diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c
index 0adc8fe..c03b411 100644
--- a/src/osmo-bts-octphy/l1_if.c
+++ b/src/osmo-bts-octphy/l1_if.c
@@ -43,6 +43,7 @@
 #include <osmo-bts/logging.h>
 #include <osmo-bts/l1sap.h>
 #include <osmo-bts/handover.h>
+#include <osmo-bts/bts.h>
 
 #include "l1_if.h"
 #include "l1_oml.h"
diff --git a/src/osmo-bts-sysmo/sysmobts_vty.c b/src/osmo-bts-sysmo/sysmobts_vty.c
index 0653f01..7876612 100644
--- a/src/osmo-bts-sysmo/sysmobts_vty.c
+++ b/src/osmo-bts-sysmo/sysmobts_vty.c
@@ -45,6 +45,7 @@
 #include <osmo-bts/bts_model.h>
 #include <osmo-bts/vty.h>
 #include <osmo-bts/rsl.h>
+#include <osmo-bts/bts.h>
 
 #include "femtobts.h"
 #include "l1_if.h"
diff --git a/src/osmo-bts-trx/trx_vty.c b/src/osmo-bts-trx/trx_vty.c
index 2e52958..fb75a4e 100644
--- a/src/osmo-bts-trx/trx_vty.c
+++ b/src/osmo-bts-trx/trx_vty.c
@@ -42,6 +42,7 @@
 #include <osmo-bts/logging.h>
 #include <osmo-bts/vty.h>
 #include <osmo-bts/scheduler.h>
+#include <osmo-bts/bts.h>
 
 #include "l1_if.h"
 #include "trx_if.h"

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/19123
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I0a4219e3f64f625ee8b364bf408b8d2bcc8085c5
Gerrit-Change-Number: 19123
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Hoernchen <ewild at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200708/909a43ce/attachment.htm>


More information about the gerrit-log mailing list