blob: 7c8636cf1e753f260b38c103975de9cffd49438b [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 Freyther1ba8fa62013-01-09 17:03:27 +010028
29#define CTRL_CMD_VTY_STRING(cmdname, cmdstr, dtype, element) \
30 CTRL_HELPER_GET_STRING(cmdname, dtype, element) \
31 CTRL_HELPER_SET_STRING(cmdname, dtype, element) \
32static struct ctrl_cmd_element cmd_##cmdname = { \
33 .name = cmdstr, \
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +010034 .get = get_##cmdname, \
35 .set = set_##cmdname, \
36 .verify = verify_vty_description_string, \
37}
38
39/**
40 * Check that there are no newlines or comments or other things
41 * that could make the VTY configuration unparsable.
42 */
43static int verify_vty_description_string(struct ctrl_cmd *cmd,
44 const char *value, void *data)
45{
46 int i;
47 const size_t len = strlen(value);
48
49 for (i = 0; i < len; ++i) {
50 switch(value[i]) {
51 case '#':
52 case '\n':
53 case '\r':
54 cmd->reply = "String includes illegal character";
55 return -1;
56 default:
57 break;
58 }
59 }
60
61 return 0;
62}
63
64CTRL_CMD_DEFINE_RANGE(net_mnc, "mnc", struct gsm_network, network_code, 0, 999);
65CTRL_CMD_DEFINE_RANGE(net_mcc, "mcc", struct gsm_network, country_code, 1, 999);
66CTRL_CMD_VTY_STRING(net_short_name, "short-name", struct gsm_network, name_short);
67CTRL_CMD_VTY_STRING(net_long_name, "long-name", struct gsm_network, name_long);
68
Holger Hans Peter Freyther5ff537c2013-01-09 17:30:11 +010069static int verify_net_apply_config(struct ctrl_cmd *cmd, const char *v, void *d)
70{
71 return 0;
72}
73
74static int get_net_apply_config(struct ctrl_cmd *cmd, void *data)
75{
76 cmd->reply = "Write only attribute";
77 return CTRL_CMD_ERROR;
78}
79
80static int set_net_apply_config(struct ctrl_cmd *cmd, void *data)
81{
82 struct gsm_network *net = cmd->node;
83 struct gsm_bts *bts;
84
85 llist_for_each_entry(bts, &net->bts_list, list) {
86 if (!is_ipaccess_bts(bts))
87 continue;
88
89 ipaccess_drop_oml(bts);
90 }
91
92 cmd->reply = "Tried to drop the BTS";
93 return CTRL_CMD_REPLY;
94}
95
96CTRL_CMD_DEFINE(net_apply_config, "apply-configuration");
97
Holger Hans Peter Freythereab2a3f2014-03-04 17:16:58 +010098static int verify_net_mcc_mnc_apply(struct ctrl_cmd *cmd, const char *value, void *d)
99{
100 char *tmp, *saveptr, *mcc, *mnc;
101
102 tmp = talloc_strdup(cmd, value);
103 if (!tmp)
104 return 1;
105
106 mcc = strtok_r(tmp, ",", &saveptr);
107 mnc = strtok_r(NULL, ",", &saveptr);
108 talloc_free(tmp);
109
110 if (!mcc || !mnc)
111 return 1;
112 return 0;
113}
114
115static int get_net_mcc_mnc_apply(struct ctrl_cmd *cmd, void *data)
116{
117 cmd->reply = "Write only attribute";
118 return CTRL_CMD_ERROR;
119}
120
121static int set_net_mcc_mnc_apply(struct ctrl_cmd *cmd, void *data)
122{
123 struct gsm_network *net = cmd->node;
124 char *tmp, *saveptr, *mcc_str, *mnc_str;
125 int mcc, mnc;
126
127 tmp = talloc_strdup(cmd, cmd->value);
128 if (!tmp)
129 goto oom;
130
131
132 mcc_str = strtok_r(tmp, ",", &saveptr);
133 mnc_str = strtok_r(NULL, ",", &saveptr);
134
135 mcc = atoi(mcc_str);
136 mnc = atoi(mnc_str);
137
138 talloc_free(tmp);
139
140 if (net->network_code == mnc && net->country_code == mcc) {
141 cmd->reply = "Nothing changed";
142 return CTRL_CMD_REPLY;
143 }
144
145 net->network_code = mnc;
146 net->country_code = mcc;
147
148 return set_net_apply_config(cmd, data);
149
150oom:
151 cmd->reply = "OOM";
152 return CTRL_CMD_ERROR;
153}
154CTRL_CMD_DEFINE(net_mcc_mnc_apply, "mcc-mnc-apply");
155
Holger Hans Peter Freytherba8679d2014-11-10 11:41:03 +0100156/* BTS related commands below */
157CTRL_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 +0100158CTRL_CMD_DEFINE_RANGE(bts_ci, "cell-identity", struct gsm_bts, cell_identity, 0, 65535);
Holger Hans Peter Freytherba8679d2014-11-10 11:41:03 +0100159
Holger Hans Peter Freyther87b35d52014-11-21 10:20:29 +0100160static int verify_bts_apply_config(struct ctrl_cmd *cmd, const char *v, void *d)
161{
162 return 0;
163}
164
165static int get_bts_apply_config(struct ctrl_cmd *cmd, void *data)
166{
167 cmd->reply = "Write only attribute";
168 return CTRL_CMD_ERROR;
169}
170
171static int set_bts_apply_config(struct ctrl_cmd *cmd, void *data)
172{
173 struct gsm_bts *bts = cmd->node;
174
175 if (!is_ipaccess_bts(bts)) {
176 cmd->reply = "BTS is not IP based";
177 return CTRL_CMD_ERROR;
178 }
179
180 ipaccess_drop_oml(bts);
181 cmd->reply = "Tried to drop the BTS";
182 return CTRL_CMD_REPLY;
183}
184
185CTRL_CMD_DEFINE(bts_apply_config, "apply-configuration");
186
Holger Hans Peter Freytherd0284c82014-11-21 11:18:45 +0100187static int verify_bts_si(struct ctrl_cmd *cmd, const char *v, void *d)
188{
189 return 0;
190}
191
192static int get_bts_si(struct ctrl_cmd *cmd, void *data)
193{
194 cmd->reply = "Write only attribute";
195 return CTRL_CMD_ERROR;
196}
197
198static int set_bts_si(struct ctrl_cmd *cmd, void *data)
199{
200 struct gsm_bts *bts = cmd->node;
201 struct gsm_bts_trx *trx;
202
203 /* Generate a new ID */
204 bts->bcch_change_mark += 1;
205 bts->bcch_change_mark %= 0x7;
206
207 llist_for_each_entry(trx, &bts->trx_list, list) {
208 int rc;
209
210 rc = gsm_bts_trx_set_system_infos(trx);
211 if (rc != 0) {
212 cmd->reply = "Failed to generate SI";
213 return CTRL_CMD_ERROR;
214 }
215 }
216
217 cmd->reply = "Generated new System Information";
218 return CTRL_CMD_REPLY;
219}
220CTRL_CMD_DEFINE(bts_si, "send-new-system-informations");
221
Holger Hans Peter Freyther2de46892014-03-23 11:17:27 +0100222/* TRX related commands below here */
223CTRL_HELPER_GET_INT(trx_max_power, struct gsm_bts_trx, max_power_red);
Holger Hans Peter Freyther2de46892014-03-23 11:17:27 +0100224static int verify_trx_max_power(struct ctrl_cmd *cmd, const char *value, void *_data)
225{
226 int tmp = atoi(value);
227
228 if (tmp < 0 || tmp > 22) {
229 cmd->reply = "Value must be between 0 and 22";
230 return -1;
231 }
232
233 if (tmp & 1) {
234 cmd->reply = "Value must be even";
235 return -1;
236 }
237
238 return 0;
239}
Holger Hans Peter Freytherb96705b2013-01-09 19:55:04 +0100240CTRL_CMD_DEFINE_RANGE(trx_arfcn, "arfcn", struct gsm_bts_trx, arfcn, 0, 1023);
Holger Hans Peter Freyther1f672322014-03-26 14:24:42 +0100241
242static int set_trx_max_power(struct ctrl_cmd *cmd, void *_data)
243{
244 struct gsm_bts_trx *trx = cmd->node;
245 int old_power;
246
247 /* remember the old value, set the new one */
248 old_power = trx->max_power_red;
249 trx->max_power_red = atoi(cmd->value);
250
251 /* Maybe update the value */
252 if (old_power != trx->max_power_red) {
253 LOGP(DCTRL, LOGL_NOTICE,
254 "%s updating max_pwr_red(%d)\n",
255 gsm_trx_name(trx), trx->max_power_red);
256 abis_nm_update_max_power_red(trx);
257 }
258
259 return get_trx_max_power(cmd, _data);
260}
Holger Hans Peter Freyther2de46892014-03-23 11:17:27 +0100261CTRL_CMD_DEFINE(trx_max_power, "max-power-reduction");
262
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +0100263int bsc_base_ctrl_cmds_install(void)
264{
265 int rc = 0;
266 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_mnc);
267 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_mcc);
268 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_short_name);
269 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_long_name);
Holger Hans Peter Freyther5ff537c2013-01-09 17:30:11 +0100270 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_apply_config);
Holger Hans Peter Freythereab2a3f2014-03-04 17:16:58 +0100271 rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_mcc_mnc_apply);
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +0100272
Holger Hans Peter Freytherba8679d2014-11-10 11:41:03 +0100273 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_lac);
Holger Hans Peter Freyther982bb292014-11-21 10:54:42 +0100274 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_ci);
Holger Hans Peter Freyther87b35d52014-11-21 10:20:29 +0100275 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_apply_config);
Holger Hans Peter Freytherd0284c82014-11-21 11:18:45 +0100276 rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_si);
Holger Hans Peter Freytherba8679d2014-11-10 11:41:03 +0100277
Holger Hans Peter Freyther2de46892014-03-23 11:17:27 +0100278 rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_max_power);
Holger Hans Peter Freytherb96705b2013-01-09 19:55:04 +0100279 rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_arfcn);
280
Holger Hans Peter Freyther1ba8fa62013-01-09 17:03:27 +0100281 return rc;
282}