blob: eaa0eac1dd1031b513c8fa878a4ec6505bcf93bd [file] [log] [blame]
Harald Welte59b04682009-06-10 05:40:52 +08001/* OpenBSC interface to quagga VTY */
Harald Welte410575a2010-03-14 23:30:30 +08002/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte59b04682009-06-10 05:40:52 +08003 * 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
Harald Weltef4625b12010-02-20 16:24:02 +010031#include <osmocore/linuxlist.h>
Harald Welte59b04682009-06-10 05:40:52 +080032#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 Weltef4625b12010-02-20 16:24:02 +010035#include <osmocore/gsm_utils.h>
Harald Weltefe96f382009-12-22 13:09:29 +010036#include <openbsc/chan_alloc.h>
Harald Welte44007742009-12-22 21:43:14 +010037#include <openbsc/meas_rep.h>
Harald Welte59b04682009-06-10 05:40:52 +080038#include <openbsc/db.h>
Harald Weltef4625b12010-02-20 16:24:02 +010039#include <osmocore/talloc.h>
Holger Hans Peter Freytherc8d862e2009-12-22 22:32:51 +010040#include <openbsc/telnet_interface.h>
Holger Hans Peter Freytherb70d45b2010-04-06 11:55:37 +020041#include <openbsc/vty.h>
Harald Weltef45981f2010-05-12 20:28:04 +020042#include <openbsc/gprs_ns.h>
Harald Welte59b04682009-06-10 05:40:52 +080043
Harald Welte10c29f62010-05-16 19:20:24 +020044#include "../bscconfig.h"
45
Harald Welte59b04682009-06-10 05:40:52 +080046static struct gsm_network *gsmnet;
47
Harald Welted6b62e32010-05-12 17:19:53 +000048/* FIXME: this should go to some common file */
49static const struct value_string gprs_ns_timer_strs[] = {
Harald Weltea9251762010-05-11 23:50:21 +020050 { 0, "tns-block" },
51 { 1, "tns-block-retries" },
52 { 2, "tns-reset" },
53 { 3, "tns-reset-retries" },
54 { 4, "tns-test" },
55 { 5, "tns-alive" },
56 { 6, "tns-alive-retries" },
57 { 0, NULL }
58};
59
Harald Welted6b62e32010-05-12 17:19:53 +000060static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Weltea9251762010-05-11 23:50:21 +020061 { 0, "blocking-timer" },
62 { 1, "blocking-retries" },
63 { 2, "unblocking-retries" },
64 { 3, "reset-timer" },
65 { 4, "reset-retries" },
66 { 5, "suspend-timer" },
67 { 6, "suspend-retries" },
68 { 7, "resume-timer" },
69 { 8, "resume-retries" },
70 { 9, "capability-update-timer" },
71 { 10, "capability-update-retries" },
72 { 0, NULL }
73};
74
Harald Weltee87eb462009-08-07 13:29:14 +020075struct cmd_node net_node = {
76 GSMNET_NODE,
77 "%s(network)#",
78 1,
79};
80
Harald Welte59b04682009-06-10 05:40:52 +080081struct cmd_node bts_node = {
82 BTS_NODE,
83 "%s(bts)#",
84 1,
85};
86
87struct cmd_node trx_node = {
88 TRX_NODE,
89 "%s(trx)#",
90 1,
91};
92
93struct cmd_node ts_node = {
94 TS_NODE,
95 "%s(ts)#",
96 1,
97};
98
Harald Welte59b04682009-06-10 05:40:52 +080099static int dummy_config_write(struct vty *v)
100{
101 return CMD_SUCCESS;
102}
103
104static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
105{
106 vty_out(vty,"Oper '%s', Admin %u, Avail '%s'%s",
107 nm_opstate_name(nms->operational), nms->administrative,
108 nm_avail_name(nms->availability), VTY_NEWLINE);
109}
110
Harald Weltefe96f382009-12-22 13:09:29 +0100111static void dump_pchan_load_vty(struct vty *vty, char *prefix,
112 const struct pchan_load *pl)
113{
114 int i;
115
116 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
117 const struct load_counter *lc = &pl->pchan[i];
118 unsigned int percent;
119
120 if (lc->total == 0)
121 continue;
122
123 percent = (lc->used * 100) / lc->total;
124
125 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
126 gsm_pchan_name(i), percent, lc->used, lc->total,
127 VTY_NEWLINE);
128 }
129}
130
Harald Welte59b04682009-06-10 05:40:52 +0800131static void net_dump_vty(struct vty *vty, struct gsm_network *net)
132{
Harald Weltefe96f382009-12-22 13:09:29 +0100133 struct pchan_load pl;
134
Harald Welte59b04682009-06-10 05:40:52 +0800135 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
136 "and has %u BTS%s", net->country_code, net->network_code,
137 net->num_bts, VTY_NEWLINE);
138 vty_out(vty, " Long network name: '%s'%s",
139 net->name_long, VTY_NEWLINE);
140 vty_out(vty, " Short network name: '%s'%s",
141 net->name_short, VTY_NEWLINE);
Harald Welte (local)a59a27e2009-08-12 14:42:23 +0200142 vty_out(vty, " Authentication policy: %s%s",
143 gsm_auth_policy_name(net->auth_policy), VTY_NEWLINE);
Harald Welte59936d72009-11-18 20:33:19 +0100144 vty_out(vty, " Location updating reject cause: %u%s",
145 net->reject_cause, VTY_NEWLINE);
Harald Weltecca253a2009-08-30 15:47:06 +0900146 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
147 VTY_NEWLINE);
Holger Hans Peter Freyther96c89822009-11-16 17:12:38 +0100148 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
149 VTY_NEWLINE);
Harald Welte52af1952009-12-13 10:53:12 +0100150 vty_out(vty, " RRLP Mode: %s%s", rrlp_mode_name(net->rrlp.mode),
151 VTY_NEWLINE);
Harald Weltea310f3e2009-12-14 09:00:24 +0100152 vty_out(vty, " MM Info: %s%s", net->send_mm_info ? "On" : "Off",
153 VTY_NEWLINE);
Harald Welte0af9c9f2009-12-19 21:41:52 +0100154 vty_out(vty, " Handover: %s%s", net->handover.active ? "On" : "Off",
155 VTY_NEWLINE);
Harald Weltefe96f382009-12-22 13:09:29 +0100156 network_chan_load(&pl, net);
157 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
158 dump_pchan_load_vty(vty, " ", &pl);
Harald Welte59b04682009-06-10 05:40:52 +0800159}
160
161DEFUN(show_net, show_net_cmd, "show network",
162 SHOW_STR "Display information about a GSM NETWORK\n")
163{
164 struct gsm_network *net = gsmnet;
165 net_dump_vty(vty, net);
166
167 return CMD_SUCCESS;
168}
169
170static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
171{
172 struct e1inp_line *line;
173
174 if (!e1l) {
175 vty_out(vty, " None%s", VTY_NEWLINE);
176 return;
177 }
178
179 line = e1l->ts->line;
180
181 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
182 line->num, line->driver->name, e1l->ts->num,
183 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
184 vty_out(vty, " E1 TEI %u, SAPI %u%s",
185 e1l->tei, e1l->sapi, VTY_NEWLINE);
186}
187
188static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
189{
Harald Weltefe96f382009-12-22 13:09:29 +0100190 struct pchan_load pl;
191
Holger Hans Peter Freythera098dfb2009-08-21 14:44:12 +0200192 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte91afe4c2009-06-20 18:15:19 +0200193 "BSIC %u, TSC %u and %u TRX%s",
194 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freythera098dfb2009-08-21 14:44:12 +0200195 bts->cell_identity,
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200196 bts->location_area_code, bts->bsic, bts->tsc,
Harald Welte91afe4c2009-06-20 18:15:19 +0200197 bts->num_trx, VTY_NEWLINE);
Harald Welte8791dac2010-05-14 17:59:53 +0200198 vty_out(vty, "Description: %s%s",
199 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Harald Welte8e9d1792009-12-12 15:38:16 +0100200 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welteb761bf82009-12-12 18:17:25 +0100201 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte8e9d1792009-12-12 15:38:16 +0100202 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
203 VTY_NEWLINE);
204 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welteb761bf82009-12-12 18:17:25 +0100205 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut8e2d8de2009-12-22 13:43:26 +0100206 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
207 VTY_NEWLINE);
208 vty_out(vty, "RACH Max transmissions: %u%s",
209 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
210 VTY_NEWLINE);
Harald Welte8c973ba2009-12-21 23:08:18 +0100211 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)e19be3f2009-08-12 13:28:23 +0200212 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800213 if (is_ipaccess_bts(bts))
Harald Welte25572872009-10-20 00:22:00 +0200214 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte59b04682009-06-10 05:40:52 +0800215 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte25572872009-10-20 00:22:00 +0200216 bts->oml_tei, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800217 vty_out(vty, " NM State: ");
218 net_dump_nmstate(vty, &bts->nm_state);
219 vty_out(vty, " Site Mgr NM State: ");
220 net_dump_nmstate(vty, &bts->site_mgr.nm_state);
221 vty_out(vty, " Paging: FIXME pending requests, %u free slots%s",
222 bts->paging.available_slots, VTY_NEWLINE);
Harald Welte25572872009-10-20 00:22:00 +0200223 if (!is_ipaccess_bts(bts)) {
224 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
225 e1isl_dump_vty(vty, bts->oml_link);
226 }
Harald Welte59b04682009-06-10 05:40:52 +0800227 /* FIXME: oml_link, chan_desc */
Harald Weltefe96f382009-12-22 13:09:29 +0100228 memset(&pl, 0, sizeof(pl));
229 bts_chan_load(&pl, bts);
230 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
231 dump_pchan_load_vty(vty, " ", &pl);
Harald Welte59b04682009-06-10 05:40:52 +0800232}
233
234DEFUN(show_bts, show_bts_cmd, "show bts [number]",
235 SHOW_STR "Display information about a BTS\n"
236 "BTS number")
237{
238 struct gsm_network *net = gsmnet;
239 int bts_nr;
240
241 if (argc != 0) {
242 /* use the BTS number that the user has specified */
243 bts_nr = atoi(argv[0]);
244 if (bts_nr > net->num_bts) {
245 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
246 VTY_NEWLINE);
247 return CMD_WARNING;
248 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200249 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte59b04682009-06-10 05:40:52 +0800250 return CMD_SUCCESS;
251 }
252 /* print all BTS's */
253 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee712a5f2009-06-21 16:17:15 +0200254 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte59b04682009-06-10 05:40:52 +0800255
256 return CMD_SUCCESS;
257}
258
Harald Welte62868882009-08-08 16:12:58 +0200259/* utility functions */
260static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
261 const char *ts, const char *ss)
262{
263 e1_link->e1_nr = atoi(line);
264 e1_link->e1_ts = atoi(ts);
265 if (!strcmp(ss, "full"))
266 e1_link->e1_ts_ss = 255;
267 else
268 e1_link->e1_ts_ss = atoi(ss);
269}
270
271static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
272 const char *prefix)
273{
274 if (!e1_link->e1_ts)
275 return;
276
277 if (e1_link->e1_ts_ss == 255)
278 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
279 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
280 else
281 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
282 prefix, e1_link->e1_nr, e1_link->e1_ts,
283 e1_link->e1_ts_ss, VTY_NEWLINE);
284}
285
286
Harald Welte97ceef92009-08-06 19:06:46 +0200287static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
288{
Harald Welte62868882009-08-08 16:12:58 +0200289 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
290 if (ts->pchan != GSM_PCHAN_NONE)
291 vty_out(vty, " phys_chan_config %s%s",
292 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
293 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welte97ceef92009-08-06 19:06:46 +0200294}
295
296static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
297{
298 int i;
299
Harald Weltee87eb462009-08-07 13:29:14 +0200300 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte8791dac2010-05-14 17:59:53 +0200301 if (trx->description)
302 vty_out(vty, " description %s%s", trx->description,
303 VTY_NEWLINE);
Holger Hans Peter Freyther32be2aa2010-04-17 06:42:07 +0200304 vty_out(vty, " rf_locked %u%s",
305 trx->nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
306 VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200307 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)b709bfe2009-12-27 20:56:38 +0100308 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200309 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200310 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
311 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte97ceef92009-08-06 19:06:46 +0200312
313 for (i = 0; i < TRX_NR_TS; i++)
314 config_write_ts_single(vty, &trx->ts[i]);
315}
316
Harald Weltea9251762010-05-11 23:50:21 +0200317static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
318{
319 unsigned int i;
320 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
321 VTY_NEWLINE);
322 if (bts->gprs.mode == BTS_GPRS_NONE)
323 return;
324
325 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
326 VTY_NEWLINE);
327 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
328 VTY_NEWLINE);
329 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
330 vty_out(vty, " gprs cell timer %s %u%s",
331 get_value_string(gprs_bssgp_cfg_strs, i),
332 bts->gprs.cell.timer[i], VTY_NEWLINE);
333 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
334 VTY_NEWLINE);
335 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
336 vty_out(vty, " gprs ns timer %s %u%s",
337 get_value_string(gprs_ns_timer_strs, i),
338 bts->gprs.nse.timer[i], VTY_NEWLINE);
339 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
340 struct gsm_bts_gprs_nsvc *nsvc =
341 &bts->gprs.nsvc[i];
342 struct in_addr ia;
343
344 ia.s_addr = htonl(nsvc->remote_ip);
345 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
346 nsvc->nsvci, VTY_NEWLINE);
347 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
348 nsvc->local_port, VTY_NEWLINE);
349 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
350 nsvc->remote_port, VTY_NEWLINE);
351 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
352 inet_ntoa(ia), VTY_NEWLINE);
353 }
354}
355
Harald Welte97ceef92009-08-06 19:06:46 +0200356static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
357{
358 struct gsm_bts_trx *trx;
359
Harald Weltee87eb462009-08-07 13:29:14 +0200360 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
361 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte8791dac2010-05-14 17:59:53 +0200362 if (bts->description)
363 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200364 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freyther6d82b7c2009-11-19 16:38:49 +0100365 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200366 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte97ceef92009-08-06 19:06:46 +0200367 VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200368 vty_out(vty, " training_sequence_code %u%s", bts->tsc, VTY_NEWLINE);
369 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)cbd46102009-08-13 10:14:26 +0200370 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welteb761bf82009-12-12 18:17:25 +0100371 vty_out(vty, " cell reselection hysteresis %u%s",
372 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
373 vty_out(vty, " rxlev access min %u%s",
374 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Harald Weltea54a2bb2009-12-01 18:04:30 +0530375 if (bts->si_common.chan_desc.t3212)
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +0200376 vty_out(vty, " periodic location update %u%s",
Harald Weltea54a2bb2009-12-01 18:04:30 +0530377 bts->si_common.chan_desc.t3212 * 10, VTY_NEWLINE);
Harald Welte3e774612009-08-10 13:48:16 +0200378 vty_out(vty, " channel allocator %s%s",
379 bts->chan_alloc_reverse ? "descending" : "ascending",
380 VTY_NEWLINE);
Sylvain Munaut8e2d8de2009-12-22 13:43:26 +0100381 vty_out(vty, " rach tx integer %u%s",
382 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
383 vty_out(vty, " rach max transmission %u%s",
384 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
385 VTY_NEWLINE);
Holger Hans Peter Freyther697ed2b2010-04-25 23:08:39 +0800386
387 if (bts->rach_b_thresh != -1)
388 vty_out(vty, " rach nm busy threshold %u%s",
389 bts->rach_b_thresh, VTY_NEWLINE);
390 if (bts->rach_ldavg_slots != -1)
391 vty_out(vty, " rach nm load average %u%s",
392 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte8c973ba2009-12-21 23:08:18 +0100393 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)e19be3f2009-08-12 13:28:23 +0200394 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther440984b2010-05-14 00:39:19 +0800395 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
396 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Harald Welte25572872009-10-20 00:22:00 +0200397 if (is_ipaccess_bts(bts)) {
Harald Weltee87eb462009-08-07 13:29:14 +0200398 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Welte3ffe1b32009-08-07 00:25:23 +0200399 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte25572872009-10-20 00:22:00 +0200400 vty_out(vty, " oml ip.access stream_id %u%s", bts->oml_tei, VTY_NEWLINE);
401 } else {
Harald Welte62868882009-08-08 16:12:58 +0200402 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
403 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
404 }
Harald Weltea9251762010-05-11 23:50:21 +0200405 config_write_bts_gprs(vty, bts);
Harald Welte97ceef92009-08-06 19:06:46 +0200406
407 llist_for_each_entry(trx, &bts->trx_list, list)
408 config_write_trx_single(vty, trx);
409}
410
411static int config_write_bts(struct vty *v)
412{
413 struct gsm_bts *bts;
414
415 llist_for_each_entry(bts, &gsmnet->bts_list, list)
416 config_write_bts_single(v, bts);
417
418 return CMD_SUCCESS;
419}
420
Harald Weltee87eb462009-08-07 13:29:14 +0200421static int config_write_net(struct vty *vty)
422{
423 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200424 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200425 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte62868882009-08-08 16:12:58 +0200426 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
427 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
Harald Welte (local)a59a27e2009-08-12 14:42:23 +0200428 vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE);
Harald Welte59936d72009-11-18 20:33:19 +0100429 vty_out(vty, " location updating reject cause %u%s",
430 gsmnet->reject_cause, VTY_NEWLINE);
Harald Weltecca253a2009-08-30 15:47:06 +0900431 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freyther6b4f5462009-11-19 16:37:48 +0100432 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Harald Welte52af1952009-12-13 10:53:12 +0100433 vty_out(vty, " rrlp mode %s%s", rrlp_mode_name(gsmnet->rrlp.mode),
434 VTY_NEWLINE);
Harald Weltea310f3e2009-12-14 09:00:24 +0100435 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
Harald Welte0af9c9f2009-12-19 21:41:52 +0100436 vty_out(vty, " handover %u%s", gsmnet->handover.active, VTY_NEWLINE);
Harald Weltea8062f12009-12-21 16:51:50 +0100437 vty_out(vty, " handover window rxlev averaging %u%s",
438 gsmnet->handover.win_rxlev_avg, VTY_NEWLINE);
439 vty_out(vty, " handover window rxqual averaging %u%s",
440 gsmnet->handover.win_rxqual_avg, VTY_NEWLINE);
441 vty_out(vty, " handover window rxlev neighbor averaging %u%s",
442 gsmnet->handover.win_rxlev_avg_neigh, VTY_NEWLINE);
443 vty_out(vty, " handover power budget interval %u%s",
444 gsmnet->handover.pwr_interval, VTY_NEWLINE);
445 vty_out(vty, " handover power budget hysteresis %u%s",
446 gsmnet->handover.pwr_hysteresis, VTY_NEWLINE);
447 vty_out(vty, " handover maximum distance %u%s",
448 gsmnet->handover.max_distance, VTY_NEWLINE);
Holger Hans Peter Freyther26ba2e72009-11-21 21:18:38 +0100449 vty_out(vty, " timer t3101 %u%s", gsmnet->T3101, VTY_NEWLINE);
Holger Hans Peter Freyther89733862009-11-21 21:42:26 +0100450 vty_out(vty, " timer t3103 %u%s", gsmnet->T3103, VTY_NEWLINE);
451 vty_out(vty, " timer t3105 %u%s", gsmnet->T3105, VTY_NEWLINE);
452 vty_out(vty, " timer t3107 %u%s", gsmnet->T3107, VTY_NEWLINE);
453 vty_out(vty, " timer t3109 %u%s", gsmnet->T3109, VTY_NEWLINE);
454 vty_out(vty, " timer t3111 %u%s", gsmnet->T3111, VTY_NEWLINE);
455 vty_out(vty, " timer t3113 %u%s", gsmnet->T3113, VTY_NEWLINE);
456 vty_out(vty, " timer t3115 %u%s", gsmnet->T3115, VTY_NEWLINE);
457 vty_out(vty, " timer t3117 %u%s", gsmnet->T3117, VTY_NEWLINE);
458 vty_out(vty, " timer t3119 %u%s", gsmnet->T3119, VTY_NEWLINE);
459 vty_out(vty, " timer t3141 %u%s", gsmnet->T3141, VTY_NEWLINE);
Harald Weltee87eb462009-08-07 13:29:14 +0200460
461 return CMD_SUCCESS;
462}
Harald Welte97ceef92009-08-06 19:06:46 +0200463
Harald Welte59b04682009-06-10 05:40:52 +0800464static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
465{
466 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
467 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte8791dac2010-05-14 17:59:53 +0200468 vty_out(vty, "Description: %s%s",
469 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Welte91afe4c2009-06-20 18:15:19 +0200470 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte62868882009-08-08 16:12:58 +0200471 "resulting BS power: %d dBm%s",
Harald Welte91afe4c2009-06-20 18:15:19 +0200472 trx->nominal_power, trx->max_power_red,
Harald Welte62868882009-08-08 16:12:58 +0200473 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800474 vty_out(vty, " NM State: ");
475 net_dump_nmstate(vty, &trx->nm_state);
476 vty_out(vty, " Baseband Transceiver NM State: ");
477 net_dump_nmstate(vty, &trx->bb_transc.nm_state);
Harald Welte25572872009-10-20 00:22:00 +0200478 if (is_ipaccess_bts(trx->bts)) {
479 vty_out(vty, " ip.access stream ID: 0x%02x%s",
480 trx->rsl_tei, VTY_NEWLINE);
481 } else {
482 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
483 e1isl_dump_vty(vty, trx->rsl_link);
484 }
Harald Welte59b04682009-06-10 05:40:52 +0800485}
486
487DEFUN(show_trx,
488 show_trx_cmd,
489 "show trx [bts_nr] [trx_nr]",
Harald Welte9e002452010-05-11 21:53:49 +0200490 SHOW_STR "Display information about a TRX\n"
491 "BTS Number\n"
492 "TRX Number\n")
Harald Welte59b04682009-06-10 05:40:52 +0800493{
494 struct gsm_network *net = gsmnet;
495 struct gsm_bts *bts = NULL;
496 struct gsm_bts_trx *trx;
497 int bts_nr, trx_nr;
498
499 if (argc >= 1) {
500 /* use the BTS number that the user has specified */
501 bts_nr = atoi(argv[0]);
502 if (bts_nr >= net->num_bts) {
503 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
504 VTY_NEWLINE);
505 return CMD_WARNING;
506 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200507 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800508 }
509 if (argc >= 2) {
510 trx_nr = atoi(argv[1]);
511 if (trx_nr >= bts->num_trx) {
512 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
513 VTY_NEWLINE);
514 return CMD_WARNING;
515 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200516 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800517 trx_dump_vty(vty, trx);
518 return CMD_SUCCESS;
519 }
520 if (bts) {
521 /* print all TRX in this BTS */
522 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200523 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800524 trx_dump_vty(vty, trx);
525 }
526 return CMD_SUCCESS;
527 }
528
529 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200530 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800531 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200532 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800533 trx_dump_vty(vty, trx);
534 }
535 }
536
537 return CMD_SUCCESS;
538}
539
Harald Welte97ceef92009-08-06 19:06:46 +0200540
Harald Welte59b04682009-06-10 05:40:52 +0800541static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
542{
Harald Welte59b04682009-06-10 05:40:52 +0800543 vty_out(vty, "Timeslot %u of TRX %u in BTS %u, phys cfg %s%s",
544 ts->nr, ts->trx->nr, ts->trx->bts->nr,
545 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
546 vty_out(vty, " NM State: ");
547 net_dump_nmstate(vty, &ts->nm_state);
Harald Welte87504212009-12-02 01:56:49 +0530548 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welte59b04682009-06-10 05:40:52 +0800549 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
550 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
551 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800552}
553
554DEFUN(show_ts,
555 show_ts_cmd,
556 "show timeslot [bts_nr] [trx_nr] [ts_nr]",
Harald Welte9e002452010-05-11 21:53:49 +0200557 SHOW_STR "Display information about a TS\n"
558 "BTS Number\n" "TRX Number\n" "Timeslot Number\n")
Harald Welte59b04682009-06-10 05:40:52 +0800559{
560 struct gsm_network *net = gsmnet;
561 struct gsm_bts *bts;
562 struct gsm_bts_trx *trx;
563 struct gsm_bts_trx_ts *ts;
564 int bts_nr, trx_nr, ts_nr;
565
566 if (argc >= 1) {
567 /* use the BTS number that the user has specified */
568 bts_nr = atoi(argv[0]);
569 if (bts_nr >= net->num_bts) {
570 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
571 VTY_NEWLINE);
572 return CMD_WARNING;
573 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200574 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800575 }
576 if (argc >= 2) {
577 trx_nr = atoi(argv[1]);
578 if (trx_nr >= bts->num_trx) {
579 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
580 VTY_NEWLINE);
581 return CMD_WARNING;
582 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200583 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800584 }
585 if (argc >= 3) {
586 ts_nr = atoi(argv[2]);
587 if (ts_nr >= TRX_NR_TS) {
588 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
589 VTY_NEWLINE);
590 return CMD_WARNING;
591 }
592 ts = &trx->ts[ts_nr];
593 ts_dump_vty(vty, ts);
594 return CMD_SUCCESS;
595 }
596 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200597 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800598 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200599 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800600 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
601 ts = &trx->ts[ts_nr];
602 ts_dump_vty(vty, ts);
603 }
604 }
605 }
606
607 return CMD_SUCCESS;
608}
609
Holger Hans Peter Freyther1dd0a1b2010-01-06 06:00:40 +0100610static void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr)
Harald Welte59b04682009-06-10 05:40:52 +0800611{
Harald Welte91afe4c2009-06-20 18:15:19 +0200612 vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id,
Harald Welte59b04682009-06-10 05:40:52 +0800613 subscr->authorized, VTY_NEWLINE);
614 if (subscr->name)
615 vty_out(vty, " Name: '%s'%s", subscr->name, VTY_NEWLINE);
616 if (subscr->extension)
617 vty_out(vty, " Extension: %s%s", subscr->extension,
618 VTY_NEWLINE);
619 if (subscr->imsi)
620 vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE);
Holger Hans Peter Freythercd8bacf2009-08-19 12:53:57 +0200621 if (subscr->tmsi != GSM_RESERVED_TMSI)
622 vty_out(vty, " TMSI: %08X%s", subscr->tmsi,
Harald Welte270c06c2009-08-15 03:24:51 +0200623 VTY_NEWLINE);
Sylvain Munaute5863a22009-12-27 19:29:28 +0100624
Harald Welte (local)02d5efa2009-08-14 20:27:16 +0200625 vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +0800626}
627
Harald Welte44007742009-12-22 21:43:14 +0100628static void meas_rep_dump_uni_vty(struct vty *vty,
629 struct gsm_meas_rep_unidir *mru,
630 const char *prefix,
631 const char *dir)
632{
633 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
634 prefix, dir, rxlev2dbm(mru->full.rx_lev),
635 dir, rxlev2dbm(mru->sub.rx_lev));
636 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
637 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
638 VTY_NEWLINE);
639}
640
641static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
642 const char *prefix)
643{
644 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
645 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
646 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
647 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
648 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
649 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
650 VTY_NEWLINE);
651 if (mr->flags & MEAS_REP_F_MS_TO)
652 vty_out(vty, "%s MS Timing Offset: %u%s", prefix,
653 mr->ms_timing_offset, VTY_NEWLINE);
654 if (mr->flags & MEAS_REP_F_MS_L1)
655 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
656 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
657 if (mr->flags & MEAS_REP_F_DL_VALID)
658 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
659 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
660}
661
Holger Hans Peter Freyther5424e022010-05-14 02:03:16 +0800662static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte59b04682009-06-10 05:40:52 +0800663{
Harald Welte44007742009-12-22 21:43:14 +0100664 int idx;
665
Harald Welte59b04682009-06-10 05:40:52 +0800666 vty_out(vty, "Lchan %u in Timeslot %u of TRX %u in BTS %u, Type %s%s",
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +0200667 lchan->nr, lchan->ts->nr, lchan->ts->trx->nr,
Harald Welte (local)02204d02009-12-27 18:05:25 +0100668 lchan->ts->trx->bts->nr, gsm_lchant_name(lchan->type),
Harald Welte59b04682009-06-10 05:40:52 +0800669 VTY_NEWLINE);
Holger Hans Peter Freyther065b8112010-03-23 06:41:45 +0100670 vty_out(vty, " Use Count: %u, State: %s%s", lchan->conn.use_count,
Harald Welteab2534c2009-12-29 10:52:38 +0100671 gsm_lchans_name(lchan->state), VTY_NEWLINE);
Harald Welteb761bf82009-12-12 18:17:25 +0100672 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
673 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
674 - lchan->bs_power*2,
675 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
676 VTY_NEWLINE);
Holger Hans Peter Freyther065b8112010-03-23 06:41:45 +0100677 if (lchan->conn.subscr) {
Harald Welte59b04682009-06-10 05:40:52 +0800678 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Holger Hans Peter Freyther065b8112010-03-23 06:41:45 +0100679 subscr_dump_vty(vty, lchan->conn.subscr);
Harald Welte59b04682009-06-10 05:40:52 +0800680 } else
681 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte87504212009-12-02 01:56:49 +0530682 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
683 struct in_addr ia;
Holger Hans Peter Freythercec1ec52010-04-07 15:39:16 +0200684 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte87504212009-12-02 01:56:49 +0530685 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
686 inet_ntoa(ia), lchan->abis_ip.bound_port,
687 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
688 VTY_NEWLINE);
689 }
Harald Welte44007742009-12-22 21:43:14 +0100690
691 /* we want to report the last measurement report */
692 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
693 lchan->meas_rep_idx, 1);
694 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte59b04682009-06-10 05:40:52 +0800695}
696
Holger Hans Peter Freythere959b4e2010-05-14 02:08:49 +0800697static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
698{
Holger Hans Peter Freythercf13a922010-05-14 01:57:02 +0800699 struct gsm_meas_rep *mr;
700 int idx;
701
702 /* we want to report the last measurement report */
703 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
704 lchan->meas_rep_idx, 1);
705 mr = &lchan->meas_rep[idx];
706
707 vty_out(vty, "Lchan: %u Timeslot: %u TRX: %u BTS: %u Type: %s - L1 MS Power: %u dBm "
708 "RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Holger Hans Peter Freythere959b4e2010-05-14 02:08:49 +0800709 lchan->nr, lchan->ts->nr, lchan->ts->trx->nr,
710 lchan->ts->trx->bts->nr, gsm_lchant_name(lchan->type),
Holger Hans Peter Freythercf13a922010-05-14 01:57:02 +0800711 mr->ms_l1.pwr,
712 rxlev2dbm(mr->dl.full.rx_lev),
713 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freythere959b4e2010-05-14 02:08:49 +0800714 VTY_NEWLINE);
715}
716
Holger Hans Peter Freyther5424e022010-05-14 02:03:16 +0800717static int lchan_summary(struct vty *vty, int argc, const char **argv,
718 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte59b04682009-06-10 05:40:52 +0800719{
720 struct gsm_network *net = gsmnet;
721 struct gsm_bts *bts;
722 struct gsm_bts_trx *trx;
723 struct gsm_bts_trx_ts *ts;
724 struct gsm_lchan *lchan;
725 int bts_nr, trx_nr, ts_nr, lchan_nr;
726
727 if (argc >= 1) {
728 /* use the BTS number that the user has specified */
729 bts_nr = atoi(argv[0]);
730 if (bts_nr >= net->num_bts) {
731 vty_out(vty, "%% can't find BTS %s%s", argv[0],
732 VTY_NEWLINE);
733 return CMD_WARNING;
734 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200735 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800736 }
737 if (argc >= 2) {
738 trx_nr = atoi(argv[1]);
739 if (trx_nr >= bts->num_trx) {
740 vty_out(vty, "%% can't find TRX %s%s", argv[1],
741 VTY_NEWLINE);
742 return CMD_WARNING;
743 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200744 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800745 }
746 if (argc >= 3) {
747 ts_nr = atoi(argv[2]);
748 if (ts_nr >= TRX_NR_TS) {
749 vty_out(vty, "%% can't find TS %s%s", argv[2],
750 VTY_NEWLINE);
751 return CMD_WARNING;
752 }
753 ts = &trx->ts[ts_nr];
754 }
755 if (argc >= 4) {
756 lchan_nr = atoi(argv[3]);
757 if (lchan_nr >= TS_MAX_LCHAN) {
758 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
759 VTY_NEWLINE);
760 return CMD_WARNING;
761 }
762 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther5424e022010-05-14 02:03:16 +0800763 dump_cb(vty, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800764 return CMD_SUCCESS;
765 }
766 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200767 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800768 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200769 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800770 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
771 ts = &trx->ts[ts_nr];
772 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN;
773 lchan_nr++) {
774 lchan = &ts->lchan[lchan_nr];
775 if (lchan->type == GSM_LCHAN_NONE)
776 continue;
Holger Hans Peter Freyther5424e022010-05-14 02:03:16 +0800777 dump_cb(vty, lchan);
Harald Welte59b04682009-06-10 05:40:52 +0800778 }
779 }
780 }
781 }
782
783 return CMD_SUCCESS;
784}
785
Holger Hans Peter Freyther5424e022010-05-14 02:03:16 +0800786
787DEFUN(show_lchan,
788 show_lchan_cmd,
789 "show lchan [bts_nr] [trx_nr] [ts_nr] [lchan_nr]",
790 SHOW_STR "Display information about a logical channel\n"
791 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
792 "Logical Channel Number\n")
793
794{
795 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
796}
797
Holger Hans Peter Freythere959b4e2010-05-14 02:08:49 +0800798DEFUN(show_lchan_summary,
799 show_lchan_summary_cmd,
800 "show lchan summary [bts_nr] [trx_nr] [ts_nr] [lchan_nr]",
801 SHOW_STR "Display information about a logical channel\n"
802 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
803 "Logical Channel Number\n")
804{
805 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
806}
807
Harald Welte59b04682009-06-10 05:40:52 +0800808static void e1drv_dump_vty(struct vty *vty, struct e1inp_driver *drv)
809{
810 vty_out(vty, "E1 Input Driver %s%s", drv->name, VTY_NEWLINE);
811}
812
813DEFUN(show_e1drv,
814 show_e1drv_cmd,
815 "show e1_driver",
816 SHOW_STR "Display information about available E1 drivers\n")
817{
818 struct e1inp_driver *drv;
819
820 llist_for_each_entry(drv, &e1inp_driver_list, list)
821 e1drv_dump_vty(vty, drv);
822
823 return CMD_SUCCESS;
824}
825
826static void e1line_dump_vty(struct vty *vty, struct e1inp_line *line)
827{
828 vty_out(vty, "E1 Line Number %u, Name %s, Driver %s%s",
829 line->num, line->name ? line->name : "",
830 line->driver->name, VTY_NEWLINE);
831}
832
833DEFUN(show_e1line,
834 show_e1line_cmd,
835 "show e1_line [line_nr]",
Harald Welte9e002452010-05-11 21:53:49 +0200836 SHOW_STR "Display information about a E1 line\n"
837 "E1 Line Number\n")
Harald Welte59b04682009-06-10 05:40:52 +0800838{
839 struct e1inp_line *line;
840
841 if (argc >= 1) {
842 int num = atoi(argv[0]);
843 llist_for_each_entry(line, &e1inp_line_list, list) {
844 if (line->num == num) {
845 e1line_dump_vty(vty, line);
846 return CMD_SUCCESS;
847 }
848 }
849 return CMD_WARNING;
850 }
851
852 llist_for_each_entry(line, &e1inp_line_list, list)
853 e1line_dump_vty(vty, line);
854
855 return CMD_SUCCESS;
856}
857
858static void e1ts_dump_vty(struct vty *vty, struct e1inp_ts *ts)
859{
Harald Welte62868882009-08-08 16:12:58 +0200860 if (ts->type == E1INP_TS_TYPE_NONE)
861 return;
Harald Welte59b04682009-06-10 05:40:52 +0800862 vty_out(vty, "E1 Timeslot %2u of Line %u is Type %s%s",
863 ts->num, ts->line->num, e1inp_tstype_name(ts->type),
864 VTY_NEWLINE);
865}
866
867DEFUN(show_e1ts,
868 show_e1ts_cmd,
869 "show e1_timeslot [line_nr] [ts_nr]",
Harald Welte9e002452010-05-11 21:53:49 +0200870 SHOW_STR "Display information about a E1 timeslot\n"
871 "E1 Line Number\n" "E1 Timeslot Number\n")
Harald Welte59b04682009-06-10 05:40:52 +0800872{
Harald Welte49c79562009-11-17 06:12:16 +0100873 struct e1inp_line *line = NULL;
Harald Welte59b04682009-06-10 05:40:52 +0800874 struct e1inp_ts *ts;
875 int ts_nr;
876
877 if (argc == 0) {
878 llist_for_each_entry(line, &e1inp_line_list, list) {
879 for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) {
880 ts = &line->ts[ts_nr];
881 e1ts_dump_vty(vty, ts);
882 }
883 }
884 return CMD_SUCCESS;
885 }
886 if (argc >= 1) {
887 int num = atoi(argv[0]);
888 llist_for_each_entry(line, &e1inp_line_list, list) {
889 if (line->num == num)
890 break;
891 }
892 if (!line || line->num != num) {
893 vty_out(vty, "E1 line %s is invalid%s",
894 argv[0], VTY_NEWLINE);
895 return CMD_WARNING;
896 }
897 }
898 if (argc >= 2) {
899 ts_nr = atoi(argv[1]);
900 if (ts_nr > NUM_E1_TS) {
901 vty_out(vty, "E1 timeslot %s is invalid%s",
902 argv[1], VTY_NEWLINE);
903 return CMD_WARNING;
904 }
905 ts = &line->ts[ts_nr];
906 e1ts_dump_vty(vty, ts);
907 return CMD_SUCCESS;
908 } else {
909 for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) {
910 ts = &line->ts[ts_nr];
911 e1ts_dump_vty(vty, ts);
912 }
913 return CMD_SUCCESS;
914 }
915 return CMD_SUCCESS;
916}
917
918static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
919{
920 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
921 subscr_dump_vty(vty, pag->subscr);
922}
923
924static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
925{
926 struct gsm_paging_request *pag;
927
928 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
929 paging_dump_vty(vty, pag);
930}
931
932DEFUN(show_paging,
933 show_paging_cmd,
934 "show paging [bts_nr]",
Harald Welte9e002452010-05-11 21:53:49 +0200935 SHOW_STR "Display information about paging reuqests of a BTS\n"
936 "BTS Number\n")
Harald Welte59b04682009-06-10 05:40:52 +0800937{
938 struct gsm_network *net = gsmnet;
939 struct gsm_bts *bts;
940 int bts_nr;
941
942 if (argc >= 1) {
943 /* use the BTS number that the user has specified */
944 bts_nr = atoi(argv[0]);
945 if (bts_nr >= net->num_bts) {
946 vty_out(vty, "%% can't find BTS %s%s", argv[0],
947 VTY_NEWLINE);
948 return CMD_WARNING;
949 }
Harald Weltee712a5f2009-06-21 16:17:15 +0200950 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800951 bts_paging_dump_vty(vty, bts);
952
953 return CMD_SUCCESS;
954 }
955 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200956 bts = gsm_bts_num(net, bts_nr);
Harald Welte59b04682009-06-10 05:40:52 +0800957 bts_paging_dump_vty(vty, bts);
958 }
959
960 return CMD_SUCCESS;
961}
962
Harald Welte9e002452010-05-11 21:53:49 +0200963#define NETWORK_STR "Configure the GSM network\n"
964
Harald Weltee87eb462009-08-07 13:29:14 +0200965DEFUN(cfg_net,
966 cfg_net_cmd,
Harald Welte9e002452010-05-11 21:53:49 +0200967 "network", NETWORK_STR)
Harald Weltee87eb462009-08-07 13:29:14 +0200968{
969 vty->index = gsmnet;
970 vty->node = GSMNET_NODE;
971
972 return CMD_SUCCESS;
973}
974
975
976DEFUN(cfg_net_ncc,
977 cfg_net_ncc_cmd,
978 "network country code <1-999>",
979 "Set the GSM network country code")
980{
981 gsmnet->country_code = atoi(argv[0]);
982
983 return CMD_SUCCESS;
984}
985
986DEFUN(cfg_net_mnc,
987 cfg_net_mnc_cmd,
988 "mobile network code <1-999>",
989 "Set the GSM mobile network code")
990{
991 gsmnet->network_code = atoi(argv[0]);
992
993 return CMD_SUCCESS;
994}
995
996DEFUN(cfg_net_name_short,
997 cfg_net_name_short_cmd,
998 "short name NAME",
999 "Set the short GSM network name")
1000{
1001 if (gsmnet->name_short)
1002 talloc_free(gsmnet->name_short);
1003
1004 gsmnet->name_short = talloc_strdup(gsmnet, argv[0]);
1005
1006 return CMD_SUCCESS;
1007}
1008
1009DEFUN(cfg_net_name_long,
1010 cfg_net_name_long_cmd,
1011 "long name NAME",
1012 "Set the long GSM network name")
1013{
1014 if (gsmnet->name_long)
1015 talloc_free(gsmnet->name_long);
1016
1017 gsmnet->name_long = talloc_strdup(gsmnet, argv[0]);
1018
1019 return CMD_SUCCESS;
1020}
Harald Welte59b04682009-06-10 05:40:52 +08001021
Harald Welte (local)a59a27e2009-08-12 14:42:23 +02001022DEFUN(cfg_net_auth_policy,
1023 cfg_net_auth_policy_cmd,
1024 "auth policy (closed|accept-all|token)",
Harald Welte9e002452010-05-11 21:53:49 +02001025 "Authentication (not cryptographic)\n"
1026 "Set the GSM network authentication policy\n"
1027 "Require the MS to be activated in HLR\n"
1028 "Accept all MS, whether in HLR or not\n"
1029 "Use SMS-token based authentication\n")
Harald Welte (local)a59a27e2009-08-12 14:42:23 +02001030{
1031 enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]);
1032
1033 gsmnet->auth_policy = policy;
1034
1035 return CMD_SUCCESS;
1036}
1037
Harald Welte59936d72009-11-18 20:33:19 +01001038DEFUN(cfg_net_reject_cause,
1039 cfg_net_reject_cause_cmd,
1040 "location updating reject cause <2-111>",
1041 "Set the reject cause of location updating reject\n")
1042{
1043 gsmnet->reject_cause = atoi(argv[0]);
1044
1045 return CMD_SUCCESS;
1046}
1047
Harald Weltecca253a2009-08-30 15:47:06 +09001048DEFUN(cfg_net_encryption,
1049 cfg_net_encryption_cmd,
1050 "encryption a5 (0|1|2)",
Harald Welte18ce31c2010-05-14 20:05:17 +02001051 "Encryption options\n"
1052 "A5 encryption\n" "A5/0: No encryption\n"
1053 "A5/1: Encryption\n" "A5/2: Export-grade Encryption\n")
Harald Weltecca253a2009-08-30 15:47:06 +09001054{
Andreas.Eversberg53293292009-11-17 09:55:26 +01001055 gsmnet->a5_encryption= atoi(argv[0]);
Harald Weltecca253a2009-08-30 15:47:06 +09001056
1057 return CMD_SUCCESS;
1058}
1059
Holger Hans Peter Freyther96c89822009-11-16 17:12:38 +01001060DEFUN(cfg_net_neci,
1061 cfg_net_neci_cmd,
1062 "neci (0|1)",
Harald Welte18ce31c2010-05-14 20:05:17 +02001063 "New Establish Cause Indication\n"
1064 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freyther96c89822009-11-16 17:12:38 +01001065{
1066 gsmnet->neci = atoi(argv[0]);
1067 return CMD_SUCCESS;
1068}
1069
Harald Welte52af1952009-12-13 10:53:12 +01001070DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
1071 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
Harald Welte9e002452010-05-11 21:53:49 +02001072 "Radio Resource Location Protocol\n"
1073 "Set the Radio Resource Location Protocol Mode\n"
1074 "Don't send RRLP request\n"
1075 "Request MS-based location\n"
1076 "Request any location, prefer MS-based\n"
1077 "Request any location, prefer MS-assisted\n")
Harald Welte52af1952009-12-13 10:53:12 +01001078{
1079 gsmnet->rrlp.mode = rrlp_mode_parse(argv[0]);
1080
1081 return CMD_SUCCESS;
1082}
1083
Harald Weltea310f3e2009-12-14 09:00:24 +01001084DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
1085 "mm info (0|1)",
1086 "Whether to send MM INFO after LOC UPD ACCEPT")
1087{
1088 gsmnet->send_mm_info = atoi(argv[0]);
1089
1090 return CMD_SUCCESS;
1091}
1092
Harald Welte9e002452010-05-11 21:53:49 +02001093#define HANDOVER_STR "Handover Options\n"
1094
Harald Welte0af9c9f2009-12-19 21:41:52 +01001095DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1096 "handover (0|1)",
Harald Welte9e002452010-05-11 21:53:49 +02001097 HANDOVER_STR
1098 "Don't perform in-call handover\n"
1099 "Perform in-call handover\n")
Harald Welte0af9c9f2009-12-19 21:41:52 +01001100{
Holger Hans Peter Freyther3524d4b2010-01-07 16:14:38 +01001101 int enable = atoi(argv[0]);
1102
1103 if (enable && ipacc_rtp_direct) {
Harald Welteaa2c3032009-12-20 13:51:01 +01001104 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1105 "is enabled by using the -P command line option%s",
1106 VTY_NEWLINE);
1107 return CMD_WARNING;
1108 }
Holger Hans Peter Freyther3524d4b2010-01-07 16:14:38 +01001109 gsmnet->handover.active = enable;
Harald Welte0af9c9f2009-12-19 21:41:52 +01001110
1111 return CMD_SUCCESS;
1112}
1113
Harald Welte9e002452010-05-11 21:53:49 +02001114#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1115#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1116#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1117#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
1118
Harald Weltea8062f12009-12-21 16:51:50 +01001119DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1120 "handover window rxlev averaging <1-10>",
Harald Welte9e002452010-05-11 21:53:49 +02001121 HO_WIN_RXLEV_STR
Harald Weltea8062f12009-12-21 16:51:50 +01001122 "How many RxLev measurements are used for averaging")
1123{
1124 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1125 return CMD_SUCCESS;
1126}
1127
1128DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1129 "handover window rxqual averaging <1-10>",
Harald Welte9e002452010-05-11 21:53:49 +02001130 HO_WIN_RXQUAL_STR
Harald Weltea8062f12009-12-21 16:51:50 +01001131 "How many RxQual measurements are used for averaging")
1132{
1133 gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
1134 return CMD_SUCCESS;
1135}
1136
1137DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1138 "handover window rxlev neighbor averaging <1-10>",
Harald Welte9e002452010-05-11 21:53:49 +02001139 HO_WIN_RXLEV_STR
Harald Weltea8062f12009-12-21 16:51:50 +01001140 "How many RxQual measurements are used for averaging")
1141{
1142 gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
1143 return CMD_SUCCESS;
1144}
1145
1146DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1147 "handover power budget interval <1-99>",
Harald Welte9e002452010-05-11 21:53:49 +02001148 HO_PBUDGET_STR
Harald Weltea8062f12009-12-21 16:51:50 +01001149 "How often to check if we have a better cell (SACCH frames)")
1150{
1151 gsmnet->handover.pwr_interval = atoi(argv[0]);
1152 return CMD_SUCCESS;
1153}
1154
1155DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1156 "handover power budget hysteresis <0-999>",
Harald Welte9e002452010-05-11 21:53:49 +02001157 HO_PBUDGET_STR
Harald Weltea8062f12009-12-21 16:51:50 +01001158 "How many dB does a neighbor to be stronger to become a HO candidate")
1159{
1160 gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
1161 return CMD_SUCCESS;
1162}
1163
1164DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1165 "handover maximum distance <0-9999>",
Harald Welte9e002452010-05-11 21:53:49 +02001166 HANDOVER_STR
Harald Weltea8062f12009-12-21 16:51:50 +01001167 "How big is the maximum timing advance before HO is forced")
1168{
1169 gsmnet->handover.max_distance = atoi(argv[0]);
1170 return CMD_SUCCESS;
1171}
Harald Welte0af9c9f2009-12-19 21:41:52 +01001172
Holger Hans Peter Freyther13ae9802009-12-22 08:27:21 +01001173#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freyther26ba2e72009-11-21 21:18:38 +01001174 DEFUN(cfg_net_T##number, \
1175 cfg_net_T##number##_cmd, \
1176 "timer t" #number " <0-65535>", \
Harald Welte9e002452010-05-11 21:53:49 +02001177 "Configure GSM Timers\n" \
Holger Hans Peter Freyther13ae9802009-12-22 08:27:21 +01001178 doc) \
Holger Hans Peter Freyther26ba2e72009-11-21 21:18:38 +01001179{ \
1180 int value = atoi(argv[0]); \
1181 \
1182 if (value < 0 || value > 65535) { \
1183 vty_out(vty, "Timer value %s out of range.%s", \
1184 argv[0], VTY_NEWLINE); \
1185 return CMD_WARNING; \
1186 } \
1187 \
1188 gsmnet->T##number = value; \
1189 return CMD_SUCCESS; \
1190}
1191
Holger Hans Peter Freyther13ae9802009-12-22 08:27:21 +01001192DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT.")
1193DECLARE_TIMER(3103, "Set the timeout value for HANDOVER.")
1194DECLARE_TIMER(3105, "Currently not used.")
1195DECLARE_TIMER(3107, "Currently not used.")
1196DECLARE_TIMER(3109, "Currently not used.")
1197DECLARE_TIMER(3111, "Currently not used.")
1198DECLARE_TIMER(3113, "Set the time to try paging a subscriber.")
1199DECLARE_TIMER(3115, "Currently not used.")
1200DECLARE_TIMER(3117, "Currently not used.")
1201DECLARE_TIMER(3119, "Currently not used.")
1202DECLARE_TIMER(3141, "Currently not used.")
Holger Hans Peter Freyther26ba2e72009-11-21 21:18:38 +01001203
1204
Harald Welte59b04682009-06-10 05:40:52 +08001205/* per-BTS configuration */
1206DEFUN(cfg_bts,
1207 cfg_bts_cmd,
1208 "bts BTS_NR",
Harald Welte9e002452010-05-11 21:53:49 +02001209 "Select a BTS to configure\n"
1210 "BTS Number\n")
Harald Welte59b04682009-06-10 05:40:52 +08001211{
1212 int bts_nr = atoi(argv[0]);
1213 struct gsm_bts *bts;
1214
Harald Weltee712a5f2009-06-21 16:17:15 +02001215 if (bts_nr > gsmnet->num_bts) {
1216 vty_out(vty, "%% The next unused BTS number is %u%s",
1217 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +08001218 return CMD_WARNING;
Harald Weltee712a5f2009-06-21 16:17:15 +02001219 } else if (bts_nr == gsmnet->num_bts) {
1220 /* allocate a new one */
1221 bts = gsm_bts_alloc(gsmnet, GSM_BTS_TYPE_UNKNOWN,
1222 HARDCODED_TSC, HARDCODED_BSIC);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001223 } else
Harald Weltee712a5f2009-06-21 16:17:15 +02001224 bts = gsm_bts_num(gsmnet, bts_nr);
1225
Daniel Willmann580085f2010-01-11 13:43:07 +01001226 if (!bts) {
1227 vty_out(vty, "%% Unable to allocate BTS %u%s",
1228 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee712a5f2009-06-21 16:17:15 +02001229 return CMD_WARNING;
Daniel Willmann580085f2010-01-11 13:43:07 +01001230 }
Harald Welte59b04682009-06-10 05:40:52 +08001231
1232 vty->index = bts;
Harald Welte8791dac2010-05-14 17:59:53 +02001233 vty->index_sub = &bts->description;
Harald Welte59b04682009-06-10 05:40:52 +08001234 vty->node = BTS_NODE;
1235
1236 return CMD_SUCCESS;
1237}
1238
1239DEFUN(cfg_bts_type,
1240 cfg_bts_type_cmd,
1241 "type TYPE",
1242 "Set the BTS type\n")
1243{
1244 struct gsm_bts *bts = vty->index;
Harald Welte59698fb2010-01-10 18:01:52 +01001245 int rc;
Harald Welte59b04682009-06-10 05:40:52 +08001246
Harald Welte59698fb2010-01-10 18:01:52 +01001247 rc = gsm_set_bts_type(bts, parse_btstype(argv[0]));
1248 if (rc < 0)
1249 return CMD_WARNING;
Harald Welte25572872009-10-20 00:22:00 +02001250
Harald Welte59b04682009-06-10 05:40:52 +08001251 return CMD_SUCCESS;
1252}
1253
Harald Welte91afe4c2009-06-20 18:15:19 +02001254DEFUN(cfg_bts_band,
1255 cfg_bts_band_cmd,
1256 "band BAND",
1257 "Set the frequency band of this BTS\n")
1258{
1259 struct gsm_bts *bts = vty->index;
Harald Welte62868882009-08-08 16:12:58 +02001260 int band = gsm_band_parse(argv[0]);
Harald Welte91afe4c2009-06-20 18:15:19 +02001261
1262 if (band < 0) {
1263 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1264 band, VTY_NEWLINE);
1265 return CMD_WARNING;
1266 }
1267
1268 bts->band = band;
1269
1270 return CMD_SUCCESS;
1271}
1272
Holger Hans Peter Freythera098dfb2009-08-21 14:44:12 +02001273DEFUN(cfg_bts_ci,
1274 cfg_bts_ci_cmd,
1275 "cell_identity <0-65535>",
1276 "Set the Cell identity of this BTS\n")
1277{
1278 struct gsm_bts *bts = vty->index;
1279 int ci = atoi(argv[0]);
1280
1281 if (ci < 0 || ci > 0xffff) {
1282 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1283 ci, VTY_NEWLINE);
1284 return CMD_WARNING;
1285 }
1286 bts->cell_identity = ci;
1287
1288 return CMD_SUCCESS;
1289}
1290
Harald Welte59b04682009-06-10 05:40:52 +08001291DEFUN(cfg_bts_lac,
1292 cfg_bts_lac_cmd,
Holger Hans Peter Freyther54a22832009-09-29 14:02:33 +02001293 "location_area_code <0-65535>",
Harald Welte59b04682009-06-10 05:40:52 +08001294 "Set the Location Area Code (LAC) of this BTS\n")
1295{
1296 struct gsm_bts *bts = vty->index;
1297 int lac = atoi(argv[0]);
1298
Holger Hans Peter Freyther54a22832009-09-29 14:02:33 +02001299 if (lac < 0 || lac > 0xffff) {
1300 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte59b04682009-06-10 05:40:52 +08001301 lac, VTY_NEWLINE);
1302 return CMD_WARNING;
1303 }
Holger Hans Peter Freyther6c6ab862009-10-01 04:07:15 +02001304
1305 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1306 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1307 lac, VTY_NEWLINE);
1308 return CMD_WARNING;
1309 }
1310
Harald Welte59b04682009-06-10 05:40:52 +08001311 bts->location_area_code = lac;
1312
1313 return CMD_SUCCESS;
1314}
1315
Harald Weltea54a2bb2009-12-01 18:04:30 +05301316
Harald Welte59b04682009-06-10 05:40:52 +08001317DEFUN(cfg_bts_tsc,
1318 cfg_bts_tsc_cmd,
1319 "training_sequence_code <0-255>",
1320 "Set the Training Sequence Code (TSC) of this BTS\n")
1321{
1322 struct gsm_bts *bts = vty->index;
1323 int tsc = atoi(argv[0]);
1324
1325 if (tsc < 0 || tsc > 0xff) {
1326 vty_out(vty, "%% TSC %d is not in the valid range (0-255)%s",
1327 tsc, VTY_NEWLINE);
1328 return CMD_WARNING;
1329 }
1330 bts->tsc = tsc;
1331
1332 return CMD_SUCCESS;
1333}
1334
1335DEFUN(cfg_bts_bsic,
1336 cfg_bts_bsic_cmd,
1337 "base_station_id_code <0-63>",
1338 "Set the Base Station Identity Code (BSIC) of this BTS\n")
1339{
1340 struct gsm_bts *bts = vty->index;
1341 int bsic = atoi(argv[0]);
1342
1343 if (bsic < 0 || bsic > 0x3f) {
Harald Welte62868882009-08-08 16:12:58 +02001344 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte59b04682009-06-10 05:40:52 +08001345 bsic, VTY_NEWLINE);
1346 return CMD_WARNING;
1347 }
1348 bts->bsic = bsic;
1349
1350 return CMD_SUCCESS;
1351}
1352
1353
1354DEFUN(cfg_bts_unit_id,
1355 cfg_bts_unit_id_cmd,
Harald Weltef515aa02009-08-07 13:27:09 +02001356 "ip.access unit_id <0-65534> <0-255>",
1357 "Set the ip.access BTS Unit ID of this BTS\n")
Harald Welte59b04682009-06-10 05:40:52 +08001358{
1359 struct gsm_bts *bts = vty->index;
1360 int site_id = atoi(argv[0]);
1361 int bts_id = atoi(argv[1]);
1362
Harald Weltef515aa02009-08-07 13:27:09 +02001363 if (!is_ipaccess_bts(bts)) {
1364 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1365 return CMD_WARNING;
1366 }
1367
Harald Welte59b04682009-06-10 05:40:52 +08001368 bts->ip_access.site_id = site_id;
1369 bts->ip_access.bts_id = bts_id;
1370
1371 return CMD_SUCCESS;
1372}
1373
Harald Welte9e002452010-05-11 21:53:49 +02001374#define OML_STR "Organization & Maintenance Link\n"
1375#define IPA_STR "ip.access Specific Options\n"
1376
Harald Welte25572872009-10-20 00:22:00 +02001377DEFUN(cfg_bts_stream_id,
1378 cfg_bts_stream_id_cmd,
1379 "oml ip.access stream_id <0-255>",
Harald Welte9e002452010-05-11 21:53:49 +02001380 OML_STR IPA_STR
Harald Welte25572872009-10-20 00:22:00 +02001381 "Set the ip.access Stream ID of the OML link of this BTS\n")
1382{
1383 struct gsm_bts *bts = vty->index;
1384 int stream_id = atoi(argv[0]);
1385
1386 if (!is_ipaccess_bts(bts)) {
1387 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1388 return CMD_WARNING;
1389 }
1390
1391 bts->oml_tei = stream_id;
1392
1393 return CMD_SUCCESS;
1394}
1395
Harald Welte9e002452010-05-11 21:53:49 +02001396#define OML_E1_STR OML_STR "E1 Line\n"
Harald Welte25572872009-10-20 00:22:00 +02001397
Harald Welte62868882009-08-08 16:12:58 +02001398DEFUN(cfg_bts_oml_e1,
1399 cfg_bts_oml_e1_cmd,
1400 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welte9e002452010-05-11 21:53:49 +02001401 OML_E1_STR
Harald Welte62868882009-08-08 16:12:58 +02001402 "E1 interface to be used for OML\n")
1403{
1404 struct gsm_bts *bts = vty->index;
1405
1406 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
1407
1408 return CMD_SUCCESS;
1409}
1410
1411
1412DEFUN(cfg_bts_oml_e1_tei,
1413 cfg_bts_oml_e1_tei_cmd,
1414 "oml e1 tei <0-63>",
Harald Welte9e002452010-05-11 21:53:49 +02001415 OML_E1_STR
Harald Welte62868882009-08-08 16:12:58 +02001416 "Set the TEI to be used for OML")
1417{
1418 struct gsm_bts *bts = vty->index;
1419
1420 bts->oml_tei = atoi(argv[0]);
1421
1422 return CMD_SUCCESS;
1423}
1424
Harald Welte3e774612009-08-10 13:48:16 +02001425DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
1426 "channel allocator (ascending|descending)",
Harald Welte9e002452010-05-11 21:53:49 +02001427 "Channnel Allocator\n" "Channel Allocator\n"
1428 "Allocate Timeslots and Transceivers in ascending order\n"
1429 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte3e774612009-08-10 13:48:16 +02001430{
1431 struct gsm_bts *bts = vty->index;
1432
1433 if (!strcmp(argv[0], "ascending"))
1434 bts->chan_alloc_reverse = 0;
1435 else
1436 bts->chan_alloc_reverse = 1;
1437
1438 return CMD_SUCCESS;
1439}
1440
Harald Welte9e002452010-05-11 21:53:49 +02001441#define RACH_STR "Random Access Control Channel\n"
1442
Sylvain Munaut8e2d8de2009-12-22 13:43:26 +01001443DEFUN(cfg_bts_rach_tx_integer,
1444 cfg_bts_rach_tx_integer_cmd,
1445 "rach tx integer <0-15>",
Harald Welte9e002452010-05-11 21:53:49 +02001446 RACH_STR
Sylvain Munaut8e2d8de2009-12-22 13:43:26 +01001447 "Set the raw tx integer value in RACH Control parameters IE")
1448{
1449 struct gsm_bts *bts = vty->index;
1450 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
1451 return CMD_SUCCESS;
1452}
1453
1454DEFUN(cfg_bts_rach_max_trans,
1455 cfg_bts_rach_max_trans_cmd,
1456 "rach max transmission (1|2|4|7)",
Harald Welte9e002452010-05-11 21:53:49 +02001457 RACH_STR
Sylvain Munaut8e2d8de2009-12-22 13:43:26 +01001458 "Set the maximum number of RACH burst transmissions")
1459{
1460 struct gsm_bts *bts = vty->index;
1461 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
1462 return CMD_SUCCESS;
1463}
1464
Harald Welte9e002452010-05-11 21:53:49 +02001465#define NM_STR "Network Management\n"
1466
Holger Hans Peter Freyther697ed2b2010-04-25 23:08:39 +08001467DEFUN(cfg_bts_rach_nm_b_thresh,
1468 cfg_bts_rach_nm_b_thresh_cmd,
1469 "rach nm busy threshold <0-255>",
Harald Welte9e002452010-05-11 21:53:49 +02001470 RACH_STR NM_STR
1471 "Set the NM Busy Threshold in dB")
Holger Hans Peter Freyther697ed2b2010-04-25 23:08:39 +08001472{
1473 struct gsm_bts *bts = vty->index;
1474 bts->rach_b_thresh = atoi(argv[0]);
1475 return CMD_SUCCESS;
1476}
1477
1478DEFUN(cfg_bts_rach_nm_ldavg,
1479 cfg_bts_rach_nm_ldavg_cmd,
1480 "rach nm load average <0-65535>",
Harald Welte9e002452010-05-11 21:53:49 +02001481 RACH_STR NM_STR
1482 "Set the NM Loadaverage Slots value")
Holger Hans Peter Freyther697ed2b2010-04-25 23:08:39 +08001483{
1484 struct gsm_bts *bts = vty->index;
1485 bts->rach_ldavg_slots = atoi(argv[0]);
1486 return CMD_SUCCESS;
1487}
1488
Harald Welte (local)e19be3f2009-08-12 13:28:23 +02001489DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
1490 "cell barred (0|1)",
1491 "Should this cell be barred from access?")
1492{
1493 struct gsm_bts *bts = vty->index;
1494
Harald Welte8c973ba2009-12-21 23:08:18 +01001495 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)e19be3f2009-08-12 13:28:23 +02001496
1497 return CMD_SUCCESS;
1498}
1499
Holger Hans Peter Freyther440984b2010-05-14 00:39:19 +08001500DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
1501 "rach emergency call allowed (0|1)",
1502 "Should this cell allow emergency calls?")
1503{
1504 struct gsm_bts *bts = vty->index;
1505
1506 if (atoi(argv[0]) == 0)
1507 bts->si_common.rach_control.t2 |= 0x4;
1508 else
1509 bts->si_common.rach_control.t2 &= ~0x4;
1510
1511 return CMD_SUCCESS;
1512}
1513
Harald Welte (local)cbd46102009-08-13 10:14:26 +02001514DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
1515 "ms max power <0-40>",
1516 "Maximum transmit power of the MS")
1517{
1518 struct gsm_bts *bts = vty->index;
1519
1520 bts->ms_max_power = atoi(argv[0]);
1521
1522 return CMD_SUCCESS;
1523}
1524
Harald Welteb761bf82009-12-12 18:17:25 +01001525DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
1526 "cell reselection hysteresis <0-14>",
1527 "Cell Re-Selection Hysteresis in dB")
1528{
1529 struct gsm_bts *bts = vty->index;
1530
1531 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
1532
1533 return CMD_SUCCESS;
1534}
1535
1536DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
1537 "rxlev access min <0-63>",
1538 "Minimum RxLev needed for cell access (better than -110dBm)")
1539{
1540 struct gsm_bts *bts = vty->index;
1541
1542 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
1543
1544 return CMD_SUCCESS;
1545}
1546
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +02001547DEFUN(cfg_bts_per_loc_upd, cfg_bts_per_loc_upd_cmd,
1548 "periodic location update <0-1530>",
1549 "Periodic Location Updating Interval in Minutes")
1550{
1551 struct gsm_bts *bts = vty->index;
1552
Harald Weltea54a2bb2009-12-01 18:04:30 +05301553 bts->si_common.chan_desc.t3212 = atoi(argv[0]) / 10;
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +02001554
1555 return CMD_SUCCESS;
1556}
1557
Harald Welte9e002452010-05-11 21:53:49 +02001558#define GPRS_TEXT "GPRS Packet Network\n"
1559
Harald Welte410575a2010-03-14 23:30:30 +08001560DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welteb42fe342010-04-18 14:00:26 +02001561 "gprs cell bvci <2-65535>",
Harald Welte9e002452010-05-11 21:53:49 +02001562 GPRS_TEXT
1563 "GPRS Cell Settings\n"
Harald Welte3055e332010-03-14 15:37:43 +08001564 "GPRS BSSGP VC Identifier")
1565{
1566 struct gsm_bts *bts = vty->index;
1567
Harald Weltecb20b7a2010-04-18 15:51:20 +02001568 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltec05a4b12010-03-14 23:56:56 +08001569 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1570 return CMD_WARNING;
1571 }
1572
Harald Welte3055e332010-03-14 15:37:43 +08001573 bts->gprs.cell.bvci = atoi(argv[0]);
1574
1575 return CMD_SUCCESS;
1576}
1577
Harald Welte4a048c52010-03-22 11:48:36 +08001578DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
1579 "gprs nsei <0-65535>",
Harald Welte9e002452010-05-11 21:53:49 +02001580 GPRS_TEXT
Harald Welte4a048c52010-03-22 11:48:36 +08001581 "GPRS NS Entity Identifier")
1582{
1583 struct gsm_bts *bts = vty->index;
1584
Harald Weltecb20b7a2010-04-18 15:51:20 +02001585 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte4a048c52010-03-22 11:48:36 +08001586 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1587 return CMD_WARNING;
1588 }
1589
1590 bts->gprs.nse.nsei = atoi(argv[0]);
1591
1592 return CMD_SUCCESS;
1593}
1594
Harald Welte9e002452010-05-11 21:53:49 +02001595#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
1596 "NSVC Logical Number\n"
Harald Welte4a048c52010-03-22 11:48:36 +08001597
Harald Welte3055e332010-03-14 15:37:43 +08001598DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
1599 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte9e002452010-05-11 21:53:49 +02001600 GPRS_TEXT NSVC_TEXT
1601 "NS Virtual Connection Identifier\n"
Harald Welte3055e332010-03-14 15:37:43 +08001602 "GPRS NS VC Identifier")
1603{
1604 struct gsm_bts *bts = vty->index;
1605 int idx = atoi(argv[0]);
1606
Harald Weltecb20b7a2010-04-18 15:51:20 +02001607 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltec05a4b12010-03-14 23:56:56 +08001608 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1609 return CMD_WARNING;
1610 }
1611
Harald Welte3055e332010-03-14 15:37:43 +08001612 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
1613
1614 return CMD_SUCCESS;
1615}
1616
Harald Welte410575a2010-03-14 23:30:30 +08001617DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
1618 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte9e002452010-05-11 21:53:49 +02001619 GPRS_TEXT NSVC_TEXT
Harald Welte410575a2010-03-14 23:30:30 +08001620 "GPRS NS Local UDP Port")
1621{
1622 struct gsm_bts *bts = vty->index;
1623 int idx = atoi(argv[0]);
1624
Harald Weltecb20b7a2010-04-18 15:51:20 +02001625 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltec05a4b12010-03-14 23:56:56 +08001626 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1627 return CMD_WARNING;
1628 }
1629
Harald Welte410575a2010-03-14 23:30:30 +08001630 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
1631
1632 return CMD_SUCCESS;
1633}
1634
1635DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
1636 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte9e002452010-05-11 21:53:49 +02001637 GPRS_TEXT NSVC_TEXT
Harald Welte410575a2010-03-14 23:30:30 +08001638 "GPRS NS Remote UDP Port")
1639{
1640 struct gsm_bts *bts = vty->index;
1641 int idx = atoi(argv[0]);
1642
Harald Weltecb20b7a2010-04-18 15:51:20 +02001643 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltec05a4b12010-03-14 23:56:56 +08001644 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1645 return CMD_WARNING;
1646 }
1647
Harald Welte410575a2010-03-14 23:30:30 +08001648 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
1649
1650 return CMD_SUCCESS;
1651}
1652
1653DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
1654 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte9e002452010-05-11 21:53:49 +02001655 GPRS_TEXT NSVC_TEXT
Harald Welte410575a2010-03-14 23:30:30 +08001656 "GPRS NS Remote IP Address")
1657{
1658 struct gsm_bts *bts = vty->index;
1659 int idx = atoi(argv[0]);
1660 struct in_addr ia;
1661
Harald Weltecb20b7a2010-04-18 15:51:20 +02001662 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltec05a4b12010-03-14 23:56:56 +08001663 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1664 return CMD_WARNING;
1665 }
1666
Harald Welte410575a2010-03-14 23:30:30 +08001667 inet_aton(argv[1], &ia);
1668 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
1669
1670 return CMD_SUCCESS;
1671}
1672
Harald Weltea9251762010-05-11 23:50:21 +02001673DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
1674 "gprs ns timer " NS_TIMERS " <0-255>",
1675 GPRS_TEXT "Network Service\n"
1676 "Network Service Timer\n"
1677 NS_TIMERS_HELP "Timer Value\n")
1678{
1679 struct gsm_bts *bts = vty->index;
1680 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
1681 int val = atoi(argv[1]);
1682
1683 if (bts->gprs.mode == BTS_GPRS_NONE) {
1684 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1685 return CMD_WARNING;
1686 }
1687
1688 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
1689 return CMD_WARNING;
1690
1691 bts->gprs.nse.timer[idx] = val;
1692
1693 return CMD_SUCCESS;
1694}
1695
1696#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)"
Harald Welte18ce31c2010-05-14 20:05:17 +02001697#define BSSGP_TIMERS_HELP \
1698 "Tbvc-block timeout\n" \
1699 "Tbvc-block retries\n" \
1700 "Tbvc-unblock retries\n" \
1701 "Tbvcc-reset timeout\n" \
1702 "Tbvc-reset retries\n" \
1703 "Tbvc-suspend timeout\n" \
1704 "Tbvc-suspend retries\n" \
1705 "Tbvc-resume timeout\n" \
1706 "Tbvc-resume retries\n" \
1707 "Tbvc-capa-update timeout\n" \
1708 "Tbvc-capa-update retries\n"
Harald Weltea9251762010-05-11 23:50:21 +02001709
1710DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
1711 "gprs cell timer " BSSGP_TIMERS " <0-255>",
1712 GPRS_TEXT "Cell / BSSGP\n"
1713 "Cell/BSSGP Timer\n"
1714 BSSGP_TIMERS_HELP "Timer Value\n")
1715{
1716 struct gsm_bts *bts = vty->index;
1717 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
1718 int val = atoi(argv[1]);
1719
1720 if (bts->gprs.mode == BTS_GPRS_NONE) {
1721 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1722 return CMD_WARNING;
1723 }
1724
1725 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
1726 return CMD_WARNING;
1727
1728 bts->gprs.cell.timer[idx] = val;
1729
1730 return CMD_SUCCESS;
1731}
1732
Harald Welte3055e332010-03-14 15:37:43 +08001733DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
1734 "gprs routing area <0-255>",
Harald Welte9e002452010-05-11 21:53:49 +02001735 GPRS_TEXT
Harald Welte3055e332010-03-14 15:37:43 +08001736 "GPRS Routing Area Code")
1737{
1738 struct gsm_bts *bts = vty->index;
1739
Harald Weltecb20b7a2010-04-18 15:51:20 +02001740 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltec05a4b12010-03-14 23:56:56 +08001741 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
1742 return CMD_WARNING;
1743 }
1744
Harald Welte3055e332010-03-14 15:37:43 +08001745 bts->gprs.rac = atoi(argv[0]);
1746
1747 return CMD_SUCCESS;
1748}
1749
Harald Weltecb20b7a2010-04-18 15:51:20 +02001750DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
1751 "gprs mode (none|gprs|egprs)",
Harald Welte9e002452010-05-11 21:53:49 +02001752 GPRS_TEXT
1753 "GPRS Mode for this BTS\n"
1754 "GPRS Disabled on this BTS\n"
1755 "GPRS Enabled on this BTS\n"
1756 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welte410575a2010-03-14 23:30:30 +08001757{
1758 struct gsm_bts *bts = vty->index;
1759
Harald Weltecb20b7a2010-04-18 15:51:20 +02001760 bts->gprs.mode = bts_gprs_mode_parse(argv[0]);
Harald Welte410575a2010-03-14 23:30:30 +08001761
1762 return CMD_SUCCESS;
1763}
1764
Harald Welte9e002452010-05-11 21:53:49 +02001765#define TRX_TEXT "Radio Transceiver\n"
Harald Welte3e774612009-08-10 13:48:16 +02001766
Harald Welte59b04682009-06-10 05:40:52 +08001767/* per TRX configuration */
1768DEFUN(cfg_trx,
1769 cfg_trx_cmd,
1770 "trx TRX_NR",
Harald Welte9e002452010-05-11 21:53:49 +02001771 TRX_TEXT
Harald Welte59b04682009-06-10 05:40:52 +08001772 "Select a TRX to configure")
1773{
1774 int trx_nr = atoi(argv[0]);
1775 struct gsm_bts *bts = vty->index;
1776 struct gsm_bts_trx *trx;
1777
Harald Weltee712a5f2009-06-21 16:17:15 +02001778 if (trx_nr > bts->num_trx) {
1779 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
1780 bts->num_trx, VTY_NEWLINE);
Harald Welte59b04682009-06-10 05:40:52 +08001781 return CMD_WARNING;
Harald Weltee712a5f2009-06-21 16:17:15 +02001782 } else if (trx_nr == bts->num_trx) {
1783 /* we need to allocate a new one */
1784 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001785 } else
Harald Weltee712a5f2009-06-21 16:17:15 +02001786 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther71135142010-03-29 08:47:44 +02001787
Harald Weltee712a5f2009-06-21 16:17:15 +02001788 if (!trx)
1789 return CMD_WARNING;
Harald Welte59b04682009-06-10 05:40:52 +08001790
1791 vty->index = trx;
Harald Welte8791dac2010-05-14 17:59:53 +02001792 vty->index_sub = &trx->description;
Harald Welte59b04682009-06-10 05:40:52 +08001793 vty->node = TRX_NODE;
1794
1795 return CMD_SUCCESS;
1796}
1797
1798DEFUN(cfg_trx_arfcn,
1799 cfg_trx_arfcn_cmd,
Harald Welte00044592010-05-14 19:00:52 +02001800 "arfcn <0-1024>",
Harald Welte59b04682009-06-10 05:40:52 +08001801 "Set the ARFCN for this TRX\n")
1802{
1803 int arfcn = atoi(argv[0]);
1804 struct gsm_bts_trx *trx = vty->index;
1805
1806 /* FIXME: check if this ARFCN is supported by this TRX */
1807
1808 trx->arfcn = arfcn;
1809
1810 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
1811 /* FIXME: use OML layer to update the ARFCN */
1812 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
1813
1814 return CMD_SUCCESS;
1815}
1816
Harald Welte (local)b709bfe2009-12-27 20:56:38 +01001817DEFUN(cfg_trx_nominal_power,
1818 cfg_trx_nominal_power_cmd,
1819 "nominal power <0-100>",
1820 "Nominal TRX RF Power in dB\n")
1821{
1822 struct gsm_bts_trx *trx = vty->index;
1823
1824 trx->nominal_power = atoi(argv[0]);
1825
1826 return CMD_SUCCESS;
1827}
1828
Harald Welte91afe4c2009-06-20 18:15:19 +02001829DEFUN(cfg_trx_max_power_red,
1830 cfg_trx_max_power_red_cmd,
1831 "max_power_red <0-100>",
1832 "Reduction of maximum BS RF Power in dB\n")
1833{
1834 int maxpwr_r = atoi(argv[0]);
1835 struct gsm_bts_trx *trx = vty->index;
Harald Welte01acd742009-11-18 09:20:22 +01001836 int upper_limit = 24; /* default 12.21 max power red. */
Harald Welte91afe4c2009-06-20 18:15:19 +02001837
1838 /* FIXME: check if our BTS type supports more than 12 */
1839 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
1840 vty_out(vty, "%% Power %d dB is not in the valid range%s",
1841 maxpwr_r, VTY_NEWLINE);
1842 return CMD_WARNING;
1843 }
1844 if (maxpwr_r & 1) {
1845 vty_out(vty, "%% Power %d dB is not an even value%s",
1846 maxpwr_r, VTY_NEWLINE);
1847 return CMD_WARNING;
1848 }
1849
1850 trx->max_power_red = maxpwr_r;
1851
1852 /* FIXME: make sure we update this using OML */
1853
1854 return CMD_SUCCESS;
1855}
1856
Harald Welte62868882009-08-08 16:12:58 +02001857DEFUN(cfg_trx_rsl_e1,
1858 cfg_trx_rsl_e1_cmd,
1859 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
1860 "E1 interface to be used for RSL\n")
1861{
1862 struct gsm_bts_trx *trx = vty->index;
1863
1864 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
1865
1866 return CMD_SUCCESS;
1867}
1868
1869DEFUN(cfg_trx_rsl_e1_tei,
1870 cfg_trx_rsl_e1_tei_cmd,
1871 "rsl e1 tei <0-63>",
1872 "Set the TEI to be used for RSL")
1873{
1874 struct gsm_bts_trx *trx = vty->index;
1875
1876 trx->rsl_tei = atoi(argv[0]);
1877
1878 return CMD_SUCCESS;
1879}
1880
Holger Hans Peter Freyther1c8b4802009-11-11 11:54:24 +01001881DEFUN(cfg_trx_rf_locked,
1882 cfg_trx_rf_locked_cmd,
1883 "rf_locked (0|1)",
1884 "Turn off RF of the TRX.\n")
1885{
1886 int locked = atoi(argv[0]);
1887 struct gsm_bts_trx *trx = vty->index;
1888
1889 gsm_trx_lock_rf(trx, locked);
1890 return CMD_SUCCESS;
1891}
Harald Welte62868882009-08-08 16:12:58 +02001892
Harald Welte59b04682009-06-10 05:40:52 +08001893/* per TS configuration */
1894DEFUN(cfg_ts,
1895 cfg_ts_cmd,
Harald Welte62868882009-08-08 16:12:58 +02001896 "timeslot <0-7>",
Harald Welte59b04682009-06-10 05:40:52 +08001897 "Select a Timeslot to configure")
1898{
1899 int ts_nr = atoi(argv[0]);
1900 struct gsm_bts_trx *trx = vty->index;
1901 struct gsm_bts_trx_ts *ts;
1902
1903 if (ts_nr >= TRX_NR_TS) {
1904 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
1905 TRX_NR_TS, VTY_NEWLINE);
1906 return CMD_WARNING;
1907 }
1908
1909 ts = &trx->ts[ts_nr];
1910
1911 vty->index = ts;
1912 vty->node = TS_NODE;
1913
1914 return CMD_SUCCESS;
1915}
1916
Harald Welte3ffe1b32009-08-07 00:25:23 +02001917DEFUN(cfg_ts_pchan,
1918 cfg_ts_pchan_cmd,
1919 "phys_chan_config PCHAN",
1920 "Physical Channel configuration (TCH/SDCCH/...)")
1921{
1922 struct gsm_bts_trx_ts *ts = vty->index;
1923 int pchanc;
1924
1925 pchanc = gsm_pchan_parse(argv[0]);
1926 if (pchanc < 0)
1927 return CMD_WARNING;
1928
1929 ts->pchan = pchanc;
1930
1931 return CMD_SUCCESS;
1932}
1933
1934DEFUN(cfg_ts_e1_subslot,
1935 cfg_ts_e1_subslot_cmd,
Harald Welte62868882009-08-08 16:12:58 +02001936 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welte3ffe1b32009-08-07 00:25:23 +02001937 "E1 sub-slot connected to this on-air timeslot")
1938{
1939 struct gsm_bts_trx_ts *ts = vty->index;
1940
Harald Welte62868882009-08-08 16:12:58 +02001941 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Welte3ffe1b32009-08-07 00:25:23 +02001942
1943 return CMD_SUCCESS;
1944}
Harald Welte59b04682009-06-10 05:40:52 +08001945
Holger Hans Peter Freytherc48a2a12010-04-10 00:08:28 +02001946extern int bsc_vty_init_extra(struct gsm_network *net);
Harald Welte10c29f62010-05-16 19:20:24 +02001947extern const char *openbsc_copyright;
Holger Hans Peter Freytherc48a2a12010-04-10 00:08:28 +02001948
Harald Welte59b04682009-06-10 05:40:52 +08001949int bsc_vty_init(struct gsm_network *net)
1950{
1951 gsmnet = net;
1952
1953 cmd_init(1);
Harald Welte10c29f62010-05-16 19:20:24 +02001954 vty_init("OpenBSC", PACKAGE_VERSION, openbsc_copyright);
Harald Welte59b04682009-06-10 05:40:52 +08001955
Harald Welte7bc28f62010-05-12 16:10:35 +00001956 install_element_ve(&show_net_cmd);
1957 install_element_ve(&show_bts_cmd);
1958 install_element_ve(&show_trx_cmd);
1959 install_element_ve(&show_ts_cmd);
1960 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freythere959b4e2010-05-14 02:08:49 +08001961 install_element_ve(&show_lchan_summary_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001962
Harald Welte7bc28f62010-05-12 16:10:35 +00001963 install_element_ve(&show_e1drv_cmd);
1964 install_element_ve(&show_e1line_cmd);
1965 install_element_ve(&show_e1ts_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001966
Harald Welte7bc28f62010-05-12 16:10:35 +00001967 install_element_ve(&show_paging_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08001968
Holger Hans Peter Freytherb70d45b2010-04-06 11:55:37 +02001969 openbsc_vty_add_cmds();
Holger Hans Peter Freytherc8d862e2009-12-22 22:32:51 +01001970
Harald Weltee87eb462009-08-07 13:29:14 +02001971 install_element(CONFIG_NODE, &cfg_net_cmd);
1972 install_node(&net_node, config_write_net);
1973 install_default(GSMNET_NODE);
Harald Welte58ed1cb2010-05-14 18:59:17 +02001974 install_element(GSMNET_NODE, &ournode_exit_cmd);
Harald Weltedc82b9b2010-05-14 19:11:04 +02001975 install_element(GSMNET_NODE, &ournode_end_cmd);
Harald Welte62868882009-08-08 16:12:58 +02001976 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
Harald Weltee87eb462009-08-07 13:29:14 +02001977 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1978 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1979 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
Harald Welte (local)a59a27e2009-08-12 14:42:23 +02001980 install_element(GSMNET_NODE, &cfg_net_auth_policy_cmd);
Harald Welte59936d72009-11-18 20:33:19 +01001981 install_element(GSMNET_NODE, &cfg_net_reject_cause_cmd);
Harald Weltecca253a2009-08-30 15:47:06 +09001982 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
Holger Hans Peter Freyther96c89822009-11-16 17:12:38 +01001983 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Welte52af1952009-12-13 10:53:12 +01001984 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
Harald Welte284ddba2009-12-14 17:49:15 +01001985 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
Harald Welte0af9c9f2009-12-19 21:41:52 +01001986 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Weltea8062f12009-12-21 16:51:50 +01001987 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
1988 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
1989 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
1990 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
1991 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
1992 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freyther26ba2e72009-11-21 21:18:38 +01001993 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther89733862009-11-21 21:42:26 +01001994 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
1995 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
1996 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
1997 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
1998 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
1999 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
2000 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
2001 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
2002 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
2003 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Harald Weltee87eb462009-08-07 13:29:14 +02002004
2005 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte97ceef92009-08-06 19:06:46 +02002006 install_node(&bts_node, config_write_bts);
Harald Welte59b04682009-06-10 05:40:52 +08002007 install_default(BTS_NODE);
Harald Welte58ed1cb2010-05-14 18:59:17 +02002008 install_element(BTS_NODE, &ournode_exit_cmd);
Harald Weltedc82b9b2010-05-14 19:11:04 +02002009 install_element(BTS_NODE, &ournode_end_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08002010 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte8791dac2010-05-14 17:59:53 +02002011 install_element(BTS_NODE, &cfg_description_cmd);
2012 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Welte91afe4c2009-06-20 18:15:19 +02002013 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freythera098dfb2009-08-21 14:44:12 +02002014 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08002015 install_element(BTS_NODE, &cfg_bts_lac_cmd);
2016 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte62868882009-08-08 16:12:58 +02002017 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08002018 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte25572872009-10-20 00:22:00 +02002019 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte62868882009-08-08 16:12:58 +02002020 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
2021 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte3e774612009-08-10 13:48:16 +02002022 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut8e2d8de2009-12-22 13:43:26 +01002023 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
2024 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Holger Hans Peter Freyther697ed2b2010-04-25 23:08:39 +08002025 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
2026 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)e19be3f2009-08-12 13:28:23 +02002027 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther440984b2010-05-14 00:39:19 +08002028 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Harald Welte (local)cbd46102009-08-13 10:14:26 +02002029 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte (local)b6ea7f72009-08-14 23:09:25 +02002030 install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd);
Harald Welteb761bf82009-12-12 18:17:25 +01002031 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
2032 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Harald Weltecb20b7a2010-04-18 15:51:20 +02002033 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
Harald Weltea9251762010-05-11 23:50:21 +02002034 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte3055e332010-03-14 15:37:43 +08002035 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
2036 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Weltea9251762010-05-11 23:50:21 +02002037 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Welte4a048c52010-03-22 11:48:36 +08002038 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte3055e332010-03-14 15:37:43 +08002039 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welte410575a2010-03-14 23:30:30 +08002040 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
2041 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
2042 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08002043
2044 install_element(BTS_NODE, &cfg_trx_cmd);
2045 install_node(&trx_node, dummy_config_write);
2046 install_default(TRX_NODE);
Harald Welte58ed1cb2010-05-14 18:59:17 +02002047 install_element(TRX_NODE, &ournode_exit_cmd);
Harald Weltedc82b9b2010-05-14 19:11:04 +02002048 install_element(TRX_NODE, &ournode_end_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08002049 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte8791dac2010-05-14 17:59:53 +02002050 install_element(TRX_NODE, &cfg_description_cmd);
2051 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)b709bfe2009-12-27 20:56:38 +01002052 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte7f597bc2009-06-20 22:36:12 +02002053 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte62868882009-08-08 16:12:58 +02002054 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
2055 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther1c8b4802009-11-11 11:54:24 +01002056 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08002057
2058 install_element(TRX_NODE, &cfg_ts_cmd);
2059 install_node(&ts_node, dummy_config_write);
2060 install_default(TS_NODE);
Harald Welte58ed1cb2010-05-14 18:59:17 +02002061 install_element(TS_NODE, &ournode_exit_cmd);
Harald Weltedc82b9b2010-05-14 19:11:04 +02002062 install_element(TS_NODE, &ournode_end_cmd);
Harald Welte3ffe1b32009-08-07 00:25:23 +02002063 install_element(TS_NODE, &cfg_ts_pchan_cmd);
2064 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte59b04682009-06-10 05:40:52 +08002065
Holger Hans Peter Freytherbdae6f92009-08-10 10:17:50 +02002066 bsc_vty_init_extra(net);
Harald Welte59b04682009-06-10 05:40:52 +08002067
2068 return 0;
2069}