blob: 248e68eb5f58bd3c74458cb23ed597f97dbd45af [file] [log] [blame]
Harald Welte59b04682009-06-10 05:40:52 +08001/* OpenBSC interface to quagga VTY */
2/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
3 * 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 Welte684b9752009-08-09 15:13:54 +020026#include <vty/buffer.h>
Harald Welte59b04682009-06-10 05:40:52 +080027#include <vty/vty.h>
28
29#include <arpa/inet.h>
30
31#include <openbsc/linuxlist.h>
32#include <openbsc/gsm_data.h>
Harald Welte59b04682009-06-10 05:40:52 +080033#include <openbsc/e1_input.h>
34#include <openbsc/abis_nm.h>
Harald Welte684b9752009-08-09 15:13:54 +020035#include <openbsc/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080036#include <openbsc/db.h>
Harald Weltee87eb462009-08-07 13:29:14 +020037#include <openbsc/talloc.h>
Harald Welte59b04682009-06-10 05:40:52 +080038
39static struct gsm_network *gsmnet;
40
Harald Weltee87eb462009-08-07 13:29:14 +020041struct cmd_node net_node = {
42 GSMNET_NODE,
43 "%s(network)#",
44 1,
45};
46
Harald Welte59b04682009-06-10 05:40:52 +080047struct cmd_node bts_node = {
48 BTS_NODE,
49 "%s(bts)#",
50 1,
51};
52
53struct cmd_node trx_node = {
54 TRX_NODE,
55 "%s(trx)#",
56 1,
57};
58
59struct cmd_node ts_node = {
60 TS_NODE,
61 "%s(ts)#",
62 1,
63};
64
Harald Welte59b04682009-06-10 05:40:52 +080065static int dummy_config_write(struct vty *v)
66{
67 return CMD_SUCCESS;
68}
69
70static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
71{
72 vty_out(vty,"Oper '%s', Admin %u, Avail '%s'%s",
73 nm_opstate_name(nms->operational), nms->administrative,
74 nm_avail_name(nms->availability), VTY_NEWLINE);
75}
76
77static void net_dump_vty(struct vty *vty, struct gsm_network *net)
78{
79 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
80 "and has %u BTS%s", net->country_code, net->network_code,
81 net->num_bts, VTY_NEWLINE);
82 vty_out(vty, " Long network name: '%s'%s",
83 net->name_long, VTY_NEWLINE);
84 vty_out(vty, " Short network name: '%s'%s",
85 net->name_short, VTY_NEWLINE);
Harald Welte (local)a59a27e2009-08-12 14:42:23 +020086 vty_out(vty, " Authentication policy: %s%s",
87 gsm_auth_policy_name(net->auth_policy), VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +080088}
89
90DEFUN(show_net, show_net_cmd, "show network",
91 SHOW_STR "Display information about a GSM NETWORK\n")
92{
93 struct gsm_network *net = gsmnet;
94 net_dump_vty(vty, net);
95
96 return CMD_SUCCESS;
97}
98
99static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
100{
101 struct e1inp_line *line;
102
103 if (!e1l) {
104 vty_out(vty, " None%s", VTY_NEWLINE);
105 return;
106 }
107
108 line = e1l->ts->line;
109
110 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
111 line->num, line->driver->name, e1l->ts->num,
112 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
113 vty_out(vty, " E1 TEI %u, SAPI %u%s",
114 e1l->tei, e1l->sapi, VTY_NEWLINE);
115}
116
117static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
118{
Harald Welte91afe4c2009-06-20 18:15:19 +0200119 vty_out(vty, "BTS %u is of %s type in band %s, has LAC %u, "
120 "BSIC %u, TSC %u and %u TRX%s",
121 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
122 bts->location_area_code, bts->bsic, bts->tsc,
123 bts->num_trx, VTY_NEWLINE);
Harald Welte (local)e19be3f2009-08-12 13:28:23 +0200124 if (bts->cell_barred)
125 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800126 if (is_ipaccess_bts(bts))
127 vty_out(vty, " Unit ID: %u/%u/0%s",
128 bts->ip_access.site_id, bts->ip_access.bts_id,
129 VTY_NEWLINE);
130 vty_out(vty, " NM State: ");
131 net_dump_nmstate(vty, &bts->nm_state);
132 vty_out(vty, " Site Mgr NM State: ");
133 net_dump_nmstate(vty, &bts->site_mgr.nm_state);
134 vty_out(vty, " Paging: FIXME pending requests, %u free slots%s",
135 bts->paging.available_slots, VTY_NEWLINE);
136 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
137 e1isl_dump_vty(vty, bts->oml_link);
138 /* FIXME: oml_link, chan_desc */
139}
140
141DEFUN(show_bts, show_bts_cmd, "show bts [number]",
142 SHOW_STR "Display information about a BTS\n"
143 "BTS number")
144{
145 struct gsm_network *net = gsmnet;
146 int bts_nr;
147
148 if (argc != 0) {
149 /* use the BTS number that the user has specified */
150 bts_nr = atoi(argv[0]);
151 if (bts_nr > net->num_bts) {
152 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
153 VTY_NEWLINE);
154 return CMD_WARNING;
155 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200156 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte59b04682009-06-10 05:40:52 +0800157 return CMD_SUCCESS;
158 }
159 /* print all BTS's */
160 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee712a5f2009-06-21 16:17:15 +0200161 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte59b04682009-06-10 05:40:52 +0800162
163 return CMD_SUCCESS;
164}
165
Harald Welte62868882009-08-08 16:12:58 +0200166/* utility functions */
167static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
168 const char *ts, const char *ss)
169{
170 e1_link->e1_nr = atoi(line);
171 e1_link->e1_ts = atoi(ts);
172 if (!strcmp(ss, "full"))
173 e1_link->e1_ts_ss = 255;
174 else
175 e1_link->e1_ts_ss = atoi(ss);
176}
177
178static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
179 const char *prefix)
180{
181 if (!e1_link->e1_ts)
182 return;
183
184 if (e1_link->e1_ts_ss == 255)
185 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
186 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
187 else
188 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
189 prefix, e1_link->e1_nr, e1_link->e1_ts,
190 e1_link->e1_ts_ss, VTY_NEWLINE);
191}
192
193
Harald Welte97ceef92009-08-06 19:06:46 +0200194static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
195{
Harald Welte62868882009-08-08 16:12:58 +0200196 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
197 if (ts->pchan != GSM_PCHAN_NONE)
198 vty_out(vty, " phys_chan_config %s%s",
199 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
200 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welte97ceef92009-08-06 19:06:46 +0200201}
202
203static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
204{
205 int i;
206
Harald Weltee87eb462009-08-07 13:29:14 +0200207 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
208 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
209 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200210 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
211 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte97ceef92009-08-06 19:06:46 +0200212
213 for (i = 0; i < TRX_NR_TS; i++)
214 config_write_ts_single(vty, &trx->ts[i]);
215}
216
217static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
218{
219 struct gsm_bts_trx *trx;
220
Harald Weltee87eb462009-08-07 13:29:14 +0200221 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
222 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
223 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
224 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte97ceef92009-08-06 19:06:46 +0200225 VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200226 vty_out(vty, " training_sequence_code %u%s", bts->tsc, VTY_NEWLINE);
227 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)cbd46102009-08-13 10:14:26 +0200228 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +0200229 if (bts->chan_desc.t3212)
230 vty_out(vty, " periodic location update %u%s",
231 bts->chan_desc.t3212 * 10, VTY_NEWLINE);
Harald Welte3e774612009-08-10 13:48:16 +0200232 vty_out(vty, " channel allocator %s%s",
233 bts->chan_alloc_reverse ? "descending" : "ascending",
234 VTY_NEWLINE);
Harald Welte (local)e19be3f2009-08-12 13:28:23 +0200235 if (bts->cell_barred)
236 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Harald Welte3ffe1b32009-08-07 00:25:23 +0200237 if (is_ipaccess_bts(bts))
Harald Weltee87eb462009-08-07 13:29:14 +0200238 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Welte3ffe1b32009-08-07 00:25:23 +0200239 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200240 else {
241 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
242 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
243 }
Harald Welte97ceef92009-08-06 19:06:46 +0200244
245 llist_for_each_entry(trx, &bts->trx_list, list)
246 config_write_trx_single(vty, trx);
247}
248
249static int config_write_bts(struct vty *v)
250{
251 struct gsm_bts *bts;
252
253 llist_for_each_entry(bts, &gsmnet->bts_list, list)
254 config_write_bts_single(v, bts);
255
256 return CMD_SUCCESS;
257}
258
Harald Weltee87eb462009-08-07 13:29:14 +0200259static int config_write_net(struct vty *vty)
260{
261 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200262 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200263 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200264 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
265 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
Harald Welte (local)a59a27e2009-08-12 14:42:23 +0200266 vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200267
268 return CMD_SUCCESS;
269}
Harald Welte97ceef92009-08-06 19:06:46 +0200270
Harald Welte59b04682009-06-10 05:40:52 +0800271static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
272{
273 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
274 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte91afe4c2009-06-20 18:15:19 +0200275 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte62868882009-08-08 16:12:58 +0200276 "resulting BS power: %d dBm%s",
Harald Welte91afe4c2009-06-20 18:15:19 +0200277 trx->nominal_power, trx->max_power_red,
Harald Welte62868882009-08-08 16:12:58 +0200278 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800279 vty_out(vty, " NM State: ");
280 net_dump_nmstate(vty, &trx->nm_state);
281 vty_out(vty, " Baseband Transceiver NM State: ");
282 net_dump_nmstate(vty, &trx->bb_transc.nm_state);
283 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
284 e1isl_dump_vty(vty, trx->rsl_link);
285}
286
287DEFUN(show_trx,
288 show_trx_cmd,
289 "show trx [bts_nr] [trx_nr]",
290 SHOW_STR "Display information about a TRX\n")
291{
292 struct gsm_network *net = gsmnet;
293 struct gsm_bts *bts = NULL;
294 struct gsm_bts_trx *trx;
295 int bts_nr, trx_nr;
296
297 if (argc >= 1) {
298 /* use the BTS number that the user has specified */
299 bts_nr = atoi(argv[0]);
300 if (bts_nr >= net->num_bts) {
301 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
302 VTY_NEWLINE);
303 return CMD_WARNING;
304 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200305 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800306 }
307 if (argc >= 2) {
308 trx_nr = atoi(argv[1]);
309 if (trx_nr >= bts->num_trx) {
310 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
311 VTY_NEWLINE);
312 return CMD_WARNING;
313 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200314 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800315 trx_dump_vty(vty, trx);
316 return CMD_SUCCESS;
317 }
318 if (bts) {
319 /* print all TRX in this BTS */
320 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200321 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800322 trx_dump_vty(vty, trx);
323 }
324 return CMD_SUCCESS;
325 }
326
327 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200328 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800329 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200330 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800331 trx_dump_vty(vty, trx);
332 }
333 }
334
335 return CMD_SUCCESS;
336}
337
Harald Welte97ceef92009-08-06 19:06:46 +0200338
Harald Welte59b04682009-06-10 05:40:52 +0800339static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
340{
341 struct in_addr ia;
342
343 vty_out(vty, "Timeslot %u of TRX %u in BTS %u, phys cfg %s%s",
344 ts->nr, ts->trx->nr, ts->trx->bts->nr,
345 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
346 vty_out(vty, " NM State: ");
347 net_dump_nmstate(vty, &ts->nm_state);
348 if (is_ipaccess_bts(ts->trx->bts)) {
349 ia.s_addr = ts->abis_ip.bound_ip;
Harald Welte8cdeaad2009-07-12 09:50:35 +0200350 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
Harald Welte59b04682009-06-10 05:40:52 +0800351 inet_ntoa(ia), ts->abis_ip.bound_port,
Harald Welte8cdeaad2009-07-12 09:50:35 +0200352 ts->abis_ip.rtp_payload2, ts->abis_ip.conn_id,
Harald Welte59b04682009-06-10 05:40:52 +0800353 VTY_NEWLINE);
354 } else {
355 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
356 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
357 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
358 }
359}
360
361DEFUN(show_ts,
362 show_ts_cmd,
363 "show timeslot [bts_nr] [trx_nr] [ts_nr]",
364 SHOW_STR "Display information about a TS\n")
365{
366 struct gsm_network *net = gsmnet;
367 struct gsm_bts *bts;
368 struct gsm_bts_trx *trx;
369 struct gsm_bts_trx_ts *ts;
370 int bts_nr, trx_nr, ts_nr;
371
372 if (argc >= 1) {
373 /* use the BTS number that the user has specified */
374 bts_nr = atoi(argv[0]);
375 if (bts_nr >= net->num_bts) {
376 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
377 VTY_NEWLINE);
378 return CMD_WARNING;
379 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200380 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800381 }
382 if (argc >= 2) {
383 trx_nr = atoi(argv[1]);
384 if (trx_nr >= bts->num_trx) {
385 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
386 VTY_NEWLINE);
387 return CMD_WARNING;
388 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200389 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800390 }
391 if (argc >= 3) {
392 ts_nr = atoi(argv[2]);
393 if (ts_nr >= TRX_NR_TS) {
394 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
395 VTY_NEWLINE);
396 return CMD_WARNING;
397 }
398 ts = &trx->ts[ts_nr];
399 ts_dump_vty(vty, ts);
400 return CMD_SUCCESS;
401 }
402 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200403 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800404 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200405 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800406 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
407 ts = &trx->ts[ts_nr];
408 ts_dump_vty(vty, ts);
409 }
410 }
411 }
412
413 return CMD_SUCCESS;
414}
415
Holger Hans Peter Freytherbdae6f92009-08-10 10:17:50 +0200416void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr)
Harald Welte59b04682009-06-10 05:40:52 +0800417{
Harald Welte91afe4c2009-06-20 18:15:19 +0200418 vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id,
Harald Welte59b04682009-06-10 05:40:52 +0800419 subscr->authorized, VTY_NEWLINE);
420 if (subscr->name)
421 vty_out(vty, " Name: '%s'%s", subscr->name, VTY_NEWLINE);
422 if (subscr->extension)
423 vty_out(vty, " Extension: %s%s", subscr->extension,
424 VTY_NEWLINE);
425 if (subscr->imsi)
426 vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE);
427 if (subscr->tmsi)
Harald Welte270c06c2009-08-15 03:24:51 +0200428 vty_out(vty, " TMSI: %08X%s", atoi(subscr->tmsi),
429 VTY_NEWLINE);
Harald Welte (local)02d5efa2009-08-14 20:27:16 +0200430 vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800431}
432
433static void lchan_dump_vty(struct vty *vty, struct gsm_lchan *lchan)
434{
435 vty_out(vty, "Lchan %u in Timeslot %u of TRX %u in BTS %u, Type %s%s",
436 lchan->nr, lchan->ts->nr, lchan->ts->trx->nr,
437 lchan->ts->trx->bts->nr, gsm_lchan_name(lchan->type),
438 VTY_NEWLINE);
439 vty_out(vty, " Use Count: %u%s", lchan->use_count, VTY_NEWLINE);
440 vty_out(vty, " BS Power %u, MS Power %u%s", lchan->bs_power,
441 lchan->ms_power, VTY_NEWLINE);
442 if (lchan->subscr) {
443 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
444 subscr_dump_vty(vty, lchan->subscr);
445 } else
446 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
447}
448
Harald Welte03740842009-06-10 23:11:52 +0800449#if 0
450TODO: callref and remote callref of call must be resolved to get gsm_trans object
Harald Welte59b04682009-06-10 05:40:52 +0800451static void call_dump_vty(struct vty *vty, struct gsm_call *call)
452{
453 vty_out(vty, "Call Type %u, State %u, Transaction ID %u%s",
454 call->type, call->state, call->transaction_id, VTY_NEWLINE);
455
456 if (call->local_lchan) {
457 vty_out(vty, "Call Local Channel:%s", VTY_NEWLINE);
458 lchan_dump_vty(vty, call->local_lchan);
459 } else
460 vty_out(vty, "Call has no Local Channel%s", VTY_NEWLINE);
461
462 if (call->remote_lchan) {
463 vty_out(vty, "Call Remote Channel:%s", VTY_NEWLINE);
464 lchan_dump_vty(vty, call->remote_lchan);
465 } else
466 vty_out(vty, "Call has no Remote Channel%s", VTY_NEWLINE);
467
468 if (call->called_subscr) {
469 vty_out(vty, "Called Subscriber:%s", VTY_NEWLINE);
470 subscr_dump_vty(vty, call->called_subscr);
471 } else
472 vty_out(vty, "Call has no Called Subscriber%s", VTY_NEWLINE);
473}
Harald Welte03740842009-06-10 23:11:52 +0800474#endif
Harald Welte59b04682009-06-10 05:40:52 +0800475
476DEFUN(show_lchan,
477 show_lchan_cmd,
478 "show lchan [bts_nr] [trx_nr] [ts_nr] [lchan_nr]",
479 SHOW_STR "Display information about a logical channel\n")
480{
481 struct gsm_network *net = gsmnet;
482 struct gsm_bts *bts;
483 struct gsm_bts_trx *trx;
484 struct gsm_bts_trx_ts *ts;
485 struct gsm_lchan *lchan;
486 int bts_nr, trx_nr, ts_nr, lchan_nr;
487
488 if (argc >= 1) {
489 /* use the BTS number that the user has specified */
490 bts_nr = atoi(argv[0]);
491 if (bts_nr >= net->num_bts) {
492 vty_out(vty, "%% can't find BTS %s%s", argv[0],
493 VTY_NEWLINE);
494 return CMD_WARNING;
495 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200496 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800497 }
498 if (argc >= 2) {
499 trx_nr = atoi(argv[1]);
500 if (trx_nr >= bts->num_trx) {
501 vty_out(vty, "%% can't find TRX %s%s", argv[1],
502 VTY_NEWLINE);
503 return CMD_WARNING;
504 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200505 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800506 }
507 if (argc >= 3) {
508 ts_nr = atoi(argv[2]);
509 if (ts_nr >= TRX_NR_TS) {
510 vty_out(vty, "%% can't find TS %s%s", argv[2],
511 VTY_NEWLINE);
512 return CMD_WARNING;
513 }
514 ts = &trx->ts[ts_nr];
515 }
516 if (argc >= 4) {
517 lchan_nr = atoi(argv[3]);
518 if (lchan_nr >= TS_MAX_LCHAN) {
519 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
520 VTY_NEWLINE);
521 return CMD_WARNING;
522 }
523 lchan = &ts->lchan[lchan_nr];
524 lchan_dump_vty(vty, lchan);
525 return CMD_SUCCESS;
526 }
527 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200528 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800529 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200530 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800531 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
532 ts = &trx->ts[ts_nr];
533 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN;
534 lchan_nr++) {
535 lchan = &ts->lchan[lchan_nr];
536 if (lchan->type == GSM_LCHAN_NONE)
537 continue;
538 lchan_dump_vty(vty, lchan);
539 }
540 }
541 }
542 }
543
544 return CMD_SUCCESS;
545}
546
547static void e1drv_dump_vty(struct vty *vty, struct e1inp_driver *drv)
548{
549 vty_out(vty, "E1 Input Driver %s%s", drv->name, VTY_NEWLINE);
550}
551
552DEFUN(show_e1drv,
553 show_e1drv_cmd,
554 "show e1_driver",
555 SHOW_STR "Display information about available E1 drivers\n")
556{
557 struct e1inp_driver *drv;
558
559 llist_for_each_entry(drv, &e1inp_driver_list, list)
560 e1drv_dump_vty(vty, drv);
561
562 return CMD_SUCCESS;
563}
564
565static void e1line_dump_vty(struct vty *vty, struct e1inp_line *line)
566{
567 vty_out(vty, "E1 Line Number %u, Name %s, Driver %s%s",
568 line->num, line->name ? line->name : "",
569 line->driver->name, VTY_NEWLINE);
570}
571
572DEFUN(show_e1line,
573 show_e1line_cmd,
574 "show e1_line [line_nr]",
575 SHOW_STR "Display information about a E1 line\n")
576{
577 struct e1inp_line *line;
578
579 if (argc >= 1) {
580 int num = atoi(argv[0]);
581 llist_for_each_entry(line, &e1inp_line_list, list) {
582 if (line->num == num) {
583 e1line_dump_vty(vty, line);
584 return CMD_SUCCESS;
585 }
586 }
587 return CMD_WARNING;
588 }
589
590 llist_for_each_entry(line, &e1inp_line_list, list)
591 e1line_dump_vty(vty, line);
592
593 return CMD_SUCCESS;
594}
595
596static void e1ts_dump_vty(struct vty *vty, struct e1inp_ts *ts)
597{
Harald Welte62868882009-08-08 16:12:58 +0200598 if (ts->type == E1INP_TS_TYPE_NONE)
599 return;
Harald Welte59b04682009-06-10 05:40:52 +0800600 vty_out(vty, "E1 Timeslot %2u of Line %u is Type %s%s",
601 ts->num, ts->line->num, e1inp_tstype_name(ts->type),
602 VTY_NEWLINE);
603}
604
605DEFUN(show_e1ts,
606 show_e1ts_cmd,
607 "show e1_timeslot [line_nr] [ts_nr]",
608 SHOW_STR "Display information about a E1 timeslot\n")
609{
610 struct e1inp_line *line;
611 struct e1inp_ts *ts;
612 int ts_nr;
613
614 if (argc == 0) {
615 llist_for_each_entry(line, &e1inp_line_list, list) {
616 for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) {
617 ts = &line->ts[ts_nr];
618 e1ts_dump_vty(vty, ts);
619 }
620 }
621 return CMD_SUCCESS;
622 }
623 if (argc >= 1) {
624 int num = atoi(argv[0]);
625 llist_for_each_entry(line, &e1inp_line_list, list) {
626 if (line->num == num)
627 break;
628 }
629 if (!line || line->num != num) {
630 vty_out(vty, "E1 line %s is invalid%s",
631 argv[0], VTY_NEWLINE);
632 return CMD_WARNING;
633 }
634 }
635 if (argc >= 2) {
636 ts_nr = atoi(argv[1]);
637 if (ts_nr > NUM_E1_TS) {
638 vty_out(vty, "E1 timeslot %s is invalid%s",
639 argv[1], VTY_NEWLINE);
640 return CMD_WARNING;
641 }
642 ts = &line->ts[ts_nr];
643 e1ts_dump_vty(vty, ts);
644 return CMD_SUCCESS;
645 } else {
646 for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) {
647 ts = &line->ts[ts_nr];
648 e1ts_dump_vty(vty, ts);
649 }
650 return CMD_SUCCESS;
651 }
652 return CMD_SUCCESS;
653}
654
655static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
656{
657 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
658 subscr_dump_vty(vty, pag->subscr);
659}
660
661static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
662{
663 struct gsm_paging_request *pag;
664
665 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
666 paging_dump_vty(vty, pag);
667}
668
669DEFUN(show_paging,
670 show_paging_cmd,
671 "show paging [bts_nr]",
672 SHOW_STR "Display information about paging reuqests of a BTS\n")
673{
674 struct gsm_network *net = gsmnet;
675 struct gsm_bts *bts;
676 int bts_nr;
677
678 if (argc >= 1) {
679 /* use the BTS number that the user has specified */
680 bts_nr = atoi(argv[0]);
681 if (bts_nr >= net->num_bts) {
682 vty_out(vty, "%% can't find BTS %s%s", argv[0],
683 VTY_NEWLINE);
684 return CMD_WARNING;
685 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200686 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800687 bts_paging_dump_vty(vty, bts);
688
689 return CMD_SUCCESS;
690 }
691 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200692 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800693 bts_paging_dump_vty(vty, bts);
694 }
695
696 return CMD_SUCCESS;
697}
698
Harald Weltee87eb462009-08-07 13:29:14 +0200699DEFUN(cfg_net,
700 cfg_net_cmd,
701 "network",
702 "Configure the GSM network")
703{
704 vty->index = gsmnet;
705 vty->node = GSMNET_NODE;
706
707 return CMD_SUCCESS;
708}
709
710
711DEFUN(cfg_net_ncc,
712 cfg_net_ncc_cmd,
713 "network country code <1-999>",
714 "Set the GSM network country code")
715{
716 gsmnet->country_code = atoi(argv[0]);
717
718 return CMD_SUCCESS;
719}
720
721DEFUN(cfg_net_mnc,
722 cfg_net_mnc_cmd,
723 "mobile network code <1-999>",
724 "Set the GSM mobile network code")
725{
726 gsmnet->network_code = atoi(argv[0]);
727
728 return CMD_SUCCESS;
729}
730
731DEFUN(cfg_net_name_short,
732 cfg_net_name_short_cmd,
733 "short name NAME",
734 "Set the short GSM network name")
735{
736 if (gsmnet->name_short)
737 talloc_free(gsmnet->name_short);
738
739 gsmnet->name_short = talloc_strdup(gsmnet, argv[0]);
740
741 return CMD_SUCCESS;
742}
743
744DEFUN(cfg_net_name_long,
745 cfg_net_name_long_cmd,
746 "long name NAME",
747 "Set the long GSM network name")
748{
749 if (gsmnet->name_long)
750 talloc_free(gsmnet->name_long);
751
752 gsmnet->name_long = talloc_strdup(gsmnet, argv[0]);
753
754 return CMD_SUCCESS;
755}
Harald Welte59b04682009-06-10 05:40:52 +0800756
Harald Welte (local)a59a27e2009-08-12 14:42:23 +0200757DEFUN(cfg_net_auth_policy,
758 cfg_net_auth_policy_cmd,
759 "auth policy (closed|accept-all|token)",
760 "Set the GSM network authentication policy\n")
761{
762 enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]);
763
764 gsmnet->auth_policy = policy;
765
766 return CMD_SUCCESS;
767}
768
Harald Welte59b04682009-06-10 05:40:52 +0800769/* per-BTS configuration */
770DEFUN(cfg_bts,
771 cfg_bts_cmd,
772 "bts BTS_NR",
773 "Select a BTS to configure\n")
774{
775 int bts_nr = atoi(argv[0]);
776 struct gsm_bts *bts;
777
Harald Weltee712a5f2009-06-21 16:17:15 +0200778 if (bts_nr > gsmnet->num_bts) {
779 vty_out(vty, "%% The next unused BTS number is %u%s",
780 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800781 return CMD_WARNING;
Harald Weltee712a5f2009-06-21 16:17:15 +0200782 } else if (bts_nr == gsmnet->num_bts) {
783 /* allocate a new one */
784 bts = gsm_bts_alloc(gsmnet, GSM_BTS_TYPE_UNKNOWN,
785 HARDCODED_TSC, HARDCODED_BSIC);
786 } else
787 bts = gsm_bts_num(gsmnet, bts_nr);
788
789 if (!bts)
790 return CMD_WARNING;
Harald Welte59b04682009-06-10 05:40:52 +0800791
792 vty->index = bts;
793 vty->node = BTS_NODE;
794
795 return CMD_SUCCESS;
796}
797
798DEFUN(cfg_bts_type,
799 cfg_bts_type_cmd,
800 "type TYPE",
801 "Set the BTS type\n")
802{
803 struct gsm_bts *bts = vty->index;
804
Harald Welte3ffe1b32009-08-07 00:25:23 +0200805 bts->type = parse_btstype(argv[0]);
806
Harald Welte59b04682009-06-10 05:40:52 +0800807 return CMD_SUCCESS;
808}
809
Harald Welte91afe4c2009-06-20 18:15:19 +0200810DEFUN(cfg_bts_band,
811 cfg_bts_band_cmd,
812 "band BAND",
813 "Set the frequency band of this BTS\n")
814{
815 struct gsm_bts *bts = vty->index;
Harald Welte62868882009-08-08 16:12:58 +0200816 int band = gsm_band_parse(argv[0]);
Harald Welte91afe4c2009-06-20 18:15:19 +0200817
818 if (band < 0) {
819 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
820 band, VTY_NEWLINE);
821 return CMD_WARNING;
822 }
823
824 bts->band = band;
825
826 return CMD_SUCCESS;
827}
828
Harald Welte59b04682009-06-10 05:40:52 +0800829DEFUN(cfg_bts_lac,
830 cfg_bts_lac_cmd,
831 "location_area_code <0-255>",
832 "Set the Location Area Code (LAC) of this BTS\n")
833{
834 struct gsm_bts *bts = vty->index;
835 int lac = atoi(argv[0]);
836
837 if (lac < 0 || lac > 0xff) {
838 vty_out(vty, "%% LAC %d is not in the valid range (0-255)%s",
839 lac, VTY_NEWLINE);
840 return CMD_WARNING;
841 }
842 bts->location_area_code = lac;
843
844 return CMD_SUCCESS;
845}
846
847DEFUN(cfg_bts_tsc,
848 cfg_bts_tsc_cmd,
849 "training_sequence_code <0-255>",
850 "Set the Training Sequence Code (TSC) of this BTS\n")
851{
852 struct gsm_bts *bts = vty->index;
853 int tsc = atoi(argv[0]);
854
855 if (tsc < 0 || tsc > 0xff) {
856 vty_out(vty, "%% TSC %d is not in the valid range (0-255)%s",
857 tsc, VTY_NEWLINE);
858 return CMD_WARNING;
859 }
860 bts->tsc = tsc;
861
862 return CMD_SUCCESS;
863}
864
865DEFUN(cfg_bts_bsic,
866 cfg_bts_bsic_cmd,
867 "base_station_id_code <0-63>",
868 "Set the Base Station Identity Code (BSIC) of this BTS\n")
869{
870 struct gsm_bts *bts = vty->index;
871 int bsic = atoi(argv[0]);
872
873 if (bsic < 0 || bsic > 0x3f) {
Harald Welte62868882009-08-08 16:12:58 +0200874 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte59b04682009-06-10 05:40:52 +0800875 bsic, VTY_NEWLINE);
876 return CMD_WARNING;
877 }
878 bts->bsic = bsic;
879
880 return CMD_SUCCESS;
881}
882
883
884DEFUN(cfg_bts_unit_id,
885 cfg_bts_unit_id_cmd,
Harald Weltef515aa02009-08-07 13:27:09 +0200886 "ip.access unit_id <0-65534> <0-255>",
887 "Set the ip.access BTS Unit ID of this BTS\n")
Harald Welte59b04682009-06-10 05:40:52 +0800888{
889 struct gsm_bts *bts = vty->index;
890 int site_id = atoi(argv[0]);
891 int bts_id = atoi(argv[1]);
892
Harald Weltef515aa02009-08-07 13:27:09 +0200893 if (!is_ipaccess_bts(bts)) {
894 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
895 return CMD_WARNING;
896 }
897
Harald Welte59b04682009-06-10 05:40:52 +0800898 bts->ip_access.site_id = site_id;
899 bts->ip_access.bts_id = bts_id;
900
901 return CMD_SUCCESS;
902}
903
Harald Welte62868882009-08-08 16:12:58 +0200904DEFUN(cfg_bts_oml_e1,
905 cfg_bts_oml_e1_cmd,
906 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
907 "E1 interface to be used for OML\n")
908{
909 struct gsm_bts *bts = vty->index;
910
911 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
912
913 return CMD_SUCCESS;
914}
915
916
917DEFUN(cfg_bts_oml_e1_tei,
918 cfg_bts_oml_e1_tei_cmd,
919 "oml e1 tei <0-63>",
920 "Set the TEI to be used for OML")
921{
922 struct gsm_bts *bts = vty->index;
923
924 bts->oml_tei = atoi(argv[0]);
925
926 return CMD_SUCCESS;
927}
928
Harald Welte3e774612009-08-10 13:48:16 +0200929DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
930 "channel allocator (ascending|descending)",
931 "Should the channel allocator allocate in reverse TRX order?")
932{
933 struct gsm_bts *bts = vty->index;
934
935 if (!strcmp(argv[0], "ascending"))
936 bts->chan_alloc_reverse = 0;
937 else
938 bts->chan_alloc_reverse = 1;
939
940 return CMD_SUCCESS;
941}
942
Harald Welte (local)e19be3f2009-08-12 13:28:23 +0200943DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
944 "cell barred (0|1)",
945 "Should this cell be barred from access?")
946{
947 struct gsm_bts *bts = vty->index;
948
949 bts->cell_barred = atoi(argv[0]);
950
951 return CMD_SUCCESS;
952}
953
Harald Welte (local)cbd46102009-08-13 10:14:26 +0200954DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
955 "ms max power <0-40>",
956 "Maximum transmit power of the MS")
957{
958 struct gsm_bts *bts = vty->index;
959
960 bts->ms_max_power = atoi(argv[0]);
961
962 return CMD_SUCCESS;
963}
964
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +0200965DEFUN(cfg_bts_per_loc_upd, cfg_bts_per_loc_upd_cmd,
966 "periodic location update <0-1530>",
967 "Periodic Location Updating Interval in Minutes")
968{
969 struct gsm_bts *bts = vty->index;
970
971 bts->chan_desc.t3212 = atoi(argv[0]) / 10;
972
973 return CMD_SUCCESS;
974}
975
Harald Welte3e774612009-08-10 13:48:16 +0200976
Harald Welte59b04682009-06-10 05:40:52 +0800977/* per TRX configuration */
978DEFUN(cfg_trx,
979 cfg_trx_cmd,
980 "trx TRX_NR",
981 "Select a TRX to configure")
982{
983 int trx_nr = atoi(argv[0]);
984 struct gsm_bts *bts = vty->index;
985 struct gsm_bts_trx *trx;
986
Harald Weltee712a5f2009-06-21 16:17:15 +0200987 if (trx_nr > bts->num_trx) {
988 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
989 bts->num_trx, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800990 return CMD_WARNING;
Harald Weltee712a5f2009-06-21 16:17:15 +0200991 } else if (trx_nr == bts->num_trx) {
992 /* we need to allocate a new one */
993 trx = gsm_bts_trx_alloc(bts);
994 } else
995 trx = gsm_bts_trx_num(bts, trx_nr);
996
997 if (!trx)
998 return CMD_WARNING;
Harald Welte59b04682009-06-10 05:40:52 +0800999
1000 vty->index = trx;
1001 vty->node = TRX_NODE;
1002
1003 return CMD_SUCCESS;
1004}
1005
1006DEFUN(cfg_trx_arfcn,
1007 cfg_trx_arfcn_cmd,
1008 "arfcn <1-1024>",
1009 "Set the ARFCN for this TRX\n")
1010{
1011 int arfcn = atoi(argv[0]);
1012 struct gsm_bts_trx *trx = vty->index;
1013
1014 /* FIXME: check if this ARFCN is supported by this TRX */
1015
1016 trx->arfcn = arfcn;
1017
1018 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
1019 /* FIXME: use OML layer to update the ARFCN */
1020 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
1021
1022 return CMD_SUCCESS;
1023}
1024
Harald Welte91afe4c2009-06-20 18:15:19 +02001025DEFUN(cfg_trx_max_power_red,
1026 cfg_trx_max_power_red_cmd,
1027 "max_power_red <0-100>",
1028 "Reduction of maximum BS RF Power in dB\n")
1029{
1030 int maxpwr_r = atoi(argv[0]);
1031 struct gsm_bts_trx *trx = vty->index;
1032 int upper_limit = 12; /* default 12.21 max power red. */
1033
1034 /* FIXME: check if our BTS type supports more than 12 */
1035 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
1036 vty_out(vty, "%% Power %d dB is not in the valid range%s",
1037 maxpwr_r, VTY_NEWLINE);
1038 return CMD_WARNING;
1039 }
1040 if (maxpwr_r & 1) {
1041 vty_out(vty, "%% Power %d dB is not an even value%s",
1042 maxpwr_r, VTY_NEWLINE);
1043 return CMD_WARNING;
1044 }
1045
1046 trx->max_power_red = maxpwr_r;
1047
1048 /* FIXME: make sure we update this using OML */
1049
1050 return CMD_SUCCESS;
1051}
1052
Harald Welte62868882009-08-08 16:12:58 +02001053DEFUN(cfg_trx_rsl_e1,
1054 cfg_trx_rsl_e1_cmd,
1055 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
1056 "E1 interface to be used for RSL\n")
1057{
1058 struct gsm_bts_trx *trx = vty->index;
1059
1060 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
1061
1062 return CMD_SUCCESS;
1063}
1064
1065DEFUN(cfg_trx_rsl_e1_tei,
1066 cfg_trx_rsl_e1_tei_cmd,
1067 "rsl e1 tei <0-63>",
1068 "Set the TEI to be used for RSL")
1069{
1070 struct gsm_bts_trx *trx = vty->index;
1071
1072 trx->rsl_tei = atoi(argv[0]);
1073
1074 return CMD_SUCCESS;
1075}
1076
1077
Harald Welte59b04682009-06-10 05:40:52 +08001078/* per TS configuration */
1079DEFUN(cfg_ts,
1080 cfg_ts_cmd,
Harald Welte62868882009-08-08 16:12:58 +02001081 "timeslot <0-7>",
Harald Welte59b04682009-06-10 05:40:52 +08001082 "Select a Timeslot to configure")
1083{
1084 int ts_nr = atoi(argv[0]);
1085 struct gsm_bts_trx *trx = vty->index;
1086 struct gsm_bts_trx_ts *ts;
1087
1088 if (ts_nr >= TRX_NR_TS) {
1089 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
1090 TRX_NR_TS, VTY_NEWLINE);
1091 return CMD_WARNING;
1092 }
1093
1094 ts = &trx->ts[ts_nr];
1095
1096 vty->index = ts;
1097 vty->node = TS_NODE;
1098
1099 return CMD_SUCCESS;
1100}
1101
Harald Welte3ffe1b32009-08-07 00:25:23 +02001102DEFUN(cfg_ts_pchan,
1103 cfg_ts_pchan_cmd,
1104 "phys_chan_config PCHAN",
1105 "Physical Channel configuration (TCH/SDCCH/...)")
1106{
1107 struct gsm_bts_trx_ts *ts = vty->index;
1108 int pchanc;
1109
1110 pchanc = gsm_pchan_parse(argv[0]);
1111 if (pchanc < 0)
1112 return CMD_WARNING;
1113
1114 ts->pchan = pchanc;
1115
1116 return CMD_SUCCESS;
1117}
1118
1119DEFUN(cfg_ts_e1_subslot,
1120 cfg_ts_e1_subslot_cmd,
Harald Welte62868882009-08-08 16:12:58 +02001121 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welte3ffe1b32009-08-07 00:25:23 +02001122 "E1 sub-slot connected to this on-air timeslot")
1123{
1124 struct gsm_bts_trx_ts *ts = vty->index;
1125
Harald Welte62868882009-08-08 16:12:58 +02001126 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Welte3ffe1b32009-08-07 00:25:23 +02001127
1128 return CMD_SUCCESS;
1129}
Harald Welte59b04682009-06-10 05:40:52 +08001130
Harald Welte59b04682009-06-10 05:40:52 +08001131int bsc_vty_init(struct gsm_network *net)
1132{
1133 gsmnet = net;
1134
1135 cmd_init(1);
1136 vty_init();
1137
1138 install_element(VIEW_NODE, &show_net_cmd);
1139 install_element(VIEW_NODE, &show_bts_cmd);
1140 install_element(VIEW_NODE, &show_trx_cmd);
1141 install_element(VIEW_NODE, &show_ts_cmd);
1142 install_element(VIEW_NODE, &show_lchan_cmd);
1143
1144 install_element(VIEW_NODE, &show_e1drv_cmd);
1145 install_element(VIEW_NODE, &show_e1line_cmd);
1146 install_element(VIEW_NODE, &show_e1ts_cmd);
1147
1148 install_element(VIEW_NODE, &show_paging_cmd);
1149
Harald Weltee87eb462009-08-07 13:29:14 +02001150 install_element(CONFIG_NODE, &cfg_net_cmd);
1151 install_node(&net_node, config_write_net);
1152 install_default(GSMNET_NODE);
Harald Welte62868882009-08-08 16:12:58 +02001153 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
Harald Weltee87eb462009-08-07 13:29:14 +02001154 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1155 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1156 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
Harald Welte (local)a59a27e2009-08-12 14:42:23 +02001157 install_element(GSMNET_NODE, &cfg_net_auth_policy_cmd);
Harald Weltee87eb462009-08-07 13:29:14 +02001158
1159 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte97ceef92009-08-06 19:06:46 +02001160 install_node(&bts_node, config_write_bts);
Harald Welte59b04682009-06-10 05:40:52 +08001161 install_default(BTS_NODE);
1162 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte91afe4c2009-06-20 18:15:19 +02001163 install_element(BTS_NODE, &cfg_bts_band_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001164 install_element(BTS_NODE, &cfg_bts_lac_cmd);
1165 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte62868882009-08-08 16:12:58 +02001166 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001167 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte62868882009-08-08 16:12:58 +02001168 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
1169 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte3e774612009-08-10 13:48:16 +02001170 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Harald Welte (local)e19be3f2009-08-12 13:28:23 +02001171 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001172 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +02001173 install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd);
Harald Welte3e774612009-08-10 13:48:16 +02001174
Harald Welte59b04682009-06-10 05:40:52 +08001175
1176 install_element(BTS_NODE, &cfg_trx_cmd);
1177 install_node(&trx_node, dummy_config_write);
1178 install_default(TRX_NODE);
1179 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte7f597bc2009-06-20 22:36:12 +02001180 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte62868882009-08-08 16:12:58 +02001181 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
1182 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001183
1184 install_element(TRX_NODE, &cfg_ts_cmd);
1185 install_node(&ts_node, dummy_config_write);
1186 install_default(TS_NODE);
Harald Welte3ffe1b32009-08-07 00:25:23 +02001187 install_element(TS_NODE, &cfg_ts_pchan_cmd);
1188 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001189
Holger Hans Peter Freytherbdae6f92009-08-10 10:17:50 +02001190 bsc_vty_init_extra(net);
Harald Welte59b04682009-06-10 05:40:52 +08001191
1192 return 0;
1193}