blob: 51e448e039c2cdfc915db211f34a47852b470fd6 [file] [log] [blame]
Neels Hofmeyre25018b2017-11-27 21:29:33 +01001/* OsmoBSC interface to quagga VTY for handover parameters */
Neels Hofmeyr5f2204a2018-02-16 16:07:02 +01002/* (C) 2009-2010 by Andreas Eversberg <jolly@eversberg.eu>
Neels Hofmeyre25018b2017-11-27 21:29:33 +01003 * (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Neels Hofmeyr5f2204a2018-02-16 16:07:02 +01004 * (C) 2017-2018 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
5 *
Neels Hofmeyre25018b2017-11-27 21:29:33 +01006 * All Rights Reserved
7 *
Neels Hofmeyr5f2204a2018-02-16 16:07:02 +01008 * Author: Andreas Eversberg <jolly@eversberg.eu>
9 * Neels Hofmeyr <nhofmeyr@sysmocom.de>
Neels Hofmeyre25018b2017-11-27 21:29:33 +010010 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Affero General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Affero General Public License for more details.
20 *
21 * You should have received a copy of the GNU Affero General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 *
24 */
25
26#include <osmocom/bsc/gsm_data.h>
27#include <osmocom/bsc/vty.h>
28#include <osmocom/bsc/handover_cfg.h>
Neels Hofmeyr909e9722017-12-07 03:54:01 +010029#include <osmocom/bsc/handover_decision_2.h>
Neels Hofmeyre25018b2017-11-27 21:29:33 +010030
31static struct handover_cfg *ho_cfg_from_vty(struct vty *vty)
32{
33 switch (vty->node) {
34 case GSMNET_NODE:
35 return gsmnet_from_vty(vty)->ho;
36 case BTS_NODE:
37 OSMO_ASSERT(vty->index);
38 return ((struct gsm_bts *)vty->index)->ho;
39 default:
40 OSMO_ASSERT(false);
41 }
42}
43
44
45#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, \
Neels Hofmeyr444f9e22018-02-15 03:59:17 +010046 VTY_CMD_PREFIX, VTY_CMD, VTY_CMD_ARG, VTY_ARG_EVAL, \
Neels Hofmeyre25018b2017-11-27 21:29:33 +010047 VTY_WRITE_FMT, VTY_WRITE_CONV, \
48 VTY_DOC) \
49DEFUN(cfg_ho_##NAME, cfg_ho_##NAME##_cmd, \
Neels Hofmeyr444f9e22018-02-15 03:59:17 +010050 VTY_CMD_PREFIX VTY_CMD " (" VTY_CMD_ARG "|default)", \
Neels Hofmeyre25018b2017-11-27 21:29:33 +010051 VTY_DOC \
52 "Use default (" #DEFAULT_VAL "), remove explicit setting on this node\n") \
53{ \
54 struct handover_cfg *ho = ho_cfg_from_vty(vty); \
55 const char *val = argv[0]; \
56 if (!strcmp(val, "default")) { \
57 const char *msg; \
58 if (ho_isset_##NAME(ho)) {\
59 ho_clear_##NAME(ho); \
60 msg = "setting removed, now is"; \
61 } else \
62 msg = "already was unset, still is"; \
Neels Hofmeyr444f9e22018-02-15 03:59:17 +010063 vty_out(vty, "%% '" VTY_CMD_PREFIX VTY_CMD "' %s " VTY_WRITE_FMT "%s%s", \
Neels Hofmeyre25018b2017-11-27 21:29:33 +010064 msg, VTY_WRITE_CONV( ho_get_##NAME(ho) ), \
65 ho_isset_on_parent_##NAME(ho)? " (set on higher level node)" : "", \
66 VTY_NEWLINE); \
67 } \
68 else \
69 ho_set_##NAME(ho, VTY_ARG_EVAL(val)); \
70 return CMD_SUCCESS; \
71}
72
73HO_CFG_ALL_MEMBERS
74#undef HO_CFG_ONE_MEMBER
75
76
Neels Hofmeyr444f9e22018-02-15 03:59:17 +010077/* Aliases of 'handover' for 'handover1' for backwards compat */
78#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, \
79 VTY_CMD_PREFIX, VTY_CMD, VTY_CMD_ARG, VTY_ARG_EVAL, \
80 VTY_WRITE_FMT, VTY_WRITE_CONV, \
81 VTY_DOC) \
Neels Hofmeyrbedbef42018-02-19 17:17:11 +010082ALIAS_DEPRECATED(cfg_ho_##NAME, cfg_ho_##NAME##_cmd_alias, \
Neels Hofmeyr444f9e22018-02-15 03:59:17 +010083 "handover " VTY_CMD " (" VTY_CMD_ARG "|default)", \
Neels Hofmeyrbedbef42018-02-19 17:17:11 +010084 "Legacy alias for 'handover1': " VTY_DOC \
Neels Hofmeyr444f9e22018-02-15 03:59:17 +010085 "Use default (" #DEFAULT_VAL "), remove explicit setting on this node\n");
86
87HODEC1_CFG_ALL_MEMBERS
88#undef HO_CFG_ONE_MEMBER
89
Neels Hofmeyr909e9722017-12-07 03:54:01 +010090static inline const int a2congestion_check_interval(const char *arg)
91{
92 if (!strcmp(arg, "disabled"))
93 return 0;
94 return atoi(arg);
95}
96
97static inline const char *congestion_check_interval2a(int val)
98{
99 static char str[9];
100 if (val < 1
101 || snprintf(str, sizeof(str), "%d", val) >= sizeof(str))
102 return "disabled";
103 return str;
104}
105
106DEFUN(cfg_net_ho_congestion_check_interval, cfg_net_ho_congestion_check_interval_cmd,
107 "handover2 congestion-check (disabled|<1-999>|now)",
108 HO_CFG_STR_HANDOVER2
109 "Configure congestion check interval" HO_CFG_STR_2
110 "Disable congestion checking, do not handover based on cell overload\n"
111 "Congestion check interval in seconds (default "
112 OSMO_STRINGIFY_VAL(HO_CFG_CONGESTION_CHECK_DEFAULT) ")\n"
113 "Manually trigger a congestion check to run right now\n")
114{
115 if (!strcmp(argv[0], "now")) {
116 hodec2_congestion_check(gsmnet_from_vty(vty));
117 return CMD_SUCCESS;
118 }
119
120 hodec2_on_change_congestion_check_interval(gsmnet_from_vty(vty),
121 a2congestion_check_interval(argv[0]));
122 return CMD_SUCCESS;
123}
124
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100125static void ho_vty_write(struct vty *vty, const char *indent, struct handover_cfg *ho)
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100126{
127#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, \
Neels Hofmeyr444f9e22018-02-15 03:59:17 +0100128 VTY_CMD_PREFIX, VTY_CMD, VTY_CMD_ARG, VTY_ARG_EVAL, \
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100129 VTY_WRITE_FMT, VTY_WRITE_CONV, \
130 VTY_DOC) \
131 if (ho_isset_##NAME(ho)) \
Neels Hofmeyr444f9e22018-02-15 03:59:17 +0100132 vty_out(vty, "%s" VTY_CMD_PREFIX VTY_CMD " " VTY_WRITE_FMT "%s", indent, \
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100133 VTY_WRITE_CONV( ho_get_##NAME(ho) ), VTY_NEWLINE);
134
135 HO_CFG_ALL_MEMBERS
136#undef HO_CFG_ONE_MEMBER
137}
138
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100139void ho_vty_write_bts(struct vty *vty, struct gsm_bts *bts)
140{
141 ho_vty_write(vty, " ", bts->ho);
142}
143
144void ho_vty_write_net(struct vty *vty, struct gsm_network *net)
145{
146 ho_vty_write(vty, " ", net->ho);
147
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100148 if (net->hodec2.congestion_check_interval_s != HO_CFG_CONGESTION_CHECK_DEFAULT)
Neels Hofmeyr444f9e22018-02-15 03:59:17 +0100149 vty_out(vty, " handover2 congestion-check %s%s",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100150 congestion_check_interval2a(net->hodec2.congestion_check_interval_s),
151 VTY_NEWLINE);
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100152}
153
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100154static void ho_vty_init_cmds(int parent_node)
155{
Neels Hofmeyr444f9e22018-02-15 03:59:17 +0100156#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, VTY0, VTY1, VTY2, VTY3, VTY4, VTY5, VTY6) \
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100157 install_element(parent_node, &cfg_ho_##NAME##_cmd);
158
159 HO_CFG_ALL_MEMBERS
160#undef HO_CFG_ONE_MEMBER
Neels Hofmeyr444f9e22018-02-15 03:59:17 +0100161
162 /* Aliases of 'handover' for 'handover1' for backwards compat */
163#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, VTY0, VTY1, VTY2, VTY3, VTY4, VTY5, VTY6) \
164 install_element(parent_node, &cfg_ho_##NAME##_cmd_alias);
165
166HODEC1_CFG_ALL_MEMBERS
167#undef HO_CFG_ONE_MEMBER
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100168}
169
170void ho_vty_init()
171{
172 ho_vty_init_cmds(GSMNET_NODE);
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100173 install_element(GSMNET_NODE, &cfg_net_ho_congestion_check_interval_cmd);
174
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100175 ho_vty_init_cmds(BTS_NODE);
176}
177