blob: 6592caeede59132e36382207db92b18fc83ea7f3 [file] [log] [blame]
Andreas Eversberg12942562012-07-12 14:31:57 +02001/* OsmoBTS VTY interface */
2
Andreas Eversberg12942562012-07-12 14:31:57 +02003
Andreas Eversberg8b761a32012-07-20 21:50:31 +02004#include <stdint.h>
Holger Hans Peter Freyther2c98f1d2014-07-02 14:56:36 +02005#include <stdlib.h>
Neels Hofmeyrd34646a2017-02-08 17:07:40 +01006#include <string.h>
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +02007#include <osmocom/core/tdef.h>
8#include <osmocom/vty/tdef_vty.h>
Andreas Eversberg12942562012-07-12 14:31:57 +02009#include <osmocom/vty/logging.h>
Jacob Erlbeck42aba812015-11-10 15:32:00 +010010#include <osmocom/vty/stats.h>
Jacob Erlbeckc0c580c2015-04-30 15:59:01 +020011#include <osmocom/vty/misc.h>
Andreas Eversberg8b761a32012-07-20 21:50:31 +020012#include <osmocom/core/linuxlist.h>
Holger Hans Peter Freythere8915b92014-07-02 14:57:47 +020013#include <osmocom/core/rate_ctr.h>
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +020014#include <osmocom/pcu/pcuif_proto.h>
Andreas Eversberg12942562012-07-12 14:31:57 +020015#include "pcu_vty.h"
Andreas Eversberg8b761a32012-07-20 21:50:31 +020016#include "gprs_rlcmac.h"
Max6dc90b82018-02-19 17:17:28 +010017#include <pdch.h>
Holger Hans Peter Freyther67ed34e2013-10-17 17:01:54 +020018#include "bts.h"
Jacob Erlbeckc0c580c2015-04-30 15:59:01 +020019#include "tbf.h"
Jacob Erlbeck62e96a32015-06-04 09:42:14 +020020#include "pcu_vty_functions.h"
21
Harald Welte717cdf52017-07-21 21:56:23 +020022extern void *tall_pcu_ctx;
23
24static const struct value_string pcu_gsmtap_categ_names[] = {
25 { PCU_GSMTAP_C_DL_UNKNOWN, "dl-unknown" },
26 { PCU_GSMTAP_C_DL_DUMMY, "dl-dummy" },
27 { PCU_GSMTAP_C_DL_CTRL, "dl-ctrl" },
28 { PCU_GSMTAP_C_DL_DATA_GPRS, "dl-data-gprs" },
29 { PCU_GSMTAP_C_DL_DATA_EGPRS, "dl-data-egprs" },
Harald Weltebc219d52017-07-29 13:42:27 +020030 { PCU_GSMTAP_C_DL_PTCCH, "dl-ptcch" },
Harald Welte717cdf52017-07-21 21:56:23 +020031
32 { PCU_GSMTAP_C_UL_UNKNOWN, "ul-unknown" },
33 { PCU_GSMTAP_C_UL_DUMMY, "ul-dummy" },
34 { PCU_GSMTAP_C_UL_CTRL, "ul-ctrl" },
35 { PCU_GSMTAP_C_UL_DATA_GPRS, "ul-data-gprs" },
36 { PCU_GSMTAP_C_UL_DATA_EGPRS, "ul-data-egprs" },
37
38 { 0, NULL }
39};
40
41static const struct value_string pcu_gsmtap_categ_help[] = {
42 { PCU_GSMTAP_C_DL_UNKNOWN, "Unknown / Unparseable / Erroneous Downlink Blocks" },
43 { PCU_GSMTAP_C_DL_DUMMY, "Downlink Dummy Blocks" },
44 { PCU_GSMTAP_C_DL_CTRL, "Downlink Control Blocks" },
45 { PCU_GSMTAP_C_DL_DATA_GPRS, "Downlink Data Blocks (GPRS)" },
46 { PCU_GSMTAP_C_DL_DATA_EGPRS, "Downlink Data Blocks (EGPRS)" },
Harald Weltebc219d52017-07-29 13:42:27 +020047 { PCU_GSMTAP_C_DL_PTCCH, "Downlink PTCCH Blocks" },
Harald Welte717cdf52017-07-21 21:56:23 +020048
49 { PCU_GSMTAP_C_UL_UNKNOWN, "Unknown / Unparseable / Erroneous Downlink Blocks" },
50 { PCU_GSMTAP_C_UL_DUMMY, "Uplink Dummy Blocks" },
51 { PCU_GSMTAP_C_UL_CTRL, "Uplink Control Blocks" },
52 { PCU_GSMTAP_C_UL_DATA_GPRS, "Uplink Data Blocks (GPRS)" },
53 { PCU_GSMTAP_C_UL_DATA_EGPRS, "Uplink Data Blocks (EGPRS)" },
54
55 { 0, NULL }
56};
57
58
59DEFUN(cfg_pcu_gsmtap_categ, cfg_pcu_gsmtap_categ_cmd, "HIDDEN", "HIDDEN")
60{
61 struct gprs_rlcmac_bts *bts = bts_main_data();
62 int categ;
63
64 categ = get_string_value(pcu_gsmtap_categ_names, argv[0]);
65 if (categ < 0)
66 return CMD_WARNING;
67
68 bts->gsmtap_categ_mask |= (1 << categ);
69
70 return CMD_SUCCESS;
71}
72
73DEFUN(cfg_pcu_no_gsmtap_categ, cfg_pcu_no_gsmtap_categ_cmd, "HIDDEN", "HIDDEN")
74{
75 struct gprs_rlcmac_bts *bts = bts_main_data();
76 int categ;
77
78 categ = get_string_value(pcu_gsmtap_categ_names, argv[0]);
79 if (categ < 0)
80 return CMD_WARNING;
81
82 bts->gsmtap_categ_mask &= ~(1 << categ);
83
84 return CMD_SUCCESS;
85}
86
87
Jacob Erlbeckf76fede2015-08-17 13:42:46 +020088int pcu_vty_go_parent(struct vty *vty)
Andreas Eversberg12942562012-07-12 14:31:57 +020089{
90 switch (vty->node) {
91#if 0
92 case TRX_NODE:
Andreas Eversberg8b761a32012-07-20 21:50:31 +020093 vty->node = PCU_NODE;
Andreas Eversberg12942562012-07-12 14:31:57 +020094 {
95 struct gsm_bts_trx *trx = vty->index;
96 vty->index = trx->bts;
97 }
98 break;
99#endif
100 default:
101 vty->node = CONFIG_NODE;
102 }
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200103 return (enum node_type) vty->node;
Andreas Eversberg12942562012-07-12 14:31:57 +0200104}
105
106int pcu_vty_is_config_node(struct vty *vty, int node)
107{
108 switch (node) {
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200109 case PCU_NODE:
Andreas Eversberg12942562012-07-12 14:31:57 +0200110 return 1;
Andreas Eversberg12942562012-07-12 14:31:57 +0200111 default:
112 return 0;
113 }
114}
115
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200116static struct cmd_node pcu_node = {
117 (enum node_type) PCU_NODE,
Jacob Erlbeckcc12f022015-04-09 15:45:24 +0200118 "%s(config-pcu)# ",
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200119 1,
120};
121
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200122static int config_write_pcu(struct vty *vty)
123{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200124 struct gprs_rlcmac_bts *bts = bts_main_data();
Harald Welte717cdf52017-07-21 21:56:23 +0200125 unsigned int i;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200126
127 vty_out(vty, "pcu%s", VTY_NEWLINE);
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200128 if (bts->egprs_enabled)
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +0100129 vty_out(vty, " egprs only%s", VTY_NEWLINE);
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200130
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200131 vty_out(vty, " flow-control-interval %d%s", bts->fc_interval,
132 VTY_NEWLINE);
Jacob Erlbeck87d73412015-04-21 12:56:48 +0200133 if (bts->fc_bvc_bucket_size)
134 vty_out(vty, " flow-control force-bvc-bucket-size %d%s",
135 bts->fc_bvc_bucket_size, VTY_NEWLINE);
136 if (bts->fc_bvc_leak_rate)
137 vty_out(vty, " flow-control force-bvc-leak-rate %d%s",
138 bts->fc_bvc_leak_rate, VTY_NEWLINE);
139 if (bts->fc_ms_bucket_size)
140 vty_out(vty, " flow-control force-ms-bucket-size %d%s",
141 bts->fc_ms_bucket_size, VTY_NEWLINE);
142 if (bts->fc_ms_leak_rate)
143 vty_out(vty, " flow-control force-ms-leak-rate %d%s",
144 bts->fc_ms_leak_rate, VTY_NEWLINE);
Holger Hans Peter Freytherc421e8a2014-07-02 14:55:17 +0200145 if (bts->force_cs) {
Andreas Eversberg499ff412012-10-03 14:21:36 +0200146 if (bts->initial_cs_ul == bts->initial_cs_dl)
147 vty_out(vty, " cs %d%s", bts->initial_cs_dl,
148 VTY_NEWLINE);
149 else
150 vty_out(vty, " cs %d %d%s", bts->initial_cs_dl,
151 bts->initial_cs_ul, VTY_NEWLINE);
Holger Hans Peter Freytherc421e8a2014-07-02 14:55:17 +0200152 }
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200153 if (bts->max_cs_dl && bts->max_cs_ul) {
154 if (bts->max_cs_ul == bts->max_cs_dl)
155 vty_out(vty, " cs max %d%s", bts->max_cs_dl,
156 VTY_NEWLINE);
157 else
158 vty_out(vty, " cs max %d %d%s", bts->max_cs_dl,
159 bts->max_cs_ul, VTY_NEWLINE);
160 }
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200161 if (bts->cs_adj_enabled)
162 vty_out(vty, " cs threshold %d %d%s",
163 bts->cs_adj_lower_limit, bts->cs_adj_upper_limit,
164 VTY_NEWLINE);
165 else
166 vty_out(vty, " no cs threshold%s", VTY_NEWLINE);
167
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200168 if (bts->cs_downgrade_threshold)
169 vty_out(vty, " cs downgrade-threshold %d%s",
170 bts->cs_downgrade_threshold, VTY_NEWLINE);
171 else
172 vty_out(vty, " no cs downgrade-threshold%s", VTY_NEWLINE);
173
Jacob Erlbeck94cde132015-06-09 09:44:36 +0200174 vty_out(vty, " cs link-quality-ranges cs1 %d cs2 %d %d cs3 %d %d cs4 %d%s",
175 bts->cs_lqual_ranges[0].high,
176 bts->cs_lqual_ranges[1].low,
177 bts->cs_lqual_ranges[1].high,
178 bts->cs_lqual_ranges[2].low,
179 bts->cs_lqual_ranges[2].high,
180 bts->cs_lqual_ranges[3].low,
181 VTY_NEWLINE);
182
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -0400183 vty_out(vty, " mcs link-quality-ranges mcs1 %d mcs2 %d %d mcs3 %d %d mcs4 %d %d mcs5 %d %d mcs6 %d %d mcs7 %d %d mcs8 %d %d mcs9 %d%s",
184 bts->mcs_lqual_ranges[0].high,
185 bts->mcs_lqual_ranges[1].low,
186 bts->mcs_lqual_ranges[1].high,
187 bts->mcs_lqual_ranges[2].low,
188 bts->mcs_lqual_ranges[2].high,
189 bts->mcs_lqual_ranges[3].low,
190 bts->mcs_lqual_ranges[3].high,
191 bts->mcs_lqual_ranges[4].low,
192 bts->mcs_lqual_ranges[4].high,
193 bts->mcs_lqual_ranges[5].low,
194 bts->mcs_lqual_ranges[5].high,
195 bts->mcs_lqual_ranges[6].low,
196 bts->mcs_lqual_ranges[6].high,
197 bts->mcs_lqual_ranges[7].low,
198 bts->mcs_lqual_ranges[7].high,
199 bts->mcs_lqual_ranges[8].low,
200 VTY_NEWLINE);
201
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +0100202 if (bts->initial_mcs_dl != 1 && bts->initial_mcs_ul != 1) {
203 if (bts->initial_mcs_ul == bts->initial_mcs_dl)
204 vty_out(vty, " mcs %d%s", bts->initial_mcs_dl,
205 VTY_NEWLINE);
206 else
207 vty_out(vty, " mcs %d %d%s", bts->initial_mcs_dl,
208 bts->initial_mcs_ul, VTY_NEWLINE);
209 }
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -0400210
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100211 if (bts->max_mcs_dl && bts->max_mcs_ul) {
212 if (bts->max_mcs_ul == bts->max_mcs_dl)
213 vty_out(vty, " mcs max %d%s", bts->max_mcs_dl,
214 VTY_NEWLINE);
215 else
216 vty_out(vty, " mcs max %d %d%s", bts->max_mcs_dl,
217 bts->max_mcs_ul, VTY_NEWLINE);
218 }
219
Jacob Erlbeck36df7742016-01-19 15:53:30 +0100220 vty_out(vty, " window-size %d %d%s", bts->ws_base, bts->ws_pdch,
221 VTY_NEWLINE);
222
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530223 if (bts->dl_arq_type)
224 vty_out(vty, " egprs dl arq-type arq2%s",
225 VTY_NEWLINE);
226
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200227 if (bts->force_llc_lifetime == 0xffff)
228 vty_out(vty, " queue lifetime infinite%s", VTY_NEWLINE);
229 else if (bts->force_llc_lifetime)
230 vty_out(vty, " queue lifetime %d%s", bts->force_llc_lifetime,
231 VTY_NEWLINE);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100232 if (bts->llc_discard_csec)
233 vty_out(vty, " queue hysteresis %d%s", bts->llc_discard_csec,
234 VTY_NEWLINE);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200235 if (bts->llc_idle_ack_csec)
236 vty_out(vty, " queue idle-ack-delay %d%s", bts->llc_idle_ack_csec,
237 VTY_NEWLINE);
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200238 if (bts->llc_codel_interval_msec == LLC_CODEL_USE_DEFAULT)
239 vty_out(vty, " queue codel%s", VTY_NEWLINE);
240 else if (bts->llc_codel_interval_msec == LLC_CODEL_DISABLE)
241 vty_out(vty, " no queue codel%s", VTY_NEWLINE);
242 else
243 vty_out(vty, " queue codel interval %d%s",
244 bts->llc_codel_interval_msec/10, VTY_NEWLINE);
245
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200246 if (bts->alloc_algorithm == alloc_algorithm_a)
247 vty_out(vty, " alloc-algorithm a%s", VTY_NEWLINE);
248 if (bts->alloc_algorithm == alloc_algorithm_b)
249 vty_out(vty, " alloc-algorithm b%s", VTY_NEWLINE);
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200250 if (bts->alloc_algorithm == alloc_algorithm_dynamic)
251 vty_out(vty, " alloc-algorithm dynamic%s", VTY_NEWLINE);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200252 if (bts->force_two_phase)
253 vty_out(vty, " two-phase-access%s", VTY_NEWLINE);
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200254 vty_out(vty, " alpha %d%s", bts->alpha, VTY_NEWLINE);
255 vty_out(vty, " gamma %d%s", bts->gamma * 2, VTY_NEWLINE);
Oliver Smith45fdc442019-09-05 15:12:20 +0200256 if (!bts->dl_tbf_preemptive_retransmission)
257 vty_out(vty, " no dl-tbf-preemptive-retransmission%s", VTY_NEWLINE);
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +0200258 if (strcmp(bts->pcu_sock_path, PCU_SOCK_DEFAULT))
259 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200260
Harald Welte717cdf52017-07-21 21:56:23 +0200261 for (i = 0; i < 32; i++) {
262 unsigned int cs = (1 << i);
263 if (bts->gsmtap_categ_mask & cs) {
264 vty_out(vty, " gsmtap-category %s%s",
265 get_value_string(pcu_gsmtap_categ_names, i), VTY_NEWLINE);
266 }
267 }
268
Harald Welte57d35152018-07-05 03:11:17 +0200269 if (bts->gb_dialect_sns)
270 vty_out(vty, " gb-dialect ip-sns%s", VTY_NEWLINE);
271 else
272 vty_out(vty, " gb-dialect classic%s", VTY_NEWLINE);
273
Maxc9ce6f92018-01-30 17:53:02 +0100274 return CMD_SUCCESS;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200275}
276
277/* per-BTS configuration */
278DEFUN(cfg_pcu,
279 cfg_pcu_cmd,
280 "pcu",
281 "BTS specific configure")
282{
283 vty->node = PCU_NODE;
284
285 return CMD_SUCCESS;
286}
287
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200288#define EGPRS_STR "EGPRS configuration\n"
289
290DEFUN(cfg_pcu_egprs,
291 cfg_pcu_egprs_cmd,
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +0100292 "egprs only",
293 EGPRS_STR "Use EGPRS and disable plain GPRS\n")
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200294{
295 struct gprs_rlcmac_bts *bts = bts_main_data();
296
297 bts->egprs_enabled = 1;
298
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200299 return CMD_SUCCESS;
300}
301
302DEFUN(cfg_pcu_no_egprs,
303 cfg_pcu_no_egprs_cmd,
304 "no egprs",
305 NO_STR EGPRS_STR)
306{
307 struct gprs_rlcmac_bts *bts = bts_main_data();
308
309 bts->egprs_enabled = 0;
310
311 return CMD_SUCCESS;
312}
313
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200314DEFUN(cfg_pcu_fc_interval,
315 cfg_pcu_fc_interval_cmd,
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200316 "flow-control-interval <1-10>",
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200317 "Interval between sending subsequent Flow Control PDUs\n"
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200318 "Interval time in seconds\n")
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200319{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200320 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200321
322 bts->fc_interval = atoi(argv[0]);
323
324 return CMD_SUCCESS;
325}
Jacob Erlbeck87d73412015-04-21 12:56:48 +0200326#define FC_STR "BSSGP Flow Control configuration\n"
327#define FC_BMAX_STR(who) "Force a fixed value for the " who " bucket size\n"
328#define FC_LR_STR(who) "Force a fixed value for the " who " leak rate\n"
329
330DEFUN(cfg_pcu_fc_bvc_bucket_size,
331 cfg_pcu_fc_bvc_bucket_size_cmd,
332 "flow-control force-bvc-bucket-size <1-6553500>",
333 FC_STR FC_BMAX_STR("BVC") "Bucket size in octets\n")
334{
335 struct gprs_rlcmac_bts *bts = bts_main_data();
336
337 bts->fc_bvc_bucket_size = atoi(argv[0]);
338
339 return CMD_SUCCESS;
340}
341
342DEFUN(cfg_pcu_no_fc_bvc_bucket_size,
343 cfg_pcu_no_fc_bvc_bucket_size_cmd,
344 "no flow-control force-bvc-bucket-size",
345 NO_STR FC_STR FC_BMAX_STR("BVC"))
346{
347 struct gprs_rlcmac_bts *bts = bts_main_data();
348
349 bts->fc_bvc_bucket_size = 0;
350
351 return CMD_SUCCESS;
352}
353
354DEFUN(cfg_pcu_fc_bvc_leak_rate,
355 cfg_pcu_fc_bvc_leak_rate_cmd,
356 "flow-control force-bvc-leak-rate <1-6553500>",
357 FC_STR FC_LR_STR("BVC") "Leak rate in bit/s\n")
358{
359 struct gprs_rlcmac_bts *bts = bts_main_data();
360
361 bts->fc_bvc_leak_rate = atoi(argv[0]);
362
363 return CMD_SUCCESS;
364}
365
366DEFUN(cfg_pcu_no_fc_bvc_leak_rate,
367 cfg_pcu_no_fc_bvc_leak_rate_cmd,
368 "no flow-control force-bvc-leak-rate",
369 NO_STR FC_STR FC_LR_STR("BVC"))
370{
371 struct gprs_rlcmac_bts *bts = bts_main_data();
372
373 bts->fc_bvc_leak_rate = 0;
374
375 return CMD_SUCCESS;
376}
377
378DEFUN(cfg_pcu_fc_ms_bucket_size,
379 cfg_pcu_fc_ms_bucket_size_cmd,
380 "flow-control force-ms-bucket-size <1-6553500>",
381 FC_STR FC_BMAX_STR("default MS") "Bucket size in octets\n")
382{
383 struct gprs_rlcmac_bts *bts = bts_main_data();
384
385 bts->fc_ms_bucket_size = atoi(argv[0]);
386
387 return CMD_SUCCESS;
388}
389
390DEFUN(cfg_pcu_no_fc_ms_bucket_size,
391 cfg_pcu_no_fc_ms_bucket_size_cmd,
392 "no flow-control force-ms-bucket-size",
393 NO_STR FC_STR FC_BMAX_STR("default MS"))
394{
395 struct gprs_rlcmac_bts *bts = bts_main_data();
396
397 bts->fc_ms_bucket_size = 0;
398
399 return CMD_SUCCESS;
400}
401
402DEFUN(cfg_pcu_fc_ms_leak_rate,
403 cfg_pcu_fc_ms_leak_rate_cmd,
404 "flow-control force-ms-leak-rate <1-6553500>",
405 FC_STR FC_LR_STR("default MS") "Leak rate in bit/s\n")
406{
407 struct gprs_rlcmac_bts *bts = bts_main_data();
408
409 bts->fc_ms_leak_rate = atoi(argv[0]);
410
411 return CMD_SUCCESS;
412}
413
414DEFUN(cfg_pcu_no_fc_ms_leak_rate,
415 cfg_pcu_no_fc_ms_leak_rate_cmd,
416 "no flow-control force-ms-leak-rate",
417 NO_STR FC_STR FC_LR_STR("default MS"))
418{
419 struct gprs_rlcmac_bts *bts = bts_main_data();
420
421 bts->fc_ms_leak_rate = 0;
422
423 return CMD_SUCCESS;
424}
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200425
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200426#define FC_BTIME_STR "Set target downlink maximum queueing time (only affects the advertised bucket size)\n"
427DEFUN(cfg_pcu_fc_bucket_time,
428 cfg_pcu_fc_bucket_time_cmd,
429 "flow-control bucket-time <1-65534>",
430 FC_STR FC_BTIME_STR "Time in centi-seconds\n")
431{
432 struct gprs_rlcmac_bts *bts = bts_main_data();
433
434 bts->fc_bucket_time = atoi(argv[0]);
435
436 return CMD_SUCCESS;
437}
438
439DEFUN(cfg_pcu_no_fc_bucket_time,
440 cfg_pcu_no_fc_bucket_time_cmd,
441 "no flow-control bucket-time",
442 NO_STR FC_STR FC_BTIME_STR)
443{
444 struct gprs_rlcmac_bts *bts = bts_main_data();
445
446 bts->fc_bucket_time = 0;
447
448 return CMD_SUCCESS;
449}
450
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200451#define CS_STR "Coding Scheme configuration\n"
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200452
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200453DEFUN(cfg_pcu_cs,
454 cfg_pcu_cs_cmd,
Andreas Eversberg499ff412012-10-03 14:21:36 +0200455 "cs <1-4> [<1-4>]",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200456 CS_STR
457 "Initial CS value to be used (overrides BTS config)\n"
458 "Use a different initial CS value for the uplink")
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200459{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200460 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200461 uint8_t cs = atoi(argv[0]);
462
463 bts->force_cs = 1;
Andreas Eversberg499ff412012-10-03 14:21:36 +0200464 bts->initial_cs_dl = cs;
465 if (argc > 1)
466 bts->initial_cs_ul = atoi(argv[1]);
467 else
468 bts->initial_cs_ul = cs;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200469
470 return CMD_SUCCESS;
471}
472
473DEFUN(cfg_pcu_no_cs,
474 cfg_pcu_no_cs_cmd,
475 "no cs",
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200476 NO_STR CS_STR)
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200477{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200478 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200479
480 bts->force_cs = 0;
481
482 return CMD_SUCCESS;
483}
484
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100485#define CS_MAX_STR "Set maximum values for adaptive CS selection (overrides BTS config)\n"
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200486DEFUN(cfg_pcu_cs_max,
487 cfg_pcu_cs_max_cmd,
488 "cs max <1-4> [<1-4>]",
489 CS_STR
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100490 CS_MAX_STR
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200491 "Maximum CS value to be used\n"
492 "Use a different maximum CS value for the uplink")
493{
494 struct gprs_rlcmac_bts *bts = bts_main_data();
495 uint8_t cs = atoi(argv[0]);
496
497 bts->max_cs_dl = cs;
498 if (argc > 1)
499 bts->max_cs_ul = atoi(argv[1]);
500 else
501 bts->max_cs_ul = cs;
502
503 return CMD_SUCCESS;
504}
505
506DEFUN(cfg_pcu_no_cs_max,
507 cfg_pcu_no_cs_max_cmd,
508 "no cs max",
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100509 NO_STR CS_STR CS_MAX_STR)
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200510{
511 struct gprs_rlcmac_bts *bts = bts_main_data();
512
513 bts->max_cs_dl = 0;
514 bts->max_cs_ul = 0;
515
516 return CMD_SUCCESS;
517}
518
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100519#define MCS_STR "Modulation and Coding Scheme configuration (EGPRS)\n"
520
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +0100521DEFUN(cfg_pcu_mcs,
522 cfg_pcu_mcs_cmd,
523 "mcs <1-9> [<1-9>]",
524 MCS_STR
525 "Initial MCS value to be used (default 1)\n"
526 "Use a different initial MCS value for the uplink")
527{
528 struct gprs_rlcmac_bts *bts = bts_main_data();
529 uint8_t cs = atoi(argv[0]);
530
531 bts->initial_mcs_dl = cs;
532 if (argc > 1)
533 bts->initial_mcs_ul = atoi(argv[1]);
534 else
535 bts->initial_mcs_ul = cs;
536
537 return CMD_SUCCESS;
538}
539
540DEFUN(cfg_pcu_no_mcs,
541 cfg_pcu_no_mcs_cmd,
542 "no mcs",
543 NO_STR MCS_STR)
544{
545 struct gprs_rlcmac_bts *bts = bts_main_data();
546
547 bts->initial_mcs_dl = 1;
548 bts->initial_mcs_ul = 1;
549
550 return CMD_SUCCESS;
551}
552
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100553DEFUN(cfg_pcu_mcs_max,
554 cfg_pcu_mcs_max_cmd,
Jacob Erlbeckf9940ca2016-01-19 10:32:33 +0100555 "mcs max <1-9> [<1-9>]",
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100556 MCS_STR
557 CS_MAX_STR
558 "Maximum MCS value to be used\n"
559 "Use a different maximum MCS value for the uplink")
560{
561 struct gprs_rlcmac_bts *bts = bts_main_data();
562 uint8_t mcs = atoi(argv[0]);
563
564 bts->max_mcs_dl = mcs;
565 if (argc > 1)
566 bts->max_mcs_ul = atoi(argv[1]);
567 else
568 bts->max_mcs_ul = mcs;
569
570 return CMD_SUCCESS;
571}
572
573DEFUN(cfg_pcu_no_mcs_max,
574 cfg_pcu_no_mcs_max_cmd,
575 "no mcs max",
576 NO_STR MCS_STR CS_MAX_STR)
577{
578 struct gprs_rlcmac_bts *bts = bts_main_data();
579
580 bts->max_mcs_dl = 0;
581 bts->max_mcs_ul = 0;
582
583 return CMD_SUCCESS;
584}
585
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530586#define DL_STR "downlink specific configuration\n"
587
588DEFUN(cfg_pcu_dl_arq_type,
589 cfg_pcu_dl_arq_cmd,
590 "egprs dl arq-type (spb|arq2)",
591 EGPRS_STR DL_STR "ARQ options\n"
592 "enable SPB(ARQ1) support\n"
593 "enable ARQ2 support")
594{
595 struct gprs_rlcmac_bts *bts = bts_main_data();
596
597 if (!strcmp(argv[0], "arq2"))
598 bts->dl_arq_type = 1;
599 else
600 bts->dl_arq_type = 0;
601
602 return CMD_SUCCESS;
603}
604
Jacob Erlbeck36df7742016-01-19 15:53:30 +0100605DEFUN(cfg_pcu_window_size,
606 cfg_pcu_window_size_cmd,
607 "window-size <0-1024> [<0-256>]",
608 "Window size configuration (b + N_PDCH * f)\n"
609 "Base value (b)\n"
610 "Factor for number of PDCH (f)")
611{
612 struct gprs_rlcmac_bts *bts = bts_main_data();
613 uint16_t b = atoi(argv[0]);
614
615 bts->ws_base = b;
616 if (argc > 1) {
617 uint16_t f = atoi(argv[1]);
618 bts->ws_pdch = f;
619 }
620
621 return CMD_SUCCESS;
622}
623
624
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200625#define QUEUE_STR "Packet queue options\n"
626#define LIFETIME_STR "Set lifetime limit of LLC frame in centi-seconds " \
627 "(overrides the value given by SGSN)\n"
628
629DEFUN(cfg_pcu_queue_lifetime,
630 cfg_pcu_queue_lifetime_cmd,
631 "queue lifetime <1-65534>",
632 QUEUE_STR LIFETIME_STR "Lifetime in centi-seconds")
633{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200634 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200635 uint16_t csec = atoi(argv[0]);
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200636
637 bts->force_llc_lifetime = csec;
638
639 return CMD_SUCCESS;
640}
641
642DEFUN(cfg_pcu_queue_lifetime_inf,
643 cfg_pcu_queue_lifetime_inf_cmd,
644 "queue lifetime infinite",
645 QUEUE_STR LIFETIME_STR "Infinite lifetime")
646{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200647 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200648
649 bts->force_llc_lifetime = 0xffff;
650
651 return CMD_SUCCESS;
652}
653
654DEFUN(cfg_pcu_no_queue_lifetime,
655 cfg_pcu_no_queue_lifetime_cmd,
656 "no queue lifetime",
657 NO_STR QUEUE_STR "Disable lifetime limit of LLC frame (use value given "
658 "by SGSN)\n")
659{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200660 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200661
662 bts->force_llc_lifetime = 0;
663
664 return CMD_SUCCESS;
665}
666
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100667#define QUEUE_HYSTERESIS_STR "Set lifetime hysteresis of LLC frame in centi-seconds " \
668 "(continue discarding until lifetime-hysteresis is reached)\n"
669
670DEFUN(cfg_pcu_queue_hysteresis,
671 cfg_pcu_queue_hysteresis_cmd,
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200672 "queue hysteresis <1-65535>",
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100673 QUEUE_STR QUEUE_HYSTERESIS_STR "Hysteresis in centi-seconds")
674{
675 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200676 uint16_t csec = atoi(argv[0]);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100677
678 bts->llc_discard_csec = csec;
679
680 return CMD_SUCCESS;
681}
682
683DEFUN(cfg_pcu_no_queue_hysteresis,
684 cfg_pcu_no_queue_hysteresis_cmd,
685 "no queue hysteresis",
686 NO_STR QUEUE_STR QUEUE_HYSTERESIS_STR)
687{
688 struct gprs_rlcmac_bts *bts = bts_main_data();
689
690 bts->llc_discard_csec = 0;
691
692 return CMD_SUCCESS;
693}
694
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200695#define QUEUE_CODEL_STR "Set CoDel queue management\n"
696
697DEFUN(cfg_pcu_queue_codel,
698 cfg_pcu_queue_codel_cmd,
699 "queue codel",
700 QUEUE_STR QUEUE_CODEL_STR)
701{
702 struct gprs_rlcmac_bts *bts = bts_main_data();
703
704 bts->llc_codel_interval_msec = LLC_CODEL_USE_DEFAULT;
705
706 return CMD_SUCCESS;
707}
708
709DEFUN(cfg_pcu_queue_codel_interval,
710 cfg_pcu_queue_codel_interval_cmd,
711 "queue codel interval <1-1000>",
712 QUEUE_STR QUEUE_CODEL_STR "Specify interval\n" "Interval in centi-seconds")
713{
714 struct gprs_rlcmac_bts *bts = bts_main_data();
715 uint16_t csec = atoi(argv[0]);
716
717 bts->llc_codel_interval_msec = 10*csec;
718
719 return CMD_SUCCESS;
720}
721
722DEFUN(cfg_pcu_no_queue_codel,
723 cfg_pcu_no_queue_codel_cmd,
724 "no queue codel",
725 NO_STR QUEUE_STR QUEUE_CODEL_STR)
726{
727 struct gprs_rlcmac_bts *bts = bts_main_data();
728
729 bts->llc_codel_interval_msec = LLC_CODEL_DISABLE;
730
731 return CMD_SUCCESS;
732}
733
734
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200735#define QUEUE_IDLE_ACK_STR "Request an ACK after the last DL LLC frame in centi-seconds\n"
736
737DEFUN(cfg_pcu_queue_idle_ack_delay,
738 cfg_pcu_queue_idle_ack_delay_cmd,
739 "queue idle-ack-delay <1-65535>",
740 QUEUE_STR QUEUE_IDLE_ACK_STR "Idle ACK delay in centi-seconds")
741{
742 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200743 uint16_t csec = atoi(argv[0]);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200744
745 bts->llc_idle_ack_csec = csec;
746
747 return CMD_SUCCESS;
748}
749
750DEFUN(cfg_pcu_no_queue_idle_ack_delay,
751 cfg_pcu_no_queue_idle_ack_delay_cmd,
752 "no queue idle-ack-delay",
753 NO_STR QUEUE_STR QUEUE_IDLE_ACK_STR)
754{
755 struct gprs_rlcmac_bts *bts = bts_main_data();
756
757 bts->llc_idle_ack_csec = 0;
758
759 return CMD_SUCCESS;
760}
761
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100762
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200763DEFUN(cfg_pcu_alloc,
764 cfg_pcu_alloc_cmd,
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200765 "alloc-algorithm (a|b|dynamic)",
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200766 "Select slot allocation algorithm to use when assigning timeslots on "
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200767 "PACCH\n"
768 "Single slot is assigned only\n"
769 "Multiple slots are assigned for semi-duplex operation\n"
770 "Dynamically select the algorithm based on the system state\n")
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200771{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200772 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200773
774 switch (argv[0][0]) {
775 case 'a':
776 bts->alloc_algorithm = alloc_algorithm_a;
777 break;
778 case 'b':
779 bts->alloc_algorithm = alloc_algorithm_b;
780 break;
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200781 default:
782 bts->alloc_algorithm = alloc_algorithm_dynamic;
783 break;
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200784 }
785
786 return CMD_SUCCESS;
787}
788
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200789DEFUN(cfg_pcu_two_phase,
790 cfg_pcu_two_phase_cmd,
791 "two-phase-access",
792 "Force two phase access when MS requests single phase access\n")
793{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200794 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200795
796 bts->force_two_phase = 1;
797
798 return CMD_SUCCESS;
799}
800
801DEFUN(cfg_pcu_no_two_phase,
802 cfg_pcu_no_two_phase_cmd,
803 "no two-phase-access",
804 NO_STR "Only use two phase access when requested my MS\n")
805{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200806 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200807
808 bts->force_two_phase = 0;
809
810 return CMD_SUCCESS;
811}
812
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200813DEFUN(cfg_pcu_alpha,
814 cfg_pcu_alpha_cmd,
815 "alpha <0-10>",
816 "Alpha parameter for MS power control in units of 0.1 (see TS 05.08) "
817 "NOTE: Be sure to set Alpha value at System information 13 too.\n"
818 "Alpha in units of 0.1\n")
819{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200820 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200821
822 bts->alpha = atoi(argv[0]);
823
824 return CMD_SUCCESS;
825}
826
827DEFUN(cfg_pcu_gamma,
828 cfg_pcu_gamma_cmd,
829 "gamma <0-62>",
830 "Gamma parameter for MS power control in units of dB (see TS 05.08)\n"
831 "Gamma in even unit of dBs\n")
832{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200833 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200834
835 bts->gamma = atoi(argv[0]) / 2;
836
837 return CMD_SUCCESS;
838}
839
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100840DEFUN(show_bts_stats,
841 show_bts_stats_cmd,
842 "show bts statistics",
843 SHOW_STR "BTS related functionality\nStatistics\n")
844{
845 vty_out_rate_ctr_group(vty, "", bts_main_data_stats());
846 return CMD_SUCCESS;
Daniel Willmann772415f2014-01-15 17:06:51 +0100847}
848
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100849#define IDLE_TIME_STR "keep an idle DL TBF alive for the time given\n"
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200850DEFUN_DEPRECATED(cfg_pcu_dl_tbf_idle_time,
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100851 cfg_pcu_dl_tbf_idle_time_cmd,
852 "dl-tbf-idle-time <1-5000>",
853 IDLE_TIME_STR "idle time in msec")
854{
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200855 vty_out(vty, "%% 'dl-tbf-idle-time' is now deprecated: use 'timer X2031 <val>' instead%s", VTY_NEWLINE);
856
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100857 struct gprs_rlcmac_bts *bts = bts_main_data();
858
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200859 if (osmo_tdef_set(bts->T_defs_pcu, -2031, atoi(argv[0]), OSMO_TDEF_MS) < 0)
860 return CMD_WARNING;
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100861 return CMD_SUCCESS;
862}
863
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200864DEFUN_DEPRECATED(cfg_pcu_no_dl_tbf_idle_time,
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100865 cfg_pcu_no_dl_tbf_idle_time_cmd,
866 "no dl-tbf-idle-time",
867 NO_STR IDLE_TIME_STR)
868{
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200869 vty_out(vty, "%% 'no dl-tbf-idle-time' is now deprecated: use 'timer X2031 0' instead%s", VTY_NEWLINE);
870
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100871 struct gprs_rlcmac_bts *bts = bts_main_data();
872
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200873 if (osmo_tdef_set(bts->T_defs_pcu, -2031, 0, OSMO_TDEF_MS) < 0)
874 return CMD_WARNING;
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100875 return CMD_SUCCESS;
876}
877
Oliver Smith45fdc442019-09-05 15:12:20 +0200878#define RETRANSMISSION_STR "retransmit blocks even before the MS had a chance to receive them (better throughput," \
879 " less readable traces)"
880DEFUN(cfg_pcu_dl_tbf_preemptive_retransmission,
881 cfg_pcu_dl_tbf_preemptive_retransmission_cmd,
882 "dl-tbf-preemptive-retransmission",
883 RETRANSMISSION_STR " (enabled by default)")
884{
885 struct gprs_rlcmac_bts *bts = bts_main_data();
886
887 bts->dl_tbf_preemptive_retransmission = true;
888
889 return CMD_SUCCESS;
890}
891
892DEFUN(cfg_pcu_no_dl_tbf_preemptive_retransmission,
893 cfg_pcu_no_dl_tbf_preemptive_retransmission_cmd,
894 "no dl-tbf-preemptive-retransmission",
895 NO_STR RETRANSMISSION_STR)
896{
897 struct gprs_rlcmac_bts *bts = bts_main_data();
898
899 bts->dl_tbf_preemptive_retransmission = false;
900
901 return CMD_SUCCESS;
902}
903
Jacob Erlbecka098c192015-05-28 16:11:19 +0200904#define MS_IDLE_TIME_STR "keep an idle MS object alive for the time given\n"
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200905DEFUN_DEPRECATED(cfg_pcu_ms_idle_time,
Jacob Erlbecka098c192015-05-28 16:11:19 +0200906 cfg_pcu_ms_idle_time_cmd,
907 "ms-idle-time <1-7200>",
908 MS_IDLE_TIME_STR "idle time in sec")
909{
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200910 vty_out(vty, "%% 'ms-idle-time' is now deprecated: use 'timer X2030 <val>' instead%s", VTY_NEWLINE);
911
Jacob Erlbecka098c192015-05-28 16:11:19 +0200912 struct gprs_rlcmac_bts *bts = bts_main_data();
913
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200914 if (osmo_tdef_set(bts->T_defs_pcu, -2030, atoi(argv[0]), OSMO_TDEF_S) < 0)
915 return CMD_WARNING;
Jacob Erlbecka098c192015-05-28 16:11:19 +0200916 return CMD_SUCCESS;
917}
918
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200919DEFUN_DEPRECATED(cfg_pcu_no_ms_idle_time,
Jacob Erlbecka098c192015-05-28 16:11:19 +0200920 cfg_pcu_no_ms_idle_time_cmd,
921 "no ms-idle-time",
922 NO_STR MS_IDLE_TIME_STR)
923{
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200924 vty_out(vty, "%% 'no ms-idle-time' is now deprecated: use 'timer X2030 0' instead%s", VTY_NEWLINE);
925
Jacob Erlbecka098c192015-05-28 16:11:19 +0200926 struct gprs_rlcmac_bts *bts = bts_main_data();
927
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200928 if (osmo_tdef_set(bts->T_defs_pcu, -2030, 0, OSMO_TDEF_S) < 0)
929 return CMD_WARNING;
Jacob Erlbecka098c192015-05-28 16:11:19 +0200930 return CMD_SUCCESS;
931}
932
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200933#define CS_ERR_LIMITS_STR "set thresholds for error rate based CS adjustment\n"
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200934DEFUN(cfg_pcu_cs_err_limits,
935 cfg_pcu_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200936 "cs threshold <0-100> <0-100>",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200937 CS_STR CS_ERR_LIMITS_STR "lower limit in %\n" "upper limit in %\n")
938{
939 struct gprs_rlcmac_bts *bts = bts_main_data();
940
941 uint8_t lower_limit = atoi(argv[0]);
942 uint8_t upper_limit = atoi(argv[1]);
943
944 if (lower_limit > upper_limit) {
945 vty_out(vty,
946 "The lower limit must be less than or equal to the "
947 "upper limit.%s", VTY_NEWLINE);
948 return CMD_WARNING;
949 }
950
951 bts->cs_adj_enabled = 1;
952 bts->cs_adj_upper_limit = upper_limit;
953 bts->cs_adj_lower_limit = lower_limit;
954
955 return CMD_SUCCESS;
956}
957
958DEFUN(cfg_pcu_no_cs_err_limits,
959 cfg_pcu_no_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200960 "no cs threshold",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200961 NO_STR CS_STR CS_ERR_LIMITS_STR)
962{
963 struct gprs_rlcmac_bts *bts = bts_main_data();
964
965 bts->cs_adj_enabled = 0;
966 bts->cs_adj_upper_limit = 100;
967 bts->cs_adj_lower_limit = 0;
968
969 return CMD_SUCCESS;
970}
971
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200972#define CS_DOWNGRADE_STR "set threshold for data size based CS downgrade\n"
973DEFUN(cfg_pcu_cs_downgrade_thrsh,
974 cfg_pcu_cs_downgrade_thrsh_cmd,
975 "cs downgrade-threshold <1-10000>",
976 CS_STR CS_DOWNGRADE_STR "downgrade if less octets left\n")
977{
978 struct gprs_rlcmac_bts *bts = bts_main_data();
979
980 bts->cs_downgrade_threshold = atoi(argv[0]);
981
982 return CMD_SUCCESS;
983}
984
985DEFUN(cfg_pcu_no_cs_downgrade_thrsh,
986 cfg_pcu_no_cs_downgrade_thrsh_cmd,
987 "no cs downgrade-threshold",
Jacob Erlbeckf1379342015-06-29 10:49:30 +0200988 NO_STR CS_STR CS_DOWNGRADE_STR)
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200989{
990 struct gprs_rlcmac_bts *bts = bts_main_data();
991
992 bts->cs_downgrade_threshold = 0;
993
994 return CMD_SUCCESS;
995}
996
997
Jacob Erlbeck94cde132015-06-09 09:44:36 +0200998DEFUN(cfg_pcu_cs_lqual_ranges,
999 cfg_pcu_cs_lqual_ranges_cmd,
1000 "cs link-quality-ranges cs1 <0-35> cs2 <0-35> <0-35> cs3 <0-35> <0-35> cs4 <0-35>",
1001 CS_STR "Set link quality ranges\n"
1002 "Set quality range for CS-1 (high value only)\n"
1003 "CS-1 high (dB)\n"
1004 "Set quality range for CS-2\n"
1005 "CS-2 low (dB)\n"
1006 "CS-2 high (dB)\n"
1007 "Set quality range for CS-3\n"
1008 "CS-3 low (dB)\n"
1009 "CS-3 high (dB)\n"
1010 "Set quality range for CS-4 (low value only)\n"
1011 "CS-4 low (dB)\n")
1012{
1013 struct gprs_rlcmac_bts *bts = bts_main_data();
1014
1015 uint8_t cs1_high = atoi(argv[0]);
1016 uint8_t cs2_low = atoi(argv[1]);
1017 uint8_t cs2_high = atoi(argv[2]);
1018 uint8_t cs3_low = atoi(argv[3]);
1019 uint8_t cs3_high = atoi(argv[4]);
1020 uint8_t cs4_low = atoi(argv[5]);
1021
1022 bts->cs_lqual_ranges[0].high = cs1_high;
1023 bts->cs_lqual_ranges[1].low = cs2_low;
1024 bts->cs_lqual_ranges[1].high = cs2_high;
1025 bts->cs_lqual_ranges[2].low = cs3_low;
1026 bts->cs_lqual_ranges[2].high = cs3_high;
1027 bts->cs_lqual_ranges[3].low = cs4_low;
1028
1029 return CMD_SUCCESS;
1030}
1031
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -04001032DEFUN(cfg_pcu_mcs_lqual_ranges,
1033 cfg_pcu_mcs_lqual_ranges_cmd,
1034 "mcs link-quality-ranges mcs1 <0-35> mcs2 <0-35> <0-35> mcs3 <0-35> <0-35> mcs4 <0-35> <0-35> mcs5 <0-35> <0-35> mcs6 <0-35> <0-35> mcs7 <0-35> <0-35> mcs8 <0-35> <0-35> mcs9 <0-35>",
1035 CS_STR "Set link quality ranges\n"
1036 "Set quality range for MCS-1 (high value only)\n"
1037 "MCS-1 high (dB)\n"
1038 "Set quality range for MCS-2\n"
1039 "MCS-2 high (dB)\n"
1040 "MCS-2 low (dB)\n"
1041 "Set quality range for MCS-3\n"
1042 "MCS-3 high (dB)\n"
1043 "MCS-3 low (dB)\n"
1044 "Set quality range for MCS-4\n"
1045 "MCS-4 high (dB)\n"
1046 "MCS-4 low (dB)\n"
1047 "Set quality range for MCS-5\n"
1048 "MCS-5 high (dB)\n"
1049 "MCS-5 low (dB)\n"
1050 "Set quality range for MCS-6\n"
1051 "MCS-6 low (dB)\n"
1052 "MCS-6 high (dB)\n"
1053 "Set quality range for MCS-7\n"
1054 "MCS-7 low (dB)\n"
1055 "MCS-7 high (dB)\n"
1056 "Set quality range for MCS-8\n"
1057 "MCS-8 low (dB)\n"
1058 "MCS-8 high (dB)\n"
1059 "Set quality range for MCS-9 (low value only)\n"
1060 "MCS-9 low (dB)\n")
1061{
1062 struct gprs_rlcmac_bts *bts = bts_main_data();
1063
1064 bts->mcs_lqual_ranges[0].high = atoi(argv[0]);
1065 bts->mcs_lqual_ranges[1].low = atoi(argv[1]);
1066 bts->mcs_lqual_ranges[1].high = atoi(argv[2]);
1067 bts->mcs_lqual_ranges[2].low = atoi(argv[3]);
1068 bts->mcs_lqual_ranges[2].high = atoi(argv[4]);
1069 bts->mcs_lqual_ranges[3].low = atoi(argv[5]);
1070 bts->mcs_lqual_ranges[3].high = atoi(argv[6]);
1071 bts->mcs_lqual_ranges[4].low = atoi(argv[7]);
1072 bts->mcs_lqual_ranges[4].high = atoi(argv[8]);
1073 bts->mcs_lqual_ranges[5].low = atoi(argv[9]);
1074 bts->mcs_lqual_ranges[5].high = atoi(argv[10]);
1075 bts->mcs_lqual_ranges[6].low = atoi(argv[11]);
1076 bts->mcs_lqual_ranges[6].high = atoi(argv[12]);
1077 bts->mcs_lqual_ranges[7].low = atoi(argv[13]);
1078 bts->mcs_lqual_ranges[7].high = atoi(argv[14]);
1079 bts->mcs_lqual_ranges[8].low = atoi(argv[15]);
1080
1081 return CMD_SUCCESS;
1082}
1083
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +02001084DEFUN(cfg_pcu_sock,
1085 cfg_pcu_sock_cmd,
1086 "pcu-socket PATH",
1087 "Configure the osmo-bts PCU socket file/path name\n"
1088 "Path of the socket to connect to\n")
1089{
1090 struct gprs_rlcmac_bts *bts = bts_main_data();
1091
1092 if (bts->pcu_sock_path) {
1093 /* FIXME: close the interface? */
1094 talloc_free(bts->pcu_sock_path);
1095 }
1096 bts->pcu_sock_path = talloc_strdup(tall_pcu_ctx, argv[0]);
1097 /* FIXME: re-open the interface? */
1098
1099 return CMD_SUCCESS;
1100}
Jacob Erlbeck94cde132015-06-09 09:44:36 +02001101
Harald Welte57d35152018-07-05 03:11:17 +02001102DEFUN(cfg_pcu_gb_dialect,
1103 cfg_pcu_gb_dialect_cmd,
1104 "gb-dialect (classic|ip-sns)",
1105 "Select which Gb interface dialect to use\n"
1106 "Classic Gb interface with NS-{RESET,BLOCK,UNBLOCK} and static configuration\n"
1107 "Modern Gb interface with IP-SNS (Sub Network Service) and dynamic configuration\n")
1108{
1109 struct gprs_rlcmac_bts *bts = bts_main_data();
1110
1111 if (!strcmp(argv[0], "ip-sns"))
1112 bts->gb_dialect_sns = true;
1113 else
1114 bts->gb_dialect_sns = false;
1115
1116 return CMD_SUCCESS;
1117}
1118
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +02001119DEFUN(show_bts_timer, show_bts_timer_cmd,
1120 "show bts-timer " OSMO_TDEF_VTY_ARG_T_OPTIONAL,
1121 SHOW_STR "Show BTS controlled timers\n"
1122 OSMO_TDEF_VTY_DOC_T)
1123{
1124 struct gprs_rlcmac_bts *bts = bts_main_data();
1125 const char *T_arg = argc > 0 ? argv[0] : NULL;
1126 return osmo_tdef_vty_show_cmd(vty, bts->T_defs_bts, T_arg, NULL);
1127}
1128
1129DEFUN(show_timer, show_timer_cmd,
1130 "show timer " OSMO_TDEF_VTY_ARG_T_OPTIONAL,
1131 SHOW_STR "Show PCU timers\n"
1132 OSMO_TDEF_VTY_DOC_T)
1133{
1134 struct gprs_rlcmac_bts *bts = bts_main_data();
1135 const char *T_arg = argc > 0 ? argv[0] : NULL;
1136 return osmo_tdef_vty_show_cmd(vty, bts->T_defs_pcu, T_arg, NULL);
1137}
1138
1139DEFUN(cfg_pcu_timer, cfg_pcu_timer_cmd,
1140 "timer " OSMO_TDEF_VTY_ARG_SET_OPTIONAL,
1141 "Configure or show PCU timers\n"
1142 OSMO_TDEF_VTY_DOC_SET)
1143{
1144 struct gprs_rlcmac_bts *bts = bts_main_data();
1145 /* If any arguments are missing, redirect to 'show' */
1146 if (argc < 2)
1147 return show_timer(self, vty, argc, argv);
1148 return osmo_tdef_vty_set_cmd(vty, bts->T_defs_pcu, argv);
1149}
1150
Daniel Willmann772415f2014-01-15 17:06:51 +01001151DEFUN(show_tbf,
1152 show_tbf_cmd,
Max12a09872018-02-01 16:07:33 +01001153 "show tbf (all|ccch|pacch)",
1154 SHOW_STR "information about TBFs\n"
1155 "All TBFs\n"
1156 "TBFs allocated via CCCH\n"
1157 "TBFs allocated via PACCH\n")
Daniel Willmann772415f2014-01-15 17:06:51 +01001158{
1159 struct gprs_rlcmac_bts *bts = bts_main_data();
Max12a09872018-02-01 16:07:33 +01001160 if (!strcmp(argv[0], "all"))
1161 return pcu_vty_show_tbf_all(vty, bts, true, true);
1162
1163 if (!strcmp(argv[0], "ccch"))
1164 return pcu_vty_show_tbf_all(vty, bts_main_data(), true, false);
1165
1166 return pcu_vty_show_tbf_all(vty, bts_main_data(), false, true);
Daniel Willmann772415f2014-01-15 17:06:51 +01001167}
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +01001168
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +02001169DEFUN(show_ms_all,
1170 show_ms_all_cmd,
1171 "show ms all",
1172 SHOW_STR "information about MSs\n" "All TBFs\n")
1173{
1174 struct gprs_rlcmac_bts *bts = bts_main_data();
1175 return pcu_vty_show_ms_all(vty, bts);
1176}
1177
Jacob Erlbeck37e896d2015-06-05 16:33:33 +02001178DEFUN(show_ms_tlli,
1179 show_ms_tlli_cmd,
1180 "show ms tlli TLLI",
1181 SHOW_STR "information about MSs\n" "Select MS by TLLI\n" "TLLI as hex\n")
1182{
1183 struct gprs_rlcmac_bts *bts = bts_main_data();
1184 char *endp = NULL;
1185 unsigned long long tlli = strtoll(argv[0], &endp, 16);
1186 if ((endp != NULL && *endp != 0) || tlli > 0xffffffffULL) {
1187 vty_out(vty, "Invalid TLLI.%s", VTY_NEWLINE);
1188 return CMD_WARNING;
1189 }
1190 return pcu_vty_show_ms_by_tlli(vty, bts, (uint32_t)tlli);
1191}
1192
1193DEFUN(show_ms_imsi,
1194 show_ms_imsi_cmd,
1195 "show ms imsi IMSI",
1196 SHOW_STR "information about MSs\n" "Select MS by IMSI\n" "IMSI\n")
1197{
1198 struct gprs_rlcmac_bts *bts = bts_main_data();
1199 return pcu_vty_show_ms_by_imsi(vty, bts, argv[0]);
1200}
1201
Andreas Eversberg12942562012-07-12 14:31:57 +02001202static const char pcu_copyright[] =
Harald Welted1e340f2013-01-17 12:24:29 +01001203 "Copyright (C) 2012 by Ivan Kluchnikov <kluchnikovi@gmail.com> and \r\n"
1204 " Andreas Eversberg <jolly@eversberg.eu>\r\n"
Andreas Eversberg12942562012-07-12 14:31:57 +02001205 "License GNU GPL version 2 or later\r\n"
1206 "This is free software: you are free to change and redistribute it.\r\n"
1207 "There is NO WARRANTY, to the extent permitted by law.\r\n";
1208
1209struct vty_app_info pcu_vty_info = {
1210 .name = "Osmo-PCU",
1211 .version = PACKAGE_VERSION,
1212 .copyright = pcu_copyright,
1213 .go_parent_cb = pcu_vty_go_parent,
1214 .is_config_node = pcu_vty_is_config_node,
1215};
1216
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02001217int pcu_vty_init(void)
Andreas Eversberg12942562012-07-12 14:31:57 +02001218{
1219// install_element_ve(&show_pcu_cmd);
1220
Harald Welte717cdf52017-07-21 21:56:23 +02001221 cfg_pcu_gsmtap_categ_cmd.string = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_names,
1222 "gsmtap-category (",
1223 "|",")", VTY_DO_LOWER);
1224 cfg_pcu_gsmtap_categ_cmd.doc = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_help,
1225 "GSMTAP Category\n",
1226 "\n", "", 0);
1227 cfg_pcu_no_gsmtap_categ_cmd.string = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_names,
1228 "no gsmtap-category (",
1229 "|",")", VTY_DO_LOWER);
1230 cfg_pcu_no_gsmtap_categ_cmd.doc = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_help,
1231 NO_STR "GSMTAP Category\n",
1232 "\n", "", 0);
1233
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02001234 logging_vty_add_cmds();
1235 osmo_stats_vty_add_cmds();
Andreas Eversberg12942562012-07-12 14:31:57 +02001236
Andreas Eversberg8b761a32012-07-20 21:50:31 +02001237 install_node(&pcu_node, config_write_pcu);
1238 install_element(CONFIG_NODE, &cfg_pcu_cmd);
Jacob Erlbeck953c7892015-09-28 18:12:57 +02001239 install_element(PCU_NODE, &cfg_pcu_egprs_cmd);
1240 install_element(PCU_NODE, &cfg_pcu_no_egprs_cmd);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +02001241 install_element(PCU_NODE, &cfg_pcu_no_two_phase_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +02001242 install_element(PCU_NODE, &cfg_pcu_cs_cmd);
1243 install_element(PCU_NODE, &cfg_pcu_no_cs_cmd);
Jacob Erlbeckb33e6752015-06-04 19:04:30 +02001244 install_element(PCU_NODE, &cfg_pcu_cs_max_cmd);
1245 install_element(PCU_NODE, &cfg_pcu_no_cs_max_cmd);
Jacob Erlbeck8322d082015-06-04 15:12:10 +02001246 install_element(PCU_NODE, &cfg_pcu_cs_err_limits_cmd);
1247 install_element(PCU_NODE, &cfg_pcu_no_cs_err_limits_cmd);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +02001248 install_element(PCU_NODE, &cfg_pcu_cs_downgrade_thrsh_cmd);
1249 install_element(PCU_NODE, &cfg_pcu_no_cs_downgrade_thrsh_cmd);
Jacob Erlbeck94cde132015-06-09 09:44:36 +02001250 install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd);
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -04001251 install_element(PCU_NODE, &cfg_pcu_mcs_lqual_ranges_cmd);
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +01001252 install_element(PCU_NODE, &cfg_pcu_mcs_cmd);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05301253 install_element(PCU_NODE, &cfg_pcu_dl_arq_cmd);
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +01001254 install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd);
Jacob Erlbeck0d058052016-01-07 11:48:28 +01001255 install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd);
1256 install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01001257 install_element(PCU_NODE, &cfg_pcu_window_size_cmd);
Andreas Eversberg24131bf2012-07-21 11:09:58 +02001258 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_cmd);
1259 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_inf_cmd);
1260 install_element(PCU_NODE, &cfg_pcu_no_queue_lifetime_cmd);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +01001261 install_element(PCU_NODE, &cfg_pcu_queue_hysteresis_cmd);
1262 install_element(PCU_NODE, &cfg_pcu_no_queue_hysteresis_cmd);
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +02001263 install_element(PCU_NODE, &cfg_pcu_queue_codel_cmd);
1264 install_element(PCU_NODE, &cfg_pcu_queue_codel_interval_cmd);
1265 install_element(PCU_NODE, &cfg_pcu_no_queue_codel_cmd);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +02001266 install_element(PCU_NODE, &cfg_pcu_queue_idle_ack_delay_cmd);
1267 install_element(PCU_NODE, &cfg_pcu_no_queue_idle_ack_delay_cmd);
Andreas Eversberga1503fa2012-07-22 08:58:09 +02001268 install_element(PCU_NODE, &cfg_pcu_alloc_cmd);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001269 install_element(PCU_NODE, &cfg_pcu_two_phase_cmd);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +02001270 install_element(PCU_NODE, &cfg_pcu_fc_interval_cmd);
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +02001271 install_element(PCU_NODE, &cfg_pcu_fc_bucket_time_cmd);
1272 install_element(PCU_NODE, &cfg_pcu_no_fc_bucket_time_cmd);
Jacob Erlbeck87d73412015-04-21 12:56:48 +02001273 install_element(PCU_NODE, &cfg_pcu_fc_bvc_bucket_size_cmd);
1274 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_bucket_size_cmd);
1275 install_element(PCU_NODE, &cfg_pcu_fc_bvc_leak_rate_cmd);
1276 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_leak_rate_cmd);
1277 install_element(PCU_NODE, &cfg_pcu_fc_ms_bucket_size_cmd);
1278 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_bucket_size_cmd);
1279 install_element(PCU_NODE, &cfg_pcu_fc_ms_leak_rate_cmd);
1280 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_leak_rate_cmd);
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +02001281 install_element(PCU_NODE, &cfg_pcu_alpha_cmd);
1282 install_element(PCU_NODE, &cfg_pcu_gamma_cmd);
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +01001283 install_element(PCU_NODE, &cfg_pcu_dl_tbf_idle_time_cmd);
1284 install_element(PCU_NODE, &cfg_pcu_no_dl_tbf_idle_time_cmd);
Oliver Smith45fdc442019-09-05 15:12:20 +02001285 install_element(PCU_NODE, &cfg_pcu_dl_tbf_preemptive_retransmission_cmd);
1286 install_element(PCU_NODE, &cfg_pcu_no_dl_tbf_preemptive_retransmission_cmd);
Jacob Erlbecka098c192015-05-28 16:11:19 +02001287 install_element(PCU_NODE, &cfg_pcu_ms_idle_time_cmd);
1288 install_element(PCU_NODE, &cfg_pcu_no_ms_idle_time_cmd);
Harald Welte717cdf52017-07-21 21:56:23 +02001289 install_element(PCU_NODE, &cfg_pcu_gsmtap_categ_cmd);
1290 install_element(PCU_NODE, &cfg_pcu_no_gsmtap_categ_cmd);
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +02001291 install_element(PCU_NODE, &cfg_pcu_sock_cmd);
Harald Welte57d35152018-07-05 03:11:17 +02001292 install_element(PCU_NODE, &cfg_pcu_gb_dialect_cmd);
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +02001293 install_element(PCU_NODE, &cfg_pcu_timer_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +02001294
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +01001295 install_element_ve(&show_bts_stats_cmd);
Daniel Willmann772415f2014-01-15 17:06:51 +01001296 install_element_ve(&show_tbf_cmd);
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +02001297 install_element_ve(&show_ms_all_cmd);
Jacob Erlbeck37e896d2015-06-05 16:33:33 +02001298 install_element_ve(&show_ms_tlli_cmd);
1299 install_element_ve(&show_ms_imsi_cmd);
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +02001300 install_element_ve(&show_bts_timer_cmd);
1301 install_element_ve(&show_timer_cmd);
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +01001302
Andreas Eversberg12942562012-07-12 14:31:57 +02001303 return 0;
1304}