blob: d59f31c160d77fadb66d7b97f41f88230daf9b3e [file] [log] [blame]
Neels Hofmeyrc69ee852016-05-10 12:50:31 +02001/* Code used by both libbsc and libmsc (common_cs means "BSC or MSC").
2 *
3 * (C) 2016 by sysmocom s.m.f.c. <info@sysmocom.de>
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02004 * (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Neels Hofmeyrc69ee852016-05-10 12:50:31 +02005 * 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 */
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +020021
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020022#include <osmocom/core/utils.h>
23
24#include <osmocom/vty/command.h>
25#include <osmocom/vty/logging.h>
26#include <osmocom/vty/stats.h>
27
Neels Hofmeyr90843962017-09-04 15:04:35 +020028#include <osmocom/msc/vty.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020029
Neels Hofmeyr90843962017-09-04 15:04:35 +020030#include <osmocom/msc/gsm_data.h>
31#include <osmocom/msc/gsm_subscriber.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020032
33struct cmd_node net_node = {
34 GSMNET_NODE,
35 "%s(config-net)# ",
36 1,
37};
38
39#define NETWORK_STR "Configure the GSM network\n"
40#define CODE_CMD_STR "Code commands\n"
41#define NAME_CMD_STR "Name Commands\n"
42#define NAME_STR "Name to use\n"
43
44DEFUN(cfg_net,
45 cfg_net_cmd,
46 "network", NETWORK_STR)
47{
48 vty->index = gsmnet_from_vty(vty);
49 vty->node = GSMNET_NODE;
50
51 return CMD_SUCCESS;
52}
53
54DEFUN(cfg_net_ncc,
55 cfg_net_ncc_cmd,
56 "network country code <1-999>",
57 "Set the GSM network country code\n"
58 "Country commands\n"
59 CODE_CMD_STR
60 "Network Country Code to use\n")
61{
62 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
63
Neels Hofmeyr379d5792018-02-22 04:04:54 +010064 gsmnet->plmn.mcc = atoi(argv[0]);
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020065
66 return CMD_SUCCESS;
67}
68
69DEFUN(cfg_net_mnc,
70 cfg_net_mnc_cmd,
71 "mobile network code <0-999>",
72 "Set the GSM mobile network code\n"
73 "Network Commands\n"
74 CODE_CMD_STR
75 "Mobile Network Code to use\n")
76{
77 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Neels Hofmeyr379d5792018-02-22 04:04:54 +010078 uint16_t mnc;
79 bool mnc_3_digits;
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020080
Neels Hofmeyr379d5792018-02-22 04:04:54 +010081 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
82 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
83 return CMD_WARNING;
84 }
85
86 gsmnet->plmn.mnc = mnc;
87 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020088
89 return CMD_SUCCESS;
90}
91
92DEFUN(cfg_net_name_short,
93 cfg_net_name_short_cmd,
94 "short name NAME",
95 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
96{
97 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
98
Harald Welte4a824ca2017-05-29 13:54:27 +020099 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200100 return CMD_SUCCESS;
101}
102
103DEFUN(cfg_net_name_long,
104 cfg_net_name_long_cmd,
105 "long name NAME",
106 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
107{
108 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
109
Harald Welte4a824ca2017-05-29 13:54:27 +0200110 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200111 return CMD_SUCCESS;
112}
113
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200114DEFUN(cfg_net_encryption,
115 cfg_net_encryption_cmd,
Harald Welte7b222aa2017-12-23 19:30:32 +0100116 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200117 "Encryption options\n"
Harald Welte7b222aa2017-12-23 19:30:32 +0100118 "GSM A5 Air Interface Encryption\n"
119 "A5/n Algorithm Number\n"
120 "A5/n Algorithm Number\n"
121 "A5/n Algorithm Number\n"
122 "A5/n Algorithm Number\n")
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200123{
124 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte7b222aa2017-12-23 19:30:32 +0100125 unsigned int i;
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200126
Harald Welte7b222aa2017-12-23 19:30:32 +0100127 gsmnet->a5_encryption_mask = 0;
128 for (i = 0; i < argc; i++)
129 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200130
131 return CMD_SUCCESS;
132}
133
Harald Welte2483f1b2016-06-19 18:06:02 +0200134DEFUN(cfg_net_authentication,
135 cfg_net_authentication_cmd,
136 "authentication (optional|required)",
137 "Whether to enforce MS authentication in 2G\n"
138 "Allow MS to attach via 2G BSC without authentication\n"
139 "Always do authentication\n")
140{
141 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
142
143 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
144
145 return CMD_SUCCESS;
146}
147
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200148DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
149 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
150 "Radio Resource Location Protocol\n"
151 "Set the Radio Resource Location Protocol Mode\n"
152 "Don't send RRLP request\n"
153 "Request MS-based location\n"
154 "Request any location, prefer MS-based\n"
155 "Request any location, prefer MS-assisted\n")
156{
157 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
158
159 gsmnet->rrlp.mode = rrlp_mode_parse(argv[0]);
160
161 return CMD_SUCCESS;
162}
163
164DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
165 "mm info (0|1)",
166 "Mobility Management\n"
167 "Send MM INFO after LOC UPD ACCEPT\n"
168 "Disable\n" "Enable\n")
169{
170 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
171
172 gsmnet->send_mm_info = atoi(argv[0]);
173
174 return CMD_SUCCESS;
175}
176
Neels Hofmeyr640b7942016-05-14 03:24:41 +0200177DEFUN(cfg_net_timezone,
178 cfg_net_timezone_cmd,
179 "timezone <-19-19> (0|15|30|45)",
180 "Set the Timezone Offset of the network\n"
181 "Timezone offset (hours)\n"
182 "Timezone offset (00 minutes)\n"
183 "Timezone offset (15 minutes)\n"
184 "Timezone offset (30 minutes)\n"
185 "Timezone offset (45 minutes)\n"
186 )
187{
188 struct gsm_network *net = vty->index;
189 int tzhr = atoi(argv[0]);
190 int tzmn = atoi(argv[1]);
191
192 net->tz.hr = tzhr;
193 net->tz.mn = tzmn;
194 net->tz.dst = 0;
195 net->tz.override = 1;
196
197 return CMD_SUCCESS;
198}
199
200DEFUN(cfg_net_timezone_dst,
201 cfg_net_timezone_dst_cmd,
202 "timezone <-19-19> (0|15|30|45) <0-2>",
203 "Set the Timezone Offset of the network\n"
204 "Timezone offset (hours)\n"
205 "Timezone offset (00 minutes)\n"
206 "Timezone offset (15 minutes)\n"
207 "Timezone offset (30 minutes)\n"
208 "Timezone offset (45 minutes)\n"
209 "DST offset (hours)\n"
210 )
211{
212 struct gsm_network *net = vty->index;
213 int tzhr = atoi(argv[0]);
214 int tzmn = atoi(argv[1]);
215 int tzdst = atoi(argv[2]);
216
217 net->tz.hr = tzhr;
218 net->tz.mn = tzmn;
219 net->tz.dst = tzdst;
220 net->tz.override = 1;
221
222 return CMD_SUCCESS;
223}
224
225DEFUN(cfg_net_no_timezone,
226 cfg_net_no_timezone_cmd,
227 "no timezone",
228 NO_STR
229 "Disable network timezone override, use system tz\n")
230{
231 struct gsm_network *net = vty->index;
232
233 net->tz.override = 0;
234
235 return CMD_SUCCESS;
236}
237
Neels Hofmeyre2f24d52017-05-08 15:12:20 +0200238DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
239 "periodic location update <6-1530>",
240 "Periodic Location Updating Interval\n"
241 "Periodic Location Updating Interval\n"
242 "Periodic Location Updating Interval\n"
243 "Periodic Location Updating Interval in Minutes\n")
244{
245 struct gsm_network *net = vty->index;
246
247 net->t3212 = atoi(argv[0]) / 6;
248
249 return CMD_SUCCESS;
250}
251
252DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
253 "no periodic location update",
254 NO_STR
255 "Periodic Location Updating Interval\n"
256 "Periodic Location Updating Interval\n"
257 "Periodic Location Updating Interval\n")
258{
259 struct gsm_network *net = vty->index;
260
261 net->t3212 = 0;
262
263 return CMD_SUCCESS;
264}
265
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +0200266static struct gsm_network *vty_global_gsm_network = NULL;
267
268/* initialize VTY elements used in both BSC and MSC */
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200269int common_cs_vty_init(struct gsm_network *network,
270 int (* config_write_net )(struct vty *))
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +0200271{
272 OSMO_ASSERT(vty_global_gsm_network == NULL);
273 vty_global_gsm_network = network;
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200274
Neels Hofmeyre2f24d52017-05-08 15:12:20 +0200275 osmo_stats_vty_add_cmds();
276
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200277 install_element(CONFIG_NODE, &cfg_net_cmd);
278 install_node(&net_node, config_write_net);
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200279 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
280 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
281 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
282 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200283 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
Harald Welte2483f1b2016-06-19 18:06:02 +0200284 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200285 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
286 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
Neels Hofmeyr640b7942016-05-14 03:24:41 +0200287 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
288 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
289 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
Neels Hofmeyre2f24d52017-05-08 15:12:20 +0200290 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
291 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +0200292
293 return CMD_SUCCESS;
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +0200294}
295
296struct gsm_network *gsmnet_from_vty(struct vty *v)
297{
298 /* It can't hurt to force callers to continue to pass the vty instance
299 * to this function, in case we'd like to retrieve the global
300 * gsm_network instance from the vty at some point in the future. But
301 * until then, just return the global pointer, which should have been
302 * initialized by common_cs_vty_init().
303 */
304 OSMO_ASSERT(vty_global_gsm_network);
305 return vty_global_gsm_network;
306}