blob: c47c8967d3a9276ba244bfac135718abf834abac [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
Pau Espin Pedrol18794422019-09-26 18:25:35 +0200274 osmo_tdef_vty_write(vty, bts->T_defs_pcu, " timer ");
275
Maxc9ce6f92018-01-30 17:53:02 +0100276 return CMD_SUCCESS;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200277}
278
279/* per-BTS configuration */
280DEFUN(cfg_pcu,
281 cfg_pcu_cmd,
282 "pcu",
283 "BTS specific configure")
284{
285 vty->node = PCU_NODE;
286
287 return CMD_SUCCESS;
288}
289
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200290#define EGPRS_STR "EGPRS configuration\n"
291
292DEFUN(cfg_pcu_egprs,
293 cfg_pcu_egprs_cmd,
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +0100294 "egprs only",
295 EGPRS_STR "Use EGPRS and disable plain GPRS\n")
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200296{
297 struct gprs_rlcmac_bts *bts = bts_main_data();
298
299 bts->egprs_enabled = 1;
300
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200301 return CMD_SUCCESS;
302}
303
304DEFUN(cfg_pcu_no_egprs,
305 cfg_pcu_no_egprs_cmd,
306 "no egprs",
307 NO_STR EGPRS_STR)
308{
309 struct gprs_rlcmac_bts *bts = bts_main_data();
310
311 bts->egprs_enabled = 0;
312
313 return CMD_SUCCESS;
314}
315
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200316DEFUN(cfg_pcu_fc_interval,
317 cfg_pcu_fc_interval_cmd,
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200318 "flow-control-interval <1-10>",
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200319 "Interval between sending subsequent Flow Control PDUs\n"
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200320 "Interval time in seconds\n")
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200321{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200322 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200323
324 bts->fc_interval = atoi(argv[0]);
325
326 return CMD_SUCCESS;
327}
Jacob Erlbeck87d73412015-04-21 12:56:48 +0200328#define FC_STR "BSSGP Flow Control configuration\n"
329#define FC_BMAX_STR(who) "Force a fixed value for the " who " bucket size\n"
330#define FC_LR_STR(who) "Force a fixed value for the " who " leak rate\n"
331
332DEFUN(cfg_pcu_fc_bvc_bucket_size,
333 cfg_pcu_fc_bvc_bucket_size_cmd,
334 "flow-control force-bvc-bucket-size <1-6553500>",
335 FC_STR FC_BMAX_STR("BVC") "Bucket size in octets\n")
336{
337 struct gprs_rlcmac_bts *bts = bts_main_data();
338
339 bts->fc_bvc_bucket_size = atoi(argv[0]);
340
341 return CMD_SUCCESS;
342}
343
344DEFUN(cfg_pcu_no_fc_bvc_bucket_size,
345 cfg_pcu_no_fc_bvc_bucket_size_cmd,
346 "no flow-control force-bvc-bucket-size",
347 NO_STR FC_STR FC_BMAX_STR("BVC"))
348{
349 struct gprs_rlcmac_bts *bts = bts_main_data();
350
351 bts->fc_bvc_bucket_size = 0;
352
353 return CMD_SUCCESS;
354}
355
356DEFUN(cfg_pcu_fc_bvc_leak_rate,
357 cfg_pcu_fc_bvc_leak_rate_cmd,
358 "flow-control force-bvc-leak-rate <1-6553500>",
359 FC_STR FC_LR_STR("BVC") "Leak rate in bit/s\n")
360{
361 struct gprs_rlcmac_bts *bts = bts_main_data();
362
363 bts->fc_bvc_leak_rate = atoi(argv[0]);
364
365 return CMD_SUCCESS;
366}
367
368DEFUN(cfg_pcu_no_fc_bvc_leak_rate,
369 cfg_pcu_no_fc_bvc_leak_rate_cmd,
370 "no flow-control force-bvc-leak-rate",
371 NO_STR FC_STR FC_LR_STR("BVC"))
372{
373 struct gprs_rlcmac_bts *bts = bts_main_data();
374
375 bts->fc_bvc_leak_rate = 0;
376
377 return CMD_SUCCESS;
378}
379
380DEFUN(cfg_pcu_fc_ms_bucket_size,
381 cfg_pcu_fc_ms_bucket_size_cmd,
382 "flow-control force-ms-bucket-size <1-6553500>",
383 FC_STR FC_BMAX_STR("default MS") "Bucket size in octets\n")
384{
385 struct gprs_rlcmac_bts *bts = bts_main_data();
386
387 bts->fc_ms_bucket_size = atoi(argv[0]);
388
389 return CMD_SUCCESS;
390}
391
392DEFUN(cfg_pcu_no_fc_ms_bucket_size,
393 cfg_pcu_no_fc_ms_bucket_size_cmd,
394 "no flow-control force-ms-bucket-size",
395 NO_STR FC_STR FC_BMAX_STR("default MS"))
396{
397 struct gprs_rlcmac_bts *bts = bts_main_data();
398
399 bts->fc_ms_bucket_size = 0;
400
401 return CMD_SUCCESS;
402}
403
404DEFUN(cfg_pcu_fc_ms_leak_rate,
405 cfg_pcu_fc_ms_leak_rate_cmd,
406 "flow-control force-ms-leak-rate <1-6553500>",
407 FC_STR FC_LR_STR("default MS") "Leak rate in bit/s\n")
408{
409 struct gprs_rlcmac_bts *bts = bts_main_data();
410
411 bts->fc_ms_leak_rate = atoi(argv[0]);
412
413 return CMD_SUCCESS;
414}
415
416DEFUN(cfg_pcu_no_fc_ms_leak_rate,
417 cfg_pcu_no_fc_ms_leak_rate_cmd,
418 "no flow-control force-ms-leak-rate",
419 NO_STR FC_STR FC_LR_STR("default MS"))
420{
421 struct gprs_rlcmac_bts *bts = bts_main_data();
422
423 bts->fc_ms_leak_rate = 0;
424
425 return CMD_SUCCESS;
426}
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200427
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200428#define FC_BTIME_STR "Set target downlink maximum queueing time (only affects the advertised bucket size)\n"
429DEFUN(cfg_pcu_fc_bucket_time,
430 cfg_pcu_fc_bucket_time_cmd,
431 "flow-control bucket-time <1-65534>",
432 FC_STR FC_BTIME_STR "Time in centi-seconds\n")
433{
434 struct gprs_rlcmac_bts *bts = bts_main_data();
435
436 bts->fc_bucket_time = atoi(argv[0]);
437
438 return CMD_SUCCESS;
439}
440
441DEFUN(cfg_pcu_no_fc_bucket_time,
442 cfg_pcu_no_fc_bucket_time_cmd,
443 "no flow-control bucket-time",
444 NO_STR FC_STR FC_BTIME_STR)
445{
446 struct gprs_rlcmac_bts *bts = bts_main_data();
447
448 bts->fc_bucket_time = 0;
449
450 return CMD_SUCCESS;
451}
452
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200453#define CS_STR "Coding Scheme configuration\n"
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200454
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200455DEFUN(cfg_pcu_cs,
456 cfg_pcu_cs_cmd,
Andreas Eversberg499ff412012-10-03 14:21:36 +0200457 "cs <1-4> [<1-4>]",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200458 CS_STR
459 "Initial CS value to be used (overrides BTS config)\n"
460 "Use a different initial CS value for the uplink")
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200461{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200462 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200463 uint8_t cs = atoi(argv[0]);
464
465 bts->force_cs = 1;
Andreas Eversberg499ff412012-10-03 14:21:36 +0200466 bts->initial_cs_dl = cs;
467 if (argc > 1)
468 bts->initial_cs_ul = atoi(argv[1]);
469 else
470 bts->initial_cs_ul = cs;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200471
472 return CMD_SUCCESS;
473}
474
475DEFUN(cfg_pcu_no_cs,
476 cfg_pcu_no_cs_cmd,
477 "no cs",
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200478 NO_STR CS_STR)
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200479{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200480 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200481
482 bts->force_cs = 0;
483
484 return CMD_SUCCESS;
485}
486
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100487#define CS_MAX_STR "Set maximum values for adaptive CS selection (overrides BTS config)\n"
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200488DEFUN(cfg_pcu_cs_max,
489 cfg_pcu_cs_max_cmd,
490 "cs max <1-4> [<1-4>]",
491 CS_STR
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100492 CS_MAX_STR
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200493 "Maximum CS value to be used\n"
494 "Use a different maximum CS value for the uplink")
495{
496 struct gprs_rlcmac_bts *bts = bts_main_data();
497 uint8_t cs = atoi(argv[0]);
498
499 bts->max_cs_dl = cs;
500 if (argc > 1)
501 bts->max_cs_ul = atoi(argv[1]);
502 else
503 bts->max_cs_ul = cs;
504
505 return CMD_SUCCESS;
506}
507
508DEFUN(cfg_pcu_no_cs_max,
509 cfg_pcu_no_cs_max_cmd,
510 "no cs max",
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100511 NO_STR CS_STR CS_MAX_STR)
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200512{
513 struct gprs_rlcmac_bts *bts = bts_main_data();
514
515 bts->max_cs_dl = 0;
516 bts->max_cs_ul = 0;
517
518 return CMD_SUCCESS;
519}
520
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100521#define MCS_STR "Modulation and Coding Scheme configuration (EGPRS)\n"
522
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +0100523DEFUN(cfg_pcu_mcs,
524 cfg_pcu_mcs_cmd,
525 "mcs <1-9> [<1-9>]",
526 MCS_STR
527 "Initial MCS value to be used (default 1)\n"
528 "Use a different initial MCS value for the uplink")
529{
530 struct gprs_rlcmac_bts *bts = bts_main_data();
531 uint8_t cs = atoi(argv[0]);
532
533 bts->initial_mcs_dl = cs;
534 if (argc > 1)
535 bts->initial_mcs_ul = atoi(argv[1]);
536 else
537 bts->initial_mcs_ul = cs;
538
539 return CMD_SUCCESS;
540}
541
542DEFUN(cfg_pcu_no_mcs,
543 cfg_pcu_no_mcs_cmd,
544 "no mcs",
545 NO_STR MCS_STR)
546{
547 struct gprs_rlcmac_bts *bts = bts_main_data();
548
549 bts->initial_mcs_dl = 1;
550 bts->initial_mcs_ul = 1;
551
552 return CMD_SUCCESS;
553}
554
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100555DEFUN(cfg_pcu_mcs_max,
556 cfg_pcu_mcs_max_cmd,
Jacob Erlbeckf9940ca2016-01-19 10:32:33 +0100557 "mcs max <1-9> [<1-9>]",
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100558 MCS_STR
559 CS_MAX_STR
560 "Maximum MCS value to be used\n"
561 "Use a different maximum MCS value for the uplink")
562{
563 struct gprs_rlcmac_bts *bts = bts_main_data();
564 uint8_t mcs = atoi(argv[0]);
565
566 bts->max_mcs_dl = mcs;
567 if (argc > 1)
568 bts->max_mcs_ul = atoi(argv[1]);
569 else
570 bts->max_mcs_ul = mcs;
571
572 return CMD_SUCCESS;
573}
574
575DEFUN(cfg_pcu_no_mcs_max,
576 cfg_pcu_no_mcs_max_cmd,
577 "no mcs max",
578 NO_STR MCS_STR CS_MAX_STR)
579{
580 struct gprs_rlcmac_bts *bts = bts_main_data();
581
582 bts->max_mcs_dl = 0;
583 bts->max_mcs_ul = 0;
584
585 return CMD_SUCCESS;
586}
587
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530588#define DL_STR "downlink specific configuration\n"
589
590DEFUN(cfg_pcu_dl_arq_type,
591 cfg_pcu_dl_arq_cmd,
592 "egprs dl arq-type (spb|arq2)",
593 EGPRS_STR DL_STR "ARQ options\n"
594 "enable SPB(ARQ1) support\n"
595 "enable ARQ2 support")
596{
597 struct gprs_rlcmac_bts *bts = bts_main_data();
598
599 if (!strcmp(argv[0], "arq2"))
600 bts->dl_arq_type = 1;
601 else
602 bts->dl_arq_type = 0;
603
604 return CMD_SUCCESS;
605}
606
Jacob Erlbeck36df7742016-01-19 15:53:30 +0100607DEFUN(cfg_pcu_window_size,
608 cfg_pcu_window_size_cmd,
609 "window-size <0-1024> [<0-256>]",
610 "Window size configuration (b + N_PDCH * f)\n"
611 "Base value (b)\n"
612 "Factor for number of PDCH (f)")
613{
614 struct gprs_rlcmac_bts *bts = bts_main_data();
615 uint16_t b = atoi(argv[0]);
616
617 bts->ws_base = b;
618 if (argc > 1) {
619 uint16_t f = atoi(argv[1]);
620 bts->ws_pdch = f;
621 }
622
623 return CMD_SUCCESS;
624}
625
626
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200627#define QUEUE_STR "Packet queue options\n"
628#define LIFETIME_STR "Set lifetime limit of LLC frame in centi-seconds " \
629 "(overrides the value given by SGSN)\n"
630
631DEFUN(cfg_pcu_queue_lifetime,
632 cfg_pcu_queue_lifetime_cmd,
633 "queue lifetime <1-65534>",
634 QUEUE_STR LIFETIME_STR "Lifetime in centi-seconds")
635{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200636 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200637 uint16_t csec = atoi(argv[0]);
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200638
639 bts->force_llc_lifetime = csec;
640
641 return CMD_SUCCESS;
642}
643
644DEFUN(cfg_pcu_queue_lifetime_inf,
645 cfg_pcu_queue_lifetime_inf_cmd,
646 "queue lifetime infinite",
647 QUEUE_STR LIFETIME_STR "Infinite lifetime")
648{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200649 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200650
651 bts->force_llc_lifetime = 0xffff;
652
653 return CMD_SUCCESS;
654}
655
656DEFUN(cfg_pcu_no_queue_lifetime,
657 cfg_pcu_no_queue_lifetime_cmd,
658 "no queue lifetime",
659 NO_STR QUEUE_STR "Disable lifetime limit of LLC frame (use value given "
660 "by SGSN)\n")
661{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200662 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200663
664 bts->force_llc_lifetime = 0;
665
666 return CMD_SUCCESS;
667}
668
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100669#define QUEUE_HYSTERESIS_STR "Set lifetime hysteresis of LLC frame in centi-seconds " \
670 "(continue discarding until lifetime-hysteresis is reached)\n"
671
672DEFUN(cfg_pcu_queue_hysteresis,
673 cfg_pcu_queue_hysteresis_cmd,
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200674 "queue hysteresis <1-65535>",
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100675 QUEUE_STR QUEUE_HYSTERESIS_STR "Hysteresis in centi-seconds")
676{
677 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200678 uint16_t csec = atoi(argv[0]);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100679
680 bts->llc_discard_csec = csec;
681
682 return CMD_SUCCESS;
683}
684
685DEFUN(cfg_pcu_no_queue_hysteresis,
686 cfg_pcu_no_queue_hysteresis_cmd,
687 "no queue hysteresis",
688 NO_STR QUEUE_STR QUEUE_HYSTERESIS_STR)
689{
690 struct gprs_rlcmac_bts *bts = bts_main_data();
691
692 bts->llc_discard_csec = 0;
693
694 return CMD_SUCCESS;
695}
696
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200697#define QUEUE_CODEL_STR "Set CoDel queue management\n"
698
699DEFUN(cfg_pcu_queue_codel,
700 cfg_pcu_queue_codel_cmd,
701 "queue codel",
702 QUEUE_STR QUEUE_CODEL_STR)
703{
704 struct gprs_rlcmac_bts *bts = bts_main_data();
705
706 bts->llc_codel_interval_msec = LLC_CODEL_USE_DEFAULT;
707
708 return CMD_SUCCESS;
709}
710
711DEFUN(cfg_pcu_queue_codel_interval,
712 cfg_pcu_queue_codel_interval_cmd,
713 "queue codel interval <1-1000>",
714 QUEUE_STR QUEUE_CODEL_STR "Specify interval\n" "Interval in centi-seconds")
715{
716 struct gprs_rlcmac_bts *bts = bts_main_data();
717 uint16_t csec = atoi(argv[0]);
718
719 bts->llc_codel_interval_msec = 10*csec;
720
721 return CMD_SUCCESS;
722}
723
724DEFUN(cfg_pcu_no_queue_codel,
725 cfg_pcu_no_queue_codel_cmd,
726 "no queue codel",
727 NO_STR QUEUE_STR QUEUE_CODEL_STR)
728{
729 struct gprs_rlcmac_bts *bts = bts_main_data();
730
731 bts->llc_codel_interval_msec = LLC_CODEL_DISABLE;
732
733 return CMD_SUCCESS;
734}
735
736
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200737#define QUEUE_IDLE_ACK_STR "Request an ACK after the last DL LLC frame in centi-seconds\n"
738
739DEFUN(cfg_pcu_queue_idle_ack_delay,
740 cfg_pcu_queue_idle_ack_delay_cmd,
741 "queue idle-ack-delay <1-65535>",
742 QUEUE_STR QUEUE_IDLE_ACK_STR "Idle ACK delay in centi-seconds")
743{
744 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200745 uint16_t csec = atoi(argv[0]);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200746
747 bts->llc_idle_ack_csec = csec;
748
749 return CMD_SUCCESS;
750}
751
752DEFUN(cfg_pcu_no_queue_idle_ack_delay,
753 cfg_pcu_no_queue_idle_ack_delay_cmd,
754 "no queue idle-ack-delay",
755 NO_STR QUEUE_STR QUEUE_IDLE_ACK_STR)
756{
757 struct gprs_rlcmac_bts *bts = bts_main_data();
758
759 bts->llc_idle_ack_csec = 0;
760
761 return CMD_SUCCESS;
762}
763
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100764
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200765DEFUN(cfg_pcu_alloc,
766 cfg_pcu_alloc_cmd,
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200767 "alloc-algorithm (a|b|dynamic)",
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200768 "Select slot allocation algorithm to use when assigning timeslots on "
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200769 "PACCH\n"
770 "Single slot is assigned only\n"
771 "Multiple slots are assigned for semi-duplex operation\n"
772 "Dynamically select the algorithm based on the system state\n")
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200773{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200774 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200775
776 switch (argv[0][0]) {
777 case 'a':
778 bts->alloc_algorithm = alloc_algorithm_a;
779 break;
780 case 'b':
781 bts->alloc_algorithm = alloc_algorithm_b;
782 break;
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200783 default:
784 bts->alloc_algorithm = alloc_algorithm_dynamic;
785 break;
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200786 }
787
788 return CMD_SUCCESS;
789}
790
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200791DEFUN(cfg_pcu_two_phase,
792 cfg_pcu_two_phase_cmd,
793 "two-phase-access",
794 "Force two phase access when MS requests single phase access\n")
795{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200796 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200797
798 bts->force_two_phase = 1;
799
800 return CMD_SUCCESS;
801}
802
803DEFUN(cfg_pcu_no_two_phase,
804 cfg_pcu_no_two_phase_cmd,
805 "no two-phase-access",
806 NO_STR "Only use two phase access when requested my MS\n")
807{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200808 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200809
810 bts->force_two_phase = 0;
811
812 return CMD_SUCCESS;
813}
814
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200815DEFUN(cfg_pcu_alpha,
816 cfg_pcu_alpha_cmd,
817 "alpha <0-10>",
818 "Alpha parameter for MS power control in units of 0.1 (see TS 05.08) "
819 "NOTE: Be sure to set Alpha value at System information 13 too.\n"
820 "Alpha in units of 0.1\n")
821{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200822 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200823
824 bts->alpha = atoi(argv[0]);
825
826 return CMD_SUCCESS;
827}
828
829DEFUN(cfg_pcu_gamma,
830 cfg_pcu_gamma_cmd,
831 "gamma <0-62>",
832 "Gamma parameter for MS power control in units of dB (see TS 05.08)\n"
833 "Gamma in even unit of dBs\n")
834{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200835 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200836
837 bts->gamma = atoi(argv[0]) / 2;
838
839 return CMD_SUCCESS;
840}
841
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100842DEFUN(show_bts_stats,
843 show_bts_stats_cmd,
844 "show bts statistics",
845 SHOW_STR "BTS related functionality\nStatistics\n")
846{
847 vty_out_rate_ctr_group(vty, "", bts_main_data_stats());
848 return CMD_SUCCESS;
Daniel Willmann772415f2014-01-15 17:06:51 +0100849}
850
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100851#define IDLE_TIME_STR "keep an idle DL TBF alive for the time given\n"
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200852DEFUN_DEPRECATED(cfg_pcu_dl_tbf_idle_time,
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100853 cfg_pcu_dl_tbf_idle_time_cmd,
854 "dl-tbf-idle-time <1-5000>",
855 IDLE_TIME_STR "idle time in msec")
856{
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200857 vty_out(vty, "%% 'dl-tbf-idle-time' is now deprecated: use 'timer X2031 <val>' instead%s", VTY_NEWLINE);
858
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100859 struct gprs_rlcmac_bts *bts = bts_main_data();
860
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200861 if (osmo_tdef_set(bts->T_defs_pcu, -2031, atoi(argv[0]), OSMO_TDEF_MS) < 0)
862 return CMD_WARNING;
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100863 return CMD_SUCCESS;
864}
865
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200866DEFUN_DEPRECATED(cfg_pcu_no_dl_tbf_idle_time,
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100867 cfg_pcu_no_dl_tbf_idle_time_cmd,
868 "no dl-tbf-idle-time",
869 NO_STR IDLE_TIME_STR)
870{
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200871 vty_out(vty, "%% 'no dl-tbf-idle-time' is now deprecated: use 'timer X2031 0' instead%s", VTY_NEWLINE);
872
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100873 struct gprs_rlcmac_bts *bts = bts_main_data();
874
Pau Espin Pedrol2b5c6292019-09-09 13:41:00 +0200875 if (osmo_tdef_set(bts->T_defs_pcu, -2031, 0, OSMO_TDEF_MS) < 0)
876 return CMD_WARNING;
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100877 return CMD_SUCCESS;
878}
879
Oliver Smith45fdc442019-09-05 15:12:20 +0200880#define RETRANSMISSION_STR "retransmit blocks even before the MS had a chance to receive them (better throughput," \
881 " less readable traces)"
882DEFUN(cfg_pcu_dl_tbf_preemptive_retransmission,
883 cfg_pcu_dl_tbf_preemptive_retransmission_cmd,
884 "dl-tbf-preemptive-retransmission",
885 RETRANSMISSION_STR " (enabled by default)")
886{
887 struct gprs_rlcmac_bts *bts = bts_main_data();
888
889 bts->dl_tbf_preemptive_retransmission = true;
890
891 return CMD_SUCCESS;
892}
893
894DEFUN(cfg_pcu_no_dl_tbf_preemptive_retransmission,
895 cfg_pcu_no_dl_tbf_preemptive_retransmission_cmd,
896 "no dl-tbf-preemptive-retransmission",
897 NO_STR RETRANSMISSION_STR)
898{
899 struct gprs_rlcmac_bts *bts = bts_main_data();
900
901 bts->dl_tbf_preemptive_retransmission = false;
902
903 return CMD_SUCCESS;
904}
905
Jacob Erlbecka098c192015-05-28 16:11:19 +0200906#define MS_IDLE_TIME_STR "keep an idle MS object alive for the time given\n"
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200907DEFUN_DEPRECATED(cfg_pcu_ms_idle_time,
Jacob Erlbecka098c192015-05-28 16:11:19 +0200908 cfg_pcu_ms_idle_time_cmd,
909 "ms-idle-time <1-7200>",
910 MS_IDLE_TIME_STR "idle time in sec")
911{
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200912 vty_out(vty, "%% 'ms-idle-time' is now deprecated: use 'timer X2030 <val>' instead%s", VTY_NEWLINE);
913
Jacob Erlbecka098c192015-05-28 16:11:19 +0200914 struct gprs_rlcmac_bts *bts = bts_main_data();
915
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200916 if (osmo_tdef_set(bts->T_defs_pcu, -2030, atoi(argv[0]), OSMO_TDEF_S) < 0)
917 return CMD_WARNING;
Jacob Erlbecka098c192015-05-28 16:11:19 +0200918 return CMD_SUCCESS;
919}
920
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200921DEFUN_DEPRECATED(cfg_pcu_no_ms_idle_time,
Jacob Erlbecka098c192015-05-28 16:11:19 +0200922 cfg_pcu_no_ms_idle_time_cmd,
923 "no ms-idle-time",
924 NO_STR MS_IDLE_TIME_STR)
925{
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200926 vty_out(vty, "%% 'no ms-idle-time' is now deprecated: use 'timer X2030 0' instead%s", VTY_NEWLINE);
927
Jacob Erlbecka098c192015-05-28 16:11:19 +0200928 struct gprs_rlcmac_bts *bts = bts_main_data();
929
Pau Espin Pedrol63700ea2019-09-09 13:19:06 +0200930 if (osmo_tdef_set(bts->T_defs_pcu, -2030, 0, OSMO_TDEF_S) < 0)
931 return CMD_WARNING;
Jacob Erlbecka098c192015-05-28 16:11:19 +0200932 return CMD_SUCCESS;
933}
934
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200935#define CS_ERR_LIMITS_STR "set thresholds for error rate based CS adjustment\n"
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200936DEFUN(cfg_pcu_cs_err_limits,
937 cfg_pcu_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200938 "cs threshold <0-100> <0-100>",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200939 CS_STR CS_ERR_LIMITS_STR "lower limit in %\n" "upper limit in %\n")
940{
941 struct gprs_rlcmac_bts *bts = bts_main_data();
942
943 uint8_t lower_limit = atoi(argv[0]);
944 uint8_t upper_limit = atoi(argv[1]);
945
946 if (lower_limit > upper_limit) {
947 vty_out(vty,
948 "The lower limit must be less than or equal to the "
949 "upper limit.%s", VTY_NEWLINE);
950 return CMD_WARNING;
951 }
952
953 bts->cs_adj_enabled = 1;
954 bts->cs_adj_upper_limit = upper_limit;
955 bts->cs_adj_lower_limit = lower_limit;
956
957 return CMD_SUCCESS;
958}
959
960DEFUN(cfg_pcu_no_cs_err_limits,
961 cfg_pcu_no_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200962 "no cs threshold",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200963 NO_STR CS_STR CS_ERR_LIMITS_STR)
964{
965 struct gprs_rlcmac_bts *bts = bts_main_data();
966
967 bts->cs_adj_enabled = 0;
968 bts->cs_adj_upper_limit = 100;
969 bts->cs_adj_lower_limit = 0;
970
971 return CMD_SUCCESS;
972}
973
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200974#define CS_DOWNGRADE_STR "set threshold for data size based CS downgrade\n"
975DEFUN(cfg_pcu_cs_downgrade_thrsh,
976 cfg_pcu_cs_downgrade_thrsh_cmd,
977 "cs downgrade-threshold <1-10000>",
978 CS_STR CS_DOWNGRADE_STR "downgrade if less octets left\n")
979{
980 struct gprs_rlcmac_bts *bts = bts_main_data();
981
982 bts->cs_downgrade_threshold = atoi(argv[0]);
983
984 return CMD_SUCCESS;
985}
986
987DEFUN(cfg_pcu_no_cs_downgrade_thrsh,
988 cfg_pcu_no_cs_downgrade_thrsh_cmd,
989 "no cs downgrade-threshold",
Jacob Erlbeckf1379342015-06-29 10:49:30 +0200990 NO_STR CS_STR CS_DOWNGRADE_STR)
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200991{
992 struct gprs_rlcmac_bts *bts = bts_main_data();
993
994 bts->cs_downgrade_threshold = 0;
995
996 return CMD_SUCCESS;
997}
998
999
Jacob Erlbeck94cde132015-06-09 09:44:36 +02001000DEFUN(cfg_pcu_cs_lqual_ranges,
1001 cfg_pcu_cs_lqual_ranges_cmd,
1002 "cs link-quality-ranges cs1 <0-35> cs2 <0-35> <0-35> cs3 <0-35> <0-35> cs4 <0-35>",
1003 CS_STR "Set link quality ranges\n"
1004 "Set quality range for CS-1 (high value only)\n"
1005 "CS-1 high (dB)\n"
1006 "Set quality range for CS-2\n"
1007 "CS-2 low (dB)\n"
1008 "CS-2 high (dB)\n"
1009 "Set quality range for CS-3\n"
1010 "CS-3 low (dB)\n"
1011 "CS-3 high (dB)\n"
1012 "Set quality range for CS-4 (low value only)\n"
1013 "CS-4 low (dB)\n")
1014{
1015 struct gprs_rlcmac_bts *bts = bts_main_data();
1016
1017 uint8_t cs1_high = atoi(argv[0]);
1018 uint8_t cs2_low = atoi(argv[1]);
1019 uint8_t cs2_high = atoi(argv[2]);
1020 uint8_t cs3_low = atoi(argv[3]);
1021 uint8_t cs3_high = atoi(argv[4]);
1022 uint8_t cs4_low = atoi(argv[5]);
1023
1024 bts->cs_lqual_ranges[0].high = cs1_high;
1025 bts->cs_lqual_ranges[1].low = cs2_low;
1026 bts->cs_lqual_ranges[1].high = cs2_high;
1027 bts->cs_lqual_ranges[2].low = cs3_low;
1028 bts->cs_lqual_ranges[2].high = cs3_high;
1029 bts->cs_lqual_ranges[3].low = cs4_low;
1030
1031 return CMD_SUCCESS;
1032}
1033
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -04001034DEFUN(cfg_pcu_mcs_lqual_ranges,
1035 cfg_pcu_mcs_lqual_ranges_cmd,
1036 "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>",
1037 CS_STR "Set link quality ranges\n"
1038 "Set quality range for MCS-1 (high value only)\n"
1039 "MCS-1 high (dB)\n"
1040 "Set quality range for MCS-2\n"
1041 "MCS-2 high (dB)\n"
1042 "MCS-2 low (dB)\n"
1043 "Set quality range for MCS-3\n"
1044 "MCS-3 high (dB)\n"
1045 "MCS-3 low (dB)\n"
1046 "Set quality range for MCS-4\n"
1047 "MCS-4 high (dB)\n"
1048 "MCS-4 low (dB)\n"
1049 "Set quality range for MCS-5\n"
1050 "MCS-5 high (dB)\n"
1051 "MCS-5 low (dB)\n"
1052 "Set quality range for MCS-6\n"
1053 "MCS-6 low (dB)\n"
1054 "MCS-6 high (dB)\n"
1055 "Set quality range for MCS-7\n"
1056 "MCS-7 low (dB)\n"
1057 "MCS-7 high (dB)\n"
1058 "Set quality range for MCS-8\n"
1059 "MCS-8 low (dB)\n"
1060 "MCS-8 high (dB)\n"
1061 "Set quality range for MCS-9 (low value only)\n"
1062 "MCS-9 low (dB)\n")
1063{
1064 struct gprs_rlcmac_bts *bts = bts_main_data();
1065
1066 bts->mcs_lqual_ranges[0].high = atoi(argv[0]);
1067 bts->mcs_lqual_ranges[1].low = atoi(argv[1]);
1068 bts->mcs_lqual_ranges[1].high = atoi(argv[2]);
1069 bts->mcs_lqual_ranges[2].low = atoi(argv[3]);
1070 bts->mcs_lqual_ranges[2].high = atoi(argv[4]);
1071 bts->mcs_lqual_ranges[3].low = atoi(argv[5]);
1072 bts->mcs_lqual_ranges[3].high = atoi(argv[6]);
1073 bts->mcs_lqual_ranges[4].low = atoi(argv[7]);
1074 bts->mcs_lqual_ranges[4].high = atoi(argv[8]);
1075 bts->mcs_lqual_ranges[5].low = atoi(argv[9]);
1076 bts->mcs_lqual_ranges[5].high = atoi(argv[10]);
1077 bts->mcs_lqual_ranges[6].low = atoi(argv[11]);
1078 bts->mcs_lqual_ranges[6].high = atoi(argv[12]);
1079 bts->mcs_lqual_ranges[7].low = atoi(argv[13]);
1080 bts->mcs_lqual_ranges[7].high = atoi(argv[14]);
1081 bts->mcs_lqual_ranges[8].low = atoi(argv[15]);
1082
1083 return CMD_SUCCESS;
1084}
1085
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +02001086DEFUN(cfg_pcu_sock,
1087 cfg_pcu_sock_cmd,
1088 "pcu-socket PATH",
1089 "Configure the osmo-bts PCU socket file/path name\n"
1090 "Path of the socket to connect to\n")
1091{
1092 struct gprs_rlcmac_bts *bts = bts_main_data();
1093
1094 if (bts->pcu_sock_path) {
1095 /* FIXME: close the interface? */
1096 talloc_free(bts->pcu_sock_path);
1097 }
1098 bts->pcu_sock_path = talloc_strdup(tall_pcu_ctx, argv[0]);
1099 /* FIXME: re-open the interface? */
1100
1101 return CMD_SUCCESS;
1102}
Jacob Erlbeck94cde132015-06-09 09:44:36 +02001103
Harald Welte57d35152018-07-05 03:11:17 +02001104DEFUN(cfg_pcu_gb_dialect,
1105 cfg_pcu_gb_dialect_cmd,
1106 "gb-dialect (classic|ip-sns)",
1107 "Select which Gb interface dialect to use\n"
1108 "Classic Gb interface with NS-{RESET,BLOCK,UNBLOCK} and static configuration\n"
1109 "Modern Gb interface with IP-SNS (Sub Network Service) and dynamic configuration\n")
1110{
1111 struct gprs_rlcmac_bts *bts = bts_main_data();
1112
1113 if (!strcmp(argv[0], "ip-sns"))
1114 bts->gb_dialect_sns = true;
1115 else
1116 bts->gb_dialect_sns = false;
1117
1118 return CMD_SUCCESS;
1119}
1120
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +02001121DEFUN(show_bts_timer, show_bts_timer_cmd,
1122 "show bts-timer " OSMO_TDEF_VTY_ARG_T_OPTIONAL,
1123 SHOW_STR "Show BTS controlled timers\n"
1124 OSMO_TDEF_VTY_DOC_T)
1125{
1126 struct gprs_rlcmac_bts *bts = bts_main_data();
1127 const char *T_arg = argc > 0 ? argv[0] : NULL;
1128 return osmo_tdef_vty_show_cmd(vty, bts->T_defs_bts, T_arg, NULL);
1129}
1130
1131DEFUN(show_timer, show_timer_cmd,
1132 "show timer " OSMO_TDEF_VTY_ARG_T_OPTIONAL,
1133 SHOW_STR "Show PCU timers\n"
1134 OSMO_TDEF_VTY_DOC_T)
1135{
1136 struct gprs_rlcmac_bts *bts = bts_main_data();
1137 const char *T_arg = argc > 0 ? argv[0] : NULL;
1138 return osmo_tdef_vty_show_cmd(vty, bts->T_defs_pcu, T_arg, NULL);
1139}
1140
1141DEFUN(cfg_pcu_timer, cfg_pcu_timer_cmd,
1142 "timer " OSMO_TDEF_VTY_ARG_SET_OPTIONAL,
1143 "Configure or show PCU timers\n"
1144 OSMO_TDEF_VTY_DOC_SET)
1145{
1146 struct gprs_rlcmac_bts *bts = bts_main_data();
1147 /* If any arguments are missing, redirect to 'show' */
1148 if (argc < 2)
1149 return show_timer(self, vty, argc, argv);
1150 return osmo_tdef_vty_set_cmd(vty, bts->T_defs_pcu, argv);
1151}
1152
Daniel Willmann772415f2014-01-15 17:06:51 +01001153DEFUN(show_tbf,
1154 show_tbf_cmd,
Max12a09872018-02-01 16:07:33 +01001155 "show tbf (all|ccch|pacch)",
1156 SHOW_STR "information about TBFs\n"
1157 "All TBFs\n"
1158 "TBFs allocated via CCCH\n"
1159 "TBFs allocated via PACCH\n")
Daniel Willmann772415f2014-01-15 17:06:51 +01001160{
1161 struct gprs_rlcmac_bts *bts = bts_main_data();
Max12a09872018-02-01 16:07:33 +01001162 if (!strcmp(argv[0], "all"))
1163 return pcu_vty_show_tbf_all(vty, bts, true, true);
1164
1165 if (!strcmp(argv[0], "ccch"))
1166 return pcu_vty_show_tbf_all(vty, bts_main_data(), true, false);
1167
1168 return pcu_vty_show_tbf_all(vty, bts_main_data(), false, true);
Daniel Willmann772415f2014-01-15 17:06:51 +01001169}
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +01001170
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +02001171DEFUN(show_ms_all,
1172 show_ms_all_cmd,
1173 "show ms all",
1174 SHOW_STR "information about MSs\n" "All TBFs\n")
1175{
1176 struct gprs_rlcmac_bts *bts = bts_main_data();
1177 return pcu_vty_show_ms_all(vty, bts);
1178}
1179
Jacob Erlbeck37e896d2015-06-05 16:33:33 +02001180DEFUN(show_ms_tlli,
1181 show_ms_tlli_cmd,
1182 "show ms tlli TLLI",
1183 SHOW_STR "information about MSs\n" "Select MS by TLLI\n" "TLLI as hex\n")
1184{
1185 struct gprs_rlcmac_bts *bts = bts_main_data();
1186 char *endp = NULL;
1187 unsigned long long tlli = strtoll(argv[0], &endp, 16);
1188 if ((endp != NULL && *endp != 0) || tlli > 0xffffffffULL) {
1189 vty_out(vty, "Invalid TLLI.%s", VTY_NEWLINE);
1190 return CMD_WARNING;
1191 }
1192 return pcu_vty_show_ms_by_tlli(vty, bts, (uint32_t)tlli);
1193}
1194
1195DEFUN(show_ms_imsi,
1196 show_ms_imsi_cmd,
1197 "show ms imsi IMSI",
1198 SHOW_STR "information about MSs\n" "Select MS by IMSI\n" "IMSI\n")
1199{
1200 struct gprs_rlcmac_bts *bts = bts_main_data();
1201 return pcu_vty_show_ms_by_imsi(vty, bts, argv[0]);
1202}
1203
Andreas Eversberg12942562012-07-12 14:31:57 +02001204static const char pcu_copyright[] =
Harald Welted1e340f2013-01-17 12:24:29 +01001205 "Copyright (C) 2012 by Ivan Kluchnikov <kluchnikovi@gmail.com> and \r\n"
1206 " Andreas Eversberg <jolly@eversberg.eu>\r\n"
Andreas Eversberg12942562012-07-12 14:31:57 +02001207 "License GNU GPL version 2 or later\r\n"
1208 "This is free software: you are free to change and redistribute it.\r\n"
1209 "There is NO WARRANTY, to the extent permitted by law.\r\n";
1210
1211struct vty_app_info pcu_vty_info = {
1212 .name = "Osmo-PCU",
1213 .version = PACKAGE_VERSION,
1214 .copyright = pcu_copyright,
1215 .go_parent_cb = pcu_vty_go_parent,
1216 .is_config_node = pcu_vty_is_config_node,
1217};
1218
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02001219int pcu_vty_init(void)
Andreas Eversberg12942562012-07-12 14:31:57 +02001220{
1221// install_element_ve(&show_pcu_cmd);
1222
Harald Welte717cdf52017-07-21 21:56:23 +02001223 cfg_pcu_gsmtap_categ_cmd.string = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_names,
1224 "gsmtap-category (",
1225 "|",")", VTY_DO_LOWER);
1226 cfg_pcu_gsmtap_categ_cmd.doc = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_help,
1227 "GSMTAP Category\n",
1228 "\n", "", 0);
1229 cfg_pcu_no_gsmtap_categ_cmd.string = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_names,
1230 "no gsmtap-category (",
1231 "|",")", VTY_DO_LOWER);
1232 cfg_pcu_no_gsmtap_categ_cmd.doc = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_help,
1233 NO_STR "GSMTAP Category\n",
1234 "\n", "", 0);
1235
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02001236 logging_vty_add_cmds();
1237 osmo_stats_vty_add_cmds();
Andreas Eversberg12942562012-07-12 14:31:57 +02001238
Andreas Eversberg8b761a32012-07-20 21:50:31 +02001239 install_node(&pcu_node, config_write_pcu);
1240 install_element(CONFIG_NODE, &cfg_pcu_cmd);
Jacob Erlbeck953c7892015-09-28 18:12:57 +02001241 install_element(PCU_NODE, &cfg_pcu_egprs_cmd);
1242 install_element(PCU_NODE, &cfg_pcu_no_egprs_cmd);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +02001243 install_element(PCU_NODE, &cfg_pcu_no_two_phase_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +02001244 install_element(PCU_NODE, &cfg_pcu_cs_cmd);
1245 install_element(PCU_NODE, &cfg_pcu_no_cs_cmd);
Jacob Erlbeckb33e6752015-06-04 19:04:30 +02001246 install_element(PCU_NODE, &cfg_pcu_cs_max_cmd);
1247 install_element(PCU_NODE, &cfg_pcu_no_cs_max_cmd);
Jacob Erlbeck8322d082015-06-04 15:12:10 +02001248 install_element(PCU_NODE, &cfg_pcu_cs_err_limits_cmd);
1249 install_element(PCU_NODE, &cfg_pcu_no_cs_err_limits_cmd);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +02001250 install_element(PCU_NODE, &cfg_pcu_cs_downgrade_thrsh_cmd);
1251 install_element(PCU_NODE, &cfg_pcu_no_cs_downgrade_thrsh_cmd);
Jacob Erlbeck94cde132015-06-09 09:44:36 +02001252 install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd);
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -04001253 install_element(PCU_NODE, &cfg_pcu_mcs_lqual_ranges_cmd);
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +01001254 install_element(PCU_NODE, &cfg_pcu_mcs_cmd);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05301255 install_element(PCU_NODE, &cfg_pcu_dl_arq_cmd);
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +01001256 install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd);
Jacob Erlbeck0d058052016-01-07 11:48:28 +01001257 install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd);
1258 install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01001259 install_element(PCU_NODE, &cfg_pcu_window_size_cmd);
Andreas Eversberg24131bf2012-07-21 11:09:58 +02001260 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_cmd);
1261 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_inf_cmd);
1262 install_element(PCU_NODE, &cfg_pcu_no_queue_lifetime_cmd);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +01001263 install_element(PCU_NODE, &cfg_pcu_queue_hysteresis_cmd);
1264 install_element(PCU_NODE, &cfg_pcu_no_queue_hysteresis_cmd);
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +02001265 install_element(PCU_NODE, &cfg_pcu_queue_codel_cmd);
1266 install_element(PCU_NODE, &cfg_pcu_queue_codel_interval_cmd);
1267 install_element(PCU_NODE, &cfg_pcu_no_queue_codel_cmd);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +02001268 install_element(PCU_NODE, &cfg_pcu_queue_idle_ack_delay_cmd);
1269 install_element(PCU_NODE, &cfg_pcu_no_queue_idle_ack_delay_cmd);
Andreas Eversberga1503fa2012-07-22 08:58:09 +02001270 install_element(PCU_NODE, &cfg_pcu_alloc_cmd);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001271 install_element(PCU_NODE, &cfg_pcu_two_phase_cmd);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +02001272 install_element(PCU_NODE, &cfg_pcu_fc_interval_cmd);
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +02001273 install_element(PCU_NODE, &cfg_pcu_fc_bucket_time_cmd);
1274 install_element(PCU_NODE, &cfg_pcu_no_fc_bucket_time_cmd);
Jacob Erlbeck87d73412015-04-21 12:56:48 +02001275 install_element(PCU_NODE, &cfg_pcu_fc_bvc_bucket_size_cmd);
1276 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_bucket_size_cmd);
1277 install_element(PCU_NODE, &cfg_pcu_fc_bvc_leak_rate_cmd);
1278 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_leak_rate_cmd);
1279 install_element(PCU_NODE, &cfg_pcu_fc_ms_bucket_size_cmd);
1280 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_bucket_size_cmd);
1281 install_element(PCU_NODE, &cfg_pcu_fc_ms_leak_rate_cmd);
1282 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_leak_rate_cmd);
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +02001283 install_element(PCU_NODE, &cfg_pcu_alpha_cmd);
1284 install_element(PCU_NODE, &cfg_pcu_gamma_cmd);
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +01001285 install_element(PCU_NODE, &cfg_pcu_dl_tbf_idle_time_cmd);
1286 install_element(PCU_NODE, &cfg_pcu_no_dl_tbf_idle_time_cmd);
Oliver Smith45fdc442019-09-05 15:12:20 +02001287 install_element(PCU_NODE, &cfg_pcu_dl_tbf_preemptive_retransmission_cmd);
1288 install_element(PCU_NODE, &cfg_pcu_no_dl_tbf_preemptive_retransmission_cmd);
Jacob Erlbecka098c192015-05-28 16:11:19 +02001289 install_element(PCU_NODE, &cfg_pcu_ms_idle_time_cmd);
1290 install_element(PCU_NODE, &cfg_pcu_no_ms_idle_time_cmd);
Harald Welte717cdf52017-07-21 21:56:23 +02001291 install_element(PCU_NODE, &cfg_pcu_gsmtap_categ_cmd);
1292 install_element(PCU_NODE, &cfg_pcu_no_gsmtap_categ_cmd);
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +02001293 install_element(PCU_NODE, &cfg_pcu_sock_cmd);
Harald Welte57d35152018-07-05 03:11:17 +02001294 install_element(PCU_NODE, &cfg_pcu_gb_dialect_cmd);
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +02001295 install_element(PCU_NODE, &cfg_pcu_timer_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +02001296
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +01001297 install_element_ve(&show_bts_stats_cmd);
Daniel Willmann772415f2014-01-15 17:06:51 +01001298 install_element_ve(&show_tbf_cmd);
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +02001299 install_element_ve(&show_ms_all_cmd);
Jacob Erlbeck37e896d2015-06-05 16:33:33 +02001300 install_element_ve(&show_ms_tlli_cmd);
1301 install_element_ve(&show_ms_imsi_cmd);
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +02001302 install_element_ve(&show_bts_timer_cmd);
1303 install_element_ve(&show_timer_cmd);
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +01001304
Andreas Eversberg12942562012-07-12 14:31:57 +02001305 return 0;
1306}