blob: 64a92b2019a05366e91c1817f5f3871d99110476 [file] [log] [blame]
Harald Welte68628e82009-03-10 12:17:57 +00001/* OpenBSC interface to quagga VTY */
Harald Welteaf387632010-03-14 23:30:30 +08002/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte68628e82009-03-10 12:17:57 +00003 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01006 * it under the terms of the GNU Affero General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
Harald Welte68628e82009-03-10 12:17:57 +00008 * (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
Harald Welte9af6ddf2011-01-01 15:25:50 +010013 * GNU Affero General Public License for more details.
Harald Welte68628e82009-03-10 12:17:57 +000014 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010015 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte68628e82009-03-10 12:17:57 +000017 *
18 */
19
20#include <stdlib.h>
Maxc08ee712016-05-11 12:45:13 +020021#include <stdbool.h>
Harald Welte68628e82009-03-10 12:17:57 +000022#include <unistd.h>
Maxd1f70ed2017-09-21 16:15:32 +020023#include <time.h>
Harald Welte68628e82009-03-10 12:17:57 +000024
Harald Welte4b037e42010-05-19 19:45:32 +020025#include <osmocom/vty/command.h>
26#include <osmocom/vty/buffer.h>
27#include <osmocom/vty/vty.h>
28#include <osmocom/vty/logging.h>
Jacob Erlbeck64630cc2015-10-26 16:25:37 +010029#include <osmocom/vty/stats.h>
Harald Welte4b037e42010-05-19 19:45:32 +020030#include <osmocom/vty/telnet_interface.h>
Harald Welte4ab9d7c2012-08-17 12:42:06 +020031#include <osmocom/vty/misc.h>
Maxc08ee712016-05-11 12:45:13 +020032#include <osmocom/gsm/protocol/gsm_04_08.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010033#include <osmocom/gsm/gsm0502.h>
Harald Welteb71147a2017-07-18 19:11:49 +020034#include <osmocom/ctrl/control_if.h>
Neels Hofmeyr7b656882017-07-09 22:09:18 +020035#include <osmocom/gsm/gsm48.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010036
Harald Welte68628e82009-03-10 12:17:57 +000037#include <arpa/inet.h>
38
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010039#include <osmocom/core/linuxlist.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020040#include <osmocom/bsc/gsm_data.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020041#include <osmocom/abis/e1_input.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020042#include <osmocom/bsc/abis_nm.h>
43#include <osmocom/bsc/abis_om2000.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010044#include <osmocom/core/utils.h>
45#include <osmocom/gsm/gsm_utils.h>
Harald Weltecdc59ff2011-05-23 20:42:26 +020046#include <osmocom/gsm/abis_nm.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020047#include <osmocom/bsc/chan_alloc.h>
48#include <osmocom/bsc/meas_rep.h>
49#include <osmocom/bsc/vty.h>
Harald Welteea34a4e2012-06-16 14:59:56 +080050#include <osmocom/gprs/gprs_ns.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020051#include <osmocom/bsc/system_information.h>
52#include <osmocom/bsc/debug.h>
53#include <osmocom/bsc/paging.h>
54#include <osmocom/bsc/ipaccess.h>
55#include <osmocom/bsc/abis_rsl.h>
56#include <osmocom/bsc/bsc_msc_data.h>
57#include <osmocom/bsc/osmo_bsc_rf.h>
58#include <osmocom/bsc/pcu_if.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020059#include <osmocom/bsc/handover.h>
Neels Hofmeyre25018b2017-11-27 21:29:33 +010060#include <osmocom/bsc/handover_cfg.h>
61#include <osmocom/bsc/handover_vty.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020062#include <osmocom/bsc/gsm_04_08_utils.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020063
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010064#include <inttypes.h>
65
Harald Weltec08e8be2011-03-04 13:53:51 +010066#include "../../bscconfig.h"
Harald Welte1353f962010-05-16 19:20:24 +020067
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010068#define BTS_NR_STR "BTS Number\n"
69#define TRX_NR_STR "TRX Number\n"
70#define TS_NR_STR "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020071#define LCHAN_NR_STR "Logical Channel Number\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010072#define BTS_TRX_STR BTS_NR_STR TRX_NR_STR
73#define BTS_TRX_TS_STR BTS_TRX_STR TS_NR_STR
74#define BTS_TRX_TS_LCHAN_STR BTS_TRX_TS_STR LCHAN_NR_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020075
Harald Welteea4647d2010-05-12 17:19:53 +000076/* FIXME: this should go to some common file */
77static const struct value_string gprs_ns_timer_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020078 { 0, "tns-block" },
79 { 1, "tns-block-retries" },
80 { 2, "tns-reset" },
81 { 3, "tns-reset-retries" },
82 { 4, "tns-test" },
83 { 5, "tns-alive" },
84 { 6, "tns-alive-retries" },
85 { 0, NULL }
86};
87
Harald Welteea4647d2010-05-12 17:19:53 +000088static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020089 { 0, "blocking-timer" },
90 { 1, "blocking-retries" },
91 { 2, "unblocking-retries" },
92 { 3, "reset-timer" },
93 { 4, "reset-retries" },
94 { 5, "suspend-timer" },
95 { 6, "suspend-retries" },
96 { 7, "resume-timer" },
97 { 8, "resume-retries" },
98 { 9, "capability-update-timer" },
99 { 10, "capability-update-retries" },
100 { 0, NULL }
101};
102
Harald Welte64c07d22011-02-15 11:43:27 +0100103static const struct value_string bts_neigh_mode_strs[] = {
104 { NL_MODE_AUTOMATIC, "automatic" },
105 { NL_MODE_MANUAL, "manual" },
106 { NL_MODE_MANUAL_SI5SEP, "manual-si5" },
107 { 0, NULL }
108};
109
Daniel Willmann7d109832012-05-14 18:43:23 +0200110const struct value_string bts_loc_fix_names[] = {
111 { BTS_LOC_FIX_INVALID, "invalid" },
112 { BTS_LOC_FIX_2D, "fix2d" },
113 { BTS_LOC_FIX_3D, "fix3d" },
114 { 0, NULL }
115};
116
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100117struct cmd_node net_node = {
118 GSMNET_NODE,
119 "%s(config-net)# ",
120 1,
121};
122
Harald Welte68628e82009-03-10 12:17:57 +0000123struct cmd_node bts_node = {
124 BTS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200125 "%s(config-net-bts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000126 1,
127};
128
129struct cmd_node trx_node = {
130 TRX_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200131 "%s(config-net-bts-trx)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000132 1,
133};
134
135struct cmd_node ts_node = {
136 TS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200137 "%s(config-net-bts-trx-ts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000138 1,
139};
140
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100141static struct gsm_network *vty_global_gsm_network = NULL;
142
143struct gsm_network *gsmnet_from_vty(struct vty *v)
144{
145 /* It can't hurt to force callers to continue to pass the vty instance
146 * to this function, in case we'd like to retrieve the global
147 * gsm_network instance from the vty at some point in the future. But
148 * until then, just return the global pointer, which should have been
149 * initialized by common_cs_vty_init().
150 */
151 OSMO_ASSERT(vty_global_gsm_network);
152 return vty_global_gsm_network;
153}
154
Harald Welte68628e82009-03-10 12:17:57 +0000155static int dummy_config_write(struct vty *v)
156{
157 return CMD_SUCCESS;
158}
159
160static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
161{
Harald Welte1304b352013-03-15 16:57:33 +0100162 vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
163 abis_nm_opstate_name(nms->operational),
164 get_value_string(abis_nm_adm_state_names, nms->administrative),
Harald Welte867d9f32011-05-23 20:30:39 +0200165 abis_nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000166}
167
Harald Welteb908cb72009-12-22 13:09:29 +0100168static void dump_pchan_load_vty(struct vty *vty, char *prefix,
169 const struct pchan_load *pl)
170{
171 int i;
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100172 int dumped = 0;
Harald Welteb908cb72009-12-22 13:09:29 +0100173
174 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
175 const struct load_counter *lc = &pl->pchan[i];
176 unsigned int percent;
177
178 if (lc->total == 0)
179 continue;
180
181 percent = (lc->used * 100) / lc->total;
182
183 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
184 gsm_pchan_name(i), percent, lc->used, lc->total,
185 VTY_NEWLINE);
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100186 dumped ++;
Harald Welteb908cb72009-12-22 13:09:29 +0100187 }
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100188 if (!dumped)
189 vty_out(vty, "%s(none)%s", prefix, VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100190}
191
Harald Welte68628e82009-03-10 12:17:57 +0000192static void net_dump_vty(struct vty *vty, struct gsm_network *net)
193{
Harald Welteb908cb72009-12-22 13:09:29 +0100194 struct pchan_load pl;
195
Harald Welteef235b52009-03-10 12:34:02 +0000196 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
197 "and has %u BTS%s", net->country_code, net->network_code,
198 net->num_bts, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200199 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900200 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
201 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100202 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
203 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800204 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
205 VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100206
207 {
208 struct gsm_bts *bts;
209 unsigned int ho_active_count = 0;
210 unsigned int ho_inactive_count = 0;
211
212 llist_for_each_entry(bts, &net->bts_list, list) {
213 if (ho_get_ho_active(bts->ho))
214 ho_active_count ++;
215 else
216 ho_inactive_count ++;
217 }
218
219 if (ho_active_count && ho_inactive_count)
220 vty_out(vty, " Handover: On at %u BTS, Off at %u BTS%s",
221 ho_active_count, ho_inactive_count, VTY_NEWLINE);
222 else
223 vty_out(vty, " Handover: %s%s", ho_active_count ? "On" : "Off",
224 VTY_NEWLINE);
225 }
226
Harald Welteb908cb72009-12-22 13:09:29 +0100227 network_chan_load(&pl, net);
228 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
229 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100230
231 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100232 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100233 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200234 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100235 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100236 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200237 vty_out(vty, " Last RF Lock Command: %s%s",
238 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
239 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000240}
241
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200242DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000243 SHOW_STR "Display information about a GSM NETWORK\n")
244{
Harald Weltedcccb182010-05-16 20:52:23 +0200245 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000246 net_dump_vty(vty, net);
247
248 return CMD_SUCCESS;
249}
250
251static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
252{
Harald Welteedb37782009-05-01 14:59:07 +0000253 struct e1inp_line *line;
254
255 if (!e1l) {
256 vty_out(vty, " None%s", VTY_NEWLINE);
257 return;
258 }
259
260 line = e1l->ts->line;
261
262 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
263 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000264 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000265 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000266 e1l->tei, e1l->sapi, VTY_NEWLINE);
267}
268
Neels Hofmeyrc1db52f2018-01-19 00:59:33 +0100269static void vty_out_neigh_list(struct vty *vty, struct bitvec *bv)
270{
271 int count = 0;
272 int i;
273 for (i = 0; i < 1024; i++) {
274 if (!bitvec_get_bit_pos(bv, i))
275 continue;
276 vty_out(vty, " %u", i);
277 count ++;
278 }
279 if (!count)
280 vty_out(vty, " (none)");
281 else
282 vty_out(vty, " (%d)", count);
283}
284
Harald Welte68628e82009-03-10 12:17:57 +0000285static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
286{
Harald Welteb908cb72009-12-22 13:09:29 +0100287 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200288 unsigned long long sec;
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100289 struct gsm_bts_trx *trx;
290 int ts_hopping_total;
291 int ts_non_hopping_total;
Harald Welteb908cb72009-12-22 13:09:29 +0100292
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200293 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100294 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200295 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200296 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100297 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100298 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200299 bts->num_trx, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100300 vty_out(vty, " Description: %s%s",
Harald Welte197dea92010-05-14 17:59:53 +0200301 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100302
303 vty_out(vty, " ARFCNs:");
304 ts_hopping_total = 0;
305 ts_non_hopping_total = 0;
306 llist_for_each_entry(trx, &bts->trx_list, list) {
307 int ts_nr;
308 int ts_hopping = 0;
309 int ts_non_hopping = 0;
310 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
311 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
312 if (ts->hopping.enabled)
313 ts_hopping++;
314 else
315 ts_non_hopping++;
316 }
317
318 if (ts_non_hopping)
319 vty_out(vty, " %u", trx->arfcn);
320 ts_hopping_total += ts_hopping;
321 ts_non_hopping_total += ts_non_hopping;
322 }
323 if (ts_hopping_total) {
324 if (ts_non_hopping_total)
325 vty_out(vty, " / Hopping on %d of %d timeslots",
326 ts_hopping_total, ts_hopping_total + ts_non_hopping_total);
327 else
328 vty_out(vty, " Hopping on all %d timeslots", ts_hopping_total);
329 }
330 vty_out(vty, "%s", VTY_NEWLINE);
331
Maxf9685c12017-03-23 12:01:07 +0100332 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100333 vty_out(vty, " PCU version %s connected%s", bts->pcu_version,
Maxf9685c12017-03-23 12:01:07 +0100334 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100335 vty_out(vty, " MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
336 vty_out(vty, " Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100337 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
338 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100339 vty_out(vty, " Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100340 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100341 vty_out(vty, " RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100342 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100343 vty_out(vty, " RACH Max transmissions: %u%s",
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100344 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
345 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100346 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200347 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200348 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100349 vty_out(vty, " Uplink DTX: %s%s",
Maxc08ee712016-05-11 12:45:13 +0200350 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
351 "enabled" : "forced", VTY_NEWLINE);
352 else
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100353 vty_out(vty, " Uplink DTX: not enabled%s", VTY_NEWLINE);
354 vty_out(vty, " Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
Maxc08ee712016-05-11 12:45:13 +0200355 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100356 vty_out(vty, " Channel Description Attachment: %s%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200357 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100358 vty_out(vty, " Channel Description BS-PA-MFRMS: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200359 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100360 vty_out(vty, " Channel Description BS-AG_BLKS-RES: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200361 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100362 vty_out(vty, " System Information present: 0x%08x, static: 0x%08x%s",
Harald Welte9fbff4a2010-07-30 11:50:09 +0200363 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100364 vty_out(vty, " Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100365 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100366 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
367 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
368 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100369 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200370 if (bts->pcu_sock_path)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100371 vty_out(vty, " PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000372 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200373 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000374 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200375 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200376 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
377 vty_out(vty, " Skip Reset: %d%s",
378 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000379 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200380 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000381 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200382 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200383 vty_out(vty, " GPRS NSE: ");
384 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
385 vty_out(vty, " GPRS CELL: ");
386 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
387 vty_out(vty, " GPRS NSVC0: ");
388 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
389 vty_out(vty, " GPRS NSVC1: ");
390 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200391 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
392 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000393 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100394 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200395 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200396 sec = bts_uptime(bts);
397 if (sec)
Maxff3fad12018-01-07 16:50:42 +0100398 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.",
399 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60);
400 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100401 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200402 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
403 e1isl_dump_vty(vty, bts->oml_link);
404 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100405
Neels Hofmeyrc1db52f2018-01-19 00:59:33 +0100406 vty_out(vty, " Neighbor Cells: ");
407 switch (bts->neigh_list_manual_mode) {
408 default:
409 case NL_MODE_AUTOMATIC:
410 vty_out(vty, "Automatic");
411 /* generate_bcch_chan_list() should populate si_common.neigh_list */
412 break;
413 case NL_MODE_MANUAL:
414 vty_out(vty, "Manual");
415 break;
416 case NL_MODE_MANUAL_SI5SEP:
417 vty_out(vty, "Manual/separate SI5");
418 break;
419 }
420 vty_out(vty, ", ARFCNs:");
421 vty_out_neigh_list(vty, &bts->si_common.neigh_list);
422 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
423 vty_out(vty, " SI5:");
424 vty_out_neigh_list(vty, &bts->si_common.si5_neigh_list);
425 }
426 vty_out(vty, "%s", VTY_NEWLINE);
427
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100428 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100429 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200430 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100431 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
432 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100433
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100434 vty_out(vty, " Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
Harald Welted82101e2017-12-09 23:07:38 +0100435 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
436 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
437 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100438 vty_out(vty, " Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
Harald Welted82101e2017-12-09 23:07:38 +0100439 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
440 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
441 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100442 vty_out(vty, " BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
Harald Welted82101e2017-12-09 23:07:38 +0100443 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
444 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
445 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000446}
447
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100448DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000449 SHOW_STR "Display information about a BTS\n"
450 "BTS number")
451{
Harald Weltedcccb182010-05-16 20:52:23 +0200452 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000453 int bts_nr;
454
455 if (argc != 0) {
456 /* use the BTS number that the user has specified */
457 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100458 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000459 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000460 VTY_NEWLINE);
461 return CMD_WARNING;
462 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200463 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000464 return CMD_SUCCESS;
465 }
466 /* print all BTS's */
467 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200468 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000469
470 return CMD_SUCCESS;
471}
472
Harald Welte42581822009-08-08 16:12:58 +0200473/* utility functions */
474static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
475 const char *ts, const char *ss)
476{
477 e1_link->e1_nr = atoi(line);
478 e1_link->e1_ts = atoi(ts);
479 if (!strcmp(ss, "full"))
480 e1_link->e1_ts_ss = 255;
481 else
482 e1_link->e1_ts_ss = atoi(ss);
483}
484
485static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
486 const char *prefix)
487{
488 if (!e1_link->e1_ts)
489 return;
490
491 if (e1_link->e1_ts_ss == 255)
492 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
493 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
494 else
495 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
496 prefix, e1_link->e1_nr, e1_link->e1_ts,
497 e1_link->e1_ts_ss, VTY_NEWLINE);
498}
499
500
Harald Welte67ce0732009-08-06 19:06:46 +0200501static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
502{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100503 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100504 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100505 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200506 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100507 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200508 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100509 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200510 ts->hopping.enabled, VTY_NEWLINE);
511 if (ts->hopping.enabled) {
512 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100513 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200514 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100515 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200516 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200517 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
518 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
519 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100520 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200521 i, VTY_NEWLINE);
522 }
Harald Welte127af342010-12-24 12:07:07 +0100523 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100524 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100525
526 if (ts->trx->bts->model->config_write_ts)
527 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200528}
529
530static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
531{
532 int i;
533
Harald Welte5013b2a2009-08-07 13:29:14 +0200534 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200535 if (trx->description)
536 vty_out(vty, " description %s%s", trx->description,
537 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200538 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200539 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200540 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200541 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100542 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200543 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200544 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
545 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200546
Harald Welteface7ed2011-02-14 16:15:21 +0100547 if (trx->bts->model->config_write_trx)
548 trx->bts->model->config_write_trx(vty, trx);
549
Harald Welte67ce0732009-08-06 19:06:46 +0200550 for (i = 0; i < TRX_NR_TS; i++)
551 config_write_ts_single(vty, &trx->ts[i]);
552}
553
Harald Welte615e9562010-05-11 23:50:21 +0200554static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
555{
556 unsigned int i;
557 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
558 VTY_NEWLINE);
559 if (bts->gprs.mode == BTS_GPRS_NONE)
560 return;
561
bhargava350533c2016-07-21 11:14:34 +0530562 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
563 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
564
Harald Welte615e9562010-05-11 23:50:21 +0200565 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
566 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100567 vty_out(vty, " gprs network-control-order nc%u%s",
568 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200569 if (!bts->gprs.ctrl_ack_type_use_block)
570 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200571 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
572 VTY_NEWLINE);
573 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
574 vty_out(vty, " gprs cell timer %s %u%s",
575 get_value_string(gprs_bssgp_cfg_strs, i),
576 bts->gprs.cell.timer[i], VTY_NEWLINE);
577 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
578 VTY_NEWLINE);
579 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
580 vty_out(vty, " gprs ns timer %s %u%s",
581 get_value_string(gprs_ns_timer_strs, i),
582 bts->gprs.nse.timer[i], VTY_NEWLINE);
583 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
584 struct gsm_bts_gprs_nsvc *nsvc =
585 &bts->gprs.nsvc[i];
586 struct in_addr ia;
587
588 ia.s_addr = htonl(nsvc->remote_ip);
589 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
590 nsvc->nsvci, VTY_NEWLINE);
591 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
592 nsvc->local_port, VTY_NEWLINE);
593 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
594 nsvc->remote_port, VTY_NEWLINE);
595 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
596 inet_ntoa(ia), VTY_NEWLINE);
597 }
598}
599
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200600/* Write the model data if there is one */
601static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200602{
603 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200604
605 if (!bts->model)
606 return;
607
608 if (bts->model->config_write_bts)
609 bts->model->config_write_bts(vty, bts);
610
611 llist_for_each_entry(trx, &bts->trx_list, list)
612 config_write_trx_single(vty, trx);
613}
614
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200615static void write_amr_modes(struct vty *vty, const char *prefix,
616 const char *name, struct amr_mode *modes, int num)
617{
618 int i;
619
620 vty_out(vty, " %s threshold %s", prefix, name);
621 for (i = 0; i < num - 1; i++)
622 vty_out(vty, " %d", modes[i].threshold);
623 vty_out(vty, "%s", VTY_NEWLINE);
624 vty_out(vty, " %s hysteresis %s", prefix, name);
625 for (i = 0; i < num - 1; i++)
626 vty_out(vty, " %d", modes[i].hysteresis);
627 vty_out(vty, "%s", VTY_NEWLINE);
628}
629
Andreas Eversberg73266522014-01-19 11:47:44 +0100630static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
631 struct amr_multirate_conf *mr, int full)
632{
633 struct gsm48_multi_rate_conf *mr_conf;
634 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
635 int i, num;
636
637 if (!(mr->gsm48_ie[1]))
638 return;
639
640 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
641
642 num = 0;
643 vty_out(vty, " %s modes", prefix);
644 for (i = 0; i < ((full) ? 8 : 6); i++) {
645 if ((mr->gsm48_ie[1] & (1 << i))) {
646 vty_out(vty, " %d", i);
647 num++;
648 }
649 }
650 vty_out(vty, "%s", VTY_NEWLINE);
651 if (num > 4)
652 num = 4;
653 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200654 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
655 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100656 }
657 vty_out(vty, " %s start-mode ", prefix);
658 if (mr_conf->icmi) {
659 num = 0;
660 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
661 if ((mr->gsm48_ie[1] & (1 << i)))
662 num++;
663 if (mr_conf->smod == num - 1) {
664 vty_out(vty, "%d%s", num, VTY_NEWLINE);
665 break;
666 }
667 }
668 } else
669 vty_out(vty, "auto%s", VTY_NEWLINE);
670}
671
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200672static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
673{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200674 int i;
Max2c16bee2017-02-15 13:51:37 +0100675 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200676
Harald Welte5013b2a2009-08-07 13:29:14 +0200677 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
678 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200679 if (bts->description)
680 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200681 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100682 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200683 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200684 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200685 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
686 vty_out(vty, " dtx uplink%s%s",
687 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
688 VTY_NEWLINE);
689 if (bts->dtxd)
690 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200691 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200692 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100693 vty_out(vty, " cell reselection hysteresis %u%s",
694 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
695 vty_out(vty, " rxlev access min %u%s",
696 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100697
698 if (bts->si_common.cell_ro_sel_par.present) {
699 struct gsm48_si_selection_params *sp;
700 sp = &bts->si_common.cell_ro_sel_par;
701
702 if (sp->cbq)
703 vty_out(vty, " cell bar qualify %u%s",
704 sp->cbq, VTY_NEWLINE);
705
706 if (sp->cell_resel_off)
707 vty_out(vty, " cell reselection offset %u%s",
708 sp->cell_resel_off*2, VTY_NEWLINE);
709
710 if (sp->temp_offs == 7)
711 vty_out(vty, " temporary offset infinite%s",
712 VTY_NEWLINE);
713 else if (sp->temp_offs)
714 vty_out(vty, " temporary offset %u%s",
715 sp->temp_offs*10, VTY_NEWLINE);
716
717 if (sp->penalty_time == 31)
718 vty_out(vty, " penalty time reserved%s",
719 VTY_NEWLINE);
720 else if (sp->penalty_time)
721 vty_out(vty, " penalty time %u%s",
722 (sp->penalty_time*20)+20, VTY_NEWLINE);
723 }
724
Harald Welte2f8b9d22017-06-18 11:12:13 +0300725 if (gsm_bts_get_radio_link_timeout(bts) < 0)
726 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
727 else
728 vty_out(vty, " radio-link-timeout %d%s",
729 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100730
Harald Welte7a8fa412009-08-10 13:48:16 +0200731 vty_out(vty, " channel allocator %s%s",
732 bts->chan_alloc_reverse ? "descending" : "ascending",
733 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100734 vty_out(vty, " rach tx integer %u%s",
735 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
736 vty_out(vty, " rach max transmission %u%s",
737 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
738 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800739
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200740 vty_out(vty, " channel-descrption attach %u%s",
741 bts->si_common.chan_desc.att, VTY_NEWLINE);
742 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
743 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
744 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
745 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
746
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800747 if (bts->rach_b_thresh != -1)
748 vty_out(vty, " rach nm busy threshold %u%s",
749 bts->rach_b_thresh, VTY_NEWLINE);
750 if (bts->rach_ldavg_slots != -1)
751 vty_out(vty, " rach nm load average %u%s",
752 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100753 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200754 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800755 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
756 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400757 if ((bts->si_common.rach_control.t3) != 0)
758 for (i = 0; i < 8; i++)
759 if (bts->si_common.rach_control.t3 & (0x1 << i))
760 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
761 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
762 for (i = 0; i < 8; i++)
763 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
764 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200765 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
766 if (bts->si_mode_static & (1 << i)) {
767 vty_out(vty, " system-information %s mode static%s",
768 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
769 vty_out(vty, " system-information %s static %s%s",
770 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200771 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200772 VTY_NEWLINE);
773 }
774 }
Harald Welte42def722017-01-13 00:10:32 +0100775 vty_out(vty, " early-classmark-sending %s%s",
776 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100777 vty_out(vty, " early-classmark-sending-3g %s%s",
778 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100779 switch (bts->type) {
780 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100781 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200782 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200783 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100784 if (bts->ip_access.rsl_ip) {
785 struct in_addr ia;
786 ia.s_addr = htonl(bts->ip_access.rsl_ip);
787 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
788 VTY_NEWLINE);
789 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200790 vty_out(vty, " oml ip.access stream_id %u line %u%s",
791 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100792 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200793 case GSM_BTS_TYPE_NOKIA_SITE:
794 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100795 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
796 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100797 vty_out(vty, " nokia_site bts-reset-timer %d%s", bts->nokia.bts_reset_timer_cnf, VTY_NEWLINE);
Andreas Eversbergb6f95162013-12-05 16:02:37 +0100798 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100799 default:
Harald Welte42581822009-08-08 16:12:58 +0200800 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
801 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100802 break;
Harald Welte42581822009-08-08 16:12:58 +0200803 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800804
805 /* if we have a limit, write it */
806 if (bts->paging.free_chans_need >= 0)
807 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
808
Harald Welte32c09622011-01-11 23:44:56 +0100809 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100810 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
811 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100812 for (i = 0; i < 1024; i++) {
813 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
814 vty_out(vty, " neighbor-list add arfcn %u%s",
815 i, VTY_NEWLINE);
816 }
817 }
Harald Welte64c07d22011-02-15 11:43:27 +0100818 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
819 for (i = 0; i < 1024; i++) {
820 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
821 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
822 i, VTY_NEWLINE);
823 }
824 }
Harald Welte32c09622011-01-11 23:44:56 +0100825
Max59a1bf32016-04-15 16:04:46 +0200826 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100827 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
828 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
829 vty_out(vty, " si2quater neighbor-list add earfcn %u "
830 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
831
832 vty_out(vty, " thresh-lo %u",
833 e->thresh_lo_valid ? e->thresh_lo : 32);
834
835 vty_out(vty, " prio %u",
836 e->prio_valid ? e->prio : 8);
837
838 vty_out(vty, " qrxlv %u",
839 e->qrxlm_valid ? e->qrxlm : 32);
840
841 tmp = e->meas_bw[i];
842 vty_out(vty, " meas %u",
843 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200844
845 vty_out(vty, "%s", VTY_NEWLINE);
846 }
847 }
848
Max26679e02016-04-20 15:57:13 +0200849 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
850 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
851 bts->si_common.data.uarfcn_list[i],
852 bts->si_common.data.scramble_list[i] & ~(1 << 9),
853 (bts->si_common.data.scramble_list[i] >> 9) & 1,
854 VTY_NEWLINE);
855 }
856
Andreas Eversberga83d5112013-12-07 18:32:28 +0100857 vty_out(vty, " codec-support fr");
858 if (bts->codec.hr)
859 vty_out(vty, " hr");
860 if (bts->codec.efr)
861 vty_out(vty, " efr");
862 if (bts->codec.amr)
863 vty_out(vty, " amr");
864 vty_out(vty, "%s", VTY_NEWLINE);
865
Andreas Eversberg73266522014-01-19 11:47:44 +0100866 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
867 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
868
Harald Welte615e9562010-05-11 23:50:21 +0200869 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200870
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200871 if (bts->excl_from_rf_lock)
872 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
873
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100874 vty_out(vty, " %sforce-combined-si%s",
875 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
876
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100877 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
878 int j;
879
880 if (bts->depends_on[i] == 0)
881 continue;
882
883 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
884 int bts_nr;
885
886 if ((bts->depends_on[i] & (1<<j)) == 0)
887 continue;
888
889 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
890 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
891 }
892 }
Harald Welte8254cf72017-05-29 13:42:19 +0200893 if (bts->pcu_sock_path)
894 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100895
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100896 ho_vty_write_bts(vty, bts);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100897
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200898 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200899}
900
901static int config_write_bts(struct vty *v)
902{
Harald Weltedcccb182010-05-16 20:52:23 +0200903 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200904 struct gsm_bts *bts;
905
906 llist_for_each_entry(bts, &gsmnet->bts_list, list)
907 config_write_bts_single(v, bts);
908
909 return CMD_SUCCESS;
910}
911
Harald Weltea0d324b2017-07-20 01:47:39 +0200912/* small helper macro for conditional dumping of timer */
913#define VTY_OUT_TIMER(number) \
914 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
915 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
916
Harald Welte5013b2a2009-08-07 13:29:14 +0200917static int config_write_net(struct vty *vty)
918{
Harald Weltedcccb182010-05-16 20:52:23 +0200919 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
920
Harald Welte5013b2a2009-08-07 13:29:14 +0200921 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200922 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200923 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900924 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100925 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800926 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100927
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100928 ho_vty_write_net(vty, gsmnet);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100929
Harald Weltea0d324b2017-07-20 01:47:39 +0200930 VTY_OUT_TIMER(3101);
931 VTY_OUT_TIMER(3103);
932 VTY_OUT_TIMER(3105);
933 VTY_OUT_TIMER(3107);
934 VTY_OUT_TIMER(3109);
935 VTY_OUT_TIMER(3111);
936 VTY_OUT_TIMER(3113);
937 VTY_OUT_TIMER(3115);
938 VTY_OUT_TIMER(3117);
939 VTY_OUT_TIMER(3119);
940 VTY_OUT_TIMER(3122);
941 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700942 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
943 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200944 if (gsmnet->tz.override != 0) {
945 if (gsmnet->tz.dst)
946 vty_out(vty, " timezone %d %d %d%s",
947 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
948 VTY_NEWLINE);
949 else
950 vty_out(vty, " timezone %d %d%s",
951 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
952 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200953 if (gsmnet->t3212 == 0)
954 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
955 else
956 vty_out(vty, " periodic location update %u%s",
957 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200958
959 return CMD_SUCCESS;
960}
Harald Welte67ce0732009-08-06 19:06:46 +0200961
Harald Welte68628e82009-03-10 12:17:57 +0000962static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
963{
964 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
965 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200966 vty_out(vty, "Description: %s%s",
967 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200968 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200969 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200970 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200971 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000972 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200973 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +0100974 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000975 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200976 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200977 if (is_ipaccess_bts(trx->bts)) {
978 vty_out(vty, " ip.access stream ID: 0x%02x%s",
979 trx->rsl_tei, VTY_NEWLINE);
980 } else {
981 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
982 e1isl_dump_vty(vty, trx->rsl_link);
983 }
Harald Welte68628e82009-03-10 12:17:57 +0000984}
985
Max6e4f1842018-01-07 16:45:42 +0100986static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
987{
988 uint8_t trx_nr;
989 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
990 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
991}
992
Harald Welte68628e82009-03-10 12:17:57 +0000993DEFUN(show_trx,
994 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100995 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200996 SHOW_STR "Display information about a TRX\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +0100997 BTS_TRX_STR)
Harald Welte68628e82009-03-10 12:17:57 +0000998{
Harald Weltedcccb182010-05-16 20:52:23 +0200999 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001000 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001001 int bts_nr, trx_nr;
1002
1003 if (argc >= 1) {
1004 /* use the BTS number that the user has specified */
1005 bts_nr = atoi(argv[0]);
1006 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001007 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001008 VTY_NEWLINE);
1009 return CMD_WARNING;
1010 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001011 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001012 }
1013 if (argc >= 2) {
1014 trx_nr = atoi(argv[1]);
1015 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001016 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001017 VTY_NEWLINE);
1018 return CMD_WARNING;
1019 }
Max6e4f1842018-01-07 16:45:42 +01001020 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001021 return CMD_SUCCESS;
1022 }
1023 if (bts) {
1024 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +01001025 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +00001026 return CMD_SUCCESS;
1027 }
1028
Max6e4f1842018-01-07 16:45:42 +01001029 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
1030 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001031
1032 return CMD_SUCCESS;
1033}
1034
Harald Welte67ce0732009-08-06 19:06:46 +02001035
Harald Welte68628e82009-03-10 12:17:57 +00001036static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
1037{
Harald Welte135a6482011-05-30 12:09:13 +02001038 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +01001039 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +01001040 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +01001041 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +01001042 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001043 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +01001044 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001045 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001046 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +05301047 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +00001048 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
1049 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
1050 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001051}
1052
1053DEFUN(show_ts,
1054 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001055 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001056 SHOW_STR "Display information about a TS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001057 BTS_TRX_TS_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001058{
Harald Weltedcccb182010-05-16 20:52:23 +02001059 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +01001060 struct gsm_bts *bts = NULL;
1061 struct gsm_bts_trx *trx = NULL;
1062 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001063 int bts_nr, trx_nr, ts_nr;
1064
1065 if (argc >= 1) {
1066 /* use the BTS number that the user has specified */
1067 bts_nr = atoi(argv[0]);
1068 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001069 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001070 VTY_NEWLINE);
1071 return CMD_WARNING;
1072 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001073 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001074 }
1075 if (argc >= 2) {
1076 trx_nr = atoi(argv[1]);
1077 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001078 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001079 VTY_NEWLINE);
1080 return CMD_WARNING;
1081 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001082 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001083 }
1084 if (argc >= 3) {
1085 ts_nr = atoi(argv[2]);
1086 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +00001087 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +00001088 VTY_NEWLINE);
1089 return CMD_WARNING;
1090 }
Harald Welte274d0152010-12-24 12:05:03 +01001091 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +00001092 ts = &trx->ts[ts_nr];
1093 ts_dump_vty(vty, ts);
1094 return CMD_SUCCESS;
1095 }
Harald Welte274d0152010-12-24 12:05:03 +01001096
1097 if (bts && trx) {
1098 /* Iterate over all TS in this TRX */
1099 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1100 ts = &trx->ts[ts_nr];
1101 ts_dump_vty(vty, ts);
1102 }
1103 } else if (bts) {
1104 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001105 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001106 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001107 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1108 ts = &trx->ts[ts_nr];
1109 ts_dump_vty(vty, ts);
1110 }
1111 }
Harald Welte274d0152010-12-24 12:05:03 +01001112 } else {
1113 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1114 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1115 bts = gsm_bts_num(net, bts_nr);
1116 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1117 trx = gsm_bts_trx_num(bts, trx_nr);
1118 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1119 ts = &trx->ts[ts_nr];
1120 ts_dump_vty(vty, ts);
1121 }
1122 }
1123 }
Harald Welte68628e82009-03-10 12:17:57 +00001124 }
1125
1126 return CMD_SUCCESS;
1127}
1128
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001129static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1130{
1131 if (strlen(bsub->imsi))
1132 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1133 if (bsub->tmsi != GSM_RESERVED_TMSI)
1134 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1135 VTY_NEWLINE);
1136 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1137}
1138
Harald Welte8387a492009-12-22 21:43:14 +01001139static void meas_rep_dump_uni_vty(struct vty *vty,
1140 struct gsm_meas_rep_unidir *mru,
1141 const char *prefix,
1142 const char *dir)
1143{
1144 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1145 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1146 dir, rxlev2dbm(mru->sub.rx_lev));
1147 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1148 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1149 VTY_NEWLINE);
1150}
1151
1152static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1153 const char *prefix)
1154{
1155 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1156 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1157 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1158 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1159 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1160 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1161 VTY_NEWLINE);
1162 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001163 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001164 if (mr->flags & MEAS_REP_F_MS_L1)
1165 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1166 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1167 if (mr->flags & MEAS_REP_F_DL_VALID)
1168 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1169 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1170}
1171
Harald Welte0a8cf322015-12-05 17:22:49 +01001172/* FIXME: move this to libosmogsm */
1173static const struct value_string gsm48_cmode_names[] = {
1174 { GSM48_CMODE_SIGN, "signalling" },
1175 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1176 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1177 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1178 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1179 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1180 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1181 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1182 { 0, NULL }
1183};
1184
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001185/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1186 * Don't do anything if the ts is not dynamic. */
1187static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1188{
1189 switch (ts->pchan) {
1190 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1191 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1192 vty_out(vty, " as %s",
1193 gsm_pchan_name(ts->dyn.pchan_is));
1194 else
1195 vty_out(vty, " switching %s -> %s",
1196 gsm_pchan_name(ts->dyn.pchan_is),
1197 gsm_pchan_name(ts->dyn.pchan_want));
1198 break;
1199 case GSM_PCHAN_TCH_F_PDCH:
1200 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1201 vty_out(vty, " as %s",
1202 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1203 : "TCH/F");
1204 else
1205 vty_out(vty, " switching %s -> %s",
1206 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1207 : "TCH/F",
1208 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1209 : "TCH/F");
1210 break;
1211 default:
1212 /* no dyn ts */
1213 break;
1214 }
1215}
1216
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001217static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001218{
Harald Welte8387a492009-12-22 21:43:14 +01001219 int idx;
1220
Harald Welte85bded82010-12-24 12:22:34 +01001221 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1222 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1223 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001224 /* show dyn TS details, if applicable */
1225 switch (lchan->ts->pchan) {
1226 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1227 vty_out(vty, " Osmocom Dyn TS:");
1228 vty_out_dyn_ts_status(vty, lchan->ts);
1229 vty_out(vty, VTY_NEWLINE);
1230 break;
1231 case GSM_PCHAN_TCH_F_PDCH:
1232 vty_out(vty, " IPACC Dyn PDCH TS:");
1233 vty_out_dyn_ts_status(vty, lchan->ts);
1234 vty_out(vty, VTY_NEWLINE);
1235 break;
1236 default:
1237 /* no dyn ts */
1238 break;
1239 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001240 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001241 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001242 gsm_lchans_name(lchan->state),
1243 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1244 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1245 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001246 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1247 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1248 - lchan->bs_power*2,
1249 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1250 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001251 vty_out(vty, " Channel Mode / Codec: %s%s",
1252 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1253 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001254 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001255 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001256 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001257 } else
1258 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301259 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1260 struct in_addr ia;
Harald Welte5f45a4a2018-02-05 21:33:34 +01001261 if (lchan->abis_ip.bound_ip) {
1262 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
1263 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1264 inet_ntoa(ia), lchan->abis_ip.bound_port,
1265 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1266 VTY_NEWLINE);
1267 }
1268 if (lchan->abis_ip.connect_ip) {
1269 ia.s_addr = htonl(lchan->abis_ip.connect_ip);
1270 vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02x%s",
1271 inet_ntoa(ia), lchan->abis_ip.connect_port,
1272 lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode,
1273 VTY_NEWLINE);
1274 }
1275
Harald Welte2c828992009-12-02 01:56:49 +05301276 }
Harald Welte8387a492009-12-22 21:43:14 +01001277
1278 /* we want to report the last measurement report */
1279 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1280 lchan->meas_rep_idx, 1);
1281 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001282}
1283
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001284static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1285{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001286 struct gsm_meas_rep *mr;
1287 int idx;
1288
1289 /* we want to report the last measurement report */
1290 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1291 lchan->meas_rep_idx, 1);
1292 mr = &lchan->meas_rep[idx];
1293
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001294 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001295 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001296 gsm_pchan_name(lchan->ts->pchan));
1297 vty_out_dyn_ts_status(vty, lchan->ts);
1298 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1299 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001300 lchan->nr,
1301 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1302 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001303 rxlev2dbm(mr->dl.full.rx_lev),
1304 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001305 VTY_NEWLINE);
1306}
1307
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001308
1309static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1310 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1311{
1312 int lchan_nr;
1313 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1314 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1315 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1316 continue;
1317 dump_cb(vty, lchan);
1318 }
1319
1320 return CMD_SUCCESS;
1321}
1322
1323static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1324 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1325{
1326 int ts_nr;
1327
1328 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1329 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1330 dump_lchan_trx_ts(ts, vty, dump_cb);
1331 }
1332
1333 return CMD_SUCCESS;
1334}
1335
1336static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1337 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1338{
1339 int trx_nr;
1340
1341 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1342 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1343 dump_lchan_trx(trx, vty, dump_cb);
1344 }
1345
1346 return CMD_SUCCESS;
1347}
1348
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001349static int lchan_summary(struct vty *vty, int argc, const char **argv,
1350 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001351{
Harald Weltedcccb182010-05-16 20:52:23 +02001352 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001353 struct gsm_bts *bts;
1354 struct gsm_bts_trx *trx;
1355 struct gsm_bts_trx_ts *ts;
1356 struct gsm_lchan *lchan;
1357 int bts_nr, trx_nr, ts_nr, lchan_nr;
1358
1359 if (argc >= 1) {
1360 /* use the BTS number that the user has specified */
1361 bts_nr = atoi(argv[0]);
1362 if (bts_nr >= net->num_bts) {
1363 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1364 VTY_NEWLINE);
1365 return CMD_WARNING;
1366 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001367 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001368
1369 if (argc == 1)
1370 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001371 }
1372 if (argc >= 2) {
1373 trx_nr = atoi(argv[1]);
1374 if (trx_nr >= bts->num_trx) {
1375 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1376 VTY_NEWLINE);
1377 return CMD_WARNING;
1378 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001379 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001380
1381 if (argc == 2)
1382 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001383 }
1384 if (argc >= 3) {
1385 ts_nr = atoi(argv[2]);
1386 if (ts_nr >= TRX_NR_TS) {
1387 vty_out(vty, "%% can't find TS %s%s", argv[2],
1388 VTY_NEWLINE);
1389 return CMD_WARNING;
1390 }
1391 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001392
1393 if (argc == 3)
1394 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001395 }
1396 if (argc >= 4) {
1397 lchan_nr = atoi(argv[3]);
1398 if (lchan_nr >= TS_MAX_LCHAN) {
1399 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1400 VTY_NEWLINE);
1401 return CMD_WARNING;
1402 }
1403 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001404 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001405 return CMD_SUCCESS;
1406 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001407
1408
Harald Welte68628e82009-03-10 12:17:57 +00001409 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001410 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001411 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001412 }
1413
1414 return CMD_SUCCESS;
1415}
1416
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001417
1418DEFUN(show_lchan,
1419 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001420 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001421 SHOW_STR "Display information about a logical channel\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001422 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001423{
1424 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1425}
1426
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001427DEFUN(show_lchan_summary,
1428 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001429 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001430 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001431 "Short summary\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001432 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001433{
1434 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1435}
1436
Philipp Maier39f62bb2017-04-09 12:32:51 +02001437DEFUN(show_subscr_conn,
1438 show_subscr_conn_cmd,
1439 "show conns",
1440 SHOW_STR "Display currently active subscriber connections\n")
1441{
1442 struct gsm_subscriber_connection *conn;
1443 struct gsm_network *net = gsmnet_from_vty(vty);
1444 bool no_conns = true;
1445 unsigned int count = 0;
1446
1447 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1448
1449 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1450 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1451 lchan_dump_full_vty(vty, conn->lchan);
1452 no_conns = false;
1453 count++;
1454 }
1455
1456 if (no_conns)
1457 vty_out(vty, "None%s", VTY_NEWLINE);
1458
1459 return CMD_SUCCESS;
1460}
1461
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001462static int trigger_ho_or_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_bts *to_bts)
1463{
1464 int rc;
1465
1466 if (!to_bts || from_lchan->ts->trx->bts == to_bts) {
1467 LOGP(DHO, LOGL_NOTICE, "%s Manually triggering Assignment from VTY\n",
1468 gsm_lchan_name(from_lchan));
1469 to_bts = from_lchan->ts->trx->bts;
1470 } else
1471 LOGP(DHO, LOGL_NOTICE, "%s (ARFCN %u) --> BTS %u Manually triggering Handover from VTY\n",
1472 gsm_lchan_name(from_lchan), from_lchan->ts->trx->arfcn, to_bts->nr);
Neels Hofmeyr6dff51d2018-02-12 16:56:41 +01001473 rc = bsc_handover_start(from_lchan, to_bts, from_lchan->type);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001474 if (rc) {
1475 vty_out(vty, "bsc_handover_start() returned %d=%s%s", rc,
1476 strerror(-rc), VTY_NEWLINE);
1477 return CMD_WARNING;
1478 }
1479 return CMD_SUCCESS;
1480}
1481
1482static int ho_or_as(struct vty *vty, const char *argv[], int argc)
Philipp Maier39f62bb2017-04-09 12:32:51 +02001483{
1484 struct gsm_network *net = gsmnet_from_vty(vty);
1485 struct gsm_subscriber_connection *conn;
1486 struct gsm_bts *bts;
1487 struct gsm_bts *new_bts = NULL;
1488 unsigned int bts_nr = atoi(argv[0]);
1489 unsigned int trx_nr = atoi(argv[1]);
1490 unsigned int ts_nr = atoi(argv[2]);
1491 unsigned int ss_nr = atoi(argv[3]);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001492 unsigned int bts_nr_new;
1493 const char *action;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001494
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001495 if (argc > 4) {
1496 bts_nr_new = atoi(argv[4]);
1497
1498 /* Lookup the BTS where we want to handover to */
1499 llist_for_each_entry(bts, &net->bts_list, list) {
1500 if (bts->nr == bts_nr_new) {
1501 new_bts = bts;
1502 break;
1503 }
1504 }
1505
1506 if (!new_bts) {
1507 vty_out(vty, "Unable to trigger handover, specified bts #%u does not exist %s",
1508 bts_nr_new, VTY_NEWLINE);
1509 return CMD_WARNING;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001510 }
1511 }
1512
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001513 action = new_bts ? "handover" : "assignment";
Philipp Maier39f62bb2017-04-09 12:32:51 +02001514
1515 /* Find the connection/lchan that we want to handover */
1516 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001517 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001518 conn->lchan->ts->trx->nr == trx_nr &&
1519 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001520 vty_out(vty, "starting %s for lchan %s...%s", action, conn->lchan->name, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001521 lchan_dump_full_vty(vty, conn->lchan);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001522 return trigger_ho_or_as(vty, conn->lchan, new_bts);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001523 }
1524 }
1525
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001526 vty_out(vty, "Unable to trigger %s, specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1527 action, bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001528
1529 return CMD_WARNING;
1530}
1531
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001532#define MANUAL_HANDOVER_STR "Manually trigger handover (for debugging)\n"
1533#define MANUAL_ASSIGNMENT_STR "Manually trigger assignment (for debugging)\n"
1534
1535DEFUN(handover_subscr_conn,
1536 handover_subscr_conn_cmd,
1537 "handover <0-255> <0-255> <0-7> <0-7> <0-255>",
1538 MANUAL_HANDOVER_STR
1539 "Current " BTS_TRX_TS_LCHAN_STR
1540 "New " BTS_NR_STR)
1541{
1542 return ho_or_as(vty, argv, argc);
1543}
1544
1545DEFUN(assignment_subscr_conn,
1546 assignment_subscr_conn_cmd,
1547 "assignment <0-255> <0-255> <0-7> <0-7>",
1548 MANUAL_ASSIGNMENT_STR
1549 "Current " BTS_TRX_TS_LCHAN_STR)
1550{
1551 return ho_or_as(vty, argv, argc);
1552}
1553
1554static struct gsm_lchan *find_used_voice_lchan(struct vty *vty)
1555{
1556 struct gsm_bts *bts;
1557 struct gsm_network *network = gsmnet_from_vty(vty);
1558
1559 llist_for_each_entry(bts, &network->bts_list, list) {
1560 struct gsm_bts_trx *trx;
1561
1562 llist_for_each_entry(trx, &bts->trx_list, list) {
1563 int i;
1564 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1565 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1566 int j;
1567 int subslots;
1568
1569 /* skip administratively deactivated timeslots */
1570 if (!nm_is_running(&ts->mo.nm_state))
1571 continue;
1572
1573 subslots = ts_subslots(ts);
1574 for (j = 0; j < subslots; j++) {
1575 struct gsm_lchan *lchan = &ts->lchan[j];
1576
1577 if (lchan->state == LCHAN_S_ACTIVE
1578 && (lchan->type == GSM_LCHAN_TCH_F
1579 || lchan->type == GSM_LCHAN_TCH_H)) {
1580
1581 vty_out(vty, "Found voice call: %s%s",
1582 gsm_lchan_name(lchan), VTY_NEWLINE);
1583 lchan_dump_full_vty(vty, lchan);
1584 return lchan;
1585 }
1586 }
1587 }
1588 }
1589 }
1590
1591 vty_out(vty, "Cannot find any ongoing voice calls%s", VTY_NEWLINE);
1592 return NULL;
1593}
1594
1595static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gsm_bts *not_this_bts,
1596 enum gsm_phys_chan_config free_type)
1597{
1598 struct gsm_bts *bts;
1599 struct gsm_network *network = gsmnet_from_vty(vty);
1600
1601 llist_for_each_entry(bts, &network->bts_list, list) {
1602 struct gsm_bts_trx *trx;
1603
1604 if (bts == not_this_bts)
1605 continue;
1606
1607 llist_for_each_entry(trx, &bts->trx_list, list) {
1608 int i;
1609 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1610 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1611 int j;
1612 int subslots;
1613
1614 /* skip administratively deactivated timeslots */
1615 if (!nm_is_running(&ts->mo.nm_state))
1616 continue;
1617
1618 if (ts->pchan != free_type)
1619 continue;
1620
1621 subslots = ts_subslots(ts);
1622 for (j = 0; j < subslots; j++) {
1623 struct gsm_lchan *lchan = &ts->lchan[j];
1624
1625 if (lchan->state == LCHAN_S_NONE) {
1626 vty_out(vty, "Found unused %s slot: %s%s",
1627 gsm_pchan_name(free_type),
1628 gsm_lchan_name(lchan),
1629 VTY_NEWLINE);
1630 lchan_dump_full_vty(vty, lchan);
1631 return bts;
1632 }
1633 }
1634 }
1635 }
1636 }
1637 vty_out(vty, "Cannot find any BTS (other than BTS %u) with free %s lchan%s",
1638 not_this_bts? not_this_bts->nr : 255, gsm_lchant_name(free_type), VTY_NEWLINE);
1639 return NULL;
1640}
1641
1642DEFUN(handover_any, handover_any_cmd,
1643 "handover any",
1644 MANUAL_HANDOVER_STR
1645 "Pick any actively used TCH/F or TCH/H lchan and handover to any other BTS."
1646 " This is likely to fail if not all BTS are guaranteed to be reachable by the MS.\n")
1647{
1648 struct gsm_lchan *from_lchan;
1649 struct gsm_bts *to_bts;
1650
1651 from_lchan = find_used_voice_lchan(vty);
1652 if (!from_lchan)
1653 return CMD_WARNING;
1654
1655 to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts,
1656 ts_pchan(from_lchan->ts));
1657 if (!to_bts)
1658 return CMD_WARNING;
1659
1660 return trigger_ho_or_as(vty, from_lchan, to_bts);
1661}
1662
1663DEFUN(assignment_any, assignment_any_cmd,
1664 "assignment any",
1665 MANUAL_ASSIGNMENT_STR
1666 "Pick any actively used TCH/F or TCH/H lchan and re-assign within the same BTS."
1667 " This will fail if no lchans of the same type are available besides the used one.\n")
1668{
1669 struct gsm_lchan *from_lchan;
1670
1671 from_lchan = find_used_voice_lchan(vty);
1672 if (!from_lchan)
1673 return CMD_WARNING;
1674
1675 return trigger_ho_or_as(vty, from_lchan, NULL);
1676}
1677
Harald Weltebe4b7302009-05-23 16:59:33 +00001678static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001679{
1680 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001681 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001682}
1683
Harald Weltebe4b7302009-05-23 16:59:33 +00001684static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001685{
1686 struct gsm_paging_request *pag;
1687
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001688 if (!bts->paging.bts)
1689 return;
1690
Harald Weltef5025b62009-03-28 16:55:11 +00001691 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1692 paging_dump_vty(vty, pag);
1693}
1694
1695DEFUN(show_paging,
1696 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001697 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001698 SHOW_STR "Display information about paging reuqests of a BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001699 BTS_NR_STR)
Harald Weltef5025b62009-03-28 16:55:11 +00001700{
Harald Weltedcccb182010-05-16 20:52:23 +02001701 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001702 struct gsm_bts *bts;
1703 int bts_nr;
1704
1705 if (argc >= 1) {
1706 /* use the BTS number that the user has specified */
1707 bts_nr = atoi(argv[0]);
1708 if (bts_nr >= net->num_bts) {
1709 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1710 VTY_NEWLINE);
1711 return CMD_WARNING;
1712 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001713 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001714 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001715
Harald Weltef5025b62009-03-28 16:55:11 +00001716 return CMD_SUCCESS;
1717 }
1718 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001719 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001720 bts_paging_dump_vty(vty, bts);
1721 }
1722
1723 return CMD_SUCCESS;
1724}
1725
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001726DEFUN(show_paging_group,
1727 show_paging_group_cmd,
1728 "show paging-group <0-255> IMSI",
1729 SHOW_STR "Display the paging group\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001730 BTS_NR_STR "IMSI\n")
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001731{
1732 struct gsm_network *net = gsmnet_from_vty(vty);
1733 struct gsm_bts *bts;
1734 unsigned int page_group;
1735 int bts_nr = atoi(argv[0]);
1736
1737 if (bts_nr >= net->num_bts) {
1738 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1739 return CMD_WARNING;
1740 }
1741
1742 bts = gsm_bts_num(net, bts_nr);
1743 if (!bts) {
1744 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1745 return CMD_WARNING;
1746 }
1747
1748 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1749 str_to_imsi(argv[1]));
1750 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1751 str_to_imsi(argv[1]), bts->nr,
1752 page_group, VTY_NEWLINE);
1753 return CMD_SUCCESS;
1754}
1755
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001756DEFUN(cfg_net_neci,
1757 cfg_net_neci_cmd,
1758 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001759 "New Establish Cause Indication\n"
1760 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001761{
Harald Weltedcccb182010-05-16 20:52:23 +02001762 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1763
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001764 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001765 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001766 return CMD_SUCCESS;
1767}
1768
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001769DEFUN(cfg_net_pag_any_tch,
1770 cfg_net_pag_any_tch_cmd,
1771 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001772 "Assign a TCH when receiving a Paging Any request\n"
1773 "Any Channel\n" "Use\n" "TCH\n"
1774 "Do not use TCH for Paging Request Any\n"
1775 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001776{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001777 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001778 gsmnet->pag_any_tch = atoi(argv[0]);
1779 gsm_net_update_ctype(gsmnet);
1780 return CMD_SUCCESS;
1781}
1782
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001783#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1784/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1785#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1786
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001787#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001788 DEFUN(cfg_net_T##number, \
1789 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001790 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001791 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001792 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001793 "Set to default timer value" \
1794 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1795 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001796{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001797 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001798 int value; \
1799 if (strcmp(argv[0], "default") == 0) \
1800 value = DEFAULT_TIMER(number); \
1801 else \
1802 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001803 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001804 gsmnet->T##number = value; \
1805 return CMD_SUCCESS; \
1806}
1807
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001808DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1809DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1810DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1811DECLARE_TIMER(3107, "Currently not used")
1812DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1813DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1814DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1815DECLARE_TIMER(3115, "Currently not used")
1816DECLARE_TIMER(3117, "Currently not used")
1817DECLARE_TIMER(3119, "Currently not used")
Stefan Sperling6cee8932018-01-30 18:14:22 +01001818DECLARE_TIMER(3122, "Default waiting time (seconds) after IMM ASS REJECT")
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001819DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001820
Maxc08ee712016-05-11 12:45:13 +02001821DEFUN_DEPRECATED(cfg_net_dtx,
1822 cfg_net_dtx_cmd,
1823 "dtx-used (0|1)",
1824 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001825{
Maxc08ee712016-05-11 12:45:13 +02001826 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1827 "configuration options of BTS instead%s", VTY_NEWLINE);
1828 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001829}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001830
Harald Welte5258fc42009-03-28 19:07:53 +00001831/* per-BTS configuration */
1832DEFUN(cfg_bts,
1833 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001834 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001835 "Select a BTS to configure\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001836 BTS_NR_STR)
Harald Welte5258fc42009-03-28 19:07:53 +00001837{
Harald Weltedcccb182010-05-16 20:52:23 +02001838 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001839 int bts_nr = atoi(argv[0]);
1840 struct gsm_bts *bts;
1841
Harald Weltee441d9c2009-06-21 16:17:15 +02001842 if (bts_nr > gsmnet->num_bts) {
1843 vty_out(vty, "%% The next unused BTS number is %u%s",
1844 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001845 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001846 } else if (bts_nr == gsmnet->num_bts) {
1847 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001848 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001849 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001850 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001851 bts = gsm_bts_num(gsmnet, bts_nr);
1852
Daniel Willmannf15c2762010-01-11 13:43:07 +01001853 if (!bts) {
1854 vty_out(vty, "%% Unable to allocate BTS %u%s",
1855 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001856 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001857 }
Harald Welte5258fc42009-03-28 19:07:53 +00001858
1859 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001860 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001861 vty->node = BTS_NODE;
1862
1863 return CMD_SUCCESS;
1864}
1865
1866DEFUN(cfg_bts_type,
1867 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001868 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001869 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001870{
1871 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001872 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001873
Max7507aef2017-04-10 13:59:14 +02001874 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001875 if (rc < 0)
1876 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001877
Harald Welte5258fc42009-03-28 19:07:53 +00001878 return CMD_SUCCESS;
1879}
1880
Harald Weltefcd24452009-06-20 18:15:19 +02001881DEFUN(cfg_bts_band,
1882 cfg_bts_band_cmd,
1883 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001884 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001885{
1886 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001887 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001888
1889 if (band < 0) {
1890 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1891 band, VTY_NEWLINE);
1892 return CMD_WARNING;
1893 }
1894
1895 bts->band = band;
1896
1897 return CMD_SUCCESS;
1898}
1899
Maxc08ee712016-05-11 12:45:13 +02001900DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1901 "Configure discontinuous transmission\n"
1902 "Enable Uplink DTX for this BTS\n"
1903 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1904 "older phones).\n")
1905{
1906 struct gsm_bts *bts = vty->index;
1907
1908 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001909 if (!is_ipaccess_bts(bts))
1910 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1911 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001912 return CMD_SUCCESS;
1913}
1914
1915DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1916 NO_STR
1917 "Configure discontinuous transmission\n"
1918 "Disable Uplink DTX for this BTS\n")
1919{
1920 struct gsm_bts *bts = vty->index;
1921
1922 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1923
1924 return CMD_SUCCESS;
1925}
1926
1927DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1928 "Configure discontinuous transmission\n"
1929 "Enable Downlink DTX for this BTS\n")
1930{
1931 struct gsm_bts *bts = vty->index;
1932
1933 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001934 if (!is_ipaccess_bts(bts))
1935 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1936 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001937 return CMD_SUCCESS;
1938}
1939
1940DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1941 NO_STR
1942 "Configure discontinuous transmission\n"
1943 "Disable Downlink DTX for this BTS\n")
1944{
1945 struct gsm_bts *bts = vty->index;
1946
1947 bts->dtxd = false;
1948
1949 return CMD_SUCCESS;
1950}
1951
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001952DEFUN(cfg_bts_ci,
1953 cfg_bts_ci_cmd,
1954 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001955 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001956{
1957 struct gsm_bts *bts = vty->index;
1958 int ci = atoi(argv[0]);
1959
1960 if (ci < 0 || ci > 0xffff) {
1961 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1962 ci, VTY_NEWLINE);
1963 return CMD_WARNING;
1964 }
1965 bts->cell_identity = ci;
1966
1967 return CMD_SUCCESS;
1968}
1969
Harald Welte5258fc42009-03-28 19:07:53 +00001970DEFUN(cfg_bts_lac,
1971 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001972 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001973 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001974{
1975 struct gsm_bts *bts = vty->index;
1976 int lac = atoi(argv[0]);
1977
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001978 if (lac < 0 || lac > 0xffff) {
1979 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001980 lac, VTY_NEWLINE);
1981 return CMD_WARNING;
1982 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001983
1984 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1985 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1986 lac, VTY_NEWLINE);
1987 return CMD_WARNING;
1988 }
1989
Harald Welte5258fc42009-03-28 19:07:53 +00001990 bts->location_area_code = lac;
1991
1992 return CMD_SUCCESS;
1993}
1994
Harald Weltea43f7892009-12-01 18:04:30 +05301995
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001996/* compatibility wrapper for old config files */
1997DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001998 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001999 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002000 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00002001{
Harald Welte5258fc42009-03-28 19:07:53 +00002002 return CMD_SUCCESS;
2003}
2004
Harald Welte78f2f502009-05-23 16:56:52 +00002005DEFUN(cfg_bts_bsic,
2006 cfg_bts_bsic_cmd,
2007 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002008 "Set the Base Station Identity Code (BSIC) of this BTS\n"
2009 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00002010{
2011 struct gsm_bts *bts = vty->index;
2012 int bsic = atoi(argv[0]);
2013
2014 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02002015 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00002016 bsic, VTY_NEWLINE);
2017 return CMD_WARNING;
2018 }
2019 bts->bsic = bsic;
2020
2021 return CMD_SUCCESS;
2022}
2023
Harald Welte4cc34222009-05-01 15:12:31 +00002024DEFUN(cfg_bts_unit_id,
2025 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02002026 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002027 "Abis/IP specific options\n"
2028 "Set the IPA BTS Unit ID\n"
2029 "Unit ID (Site)\n"
2030 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00002031{
2032 struct gsm_bts *bts = vty->index;
2033 int site_id = atoi(argv[0]);
2034 int bts_id = atoi(argv[1]);
2035
Harald Welte07dc73d2009-08-07 13:27:09 +02002036 if (!is_ipaccess_bts(bts)) {
2037 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2038 return CMD_WARNING;
2039 }
2040
Harald Welte4cc34222009-05-01 15:12:31 +00002041 bts->ip_access.site_id = site_id;
2042 bts->ip_access.bts_id = bts_id;
2043
2044 return CMD_SUCCESS;
2045}
2046
Harald Welte8b291802013-03-12 13:57:05 +01002047DEFUN(cfg_bts_rsl_ip,
2048 cfg_bts_rsl_ip_cmd,
2049 "ip.access rsl-ip A.B.C.D",
2050 "Abis/IP specific options\n"
2051 "Set the IPA RSL IP Address of the BSC\n"
2052 "Destination IP address for RSL connection\n")
2053{
2054 struct gsm_bts *bts = vty->index;
2055 struct in_addr ia;
2056
2057 if (!is_ipaccess_bts(bts)) {
2058 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2059 return CMD_WARNING;
2060 }
2061
2062 inet_aton(argv[0], &ia);
2063 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
2064
2065 return CMD_SUCCESS;
2066}
2067
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002068#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01002069
Sylvain Munautc9519462011-10-17 14:04:55 +02002070DEFUN(cfg_bts_nokia_site_skip_reset,
2071 cfg_bts_nokia_site_skip_reset_cmd,
2072 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002073 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002074 "Skip the reset step during bootstrap process of this BTS\n"
2075 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02002076{
2077 struct gsm_bts *bts = vty->index;
2078
2079 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
2080 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
2081 return CMD_WARNING;
2082 }
2083
2084 bts->nokia.skip_reset = atoi(argv[0]);
2085
2086 return CMD_SUCCESS;
2087}
2088
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002089DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
2090 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
2091 "nokia_site no-local-rel-conf (0|1)",
2092 NOKIA_STR
2093 "Do not wait for RELease CONFirm message when releasing channel locally\n"
2094 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
2095{
2096 struct gsm_bts *bts = vty->index;
2097
2098 if (!is_nokia_bts(bts)) {
2099 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2100 VTY_NEWLINE);
2101 return CMD_WARNING;
2102 }
2103
2104 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
2105
2106 return CMD_SUCCESS;
2107}
2108
Sipos Csaba56e17662015-02-07 13:27:36 +01002109DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
2110 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
2111 "nokia_site bts-reset-timer <15-100>",
2112 NOKIA_STR
2113 "The amount of time (in sec.) between BTS_RESET is sent,\n"
2114 "and the BTS is being bootstrapped.\n")
2115{
2116 struct gsm_bts *bts = vty->index;
2117
2118 if (!is_nokia_bts(bts)) {
2119 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2120 VTY_NEWLINE);
2121 return CMD_WARNING;
2122 }
2123
2124 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
2125
2126 return CMD_SUCCESS;
2127}
Harald Welte8f0ed552010-05-11 21:53:49 +02002128#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002129#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02002130
Harald Welte8175e952009-10-20 00:22:00 +02002131DEFUN(cfg_bts_stream_id,
2132 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002133 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02002134 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002135 "Set the ip.access Stream ID of the OML link of this BTS\n"
2136 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02002137{
2138 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002139 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02002140
2141 if (!is_ipaccess_bts(bts)) {
2142 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2143 return CMD_WARNING;
2144 }
2145
2146 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002147 /* This is used by e1inp_bind_ops callback for each BTS model. */
2148 bts->oml_e1_link.e1_nr = linenr;
2149
2150 return CMD_SUCCESS;
2151}
2152
Harald Welted13e0cd2012-08-17 09:52:03 +02002153#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02002154
Harald Welte42581822009-08-08 16:12:58 +02002155DEFUN(cfg_bts_oml_e1,
2156 cfg_bts_oml_e1_cmd,
2157 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02002158 OML_E1_STR
2159 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002160 "E1/T1 line number to be used for OML\n"
2161 "E1/T1 timeslot to be used for OML\n"
2162 "E1/T1 timeslot to be used for OML\n"
2163 "E1/T1 sub-slot to be used for OML\n"
2164 "Use E1/T1 sub-slot 0\n"
2165 "Use E1/T1 sub-slot 1\n"
2166 "Use E1/T1 sub-slot 2\n"
2167 "Use E1/T1 sub-slot 3\n"
2168 "Use full E1 slot 3\n"
2169 )
Harald Welte42581822009-08-08 16:12:58 +02002170{
2171 struct gsm_bts *bts = vty->index;
2172
2173 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2174
2175 return CMD_SUCCESS;
2176}
2177
2178
2179DEFUN(cfg_bts_oml_e1_tei,
2180 cfg_bts_oml_e1_tei_cmd,
2181 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002182 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002183 "Set the TEI to be used for OML\n"
2184 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002185{
2186 struct gsm_bts *bts = vty->index;
2187
2188 bts->oml_tei = atoi(argv[0]);
2189
2190 return CMD_SUCCESS;
2191}
2192
Harald Welte7a8fa412009-08-10 13:48:16 +02002193DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2194 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002195 "Channnel Allocator\n" "Channel Allocator\n"
2196 "Allocate Timeslots and Transceivers in ascending order\n"
2197 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002198{
2199 struct gsm_bts *bts = vty->index;
2200
2201 if (!strcmp(argv[0], "ascending"))
2202 bts->chan_alloc_reverse = 0;
2203 else
2204 bts->chan_alloc_reverse = 1;
2205
2206 return CMD_SUCCESS;
2207}
2208
Harald Welte8f0ed552010-05-11 21:53:49 +02002209#define RACH_STR "Random Access Control Channel\n"
2210
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002211DEFUN(cfg_bts_rach_tx_integer,
2212 cfg_bts_rach_tx_integer_cmd,
2213 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002214 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002215 "Set the raw tx integer value in RACH Control parameters IE\n"
2216 "Set the raw tx integer value in RACH Control parameters IE\n"
2217 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002218{
2219 struct gsm_bts *bts = vty->index;
2220 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2221 return CMD_SUCCESS;
2222}
2223
2224DEFUN(cfg_bts_rach_max_trans,
2225 cfg_bts_rach_max_trans_cmd,
2226 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002227 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002228 "Set the maximum number of RACH burst transmissions\n"
2229 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002230 "Maximum number of 1 RACH burst transmissions\n"
2231 "Maximum number of 2 RACH burst transmissions\n"
2232 "Maximum number of 4 RACH burst transmissions\n"
2233 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002234{
2235 struct gsm_bts *bts = vty->index;
2236 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2237 return CMD_SUCCESS;
2238}
2239
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002240#define CD_STR "Channel Description\n"
2241
2242DEFUN(cfg_bts_chan_desc_att,
2243 cfg_bts_chan_desc_att_cmd,
2244 "channel-descrption attach (0|1)",
2245 CD_STR
2246 "Set if attachment is required\n"
2247 "Attachment is NOT required\n"
2248 "Attachment is required (standard)\n")
2249{
2250 struct gsm_bts *bts = vty->index;
2251 bts->si_common.chan_desc.att = atoi(argv[0]);
2252 return CMD_SUCCESS;
2253}
2254
2255DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2256 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2257 "channel-descrption bs-pa-mfrms <2-9>",
2258 CD_STR
2259 "Set number of multiframe periods for paging groups\n"
2260 "Number of multiframe periods for paging groups\n")
2261{
2262 struct gsm_bts *bts = vty->index;
2263 int bs_pa_mfrms = atoi(argv[0]);
2264
2265 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2266 return CMD_SUCCESS;
2267}
2268
2269DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2270 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2271 "channel-descrption bs-ag-blks-res <0-7>",
2272 CD_STR
2273 "Set number of blocks reserved for access grant\n"
2274 "Number of blocks reserved for access grant\n")
2275{
2276 struct gsm_bts *bts = vty->index;
2277 int bs_ag_blks_res = atoi(argv[0]);
2278
2279 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2280 return CMD_SUCCESS;
2281}
2282
Harald Welte8f0ed552010-05-11 21:53:49 +02002283#define NM_STR "Network Management\n"
2284
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002285DEFUN(cfg_bts_rach_nm_b_thresh,
2286 cfg_bts_rach_nm_b_thresh_cmd,
2287 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002288 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002289 "Set the NM Busy Threshold\n"
2290 "Set the NM Busy Threshold\n"
2291 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002292{
2293 struct gsm_bts *bts = vty->index;
2294 bts->rach_b_thresh = atoi(argv[0]);
2295 return CMD_SUCCESS;
2296}
2297
2298DEFUN(cfg_bts_rach_nm_ldavg,
2299 cfg_bts_rach_nm_ldavg_cmd,
2300 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002301 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002302 "Set the NM Loadaverage Slots value\n"
2303 "Set the NM Loadaverage Slots value\n"
2304 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002305{
2306 struct gsm_bts *bts = vty->index;
2307 bts->rach_ldavg_slots = atoi(argv[0]);
2308 return CMD_SUCCESS;
2309}
2310
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002311DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2312 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002313 "Should this cell be barred from access?\n"
2314 "Should this cell be barred from access?\n"
2315 "Cell should NOT be barred\n"
2316 "Cell should be barred\n")
2317
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002318{
2319 struct gsm_bts *bts = vty->index;
2320
Harald Welte71355012009-12-21 23:08:18 +01002321 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002322
2323 return CMD_SUCCESS;
2324}
2325
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002326DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2327 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002328 RACH_STR
2329 "Should this cell allow emergency calls?\n"
2330 "Should this cell allow emergency calls?\n"
2331 "Should this cell allow emergency calls?\n"
2332 "Do NOT allow emergency calls\n"
2333 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002334{
2335 struct gsm_bts *bts = vty->index;
2336
2337 if (atoi(argv[0]) == 0)
2338 bts->si_common.rach_control.t2 |= 0x4;
2339 else
2340 bts->si_common.rach_control.t2 &= ~0x4;
2341
2342 return CMD_SUCCESS;
2343}
2344
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002345DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2346 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2347 RACH_STR
2348 "Set access control class\n"
2349 "Access control class 0\n"
2350 "Access control class 1\n"
2351 "Access control class 2\n"
2352 "Access control class 3\n"
2353 "Access control class 4\n"
2354 "Access control class 5\n"
2355 "Access control class 6\n"
2356 "Access control class 7\n"
2357 "Access control class 8\n"
2358 "Access control class 9\n"
2359 "Access control class 11 for PLMN use\n"
2360 "Access control class 12 for security services\n"
2361 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2362 "Access control class 14 for emergency services\n"
2363 "Access control class 15 for PLMN staff\n"
2364 "barred to use access control class\n"
2365 "allowed to use access control class\n")
2366{
2367 struct gsm_bts *bts = vty->index;
2368
2369 uint8_t control_class;
2370 uint8_t allowed = 0;
2371
2372 if (strcmp(argv[1], "allowed") == 0)
2373 allowed = 1;
2374
2375 control_class = atoi(argv[0]);
2376 if (control_class < 8)
2377 if (allowed)
2378 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2379 else
2380 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2381 else
2382 if (allowed)
2383 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2384 else
2385 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2386
2387 return CMD_SUCCESS;
2388}
2389
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002390DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2391 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002392 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002393 "Maximum transmit power of the MS\n"
2394 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002395 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002396{
2397 struct gsm_bts *bts = vty->index;
2398
2399 bts->ms_max_power = atoi(argv[0]);
2400
2401 return CMD_SUCCESS;
2402}
2403
Harald Weltecfaabbb2012-08-16 23:23:50 +02002404#define CELL_STR "Cell Parameters\n"
2405
Harald Welte73225282009-12-12 18:17:25 +01002406DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2407 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002408 CELL_STR "Cell re-selection parameters\n"
2409 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002410 "Cell Re-Selection Hysteresis in dB")
2411{
2412 struct gsm_bts *bts = vty->index;
2413
2414 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2415
2416 return CMD_SUCCESS;
2417}
2418
2419DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2420 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002421 "Minimum RxLev needed for cell access\n"
2422 "Minimum RxLev needed for cell access\n"
2423 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002424 "Minimum RxLev needed for cell access (better than -110dBm)")
2425{
2426 struct gsm_bts *bts = vty->index;
2427
2428 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2429
2430 return CMD_SUCCESS;
2431}
2432
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002433DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2434 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002435 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2436 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002437{
2438 struct gsm_bts *bts = vty->index;
2439
2440 bts->si_common.cell_ro_sel_par.present = 1;
2441 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2442
2443 return CMD_SUCCESS;
2444}
2445
2446DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2447 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002448 CELL_STR "Cell Re-Selection Parameters\n"
2449 "Cell Re-Selection Offset (CRO) in dB\n"
2450 "Cell Re-Selection Offset (CRO) in dB\n"
2451 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002452{
2453 struct gsm_bts *bts = vty->index;
2454
2455 bts->si_common.cell_ro_sel_par.present = 1;
2456 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2457
2458 return CMD_SUCCESS;
2459}
2460
2461DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2462 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002463 "Cell selection temporary negative offset\n"
2464 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002465 "Cell selection temporary negative offset in dB")
2466{
2467 struct gsm_bts *bts = vty->index;
2468
2469 bts->si_common.cell_ro_sel_par.present = 1;
2470 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2471
2472 return CMD_SUCCESS;
2473}
2474
2475DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2476 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002477 "Cell selection temporary negative offset\n"
2478 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002479 "Sets cell selection temporary negative offset to infinity")
2480{
2481 struct gsm_bts *bts = vty->index;
2482
2483 bts->si_common.cell_ro_sel_par.present = 1;
2484 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2485
2486 return CMD_SUCCESS;
2487}
2488
2489DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2490 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002491 "Cell selection penalty time\n"
2492 "Cell selection penalty time\n"
2493 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002494{
2495 struct gsm_bts *bts = vty->index;
2496
2497 bts->si_common.cell_ro_sel_par.present = 1;
2498 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2499
2500 return CMD_SUCCESS;
2501}
2502
2503DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2504 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002505 "Cell selection penalty time\n"
2506 "Cell selection penalty time\n"
2507 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002508 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2509 "and TEMPORARY_OFFSET is ignored)")
2510{
2511 struct gsm_bts *bts = vty->index;
2512
2513 bts->si_common.cell_ro_sel_par.present = 1;
2514 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2515
2516 return CMD_SUCCESS;
2517}
2518
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002519DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2520 "radio-link-timeout <4-64>",
2521 "Radio link timeout criterion (BTS side)\n"
2522 "Radio link timeout value (lost SACCH block)\n")
2523{
2524 struct gsm_bts *bts = vty->index;
2525
Harald Welte2f8b9d22017-06-18 11:12:13 +03002526 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2527
2528 return CMD_SUCCESS;
2529}
2530
2531DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2532 "radio-link-timeout infinite",
2533 "Radio link timeout criterion (BTS side)\n"
2534 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2535{
2536 struct gsm_bts *bts = vty->index;
2537
2538 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2539 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2540 return CMD_WARNING;
2541 }
2542
2543 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2544 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002545
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002546 return CMD_SUCCESS;
2547}
2548
Harald Welte8f0ed552010-05-11 21:53:49 +02002549#define GPRS_TEXT "GPRS Packet Network\n"
2550
Harald Welteaf387632010-03-14 23:30:30 +08002551DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002552 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002553 GPRS_TEXT
2554 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002555 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002556 "GPRS BSSGP VC Identifier")
2557{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002558 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002559 struct gsm_bts *bts = vty->index;
2560
Harald Welte4511d892010-04-18 15:51:20 +02002561 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002562 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2563 return CMD_WARNING;
2564 }
2565
Harald Welte97a282b2010-03-14 15:37:43 +08002566 bts->gprs.cell.bvci = atoi(argv[0]);
2567
2568 return CMD_SUCCESS;
2569}
2570
Harald Weltea5731cf2010-03-22 11:48:36 +08002571DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2572 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002573 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002574 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002575 "GPRS NS Entity Identifier")
2576{
2577 struct gsm_bts *bts = vty->index;
2578
Harald Welte4511d892010-04-18 15:51:20 +02002579 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002580 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2581 return CMD_WARNING;
2582 }
2583
2584 bts->gprs.nse.nsei = atoi(argv[0]);
2585
2586 return CMD_SUCCESS;
2587}
2588
Harald Welte8f0ed552010-05-11 21:53:49 +02002589#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2590 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002591
Harald Welte97a282b2010-03-14 15:37:43 +08002592DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2593 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002594 GPRS_TEXT NSVC_TEXT
2595 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002596 "GPRS NS VC Identifier")
2597{
2598 struct gsm_bts *bts = vty->index;
2599 int idx = atoi(argv[0]);
2600
Harald Welte4511d892010-04-18 15:51:20 +02002601 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002602 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2603 return CMD_WARNING;
2604 }
2605
Harald Welte97a282b2010-03-14 15:37:43 +08002606 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2607
2608 return CMD_SUCCESS;
2609}
2610
Harald Welteaf387632010-03-14 23:30:30 +08002611DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2612 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002613 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002614 "GPRS NS Local UDP Port\n"
2615 "GPRS NS Local UDP Port\n"
2616 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002617 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002618{
2619 struct gsm_bts *bts = vty->index;
2620 int idx = atoi(argv[0]);
2621
Harald Welte4511d892010-04-18 15:51:20 +02002622 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002623 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2624 return CMD_WARNING;
2625 }
2626
Harald Welteaf387632010-03-14 23:30:30 +08002627 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2628
2629 return CMD_SUCCESS;
2630}
2631
2632DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2633 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002634 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002635 "GPRS NS Remote UDP Port\n"
2636 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002637 "GPRS NS Remote UDP Port\n"
2638 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002639{
2640 struct gsm_bts *bts = vty->index;
2641 int idx = atoi(argv[0]);
2642
Harald Welte4511d892010-04-18 15:51:20 +02002643 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002644 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2645 return CMD_WARNING;
2646 }
2647
Harald Welteaf387632010-03-14 23:30:30 +08002648 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2649
2650 return CMD_SUCCESS;
2651}
2652
2653DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2654 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002655 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002656 "GPRS NS Remote IP Address\n"
2657 "GPRS NS Remote IP Address\n"
2658 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002659{
2660 struct gsm_bts *bts = vty->index;
2661 int idx = atoi(argv[0]);
2662 struct in_addr ia;
2663
Harald Welte4511d892010-04-18 15:51:20 +02002664 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002665 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2666 return CMD_WARNING;
2667 }
2668
Harald Welteaf387632010-03-14 23:30:30 +08002669 inet_aton(argv[1], &ia);
2670 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2671
2672 return CMD_SUCCESS;
2673}
2674
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002675DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002676 "paging free <-1-1024>",
2677 "Paging options\n"
2678 "Only page when having a certain amount of free slots\n"
2679 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002680{
2681 struct gsm_bts *bts = vty->index;
2682
2683 bts->paging.free_chans_need = atoi(argv[0]);
2684 return CMD_SUCCESS;
2685}
2686
Harald Welte615e9562010-05-11 23:50:21 +02002687DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2688 "gprs ns timer " NS_TIMERS " <0-255>",
2689 GPRS_TEXT "Network Service\n"
2690 "Network Service Timer\n"
2691 NS_TIMERS_HELP "Timer Value\n")
2692{
2693 struct gsm_bts *bts = vty->index;
2694 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2695 int val = atoi(argv[1]);
2696
2697 if (bts->gprs.mode == BTS_GPRS_NONE) {
2698 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2699 return CMD_WARNING;
2700 }
2701
2702 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2703 return CMD_WARNING;
2704
2705 bts->gprs.nse.timer[idx] = val;
2706
2707 return CMD_SUCCESS;
2708}
2709
2710#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 Welte28326062010-05-14 20:05:17 +02002711#define BSSGP_TIMERS_HELP \
2712 "Tbvc-block timeout\n" \
2713 "Tbvc-block retries\n" \
2714 "Tbvc-unblock retries\n" \
2715 "Tbvcc-reset timeout\n" \
2716 "Tbvc-reset retries\n" \
2717 "Tbvc-suspend timeout\n" \
2718 "Tbvc-suspend retries\n" \
2719 "Tbvc-resume timeout\n" \
2720 "Tbvc-resume retries\n" \
2721 "Tbvc-capa-update timeout\n" \
2722 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002723
2724DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2725 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2726 GPRS_TEXT "Cell / BSSGP\n"
2727 "Cell/BSSGP Timer\n"
2728 BSSGP_TIMERS_HELP "Timer Value\n")
2729{
2730 struct gsm_bts *bts = vty->index;
2731 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2732 int val = atoi(argv[1]);
2733
2734 if (bts->gprs.mode == BTS_GPRS_NONE) {
2735 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2736 return CMD_WARNING;
2737 }
2738
2739 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2740 return CMD_WARNING;
2741
2742 bts->gprs.cell.timer[idx] = val;
2743
2744 return CMD_SUCCESS;
2745}
2746
Harald Welte97a282b2010-03-14 15:37:43 +08002747DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2748 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002749 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002750 "GPRS Routing Area Code\n"
2751 "GPRS Routing Area Code\n"
2752 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002753{
2754 struct gsm_bts *bts = vty->index;
2755
Harald Welte4511d892010-04-18 15:51:20 +02002756 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002757 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2758 return CMD_WARNING;
2759 }
2760
Harald Welte97a282b2010-03-14 15:37:43 +08002761 bts->gprs.rac = atoi(argv[0]);
2762
2763 return CMD_SUCCESS;
2764}
2765
Max292ec582016-07-28 11:55:37 +02002766DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2767 "gprs control-ack-type-rach", GPRS_TEXT
2768 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2769 "four access bursts format instead of default RLC/MAC control block\n")
2770{
2771 struct gsm_bts *bts = vty->index;
2772
2773 if (bts->gprs.mode == BTS_GPRS_NONE) {
2774 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2775 return CMD_WARNING;
2776 }
2777
2778 bts->gprs.ctrl_ack_type_use_block = false;
2779
2780 return CMD_SUCCESS;
2781}
2782
2783DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2784 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2785 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2786 "four access bursts format instead of default RLC/MAC control block\n")
2787{
2788 struct gsm_bts *bts = vty->index;
2789
2790 if (bts->gprs.mode == BTS_GPRS_NONE) {
2791 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2792 return CMD_WARNING;
2793 }
2794
2795 bts->gprs.ctrl_ack_type_use_block = true;
2796
2797 return CMD_SUCCESS;
2798}
2799
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002800DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2801 "gprs network-control-order (nc0|nc1|nc2)",
2802 GPRS_TEXT
2803 "GPRS Network Control Order\n"
2804 "MS controlled cell re-selection, no measurement reporting\n"
2805 "MS controlled cell re-selection, MS sends measurement reports\n"
2806 "Network controlled cell re-selection, MS sends measurement reports\n")
2807{
2808 struct gsm_bts *bts = vty->index;
2809
2810 if (bts->gprs.mode == BTS_GPRS_NONE) {
2811 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2812 return CMD_WARNING;
2813 }
2814
2815 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2816
2817 return CMD_SUCCESS;
2818}
2819
Harald Welte4511d892010-04-18 15:51:20 +02002820DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2821 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002822 GPRS_TEXT
2823 "GPRS Mode for this BTS\n"
2824 "GPRS Disabled on this BTS\n"
2825 "GPRS Enabled on this BTS\n"
2826 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002827{
2828 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002829 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002830
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002831 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002832 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2833 VTY_NEWLINE);
2834 return CMD_WARNING;
2835 }
2836
2837 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002838
2839 return CMD_SUCCESS;
2840}
2841
bhargava350533c2016-07-21 11:14:34 +05302842DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2843 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2844 "gprs 11bit_rach_support_for_egprs (0|1)",
2845 GPRS_TEXT "11 bit RACH options\n"
2846 "Disable 11 bit RACH for EGPRS\n"
2847 "Enable 11 bit RACH for EGPRS")
2848{
2849 struct gsm_bts *bts = vty->index;
2850
2851 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2852
2853 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2854 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2855 return CMD_WARNING;
2856 }
2857
2858 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2859 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2860 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2861 " enabled%s", VTY_NEWLINE);
2862 return CMD_WARNING;
2863 }
2864
2865 return CMD_SUCCESS;
2866}
2867
Harald Welte9fbff4a2010-07-30 11:50:09 +02002868#define SI_TEXT "System Information Messages\n"
2869#define SI_TYPE_TEXT "(1|2|3|4|5|6|7|8|9|10|13|16|17|18|19|20|2bis|2ter|2quater|5bis|5ter)"
2870#define SI_TYPE_HELP "System Information Type 1\n" \
2871 "System Information Type 2\n" \
2872 "System Information Type 3\n" \
2873 "System Information Type 4\n" \
2874 "System Information Type 5\n" \
2875 "System Information Type 6\n" \
2876 "System Information Type 7\n" \
2877 "System Information Type 8\n" \
2878 "System Information Type 9\n" \
2879 "System Information Type 10\n" \
2880 "System Information Type 13\n" \
2881 "System Information Type 16\n" \
2882 "System Information Type 17\n" \
2883 "System Information Type 18\n" \
2884 "System Information Type 19\n" \
2885 "System Information Type 20\n" \
2886 "System Information Type 2bis\n" \
2887 "System Information Type 2ter\n" \
2888 "System Information Type 2quater\n" \
2889 "System Information Type 5bis\n" \
2890 "System Information Type 5ter\n"
2891
2892DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2893 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2894 SI_TEXT SI_TYPE_HELP
2895 "System Information Mode\n"
2896 "Static user-specified\n"
2897 "Dynamic, BSC-computed\n")
2898{
2899 struct gsm_bts *bts = vty->index;
2900 int type;
2901
2902 type = get_string_value(osmo_sitype_strs, argv[0]);
2903 if (type < 0) {
2904 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2905 return CMD_WARNING;
2906 }
2907
2908 if (!strcmp(argv[1], "static"))
2909 bts->si_mode_static |= (1 << type);
2910 else
2911 bts->si_mode_static &= ~(1 << type);
2912
2913 return CMD_SUCCESS;
2914}
2915
2916DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2917 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2918 SI_TEXT SI_TYPE_HELP
2919 "Static System Information filling\n"
2920 "Static user-specified SI content in HEX notation\n")
2921{
2922 struct gsm_bts *bts = vty->index;
2923 int rc, type;
2924
2925 type = get_string_value(osmo_sitype_strs, argv[0]);
2926 if (type < 0) {
2927 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2928 return CMD_WARNING;
2929 }
2930
2931 if (!(bts->si_mode_static & (1 << type))) {
2932 vty_out(vty, "SI Type %s is not configured in static mode%s",
2933 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2934 return CMD_WARNING;
2935 }
2936
Harald Welte290aaed2010-07-30 11:53:18 +02002937 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002938 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002939
2940 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002941 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2942 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002943 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2944 return CMD_WARNING;
2945 }
2946
2947 /* Mark this SI as present */
2948 bts->si_valid |= (1 << type);
2949
2950 return CMD_SUCCESS;
2951}
2952
Harald Welte42def722017-01-13 00:10:32 +01002953DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2954 "early-classmark-sending (allowed|forbidden)",
2955 "Early Classmark Sending\n"
2956 "Early Classmark Sending is allowed\n"
2957 "Early Classmark Sending is forbidden\n")
2958{
2959 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002960
2961 if (!strcmp(argv[0], "allowed"))
2962 bts->early_classmark_allowed = true;
2963 else
2964 bts->early_classmark_allowed = false;
2965
2966 return CMD_SUCCESS;
2967}
2968
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002969DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2970 "early-classmark-sending-3g (allowed|forbidden)",
2971 "3G Early Classmark Sending\n"
2972 "3G Early Classmark Sending is allowed\n"
2973 "3G Early Classmark Sending is forbidden\n")
2974{
2975 struct gsm_bts *bts = vty->index;
2976
2977 if (!strcmp(argv[0], "allowed"))
2978 bts->early_classmark_allowed_3g = true;
2979 else
2980 bts->early_classmark_allowed_3g = false;
2981
2982 return CMD_SUCCESS;
2983}
2984
Harald Welte32c09622011-01-11 23:44:56 +01002985DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002986 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002987 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002988 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2989 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002990{
2991 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002992 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002993
Harald Welte64c07d22011-02-15 11:43:27 +01002994 switch (mode) {
2995 case NL_MODE_MANUAL_SI5SEP:
2996 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002997 /* make sure we clear the current list when switching to
2998 * manual mode */
2999 if (bts->neigh_list_manual_mode == 0)
3000 memset(&bts->si_common.data.neigh_list, 0,
3001 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01003002 break;
3003 default:
3004 break;
3005 }
3006
3007 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01003008
3009 return CMD_SUCCESS;
3010}
3011
3012DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003013 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01003014 "Neighbor List\n" "Add to manual neighbor list\n"
3015 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
3016 "ARFCN of neighbor\n")
3017{
3018 struct gsm_bts *bts = vty->index;
3019 struct bitvec *bv = &bts->si_common.neigh_list;
3020 uint16_t arfcn = atoi(argv[1]);
3021
3022 if (!bts->neigh_list_manual_mode) {
3023 vty_out(vty, "%% Cannot configure neighbor list in "
3024 "automatic mode%s", VTY_NEWLINE);
3025 return CMD_WARNING;
3026 }
3027
3028 if (!strcmp(argv[0], "add"))
3029 bitvec_set_bit_pos(bv, arfcn, 1);
3030 else
3031 bitvec_set_bit_pos(bv, arfcn, 0);
3032
3033 return CMD_SUCCESS;
3034}
3035
Max70fdd242017-06-15 15:10:53 +02003036/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02003037DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01003038 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
3039 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
3040 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
3041 "Add to manual SI2quater neighbor list\n"
3042 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
3043 "threshold high bits\n" "threshold high bits\n"
3044 "threshold low bits\n" "threshold low bits (32 means NA)\n"
3045 "priority\n" "priority (8 means NA)\n"
3046 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
3047 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02003048{
3049 struct gsm_bts *bts = vty->index;
3050 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
3051 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01003052 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
3053 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02003054 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02003055
Max70fdd242017-06-15 15:10:53 +02003056 switch (r) {
3057 case 1:
3058 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
3059 thresh_hi, VTY_NEWLINE);
3060 break;
3061 case EARFCN_THRESH_LOW_INVALID:
3062 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
3063 thresh_lo, VTY_NEWLINE);
3064 break;
3065 case EARFCN_QRXLV_INVALID + 1:
3066 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
3067 qrx, VTY_NEWLINE);
3068 break;
3069 case EARFCN_PRIO_INVALID:
3070 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
3071 prio, VTY_NEWLINE);
3072 break;
3073 default:
3074 if (r < 0) {
3075 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
3076 return CMD_WARNING;
3077 }
Max59a1bf32016-04-15 16:04:46 +02003078 }
3079
Max70fdd242017-06-15 15:10:53 +02003080 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01003081 return CMD_SUCCESS;
3082
Maxf39d03a2017-05-12 17:00:30 +02003083 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02003084 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02003085 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01003086
Maxaafff962016-04-20 15:57:14 +02003087 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02003088}
3089
3090DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02003091 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02003092 "SI2quater Neighbor List\n"
3093 "SI2quater Neighbor List\n"
3094 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02003095 "EARFCN of neighbor\n"
3096 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02003097{
3098 struct gsm_bts *bts = vty->index;
3099 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02003100 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02003101 int r = osmo_earfcn_del(e, arfcn);
3102 if (r < 0) {
3103 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02003104 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02003105 return CMD_WARNING;
3106 }
3107
3108 return CMD_SUCCESS;
3109}
3110
Max26679e02016-04-20 15:57:13 +02003111DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02003112 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02003113 "SI2quater Neighbor List\n"
3114 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
3115 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
3116 "diversity bit\n")
3117{
3118 struct gsm_bts *bts = vty->index;
3119 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
3120
3121 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
3122 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02003123 vty_out(vty, "Unable to add UARFCN: max number of UARFCNs (%u) reached%s", MAX_EARFCN_LIST, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01003124 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02003125 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02003126 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
3127 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01003128 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02003129 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02003130 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02003131 return CMD_WARNING;
3132 }
3133
3134 return CMD_SUCCESS;
3135}
3136
3137DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02003138 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02003139 "SI2quater Neighbor List\n"
3140 "SI2quater Neighbor List\n"
3141 "Delete from SI2quater manual neighbor list\n"
3142 "UARFCN of neighbor\n"
3143 "UARFCN\n"
3144 "scrambling code\n")
3145{
3146 struct gsm_bts *bts = vty->index;
3147
3148 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
3149 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
3150 VTY_NEWLINE);
3151 return CMD_WARNING;
3152 }
3153
3154 return CMD_SUCCESS;
3155}
3156
Harald Welte64c07d22011-02-15 11:43:27 +01003157DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003158 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003159 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003160 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
3161 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
3162 "ARFCN of neighbor\n")
3163{
3164 struct gsm_bts *bts = vty->index;
3165 struct bitvec *bv = &bts->si_common.si5_neigh_list;
3166 uint16_t arfcn = atoi(argv[1]);
3167
3168 if (!bts->neigh_list_manual_mode) {
3169 vty_out(vty, "%% Cannot configure neighbor list in "
3170 "automatic mode%s", VTY_NEWLINE);
3171 return CMD_WARNING;
3172 }
3173
3174 if (!strcmp(argv[0], "add"))
3175 bitvec_set_bit_pos(bv, arfcn, 1);
3176 else
3177 bitvec_set_bit_pos(bv, arfcn, 0);
3178
3179 return CMD_SUCCESS;
3180}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003181
Harald Welte8254cf72017-05-29 13:42:19 +02003182DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3183 "pcu-socket PATH",
3184 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3185 "Path in the file system for the unix-domain PCU socket\n")
3186{
3187 struct gsm_bts *bts = vty->index;
3188 int rc;
3189
Harald Welte4a824ca2017-05-29 13:54:27 +02003190 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003191 pcu_sock_exit(bts);
3192 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3193 if (rc < 0) {
3194 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3195 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3196 return CMD_WARNING;
3197 }
3198
3199 return CMD_SUCCESS;
3200}
3201
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003202#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3203
3204DEFUN(cfg_bts_excl_rf_lock,
3205 cfg_bts_excl_rf_lock_cmd,
3206 "rf-lock-exclude",
3207 EXCL_RFLOCK_STR)
3208{
3209 struct gsm_bts *bts = vty->index;
3210 bts->excl_from_rf_lock = 1;
3211 return CMD_SUCCESS;
3212}
3213
3214DEFUN(cfg_bts_no_excl_rf_lock,
3215 cfg_bts_no_excl_rf_lock_cmd,
3216 "no rf-lock-exclude",
3217 NO_STR EXCL_RFLOCK_STR)
3218{
3219 struct gsm_bts *bts = vty->index;
3220 bts->excl_from_rf_lock = 0;
3221 return CMD_SUCCESS;
3222}
3223
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003224#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3225
3226DEFUN(cfg_bts_force_comb_si,
3227 cfg_bts_force_comb_si_cmd,
3228 "force-combined-si",
3229 FORCE_COMB_SI_STR)
3230{
3231 struct gsm_bts *bts = vty->index;
3232 bts->force_combined_si = 1;
3233 return CMD_SUCCESS;
3234}
3235
3236DEFUN(cfg_bts_no_force_comb_si,
3237 cfg_bts_no_force_comb_si_cmd,
3238 "no force-combined-si",
3239 NO_STR FORCE_COMB_SI_STR)
3240{
3241 struct gsm_bts *bts = vty->index;
3242 bts->force_combined_si = 0;
3243 return CMD_SUCCESS;
3244}
3245
Andreas Eversberga83d5112013-12-07 18:32:28 +01003246static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3247{
3248 struct gsm_bts *bts = vty->index;
3249 struct bts_codec_conf *codec = &bts->codec;
3250 int i;
3251
3252 codec->hr = 0;
3253 codec->efr = 0;
3254 codec->amr = 0;
3255 for (i = 0; i < argc; i++) {
3256 if (!strcmp(argv[i], "hr"))
3257 codec->hr = 1;
3258 if (!strcmp(argv[i], "efr"))
3259 codec->efr = 1;
3260 if (!strcmp(argv[i], "amr"))
3261 codec->amr = 1;
3262 }
3263}
3264
3265#define CODEC_PAR_STR " (hr|efr|amr)"
3266#define CODEC_HELP_STR "Half Rate\n" \
3267 "Enhanced Full Rate\nAdaptive Multirate\n"
3268
3269DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3270 "codec-support fr",
3271 "Codec Support settings\nFullrate\n")
3272{
3273 _get_codec_from_arg(vty, 0, argv);
3274 return CMD_SUCCESS;
3275}
3276
3277DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3278 "codec-support fr" CODEC_PAR_STR,
3279 "Codec Support settings\nFullrate\n"
3280 CODEC_HELP_STR)
3281{
3282 _get_codec_from_arg(vty, 1, argv);
3283 return CMD_SUCCESS;
3284}
3285
3286DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3287 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3288 "Codec Support settings\nFullrate\n"
3289 CODEC_HELP_STR CODEC_HELP_STR)
3290{
3291 _get_codec_from_arg(vty, 2, argv);
3292 return CMD_SUCCESS;
3293}
3294
3295DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3296 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3297 "Codec Support settings\nFullrate\n"
3298 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3299{
3300 _get_codec_from_arg(vty, 3, argv);
3301 return CMD_SUCCESS;
3302}
3303
3304DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3305 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3306 "Codec Support settings\nFullrate\n"
3307 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3308{
3309 _get_codec_from_arg(vty, 4, argv);
3310 return CMD_SUCCESS;
3311}
3312
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003313DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3314 "depends-on-bts <0-255>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003315 "This BTS can only be started if another one is up\n"
3316 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003317{
3318 struct gsm_bts *bts = vty->index;
3319 struct gsm_bts *other_bts;
3320 int dep = atoi(argv[0]);
3321
3322
3323 if (!is_ipaccess_bts(bts)) {
3324 vty_out(vty, "This feature is only available for IP systems.%s",
3325 VTY_NEWLINE);
3326 return CMD_WARNING;
3327 }
3328
3329 other_bts = gsm_bts_num(bts->network, dep);
3330 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3331 vty_out(vty, "This feature is only available for IP systems.%s",
3332 VTY_NEWLINE);
3333 return CMD_WARNING;
3334 }
3335
3336 if (dep >= bts->nr) {
3337 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3338 VTY_NEWLINE);
3339 return CMD_WARNING;
3340 }
3341
3342 bts_depend_mark(bts, dep);
3343 return CMD_SUCCESS;
3344}
3345
3346DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3347 "depeneds-on-bts <0-255>",
3348 NO_STR "This BTS can only be started if another one is up\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003349 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003350{
3351 struct gsm_bts *bts = vty->index;
3352 int dep = atoi(argv[0]);
3353
3354 bts_depend_clear(bts, dep);
3355 return CMD_SUCCESS;
3356}
3357
Andreas Eversberg73266522014-01-19 11:47:44 +01003358#define AMR_TEXT "Adaptive Multi Rate settings\n"
3359#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3360#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3361 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3362#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3363#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3364
3365static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3366{
3367 struct gsm_bts *bts = vty->index;
3368 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3369 struct gsm48_multi_rate_conf *mr_conf =
3370 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3371 int i;
3372
3373 mr->gsm48_ie[1] = 0;
3374 for (i = 0; i < argc; i++)
3375 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3376 mr_conf->icmi = 0;
3377}
3378
3379static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3380{
3381 struct gsm_bts *bts = vty->index;
3382 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003383 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003384 int i;
3385
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003386 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3387 for (i = 0; i < argc - 1; i++)
3388 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003389}
3390
3391static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3392{
3393 struct gsm_bts *bts = vty->index;
3394 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003395 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003396 int i;
3397
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003398 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3399 for (i = 0; i < argc - 1; i++)
3400 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003401}
3402
3403static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3404{
3405 struct gsm_bts *bts = vty->index;
3406 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3407 struct gsm48_multi_rate_conf *mr_conf =
3408 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3409 int num = 0, i;
3410
3411 for (i = 0; i < ((full) ? 8 : 6); i++) {
3412 if ((mr->gsm48_ie[1] & (1 << i))) {
3413 num++;
3414 }
3415 }
3416
3417 if (argv[0][0] == 'a' || num == 0)
3418 mr_conf->icmi = 0;
3419 else {
3420 mr_conf->icmi = 1;
3421 if (num < atoi(argv[0]))
3422 mr_conf->smod = num - 1;
3423 else
3424 mr_conf->smod = atoi(argv[0]) - 1;
3425 }
3426}
3427
3428#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3429#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3430 "10,2k\n12,2k\n"
3431
3432#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3433#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3434
3435#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3436#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3437
3438DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3439 "amr tch-f modes" AMR_TCHF_PAR_STR,
3440 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3441 AMR_TCHF_HELP_STR)
3442{
3443 get_amr_from_arg(vty, 1, argv, 1);
3444 return CMD_SUCCESS;
3445}
3446
3447DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3448 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3449 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3450 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3451{
3452 get_amr_from_arg(vty, 2, argv, 1);
3453 return CMD_SUCCESS;
3454}
3455
3456DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3457 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3458 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3459 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3460{
3461 get_amr_from_arg(vty, 3, argv, 1);
3462 return CMD_SUCCESS;
3463}
3464
3465DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3466 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3467 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3468 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3469{
3470 get_amr_from_arg(vty, 4, argv, 1);
3471 return CMD_SUCCESS;
3472}
3473
3474DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3475 "amr tch-f start-mode (auto|1|2|3|4)",
3476 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3477{
3478 get_amr_start_from_arg(vty, argv, 1);
3479 return CMD_SUCCESS;
3480}
3481
3482DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3483 "amr tch-f threshold (ms|bts) <0-63>",
3484 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3485 AMR_TH_HELP_STR)
3486{
3487 get_amr_th_from_arg(vty, 2, argv, 1);
3488 return CMD_SUCCESS;
3489}
3490
3491DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3492 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3493 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3494 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3495{
3496 get_amr_th_from_arg(vty, 3, argv, 1);
3497 return CMD_SUCCESS;
3498}
3499
3500DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3501 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3502 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3503 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3504{
3505 get_amr_th_from_arg(vty, 4, argv, 1);
3506 return CMD_SUCCESS;
3507}
3508
3509DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3510 "amr tch-f hysteresis (ms|bts) <0-15>",
3511 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3512 AMR_HY_HELP_STR)
3513{
3514 get_amr_hy_from_arg(vty, 2, argv, 1);
3515 return CMD_SUCCESS;
3516}
3517
3518DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3519 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3520 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3521 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3522{
3523 get_amr_hy_from_arg(vty, 3, argv, 1);
3524 return CMD_SUCCESS;
3525}
3526
3527DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3528 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3529 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3530 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3531{
3532 get_amr_hy_from_arg(vty, 4, argv, 1);
3533 return CMD_SUCCESS;
3534}
3535
3536DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3537 "amr tch-h modes" AMR_TCHH_PAR_STR,
3538 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3539 AMR_TCHH_HELP_STR)
3540{
3541 get_amr_from_arg(vty, 1, argv, 0);
3542 return CMD_SUCCESS;
3543}
3544
3545DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3546 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3547 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3548 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3549{
3550 get_amr_from_arg(vty, 2, argv, 0);
3551 return CMD_SUCCESS;
3552}
3553
3554DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3555 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3556 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3557 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3558{
3559 get_amr_from_arg(vty, 3, argv, 0);
3560 return CMD_SUCCESS;
3561}
3562
3563DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3564 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3565 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3566 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3567{
3568 get_amr_from_arg(vty, 4, argv, 0);
3569 return CMD_SUCCESS;
3570}
3571
3572DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3573 "amr tch-h start-mode (auto|1|2|3|4)",
3574 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3575{
3576 get_amr_start_from_arg(vty, argv, 0);
3577 return CMD_SUCCESS;
3578}
3579
3580DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3581 "amr tch-h threshold (ms|bts) <0-63>",
3582 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3583 AMR_TH_HELP_STR)
3584{
3585 get_amr_th_from_arg(vty, 2, argv, 0);
3586 return CMD_SUCCESS;
3587}
3588
3589DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3590 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3591 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3592 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3593{
3594 get_amr_th_from_arg(vty, 3, argv, 0);
3595 return CMD_SUCCESS;
3596}
3597
3598DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3599 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3600 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3601 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3602{
3603 get_amr_th_from_arg(vty, 4, argv, 0);
3604 return CMD_SUCCESS;
3605}
3606
3607DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3608 "amr tch-h hysteresis (ms|bts) <0-15>",
3609 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3610 AMR_HY_HELP_STR)
3611{
3612 get_amr_hy_from_arg(vty, 2, argv, 0);
3613 return CMD_SUCCESS;
3614}
3615
3616DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3617 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3618 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3619 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3620{
3621 get_amr_hy_from_arg(vty, 3, argv, 0);
3622 return CMD_SUCCESS;
3623}
3624
3625DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3626 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3627 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3628 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3629{
3630 get_amr_hy_from_arg(vty, 4, argv, 0);
3631 return CMD_SUCCESS;
3632}
3633
Harald Welte8f0ed552010-05-11 21:53:49 +02003634#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003635
Harald Welte5258fc42009-03-28 19:07:53 +00003636/* per TRX configuration */
3637DEFUN(cfg_trx,
3638 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003639 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003640 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003641 "Select a TRX to configure")
3642{
3643 int trx_nr = atoi(argv[0]);
3644 struct gsm_bts *bts = vty->index;
3645 struct gsm_bts_trx *trx;
3646
Harald Weltee441d9c2009-06-21 16:17:15 +02003647 if (trx_nr > bts->num_trx) {
3648 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3649 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003650 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003651 } else if (trx_nr == bts->num_trx) {
3652 /* we need to allocate a new one */
3653 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003654 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003655 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003656
Harald Weltee441d9c2009-06-21 16:17:15 +02003657 if (!trx)
3658 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003659
3660 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003661 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003662 vty->node = TRX_NODE;
3663
3664 return CMD_SUCCESS;
3665}
3666
3667DEFUN(cfg_trx_arfcn,
3668 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003669 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003670 "Set the ARFCN for this TRX\n"
3671 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003672{
3673 int arfcn = atoi(argv[0]);
3674 struct gsm_bts_trx *trx = vty->index;
3675
3676 /* FIXME: check if this ARFCN is supported by this TRX */
3677
3678 trx->arfcn = arfcn;
3679
3680 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3681 /* FIXME: use OML layer to update the ARFCN */
3682 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3683
3684 return CMD_SUCCESS;
3685}
3686
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003687DEFUN(cfg_trx_nominal_power,
3688 cfg_trx_nominal_power_cmd,
3689 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003690 "Nominal TRX RF Power in dBm\n"
3691 "Nominal TRX RF Power in dBm\n"
3692 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003693{
3694 struct gsm_bts_trx *trx = vty->index;
3695
3696 trx->nominal_power = atoi(argv[0]);
3697
3698 return CMD_SUCCESS;
3699}
3700
Harald Weltefcd24452009-06-20 18:15:19 +02003701DEFUN(cfg_trx_max_power_red,
3702 cfg_trx_max_power_red_cmd,
3703 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003704 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003705 "Reduction of maximum BS RF Power in dB\n")
3706{
3707 int maxpwr_r = atoi(argv[0]);
3708 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003709 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003710
3711 /* FIXME: check if our BTS type supports more than 12 */
3712 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3713 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3714 maxpwr_r, VTY_NEWLINE);
3715 return CMD_WARNING;
3716 }
3717 if (maxpwr_r & 1) {
3718 vty_out(vty, "%% Power %d dB is not an even value%s",
3719 maxpwr_r, VTY_NEWLINE);
3720 return CMD_WARNING;
3721 }
3722
3723 trx->max_power_red = maxpwr_r;
3724
3725 /* FIXME: make sure we update this using OML */
3726
3727 return CMD_SUCCESS;
3728}
3729
Harald Welte42581822009-08-08 16:12:58 +02003730DEFUN(cfg_trx_rsl_e1,
3731 cfg_trx_rsl_e1_cmd,
3732 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003733 "RSL Parameters\n"
3734 "E1/T1 interface to be used for RSL\n"
3735 "E1/T1 interface to be used for RSL\n"
3736 "E1/T1 Line Number to be used for RSL\n"
3737 "E1/T1 Timeslot to be used for RSL\n"
3738 "E1/T1 Timeslot to be used for RSL\n"
3739 "E1/T1 Sub-slot to be used for RSL\n"
3740 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3741 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3742 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3743 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3744 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003745{
3746 struct gsm_bts_trx *trx = vty->index;
3747
3748 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3749
3750 return CMD_SUCCESS;
3751}
3752
3753DEFUN(cfg_trx_rsl_e1_tei,
3754 cfg_trx_rsl_e1_tei_cmd,
3755 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003756 "RSL Parameters\n"
3757 "Set the TEI to be used for RSL\n"
3758 "Set the TEI to be used for RSL\n"
3759 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003760{
3761 struct gsm_bts_trx *trx = vty->index;
3762
3763 trx->rsl_tei = atoi(argv[0]);
3764
3765 return CMD_SUCCESS;
3766}
3767
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003768DEFUN(cfg_trx_rf_locked,
3769 cfg_trx_rf_locked_cmd,
3770 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003771 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3772 "TRX is NOT RF locked (active)\n"
3773 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003774{
3775 int locked = atoi(argv[0]);
3776 struct gsm_bts_trx *trx = vty->index;
3777
Maxbe356ed2017-09-07 19:10:09 +02003778 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003779 return CMD_SUCCESS;
3780}
Harald Welte42581822009-08-08 16:12:58 +02003781
Harald Welte5258fc42009-03-28 19:07:53 +00003782/* per TS configuration */
3783DEFUN(cfg_ts,
3784 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003785 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003786 "Select a Timeslot to configure\n"
3787 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003788{
3789 int ts_nr = atoi(argv[0]);
3790 struct gsm_bts_trx *trx = vty->index;
3791 struct gsm_bts_trx_ts *ts;
3792
3793 if (ts_nr >= TRX_NR_TS) {
3794 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3795 TRX_NR_TS, VTY_NEWLINE);
3796 return CMD_WARNING;
3797 }
3798
3799 ts = &trx->ts[ts_nr];
3800
3801 vty->index = ts;
3802 vty->node = TS_NODE;
3803
3804 return CMD_SUCCESS;
3805}
3806
Harald Weltea6fd58e2009-08-07 00:25:23 +02003807DEFUN(cfg_ts_pchan,
3808 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003809 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003810 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003811{
3812 struct gsm_bts_trx_ts *ts = vty->index;
3813 int pchanc;
3814
3815 pchanc = gsm_pchan_parse(argv[0]);
3816 if (pchanc < 0)
3817 return CMD_WARNING;
3818
3819 ts->pchan = pchanc;
3820
3821 return CMD_SUCCESS;
3822}
3823
3824/* used for backwards compatibility with old config files that still
3825 * have uppercase pchan type names */
3826DEFUN_HIDDEN(cfg_ts_pchan_compat,
3827 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003828 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003829 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003830{
3831 struct gsm_bts_trx_ts *ts = vty->index;
3832 int pchanc;
3833
3834 pchanc = gsm_pchan_parse(argv[0]);
3835 if (pchanc < 0)
3836 return CMD_WARNING;
3837
3838 ts->pchan = pchanc;
3839
3840 return CMD_SUCCESS;
3841}
3842
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003843
3844
Harald Welte135a6482011-05-30 12:09:13 +02003845DEFUN(cfg_ts_tsc,
3846 cfg_ts_tsc_cmd,
3847 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003848 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003849{
3850 struct gsm_bts_trx_ts *ts = vty->index;
3851
Max71d082b2017-05-30 15:03:38 +02003852 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003853 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3854 "falling back to BCC%s", VTY_NEWLINE);
3855 ts->tsc = -1;
3856 return CMD_WARNING;
3857 }
3858
Harald Welte135a6482011-05-30 12:09:13 +02003859 ts->tsc = atoi(argv[0]);
3860
3861 return CMD_SUCCESS;
3862}
3863
Harald Weltea39b0f22010-06-14 22:26:10 +02003864#define HOPPING_STR "Configure frequency hopping\n"
3865
3866DEFUN(cfg_ts_hopping,
3867 cfg_ts_hopping_cmd,
3868 "hopping enabled (0|1)",
3869 HOPPING_STR "Enable or disable frequency hopping\n"
3870 "Disable frequency hopping\n" "Enable frequency hopping\n")
3871{
3872 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003873 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003874
Max71d082b2017-05-30 15:03:38 +02003875 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003876 vty_out(vty, "BTS model does not support hopping%s",
3877 VTY_NEWLINE);
3878 return CMD_WARNING;
3879 }
3880
3881 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003882
3883 return CMD_SUCCESS;
3884}
3885
Harald Welte6e0cd042009-09-12 13:05:33 +02003886DEFUN(cfg_ts_hsn,
3887 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003888 "hopping sequence-number <0-63>",
3889 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003890 "Which hopping sequence to use for this channel\n"
3891 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003892{
3893 struct gsm_bts_trx_ts *ts = vty->index;
3894
3895 ts->hopping.hsn = atoi(argv[0]);
3896
3897 return CMD_SUCCESS;
3898}
3899
3900DEFUN(cfg_ts_maio,
3901 cfg_ts_maio_cmd,
3902 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003903 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003904 "Which hopping MAIO to use for this channel\n"
3905 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003906{
3907 struct gsm_bts_trx_ts *ts = vty->index;
3908
3909 ts->hopping.maio = atoi(argv[0]);
3910
3911 return CMD_SUCCESS;
3912}
3913
3914DEFUN(cfg_ts_arfcn_add,
3915 cfg_ts_arfcn_add_cmd,
3916 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003917 HOPPING_STR "Configure hopping ARFCN list\n"
3918 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003919{
3920 struct gsm_bts_trx_ts *ts = vty->index;
3921 int arfcn = atoi(argv[0]);
3922
Harald Weltea39b0f22010-06-14 22:26:10 +02003923 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3924
Harald Welte6e0cd042009-09-12 13:05:33 +02003925 return CMD_SUCCESS;
3926}
3927
3928DEFUN(cfg_ts_arfcn_del,
3929 cfg_ts_arfcn_del_cmd,
3930 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003931 HOPPING_STR "Configure hopping ARFCN list\n"
3932 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003933{
3934 struct gsm_bts_trx_ts *ts = vty->index;
3935 int arfcn = atoi(argv[0]);
3936
Harald Weltea39b0f22010-06-14 22:26:10 +02003937 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3938
Harald Welte6e0cd042009-09-12 13:05:33 +02003939 return CMD_SUCCESS;
3940}
3941
Harald Weltea6fd58e2009-08-07 00:25:23 +02003942DEFUN(cfg_ts_e1_subslot,
3943 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003944 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003945 "E1/T1 channel connected to this on-air timeslot\n"
3946 "E1/T1 channel connected to this on-air timeslot\n"
3947 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003948 "E1/T1 timeslot connected to this on-air timeslot\n"
3949 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003950 "E1/T1 sub-slot connected to this on-air timeslot\n"
3951 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3952 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3953 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3954 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3955 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003956{
3957 struct gsm_bts_trx_ts *ts = vty->index;
3958
Harald Welte42581822009-08-08 16:12:58 +02003959 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003960
3961 return CMD_SUCCESS;
3962}
Harald Welte5258fc42009-03-28 19:07:53 +00003963
Harald Welte4f10c252010-05-16 21:47:13 +02003964void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3965{
Harald Weltecf9d4312017-12-13 23:17:16 +01003966 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003967 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003968 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003969 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003970}
3971
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003972DEFUN(drop_bts,
3973 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003974 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003975 "Debug/Simulation command to drop Abis/IP BTS\n"
3976 "Debug/Simulation command to drop Abis/IP BTS\n"
3977 "Debug/Simulation command to drop Abis/IP BTS\n"
3978 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003979{
3980 struct gsm_network *gsmnet;
3981 struct gsm_bts_trx *trx;
3982 struct gsm_bts *bts;
3983 unsigned int bts_nr;
3984
3985 gsmnet = gsmnet_from_vty(vty);
3986
3987 bts_nr = atoi(argv[0]);
3988 if (bts_nr >= gsmnet->num_bts) {
3989 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3990 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3991 return CMD_WARNING;
3992 }
3993
3994 bts = gsm_bts_num(gsmnet, bts_nr);
3995 if (!bts) {
3996 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3997 return CMD_WARNING;
3998 }
3999
4000 if (!is_ipaccess_bts(bts)) {
4001 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
4002 return CMD_WARNING;
4003 }
4004
4005
4006 /* close all connections */
4007 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004008 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004009 } else if (strcmp(argv[1], "rsl") == 0) {
4010 /* close all rsl connections */
4011 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004012 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004013 }
4014 } else {
4015 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
4016 return CMD_WARNING;
4017 }
4018
4019 return CMD_SUCCESS;
4020}
4021
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004022DEFUN(restart_bts, restart_bts_cmd,
4023 "restart-bts <0-65535>",
4024 "Restart ip.access nanoBTS through OML\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004025 BTS_NR_STR)
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004026{
4027 struct gsm_network *gsmnet;
4028 struct gsm_bts_trx *trx;
4029 struct gsm_bts *bts;
4030 unsigned int bts_nr;
4031
4032 gsmnet = gsmnet_from_vty(vty);
4033
4034 bts_nr = atoi(argv[0]);
4035 if (bts_nr >= gsmnet->num_bts) {
4036 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4037 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4038 return CMD_WARNING;
4039 }
4040
4041 bts = gsm_bts_num(gsmnet, bts_nr);
4042 if (!bts) {
4043 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4044 return CMD_WARNING;
4045 }
4046
4047 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
4048 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
4049 VTY_NEWLINE);
4050 return CMD_WARNING;
4051 }
4052
4053 /* go from last TRX to c0 */
4054 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4055 abis_nm_ipaccess_restart(trx);
4056
4057 return CMD_SUCCESS;
4058}
4059
Harald Welte8e2e22f2017-07-10 20:25:10 +02004060DEFUN(bts_resend, bts_resend_cmd,
4061 "bts <0-255> resend-system-information",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004062 "BTS Specific Commands\n" BTS_NR_STR
Harald Welte8e2e22f2017-07-10 20:25:10 +02004063 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
4064{
4065 struct gsm_network *gsmnet;
4066 struct gsm_bts_trx *trx;
4067 struct gsm_bts *bts;
4068 unsigned int bts_nr;
4069
4070 gsmnet = gsmnet_from_vty(vty);
4071
4072 bts_nr = atoi(argv[0]);
4073 if (bts_nr >= gsmnet->num_bts) {
4074 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4075 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4076 return CMD_WARNING;
4077 }
4078
4079 bts = gsm_bts_num(gsmnet, bts_nr);
4080 if (!bts) {
4081 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4082 return CMD_WARNING;
4083 }
4084
4085 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4086 gsm_bts_trx_set_system_infos(trx);
4087
4088 return CMD_SUCCESS;
4089}
4090
4091
Harald Welte30f1f372014-12-28 15:00:45 +01004092DEFUN(smscb_cmd, smscb_cmd_cmd,
4093 "bts <0-255> smscb-command <1-4> HEXSTRING",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004094 "BTS related commands\n" BTS_NR_STR
Harald Welte30f1f372014-12-28 15:00:45 +01004095 "SMS Cell Broadcast\n" "Last Valid Block\n"
4096 "Hex Encoded SMSCB message (up to 88 octets)\n")
4097{
4098 struct gsm_bts *bts;
4099 int bts_nr = atoi(argv[0]);
4100 int last_block = atoi(argv[1]);
4101 struct rsl_ie_cb_cmd_type cb_cmd;
4102 uint8_t buf[88];
4103 int rc;
4104
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02004105 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01004106 if (!bts) {
4107 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4108 return CMD_WARNING;
4109 }
4110 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
4111 if (rc < 0 || rc > sizeof(buf)) {
4112 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
4113 return CMD_WARNING;
4114 }
4115
4116 cb_cmd.spare = 0;
4117 cb_cmd.def_bcast = 0;
4118 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
4119
4120 switch (last_block) {
4121 case 1:
4122 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
4123 break;
4124 case 2:
4125 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
4126 break;
4127 case 3:
4128 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
4129 break;
4130 case 4:
4131 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
4132 break;
4133 }
4134
4135 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
4136
4137 return CMD_SUCCESS;
4138}
4139
Harald Welte7fe00fb2017-05-27 14:09:50 +02004140/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02004141static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
4142 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02004143{
Harald Welte645eb622017-05-27 15:52:58 +02004144 int bts_nr = atoi(bts_str);
4145 int trx_nr = atoi(trx_str);
4146 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004147 struct gsm_bts *bts;
4148 struct gsm_bts_trx *trx;
4149 struct gsm_bts_trx_ts *ts;
4150
4151 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
4152 if (!bts) {
4153 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4154 return NULL;
4155 }
4156
4157 trx = gsm_bts_trx_num(bts, trx_nr);
4158 if (!trx) {
4159 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
4160 return NULL;
4161 }
4162
4163 ts = &trx->ts[ts_nr];
4164
4165 return ts;
4166}
Harald Welte30f1f372014-12-28 15:00:45 +01004167
Harald Welted0d2b0b2010-12-23 13:18:07 +01004168DEFUN(pdch_act, pdch_act_cmd,
4169 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004170 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4171 "TRX Timeslot\n" TS_NR_STR "Packet Data Channel\n"
Harald Welted0d2b0b2010-12-23 13:18:07 +01004172 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4173 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4174{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004175 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004176 int activate;
4177
Harald Welte645eb622017-05-27 15:52:58 +02004178 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004179 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004180 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004181
Harald Welte7fe00fb2017-05-27 14:09:50 +02004182 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004183 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4184 VTY_NEWLINE);
4185 return CMD_WARNING;
4186 }
4187
Harald Welted0d2b0b2010-12-23 13:18:07 +01004188 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4189 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004190 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004191 return CMD_WARNING;
4192 }
4193
4194 if (!strcmp(argv[3], "activate"))
4195 activate = 1;
4196 else
4197 activate = 0;
4198
4199 rsl_ipacc_pdch_activate(ts, activate);
4200
4201 return CMD_SUCCESS;
4202
4203}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004204
Harald Welte2abd5e12017-05-27 14:10:40 +02004205/* determine the logical channel type based on the physical channel type */
4206static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4207{
4208 switch (pchan) {
4209 case GSM_PCHAN_TCH_F:
4210 return GSM_LCHAN_TCH_F;
4211 case GSM_PCHAN_TCH_H:
4212 return GSM_LCHAN_TCH_H;
4213 case GSM_PCHAN_SDCCH8_SACCH8C:
4214 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4215 case GSM_PCHAN_CCCH_SDCCH4:
4216 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4217 return GSM_LCHAN_SDCCH;
4218 default:
4219 return -1;
4220 }
4221}
4222
4223/* configure the lchan for a single AMR mode (as specified) */
4224static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4225{
4226 struct amr_multirate_conf mr;
4227 struct gsm48_multi_rate_conf *mr_conf;
4228 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4229
4230 if (amr_mode > 7)
4231 return -1;
4232
4233 memset(&mr, 0, sizeof(mr));
4234 mr_conf->ver = 1;
4235 /* bit-mask of supported modes, only one bit is set. Reflects
4236 * Figure 10.5.2.47a where there are no thershold and only a
4237 * single mode */
4238 mr.gsm48_ie[1] = 1 << amr_mode;
4239
4240 mr.ms_mode[0].mode = amr_mode;
4241 mr.bts_mode[0].mode = amr_mode;
4242
4243 /* encode this configuration into the lchan for both uplink and
4244 * downlink direction */
4245 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4246 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4247
4248 return 0;
4249}
4250
4251/* Debug/Measurement command to activate a given logical channel
4252 * manually in a given mode/codec. This is useful for receiver
4253 * performance testing (FER/RBER/...) */
4254DEFUN(lchan_act, lchan_act_cmd,
4255 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004256 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4257 "TRX Timeslot\n" TS_NR_STR "Sub-Slot Number\n" LCHAN_NR_STR
Harald Welte2abd5e12017-05-27 14:10:40 +02004258 "Manual Channel Activation (e.g. for BER test)\n"
4259 "Manual Channel Deactivation (e.g. for BER test)\n"
4260 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4261{
4262 struct gsm_bts_trx_ts *ts;
4263 struct gsm_lchan *lchan;
4264 int ss_nr = atoi(argv[3]);
4265 const char *act_str = argv[4];
4266 const char *codec_str = argv[5];
4267 int activate;
4268
4269 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4270 if (!ts)
4271 return CMD_WARNING;
4272
4273 lchan = &ts->lchan[ss_nr];
4274
4275 if (!strcmp(act_str, "activate"))
4276 activate = 1;
4277 else
4278 activate = 0;
4279
4280 if (ss_nr >= ts_subslots(ts)) {
4281 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4282 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4283 return CMD_WARNING;
4284 }
4285
4286 if (activate) {
4287 int lchan_t;
4288 if (lchan->state != LCHAN_S_NONE) {
4289 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4290 return CMD_WARNING;
4291 }
4292 lchan_t = lchan_type_by_pchan(ts->pchan);
4293 if (lchan_t < 0)
4294 return CMD_WARNING;
4295 /* configure the lchan */
4296 lchan->type = lchan_t;
4297 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4298 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4299 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4300 else if (!strcmp(codec_str, "efr"))
4301 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4302 else if (!strcmp(codec_str, "amr")) {
4303 int amr_mode;
4304 if (argc < 7) {
4305 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4306 return CMD_WARNING;
4307 }
4308 amr_mode = atoi(argv[6]);
4309 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4310 lchan_set_single_amr_mode(lchan, amr_mode);
4311 }
4312 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4313 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4314 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004315 } else {
4316 rsl_direct_rf_release(lchan);
4317 }
4318
4319 return CMD_SUCCESS;
4320}
4321
Harald Welte3f86c522017-05-27 15:53:28 +02004322DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4323 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004324 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4325 "TRX Timeslot\n" TS_NR_STR "Sub-Slot\n" LCHAN_NR_STR
Harald Welte3f86c522017-05-27 15:53:28 +02004326 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4327{
4328 struct gsm_bts_trx_ts *ts;
4329 struct gsm_lchan *lchan;
4330 int ss_nr = atoi(argv[3]);
4331 int port = atoi(argv[5]);
4332 struct in_addr ia;
4333 inet_aton(argv[4], &ia);
4334
4335 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4336 if (!ts)
4337 return CMD_WARNING;
4338
4339 lchan = &ts->lchan[ss_nr];
4340
4341 if (ss_nr >= ts_subslots(ts)) {
4342 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4343 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4344 return CMD_WARNING;
4345 }
4346
4347 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4348 inet_ntoa(ia), port, VTY_NEWLINE);
4349 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4350 return CMD_SUCCESS;
4351}
Harald Welteb71147a2017-07-18 19:11:49 +02004352
4353DEFUN(ctrl_trap, ctrl_trap_cmd,
4354 "ctrl-interface generate-trap TRAP VALUE",
4355 "Commands related to the CTRL Interface\n"
4356 "Generate a TRAP for test purpose\n"
4357 "Identity/Name of the TRAP variable\n"
4358 "Value of the TRAP variable\n")
4359{
4360 struct gsm_network *net = gsmnet_from_vty(vty);
4361
4362 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4363 return CMD_SUCCESS;
4364}
4365
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004366#define NETWORK_STR "Configure the GSM network\n"
4367#define CODE_CMD_STR "Code commands\n"
4368#define NAME_CMD_STR "Name Commands\n"
4369#define NAME_STR "Name to use\n"
4370
4371DEFUN(cfg_net,
4372 cfg_net_cmd,
4373 "network", NETWORK_STR)
4374{
4375 vty->index = gsmnet_from_vty(vty);
4376 vty->node = GSMNET_NODE;
4377
4378 return CMD_SUCCESS;
4379}
4380
4381DEFUN(cfg_net_ncc,
4382 cfg_net_ncc_cmd,
4383 "network country code <1-999>",
4384 "Set the GSM network country code\n"
4385 "Country commands\n"
4386 CODE_CMD_STR
4387 "Network Country Code to use\n")
4388{
4389 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4390
4391 gsmnet->country_code = atoi(argv[0]);
4392
4393 return CMD_SUCCESS;
4394}
4395
4396DEFUN(cfg_net_mnc,
4397 cfg_net_mnc_cmd,
4398 "mobile network code <0-999>",
4399 "Set the GSM mobile network code\n"
4400 "Network Commands\n"
4401 CODE_CMD_STR
4402 "Mobile Network Code to use\n")
4403{
4404 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4405
4406 gsmnet->network_code = atoi(argv[0]);
4407
4408 return CMD_SUCCESS;
4409}
4410
4411DEFUN(cfg_net_encryption,
4412 cfg_net_encryption_cmd,
4413 "encryption a5 (0|1|2|3)",
4414 "Encryption options\n"
4415 "A5 encryption\n" "A5/0: No encryption\n"
4416 "A5/1: Encryption\n" "A5/2: Export-grade Encryption\n"
4417 "A5/3: 'New' Secure Encryption\n")
4418{
4419 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4420
4421 gsmnet->a5_encryption = atoi(argv[0]);
4422
4423 return CMD_SUCCESS;
4424}
4425
4426DEFUN(cfg_net_dyn_ts_allow_tch_f,
4427 cfg_net_dyn_ts_allow_tch_f_cmd,
4428 "dyn_ts_allow_tch_f (0|1)",
4429 "Allow or disallow allocating TCH/F on TCH_F_TCH_H_PDCH timeslots\n"
4430 "Disallow TCH/F on TCH_F_TCH_H_PDCH (default)\n"
4431 "Allow TCH/F on TCH_F_TCH_H_PDCH\n")
4432{
4433 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4434 gsmnet->dyn_ts_allow_tch_f = atoi(argv[0]) ? true : false;
4435 return CMD_SUCCESS;
4436}
4437
4438DEFUN(cfg_net_timezone,
4439 cfg_net_timezone_cmd,
4440 "timezone <-19-19> (0|15|30|45)",
4441 "Set the Timezone Offset of the network\n"
4442 "Timezone offset (hours)\n"
4443 "Timezone offset (00 minutes)\n"
4444 "Timezone offset (15 minutes)\n"
4445 "Timezone offset (30 minutes)\n"
4446 "Timezone offset (45 minutes)\n"
4447 )
4448{
4449 struct gsm_network *net = vty->index;
4450 int tzhr = atoi(argv[0]);
4451 int tzmn = atoi(argv[1]);
4452
4453 net->tz.hr = tzhr;
4454 net->tz.mn = tzmn;
4455 net->tz.dst = 0;
4456 net->tz.override = 1;
4457
4458 return CMD_SUCCESS;
4459}
4460
4461DEFUN(cfg_net_timezone_dst,
4462 cfg_net_timezone_dst_cmd,
4463 "timezone <-19-19> (0|15|30|45) <0-2>",
4464 "Set the Timezone Offset of the network\n"
4465 "Timezone offset (hours)\n"
4466 "Timezone offset (00 minutes)\n"
4467 "Timezone offset (15 minutes)\n"
4468 "Timezone offset (30 minutes)\n"
4469 "Timezone offset (45 minutes)\n"
4470 "DST offset (hours)\n"
4471 )
4472{
4473 struct gsm_network *net = vty->index;
4474 int tzhr = atoi(argv[0]);
4475 int tzmn = atoi(argv[1]);
4476 int tzdst = atoi(argv[2]);
4477
4478 net->tz.hr = tzhr;
4479 net->tz.mn = tzmn;
4480 net->tz.dst = tzdst;
4481 net->tz.override = 1;
4482
4483 return CMD_SUCCESS;
4484}
4485
4486DEFUN(cfg_net_no_timezone,
4487 cfg_net_no_timezone_cmd,
4488 "no timezone",
4489 NO_STR
4490 "Disable network timezone override, use system tz\n")
4491{
4492 struct gsm_network *net = vty->index;
4493
4494 net->tz.override = 0;
4495
4496 return CMD_SUCCESS;
4497}
4498
4499DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
4500 "periodic location update <6-1530>",
4501 "Periodic Location Updating Interval\n"
4502 "Periodic Location Updating Interval\n"
4503 "Periodic Location Updating Interval\n"
4504 "Periodic Location Updating Interval in Minutes\n")
4505{
4506 struct gsm_network *net = vty->index;
4507
4508 net->t3212 = atoi(argv[0]) / 6;
4509
4510 return CMD_SUCCESS;
4511}
4512
4513DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
4514 "no periodic location update",
4515 NO_STR
4516 "Periodic Location Updating Interval\n"
4517 "Periodic Location Updating Interval\n"
4518 "Periodic Location Updating Interval\n")
4519{
4520 struct gsm_network *net = vty->index;
4521
4522 net->t3212 = 0;
4523
4524 return CMD_SUCCESS;
4525}
4526
Harald Weltedcccb182010-05-16 20:52:23 +02004527extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004528
Maxdb0e3802017-01-12 19:35:11 +01004529int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004530{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004531 cfg_ts_pchan_cmd.string =
4532 vty_cmd_string_from_valstr(tall_bsc_ctx,
4533 gsm_pchant_names,
4534 "phys_chan_config (", "|", ")",
4535 VTY_DO_LOWER);
4536 cfg_ts_pchan_cmd.doc =
4537 vty_cmd_string_from_valstr(tall_bsc_ctx,
4538 gsm_pchant_descs,
4539 "Physical Channel Combination\n",
4540 "\n", "", 0);
4541
Harald Weltee555c2b2012-08-17 13:02:12 +02004542 cfg_bts_type_cmd.string =
4543 vty_cmd_string_from_valstr(tall_bsc_ctx,
4544 bts_type_names,
4545 "type (", "|", ")",
4546 VTY_DO_LOWER);
4547 cfg_bts_type_cmd.doc =
4548 vty_cmd_string_from_valstr(tall_bsc_ctx,
4549 bts_type_descs,
4550 "BTS Vendor/Type\n",
4551 "\n", "", 0);
4552
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004553 OSMO_ASSERT(vty_global_gsm_network == NULL);
4554 vty_global_gsm_network = network;
4555
4556 osmo_stats_vty_add_cmds();
4557
4558 install_element(CONFIG_NODE, &cfg_net_cmd);
4559 install_node(&net_node, config_write_net);
4560 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
4561 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
4562 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
4563 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
4564 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
4565 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
4566 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
4567 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
4568 install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);
Harald Weltee555c2b2012-08-17 13:02:12 +02004569
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004570 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004571 install_element_ve(&show_bts_cmd);
4572 install_element_ve(&show_trx_cmd);
4573 install_element_ve(&show_ts_cmd);
4574 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004575 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004576
Philipp Maier39f62bb2017-04-09 12:32:51 +02004577 install_element_ve(&show_subscr_conn_cmd);
4578 install_element_ve(&handover_subscr_conn_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004579 install_element_ve(&handover_any_cmd);
4580 install_element_ve(&assignment_subscr_conn_cmd);
4581 install_element_ve(&assignment_any_cmd);
Philipp Maier39f62bb2017-04-09 12:32:51 +02004582
Harald Welteb4d5b172010-05-12 16:10:35 +00004583 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004584 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004585
Maxdb0e3802017-01-12 19:35:11 +01004586 logging_vty_add_cmds(NULL);
Harald Welte2f4f4b82018-02-14 00:50:27 +01004587 osmo_talloc_vty_add_cmds();
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004588
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004589 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004590 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004591 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4592 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4593 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4594 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4595 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4596 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4597 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4598 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4599 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004600 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004601 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004602 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004603 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004604 /* See also handover commands added on net level from handover_vty.c */
Harald Welte5013b2a2009-08-07 13:29:14 +02004605
4606 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004607 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004608 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004609 install_element(BTS_NODE, &cfg_description_cmd);
4610 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004611 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004612 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004613 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4614 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4615 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4616 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004617 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4618 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004619 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004620 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004621 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004622 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004623 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004624 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004625 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004626 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4627 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004628 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004629 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4630 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004631 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4632 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4633 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004634 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4635 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004636 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004637 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004638 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004639 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004640 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4641 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004642 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4643 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4644 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4645 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4646 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4647 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004648 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004649 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004650 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304651 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004652 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004653 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004654 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004655 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4656 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004657 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004658 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004659 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004660 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004661 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4662 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4663 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004664 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004665 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4666 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004667 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004668 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004669 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4670 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004671 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004672 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4673 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004674 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4675 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004676 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4677 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004678 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4679 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004680 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4681 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4682 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4683 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4684 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004685 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4686 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004687 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4688 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4689 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4690 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4691 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4692 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4693 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4694 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4695 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4696 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4697 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4698 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4699 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4700 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4701 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4702 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4703 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4704 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4705 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4706 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4707 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4708 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004709 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004710 /* See also handover commands added on bts level from handover_vty.c */
Harald Welte68628e82009-03-10 12:17:57 +00004711
Harald Welte5258fc42009-03-28 19:07:53 +00004712 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004713 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004714 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004715 install_element(TRX_NODE, &cfg_description_cmd);
4716 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004717 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004718 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004719 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4720 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004721 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004722
Harald Welte5258fc42009-03-28 19:07:53 +00004723 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004724 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004725 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004726 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004727 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004728 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004729 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4730 install_element(TS_NODE, &cfg_ts_maio_cmd);
4731 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4732 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004733 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004734
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004735 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004736 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004737 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004738 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004739 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004740 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004741 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004742 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004743
Harald Welte81c9b9c2010-05-31 16:40:40 +02004744 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004745 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004746 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004747 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004748
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004749 ho_vty_init();
4750
Harald Weltedcccb182010-05-16 20:52:23 +02004751 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004752
Harald Welte68628e82009-03-10 12:17:57 +00004753 return 0;
4754}