blob: 94f89b567836bfe2f2c2df3d8e8a897898b67003 [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 Erlbeckc0c580c2015-04-30 15:59:01 +02007#include <osmocom/vty/misc.h>
Andreas Eversberg8b761a32012-07-20 21:50:31 +02008#include <osmocom/core/linuxlist.h>
Holger Hans Peter Freythere8915b92014-07-02 14:57:47 +02009#include <osmocom/core/rate_ctr.h>
Andreas Eversberg12942562012-07-12 14:31:57 +020010#include "pcu_vty.h"
Andreas Eversberg8b761a32012-07-20 21:50:31 +020011#include "gprs_rlcmac.h"
Holger Hans Peter Freyther67ed34e2013-10-17 17:01:54 +020012#include "bts.h"
Jacob Erlbeckc0c580c2015-04-30 15:59:01 +020013#include "tbf.h"
Andreas Eversberg12942562012-07-12 14:31:57 +020014
Jacob Erlbeck62e96a32015-06-04 09:42:14 +020015#include "pcu_vty_functions.h"
16
Andreas Eversberg12942562012-07-12 14:31:57 +020017enum node_type pcu_vty_go_parent(struct vty *vty)
18{
19 switch (vty->node) {
20#if 0
21 case TRX_NODE:
Andreas Eversberg8b761a32012-07-20 21:50:31 +020022 vty->node = PCU_NODE;
Andreas Eversberg12942562012-07-12 14:31:57 +020023 {
24 struct gsm_bts_trx *trx = vty->index;
25 vty->index = trx->bts;
26 }
27 break;
28#endif
29 default:
30 vty->node = CONFIG_NODE;
31 }
Andreas Eversberg8b761a32012-07-20 21:50:31 +020032 return (enum node_type) vty->node;
Andreas Eversberg12942562012-07-12 14:31:57 +020033}
34
35int pcu_vty_is_config_node(struct vty *vty, int node)
36{
37 switch (node) {
Andreas Eversberg8b761a32012-07-20 21:50:31 +020038 case PCU_NODE:
Andreas Eversberg12942562012-07-12 14:31:57 +020039 return 1;
Andreas Eversberg12942562012-07-12 14:31:57 +020040 default:
41 return 0;
42 }
43}
44
Andreas Eversberg8b761a32012-07-20 21:50:31 +020045static struct cmd_node pcu_node = {
46 (enum node_type) PCU_NODE,
Jacob Erlbeckcc12f022015-04-09 15:45:24 +020047 "%s(config-pcu)# ",
Andreas Eversberg8b761a32012-07-20 21:50:31 +020048 1,
49};
50
Andreas Eversberg8b761a32012-07-20 21:50:31 +020051static int config_write_pcu(struct vty *vty)
52{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +020053 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +020054
55 vty_out(vty, "pcu%s", VTY_NEWLINE);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +020056 vty_out(vty, " flow-control-interval %d%s", bts->fc_interval,
57 VTY_NEWLINE);
Jacob Erlbeck87d73412015-04-21 12:56:48 +020058 if (bts->fc_bvc_bucket_size)
59 vty_out(vty, " flow-control force-bvc-bucket-size %d%s",
60 bts->fc_bvc_bucket_size, VTY_NEWLINE);
61 if (bts->fc_bvc_leak_rate)
62 vty_out(vty, " flow-control force-bvc-leak-rate %d%s",
63 bts->fc_bvc_leak_rate, VTY_NEWLINE);
64 if (bts->fc_ms_bucket_size)
65 vty_out(vty, " flow-control force-ms-bucket-size %d%s",
66 bts->fc_ms_bucket_size, VTY_NEWLINE);
67 if (bts->fc_ms_leak_rate)
68 vty_out(vty, " flow-control force-ms-leak-rate %d%s",
69 bts->fc_ms_leak_rate, VTY_NEWLINE);
Holger Hans Peter Freytherc421e8a2014-07-02 14:55:17 +020070 if (bts->force_cs) {
Andreas Eversberg499ff412012-10-03 14:21:36 +020071 if (bts->initial_cs_ul == bts->initial_cs_dl)
72 vty_out(vty, " cs %d%s", bts->initial_cs_dl,
73 VTY_NEWLINE);
74 else
75 vty_out(vty, " cs %d %d%s", bts->initial_cs_dl,
76 bts->initial_cs_ul, VTY_NEWLINE);
Holger Hans Peter Freytherc421e8a2014-07-02 14:55:17 +020077 }
Jacob Erlbeckb33e6752015-06-04 19:04:30 +020078 if (bts->max_cs_dl && bts->max_cs_ul) {
79 if (bts->max_cs_ul == bts->max_cs_dl)
80 vty_out(vty, " cs max %d%s", bts->max_cs_dl,
81 VTY_NEWLINE);
82 else
83 vty_out(vty, " cs max %d %d%s", bts->max_cs_dl,
84 bts->max_cs_ul, VTY_NEWLINE);
85 }
Jacob Erlbeck8322d082015-06-04 15:12:10 +020086 if (bts->cs_adj_enabled)
87 vty_out(vty, " cs threshold %d %d%s",
88 bts->cs_adj_lower_limit, bts->cs_adj_upper_limit,
89 VTY_NEWLINE);
90 else
91 vty_out(vty, " no cs threshold%s", VTY_NEWLINE);
92
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +020093 if (bts->cs_downgrade_threshold)
94 vty_out(vty, " cs downgrade-threshold %d%s",
95 bts->cs_downgrade_threshold, VTY_NEWLINE);
96 else
97 vty_out(vty, " no cs downgrade-threshold%s", VTY_NEWLINE);
98
Jacob Erlbeck94cde132015-06-09 09:44:36 +020099 vty_out(vty, " cs link-quality-ranges cs1 %d cs2 %d %d cs3 %d %d cs4 %d%s",
100 bts->cs_lqual_ranges[0].high,
101 bts->cs_lqual_ranges[1].low,
102 bts->cs_lqual_ranges[1].high,
103 bts->cs_lqual_ranges[2].low,
104 bts->cs_lqual_ranges[2].high,
105 bts->cs_lqual_ranges[3].low,
106 VTY_NEWLINE);
107
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200108 if (bts->force_llc_lifetime == 0xffff)
109 vty_out(vty, " queue lifetime infinite%s", VTY_NEWLINE);
110 else if (bts->force_llc_lifetime)
111 vty_out(vty, " queue lifetime %d%s", bts->force_llc_lifetime,
112 VTY_NEWLINE);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100113 if (bts->llc_discard_csec)
114 vty_out(vty, " queue hysteresis %d%s", bts->llc_discard_csec,
115 VTY_NEWLINE);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200116 if (bts->llc_idle_ack_csec)
117 vty_out(vty, " queue idle-ack-delay %d%s", bts->llc_idle_ack_csec,
118 VTY_NEWLINE);
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200119 if (bts->llc_codel_interval_msec == LLC_CODEL_USE_DEFAULT)
120 vty_out(vty, " queue codel%s", VTY_NEWLINE);
121 else if (bts->llc_codel_interval_msec == LLC_CODEL_DISABLE)
122 vty_out(vty, " no queue codel%s", VTY_NEWLINE);
123 else
124 vty_out(vty, " queue codel interval %d%s",
125 bts->llc_codel_interval_msec/10, VTY_NEWLINE);
126
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200127 if (bts->alloc_algorithm == alloc_algorithm_a)
128 vty_out(vty, " alloc-algorithm a%s", VTY_NEWLINE);
129 if (bts->alloc_algorithm == alloc_algorithm_b)
130 vty_out(vty, " alloc-algorithm b%s", VTY_NEWLINE);
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200131 if (bts->alloc_algorithm == alloc_algorithm_dynamic)
132 vty_out(vty, " alloc-algorithm dynamic%s", VTY_NEWLINE);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200133 if (bts->force_two_phase)
134 vty_out(vty, " two-phase-access%s", VTY_NEWLINE);
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200135 vty_out(vty, " alpha %d%s", bts->alpha, VTY_NEWLINE);
136 vty_out(vty, " gamma %d%s", bts->gamma * 2, VTY_NEWLINE);
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100137 if (bts->dl_tbf_idle_msec)
138 vty_out(vty, " dl-tbf-idle-time %d%s", bts->dl_tbf_idle_msec,
139 VTY_NEWLINE);
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200140
Jacob Erlbeck62e96a32015-06-04 09:42:14 +0200141 return pcu_vty_config_write_pcu_ext(vty);
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200142}
143
144/* per-BTS configuration */
145DEFUN(cfg_pcu,
146 cfg_pcu_cmd,
147 "pcu",
148 "BTS specific configure")
149{
150 vty->node = PCU_NODE;
151
152 return CMD_SUCCESS;
153}
154
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200155DEFUN(cfg_pcu_fc_interval,
156 cfg_pcu_fc_interval_cmd,
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200157 "flow-control-interval <1-10>",
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200158 "Interval between sending subsequent Flow Control PDUs\n"
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200159 "Interval time in seconds\n")
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200160{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200161 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200162
163 bts->fc_interval = atoi(argv[0]);
164
165 return CMD_SUCCESS;
166}
Jacob Erlbeck87d73412015-04-21 12:56:48 +0200167#define FC_STR "BSSGP Flow Control configuration\n"
168#define FC_BMAX_STR(who) "Force a fixed value for the " who " bucket size\n"
169#define FC_LR_STR(who) "Force a fixed value for the " who " leak rate\n"
170
171DEFUN(cfg_pcu_fc_bvc_bucket_size,
172 cfg_pcu_fc_bvc_bucket_size_cmd,
173 "flow-control force-bvc-bucket-size <1-6553500>",
174 FC_STR FC_BMAX_STR("BVC") "Bucket size in octets\n")
175{
176 struct gprs_rlcmac_bts *bts = bts_main_data();
177
178 bts->fc_bvc_bucket_size = atoi(argv[0]);
179
180 return CMD_SUCCESS;
181}
182
183DEFUN(cfg_pcu_no_fc_bvc_bucket_size,
184 cfg_pcu_no_fc_bvc_bucket_size_cmd,
185 "no flow-control force-bvc-bucket-size",
186 NO_STR FC_STR FC_BMAX_STR("BVC"))
187{
188 struct gprs_rlcmac_bts *bts = bts_main_data();
189
190 bts->fc_bvc_bucket_size = 0;
191
192 return CMD_SUCCESS;
193}
194
195DEFUN(cfg_pcu_fc_bvc_leak_rate,
196 cfg_pcu_fc_bvc_leak_rate_cmd,
197 "flow-control force-bvc-leak-rate <1-6553500>",
198 FC_STR FC_LR_STR("BVC") "Leak rate in bit/s\n")
199{
200 struct gprs_rlcmac_bts *bts = bts_main_data();
201
202 bts->fc_bvc_leak_rate = atoi(argv[0]);
203
204 return CMD_SUCCESS;
205}
206
207DEFUN(cfg_pcu_no_fc_bvc_leak_rate,
208 cfg_pcu_no_fc_bvc_leak_rate_cmd,
209 "no flow-control force-bvc-leak-rate",
210 NO_STR FC_STR FC_LR_STR("BVC"))
211{
212 struct gprs_rlcmac_bts *bts = bts_main_data();
213
214 bts->fc_bvc_leak_rate = 0;
215
216 return CMD_SUCCESS;
217}
218
219DEFUN(cfg_pcu_fc_ms_bucket_size,
220 cfg_pcu_fc_ms_bucket_size_cmd,
221 "flow-control force-ms-bucket-size <1-6553500>",
222 FC_STR FC_BMAX_STR("default MS") "Bucket size in octets\n")
223{
224 struct gprs_rlcmac_bts *bts = bts_main_data();
225
226 bts->fc_ms_bucket_size = atoi(argv[0]);
227
228 return CMD_SUCCESS;
229}
230
231DEFUN(cfg_pcu_no_fc_ms_bucket_size,
232 cfg_pcu_no_fc_ms_bucket_size_cmd,
233 "no flow-control force-ms-bucket-size",
234 NO_STR FC_STR FC_BMAX_STR("default MS"))
235{
236 struct gprs_rlcmac_bts *bts = bts_main_data();
237
238 bts->fc_ms_bucket_size = 0;
239
240 return CMD_SUCCESS;
241}
242
243DEFUN(cfg_pcu_fc_ms_leak_rate,
244 cfg_pcu_fc_ms_leak_rate_cmd,
245 "flow-control force-ms-leak-rate <1-6553500>",
246 FC_STR FC_LR_STR("default MS") "Leak rate in bit/s\n")
247{
248 struct gprs_rlcmac_bts *bts = bts_main_data();
249
250 bts->fc_ms_leak_rate = atoi(argv[0]);
251
252 return CMD_SUCCESS;
253}
254
255DEFUN(cfg_pcu_no_fc_ms_leak_rate,
256 cfg_pcu_no_fc_ms_leak_rate_cmd,
257 "no flow-control force-ms-leak-rate",
258 NO_STR FC_STR FC_LR_STR("default MS"))
259{
260 struct gprs_rlcmac_bts *bts = bts_main_data();
261
262 bts->fc_ms_leak_rate = 0;
263
264 return CMD_SUCCESS;
265}
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200266
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200267#define FC_BTIME_STR "Set target downlink maximum queueing time (only affects the advertised bucket size)\n"
268DEFUN(cfg_pcu_fc_bucket_time,
269 cfg_pcu_fc_bucket_time_cmd,
270 "flow-control bucket-time <1-65534>",
271 FC_STR FC_BTIME_STR "Time in centi-seconds\n")
272{
273 struct gprs_rlcmac_bts *bts = bts_main_data();
274
275 bts->fc_bucket_time = atoi(argv[0]);
276
277 return CMD_SUCCESS;
278}
279
280DEFUN(cfg_pcu_no_fc_bucket_time,
281 cfg_pcu_no_fc_bucket_time_cmd,
282 "no flow-control bucket-time",
283 NO_STR FC_STR FC_BTIME_STR)
284{
285 struct gprs_rlcmac_bts *bts = bts_main_data();
286
287 bts->fc_bucket_time = 0;
288
289 return CMD_SUCCESS;
290}
291
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200292#define CS_STR "Coding Scheme configuration\n"
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200293
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200294DEFUN(cfg_pcu_cs,
295 cfg_pcu_cs_cmd,
Andreas Eversberg499ff412012-10-03 14:21:36 +0200296 "cs <1-4> [<1-4>]",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200297 CS_STR
298 "Initial CS value to be used (overrides BTS config)\n"
299 "Use a different initial CS value for the uplink")
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200300{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200301 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200302 uint8_t cs = atoi(argv[0]);
303
304 bts->force_cs = 1;
Andreas Eversberg499ff412012-10-03 14:21:36 +0200305 bts->initial_cs_dl = cs;
306 if (argc > 1)
307 bts->initial_cs_ul = atoi(argv[1]);
308 else
309 bts->initial_cs_ul = cs;
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200310
311 return CMD_SUCCESS;
312}
313
314DEFUN(cfg_pcu_no_cs,
315 cfg_pcu_no_cs_cmd,
316 "no cs",
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200317 NO_STR CS_STR)
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200318{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200319 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200320
321 bts->force_cs = 0;
322
323 return CMD_SUCCESS;
324}
325
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200326DEFUN(cfg_pcu_cs_max,
327 cfg_pcu_cs_max_cmd,
328 "cs max <1-4> [<1-4>]",
329 CS_STR
330 "Set maximum values for adaptive CS selection (overrides BTS config)\n"
331 "Maximum CS value to be used\n"
332 "Use a different maximum CS value for the uplink")
333{
334 struct gprs_rlcmac_bts *bts = bts_main_data();
335 uint8_t cs = atoi(argv[0]);
336
337 bts->max_cs_dl = cs;
338 if (argc > 1)
339 bts->max_cs_ul = atoi(argv[1]);
340 else
341 bts->max_cs_ul = cs;
342
343 return CMD_SUCCESS;
344}
345
346DEFUN(cfg_pcu_no_cs_max,
347 cfg_pcu_no_cs_max_cmd,
348 "no cs max",
349 NO_STR CS_STR
350 "Set maximum values for adaptive CS selection (overrides BTS config)\n")
351{
352 struct gprs_rlcmac_bts *bts = bts_main_data();
353
354 bts->max_cs_dl = 0;
355 bts->max_cs_ul = 0;
356
357 return CMD_SUCCESS;
358}
359
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200360#define QUEUE_STR "Packet queue options\n"
361#define LIFETIME_STR "Set lifetime limit of LLC frame in centi-seconds " \
362 "(overrides the value given by SGSN)\n"
363
364DEFUN(cfg_pcu_queue_lifetime,
365 cfg_pcu_queue_lifetime_cmd,
366 "queue lifetime <1-65534>",
367 QUEUE_STR LIFETIME_STR "Lifetime in centi-seconds")
368{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200369 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200370 uint16_t csec = atoi(argv[0]);
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200371
372 bts->force_llc_lifetime = csec;
373
374 return CMD_SUCCESS;
375}
376
377DEFUN(cfg_pcu_queue_lifetime_inf,
378 cfg_pcu_queue_lifetime_inf_cmd,
379 "queue lifetime infinite",
380 QUEUE_STR LIFETIME_STR "Infinite lifetime")
381{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200382 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200383
384 bts->force_llc_lifetime = 0xffff;
385
386 return CMD_SUCCESS;
387}
388
389DEFUN(cfg_pcu_no_queue_lifetime,
390 cfg_pcu_no_queue_lifetime_cmd,
391 "no queue lifetime",
392 NO_STR QUEUE_STR "Disable lifetime limit of LLC frame (use value given "
393 "by SGSN)\n")
394{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200395 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200396
397 bts->force_llc_lifetime = 0;
398
399 return CMD_SUCCESS;
400}
401
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100402#define QUEUE_HYSTERESIS_STR "Set lifetime hysteresis of LLC frame in centi-seconds " \
403 "(continue discarding until lifetime-hysteresis is reached)\n"
404
405DEFUN(cfg_pcu_queue_hysteresis,
406 cfg_pcu_queue_hysteresis_cmd,
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200407 "queue hysteresis <1-65535>",
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100408 QUEUE_STR QUEUE_HYSTERESIS_STR "Hysteresis in centi-seconds")
409{
410 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200411 uint16_t csec = atoi(argv[0]);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100412
413 bts->llc_discard_csec = csec;
414
415 return CMD_SUCCESS;
416}
417
418DEFUN(cfg_pcu_no_queue_hysteresis,
419 cfg_pcu_no_queue_hysteresis_cmd,
420 "no queue hysteresis",
421 NO_STR QUEUE_STR QUEUE_HYSTERESIS_STR)
422{
423 struct gprs_rlcmac_bts *bts = bts_main_data();
424
425 bts->llc_discard_csec = 0;
426
427 return CMD_SUCCESS;
428}
429
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200430#define QUEUE_CODEL_STR "Set CoDel queue management\n"
431
432DEFUN(cfg_pcu_queue_codel,
433 cfg_pcu_queue_codel_cmd,
434 "queue codel",
435 QUEUE_STR QUEUE_CODEL_STR)
436{
437 struct gprs_rlcmac_bts *bts = bts_main_data();
438
439 bts->llc_codel_interval_msec = LLC_CODEL_USE_DEFAULT;
440
441 return CMD_SUCCESS;
442}
443
444DEFUN(cfg_pcu_queue_codel_interval,
445 cfg_pcu_queue_codel_interval_cmd,
446 "queue codel interval <1-1000>",
447 QUEUE_STR QUEUE_CODEL_STR "Specify interval\n" "Interval in centi-seconds")
448{
449 struct gprs_rlcmac_bts *bts = bts_main_data();
450 uint16_t csec = atoi(argv[0]);
451
452 bts->llc_codel_interval_msec = 10*csec;
453
454 return CMD_SUCCESS;
455}
456
457DEFUN(cfg_pcu_no_queue_codel,
458 cfg_pcu_no_queue_codel_cmd,
459 "no queue codel",
460 NO_STR QUEUE_STR QUEUE_CODEL_STR)
461{
462 struct gprs_rlcmac_bts *bts = bts_main_data();
463
464 bts->llc_codel_interval_msec = LLC_CODEL_DISABLE;
465
466 return CMD_SUCCESS;
467}
468
469
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200470#define QUEUE_IDLE_ACK_STR "Request an ACK after the last DL LLC frame in centi-seconds\n"
471
472DEFUN(cfg_pcu_queue_idle_ack_delay,
473 cfg_pcu_queue_idle_ack_delay_cmd,
474 "queue idle-ack-delay <1-65535>",
475 QUEUE_STR QUEUE_IDLE_ACK_STR "Idle ACK delay in centi-seconds")
476{
477 struct gprs_rlcmac_bts *bts = bts_main_data();
Jacob Erlbeck2acfbeb2015-04-30 17:55:16 +0200478 uint16_t csec = atoi(argv[0]);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200479
480 bts->llc_idle_ack_csec = csec;
481
482 return CMD_SUCCESS;
483}
484
485DEFUN(cfg_pcu_no_queue_idle_ack_delay,
486 cfg_pcu_no_queue_idle_ack_delay_cmd,
487 "no queue idle-ack-delay",
488 NO_STR QUEUE_STR QUEUE_IDLE_ACK_STR)
489{
490 struct gprs_rlcmac_bts *bts = bts_main_data();
491
492 bts->llc_idle_ack_csec = 0;
493
494 return CMD_SUCCESS;
495}
496
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100497
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200498DEFUN(cfg_pcu_alloc,
499 cfg_pcu_alloc_cmd,
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200500 "alloc-algorithm (a|b|dynamic)",
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200501 "Select slot allocation algorithm to use when assigning timeslots on "
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200502 "PACCH\n"
503 "Single slot is assigned only\n"
504 "Multiple slots are assigned for semi-duplex operation\n"
505 "Dynamically select the algorithm based on the system state\n")
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200506{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200507 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200508
509 switch (argv[0][0]) {
510 case 'a':
511 bts->alloc_algorithm = alloc_algorithm_a;
512 break;
513 case 'b':
514 bts->alloc_algorithm = alloc_algorithm_b;
515 break;
Jacob Erlbeck400ec022015-07-14 13:31:48 +0200516 default:
517 bts->alloc_algorithm = alloc_algorithm_dynamic;
518 break;
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200519 }
520
521 return CMD_SUCCESS;
522}
523
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200524DEFUN(cfg_pcu_two_phase,
525 cfg_pcu_two_phase_cmd,
526 "two-phase-access",
527 "Force two phase access when MS requests single phase access\n")
528{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200529 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200530
531 bts->force_two_phase = 1;
532
533 return CMD_SUCCESS;
534}
535
536DEFUN(cfg_pcu_no_two_phase,
537 cfg_pcu_no_two_phase_cmd,
538 "no two-phase-access",
539 NO_STR "Only use two phase access when requested my MS\n")
540{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200541 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200542
543 bts->force_two_phase = 0;
544
545 return CMD_SUCCESS;
546}
547
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200548DEFUN(cfg_pcu_alpha,
549 cfg_pcu_alpha_cmd,
550 "alpha <0-10>",
551 "Alpha parameter for MS power control in units of 0.1 (see TS 05.08) "
552 "NOTE: Be sure to set Alpha value at System information 13 too.\n"
553 "Alpha in units of 0.1\n")
554{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200555 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200556
557 bts->alpha = atoi(argv[0]);
558
559 return CMD_SUCCESS;
560}
561
562DEFUN(cfg_pcu_gamma,
563 cfg_pcu_gamma_cmd,
564 "gamma <0-62>",
565 "Gamma parameter for MS power control in units of dB (see TS 05.08)\n"
566 "Gamma in even unit of dBs\n")
567{
Holger Hans Peter Freytherb6acfda2013-10-17 19:41:11 +0200568 struct gprs_rlcmac_bts *bts = bts_main_data();
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200569
570 bts->gamma = atoi(argv[0]) / 2;
571
572 return CMD_SUCCESS;
573}
574
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100575DEFUN(show_bts_stats,
576 show_bts_stats_cmd,
577 "show bts statistics",
578 SHOW_STR "BTS related functionality\nStatistics\n")
579{
580 vty_out_rate_ctr_group(vty, "", bts_main_data_stats());
581 return CMD_SUCCESS;
Daniel Willmann772415f2014-01-15 17:06:51 +0100582}
583
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100584#define IDLE_TIME_STR "keep an idle DL TBF alive for the time given\n"
585DEFUN(cfg_pcu_dl_tbf_idle_time,
586 cfg_pcu_dl_tbf_idle_time_cmd,
587 "dl-tbf-idle-time <1-5000>",
588 IDLE_TIME_STR "idle time in msec")
589{
590 struct gprs_rlcmac_bts *bts = bts_main_data();
591
592 bts->dl_tbf_idle_msec = atoi(argv[0]);
593
594 return CMD_SUCCESS;
595}
596
597DEFUN(cfg_pcu_no_dl_tbf_idle_time,
598 cfg_pcu_no_dl_tbf_idle_time_cmd,
599 "no dl-tbf-idle-time",
600 NO_STR IDLE_TIME_STR)
601{
602 struct gprs_rlcmac_bts *bts = bts_main_data();
603
604 bts->dl_tbf_idle_msec = 0;
605
606 return CMD_SUCCESS;
607}
608
Jacob Erlbecka098c192015-05-28 16:11:19 +0200609#define MS_IDLE_TIME_STR "keep an idle MS object alive for the time given\n"
610DEFUN(cfg_pcu_ms_idle_time,
611 cfg_pcu_ms_idle_time_cmd,
612 "ms-idle-time <1-7200>",
613 MS_IDLE_TIME_STR "idle time in sec")
614{
615 struct gprs_rlcmac_bts *bts = bts_main_data();
616
617 bts->ms_idle_sec = atoi(argv[0]);
618
619 return CMD_SUCCESS;
620}
621
622DEFUN(cfg_pcu_no_ms_idle_time,
623 cfg_pcu_no_ms_idle_time_cmd,
624 "no ms-idle-time",
625 NO_STR MS_IDLE_TIME_STR)
626{
627 struct gprs_rlcmac_bts *bts = bts_main_data();
628
629 bts->ms_idle_sec = 0;
630
631 return CMD_SUCCESS;
632}
633
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200634#define CS_ERR_LIMITS_STR "set thresholds for error rate based CS adjustment\n"
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200635DEFUN(cfg_pcu_cs_err_limits,
636 cfg_pcu_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200637 "cs threshold <0-100> <0-100>",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200638 CS_STR CS_ERR_LIMITS_STR "lower limit in %\n" "upper limit in %\n")
639{
640 struct gprs_rlcmac_bts *bts = bts_main_data();
641
642 uint8_t lower_limit = atoi(argv[0]);
643 uint8_t upper_limit = atoi(argv[1]);
644
645 if (lower_limit > upper_limit) {
646 vty_out(vty,
647 "The lower limit must be less than or equal to the "
648 "upper limit.%s", VTY_NEWLINE);
649 return CMD_WARNING;
650 }
651
652 bts->cs_adj_enabled = 1;
653 bts->cs_adj_upper_limit = upper_limit;
654 bts->cs_adj_lower_limit = lower_limit;
655
656 return CMD_SUCCESS;
657}
658
659DEFUN(cfg_pcu_no_cs_err_limits,
660 cfg_pcu_no_cs_err_limits_cmd,
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200661 "no cs threshold",
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200662 NO_STR CS_STR CS_ERR_LIMITS_STR)
663{
664 struct gprs_rlcmac_bts *bts = bts_main_data();
665
666 bts->cs_adj_enabled = 0;
667 bts->cs_adj_upper_limit = 100;
668 bts->cs_adj_lower_limit = 0;
669
670 return CMD_SUCCESS;
671}
672
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200673#define CS_DOWNGRADE_STR "set threshold for data size based CS downgrade\n"
674DEFUN(cfg_pcu_cs_downgrade_thrsh,
675 cfg_pcu_cs_downgrade_thrsh_cmd,
676 "cs downgrade-threshold <1-10000>",
677 CS_STR CS_DOWNGRADE_STR "downgrade if less octets left\n")
678{
679 struct gprs_rlcmac_bts *bts = bts_main_data();
680
681 bts->cs_downgrade_threshold = atoi(argv[0]);
682
683 return CMD_SUCCESS;
684}
685
686DEFUN(cfg_pcu_no_cs_downgrade_thrsh,
687 cfg_pcu_no_cs_downgrade_thrsh_cmd,
688 "no cs downgrade-threshold",
Jacob Erlbeckf1379342015-06-29 10:49:30 +0200689 NO_STR CS_STR CS_DOWNGRADE_STR)
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200690{
691 struct gprs_rlcmac_bts *bts = bts_main_data();
692
693 bts->cs_downgrade_threshold = 0;
694
695 return CMD_SUCCESS;
696}
697
698
Jacob Erlbeck94cde132015-06-09 09:44:36 +0200699DEFUN(cfg_pcu_cs_lqual_ranges,
700 cfg_pcu_cs_lqual_ranges_cmd,
701 "cs link-quality-ranges cs1 <0-35> cs2 <0-35> <0-35> cs3 <0-35> <0-35> cs4 <0-35>",
702 CS_STR "Set link quality ranges\n"
703 "Set quality range for CS-1 (high value only)\n"
704 "CS-1 high (dB)\n"
705 "Set quality range for CS-2\n"
706 "CS-2 low (dB)\n"
707 "CS-2 high (dB)\n"
708 "Set quality range for CS-3\n"
709 "CS-3 low (dB)\n"
710 "CS-3 high (dB)\n"
711 "Set quality range for CS-4 (low value only)\n"
712 "CS-4 low (dB)\n")
713{
714 struct gprs_rlcmac_bts *bts = bts_main_data();
715
716 uint8_t cs1_high = atoi(argv[0]);
717 uint8_t cs2_low = atoi(argv[1]);
718 uint8_t cs2_high = atoi(argv[2]);
719 uint8_t cs3_low = atoi(argv[3]);
720 uint8_t cs3_high = atoi(argv[4]);
721 uint8_t cs4_low = atoi(argv[5]);
722
723 bts->cs_lqual_ranges[0].high = cs1_high;
724 bts->cs_lqual_ranges[1].low = cs2_low;
725 bts->cs_lqual_ranges[1].high = cs2_high;
726 bts->cs_lqual_ranges[2].low = cs3_low;
727 bts->cs_lqual_ranges[2].high = cs3_high;
728 bts->cs_lqual_ranges[3].low = cs4_low;
729
730 return CMD_SUCCESS;
731}
732
733
Daniel Willmann772415f2014-01-15 17:06:51 +0100734DEFUN(show_tbf,
735 show_tbf_cmd,
736 "show tbf all",
Holger Hans Peter Freyther49f26bf2014-12-20 15:21:43 +0100737 SHOW_STR "information about TBFs\n" "All TBFs\n")
Daniel Willmann772415f2014-01-15 17:06:51 +0100738{
739 struct gprs_rlcmac_bts *bts = bts_main_data();
740 struct llist_head *tbf;
741
742 vty_out(vty, "UL TBFs%s", VTY_NEWLINE);
743 llist_for_each(tbf, &bts->ul_tbfs) {
744 tbf_print_vty_info(vty, tbf);
745 }
746
747 vty_out(vty, "%sDL TBFs%s", VTY_NEWLINE, VTY_NEWLINE);
748 llist_for_each(tbf, &bts->dl_tbfs) {
749 tbf_print_vty_info(vty, tbf);
750 }
751
752 return CMD_SUCCESS;
753}
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100754
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +0200755DEFUN(show_ms_all,
756 show_ms_all_cmd,
757 "show ms all",
758 SHOW_STR "information about MSs\n" "All TBFs\n")
759{
760 struct gprs_rlcmac_bts *bts = bts_main_data();
761 return pcu_vty_show_ms_all(vty, bts);
762}
763
Jacob Erlbeck37e896d2015-06-05 16:33:33 +0200764DEFUN(show_ms_tlli,
765 show_ms_tlli_cmd,
766 "show ms tlli TLLI",
767 SHOW_STR "information about MSs\n" "Select MS by TLLI\n" "TLLI as hex\n")
768{
769 struct gprs_rlcmac_bts *bts = bts_main_data();
770 char *endp = NULL;
771 unsigned long long tlli = strtoll(argv[0], &endp, 16);
772 if ((endp != NULL && *endp != 0) || tlli > 0xffffffffULL) {
773 vty_out(vty, "Invalid TLLI.%s", VTY_NEWLINE);
774 return CMD_WARNING;
775 }
776 return pcu_vty_show_ms_by_tlli(vty, bts, (uint32_t)tlli);
777}
778
779DEFUN(show_ms_imsi,
780 show_ms_imsi_cmd,
781 "show ms imsi IMSI",
782 SHOW_STR "information about MSs\n" "Select MS by IMSI\n" "IMSI\n")
783{
784 struct gprs_rlcmac_bts *bts = bts_main_data();
785 return pcu_vty_show_ms_by_imsi(vty, bts, argv[0]);
786}
787
Andreas Eversberg12942562012-07-12 14:31:57 +0200788static const char pcu_copyright[] =
Harald Welted1e340f2013-01-17 12:24:29 +0100789 "Copyright (C) 2012 by Ivan Kluchnikov <kluchnikovi@gmail.com> and \r\n"
790 " Andreas Eversberg <jolly@eversberg.eu>\r\n"
Andreas Eversberg12942562012-07-12 14:31:57 +0200791 "License GNU GPL version 2 or later\r\n"
792 "This is free software: you are free to change and redistribute it.\r\n"
793 "There is NO WARRANTY, to the extent permitted by law.\r\n";
794
795struct vty_app_info pcu_vty_info = {
796 .name = "Osmo-PCU",
797 .version = PACKAGE_VERSION,
798 .copyright = pcu_copyright,
799 .go_parent_cb = pcu_vty_go_parent,
800 .is_config_node = pcu_vty_is_config_node,
801};
802
803int pcu_vty_init(const struct log_info *cat)
804{
805// install_element_ve(&show_pcu_cmd);
806
807 logging_vty_add_cmds(cat);
808
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200809 install_node(&pcu_node, config_write_pcu);
810 install_element(CONFIG_NODE, &cfg_pcu_cmd);
Jacob Erlbeckcc12f022015-04-09 15:45:24 +0200811 vty_install_default(PCU_NODE);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200812 install_element(PCU_NODE, &cfg_pcu_no_two_phase_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200813 install_element(PCU_NODE, &cfg_pcu_cs_cmd);
814 install_element(PCU_NODE, &cfg_pcu_no_cs_cmd);
Jacob Erlbeckb33e6752015-06-04 19:04:30 +0200815 install_element(PCU_NODE, &cfg_pcu_cs_max_cmd);
816 install_element(PCU_NODE, &cfg_pcu_no_cs_max_cmd);
Jacob Erlbeck8322d082015-06-04 15:12:10 +0200817 install_element(PCU_NODE, &cfg_pcu_cs_err_limits_cmd);
818 install_element(PCU_NODE, &cfg_pcu_no_cs_err_limits_cmd);
Jacob Erlbeck70b96aa2015-06-12 10:52:34 +0200819 install_element(PCU_NODE, &cfg_pcu_cs_downgrade_thrsh_cmd);
820 install_element(PCU_NODE, &cfg_pcu_no_cs_downgrade_thrsh_cmd);
Jacob Erlbeck94cde132015-06-09 09:44:36 +0200821 install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd);
Andreas Eversberg24131bf2012-07-21 11:09:58 +0200822 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_cmd);
823 install_element(PCU_NODE, &cfg_pcu_queue_lifetime_inf_cmd);
824 install_element(PCU_NODE, &cfg_pcu_no_queue_lifetime_cmd);
Jacob Erlbeck0c1c8772015-03-20 12:02:42 +0100825 install_element(PCU_NODE, &cfg_pcu_queue_hysteresis_cmd);
826 install_element(PCU_NODE, &cfg_pcu_no_queue_hysteresis_cmd);
Jacob Erlbeckd4ad7312015-07-17 16:39:09 +0200827 install_element(PCU_NODE, &cfg_pcu_queue_codel_cmd);
828 install_element(PCU_NODE, &cfg_pcu_queue_codel_interval_cmd);
829 install_element(PCU_NODE, &cfg_pcu_no_queue_codel_cmd);
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200830 install_element(PCU_NODE, &cfg_pcu_queue_idle_ack_delay_cmd);
831 install_element(PCU_NODE, &cfg_pcu_no_queue_idle_ack_delay_cmd);
Andreas Eversberga1503fa2012-07-22 08:58:09 +0200832 install_element(PCU_NODE, &cfg_pcu_alloc_cmd);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200833 install_element(PCU_NODE, &cfg_pcu_two_phase_cmd);
Andreas Eversbergcd8a83a2012-09-23 06:41:21 +0200834 install_element(PCU_NODE, &cfg_pcu_fc_interval_cmd);
Jacob Erlbeck0288cdb2015-05-06 10:47:30 +0200835 install_element(PCU_NODE, &cfg_pcu_fc_bucket_time_cmd);
836 install_element(PCU_NODE, &cfg_pcu_no_fc_bucket_time_cmd);
Jacob Erlbeck87d73412015-04-21 12:56:48 +0200837 install_element(PCU_NODE, &cfg_pcu_fc_bvc_bucket_size_cmd);
838 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_bucket_size_cmd);
839 install_element(PCU_NODE, &cfg_pcu_fc_bvc_leak_rate_cmd);
840 install_element(PCU_NODE, &cfg_pcu_no_fc_bvc_leak_rate_cmd);
841 install_element(PCU_NODE, &cfg_pcu_fc_ms_bucket_size_cmd);
842 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_bucket_size_cmd);
843 install_element(PCU_NODE, &cfg_pcu_fc_ms_leak_rate_cmd);
844 install_element(PCU_NODE, &cfg_pcu_no_fc_ms_leak_rate_cmd);
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200845 install_element(PCU_NODE, &cfg_pcu_alpha_cmd);
846 install_element(PCU_NODE, &cfg_pcu_gamma_cmd);
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100847 install_element(PCU_NODE, &cfg_pcu_dl_tbf_idle_time_cmd);
848 install_element(PCU_NODE, &cfg_pcu_no_dl_tbf_idle_time_cmd);
Jacob Erlbecka098c192015-05-28 16:11:19 +0200849 install_element(PCU_NODE, &cfg_pcu_ms_idle_time_cmd);
850 install_element(PCU_NODE, &cfg_pcu_no_ms_idle_time_cmd);
Andreas Eversberg8b761a32012-07-20 21:50:31 +0200851
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100852 install_element_ve(&show_bts_stats_cmd);
Daniel Willmann772415f2014-01-15 17:06:51 +0100853 install_element_ve(&show_tbf_cmd);
Jacob Erlbeckf47f68a2015-06-04 10:23:24 +0200854 install_element_ve(&show_ms_all_cmd);
Jacob Erlbeck37e896d2015-06-05 16:33:33 +0200855 install_element_ve(&show_ms_tlli_cmd);
856 install_element_ve(&show_ms_imsi_cmd);
Holger Hans Peter Freytherf5372982013-10-27 09:02:31 +0100857
Andreas Eversberg12942562012-07-12 14:31:57 +0200858 return 0;
859}