blob: aea4a9bc836687dbe1d53a2d0c8296878b17c2fd [file] [log] [blame]
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +01001/*
Holger Hans Peter Freyther87b35d52014-11-21 10:20:29 +01002 * (C) 2013-2014 by Holger Hans Peter Freyther
3 * (C) 2013-2014 by sysmocom s.f.m.c. GmbH
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +01004 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
Harald Welte5919b6a2014-08-20 23:47:15 +020021#include <errno.h>
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +010022
Harald Welte5919b6a2014-08-20 23:47:15 +020023#include <osmocom/ctrl/control_cmd.h>
Holger Hans Peter Freyther5ff537c2013-01-09 17:30:11 +010024#include <openbsc/ipaccess.h>
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +010025#include <openbsc/gsm_data.h>
Holger Hans Peter Freyther1f672322014-03-26 14:24:42 +010026#include <openbsc/abis_nm.h>
27#include <openbsc/debug.h>
Holger Hans Peter Freyther9fe98462014-12-05 12:03:24 +010028#include <openbsc/chan_alloc.h>
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +010029
30#define CTRL_CMD_VTY_STRING(cmdname, cmdstr, dtype, element) \
31 CTRL_HELPER_GET_STRING(cmdname, dtype, element) \
32 CTRL_HELPER_SET_STRING(cmdname, dtype, element) \
33static struct ctrl_cmd_element cmd_##cmdname = { \
34 .name = cmdstr, \
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +010035 .get = get_##cmdname, \
36 .set = set_##cmdname, \
37 .verify = verify_vty_description_string, \
38}
39
40/**
41 * Check that there are no newlines or comments or other things
42 * that could make the VTY configuration unparsable.
43 */
44static int verify_vty_description_string(struct ctrl_cmd *cmd,
45 const char *value, void *data)
46{
47 int i;
48 const size_t len = strlen(value);
49
50 for (i = 0; i < len; ++i) {
51 switch(value[i]) {
52 case '#':
53 case '\n':
54 case '\r':
55 cmd->reply = "String includes illegal character";
56 return -1;
57 default:
58 break;
59 }
60 }
61
62 return 0;
63}
64
65CTRL_CMD_DEFINE_RANGE(net_mnc, "mnc", struct gsm_network, network_code, 0, 999);
66CTRL_CMD_DEFINE_RANGE(net_mcc, "mcc", struct gsm_network, country_code, 1, 999);
67CTRL_CMD_VTY_STRING(net_short_name, "short-name", struct gsm_network, name_short);
68CTRL_CMD_VTY_STRING(net_long_name, "long-name", struct gsm_network, name_long);
69
Holger Hans Peter Freyther5ff537c2013-01-09 17:30:11 +010070static int verify_net_apply_config(struct ctrl_cmd *cmd, const char *v, void *d)
71{
72 return 0;
73}
74
75static int get_net_apply_config(struct ctrl_cmd *cmd, void *data)
76{
77 cmd->reply = "Write only attribute";
78 return CTRL_CMD_ERROR;
79}
80
81static int set_net_apply_config(struct ctrl_cmd *cmd, void *data)
82{
83 struct gsm_network *net = cmd->node;
84 struct gsm_bts *bts;
85
86 llist_for_each_entry(bts, &net->bts_list, list) {
87 if (!is_ipaccess_bts(bts))
88 continue;
89
90 ipaccess_drop_oml(bts);
91 }
92
93 cmd->reply = "Tried to drop the BTS";
94 return CTRL_CMD_REPLY;
95}
96
97CTRL_CMD_DEFINE(net_apply_config, "apply-configuration");
98
Holger Hans Peter Freythereab2a3f2014-03-04 17:16:58 +010099static int verify_net_mcc_mnc_apply(struct ctrl_cmd *cmd, const char *value, void *d)
100{
101 char *tmp, *saveptr, *mcc, *mnc;
102
103 tmp = talloc_strdup(cmd, value);
104 if (!tmp)
105 return 1;
106
107 mcc = strtok_r(tmp, ",", &saveptr);
108 mnc = strtok_r(NULL, ",", &saveptr);
109 talloc_free(tmp);
110
111 if (!mcc || !mnc)
112 return 1;
113 return 0;
114}
115
116static int get_net_mcc_mnc_apply(struct ctrl_cmd *cmd, void *data)
117{
118 cmd->reply = "Write only attribute";
119 return CTRL_CMD_ERROR;
120}
121
122static int set_net_mcc_mnc_apply(struct ctrl_cmd *cmd, void *data)
123{
124 struct gsm_network *net = cmd->node;
125 char *tmp, *saveptr, *mcc_str, *mnc_str;
126 int mcc, mnc;
127
128 tmp = talloc_strdup(cmd, cmd->value);
129 if (!tmp)
130 goto oom;
131
132
133 mcc_str = strtok_r(tmp, ",", &saveptr);
134 mnc_str = strtok_r(NULL, ",", &saveptr);
135
136 mcc = atoi(mcc_str);
137 mnc = atoi(mnc_str);
138
139 talloc_free(tmp);
140
141 if (net->network_code == mnc && net->country_code == mcc) {
142 cmd->reply = "Nothing changed";
143 return CTRL_CMD_REPLY;
144 }
145
146 net->network_code = mnc;
147 net->country_code = mcc;
148
149 return set_net_apply_config(cmd, data);
150
151oom:
152 cmd->reply = "OOM";
153 return CTRL_CMD_ERROR;
154}
155CTRL_CMD_DEFINE(net_mcc_mnc_apply, "mcc-mnc-apply");
156
Holger Hans Peter Freytherba8679d2014-11-10 11:41:03 +0100157/* BTS related commands below */
158CTRL_CMD_DEFINE_RANGE(bts_lac, "location-area-code", struct gsm_bts, location_area_code, 0, 65535);
Holger Hans Peter Freyther982bb292014-11-21 10:54:42 +0100159CTRL_CMD_DEFINE_RANGE(bts_ci, "cell-identity", struct gsm_bts, cell_identity, 0, 65535);
Holger Hans Peter Freytherba8679d2014-11-10 11:41:03 +0100160
Holger Hans Peter Freyther87b35d52014-11-21 10:20:29 +0100161static int verify_bts_apply_config(struct ctrl_cmd *cmd, const char *v, void *d)
162{
163 return 0;
164}
165
166static int get_bts_apply_config(struct ctrl_cmd *cmd, void *data)
167{
168 cmd->reply = "Write only attribute";
169 return CTRL_CMD_ERROR;
170}
171
172static int set_bts_apply_config(struct ctrl_cmd *cmd, void *data)
173{
174 struct gsm_bts *bts = cmd->node;
175
176 if (!is_ipaccess_bts(bts)) {
177 cmd->reply = "BTS is not IP based";
178 return CTRL_CMD_ERROR;
179 }
180
181 ipaccess_drop_oml(bts);
182 cmd->reply = "Tried to drop the BTS";
183 return CTRL_CMD_REPLY;
184}
185
186CTRL_CMD_DEFINE(bts_apply_config, "apply-configuration");
187
Holger Hans Peter Freytherd0284c82014-11-21 11:18:45 +0100188static int verify_bts_si(struct ctrl_cmd *cmd, const char *v, void *d)
189{
190 return 0;
191}
192
193static int get_bts_si(struct ctrl_cmd *cmd, void *data)
194{
195 cmd->reply = "Write only attribute";
196 return CTRL_CMD_ERROR;
197}
198
199static int set_bts_si(struct ctrl_cmd *cmd, void *data)
200{
201 struct gsm_bts *bts = cmd->node;
202 struct gsm_bts_trx *trx;
203
204 /* Generate a new ID */
205 bts->bcch_change_mark += 1;
206 bts->bcch_change_mark %= 0x7;
207
208 llist_for_each_entry(trx, &bts->trx_list, list) {
209 int rc;
210
211 rc = gsm_bts_trx_set_system_infos(trx);
212 if (rc != 0) {
213 cmd->reply = "Failed to generate SI";
214 return CTRL_CMD_ERROR;
215 }
216 }
217
218 cmd->reply = "Generated new System Information";
219 return CTRL_CMD_REPLY;
220}
221CTRL_CMD_DEFINE(bts_si, "send-new-system-informations");
222
Holger Hans Peter Freyther9fe98462014-12-05 12:03:24 +0100223static int verify_bts_chan_load(struct ctrl_cmd *cmd, const char *v, void *d)
224{
225 return 0;
226}
227
228static int get_bts_chan_load(struct ctrl_cmd *cmd, void *data)
229{
230 int i;
231 struct pchan_load pl;
232 struct gsm_bts *bts;
233 const char *space = "";
234
235 bts = cmd->node;
236 memset(&pl, 0, sizeof(pl));
237 bts_chan_load(&pl, bts);
238
239 cmd->reply = talloc_strdup(cmd, "");
240
241 for (i = 0; i < ARRAY_SIZE(pl.pchan); ++i) {
242 const struct load_counter *lc = &pl.pchan[i];
243
244 /* These can never have user load */
245 if (i == GSM_PCHAN_NONE)
246 continue;
247 if (i == GSM_PCHAN_CCCH)
248 continue;
249 if (i == GSM_PCHAN_PDCH)
250 continue;
Holger Hans Peter Freyther5f3657d2015-01-31 19:42:42 +0100251 if (i == GSM_PCHAN_UNKNOWN)
252 continue;
Holger Hans Peter Freyther9fe98462014-12-05 12:03:24 +0100253
254 cmd->reply = talloc_asprintf_append(cmd->reply,
255 "%s%s,%u,%u",
256 space, gsm_pchan_name(i), lc->used, lc->total);
257 if (!cmd->reply)
258 goto error;
259 space = " ";
260 }
261
262 return CTRL_CMD_REPLY;
263
264error:
265 cmd->reply = "Memory allocation failure";
266 return CTRL_CMD_ERROR;
267}
268
269static int set_bts_chan_load(struct ctrl_cmd *cmd, void *data)
270{
271 cmd->reply = "Read only attribute";
272 return CTRL_CMD_ERROR;
273}
274CTRL_CMD_DEFINE(bts_chan_load, "channel-load");
275
Holger Hans Peter Freyther0c47d9e2014-12-05 14:44:21 +0100276static int verify_bts_oml_conn(struct ctrl_cmd *cmd, const char *value, void *_data)
277{
278 struct gsm_bts *bts = cmd->node;
279
280 if (!is_ipaccess_bts(bts)) {
281 cmd->reply = "";
282 return -1;
283 }
284 return 0;
285}
286
287static int get_bts_oml_conn(struct ctrl_cmd *cmd, void *data)
288{
289 struct gsm_bts *bts = cmd->node;
290
291 cmd->reply = bts->oml_link ? "connected" : "disconnected";
292 return CTRL_CMD_REPLY;
293}
294
295static int set_bts_oml_conn(struct ctrl_cmd *cmd, void *data)
296{
297 cmd->reply = "Read only attribute";
298 return CTRL_CMD_ERROR;
299}
300CTRL_CMD_DEFINE(bts_oml_conn, "oml-connection-state");
301
Holger Hans Peter Freyther2de46892014-03-23 11:17:27 +0100302/* TRX related commands below here */
303CTRL_HELPER_GET_INT(trx_max_power, struct gsm_bts_trx, max_power_red);
Holger Hans Peter Freyther2de46892014-03-23 11:17:27 +0100304static int verify_trx_max_power(struct ctrl_cmd *cmd, const char *value, void *_data)
305{
306 int tmp = atoi(value);
307
308 if (tmp < 0 || tmp > 22) {
309 cmd->reply = "Value must be between 0 and 22";
310 return -1;
311 }
312
313 if (tmp & 1) {
314 cmd->reply = "Value must be even";
315 return -1;
316 }
317
318 return 0;
319}
Holger Hans Peter Freytherb96705b2013-01-09 19:55:04 +0100320CTRL_CMD_DEFINE_RANGE(trx_arfcn, "arfcn", struct gsm_bts_trx, arfcn, 0, 1023);
Holger Hans Peter Freyther1f672322014-03-26 14:24:42 +0100321
322static int set_trx_max_power(struct ctrl_cmd *cmd, void *_data)
323{
324 struct gsm_bts_trx *trx = cmd->node;
325 int old_power;
326
327 /* remember the old value, set the new one */
328 old_power = trx->max_power_red;
329 trx->max_power_red = atoi(cmd->value);
330
331 /* Maybe update the value */
332 if (old_power != trx->max_power_red) {
333 LOGP(DCTRL, LOGL_NOTICE,
334 "%s updating max_pwr_red(%d)\n",
335 gsm_trx_name(trx), trx->max_power_red);
336 abis_nm_update_max_power_red(trx);
337 }
338
339 return get_trx_max_power(cmd, _data);
340}
Holger Hans Peter Freyther2de46892014-03-23 11:17:27 +0100341CTRL_CMD_DEFINE(trx_max_power, "max-power-reduction");
342
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +0100343int bsc_base_ctrl_cmds_install(void)
344{
345 int rc = 0;
346 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_mnc);
347 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_mcc);
348 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_short_name);
349 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_long_name);
Holger Hans Peter Freyther5ff537c2013-01-09 17:30:11 +0100350 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_apply_config);
Holger Hans Peter Freythereab2a3f2014-03-04 17:16:58 +0100351 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_mcc_mnc_apply);
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +0100352
Holger Hans Peter Freytherba8679d2014-11-10 11:41:03 +0100353 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_lac);
Holger Hans Peter Freyther982bb292014-11-21 10:54:42 +0100354 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_ci);
Holger Hans Peter Freyther87b35d52014-11-21 10:20:29 +0100355 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_apply_config);
Holger Hans Peter Freytherd0284c82014-11-21 11:18:45 +0100356 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_si);
Holger Hans Peter Freyther9fe98462014-12-05 12:03:24 +0100357 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_chan_load);
Holger Hans Peter Freyther0c47d9e2014-12-05 14:44:21 +0100358 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_oml_conn);
Holger Hans Peter Freytherba8679d2014-11-10 11:41:03 +0100359
Holger Hans Peter Freyther2de46892014-03-23 11:17:27 +0100360 rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_max_power);
Holger Hans Peter Freytherb96705b2013-01-09 19:55:04 +0100361 rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_arfcn);
362
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +0100363 return rc;
364}