blob: a9d57a380069385cf9535e6fb4272e277b936012 [file] [log] [blame]
Pau Espin Pedrol388ed582020-07-15 20:53:16 +02001#pragma once
2
3#include <stdint.h>
4#include <sys/types.h>
5#include <stdbool.h>
6
7#include <osmocom/core/linuxlist.h>
8#include <osmocom/core/msgb.h>
9#include <osmocom/core/bitvec.h>
10#include <osmocom/gsm/tlv.h>
11#include <osmocom/gsm/bts_features.h>
12
13#include <osmocom/abis/e1_input.h>
14
15#include "osmocom/bsc/gsm_data.h"
Pau Espin Pedrolaca53202020-07-16 14:49:36 +020016#include "osmocom/bsc/bts_trx.h"
Pau Espin Pedrol388ed582020-07-15 20:53:16 +020017
18enum bts_counter_id {
19 BTS_CTR_CHREQ_TOTAL,
20 BTS_CTR_CHREQ_SUCCESSFUL,
21 BTS_CTR_CHREQ_NO_CHANNEL,
22 BTS_CTR_CHAN_RF_FAIL,
23 BTS_CTR_CHAN_RLL_ERR,
24 BTS_CTR_BTS_OML_FAIL,
25 BTS_CTR_BTS_RSL_FAIL,
26 BTS_CTR_CODEC_AMR_F,
27 BTS_CTR_CODEC_AMR_H,
28 BTS_CTR_CODEC_EFR,
29 BTS_CTR_CODEC_V1_FR,
30 BTS_CTR_CODEC_V1_HR,
31 BTS_CTR_PAGING_ATTEMPTED,
32 BTS_CTR_PAGING_ALREADY,
33 BTS_CTR_PAGING_RESPONDED,
34 BTS_CTR_PAGING_EXPIRED,
35 BTS_CTR_PAGING_NO_ACTIVE_PAGING,
36 BTS_CTR_PAGING_MSC_FLUSH,
37 BTS_CTR_CHAN_ACT_TOTAL,
38 BTS_CTR_CHAN_ACT_NACK,
39 BTS_CTR_RSL_UNKNOWN,
40 BTS_CTR_RSL_IPA_NACK,
41 BTS_CTR_RSL_DELETE_IND,
42 BTS_CTR_MODE_MODIFY_NACK,
43 BTS_CTR_LCHAN_BORKEN_FROM_UNUSED,
44 BTS_CTR_LCHAN_BORKEN_FROM_WAIT_ACTIV_ACK,
45 BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RF_RELEASE_ACK,
46 BTS_CTR_LCHAN_BORKEN_FROM_BORKEN,
47 BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN,
48 BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK,
49 BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK,
50 BTS_CTR_LCHAN_BORKEN_EV_RF_CHAN_REL_ACK,
51 BTS_CTR_LCHAN_BORKEN_EV_VTY,
52 BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN,
Philipp Maier92eed412020-08-21 20:47:49 +020053 BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RR_CHAN_MODE_MODIFY_ACK,
54 BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RSL_CHAN_MODE_MODIFY_ACK,
Pau Espin Pedrol388ed582020-07-15 20:53:16 +020055 BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED,
56 BTS_CTR_TS_BORKEN_FROM_UNUSED,
57 BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_ACT,
58 BTS_CTR_TS_BORKEN_FROM_PDCH,
59 BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_DEACT,
60 BTS_CTR_TS_BORKEN_FROM_IN_USE,
61 BTS_CTR_TS_BORKEN_FROM_BORKEN,
62 BTS_CTR_TS_BORKEN_FROM_UNKNOWN,
63 BTS_CTR_TS_BORKEN_EV_PDCH_ACT_ACK_NACK,
64 BTS_CTR_TS_BORKEN_EV_PDCH_DEACT_ACK_NACK,
65 BTS_CTR_TS_BORKEN_EV_TEARDOWN,
66 BTS_CTR_ASSIGNMENT_ATTEMPTED,
67 BTS_CTR_ASSIGNMENT_COMPLETED,
68 BTS_CTR_ASSIGNMENT_STOPPED,
69 BTS_CTR_ASSIGNMENT_NO_CHANNEL,
70 BTS_CTR_ASSIGNMENT_TIMEOUT,
71 BTS_CTR_ASSIGNMENT_FAILED,
72 BTS_CTR_ASSIGNMENT_ERROR,
Daniel Willmann02f0b302020-08-17 17:09:41 +020073 BTS_CTR_HANDOVER_ATTEMPTED,
74 BTS_CTR_HANDOVER_COMPLETED,
75 BTS_CTR_HANDOVER_STOPPED,
76 BTS_CTR_HANDOVER_NO_CHANNEL,
77 BTS_CTR_HANDOVER_TIMEOUT,
78 BTS_CTR_HANDOVER_FAILED,
79 BTS_CTR_HANDOVER_ERROR,
Daniel Willmannbf2a4b62020-08-20 15:25:37 +020080 BTS_CTR_INTRA_CELL_HO_ATTEMPTED,
81 BTS_CTR_INTRA_CELL_HO_COMPLETED,
82 BTS_CTR_INTRA_CELL_HO_STOPPED,
83 BTS_CTR_INTRA_CELL_HO_NO_CHANNEL,
84 BTS_CTR_INTRA_CELL_HO_TIMEOUT,
85 BTS_CTR_INTRA_CELL_HO_FAILED,
86 BTS_CTR_INTRA_CELL_HO_ERROR,
87 BTS_CTR_INTRA_BSC_HO_ATTEMPTED,
88 BTS_CTR_INTRA_BSC_HO_COMPLETED,
89 BTS_CTR_INTRA_BSC_HO_STOPPED,
90 BTS_CTR_INTRA_BSC_HO_NO_CHANNEL,
91 BTS_CTR_INTRA_BSC_HO_TIMEOUT,
92 BTS_CTR_INTRA_BSC_HO_FAILED,
93 BTS_CTR_INTRA_BSC_HO_ERROR,
Daniel Willmann02f0b302020-08-17 17:09:41 +020094 BTS_CTR_INTER_BSC_HO_OUT_ATTEMPTED,
95 BTS_CTR_INTER_BSC_HO_OUT_COMPLETED,
96 BTS_CTR_INTER_BSC_HO_OUT_STOPPED,
97 BTS_CTR_INTER_BSC_HO_OUT_TIMEOUT,
Neels Hofmeyrdbe59f62020-08-29 03:23:31 +000098 BTS_CTR_INTER_BSC_HO_OUT_FAILED,
Daniel Willmann02f0b302020-08-17 17:09:41 +020099 BTS_CTR_INTER_BSC_HO_OUT_ERROR,
100 BTS_CTR_INTER_BSC_HO_IN_ATTEMPTED,
101 BTS_CTR_INTER_BSC_HO_IN_COMPLETED,
102 BTS_CTR_INTER_BSC_HO_IN_STOPPED,
103 BTS_CTR_INTER_BSC_HO_IN_NO_CHANNEL,
104 BTS_CTR_INTER_BSC_HO_IN_FAILED,
105 BTS_CTR_INTER_BSC_HO_IN_TIMEOUT,
106 BTS_CTR_INTER_BSC_HO_IN_ERROR,
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200107};
108
109static const struct rate_ctr_desc bts_ctr_description[] = {
110 [BTS_CTR_CHREQ_TOTAL] = {"chreq:total", "Received channel requests"},
111 [BTS_CTR_CHREQ_SUCCESSFUL] = {"chreq:successful", "Successful channel requests (immediate assign sent)"},
112 [BTS_CTR_CHREQ_NO_CHANNEL] = {"chreq:no_channel", "Sent to MS no channel available"},
113 [BTS_CTR_CHAN_RF_FAIL] = {"chan:rf_fail", "Received a RF failure indication from BTS"},
114 [BTS_CTR_CHAN_RLL_ERR] = {"chan:rll_err", "Received a RLL failure with T200 cause from BTS"},
115 [BTS_CTR_BTS_OML_FAIL] = {"oml_fail", "Received a TEI down on a OML link"},
116 [BTS_CTR_BTS_RSL_FAIL] = {"rsl_fail", "Received a TEI down on a OML link"},
117 [BTS_CTR_CODEC_AMR_F] = {"codec:amr_f", "Count the usage of AMR/F codec by channel mode requested"},
118 [BTS_CTR_CODEC_AMR_H] = {"codec:amr_h", "Count the usage of AMR/H codec by channel mode requested"},
119 [BTS_CTR_CODEC_EFR] = {"codec:efr", "Count the usage of EFR codec by channel mode requested"},
120 [BTS_CTR_CODEC_V1_FR] = {"codec:fr", "Count the usage of FR codec by channel mode requested"},
121 [BTS_CTR_CODEC_V1_HR] = {"codec:hr", "Count the usage of HR codec by channel mode requested"},
122
123 [BTS_CTR_PAGING_ATTEMPTED] = {"paging:attempted", "Paging attempts for a subscriber"},
124 [BTS_CTR_PAGING_ALREADY] = {"paging:already", "Paging attempts ignored as subscriber was already being paged"},
125 [BTS_CTR_PAGING_RESPONDED] = {"paging:responded", "Paging attempts with successful paging response"},
126 [BTS_CTR_PAGING_EXPIRED] = {"paging:expired", "Paging Request expired because of timeout T3113"},
127 [BTS_CTR_PAGING_NO_ACTIVE_PAGING] = {"paging:no_active_paging", "Paging response without an active paging request (arrived after paging expiration?)"},
128 [BTS_CTR_PAGING_MSC_FLUSH] = {"paging:msc_flush", "Paging flushed due to MSC Reset BSSMAP message"},
129 [BTS_CTR_CHAN_ACT_TOTAL] = {"chan_act:total", "Total number of Channel Activations"},
130 [BTS_CTR_CHAN_ACT_NACK] = {"chan_act:nack", "Number of Channel Activations that the BTS NACKed"},
131 [BTS_CTR_RSL_UNKNOWN] = {"rsl:unknown", "Number of unknown/unsupported RSL messages received from BTS"},
132 [BTS_CTR_RSL_IPA_NACK] = {"rsl:ipa_nack", "Number of IPA (RTP/dyn-PDCH) related NACKs received from BTS"},
133 [BTS_CTR_RSL_DELETE_IND] = {"rsl:delete_ind", "Number of RSL DELETE INDICATION (DL CCCH overload)"},
134 [BTS_CTR_MODE_MODIFY_NACK] = {"chan:mode_modify_nack", "Number of Channel Mode Modify NACKs received from BTS"},
135
136 /* lchan/TS BORKEN state counters */
137 [BTS_CTR_LCHAN_BORKEN_FROM_UNUSED] = {"lchan_borken:from_state:unused", "Transitions from lchan UNUSED state to BORKEN state"},
138 [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"},
139 [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"},
140 [BTS_CTR_LCHAN_BORKEN_FROM_BORKEN] = {"lchan_borken:from_state:borken", "Transitions from lchan BORKEN state to BORKEN state"},
Philipp Maier92eed412020-08-21 20:47:49 +0200141 [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RR_CHAN_MODE_MODIFY_ACK] = {"lchan_borken:from_state:wait_rr_chan_mode_modify_ack", "Transitions from lchan WAIT_RR_CHAN_MODE_MODIFY_ACK state to BORKEN state"},
142 [BTS_CTR_LCHAN_BORKEN_FROM_WAIT_RSL_CHAN_MODE_MODIFY_ACK] = {"lchan_borken:from_state:wait_rsl_chan_mode_modify_ack", "Transitions from lchan RSL_CHAN_MODE_MODIFY_ACK state to BORKEN state"},
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200143 [BTS_CTR_LCHAN_BORKEN_FROM_UNKNOWN] = {"lchan_borken:from_state:unknown", "Transitions from an unknown lchan state to BORKEN state"},
144 [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_ACK] = {"lchan_borken:event:chan_activ_ack", "CHAN_ACTIV_ACK received in the lchan BORKEN state"},
145 [BTS_CTR_LCHAN_BORKEN_EV_CHAN_ACTIV_NACK] = {"lchan_borken:event:chan_activ_nack", "CHAN_ACTIV_NACK received in the lchan BORKEN state"},
146 [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"},
147 [BTS_CTR_LCHAN_BORKEN_EV_VTY] = {"lchan_borken:event:vty", "VTY commands received in the lchan BORKEN state"},
148 [BTS_CTR_LCHAN_BORKEN_EV_TEARDOWN] = {"lchan_borken:event:teardown", "lchan in a BORKEN state is shutting down (BTS disconnected?)"},
149 [BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED] = {"ts_borken:from_state:not_initialized", "Transitions from TS NOT_INITIALIZED state to BORKEN state"},
150 [BTS_CTR_TS_BORKEN_FROM_UNUSED] = {"ts_borken:from_state:unused", "Transitions from TS UNUSED state to BORKEN state"},
151 [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"},
152 [BTS_CTR_TS_BORKEN_FROM_PDCH] = {"ts_borken:from_state:pdch", "Transitions from TS PDCH state to BORKEN state"},
153 [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"},
154 [BTS_CTR_TS_BORKEN_FROM_IN_USE] = {"ts_borken:from_state:in_use", "Transitions from TS IN_USE state to BORKEN state"},
155 [BTS_CTR_TS_BORKEN_FROM_BORKEN] = {"ts_borken:from_state:borken", "Transitions from TS BORKEN state to BORKEN state"},
156 [BTS_CTR_TS_BORKEN_FROM_UNKNOWN] = {"ts_borken:from_state:unknown", "Transitions from an unknown TS state to BORKEN state"},
157 [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"},
158 [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"},
159 [BTS_CTR_TS_BORKEN_EV_TEARDOWN] = {"ts_borken:event:teardown", "TS in a BORKEN state is shutting down (BTS disconnected?)"},
160 [BTS_CTR_ASSIGNMENT_ATTEMPTED] = {"assignment:attempted", "Assignment attempts"},
161 [BTS_CTR_ASSIGNMENT_COMPLETED] = {"assignment:completed", "Assignment completed"},
162 [BTS_CTR_ASSIGNMENT_STOPPED] = {"assignment:stopped", "Connection ended during Assignment"},
163 [BTS_CTR_ASSIGNMENT_NO_CHANNEL] = {"assignment:no_channel", "Failure to allocate lchan for Assignment"},
164 [BTS_CTR_ASSIGNMENT_TIMEOUT] = {"assignment:timeout", "Assignment timed out"},
165 [BTS_CTR_ASSIGNMENT_FAILED] = {"assignment:failed", "Received Assignment Failure message"},
166 [BTS_CTR_ASSIGNMENT_ERROR] = {"assignment:error", "Assignment failed for other reason"},
167
Daniel Willmann02f0b302020-08-17 17:09:41 +0200168 [BTS_CTR_HANDOVER_ATTEMPTED] = {"handover:attempted", "Intra-BSC handover attempts"},
169 [BTS_CTR_HANDOVER_COMPLETED] = {"handover:completed", "Intra-BSC handover completed"},
170 [BTS_CTR_HANDOVER_STOPPED] = {"handover:stopped", "Connection ended during HO"},
171 [BTS_CTR_HANDOVER_NO_CHANNEL] = {"handover:no_channel", "Failure to allocate lchan for HO"},
172 [BTS_CTR_HANDOVER_TIMEOUT] = {"handover:timeout", "Handover timed out"},
173 [BTS_CTR_HANDOVER_FAILED] = {"handover:failed", "Received Handover Fail messages"},
174 [BTS_CTR_HANDOVER_ERROR] = {"handover:error", "Re-assignment failed for other reason"},
175
Daniel Willmannbf2a4b62020-08-20 15:25:37 +0200176 [BTS_CTR_INTRA_CELL_HO_ATTEMPTED] = {"intra_cell_ho:attempted", "Intra-Cell handover attempts"},
177 [BTS_CTR_INTRA_CELL_HO_COMPLETED] = {"intra_cell_ho:completed", "Intra-Cell handover completed"},
178 [BTS_CTR_INTRA_CELL_HO_STOPPED] = {"intra_cell_ho:stopped", "Connection ended during HO"},
179 [BTS_CTR_INTRA_CELL_HO_NO_CHANNEL] = {"intra_cell_ho:no_channel", "Failure to allocate lchan for HO"},
180 [BTS_CTR_INTRA_CELL_HO_TIMEOUT] = {"intra_cell_ho:timeout", "Handover timed out"},
181 [BTS_CTR_INTRA_CELL_HO_FAILED] = {"intra_cell_ho:failed", "Received Handover Fail messages"},
182 [BTS_CTR_INTRA_CELL_HO_ERROR] = {"intra_cell_ho:error", "Re-assignment failed for other reason"},
183
184 [BTS_CTR_INTRA_BSC_HO_ATTEMPTED] = {"intra_bsc_ho:attempted", "Intra-BSC handover attempts"},
185 [BTS_CTR_INTRA_BSC_HO_COMPLETED] = {"intra_bsc_ho:completed", "Intra-BSC handover completed"},
186 [BTS_CTR_INTRA_BSC_HO_STOPPED] = {"intra_bsc_ho:stopped", "Connection ended during HO"},
187 [BTS_CTR_INTRA_BSC_HO_NO_CHANNEL] = {"intra_bsc_ho:no_channel", "Failure to allocate lchan for HO"},
188 [BTS_CTR_INTRA_BSC_HO_TIMEOUT] = {"intra_bsc_ho:timeout", "Handover timed out"},
189 [BTS_CTR_INTRA_BSC_HO_FAILED] = {"intra_bsc_ho:failed", "Received Handover Fail messages"},
190 [BTS_CTR_INTRA_BSC_HO_ERROR] = {"intra_bsc_ho:error", "Re-assignment failed for other reason"},
191
Daniel Willmann02f0b302020-08-17 17:09:41 +0200192 [BTS_CTR_INTER_BSC_HO_OUT_ATTEMPTED] = {"interbsc_ho_out:attempted",
193 "Attempts to handover to remote BSS"},
194 [BTS_CTR_INTER_BSC_HO_OUT_COMPLETED] = {"interbsc_ho_out:completed",
195 "Handover to remote BSS completed"},
196 [BTS_CTR_INTER_BSC_HO_OUT_STOPPED] = {"interbsc_ho_out:stopped", "Connection ended during HO"},
197 [BTS_CTR_INTER_BSC_HO_OUT_TIMEOUT] = {"interbsc_ho_out:timeout", "Handover timed out"},
Neels Hofmeyrdbe59f62020-08-29 03:23:31 +0000198 [BTS_CTR_INTER_BSC_HO_OUT_FAILED] = {"interbsc_ho_out:failed", "Received Handover Fail message"},
Daniel Willmann02f0b302020-08-17 17:09:41 +0200199 [BTS_CTR_INTER_BSC_HO_OUT_ERROR] = {"interbsc_ho_out:error",
200 "Handover to remote BSS failed for other reason"},
201
202 [BTS_CTR_INTER_BSC_HO_IN_ATTEMPTED] = {"interbsc_ho_in:attempted",
203 "Attempts to handover from remote BSS"},
204 [BTS_CTR_INTER_BSC_HO_IN_COMPLETED] = {"interbsc_ho_in:completed",
205 "Handover from remote BSS completed"},
206 [BTS_CTR_INTER_BSC_HO_IN_STOPPED] = {"interbsc_ho_in:stopped", "Connection ended during HO"},
207 [BTS_CTR_INTER_BSC_HO_IN_NO_CHANNEL] = {"interbsc_ho_in:no_channel",
208 "Failure to allocate lchan for HO"},
209 [BTS_CTR_INTER_BSC_HO_IN_TIMEOUT] = {"interbsc_ho_in:timeout", "Handover from remote BSS timed out"},
210 [BTS_CTR_INTER_BSC_HO_IN_FAILED] = {"interbsc_ho_in:failed", "Received Handover Fail message"},
211 [BTS_CTR_INTER_BSC_HO_IN_ERROR] = {"interbsc_ho_in:error",
212 "Handover from remote BSS failed for other reason"},
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200213};
214
215static const struct rate_ctr_group_desc bts_ctrg_desc = {
216 "bts",
217 "base transceiver station",
218 OSMO_STATS_CLASS_GLOBAL,
219 ARRAY_SIZE(bts_ctr_description),
220 bts_ctr_description,
221};
222
223enum {
224 BTS_STAT_CHAN_LOAD_AVERAGE,
225 BTS_STAT_CHAN_CCCH_SDCCH4_USED,
226 BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL,
227 BTS_STAT_CHAN_TCH_F_USED,
228 BTS_STAT_CHAN_TCH_F_TOTAL,
229 BTS_STAT_CHAN_TCH_H_USED,
230 BTS_STAT_CHAN_TCH_H_TOTAL,
231 BTS_STAT_CHAN_SDCCH8_USED,
232 BTS_STAT_CHAN_SDCCH8_TOTAL,
233 BTS_STAT_CHAN_TCH_F_PDCH_USED,
234 BTS_STAT_CHAN_TCH_F_PDCH_TOTAL,
235 BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED,
236 BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL,
237 BTS_STAT_CHAN_SDCCH8_CBCH_USED,
238 BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL,
239 BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED,
240 BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL,
241 BTS_STAT_T3122,
242 BTS_STAT_RACH_BUSY,
243 BTS_STAT_RACH_ACCESS,
244 BTS_STAT_OML_CONNECTED,
245 BTS_STAT_RSL_CONNECTED,
246 BTS_STAT_LCHAN_BORKEN,
247 BTS_STAT_TS_BORKEN,
248};
249
Daniel Willmannbf2a4b62020-08-20 15:25:37 +0200250static const struct osmo_stat_item_desc bts_stat_desc[] = {
251 [BTS_STAT_CHAN_LOAD_AVERAGE] = { "chanloadavg", "Channel load average", "%", 16, 0 },
252 [BTS_STAT_CHAN_CCCH_SDCCH4_USED] = { "chan_ccch_sdcch4:used",
253 "Number of CCCH+SDCCH4 channels used", "", 16, 0 },
254 [BTS_STAT_CHAN_CCCH_SDCCH4_TOTAL] = { "chan_ccch_sdcch4:total",
255 "Number of CCCH+SDCCH4 channels total", "", 16, 0 },
256 [BTS_STAT_CHAN_TCH_F_USED] = { "chan_tch_f:used",
257 "Number of TCH/F channels used", "", 16, 0 },
258 [BTS_STAT_CHAN_TCH_F_TOTAL] = { "chan_tch_f:total",
259 "Number of TCH/F channels total", "", 16, 0 },
260 [BTS_STAT_CHAN_TCH_H_USED] = { "chan_tch_h:used",
261 "Number of TCH/H channels used", "", 16, 0 },
262 [BTS_STAT_CHAN_TCH_H_TOTAL] = { "chan_tch_h:total",
263 "Number of TCH/H channels total", "", 16, 0 },
264 [BTS_STAT_CHAN_SDCCH8_USED] = { "chan_sdcch8:used",
265 "Number of SDCCH8 channels used", "", 16, 0 },
266 [BTS_STAT_CHAN_SDCCH8_TOTAL] = { "chan_sdcch8:total",
267 "Number of SDCCH8 channels total", "", 16, 0 },
268 [BTS_STAT_CHAN_TCH_F_PDCH_USED] = { "chan_tch_f_pdch:used",
269 "Number of TCH/F_PDCH channels used", "", 16, 0 },
270 [BTS_STAT_CHAN_TCH_F_PDCH_TOTAL] = { "chan_tch_f_pdch:total",
271 "Number of TCH/F_PDCH channels total", "", 16, 0 },
272 [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED] = { "chan_ccch_sdcch4_cbch:used",
273 "Number of CCCH+SDCCH4+CBCH channels used", "", 16, 0 },
274 [BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_TOTAL] = { "chan_ccch_sdcch4_cbch:total",
275 "Number of CCCH+SDCCH4+CBCH channels total", "", 16, 0 },
276 [BTS_STAT_CHAN_SDCCH8_CBCH_USED] = { "chan_sdcch8_cbch:used",
277 "Number of SDCCH8+CBCH channels used", "", 16, 0 },
278 [BTS_STAT_CHAN_SDCCH8_CBCH_TOTAL] = { "chan_sdcch8_cbch:total",
279 "Number of SDCCH8+CBCH channels total", "", 16, 0 },
280 [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_USED] = { "chan_tch_f_tch_h_pdch:used",
281 "Number of TCH/F_TCH/H_PDCH channels used", "", 16, 0 },
282 [BTS_STAT_CHAN_TCH_F_TCH_H_PDCH_TOTAL] = { "chan_tch_f_tch_h_pdch:total",
283 "Number of TCH/F_TCH/H_PDCH channels total", "", 16, 0 },
284 [BTS_STAT_T3122] = { "T3122", "T3122 IMMEDIATE ASSIGNMENT REJECT wait indicator",
285 "s", 16, GSM_T3122_DEFAULT },
286 [BTS_STAT_RACH_BUSY] = { "rach_busy",
287 "RACH slots with signal above threshold", "%", 16, 0 },
288 [BTS_STAT_RACH_ACCESS] = { "rach_access",
289 "RACH slots with access bursts in them", "%", 16, 0 },
290 [BTS_STAT_OML_CONNECTED] = { "oml_connected", "Number of OML links connected", "", 16, 0 },
291 [BTS_STAT_RSL_CONNECTED] = { "rsl_connected", "Number of RSL links connected", "", 16, 0 },
292 [BTS_STAT_LCHAN_BORKEN] = { "lchan_borken",
293 "Number of lchans in the BORKEN state", "", 16, 0 },
294 [BTS_STAT_TS_BORKEN] = { "ts_borken",
295 "Number of timeslots in the BORKEN state", "", 16, 0 },
296};
297
298static const struct osmo_stat_item_group_desc bts_statg_desc = {
299 .group_name_prefix = "bts",
300 .group_description = "base transceiver station",
301 .class_id = OSMO_STATS_CLASS_GLOBAL,
302 .num_items = ARRAY_SIZE(bts_stat_desc),
303 .item_desc = bts_stat_desc,
304};
305
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200306enum gsm_bts_type {
307 GSM_BTS_TYPE_UNKNOWN,
308 GSM_BTS_TYPE_BS11,
309 GSM_BTS_TYPE_NANOBTS,
310 GSM_BTS_TYPE_RBS2000,
311 GSM_BTS_TYPE_NOKIA_SITE,
312 GSM_BTS_TYPE_OSMOBTS,
313 _NUM_GSM_BTS_TYPE
314};
315extern const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1];
316extern const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1];
317
318enum gsm_bts_type_variant {
319 BTS_UNKNOWN,
320 BTS_OSMO_LITECELL15,
321 BTS_OSMO_OCTPHY,
322 BTS_OSMO_SYSMO,
323 BTS_OSMO_TRX,
324 _NUM_BTS_VARIANT
325};
326
327/* Used by OML layer for BTS Attribute reporting */
328enum bts_attribute {
329 BTS_TYPE_VARIANT,
330 BTS_SUB_MODEL,
331 TRX_PHY_VERSION,
332};
333
334struct vty;
335
336struct gsm_bts_model {
337 struct llist_head list;
338
339 enum gsm_bts_type type;
340 enum gsm_bts_type_variant variant;
341 const char *name;
342
343 bool started;
344 int (*start)(struct gsm_network *net);
345 int (*oml_rcvmsg)(struct msgb *msg);
346 char * (*oml_status)(const struct gsm_bts *bts);
347
348 void (*e1line_bind_ops)(struct e1inp_line *line);
349
350 void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);
351 void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);
352 void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts);
353
354 /* Should SI2bis and SI2ter be disabled by default on this BTS model? */
355 bool force_combined_si;
356
357 struct tlv_definition nm_att_tlvdef;
358
359 /* features of a given BTS model set via gsm_bts_model_register() locally */
360 struct bitvec features;
361 uint8_t _features_data[MAX_BTS_FEATURES/8];
362};
363
Pau Espin Pedrol4338de52020-09-30 12:52:04 +0200364/* BTS Site Manager */
365struct gsm_bts_sm {
366 struct gsm_abis_mo mo;
367};
368
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200369/* One BTS */
370struct gsm_bts {
371 /* list header in net->bts_list */
372 struct llist_head list;
373
374 /* Geographical location of the BTS */
375 struct llist_head loc_list;
376
377 /* number of this BTS in network */
378 uint8_t nr;
379 /* human readable name / description */
380 char *description;
381 /* Cell Identity */
382 uint16_t cell_identity;
383 /* location area code of this BTS */
384 uint16_t location_area_code;
385 /* Base Station Identification Code (BSIC), lower 3 bits is BCC,
386 * which is used as TSC for the CCCH */
387 uint8_t bsic;
388 /* type of BTS */
389 enum gsm_bts_type type;
390 enum gsm_bts_type_variant variant;
391 struct gsm_bts_model *model;
392 enum gsm_band band;
393 char version[MAX_VERSION_LENGTH];
394 char sub_model[MAX_VERSION_LENGTH];
395
396 /* features of a given BTS set/reported via OML */
397 struct bitvec features;
398 uint8_t _features_data[MAX_BTS_FEATURES/8];
399
400 /* Connected PCU version (if any) */
401 char pcu_version[MAX_VERSION_LENGTH];
402
403 /* maximum Tx power that the MS is permitted to use in this cell */
404 int ms_max_power;
405
406 /* how do we talk OML with this TRX? */
407 struct gsm_e1_subslot oml_e1_link;
408 uint8_t oml_tei;
409 struct e1inp_sign_link *oml_link;
410 /* Timer to use for deferred drop of OML link, see \ref ipaccess_drop_oml_deferred */
411 struct osmo_timer_list oml_drop_link_timer;
412 /* when OML link was established */
413 time_t uptime;
414
415 /* Abis network management O&M handle */
416 struct abis_nm_h *nmh;
417
418 struct gsm_abis_mo mo;
419
420 /* number of this BTS on given E1 link */
421 uint8_t bts_nr;
422
423 /* DTX features of this BTS */
424 enum gsm48_dtx_mode dtxu;
425 bool dtxd;
426
427 /* paging state and control */
428 struct gsm_bts_paging_state paging;
429
430 /* CCCH is on C0 */
431 struct gsm_bts_trx *c0;
432
Pau Espin Pedrol4338de52020-09-30 12:52:04 +0200433 struct gsm_bts_sm site_mgr;
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200434
435 /* bitmask of all SI that are present/valid in si_buf */
436 uint32_t si_valid;
437 /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
438 uint8_t si2q_index; /* distinguish individual SI2quater messages */
439 uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
440 /* buffers where we put the pre-computed SI */
441 sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
442 /* offsets used while generating SI2quater */
443 size_t e_offset;
444 size_t u_offset;
445 /* 3GPP TS 08.58 §8.5.1 BCCH INFORMATION. Some nanoBTS fail upon
446 * receival of empty SI disabling unsupported SI. see OS#3707. */
447 bool si_unused_send_empty;
448
449 /* ip.access Unit ID's have Site/BTS/TRX layout */
450 union {
451 struct {
452 uint16_t site_id;
453 uint16_t bts_id;
454 uint32_t flags;
455 uint32_t rsl_ip;
456 } ip_access;
457 struct {
458 struct {
459 struct gsm_abis_mo mo;
460 } cclk;
461 struct {
462 struct gsm_abis_mo mo;
463 } rack;
464 struct gsm_envabtse envabtse[4];
465 } bs11;
466 struct {
467 struct {
468 struct om2k_mo om2k_mo;
469 struct gsm_abis_mo mo;
470 struct llist_head conn_groups;
471 } cf;
472 struct {
473 struct om2k_mo om2k_mo;
474 struct gsm_abis_mo mo;
475 struct llist_head conn_groups;
476 } is;
477 struct {
478 struct om2k_mo om2k_mo;
479 struct gsm_abis_mo mo;
480 struct llist_head conn_groups;
481 } con;
482 struct {
483 struct om2k_mo om2k_mo;
484 struct gsm_abis_mo mo;
485 } dp;
486 struct {
487 struct om2k_mo om2k_mo;
488 struct gsm_abis_mo mo;
489 } tf;
490 struct {
491 struct om2k_mo om2k_mo;
492 struct gsm_abis_mo mo;
493 } mctr;
494 uint32_t use_superchannel:1;
495 struct {
496 uint16_t limit;
497 uint16_t active;
498 } om2k_version[16];
499 } rbs2000;
500 struct {
501 uint8_t bts_type;
502 unsigned int configured:1, /* we sent the config data request */
503 skip_reset:1, /* skip reset at bootstrap */
504 no_loc_rel_cnf:1, /* don't wait for RSL REL CONF */
505 bts_reset_timer_cnf, /* timer for BTS RESET */
506 did_reset:1, /* we received a RESET ACK */
507 wait_reset:2; /* we are waiting for reset to complete */
508 struct osmo_timer_list reset_timer;
509 } nokia;
510 };
511
512 /* Not entirely sure how ip.access specific this is */
513 struct {
514 enum bts_gprs_mode mode;
515 struct {
516 struct gsm_abis_mo mo;
517 uint16_t nsei;
518 uint8_t timer[7];
519 } nse;
520 struct {
521 struct gsm_abis_mo mo;
522 uint16_t bvci;
523 uint8_t timer[11];
524 struct gprs_rlc_cfg rlc_cfg;
525 } cell;
526 struct gsm_bts_gprs_nsvc nsvc[2];
527 uint8_t rac;
528 uint8_t net_ctrl_ord;
529 bool ctrl_ack_type_use_block;
530 bool egprs_pkt_chan_request;
531 } gprs;
532
533 /* threshold (in percent) when BTS shall send CCCH LOAD IND */
534 int ccch_load_ind_thresh;
535
536 /* RACH NM values */
537 int rach_b_thresh;
538 int rach_ldavg_slots;
539
540 /* transceivers */
541 int num_trx;
542 struct llist_head trx_list;
543
544 /* SI related items */
545 int force_combined_si;
546 bool force_combined_si_set;
547 int bcch_change_mark;
548
549 /* Abis NM queue */
550 struct llist_head abis_queue;
551 int abis_nm_pend;
552
553 struct gsm_network *network;
554
555 /* should the channel allocator allocate channels from high TRX to TRX0,
556 * rather than starting from TRX0 and go upwards? */
557 int chan_alloc_reverse;
558
559 enum neigh_list_manual_mode neigh_list_manual_mode;
560 /* parameters from which we build SYSTEM INFORMATION */
561 struct {
562 struct gsm48_rach_control rach_control;
563 uint8_t ncc_permitted;
564 struct gsm48_cell_sel_par cell_sel_par;
565 struct gsm48_si_selection_params cell_ro_sel_par; /* rest octet */
566 struct gsm48_cell_options cell_options;
567 struct gsm48_control_channel_descr chan_desc;
568 struct bitvec neigh_list;
569 struct bitvec cell_alloc;
570 struct bitvec si5_neigh_list;
571 struct osmo_earfcn_si2q si2quater_neigh_list;
572 size_t uarfcn_length; /* index for uarfcn and scramble lists */
573 struct {
574 /* bitmask large enough for all possible ARFCN's */
575 uint8_t neigh_list[1024/8];
576 uint8_t cell_alloc[1024/8];
577 /* If the user wants a different neighbor list in SI5 than in SI2 */
578 uint8_t si5_neigh_list[1024/8];
579 uint8_t meas_bw_list[MAX_EARFCN_LIST];
580 uint16_t earfcn_list[MAX_EARFCN_LIST];
581 uint16_t uarfcn_list[MAX_EARFCN_LIST];
582 uint16_t scramble_list[MAX_EARFCN_LIST];
583 } data;
584 } si_common;
585 bool early_classmark_allowed;
586 bool early_classmark_allowed_3g;
587 /* for testing only: Have an infinitely long radio link timeout */
588 bool infinite_radio_link_timeout;
589
590 /* do we use static (user-defined) system information messages? (bitmask) */
591 uint32_t si_mode_static;
592
593 /* access control class ramping */
Pau Espin Pedroldeaa6fd2020-07-16 20:53:21 +0200594 struct acc_mgr acc_mgr;
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200595 struct acc_ramp acc_ramp;
596
597 /* exclude the BTS from the global RF Lock handling */
598 int excl_from_rf_lock;
599
600 /* supported codecs beside FR */
601 struct bts_codec_conf codec;
602
603 /* BTS dependencies bit field */
604 uint32_t depends_on[256/(8*4)];
605
606 /* full and half rate multirate config */
607 struct amr_multirate_conf mr_full;
608 struct amr_multirate_conf mr_half;
609
610 /* PCU socket state */
611 char *pcu_sock_path;
612 struct pcu_sock_state *pcu_state;
613
614 struct rate_ctr_group *bts_ctrs;
615 struct osmo_stat_item_group *bts_statg;
616
617 struct handover_cfg *ho;
618
619 /* A list of struct gsm_bts_ref, indicating neighbors of this BTS.
620 * When the si_common neigh_list is in automatic mode, it is populated from this list as well as
621 * gsm_network->neighbor_bss_cells. */
622 struct llist_head local_neighbors;
623
624 /* BTS-specific overrides for timer values from struct gsm_network. */
625 uint8_t T3122; /* ASSIGNMENT REJECT wait indication */
626 bool T3113_dynamic; /* Calculate T3113 timeout dynamically based on BTS channel config and load */
627
628 /* Periodic channel load measurements are used to maintain T3122. */
629 struct load_counter chan_load_samples[7];
630 int chan_load_samples_idx;
631 uint8_t chan_load_avg; /* current channel load average in percent (0 - 100). */
632
633 /* cell broadcast system */
634 struct osmo_timer_list cbch_timer;
635 struct bts_smscb_chan_state cbch_basic;
636 struct bts_smscb_chan_state cbch_extended;
637 struct osmo_timer_list etws_timer; /* when to stop ETWS PN */
638
639 struct llist_head oml_fail_rep;
Philipp Maiercc6d35d2020-08-21 22:40:23 +0200640 struct llist_head chan_rqd_queue;
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200641};
642
643#define GSM_BTS_SI2Q(bts, i) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
644#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
645#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
646
647/* this actually refers to the IPA transport, not the BTS model */
648static inline int is_ipaccess_bts(const struct gsm_bts *bts)
649{
650 switch (bts->type) {
651 case GSM_BTS_TYPE_NANOBTS:
652 case GSM_BTS_TYPE_OSMOBTS:
653 return 1;
654 default:
655 break;
656 }
657 return 0;
658}
659
660static inline int is_sysmobts_v2(const struct gsm_bts *bts)
661{
662 switch (bts->type) {
663 case GSM_BTS_TYPE_OSMOBTS:
664 return 1;
665 default:
666 break;
667 }
668 return 0;
669}
670
671static inline int is_siemens_bts(const struct gsm_bts *bts)
672{
673 switch (bts->type) {
674 case GSM_BTS_TYPE_BS11:
675 return 1;
676 default:
677 break;
678 }
679
680 return 0;
681}
682
683static inline int is_nokia_bts(const struct gsm_bts *bts)
684{
685 switch (bts->type) {
686 case GSM_BTS_TYPE_NOKIA_SITE:
687 return 1;
688 default:
689 break;
690 }
691
692 return 0;
693}
694
695static inline int is_ericsson_bts(const struct gsm_bts *bts)
696{
697 switch (bts->type) {
698 case GSM_BTS_TYPE_RBS2000:
699 return 1;
700 default:
701 break;
702 }
703
704 return 0;
705}
706
707static inline int is_e1_bts(const struct gsm_bts *bts)
708{
709 switch (bts->type) {
710 case GSM_BTS_TYPE_BS11:
711 case GSM_BTS_TYPE_RBS2000:
712 case GSM_BTS_TYPE_NOKIA_SITE:
713 return 1;
714 default:
715 break;
716 }
717
718 return 0;
719}
720
721static inline const struct osmo_location_area_id *bts_lai(struct gsm_bts *bts)
722{
723 static struct osmo_location_area_id lai;
724 lai = (struct osmo_location_area_id){
725 .plmn = bts->network->plmn,
726 .lac = bts->location_area_code,
727 };
728 return &lai;
729}
730
Pau Espin Pedrol4338de52020-09-30 12:52:04 +0200731static inline struct gsm_bts *gsm_bts_sm_get_bts(struct gsm_bts_sm *site_mgr) {
732 return (struct gsm_bts *)container_of(site_mgr, struct gsm_bts, site_mgr);
733}
734
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200735struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num);
736
737char *gsm_bts_name(const struct gsm_bts *bts);
738
739bool gsm_bts_matches_lai(const struct gsm_bts *bts, const struct osmo_location_area_id *lai);
740bool gsm_bts_matches_cell_id(const struct gsm_bts *bts, const struct gsm0808_cell_id *cell_id);
741
742int gsm_bts_local_neighbor_add(struct gsm_bts *bts, struct gsm_bts *neighbor);
743int gsm_bts_local_neighbor_del(struct gsm_bts *bts, const struct gsm_bts *neighbor);
744
745/* return the gsm_lchan for the CBCH (if it exists at all) */
746struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
747
748int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
749
Pau Espin Pedrole2f1c952020-07-16 14:20:32 +0200750struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num);
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200751
752int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);
753
754unsigned long long bts_uptime(const struct gsm_bts *bts);
755
756char *get_model_oml_status(const struct gsm_bts *bts);
757/* reset the state of all MO in the BTS */
758void gsm_bts_mo_reset(struct gsm_bts *bts);
759
760/* dependency handling */
761void bts_depend_mark(struct gsm_bts *bts, int dep);
762void bts_depend_clear(struct gsm_bts *bts, int dep);
763int bts_depend_check(struct gsm_bts *bts);
764int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other);
765
766int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts);
767void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value);
768
769void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data);
770
771int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);
772
Pau Espin Pedrol8d4f94a2020-07-16 15:17:20 +0200773int gsm_bts_set_system_infos(struct gsm_bts *bts);
774
Pau Espin Pedrol388ed582020-07-15 20:53:16 +0200775int gsm_bts_model_register(struct gsm_bts_model *model);
776struct gsm_bts_model *bts_model_find(enum gsm_bts_type type);
777
778enum gsm_bts_type str2btstype(const char *arg);
779const char *btstype2str(enum gsm_bts_type type);
780
781enum bts_attribute str2btsattr(const char *s);
782const char *btsatttr2str(enum bts_attribute v);
783
784enum gsm_bts_type_variant str2btsvariant(const char *arg);
785const char *btsvariant2str(enum gsm_bts_type_variant v);