blob: 9dc754e960a8450de2841b911182d98eb6c8d010 [file] [log] [blame]
Harald Welte68628e82009-03-10 12:17:57 +00001/* OpenBSC interface to quagga VTY */
Harald Welte51e4bf32017-12-23 17:30:18 +01002/* (C) 2009-2017 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>
Stefan Sperling6442e432018-02-06 14:44:54 +010063#include <osmocom/bsc/acc_ramp.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020064
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010065#include <inttypes.h>
66
Harald Weltec08e8be2011-03-04 13:53:51 +010067#include "../../bscconfig.h"
Harald Welte1353f962010-05-16 19:20:24 +020068
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010069#define BTS_NR_STR "BTS Number\n"
70#define TRX_NR_STR "TRX Number\n"
71#define TS_NR_STR "Timeslot Number\n"
Harald Welte0bfd8d92018-02-12 18:06:53 +010072#define SS_NR_STR "Sub-slot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020073#define LCHAN_NR_STR "Logical Channel Number\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010074#define BTS_TRX_STR BTS_NR_STR TRX_NR_STR
75#define BTS_TRX_TS_STR BTS_TRX_STR TS_NR_STR
76#define BTS_TRX_TS_LCHAN_STR BTS_TRX_TS_STR LCHAN_NR_STR
Harald Welte0bfd8d92018-02-12 18:06:53 +010077#define BTS_NR_TRX_TS_STR2 \
78 "BTS for manual command\n" BTS_NR_STR \
79 "TRX for manual command\n" TRX_NR_STR \
80 "Timeslot for manual command\n" TS_NR_STR
81#define BTS_NR_TRX_TS_SS_STR2 \
82 BTS_NR_TRX_TS_STR2 \
83 "Sub-slot for manual command\n" SS_NR_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020084
Harald Welteea4647d2010-05-12 17:19:53 +000085/* FIXME: this should go to some common file */
86static const struct value_string gprs_ns_timer_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020087 { 0, "tns-block" },
88 { 1, "tns-block-retries" },
89 { 2, "tns-reset" },
90 { 3, "tns-reset-retries" },
91 { 4, "tns-test" },
92 { 5, "tns-alive" },
93 { 6, "tns-alive-retries" },
94 { 0, NULL }
95};
96
Harald Welteea4647d2010-05-12 17:19:53 +000097static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020098 { 0, "blocking-timer" },
99 { 1, "blocking-retries" },
100 { 2, "unblocking-retries" },
101 { 3, "reset-timer" },
102 { 4, "reset-retries" },
103 { 5, "suspend-timer" },
104 { 6, "suspend-retries" },
105 { 7, "resume-timer" },
106 { 8, "resume-retries" },
107 { 9, "capability-update-timer" },
108 { 10, "capability-update-retries" },
109 { 0, NULL }
110};
111
Harald Welte64c07d22011-02-15 11:43:27 +0100112static const struct value_string bts_neigh_mode_strs[] = {
113 { NL_MODE_AUTOMATIC, "automatic" },
114 { NL_MODE_MANUAL, "manual" },
115 { NL_MODE_MANUAL_SI5SEP, "manual-si5" },
116 { 0, NULL }
117};
118
Daniel Willmann7d109832012-05-14 18:43:23 +0200119const struct value_string bts_loc_fix_names[] = {
120 { BTS_LOC_FIX_INVALID, "invalid" },
121 { BTS_LOC_FIX_2D, "fix2d" },
122 { BTS_LOC_FIX_3D, "fix3d" },
123 { 0, NULL }
124};
125
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100126struct cmd_node net_node = {
127 GSMNET_NODE,
128 "%s(config-net)# ",
129 1,
130};
131
Harald Welte68628e82009-03-10 12:17:57 +0000132struct cmd_node bts_node = {
133 BTS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200134 "%s(config-net-bts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000135 1,
136};
137
138struct cmd_node trx_node = {
139 TRX_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200140 "%s(config-net-bts-trx)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000141 1,
142};
143
144struct cmd_node ts_node = {
145 TS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200146 "%s(config-net-bts-trx-ts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000147 1,
148};
149
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100150static struct gsm_network *vty_global_gsm_network = NULL;
151
152struct gsm_network *gsmnet_from_vty(struct vty *v)
153{
154 /* It can't hurt to force callers to continue to pass the vty instance
155 * to this function, in case we'd like to retrieve the global
156 * gsm_network instance from the vty at some point in the future. But
157 * until then, just return the global pointer, which should have been
158 * initialized by common_cs_vty_init().
159 */
160 OSMO_ASSERT(vty_global_gsm_network);
161 return vty_global_gsm_network;
162}
163
Harald Welte68628e82009-03-10 12:17:57 +0000164static int dummy_config_write(struct vty *v)
165{
166 return CMD_SUCCESS;
167}
168
169static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
170{
Harald Welte1304b352013-03-15 16:57:33 +0100171 vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
172 abis_nm_opstate_name(nms->operational),
173 get_value_string(abis_nm_adm_state_names, nms->administrative),
Harald Welte867d9f32011-05-23 20:30:39 +0200174 abis_nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000175}
176
Harald Welteb908cb72009-12-22 13:09:29 +0100177static void dump_pchan_load_vty(struct vty *vty, char *prefix,
178 const struct pchan_load *pl)
179{
180 int i;
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100181 int dumped = 0;
Harald Welteb908cb72009-12-22 13:09:29 +0100182
183 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
184 const struct load_counter *lc = &pl->pchan[i];
185 unsigned int percent;
186
187 if (lc->total == 0)
188 continue;
189
190 percent = (lc->used * 100) / lc->total;
191
192 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
193 gsm_pchan_name(i), percent, lc->used, lc->total,
194 VTY_NEWLINE);
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100195 dumped ++;
Harald Welteb908cb72009-12-22 13:09:29 +0100196 }
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100197 if (!dumped)
198 vty_out(vty, "%s(none)%s", prefix, VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100199}
200
Harald Welte68628e82009-03-10 12:17:57 +0000201static void net_dump_vty(struct vty *vty, struct gsm_network *net)
202{
Harald Welteb908cb72009-12-22 13:09:29 +0100203 struct pchan_load pl;
Harald Welte51e4bf32017-12-23 17:30:18 +0100204 int i;
Harald Welteb908cb72009-12-22 13:09:29 +0100205
Neels Hofmeyrf93970b2018-03-05 02:09:40 +0100206 vty_out(vty, "BSC is on MCC-MNC %s and has %u BTS%s",
207 osmo_plmn_name(&net->plmn), net->num_bts, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200208 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte51e4bf32017-12-23 17:30:18 +0100209 vty_out(vty, " Encryption:");
210 for (i = 0; i < 8; i++) {
211 if (net->a5_encryption_mask & (1 << i))
212 vty_out(vty, " A5/%u", i);
213 }
214 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100215 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
216 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800217 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
218 VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100219
220 {
221 struct gsm_bts *bts;
222 unsigned int ho_active_count = 0;
223 unsigned int ho_inactive_count = 0;
224
225 llist_for_each_entry(bts, &net->bts_list, list) {
226 if (ho_get_ho_active(bts->ho))
227 ho_active_count ++;
228 else
229 ho_inactive_count ++;
230 }
231
232 if (ho_active_count && ho_inactive_count)
233 vty_out(vty, " Handover: On at %u BTS, Off at %u BTS%s",
234 ho_active_count, ho_inactive_count, VTY_NEWLINE);
235 else
236 vty_out(vty, " Handover: %s%s", ho_active_count ? "On" : "Off",
237 VTY_NEWLINE);
238 }
239
Harald Welteb908cb72009-12-22 13:09:29 +0100240 network_chan_load(&pl, net);
241 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
242 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100243
244 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100245 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100246 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200247 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100248 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100249 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200250 vty_out(vty, " Last RF Lock Command: %s%s",
251 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
252 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000253}
254
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200255DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000256 SHOW_STR "Display information about a GSM NETWORK\n")
257{
Harald Weltedcccb182010-05-16 20:52:23 +0200258 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000259 net_dump_vty(vty, net);
260
261 return CMD_SUCCESS;
262}
263
264static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
265{
Harald Welteedb37782009-05-01 14:59:07 +0000266 struct e1inp_line *line;
267
268 if (!e1l) {
269 vty_out(vty, " None%s", VTY_NEWLINE);
270 return;
271 }
272
273 line = e1l->ts->line;
274
275 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
276 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000277 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000278 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000279 e1l->tei, e1l->sapi, VTY_NEWLINE);
280}
281
Neels Hofmeyrc1db52f2018-01-19 00:59:33 +0100282static void vty_out_neigh_list(struct vty *vty, struct bitvec *bv)
283{
284 int count = 0;
285 int i;
286 for (i = 0; i < 1024; i++) {
287 if (!bitvec_get_bit_pos(bv, i))
288 continue;
289 vty_out(vty, " %u", i);
290 count ++;
291 }
292 if (!count)
293 vty_out(vty, " (none)");
294 else
295 vty_out(vty, " (%d)", count);
296}
297
Philipp Maierf27dbc52018-02-21 13:25:57 +0100298static void bts_dump_vty_features(struct vty *vty, struct gsm_bts *bts)
299{
300 unsigned int i;
301 bool no_features = true;
302 vty_out(vty, " Features:%s", VTY_NEWLINE);
303
304 for (i = 0; i < _NUM_BTS_FEAT; i++) {
305 if (osmo_bts_has_feature(&bts->features, i)) {
306 vty_out(vty, " %03u ", i);
307 vty_out(vty, "%-40s%s", osmo_bts_feature_name(i), VTY_NEWLINE);
308 no_features = false;
309 }
310 }
311
312 if (no_features)
313 vty_out(vty, " (not available)%s", VTY_NEWLINE);
314}
315
Harald Welte68628e82009-03-10 12:17:57 +0000316static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
317{
Harald Welteb908cb72009-12-22 13:09:29 +0100318 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200319 unsigned long long sec;
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100320 struct gsm_bts_trx *trx;
321 int ts_hopping_total;
322 int ts_non_hopping_total;
Harald Welteb908cb72009-12-22 13:09:29 +0100323
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200324 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100325 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200326 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200327 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100328 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100329 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200330 bts->num_trx, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100331 vty_out(vty, " Description: %s%s",
Harald Welte197dea92010-05-14 17:59:53 +0200332 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100333
334 vty_out(vty, " ARFCNs:");
335 ts_hopping_total = 0;
336 ts_non_hopping_total = 0;
337 llist_for_each_entry(trx, &bts->trx_list, list) {
338 int ts_nr;
339 int ts_hopping = 0;
340 int ts_non_hopping = 0;
341 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
342 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
343 if (ts->hopping.enabled)
344 ts_hopping++;
345 else
346 ts_non_hopping++;
347 }
348
349 if (ts_non_hopping)
350 vty_out(vty, " %u", trx->arfcn);
351 ts_hopping_total += ts_hopping;
352 ts_non_hopping_total += ts_non_hopping;
353 }
354 if (ts_hopping_total) {
355 if (ts_non_hopping_total)
356 vty_out(vty, " / Hopping on %d of %d timeslots",
357 ts_hopping_total, ts_hopping_total + ts_non_hopping_total);
358 else
359 vty_out(vty, " Hopping on all %d timeslots", ts_hopping_total);
360 }
361 vty_out(vty, "%s", VTY_NEWLINE);
362
Maxf9685c12017-03-23 12:01:07 +0100363 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100364 vty_out(vty, " PCU version %s connected%s", bts->pcu_version,
Maxf9685c12017-03-23 12:01:07 +0100365 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100366 vty_out(vty, " MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
367 vty_out(vty, " Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100368 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
369 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100370 vty_out(vty, " Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100371 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Stefan Sperling6442e432018-02-06 14:44:54 +0100372 vty_out(vty, " Access Control Class ramping: %senabled%s",
373 acc_ramp_is_enabled(&bts->acc_ramp) ? "" : "not ", VTY_NEWLINE);
374 if (acc_ramp_is_enabled(&bts->acc_ramp)) {
375 if (!acc_ramp_step_interval_is_dynamic(&bts->acc_ramp))
376 vty_out(vty, " Access Control Class ramping step interval: %u seconds%s",
377 acc_ramp_get_step_interval(&bts->acc_ramp), VTY_NEWLINE);
378 else
379 vty_out(vty, " Access Control Class ramping step interval: dynamic%s", VTY_NEWLINE);
380 vty_out(vty, " enabling %u Access Control Class%s per ramping step%s",
381 acc_ramp_get_step_size(&bts->acc_ramp),
382 acc_ramp_get_step_size(&bts->acc_ramp) > 1 ? "es" : "", VTY_NEWLINE);
383 }
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100384 vty_out(vty, " RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100385 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100386 vty_out(vty, " RACH Max transmissions: %u%s",
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100387 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
388 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100389 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200390 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200391 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100392 vty_out(vty, " Uplink DTX: %s%s",
Maxc08ee712016-05-11 12:45:13 +0200393 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
394 "enabled" : "forced", VTY_NEWLINE);
395 else
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100396 vty_out(vty, " Uplink DTX: not enabled%s", VTY_NEWLINE);
397 vty_out(vty, " Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
Maxc08ee712016-05-11 12:45:13 +0200398 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100399 vty_out(vty, " Channel Description Attachment: %s%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200400 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100401 vty_out(vty, " Channel Description BS-PA-MFRMS: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200402 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100403 vty_out(vty, " Channel Description BS-AG_BLKS-RES: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200404 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100405 vty_out(vty, " System Information present: 0x%08x, static: 0x%08x%s",
Harald Welte9fbff4a2010-07-30 11:50:09 +0200406 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100407 vty_out(vty, " Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100408 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100409 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
410 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
411 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100412 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200413 if (bts->pcu_sock_path)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100414 vty_out(vty, " PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000415 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200416 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000417 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200418 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200419 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
420 vty_out(vty, " Skip Reset: %d%s",
421 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000422 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200423 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000424 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200425 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200426 vty_out(vty, " GPRS NSE: ");
427 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
428 vty_out(vty, " GPRS CELL: ");
429 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
430 vty_out(vty, " GPRS NSVC0: ");
431 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
432 vty_out(vty, " GPRS NSVC1: ");
433 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200434 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
435 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000436 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100437 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200438 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200439 sec = bts_uptime(bts);
440 if (sec)
Maxff3fad12018-01-07 16:50:42 +0100441 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.",
442 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60);
443 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100444 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200445 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
446 e1isl_dump_vty(vty, bts->oml_link);
447 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100448
Neels Hofmeyrc1db52f2018-01-19 00:59:33 +0100449 vty_out(vty, " Neighbor Cells: ");
450 switch (bts->neigh_list_manual_mode) {
451 default:
452 case NL_MODE_AUTOMATIC:
453 vty_out(vty, "Automatic");
454 /* generate_bcch_chan_list() should populate si_common.neigh_list */
455 break;
456 case NL_MODE_MANUAL:
457 vty_out(vty, "Manual");
458 break;
459 case NL_MODE_MANUAL_SI5SEP:
460 vty_out(vty, "Manual/separate SI5");
461 break;
462 }
463 vty_out(vty, ", ARFCNs:");
464 vty_out_neigh_list(vty, &bts->si_common.neigh_list);
465 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
466 vty_out(vty, " SI5:");
467 vty_out_neigh_list(vty, &bts->si_common.si5_neigh_list);
468 }
469 vty_out(vty, "%s", VTY_NEWLINE);
470
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100471 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100472 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200473 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100474 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
475 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100476
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100477 vty_out(vty, " Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
Harald Welted82101e2017-12-09 23:07:38 +0100478 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
479 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
480 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100481 vty_out(vty, " Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
Harald Welted82101e2017-12-09 23:07:38 +0100482 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
483 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
484 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100485 vty_out(vty, " BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
Harald Welted82101e2017-12-09 23:07:38 +0100486 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
487 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
488 VTY_NEWLINE);
Philipp Maierf27dbc52018-02-21 13:25:57 +0100489
490 bts_dump_vty_features(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +0000491}
492
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100493DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000494 SHOW_STR "Display information about a BTS\n"
495 "BTS number")
496{
Harald Weltedcccb182010-05-16 20:52:23 +0200497 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000498 int bts_nr;
499
500 if (argc != 0) {
501 /* use the BTS number that the user has specified */
502 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100503 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000504 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000505 VTY_NEWLINE);
506 return CMD_WARNING;
507 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200508 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000509 return CMD_SUCCESS;
510 }
511 /* print all BTS's */
512 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200513 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000514
515 return CMD_SUCCESS;
516}
517
Harald Welte42581822009-08-08 16:12:58 +0200518/* utility functions */
519static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
520 const char *ts, const char *ss)
521{
522 e1_link->e1_nr = atoi(line);
523 e1_link->e1_ts = atoi(ts);
524 if (!strcmp(ss, "full"))
525 e1_link->e1_ts_ss = 255;
526 else
527 e1_link->e1_ts_ss = atoi(ss);
528}
529
530static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
531 const char *prefix)
532{
533 if (!e1_link->e1_ts)
534 return;
535
536 if (e1_link->e1_ts_ss == 255)
537 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
538 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
539 else
540 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
541 prefix, e1_link->e1_nr, e1_link->e1_ts,
542 e1_link->e1_ts_ss, VTY_NEWLINE);
543}
544
545
Harald Welte67ce0732009-08-06 19:06:46 +0200546static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
547{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100548 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100549 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100550 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200551 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100552 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200553 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100554 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200555 ts->hopping.enabled, VTY_NEWLINE);
556 if (ts->hopping.enabled) {
557 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100558 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200559 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100560 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200561 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200562 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
563 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
564 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100565 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200566 i, VTY_NEWLINE);
567 }
Harald Welte127af342010-12-24 12:07:07 +0100568 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100569 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100570
571 if (ts->trx->bts->model->config_write_ts)
572 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200573}
574
575static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
576{
577 int i;
578
Harald Welte5013b2a2009-08-07 13:29:14 +0200579 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200580 if (trx->description)
581 vty_out(vty, " description %s%s", trx->description,
582 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200583 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200584 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200585 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200586 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100587 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200588 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200589 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
590 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200591
Harald Welteface7ed2011-02-14 16:15:21 +0100592 if (trx->bts->model->config_write_trx)
593 trx->bts->model->config_write_trx(vty, trx);
594
Harald Welte67ce0732009-08-06 19:06:46 +0200595 for (i = 0; i < TRX_NR_TS; i++)
596 config_write_ts_single(vty, &trx->ts[i]);
597}
598
Harald Welte615e9562010-05-11 23:50:21 +0200599static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
600{
601 unsigned int i;
602 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
603 VTY_NEWLINE);
604 if (bts->gprs.mode == BTS_GPRS_NONE)
605 return;
606
bhargava350533c2016-07-21 11:14:34 +0530607 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
608 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
609
Harald Welte615e9562010-05-11 23:50:21 +0200610 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
611 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100612 vty_out(vty, " gprs network-control-order nc%u%s",
613 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200614 if (!bts->gprs.ctrl_ack_type_use_block)
615 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200616 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
617 VTY_NEWLINE);
618 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
619 vty_out(vty, " gprs cell timer %s %u%s",
620 get_value_string(gprs_bssgp_cfg_strs, i),
621 bts->gprs.cell.timer[i], VTY_NEWLINE);
622 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
623 VTY_NEWLINE);
624 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
625 vty_out(vty, " gprs ns timer %s %u%s",
626 get_value_string(gprs_ns_timer_strs, i),
627 bts->gprs.nse.timer[i], VTY_NEWLINE);
628 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
629 struct gsm_bts_gprs_nsvc *nsvc =
630 &bts->gprs.nsvc[i];
631 struct in_addr ia;
632
633 ia.s_addr = htonl(nsvc->remote_ip);
634 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
635 nsvc->nsvci, VTY_NEWLINE);
636 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
637 nsvc->local_port, VTY_NEWLINE);
638 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
639 nsvc->remote_port, VTY_NEWLINE);
640 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
641 inet_ntoa(ia), VTY_NEWLINE);
642 }
643}
644
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200645/* Write the model data if there is one */
646static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200647{
648 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200649
650 if (!bts->model)
651 return;
652
653 if (bts->model->config_write_bts)
654 bts->model->config_write_bts(vty, bts);
655
656 llist_for_each_entry(trx, &bts->trx_list, list)
657 config_write_trx_single(vty, trx);
658}
659
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200660static void write_amr_modes(struct vty *vty, const char *prefix,
661 const char *name, struct amr_mode *modes, int num)
662{
663 int i;
664
665 vty_out(vty, " %s threshold %s", prefix, name);
666 for (i = 0; i < num - 1; i++)
667 vty_out(vty, " %d", modes[i].threshold);
668 vty_out(vty, "%s", VTY_NEWLINE);
669 vty_out(vty, " %s hysteresis %s", prefix, name);
670 for (i = 0; i < num - 1; i++)
671 vty_out(vty, " %d", modes[i].hysteresis);
672 vty_out(vty, "%s", VTY_NEWLINE);
673}
674
Andreas Eversberg73266522014-01-19 11:47:44 +0100675static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
676 struct amr_multirate_conf *mr, int full)
677{
678 struct gsm48_multi_rate_conf *mr_conf;
679 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
680 int i, num;
681
682 if (!(mr->gsm48_ie[1]))
683 return;
684
685 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
686
687 num = 0;
688 vty_out(vty, " %s modes", prefix);
689 for (i = 0; i < ((full) ? 8 : 6); i++) {
690 if ((mr->gsm48_ie[1] & (1 << i))) {
691 vty_out(vty, " %d", i);
692 num++;
693 }
694 }
695 vty_out(vty, "%s", VTY_NEWLINE);
696 if (num > 4)
697 num = 4;
698 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200699 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
700 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100701 }
702 vty_out(vty, " %s start-mode ", prefix);
703 if (mr_conf->icmi) {
704 num = 0;
705 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
706 if ((mr->gsm48_ie[1] & (1 << i)))
707 num++;
708 if (mr_conf->smod == num - 1) {
709 vty_out(vty, "%d%s", num, VTY_NEWLINE);
710 break;
711 }
712 }
713 } else
714 vty_out(vty, "auto%s", VTY_NEWLINE);
715}
716
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200717static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
718{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200719 int i;
Max2c16bee2017-02-15 13:51:37 +0100720 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200721
Harald Welte5013b2a2009-08-07 13:29:14 +0200722 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
723 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200724 if (bts->description)
725 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200726 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100727 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200728 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200729 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200730 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
731 vty_out(vty, " dtx uplink%s%s",
732 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
733 VTY_NEWLINE);
734 if (bts->dtxd)
735 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200736 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200737 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100738 vty_out(vty, " cell reselection hysteresis %u%s",
739 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
740 vty_out(vty, " rxlev access min %u%s",
741 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100742
743 if (bts->si_common.cell_ro_sel_par.present) {
744 struct gsm48_si_selection_params *sp;
745 sp = &bts->si_common.cell_ro_sel_par;
746
747 if (sp->cbq)
748 vty_out(vty, " cell bar qualify %u%s",
749 sp->cbq, VTY_NEWLINE);
750
751 if (sp->cell_resel_off)
752 vty_out(vty, " cell reselection offset %u%s",
753 sp->cell_resel_off*2, VTY_NEWLINE);
754
755 if (sp->temp_offs == 7)
756 vty_out(vty, " temporary offset infinite%s",
757 VTY_NEWLINE);
758 else if (sp->temp_offs)
759 vty_out(vty, " temporary offset %u%s",
760 sp->temp_offs*10, VTY_NEWLINE);
761
762 if (sp->penalty_time == 31)
763 vty_out(vty, " penalty time reserved%s",
764 VTY_NEWLINE);
765 else if (sp->penalty_time)
766 vty_out(vty, " penalty time %u%s",
767 (sp->penalty_time*20)+20, VTY_NEWLINE);
768 }
769
Harald Welte2f8b9d22017-06-18 11:12:13 +0300770 if (gsm_bts_get_radio_link_timeout(bts) < 0)
771 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
772 else
773 vty_out(vty, " radio-link-timeout %d%s",
774 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100775
Harald Welte7a8fa412009-08-10 13:48:16 +0200776 vty_out(vty, " channel allocator %s%s",
777 bts->chan_alloc_reverse ? "descending" : "ascending",
778 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100779 vty_out(vty, " rach tx integer %u%s",
780 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
781 vty_out(vty, " rach max transmission %u%s",
782 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
783 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800784
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200785 vty_out(vty, " channel-descrption attach %u%s",
786 bts->si_common.chan_desc.att, VTY_NEWLINE);
787 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
788 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
789 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
790 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
791
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800792 if (bts->rach_b_thresh != -1)
793 vty_out(vty, " rach nm busy threshold %u%s",
794 bts->rach_b_thresh, VTY_NEWLINE);
795 if (bts->rach_ldavg_slots != -1)
796 vty_out(vty, " rach nm load average %u%s",
797 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100798 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200799 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800800 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
801 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400802 if ((bts->si_common.rach_control.t3) != 0)
803 for (i = 0; i < 8; i++)
804 if (bts->si_common.rach_control.t3 & (0x1 << i))
805 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
806 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
807 for (i = 0; i < 8; i++)
808 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
809 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Stefan Sperling6442e432018-02-06 14:44:54 +0100810 vty_out(vty, " %saccess-control-class-ramping%s", acc_ramp_is_enabled(&bts->acc_ramp) ? "" : "no ", VTY_NEWLINE);
811 if (!acc_ramp_step_interval_is_dynamic(&bts->acc_ramp)) {
812 vty_out(vty, " access-control-class-ramping-step-interval %u%s",
813 acc_ramp_get_step_interval(&bts->acc_ramp), VTY_NEWLINE);
814 } else {
815 vty_out(vty, " access-control-class-ramping-step-interval dynamic%s", VTY_NEWLINE);
816 }
817 vty_out(vty, " access-control-class-ramping-step-size %u%s", acc_ramp_get_step_size(&bts->acc_ramp),
818 VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200819 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
820 if (bts->si_mode_static & (1 << i)) {
821 vty_out(vty, " system-information %s mode static%s",
822 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
823 vty_out(vty, " system-information %s static %s%s",
824 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200825 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200826 VTY_NEWLINE);
827 }
828 }
Harald Welte42def722017-01-13 00:10:32 +0100829 vty_out(vty, " early-classmark-sending %s%s",
830 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100831 vty_out(vty, " early-classmark-sending-3g %s%s",
832 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100833 switch (bts->type) {
834 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100835 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200836 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200837 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100838 if (bts->ip_access.rsl_ip) {
839 struct in_addr ia;
840 ia.s_addr = htonl(bts->ip_access.rsl_ip);
841 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
842 VTY_NEWLINE);
843 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200844 vty_out(vty, " oml ip.access stream_id %u line %u%s",
845 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100846 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200847 case GSM_BTS_TYPE_NOKIA_SITE:
848 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100849 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
850 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100851 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 +0100852 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100853 default:
Harald Welte42581822009-08-08 16:12:58 +0200854 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
855 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100856 break;
Harald Welte42581822009-08-08 16:12:58 +0200857 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800858
859 /* if we have a limit, write it */
860 if (bts->paging.free_chans_need >= 0)
861 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
862
Harald Welte32c09622011-01-11 23:44:56 +0100863 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100864 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
865 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100866 for (i = 0; i < 1024; i++) {
867 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
868 vty_out(vty, " neighbor-list add arfcn %u%s",
869 i, VTY_NEWLINE);
870 }
871 }
Harald Welte64c07d22011-02-15 11:43:27 +0100872 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
873 for (i = 0; i < 1024; i++) {
874 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
875 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
876 i, VTY_NEWLINE);
877 }
878 }
Harald Welte32c09622011-01-11 23:44:56 +0100879
Max59a1bf32016-04-15 16:04:46 +0200880 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100881 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
882 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
883 vty_out(vty, " si2quater neighbor-list add earfcn %u "
884 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
885
886 vty_out(vty, " thresh-lo %u",
887 e->thresh_lo_valid ? e->thresh_lo : 32);
888
889 vty_out(vty, " prio %u",
890 e->prio_valid ? e->prio : 8);
891
892 vty_out(vty, " qrxlv %u",
893 e->qrxlm_valid ? e->qrxlm : 32);
894
895 tmp = e->meas_bw[i];
896 vty_out(vty, " meas %u",
897 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200898
899 vty_out(vty, "%s", VTY_NEWLINE);
900 }
901 }
902
Max26679e02016-04-20 15:57:13 +0200903 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
904 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
905 bts->si_common.data.uarfcn_list[i],
906 bts->si_common.data.scramble_list[i] & ~(1 << 9),
907 (bts->si_common.data.scramble_list[i] >> 9) & 1,
908 VTY_NEWLINE);
909 }
910
Andreas Eversberga83d5112013-12-07 18:32:28 +0100911 vty_out(vty, " codec-support fr");
912 if (bts->codec.hr)
913 vty_out(vty, " hr");
914 if (bts->codec.efr)
915 vty_out(vty, " efr");
916 if (bts->codec.amr)
917 vty_out(vty, " amr");
918 vty_out(vty, "%s", VTY_NEWLINE);
919
Andreas Eversberg73266522014-01-19 11:47:44 +0100920 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
921 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
922
Harald Welte615e9562010-05-11 23:50:21 +0200923 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200924
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200925 if (bts->excl_from_rf_lock)
926 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
927
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100928 vty_out(vty, " %sforce-combined-si%s",
929 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
930
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100931 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
932 int j;
933
934 if (bts->depends_on[i] == 0)
935 continue;
936
937 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
938 int bts_nr;
939
940 if ((bts->depends_on[i] & (1<<j)) == 0)
941 continue;
942
943 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
944 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
945 }
946 }
Harald Welte8254cf72017-05-29 13:42:19 +0200947 if (bts->pcu_sock_path)
948 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100949
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100950 ho_vty_write_bts(vty, bts);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100951
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200952 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200953}
954
955static int config_write_bts(struct vty *v)
956{
Harald Weltedcccb182010-05-16 20:52:23 +0200957 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200958 struct gsm_bts *bts;
959
960 llist_for_each_entry(bts, &gsmnet->bts_list, list)
961 config_write_bts_single(v, bts);
962
963 return CMD_SUCCESS;
964}
965
Harald Weltea0d324b2017-07-20 01:47:39 +0200966/* small helper macro for conditional dumping of timer */
967#define VTY_OUT_TIMER(number) \
968 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
969 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
970
Harald Welte5013b2a2009-08-07 13:29:14 +0200971static int config_write_net(struct vty *vty)
972{
Harald Weltedcccb182010-05-16 20:52:23 +0200973 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte51e4bf32017-12-23 17:30:18 +0100974 int i;
Harald Weltedcccb182010-05-16 20:52:23 +0200975
Harald Welte5013b2a2009-08-07 13:29:14 +0200976 vty_out(vty, "network%s", VTY_NEWLINE);
Neels Hofmeyrf93970b2018-03-05 02:09:40 +0100977 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
978 vty_out(vty, " mobile network code %s%s",
979 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
Harald Welte51e4bf32017-12-23 17:30:18 +0100980 vty_out(vty, " encryption a5");
981 for (i = 0; i < 8; i++) {
982 if (gsmnet->a5_encryption_mask & (1 << i))
983 vty_out(vty, " %u", i);
984 }
985 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100986 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800987 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100988
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100989 ho_vty_write_net(vty, gsmnet);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100990
Harald Weltea0d324b2017-07-20 01:47:39 +0200991 VTY_OUT_TIMER(3101);
992 VTY_OUT_TIMER(3103);
993 VTY_OUT_TIMER(3105);
994 VTY_OUT_TIMER(3107);
995 VTY_OUT_TIMER(3109);
996 VTY_OUT_TIMER(3111);
997 VTY_OUT_TIMER(3113);
998 VTY_OUT_TIMER(3115);
999 VTY_OUT_TIMER(3117);
1000 VTY_OUT_TIMER(3119);
1001 VTY_OUT_TIMER(3122);
1002 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +07001003 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
1004 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +02001005 if (gsmnet->tz.override != 0) {
1006 if (gsmnet->tz.dst)
1007 vty_out(vty, " timezone %d %d %d%s",
1008 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
1009 VTY_NEWLINE);
1010 else
1011 vty_out(vty, " timezone %d %d%s",
1012 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
1013 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +02001014 if (gsmnet->t3212 == 0)
1015 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
1016 else
1017 vty_out(vty, " periodic location update %u%s",
1018 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +02001019
1020 return CMD_SUCCESS;
1021}
Harald Welte67ce0732009-08-06 19:06:46 +02001022
Harald Welte68628e82009-03-10 12:17:57 +00001023static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
1024{
1025 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
1026 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +02001027 vty_out(vty, "Description: %s%s",
1028 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +02001029 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +02001030 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +02001031 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +02001032 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001033 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001034 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +01001035 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001036 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001037 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +02001038 if (is_ipaccess_bts(trx->bts)) {
1039 vty_out(vty, " ip.access stream ID: 0x%02x%s",
1040 trx->rsl_tei, VTY_NEWLINE);
1041 } else {
1042 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
1043 e1isl_dump_vty(vty, trx->rsl_link);
1044 }
Harald Welte68628e82009-03-10 12:17:57 +00001045}
1046
Max6e4f1842018-01-07 16:45:42 +01001047static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
1048{
1049 uint8_t trx_nr;
1050 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
1051 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
1052}
1053
Harald Welte68628e82009-03-10 12:17:57 +00001054DEFUN(show_trx,
1055 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001056 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001057 SHOW_STR "Display information about a TRX\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001058 BTS_TRX_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001059{
Harald Weltedcccb182010-05-16 20:52:23 +02001060 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001061 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001062 int bts_nr, trx_nr;
1063
1064 if (argc >= 1) {
1065 /* use the BTS number that the user has specified */
1066 bts_nr = atoi(argv[0]);
1067 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001068 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001069 VTY_NEWLINE);
1070 return CMD_WARNING;
1071 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001072 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001073 }
1074 if (argc >= 2) {
1075 trx_nr = atoi(argv[1]);
1076 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001077 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001078 VTY_NEWLINE);
1079 return CMD_WARNING;
1080 }
Max6e4f1842018-01-07 16:45:42 +01001081 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001082 return CMD_SUCCESS;
1083 }
1084 if (bts) {
1085 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +01001086 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +00001087 return CMD_SUCCESS;
1088 }
1089
Max6e4f1842018-01-07 16:45:42 +01001090 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
1091 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001092
1093 return CMD_SUCCESS;
1094}
1095
Harald Welte67ce0732009-08-06 19:06:46 +02001096
Harald Welte68628e82009-03-10 12:17:57 +00001097static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
1098{
Harald Welte135a6482011-05-30 12:09:13 +02001099 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +01001100 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +01001101 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +01001102 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +01001103 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001104 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +01001105 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001106 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001107 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +05301108 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +00001109 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
1110 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
1111 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001112}
1113
1114DEFUN(show_ts,
1115 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001116 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001117 SHOW_STR "Display information about a TS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001118 BTS_TRX_TS_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001119{
Harald Weltedcccb182010-05-16 20:52:23 +02001120 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +01001121 struct gsm_bts *bts = NULL;
1122 struct gsm_bts_trx *trx = NULL;
1123 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001124 int bts_nr, trx_nr, ts_nr;
1125
1126 if (argc >= 1) {
1127 /* use the BTS number that the user has specified */
1128 bts_nr = atoi(argv[0]);
1129 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001130 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001131 VTY_NEWLINE);
1132 return CMD_WARNING;
1133 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001134 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001135 }
1136 if (argc >= 2) {
1137 trx_nr = atoi(argv[1]);
1138 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001139 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001140 VTY_NEWLINE);
1141 return CMD_WARNING;
1142 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001143 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001144 }
1145 if (argc >= 3) {
1146 ts_nr = atoi(argv[2]);
1147 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +00001148 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +00001149 VTY_NEWLINE);
1150 return CMD_WARNING;
1151 }
Harald Welte274d0152010-12-24 12:05:03 +01001152 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +00001153 ts = &trx->ts[ts_nr];
1154 ts_dump_vty(vty, ts);
1155 return CMD_SUCCESS;
1156 }
Harald Welte274d0152010-12-24 12:05:03 +01001157
1158 if (bts && trx) {
1159 /* Iterate over all TS in this TRX */
1160 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1161 ts = &trx->ts[ts_nr];
1162 ts_dump_vty(vty, ts);
1163 }
1164 } else if (bts) {
1165 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001166 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001167 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001168 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1169 ts = &trx->ts[ts_nr];
1170 ts_dump_vty(vty, ts);
1171 }
1172 }
Harald Welte274d0152010-12-24 12:05:03 +01001173 } else {
1174 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1175 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1176 bts = gsm_bts_num(net, bts_nr);
1177 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1178 trx = gsm_bts_trx_num(bts, trx_nr);
1179 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1180 ts = &trx->ts[ts_nr];
1181 ts_dump_vty(vty, ts);
1182 }
1183 }
1184 }
Harald Welte68628e82009-03-10 12:17:57 +00001185 }
1186
1187 return CMD_SUCCESS;
1188}
1189
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001190static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1191{
1192 if (strlen(bsub->imsi))
1193 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1194 if (bsub->tmsi != GSM_RESERVED_TMSI)
1195 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1196 VTY_NEWLINE);
1197 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1198}
1199
Harald Welte8387a492009-12-22 21:43:14 +01001200static void meas_rep_dump_uni_vty(struct vty *vty,
1201 struct gsm_meas_rep_unidir *mru,
1202 const char *prefix,
1203 const char *dir)
1204{
1205 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1206 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1207 dir, rxlev2dbm(mru->sub.rx_lev));
1208 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1209 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1210 VTY_NEWLINE);
1211}
1212
1213static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1214 const char *prefix)
1215{
1216 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1217 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1218 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1219 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1220 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1221 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1222 VTY_NEWLINE);
1223 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001224 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001225 if (mr->flags & MEAS_REP_F_MS_L1)
1226 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1227 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1228 if (mr->flags & MEAS_REP_F_DL_VALID)
1229 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1230 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1231}
1232
Harald Welte0a8cf322015-12-05 17:22:49 +01001233/* FIXME: move this to libosmogsm */
1234static const struct value_string gsm48_cmode_names[] = {
1235 { GSM48_CMODE_SIGN, "signalling" },
1236 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1237 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1238 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1239 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1240 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1241 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1242 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1243 { 0, NULL }
1244};
1245
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001246/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1247 * Don't do anything if the ts is not dynamic. */
1248static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1249{
1250 switch (ts->pchan) {
1251 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1252 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1253 vty_out(vty, " as %s",
1254 gsm_pchan_name(ts->dyn.pchan_is));
1255 else
1256 vty_out(vty, " switching %s -> %s",
1257 gsm_pchan_name(ts->dyn.pchan_is),
1258 gsm_pchan_name(ts->dyn.pchan_want));
1259 break;
1260 case GSM_PCHAN_TCH_F_PDCH:
1261 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1262 vty_out(vty, " as %s",
1263 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1264 : "TCH/F");
1265 else
1266 vty_out(vty, " switching %s -> %s",
1267 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1268 : "TCH/F",
1269 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1270 : "TCH/F");
1271 break;
1272 default:
1273 /* no dyn ts */
1274 break;
1275 }
1276}
1277
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001278static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001279{
Harald Welte8387a492009-12-22 21:43:14 +01001280 int idx;
1281
Harald Welte85bded82010-12-24 12:22:34 +01001282 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1283 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1284 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001285 /* show dyn TS details, if applicable */
1286 switch (lchan->ts->pchan) {
1287 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1288 vty_out(vty, " Osmocom Dyn TS:");
1289 vty_out_dyn_ts_status(vty, lchan->ts);
1290 vty_out(vty, VTY_NEWLINE);
1291 break;
1292 case GSM_PCHAN_TCH_F_PDCH:
1293 vty_out(vty, " IPACC Dyn PDCH TS:");
1294 vty_out_dyn_ts_status(vty, lchan->ts);
1295 vty_out(vty, VTY_NEWLINE);
1296 break;
1297 default:
1298 /* no dyn ts */
1299 break;
1300 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001301 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001302 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001303 gsm_lchans_name(lchan->state),
1304 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1305 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1306 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001307 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1308 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1309 - lchan->bs_power*2,
1310 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1311 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001312 vty_out(vty, " Channel Mode / Codec: %s%s",
1313 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1314 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001315 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001316 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001317 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001318 } else
1319 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301320 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1321 struct in_addr ia;
Harald Welte5f45a4a2018-02-05 21:33:34 +01001322 if (lchan->abis_ip.bound_ip) {
1323 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
1324 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1325 inet_ntoa(ia), lchan->abis_ip.bound_port,
1326 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1327 VTY_NEWLINE);
1328 }
1329 if (lchan->abis_ip.connect_ip) {
1330 ia.s_addr = htonl(lchan->abis_ip.connect_ip);
1331 vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02x%s",
1332 inet_ntoa(ia), lchan->abis_ip.connect_port,
1333 lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode,
1334 VTY_NEWLINE);
1335 }
1336
Harald Welte2c828992009-12-02 01:56:49 +05301337 }
Harald Welte8387a492009-12-22 21:43:14 +01001338
1339 /* we want to report the last measurement report */
1340 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1341 lchan->meas_rep_idx, 1);
1342 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001343}
1344
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001345static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1346{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001347 struct gsm_meas_rep *mr;
1348 int idx;
1349
1350 /* we want to report the last measurement report */
1351 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1352 lchan->meas_rep_idx, 1);
1353 mr = &lchan->meas_rep[idx];
1354
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001355 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001356 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001357 gsm_pchan_name(lchan->ts->pchan));
1358 vty_out_dyn_ts_status(vty, lchan->ts);
1359 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1360 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001361 lchan->nr,
1362 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1363 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001364 rxlev2dbm(mr->dl.full.rx_lev),
1365 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001366 VTY_NEWLINE);
1367}
1368
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001369
1370static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1371 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1372{
1373 int lchan_nr;
1374 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1375 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1376 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1377 continue;
1378 dump_cb(vty, lchan);
1379 }
1380
1381 return CMD_SUCCESS;
1382}
1383
1384static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1385 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1386{
1387 int ts_nr;
1388
1389 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1390 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1391 dump_lchan_trx_ts(ts, vty, dump_cb);
1392 }
1393
1394 return CMD_SUCCESS;
1395}
1396
1397static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1398 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1399{
1400 int trx_nr;
1401
1402 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1403 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1404 dump_lchan_trx(trx, vty, dump_cb);
1405 }
1406
1407 return CMD_SUCCESS;
1408}
1409
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001410static int lchan_summary(struct vty *vty, int argc, const char **argv,
1411 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001412{
Harald Weltedcccb182010-05-16 20:52:23 +02001413 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001414 struct gsm_bts *bts;
1415 struct gsm_bts_trx *trx;
1416 struct gsm_bts_trx_ts *ts;
1417 struct gsm_lchan *lchan;
1418 int bts_nr, trx_nr, ts_nr, lchan_nr;
1419
1420 if (argc >= 1) {
1421 /* use the BTS number that the user has specified */
1422 bts_nr = atoi(argv[0]);
1423 if (bts_nr >= net->num_bts) {
1424 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1425 VTY_NEWLINE);
1426 return CMD_WARNING;
1427 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001428 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001429
1430 if (argc == 1)
1431 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001432 }
1433 if (argc >= 2) {
1434 trx_nr = atoi(argv[1]);
1435 if (trx_nr >= bts->num_trx) {
1436 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1437 VTY_NEWLINE);
1438 return CMD_WARNING;
1439 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001440 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001441
1442 if (argc == 2)
1443 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001444 }
1445 if (argc >= 3) {
1446 ts_nr = atoi(argv[2]);
1447 if (ts_nr >= TRX_NR_TS) {
1448 vty_out(vty, "%% can't find TS %s%s", argv[2],
1449 VTY_NEWLINE);
1450 return CMD_WARNING;
1451 }
1452 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001453
1454 if (argc == 3)
1455 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001456 }
1457 if (argc >= 4) {
1458 lchan_nr = atoi(argv[3]);
1459 if (lchan_nr >= TS_MAX_LCHAN) {
1460 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1461 VTY_NEWLINE);
1462 return CMD_WARNING;
1463 }
1464 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001465 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001466 return CMD_SUCCESS;
1467 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001468
1469
Harald Welte68628e82009-03-10 12:17:57 +00001470 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001471 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001472 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001473 }
1474
1475 return CMD_SUCCESS;
1476}
1477
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001478
1479DEFUN(show_lchan,
1480 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001481 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001482 SHOW_STR "Display information about a logical channel\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001483 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001484{
1485 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1486}
1487
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001488DEFUN(show_lchan_summary,
1489 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001490 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001491 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001492 "Short summary\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001493 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001494{
1495 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1496}
1497
Philipp Maier39f62bb2017-04-09 12:32:51 +02001498DEFUN(show_subscr_conn,
1499 show_subscr_conn_cmd,
1500 "show conns",
1501 SHOW_STR "Display currently active subscriber connections\n")
1502{
1503 struct gsm_subscriber_connection *conn;
1504 struct gsm_network *net = gsmnet_from_vty(vty);
1505 bool no_conns = true;
1506 unsigned int count = 0;
1507
1508 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1509
1510 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1511 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1512 lchan_dump_full_vty(vty, conn->lchan);
1513 no_conns = false;
1514 count++;
1515 }
1516
1517 if (no_conns)
1518 vty_out(vty, "None%s", VTY_NEWLINE);
1519
1520 return CMD_SUCCESS;
1521}
1522
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001523static int trigger_ho_or_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_bts *to_bts)
1524{
1525 int rc;
1526
1527 if (!to_bts || from_lchan->ts->trx->bts == to_bts) {
1528 LOGP(DHO, LOGL_NOTICE, "%s Manually triggering Assignment from VTY\n",
1529 gsm_lchan_name(from_lchan));
1530 to_bts = from_lchan->ts->trx->bts;
1531 } else
1532 LOGP(DHO, LOGL_NOTICE, "%s (ARFCN %u) --> BTS %u Manually triggering Handover from VTY\n",
1533 gsm_lchan_name(from_lchan), from_lchan->ts->trx->arfcn, to_bts->nr);
Neels Hofmeyr45e46d22018-02-15 14:10:12 +01001534 rc = bsc_handover_start(HODEC_NONE, from_lchan, to_bts, from_lchan->type);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001535 if (rc) {
1536 vty_out(vty, "bsc_handover_start() returned %d=%s%s", rc,
1537 strerror(-rc), VTY_NEWLINE);
1538 return CMD_WARNING;
1539 }
1540 return CMD_SUCCESS;
1541}
1542
1543static int ho_or_as(struct vty *vty, const char *argv[], int argc)
Philipp Maier39f62bb2017-04-09 12:32:51 +02001544{
1545 struct gsm_network *net = gsmnet_from_vty(vty);
1546 struct gsm_subscriber_connection *conn;
1547 struct gsm_bts *bts;
1548 struct gsm_bts *new_bts = NULL;
1549 unsigned int bts_nr = atoi(argv[0]);
1550 unsigned int trx_nr = atoi(argv[1]);
1551 unsigned int ts_nr = atoi(argv[2]);
1552 unsigned int ss_nr = atoi(argv[3]);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001553 unsigned int bts_nr_new;
1554 const char *action;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001555
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001556 if (argc > 4) {
1557 bts_nr_new = atoi(argv[4]);
1558
1559 /* Lookup the BTS where we want to handover to */
1560 llist_for_each_entry(bts, &net->bts_list, list) {
1561 if (bts->nr == bts_nr_new) {
1562 new_bts = bts;
1563 break;
1564 }
1565 }
1566
1567 if (!new_bts) {
1568 vty_out(vty, "Unable to trigger handover, specified bts #%u does not exist %s",
1569 bts_nr_new, VTY_NEWLINE);
1570 return CMD_WARNING;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001571 }
1572 }
1573
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001574 action = new_bts ? "handover" : "assignment";
Philipp Maier39f62bb2017-04-09 12:32:51 +02001575
1576 /* Find the connection/lchan that we want to handover */
1577 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001578 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001579 conn->lchan->ts->trx->nr == trx_nr &&
1580 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001581 vty_out(vty, "starting %s for lchan %s...%s", action, conn->lchan->name, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001582 lchan_dump_full_vty(vty, conn->lchan);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001583 return trigger_ho_or_as(vty, conn->lchan, new_bts);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001584 }
1585 }
1586
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001587 vty_out(vty, "Unable to trigger %s, specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1588 action, bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001589
1590 return CMD_WARNING;
1591}
1592
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001593#define MANUAL_HANDOVER_STR "Manually trigger handover (for debugging)\n"
1594#define MANUAL_ASSIGNMENT_STR "Manually trigger assignment (for debugging)\n"
1595
1596DEFUN(handover_subscr_conn,
1597 handover_subscr_conn_cmd,
Harald Welteb22dcb82018-02-12 17:57:57 +01001598 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> handover <0-255>",
Harald Welte0bfd8d92018-02-12 18:06:53 +01001599 BTS_NR_TRX_TS_SS_STR2
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001600 MANUAL_HANDOVER_STR
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001601 "New " BTS_NR_STR)
1602{
1603 return ho_or_as(vty, argv, argc);
1604}
1605
1606DEFUN(assignment_subscr_conn,
1607 assignment_subscr_conn_cmd,
Harald Welteb22dcb82018-02-12 17:57:57 +01001608 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> assignment",
Harald Welte0bfd8d92018-02-12 18:06:53 +01001609 BTS_NR_TRX_TS_SS_STR2
Harald Welteb22dcb82018-02-12 17:57:57 +01001610 MANUAL_ASSIGNMENT_STR)
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001611{
1612 return ho_or_as(vty, argv, argc);
1613}
1614
1615static struct gsm_lchan *find_used_voice_lchan(struct vty *vty)
1616{
1617 struct gsm_bts *bts;
1618 struct gsm_network *network = gsmnet_from_vty(vty);
1619
1620 llist_for_each_entry(bts, &network->bts_list, list) {
1621 struct gsm_bts_trx *trx;
1622
1623 llist_for_each_entry(trx, &bts->trx_list, list) {
1624 int i;
1625 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1626 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1627 int j;
1628 int subslots;
1629
1630 /* skip administratively deactivated timeslots */
1631 if (!nm_is_running(&ts->mo.nm_state))
1632 continue;
1633
1634 subslots = ts_subslots(ts);
1635 for (j = 0; j < subslots; j++) {
1636 struct gsm_lchan *lchan = &ts->lchan[j];
1637
1638 if (lchan->state == LCHAN_S_ACTIVE
1639 && (lchan->type == GSM_LCHAN_TCH_F
1640 || lchan->type == GSM_LCHAN_TCH_H)) {
1641
1642 vty_out(vty, "Found voice call: %s%s",
1643 gsm_lchan_name(lchan), VTY_NEWLINE);
1644 lchan_dump_full_vty(vty, lchan);
1645 return lchan;
1646 }
1647 }
1648 }
1649 }
1650 }
1651
1652 vty_out(vty, "Cannot find any ongoing voice calls%s", VTY_NEWLINE);
1653 return NULL;
1654}
1655
1656static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gsm_bts *not_this_bts,
1657 enum gsm_phys_chan_config free_type)
1658{
1659 struct gsm_bts *bts;
1660 struct gsm_network *network = gsmnet_from_vty(vty);
1661
1662 llist_for_each_entry(bts, &network->bts_list, list) {
1663 struct gsm_bts_trx *trx;
1664
1665 if (bts == not_this_bts)
1666 continue;
1667
1668 llist_for_each_entry(trx, &bts->trx_list, list) {
1669 int i;
1670 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1671 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1672 int j;
1673 int subslots;
1674
1675 /* skip administratively deactivated timeslots */
1676 if (!nm_is_running(&ts->mo.nm_state))
1677 continue;
1678
1679 if (ts->pchan != free_type)
1680 continue;
1681
1682 subslots = ts_subslots(ts);
1683 for (j = 0; j < subslots; j++) {
1684 struct gsm_lchan *lchan = &ts->lchan[j];
1685
1686 if (lchan->state == LCHAN_S_NONE) {
1687 vty_out(vty, "Found unused %s slot: %s%s",
1688 gsm_pchan_name(free_type),
1689 gsm_lchan_name(lchan),
1690 VTY_NEWLINE);
1691 lchan_dump_full_vty(vty, lchan);
1692 return bts;
1693 }
1694 }
1695 }
1696 }
1697 }
1698 vty_out(vty, "Cannot find any BTS (other than BTS %u) with free %s lchan%s",
1699 not_this_bts? not_this_bts->nr : 255, gsm_lchant_name(free_type), VTY_NEWLINE);
1700 return NULL;
1701}
1702
1703DEFUN(handover_any, handover_any_cmd,
1704 "handover any",
1705 MANUAL_HANDOVER_STR
1706 "Pick any actively used TCH/F or TCH/H lchan and handover to any other BTS."
1707 " This is likely to fail if not all BTS are guaranteed to be reachable by the MS.\n")
1708{
1709 struct gsm_lchan *from_lchan;
1710 struct gsm_bts *to_bts;
1711
1712 from_lchan = find_used_voice_lchan(vty);
1713 if (!from_lchan)
1714 return CMD_WARNING;
1715
1716 to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts,
1717 ts_pchan(from_lchan->ts));
1718 if (!to_bts)
1719 return CMD_WARNING;
1720
1721 return trigger_ho_or_as(vty, from_lchan, to_bts);
1722}
1723
1724DEFUN(assignment_any, assignment_any_cmd,
1725 "assignment any",
1726 MANUAL_ASSIGNMENT_STR
1727 "Pick any actively used TCH/F or TCH/H lchan and re-assign within the same BTS."
1728 " This will fail if no lchans of the same type are available besides the used one.\n")
1729{
1730 struct gsm_lchan *from_lchan;
1731
1732 from_lchan = find_used_voice_lchan(vty);
1733 if (!from_lchan)
1734 return CMD_WARNING;
1735
1736 return trigger_ho_or_as(vty, from_lchan, NULL);
1737}
1738
Harald Weltebe4b7302009-05-23 16:59:33 +00001739static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001740{
1741 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001742 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001743}
1744
Harald Weltebe4b7302009-05-23 16:59:33 +00001745static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001746{
1747 struct gsm_paging_request *pag;
1748
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001749 if (!bts->paging.bts)
1750 return;
1751
Harald Weltef5025b62009-03-28 16:55:11 +00001752 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1753 paging_dump_vty(vty, pag);
1754}
1755
1756DEFUN(show_paging,
1757 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001758 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001759 SHOW_STR "Display information about paging reuqests of a BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001760 BTS_NR_STR)
Harald Weltef5025b62009-03-28 16:55:11 +00001761{
Harald Weltedcccb182010-05-16 20:52:23 +02001762 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001763 struct gsm_bts *bts;
1764 int bts_nr;
1765
1766 if (argc >= 1) {
1767 /* use the BTS number that the user has specified */
1768 bts_nr = atoi(argv[0]);
1769 if (bts_nr >= net->num_bts) {
1770 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1771 VTY_NEWLINE);
1772 return CMD_WARNING;
1773 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001774 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001775 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001776
Harald Weltef5025b62009-03-28 16:55:11 +00001777 return CMD_SUCCESS;
1778 }
1779 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001780 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001781 bts_paging_dump_vty(vty, bts);
1782 }
1783
1784 return CMD_SUCCESS;
1785}
1786
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001787DEFUN(show_paging_group,
1788 show_paging_group_cmd,
1789 "show paging-group <0-255> IMSI",
1790 SHOW_STR "Display the paging group\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001791 BTS_NR_STR "IMSI\n")
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001792{
1793 struct gsm_network *net = gsmnet_from_vty(vty);
1794 struct gsm_bts *bts;
1795 unsigned int page_group;
1796 int bts_nr = atoi(argv[0]);
1797
1798 if (bts_nr >= net->num_bts) {
1799 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1800 return CMD_WARNING;
1801 }
1802
1803 bts = gsm_bts_num(net, bts_nr);
1804 if (!bts) {
1805 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1806 return CMD_WARNING;
1807 }
1808
1809 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1810 str_to_imsi(argv[1]));
1811 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1812 str_to_imsi(argv[1]), bts->nr,
1813 page_group, VTY_NEWLINE);
1814 return CMD_SUCCESS;
1815}
1816
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001817DEFUN(cfg_net_neci,
1818 cfg_net_neci_cmd,
1819 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001820 "New Establish Cause Indication\n"
1821 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001822{
Harald Weltedcccb182010-05-16 20:52:23 +02001823 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1824
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001825 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001826 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001827 return CMD_SUCCESS;
1828}
1829
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001830DEFUN(cfg_net_pag_any_tch,
1831 cfg_net_pag_any_tch_cmd,
1832 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001833 "Assign a TCH when receiving a Paging Any request\n"
1834 "Any Channel\n" "Use\n" "TCH\n"
1835 "Do not use TCH for Paging Request Any\n"
1836 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001837{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001838 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001839 gsmnet->pag_any_tch = atoi(argv[0]);
1840 gsm_net_update_ctype(gsmnet);
1841 return CMD_SUCCESS;
1842}
1843
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001844#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1845/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1846#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1847
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001848#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001849 DEFUN(cfg_net_T##number, \
1850 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001851 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001852 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001853 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001854 "Set to default timer value" \
1855 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1856 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001857{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001858 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001859 int value; \
1860 if (strcmp(argv[0], "default") == 0) \
1861 value = DEFAULT_TIMER(number); \
1862 else \
1863 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001864 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001865 gsmnet->T##number = value; \
1866 return CMD_SUCCESS; \
1867}
1868
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001869DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1870DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1871DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1872DECLARE_TIMER(3107, "Currently not used")
1873DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1874DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1875DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1876DECLARE_TIMER(3115, "Currently not used")
1877DECLARE_TIMER(3117, "Currently not used")
1878DECLARE_TIMER(3119, "Currently not used")
Stefan Sperling6cee8932018-01-30 18:14:22 +01001879DECLARE_TIMER(3122, "Default waiting time (seconds) after IMM ASS REJECT")
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001880DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001881
Maxc08ee712016-05-11 12:45:13 +02001882DEFUN_DEPRECATED(cfg_net_dtx,
1883 cfg_net_dtx_cmd,
1884 "dtx-used (0|1)",
1885 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001886{
Maxc08ee712016-05-11 12:45:13 +02001887 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1888 "configuration options of BTS instead%s", VTY_NEWLINE);
1889 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001890}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001891
Harald Welte5258fc42009-03-28 19:07:53 +00001892/* per-BTS configuration */
1893DEFUN(cfg_bts,
1894 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001895 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001896 "Select a BTS to configure\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001897 BTS_NR_STR)
Harald Welte5258fc42009-03-28 19:07:53 +00001898{
Harald Weltedcccb182010-05-16 20:52:23 +02001899 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001900 int bts_nr = atoi(argv[0]);
1901 struct gsm_bts *bts;
1902
Harald Weltee441d9c2009-06-21 16:17:15 +02001903 if (bts_nr > gsmnet->num_bts) {
1904 vty_out(vty, "%% The next unused BTS number is %u%s",
1905 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001906 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001907 } else if (bts_nr == gsmnet->num_bts) {
1908 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001909 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001910 HARDCODED_BSIC);
Stefan Sperling6442e432018-02-06 14:44:54 +01001911 /*
1912 * Initalize bts->acc_ramp here. Else we could segfault while
1913 * processing a configuration file with ACC ramping settings.
1914 */
1915 acc_ramp_init(&bts->acc_ramp, false, bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001916 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001917 bts = gsm_bts_num(gsmnet, bts_nr);
1918
Daniel Willmannf15c2762010-01-11 13:43:07 +01001919 if (!bts) {
1920 vty_out(vty, "%% Unable to allocate BTS %u%s",
1921 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001922 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001923 }
Harald Welte5258fc42009-03-28 19:07:53 +00001924
1925 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001926 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001927 vty->node = BTS_NODE;
1928
1929 return CMD_SUCCESS;
1930}
1931
1932DEFUN(cfg_bts_type,
1933 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001934 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001935 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001936{
1937 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001938 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001939
Max7507aef2017-04-10 13:59:14 +02001940 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001941 if (rc < 0)
1942 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001943
Harald Welte5258fc42009-03-28 19:07:53 +00001944 return CMD_SUCCESS;
1945}
1946
Harald Weltefcd24452009-06-20 18:15:19 +02001947DEFUN(cfg_bts_band,
1948 cfg_bts_band_cmd,
1949 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001950 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001951{
1952 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001953 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001954
1955 if (band < 0) {
1956 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1957 band, VTY_NEWLINE);
1958 return CMD_WARNING;
1959 }
1960
1961 bts->band = band;
1962
1963 return CMD_SUCCESS;
1964}
1965
Maxc08ee712016-05-11 12:45:13 +02001966DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1967 "Configure discontinuous transmission\n"
1968 "Enable Uplink DTX for this BTS\n"
1969 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1970 "older phones).\n")
1971{
1972 struct gsm_bts *bts = vty->index;
1973
1974 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001975 if (!is_ipaccess_bts(bts))
1976 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1977 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001978 return CMD_SUCCESS;
1979}
1980
1981DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1982 NO_STR
1983 "Configure discontinuous transmission\n"
1984 "Disable Uplink DTX for this BTS\n")
1985{
1986 struct gsm_bts *bts = vty->index;
1987
1988 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1989
1990 return CMD_SUCCESS;
1991}
1992
1993DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1994 "Configure discontinuous transmission\n"
1995 "Enable Downlink DTX for this BTS\n")
1996{
1997 struct gsm_bts *bts = vty->index;
1998
1999 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02002000 if (!is_ipaccess_bts(bts))
2001 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
2002 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02002003 return CMD_SUCCESS;
2004}
2005
2006DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
2007 NO_STR
2008 "Configure discontinuous transmission\n"
2009 "Disable Downlink DTX for this BTS\n")
2010{
2011 struct gsm_bts *bts = vty->index;
2012
2013 bts->dtxd = false;
2014
2015 return CMD_SUCCESS;
2016}
2017
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02002018DEFUN(cfg_bts_ci,
2019 cfg_bts_ci_cmd,
2020 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002021 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02002022{
2023 struct gsm_bts *bts = vty->index;
2024 int ci = atoi(argv[0]);
2025
2026 if (ci < 0 || ci > 0xffff) {
2027 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
2028 ci, VTY_NEWLINE);
2029 return CMD_WARNING;
2030 }
2031 bts->cell_identity = ci;
2032
2033 return CMD_SUCCESS;
2034}
2035
Harald Welte5258fc42009-03-28 19:07:53 +00002036DEFUN(cfg_bts_lac,
2037 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02002038 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002039 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00002040{
2041 struct gsm_bts *bts = vty->index;
2042 int lac = atoi(argv[0]);
2043
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02002044 if (lac < 0 || lac > 0xffff) {
2045 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00002046 lac, VTY_NEWLINE);
2047 return CMD_WARNING;
2048 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02002049
2050 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
2051 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
2052 lac, VTY_NEWLINE);
2053 return CMD_WARNING;
2054 }
2055
Harald Welte5258fc42009-03-28 19:07:53 +00002056 bts->location_area_code = lac;
2057
2058 return CMD_SUCCESS;
2059}
2060
Harald Weltea43f7892009-12-01 18:04:30 +05302061
Harald Weltea2bbc5e2015-11-20 10:43:31 +01002062/* compatibility wrapper for old config files */
2063DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00002064 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02002065 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002066 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00002067{
Harald Welte5258fc42009-03-28 19:07:53 +00002068 return CMD_SUCCESS;
2069}
2070
Harald Welte78f2f502009-05-23 16:56:52 +00002071DEFUN(cfg_bts_bsic,
2072 cfg_bts_bsic_cmd,
2073 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002074 "Set the Base Station Identity Code (BSIC) of this BTS\n"
2075 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00002076{
2077 struct gsm_bts *bts = vty->index;
2078 int bsic = atoi(argv[0]);
2079
2080 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02002081 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00002082 bsic, VTY_NEWLINE);
2083 return CMD_WARNING;
2084 }
2085 bts->bsic = bsic;
2086
2087 return CMD_SUCCESS;
2088}
2089
Harald Welte4cc34222009-05-01 15:12:31 +00002090DEFUN(cfg_bts_unit_id,
2091 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02002092 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002093 "Abis/IP specific options\n"
2094 "Set the IPA BTS Unit ID\n"
2095 "Unit ID (Site)\n"
2096 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00002097{
2098 struct gsm_bts *bts = vty->index;
2099 int site_id = atoi(argv[0]);
2100 int bts_id = atoi(argv[1]);
2101
Harald Welte07dc73d2009-08-07 13:27:09 +02002102 if (!is_ipaccess_bts(bts)) {
2103 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2104 return CMD_WARNING;
2105 }
2106
Harald Welte4cc34222009-05-01 15:12:31 +00002107 bts->ip_access.site_id = site_id;
2108 bts->ip_access.bts_id = bts_id;
2109
2110 return CMD_SUCCESS;
2111}
2112
Harald Welte8b291802013-03-12 13:57:05 +01002113DEFUN(cfg_bts_rsl_ip,
2114 cfg_bts_rsl_ip_cmd,
2115 "ip.access rsl-ip A.B.C.D",
2116 "Abis/IP specific options\n"
2117 "Set the IPA RSL IP Address of the BSC\n"
2118 "Destination IP address for RSL connection\n")
2119{
2120 struct gsm_bts *bts = vty->index;
2121 struct in_addr ia;
2122
2123 if (!is_ipaccess_bts(bts)) {
2124 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2125 return CMD_WARNING;
2126 }
2127
2128 inet_aton(argv[0], &ia);
2129 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
2130
2131 return CMD_SUCCESS;
2132}
2133
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002134#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01002135
Sylvain Munautc9519462011-10-17 14:04:55 +02002136DEFUN(cfg_bts_nokia_site_skip_reset,
2137 cfg_bts_nokia_site_skip_reset_cmd,
2138 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002139 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002140 "Skip the reset step during bootstrap process of this BTS\n"
2141 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02002142{
2143 struct gsm_bts *bts = vty->index;
2144
2145 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
2146 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
2147 return CMD_WARNING;
2148 }
2149
2150 bts->nokia.skip_reset = atoi(argv[0]);
2151
2152 return CMD_SUCCESS;
2153}
2154
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002155DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
2156 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
2157 "nokia_site no-local-rel-conf (0|1)",
2158 NOKIA_STR
2159 "Do not wait for RELease CONFirm message when releasing channel locally\n"
2160 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
2161{
2162 struct gsm_bts *bts = vty->index;
2163
2164 if (!is_nokia_bts(bts)) {
2165 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2166 VTY_NEWLINE);
2167 return CMD_WARNING;
2168 }
2169
2170 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
2171
2172 return CMD_SUCCESS;
2173}
2174
Sipos Csaba56e17662015-02-07 13:27:36 +01002175DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
2176 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
2177 "nokia_site bts-reset-timer <15-100>",
2178 NOKIA_STR
2179 "The amount of time (in sec.) between BTS_RESET is sent,\n"
2180 "and the BTS is being bootstrapped.\n")
2181{
2182 struct gsm_bts *bts = vty->index;
2183
2184 if (!is_nokia_bts(bts)) {
2185 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2186 VTY_NEWLINE);
2187 return CMD_WARNING;
2188 }
2189
2190 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
2191
2192 return CMD_SUCCESS;
2193}
Harald Welte8f0ed552010-05-11 21:53:49 +02002194#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002195#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02002196
Harald Welte8175e952009-10-20 00:22:00 +02002197DEFUN(cfg_bts_stream_id,
2198 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002199 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02002200 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002201 "Set the ip.access Stream ID of the OML link of this BTS\n"
2202 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02002203{
2204 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002205 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02002206
2207 if (!is_ipaccess_bts(bts)) {
2208 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2209 return CMD_WARNING;
2210 }
2211
2212 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002213 /* This is used by e1inp_bind_ops callback for each BTS model. */
2214 bts->oml_e1_link.e1_nr = linenr;
2215
2216 return CMD_SUCCESS;
2217}
2218
Harald Welted13e0cd2012-08-17 09:52:03 +02002219#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02002220
Harald Welte42581822009-08-08 16:12:58 +02002221DEFUN(cfg_bts_oml_e1,
2222 cfg_bts_oml_e1_cmd,
2223 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02002224 OML_E1_STR
2225 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002226 "E1/T1 line number to be used for OML\n"
2227 "E1/T1 timeslot to be used for OML\n"
2228 "E1/T1 timeslot to be used for OML\n"
2229 "E1/T1 sub-slot to be used for OML\n"
2230 "Use E1/T1 sub-slot 0\n"
2231 "Use E1/T1 sub-slot 1\n"
2232 "Use E1/T1 sub-slot 2\n"
2233 "Use E1/T1 sub-slot 3\n"
2234 "Use full E1 slot 3\n"
2235 )
Harald Welte42581822009-08-08 16:12:58 +02002236{
2237 struct gsm_bts *bts = vty->index;
2238
2239 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2240
2241 return CMD_SUCCESS;
2242}
2243
2244
2245DEFUN(cfg_bts_oml_e1_tei,
2246 cfg_bts_oml_e1_tei_cmd,
2247 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002248 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002249 "Set the TEI to be used for OML\n"
2250 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002251{
2252 struct gsm_bts *bts = vty->index;
2253
2254 bts->oml_tei = atoi(argv[0]);
2255
2256 return CMD_SUCCESS;
2257}
2258
Harald Welte7a8fa412009-08-10 13:48:16 +02002259DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2260 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002261 "Channnel Allocator\n" "Channel Allocator\n"
2262 "Allocate Timeslots and Transceivers in ascending order\n"
2263 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002264{
2265 struct gsm_bts *bts = vty->index;
2266
2267 if (!strcmp(argv[0], "ascending"))
2268 bts->chan_alloc_reverse = 0;
2269 else
2270 bts->chan_alloc_reverse = 1;
2271
2272 return CMD_SUCCESS;
2273}
2274
Harald Welte8f0ed552010-05-11 21:53:49 +02002275#define RACH_STR "Random Access Control Channel\n"
2276
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002277DEFUN(cfg_bts_rach_tx_integer,
2278 cfg_bts_rach_tx_integer_cmd,
2279 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002280 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002281 "Set the raw tx integer value in RACH Control parameters IE\n"
2282 "Set the raw tx integer value in RACH Control parameters IE\n"
2283 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002284{
2285 struct gsm_bts *bts = vty->index;
2286 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2287 return CMD_SUCCESS;
2288}
2289
2290DEFUN(cfg_bts_rach_max_trans,
2291 cfg_bts_rach_max_trans_cmd,
2292 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002293 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002294 "Set the maximum number of RACH burst transmissions\n"
2295 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002296 "Maximum number of 1 RACH burst transmissions\n"
2297 "Maximum number of 2 RACH burst transmissions\n"
2298 "Maximum number of 4 RACH burst transmissions\n"
2299 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002300{
2301 struct gsm_bts *bts = vty->index;
2302 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2303 return CMD_SUCCESS;
2304}
2305
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002306#define CD_STR "Channel Description\n"
2307
2308DEFUN(cfg_bts_chan_desc_att,
2309 cfg_bts_chan_desc_att_cmd,
2310 "channel-descrption attach (0|1)",
2311 CD_STR
2312 "Set if attachment is required\n"
2313 "Attachment is NOT required\n"
2314 "Attachment is required (standard)\n")
2315{
2316 struct gsm_bts *bts = vty->index;
2317 bts->si_common.chan_desc.att = atoi(argv[0]);
2318 return CMD_SUCCESS;
2319}
2320
2321DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2322 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2323 "channel-descrption bs-pa-mfrms <2-9>",
2324 CD_STR
2325 "Set number of multiframe periods for paging groups\n"
2326 "Number of multiframe periods for paging groups\n")
2327{
2328 struct gsm_bts *bts = vty->index;
2329 int bs_pa_mfrms = atoi(argv[0]);
2330
2331 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2332 return CMD_SUCCESS;
2333}
2334
2335DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2336 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2337 "channel-descrption bs-ag-blks-res <0-7>",
2338 CD_STR
2339 "Set number of blocks reserved for access grant\n"
2340 "Number of blocks reserved for access grant\n")
2341{
2342 struct gsm_bts *bts = vty->index;
2343 int bs_ag_blks_res = atoi(argv[0]);
2344
2345 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2346 return CMD_SUCCESS;
2347}
2348
Harald Welte8f0ed552010-05-11 21:53:49 +02002349#define NM_STR "Network Management\n"
2350
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002351DEFUN(cfg_bts_rach_nm_b_thresh,
2352 cfg_bts_rach_nm_b_thresh_cmd,
2353 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002354 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002355 "Set the NM Busy Threshold\n"
2356 "Set the NM Busy Threshold\n"
2357 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002358{
2359 struct gsm_bts *bts = vty->index;
2360 bts->rach_b_thresh = atoi(argv[0]);
2361 return CMD_SUCCESS;
2362}
2363
2364DEFUN(cfg_bts_rach_nm_ldavg,
2365 cfg_bts_rach_nm_ldavg_cmd,
2366 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002367 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002368 "Set the NM Loadaverage Slots value\n"
2369 "Set the NM Loadaverage Slots value\n"
2370 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002371{
2372 struct gsm_bts *bts = vty->index;
2373 bts->rach_ldavg_slots = atoi(argv[0]);
2374 return CMD_SUCCESS;
2375}
2376
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002377DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2378 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002379 "Should this cell be barred from access?\n"
2380 "Should this cell be barred from access?\n"
2381 "Cell should NOT be barred\n"
2382 "Cell should be barred\n")
2383
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002384{
2385 struct gsm_bts *bts = vty->index;
2386
Harald Welte71355012009-12-21 23:08:18 +01002387 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002388
2389 return CMD_SUCCESS;
2390}
2391
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002392DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2393 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002394 RACH_STR
2395 "Should this cell allow emergency calls?\n"
2396 "Should this cell allow emergency calls?\n"
2397 "Should this cell allow emergency calls?\n"
2398 "Do NOT allow emergency calls\n"
2399 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002400{
2401 struct gsm_bts *bts = vty->index;
2402
2403 if (atoi(argv[0]) == 0)
2404 bts->si_common.rach_control.t2 |= 0x4;
2405 else
2406 bts->si_common.rach_control.t2 &= ~0x4;
2407
2408 return CMD_SUCCESS;
2409}
2410
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002411DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2412 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2413 RACH_STR
2414 "Set access control class\n"
2415 "Access control class 0\n"
2416 "Access control class 1\n"
2417 "Access control class 2\n"
2418 "Access control class 3\n"
2419 "Access control class 4\n"
2420 "Access control class 5\n"
2421 "Access control class 6\n"
2422 "Access control class 7\n"
2423 "Access control class 8\n"
2424 "Access control class 9\n"
2425 "Access control class 11 for PLMN use\n"
2426 "Access control class 12 for security services\n"
2427 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2428 "Access control class 14 for emergency services\n"
2429 "Access control class 15 for PLMN staff\n"
2430 "barred to use access control class\n"
2431 "allowed to use access control class\n")
2432{
2433 struct gsm_bts *bts = vty->index;
2434
2435 uint8_t control_class;
2436 uint8_t allowed = 0;
2437
2438 if (strcmp(argv[1], "allowed") == 0)
2439 allowed = 1;
2440
2441 control_class = atoi(argv[0]);
2442 if (control_class < 8)
2443 if (allowed)
2444 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2445 else
2446 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2447 else
2448 if (allowed)
2449 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2450 else
2451 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2452
2453 return CMD_SUCCESS;
2454}
2455
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002456DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2457 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002458 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002459 "Maximum transmit power of the MS\n"
2460 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002461 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002462{
2463 struct gsm_bts *bts = vty->index;
2464
2465 bts->ms_max_power = atoi(argv[0]);
2466
2467 return CMD_SUCCESS;
2468}
2469
Harald Weltecfaabbb2012-08-16 23:23:50 +02002470#define CELL_STR "Cell Parameters\n"
2471
Harald Welte73225282009-12-12 18:17:25 +01002472DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2473 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002474 CELL_STR "Cell re-selection parameters\n"
2475 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002476 "Cell Re-Selection Hysteresis in dB")
2477{
2478 struct gsm_bts *bts = vty->index;
2479
2480 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2481
2482 return CMD_SUCCESS;
2483}
2484
2485DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2486 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002487 "Minimum RxLev needed for cell access\n"
2488 "Minimum RxLev needed for cell access\n"
2489 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002490 "Minimum RxLev needed for cell access (better than -110dBm)")
2491{
2492 struct gsm_bts *bts = vty->index;
2493
2494 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2495
2496 return CMD_SUCCESS;
2497}
2498
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002499DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2500 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002501 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2502 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002503{
2504 struct gsm_bts *bts = vty->index;
2505
2506 bts->si_common.cell_ro_sel_par.present = 1;
2507 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2508
2509 return CMD_SUCCESS;
2510}
2511
2512DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2513 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002514 CELL_STR "Cell Re-Selection Parameters\n"
2515 "Cell Re-Selection Offset (CRO) in dB\n"
2516 "Cell Re-Selection Offset (CRO) in dB\n"
2517 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002518{
2519 struct gsm_bts *bts = vty->index;
2520
2521 bts->si_common.cell_ro_sel_par.present = 1;
2522 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2523
2524 return CMD_SUCCESS;
2525}
2526
2527DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2528 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002529 "Cell selection temporary negative offset\n"
2530 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002531 "Cell selection temporary negative offset in dB")
2532{
2533 struct gsm_bts *bts = vty->index;
2534
2535 bts->si_common.cell_ro_sel_par.present = 1;
2536 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2537
2538 return CMD_SUCCESS;
2539}
2540
2541DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2542 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002543 "Cell selection temporary negative offset\n"
2544 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002545 "Sets cell selection temporary negative offset to infinity")
2546{
2547 struct gsm_bts *bts = vty->index;
2548
2549 bts->si_common.cell_ro_sel_par.present = 1;
2550 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2551
2552 return CMD_SUCCESS;
2553}
2554
2555DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2556 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002557 "Cell selection penalty time\n"
2558 "Cell selection penalty time\n"
2559 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002560{
2561 struct gsm_bts *bts = vty->index;
2562
2563 bts->si_common.cell_ro_sel_par.present = 1;
2564 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2565
2566 return CMD_SUCCESS;
2567}
2568
2569DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2570 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002571 "Cell selection penalty time\n"
2572 "Cell selection penalty time\n"
2573 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002574 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2575 "and TEMPORARY_OFFSET is ignored)")
2576{
2577 struct gsm_bts *bts = vty->index;
2578
2579 bts->si_common.cell_ro_sel_par.present = 1;
2580 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2581
2582 return CMD_SUCCESS;
2583}
2584
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002585DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2586 "radio-link-timeout <4-64>",
2587 "Radio link timeout criterion (BTS side)\n"
2588 "Radio link timeout value (lost SACCH block)\n")
2589{
2590 struct gsm_bts *bts = vty->index;
2591
Harald Welte2f8b9d22017-06-18 11:12:13 +03002592 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2593
2594 return CMD_SUCCESS;
2595}
2596
2597DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2598 "radio-link-timeout infinite",
2599 "Radio link timeout criterion (BTS side)\n"
2600 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2601{
2602 struct gsm_bts *bts = vty->index;
2603
2604 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2605 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2606 return CMD_WARNING;
2607 }
2608
2609 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2610 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002611
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002612 return CMD_SUCCESS;
2613}
2614
Harald Welte8f0ed552010-05-11 21:53:49 +02002615#define GPRS_TEXT "GPRS Packet Network\n"
2616
Harald Welteaf387632010-03-14 23:30:30 +08002617DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002618 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002619 GPRS_TEXT
2620 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002621 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002622 "GPRS BSSGP VC Identifier")
2623{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002624 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002625 struct gsm_bts *bts = vty->index;
2626
Harald Welte4511d892010-04-18 15:51:20 +02002627 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002628 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2629 return CMD_WARNING;
2630 }
2631
Harald Welte97a282b2010-03-14 15:37:43 +08002632 bts->gprs.cell.bvci = atoi(argv[0]);
2633
2634 return CMD_SUCCESS;
2635}
2636
Harald Weltea5731cf2010-03-22 11:48:36 +08002637DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2638 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002639 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002640 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002641 "GPRS NS Entity Identifier")
2642{
2643 struct gsm_bts *bts = vty->index;
2644
Harald Welte4511d892010-04-18 15:51:20 +02002645 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002646 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2647 return CMD_WARNING;
2648 }
2649
2650 bts->gprs.nse.nsei = atoi(argv[0]);
2651
2652 return CMD_SUCCESS;
2653}
2654
Harald Welte8f0ed552010-05-11 21:53:49 +02002655#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2656 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002657
Harald Welte97a282b2010-03-14 15:37:43 +08002658DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2659 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002660 GPRS_TEXT NSVC_TEXT
2661 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002662 "GPRS NS VC Identifier")
2663{
2664 struct gsm_bts *bts = vty->index;
2665 int idx = atoi(argv[0]);
2666
Harald Welte4511d892010-04-18 15:51:20 +02002667 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002668 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2669 return CMD_WARNING;
2670 }
2671
Harald Welte97a282b2010-03-14 15:37:43 +08002672 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2673
2674 return CMD_SUCCESS;
2675}
2676
Harald Welteaf387632010-03-14 23:30:30 +08002677DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2678 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002679 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002680 "GPRS NS Local UDP Port\n"
2681 "GPRS NS Local UDP Port\n"
2682 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002683 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002684{
2685 struct gsm_bts *bts = vty->index;
2686 int idx = atoi(argv[0]);
2687
Harald Welte4511d892010-04-18 15:51:20 +02002688 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002689 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2690 return CMD_WARNING;
2691 }
2692
Harald Welteaf387632010-03-14 23:30:30 +08002693 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2694
2695 return CMD_SUCCESS;
2696}
2697
2698DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2699 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002700 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002701 "GPRS NS Remote UDP Port\n"
2702 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002703 "GPRS NS Remote UDP Port\n"
2704 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002705{
2706 struct gsm_bts *bts = vty->index;
2707 int idx = atoi(argv[0]);
2708
Harald Welte4511d892010-04-18 15:51:20 +02002709 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002710 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2711 return CMD_WARNING;
2712 }
2713
Harald Welteaf387632010-03-14 23:30:30 +08002714 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2715
2716 return CMD_SUCCESS;
2717}
2718
2719DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2720 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002721 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002722 "GPRS NS Remote IP Address\n"
2723 "GPRS NS Remote IP Address\n"
2724 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002725{
2726 struct gsm_bts *bts = vty->index;
2727 int idx = atoi(argv[0]);
2728 struct in_addr ia;
2729
Harald Welte4511d892010-04-18 15:51:20 +02002730 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002731 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2732 return CMD_WARNING;
2733 }
2734
Harald Welteaf387632010-03-14 23:30:30 +08002735 inet_aton(argv[1], &ia);
2736 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2737
2738 return CMD_SUCCESS;
2739}
2740
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002741DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002742 "paging free <-1-1024>",
2743 "Paging options\n"
2744 "Only page when having a certain amount of free slots\n"
2745 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002746{
2747 struct gsm_bts *bts = vty->index;
2748
2749 bts->paging.free_chans_need = atoi(argv[0]);
2750 return CMD_SUCCESS;
2751}
2752
Harald Welte615e9562010-05-11 23:50:21 +02002753DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2754 "gprs ns timer " NS_TIMERS " <0-255>",
2755 GPRS_TEXT "Network Service\n"
2756 "Network Service Timer\n"
2757 NS_TIMERS_HELP "Timer Value\n")
2758{
2759 struct gsm_bts *bts = vty->index;
2760 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2761 int val = atoi(argv[1]);
2762
2763 if (bts->gprs.mode == BTS_GPRS_NONE) {
2764 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2765 return CMD_WARNING;
2766 }
2767
2768 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2769 return CMD_WARNING;
2770
2771 bts->gprs.nse.timer[idx] = val;
2772
2773 return CMD_SUCCESS;
2774}
2775
2776#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 +02002777#define BSSGP_TIMERS_HELP \
2778 "Tbvc-block timeout\n" \
2779 "Tbvc-block retries\n" \
2780 "Tbvc-unblock retries\n" \
2781 "Tbvcc-reset timeout\n" \
2782 "Tbvc-reset retries\n" \
2783 "Tbvc-suspend timeout\n" \
2784 "Tbvc-suspend retries\n" \
2785 "Tbvc-resume timeout\n" \
2786 "Tbvc-resume retries\n" \
2787 "Tbvc-capa-update timeout\n" \
2788 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002789
2790DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2791 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2792 GPRS_TEXT "Cell / BSSGP\n"
2793 "Cell/BSSGP Timer\n"
2794 BSSGP_TIMERS_HELP "Timer Value\n")
2795{
2796 struct gsm_bts *bts = vty->index;
2797 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2798 int val = atoi(argv[1]);
2799
2800 if (bts->gprs.mode == BTS_GPRS_NONE) {
2801 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2802 return CMD_WARNING;
2803 }
2804
2805 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2806 return CMD_WARNING;
2807
2808 bts->gprs.cell.timer[idx] = val;
2809
2810 return CMD_SUCCESS;
2811}
2812
Harald Welte97a282b2010-03-14 15:37:43 +08002813DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2814 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002815 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002816 "GPRS Routing Area Code\n"
2817 "GPRS Routing Area Code\n"
2818 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002819{
2820 struct gsm_bts *bts = vty->index;
2821
Harald Welte4511d892010-04-18 15:51:20 +02002822 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002823 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2824 return CMD_WARNING;
2825 }
2826
Harald Welte97a282b2010-03-14 15:37:43 +08002827 bts->gprs.rac = atoi(argv[0]);
2828
2829 return CMD_SUCCESS;
2830}
2831
Max292ec582016-07-28 11:55:37 +02002832DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2833 "gprs control-ack-type-rach", GPRS_TEXT
2834 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2835 "four access bursts format instead of default RLC/MAC control block\n")
2836{
2837 struct gsm_bts *bts = vty->index;
2838
2839 if (bts->gprs.mode == BTS_GPRS_NONE) {
2840 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2841 return CMD_WARNING;
2842 }
2843
2844 bts->gprs.ctrl_ack_type_use_block = false;
2845
2846 return CMD_SUCCESS;
2847}
2848
2849DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2850 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2851 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2852 "four access bursts format instead of default RLC/MAC control block\n")
2853{
2854 struct gsm_bts *bts = vty->index;
2855
2856 if (bts->gprs.mode == BTS_GPRS_NONE) {
2857 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2858 return CMD_WARNING;
2859 }
2860
2861 bts->gprs.ctrl_ack_type_use_block = true;
2862
2863 return CMD_SUCCESS;
2864}
2865
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002866DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2867 "gprs network-control-order (nc0|nc1|nc2)",
2868 GPRS_TEXT
2869 "GPRS Network Control Order\n"
2870 "MS controlled cell re-selection, no measurement reporting\n"
2871 "MS controlled cell re-selection, MS sends measurement reports\n"
2872 "Network controlled cell re-selection, MS sends measurement reports\n")
2873{
2874 struct gsm_bts *bts = vty->index;
2875
2876 if (bts->gprs.mode == BTS_GPRS_NONE) {
2877 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2878 return CMD_WARNING;
2879 }
2880
2881 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2882
2883 return CMD_SUCCESS;
2884}
2885
Harald Welte4511d892010-04-18 15:51:20 +02002886DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2887 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002888 GPRS_TEXT
2889 "GPRS Mode for this BTS\n"
2890 "GPRS Disabled on this BTS\n"
2891 "GPRS Enabled on this BTS\n"
2892 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002893{
2894 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002895 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002896
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002897 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002898 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2899 VTY_NEWLINE);
2900 return CMD_WARNING;
2901 }
2902
2903 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002904
2905 return CMD_SUCCESS;
2906}
2907
bhargava350533c2016-07-21 11:14:34 +05302908DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2909 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2910 "gprs 11bit_rach_support_for_egprs (0|1)",
2911 GPRS_TEXT "11 bit RACH options\n"
2912 "Disable 11 bit RACH for EGPRS\n"
2913 "Enable 11 bit RACH for EGPRS")
2914{
2915 struct gsm_bts *bts = vty->index;
2916
2917 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2918
2919 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2920 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2921 return CMD_WARNING;
2922 }
2923
2924 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2925 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2926 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2927 " enabled%s", VTY_NEWLINE);
2928 return CMD_WARNING;
2929 }
2930
2931 return CMD_SUCCESS;
2932}
2933
Harald Welte9fbff4a2010-07-30 11:50:09 +02002934#define SI_TEXT "System Information Messages\n"
2935#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)"
2936#define SI_TYPE_HELP "System Information Type 1\n" \
2937 "System Information Type 2\n" \
2938 "System Information Type 3\n" \
2939 "System Information Type 4\n" \
2940 "System Information Type 5\n" \
2941 "System Information Type 6\n" \
2942 "System Information Type 7\n" \
2943 "System Information Type 8\n" \
2944 "System Information Type 9\n" \
2945 "System Information Type 10\n" \
2946 "System Information Type 13\n" \
2947 "System Information Type 16\n" \
2948 "System Information Type 17\n" \
2949 "System Information Type 18\n" \
2950 "System Information Type 19\n" \
2951 "System Information Type 20\n" \
2952 "System Information Type 2bis\n" \
2953 "System Information Type 2ter\n" \
2954 "System Information Type 2quater\n" \
2955 "System Information Type 5bis\n" \
2956 "System Information Type 5ter\n"
2957
2958DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2959 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2960 SI_TEXT SI_TYPE_HELP
2961 "System Information Mode\n"
2962 "Static user-specified\n"
2963 "Dynamic, BSC-computed\n")
2964{
2965 struct gsm_bts *bts = vty->index;
2966 int type;
2967
2968 type = get_string_value(osmo_sitype_strs, argv[0]);
2969 if (type < 0) {
2970 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2971 return CMD_WARNING;
2972 }
2973
2974 if (!strcmp(argv[1], "static"))
2975 bts->si_mode_static |= (1 << type);
2976 else
2977 bts->si_mode_static &= ~(1 << type);
2978
2979 return CMD_SUCCESS;
2980}
2981
2982DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2983 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2984 SI_TEXT SI_TYPE_HELP
2985 "Static System Information filling\n"
2986 "Static user-specified SI content in HEX notation\n")
2987{
2988 struct gsm_bts *bts = vty->index;
2989 int rc, type;
2990
2991 type = get_string_value(osmo_sitype_strs, argv[0]);
2992 if (type < 0) {
2993 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2994 return CMD_WARNING;
2995 }
2996
2997 if (!(bts->si_mode_static & (1 << type))) {
2998 vty_out(vty, "SI Type %s is not configured in static mode%s",
2999 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
3000 return CMD_WARNING;
3001 }
3002
Harald Welte290aaed2010-07-30 11:53:18 +02003003 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02003004 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02003005
3006 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02003007 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
3008 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02003009 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3010 return CMD_WARNING;
3011 }
3012
3013 /* Mark this SI as present */
3014 bts->si_valid |= (1 << type);
3015
3016 return CMD_SUCCESS;
3017}
3018
Harald Welte42def722017-01-13 00:10:32 +01003019DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
3020 "early-classmark-sending (allowed|forbidden)",
3021 "Early Classmark Sending\n"
3022 "Early Classmark Sending is allowed\n"
3023 "Early Classmark Sending is forbidden\n")
3024{
3025 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01003026
3027 if (!strcmp(argv[0], "allowed"))
3028 bts->early_classmark_allowed = true;
3029 else
3030 bts->early_classmark_allowed = false;
3031
3032 return CMD_SUCCESS;
3033}
3034
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01003035DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
3036 "early-classmark-sending-3g (allowed|forbidden)",
3037 "3G Early Classmark Sending\n"
3038 "3G Early Classmark Sending is allowed\n"
3039 "3G Early Classmark Sending is forbidden\n")
3040{
3041 struct gsm_bts *bts = vty->index;
3042
3043 if (!strcmp(argv[0], "allowed"))
3044 bts->early_classmark_allowed_3g = true;
3045 else
3046 bts->early_classmark_allowed_3g = false;
3047
3048 return CMD_SUCCESS;
3049}
3050
Harald Welte32c09622011-01-11 23:44:56 +01003051DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01003052 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01003053 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003054 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
3055 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01003056{
3057 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01003058 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01003059
Harald Welte64c07d22011-02-15 11:43:27 +01003060 switch (mode) {
3061 case NL_MODE_MANUAL_SI5SEP:
3062 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01003063 /* make sure we clear the current list when switching to
3064 * manual mode */
3065 if (bts->neigh_list_manual_mode == 0)
3066 memset(&bts->si_common.data.neigh_list, 0,
3067 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01003068 break;
3069 default:
3070 break;
3071 }
3072
3073 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01003074
3075 return CMD_SUCCESS;
3076}
3077
3078DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003079 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01003080 "Neighbor List\n" "Add to manual neighbor list\n"
3081 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
3082 "ARFCN of neighbor\n")
3083{
3084 struct gsm_bts *bts = vty->index;
3085 struct bitvec *bv = &bts->si_common.neigh_list;
3086 uint16_t arfcn = atoi(argv[1]);
3087
3088 if (!bts->neigh_list_manual_mode) {
3089 vty_out(vty, "%% Cannot configure neighbor list in "
3090 "automatic mode%s", VTY_NEWLINE);
3091 return CMD_WARNING;
3092 }
3093
3094 if (!strcmp(argv[0], "add"))
3095 bitvec_set_bit_pos(bv, arfcn, 1);
3096 else
3097 bitvec_set_bit_pos(bv, arfcn, 0);
3098
3099 return CMD_SUCCESS;
3100}
3101
Max70fdd242017-06-15 15:10:53 +02003102/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02003103DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01003104 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
3105 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
3106 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
3107 "Add to manual SI2quater neighbor list\n"
3108 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
3109 "threshold high bits\n" "threshold high bits\n"
3110 "threshold low bits\n" "threshold low bits (32 means NA)\n"
3111 "priority\n" "priority (8 means NA)\n"
3112 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
3113 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02003114{
3115 struct gsm_bts *bts = vty->index;
3116 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
3117 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01003118 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
3119 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02003120 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02003121
Max70fdd242017-06-15 15:10:53 +02003122 switch (r) {
3123 case 1:
3124 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
3125 thresh_hi, VTY_NEWLINE);
3126 break;
3127 case EARFCN_THRESH_LOW_INVALID:
3128 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
3129 thresh_lo, VTY_NEWLINE);
3130 break;
3131 case EARFCN_QRXLV_INVALID + 1:
3132 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
3133 qrx, VTY_NEWLINE);
3134 break;
3135 case EARFCN_PRIO_INVALID:
3136 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
3137 prio, VTY_NEWLINE);
3138 break;
3139 default:
3140 if (r < 0) {
3141 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
3142 return CMD_WARNING;
3143 }
Max59a1bf32016-04-15 16:04:46 +02003144 }
3145
Max70fdd242017-06-15 15:10:53 +02003146 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01003147 return CMD_SUCCESS;
3148
Maxf39d03a2017-05-12 17:00:30 +02003149 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02003150 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02003151 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01003152
Maxaafff962016-04-20 15:57:14 +02003153 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02003154}
3155
3156DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02003157 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02003158 "SI2quater Neighbor List\n"
3159 "SI2quater Neighbor List\n"
3160 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02003161 "EARFCN of neighbor\n"
3162 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02003163{
3164 struct gsm_bts *bts = vty->index;
3165 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02003166 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02003167 int r = osmo_earfcn_del(e, arfcn);
3168 if (r < 0) {
3169 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02003170 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02003171 return CMD_WARNING;
3172 }
3173
3174 return CMD_SUCCESS;
3175}
3176
Max26679e02016-04-20 15:57:13 +02003177DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02003178 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02003179 "SI2quater Neighbor List\n"
3180 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
3181 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
3182 "diversity bit\n")
3183{
3184 struct gsm_bts *bts = vty->index;
3185 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
3186
3187 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
3188 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02003189 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 +01003190 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02003191 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02003192 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
3193 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01003194 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02003195 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02003196 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02003197 return CMD_WARNING;
3198 }
3199
3200 return CMD_SUCCESS;
3201}
3202
3203DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02003204 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02003205 "SI2quater Neighbor List\n"
3206 "SI2quater Neighbor List\n"
3207 "Delete from SI2quater manual neighbor list\n"
3208 "UARFCN of neighbor\n"
3209 "UARFCN\n"
3210 "scrambling code\n")
3211{
3212 struct gsm_bts *bts = vty->index;
3213
3214 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
3215 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
3216 VTY_NEWLINE);
3217 return CMD_WARNING;
3218 }
3219
3220 return CMD_SUCCESS;
3221}
3222
Harald Welte64c07d22011-02-15 11:43:27 +01003223DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003224 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003225 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003226 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
3227 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
3228 "ARFCN of neighbor\n")
3229{
3230 struct gsm_bts *bts = vty->index;
3231 struct bitvec *bv = &bts->si_common.si5_neigh_list;
3232 uint16_t arfcn = atoi(argv[1]);
3233
3234 if (!bts->neigh_list_manual_mode) {
3235 vty_out(vty, "%% Cannot configure neighbor list in "
3236 "automatic mode%s", VTY_NEWLINE);
3237 return CMD_WARNING;
3238 }
3239
3240 if (!strcmp(argv[0], "add"))
3241 bitvec_set_bit_pos(bv, arfcn, 1);
3242 else
3243 bitvec_set_bit_pos(bv, arfcn, 0);
3244
3245 return CMD_SUCCESS;
3246}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003247
Harald Welte8254cf72017-05-29 13:42:19 +02003248DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3249 "pcu-socket PATH",
3250 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3251 "Path in the file system for the unix-domain PCU socket\n")
3252{
3253 struct gsm_bts *bts = vty->index;
3254 int rc;
3255
Harald Welte4a824ca2017-05-29 13:54:27 +02003256 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003257 pcu_sock_exit(bts);
3258 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3259 if (rc < 0) {
3260 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3261 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3262 return CMD_WARNING;
3263 }
3264
3265 return CMD_SUCCESS;
3266}
3267
Stefan Sperling6442e432018-02-06 14:44:54 +01003268DEFUN(cfg_bts_acc_ramping,
3269 cfg_bts_acc_ramping_cmd,
3270 "access-control-class-ramping",
3271 "Enable Access Control Class ramping\n")
3272{
3273 struct gsm_bts *bts = vty->index;
3274
3275 acc_ramp_init(&bts->acc_ramp, true, bts);
3276
3277 /* ACC ramping takes effect when the BTS reconnects. */
3278 return CMD_SUCCESS;
3279}
3280
3281DEFUN(cfg_bts_no_acc_ramping, cfg_bts_no_acc_ramping_cmd,
3282 "no access-control-class-ramping",
3283 NO_STR
3284 "Disable Access Control Class ramping\n")
3285{
3286 struct gsm_bts *bts = vty->index;
3287
3288 if (acc_ramp_is_enabled(&bts->acc_ramp)) {
3289 acc_ramp_abort(&bts->acc_ramp);
3290 acc_ramp_init(&bts->acc_ramp, false, bts);
3291 gsm_bts_set_system_infos(bts);
3292 }
3293
3294 return CMD_SUCCESS;
3295}
3296
3297DEFUN(cfg_bts_acc_ramping_step_interval,
3298 cfg_bts_acc_ramping_step_interval_cmd,
3299 "access-control-class-ramping-step-interval (<"
3300 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MIN) "-"
3301 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MAX) ">|dynamic)",
3302 "Configure Access Control Class ramping step interval\n"
3303 "Set a fixed step interval (in seconds)\n"
3304 "Use dynamic step interval based on BTS channel load\n")
3305{
3306 struct gsm_bts *bts = vty->index;
3307 bool dynamic = (strcmp(argv[0], "dynamic") == 0);
3308 int error;
3309
3310 if (dynamic) {
3311 acc_ramp_set_step_interval_dynamic(&bts->acc_ramp);
3312 return CMD_SUCCESS;
3313 }
3314
3315 error = acc_ramp_set_step_interval(&bts->acc_ramp, atoi(argv[0]));
3316 if (error != 0) {
3317 if (error == -ERANGE)
3318 vty_out(vty, "Unable to set ACC ramp step interval: value out of range%s", VTY_NEWLINE);
3319 else
3320 vty_out(vty, "Unable to set ACC ramp step interval: unknown error%s", VTY_NEWLINE);
3321 return CMD_WARNING;
3322 }
3323
3324 return CMD_SUCCESS;
3325}
3326
3327DEFUN(cfg_bts_acc_ramping_step_size,
3328 cfg_bts_acc_ramping_step_size_cmd,
3329 "access-control-class-ramping-step-size (<"
3330 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MIN) "-"
3331 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MAX) ">)",
3332 "Configure Access Control Class ramping step size\n"
3333 "Set the number of Access Control Classes to enable per ramping step\n")
3334{
3335 struct gsm_bts *bts = vty->index;
3336 int error;
3337
3338 error = acc_ramp_set_step_size(&bts->acc_ramp, atoi(argv[0]));
3339 if (error != 0) {
3340 if (error == -ERANGE)
3341 vty_out(vty, "Unable to set ACC ramp step size: value out of range%s", VTY_NEWLINE);
3342 else
3343 vty_out(vty, "Unable to set ACC ramp step size: unknown error%s", VTY_NEWLINE);
3344 return CMD_WARNING;
3345 }
3346
3347 return CMD_SUCCESS;
3348}
3349
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003350#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3351
3352DEFUN(cfg_bts_excl_rf_lock,
3353 cfg_bts_excl_rf_lock_cmd,
3354 "rf-lock-exclude",
3355 EXCL_RFLOCK_STR)
3356{
3357 struct gsm_bts *bts = vty->index;
3358 bts->excl_from_rf_lock = 1;
3359 return CMD_SUCCESS;
3360}
3361
3362DEFUN(cfg_bts_no_excl_rf_lock,
3363 cfg_bts_no_excl_rf_lock_cmd,
3364 "no rf-lock-exclude",
3365 NO_STR EXCL_RFLOCK_STR)
3366{
3367 struct gsm_bts *bts = vty->index;
3368 bts->excl_from_rf_lock = 0;
3369 return CMD_SUCCESS;
3370}
3371
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003372#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3373
3374DEFUN(cfg_bts_force_comb_si,
3375 cfg_bts_force_comb_si_cmd,
3376 "force-combined-si",
3377 FORCE_COMB_SI_STR)
3378{
3379 struct gsm_bts *bts = vty->index;
3380 bts->force_combined_si = 1;
3381 return CMD_SUCCESS;
3382}
3383
3384DEFUN(cfg_bts_no_force_comb_si,
3385 cfg_bts_no_force_comb_si_cmd,
3386 "no force-combined-si",
3387 NO_STR FORCE_COMB_SI_STR)
3388{
3389 struct gsm_bts *bts = vty->index;
3390 bts->force_combined_si = 0;
3391 return CMD_SUCCESS;
3392}
3393
Andreas Eversberga83d5112013-12-07 18:32:28 +01003394static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3395{
3396 struct gsm_bts *bts = vty->index;
3397 struct bts_codec_conf *codec = &bts->codec;
3398 int i;
3399
3400 codec->hr = 0;
3401 codec->efr = 0;
3402 codec->amr = 0;
3403 for (i = 0; i < argc; i++) {
3404 if (!strcmp(argv[i], "hr"))
3405 codec->hr = 1;
3406 if (!strcmp(argv[i], "efr"))
3407 codec->efr = 1;
3408 if (!strcmp(argv[i], "amr"))
3409 codec->amr = 1;
3410 }
3411}
3412
3413#define CODEC_PAR_STR " (hr|efr|amr)"
3414#define CODEC_HELP_STR "Half Rate\n" \
3415 "Enhanced Full Rate\nAdaptive Multirate\n"
3416
3417DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3418 "codec-support fr",
3419 "Codec Support settings\nFullrate\n")
3420{
3421 _get_codec_from_arg(vty, 0, argv);
3422 return CMD_SUCCESS;
3423}
3424
3425DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3426 "codec-support fr" CODEC_PAR_STR,
3427 "Codec Support settings\nFullrate\n"
3428 CODEC_HELP_STR)
3429{
3430 _get_codec_from_arg(vty, 1, argv);
3431 return CMD_SUCCESS;
3432}
3433
3434DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3435 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3436 "Codec Support settings\nFullrate\n"
3437 CODEC_HELP_STR CODEC_HELP_STR)
3438{
3439 _get_codec_from_arg(vty, 2, argv);
3440 return CMD_SUCCESS;
3441}
3442
3443DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3444 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3445 "Codec Support settings\nFullrate\n"
3446 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3447{
3448 _get_codec_from_arg(vty, 3, argv);
3449 return CMD_SUCCESS;
3450}
3451
3452DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3453 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3454 "Codec Support settings\nFullrate\n"
3455 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3456{
3457 _get_codec_from_arg(vty, 4, argv);
3458 return CMD_SUCCESS;
3459}
3460
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003461DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3462 "depends-on-bts <0-255>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003463 "This BTS can only be started if another one is up\n"
3464 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003465{
3466 struct gsm_bts *bts = vty->index;
3467 struct gsm_bts *other_bts;
3468 int dep = atoi(argv[0]);
3469
3470
3471 if (!is_ipaccess_bts(bts)) {
3472 vty_out(vty, "This feature is only available for IP systems.%s",
3473 VTY_NEWLINE);
3474 return CMD_WARNING;
3475 }
3476
3477 other_bts = gsm_bts_num(bts->network, dep);
3478 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3479 vty_out(vty, "This feature is only available for IP systems.%s",
3480 VTY_NEWLINE);
3481 return CMD_WARNING;
3482 }
3483
3484 if (dep >= bts->nr) {
3485 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3486 VTY_NEWLINE);
3487 return CMD_WARNING;
3488 }
3489
3490 bts_depend_mark(bts, dep);
3491 return CMD_SUCCESS;
3492}
3493
3494DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3495 "depeneds-on-bts <0-255>",
3496 NO_STR "This BTS can only be started if another one is up\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003497 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003498{
3499 struct gsm_bts *bts = vty->index;
3500 int dep = atoi(argv[0]);
3501
3502 bts_depend_clear(bts, dep);
3503 return CMD_SUCCESS;
3504}
3505
Andreas Eversberg73266522014-01-19 11:47:44 +01003506#define AMR_TEXT "Adaptive Multi Rate settings\n"
3507#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3508#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3509 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3510#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3511#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3512
3513static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3514{
3515 struct gsm_bts *bts = vty->index;
3516 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3517 struct gsm48_multi_rate_conf *mr_conf =
3518 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3519 int i;
3520
3521 mr->gsm48_ie[1] = 0;
3522 for (i = 0; i < argc; i++)
3523 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3524 mr_conf->icmi = 0;
3525}
3526
3527static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3528{
3529 struct gsm_bts *bts = vty->index;
3530 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003531 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003532 int i;
3533
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003534 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3535 for (i = 0; i < argc - 1; i++)
3536 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003537}
3538
3539static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3540{
3541 struct gsm_bts *bts = vty->index;
3542 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003543 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003544 int i;
3545
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003546 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3547 for (i = 0; i < argc - 1; i++)
3548 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003549}
3550
3551static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3552{
3553 struct gsm_bts *bts = vty->index;
3554 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3555 struct gsm48_multi_rate_conf *mr_conf =
3556 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3557 int num = 0, i;
3558
3559 for (i = 0; i < ((full) ? 8 : 6); i++) {
3560 if ((mr->gsm48_ie[1] & (1 << i))) {
3561 num++;
3562 }
3563 }
3564
3565 if (argv[0][0] == 'a' || num == 0)
3566 mr_conf->icmi = 0;
3567 else {
3568 mr_conf->icmi = 1;
3569 if (num < atoi(argv[0]))
3570 mr_conf->smod = num - 1;
3571 else
3572 mr_conf->smod = atoi(argv[0]) - 1;
3573 }
3574}
3575
3576#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3577#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3578 "10,2k\n12,2k\n"
3579
3580#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3581#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3582
3583#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3584#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3585
3586DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3587 "amr tch-f modes" AMR_TCHF_PAR_STR,
3588 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3589 AMR_TCHF_HELP_STR)
3590{
3591 get_amr_from_arg(vty, 1, argv, 1);
3592 return CMD_SUCCESS;
3593}
3594
3595DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3596 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3597 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3598 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3599{
3600 get_amr_from_arg(vty, 2, argv, 1);
3601 return CMD_SUCCESS;
3602}
3603
3604DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3605 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3606 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3607 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3608{
3609 get_amr_from_arg(vty, 3, argv, 1);
3610 return CMD_SUCCESS;
3611}
3612
3613DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3614 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3615 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3616 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3617{
3618 get_amr_from_arg(vty, 4, argv, 1);
3619 return CMD_SUCCESS;
3620}
3621
3622DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3623 "amr tch-f start-mode (auto|1|2|3|4)",
3624 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3625{
3626 get_amr_start_from_arg(vty, argv, 1);
3627 return CMD_SUCCESS;
3628}
3629
3630DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3631 "amr tch-f threshold (ms|bts) <0-63>",
3632 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3633 AMR_TH_HELP_STR)
3634{
3635 get_amr_th_from_arg(vty, 2, argv, 1);
3636 return CMD_SUCCESS;
3637}
3638
3639DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3640 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3641 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3642 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3643{
3644 get_amr_th_from_arg(vty, 3, argv, 1);
3645 return CMD_SUCCESS;
3646}
3647
3648DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3649 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3650 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3651 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3652{
3653 get_amr_th_from_arg(vty, 4, argv, 1);
3654 return CMD_SUCCESS;
3655}
3656
3657DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3658 "amr tch-f hysteresis (ms|bts) <0-15>",
3659 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3660 AMR_HY_HELP_STR)
3661{
3662 get_amr_hy_from_arg(vty, 2, argv, 1);
3663 return CMD_SUCCESS;
3664}
3665
3666DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3667 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3668 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3669 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3670{
3671 get_amr_hy_from_arg(vty, 3, argv, 1);
3672 return CMD_SUCCESS;
3673}
3674
3675DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3676 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3677 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3678 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3679{
3680 get_amr_hy_from_arg(vty, 4, argv, 1);
3681 return CMD_SUCCESS;
3682}
3683
3684DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3685 "amr tch-h modes" AMR_TCHH_PAR_STR,
3686 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3687 AMR_TCHH_HELP_STR)
3688{
3689 get_amr_from_arg(vty, 1, argv, 0);
3690 return CMD_SUCCESS;
3691}
3692
3693DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3694 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3695 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3696 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3697{
3698 get_amr_from_arg(vty, 2, argv, 0);
3699 return CMD_SUCCESS;
3700}
3701
3702DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3703 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3704 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3705 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3706{
3707 get_amr_from_arg(vty, 3, argv, 0);
3708 return CMD_SUCCESS;
3709}
3710
3711DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3712 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3713 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3714 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3715{
3716 get_amr_from_arg(vty, 4, argv, 0);
3717 return CMD_SUCCESS;
3718}
3719
3720DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3721 "amr tch-h start-mode (auto|1|2|3|4)",
3722 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3723{
3724 get_amr_start_from_arg(vty, argv, 0);
3725 return CMD_SUCCESS;
3726}
3727
3728DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3729 "amr tch-h threshold (ms|bts) <0-63>",
3730 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3731 AMR_TH_HELP_STR)
3732{
3733 get_amr_th_from_arg(vty, 2, argv, 0);
3734 return CMD_SUCCESS;
3735}
3736
3737DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3738 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3739 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3740 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3741{
3742 get_amr_th_from_arg(vty, 3, argv, 0);
3743 return CMD_SUCCESS;
3744}
3745
3746DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3747 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3748 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3749 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3750{
3751 get_amr_th_from_arg(vty, 4, argv, 0);
3752 return CMD_SUCCESS;
3753}
3754
3755DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3756 "amr tch-h hysteresis (ms|bts) <0-15>",
3757 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3758 AMR_HY_HELP_STR)
3759{
3760 get_amr_hy_from_arg(vty, 2, argv, 0);
3761 return CMD_SUCCESS;
3762}
3763
3764DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3765 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3766 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3767 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3768{
3769 get_amr_hy_from_arg(vty, 3, argv, 0);
3770 return CMD_SUCCESS;
3771}
3772
3773DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3774 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3775 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3776 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3777{
3778 get_amr_hy_from_arg(vty, 4, argv, 0);
3779 return CMD_SUCCESS;
3780}
3781
Harald Welte8f0ed552010-05-11 21:53:49 +02003782#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003783
Harald Welte5258fc42009-03-28 19:07:53 +00003784/* per TRX configuration */
3785DEFUN(cfg_trx,
3786 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003787 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003788 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003789 "Select a TRX to configure")
3790{
3791 int trx_nr = atoi(argv[0]);
3792 struct gsm_bts *bts = vty->index;
3793 struct gsm_bts_trx *trx;
3794
Harald Weltee441d9c2009-06-21 16:17:15 +02003795 if (trx_nr > bts->num_trx) {
3796 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3797 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003798 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003799 } else if (trx_nr == bts->num_trx) {
3800 /* we need to allocate a new one */
3801 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003802 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003803 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003804
Harald Weltee441d9c2009-06-21 16:17:15 +02003805 if (!trx)
3806 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003807
3808 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003809 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003810 vty->node = TRX_NODE;
3811
3812 return CMD_SUCCESS;
3813}
3814
3815DEFUN(cfg_trx_arfcn,
3816 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003817 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003818 "Set the ARFCN for this TRX\n"
3819 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003820{
3821 int arfcn = atoi(argv[0]);
3822 struct gsm_bts_trx *trx = vty->index;
3823
3824 /* FIXME: check if this ARFCN is supported by this TRX */
3825
3826 trx->arfcn = arfcn;
3827
3828 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3829 /* FIXME: use OML layer to update the ARFCN */
3830 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3831
3832 return CMD_SUCCESS;
3833}
3834
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003835DEFUN(cfg_trx_nominal_power,
3836 cfg_trx_nominal_power_cmd,
3837 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003838 "Nominal TRX RF Power in dBm\n"
3839 "Nominal TRX RF Power in dBm\n"
3840 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003841{
3842 struct gsm_bts_trx *trx = vty->index;
3843
3844 trx->nominal_power = atoi(argv[0]);
3845
3846 return CMD_SUCCESS;
3847}
3848
Harald Weltefcd24452009-06-20 18:15:19 +02003849DEFUN(cfg_trx_max_power_red,
3850 cfg_trx_max_power_red_cmd,
3851 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003852 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003853 "Reduction of maximum BS RF Power in dB\n")
3854{
3855 int maxpwr_r = atoi(argv[0]);
3856 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003857 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003858
3859 /* FIXME: check if our BTS type supports more than 12 */
3860 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3861 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3862 maxpwr_r, VTY_NEWLINE);
3863 return CMD_WARNING;
3864 }
3865 if (maxpwr_r & 1) {
3866 vty_out(vty, "%% Power %d dB is not an even value%s",
3867 maxpwr_r, VTY_NEWLINE);
3868 return CMD_WARNING;
3869 }
3870
3871 trx->max_power_red = maxpwr_r;
3872
3873 /* FIXME: make sure we update this using OML */
3874
3875 return CMD_SUCCESS;
3876}
3877
Harald Welte42581822009-08-08 16:12:58 +02003878DEFUN(cfg_trx_rsl_e1,
3879 cfg_trx_rsl_e1_cmd,
3880 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003881 "RSL Parameters\n"
3882 "E1/T1 interface to be used for RSL\n"
3883 "E1/T1 interface to be used for RSL\n"
3884 "E1/T1 Line Number to be used for RSL\n"
3885 "E1/T1 Timeslot to be used for RSL\n"
3886 "E1/T1 Timeslot to be used for RSL\n"
3887 "E1/T1 Sub-slot to be used for RSL\n"
3888 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3889 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3890 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3891 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3892 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003893{
3894 struct gsm_bts_trx *trx = vty->index;
3895
3896 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3897
3898 return CMD_SUCCESS;
3899}
3900
3901DEFUN(cfg_trx_rsl_e1_tei,
3902 cfg_trx_rsl_e1_tei_cmd,
3903 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003904 "RSL Parameters\n"
3905 "Set the TEI to be used for RSL\n"
3906 "Set the TEI to be used for RSL\n"
3907 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003908{
3909 struct gsm_bts_trx *trx = vty->index;
3910
3911 trx->rsl_tei = atoi(argv[0]);
3912
3913 return CMD_SUCCESS;
3914}
3915
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003916DEFUN(cfg_trx_rf_locked,
3917 cfg_trx_rf_locked_cmd,
3918 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003919 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3920 "TRX is NOT RF locked (active)\n"
3921 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003922{
3923 int locked = atoi(argv[0]);
3924 struct gsm_bts_trx *trx = vty->index;
3925
Maxbe356ed2017-09-07 19:10:09 +02003926 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003927 return CMD_SUCCESS;
3928}
Harald Welte42581822009-08-08 16:12:58 +02003929
Harald Welte5258fc42009-03-28 19:07:53 +00003930/* per TS configuration */
3931DEFUN(cfg_ts,
3932 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003933 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003934 "Select a Timeslot to configure\n"
3935 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003936{
3937 int ts_nr = atoi(argv[0]);
3938 struct gsm_bts_trx *trx = vty->index;
3939 struct gsm_bts_trx_ts *ts;
3940
3941 if (ts_nr >= TRX_NR_TS) {
3942 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3943 TRX_NR_TS, VTY_NEWLINE);
3944 return CMD_WARNING;
3945 }
3946
3947 ts = &trx->ts[ts_nr];
3948
3949 vty->index = ts;
3950 vty->node = TS_NODE;
3951
3952 return CMD_SUCCESS;
3953}
3954
Harald Weltea6fd58e2009-08-07 00:25:23 +02003955DEFUN(cfg_ts_pchan,
3956 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003957 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003958 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003959{
3960 struct gsm_bts_trx_ts *ts = vty->index;
3961 int pchanc;
3962
3963 pchanc = gsm_pchan_parse(argv[0]);
3964 if (pchanc < 0)
3965 return CMD_WARNING;
3966
3967 ts->pchan = pchanc;
3968
3969 return CMD_SUCCESS;
3970}
3971
3972/* used for backwards compatibility with old config files that still
3973 * have uppercase pchan type names */
3974DEFUN_HIDDEN(cfg_ts_pchan_compat,
3975 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003976 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003977 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003978{
3979 struct gsm_bts_trx_ts *ts = vty->index;
3980 int pchanc;
3981
3982 pchanc = gsm_pchan_parse(argv[0]);
3983 if (pchanc < 0)
3984 return CMD_WARNING;
3985
3986 ts->pchan = pchanc;
3987
3988 return CMD_SUCCESS;
3989}
3990
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003991
3992
Harald Welte135a6482011-05-30 12:09:13 +02003993DEFUN(cfg_ts_tsc,
3994 cfg_ts_tsc_cmd,
3995 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003996 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003997{
3998 struct gsm_bts_trx_ts *ts = vty->index;
3999
Philipp Maier8c498fc2018-02-21 13:24:36 +01004000 if (!osmo_bts_has_feature(&ts->trx->bts->model->features, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01004001 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
4002 "falling back to BCC%s", VTY_NEWLINE);
4003 ts->tsc = -1;
4004 return CMD_WARNING;
4005 }
4006
Harald Welte135a6482011-05-30 12:09:13 +02004007 ts->tsc = atoi(argv[0]);
4008
4009 return CMD_SUCCESS;
4010}
4011
Harald Weltea39b0f22010-06-14 22:26:10 +02004012#define HOPPING_STR "Configure frequency hopping\n"
4013
4014DEFUN(cfg_ts_hopping,
4015 cfg_ts_hopping_cmd,
4016 "hopping enabled (0|1)",
4017 HOPPING_STR "Enable or disable frequency hopping\n"
4018 "Disable frequency hopping\n" "Enable frequency hopping\n")
4019{
4020 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02004021 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02004022
Philipp Maier8c498fc2018-02-21 13:24:36 +01004023 if (enabled && !osmo_bts_has_feature(&ts->trx->bts->model->features, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02004024 vty_out(vty, "BTS model does not support hopping%s",
4025 VTY_NEWLINE);
4026 return CMD_WARNING;
4027 }
4028
4029 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02004030
4031 return CMD_SUCCESS;
4032}
4033
Harald Welte6e0cd042009-09-12 13:05:33 +02004034DEFUN(cfg_ts_hsn,
4035 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02004036 "hopping sequence-number <0-63>",
4037 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02004038 "Which hopping sequence to use for this channel\n"
4039 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004040{
4041 struct gsm_bts_trx_ts *ts = vty->index;
4042
4043 ts->hopping.hsn = atoi(argv[0]);
4044
4045 return CMD_SUCCESS;
4046}
4047
4048DEFUN(cfg_ts_maio,
4049 cfg_ts_maio_cmd,
4050 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02004051 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02004052 "Which hopping MAIO to use for this channel\n"
4053 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004054{
4055 struct gsm_bts_trx_ts *ts = vty->index;
4056
4057 ts->hopping.maio = atoi(argv[0]);
4058
4059 return CMD_SUCCESS;
4060}
4061
4062DEFUN(cfg_ts_arfcn_add,
4063 cfg_ts_arfcn_add_cmd,
4064 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02004065 HOPPING_STR "Configure hopping ARFCN list\n"
4066 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004067{
4068 struct gsm_bts_trx_ts *ts = vty->index;
4069 int arfcn = atoi(argv[0]);
4070
Harald Weltea39b0f22010-06-14 22:26:10 +02004071 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
4072
Harald Welte6e0cd042009-09-12 13:05:33 +02004073 return CMD_SUCCESS;
4074}
4075
4076DEFUN(cfg_ts_arfcn_del,
4077 cfg_ts_arfcn_del_cmd,
4078 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02004079 HOPPING_STR "Configure hopping ARFCN list\n"
4080 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004081{
4082 struct gsm_bts_trx_ts *ts = vty->index;
4083 int arfcn = atoi(argv[0]);
4084
Harald Weltea39b0f22010-06-14 22:26:10 +02004085 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
4086
Harald Welte6e0cd042009-09-12 13:05:33 +02004087 return CMD_SUCCESS;
4088}
4089
Harald Weltea6fd58e2009-08-07 00:25:23 +02004090DEFUN(cfg_ts_e1_subslot,
4091 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02004092 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02004093 "E1/T1 channel connected to this on-air timeslot\n"
4094 "E1/T1 channel connected to this on-air timeslot\n"
4095 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02004096 "E1/T1 timeslot connected to this on-air timeslot\n"
4097 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02004098 "E1/T1 sub-slot connected to this on-air timeslot\n"
4099 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
4100 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
4101 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
4102 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
4103 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02004104{
4105 struct gsm_bts_trx_ts *ts = vty->index;
4106
Harald Welte42581822009-08-08 16:12:58 +02004107 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004108
4109 return CMD_SUCCESS;
4110}
Harald Welte5258fc42009-03-28 19:07:53 +00004111
Harald Welte4f10c252010-05-16 21:47:13 +02004112void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
4113{
Harald Weltecf9d4312017-12-13 23:17:16 +01004114 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02004115 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01004116 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02004117 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02004118}
4119
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004120DEFUN(drop_bts,
4121 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02004122 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02004123 "Debug/Simulation command to drop Abis/IP BTS\n"
4124 "Debug/Simulation command to drop Abis/IP BTS\n"
4125 "Debug/Simulation command to drop Abis/IP BTS\n"
4126 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004127{
4128 struct gsm_network *gsmnet;
4129 struct gsm_bts_trx *trx;
4130 struct gsm_bts *bts;
4131 unsigned int bts_nr;
4132
4133 gsmnet = gsmnet_from_vty(vty);
4134
4135 bts_nr = atoi(argv[0]);
4136 if (bts_nr >= gsmnet->num_bts) {
4137 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4138 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4139 return CMD_WARNING;
4140 }
4141
4142 bts = gsm_bts_num(gsmnet, bts_nr);
4143 if (!bts) {
4144 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4145 return CMD_WARNING;
4146 }
4147
4148 if (!is_ipaccess_bts(bts)) {
4149 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
4150 return CMD_WARNING;
4151 }
4152
4153
4154 /* close all connections */
4155 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004156 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004157 } else if (strcmp(argv[1], "rsl") == 0) {
4158 /* close all rsl connections */
4159 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004160 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004161 }
4162 } else {
4163 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
4164 return CMD_WARNING;
4165 }
4166
4167 return CMD_SUCCESS;
4168}
4169
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004170DEFUN(restart_bts, restart_bts_cmd,
4171 "restart-bts <0-65535>",
4172 "Restart ip.access nanoBTS through OML\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004173 BTS_NR_STR)
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004174{
4175 struct gsm_network *gsmnet;
4176 struct gsm_bts_trx *trx;
4177 struct gsm_bts *bts;
4178 unsigned int bts_nr;
4179
4180 gsmnet = gsmnet_from_vty(vty);
4181
4182 bts_nr = atoi(argv[0]);
4183 if (bts_nr >= gsmnet->num_bts) {
4184 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4185 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4186 return CMD_WARNING;
4187 }
4188
4189 bts = gsm_bts_num(gsmnet, bts_nr);
4190 if (!bts) {
4191 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4192 return CMD_WARNING;
4193 }
4194
4195 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
4196 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
4197 VTY_NEWLINE);
4198 return CMD_WARNING;
4199 }
4200
4201 /* go from last TRX to c0 */
4202 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4203 abis_nm_ipaccess_restart(trx);
4204
4205 return CMD_SUCCESS;
4206}
4207
Harald Welte8e2e22f2017-07-10 20:25:10 +02004208DEFUN(bts_resend, bts_resend_cmd,
4209 "bts <0-255> resend-system-information",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004210 "BTS Specific Commands\n" BTS_NR_STR
Harald Welte8e2e22f2017-07-10 20:25:10 +02004211 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
4212{
4213 struct gsm_network *gsmnet;
4214 struct gsm_bts_trx *trx;
4215 struct gsm_bts *bts;
4216 unsigned int bts_nr;
4217
4218 gsmnet = gsmnet_from_vty(vty);
4219
4220 bts_nr = atoi(argv[0]);
4221 if (bts_nr >= gsmnet->num_bts) {
4222 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4223 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4224 return CMD_WARNING;
4225 }
4226
4227 bts = gsm_bts_num(gsmnet, bts_nr);
4228 if (!bts) {
4229 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4230 return CMD_WARNING;
4231 }
4232
4233 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4234 gsm_bts_trx_set_system_infos(trx);
4235
4236 return CMD_SUCCESS;
4237}
4238
4239
Harald Welte30f1f372014-12-28 15:00:45 +01004240DEFUN(smscb_cmd, smscb_cmd_cmd,
4241 "bts <0-255> smscb-command <1-4> HEXSTRING",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004242 "BTS related commands\n" BTS_NR_STR
Harald Welte30f1f372014-12-28 15:00:45 +01004243 "SMS Cell Broadcast\n" "Last Valid Block\n"
4244 "Hex Encoded SMSCB message (up to 88 octets)\n")
4245{
4246 struct gsm_bts *bts;
4247 int bts_nr = atoi(argv[0]);
4248 int last_block = atoi(argv[1]);
4249 struct rsl_ie_cb_cmd_type cb_cmd;
4250 uint8_t buf[88];
4251 int rc;
4252
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02004253 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01004254 if (!bts) {
4255 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4256 return CMD_WARNING;
4257 }
4258 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
4259 if (rc < 0 || rc > sizeof(buf)) {
4260 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
4261 return CMD_WARNING;
4262 }
4263
4264 cb_cmd.spare = 0;
4265 cb_cmd.def_bcast = 0;
4266 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
4267
4268 switch (last_block) {
4269 case 1:
4270 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
4271 break;
4272 case 2:
4273 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
4274 break;
4275 case 3:
4276 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
4277 break;
4278 case 4:
4279 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
4280 break;
Vadim Yanitskiy56dec0c2018-03-06 17:18:25 +07004281 default:
4282 vty_out(vty, "Error parsing LASTBLOCK%s", VTY_NEWLINE);
4283 return CMD_WARNING;
Harald Welte30f1f372014-12-28 15:00:45 +01004284 }
4285
4286 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
4287
4288 return CMD_SUCCESS;
4289}
4290
Harald Welte7fe00fb2017-05-27 14:09:50 +02004291/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02004292static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
4293 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02004294{
Harald Welte645eb622017-05-27 15:52:58 +02004295 int bts_nr = atoi(bts_str);
4296 int trx_nr = atoi(trx_str);
4297 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004298 struct gsm_bts *bts;
4299 struct gsm_bts_trx *trx;
4300 struct gsm_bts_trx_ts *ts;
4301
4302 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
4303 if (!bts) {
4304 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4305 return NULL;
4306 }
4307
4308 trx = gsm_bts_trx_num(bts, trx_nr);
4309 if (!trx) {
4310 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
4311 return NULL;
4312 }
4313
4314 ts = &trx->ts[ts_nr];
4315
4316 return ts;
4317}
Harald Welte30f1f372014-12-28 15:00:45 +01004318
Harald Welted0d2b0b2010-12-23 13:18:07 +01004319DEFUN(pdch_act, pdch_act_cmd,
4320 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
Harald Welte0bfd8d92018-02-12 18:06:53 +01004321 BTS_NR_TRX_TS_STR2
4322 "Packet Data Channel\n"
Harald Welted0d2b0b2010-12-23 13:18:07 +01004323 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4324 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4325{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004326 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004327 int activate;
4328
Harald Welte645eb622017-05-27 15:52:58 +02004329 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004330 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004331 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004332
Harald Welte7fe00fb2017-05-27 14:09:50 +02004333 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004334 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4335 VTY_NEWLINE);
4336 return CMD_WARNING;
4337 }
4338
Harald Welted0d2b0b2010-12-23 13:18:07 +01004339 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4340 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004341 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004342 return CMD_WARNING;
4343 }
4344
4345 if (!strcmp(argv[3], "activate"))
4346 activate = 1;
4347 else
4348 activate = 0;
4349
4350 rsl_ipacc_pdch_activate(ts, activate);
4351
4352 return CMD_SUCCESS;
4353
4354}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004355
Harald Welte2abd5e12017-05-27 14:10:40 +02004356/* determine the logical channel type based on the physical channel type */
4357static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4358{
4359 switch (pchan) {
4360 case GSM_PCHAN_TCH_F:
4361 return GSM_LCHAN_TCH_F;
4362 case GSM_PCHAN_TCH_H:
4363 return GSM_LCHAN_TCH_H;
4364 case GSM_PCHAN_SDCCH8_SACCH8C:
4365 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4366 case GSM_PCHAN_CCCH_SDCCH4:
4367 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4368 return GSM_LCHAN_SDCCH;
4369 default:
4370 return -1;
4371 }
4372}
4373
4374/* configure the lchan for a single AMR mode (as specified) */
4375static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4376{
4377 struct amr_multirate_conf mr;
4378 struct gsm48_multi_rate_conf *mr_conf;
4379 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4380
4381 if (amr_mode > 7)
4382 return -1;
4383
4384 memset(&mr, 0, sizeof(mr));
4385 mr_conf->ver = 1;
4386 /* bit-mask of supported modes, only one bit is set. Reflects
4387 * Figure 10.5.2.47a where there are no thershold and only a
4388 * single mode */
4389 mr.gsm48_ie[1] = 1 << amr_mode;
4390
4391 mr.ms_mode[0].mode = amr_mode;
4392 mr.bts_mode[0].mode = amr_mode;
4393
4394 /* encode this configuration into the lchan for both uplink and
4395 * downlink direction */
4396 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4397 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4398
4399 return 0;
4400}
4401
4402/* Debug/Measurement command to activate a given logical channel
4403 * manually in a given mode/codec. This is useful for receiver
4404 * performance testing (FER/RBER/...) */
4405DEFUN(lchan_act, lchan_act_cmd,
4406 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
Harald Welte0bfd8d92018-02-12 18:06:53 +01004407 BTS_NR_TRX_TS_SS_STR2
Harald Welte2abd5e12017-05-27 14:10:40 +02004408 "Manual Channel Activation (e.g. for BER test)\n"
4409 "Manual Channel Deactivation (e.g. for BER test)\n"
4410 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4411{
4412 struct gsm_bts_trx_ts *ts;
4413 struct gsm_lchan *lchan;
4414 int ss_nr = atoi(argv[3]);
4415 const char *act_str = argv[4];
4416 const char *codec_str = argv[5];
4417 int activate;
4418
4419 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4420 if (!ts)
4421 return CMD_WARNING;
4422
4423 lchan = &ts->lchan[ss_nr];
4424
4425 if (!strcmp(act_str, "activate"))
4426 activate = 1;
4427 else
4428 activate = 0;
4429
4430 if (ss_nr >= ts_subslots(ts)) {
4431 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4432 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4433 return CMD_WARNING;
4434 }
4435
4436 if (activate) {
4437 int lchan_t;
4438 if (lchan->state != LCHAN_S_NONE) {
4439 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4440 return CMD_WARNING;
4441 }
4442 lchan_t = lchan_type_by_pchan(ts->pchan);
4443 if (lchan_t < 0)
4444 return CMD_WARNING;
4445 /* configure the lchan */
4446 lchan->type = lchan_t;
4447 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4448 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4449 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4450 else if (!strcmp(codec_str, "efr"))
4451 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4452 else if (!strcmp(codec_str, "amr")) {
4453 int amr_mode;
4454 if (argc < 7) {
4455 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4456 return CMD_WARNING;
4457 }
4458 amr_mode = atoi(argv[6]);
4459 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4460 lchan_set_single_amr_mode(lchan, amr_mode);
4461 }
4462 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4463 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4464 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004465 } else {
4466 rsl_direct_rf_release(lchan);
4467 }
4468
4469 return CMD_SUCCESS;
4470}
4471
Harald Welte3f86c522017-05-27 15:53:28 +02004472DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4473 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
Harald Welte0bfd8d92018-02-12 18:06:53 +01004474 BTS_NR_TRX_TS_SS_STR2
Harald Welte3f86c522017-05-27 15:53:28 +02004475 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4476{
4477 struct gsm_bts_trx_ts *ts;
4478 struct gsm_lchan *lchan;
4479 int ss_nr = atoi(argv[3]);
4480 int port = atoi(argv[5]);
4481 struct in_addr ia;
4482 inet_aton(argv[4], &ia);
4483
4484 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4485 if (!ts)
4486 return CMD_WARNING;
4487
4488 lchan = &ts->lchan[ss_nr];
4489
4490 if (ss_nr >= ts_subslots(ts)) {
4491 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4492 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4493 return CMD_WARNING;
4494 }
4495
4496 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4497 inet_ntoa(ia), port, VTY_NEWLINE);
4498 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4499 return CMD_SUCCESS;
4500}
Harald Welteb71147a2017-07-18 19:11:49 +02004501
4502DEFUN(ctrl_trap, ctrl_trap_cmd,
4503 "ctrl-interface generate-trap TRAP VALUE",
4504 "Commands related to the CTRL Interface\n"
4505 "Generate a TRAP for test purpose\n"
4506 "Identity/Name of the TRAP variable\n"
4507 "Value of the TRAP variable\n")
4508{
4509 struct gsm_network *net = gsmnet_from_vty(vty);
4510
4511 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4512 return CMD_SUCCESS;
4513}
4514
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004515#define NETWORK_STR "Configure the GSM network\n"
4516#define CODE_CMD_STR "Code commands\n"
4517#define NAME_CMD_STR "Name Commands\n"
4518#define NAME_STR "Name to use\n"
4519
4520DEFUN(cfg_net,
4521 cfg_net_cmd,
4522 "network", NETWORK_STR)
4523{
4524 vty->index = gsmnet_from_vty(vty);
4525 vty->node = GSMNET_NODE;
4526
4527 return CMD_SUCCESS;
4528}
4529
4530DEFUN(cfg_net_ncc,
4531 cfg_net_ncc_cmd,
4532 "network country code <1-999>",
4533 "Set the GSM network country code\n"
4534 "Country commands\n"
4535 CODE_CMD_STR
4536 "Network Country Code to use\n")
4537{
4538 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004539 uint16_t mcc;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004540
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004541 if (osmo_mcc_from_str(argv[0], &mcc)) {
4542 vty_out(vty, "%% Error decoding MCC: %s%s", argv[0], VTY_NEWLINE);
4543 return CMD_WARNING;
4544 }
4545
4546 gsmnet->plmn.mcc = mcc;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004547
4548 return CMD_SUCCESS;
4549}
4550
4551DEFUN(cfg_net_mnc,
4552 cfg_net_mnc_cmd,
4553 "mobile network code <0-999>",
4554 "Set the GSM mobile network code\n"
4555 "Network Commands\n"
4556 CODE_CMD_STR
4557 "Mobile Network Code to use\n")
4558{
4559 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004560 uint16_t mnc;
4561 bool mnc_3_digits;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004562
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004563 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
4564 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
4565 return CMD_WARNING;
4566 }
4567
4568 gsmnet->plmn.mnc = mnc;
4569 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004570
4571 return CMD_SUCCESS;
4572}
4573
4574DEFUN(cfg_net_encryption,
4575 cfg_net_encryption_cmd,
Harald Welte51e4bf32017-12-23 17:30:18 +01004576 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
4577 "Encryption options\n"
4578 "GSM A5 Air Interface Encryption\n"
4579 "A5/n Algorithm Number\n"
4580 "A5/n Algorithm Number\n"
4581 "A5/n Algorithm Number\n"
4582 "A5/n Algorithm Number\n")
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004583{
4584 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte51e4bf32017-12-23 17:30:18 +01004585 unsigned int i;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004586
Harald Welte51e4bf32017-12-23 17:30:18 +01004587 gsmnet->a5_encryption_mask = 0;
4588 for (i = 0; i < argc; i++)
4589 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004590
4591 return CMD_SUCCESS;
4592}
4593
4594DEFUN(cfg_net_dyn_ts_allow_tch_f,
4595 cfg_net_dyn_ts_allow_tch_f_cmd,
4596 "dyn_ts_allow_tch_f (0|1)",
4597 "Allow or disallow allocating TCH/F on TCH_F_TCH_H_PDCH timeslots\n"
4598 "Disallow TCH/F on TCH_F_TCH_H_PDCH (default)\n"
4599 "Allow TCH/F on TCH_F_TCH_H_PDCH\n")
4600{
4601 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4602 gsmnet->dyn_ts_allow_tch_f = atoi(argv[0]) ? true : false;
4603 return CMD_SUCCESS;
4604}
4605
4606DEFUN(cfg_net_timezone,
4607 cfg_net_timezone_cmd,
4608 "timezone <-19-19> (0|15|30|45)",
4609 "Set the Timezone Offset of the network\n"
4610 "Timezone offset (hours)\n"
4611 "Timezone offset (00 minutes)\n"
4612 "Timezone offset (15 minutes)\n"
4613 "Timezone offset (30 minutes)\n"
4614 "Timezone offset (45 minutes)\n"
4615 )
4616{
4617 struct gsm_network *net = vty->index;
4618 int tzhr = atoi(argv[0]);
4619 int tzmn = atoi(argv[1]);
4620
4621 net->tz.hr = tzhr;
4622 net->tz.mn = tzmn;
4623 net->tz.dst = 0;
4624 net->tz.override = 1;
4625
4626 return CMD_SUCCESS;
4627}
4628
4629DEFUN(cfg_net_timezone_dst,
4630 cfg_net_timezone_dst_cmd,
4631 "timezone <-19-19> (0|15|30|45) <0-2>",
4632 "Set the Timezone Offset of the network\n"
4633 "Timezone offset (hours)\n"
4634 "Timezone offset (00 minutes)\n"
4635 "Timezone offset (15 minutes)\n"
4636 "Timezone offset (30 minutes)\n"
4637 "Timezone offset (45 minutes)\n"
4638 "DST offset (hours)\n"
4639 )
4640{
4641 struct gsm_network *net = vty->index;
4642 int tzhr = atoi(argv[0]);
4643 int tzmn = atoi(argv[1]);
4644 int tzdst = atoi(argv[2]);
4645
4646 net->tz.hr = tzhr;
4647 net->tz.mn = tzmn;
4648 net->tz.dst = tzdst;
4649 net->tz.override = 1;
4650
4651 return CMD_SUCCESS;
4652}
4653
4654DEFUN(cfg_net_no_timezone,
4655 cfg_net_no_timezone_cmd,
4656 "no timezone",
4657 NO_STR
4658 "Disable network timezone override, use system tz\n")
4659{
4660 struct gsm_network *net = vty->index;
4661
4662 net->tz.override = 0;
4663
4664 return CMD_SUCCESS;
4665}
4666
4667DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
4668 "periodic location update <6-1530>",
4669 "Periodic Location Updating Interval\n"
4670 "Periodic Location Updating Interval\n"
4671 "Periodic Location Updating Interval\n"
4672 "Periodic Location Updating Interval in Minutes\n")
4673{
4674 struct gsm_network *net = vty->index;
4675
4676 net->t3212 = atoi(argv[0]) / 6;
4677
4678 return CMD_SUCCESS;
4679}
4680
4681DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
4682 "no periodic location update",
4683 NO_STR
4684 "Periodic Location Updating Interval\n"
4685 "Periodic Location Updating Interval\n"
4686 "Periodic Location Updating Interval\n")
4687{
4688 struct gsm_network *net = vty->index;
4689
4690 net->t3212 = 0;
4691
4692 return CMD_SUCCESS;
4693}
4694
Harald Weltedcccb182010-05-16 20:52:23 +02004695extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004696
Maxdb0e3802017-01-12 19:35:11 +01004697int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004698{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004699 cfg_ts_pchan_cmd.string =
4700 vty_cmd_string_from_valstr(tall_bsc_ctx,
4701 gsm_pchant_names,
4702 "phys_chan_config (", "|", ")",
4703 VTY_DO_LOWER);
4704 cfg_ts_pchan_cmd.doc =
4705 vty_cmd_string_from_valstr(tall_bsc_ctx,
4706 gsm_pchant_descs,
4707 "Physical Channel Combination\n",
4708 "\n", "", 0);
4709
Harald Weltee555c2b2012-08-17 13:02:12 +02004710 cfg_bts_type_cmd.string =
4711 vty_cmd_string_from_valstr(tall_bsc_ctx,
4712 bts_type_names,
4713 "type (", "|", ")",
4714 VTY_DO_LOWER);
4715 cfg_bts_type_cmd.doc =
4716 vty_cmd_string_from_valstr(tall_bsc_ctx,
4717 bts_type_descs,
4718 "BTS Vendor/Type\n",
4719 "\n", "", 0);
4720
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004721 OSMO_ASSERT(vty_global_gsm_network == NULL);
4722 vty_global_gsm_network = network;
4723
4724 osmo_stats_vty_add_cmds();
4725
4726 install_element(CONFIG_NODE, &cfg_net_cmd);
4727 install_node(&net_node, config_write_net);
4728 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
4729 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
4730 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
4731 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
4732 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
4733 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
4734 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
4735 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
4736 install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);
Harald Weltee555c2b2012-08-17 13:02:12 +02004737
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004738 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004739 install_element_ve(&show_bts_cmd);
4740 install_element_ve(&show_trx_cmd);
4741 install_element_ve(&show_ts_cmd);
4742 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004743 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004744
Philipp Maier39f62bb2017-04-09 12:32:51 +02004745 install_element_ve(&show_subscr_conn_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004746 install_element_ve(&handover_any_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004747 install_element_ve(&assignment_any_cmd);
Philipp Maier39f62bb2017-04-09 12:32:51 +02004748
Harald Welteb4d5b172010-05-12 16:10:35 +00004749 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004750 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004751
Maxdb0e3802017-01-12 19:35:11 +01004752 logging_vty_add_cmds(NULL);
Harald Welte2f4f4b82018-02-14 00:50:27 +01004753 osmo_talloc_vty_add_cmds();
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004754
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004755 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004756 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004757 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4758 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4759 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4760 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4761 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4762 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4763 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4764 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4765 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004766 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004767 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004768 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004769 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004770 /* See also handover commands added on net level from handover_vty.c */
Harald Welte5013b2a2009-08-07 13:29:14 +02004771
4772 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004773 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004774 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004775 install_element(BTS_NODE, &cfg_description_cmd);
4776 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004777 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004778 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004779 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4780 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4781 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4782 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004783 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4784 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004785 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004786 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004787 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004788 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004789 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004790 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004791 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004792 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4793 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004794 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004795 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4796 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004797 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4798 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4799 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004800 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4801 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004802 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004803 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004804 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004805 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004806 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4807 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004808 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4809 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4810 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4811 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4812 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4813 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004814 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004815 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004816 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304817 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004818 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004819 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004820 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004821 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4822 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004823 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004824 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004825 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004826 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004827 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4828 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4829 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004830 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004831 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4832 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004833 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004834 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004835 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4836 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004837 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004838 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4839 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004840 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4841 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004842 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4843 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004844 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4845 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004846 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4847 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4848 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4849 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4850 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004851 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4852 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004853 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4854 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4855 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4856 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4857 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4858 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4859 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4860 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4861 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4862 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4863 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4864 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4865 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4866 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4867 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4868 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4869 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4870 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4871 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4872 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4873 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4874 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004875 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Stefan Sperling6442e432018-02-06 14:44:54 +01004876 install_element(BTS_NODE, &cfg_bts_acc_ramping_cmd);
4877 install_element(BTS_NODE, &cfg_bts_no_acc_ramping_cmd);
4878 install_element(BTS_NODE, &cfg_bts_acc_ramping_step_interval_cmd);
4879 install_element(BTS_NODE, &cfg_bts_acc_ramping_step_size_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004880 /* See also handover commands added on bts level from handover_vty.c */
Harald Welte68628e82009-03-10 12:17:57 +00004881
Harald Welte5258fc42009-03-28 19:07:53 +00004882 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004883 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004884 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004885 install_element(TRX_NODE, &cfg_description_cmd);
4886 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004887 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004888 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004889 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4890 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004891 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004892
Harald Welte5258fc42009-03-28 19:07:53 +00004893 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004894 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004895 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004896 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004897 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004898 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004899 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4900 install_element(TS_NODE, &cfg_ts_maio_cmd);
4901 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4902 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004903 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004904
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004905 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004906 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004907 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004908 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004909 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004910 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welteb22dcb82018-02-12 17:57:57 +01004911 install_element(ENABLE_NODE, &handover_subscr_conn_cmd);
4912 install_element(ENABLE_NODE, &assignment_subscr_conn_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004913 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004914 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004915
Harald Welte81c9b9c2010-05-31 16:40:40 +02004916 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004917 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004918 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004919 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004920
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004921 ho_vty_init();
4922
Harald Weltedcccb182010-05-16 20:52:23 +02004923 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004924
Harald Welte68628e82009-03-10 12:17:57 +00004925 return 0;
4926}