blob: 79124d9341c5166c5284f36050f4de753c98b634 [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 Weltecca253a2009-08-30 15:47:06 +090088 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
89 VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +080090}
91
92DEFUN(show_net, show_net_cmd, "show network",
93 SHOW_STR "Display information about a GSM NETWORK\n")
94{
95 struct gsm_network *net = gsmnet;
96 net_dump_vty(vty, net);
97
98 return CMD_SUCCESS;
99}
100
101static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
102{
103 struct e1inp_line *line;
104
105 if (!e1l) {
106 vty_out(vty, " None%s", VTY_NEWLINE);
107 return;
108 }
109
110 line = e1l->ts->line;
111
112 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
113 line->num, line->driver->name, e1l->ts->num,
114 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
115 vty_out(vty, " E1 TEI %u, SAPI %u%s",
116 e1l->tei, e1l->sapi, VTY_NEWLINE);
117}
118
119static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
120{
Holger Hans Peter Freythera098dfb2009-08-21 14:44:12 +0200121 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte91afe4c2009-06-20 18:15:19 +0200122 "BSIC %u, TSC %u and %u TRX%s",
123 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freythera098dfb2009-08-21 14:44:12 +0200124 bts->cell_identity,
Harald Welte91afe4c2009-06-20 18:15:19 +0200125 bts->location_area_code, bts->bsic, bts->tsc,
126 bts->num_trx, VTY_NEWLINE);
Harald Welte (local)e19be3f2009-08-12 13:28:23 +0200127 if (bts->cell_barred)
128 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800129 if (is_ipaccess_bts(bts))
130 vty_out(vty, " Unit ID: %u/%u/0%s",
131 bts->ip_access.site_id, bts->ip_access.bts_id,
132 VTY_NEWLINE);
133 vty_out(vty, " NM State: ");
134 net_dump_nmstate(vty, &bts->nm_state);
135 vty_out(vty, " Site Mgr NM State: ");
136 net_dump_nmstate(vty, &bts->site_mgr.nm_state);
137 vty_out(vty, " Paging: FIXME pending requests, %u free slots%s",
138 bts->paging.available_slots, VTY_NEWLINE);
139 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
140 e1isl_dump_vty(vty, bts->oml_link);
141 /* FIXME: oml_link, chan_desc */
142}
143
144DEFUN(show_bts, show_bts_cmd, "show bts [number]",
145 SHOW_STR "Display information about a BTS\n"
146 "BTS number")
147{
148 struct gsm_network *net = gsmnet;
149 int bts_nr;
150
151 if (argc != 0) {
152 /* use the BTS number that the user has specified */
153 bts_nr = atoi(argv[0]);
154 if (bts_nr > net->num_bts) {
155 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
156 VTY_NEWLINE);
157 return CMD_WARNING;
158 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200159 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte59b04682009-06-10 05:40:52 +0800160 return CMD_SUCCESS;
161 }
162 /* print all BTS's */
163 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee712a5f2009-06-21 16:17:15 +0200164 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte59b04682009-06-10 05:40:52 +0800165
166 return CMD_SUCCESS;
167}
168
Harald Welte62868882009-08-08 16:12:58 +0200169/* utility functions */
170static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
171 const char *ts, const char *ss)
172{
173 e1_link->e1_nr = atoi(line);
174 e1_link->e1_ts = atoi(ts);
175 if (!strcmp(ss, "full"))
176 e1_link->e1_ts_ss = 255;
177 else
178 e1_link->e1_ts_ss = atoi(ss);
179}
180
181static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
182 const char *prefix)
183{
184 if (!e1_link->e1_ts)
185 return;
186
187 if (e1_link->e1_ts_ss == 255)
188 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
189 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
190 else
191 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
192 prefix, e1_link->e1_nr, e1_link->e1_ts,
193 e1_link->e1_ts_ss, VTY_NEWLINE);
194}
195
196
Harald Welte97ceef92009-08-06 19:06:46 +0200197static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
198{
Harald Welte62868882009-08-08 16:12:58 +0200199 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
200 if (ts->pchan != GSM_PCHAN_NONE)
201 vty_out(vty, " phys_chan_config %s%s",
202 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
203 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welte97ceef92009-08-06 19:06:46 +0200204}
205
206static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
207{
208 int i;
209
Harald Weltee87eb462009-08-07 13:29:14 +0200210 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
211 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
212 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200213 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
214 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte97ceef92009-08-06 19:06:46 +0200215
216 for (i = 0; i < TRX_NR_TS; i++)
217 config_write_ts_single(vty, &trx->ts[i]);
218}
219
220static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
221{
222 struct gsm_bts_trx *trx;
223
Harald Weltee87eb462009-08-07 13:29:14 +0200224 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
225 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
226 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freythera098dfb2009-08-21 14:44:12 +0200227 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200228 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte97ceef92009-08-06 19:06:46 +0200229 VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200230 vty_out(vty, " training_sequence_code %u%s", bts->tsc, VTY_NEWLINE);
231 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)cbd46102009-08-13 10:14:26 +0200232 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +0200233 if (bts->chan_desc.t3212)
234 vty_out(vty, " periodic location update %u%s",
235 bts->chan_desc.t3212 * 10, VTY_NEWLINE);
Harald Welte3e774612009-08-10 13:48:16 +0200236 vty_out(vty, " channel allocator %s%s",
237 bts->chan_alloc_reverse ? "descending" : "ascending",
238 VTY_NEWLINE);
Harald Welte (local)e19be3f2009-08-12 13:28:23 +0200239 if (bts->cell_barred)
240 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Harald Welte3ffe1b32009-08-07 00:25:23 +0200241 if (is_ipaccess_bts(bts))
Harald Weltee87eb462009-08-07 13:29:14 +0200242 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Welte3ffe1b32009-08-07 00:25:23 +0200243 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200244 else {
245 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
246 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
247 }
Harald Welte97ceef92009-08-06 19:06:46 +0200248
249 llist_for_each_entry(trx, &bts->trx_list, list)
250 config_write_trx_single(vty, trx);
251}
252
253static int config_write_bts(struct vty *v)
254{
255 struct gsm_bts *bts;
256
257 llist_for_each_entry(bts, &gsmnet->bts_list, list)
258 config_write_bts_single(v, bts);
259
260 return CMD_SUCCESS;
261}
262
Harald Weltee87eb462009-08-07 13:29:14 +0200263static int config_write_net(struct vty *vty)
264{
265 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200266 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200267 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200268 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
269 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
Harald Welte (local)a59a27e2009-08-12 14:42:23 +0200270 vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE);
Harald Weltecca253a2009-08-30 15:47:06 +0900271 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200272
273 return CMD_SUCCESS;
274}
Harald Welte97ceef92009-08-06 19:06:46 +0200275
Harald Welte59b04682009-06-10 05:40:52 +0800276static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
277{
278 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
279 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte91afe4c2009-06-20 18:15:19 +0200280 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte62868882009-08-08 16:12:58 +0200281 "resulting BS power: %d dBm%s",
Harald Welte91afe4c2009-06-20 18:15:19 +0200282 trx->nominal_power, trx->max_power_red,
Harald Welte62868882009-08-08 16:12:58 +0200283 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800284 vty_out(vty, " NM State: ");
285 net_dump_nmstate(vty, &trx->nm_state);
286 vty_out(vty, " Baseband Transceiver NM State: ");
287 net_dump_nmstate(vty, &trx->bb_transc.nm_state);
288 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
289 e1isl_dump_vty(vty, trx->rsl_link);
290}
291
292DEFUN(show_trx,
293 show_trx_cmd,
294 "show trx [bts_nr] [trx_nr]",
295 SHOW_STR "Display information about a TRX\n")
296{
297 struct gsm_network *net = gsmnet;
298 struct gsm_bts *bts = NULL;
299 struct gsm_bts_trx *trx;
300 int bts_nr, trx_nr;
301
302 if (argc >= 1) {
303 /* use the BTS number that the user has specified */
304 bts_nr = atoi(argv[0]);
305 if (bts_nr >= net->num_bts) {
306 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
307 VTY_NEWLINE);
308 return CMD_WARNING;
309 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200310 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800311 }
312 if (argc >= 2) {
313 trx_nr = atoi(argv[1]);
314 if (trx_nr >= bts->num_trx) {
315 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
316 VTY_NEWLINE);
317 return CMD_WARNING;
318 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200319 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800320 trx_dump_vty(vty, trx);
321 return CMD_SUCCESS;
322 }
323 if (bts) {
324 /* print all TRX in this BTS */
325 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200326 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800327 trx_dump_vty(vty, trx);
328 }
329 return CMD_SUCCESS;
330 }
331
332 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200333 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800334 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200335 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800336 trx_dump_vty(vty, trx);
337 }
338 }
339
340 return CMD_SUCCESS;
341}
342
Harald Welte97ceef92009-08-06 19:06:46 +0200343
Harald Welte59b04682009-06-10 05:40:52 +0800344static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
345{
346 struct in_addr ia;
347
348 vty_out(vty, "Timeslot %u of TRX %u in BTS %u, phys cfg %s%s",
349 ts->nr, ts->trx->nr, ts->trx->bts->nr,
350 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
351 vty_out(vty, " NM State: ");
352 net_dump_nmstate(vty, &ts->nm_state);
353 if (is_ipaccess_bts(ts->trx->bts)) {
354 ia.s_addr = ts->abis_ip.bound_ip;
Harald Welte8cdeaad2009-07-12 09:50:35 +0200355 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
Harald Welte59b04682009-06-10 05:40:52 +0800356 inet_ntoa(ia), ts->abis_ip.bound_port,
Harald Welte8cdeaad2009-07-12 09:50:35 +0200357 ts->abis_ip.rtp_payload2, ts->abis_ip.conn_id,
Harald Welte59b04682009-06-10 05:40:52 +0800358 VTY_NEWLINE);
359 } else {
360 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
361 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
362 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
363 }
364}
365
366DEFUN(show_ts,
367 show_ts_cmd,
368 "show timeslot [bts_nr] [trx_nr] [ts_nr]",
369 SHOW_STR "Display information about a TS\n")
370{
371 struct gsm_network *net = gsmnet;
372 struct gsm_bts *bts;
373 struct gsm_bts_trx *trx;
374 struct gsm_bts_trx_ts *ts;
375 int bts_nr, trx_nr, ts_nr;
376
377 if (argc >= 1) {
378 /* use the BTS number that the user has specified */
379 bts_nr = atoi(argv[0]);
380 if (bts_nr >= net->num_bts) {
381 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
382 VTY_NEWLINE);
383 return CMD_WARNING;
384 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200385 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800386 }
387 if (argc >= 2) {
388 trx_nr = atoi(argv[1]);
389 if (trx_nr >= bts->num_trx) {
390 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
391 VTY_NEWLINE);
392 return CMD_WARNING;
393 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200394 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800395 }
396 if (argc >= 3) {
397 ts_nr = atoi(argv[2]);
398 if (ts_nr >= TRX_NR_TS) {
399 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
400 VTY_NEWLINE);
401 return CMD_WARNING;
402 }
403 ts = &trx->ts[ts_nr];
404 ts_dump_vty(vty, ts);
405 return CMD_SUCCESS;
406 }
407 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200408 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800409 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200410 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800411 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
412 ts = &trx->ts[ts_nr];
413 ts_dump_vty(vty, ts);
414 }
415 }
416 }
417
418 return CMD_SUCCESS;
419}
420
Holger Hans Peter Freytherbdae6f92009-08-10 10:17:50 +0200421void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr)
Harald Welte59b04682009-06-10 05:40:52 +0800422{
Harald Welte91afe4c2009-06-20 18:15:19 +0200423 vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id,
Harald Welte59b04682009-06-10 05:40:52 +0800424 subscr->authorized, VTY_NEWLINE);
425 if (subscr->name)
426 vty_out(vty, " Name: '%s'%s", subscr->name, VTY_NEWLINE);
427 if (subscr->extension)
428 vty_out(vty, " Extension: %s%s", subscr->extension,
429 VTY_NEWLINE);
430 if (subscr->imsi)
431 vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE);
Holger Hans Peter Freythercd8bacf2009-08-19 12:53:57 +0200432 if (subscr->tmsi != GSM_RESERVED_TMSI)
433 vty_out(vty, " TMSI: %08X%s", subscr->tmsi,
Harald Welte270c06c2009-08-15 03:24:51 +0200434 VTY_NEWLINE);
Harald Welte (local)02d5efa2009-08-14 20:27:16 +0200435 vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800436}
437
438static void lchan_dump_vty(struct vty *vty, struct gsm_lchan *lchan)
439{
440 vty_out(vty, "Lchan %u in Timeslot %u of TRX %u in BTS %u, Type %s%s",
441 lchan->nr, lchan->ts->nr, lchan->ts->trx->nr,
442 lchan->ts->trx->bts->nr, gsm_lchan_name(lchan->type),
443 VTY_NEWLINE);
444 vty_out(vty, " Use Count: %u%s", lchan->use_count, VTY_NEWLINE);
445 vty_out(vty, " BS Power %u, MS Power %u%s", lchan->bs_power,
446 lchan->ms_power, VTY_NEWLINE);
447 if (lchan->subscr) {
448 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
449 subscr_dump_vty(vty, lchan->subscr);
450 } else
451 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
452}
453
Harald Welte03740842009-06-10 23:11:52 +0800454#if 0
455TODO: callref and remote callref of call must be resolved to get gsm_trans object
Harald Welte59b04682009-06-10 05:40:52 +0800456static void call_dump_vty(struct vty *vty, struct gsm_call *call)
457{
458 vty_out(vty, "Call Type %u, State %u, Transaction ID %u%s",
459 call->type, call->state, call->transaction_id, VTY_NEWLINE);
460
461 if (call->local_lchan) {
462 vty_out(vty, "Call Local Channel:%s", VTY_NEWLINE);
463 lchan_dump_vty(vty, call->local_lchan);
464 } else
465 vty_out(vty, "Call has no Local Channel%s", VTY_NEWLINE);
466
467 if (call->remote_lchan) {
468 vty_out(vty, "Call Remote Channel:%s", VTY_NEWLINE);
469 lchan_dump_vty(vty, call->remote_lchan);
470 } else
471 vty_out(vty, "Call has no Remote Channel%s", VTY_NEWLINE);
472
473 if (call->called_subscr) {
474 vty_out(vty, "Called Subscriber:%s", VTY_NEWLINE);
475 subscr_dump_vty(vty, call->called_subscr);
476 } else
477 vty_out(vty, "Call has no Called Subscriber%s", VTY_NEWLINE);
478}
Harald Welte03740842009-06-10 23:11:52 +0800479#endif
Harald Welte59b04682009-06-10 05:40:52 +0800480
481DEFUN(show_lchan,
482 show_lchan_cmd,
483 "show lchan [bts_nr] [trx_nr] [ts_nr] [lchan_nr]",
484 SHOW_STR "Display information about a logical channel\n")
485{
486 struct gsm_network *net = gsmnet;
487 struct gsm_bts *bts;
488 struct gsm_bts_trx *trx;
489 struct gsm_bts_trx_ts *ts;
490 struct gsm_lchan *lchan;
491 int bts_nr, trx_nr, ts_nr, lchan_nr;
492
493 if (argc >= 1) {
494 /* use the BTS number that the user has specified */
495 bts_nr = atoi(argv[0]);
496 if (bts_nr >= net->num_bts) {
497 vty_out(vty, "%% can't find BTS %s%s", argv[0],
498 VTY_NEWLINE);
499 return CMD_WARNING;
500 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200501 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800502 }
503 if (argc >= 2) {
504 trx_nr = atoi(argv[1]);
505 if (trx_nr >= bts->num_trx) {
506 vty_out(vty, "%% can't find TRX %s%s", argv[1],
507 VTY_NEWLINE);
508 return CMD_WARNING;
509 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200510 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800511 }
512 if (argc >= 3) {
513 ts_nr = atoi(argv[2]);
514 if (ts_nr >= TRX_NR_TS) {
515 vty_out(vty, "%% can't find TS %s%s", argv[2],
516 VTY_NEWLINE);
517 return CMD_WARNING;
518 }
519 ts = &trx->ts[ts_nr];
520 }
521 if (argc >= 4) {
522 lchan_nr = atoi(argv[3]);
523 if (lchan_nr >= TS_MAX_LCHAN) {
524 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
525 VTY_NEWLINE);
526 return CMD_WARNING;
527 }
528 lchan = &ts->lchan[lchan_nr];
529 lchan_dump_vty(vty, lchan);
530 return CMD_SUCCESS;
531 }
532 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200533 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800534 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200535 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800536 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
537 ts = &trx->ts[ts_nr];
538 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN;
539 lchan_nr++) {
540 lchan = &ts->lchan[lchan_nr];
541 if (lchan->type == GSM_LCHAN_NONE)
542 continue;
543 lchan_dump_vty(vty, lchan);
544 }
545 }
546 }
547 }
548
549 return CMD_SUCCESS;
550}
551
552static void e1drv_dump_vty(struct vty *vty, struct e1inp_driver *drv)
553{
554 vty_out(vty, "E1 Input Driver %s%s", drv->name, VTY_NEWLINE);
555}
556
557DEFUN(show_e1drv,
558 show_e1drv_cmd,
559 "show e1_driver",
560 SHOW_STR "Display information about available E1 drivers\n")
561{
562 struct e1inp_driver *drv;
563
564 llist_for_each_entry(drv, &e1inp_driver_list, list)
565 e1drv_dump_vty(vty, drv);
566
567 return CMD_SUCCESS;
568}
569
570static void e1line_dump_vty(struct vty *vty, struct e1inp_line *line)
571{
572 vty_out(vty, "E1 Line Number %u, Name %s, Driver %s%s",
573 line->num, line->name ? line->name : "",
574 line->driver->name, VTY_NEWLINE);
575}
576
577DEFUN(show_e1line,
578 show_e1line_cmd,
579 "show e1_line [line_nr]",
580 SHOW_STR "Display information about a E1 line\n")
581{
582 struct e1inp_line *line;
583
584 if (argc >= 1) {
585 int num = atoi(argv[0]);
586 llist_for_each_entry(line, &e1inp_line_list, list) {
587 if (line->num == num) {
588 e1line_dump_vty(vty, line);
589 return CMD_SUCCESS;
590 }
591 }
592 return CMD_WARNING;
593 }
594
595 llist_for_each_entry(line, &e1inp_line_list, list)
596 e1line_dump_vty(vty, line);
597
598 return CMD_SUCCESS;
599}
600
601static void e1ts_dump_vty(struct vty *vty, struct e1inp_ts *ts)
602{
Harald Welte62868882009-08-08 16:12:58 +0200603 if (ts->type == E1INP_TS_TYPE_NONE)
604 return;
Harald Welte59b04682009-06-10 05:40:52 +0800605 vty_out(vty, "E1 Timeslot %2u of Line %u is Type %s%s",
606 ts->num, ts->line->num, e1inp_tstype_name(ts->type),
607 VTY_NEWLINE);
608}
609
610DEFUN(show_e1ts,
611 show_e1ts_cmd,
612 "show e1_timeslot [line_nr] [ts_nr]",
613 SHOW_STR "Display information about a E1 timeslot\n")
614{
615 struct e1inp_line *line;
616 struct e1inp_ts *ts;
617 int ts_nr;
618
619 if (argc == 0) {
620 llist_for_each_entry(line, &e1inp_line_list, list) {
621 for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) {
622 ts = &line->ts[ts_nr];
623 e1ts_dump_vty(vty, ts);
624 }
625 }
626 return CMD_SUCCESS;
627 }
628 if (argc >= 1) {
629 int num = atoi(argv[0]);
630 llist_for_each_entry(line, &e1inp_line_list, list) {
631 if (line->num == num)
632 break;
633 }
634 if (!line || line->num != num) {
635 vty_out(vty, "E1 line %s is invalid%s",
636 argv[0], VTY_NEWLINE);
637 return CMD_WARNING;
638 }
639 }
640 if (argc >= 2) {
641 ts_nr = atoi(argv[1]);
642 if (ts_nr > NUM_E1_TS) {
643 vty_out(vty, "E1 timeslot %s is invalid%s",
644 argv[1], VTY_NEWLINE);
645 return CMD_WARNING;
646 }
647 ts = &line->ts[ts_nr];
648 e1ts_dump_vty(vty, ts);
649 return CMD_SUCCESS;
650 } else {
651 for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) {
652 ts = &line->ts[ts_nr];
653 e1ts_dump_vty(vty, ts);
654 }
655 return CMD_SUCCESS;
656 }
657 return CMD_SUCCESS;
658}
659
660static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
661{
662 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
663 subscr_dump_vty(vty, pag->subscr);
664}
665
666static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
667{
668 struct gsm_paging_request *pag;
669
670 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
671 paging_dump_vty(vty, pag);
672}
673
674DEFUN(show_paging,
675 show_paging_cmd,
676 "show paging [bts_nr]",
677 SHOW_STR "Display information about paging reuqests of a BTS\n")
678{
679 struct gsm_network *net = gsmnet;
680 struct gsm_bts *bts;
681 int bts_nr;
682
683 if (argc >= 1) {
684 /* use the BTS number that the user has specified */
685 bts_nr = atoi(argv[0]);
686 if (bts_nr >= net->num_bts) {
687 vty_out(vty, "%% can't find BTS %s%s", argv[0],
688 VTY_NEWLINE);
689 return CMD_WARNING;
690 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200691 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800692 bts_paging_dump_vty(vty, bts);
693
694 return CMD_SUCCESS;
695 }
696 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200697 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800698 bts_paging_dump_vty(vty, bts);
699 }
700
701 return CMD_SUCCESS;
702}
703
Harald Weltee87eb462009-08-07 13:29:14 +0200704DEFUN(cfg_net,
705 cfg_net_cmd,
706 "network",
707 "Configure the GSM network")
708{
709 vty->index = gsmnet;
710 vty->node = GSMNET_NODE;
711
712 return CMD_SUCCESS;
713}
714
715
716DEFUN(cfg_net_ncc,
717 cfg_net_ncc_cmd,
718 "network country code <1-999>",
719 "Set the GSM network country code")
720{
721 gsmnet->country_code = atoi(argv[0]);
722
723 return CMD_SUCCESS;
724}
725
726DEFUN(cfg_net_mnc,
727 cfg_net_mnc_cmd,
728 "mobile network code <1-999>",
729 "Set the GSM mobile network code")
730{
731 gsmnet->network_code = atoi(argv[0]);
732
733 return CMD_SUCCESS;
734}
735
736DEFUN(cfg_net_name_short,
737 cfg_net_name_short_cmd,
738 "short name NAME",
739 "Set the short GSM network name")
740{
741 if (gsmnet->name_short)
742 talloc_free(gsmnet->name_short);
743
744 gsmnet->name_short = talloc_strdup(gsmnet, argv[0]);
745
746 return CMD_SUCCESS;
747}
748
749DEFUN(cfg_net_name_long,
750 cfg_net_name_long_cmd,
751 "long name NAME",
752 "Set the long GSM network name")
753{
754 if (gsmnet->name_long)
755 talloc_free(gsmnet->name_long);
756
757 gsmnet->name_long = talloc_strdup(gsmnet, argv[0]);
758
759 return CMD_SUCCESS;
760}
Harald Welte59b04682009-06-10 05:40:52 +0800761
Harald Welte (local)a59a27e2009-08-12 14:42:23 +0200762DEFUN(cfg_net_auth_policy,
763 cfg_net_auth_policy_cmd,
764 "auth policy (closed|accept-all|token)",
765 "Set the GSM network authentication policy\n")
766{
767 enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]);
768
769 gsmnet->auth_policy = policy;
770
771 return CMD_SUCCESS;
772}
773
Harald Weltecca253a2009-08-30 15:47:06 +0900774DEFUN(cfg_net_encryption,
775 cfg_net_encryption_cmd,
776 "encryption a5 (0|1|2)",
777 "Enable or disable encryption (A5) for this network\n")
778{
779 gsmnet->auth_policy = atoi(argv[0]);
780
781 return CMD_SUCCESS;
782}
783
Harald Welte59b04682009-06-10 05:40:52 +0800784/* per-BTS configuration */
785DEFUN(cfg_bts,
786 cfg_bts_cmd,
787 "bts BTS_NR",
788 "Select a BTS to configure\n")
789{
790 int bts_nr = atoi(argv[0]);
791 struct gsm_bts *bts;
792
Harald Weltee712a5f2009-06-21 16:17:15 +0200793 if (bts_nr > gsmnet->num_bts) {
794 vty_out(vty, "%% The next unused BTS number is %u%s",
795 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800796 return CMD_WARNING;
Harald Weltee712a5f2009-06-21 16:17:15 +0200797 } else if (bts_nr == gsmnet->num_bts) {
798 /* allocate a new one */
799 bts = gsm_bts_alloc(gsmnet, GSM_BTS_TYPE_UNKNOWN,
800 HARDCODED_TSC, HARDCODED_BSIC);
801 } else
802 bts = gsm_bts_num(gsmnet, bts_nr);
803
804 if (!bts)
805 return CMD_WARNING;
Harald Welte59b04682009-06-10 05:40:52 +0800806
807 vty->index = bts;
808 vty->node = BTS_NODE;
809
810 return CMD_SUCCESS;
811}
812
813DEFUN(cfg_bts_type,
814 cfg_bts_type_cmd,
815 "type TYPE",
816 "Set the BTS type\n")
817{
818 struct gsm_bts *bts = vty->index;
819
Harald Welte3ffe1b32009-08-07 00:25:23 +0200820 bts->type = parse_btstype(argv[0]);
821
Harald Welte59b04682009-06-10 05:40:52 +0800822 return CMD_SUCCESS;
823}
824
Harald Welte91afe4c2009-06-20 18:15:19 +0200825DEFUN(cfg_bts_band,
826 cfg_bts_band_cmd,
827 "band BAND",
828 "Set the frequency band of this BTS\n")
829{
830 struct gsm_bts *bts = vty->index;
Harald Welte62868882009-08-08 16:12:58 +0200831 int band = gsm_band_parse(argv[0]);
Harald Welte91afe4c2009-06-20 18:15:19 +0200832
833 if (band < 0) {
834 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
835 band, VTY_NEWLINE);
836 return CMD_WARNING;
837 }
838
839 bts->band = band;
840
841 return CMD_SUCCESS;
842}
843
Holger Hans Peter Freythera098dfb2009-08-21 14:44:12 +0200844DEFUN(cfg_bts_ci,
845 cfg_bts_ci_cmd,
846 "cell_identity <0-65535>",
847 "Set the Cell identity of this BTS\n")
848{
849 struct gsm_bts *bts = vty->index;
850 int ci = atoi(argv[0]);
851
852 if (ci < 0 || ci > 0xffff) {
853 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
854 ci, VTY_NEWLINE);
855 return CMD_WARNING;
856 }
857 bts->cell_identity = ci;
858
859 return CMD_SUCCESS;
860}
861
Harald Welte59b04682009-06-10 05:40:52 +0800862DEFUN(cfg_bts_lac,
863 cfg_bts_lac_cmd,
Holger Hans Peter Freyther54a22832009-09-29 14:02:33 +0200864 "location_area_code <0-65535>",
Harald Welte59b04682009-06-10 05:40:52 +0800865 "Set the Location Area Code (LAC) of this BTS\n")
866{
867 struct gsm_bts *bts = vty->index;
868 int lac = atoi(argv[0]);
869
Holger Hans Peter Freyther54a22832009-09-29 14:02:33 +0200870 if (lac < 0 || lac > 0xffff) {
871 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte59b04682009-06-10 05:40:52 +0800872 lac, VTY_NEWLINE);
873 return CMD_WARNING;
874 }
875 bts->location_area_code = lac;
876
877 return CMD_SUCCESS;
878}
879
880DEFUN(cfg_bts_tsc,
881 cfg_bts_tsc_cmd,
882 "training_sequence_code <0-255>",
883 "Set the Training Sequence Code (TSC) of this BTS\n")
884{
885 struct gsm_bts *bts = vty->index;
886 int tsc = atoi(argv[0]);
887
888 if (tsc < 0 || tsc > 0xff) {
889 vty_out(vty, "%% TSC %d is not in the valid range (0-255)%s",
890 tsc, VTY_NEWLINE);
891 return CMD_WARNING;
892 }
893 bts->tsc = tsc;
894
895 return CMD_SUCCESS;
896}
897
898DEFUN(cfg_bts_bsic,
899 cfg_bts_bsic_cmd,
900 "base_station_id_code <0-63>",
901 "Set the Base Station Identity Code (BSIC) of this BTS\n")
902{
903 struct gsm_bts *bts = vty->index;
904 int bsic = atoi(argv[0]);
905
906 if (bsic < 0 || bsic > 0x3f) {
Harald Welte62868882009-08-08 16:12:58 +0200907 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte59b04682009-06-10 05:40:52 +0800908 bsic, VTY_NEWLINE);
909 return CMD_WARNING;
910 }
911 bts->bsic = bsic;
912
913 return CMD_SUCCESS;
914}
915
916
917DEFUN(cfg_bts_unit_id,
918 cfg_bts_unit_id_cmd,
Harald Weltef515aa02009-08-07 13:27:09 +0200919 "ip.access unit_id <0-65534> <0-255>",
920 "Set the ip.access BTS Unit ID of this BTS\n")
Harald Welte59b04682009-06-10 05:40:52 +0800921{
922 struct gsm_bts *bts = vty->index;
923 int site_id = atoi(argv[0]);
924 int bts_id = atoi(argv[1]);
925
Harald Weltef515aa02009-08-07 13:27:09 +0200926 if (!is_ipaccess_bts(bts)) {
927 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
928 return CMD_WARNING;
929 }
930
Harald Welte59b04682009-06-10 05:40:52 +0800931 bts->ip_access.site_id = site_id;
932 bts->ip_access.bts_id = bts_id;
933
934 return CMD_SUCCESS;
935}
936
Harald Welte62868882009-08-08 16:12:58 +0200937DEFUN(cfg_bts_oml_e1,
938 cfg_bts_oml_e1_cmd,
939 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
940 "E1 interface to be used for OML\n")
941{
942 struct gsm_bts *bts = vty->index;
943
944 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
945
946 return CMD_SUCCESS;
947}
948
949
950DEFUN(cfg_bts_oml_e1_tei,
951 cfg_bts_oml_e1_tei_cmd,
952 "oml e1 tei <0-63>",
953 "Set the TEI to be used for OML")
954{
955 struct gsm_bts *bts = vty->index;
956
957 bts->oml_tei = atoi(argv[0]);
958
959 return CMD_SUCCESS;
960}
961
Harald Welte3e774612009-08-10 13:48:16 +0200962DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
963 "channel allocator (ascending|descending)",
964 "Should the channel allocator allocate in reverse TRX order?")
965{
966 struct gsm_bts *bts = vty->index;
967
968 if (!strcmp(argv[0], "ascending"))
969 bts->chan_alloc_reverse = 0;
970 else
971 bts->chan_alloc_reverse = 1;
972
973 return CMD_SUCCESS;
974}
975
Harald Welte (local)e19be3f2009-08-12 13:28:23 +0200976DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
977 "cell barred (0|1)",
978 "Should this cell be barred from access?")
979{
980 struct gsm_bts *bts = vty->index;
981
982 bts->cell_barred = atoi(argv[0]);
983
984 return CMD_SUCCESS;
985}
986
Harald Welte (local)cbd46102009-08-13 10:14:26 +0200987DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
988 "ms max power <0-40>",
989 "Maximum transmit power of the MS")
990{
991 struct gsm_bts *bts = vty->index;
992
993 bts->ms_max_power = atoi(argv[0]);
994
995 return CMD_SUCCESS;
996}
997
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +0200998DEFUN(cfg_bts_per_loc_upd, cfg_bts_per_loc_upd_cmd,
999 "periodic location update <0-1530>",
1000 "Periodic Location Updating Interval in Minutes")
1001{
1002 struct gsm_bts *bts = vty->index;
1003
1004 bts->chan_desc.t3212 = atoi(argv[0]) / 10;
1005
1006 return CMD_SUCCESS;
1007}
1008
Harald Welte3e774612009-08-10 13:48:16 +02001009
Harald Welte59b04682009-06-10 05:40:52 +08001010/* per TRX configuration */
1011DEFUN(cfg_trx,
1012 cfg_trx_cmd,
1013 "trx TRX_NR",
1014 "Select a TRX to configure")
1015{
1016 int trx_nr = atoi(argv[0]);
1017 struct gsm_bts *bts = vty->index;
1018 struct gsm_bts_trx *trx;
1019
Harald Weltee712a5f2009-06-21 16:17:15 +02001020 if (trx_nr > bts->num_trx) {
1021 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
1022 bts->num_trx, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +08001023 return CMD_WARNING;
Harald Weltee712a5f2009-06-21 16:17:15 +02001024 } else if (trx_nr == bts->num_trx) {
1025 /* we need to allocate a new one */
1026 trx = gsm_bts_trx_alloc(bts);
1027 } else
1028 trx = gsm_bts_trx_num(bts, trx_nr);
1029
1030 if (!trx)
1031 return CMD_WARNING;
Harald Welte59b04682009-06-10 05:40:52 +08001032
1033 vty->index = trx;
1034 vty->node = TRX_NODE;
1035
1036 return CMD_SUCCESS;
1037}
1038
1039DEFUN(cfg_trx_arfcn,
1040 cfg_trx_arfcn_cmd,
1041 "arfcn <1-1024>",
1042 "Set the ARFCN for this TRX\n")
1043{
1044 int arfcn = atoi(argv[0]);
1045 struct gsm_bts_trx *trx = vty->index;
1046
1047 /* FIXME: check if this ARFCN is supported by this TRX */
1048
1049 trx->arfcn = arfcn;
1050
1051 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
1052 /* FIXME: use OML layer to update the ARFCN */
1053 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
1054
1055 return CMD_SUCCESS;
1056}
1057
Harald Welte91afe4c2009-06-20 18:15:19 +02001058DEFUN(cfg_trx_max_power_red,
1059 cfg_trx_max_power_red_cmd,
1060 "max_power_red <0-100>",
1061 "Reduction of maximum BS RF Power in dB\n")
1062{
1063 int maxpwr_r = atoi(argv[0]);
1064 struct gsm_bts_trx *trx = vty->index;
1065 int upper_limit = 12; /* default 12.21 max power red. */
1066
1067 /* FIXME: check if our BTS type supports more than 12 */
1068 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
1069 vty_out(vty, "%% Power %d dB is not in the valid range%s",
1070 maxpwr_r, VTY_NEWLINE);
1071 return CMD_WARNING;
1072 }
1073 if (maxpwr_r & 1) {
1074 vty_out(vty, "%% Power %d dB is not an even value%s",
1075 maxpwr_r, VTY_NEWLINE);
1076 return CMD_WARNING;
1077 }
1078
1079 trx->max_power_red = maxpwr_r;
1080
1081 /* FIXME: make sure we update this using OML */
1082
1083 return CMD_SUCCESS;
1084}
1085
Harald Welte62868882009-08-08 16:12:58 +02001086DEFUN(cfg_trx_rsl_e1,
1087 cfg_trx_rsl_e1_cmd,
1088 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
1089 "E1 interface to be used for RSL\n")
1090{
1091 struct gsm_bts_trx *trx = vty->index;
1092
1093 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
1094
1095 return CMD_SUCCESS;
1096}
1097
1098DEFUN(cfg_trx_rsl_e1_tei,
1099 cfg_trx_rsl_e1_tei_cmd,
1100 "rsl e1 tei <0-63>",
1101 "Set the TEI to be used for RSL")
1102{
1103 struct gsm_bts_trx *trx = vty->index;
1104
1105 trx->rsl_tei = atoi(argv[0]);
1106
1107 return CMD_SUCCESS;
1108}
1109
1110
Harald Welte59b04682009-06-10 05:40:52 +08001111/* per TS configuration */
1112DEFUN(cfg_ts,
1113 cfg_ts_cmd,
Harald Welte62868882009-08-08 16:12:58 +02001114 "timeslot <0-7>",
Harald Welte59b04682009-06-10 05:40:52 +08001115 "Select a Timeslot to configure")
1116{
1117 int ts_nr = atoi(argv[0]);
1118 struct gsm_bts_trx *trx = vty->index;
1119 struct gsm_bts_trx_ts *ts;
1120
1121 if (ts_nr >= TRX_NR_TS) {
1122 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
1123 TRX_NR_TS, VTY_NEWLINE);
1124 return CMD_WARNING;
1125 }
1126
1127 ts = &trx->ts[ts_nr];
1128
1129 vty->index = ts;
1130 vty->node = TS_NODE;
1131
1132 return CMD_SUCCESS;
1133}
1134
Harald Welte3ffe1b32009-08-07 00:25:23 +02001135DEFUN(cfg_ts_pchan,
1136 cfg_ts_pchan_cmd,
1137 "phys_chan_config PCHAN",
1138 "Physical Channel configuration (TCH/SDCCH/...)")
1139{
1140 struct gsm_bts_trx_ts *ts = vty->index;
1141 int pchanc;
1142
1143 pchanc = gsm_pchan_parse(argv[0]);
1144 if (pchanc < 0)
1145 return CMD_WARNING;
1146
1147 ts->pchan = pchanc;
1148
1149 return CMD_SUCCESS;
1150}
1151
1152DEFUN(cfg_ts_e1_subslot,
1153 cfg_ts_e1_subslot_cmd,
Harald Welte62868882009-08-08 16:12:58 +02001154 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welte3ffe1b32009-08-07 00:25:23 +02001155 "E1 sub-slot connected to this on-air timeslot")
1156{
1157 struct gsm_bts_trx_ts *ts = vty->index;
1158
Harald Welte62868882009-08-08 16:12:58 +02001159 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Welte3ffe1b32009-08-07 00:25:23 +02001160
1161 return CMD_SUCCESS;
1162}
Harald Welte59b04682009-06-10 05:40:52 +08001163
Harald Welte59b04682009-06-10 05:40:52 +08001164int bsc_vty_init(struct gsm_network *net)
1165{
1166 gsmnet = net;
1167
1168 cmd_init(1);
1169 vty_init();
1170
1171 install_element(VIEW_NODE, &show_net_cmd);
1172 install_element(VIEW_NODE, &show_bts_cmd);
1173 install_element(VIEW_NODE, &show_trx_cmd);
1174 install_element(VIEW_NODE, &show_ts_cmd);
1175 install_element(VIEW_NODE, &show_lchan_cmd);
1176
1177 install_element(VIEW_NODE, &show_e1drv_cmd);
1178 install_element(VIEW_NODE, &show_e1line_cmd);
1179 install_element(VIEW_NODE, &show_e1ts_cmd);
1180
1181 install_element(VIEW_NODE, &show_paging_cmd);
1182
Harald Weltee87eb462009-08-07 13:29:14 +02001183 install_element(CONFIG_NODE, &cfg_net_cmd);
1184 install_node(&net_node, config_write_net);
1185 install_default(GSMNET_NODE);
Harald Welte62868882009-08-08 16:12:58 +02001186 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
Harald Weltee87eb462009-08-07 13:29:14 +02001187 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1188 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1189 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
Harald Welte (local)a59a27e2009-08-12 14:42:23 +02001190 install_element(GSMNET_NODE, &cfg_net_auth_policy_cmd);
Harald Weltecca253a2009-08-30 15:47:06 +09001191 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
Harald Weltee87eb462009-08-07 13:29:14 +02001192
1193 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte97ceef92009-08-06 19:06:46 +02001194 install_node(&bts_node, config_write_bts);
Harald Welte59b04682009-06-10 05:40:52 +08001195 install_default(BTS_NODE);
1196 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte91afe4c2009-06-20 18:15:19 +02001197 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freythera098dfb2009-08-21 14:44:12 +02001198 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001199 install_element(BTS_NODE, &cfg_bts_lac_cmd);
1200 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte62868882009-08-08 16:12:58 +02001201 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001202 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte62868882009-08-08 16:12:58 +02001203 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
1204 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte3e774612009-08-10 13:48:16 +02001205 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Harald Welte (local)e19be3f2009-08-12 13:28:23 +02001206 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001207 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +02001208 install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd);
Harald Welte3e774612009-08-10 13:48:16 +02001209
Harald Welte59b04682009-06-10 05:40:52 +08001210
1211 install_element(BTS_NODE, &cfg_trx_cmd);
1212 install_node(&trx_node, dummy_config_write);
1213 install_default(TRX_NODE);
1214 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte7f597bc2009-06-20 22:36:12 +02001215 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte62868882009-08-08 16:12:58 +02001216 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
1217 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001218
1219 install_element(TRX_NODE, &cfg_ts_cmd);
1220 install_node(&ts_node, dummy_config_write);
1221 install_default(TS_NODE);
Harald Welte3ffe1b32009-08-07 00:25:23 +02001222 install_element(TS_NODE, &cfg_ts_pchan_cmd);
1223 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001224
Holger Hans Peter Freytherbdae6f92009-08-10 10:17:50 +02001225 bsc_vty_init_extra(net);
Harald Welte59b04682009-06-10 05:40:52 +08001226
1227 return 0;
1228}