blob: a566e7353bda60e17b7cbc34ebbc77036d086de2 [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>
Andreas Eversberg12942562012-07-12 14:31:57 +02007#include <osmocom/vty/logging.h>
Jacob Erlbeck42aba812015-11-10 15:32:00 +01008#include <osmocom/vty/stats.h>
Jacob Erlbeckc0c580c2015-04-30 15:59:01 +02009#include <osmocom/vty/misc.h>
Andreas Eversberg8b761a32012-07-20 21:50:31 +020010#include <osmocom/core/linuxlist.h>
Holger Hans Peter Freythere8915b92014-07-02 14:57:47 +020011#include <osmocom/core/rate_ctr.h>
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +020012#include <osmocom/pcu/pcuif_proto.h>
Andreas Eversberg12942562012-07-12 14:31:57 +020013#include "pcu_vty.h"
Andreas Eversberg8b761a32012-07-20 21:50:31 +020014#include "gprs_rlcmac.h"
Max6dc90b82018-02-19 17:17:28 +010015#include <pdch.h>
Holger Hans Peter Freyther67ed34e2013-10-17 17:01:54 +020016#include "bts.h"
Jacob Erlbeckc0c580c2015-04-30 15:59:01 +020017#include "tbf.h"
Jacob Erlbeck62e96a32015-06-04 09:42:14 +020018#include "pcu_vty_functions.h"
19
Harald Welte717cdf52017-07-21 21:56:23 +020020extern void *tall_pcu_ctx;
21
22static const struct value_string pcu_gsmtap_categ_names[] = {
23 { PCU_GSMTAP_C_DL_UNKNOWN, "dl-unknown" },
24 { PCU_GSMTAP_C_DL_DUMMY, "dl-dummy" },
25 { PCU_GSMTAP_C_DL_CTRL, "dl-ctrl" },
26 { PCU_GSMTAP_C_DL_DATA_GPRS, "dl-data-gprs" },
27 { PCU_GSMTAP_C_DL_DATA_EGPRS, "dl-data-egprs" },
Harald Weltebc219d52017-07-29 13:42:27 +020028 { PCU_GSMTAP_C_DL_PTCCH, "dl-ptcch" },
Harald Welte717cdf52017-07-21 21:56:23 +020029
30 { PCU_GSMTAP_C_UL_UNKNOWN, "ul-unknown" },
31 { PCU_GSMTAP_C_UL_DUMMY, "ul-dummy" },
32 { PCU_GSMTAP_C_UL_CTRL, "ul-ctrl" },
33 { PCU_GSMTAP_C_UL_DATA_GPRS, "ul-data-gprs" },
34 { PCU_GSMTAP_C_UL_DATA_EGPRS, "ul-data-egprs" },
35
36 { 0, NULL }
37};
38
39static const struct value_string pcu_gsmtap_categ_help[] = {
40 { PCU_GSMTAP_C_DL_UNKNOWN, "Unknown / Unparseable / Erroneous Downlink Blocks" },
41 { PCU_GSMTAP_C_DL_DUMMY, "Downlink Dummy Blocks" },
42 { PCU_GSMTAP_C_DL_CTRL, "Downlink Control Blocks" },
43 { PCU_GSMTAP_C_DL_DATA_GPRS, "Downlink Data Blocks (GPRS)" },
44 { PCU_GSMTAP_C_DL_DATA_EGPRS, "Downlink Data Blocks (EGPRS)" },
Harald Weltebc219d52017-07-29 13:42:27 +020045 { PCU_GSMTAP_C_DL_PTCCH, "Downlink PTCCH Blocks" },
Harald Welte717cdf52017-07-21 21:56:23 +020046
47 { PCU_GSMTAP_C_UL_UNKNOWN, "Unknown / Unparseable / Erroneous Downlink Blocks" },
48 { PCU_GSMTAP_C_UL_DUMMY, "Uplink Dummy Blocks" },
49 { PCU_GSMTAP_C_UL_CTRL, "Uplink Control Blocks" },
50 { PCU_GSMTAP_C_UL_DATA_GPRS, "Uplink Data Blocks (GPRS)" },
51 { PCU_GSMTAP_C_UL_DATA_EGPRS, "Uplink Data Blocks (EGPRS)" },
52
53 { 0, NULL }
54};
55
56
57DEFUN(cfg_pcu_gsmtap_categ, cfg_pcu_gsmtap_categ_cmd, "HIDDEN", "HIDDEN")
58{
59 struct gprs_rlcmac_bts *bts = bts_main_data();
60 int categ;
61
62 categ = get_string_value(pcu_gsmtap_categ_names, argv[0]);
63 if (categ < 0)
64 return CMD_WARNING;
65
66 bts->gsmtap_categ_mask |= (1 << categ);
67
68 return CMD_SUCCESS;
69}
70
71DEFUN(cfg_pcu_no_gsmtap_categ, cfg_pcu_no_gsmtap_categ_cmd, "HIDDEN", "HIDDEN")
72{
73 struct gprs_rlcmac_bts *bts = bts_main_data();
74 int categ;
75
76 categ = get_string_value(pcu_gsmtap_categ_names, argv[0]);
77 if (categ < 0)
78 return CMD_WARNING;
79
80 bts->gsmtap_categ_mask &= ~(1 << categ);
81
82 return CMD_SUCCESS;
83}
84
85
Jacob Erlbeckf76fede2015-08-17 13:42:46 +020086int pcu_vty_go_parent(struct vty *vty)
Andreas Eversberg12942562012-07-12 14:31:57 +020087{
88 switch (vty->node) {
89#if 0
90 case TRX_NODE:
Andreas Eversberg8b761a32012-07-20 21:50:31 +020091 vty->node = PCU_NODE;
Andreas Eversberg12942562012-07-12 14:31:57 +020092 {
93 struct gsm_bts_trx *trx = vty->index;
94 vty->index = trx->bts;
95 }
96 break;
97#endif
98 default:
99 vty->node = CONFIG_NODE;
100 }
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200101 return (enum node_type) vty->node;
Andreas Eversberg12942562012-07-12 14:31:57 +0200102}
103
104int pcu_vty_is_config_node(struct vty *vty, int node)
105{
106 switch (node) {
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200107 case PCU_NODE:
Andreas Eversberg12942562012-07-12 14:31:57 +0200108 return 1;
Andreas Eversberg12942562012-07-12 14:31:57 +0200109 default:
110 return 0;
111 }
112}
113
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200114static struct cmd_node pcu_node = {
115 (enum node_type) PCU_NODE,
Jacob Erlbeckcc12f022015-04-09 15:45:24 +0200116 "%s(config-pcu)# ",
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200117 1,
118};
119
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200120static int config_write_pcu(struct vty *vty)
121{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200122 struct gprs_rlcmac_bts *bts = bts_main_data();
Harald Welte717cdf52017-07-21 21:56:23 +0200123 unsigned int i;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200124
125 vty_out(vty, "pcu%s", VTY_NEWLINE);
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200126 if (bts->egprs_enabled)
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +0100127 vty_out(vty, " egprs only%s", VTY_NEWLINE);
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200128
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200129 vty_out(vty, " flow-control-interval %d%s", bts->fc_interval,
130 VTY_NEWLINE);
Jacob Erlbeck87d73412015-04-21 12:56:48 +0200131 if (bts->fc_bvc_bucket_size)
132 vty_out(vty, " flow-control force-bvc-bucket-size %d%s",
133 bts->fc_bvc_bucket_size, VTY_NEWLINE);
134 if (bts->fc_bvc_leak_rate)
135 vty_out(vty, " flow-control force-bvc-leak-rate %d%s",
136 bts->fc_bvc_leak_rate, VTY_NEWLINE);
137 if (bts->fc_ms_bucket_size)
138 vty_out(vty, " flow-control force-ms-bucket-size %d%s",
139 bts->fc_ms_bucket_size, VTY_NEWLINE);
140 if (bts->fc_ms_leak_rate)
141 vty_out(vty, " flow-control force-ms-leak-rate %d%s",
142 bts->fc_ms_leak_rate, VTY_NEWLINE);
Holger Hans Peter Freytherc421e8a2014-07-02 14:55:17 +0200143 if (bts->force_cs) {
Andreas Eversberg499ff412012-10-03 14:21:36 +0200144 if (bts->initial_cs_ul == bts->initial_cs_dl)
145 vty_out(vty, " cs %d%s", bts->initial_cs_dl,
146 VTY_NEWLINE);
147 else
148 vty_out(vty, " cs %d %d%s", bts->initial_cs_dl,
149 bts->initial_cs_ul, VTY_NEWLINE);
Holger Hans Peter Freytherc421e8a2014-07-02 14:55:17 +0200150 }
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200151 if (bts->max_cs_dl && bts->max_cs_ul) {
152 if (bts->max_cs_ul == bts->max_cs_dl)
153 vty_out(vty, " cs max %d%s", bts->max_cs_dl,
154 VTY_NEWLINE);
155 else
156 vty_out(vty, " cs max %d %d%s", bts->max_cs_dl,
157 bts->max_cs_ul, VTY_NEWLINE);
158 }
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200159 if (bts->cs_adj_enabled)
160 vty_out(vty, " cs threshold %d %d%s",
161 bts->cs_adj_lower_limit, bts->cs_adj_upper_limit,
162 VTY_NEWLINE);
163 else
164 vty_out(vty, " no cs threshold%s", VTY_NEWLINE);
165
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200166 if (bts->cs_downgrade_threshold)
167 vty_out(vty, " cs downgrade-threshold %d%s",
168 bts->cs_downgrade_threshold, VTY_NEWLINE);
169 else
170 vty_out(vty, " no cs downgrade-threshold%s", VTY_NEWLINE);
171
Jacob Erlbeck94cde132015-06-09 09:44:36 +0200172 vty_out(vty, " cs link-quality-ranges cs1 %d cs2 %d %d cs3 %d %d cs4 %d%s",
173 bts->cs_lqual_ranges[0].high,
174 bts->cs_lqual_ranges[1].low,
175 bts->cs_lqual_ranges[1].high,
176 bts->cs_lqual_ranges[2].low,
177 bts->cs_lqual_ranges[2].high,
178 bts->cs_lqual_ranges[3].low,
179 VTY_NEWLINE);
180
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -0400181 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",
182 bts->mcs_lqual_ranges[0].high,
183 bts->mcs_lqual_ranges[1].low,
184 bts->mcs_lqual_ranges[1].high,
185 bts->mcs_lqual_ranges[2].low,
186 bts->mcs_lqual_ranges[2].high,
187 bts->mcs_lqual_ranges[3].low,
188 bts->mcs_lqual_ranges[3].high,
189 bts->mcs_lqual_ranges[4].low,
190 bts->mcs_lqual_ranges[4].high,
191 bts->mcs_lqual_ranges[5].low,
192 bts->mcs_lqual_ranges[5].high,
193 bts->mcs_lqual_ranges[6].low,
194 bts->mcs_lqual_ranges[6].high,
195 bts->mcs_lqual_ranges[7].low,
196 bts->mcs_lqual_ranges[7].high,
197 bts->mcs_lqual_ranges[8].low,
198 VTY_NEWLINE);
199
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +0100200 if (bts->initial_mcs_dl != 1 && bts->initial_mcs_ul != 1) {
201 if (bts->initial_mcs_ul == bts->initial_mcs_dl)
202 vty_out(vty, " mcs %d%s", bts->initial_mcs_dl,
203 VTY_NEWLINE);
204 else
205 vty_out(vty, " mcs %d %d%s", bts->initial_mcs_dl,
206 bts->initial_mcs_ul, VTY_NEWLINE);
207 }
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -0400208
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100209 if (bts->max_mcs_dl && bts->max_mcs_ul) {
210 if (bts->max_mcs_ul == bts->max_mcs_dl)
211 vty_out(vty, " mcs max %d%s", bts->max_mcs_dl,
212 VTY_NEWLINE);
213 else
214 vty_out(vty, " mcs max %d %d%s", bts->max_mcs_dl,
215 bts->max_mcs_ul, VTY_NEWLINE);
216 }
217
Jacob Erlbeck36df7742016-01-19 15:53:30 +0100218 vty_out(vty, " window-size %d %d%s", bts->ws_base, bts->ws_pdch,
219 VTY_NEWLINE);
220
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530221 if (bts->dl_arq_type)
222 vty_out(vty, " egprs dl arq-type arq2%s",
223 VTY_NEWLINE);
224
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200225 if (bts->force_llc_lifetime == 0xffff)
226 vty_out(vty, " queue lifetime infinite%s", VTY_NEWLINE);
227 else if (bts->force_llc_lifetime)
228 vty_out(vty, " queue lifetime %d%s", bts->force_llc_lifetime,
229 VTY_NEWLINE);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100230 if (bts->llc_discard_csec)
231 vty_out(vty, " queue hysteresis %d%s", bts->llc_discard_csec,
232 VTY_NEWLINE);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200233 if (bts->llc_idle_ack_csec)
234 vty_out(vty, " queue idle-ack-delay %d%s", bts->llc_idle_ack_csec,
235 VTY_NEWLINE);
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200236 if (bts->llc_codel_interval_msec == LLC_CODEL_USE_DEFAULT)
237 vty_out(vty, " queue codel%s", VTY_NEWLINE);
238 else if (bts->llc_codel_interval_msec == LLC_CODEL_DISABLE)
239 vty_out(vty, " no queue codel%s", VTY_NEWLINE);
240 else
241 vty_out(vty, " queue codel interval %d%s",
242 bts->llc_codel_interval_msec/10, VTY_NEWLINE);
243
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200244 if (bts->alloc_algorithm == alloc_algorithm_a)
245 vty_out(vty, " alloc-algorithm a%s", VTY_NEWLINE);
246 if (bts->alloc_algorithm == alloc_algorithm_b)
247 vty_out(vty, " alloc-algorithm b%s", VTY_NEWLINE);
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200248 if (bts->alloc_algorithm == alloc_algorithm_dynamic)
249 vty_out(vty, " alloc-algorithm dynamic%s", VTY_NEWLINE);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200250 if (bts->force_two_phase)
251 vty_out(vty, " two-phase-access%s", VTY_NEWLINE);
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200252 vty_out(vty, " alpha %d%s", bts->alpha, VTY_NEWLINE);
253 vty_out(vty, " gamma %d%s", bts->gamma * 2, VTY_NEWLINE);
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100254 if (bts->dl_tbf_idle_msec)
255 vty_out(vty, " dl-tbf-idle-time %d%s", bts->dl_tbf_idle_msec,
256 VTY_NEWLINE);
Oliver Smith45fdc442019-09-05 15:12:20 +0200257 if (!bts->dl_tbf_preemptive_retransmission)
258 vty_out(vty, " no dl-tbf-preemptive-retransmission%s", VTY_NEWLINE);
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +0200259 if (strcmp(bts->pcu_sock_path, PCU_SOCK_DEFAULT))
260 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200261
Harald Welte717cdf52017-07-21 21:56:23 +0200262 for (i = 0; i < 32; i++) {
263 unsigned int cs = (1 << i);
264 if (bts->gsmtap_categ_mask & cs) {
265 vty_out(vty, " gsmtap-category %s%s",
266 get_value_string(pcu_gsmtap_categ_names, i), VTY_NEWLINE);
267 }
268 }
269
Harald Welte57d35152018-07-05 03:11:17 +0200270 if (bts->gb_dialect_sns)
271 vty_out(vty, " gb-dialect ip-sns%s", VTY_NEWLINE);
272 else
273 vty_out(vty, " gb-dialect classic%s", VTY_NEWLINE);
274
Maxc9ce6f92018-01-30 17:53:02 +0100275 return CMD_SUCCESS;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200276}
277
278/* per-BTS configuration */
279DEFUN(cfg_pcu,
280 cfg_pcu_cmd,
281 "pcu",
282 "BTS specific configure")
283{
284 vty->node = PCU_NODE;
285
286 return CMD_SUCCESS;
287}
288
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200289#define EGPRS_STR "EGPRS configuration\n"
290
291DEFUN(cfg_pcu_egprs,
292 cfg_pcu_egprs_cmd,
Jacob Erlbeck9b3d7e02016-01-19 10:44:42 +0100293 "egprs only",
294 EGPRS_STR "Use EGPRS and disable plain GPRS\n")
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200295{
296 struct gprs_rlcmac_bts *bts = bts_main_data();
297
298 bts->egprs_enabled = 1;
299
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200300 return CMD_SUCCESS;
301}
302
303DEFUN(cfg_pcu_no_egprs,
304 cfg_pcu_no_egprs_cmd,
305 "no egprs",
306 NO_STR EGPRS_STR)
307{
308 struct gprs_rlcmac_bts *bts = bts_main_data();
309
310 bts->egprs_enabled = 0;
311
312 return CMD_SUCCESS;
313}
314
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200315DEFUN(cfg_pcu_fc_interval,
316 cfg_pcu_fc_interval_cmd,
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200317 "flow-control-interval <1-10>",
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200318 "Interval between sending subsequent Flow Control PDUs\n"
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200319 "Interval time in seconds\n")
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200320{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200321 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200322
323 bts->fc_interval = atoi(argv[0]);
324
325 return CMD_SUCCESS;
326}
Jacob Erlbeck87d73412015-04-21 12:56:48 +0200327#define FC_STR "BSSGP Flow Control configuration\n"
328#define FC_BMAX_STR(who) "Force a fixed value for the " who " bucket size\n"
329#define FC_LR_STR(who) "Force a fixed value for the " who " leak rate\n"
330
331DEFUN(cfg_pcu_fc_bvc_bucket_size,
332 cfg_pcu_fc_bvc_bucket_size_cmd,
333 "flow-control force-bvc-bucket-size <1-6553500>",
334 FC_STR FC_BMAX_STR("BVC") "Bucket size in octets\n")
335{
336 struct gprs_rlcmac_bts *bts = bts_main_data();
337
338 bts->fc_bvc_bucket_size = atoi(argv[0]);
339
340 return CMD_SUCCESS;
341}
342
343DEFUN(cfg_pcu_no_fc_bvc_bucket_size,
344 cfg_pcu_no_fc_bvc_bucket_size_cmd,
345 "no flow-control force-bvc-bucket-size",
346 NO_STR FC_STR FC_BMAX_STR("BVC"))
347{
348 struct gprs_rlcmac_bts *bts = bts_main_data();
349
350 bts->fc_bvc_bucket_size = 0;
351
352 return CMD_SUCCESS;
353}
354
355DEFUN(cfg_pcu_fc_bvc_leak_rate,
356 cfg_pcu_fc_bvc_leak_rate_cmd,
357 "flow-control force-bvc-leak-rate <1-6553500>",
358 FC_STR FC_LR_STR("BVC") "Leak rate in bit/s\n")
359{
360 struct gprs_rlcmac_bts *bts = bts_main_data();
361
362 bts->fc_bvc_leak_rate = atoi(argv[0]);
363
364 return CMD_SUCCESS;
365}
366
367DEFUN(cfg_pcu_no_fc_bvc_leak_rate,
368 cfg_pcu_no_fc_bvc_leak_rate_cmd,
369 "no flow-control force-bvc-leak-rate",
370 NO_STR FC_STR FC_LR_STR("BVC"))
371{
372 struct gprs_rlcmac_bts *bts = bts_main_data();
373
374 bts->fc_bvc_leak_rate = 0;
375
376 return CMD_SUCCESS;
377}
378
379DEFUN(cfg_pcu_fc_ms_bucket_size,
380 cfg_pcu_fc_ms_bucket_size_cmd,
381 "flow-control force-ms-bucket-size <1-6553500>",
382 FC_STR FC_BMAX_STR("default MS") "Bucket size in octets\n")
383{
384 struct gprs_rlcmac_bts *bts = bts_main_data();
385
386 bts->fc_ms_bucket_size = atoi(argv[0]);
387
388 return CMD_SUCCESS;
389}
390
391DEFUN(cfg_pcu_no_fc_ms_bucket_size,
392 cfg_pcu_no_fc_ms_bucket_size_cmd,
393 "no flow-control force-ms-bucket-size",
394 NO_STR FC_STR FC_BMAX_STR("default MS"))
395{
396 struct gprs_rlcmac_bts *bts = bts_main_data();
397
398 bts->fc_ms_bucket_size = 0;
399
400 return CMD_SUCCESS;
401}
402
403DEFUN(cfg_pcu_fc_ms_leak_rate,
404 cfg_pcu_fc_ms_leak_rate_cmd,
405 "flow-control force-ms-leak-rate <1-6553500>",
406 FC_STR FC_LR_STR("default MS") "Leak rate in bit/s\n")
407{
408 struct gprs_rlcmac_bts *bts = bts_main_data();
409
410 bts->fc_ms_leak_rate = atoi(argv[0]);
411
412 return CMD_SUCCESS;
413}
414
415DEFUN(cfg_pcu_no_fc_ms_leak_rate,
416 cfg_pcu_no_fc_ms_leak_rate_cmd,
417 "no flow-control force-ms-leak-rate",
418 NO_STR FC_STR FC_LR_STR("default MS"))
419{
420 struct gprs_rlcmac_bts *bts = bts_main_data();
421
422 bts->fc_ms_leak_rate = 0;
423
424 return CMD_SUCCESS;
425}
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200426
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200427#define FC_BTIME_STR "Set target downlink maximum queueing time (only affects the advertised bucket size)\n"
428DEFUN(cfg_pcu_fc_bucket_time,
429 cfg_pcu_fc_bucket_time_cmd,
430 "flow-control bucket-time <1-65534>",
431 FC_STR FC_BTIME_STR "Time in centi-seconds\n")
432{
433 struct gprs_rlcmac_bts *bts = bts_main_data();
434
435 bts->fc_bucket_time = atoi(argv[0]);
436
437 return CMD_SUCCESS;
438}
439
440DEFUN(cfg_pcu_no_fc_bucket_time,
441 cfg_pcu_no_fc_bucket_time_cmd,
442 "no flow-control bucket-time",
443 NO_STR FC_STR FC_BTIME_STR)
444{
445 struct gprs_rlcmac_bts *bts = bts_main_data();
446
447 bts->fc_bucket_time = 0;
448
449 return CMD_SUCCESS;
450}
451
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200452#define CS_STR "Coding Scheme configuration\n"
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200453
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200454DEFUN(cfg_pcu_cs,
455 cfg_pcu_cs_cmd,
Andreas Eversberg499ff412012-10-03 14:21:36 +0200456 "cs <1-4> [<1-4>]",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200457 CS_STR
458 "Initial CS value to be used (overrides BTS config)\n"
459 "Use a different initial CS value for the uplink")
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200460{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200461 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200462 uint8_t cs = atoi(argv[0]);
463
464 bts->force_cs = 1;
Andreas Eversberg499ff412012-10-03 14:21:36 +0200465 bts->initial_cs_dl = cs;
466 if (argc > 1)
467 bts->initial_cs_ul = atoi(argv[1]);
468 else
469 bts->initial_cs_ul = cs;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200470
471 return CMD_SUCCESS;
472}
473
474DEFUN(cfg_pcu_no_cs,
475 cfg_pcu_no_cs_cmd,
476 "no cs",
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200477 NO_STR CS_STR)
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200478{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200479 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200480
481 bts->force_cs = 0;
482
483 return CMD_SUCCESS;
484}
485
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100486#define CS_MAX_STR "Set maximum values for adaptive CS selection (overrides BTS config)\n"
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200487DEFUN(cfg_pcu_cs_max,
488 cfg_pcu_cs_max_cmd,
489 "cs max <1-4> [<1-4>]",
490 CS_STR
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100491 CS_MAX_STR
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200492 "Maximum CS value to be used\n"
493 "Use a different maximum CS value for the uplink")
494{
495 struct gprs_rlcmac_bts *bts = bts_main_data();
496 uint8_t cs = atoi(argv[0]);
497
498 bts->max_cs_dl = cs;
499 if (argc > 1)
500 bts->max_cs_ul = atoi(argv[1]);
501 else
502 bts->max_cs_ul = cs;
503
504 return CMD_SUCCESS;
505}
506
507DEFUN(cfg_pcu_no_cs_max,
508 cfg_pcu_no_cs_max_cmd,
509 "no cs max",
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100510 NO_STR CS_STR CS_MAX_STR)
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200511{
512 struct gprs_rlcmac_bts *bts = bts_main_data();
513
514 bts->max_cs_dl = 0;
515 bts->max_cs_ul = 0;
516
517 return CMD_SUCCESS;
518}
519
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100520#define MCS_STR "Modulation and Coding Scheme configuration (EGPRS)\n"
521
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +0100522DEFUN(cfg_pcu_mcs,
523 cfg_pcu_mcs_cmd,
524 "mcs <1-9> [<1-9>]",
525 MCS_STR
526 "Initial MCS value to be used (default 1)\n"
527 "Use a different initial MCS value for the uplink")
528{
529 struct gprs_rlcmac_bts *bts = bts_main_data();
530 uint8_t cs = atoi(argv[0]);
531
532 bts->initial_mcs_dl = cs;
533 if (argc > 1)
534 bts->initial_mcs_ul = atoi(argv[1]);
535 else
536 bts->initial_mcs_ul = cs;
537
538 return CMD_SUCCESS;
539}
540
541DEFUN(cfg_pcu_no_mcs,
542 cfg_pcu_no_mcs_cmd,
543 "no mcs",
544 NO_STR MCS_STR)
545{
546 struct gprs_rlcmac_bts *bts = bts_main_data();
547
548 bts->initial_mcs_dl = 1;
549 bts->initial_mcs_ul = 1;
550
551 return CMD_SUCCESS;
552}
553
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100554DEFUN(cfg_pcu_mcs_max,
555 cfg_pcu_mcs_max_cmd,
Jacob Erlbeckf9940ca2016-01-19 10:32:33 +0100556 "mcs max <1-9> [<1-9>]",
Jacob Erlbeck0d058052016-01-07 11:48:28 +0100557 MCS_STR
558 CS_MAX_STR
559 "Maximum MCS value to be used\n"
560 "Use a different maximum MCS value for the uplink")
561{
562 struct gprs_rlcmac_bts *bts = bts_main_data();
563 uint8_t mcs = atoi(argv[0]);
564
565 bts->max_mcs_dl = mcs;
566 if (argc > 1)
567 bts->max_mcs_ul = atoi(argv[1]);
568 else
569 bts->max_mcs_ul = mcs;
570
571 return CMD_SUCCESS;
572}
573
574DEFUN(cfg_pcu_no_mcs_max,
575 cfg_pcu_no_mcs_max_cmd,
576 "no mcs max",
577 NO_STR MCS_STR CS_MAX_STR)
578{
579 struct gprs_rlcmac_bts *bts = bts_main_data();
580
581 bts->max_mcs_dl = 0;
582 bts->max_mcs_ul = 0;
583
584 return CMD_SUCCESS;
585}
586
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530587#define DL_STR "downlink specific configuration\n"
588
589DEFUN(cfg_pcu_dl_arq_type,
590 cfg_pcu_dl_arq_cmd,
591 "egprs dl arq-type (spb|arq2)",
592 EGPRS_STR DL_STR "ARQ options\n"
593 "enable SPB(ARQ1) support\n"
594 "enable ARQ2 support")
595{
596 struct gprs_rlcmac_bts *bts = bts_main_data();
597
598 if (!strcmp(argv[0], "arq2"))
599 bts->dl_arq_type = 1;
600 else
601 bts->dl_arq_type = 0;
602
603 return CMD_SUCCESS;
604}
605
Jacob Erlbeck36df7742016-01-19 15:53:30 +0100606DEFUN(cfg_pcu_window_size,
607 cfg_pcu_window_size_cmd,
608 "window-size <0-1024> [<0-256>]",
609 "Window size configuration (b + N_PDCH * f)\n"
610 "Base value (b)\n"
611 "Factor for number of PDCH (f)")
612{
613 struct gprs_rlcmac_bts *bts = bts_main_data();
614 uint16_t b = atoi(argv[0]);
615
616 bts->ws_base = b;
617 if (argc > 1) {
618 uint16_t f = atoi(argv[1]);
619 bts->ws_pdch = f;
620 }
621
622 return CMD_SUCCESS;
623}
624
625
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200626#define QUEUE_STR "Packet queue options\n"
627#define LIFETIME_STR "Set lifetime limit of LLC frame in centi-seconds " \
628 "(overrides the value given by SGSN)\n"
629
630DEFUN(cfg_pcu_queue_lifetime,
631 cfg_pcu_queue_lifetime_cmd,
632 "queue lifetime <1-65534>",
633 QUEUE_STR LIFETIME_STR "Lifetime in centi-seconds")
634{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200635 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200636 uint16_t csec = atoi(argv[0]);
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200637
638 bts->force_llc_lifetime = csec;
639
640 return CMD_SUCCESS;
641}
642
643DEFUN(cfg_pcu_queue_lifetime_inf,
644 cfg_pcu_queue_lifetime_inf_cmd,
645 "queue lifetime infinite",
646 QUEUE_STR LIFETIME_STR "Infinite lifetime")
647{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200648 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200649
650 bts->force_llc_lifetime = 0xffff;
651
652 return CMD_SUCCESS;
653}
654
655DEFUN(cfg_pcu_no_queue_lifetime,
656 cfg_pcu_no_queue_lifetime_cmd,
657 "no queue lifetime",
658 NO_STR QUEUE_STR "Disable lifetime limit of LLC frame (use value given "
659 "by SGSN)\n")
660{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200661 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200662
663 bts->force_llc_lifetime = 0;
664
665 return CMD_SUCCESS;
666}
667
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100668#define QUEUE_HYSTERESIS_STR "Set lifetime hysteresis of LLC frame in centi-seconds " \
669 "(continue discarding until lifetime-hysteresis is reached)\n"
670
671DEFUN(cfg_pcu_queue_hysteresis,
672 cfg_pcu_queue_hysteresis_cmd,
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200673 "queue hysteresis <1-65535>",
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100674 QUEUE_STR QUEUE_HYSTERESIS_STR "Hysteresis in centi-seconds")
675{
676 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200677 uint16_t csec = atoi(argv[0]);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100678
679 bts->llc_discard_csec = csec;
680
681 return CMD_SUCCESS;
682}
683
684DEFUN(cfg_pcu_no_queue_hysteresis,
685 cfg_pcu_no_queue_hysteresis_cmd,
686 "no queue hysteresis",
687 NO_STR QUEUE_STR QUEUE_HYSTERESIS_STR)
688{
689 struct gprs_rlcmac_bts *bts = bts_main_data();
690
691 bts->llc_discard_csec = 0;
692
693 return CMD_SUCCESS;
694}
695
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200696#define QUEUE_CODEL_STR "Set CoDel queue management\n"
697
698DEFUN(cfg_pcu_queue_codel,
699 cfg_pcu_queue_codel_cmd,
700 "queue codel",
701 QUEUE_STR QUEUE_CODEL_STR)
702{
703 struct gprs_rlcmac_bts *bts = bts_main_data();
704
705 bts->llc_codel_interval_msec = LLC_CODEL_USE_DEFAULT;
706
707 return CMD_SUCCESS;
708}
709
710DEFUN(cfg_pcu_queue_codel_interval,
711 cfg_pcu_queue_codel_interval_cmd,
712 "queue codel interval <1-1000>",
713 QUEUE_STR QUEUE_CODEL_STR "Specify interval\n" "Interval in centi-seconds")
714{
715 struct gprs_rlcmac_bts *bts = bts_main_data();
716 uint16_t csec = atoi(argv[0]);
717
718 bts->llc_codel_interval_msec = 10*csec;
719
720 return CMD_SUCCESS;
721}
722
723DEFUN(cfg_pcu_no_queue_codel,
724 cfg_pcu_no_queue_codel_cmd,
725 "no queue codel",
726 NO_STR QUEUE_STR QUEUE_CODEL_STR)
727{
728 struct gprs_rlcmac_bts *bts = bts_main_data();
729
730 bts->llc_codel_interval_msec = LLC_CODEL_DISABLE;
731
732 return CMD_SUCCESS;
733}
734
735
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200736#define QUEUE_IDLE_ACK_STR "Request an ACK after the last DL LLC frame in centi-seconds\n"
737
738DEFUN(cfg_pcu_queue_idle_ack_delay,
739 cfg_pcu_queue_idle_ack_delay_cmd,
740 "queue idle-ack-delay <1-65535>",
741 QUEUE_STR QUEUE_IDLE_ACK_STR "Idle ACK delay in centi-seconds")
742{
743 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200744 uint16_t csec = atoi(argv[0]);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200745
746 bts->llc_idle_ack_csec = csec;
747
748 return CMD_SUCCESS;
749}
750
751DEFUN(cfg_pcu_no_queue_idle_ack_delay,
752 cfg_pcu_no_queue_idle_ack_delay_cmd,
753 "no queue idle-ack-delay",
754 NO_STR QUEUE_STR QUEUE_IDLE_ACK_STR)
755{
756 struct gprs_rlcmac_bts *bts = bts_main_data();
757
758 bts->llc_idle_ack_csec = 0;
759
760 return CMD_SUCCESS;
761}
762
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100763
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200764DEFUN(cfg_pcu_alloc,
765 cfg_pcu_alloc_cmd,
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200766 "alloc-algorithm (a|b|dynamic)",
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200767 "Select slot allocation algorithm to use when assigning timeslots on "
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200768 "PACCH\n"
769 "Single slot is assigned only\n"
770 "Multiple slots are assigned for semi-duplex operation\n"
771 "Dynamically select the algorithm based on the system state\n")
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200772{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200773 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200774
775 switch (argv[0][0]) {
776 case 'a':
777 bts->alloc_algorithm = alloc_algorithm_a;
778 break;
779 case 'b':
780 bts->alloc_algorithm = alloc_algorithm_b;
781 break;
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200782 default:
783 bts->alloc_algorithm = alloc_algorithm_dynamic;
784 break;
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200785 }
786
787 return CMD_SUCCESS;
788}
789
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200790DEFUN(cfg_pcu_two_phase,
791 cfg_pcu_two_phase_cmd,
792 "two-phase-access",
793 "Force two phase access when MS requests single phase access\n")
794{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200795 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200796
797 bts->force_two_phase = 1;
798
799 return CMD_SUCCESS;
800}
801
802DEFUN(cfg_pcu_no_two_phase,
803 cfg_pcu_no_two_phase_cmd,
804 "no two-phase-access",
805 NO_STR "Only use two phase access when requested my MS\n")
806{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200807 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200808
809 bts->force_two_phase = 0;
810
811 return CMD_SUCCESS;
812}
813
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200814DEFUN(cfg_pcu_alpha,
815 cfg_pcu_alpha_cmd,
816 "alpha <0-10>",
817 "Alpha parameter for MS power control in units of 0.1 (see TS 05.08) "
818 "NOTE: Be sure to set Alpha value at System information 13 too.\n"
819 "Alpha in units of 0.1\n")
820{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200821 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200822
823 bts->alpha = atoi(argv[0]);
824
825 return CMD_SUCCESS;
826}
827
828DEFUN(cfg_pcu_gamma,
829 cfg_pcu_gamma_cmd,
830 "gamma <0-62>",
831 "Gamma parameter for MS power control in units of dB (see TS 05.08)\n"
832 "Gamma in even unit of dBs\n")
833{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200834 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200835
836 bts->gamma = atoi(argv[0]) / 2;
837
838 return CMD_SUCCESS;
839}
840
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100841DEFUN(show_bts_stats,
842 show_bts_stats_cmd,
843 "show bts statistics",
844 SHOW_STR "BTS related functionality\nStatistics\n")
845{
846 vty_out_rate_ctr_group(vty, "", bts_main_data_stats());
847 return CMD_SUCCESS;
Daniel Willmann772415f2014-01-15 17:06:51 +0100848}
849
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100850#define IDLE_TIME_STR "keep an idle DL TBF alive for the time given\n"
851DEFUN(cfg_pcu_dl_tbf_idle_time,
852 cfg_pcu_dl_tbf_idle_time_cmd,
853 "dl-tbf-idle-time <1-5000>",
854 IDLE_TIME_STR "idle time in msec")
855{
856 struct gprs_rlcmac_bts *bts = bts_main_data();
857
858 bts->dl_tbf_idle_msec = atoi(argv[0]);
859
860 return CMD_SUCCESS;
861}
862
863DEFUN(cfg_pcu_no_dl_tbf_idle_time,
864 cfg_pcu_no_dl_tbf_idle_time_cmd,
865 "no dl-tbf-idle-time",
866 NO_STR IDLE_TIME_STR)
867{
868 struct gprs_rlcmac_bts *bts = bts_main_data();
869
870 bts->dl_tbf_idle_msec = 0;
871
872 return CMD_SUCCESS;
873}
874
Oliver Smith45fdc442019-09-05 15:12:20 +0200875#define RETRANSMISSION_STR "retransmit blocks even before the MS had a chance to receive them (better throughput," \
876 " less readable traces)"
877DEFUN(cfg_pcu_dl_tbf_preemptive_retransmission,
878 cfg_pcu_dl_tbf_preemptive_retransmission_cmd,
879 "dl-tbf-preemptive-retransmission",
880 RETRANSMISSION_STR " (enabled by default)")
881{
882 struct gprs_rlcmac_bts *bts = bts_main_data();
883
884 bts->dl_tbf_preemptive_retransmission = true;
885
886 return CMD_SUCCESS;
887}
888
889DEFUN(cfg_pcu_no_dl_tbf_preemptive_retransmission,
890 cfg_pcu_no_dl_tbf_preemptive_retransmission_cmd,
891 "no dl-tbf-preemptive-retransmission",
892 NO_STR RETRANSMISSION_STR)
893{
894 struct gprs_rlcmac_bts *bts = bts_main_data();
895
896 bts->dl_tbf_preemptive_retransmission = false;
897
898 return CMD_SUCCESS;
899}
900
Jacob Erlbecka098c192015-05-28 16:11:19 +0200901#define MS_IDLE_TIME_STR "keep an idle MS object alive for the time given\n"
902DEFUN(cfg_pcu_ms_idle_time,
903 cfg_pcu_ms_idle_time_cmd,
904 "ms-idle-time <1-7200>",
905 MS_IDLE_TIME_STR "idle time in sec")
906{
907 struct gprs_rlcmac_bts *bts = bts_main_data();
908
909 bts->ms_idle_sec = atoi(argv[0]);
910
911 return CMD_SUCCESS;
912}
913
914DEFUN(cfg_pcu_no_ms_idle_time,
915 cfg_pcu_no_ms_idle_time_cmd,
916 "no ms-idle-time",
917 NO_STR MS_IDLE_TIME_STR)
918{
919 struct gprs_rlcmac_bts *bts = bts_main_data();
920
921 bts->ms_idle_sec = 0;
922
923 return CMD_SUCCESS;
924}
925
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200926#define CS_ERR_LIMITS_STR "set thresholds for error rate based CS adjustment\n"
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200927DEFUN(cfg_pcu_cs_err_limits,
928 cfg_pcu_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200929 "cs threshold <0-100> <0-100>",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200930 CS_STR CS_ERR_LIMITS_STR "lower limit in %\n" "upper limit in %\n")
931{
932 struct gprs_rlcmac_bts *bts = bts_main_data();
933
934 uint8_t lower_limit = atoi(argv[0]);
935 uint8_t upper_limit = atoi(argv[1]);
936
937 if (lower_limit > upper_limit) {
938 vty_out(vty,
939 "The lower limit must be less than or equal to the "
940 "upper limit.%s", VTY_NEWLINE);
941 return CMD_WARNING;
942 }
943
944 bts->cs_adj_enabled = 1;
945 bts->cs_adj_upper_limit = upper_limit;
946 bts->cs_adj_lower_limit = lower_limit;
947
948 return CMD_SUCCESS;
949}
950
951DEFUN(cfg_pcu_no_cs_err_limits,
952 cfg_pcu_no_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200953 "no cs threshold",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200954 NO_STR CS_STR CS_ERR_LIMITS_STR)
955{
956 struct gprs_rlcmac_bts *bts = bts_main_data();
957
958 bts->cs_adj_enabled = 0;
959 bts->cs_adj_upper_limit = 100;
960 bts->cs_adj_lower_limit = 0;
961
962 return CMD_SUCCESS;
963}
964
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200965#define CS_DOWNGRADE_STR "set threshold for data size based CS downgrade\n"
966DEFUN(cfg_pcu_cs_downgrade_thrsh,
967 cfg_pcu_cs_downgrade_thrsh_cmd,
968 "cs downgrade-threshold <1-10000>",
969 CS_STR CS_DOWNGRADE_STR "downgrade if less octets left\n")
970{
971 struct gprs_rlcmac_bts *bts = bts_main_data();
972
973 bts->cs_downgrade_threshold = atoi(argv[0]);
974
975 return CMD_SUCCESS;
976}
977
978DEFUN(cfg_pcu_no_cs_downgrade_thrsh,
979 cfg_pcu_no_cs_downgrade_thrsh_cmd,
980 "no cs downgrade-threshold",
Jacob Erlbeckf1379342015-06-29 10:49:30 +0200981 NO_STR CS_STR CS_DOWNGRADE_STR)
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200982{
983 struct gprs_rlcmac_bts *bts = bts_main_data();
984
985 bts->cs_downgrade_threshold = 0;
986
987 return CMD_SUCCESS;
988}
989
990
Jacob Erlbeck94cde132015-06-09 09:44:36 +0200991DEFUN(cfg_pcu_cs_lqual_ranges,
992 cfg_pcu_cs_lqual_ranges_cmd,
993 "cs link-quality-ranges cs1 <0-35> cs2 <0-35> <0-35> cs3 <0-35> <0-35> cs4 <0-35>",
994 CS_STR "Set link quality ranges\n"
995 "Set quality range for CS-1 (high value only)\n"
996 "CS-1 high (dB)\n"
997 "Set quality range for CS-2\n"
998 "CS-2 low (dB)\n"
999 "CS-2 high (dB)\n"
1000 "Set quality range for CS-3\n"
1001 "CS-3 low (dB)\n"
1002 "CS-3 high (dB)\n"
1003 "Set quality range for CS-4 (low value only)\n"
1004 "CS-4 low (dB)\n")
1005{
1006 struct gprs_rlcmac_bts *bts = bts_main_data();
1007
1008 uint8_t cs1_high = atoi(argv[0]);
1009 uint8_t cs2_low = atoi(argv[1]);
1010 uint8_t cs2_high = atoi(argv[2]);
1011 uint8_t cs3_low = atoi(argv[3]);
1012 uint8_t cs3_high = atoi(argv[4]);
1013 uint8_t cs4_low = atoi(argv[5]);
1014
1015 bts->cs_lqual_ranges[0].high = cs1_high;
1016 bts->cs_lqual_ranges[1].low = cs2_low;
1017 bts->cs_lqual_ranges[1].high = cs2_high;
1018 bts->cs_lqual_ranges[2].low = cs3_low;
1019 bts->cs_lqual_ranges[2].high = cs3_high;
1020 bts->cs_lqual_ranges[3].low = cs4_low;
1021
1022 return CMD_SUCCESS;
1023}
1024
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -04001025DEFUN(cfg_pcu_mcs_lqual_ranges,
1026 cfg_pcu_mcs_lqual_ranges_cmd,
1027 "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>",
1028 CS_STR "Set link quality ranges\n"
1029 "Set quality range for MCS-1 (high value only)\n"
1030 "MCS-1 high (dB)\n"
1031 "Set quality range for MCS-2\n"
1032 "MCS-2 high (dB)\n"
1033 "MCS-2 low (dB)\n"
1034 "Set quality range for MCS-3\n"
1035 "MCS-3 high (dB)\n"
1036 "MCS-3 low (dB)\n"
1037 "Set quality range for MCS-4\n"
1038 "MCS-4 high (dB)\n"
1039 "MCS-4 low (dB)\n"
1040 "Set quality range for MCS-5\n"
1041 "MCS-5 high (dB)\n"
1042 "MCS-5 low (dB)\n"
1043 "Set quality range for MCS-6\n"
1044 "MCS-6 low (dB)\n"
1045 "MCS-6 high (dB)\n"
1046 "Set quality range for MCS-7\n"
1047 "MCS-7 low (dB)\n"
1048 "MCS-7 high (dB)\n"
1049 "Set quality range for MCS-8\n"
1050 "MCS-8 low (dB)\n"
1051 "MCS-8 high (dB)\n"
1052 "Set quality range for MCS-9 (low value only)\n"
1053 "MCS-9 low (dB)\n")
1054{
1055 struct gprs_rlcmac_bts *bts = bts_main_data();
1056
1057 bts->mcs_lqual_ranges[0].high = atoi(argv[0]);
1058 bts->mcs_lqual_ranges[1].low = atoi(argv[1]);
1059 bts->mcs_lqual_ranges[1].high = atoi(argv[2]);
1060 bts->mcs_lqual_ranges[2].low = atoi(argv[3]);
1061 bts->mcs_lqual_ranges[2].high = atoi(argv[4]);
1062 bts->mcs_lqual_ranges[3].low = atoi(argv[5]);
1063 bts->mcs_lqual_ranges[3].high = atoi(argv[6]);
1064 bts->mcs_lqual_ranges[4].low = atoi(argv[7]);
1065 bts->mcs_lqual_ranges[4].high = atoi(argv[8]);
1066 bts->mcs_lqual_ranges[5].low = atoi(argv[9]);
1067 bts->mcs_lqual_ranges[5].high = atoi(argv[10]);
1068 bts->mcs_lqual_ranges[6].low = atoi(argv[11]);
1069 bts->mcs_lqual_ranges[6].high = atoi(argv[12]);
1070 bts->mcs_lqual_ranges[7].low = atoi(argv[13]);
1071 bts->mcs_lqual_ranges[7].high = atoi(argv[14]);
1072 bts->mcs_lqual_ranges[8].low = atoi(argv[15]);
1073
1074 return CMD_SUCCESS;
1075}
1076
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +02001077DEFUN(cfg_pcu_sock,
1078 cfg_pcu_sock_cmd,
1079 "pcu-socket PATH",
1080 "Configure the osmo-bts PCU socket file/path name\n"
1081 "Path of the socket to connect to\n")
1082{
1083 struct gprs_rlcmac_bts *bts = bts_main_data();
1084
1085 if (bts->pcu_sock_path) {
1086 /* FIXME: close the interface? */
1087 talloc_free(bts->pcu_sock_path);
1088 }
1089 bts->pcu_sock_path = talloc_strdup(tall_pcu_ctx, argv[0]);
1090 /* FIXME: re-open the interface? */
1091
1092 return CMD_SUCCESS;
1093}
Jacob Erlbeck94cde132015-06-09 09:44:36 +02001094
Harald Welte57d35152018-07-05 03:11:17 +02001095DEFUN(cfg_pcu_gb_dialect,
1096 cfg_pcu_gb_dialect_cmd,
1097 "gb-dialect (classic|ip-sns)",
1098 "Select which Gb interface dialect to use\n"
1099 "Classic Gb interface with NS-{RESET,BLOCK,UNBLOCK} and static configuration\n"
1100 "Modern Gb interface with IP-SNS (Sub Network Service) and dynamic configuration\n")
1101{
1102 struct gprs_rlcmac_bts *bts = bts_main_data();
1103
1104 if (!strcmp(argv[0], "ip-sns"))
1105 bts->gb_dialect_sns = true;
1106 else
1107 bts->gb_dialect_sns = false;
1108
1109 return CMD_SUCCESS;
1110}
1111
Daniel Willmann772415f2014-01-15 17:06:51 +01001112DEFUN(show_tbf,
1113 show_tbf_cmd,
Max12a09872018-02-01 16:07:33 +01001114 "show tbf (all|ccch|pacch)",
1115 SHOW_STR "information about TBFs\n"
1116 "All TBFs\n"
1117 "TBFs allocated via CCCH\n"
1118 "TBFs allocated via PACCH\n")
Daniel Willmann772415f2014-01-15 17:06:51 +01001119{
1120 struct gprs_rlcmac_bts *bts = bts_main_data();
Max12a09872018-02-01 16:07:33 +01001121 if (!strcmp(argv[0], "all"))
1122 return pcu_vty_show_tbf_all(vty, bts, true, true);
1123
1124 if (!strcmp(argv[0], "ccch"))
1125 return pcu_vty_show_tbf_all(vty, bts_main_data(), true, false);
1126
1127 return pcu_vty_show_tbf_all(vty, bts_main_data(), false, true);
Daniel Willmann772415f2014-01-15 17:06:51 +01001128}
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +01001129
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +02001130DEFUN(show_ms_all,
1131 show_ms_all_cmd,
1132 "show ms all",
1133 SHOW_STR "information about MSs\n" "All TBFs\n")
1134{
1135 struct gprs_rlcmac_bts *bts = bts_main_data();
1136 return pcu_vty_show_ms_all(vty, bts);
1137}
1138
Jacob Erlbeck37e896d2015-06-05 16:33:33 +02001139DEFUN(show_ms_tlli,
1140 show_ms_tlli_cmd,
1141 "show ms tlli TLLI",
1142 SHOW_STR "information about MSs\n" "Select MS by TLLI\n" "TLLI as hex\n")
1143{
1144 struct gprs_rlcmac_bts *bts = bts_main_data();
1145 char *endp = NULL;
1146 unsigned long long tlli = strtoll(argv[0], &endp, 16);
1147 if ((endp != NULL && *endp != 0) || tlli > 0xffffffffULL) {
1148 vty_out(vty, "Invalid TLLI.%s", VTY_NEWLINE);
1149 return CMD_WARNING;
1150 }
1151 return pcu_vty_show_ms_by_tlli(vty, bts, (uint32_t)tlli);
1152}
1153
1154DEFUN(show_ms_imsi,
1155 show_ms_imsi_cmd,
1156 "show ms imsi IMSI",
1157 SHOW_STR "information about MSs\n" "Select MS by IMSI\n" "IMSI\n")
1158{
1159 struct gprs_rlcmac_bts *bts = bts_main_data();
1160 return pcu_vty_show_ms_by_imsi(vty, bts, argv[0]);
1161}
1162
Andreas Eversberg12942562012-07-12 14:31:57 +02001163static const char pcu_copyright[] =
Harald Welted1e340f2013-01-17 12:24:29 +01001164 "Copyright (C) 2012 by Ivan Kluchnikov <kluchnikovi@gmail.com> and \r\n"
1165 " Andreas Eversberg <jolly@eversberg.eu>\r\n"
Andreas Eversberg12942562012-07-12 14:31:57 +02001166 "License GNU GPL version 2 or later\r\n"
1167 "This is free software: you are free to change and redistribute it.\r\n"
1168 "There is NO WARRANTY, to the extent permitted by law.\r\n";
1169
1170struct vty_app_info pcu_vty_info = {
1171 .name = "Osmo-PCU",
1172 .version = PACKAGE_VERSION,
1173 .copyright = pcu_copyright,
1174 .go_parent_cb = pcu_vty_go_parent,
1175 .is_config_node = pcu_vty_is_config_node,
1176};
1177
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02001178int pcu_vty_init(void)
Andreas Eversberg12942562012-07-12 14:31:57 +02001179{
1180// install_element_ve(&show_pcu_cmd);
1181
Harald Welte717cdf52017-07-21 21:56:23 +02001182 cfg_pcu_gsmtap_categ_cmd.string = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_names,
1183 "gsmtap-category (",
1184 "|",")", VTY_DO_LOWER);
1185 cfg_pcu_gsmtap_categ_cmd.doc = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_help,
1186 "GSMTAP Category\n",
1187 "\n", "", 0);
1188 cfg_pcu_no_gsmtap_categ_cmd.string = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_names,
1189 "no gsmtap-category (",
1190 "|",")", VTY_DO_LOWER);
1191 cfg_pcu_no_gsmtap_categ_cmd.doc = vty_cmd_string_from_valstr(tall_pcu_ctx, pcu_gsmtap_categ_help,
1192 NO_STR "GSMTAP Category\n",
1193 "\n", "", 0);
1194
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +02001195 logging_vty_add_cmds();
1196 osmo_stats_vty_add_cmds();
Andreas Eversberg12942562012-07-12 14:31:57 +02001197
Andreas Eversberg8b761a32012-07-20 21:50:31 +02001198 install_node(&pcu_node, config_write_pcu);
1199 install_element(CONFIG_NODE, &cfg_pcu_cmd);
Jacob Erlbeck953c7892015-09-28 18:12:57 +02001200 install_element(PCU_NODE, &cfg_pcu_egprs_cmd);
1201 install_element(PCU_NODE, &cfg_pcu_no_egprs_cmd);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +02001202 install_element(PCU_NODE, &cfg_pcu_no_two_phase_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +02001203 install_element(PCU_NODE, &cfg_pcu_cs_cmd);
1204 install_element(PCU_NODE, &cfg_pcu_no_cs_cmd);
Jacob Erlbeckb33e6752015-06-04 19:04:30 +02001205 install_element(PCU_NODE, &cfg_pcu_cs_max_cmd);
1206 install_element(PCU_NODE, &cfg_pcu_no_cs_max_cmd);
Jacob Erlbeck8322d082015-06-04 15:12:10 +02001207 install_element(PCU_NODE, &cfg_pcu_cs_err_limits_cmd);
1208 install_element(PCU_NODE, &cfg_pcu_no_cs_err_limits_cmd);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +02001209 install_element(PCU_NODE, &cfg_pcu_cs_downgrade_thrsh_cmd);
1210 install_element(PCU_NODE, &cfg_pcu_no_cs_downgrade_thrsh_cmd);
Jacob Erlbeck94cde132015-06-09 09:44:36 +02001211 install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd);
Minh-Quang Nguyen1f189092017-08-16 09:50:06 -04001212 install_element(PCU_NODE, &cfg_pcu_mcs_lqual_ranges_cmd);
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +01001213 install_element(PCU_NODE, &cfg_pcu_mcs_cmd);
Aravind Sirsikar50b09702016-08-22 17:21:10 +05301214 install_element(PCU_NODE, &cfg_pcu_dl_arq_cmd);
Jacob Erlbeck4cc46d32016-02-02 16:02:16 +01001215 install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd);
Jacob Erlbeck0d058052016-01-07 11:48:28 +01001216 install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd);
1217 install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd);
Jacob Erlbeck36df7742016-01-19 15:53:30 +01001218 install_element(PCU_NODE, &cfg_pcu_window_size_cmd);
Andreas Eversberg24131bf2012-07-21 11:09:58 +02001219 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_cmd);
1220 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_inf_cmd);
1221 install_element(PCU_NODE, &cfg_pcu_no_queue_lifetime_cmd);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +01001222 install_element(PCU_NODE, &cfg_pcu_queue_hysteresis_cmd);
1223 install_element(PCU_NODE, &cfg_pcu_no_queue_hysteresis_cmd);
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +02001224 install_element(PCU_NODE, &cfg_pcu_queue_codel_cmd);
1225 install_element(PCU_NODE, &cfg_pcu_queue_codel_interval_cmd);
1226 install_element(PCU_NODE, &cfg_pcu_no_queue_codel_cmd);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +02001227 install_element(PCU_NODE, &cfg_pcu_queue_idle_ack_delay_cmd);
1228 install_element(PCU_NODE, &cfg_pcu_no_queue_idle_ack_delay_cmd);
Andreas Eversberga1503fa2012-07-22 08:58:09 +02001229 install_element(PCU_NODE, &cfg_pcu_alloc_cmd);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001230 install_element(PCU_NODE, &cfg_pcu_two_phase_cmd);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +02001231 install_element(PCU_NODE, &cfg_pcu_fc_interval_cmd);
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +02001232 install_element(PCU_NODE, &cfg_pcu_fc_bucket_time_cmd);
1233 install_element(PCU_NODE, &cfg_pcu_no_fc_bucket_time_cmd);
Jacob Erlbeck87d73412015-04-21 12:56:48 +02001234 install_element(PCU_NODE, &cfg_pcu_fc_bvc_bucket_size_cmd);
1235 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_bucket_size_cmd);
1236 install_element(PCU_NODE, &cfg_pcu_fc_bvc_leak_rate_cmd);
1237 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_leak_rate_cmd);
1238 install_element(PCU_NODE, &cfg_pcu_fc_ms_bucket_size_cmd);
1239 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_bucket_size_cmd);
1240 install_element(PCU_NODE, &cfg_pcu_fc_ms_leak_rate_cmd);
1241 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_leak_rate_cmd);
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +02001242 install_element(PCU_NODE, &cfg_pcu_alpha_cmd);
1243 install_element(PCU_NODE, &cfg_pcu_gamma_cmd);
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +01001244 install_element(PCU_NODE, &cfg_pcu_dl_tbf_idle_time_cmd);
1245 install_element(PCU_NODE, &cfg_pcu_no_dl_tbf_idle_time_cmd);
Oliver Smith45fdc442019-09-05 15:12:20 +02001246 install_element(PCU_NODE, &cfg_pcu_dl_tbf_preemptive_retransmission_cmd);
1247 install_element(PCU_NODE, &cfg_pcu_no_dl_tbf_preemptive_retransmission_cmd);
Jacob Erlbecka098c192015-05-28 16:11:19 +02001248 install_element(PCU_NODE, &cfg_pcu_ms_idle_time_cmd);
1249 install_element(PCU_NODE, &cfg_pcu_no_ms_idle_time_cmd);
Harald Welte717cdf52017-07-21 21:56:23 +02001250 install_element(PCU_NODE, &cfg_pcu_gsmtap_categ_cmd);
1251 install_element(PCU_NODE, &cfg_pcu_no_gsmtap_categ_cmd);
Pau Espin Pedrolc4178e52017-08-08 15:03:50 +02001252 install_element(PCU_NODE, &cfg_pcu_sock_cmd);
Harald Welte57d35152018-07-05 03:11:17 +02001253 install_element(PCU_NODE, &cfg_pcu_gb_dialect_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +02001254
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +01001255 install_element_ve(&show_bts_stats_cmd);
Daniel Willmann772415f2014-01-15 17:06:51 +01001256 install_element_ve(&show_tbf_cmd);
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +02001257 install_element_ve(&show_ms_all_cmd);
Jacob Erlbeck37e896d2015-06-05 16:33:33 +02001258 install_element_ve(&show_ms_tlli_cmd);
1259 install_element_ve(&show_ms_imsi_cmd);
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +01001260
Andreas Eversberg12942562012-07-12 14:31:57 +02001261 return 0;
1262}