blob: acfdd94defeec580234243dd054aaaeb828053ad [file] [log] [blame]
Harald Welte68628e82009-03-10 12:17:57 +00001/* OpenBSC interface to quagga VTY */
Harald Welteaf387632010-03-14 23:30:30 +08002/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte68628e82009-03-10 12:17:57 +00003 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 */
20
21#include <stdlib.h>
22#include <unistd.h>
23#include <sys/types.h>
24
25#include <vty/command.h>
Harald Weltef9daefd2009-08-09 15:13:54 +020026#include <vty/buffer.h>
Harald Welte68628e82009-03-10 12:17:57 +000027#include <vty/vty.h>
28
29#include <arpa/inet.h>
30
Harald Weltedfe6c7d2010-02-20 16:24:02 +010031#include <osmocore/linuxlist.h>
Harald Welte68628e82009-03-10 12:17:57 +000032#include <openbsc/gsm_data.h>
Harald Welte68628e82009-03-10 12:17:57 +000033#include <openbsc/e1_input.h>
Harald Welte1bc77352009-03-10 19:47:51 +000034#include <openbsc/abis_nm.h>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010035#include <osmocore/gsm_utils.h>
Harald Welteb908cb72009-12-22 13:09:29 +010036#include <openbsc/chan_alloc.h>
Harald Welte8387a492009-12-22 21:43:14 +010037#include <openbsc/meas_rep.h>
Harald Welte40f82892009-05-23 17:31:39 +000038#include <openbsc/db.h>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010039#include <osmocore/talloc.h>
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +010040#include <openbsc/telnet_interface.h>
Holger Hans Peter Freyther3c712322010-04-06 11:55:37 +020041#include <openbsc/vty.h>
Harald Welte68628e82009-03-10 12:17:57 +000042
43static struct gsm_network *gsmnet;
44
Harald Welte615e9562010-05-11 23:50:21 +020045static struct value_string gprs_ns_timer_strs[] = {
46 { 0, "tns-block" },
47 { 1, "tns-block-retries" },
48 { 2, "tns-reset" },
49 { 3, "tns-reset-retries" },
50 { 4, "tns-test" },
51 { 5, "tns-alive" },
52 { 6, "tns-alive-retries" },
53 { 0, NULL }
54};
55
56static struct value_string gprs_bssgp_cfg_strs[] = {
57 { 0, "blocking-timer" },
58 { 1, "blocking-retries" },
59 { 2, "unblocking-retries" },
60 { 3, "reset-timer" },
61 { 4, "reset-retries" },
62 { 5, "suspend-timer" },
63 { 6, "suspend-retries" },
64 { 7, "resume-timer" },
65 { 8, "resume-retries" },
66 { 9, "capability-update-timer" },
67 { 10, "capability-update-retries" },
68 { 0, NULL }
69};
70
Harald Welte5013b2a2009-08-07 13:29:14 +020071struct cmd_node net_node = {
72 GSMNET_NODE,
73 "%s(network)#",
74 1,
75};
76
Harald Welte68628e82009-03-10 12:17:57 +000077struct cmd_node bts_node = {
78 BTS_NODE,
79 "%s(bts)#",
80 1,
81};
82
83struct cmd_node trx_node = {
84 TRX_NODE,
85 "%s(trx)#",
86 1,
87};
88
89struct cmd_node ts_node = {
90 TS_NODE,
91 "%s(ts)#",
92 1,
93};
94
95static int dummy_config_write(struct vty *v)
96{
97 return CMD_SUCCESS;
98}
99
100static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
101{
Harald Welte1bc77352009-03-10 19:47:51 +0000102 vty_out(vty,"Oper '%s', Admin %u, Avail '%s'%s",
103 nm_opstate_name(nms->operational), nms->administrative,
104 nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000105}
106
Harald Welteb908cb72009-12-22 13:09:29 +0100107static void dump_pchan_load_vty(struct vty *vty, char *prefix,
108 const struct pchan_load *pl)
109{
110 int i;
111
112 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
113 const struct load_counter *lc = &pl->pchan[i];
114 unsigned int percent;
115
116 if (lc->total == 0)
117 continue;
118
119 percent = (lc->used * 100) / lc->total;
120
121 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
122 gsm_pchan_name(i), percent, lc->used, lc->total,
123 VTY_NEWLINE);
124 }
125}
126
Harald Welte68628e82009-03-10 12:17:57 +0000127static void net_dump_vty(struct vty *vty, struct gsm_network *net)
128{
Harald Welteb908cb72009-12-22 13:09:29 +0100129 struct pchan_load pl;
130
Harald Welteef235b52009-03-10 12:34:02 +0000131 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
132 "and has %u BTS%s", net->country_code, net->network_code,
133 net->num_bts, VTY_NEWLINE);
Harald Welte1bc77352009-03-10 19:47:51 +0000134 vty_out(vty, " Long network name: '%s'%s",
Harald Welte68628e82009-03-10 12:17:57 +0000135 net->name_long, VTY_NEWLINE);
Harald Welte1bc77352009-03-10 19:47:51 +0000136 vty_out(vty, " Short network name: '%s'%s",
Harald Welte68628e82009-03-10 12:17:57 +0000137 net->name_short, VTY_NEWLINE);
Harald Welte (local)69de3972009-08-12 14:42:23 +0200138 vty_out(vty, " Authentication policy: %s%s",
139 gsm_auth_policy_name(net->auth_policy), VTY_NEWLINE);
Harald Welte1085c092009-11-18 20:33:19 +0100140 vty_out(vty, " Location updating reject cause: %u%s",
141 net->reject_cause, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900142 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
143 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100144 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
145 VTY_NEWLINE);
Harald Welteeab84a12009-12-13 10:53:12 +0100146 vty_out(vty, " RRLP Mode: %s%s", rrlp_mode_name(net->rrlp.mode),
147 VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100148 vty_out(vty, " MM Info: %s%s", net->send_mm_info ? "On" : "Off",
149 VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100150 vty_out(vty, " Handover: %s%s", net->handover.active ? "On" : "Off",
151 VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100152 network_chan_load(&pl, net);
153 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
154 dump_pchan_load_vty(vty, " ", &pl);
Harald Welte68628e82009-03-10 12:17:57 +0000155}
156
157DEFUN(show_net, show_net_cmd, "show network",
158 SHOW_STR "Display information about a GSM NETWORK\n")
159{
160 struct gsm_network *net = gsmnet;
161 net_dump_vty(vty, net);
162
163 return CMD_SUCCESS;
164}
165
166static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
167{
Harald Welteedb37782009-05-01 14:59:07 +0000168 struct e1inp_line *line;
169
170 if (!e1l) {
171 vty_out(vty, " None%s", VTY_NEWLINE);
172 return;
173 }
174
175 line = e1l->ts->line;
176
177 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
178 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000179 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000180 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000181 e1l->tei, e1l->sapi, VTY_NEWLINE);
182}
183
184static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
185{
Harald Welteb908cb72009-12-22 13:09:29 +0100186 struct pchan_load pl;
187
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200188 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Weltefcd24452009-06-20 18:15:19 +0200189 "BSIC %u, TSC %u and %u TRX%s",
190 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200191 bts->cell_identity,
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200192 bts->location_area_code, bts->bsic, bts->tsc,
Harald Weltefcd24452009-06-20 18:15:19 +0200193 bts->num_trx, VTY_NEWLINE);
Harald Welte1d8dbc42009-12-12 15:38:16 +0100194 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100195 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100196 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
197 VTY_NEWLINE);
198 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100199 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100200 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
201 VTY_NEWLINE);
202 vty_out(vty, "RACH Max transmissions: %u%s",
203 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
204 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100205 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200206 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000207 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200208 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000209 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200210 bts->oml_tei, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000211 vty_out(vty, " NM State: ");
212 net_dump_nmstate(vty, &bts->nm_state);
213 vty_out(vty, " Site Mgr NM State: ");
214 net_dump_nmstate(vty, &bts->site_mgr.nm_state);
215 vty_out(vty, " Paging: FIXME pending requests, %u free slots%s",
216 bts->paging.available_slots, VTY_NEWLINE);
Harald Welte8175e952009-10-20 00:22:00 +0200217 if (!is_ipaccess_bts(bts)) {
218 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
219 e1isl_dump_vty(vty, bts->oml_link);
220 }
Harald Welte68628e82009-03-10 12:17:57 +0000221 /* FIXME: oml_link, chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100222 memset(&pl, 0, sizeof(pl));
223 bts_chan_load(&pl, bts);
224 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
225 dump_pchan_load_vty(vty, " ", &pl);
Harald Welte68628e82009-03-10 12:17:57 +0000226}
227
228DEFUN(show_bts, show_bts_cmd, "show bts [number]",
229 SHOW_STR "Display information about a BTS\n"
230 "BTS number")
231{
232 struct gsm_network *net = gsmnet;
233 int bts_nr;
234
235 if (argc != 0) {
236 /* use the BTS number that the user has specified */
237 bts_nr = atoi(argv[0]);
238 if (bts_nr > net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000239 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000240 VTY_NEWLINE);
241 return CMD_WARNING;
242 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200243 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000244 return CMD_SUCCESS;
245 }
246 /* print all BTS's */
247 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200248 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000249
250 return CMD_SUCCESS;
251}
252
Harald Welte42581822009-08-08 16:12:58 +0200253/* utility functions */
254static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
255 const char *ts, const char *ss)
256{
257 e1_link->e1_nr = atoi(line);
258 e1_link->e1_ts = atoi(ts);
259 if (!strcmp(ss, "full"))
260 e1_link->e1_ts_ss = 255;
261 else
262 e1_link->e1_ts_ss = atoi(ss);
263}
264
265static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
266 const char *prefix)
267{
268 if (!e1_link->e1_ts)
269 return;
270
271 if (e1_link->e1_ts_ss == 255)
272 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
273 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
274 else
275 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
276 prefix, e1_link->e1_nr, e1_link->e1_ts,
277 e1_link->e1_ts_ss, VTY_NEWLINE);
278}
279
280
Harald Welte67ce0732009-08-06 19:06:46 +0200281static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
282{
Harald Welte42581822009-08-08 16:12:58 +0200283 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
284 if (ts->pchan != GSM_PCHAN_NONE)
285 vty_out(vty, " phys_chan_config %s%s",
286 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
287 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welte67ce0732009-08-06 19:06:46 +0200288}
289
290static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
291{
292 int i;
293
Harald Welte5013b2a2009-08-07 13:29:14 +0200294 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200295 vty_out(vty, " rf_locked %u%s",
296 trx->nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
297 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200298 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100299 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200300 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200301 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
302 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200303
304 for (i = 0; i < TRX_NR_TS; i++)
305 config_write_ts_single(vty, &trx->ts[i]);
306}
307
Harald Welte615e9562010-05-11 23:50:21 +0200308static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
309{
310 unsigned int i;
311 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
312 VTY_NEWLINE);
313 if (bts->gprs.mode == BTS_GPRS_NONE)
314 return;
315
316 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
317 VTY_NEWLINE);
318 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
319 VTY_NEWLINE);
320 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
321 vty_out(vty, " gprs cell timer %s %u%s",
322 get_value_string(gprs_bssgp_cfg_strs, i),
323 bts->gprs.cell.timer[i], VTY_NEWLINE);
324 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
325 VTY_NEWLINE);
326 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
327 vty_out(vty, " gprs ns timer %s %u%s",
328 get_value_string(gprs_ns_timer_strs, i),
329 bts->gprs.nse.timer[i], VTY_NEWLINE);
330 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
331 struct gsm_bts_gprs_nsvc *nsvc =
332 &bts->gprs.nsvc[i];
333 struct in_addr ia;
334
335 ia.s_addr = htonl(nsvc->remote_ip);
336 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
337 nsvc->nsvci, VTY_NEWLINE);
338 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
339 nsvc->local_port, VTY_NEWLINE);
340 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
341 nsvc->remote_port, VTY_NEWLINE);
342 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
343 inet_ntoa(ia), VTY_NEWLINE);
344 }
345}
346
Harald Welte67ce0732009-08-06 19:06:46 +0200347static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
348{
349 struct gsm_bts_trx *trx;
350
Harald Welte5013b2a2009-08-07 13:29:14 +0200351 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
352 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
353 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100354 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200355 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200356 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200357 vty_out(vty, " training_sequence_code %u%s", bts->tsc, VTY_NEWLINE);
358 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200359 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100360 vty_out(vty, " cell reselection hysteresis %u%s",
361 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
362 vty_out(vty, " rxlev access min %u%s",
363 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Harald Weltea43f7892009-12-01 18:04:30 +0530364 if (bts->si_common.chan_desc.t3212)
Harald Welte (local)efc92312009-08-14 23:09:25 +0200365 vty_out(vty, " periodic location update %u%s",
Harald Weltea43f7892009-12-01 18:04:30 +0530366 bts->si_common.chan_desc.t3212 * 10, VTY_NEWLINE);
Harald Welte7a8fa412009-08-10 13:48:16 +0200367 vty_out(vty, " channel allocator %s%s",
368 bts->chan_alloc_reverse ? "descending" : "ascending",
369 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100370 vty_out(vty, " rach tx integer %u%s",
371 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
372 vty_out(vty, " rach max transmission %u%s",
373 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
374 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800375
376 if (bts->rach_b_thresh != -1)
377 vty_out(vty, " rach nm busy threshold %u%s",
378 bts->rach_b_thresh, VTY_NEWLINE);
379 if (bts->rach_ldavg_slots != -1)
380 vty_out(vty, " rach nm load average %u%s",
381 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100382 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200383 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Harald Welte8175e952009-10-20 00:22:00 +0200384 if (is_ipaccess_bts(bts)) {
Harald Welte5013b2a2009-08-07 13:29:14 +0200385 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200386 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8175e952009-10-20 00:22:00 +0200387 vty_out(vty, " oml ip.access stream_id %u%s", bts->oml_tei, VTY_NEWLINE);
388 } else {
Harald Welte42581822009-08-08 16:12:58 +0200389 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
390 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
391 }
Harald Welte615e9562010-05-11 23:50:21 +0200392 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200393
394 llist_for_each_entry(trx, &bts->trx_list, list)
395 config_write_trx_single(vty, trx);
396}
397
398static int config_write_bts(struct vty *v)
399{
400 struct gsm_bts *bts;
401
402 llist_for_each_entry(bts, &gsmnet->bts_list, list)
403 config_write_bts_single(v, bts);
404
405 return CMD_SUCCESS;
406}
407
Harald Welte5013b2a2009-08-07 13:29:14 +0200408static int config_write_net(struct vty *vty)
409{
410 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200411 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200412 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200413 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
414 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
Harald Welte (local)69de3972009-08-12 14:42:23 +0200415 vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE);
Harald Welte1085c092009-11-18 20:33:19 +0100416 vty_out(vty, " location updating reject cause %u%s",
417 gsmnet->reject_cause, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900418 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100419 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Harald Welteeab84a12009-12-13 10:53:12 +0100420 vty_out(vty, " rrlp mode %s%s", rrlp_mode_name(gsmnet->rrlp.mode),
421 VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100422 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100423 vty_out(vty, " handover %u%s", gsmnet->handover.active, VTY_NEWLINE);
Harald Welteb720bd32009-12-21 16:51:50 +0100424 vty_out(vty, " handover window rxlev averaging %u%s",
425 gsmnet->handover.win_rxlev_avg, VTY_NEWLINE);
426 vty_out(vty, " handover window rxqual averaging %u%s",
427 gsmnet->handover.win_rxqual_avg, VTY_NEWLINE);
428 vty_out(vty, " handover window rxlev neighbor averaging %u%s",
429 gsmnet->handover.win_rxlev_avg_neigh, VTY_NEWLINE);
430 vty_out(vty, " handover power budget interval %u%s",
431 gsmnet->handover.pwr_interval, VTY_NEWLINE);
432 vty_out(vty, " handover power budget hysteresis %u%s",
433 gsmnet->handover.pwr_hysteresis, VTY_NEWLINE);
434 vty_out(vty, " handover maximum distance %u%s",
435 gsmnet->handover.max_distance, VTY_NEWLINE);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +0100436 vty_out(vty, " timer t3101 %u%s", gsmnet->T3101, VTY_NEWLINE);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +0100437 vty_out(vty, " timer t3103 %u%s", gsmnet->T3103, VTY_NEWLINE);
438 vty_out(vty, " timer t3105 %u%s", gsmnet->T3105, VTY_NEWLINE);
439 vty_out(vty, " timer t3107 %u%s", gsmnet->T3107, VTY_NEWLINE);
440 vty_out(vty, " timer t3109 %u%s", gsmnet->T3109, VTY_NEWLINE);
441 vty_out(vty, " timer t3111 %u%s", gsmnet->T3111, VTY_NEWLINE);
442 vty_out(vty, " timer t3113 %u%s", gsmnet->T3113, VTY_NEWLINE);
443 vty_out(vty, " timer t3115 %u%s", gsmnet->T3115, VTY_NEWLINE);
444 vty_out(vty, " timer t3117 %u%s", gsmnet->T3117, VTY_NEWLINE);
445 vty_out(vty, " timer t3119 %u%s", gsmnet->T3119, VTY_NEWLINE);
446 vty_out(vty, " timer t3141 %u%s", gsmnet->T3141, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200447
448 return CMD_SUCCESS;
449}
Harald Welte67ce0732009-08-06 19:06:46 +0200450
Harald Welte68628e82009-03-10 12:17:57 +0000451static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
452{
453 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
454 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200455 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200456 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200457 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200458 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000459 vty_out(vty, " NM State: ");
460 net_dump_nmstate(vty, &trx->nm_state);
461 vty_out(vty, " Baseband Transceiver NM State: ");
462 net_dump_nmstate(vty, &trx->bb_transc.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200463 if (is_ipaccess_bts(trx->bts)) {
464 vty_out(vty, " ip.access stream ID: 0x%02x%s",
465 trx->rsl_tei, VTY_NEWLINE);
466 } else {
467 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
468 e1isl_dump_vty(vty, trx->rsl_link);
469 }
Harald Welte68628e82009-03-10 12:17:57 +0000470}
471
472DEFUN(show_trx,
473 show_trx_cmd,
474 "show trx [bts_nr] [trx_nr]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200475 SHOW_STR "Display information about a TRX\n"
476 "BTS Number\n"
477 "TRX Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000478{
479 struct gsm_network *net = gsmnet;
480 struct gsm_bts *bts = NULL;
481 struct gsm_bts_trx *trx;
482 int bts_nr, trx_nr;
483
484 if (argc >= 1) {
485 /* use the BTS number that the user has specified */
486 bts_nr = atoi(argv[0]);
487 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000488 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000489 VTY_NEWLINE);
490 return CMD_WARNING;
491 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200492 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000493 }
494 if (argc >= 2) {
495 trx_nr = atoi(argv[1]);
496 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000497 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000498 VTY_NEWLINE);
499 return CMD_WARNING;
500 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200501 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000502 trx_dump_vty(vty, trx);
503 return CMD_SUCCESS;
504 }
505 if (bts) {
506 /* print all TRX in this BTS */
507 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200508 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000509 trx_dump_vty(vty, trx);
510 }
511 return CMD_SUCCESS;
512 }
513
514 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200515 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000516 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200517 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000518 trx_dump_vty(vty, trx);
519 }
520 }
521
522 return CMD_SUCCESS;
523}
524
Harald Welte67ce0732009-08-06 19:06:46 +0200525
Harald Welte68628e82009-03-10 12:17:57 +0000526static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
527{
Harald Welte68628e82009-03-10 12:17:57 +0000528 vty_out(vty, "Timeslot %u of TRX %u in BTS %u, phys cfg %s%s",
529 ts->nr, ts->trx->nr, ts->trx->bts->nr,
530 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
531 vty_out(vty, " NM State: ");
532 net_dump_nmstate(vty, &ts->nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530533 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000534 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
535 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
536 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000537}
538
539DEFUN(show_ts,
540 show_ts_cmd,
Harald Welte1bc77352009-03-10 19:47:51 +0000541 "show timeslot [bts_nr] [trx_nr] [ts_nr]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200542 SHOW_STR "Display information about a TS\n"
543 "BTS Number\n" "TRX Number\n" "Timeslot Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000544{
545 struct gsm_network *net = gsmnet;
546 struct gsm_bts *bts;
547 struct gsm_bts_trx *trx;
548 struct gsm_bts_trx_ts *ts;
549 int bts_nr, trx_nr, ts_nr;
550
551 if (argc >= 1) {
552 /* use the BTS number that the user has specified */
553 bts_nr = atoi(argv[0]);
554 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000555 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000556 VTY_NEWLINE);
557 return CMD_WARNING;
558 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200559 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000560 }
561 if (argc >= 2) {
562 trx_nr = atoi(argv[1]);
563 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000564 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000565 VTY_NEWLINE);
566 return CMD_WARNING;
567 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200568 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000569 }
570 if (argc >= 3) {
571 ts_nr = atoi(argv[2]);
572 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +0000573 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +0000574 VTY_NEWLINE);
575 return CMD_WARNING;
576 }
577 ts = &trx->ts[ts_nr];
578 ts_dump_vty(vty, ts);
579 return CMD_SUCCESS;
580 }
581 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200582 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000583 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200584 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000585 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
586 ts = &trx->ts[ts_nr];
587 ts_dump_vty(vty, ts);
588 }
589 }
590 }
591
592 return CMD_SUCCESS;
593}
594
Holger Hans Peter Freyther424c4f02010-01-06 06:00:40 +0100595static void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr)
Harald Welte68628e82009-03-10 12:17:57 +0000596{
Harald Weltefcd24452009-06-20 18:15:19 +0200597 vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id,
Harald Welte40f82892009-05-23 17:31:39 +0000598 subscr->authorized, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000599 if (subscr->name)
Harald Welte1bc77352009-03-10 19:47:51 +0000600 vty_out(vty, " Name: '%s'%s", subscr->name, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000601 if (subscr->extension)
602 vty_out(vty, " Extension: %s%s", subscr->extension,
603 VTY_NEWLINE);
604 if (subscr->imsi)
605 vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE);
Holger Hans Peter Freyther22230252009-08-19 12:53:57 +0200606 if (subscr->tmsi != GSM_RESERVED_TMSI)
607 vty_out(vty, " TMSI: %08X%s", subscr->tmsi,
Harald Welte731fd912009-08-15 03:24:51 +0200608 VTY_NEWLINE);
Sylvain Munautaf292642009-12-27 19:29:28 +0100609
Harald Welte (local)15920de2009-08-14 20:27:16 +0200610 vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000611}
612
Harald Welte8387a492009-12-22 21:43:14 +0100613static void meas_rep_dump_uni_vty(struct vty *vty,
614 struct gsm_meas_rep_unidir *mru,
615 const char *prefix,
616 const char *dir)
617{
618 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
619 prefix, dir, rxlev2dbm(mru->full.rx_lev),
620 dir, rxlev2dbm(mru->sub.rx_lev));
621 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
622 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
623 VTY_NEWLINE);
624}
625
626static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
627 const char *prefix)
628{
629 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
630 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
631 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
632 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
633 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
634 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
635 VTY_NEWLINE);
636 if (mr->flags & MEAS_REP_F_MS_TO)
637 vty_out(vty, "%s MS Timing Offset: %u%s", prefix,
638 mr->ms_timing_offset, VTY_NEWLINE);
639 if (mr->flags & MEAS_REP_F_MS_L1)
640 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
641 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
642 if (mr->flags & MEAS_REP_F_DL_VALID)
643 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
644 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
645}
646
Harald Welte68628e82009-03-10 12:17:57 +0000647static void lchan_dump_vty(struct vty *vty, struct gsm_lchan *lchan)
648{
Harald Welte8387a492009-12-22 21:43:14 +0100649 int idx;
650
Harald Welte68628e82009-03-10 12:17:57 +0000651 vty_out(vty, "Lchan %u in Timeslot %u of TRX %u in BTS %u, Type %s%s",
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +0200652 lchan->nr, lchan->ts->nr, lchan->ts->trx->nr,
Harald Welte (local)ccd88452009-12-27 18:05:25 +0100653 lchan->ts->trx->bts->nr, gsm_lchant_name(lchan->type),
Harald Welte68628e82009-03-10 12:17:57 +0000654 VTY_NEWLINE);
Holger Hans Peter Freyther68884aa2010-03-23 06:41:45 +0100655 vty_out(vty, " Use Count: %u, State: %s%s", lchan->conn.use_count,
Harald Welte1887f9d2009-12-29 10:52:38 +0100656 gsm_lchans_name(lchan->state), VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100657 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
658 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
659 - lchan->bs_power*2,
660 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
661 VTY_NEWLINE);
Holger Hans Peter Freyther68884aa2010-03-23 06:41:45 +0100662 if (lchan->conn.subscr) {
Harald Welte68628e82009-03-10 12:17:57 +0000663 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Holger Hans Peter Freyther68884aa2010-03-23 06:41:45 +0100664 subscr_dump_vty(vty, lchan->conn.subscr);
Harald Welte68628e82009-03-10 12:17:57 +0000665 } else
666 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +0530667 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
668 struct in_addr ia;
Holger Hans Peter Freyther54fa7992010-04-07 15:39:16 +0200669 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte2c828992009-12-02 01:56:49 +0530670 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
671 inet_ntoa(ia), lchan->abis_ip.bound_port,
672 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
673 VTY_NEWLINE);
674 }
Harald Welte8387a492009-12-22 21:43:14 +0100675
676 /* we want to report the last measurement report */
677 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
678 lchan->meas_rep_idx, 1);
679 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +0000680}
681
Harald Welte4bfdfe72009-06-10 23:11:52 +0800682#if 0
683TODO: callref and remote callref of call must be resolved to get gsm_trans object
Harald Welte68628e82009-03-10 12:17:57 +0000684static void call_dump_vty(struct vty *vty, struct gsm_call *call)
685{
686 vty_out(vty, "Call Type %u, State %u, Transaction ID %u%s",
687 call->type, call->state, call->transaction_id, VTY_NEWLINE);
688
689 if (call->local_lchan) {
690 vty_out(vty, "Call Local Channel:%s", VTY_NEWLINE);
691 lchan_dump_vty(vty, call->local_lchan);
692 } else
693 vty_out(vty, "Call has no Local Channel%s", VTY_NEWLINE);
694
695 if (call->remote_lchan) {
696 vty_out(vty, "Call Remote Channel:%s", VTY_NEWLINE);
697 lchan_dump_vty(vty, call->remote_lchan);
698 } else
699 vty_out(vty, "Call has no Remote Channel%s", VTY_NEWLINE);
700
701 if (call->called_subscr) {
702 vty_out(vty, "Called Subscriber:%s", VTY_NEWLINE);
703 subscr_dump_vty(vty, call->called_subscr);
704 } else
705 vty_out(vty, "Call has no Called Subscriber%s", VTY_NEWLINE);
706}
Harald Welte4bfdfe72009-06-10 23:11:52 +0800707#endif
Harald Welte68628e82009-03-10 12:17:57 +0000708
709DEFUN(show_lchan,
710 show_lchan_cmd,
711 "show lchan [bts_nr] [trx_nr] [ts_nr] [lchan_nr]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200712 SHOW_STR "Display information about a logical channel\n"
713 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
714 "Logical Channel Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000715{
716 struct gsm_network *net = gsmnet;
717 struct gsm_bts *bts;
718 struct gsm_bts_trx *trx;
719 struct gsm_bts_trx_ts *ts;
720 struct gsm_lchan *lchan;
721 int bts_nr, trx_nr, ts_nr, lchan_nr;
722
723 if (argc >= 1) {
724 /* use the BTS number that the user has specified */
725 bts_nr = atoi(argv[0]);
726 if (bts_nr >= net->num_bts) {
727 vty_out(vty, "%% can't find BTS %s%s", argv[0],
728 VTY_NEWLINE);
729 return CMD_WARNING;
730 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200731 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000732 }
733 if (argc >= 2) {
734 trx_nr = atoi(argv[1]);
735 if (trx_nr >= bts->num_trx) {
736 vty_out(vty, "%% can't find TRX %s%s", argv[1],
737 VTY_NEWLINE);
738 return CMD_WARNING;
739 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200740 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000741 }
742 if (argc >= 3) {
743 ts_nr = atoi(argv[2]);
744 if (ts_nr >= TRX_NR_TS) {
745 vty_out(vty, "%% can't find TS %s%s", argv[2],
746 VTY_NEWLINE);
747 return CMD_WARNING;
748 }
749 ts = &trx->ts[ts_nr];
750 }
751 if (argc >= 4) {
752 lchan_nr = atoi(argv[3]);
753 if (lchan_nr >= TS_MAX_LCHAN) {
754 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
755 VTY_NEWLINE);
756 return CMD_WARNING;
757 }
758 lchan = &ts->lchan[lchan_nr];
759 lchan_dump_vty(vty, lchan);
760 return CMD_SUCCESS;
761 }
762 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200763 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000764 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200765 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000766 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
767 ts = &trx->ts[ts_nr];
768 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN;
769 lchan_nr++) {
770 lchan = &ts->lchan[lchan_nr];
Harald Welteef235b52009-03-10 12:34:02 +0000771 if (lchan->type == GSM_LCHAN_NONE)
772 continue;
Harald Welte68628e82009-03-10 12:17:57 +0000773 lchan_dump_vty(vty, lchan);
774 }
775 }
776 }
777 }
778
779 return CMD_SUCCESS;
780}
781
Harald Welte1bc77352009-03-10 19:47:51 +0000782static void e1drv_dump_vty(struct vty *vty, struct e1inp_driver *drv)
783{
784 vty_out(vty, "E1 Input Driver %s%s", drv->name, VTY_NEWLINE);
785}
786
787DEFUN(show_e1drv,
788 show_e1drv_cmd,
789 "show e1_driver",
790 SHOW_STR "Display information about available E1 drivers\n")
791{
792 struct e1inp_driver *drv;
793
794 llist_for_each_entry(drv, &e1inp_driver_list, list)
795 e1drv_dump_vty(vty, drv);
796
797 return CMD_SUCCESS;
798}
799
Harald Welte68628e82009-03-10 12:17:57 +0000800static void e1line_dump_vty(struct vty *vty, struct e1inp_line *line)
801{
802 vty_out(vty, "E1 Line Number %u, Name %s, Driver %s%s",
803 line->num, line->name ? line->name : "",
804 line->driver->name, VTY_NEWLINE);
805}
806
807DEFUN(show_e1line,
808 show_e1line_cmd,
809 "show e1_line [line_nr]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200810 SHOW_STR "Display information about a E1 line\n"
811 "E1 Line Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000812{
Harald Welte1bc77352009-03-10 19:47:51 +0000813 struct e1inp_line *line;
814
815 if (argc >= 1) {
816 int num = atoi(argv[0]);
817 llist_for_each_entry(line, &e1inp_line_list, list) {
818 if (line->num == num) {
819 e1line_dump_vty(vty, line);
820 return CMD_SUCCESS;
821 }
822 }
823 return CMD_WARNING;
824 }
825
826 llist_for_each_entry(line, &e1inp_line_list, list)
827 e1line_dump_vty(vty, line);
828
829 return CMD_SUCCESS;
Harald Welte68628e82009-03-10 12:17:57 +0000830}
831
832static void e1ts_dump_vty(struct vty *vty, struct e1inp_ts *ts)
833{
Harald Welte42581822009-08-08 16:12:58 +0200834 if (ts->type == E1INP_TS_TYPE_NONE)
835 return;
Harald Welte1bc77352009-03-10 19:47:51 +0000836 vty_out(vty, "E1 Timeslot %2u of Line %u is Type %s%s",
837 ts->num, ts->line->num, e1inp_tstype_name(ts->type),
838 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000839}
840
841DEFUN(show_e1ts,
842 show_e1ts_cmd,
843 "show e1_timeslot [line_nr] [ts_nr]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200844 SHOW_STR "Display information about a E1 timeslot\n"
845 "E1 Line Number\n" "E1 Timeslot Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000846{
Harald Welte986c3d72009-11-17 06:12:16 +0100847 struct e1inp_line *line = NULL;
Harald Welte1bc77352009-03-10 19:47:51 +0000848 struct e1inp_ts *ts;
849 int ts_nr;
Harald Welte68628e82009-03-10 12:17:57 +0000850
Harald Welte1bc77352009-03-10 19:47:51 +0000851 if (argc == 0) {
852 llist_for_each_entry(line, &e1inp_line_list, list) {
853 for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) {
854 ts = &line->ts[ts_nr];
855 e1ts_dump_vty(vty, ts);
856 }
857 }
858 return CMD_SUCCESS;
859 }
860 if (argc >= 1) {
861 int num = atoi(argv[0]);
862 llist_for_each_entry(line, &e1inp_line_list, list) {
863 if (line->num == num)
864 break;
865 }
866 if (!line || line->num != num) {
867 vty_out(vty, "E1 line %s is invalid%s",
868 argv[0], VTY_NEWLINE);
869 return CMD_WARNING;
870 }
871 }
872 if (argc >= 2) {
873 ts_nr = atoi(argv[1]);
874 if (ts_nr > NUM_E1_TS) {
875 vty_out(vty, "E1 timeslot %s is invalid%s",
876 argv[1], VTY_NEWLINE);
877 return CMD_WARNING;
878 }
879 ts = &line->ts[ts_nr];
880 e1ts_dump_vty(vty, ts);
881 return CMD_SUCCESS;
882 } else {
883 for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) {
884 ts = &line->ts[ts_nr];
885 e1ts_dump_vty(vty, ts);
886 }
887 return CMD_SUCCESS;
888 }
889 return CMD_SUCCESS;
Harald Welte68628e82009-03-10 12:17:57 +0000890}
891
Harald Weltebe4b7302009-05-23 16:59:33 +0000892static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +0000893{
894 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
895 subscr_dump_vty(vty, pag->subscr);
896}
897
Harald Weltebe4b7302009-05-23 16:59:33 +0000898static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +0000899{
900 struct gsm_paging_request *pag;
901
902 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
903 paging_dump_vty(vty, pag);
904}
905
906DEFUN(show_paging,
907 show_paging_cmd,
908 "show paging [bts_nr]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200909 SHOW_STR "Display information about paging reuqests of a BTS\n"
910 "BTS Number\n")
Harald Weltef5025b62009-03-28 16:55:11 +0000911{
912 struct gsm_network *net = gsmnet;
913 struct gsm_bts *bts;
914 int bts_nr;
915
916 if (argc >= 1) {
917 /* use the BTS number that the user has specified */
918 bts_nr = atoi(argv[0]);
919 if (bts_nr >= net->num_bts) {
920 vty_out(vty, "%% can't find BTS %s%s", argv[0],
921 VTY_NEWLINE);
922 return CMD_WARNING;
923 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200924 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +0000925 bts_paging_dump_vty(vty, bts);
926
927 return CMD_SUCCESS;
928 }
929 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200930 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +0000931 bts_paging_dump_vty(vty, bts);
932 }
933
934 return CMD_SUCCESS;
935}
936
Harald Welte8f0ed552010-05-11 21:53:49 +0200937#define NETWORK_STR "Configure the GSM network\n"
938
Harald Welte5013b2a2009-08-07 13:29:14 +0200939DEFUN(cfg_net,
940 cfg_net_cmd,
Harald Welte8f0ed552010-05-11 21:53:49 +0200941 "network", NETWORK_STR)
Harald Welte5013b2a2009-08-07 13:29:14 +0200942{
943 vty->index = gsmnet;
944 vty->node = GSMNET_NODE;
945
946 return CMD_SUCCESS;
947}
948
949
950DEFUN(cfg_net_ncc,
951 cfg_net_ncc_cmd,
952 "network country code <1-999>",
953 "Set the GSM network country code")
954{
955 gsmnet->country_code = atoi(argv[0]);
956
957 return CMD_SUCCESS;
958}
959
960DEFUN(cfg_net_mnc,
961 cfg_net_mnc_cmd,
962 "mobile network code <1-999>",
963 "Set the GSM mobile network code")
964{
965 gsmnet->network_code = atoi(argv[0]);
966
967 return CMD_SUCCESS;
968}
969
970DEFUN(cfg_net_name_short,
971 cfg_net_name_short_cmd,
972 "short name NAME",
973 "Set the short GSM network name")
974{
975 if (gsmnet->name_short)
976 talloc_free(gsmnet->name_short);
977
978 gsmnet->name_short = talloc_strdup(gsmnet, argv[0]);
979
980 return CMD_SUCCESS;
981}
982
983DEFUN(cfg_net_name_long,
984 cfg_net_name_long_cmd,
985 "long name NAME",
986 "Set the long GSM network name")
987{
988 if (gsmnet->name_long)
989 talloc_free(gsmnet->name_long);
990
991 gsmnet->name_long = talloc_strdup(gsmnet, argv[0]);
992
993 return CMD_SUCCESS;
994}
Harald Welte40f82892009-05-23 17:31:39 +0000995
Harald Welte (local)69de3972009-08-12 14:42:23 +0200996DEFUN(cfg_net_auth_policy,
997 cfg_net_auth_policy_cmd,
998 "auth policy (closed|accept-all|token)",
Harald Welte8f0ed552010-05-11 21:53:49 +0200999 "Authentication (not cryptographic)\n"
1000 "Set the GSM network authentication policy\n"
1001 "Require the MS to be activated in HLR\n"
1002 "Accept all MS, whether in HLR or not\n"
1003 "Use SMS-token based authentication\n")
Harald Welte (local)69de3972009-08-12 14:42:23 +02001004{
1005 enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]);
1006
1007 gsmnet->auth_policy = policy;
1008
1009 return CMD_SUCCESS;
1010}
1011
Harald Welte1085c092009-11-18 20:33:19 +01001012DEFUN(cfg_net_reject_cause,
1013 cfg_net_reject_cause_cmd,
1014 "location updating reject cause <2-111>",
1015 "Set the reject cause of location updating reject\n")
1016{
1017 gsmnet->reject_cause = atoi(argv[0]);
1018
1019 return CMD_SUCCESS;
1020}
1021
Harald Welte4381cfe2009-08-30 15:47:06 +09001022DEFUN(cfg_net_encryption,
1023 cfg_net_encryption_cmd,
1024 "encryption a5 (0|1|2)",
1025 "Enable or disable encryption (A5) for this network\n")
1026{
Andreas.Eversberg1059deb2009-11-17 09:55:26 +01001027 gsmnet->a5_encryption= atoi(argv[0]);
Harald Welte4381cfe2009-08-30 15:47:06 +09001028
1029 return CMD_SUCCESS;
1030}
1031
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001032DEFUN(cfg_net_neci,
1033 cfg_net_neci_cmd,
1034 "neci (0|1)",
1035 "Set if NECI of cell selection is to be set")
1036{
1037 gsmnet->neci = atoi(argv[0]);
1038 return CMD_SUCCESS;
1039}
1040
Harald Welteeab84a12009-12-13 10:53:12 +01001041DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
1042 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001043 "Radio Resource Location Protocol\n"
1044 "Set the Radio Resource Location Protocol Mode\n"
1045 "Don't send RRLP request\n"
1046 "Request MS-based location\n"
1047 "Request any location, prefer MS-based\n"
1048 "Request any location, prefer MS-assisted\n")
Harald Welteeab84a12009-12-13 10:53:12 +01001049{
1050 gsmnet->rrlp.mode = rrlp_mode_parse(argv[0]);
1051
1052 return CMD_SUCCESS;
1053}
1054
Harald Welte648b6ce2009-12-14 09:00:24 +01001055DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
1056 "mm info (0|1)",
1057 "Whether to send MM INFO after LOC UPD ACCEPT")
1058{
1059 gsmnet->send_mm_info = atoi(argv[0]);
1060
1061 return CMD_SUCCESS;
1062}
1063
Harald Welte8f0ed552010-05-11 21:53:49 +02001064#define HANDOVER_STR "Handover Options\n"
1065
Harald Weltebc814502009-12-19 21:41:52 +01001066DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1067 "handover (0|1)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001068 HANDOVER_STR
1069 "Don't perform in-call handover\n"
1070 "Perform in-call handover\n")
Harald Weltebc814502009-12-19 21:41:52 +01001071{
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001072 int enable = atoi(argv[0]);
1073
1074 if (enable && ipacc_rtp_direct) {
Harald Weltefe03f0d2009-12-20 13:51:01 +01001075 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1076 "is enabled by using the -P command line option%s",
1077 VTY_NEWLINE);
1078 return CMD_WARNING;
1079 }
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001080 gsmnet->handover.active = enable;
Harald Weltebc814502009-12-19 21:41:52 +01001081
1082 return CMD_SUCCESS;
1083}
1084
Harald Welte8f0ed552010-05-11 21:53:49 +02001085#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1086#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1087#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1088#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
1089
Harald Welteb720bd32009-12-21 16:51:50 +01001090DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1091 "handover window rxlev averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001092 HO_WIN_RXLEV_STR
Harald Welteb720bd32009-12-21 16:51:50 +01001093 "How many RxLev measurements are used for averaging")
1094{
1095 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1096 return CMD_SUCCESS;
1097}
1098
1099DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1100 "handover window rxqual averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001101 HO_WIN_RXQUAL_STR
Harald Welteb720bd32009-12-21 16:51:50 +01001102 "How many RxQual measurements are used for averaging")
1103{
1104 gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
1105 return CMD_SUCCESS;
1106}
1107
1108DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1109 "handover window rxlev neighbor averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001110 HO_WIN_RXLEV_STR
Harald Welteb720bd32009-12-21 16:51:50 +01001111 "How many RxQual measurements are used for averaging")
1112{
1113 gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
1114 return CMD_SUCCESS;
1115}
1116
1117DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1118 "handover power budget interval <1-99>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001119 HO_PBUDGET_STR
Harald Welteb720bd32009-12-21 16:51:50 +01001120 "How often to check if we have a better cell (SACCH frames)")
1121{
1122 gsmnet->handover.pwr_interval = atoi(argv[0]);
1123 return CMD_SUCCESS;
1124}
1125
1126DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1127 "handover power budget hysteresis <0-999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001128 HO_PBUDGET_STR
Harald Welteb720bd32009-12-21 16:51:50 +01001129 "How many dB does a neighbor to be stronger to become a HO candidate")
1130{
1131 gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
1132 return CMD_SUCCESS;
1133}
1134
1135DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1136 "handover maximum distance <0-9999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001137 HANDOVER_STR
Harald Welteb720bd32009-12-21 16:51:50 +01001138 "How big is the maximum timing advance before HO is forced")
1139{
1140 gsmnet->handover.max_distance = atoi(argv[0]);
1141 return CMD_SUCCESS;
1142}
Harald Weltebc814502009-12-19 21:41:52 +01001143
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001144#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001145 DEFUN(cfg_net_T##number, \
1146 cfg_net_T##number##_cmd, \
1147 "timer t" #number " <0-65535>", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001148 "Configure GSM Timers\n" \
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001149 doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001150{ \
1151 int value = atoi(argv[0]); \
1152 \
1153 if (value < 0 || value > 65535) { \
1154 vty_out(vty, "Timer value %s out of range.%s", \
1155 argv[0], VTY_NEWLINE); \
1156 return CMD_WARNING; \
1157 } \
1158 \
1159 gsmnet->T##number = value; \
1160 return CMD_SUCCESS; \
1161}
1162
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001163DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT.")
1164DECLARE_TIMER(3103, "Set the timeout value for HANDOVER.")
1165DECLARE_TIMER(3105, "Currently not used.")
1166DECLARE_TIMER(3107, "Currently not used.")
1167DECLARE_TIMER(3109, "Currently not used.")
1168DECLARE_TIMER(3111, "Currently not used.")
1169DECLARE_TIMER(3113, "Set the time to try paging a subscriber.")
1170DECLARE_TIMER(3115, "Currently not used.")
1171DECLARE_TIMER(3117, "Currently not used.")
1172DECLARE_TIMER(3119, "Currently not used.")
1173DECLARE_TIMER(3141, "Currently not used.")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001174
1175
Harald Welte5258fc42009-03-28 19:07:53 +00001176/* per-BTS configuration */
1177DEFUN(cfg_bts,
1178 cfg_bts_cmd,
1179 "bts BTS_NR",
Harald Welte8f0ed552010-05-11 21:53:49 +02001180 "Select a BTS to configure\n"
1181 "BTS Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001182{
1183 int bts_nr = atoi(argv[0]);
1184 struct gsm_bts *bts;
1185
Harald Weltee441d9c2009-06-21 16:17:15 +02001186 if (bts_nr > gsmnet->num_bts) {
1187 vty_out(vty, "%% The next unused BTS number is %u%s",
1188 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001189 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001190 } else if (bts_nr == gsmnet->num_bts) {
1191 /* allocate a new one */
1192 bts = gsm_bts_alloc(gsmnet, GSM_BTS_TYPE_UNKNOWN,
1193 HARDCODED_TSC, HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001194 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001195 bts = gsm_bts_num(gsmnet, bts_nr);
1196
Daniel Willmannf15c2762010-01-11 13:43:07 +01001197 if (!bts) {
1198 vty_out(vty, "%% Unable to allocate BTS %u%s",
1199 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001200 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001201 }
Harald Welte5258fc42009-03-28 19:07:53 +00001202
1203 vty->index = bts;
1204 vty->node = BTS_NODE;
1205
1206 return CMD_SUCCESS;
1207}
1208
1209DEFUN(cfg_bts_type,
1210 cfg_bts_type_cmd,
1211 "type TYPE",
1212 "Set the BTS type\n")
1213{
1214 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001215 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001216
Harald Welte39315c42010-01-10 18:01:52 +01001217 rc = gsm_set_bts_type(bts, parse_btstype(argv[0]));
1218 if (rc < 0)
1219 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001220
Harald Welte5258fc42009-03-28 19:07:53 +00001221 return CMD_SUCCESS;
1222}
1223
Harald Weltefcd24452009-06-20 18:15:19 +02001224DEFUN(cfg_bts_band,
1225 cfg_bts_band_cmd,
1226 "band BAND",
1227 "Set the frequency band of this BTS\n")
1228{
1229 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001230 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001231
1232 if (band < 0) {
1233 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1234 band, VTY_NEWLINE);
1235 return CMD_WARNING;
1236 }
1237
1238 bts->band = band;
1239
1240 return CMD_SUCCESS;
1241}
1242
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001243DEFUN(cfg_bts_ci,
1244 cfg_bts_ci_cmd,
1245 "cell_identity <0-65535>",
1246 "Set the Cell identity of this BTS\n")
1247{
1248 struct gsm_bts *bts = vty->index;
1249 int ci = atoi(argv[0]);
1250
1251 if (ci < 0 || ci > 0xffff) {
1252 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1253 ci, VTY_NEWLINE);
1254 return CMD_WARNING;
1255 }
1256 bts->cell_identity = ci;
1257
1258 return CMD_SUCCESS;
1259}
1260
Harald Welte5258fc42009-03-28 19:07:53 +00001261DEFUN(cfg_bts_lac,
1262 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001263 "location_area_code <0-65535>",
Harald Welte5258fc42009-03-28 19:07:53 +00001264 "Set the Location Area Code (LAC) of this BTS\n")
1265{
1266 struct gsm_bts *bts = vty->index;
1267 int lac = atoi(argv[0]);
1268
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001269 if (lac < 0 || lac > 0xffff) {
1270 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001271 lac, VTY_NEWLINE);
1272 return CMD_WARNING;
1273 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001274
1275 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1276 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1277 lac, VTY_NEWLINE);
1278 return CMD_WARNING;
1279 }
1280
Harald Welte5258fc42009-03-28 19:07:53 +00001281 bts->location_area_code = lac;
1282
1283 return CMD_SUCCESS;
1284}
1285
Harald Weltea43f7892009-12-01 18:04:30 +05301286
Harald Welte5258fc42009-03-28 19:07:53 +00001287DEFUN(cfg_bts_tsc,
1288 cfg_bts_tsc_cmd,
1289 "training_sequence_code <0-255>",
1290 "Set the Training Sequence Code (TSC) of this BTS\n")
1291{
1292 struct gsm_bts *bts = vty->index;
1293 int tsc = atoi(argv[0]);
1294
1295 if (tsc < 0 || tsc > 0xff) {
1296 vty_out(vty, "%% TSC %d is not in the valid range (0-255)%s",
1297 tsc, VTY_NEWLINE);
1298 return CMD_WARNING;
1299 }
1300 bts->tsc = tsc;
1301
1302 return CMD_SUCCESS;
1303}
1304
Harald Welte78f2f502009-05-23 16:56:52 +00001305DEFUN(cfg_bts_bsic,
1306 cfg_bts_bsic_cmd,
1307 "base_station_id_code <0-63>",
1308 "Set the Base Station Identity Code (BSIC) of this BTS\n")
1309{
1310 struct gsm_bts *bts = vty->index;
1311 int bsic = atoi(argv[0]);
1312
1313 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001314 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001315 bsic, VTY_NEWLINE);
1316 return CMD_WARNING;
1317 }
1318 bts->bsic = bsic;
1319
1320 return CMD_SUCCESS;
1321}
1322
1323
Harald Welte4cc34222009-05-01 15:12:31 +00001324DEFUN(cfg_bts_unit_id,
1325 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001326 "ip.access unit_id <0-65534> <0-255>",
1327 "Set the ip.access BTS Unit ID of this BTS\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001328{
1329 struct gsm_bts *bts = vty->index;
1330 int site_id = atoi(argv[0]);
1331 int bts_id = atoi(argv[1]);
1332
Harald Welte07dc73d2009-08-07 13:27:09 +02001333 if (!is_ipaccess_bts(bts)) {
1334 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1335 return CMD_WARNING;
1336 }
1337
Harald Welte4cc34222009-05-01 15:12:31 +00001338 bts->ip_access.site_id = site_id;
1339 bts->ip_access.bts_id = bts_id;
1340
1341 return CMD_SUCCESS;
1342}
1343
Harald Welte8f0ed552010-05-11 21:53:49 +02001344#define OML_STR "Organization & Maintenance Link\n"
1345#define IPA_STR "ip.access Specific Options\n"
1346
Harald Welte8175e952009-10-20 00:22:00 +02001347DEFUN(cfg_bts_stream_id,
1348 cfg_bts_stream_id_cmd,
1349 "oml ip.access stream_id <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001350 OML_STR IPA_STR
Harald Welte8175e952009-10-20 00:22:00 +02001351 "Set the ip.access Stream ID of the OML link of this BTS\n")
1352{
1353 struct gsm_bts *bts = vty->index;
1354 int stream_id = atoi(argv[0]);
1355
1356 if (!is_ipaccess_bts(bts)) {
1357 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1358 return CMD_WARNING;
1359 }
1360
1361 bts->oml_tei = stream_id;
1362
1363 return CMD_SUCCESS;
1364}
1365
Harald Welte8f0ed552010-05-11 21:53:49 +02001366#define OML_E1_STR OML_STR "E1 Line\n"
Harald Welte8175e952009-10-20 00:22:00 +02001367
Harald Welte42581822009-08-08 16:12:58 +02001368DEFUN(cfg_bts_oml_e1,
1369 cfg_bts_oml_e1_cmd,
1370 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001371 OML_E1_STR
Harald Welte42581822009-08-08 16:12:58 +02001372 "E1 interface to be used for OML\n")
1373{
1374 struct gsm_bts *bts = vty->index;
1375
1376 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
1377
1378 return CMD_SUCCESS;
1379}
1380
1381
1382DEFUN(cfg_bts_oml_e1_tei,
1383 cfg_bts_oml_e1_tei_cmd,
1384 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001385 OML_E1_STR
Harald Welte42581822009-08-08 16:12:58 +02001386 "Set the TEI to be used for OML")
1387{
1388 struct gsm_bts *bts = vty->index;
1389
1390 bts->oml_tei = atoi(argv[0]);
1391
1392 return CMD_SUCCESS;
1393}
1394
Harald Welte7a8fa412009-08-10 13:48:16 +02001395DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
1396 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001397 "Channnel Allocator\n" "Channel Allocator\n"
1398 "Allocate Timeslots and Transceivers in ascending order\n"
1399 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02001400{
1401 struct gsm_bts *bts = vty->index;
1402
1403 if (!strcmp(argv[0], "ascending"))
1404 bts->chan_alloc_reverse = 0;
1405 else
1406 bts->chan_alloc_reverse = 1;
1407
1408 return CMD_SUCCESS;
1409}
1410
Harald Welte8f0ed552010-05-11 21:53:49 +02001411#define RACH_STR "Random Access Control Channel\n"
1412
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01001413DEFUN(cfg_bts_rach_tx_integer,
1414 cfg_bts_rach_tx_integer_cmd,
1415 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001416 RACH_STR
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01001417 "Set the raw tx integer value in RACH Control parameters IE")
1418{
1419 struct gsm_bts *bts = vty->index;
1420 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
1421 return CMD_SUCCESS;
1422}
1423
1424DEFUN(cfg_bts_rach_max_trans,
1425 cfg_bts_rach_max_trans_cmd,
1426 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001427 RACH_STR
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01001428 "Set the maximum number of RACH burst transmissions")
1429{
1430 struct gsm_bts *bts = vty->index;
1431 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
1432 return CMD_SUCCESS;
1433}
1434
Harald Welte8f0ed552010-05-11 21:53:49 +02001435#define NM_STR "Network Management\n"
1436
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08001437DEFUN(cfg_bts_rach_nm_b_thresh,
1438 cfg_bts_rach_nm_b_thresh_cmd,
1439 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001440 RACH_STR NM_STR
1441 "Set the NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08001442{
1443 struct gsm_bts *bts = vty->index;
1444 bts->rach_b_thresh = atoi(argv[0]);
1445 return CMD_SUCCESS;
1446}
1447
1448DEFUN(cfg_bts_rach_nm_ldavg,
1449 cfg_bts_rach_nm_ldavg_cmd,
1450 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001451 RACH_STR NM_STR
1452 "Set the NM Loadaverage Slots value")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08001453{
1454 struct gsm_bts *bts = vty->index;
1455 bts->rach_ldavg_slots = atoi(argv[0]);
1456 return CMD_SUCCESS;
1457}
1458
Harald Welte (local)5dececf2009-08-12 13:28:23 +02001459DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
1460 "cell barred (0|1)",
1461 "Should this cell be barred from access?")
1462{
1463 struct gsm_bts *bts = vty->index;
1464
Harald Welte71355012009-12-21 23:08:18 +01001465 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02001466
1467 return CMD_SUCCESS;
1468}
1469
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001470DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
1471 "ms max power <0-40>",
1472 "Maximum transmit power of the MS")
1473{
1474 struct gsm_bts *bts = vty->index;
1475
1476 bts->ms_max_power = atoi(argv[0]);
1477
1478 return CMD_SUCCESS;
1479}
1480
Harald Welte73225282009-12-12 18:17:25 +01001481DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
1482 "cell reselection hysteresis <0-14>",
1483 "Cell Re-Selection Hysteresis in dB")
1484{
1485 struct gsm_bts *bts = vty->index;
1486
1487 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
1488
1489 return CMD_SUCCESS;
1490}
1491
1492DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
1493 "rxlev access min <0-63>",
1494 "Minimum RxLev needed for cell access (better than -110dBm)")
1495{
1496 struct gsm_bts *bts = vty->index;
1497
1498 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
1499
1500 return CMD_SUCCESS;
1501}
1502
Harald Welte (local)efc92312009-08-14 23:09:25 +02001503DEFUN(cfg_bts_per_loc_upd, cfg_bts_per_loc_upd_cmd,
1504 "periodic location update <0-1530>",
1505 "Periodic Location Updating Interval in Minutes")
1506{
1507 struct gsm_bts *bts = vty->index;
1508
Harald Weltea43f7892009-12-01 18:04:30 +05301509 bts->si_common.chan_desc.t3212 = atoi(argv[0]) / 10;
Harald Welte (local)efc92312009-08-14 23:09:25 +02001510
1511 return CMD_SUCCESS;
1512}
1513
Harald Welte8f0ed552010-05-11 21:53:49 +02001514#define GPRS_TEXT "GPRS Packet Network\n"
1515
Harald Welteaf387632010-03-14 23:30:30 +08001516DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02001517 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001518 GPRS_TEXT
1519 "GPRS Cell Settings\n"
Harald Welte97a282b2010-03-14 15:37:43 +08001520 "GPRS BSSGP VC Identifier")
1521{
1522 struct gsm_bts *bts = vty->index;
1523
Harald Welte4511d892010-04-18 15:51:20 +02001524 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08001525 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1526 return CMD_WARNING;
1527 }
1528
Harald Welte97a282b2010-03-14 15:37:43 +08001529 bts->gprs.cell.bvci = atoi(argv[0]);
1530
1531 return CMD_SUCCESS;
1532}
1533
Harald Weltea5731cf2010-03-22 11:48:36 +08001534DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
1535 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001536 GPRS_TEXT
Harald Weltea5731cf2010-03-22 11:48:36 +08001537 "GPRS NS Entity Identifier")
1538{
1539 struct gsm_bts *bts = vty->index;
1540
Harald Welte4511d892010-04-18 15:51:20 +02001541 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08001542 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1543 return CMD_WARNING;
1544 }
1545
1546 bts->gprs.nse.nsei = atoi(argv[0]);
1547
1548 return CMD_SUCCESS;
1549}
1550
Harald Welte8f0ed552010-05-11 21:53:49 +02001551#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
1552 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08001553
Harald Welte97a282b2010-03-14 15:37:43 +08001554DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
1555 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001556 GPRS_TEXT NSVC_TEXT
1557 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08001558 "GPRS NS VC Identifier")
1559{
1560 struct gsm_bts *bts = vty->index;
1561 int idx = atoi(argv[0]);
1562
Harald Welte4511d892010-04-18 15:51:20 +02001563 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08001564 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1565 return CMD_WARNING;
1566 }
1567
Harald Welte97a282b2010-03-14 15:37:43 +08001568 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
1569
1570 return CMD_SUCCESS;
1571}
1572
Harald Welteaf387632010-03-14 23:30:30 +08001573DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
1574 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001575 GPRS_TEXT NSVC_TEXT
Harald Welteaf387632010-03-14 23:30:30 +08001576 "GPRS NS Local UDP Port")
1577{
1578 struct gsm_bts *bts = vty->index;
1579 int idx = atoi(argv[0]);
1580
Harald Welte4511d892010-04-18 15:51:20 +02001581 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08001582 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1583 return CMD_WARNING;
1584 }
1585
Harald Welteaf387632010-03-14 23:30:30 +08001586 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
1587
1588 return CMD_SUCCESS;
1589}
1590
1591DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
1592 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001593 GPRS_TEXT NSVC_TEXT
Harald Welteaf387632010-03-14 23:30:30 +08001594 "GPRS NS Remote UDP Port")
1595{
1596 struct gsm_bts *bts = vty->index;
1597 int idx = atoi(argv[0]);
1598
Harald Welte4511d892010-04-18 15:51:20 +02001599 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08001600 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1601 return CMD_WARNING;
1602 }
1603
Harald Welteaf387632010-03-14 23:30:30 +08001604 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
1605
1606 return CMD_SUCCESS;
1607}
1608
1609DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
1610 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02001611 GPRS_TEXT NSVC_TEXT
Harald Welteaf387632010-03-14 23:30:30 +08001612 "GPRS NS Remote IP Address")
1613{
1614 struct gsm_bts *bts = vty->index;
1615 int idx = atoi(argv[0]);
1616 struct in_addr ia;
1617
Harald Welte4511d892010-04-18 15:51:20 +02001618 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08001619 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1620 return CMD_WARNING;
1621 }
1622
Harald Welteaf387632010-03-14 23:30:30 +08001623 inet_aton(argv[1], &ia);
1624 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
1625
1626 return CMD_SUCCESS;
1627}
1628
Harald Welte615e9562010-05-11 23:50:21 +02001629#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)"
1630#define NS_TIMERS_HELP \
1631 "(un)blocking Timer (Tns-block) timeout\n" \
1632 "(un)blocking Timer (Tns-block) number of retries\n" \
1633 "Reset Timer (Tns-reset) timeout\n" \
1634 "Reset Timer (Tns-reset) number of retries\n" \
1635 "Test Timer (Tns-test) timeout\n" \
1636
1637DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
1638 "gprs ns timer " NS_TIMERS " <0-255>",
1639 GPRS_TEXT "Network Service\n"
1640 "Network Service Timer\n"
1641 NS_TIMERS_HELP "Timer Value\n")
1642{
1643 struct gsm_bts *bts = vty->index;
1644 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
1645 int val = atoi(argv[1]);
1646
1647 if (bts->gprs.mode == BTS_GPRS_NONE) {
1648 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1649 return CMD_WARNING;
1650 }
1651
1652 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
1653 return CMD_WARNING;
1654
1655 bts->gprs.nse.timer[idx] = val;
1656
1657 return CMD_SUCCESS;
1658}
1659
1660#define BSSGP_TIMERS "(blocking-timer|blocking-retries|unblocking-retries|reset-timer|reset-retries|suspend-timer|suspend-retries|resume-timer|resume-retries|capability-update-timer|capability-update-retries)"
1661#define BSSGP_TIMERS_HELP ""
1662
1663DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
1664 "gprs cell timer " BSSGP_TIMERS " <0-255>",
1665 GPRS_TEXT "Cell / BSSGP\n"
1666 "Cell/BSSGP Timer\n"
1667 BSSGP_TIMERS_HELP "Timer Value\n")
1668{
1669 struct gsm_bts *bts = vty->index;
1670 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
1671 int val = atoi(argv[1]);
1672
1673 if (bts->gprs.mode == BTS_GPRS_NONE) {
1674 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1675 return CMD_WARNING;
1676 }
1677
1678 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
1679 return CMD_WARNING;
1680
1681 bts->gprs.cell.timer[idx] = val;
1682
1683 return CMD_SUCCESS;
1684}
1685
Harald Welte97a282b2010-03-14 15:37:43 +08001686DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
1687 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001688 GPRS_TEXT
Harald Welte97a282b2010-03-14 15:37:43 +08001689 "GPRS Routing Area Code")
1690{
1691 struct gsm_bts *bts = vty->index;
1692
Harald Welte4511d892010-04-18 15:51:20 +02001693 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08001694 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1695 return CMD_WARNING;
1696 }
1697
Harald Welte97a282b2010-03-14 15:37:43 +08001698 bts->gprs.rac = atoi(argv[0]);
1699
1700 return CMD_SUCCESS;
1701}
1702
Harald Welte4511d892010-04-18 15:51:20 +02001703DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
1704 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001705 GPRS_TEXT
1706 "GPRS Mode for this BTS\n"
1707 "GPRS Disabled on this BTS\n"
1708 "GPRS Enabled on this BTS\n"
1709 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08001710{
1711 struct gsm_bts *bts = vty->index;
1712
Harald Welte4511d892010-04-18 15:51:20 +02001713 bts->gprs.mode = bts_gprs_mode_parse(argv[0]);
Harald Welteaf387632010-03-14 23:30:30 +08001714
1715 return CMD_SUCCESS;
1716}
1717
Harald Welte8f0ed552010-05-11 21:53:49 +02001718#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02001719
Harald Welte5258fc42009-03-28 19:07:53 +00001720/* per TRX configuration */
1721DEFUN(cfg_trx,
1722 cfg_trx_cmd,
1723 "trx TRX_NR",
Harald Welte8f0ed552010-05-11 21:53:49 +02001724 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00001725 "Select a TRX to configure")
1726{
1727 int trx_nr = atoi(argv[0]);
1728 struct gsm_bts *bts = vty->index;
1729 struct gsm_bts_trx *trx;
1730
Harald Weltee441d9c2009-06-21 16:17:15 +02001731 if (trx_nr > bts->num_trx) {
1732 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
1733 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001734 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001735 } else if (trx_nr == bts->num_trx) {
1736 /* we need to allocate a new one */
1737 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001738 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001739 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001740
Harald Weltee441d9c2009-06-21 16:17:15 +02001741 if (!trx)
1742 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00001743
1744 vty->index = trx;
1745 vty->node = TRX_NODE;
1746
1747 return CMD_SUCCESS;
1748}
1749
1750DEFUN(cfg_trx_arfcn,
1751 cfg_trx_arfcn_cmd,
1752 "arfcn <1-1024>",
1753 "Set the ARFCN for this TRX\n")
1754{
1755 int arfcn = atoi(argv[0]);
1756 struct gsm_bts_trx *trx = vty->index;
1757
1758 /* FIXME: check if this ARFCN is supported by this TRX */
1759
1760 trx->arfcn = arfcn;
1761
1762 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
1763 /* FIXME: use OML layer to update the ARFCN */
1764 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
1765
1766 return CMD_SUCCESS;
1767}
1768
Harald Welte (local)7b37d972009-12-27 20:56:38 +01001769DEFUN(cfg_trx_nominal_power,
1770 cfg_trx_nominal_power_cmd,
1771 "nominal power <0-100>",
1772 "Nominal TRX RF Power in dB\n")
1773{
1774 struct gsm_bts_trx *trx = vty->index;
1775
1776 trx->nominal_power = atoi(argv[0]);
1777
1778 return CMD_SUCCESS;
1779}
1780
Harald Weltefcd24452009-06-20 18:15:19 +02001781DEFUN(cfg_trx_max_power_red,
1782 cfg_trx_max_power_red_cmd,
1783 "max_power_red <0-100>",
1784 "Reduction of maximum BS RF Power in dB\n")
1785{
1786 int maxpwr_r = atoi(argv[0]);
1787 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01001788 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02001789
1790 /* FIXME: check if our BTS type supports more than 12 */
1791 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
1792 vty_out(vty, "%% Power %d dB is not in the valid range%s",
1793 maxpwr_r, VTY_NEWLINE);
1794 return CMD_WARNING;
1795 }
1796 if (maxpwr_r & 1) {
1797 vty_out(vty, "%% Power %d dB is not an even value%s",
1798 maxpwr_r, VTY_NEWLINE);
1799 return CMD_WARNING;
1800 }
1801
1802 trx->max_power_red = maxpwr_r;
1803
1804 /* FIXME: make sure we update this using OML */
1805
1806 return CMD_SUCCESS;
1807}
1808
Harald Welte42581822009-08-08 16:12:58 +02001809DEFUN(cfg_trx_rsl_e1,
1810 cfg_trx_rsl_e1_cmd,
1811 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
1812 "E1 interface to be used for RSL\n")
1813{
1814 struct gsm_bts_trx *trx = vty->index;
1815
1816 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
1817
1818 return CMD_SUCCESS;
1819}
1820
1821DEFUN(cfg_trx_rsl_e1_tei,
1822 cfg_trx_rsl_e1_tei_cmd,
1823 "rsl e1 tei <0-63>",
1824 "Set the TEI to be used for RSL")
1825{
1826 struct gsm_bts_trx *trx = vty->index;
1827
1828 trx->rsl_tei = atoi(argv[0]);
1829
1830 return CMD_SUCCESS;
1831}
1832
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01001833DEFUN(cfg_trx_rf_locked,
1834 cfg_trx_rf_locked_cmd,
1835 "rf_locked (0|1)",
1836 "Turn off RF of the TRX.\n")
1837{
1838 int locked = atoi(argv[0]);
1839 struct gsm_bts_trx *trx = vty->index;
1840
1841 gsm_trx_lock_rf(trx, locked);
1842 return CMD_SUCCESS;
1843}
Harald Welte42581822009-08-08 16:12:58 +02001844
Harald Welte5258fc42009-03-28 19:07:53 +00001845/* per TS configuration */
1846DEFUN(cfg_ts,
1847 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02001848 "timeslot <0-7>",
Harald Welte5258fc42009-03-28 19:07:53 +00001849 "Select a Timeslot to configure")
1850{
1851 int ts_nr = atoi(argv[0]);
1852 struct gsm_bts_trx *trx = vty->index;
1853 struct gsm_bts_trx_ts *ts;
1854
1855 if (ts_nr >= TRX_NR_TS) {
1856 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
1857 TRX_NR_TS, VTY_NEWLINE);
1858 return CMD_WARNING;
1859 }
1860
1861 ts = &trx->ts[ts_nr];
1862
1863 vty->index = ts;
1864 vty->node = TS_NODE;
1865
1866 return CMD_SUCCESS;
1867}
1868
Harald Weltea6fd58e2009-08-07 00:25:23 +02001869DEFUN(cfg_ts_pchan,
1870 cfg_ts_pchan_cmd,
1871 "phys_chan_config PCHAN",
1872 "Physical Channel configuration (TCH/SDCCH/...)")
1873{
1874 struct gsm_bts_trx_ts *ts = vty->index;
1875 int pchanc;
1876
1877 pchanc = gsm_pchan_parse(argv[0]);
1878 if (pchanc < 0)
1879 return CMD_WARNING;
1880
1881 ts->pchan = pchanc;
1882
1883 return CMD_SUCCESS;
1884}
1885
1886DEFUN(cfg_ts_e1_subslot,
1887 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02001888 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltea6fd58e2009-08-07 00:25:23 +02001889 "E1 sub-slot connected to this on-air timeslot")
1890{
1891 struct gsm_bts_trx_ts *ts = vty->index;
1892
Harald Welte42581822009-08-08 16:12:58 +02001893 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02001894
1895 return CMD_SUCCESS;
1896}
Harald Welte5258fc42009-03-28 19:07:53 +00001897
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02001898extern int bsc_vty_init_extra(struct gsm_network *net);
1899
Harald Welte68628e82009-03-10 12:17:57 +00001900int bsc_vty_init(struct gsm_network *net)
1901{
1902 gsmnet = net;
1903
1904 cmd_init(1);
1905 vty_init();
1906
Harald Welteb4d5b172010-05-12 16:10:35 +00001907 install_element_ve(&show_net_cmd);
1908 install_element_ve(&show_bts_cmd);
1909 install_element_ve(&show_trx_cmd);
1910 install_element_ve(&show_ts_cmd);
1911 install_element_ve(&show_lchan_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00001912
Harald Welteb4d5b172010-05-12 16:10:35 +00001913 install_element_ve(&show_e1drv_cmd);
1914 install_element_ve(&show_e1line_cmd);
1915 install_element_ve(&show_e1ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00001916
Harald Welteb4d5b172010-05-12 16:10:35 +00001917 install_element_ve(&show_paging_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00001918
Holger Hans Peter Freyther3c712322010-04-06 11:55:37 +02001919 openbsc_vty_add_cmds();
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01001920
Harald Welte5013b2a2009-08-07 13:29:14 +02001921 install_element(CONFIG_NODE, &cfg_net_cmd);
1922 install_node(&net_node, config_write_net);
1923 install_default(GSMNET_NODE);
Harald Welte42581822009-08-08 16:12:58 +02001924 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02001925 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1926 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1927 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
Harald Welte (local)69de3972009-08-12 14:42:23 +02001928 install_element(GSMNET_NODE, &cfg_net_auth_policy_cmd);
Harald Welte1085c092009-11-18 20:33:19 +01001929 install_element(GSMNET_NODE, &cfg_net_reject_cause_cmd);
Harald Welte4381cfe2009-08-30 15:47:06 +09001930 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001931 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Welteeab84a12009-12-13 10:53:12 +01001932 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
Harald Welte3d23db42009-12-14 17:49:15 +01001933 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
Harald Weltebc814502009-12-19 21:41:52 +01001934 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Welteb720bd32009-12-21 16:51:50 +01001935 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
1936 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
1937 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
1938 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
1939 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
1940 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001941 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01001942 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
1943 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
1944 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
1945 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
1946 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
1947 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
1948 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
1949 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
1950 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
1951 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02001952
1953 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02001954 install_node(&bts_node, config_write_bts);
Harald Welte68628e82009-03-10 12:17:57 +00001955 install_default(BTS_NODE);
Harald Welte5258fc42009-03-28 19:07:53 +00001956 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02001957 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001958 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00001959 install_element(BTS_NODE, &cfg_bts_lac_cmd);
1960 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02001961 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00001962 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02001963 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02001964 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
1965 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02001966 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01001967 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
1968 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08001969 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
1970 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02001971 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02001972 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte (local)efc92312009-08-14 23:09:25 +02001973 install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd);
Harald Welte73225282009-12-12 18:17:25 +01001974 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
1975 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02001976 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02001977 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08001978 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
1979 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02001980 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08001981 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08001982 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08001983 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
1984 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
1985 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00001986
Harald Welte5258fc42009-03-28 19:07:53 +00001987 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00001988 install_node(&trx_node, dummy_config_write);
Harald Welte68628e82009-03-10 12:17:57 +00001989 install_default(TRX_NODE);
Harald Welte5258fc42009-03-28 19:07:53 +00001990 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01001991 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02001992 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02001993 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
1994 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01001995 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00001996
Harald Welte5258fc42009-03-28 19:07:53 +00001997 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00001998 install_node(&ts_node, dummy_config_write);
Harald Welte68628e82009-03-10 12:17:57 +00001999 install_default(TS_NODE);
Harald Weltea6fd58e2009-08-07 00:25:23 +02002000 install_element(TS_NODE, &cfg_ts_pchan_cmd);
2001 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00002002
Holger Hans Peter Freythercfa90d42009-08-10 10:17:50 +02002003 bsc_vty_init_extra(net);
Harald Welte40f82892009-05-23 17:31:39 +00002004
Harald Welte68628e82009-03-10 12:17:57 +00002005 return 0;
2006}