blob: 5196ae24c4edab3b0bccce781a2becc440206fd7 [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>
Andreas Eversberg12942562012-07-12 14:31:57 +02006#include <osmocom/vty/logging.h>
Jacob Erlbeck42aba812015-11-10 15:32:00 +01007#include <osmocom/vty/stats.h>
Jacob Erlbeckc0c580c2015-04-30 15:59:01 +02008#include <osmocom/vty/misc.h>
Andreas Eversberg8b761a32012-07-20 21:50:31 +02009#include <osmocom/core/linuxlist.h>
Holger Hans Peter Freythere8915b92014-07-02 14:57:47 +020010#include <osmocom/core/rate_ctr.h>
Andreas Eversberg12942562012-07-12 14:31:57 +020011#include "pcu_vty.h"
Andreas Eversberg8b761a32012-07-20 21:50:31 +020012#include "gprs_rlcmac.h"
Holger Hans Peter Freyther67ed34e2013-10-17 17:01:54 +020013#include "bts.h"
Jacob Erlbeckc0c580c2015-04-30 15:59:01 +020014#include "tbf.h"
Andreas Eversberg12942562012-07-12 14:31:57 +020015
Jacob Erlbeck62e96a32015-06-04 09:42:14 +020016#include "pcu_vty_functions.h"
17
Jacob Erlbeckf76fede2015-08-17 13:42:46 +020018int pcu_vty_go_parent(struct vty *vty)
Andreas Eversberg12942562012-07-12 14:31:57 +020019{
20 switch (vty->node) {
21#if 0
22 case TRX_NODE:
Andreas Eversberg8b761a32012-07-20 21:50:31 +020023 vty->node = PCU_NODE;
Andreas Eversberg12942562012-07-12 14:31:57 +020024 {
25 struct gsm_bts_trx *trx = vty->index;
26 vty->index = trx->bts;
27 }
28 break;
29#endif
30 default:
31 vty->node = CONFIG_NODE;
32 }
Andreas Eversberg8b761a32012-07-20 21:50:31 +020033 return (enum node_type) vty->node;
Andreas Eversberg12942562012-07-12 14:31:57 +020034}
35
36int pcu_vty_is_config_node(struct vty *vty, int node)
37{
38 switch (node) {
Andreas Eversberg8b761a32012-07-20 21:50:31 +020039 case PCU_NODE:
Andreas Eversberg12942562012-07-12 14:31:57 +020040 return 1;
Andreas Eversberg12942562012-07-12 14:31:57 +020041 default:
42 return 0;
43 }
44}
45
Andreas Eversberg8b761a32012-07-20 21:50:31 +020046static struct cmd_node pcu_node = {
47 (enum node_type) PCU_NODE,
Jacob Erlbeckcc12f022015-04-09 15:45:24 +020048 "%s(config-pcu)# ",
Andreas Eversberg8b761a32012-07-20 21:50:31 +020049 1,
50};
51
Andreas Eversberg8b761a32012-07-20 21:50:31 +020052static int config_write_pcu(struct vty *vty)
53{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +020054 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +020055
56 vty_out(vty, "pcu%s", VTY_NEWLINE);
Jacob Erlbeck953c7892015-09-28 18:12:57 +020057 if (bts->egprs_enabled)
58 vty_out(vty, " egprs%s", VTY_NEWLINE);
59 else
60 vty_out(vty, " no egprs%s", VTY_NEWLINE);
61
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +020062 vty_out(vty, " flow-control-interval %d%s", bts->fc_interval,
63 VTY_NEWLINE);
Jacob Erlbeck87d73412015-04-21 12:56:48 +020064 if (bts->fc_bvc_bucket_size)
65 vty_out(vty, " flow-control force-bvc-bucket-size %d%s",
66 bts->fc_bvc_bucket_size, VTY_NEWLINE);
67 if (bts->fc_bvc_leak_rate)
68 vty_out(vty, " flow-control force-bvc-leak-rate %d%s",
69 bts->fc_bvc_leak_rate, VTY_NEWLINE);
70 if (bts->fc_ms_bucket_size)
71 vty_out(vty, " flow-control force-ms-bucket-size %d%s",
72 bts->fc_ms_bucket_size, VTY_NEWLINE);
73 if (bts->fc_ms_leak_rate)
74 vty_out(vty, " flow-control force-ms-leak-rate %d%s",
75 bts->fc_ms_leak_rate, VTY_NEWLINE);
Holger Hans Peter Freytherc421e8a2014-07-02 14:55:17 +020076 if (bts->force_cs) {
Andreas Eversberg499ff412012-10-03 14:21:36 +020077 if (bts->initial_cs_ul == bts->initial_cs_dl)
78 vty_out(vty, " cs %d%s", bts->initial_cs_dl,
79 VTY_NEWLINE);
80 else
81 vty_out(vty, " cs %d %d%s", bts->initial_cs_dl,
82 bts->initial_cs_ul, VTY_NEWLINE);
Holger Hans Peter Freytherc421e8a2014-07-02 14:55:17 +020083 }
Jacob Erlbeckb33e6752015-06-04 19:04:30 +020084 if (bts->max_cs_dl && bts->max_cs_ul) {
85 if (bts->max_cs_ul == bts->max_cs_dl)
86 vty_out(vty, " cs max %d%s", bts->max_cs_dl,
87 VTY_NEWLINE);
88 else
89 vty_out(vty, " cs max %d %d%s", bts->max_cs_dl,
90 bts->max_cs_ul, VTY_NEWLINE);
91 }
Jacob Erlbeck8322d082015-06-04 15:12:10 +020092 if (bts->cs_adj_enabled)
93 vty_out(vty, " cs threshold %d %d%s",
94 bts->cs_adj_lower_limit, bts->cs_adj_upper_limit,
95 VTY_NEWLINE);
96 else
97 vty_out(vty, " no cs threshold%s", VTY_NEWLINE);
98
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +020099 if (bts->cs_downgrade_threshold)
100 vty_out(vty, " cs downgrade-threshold %d%s",
101 bts->cs_downgrade_threshold, VTY_NEWLINE);
102 else
103 vty_out(vty, " no cs downgrade-threshold%s", VTY_NEWLINE);
104
Jacob Erlbeck94cde132015-06-09 09:44:36 +0200105 vty_out(vty, " cs link-quality-ranges cs1 %d cs2 %d %d cs3 %d %d cs4 %d%s",
106 bts->cs_lqual_ranges[0].high,
107 bts->cs_lqual_ranges[1].low,
108 bts->cs_lqual_ranges[1].high,
109 bts->cs_lqual_ranges[2].low,
110 bts->cs_lqual_ranges[2].high,
111 bts->cs_lqual_ranges[3].low,
112 VTY_NEWLINE);
113
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200114 if (bts->force_llc_lifetime == 0xffff)
115 vty_out(vty, " queue lifetime infinite%s", VTY_NEWLINE);
116 else if (bts->force_llc_lifetime)
117 vty_out(vty, " queue lifetime %d%s", bts->force_llc_lifetime,
118 VTY_NEWLINE);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100119 if (bts->llc_discard_csec)
120 vty_out(vty, " queue hysteresis %d%s", bts->llc_discard_csec,
121 VTY_NEWLINE);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200122 if (bts->llc_idle_ack_csec)
123 vty_out(vty, " queue idle-ack-delay %d%s", bts->llc_idle_ack_csec,
124 VTY_NEWLINE);
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200125 if (bts->llc_codel_interval_msec == LLC_CODEL_USE_DEFAULT)
126 vty_out(vty, " queue codel%s", VTY_NEWLINE);
127 else if (bts->llc_codel_interval_msec == LLC_CODEL_DISABLE)
128 vty_out(vty, " no queue codel%s", VTY_NEWLINE);
129 else
130 vty_out(vty, " queue codel interval %d%s",
131 bts->llc_codel_interval_msec/10, VTY_NEWLINE);
132
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200133 if (bts->alloc_algorithm == alloc_algorithm_a)
134 vty_out(vty, " alloc-algorithm a%s", VTY_NEWLINE);
135 if (bts->alloc_algorithm == alloc_algorithm_b)
136 vty_out(vty, " alloc-algorithm b%s", VTY_NEWLINE);
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200137 if (bts->alloc_algorithm == alloc_algorithm_dynamic)
138 vty_out(vty, " alloc-algorithm dynamic%s", VTY_NEWLINE);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200139 if (bts->force_two_phase)
140 vty_out(vty, " two-phase-access%s", VTY_NEWLINE);
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200141 vty_out(vty, " alpha %d%s", bts->alpha, VTY_NEWLINE);
142 vty_out(vty, " gamma %d%s", bts->gamma * 2, VTY_NEWLINE);
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100143 if (bts->dl_tbf_idle_msec)
144 vty_out(vty, " dl-tbf-idle-time %d%s", bts->dl_tbf_idle_msec,
145 VTY_NEWLINE);
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200146
Jacob Erlbeck62e96a32015-06-04 09:42:14 +0200147 return pcu_vty_config_write_pcu_ext(vty);
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200148}
149
150/* per-BTS configuration */
151DEFUN(cfg_pcu,
152 cfg_pcu_cmd,
153 "pcu",
154 "BTS specific configure")
155{
156 vty->node = PCU_NODE;
157
158 return CMD_SUCCESS;
159}
160
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200161#define EGPRS_STR "EGPRS configuration\n"
162
163DEFUN(cfg_pcu_egprs,
164 cfg_pcu_egprs_cmd,
165 "egprs",
166 EGPRS_STR)
167{
168 struct gprs_rlcmac_bts *bts = bts_main_data();
169
170 bts->egprs_enabled = 1;
171
172 vty_out(vty, "%%Note that EGPRS support is in an experimental state. "
173 "Do not use this in production!%s", VTY_NEWLINE);
174
175 return CMD_SUCCESS;
176}
177
178DEFUN(cfg_pcu_no_egprs,
179 cfg_pcu_no_egprs_cmd,
180 "no egprs",
181 NO_STR EGPRS_STR)
182{
183 struct gprs_rlcmac_bts *bts = bts_main_data();
184
185 bts->egprs_enabled = 0;
186
187 return CMD_SUCCESS;
188}
189
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200190DEFUN(cfg_pcu_fc_interval,
191 cfg_pcu_fc_interval_cmd,
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200192 "flow-control-interval <1-10>",
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200193 "Interval between sending subsequent Flow Control PDUs\n"
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200194 "Interval time in seconds\n")
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200195{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200196 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200197
198 bts->fc_interval = atoi(argv[0]);
199
200 return CMD_SUCCESS;
201}
Jacob Erlbeck87d73412015-04-21 12:56:48 +0200202#define FC_STR "BSSGP Flow Control configuration\n"
203#define FC_BMAX_STR(who) "Force a fixed value for the " who " bucket size\n"
204#define FC_LR_STR(who) "Force a fixed value for the " who " leak rate\n"
205
206DEFUN(cfg_pcu_fc_bvc_bucket_size,
207 cfg_pcu_fc_bvc_bucket_size_cmd,
208 "flow-control force-bvc-bucket-size <1-6553500>",
209 FC_STR FC_BMAX_STR("BVC") "Bucket size in octets\n")
210{
211 struct gprs_rlcmac_bts *bts = bts_main_data();
212
213 bts->fc_bvc_bucket_size = atoi(argv[0]);
214
215 return CMD_SUCCESS;
216}
217
218DEFUN(cfg_pcu_no_fc_bvc_bucket_size,
219 cfg_pcu_no_fc_bvc_bucket_size_cmd,
220 "no flow-control force-bvc-bucket-size",
221 NO_STR FC_STR FC_BMAX_STR("BVC"))
222{
223 struct gprs_rlcmac_bts *bts = bts_main_data();
224
225 bts->fc_bvc_bucket_size = 0;
226
227 return CMD_SUCCESS;
228}
229
230DEFUN(cfg_pcu_fc_bvc_leak_rate,
231 cfg_pcu_fc_bvc_leak_rate_cmd,
232 "flow-control force-bvc-leak-rate <1-6553500>",
233 FC_STR FC_LR_STR("BVC") "Leak rate in bit/s\n")
234{
235 struct gprs_rlcmac_bts *bts = bts_main_data();
236
237 bts->fc_bvc_leak_rate = atoi(argv[0]);
238
239 return CMD_SUCCESS;
240}
241
242DEFUN(cfg_pcu_no_fc_bvc_leak_rate,
243 cfg_pcu_no_fc_bvc_leak_rate_cmd,
244 "no flow-control force-bvc-leak-rate",
245 NO_STR FC_STR FC_LR_STR("BVC"))
246{
247 struct gprs_rlcmac_bts *bts = bts_main_data();
248
249 bts->fc_bvc_leak_rate = 0;
250
251 return CMD_SUCCESS;
252}
253
254DEFUN(cfg_pcu_fc_ms_bucket_size,
255 cfg_pcu_fc_ms_bucket_size_cmd,
256 "flow-control force-ms-bucket-size <1-6553500>",
257 FC_STR FC_BMAX_STR("default MS") "Bucket size in octets\n")
258{
259 struct gprs_rlcmac_bts *bts = bts_main_data();
260
261 bts->fc_ms_bucket_size = atoi(argv[0]);
262
263 return CMD_SUCCESS;
264}
265
266DEFUN(cfg_pcu_no_fc_ms_bucket_size,
267 cfg_pcu_no_fc_ms_bucket_size_cmd,
268 "no flow-control force-ms-bucket-size",
269 NO_STR FC_STR FC_BMAX_STR("default MS"))
270{
271 struct gprs_rlcmac_bts *bts = bts_main_data();
272
273 bts->fc_ms_bucket_size = 0;
274
275 return CMD_SUCCESS;
276}
277
278DEFUN(cfg_pcu_fc_ms_leak_rate,
279 cfg_pcu_fc_ms_leak_rate_cmd,
280 "flow-control force-ms-leak-rate <1-6553500>",
281 FC_STR FC_LR_STR("default MS") "Leak rate in bit/s\n")
282{
283 struct gprs_rlcmac_bts *bts = bts_main_data();
284
285 bts->fc_ms_leak_rate = atoi(argv[0]);
286
287 return CMD_SUCCESS;
288}
289
290DEFUN(cfg_pcu_no_fc_ms_leak_rate,
291 cfg_pcu_no_fc_ms_leak_rate_cmd,
292 "no flow-control force-ms-leak-rate",
293 NO_STR FC_STR FC_LR_STR("default MS"))
294{
295 struct gprs_rlcmac_bts *bts = bts_main_data();
296
297 bts->fc_ms_leak_rate = 0;
298
299 return CMD_SUCCESS;
300}
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200301
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200302#define FC_BTIME_STR "Set target downlink maximum queueing time (only affects the advertised bucket size)\n"
303DEFUN(cfg_pcu_fc_bucket_time,
304 cfg_pcu_fc_bucket_time_cmd,
305 "flow-control bucket-time <1-65534>",
306 FC_STR FC_BTIME_STR "Time in centi-seconds\n")
307{
308 struct gprs_rlcmac_bts *bts = bts_main_data();
309
310 bts->fc_bucket_time = atoi(argv[0]);
311
312 return CMD_SUCCESS;
313}
314
315DEFUN(cfg_pcu_no_fc_bucket_time,
316 cfg_pcu_no_fc_bucket_time_cmd,
317 "no flow-control bucket-time",
318 NO_STR FC_STR FC_BTIME_STR)
319{
320 struct gprs_rlcmac_bts *bts = bts_main_data();
321
322 bts->fc_bucket_time = 0;
323
324 return CMD_SUCCESS;
325}
326
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200327#define CS_STR "Coding Scheme configuration\n"
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200328
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200329DEFUN(cfg_pcu_cs,
330 cfg_pcu_cs_cmd,
Andreas Eversberg499ff412012-10-03 14:21:36 +0200331 "cs <1-4> [<1-4>]",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200332 CS_STR
333 "Initial CS value to be used (overrides BTS config)\n"
334 "Use a different initial CS value for the uplink")
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200335{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200336 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200337 uint8_t cs = atoi(argv[0]);
338
339 bts->force_cs = 1;
Andreas Eversberg499ff412012-10-03 14:21:36 +0200340 bts->initial_cs_dl = cs;
341 if (argc > 1)
342 bts->initial_cs_ul = atoi(argv[1]);
343 else
344 bts->initial_cs_ul = cs;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200345
346 return CMD_SUCCESS;
347}
348
349DEFUN(cfg_pcu_no_cs,
350 cfg_pcu_no_cs_cmd,
351 "no cs",
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200352 NO_STR CS_STR)
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200353{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200354 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200355
356 bts->force_cs = 0;
357
358 return CMD_SUCCESS;
359}
360
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200361DEFUN(cfg_pcu_cs_max,
362 cfg_pcu_cs_max_cmd,
363 "cs max <1-4> [<1-4>]",
364 CS_STR
365 "Set maximum values for adaptive CS selection (overrides BTS config)\n"
366 "Maximum CS value to be used\n"
367 "Use a different maximum CS value for the uplink")
368{
369 struct gprs_rlcmac_bts *bts = bts_main_data();
370 uint8_t cs = atoi(argv[0]);
371
372 bts->max_cs_dl = cs;
373 if (argc > 1)
374 bts->max_cs_ul = atoi(argv[1]);
375 else
376 bts->max_cs_ul = cs;
377
378 return CMD_SUCCESS;
379}
380
381DEFUN(cfg_pcu_no_cs_max,
382 cfg_pcu_no_cs_max_cmd,
383 "no cs max",
384 NO_STR CS_STR
385 "Set maximum values for adaptive CS selection (overrides BTS config)\n")
386{
387 struct gprs_rlcmac_bts *bts = bts_main_data();
388
389 bts->max_cs_dl = 0;
390 bts->max_cs_ul = 0;
391
392 return CMD_SUCCESS;
393}
394
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200395#define QUEUE_STR "Packet queue options\n"
396#define LIFETIME_STR "Set lifetime limit of LLC frame in centi-seconds " \
397 "(overrides the value given by SGSN)\n"
398
399DEFUN(cfg_pcu_queue_lifetime,
400 cfg_pcu_queue_lifetime_cmd,
401 "queue lifetime <1-65534>",
402 QUEUE_STR LIFETIME_STR "Lifetime in centi-seconds")
403{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200404 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200405 uint16_t csec = atoi(argv[0]);
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200406
407 bts->force_llc_lifetime = csec;
408
409 return CMD_SUCCESS;
410}
411
412DEFUN(cfg_pcu_queue_lifetime_inf,
413 cfg_pcu_queue_lifetime_inf_cmd,
414 "queue lifetime infinite",
415 QUEUE_STR LIFETIME_STR "Infinite lifetime")
416{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200417 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200418
419 bts->force_llc_lifetime = 0xffff;
420
421 return CMD_SUCCESS;
422}
423
424DEFUN(cfg_pcu_no_queue_lifetime,
425 cfg_pcu_no_queue_lifetime_cmd,
426 "no queue lifetime",
427 NO_STR QUEUE_STR "Disable lifetime limit of LLC frame (use value given "
428 "by SGSN)\n")
429{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200430 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200431
432 bts->force_llc_lifetime = 0;
433
434 return CMD_SUCCESS;
435}
436
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100437#define QUEUE_HYSTERESIS_STR "Set lifetime hysteresis of LLC frame in centi-seconds " \
438 "(continue discarding until lifetime-hysteresis is reached)\n"
439
440DEFUN(cfg_pcu_queue_hysteresis,
441 cfg_pcu_queue_hysteresis_cmd,
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200442 "queue hysteresis <1-65535>",
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100443 QUEUE_STR QUEUE_HYSTERESIS_STR "Hysteresis in centi-seconds")
444{
445 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200446 uint16_t csec = atoi(argv[0]);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100447
448 bts->llc_discard_csec = csec;
449
450 return CMD_SUCCESS;
451}
452
453DEFUN(cfg_pcu_no_queue_hysteresis,
454 cfg_pcu_no_queue_hysteresis_cmd,
455 "no queue hysteresis",
456 NO_STR QUEUE_STR QUEUE_HYSTERESIS_STR)
457{
458 struct gprs_rlcmac_bts *bts = bts_main_data();
459
460 bts->llc_discard_csec = 0;
461
462 return CMD_SUCCESS;
463}
464
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200465#define QUEUE_CODEL_STR "Set CoDel queue management\n"
466
467DEFUN(cfg_pcu_queue_codel,
468 cfg_pcu_queue_codel_cmd,
469 "queue codel",
470 QUEUE_STR QUEUE_CODEL_STR)
471{
472 struct gprs_rlcmac_bts *bts = bts_main_data();
473
474 bts->llc_codel_interval_msec = LLC_CODEL_USE_DEFAULT;
475
476 return CMD_SUCCESS;
477}
478
479DEFUN(cfg_pcu_queue_codel_interval,
480 cfg_pcu_queue_codel_interval_cmd,
481 "queue codel interval <1-1000>",
482 QUEUE_STR QUEUE_CODEL_STR "Specify interval\n" "Interval in centi-seconds")
483{
484 struct gprs_rlcmac_bts *bts = bts_main_data();
485 uint16_t csec = atoi(argv[0]);
486
487 bts->llc_codel_interval_msec = 10*csec;
488
489 return CMD_SUCCESS;
490}
491
492DEFUN(cfg_pcu_no_queue_codel,
493 cfg_pcu_no_queue_codel_cmd,
494 "no queue codel",
495 NO_STR QUEUE_STR QUEUE_CODEL_STR)
496{
497 struct gprs_rlcmac_bts *bts = bts_main_data();
498
499 bts->llc_codel_interval_msec = LLC_CODEL_DISABLE;
500
501 return CMD_SUCCESS;
502}
503
504
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200505#define QUEUE_IDLE_ACK_STR "Request an ACK after the last DL LLC frame in centi-seconds\n"
506
507DEFUN(cfg_pcu_queue_idle_ack_delay,
508 cfg_pcu_queue_idle_ack_delay_cmd,
509 "queue idle-ack-delay <1-65535>",
510 QUEUE_STR QUEUE_IDLE_ACK_STR "Idle ACK delay in centi-seconds")
511{
512 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200513 uint16_t csec = atoi(argv[0]);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200514
515 bts->llc_idle_ack_csec = csec;
516
517 return CMD_SUCCESS;
518}
519
520DEFUN(cfg_pcu_no_queue_idle_ack_delay,
521 cfg_pcu_no_queue_idle_ack_delay_cmd,
522 "no queue idle-ack-delay",
523 NO_STR QUEUE_STR QUEUE_IDLE_ACK_STR)
524{
525 struct gprs_rlcmac_bts *bts = bts_main_data();
526
527 bts->llc_idle_ack_csec = 0;
528
529 return CMD_SUCCESS;
530}
531
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100532
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200533DEFUN(cfg_pcu_alloc,
534 cfg_pcu_alloc_cmd,
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200535 "alloc-algorithm (a|b|dynamic)",
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200536 "Select slot allocation algorithm to use when assigning timeslots on "
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200537 "PACCH\n"
538 "Single slot is assigned only\n"
539 "Multiple slots are assigned for semi-duplex operation\n"
540 "Dynamically select the algorithm based on the system state\n")
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200541{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200542 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200543
544 switch (argv[0][0]) {
545 case 'a':
546 bts->alloc_algorithm = alloc_algorithm_a;
547 break;
548 case 'b':
549 bts->alloc_algorithm = alloc_algorithm_b;
550 break;
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200551 default:
552 bts->alloc_algorithm = alloc_algorithm_dynamic;
553 break;
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200554 }
555
556 return CMD_SUCCESS;
557}
558
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200559DEFUN(cfg_pcu_two_phase,
560 cfg_pcu_two_phase_cmd,
561 "two-phase-access",
562 "Force two phase access when MS requests single phase access\n")
563{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200564 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200565
566 bts->force_two_phase = 1;
567
568 return CMD_SUCCESS;
569}
570
571DEFUN(cfg_pcu_no_two_phase,
572 cfg_pcu_no_two_phase_cmd,
573 "no two-phase-access",
574 NO_STR "Only use two phase access when requested my MS\n")
575{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200576 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200577
578 bts->force_two_phase = 0;
579
580 return CMD_SUCCESS;
581}
582
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200583DEFUN(cfg_pcu_alpha,
584 cfg_pcu_alpha_cmd,
585 "alpha <0-10>",
586 "Alpha parameter for MS power control in units of 0.1 (see TS 05.08) "
587 "NOTE: Be sure to set Alpha value at System information 13 too.\n"
588 "Alpha in units of 0.1\n")
589{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200590 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200591
592 bts->alpha = atoi(argv[0]);
593
594 return CMD_SUCCESS;
595}
596
597DEFUN(cfg_pcu_gamma,
598 cfg_pcu_gamma_cmd,
599 "gamma <0-62>",
600 "Gamma parameter for MS power control in units of dB (see TS 05.08)\n"
601 "Gamma in even unit of dBs\n")
602{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200603 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200604
605 bts->gamma = atoi(argv[0]) / 2;
606
607 return CMD_SUCCESS;
608}
609
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100610DEFUN(show_bts_stats,
611 show_bts_stats_cmd,
612 "show bts statistics",
613 SHOW_STR "BTS related functionality\nStatistics\n")
614{
615 vty_out_rate_ctr_group(vty, "", bts_main_data_stats());
616 return CMD_SUCCESS;
Daniel Willmann772415f2014-01-15 17:06:51 +0100617}
618
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100619#define IDLE_TIME_STR "keep an idle DL TBF alive for the time given\n"
620DEFUN(cfg_pcu_dl_tbf_idle_time,
621 cfg_pcu_dl_tbf_idle_time_cmd,
622 "dl-tbf-idle-time <1-5000>",
623 IDLE_TIME_STR "idle time in msec")
624{
625 struct gprs_rlcmac_bts *bts = bts_main_data();
626
627 bts->dl_tbf_idle_msec = atoi(argv[0]);
628
629 return CMD_SUCCESS;
630}
631
632DEFUN(cfg_pcu_no_dl_tbf_idle_time,
633 cfg_pcu_no_dl_tbf_idle_time_cmd,
634 "no dl-tbf-idle-time",
635 NO_STR IDLE_TIME_STR)
636{
637 struct gprs_rlcmac_bts *bts = bts_main_data();
638
639 bts->dl_tbf_idle_msec = 0;
640
641 return CMD_SUCCESS;
642}
643
Jacob Erlbecka098c192015-05-28 16:11:19 +0200644#define MS_IDLE_TIME_STR "keep an idle MS object alive for the time given\n"
645DEFUN(cfg_pcu_ms_idle_time,
646 cfg_pcu_ms_idle_time_cmd,
647 "ms-idle-time <1-7200>",
648 MS_IDLE_TIME_STR "idle time in sec")
649{
650 struct gprs_rlcmac_bts *bts = bts_main_data();
651
652 bts->ms_idle_sec = atoi(argv[0]);
653
654 return CMD_SUCCESS;
655}
656
657DEFUN(cfg_pcu_no_ms_idle_time,
658 cfg_pcu_no_ms_idle_time_cmd,
659 "no ms-idle-time",
660 NO_STR MS_IDLE_TIME_STR)
661{
662 struct gprs_rlcmac_bts *bts = bts_main_data();
663
664 bts->ms_idle_sec = 0;
665
666 return CMD_SUCCESS;
667}
668
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200669#define CS_ERR_LIMITS_STR "set thresholds for error rate based CS adjustment\n"
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200670DEFUN(cfg_pcu_cs_err_limits,
671 cfg_pcu_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200672 "cs threshold <0-100> <0-100>",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200673 CS_STR CS_ERR_LIMITS_STR "lower limit in %\n" "upper limit in %\n")
674{
675 struct gprs_rlcmac_bts *bts = bts_main_data();
676
677 uint8_t lower_limit = atoi(argv[0]);
678 uint8_t upper_limit = atoi(argv[1]);
679
680 if (lower_limit > upper_limit) {
681 vty_out(vty,
682 "The lower limit must be less than or equal to the "
683 "upper limit.%s", VTY_NEWLINE);
684 return CMD_WARNING;
685 }
686
687 bts->cs_adj_enabled = 1;
688 bts->cs_adj_upper_limit = upper_limit;
689 bts->cs_adj_lower_limit = lower_limit;
690
691 return CMD_SUCCESS;
692}
693
694DEFUN(cfg_pcu_no_cs_err_limits,
695 cfg_pcu_no_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200696 "no cs threshold",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200697 NO_STR CS_STR CS_ERR_LIMITS_STR)
698{
699 struct gprs_rlcmac_bts *bts = bts_main_data();
700
701 bts->cs_adj_enabled = 0;
702 bts->cs_adj_upper_limit = 100;
703 bts->cs_adj_lower_limit = 0;
704
705 return CMD_SUCCESS;
706}
707
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200708#define CS_DOWNGRADE_STR "set threshold for data size based CS downgrade\n"
709DEFUN(cfg_pcu_cs_downgrade_thrsh,
710 cfg_pcu_cs_downgrade_thrsh_cmd,
711 "cs downgrade-threshold <1-10000>",
712 CS_STR CS_DOWNGRADE_STR "downgrade if less octets left\n")
713{
714 struct gprs_rlcmac_bts *bts = bts_main_data();
715
716 bts->cs_downgrade_threshold = atoi(argv[0]);
717
718 return CMD_SUCCESS;
719}
720
721DEFUN(cfg_pcu_no_cs_downgrade_thrsh,
722 cfg_pcu_no_cs_downgrade_thrsh_cmd,
723 "no cs downgrade-threshold",
Jacob Erlbeckf1379342015-06-29 10:49:30 +0200724 NO_STR CS_STR CS_DOWNGRADE_STR)
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200725{
726 struct gprs_rlcmac_bts *bts = bts_main_data();
727
728 bts->cs_downgrade_threshold = 0;
729
730 return CMD_SUCCESS;
731}
732
733
Jacob Erlbeck94cde132015-06-09 09:44:36 +0200734DEFUN(cfg_pcu_cs_lqual_ranges,
735 cfg_pcu_cs_lqual_ranges_cmd,
736 "cs link-quality-ranges cs1 <0-35> cs2 <0-35> <0-35> cs3 <0-35> <0-35> cs4 <0-35>",
737 CS_STR "Set link quality ranges\n"
738 "Set quality range for CS-1 (high value only)\n"
739 "CS-1 high (dB)\n"
740 "Set quality range for CS-2\n"
741 "CS-2 low (dB)\n"
742 "CS-2 high (dB)\n"
743 "Set quality range for CS-3\n"
744 "CS-3 low (dB)\n"
745 "CS-3 high (dB)\n"
746 "Set quality range for CS-4 (low value only)\n"
747 "CS-4 low (dB)\n")
748{
749 struct gprs_rlcmac_bts *bts = bts_main_data();
750
751 uint8_t cs1_high = atoi(argv[0]);
752 uint8_t cs2_low = atoi(argv[1]);
753 uint8_t cs2_high = atoi(argv[2]);
754 uint8_t cs3_low = atoi(argv[3]);
755 uint8_t cs3_high = atoi(argv[4]);
756 uint8_t cs4_low = atoi(argv[5]);
757
758 bts->cs_lqual_ranges[0].high = cs1_high;
759 bts->cs_lqual_ranges[1].low = cs2_low;
760 bts->cs_lqual_ranges[1].high = cs2_high;
761 bts->cs_lqual_ranges[2].low = cs3_low;
762 bts->cs_lqual_ranges[2].high = cs3_high;
763 bts->cs_lqual_ranges[3].low = cs4_low;
764
765 return CMD_SUCCESS;
766}
767
768
Daniel Willmann772415f2014-01-15 17:06:51 +0100769DEFUN(show_tbf,
770 show_tbf_cmd,
771 "show tbf all",
Holger Hans Peter Freyther49f26bf2014-12-20 15:21:43 +0100772 SHOW_STR "information about TBFs\n" "All TBFs\n")
Daniel Willmann772415f2014-01-15 17:06:51 +0100773{
774 struct gprs_rlcmac_bts *bts = bts_main_data();
775 struct llist_head *tbf;
776
777 vty_out(vty, "UL TBFs%s", VTY_NEWLINE);
778 llist_for_each(tbf, &bts->ul_tbfs) {
779 tbf_print_vty_info(vty, tbf);
780 }
781
782 vty_out(vty, "%sDL TBFs%s", VTY_NEWLINE, VTY_NEWLINE);
783 llist_for_each(tbf, &bts->dl_tbfs) {
784 tbf_print_vty_info(vty, tbf);
785 }
786
787 return CMD_SUCCESS;
788}
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100789
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +0200790DEFUN(show_ms_all,
791 show_ms_all_cmd,
792 "show ms all",
793 SHOW_STR "information about MSs\n" "All TBFs\n")
794{
795 struct gprs_rlcmac_bts *bts = bts_main_data();
796 return pcu_vty_show_ms_all(vty, bts);
797}
798
Jacob Erlbeck37e896d2015-06-05 16:33:33 +0200799DEFUN(show_ms_tlli,
800 show_ms_tlli_cmd,
801 "show ms tlli TLLI",
802 SHOW_STR "information about MSs\n" "Select MS by TLLI\n" "TLLI as hex\n")
803{
804 struct gprs_rlcmac_bts *bts = bts_main_data();
805 char *endp = NULL;
806 unsigned long long tlli = strtoll(argv[0], &endp, 16);
807 if ((endp != NULL && *endp != 0) || tlli > 0xffffffffULL) {
808 vty_out(vty, "Invalid TLLI.%s", VTY_NEWLINE);
809 return CMD_WARNING;
810 }
811 return pcu_vty_show_ms_by_tlli(vty, bts, (uint32_t)tlli);
812}
813
814DEFUN(show_ms_imsi,
815 show_ms_imsi_cmd,
816 "show ms imsi IMSI",
817 SHOW_STR "information about MSs\n" "Select MS by IMSI\n" "IMSI\n")
818{
819 struct gprs_rlcmac_bts *bts = bts_main_data();
820 return pcu_vty_show_ms_by_imsi(vty, bts, argv[0]);
821}
822
Andreas Eversberg12942562012-07-12 14:31:57 +0200823static const char pcu_copyright[] =
Harald Welted1e340f2013-01-17 12:24:29 +0100824 "Copyright (C) 2012 by Ivan Kluchnikov <kluchnikovi@gmail.com> and \r\n"
825 " Andreas Eversberg <jolly@eversberg.eu>\r\n"
Andreas Eversberg12942562012-07-12 14:31:57 +0200826 "License GNU GPL version 2 or later\r\n"
827 "This is free software: you are free to change and redistribute it.\r\n"
828 "There is NO WARRANTY, to the extent permitted by law.\r\n";
829
830struct vty_app_info pcu_vty_info = {
831 .name = "Osmo-PCU",
832 .version = PACKAGE_VERSION,
833 .copyright = pcu_copyright,
834 .go_parent_cb = pcu_vty_go_parent,
835 .is_config_node = pcu_vty_is_config_node,
836};
837
838int pcu_vty_init(const struct log_info *cat)
839{
840// install_element_ve(&show_pcu_cmd);
841
842 logging_vty_add_cmds(cat);
Jacob Erlbeck42aba812015-11-10 15:32:00 +0100843 osmo_stats_vty_add_cmds(cat);
Andreas Eversberg12942562012-07-12 14:31:57 +0200844
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200845 install_node(&pcu_node, config_write_pcu);
846 install_element(CONFIG_NODE, &cfg_pcu_cmd);
Jacob Erlbeckcc12f022015-04-09 15:45:24 +0200847 vty_install_default(PCU_NODE);
Jacob Erlbeck953c7892015-09-28 18:12:57 +0200848 install_element(PCU_NODE, &cfg_pcu_egprs_cmd);
849 install_element(PCU_NODE, &cfg_pcu_no_egprs_cmd);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200850 install_element(PCU_NODE, &cfg_pcu_no_two_phase_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200851 install_element(PCU_NODE, &cfg_pcu_cs_cmd);
852 install_element(PCU_NODE, &cfg_pcu_no_cs_cmd);
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200853 install_element(PCU_NODE, &cfg_pcu_cs_max_cmd);
854 install_element(PCU_NODE, &cfg_pcu_no_cs_max_cmd);
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200855 install_element(PCU_NODE, &cfg_pcu_cs_err_limits_cmd);
856 install_element(PCU_NODE, &cfg_pcu_no_cs_err_limits_cmd);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200857 install_element(PCU_NODE, &cfg_pcu_cs_downgrade_thrsh_cmd);
858 install_element(PCU_NODE, &cfg_pcu_no_cs_downgrade_thrsh_cmd);
Jacob Erlbeck94cde132015-06-09 09:44:36 +0200859 install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd);
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200860 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_cmd);
861 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_inf_cmd);
862 install_element(PCU_NODE, &cfg_pcu_no_queue_lifetime_cmd);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100863 install_element(PCU_NODE, &cfg_pcu_queue_hysteresis_cmd);
864 install_element(PCU_NODE, &cfg_pcu_no_queue_hysteresis_cmd);
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200865 install_element(PCU_NODE, &cfg_pcu_queue_codel_cmd);
866 install_element(PCU_NODE, &cfg_pcu_queue_codel_interval_cmd);
867 install_element(PCU_NODE, &cfg_pcu_no_queue_codel_cmd);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200868 install_element(PCU_NODE, &cfg_pcu_queue_idle_ack_delay_cmd);
869 install_element(PCU_NODE, &cfg_pcu_no_queue_idle_ack_delay_cmd);
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200870 install_element(PCU_NODE, &cfg_pcu_alloc_cmd);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200871 install_element(PCU_NODE, &cfg_pcu_two_phase_cmd);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200872 install_element(PCU_NODE, &cfg_pcu_fc_interval_cmd);
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200873 install_element(PCU_NODE, &cfg_pcu_fc_bucket_time_cmd);
874 install_element(PCU_NODE, &cfg_pcu_no_fc_bucket_time_cmd);
Jacob Erlbeck87d73412015-04-21 12:56:48 +0200875 install_element(PCU_NODE, &cfg_pcu_fc_bvc_bucket_size_cmd);
876 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_bucket_size_cmd);
877 install_element(PCU_NODE, &cfg_pcu_fc_bvc_leak_rate_cmd);
878 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_leak_rate_cmd);
879 install_element(PCU_NODE, &cfg_pcu_fc_ms_bucket_size_cmd);
880 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_bucket_size_cmd);
881 install_element(PCU_NODE, &cfg_pcu_fc_ms_leak_rate_cmd);
882 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_leak_rate_cmd);
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200883 install_element(PCU_NODE, &cfg_pcu_alpha_cmd);
884 install_element(PCU_NODE, &cfg_pcu_gamma_cmd);
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100885 install_element(PCU_NODE, &cfg_pcu_dl_tbf_idle_time_cmd);
886 install_element(PCU_NODE, &cfg_pcu_no_dl_tbf_idle_time_cmd);
Jacob Erlbecka098c192015-05-28 16:11:19 +0200887 install_element(PCU_NODE, &cfg_pcu_ms_idle_time_cmd);
888 install_element(PCU_NODE, &cfg_pcu_no_ms_idle_time_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200889
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100890 install_element_ve(&show_bts_stats_cmd);
Daniel Willmann772415f2014-01-15 17:06:51 +0100891 install_element_ve(&show_tbf_cmd);
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +0200892 install_element_ve(&show_ms_all_cmd);
Jacob Erlbeck37e896d2015-06-05 16:33:33 +0200893 install_element_ve(&show_ms_tlli_cmd);
894 install_element_ve(&show_ms_imsi_cmd);
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100895
Andreas Eversberg12942562012-07-12 14:31:57 +0200896 return 0;
897}