blob: ea4c8d04619ee4c8e5a8a811d0fe4fca33597258 [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 Hofmeyrf28f1ef2018-04-20 15:53:53 +020064#include <osmocom/bsc/meas_feed.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020065
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010066#include <inttypes.h>
67
Harald Weltec08e8be2011-03-04 13:53:51 +010068#include "../../bscconfig.h"
Harald Welte1353f962010-05-16 19:20:24 +020069
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010070#define BTS_NR_STR "BTS Number\n"
71#define TRX_NR_STR "TRX Number\n"
72#define TS_NR_STR "Timeslot Number\n"
Harald Welte0bfd8d92018-02-12 18:06:53 +010073#define SS_NR_STR "Sub-slot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020074#define LCHAN_NR_STR "Logical Channel Number\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010075#define BTS_TRX_STR BTS_NR_STR TRX_NR_STR
76#define BTS_TRX_TS_STR BTS_TRX_STR TS_NR_STR
77#define BTS_TRX_TS_LCHAN_STR BTS_TRX_TS_STR LCHAN_NR_STR
Harald Welte0bfd8d92018-02-12 18:06:53 +010078#define BTS_NR_TRX_TS_STR2 \
79 "BTS for manual command\n" BTS_NR_STR \
80 "TRX for manual command\n" TRX_NR_STR \
81 "Timeslot for manual command\n" TS_NR_STR
82#define BTS_NR_TRX_TS_SS_STR2 \
83 BTS_NR_TRX_TS_STR2 \
84 "Sub-slot for manual command\n" SS_NR_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020085
Harald Welteea4647d2010-05-12 17:19:53 +000086/* FIXME: this should go to some common file */
87static const struct value_string gprs_ns_timer_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020088 { 0, "tns-block" },
89 { 1, "tns-block-retries" },
90 { 2, "tns-reset" },
91 { 3, "tns-reset-retries" },
92 { 4, "tns-test" },
93 { 5, "tns-alive" },
94 { 6, "tns-alive-retries" },
95 { 0, NULL }
96};
97
Harald Welteea4647d2010-05-12 17:19:53 +000098static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020099 { 0, "blocking-timer" },
100 { 1, "blocking-retries" },
101 { 2, "unblocking-retries" },
102 { 3, "reset-timer" },
103 { 4, "reset-retries" },
104 { 5, "suspend-timer" },
105 { 6, "suspend-retries" },
106 { 7, "resume-timer" },
107 { 8, "resume-retries" },
108 { 9, "capability-update-timer" },
109 { 10, "capability-update-retries" },
110 { 0, NULL }
111};
112
Harald Welte64c07d22011-02-15 11:43:27 +0100113static const struct value_string bts_neigh_mode_strs[] = {
114 { NL_MODE_AUTOMATIC, "automatic" },
115 { NL_MODE_MANUAL, "manual" },
116 { NL_MODE_MANUAL_SI5SEP, "manual-si5" },
117 { 0, NULL }
118};
119
Daniel Willmann7d109832012-05-14 18:43:23 +0200120const struct value_string bts_loc_fix_names[] = {
121 { BTS_LOC_FIX_INVALID, "invalid" },
122 { BTS_LOC_FIX_2D, "fix2d" },
123 { BTS_LOC_FIX_3D, "fix3d" },
124 { 0, NULL }
125};
126
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100127struct cmd_node net_node = {
128 GSMNET_NODE,
129 "%s(config-net)# ",
130 1,
131};
132
Harald Welte68628e82009-03-10 12:17:57 +0000133struct cmd_node bts_node = {
134 BTS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200135 "%s(config-net-bts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000136 1,
137};
138
139struct cmd_node trx_node = {
140 TRX_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200141 "%s(config-net-bts-trx)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000142 1,
143};
144
145struct cmd_node ts_node = {
146 TS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200147 "%s(config-net-bts-trx-ts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000148 1,
149};
150
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100151static struct gsm_network *vty_global_gsm_network = NULL;
152
153struct gsm_network *gsmnet_from_vty(struct vty *v)
154{
155 /* It can't hurt to force callers to continue to pass the vty instance
156 * to this function, in case we'd like to retrieve the global
157 * gsm_network instance from the vty at some point in the future. But
158 * until then, just return the global pointer, which should have been
159 * initialized by common_cs_vty_init().
160 */
161 OSMO_ASSERT(vty_global_gsm_network);
162 return vty_global_gsm_network;
163}
164
Harald Welte68628e82009-03-10 12:17:57 +0000165static int dummy_config_write(struct vty *v)
166{
167 return CMD_SUCCESS;
168}
169
170static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
171{
Harald Welte1304b352013-03-15 16:57:33 +0100172 vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
173 abis_nm_opstate_name(nms->operational),
174 get_value_string(abis_nm_adm_state_names, nms->administrative),
Harald Welte867d9f32011-05-23 20:30:39 +0200175 abis_nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000176}
177
Harald Welteb908cb72009-12-22 13:09:29 +0100178static void dump_pchan_load_vty(struct vty *vty, char *prefix,
179 const struct pchan_load *pl)
180{
181 int i;
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100182 int dumped = 0;
Harald Welteb908cb72009-12-22 13:09:29 +0100183
184 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
185 const struct load_counter *lc = &pl->pchan[i];
186 unsigned int percent;
187
188 if (lc->total == 0)
189 continue;
190
191 percent = (lc->used * 100) / lc->total;
192
193 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
194 gsm_pchan_name(i), percent, lc->used, lc->total,
195 VTY_NEWLINE);
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100196 dumped ++;
Harald Welteb908cb72009-12-22 13:09:29 +0100197 }
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100198 if (!dumped)
199 vty_out(vty, "%s(none)%s", prefix, VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100200}
201
Harald Welte68628e82009-03-10 12:17:57 +0000202static void net_dump_vty(struct vty *vty, struct gsm_network *net)
203{
Harald Welteb908cb72009-12-22 13:09:29 +0100204 struct pchan_load pl;
Harald Welte51e4bf32017-12-23 17:30:18 +0100205 int i;
Harald Welteb908cb72009-12-22 13:09:29 +0100206
Neels Hofmeyrf93970b2018-03-05 02:09:40 +0100207 vty_out(vty, "BSC is on MCC-MNC %s and has %u BTS%s",
208 osmo_plmn_name(&net->plmn), net->num_bts, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200209 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte51e4bf32017-12-23 17:30:18 +0100210 vty_out(vty, " Encryption:");
211 for (i = 0; i < 8; i++) {
212 if (net->a5_encryption_mask & (1 << i))
213 vty_out(vty, " A5/%u", i);
214 }
215 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100216 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
217 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800218 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
219 VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100220
221 {
222 struct gsm_bts *bts;
223 unsigned int ho_active_count = 0;
224 unsigned int ho_inactive_count = 0;
225
226 llist_for_each_entry(bts, &net->bts_list, list) {
227 if (ho_get_ho_active(bts->ho))
228 ho_active_count ++;
229 else
230 ho_inactive_count ++;
231 }
232
233 if (ho_active_count && ho_inactive_count)
234 vty_out(vty, " Handover: On at %u BTS, Off at %u BTS%s",
235 ho_active_count, ho_inactive_count, VTY_NEWLINE);
236 else
237 vty_out(vty, " Handover: %s%s", ho_active_count ? "On" : "Off",
238 VTY_NEWLINE);
239 }
240
Harald Welteb908cb72009-12-22 13:09:29 +0100241 network_chan_load(&pl, net);
242 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
243 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100244
245 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100246 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100247 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200248 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100249 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100250 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200251 vty_out(vty, " Last RF Lock Command: %s%s",
252 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
253 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000254}
255
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200256DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000257 SHOW_STR "Display information about a GSM NETWORK\n")
258{
Harald Weltedcccb182010-05-16 20:52:23 +0200259 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000260 net_dump_vty(vty, net);
261
262 return CMD_SUCCESS;
263}
264
265static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
266{
Harald Welteedb37782009-05-01 14:59:07 +0000267 struct e1inp_line *line;
268
269 if (!e1l) {
270 vty_out(vty, " None%s", VTY_NEWLINE);
271 return;
272 }
273
274 line = e1l->ts->line;
275
276 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
277 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000278 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000279 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000280 e1l->tei, e1l->sapi, VTY_NEWLINE);
281}
282
Neels Hofmeyrc1db52f2018-01-19 00:59:33 +0100283static void vty_out_neigh_list(struct vty *vty, struct bitvec *bv)
284{
285 int count = 0;
286 int i;
287 for (i = 0; i < 1024; i++) {
288 if (!bitvec_get_bit_pos(bv, i))
289 continue;
290 vty_out(vty, " %u", i);
291 count ++;
292 }
293 if (!count)
294 vty_out(vty, " (none)");
295 else
296 vty_out(vty, " (%d)", count);
297}
298
Philipp Maierf27dbc52018-02-21 13:25:57 +0100299static void bts_dump_vty_features(struct vty *vty, struct gsm_bts *bts)
300{
301 unsigned int i;
302 bool no_features = true;
303 vty_out(vty, " Features:%s", VTY_NEWLINE);
304
305 for (i = 0; i < _NUM_BTS_FEAT; i++) {
306 if (osmo_bts_has_feature(&bts->features, i)) {
307 vty_out(vty, " %03u ", i);
308 vty_out(vty, "%-40s%s", osmo_bts_feature_name(i), VTY_NEWLINE);
309 no_features = false;
310 }
311 }
312
313 if (no_features)
314 vty_out(vty, " (not available)%s", VTY_NEWLINE);
315}
316
Harald Welte68628e82009-03-10 12:17:57 +0000317static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
318{
Harald Welteb908cb72009-12-22 13:09:29 +0100319 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200320 unsigned long long sec;
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100321 struct gsm_bts_trx *trx;
322 int ts_hopping_total;
323 int ts_non_hopping_total;
Harald Welteb908cb72009-12-22 13:09:29 +0100324
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200325 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100326 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200327 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200328 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100329 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100330 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200331 bts->num_trx, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100332 vty_out(vty, " Description: %s%s",
Harald Welte197dea92010-05-14 17:59:53 +0200333 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100334
335 vty_out(vty, " ARFCNs:");
336 ts_hopping_total = 0;
337 ts_non_hopping_total = 0;
338 llist_for_each_entry(trx, &bts->trx_list, list) {
339 int ts_nr;
340 int ts_hopping = 0;
341 int ts_non_hopping = 0;
342 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
343 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
344 if (ts->hopping.enabled)
345 ts_hopping++;
346 else
347 ts_non_hopping++;
348 }
349
350 if (ts_non_hopping)
351 vty_out(vty, " %u", trx->arfcn);
352 ts_hopping_total += ts_hopping;
353 ts_non_hopping_total += ts_non_hopping;
354 }
355 if (ts_hopping_total) {
356 if (ts_non_hopping_total)
357 vty_out(vty, " / Hopping on %d of %d timeslots",
358 ts_hopping_total, ts_hopping_total + ts_non_hopping_total);
359 else
360 vty_out(vty, " Hopping on all %d timeslots", ts_hopping_total);
361 }
362 vty_out(vty, "%s", VTY_NEWLINE);
363
Maxf9685c12017-03-23 12:01:07 +0100364 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100365 vty_out(vty, " PCU version %s connected%s", bts->pcu_version,
Maxf9685c12017-03-23 12:01:07 +0100366 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100367 vty_out(vty, " MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
368 vty_out(vty, " Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100369 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
370 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100371 vty_out(vty, " Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100372 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Stefan Sperling6442e432018-02-06 14:44:54 +0100373 vty_out(vty, " Access Control Class ramping: %senabled%s",
374 acc_ramp_is_enabled(&bts->acc_ramp) ? "" : "not ", VTY_NEWLINE);
375 if (acc_ramp_is_enabled(&bts->acc_ramp)) {
376 if (!acc_ramp_step_interval_is_dynamic(&bts->acc_ramp))
377 vty_out(vty, " Access Control Class ramping step interval: %u seconds%s",
378 acc_ramp_get_step_interval(&bts->acc_ramp), VTY_NEWLINE);
379 else
380 vty_out(vty, " Access Control Class ramping step interval: dynamic%s", VTY_NEWLINE);
381 vty_out(vty, " enabling %u Access Control Class%s per ramping step%s",
382 acc_ramp_get_step_size(&bts->acc_ramp),
383 acc_ramp_get_step_size(&bts->acc_ramp) > 1 ? "es" : "", VTY_NEWLINE);
384 }
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100385 vty_out(vty, " RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100386 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100387 vty_out(vty, " RACH Max transmissions: %u%s",
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100388 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
389 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100390 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200391 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200392 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100393 vty_out(vty, " Uplink DTX: %s%s",
Maxc08ee712016-05-11 12:45:13 +0200394 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
395 "enabled" : "forced", VTY_NEWLINE);
396 else
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100397 vty_out(vty, " Uplink DTX: not enabled%s", VTY_NEWLINE);
398 vty_out(vty, " Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
Maxc08ee712016-05-11 12:45:13 +0200399 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100400 vty_out(vty, " Channel Description Attachment: %s%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200401 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100402 vty_out(vty, " Channel Description BS-PA-MFRMS: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200403 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100404 vty_out(vty, " Channel Description BS-AG_BLKS-RES: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200405 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100406 vty_out(vty, " System Information present: 0x%08x, static: 0x%08x%s",
Harald Welte9fbff4a2010-07-30 11:50:09 +0200407 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100408 vty_out(vty, " Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100409 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100410 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
411 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
412 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100413 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200414 if (bts->pcu_sock_path)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100415 vty_out(vty, " PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000416 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200417 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000418 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200419 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200420 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
421 vty_out(vty, " Skip Reset: %d%s",
422 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000423 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200424 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000425 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200426 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200427 vty_out(vty, " GPRS NSE: ");
428 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
429 vty_out(vty, " GPRS CELL: ");
430 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
431 vty_out(vty, " GPRS NSVC0: ");
432 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
433 vty_out(vty, " GPRS NSVC1: ");
434 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200435 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
436 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000437 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100438 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200439 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200440 sec = bts_uptime(bts);
441 if (sec)
Maxff3fad12018-01-07 16:50:42 +0100442 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.",
443 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60);
444 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100445 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200446 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
447 e1isl_dump_vty(vty, bts->oml_link);
448 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100449
Neels Hofmeyrc1db52f2018-01-19 00:59:33 +0100450 vty_out(vty, " Neighbor Cells: ");
451 switch (bts->neigh_list_manual_mode) {
452 default:
453 case NL_MODE_AUTOMATIC:
454 vty_out(vty, "Automatic");
455 /* generate_bcch_chan_list() should populate si_common.neigh_list */
456 break;
457 case NL_MODE_MANUAL:
458 vty_out(vty, "Manual");
459 break;
460 case NL_MODE_MANUAL_SI5SEP:
461 vty_out(vty, "Manual/separate SI5");
462 break;
463 }
464 vty_out(vty, ", ARFCNs:");
465 vty_out_neigh_list(vty, &bts->si_common.neigh_list);
466 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
467 vty_out(vty, " SI5:");
468 vty_out_neigh_list(vty, &bts->si_common.si5_neigh_list);
469 }
470 vty_out(vty, "%s", VTY_NEWLINE);
471
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100472 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100473 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200474 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100475 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
476 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100477
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100478 vty_out(vty, " Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
Harald Welted82101e2017-12-09 23:07:38 +0100479 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
480 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
481 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100482 vty_out(vty, " Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
Harald Welted82101e2017-12-09 23:07:38 +0100483 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
484 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
485 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100486 vty_out(vty, " BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
Harald Welted82101e2017-12-09 23:07:38 +0100487 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
488 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
489 VTY_NEWLINE);
Philipp Maierf27dbc52018-02-21 13:25:57 +0100490
491 bts_dump_vty_features(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +0000492}
493
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100494DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000495 SHOW_STR "Display information about a BTS\n"
496 "BTS number")
497{
Harald Weltedcccb182010-05-16 20:52:23 +0200498 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000499 int bts_nr;
500
501 if (argc != 0) {
502 /* use the BTS number that the user has specified */
503 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100504 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000505 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000506 VTY_NEWLINE);
507 return CMD_WARNING;
508 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200509 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000510 return CMD_SUCCESS;
511 }
512 /* print all BTS's */
513 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200514 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000515
516 return CMD_SUCCESS;
517}
518
Harald Welte42581822009-08-08 16:12:58 +0200519/* utility functions */
520static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
521 const char *ts, const char *ss)
522{
523 e1_link->e1_nr = atoi(line);
524 e1_link->e1_ts = atoi(ts);
525 if (!strcmp(ss, "full"))
526 e1_link->e1_ts_ss = 255;
527 else
528 e1_link->e1_ts_ss = atoi(ss);
529}
530
531static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
532 const char *prefix)
533{
534 if (!e1_link->e1_ts)
535 return;
536
537 if (e1_link->e1_ts_ss == 255)
538 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
539 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
540 else
541 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
542 prefix, e1_link->e1_nr, e1_link->e1_ts,
543 e1_link->e1_ts_ss, VTY_NEWLINE);
544}
545
546
Harald Welte67ce0732009-08-06 19:06:46 +0200547static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
548{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100549 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100550 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100551 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200552 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100553 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200554 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100555 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200556 ts->hopping.enabled, VTY_NEWLINE);
557 if (ts->hopping.enabled) {
558 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100559 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200560 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100561 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200562 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200563 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
564 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
565 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100566 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200567 i, VTY_NEWLINE);
568 }
Harald Welte127af342010-12-24 12:07:07 +0100569 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100570 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100571
572 if (ts->trx->bts->model->config_write_ts)
573 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200574}
575
576static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
577{
578 int i;
579
Harald Welte5013b2a2009-08-07 13:29:14 +0200580 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200581 if (trx->description)
582 vty_out(vty, " description %s%s", trx->description,
583 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200584 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200585 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200586 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200587 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100588 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200589 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200590 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
591 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200592
Harald Welteface7ed2011-02-14 16:15:21 +0100593 if (trx->bts->model->config_write_trx)
594 trx->bts->model->config_write_trx(vty, trx);
595
Harald Welte67ce0732009-08-06 19:06:46 +0200596 for (i = 0; i < TRX_NR_TS; i++)
597 config_write_ts_single(vty, &trx->ts[i]);
598}
599
Harald Welte615e9562010-05-11 23:50:21 +0200600static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
601{
602 unsigned int i;
603 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
604 VTY_NEWLINE);
605 if (bts->gprs.mode == BTS_GPRS_NONE)
606 return;
607
bhargava350533c2016-07-21 11:14:34 +0530608 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
609 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
610
Harald Welte615e9562010-05-11 23:50:21 +0200611 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
612 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100613 vty_out(vty, " gprs network-control-order nc%u%s",
614 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200615 if (!bts->gprs.ctrl_ack_type_use_block)
616 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200617 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
618 VTY_NEWLINE);
619 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
620 vty_out(vty, " gprs cell timer %s %u%s",
621 get_value_string(gprs_bssgp_cfg_strs, i),
622 bts->gprs.cell.timer[i], VTY_NEWLINE);
623 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
624 VTY_NEWLINE);
625 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
626 vty_out(vty, " gprs ns timer %s %u%s",
627 get_value_string(gprs_ns_timer_strs, i),
628 bts->gprs.nse.timer[i], VTY_NEWLINE);
629 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
630 struct gsm_bts_gprs_nsvc *nsvc =
631 &bts->gprs.nsvc[i];
632 struct in_addr ia;
633
634 ia.s_addr = htonl(nsvc->remote_ip);
635 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
636 nsvc->nsvci, VTY_NEWLINE);
637 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
638 nsvc->local_port, VTY_NEWLINE);
639 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
640 nsvc->remote_port, VTY_NEWLINE);
641 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
642 inet_ntoa(ia), VTY_NEWLINE);
643 }
644}
645
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200646/* Write the model data if there is one */
647static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200648{
649 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200650
651 if (!bts->model)
652 return;
653
654 if (bts->model->config_write_bts)
655 bts->model->config_write_bts(vty, bts);
656
657 llist_for_each_entry(trx, &bts->trx_list, list)
658 config_write_trx_single(vty, trx);
659}
660
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200661static void write_amr_modes(struct vty *vty, const char *prefix,
662 const char *name, struct amr_mode *modes, int num)
663{
664 int i;
665
666 vty_out(vty, " %s threshold %s", prefix, name);
667 for (i = 0; i < num - 1; i++)
668 vty_out(vty, " %d", modes[i].threshold);
669 vty_out(vty, "%s", VTY_NEWLINE);
670 vty_out(vty, " %s hysteresis %s", prefix, name);
671 for (i = 0; i < num - 1; i++)
672 vty_out(vty, " %d", modes[i].hysteresis);
673 vty_out(vty, "%s", VTY_NEWLINE);
674}
675
Andreas Eversberg73266522014-01-19 11:47:44 +0100676static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
677 struct amr_multirate_conf *mr, int full)
678{
679 struct gsm48_multi_rate_conf *mr_conf;
680 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
681 int i, num;
682
683 if (!(mr->gsm48_ie[1]))
684 return;
685
686 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
687
688 num = 0;
689 vty_out(vty, " %s modes", prefix);
690 for (i = 0; i < ((full) ? 8 : 6); i++) {
691 if ((mr->gsm48_ie[1] & (1 << i))) {
692 vty_out(vty, " %d", i);
693 num++;
694 }
695 }
696 vty_out(vty, "%s", VTY_NEWLINE);
697 if (num > 4)
698 num = 4;
699 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200700 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
701 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100702 }
703 vty_out(vty, " %s start-mode ", prefix);
704 if (mr_conf->icmi) {
705 num = 0;
706 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
707 if ((mr->gsm48_ie[1] & (1 << i)))
708 num++;
709 if (mr_conf->smod == num - 1) {
710 vty_out(vty, "%d%s", num, VTY_NEWLINE);
711 break;
712 }
713 }
714 } else
715 vty_out(vty, "auto%s", VTY_NEWLINE);
716}
717
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200718static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
719{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200720 int i;
Max2c16bee2017-02-15 13:51:37 +0100721 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200722
Harald Welte5013b2a2009-08-07 13:29:14 +0200723 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
724 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200725 if (bts->description)
726 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200727 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100728 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200729 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200730 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200731 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
732 vty_out(vty, " dtx uplink%s%s",
733 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
734 VTY_NEWLINE);
735 if (bts->dtxd)
736 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200737 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200738 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100739 vty_out(vty, " cell reselection hysteresis %u%s",
740 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
741 vty_out(vty, " rxlev access min %u%s",
742 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100743
744 if (bts->si_common.cell_ro_sel_par.present) {
745 struct gsm48_si_selection_params *sp;
746 sp = &bts->si_common.cell_ro_sel_par;
747
748 if (sp->cbq)
749 vty_out(vty, " cell bar qualify %u%s",
750 sp->cbq, VTY_NEWLINE);
751
752 if (sp->cell_resel_off)
753 vty_out(vty, " cell reselection offset %u%s",
754 sp->cell_resel_off*2, VTY_NEWLINE);
755
756 if (sp->temp_offs == 7)
757 vty_out(vty, " temporary offset infinite%s",
758 VTY_NEWLINE);
759 else if (sp->temp_offs)
760 vty_out(vty, " temporary offset %u%s",
761 sp->temp_offs*10, VTY_NEWLINE);
762
763 if (sp->penalty_time == 31)
764 vty_out(vty, " penalty time reserved%s",
765 VTY_NEWLINE);
766 else if (sp->penalty_time)
767 vty_out(vty, " penalty time %u%s",
768 (sp->penalty_time*20)+20, VTY_NEWLINE);
769 }
770
Harald Welte2f8b9d22017-06-18 11:12:13 +0300771 if (gsm_bts_get_radio_link_timeout(bts) < 0)
772 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
773 else
774 vty_out(vty, " radio-link-timeout %d%s",
775 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100776
Harald Welte7a8fa412009-08-10 13:48:16 +0200777 vty_out(vty, " channel allocator %s%s",
778 bts->chan_alloc_reverse ? "descending" : "ascending",
779 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100780 vty_out(vty, " rach tx integer %u%s",
781 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
782 vty_out(vty, " rach max transmission %u%s",
783 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
784 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800785
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200786 vty_out(vty, " channel-descrption attach %u%s",
787 bts->si_common.chan_desc.att, VTY_NEWLINE);
788 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
789 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
790 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
791 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
792
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800793 if (bts->rach_b_thresh != -1)
794 vty_out(vty, " rach nm busy threshold %u%s",
795 bts->rach_b_thresh, VTY_NEWLINE);
796 if (bts->rach_ldavg_slots != -1)
797 vty_out(vty, " rach nm load average %u%s",
798 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100799 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200800 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800801 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
802 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400803 if ((bts->si_common.rach_control.t3) != 0)
804 for (i = 0; i < 8; i++)
805 if (bts->si_common.rach_control.t3 & (0x1 << i))
806 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
807 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
808 for (i = 0; i < 8; i++)
809 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
810 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Stefan Sperling6442e432018-02-06 14:44:54 +0100811 vty_out(vty, " %saccess-control-class-ramping%s", acc_ramp_is_enabled(&bts->acc_ramp) ? "" : "no ", VTY_NEWLINE);
812 if (!acc_ramp_step_interval_is_dynamic(&bts->acc_ramp)) {
813 vty_out(vty, " access-control-class-ramping-step-interval %u%s",
814 acc_ramp_get_step_interval(&bts->acc_ramp), VTY_NEWLINE);
815 } else {
816 vty_out(vty, " access-control-class-ramping-step-interval dynamic%s", VTY_NEWLINE);
817 }
818 vty_out(vty, " access-control-class-ramping-step-size %u%s", acc_ramp_get_step_size(&bts->acc_ramp),
819 VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200820 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
821 if (bts->si_mode_static & (1 << i)) {
822 vty_out(vty, " system-information %s mode static%s",
823 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
824 vty_out(vty, " system-information %s static %s%s",
825 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200826 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200827 VTY_NEWLINE);
828 }
829 }
Harald Welte42def722017-01-13 00:10:32 +0100830 vty_out(vty, " early-classmark-sending %s%s",
831 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100832 vty_out(vty, " early-classmark-sending-3g %s%s",
833 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100834 switch (bts->type) {
835 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100836 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200837 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200838 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100839 if (bts->ip_access.rsl_ip) {
840 struct in_addr ia;
841 ia.s_addr = htonl(bts->ip_access.rsl_ip);
842 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
843 VTY_NEWLINE);
844 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200845 vty_out(vty, " oml ip.access stream_id %u line %u%s",
846 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100847 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200848 case GSM_BTS_TYPE_NOKIA_SITE:
849 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100850 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
851 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100852 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 +0100853 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100854 default:
Harald Welte42581822009-08-08 16:12:58 +0200855 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
856 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100857 break;
Harald Welte42581822009-08-08 16:12:58 +0200858 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800859
860 /* if we have a limit, write it */
861 if (bts->paging.free_chans_need >= 0)
862 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
863
Harald Welte32c09622011-01-11 23:44:56 +0100864 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100865 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
866 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100867 for (i = 0; i < 1024; i++) {
868 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
869 vty_out(vty, " neighbor-list add arfcn %u%s",
870 i, VTY_NEWLINE);
871 }
872 }
Harald Welte64c07d22011-02-15 11:43:27 +0100873 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
874 for (i = 0; i < 1024; i++) {
875 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
876 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
877 i, VTY_NEWLINE);
878 }
879 }
Harald Welte32c09622011-01-11 23:44:56 +0100880
Max59a1bf32016-04-15 16:04:46 +0200881 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100882 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
883 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
884 vty_out(vty, " si2quater neighbor-list add earfcn %u "
885 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
886
887 vty_out(vty, " thresh-lo %u",
888 e->thresh_lo_valid ? e->thresh_lo : 32);
889
890 vty_out(vty, " prio %u",
891 e->prio_valid ? e->prio : 8);
892
893 vty_out(vty, " qrxlv %u",
894 e->qrxlm_valid ? e->qrxlm : 32);
895
896 tmp = e->meas_bw[i];
897 vty_out(vty, " meas %u",
898 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200899
900 vty_out(vty, "%s", VTY_NEWLINE);
901 }
902 }
903
Max26679e02016-04-20 15:57:13 +0200904 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
905 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
906 bts->si_common.data.uarfcn_list[i],
907 bts->si_common.data.scramble_list[i] & ~(1 << 9),
908 (bts->si_common.data.scramble_list[i] >> 9) & 1,
909 VTY_NEWLINE);
910 }
911
Andreas Eversberga83d5112013-12-07 18:32:28 +0100912 vty_out(vty, " codec-support fr");
913 if (bts->codec.hr)
914 vty_out(vty, " hr");
915 if (bts->codec.efr)
916 vty_out(vty, " efr");
917 if (bts->codec.amr)
918 vty_out(vty, " amr");
919 vty_out(vty, "%s", VTY_NEWLINE);
920
Andreas Eversberg73266522014-01-19 11:47:44 +0100921 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
922 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
923
Harald Welte615e9562010-05-11 23:50:21 +0200924 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200925
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200926 if (bts->excl_from_rf_lock)
927 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
928
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100929 vty_out(vty, " %sforce-combined-si%s",
930 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
931
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100932 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
933 int j;
934
935 if (bts->depends_on[i] == 0)
936 continue;
937
938 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
939 int bts_nr;
940
941 if ((bts->depends_on[i] & (1<<j)) == 0)
942 continue;
943
944 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
945 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
946 }
947 }
Harald Welte8254cf72017-05-29 13:42:19 +0200948 if (bts->pcu_sock_path)
949 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100950
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100951 ho_vty_write_bts(vty, bts);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100952
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200953 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200954}
955
956static int config_write_bts(struct vty *v)
957{
Harald Weltedcccb182010-05-16 20:52:23 +0200958 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200959 struct gsm_bts *bts;
960
961 llist_for_each_entry(bts, &gsmnet->bts_list, list)
962 config_write_bts_single(v, bts);
963
964 return CMD_SUCCESS;
965}
966
Harald Weltea0d324b2017-07-20 01:47:39 +0200967/* small helper macro for conditional dumping of timer */
968#define VTY_OUT_TIMER(number) \
969 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
970 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
971
Harald Welte5013b2a2009-08-07 13:29:14 +0200972static int config_write_net(struct vty *vty)
973{
Harald Weltedcccb182010-05-16 20:52:23 +0200974 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte51e4bf32017-12-23 17:30:18 +0100975 int i;
Harald Weltedcccb182010-05-16 20:52:23 +0200976
Harald Welte5013b2a2009-08-07 13:29:14 +0200977 vty_out(vty, "network%s", VTY_NEWLINE);
Neels Hofmeyrf93970b2018-03-05 02:09:40 +0100978 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
979 vty_out(vty, " mobile network code %s%s",
980 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
Harald Welte51e4bf32017-12-23 17:30:18 +0100981 vty_out(vty, " encryption a5");
982 for (i = 0; i < 8; i++) {
983 if (gsmnet->a5_encryption_mask & (1 << i))
984 vty_out(vty, " %u", i);
985 }
986 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100987 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800988 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100989
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100990 ho_vty_write_net(vty, gsmnet);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100991
Harald Weltea0d324b2017-07-20 01:47:39 +0200992 VTY_OUT_TIMER(3101);
993 VTY_OUT_TIMER(3103);
994 VTY_OUT_TIMER(3105);
995 VTY_OUT_TIMER(3107);
996 VTY_OUT_TIMER(3109);
997 VTY_OUT_TIMER(3111);
998 VTY_OUT_TIMER(3113);
999 VTY_OUT_TIMER(3115);
1000 VTY_OUT_TIMER(3117);
1001 VTY_OUT_TIMER(3119);
1002 VTY_OUT_TIMER(3122);
1003 VTY_OUT_TIMER(3141);
Neels Hofmeyr78faf702018-05-10 05:22:50 +02001004 if (!gsmnet->dyn_ts_allow_tch_f)
1005 vty_out(vty, " dyn_ts_allow_tch_f 0%s", VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +02001006 if (gsmnet->tz.override != 0) {
1007 if (gsmnet->tz.dst)
1008 vty_out(vty, " timezone %d %d %d%s",
1009 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
1010 VTY_NEWLINE);
1011 else
1012 vty_out(vty, " timezone %d %d%s",
1013 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
1014 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +02001015 if (gsmnet->t3212 == 0)
1016 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
1017 else
1018 vty_out(vty, " periodic location update %u%s",
1019 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +02001020
Neels Hofmeyrf28f1ef2018-04-20 15:53:53 +02001021 {
1022 uint16_t meas_port;
1023 char *meas_host;
1024 const char *meas_scenario;
1025
1026 meas_feed_cfg_get(&meas_host, &meas_port);
1027 meas_scenario = meas_feed_scenario_get();
1028
1029 if (meas_port)
1030 vty_out(vty, " meas-feed destination %s %u%s",
1031 meas_host, meas_port, VTY_NEWLINE);
1032 if (strlen(meas_scenario) > 0)
1033 vty_out(vty, " meas-feed scenario %s%s",
1034 meas_scenario, VTY_NEWLINE);
1035 }
1036
Harald Welte5013b2a2009-08-07 13:29:14 +02001037 return CMD_SUCCESS;
1038}
Harald Welte67ce0732009-08-06 19:06:46 +02001039
Harald Welte68628e82009-03-10 12:17:57 +00001040static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
1041{
1042 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
1043 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +02001044 vty_out(vty, "Description: %s%s",
1045 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +02001046 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +02001047 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +02001048 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +02001049 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001050 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001051 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +01001052 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001053 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001054 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +02001055 if (is_ipaccess_bts(trx->bts)) {
1056 vty_out(vty, " ip.access stream ID: 0x%02x%s",
1057 trx->rsl_tei, VTY_NEWLINE);
1058 } else {
1059 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
1060 e1isl_dump_vty(vty, trx->rsl_link);
1061 }
Harald Welte68628e82009-03-10 12:17:57 +00001062}
1063
Max6e4f1842018-01-07 16:45:42 +01001064static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
1065{
1066 uint8_t trx_nr;
1067 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
1068 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
1069}
1070
Harald Welte68628e82009-03-10 12:17:57 +00001071DEFUN(show_trx,
1072 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001073 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001074 SHOW_STR "Display information about a TRX\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001075 BTS_TRX_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001076{
Harald Weltedcccb182010-05-16 20:52:23 +02001077 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001078 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001079 int bts_nr, trx_nr;
1080
1081 if (argc >= 1) {
1082 /* use the BTS number that the user has specified */
1083 bts_nr = atoi(argv[0]);
1084 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001085 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001086 VTY_NEWLINE);
1087 return CMD_WARNING;
1088 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001089 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001090 }
1091 if (argc >= 2) {
1092 trx_nr = atoi(argv[1]);
1093 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001094 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001095 VTY_NEWLINE);
1096 return CMD_WARNING;
1097 }
Max6e4f1842018-01-07 16:45:42 +01001098 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001099 return CMD_SUCCESS;
1100 }
1101 if (bts) {
1102 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +01001103 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +00001104 return CMD_SUCCESS;
1105 }
1106
Max6e4f1842018-01-07 16:45:42 +01001107 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
1108 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001109
1110 return CMD_SUCCESS;
1111}
1112
Harald Welte67ce0732009-08-06 19:06:46 +02001113
Harald Welte68628e82009-03-10 12:17:57 +00001114static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
1115{
Harald Welte135a6482011-05-30 12:09:13 +02001116 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +01001117 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +01001118 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Welte0383a092018-04-07 19:02:33 +02001119 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH) {
Harald Welteb29cea12010-12-24 12:26:13 +01001120 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001121 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Welte0383a092018-04-07 19:02:33 +02001122 } else if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
1123 vty_out(vty, " (%s mode)", gsm_pchan_name(ts->dyn.pchan_is));
1124 }
Harald Weltecd103a92010-12-24 12:14:52 +01001125 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001126 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001127 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +05301128 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +00001129 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
1130 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
1131 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001132}
1133
1134DEFUN(show_ts,
1135 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001136 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001137 SHOW_STR "Display information about a TS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001138 BTS_TRX_TS_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001139{
Harald Weltedcccb182010-05-16 20:52:23 +02001140 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +01001141 struct gsm_bts *bts = NULL;
1142 struct gsm_bts_trx *trx = NULL;
1143 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001144 int bts_nr, trx_nr, ts_nr;
1145
1146 if (argc >= 1) {
1147 /* use the BTS number that the user has specified */
1148 bts_nr = atoi(argv[0]);
1149 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001150 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001151 VTY_NEWLINE);
1152 return CMD_WARNING;
1153 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001154 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001155 }
1156 if (argc >= 2) {
1157 trx_nr = atoi(argv[1]);
1158 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001159 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001160 VTY_NEWLINE);
1161 return CMD_WARNING;
1162 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001163 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001164 }
1165 if (argc >= 3) {
1166 ts_nr = atoi(argv[2]);
1167 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +00001168 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +00001169 VTY_NEWLINE);
1170 return CMD_WARNING;
1171 }
Harald Welte274d0152010-12-24 12:05:03 +01001172 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +00001173 ts = &trx->ts[ts_nr];
1174 ts_dump_vty(vty, ts);
1175 return CMD_SUCCESS;
1176 }
Harald Welte274d0152010-12-24 12:05:03 +01001177
1178 if (bts && trx) {
1179 /* Iterate over all TS in this TRX */
1180 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1181 ts = &trx->ts[ts_nr];
1182 ts_dump_vty(vty, ts);
1183 }
1184 } else if (bts) {
1185 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001186 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001187 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001188 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1189 ts = &trx->ts[ts_nr];
1190 ts_dump_vty(vty, ts);
1191 }
1192 }
Harald Welte274d0152010-12-24 12:05:03 +01001193 } else {
1194 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1195 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1196 bts = gsm_bts_num(net, bts_nr);
1197 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1198 trx = gsm_bts_trx_num(bts, trx_nr);
1199 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1200 ts = &trx->ts[ts_nr];
1201 ts_dump_vty(vty, ts);
1202 }
1203 }
1204 }
Harald Welte68628e82009-03-10 12:17:57 +00001205 }
1206
1207 return CMD_SUCCESS;
1208}
1209
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001210static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1211{
1212 if (strlen(bsub->imsi))
1213 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1214 if (bsub->tmsi != GSM_RESERVED_TMSI)
1215 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1216 VTY_NEWLINE);
1217 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1218}
1219
Harald Welte8387a492009-12-22 21:43:14 +01001220static void meas_rep_dump_uni_vty(struct vty *vty,
1221 struct gsm_meas_rep_unidir *mru,
1222 const char *prefix,
1223 const char *dir)
1224{
1225 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1226 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1227 dir, rxlev2dbm(mru->sub.rx_lev));
1228 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1229 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1230 VTY_NEWLINE);
1231}
1232
1233static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1234 const char *prefix)
1235{
1236 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1237 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1238 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1239 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1240 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1241 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1242 VTY_NEWLINE);
1243 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001244 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001245 if (mr->flags & MEAS_REP_F_MS_L1)
1246 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1247 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1248 if (mr->flags & MEAS_REP_F_DL_VALID)
1249 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1250 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1251}
1252
Harald Welte0a8cf322015-12-05 17:22:49 +01001253/* FIXME: move this to libosmogsm */
1254static const struct value_string gsm48_cmode_names[] = {
1255 { GSM48_CMODE_SIGN, "signalling" },
1256 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1257 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1258 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1259 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1260 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1261 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1262 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1263 { 0, NULL }
1264};
1265
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001266/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1267 * Don't do anything if the ts is not dynamic. */
1268static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1269{
1270 switch (ts->pchan) {
1271 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1272 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1273 vty_out(vty, " as %s",
1274 gsm_pchan_name(ts->dyn.pchan_is));
1275 else
1276 vty_out(vty, " switching %s -> %s",
1277 gsm_pchan_name(ts->dyn.pchan_is),
1278 gsm_pchan_name(ts->dyn.pchan_want));
1279 break;
1280 case GSM_PCHAN_TCH_F_PDCH:
1281 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1282 vty_out(vty, " as %s",
1283 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1284 : "TCH/F");
1285 else
1286 vty_out(vty, " switching %s -> %s",
1287 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1288 : "TCH/F",
1289 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1290 : "TCH/F");
1291 break;
1292 default:
1293 /* no dyn ts */
1294 break;
1295 }
1296}
1297
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001298static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001299{
Harald Welte8387a492009-12-22 21:43:14 +01001300 int idx;
1301
Harald Welte85bded82010-12-24 12:22:34 +01001302 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1303 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1304 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001305 /* show dyn TS details, if applicable */
1306 switch (lchan->ts->pchan) {
1307 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1308 vty_out(vty, " Osmocom Dyn TS:");
1309 vty_out_dyn_ts_status(vty, lchan->ts);
1310 vty_out(vty, VTY_NEWLINE);
1311 break;
1312 case GSM_PCHAN_TCH_F_PDCH:
1313 vty_out(vty, " IPACC Dyn PDCH TS:");
1314 vty_out_dyn_ts_status(vty, lchan->ts);
1315 vty_out(vty, VTY_NEWLINE);
1316 break;
1317 default:
1318 /* no dyn ts */
1319 break;
1320 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001321 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001322 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001323 gsm_lchans_name(lchan->state),
1324 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1325 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1326 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001327 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1328 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1329 - lchan->bs_power*2,
1330 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1331 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001332 vty_out(vty, " Channel Mode / Codec: %s%s",
1333 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1334 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001335 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001336 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001337 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001338 } else
1339 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301340 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1341 struct in_addr ia;
Harald Welte5f45a4a2018-02-05 21:33:34 +01001342 if (lchan->abis_ip.bound_ip) {
1343 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
1344 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1345 inet_ntoa(ia), lchan->abis_ip.bound_port,
1346 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1347 VTY_NEWLINE);
1348 }
1349 if (lchan->abis_ip.connect_ip) {
1350 ia.s_addr = htonl(lchan->abis_ip.connect_ip);
1351 vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02x%s",
1352 inet_ntoa(ia), lchan->abis_ip.connect_port,
1353 lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode,
1354 VTY_NEWLINE);
1355 }
1356
Harald Welte2c828992009-12-02 01:56:49 +05301357 }
Harald Welte8387a492009-12-22 21:43:14 +01001358
1359 /* we want to report the last measurement report */
1360 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1361 lchan->meas_rep_idx, 1);
1362 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001363}
1364
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001365static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1366{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001367 struct gsm_meas_rep *mr;
1368 int idx;
1369
1370 /* we want to report the last measurement report */
1371 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1372 lchan->meas_rep_idx, 1);
1373 mr = &lchan->meas_rep[idx];
1374
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001375 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001376 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001377 gsm_pchan_name(lchan->ts->pchan));
1378 vty_out_dyn_ts_status(vty, lchan->ts);
1379 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1380 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001381 lchan->nr,
1382 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1383 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001384 rxlev2dbm(mr->dl.full.rx_lev),
1385 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001386 VTY_NEWLINE);
1387}
1388
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001389
1390static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1391 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1392{
1393 int lchan_nr;
1394 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1395 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1396 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1397 continue;
1398 dump_cb(vty, lchan);
1399 }
1400
1401 return CMD_SUCCESS;
1402}
1403
1404static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1405 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1406{
1407 int ts_nr;
1408
1409 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1410 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1411 dump_lchan_trx_ts(ts, vty, dump_cb);
1412 }
1413
1414 return CMD_SUCCESS;
1415}
1416
1417static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1418 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1419{
1420 int trx_nr;
1421
1422 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1423 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1424 dump_lchan_trx(trx, vty, dump_cb);
1425 }
1426
1427 return CMD_SUCCESS;
1428}
1429
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001430static int lchan_summary(struct vty *vty, int argc, const char **argv,
1431 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001432{
Harald Weltedcccb182010-05-16 20:52:23 +02001433 struct gsm_network *net = gsmnet_from_vty(vty);
Pau Espin Pedrolcf48c542018-03-26 18:20:34 +02001434 struct gsm_bts *bts = NULL;
1435 struct gsm_bts_trx *trx = NULL;
1436 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001437 struct gsm_lchan *lchan;
1438 int bts_nr, trx_nr, ts_nr, lchan_nr;
1439
1440 if (argc >= 1) {
1441 /* use the BTS number that the user has specified */
1442 bts_nr = atoi(argv[0]);
1443 if (bts_nr >= net->num_bts) {
1444 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1445 VTY_NEWLINE);
1446 return CMD_WARNING;
1447 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001448 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001449
1450 if (argc == 1)
1451 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001452 }
1453 if (argc >= 2) {
1454 trx_nr = atoi(argv[1]);
1455 if (trx_nr >= bts->num_trx) {
1456 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1457 VTY_NEWLINE);
1458 return CMD_WARNING;
1459 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001460 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001461
1462 if (argc == 2)
1463 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001464 }
1465 if (argc >= 3) {
1466 ts_nr = atoi(argv[2]);
1467 if (ts_nr >= TRX_NR_TS) {
1468 vty_out(vty, "%% can't find TS %s%s", argv[2],
1469 VTY_NEWLINE);
1470 return CMD_WARNING;
1471 }
1472 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001473
1474 if (argc == 3)
1475 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001476 }
1477 if (argc >= 4) {
1478 lchan_nr = atoi(argv[3]);
1479 if (lchan_nr >= TS_MAX_LCHAN) {
1480 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1481 VTY_NEWLINE);
1482 return CMD_WARNING;
1483 }
1484 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001485 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001486 return CMD_SUCCESS;
1487 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001488
1489
Harald Welte68628e82009-03-10 12:17:57 +00001490 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001491 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001492 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001493 }
1494
1495 return CMD_SUCCESS;
1496}
1497
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001498
1499DEFUN(show_lchan,
1500 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001501 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001502 SHOW_STR "Display information about a logical channel\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001503 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001504{
1505 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1506}
1507
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001508DEFUN(show_lchan_summary,
1509 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001510 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001511 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001512 "Short summary\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001513 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001514{
1515 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1516}
1517
Philipp Maier39f62bb2017-04-09 12:32:51 +02001518DEFUN(show_subscr_conn,
1519 show_subscr_conn_cmd,
1520 "show conns",
1521 SHOW_STR "Display currently active subscriber connections\n")
1522{
1523 struct gsm_subscriber_connection *conn;
1524 struct gsm_network *net = gsmnet_from_vty(vty);
1525 bool no_conns = true;
1526 unsigned int count = 0;
1527
1528 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1529
1530 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1531 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1532 lchan_dump_full_vty(vty, conn->lchan);
1533 no_conns = false;
1534 count++;
1535 }
1536
1537 if (no_conns)
1538 vty_out(vty, "None%s", VTY_NEWLINE);
1539
1540 return CMD_SUCCESS;
1541}
1542
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001543static int trigger_ho_or_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_bts *to_bts)
1544{
1545 int rc;
1546
1547 if (!to_bts || from_lchan->ts->trx->bts == to_bts) {
1548 LOGP(DHO, LOGL_NOTICE, "%s Manually triggering Assignment from VTY\n",
1549 gsm_lchan_name(from_lchan));
1550 to_bts = from_lchan->ts->trx->bts;
1551 } else
1552 LOGP(DHO, LOGL_NOTICE, "%s (ARFCN %u) --> BTS %u Manually triggering Handover from VTY\n",
1553 gsm_lchan_name(from_lchan), from_lchan->ts->trx->arfcn, to_bts->nr);
Neels Hofmeyr45e46d22018-02-15 14:10:12 +01001554 rc = bsc_handover_start(HODEC_NONE, from_lchan, to_bts, from_lchan->type);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001555 if (rc) {
1556 vty_out(vty, "bsc_handover_start() returned %d=%s%s", rc,
1557 strerror(-rc), VTY_NEWLINE);
1558 return CMD_WARNING;
1559 }
1560 return CMD_SUCCESS;
1561}
1562
1563static int ho_or_as(struct vty *vty, const char *argv[], int argc)
Philipp Maier39f62bb2017-04-09 12:32:51 +02001564{
1565 struct gsm_network *net = gsmnet_from_vty(vty);
1566 struct gsm_subscriber_connection *conn;
1567 struct gsm_bts *bts;
1568 struct gsm_bts *new_bts = NULL;
1569 unsigned int bts_nr = atoi(argv[0]);
1570 unsigned int trx_nr = atoi(argv[1]);
1571 unsigned int ts_nr = atoi(argv[2]);
1572 unsigned int ss_nr = atoi(argv[3]);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001573 unsigned int bts_nr_new;
1574 const char *action;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001575
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001576 if (argc > 4) {
1577 bts_nr_new = atoi(argv[4]);
1578
1579 /* Lookup the BTS where we want to handover to */
1580 llist_for_each_entry(bts, &net->bts_list, list) {
1581 if (bts->nr == bts_nr_new) {
1582 new_bts = bts;
1583 break;
1584 }
1585 }
1586
1587 if (!new_bts) {
1588 vty_out(vty, "Unable to trigger handover, specified bts #%u does not exist %s",
1589 bts_nr_new, VTY_NEWLINE);
1590 return CMD_WARNING;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001591 }
1592 }
1593
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001594 action = new_bts ? "handover" : "assignment";
Philipp Maier39f62bb2017-04-09 12:32:51 +02001595
1596 /* Find the connection/lchan that we want to handover */
1597 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001598 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001599 conn->lchan->ts->trx->nr == trx_nr &&
1600 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001601 vty_out(vty, "starting %s for lchan %s...%s", action, conn->lchan->name, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001602 lchan_dump_full_vty(vty, conn->lchan);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001603 return trigger_ho_or_as(vty, conn->lchan, new_bts);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001604 }
1605 }
1606
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001607 vty_out(vty, "Unable to trigger %s, specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1608 action, bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001609
1610 return CMD_WARNING;
1611}
1612
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001613#define MANUAL_HANDOVER_STR "Manually trigger handover (for debugging)\n"
1614#define MANUAL_ASSIGNMENT_STR "Manually trigger assignment (for debugging)\n"
1615
1616DEFUN(handover_subscr_conn,
1617 handover_subscr_conn_cmd,
Harald Welteb22dcb82018-02-12 17:57:57 +01001618 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> handover <0-255>",
Harald Welte0bfd8d92018-02-12 18:06:53 +01001619 BTS_NR_TRX_TS_SS_STR2
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001620 MANUAL_HANDOVER_STR
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001621 "New " BTS_NR_STR)
1622{
1623 return ho_or_as(vty, argv, argc);
1624}
1625
1626DEFUN(assignment_subscr_conn,
1627 assignment_subscr_conn_cmd,
Harald Welteb22dcb82018-02-12 17:57:57 +01001628 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> assignment",
Harald Welte0bfd8d92018-02-12 18:06:53 +01001629 BTS_NR_TRX_TS_SS_STR2
Harald Welteb22dcb82018-02-12 17:57:57 +01001630 MANUAL_ASSIGNMENT_STR)
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001631{
1632 return ho_or_as(vty, argv, argc);
1633}
1634
1635static struct gsm_lchan *find_used_voice_lchan(struct vty *vty)
1636{
1637 struct gsm_bts *bts;
1638 struct gsm_network *network = gsmnet_from_vty(vty);
1639
1640 llist_for_each_entry(bts, &network->bts_list, list) {
1641 struct gsm_bts_trx *trx;
1642
1643 llist_for_each_entry(trx, &bts->trx_list, list) {
1644 int i;
1645 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1646 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1647 int j;
1648 int subslots;
1649
1650 /* skip administratively deactivated timeslots */
1651 if (!nm_is_running(&ts->mo.nm_state))
1652 continue;
1653
1654 subslots = ts_subslots(ts);
1655 for (j = 0; j < subslots; j++) {
1656 struct gsm_lchan *lchan = &ts->lchan[j];
1657
1658 if (lchan->state == LCHAN_S_ACTIVE
1659 && (lchan->type == GSM_LCHAN_TCH_F
1660 || lchan->type == GSM_LCHAN_TCH_H)) {
1661
1662 vty_out(vty, "Found voice call: %s%s",
1663 gsm_lchan_name(lchan), VTY_NEWLINE);
1664 lchan_dump_full_vty(vty, lchan);
1665 return lchan;
1666 }
1667 }
1668 }
1669 }
1670 }
1671
1672 vty_out(vty, "Cannot find any ongoing voice calls%s", VTY_NEWLINE);
1673 return NULL;
1674}
1675
1676static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gsm_bts *not_this_bts,
1677 enum gsm_phys_chan_config free_type)
1678{
1679 struct gsm_bts *bts;
1680 struct gsm_network *network = gsmnet_from_vty(vty);
1681
1682 llist_for_each_entry(bts, &network->bts_list, list) {
1683 struct gsm_bts_trx *trx;
1684
1685 if (bts == not_this_bts)
1686 continue;
1687
1688 llist_for_each_entry(trx, &bts->trx_list, list) {
1689 int i;
1690 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1691 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1692 int j;
1693 int subslots;
1694
1695 /* skip administratively deactivated timeslots */
1696 if (!nm_is_running(&ts->mo.nm_state))
1697 continue;
1698
1699 if (ts->pchan != free_type)
1700 continue;
1701
1702 subslots = ts_subslots(ts);
1703 for (j = 0; j < subslots; j++) {
1704 struct gsm_lchan *lchan = &ts->lchan[j];
1705
1706 if (lchan->state == LCHAN_S_NONE) {
1707 vty_out(vty, "Found unused %s slot: %s%s",
1708 gsm_pchan_name(free_type),
1709 gsm_lchan_name(lchan),
1710 VTY_NEWLINE);
1711 lchan_dump_full_vty(vty, lchan);
1712 return bts;
1713 }
1714 }
1715 }
1716 }
1717 }
1718 vty_out(vty, "Cannot find any BTS (other than BTS %u) with free %s lchan%s",
1719 not_this_bts? not_this_bts->nr : 255, gsm_lchant_name(free_type), VTY_NEWLINE);
1720 return NULL;
1721}
1722
1723DEFUN(handover_any, handover_any_cmd,
1724 "handover any",
1725 MANUAL_HANDOVER_STR
1726 "Pick any actively used TCH/F or TCH/H lchan and handover to any other BTS."
1727 " This is likely to fail if not all BTS are guaranteed to be reachable by the MS.\n")
1728{
1729 struct gsm_lchan *from_lchan;
1730 struct gsm_bts *to_bts;
1731
1732 from_lchan = find_used_voice_lchan(vty);
1733 if (!from_lchan)
1734 return CMD_WARNING;
1735
1736 to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts,
1737 ts_pchan(from_lchan->ts));
1738 if (!to_bts)
1739 return CMD_WARNING;
1740
1741 return trigger_ho_or_as(vty, from_lchan, to_bts);
1742}
1743
1744DEFUN(assignment_any, assignment_any_cmd,
1745 "assignment any",
1746 MANUAL_ASSIGNMENT_STR
1747 "Pick any actively used TCH/F or TCH/H lchan and re-assign within the same BTS."
1748 " This will fail if no lchans of the same type are available besides the used one.\n")
1749{
1750 struct gsm_lchan *from_lchan;
1751
1752 from_lchan = find_used_voice_lchan(vty);
1753 if (!from_lchan)
1754 return CMD_WARNING;
1755
1756 return trigger_ho_or_as(vty, from_lchan, NULL);
1757}
1758
Harald Weltebe4b7302009-05-23 16:59:33 +00001759static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001760{
1761 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001762 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001763}
1764
Harald Weltebe4b7302009-05-23 16:59:33 +00001765static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001766{
1767 struct gsm_paging_request *pag;
1768
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001769 if (!bts->paging.bts)
1770 return;
1771
Harald Weltef5025b62009-03-28 16:55:11 +00001772 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1773 paging_dump_vty(vty, pag);
1774}
1775
1776DEFUN(show_paging,
1777 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001778 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001779 SHOW_STR "Display information about paging reuqests of a BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001780 BTS_NR_STR)
Harald Weltef5025b62009-03-28 16:55:11 +00001781{
Harald Weltedcccb182010-05-16 20:52:23 +02001782 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001783 struct gsm_bts *bts;
1784 int bts_nr;
1785
1786 if (argc >= 1) {
1787 /* use the BTS number that the user has specified */
1788 bts_nr = atoi(argv[0]);
1789 if (bts_nr >= net->num_bts) {
1790 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1791 VTY_NEWLINE);
1792 return CMD_WARNING;
1793 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001794 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001795 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001796
Harald Weltef5025b62009-03-28 16:55:11 +00001797 return CMD_SUCCESS;
1798 }
1799 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001800 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001801 bts_paging_dump_vty(vty, bts);
1802 }
1803
1804 return CMD_SUCCESS;
1805}
1806
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001807DEFUN(show_paging_group,
1808 show_paging_group_cmd,
1809 "show paging-group <0-255> IMSI",
1810 SHOW_STR "Display the paging group\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001811 BTS_NR_STR "IMSI\n")
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001812{
1813 struct gsm_network *net = gsmnet_from_vty(vty);
1814 struct gsm_bts *bts;
1815 unsigned int page_group;
1816 int bts_nr = atoi(argv[0]);
1817
1818 if (bts_nr >= net->num_bts) {
1819 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1820 return CMD_WARNING;
1821 }
1822
1823 bts = gsm_bts_num(net, bts_nr);
1824 if (!bts) {
1825 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1826 return CMD_WARNING;
1827 }
1828
1829 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1830 str_to_imsi(argv[1]));
1831 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1832 str_to_imsi(argv[1]), bts->nr,
1833 page_group, VTY_NEWLINE);
1834 return CMD_SUCCESS;
1835}
1836
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001837DEFUN(cfg_net_neci,
1838 cfg_net_neci_cmd,
1839 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001840 "New Establish Cause Indication\n"
1841 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001842{
Harald Weltedcccb182010-05-16 20:52:23 +02001843 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1844
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001845 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001846 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001847 return CMD_SUCCESS;
1848}
1849
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001850DEFUN(cfg_net_pag_any_tch,
1851 cfg_net_pag_any_tch_cmd,
1852 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001853 "Assign a TCH when receiving a Paging Any request\n"
1854 "Any Channel\n" "Use\n" "TCH\n"
1855 "Do not use TCH for Paging Request Any\n"
1856 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001857{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001858 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001859 gsmnet->pag_any_tch = atoi(argv[0]);
1860 gsm_net_update_ctype(gsmnet);
1861 return CMD_SUCCESS;
1862}
1863
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001864#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1865/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1866#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1867
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001868#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001869 DEFUN(cfg_net_T##number, \
1870 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001871 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001872 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001873 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001874 "Set to default timer value" \
1875 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1876 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001877{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001878 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001879 int value; \
1880 if (strcmp(argv[0], "default") == 0) \
1881 value = DEFAULT_TIMER(number); \
1882 else \
1883 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001884 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001885 gsmnet->T##number = value; \
1886 return CMD_SUCCESS; \
1887}
1888
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001889DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1890DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1891DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1892DECLARE_TIMER(3107, "Currently not used")
1893DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1894DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1895DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1896DECLARE_TIMER(3115, "Currently not used")
1897DECLARE_TIMER(3117, "Currently not used")
1898DECLARE_TIMER(3119, "Currently not used")
Stefan Sperling6cee8932018-01-30 18:14:22 +01001899DECLARE_TIMER(3122, "Default waiting time (seconds) after IMM ASS REJECT")
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001900DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001901
Maxc08ee712016-05-11 12:45:13 +02001902DEFUN_DEPRECATED(cfg_net_dtx,
1903 cfg_net_dtx_cmd,
1904 "dtx-used (0|1)",
1905 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001906{
Maxc08ee712016-05-11 12:45:13 +02001907 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1908 "configuration options of BTS instead%s", VTY_NEWLINE);
1909 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001910}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001911
Harald Welte5258fc42009-03-28 19:07:53 +00001912/* per-BTS configuration */
1913DEFUN(cfg_bts,
1914 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001915 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001916 "Select a BTS to configure\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001917 BTS_NR_STR)
Harald Welte5258fc42009-03-28 19:07:53 +00001918{
Harald Weltedcccb182010-05-16 20:52:23 +02001919 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001920 int bts_nr = atoi(argv[0]);
1921 struct gsm_bts *bts;
1922
Harald Weltee441d9c2009-06-21 16:17:15 +02001923 if (bts_nr > gsmnet->num_bts) {
1924 vty_out(vty, "%% The next unused BTS number is %u%s",
1925 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001926 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001927 } else if (bts_nr == gsmnet->num_bts) {
1928 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001929 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001930 HARDCODED_BSIC);
Stefan Sperling6442e432018-02-06 14:44:54 +01001931 /*
1932 * Initalize bts->acc_ramp here. Else we could segfault while
1933 * processing a configuration file with ACC ramping settings.
1934 */
Stefan Sperlingea333412018-04-10 16:36:54 +02001935 acc_ramp_init(&bts->acc_ramp, bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001936 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001937 bts = gsm_bts_num(gsmnet, bts_nr);
1938
Daniel Willmannf15c2762010-01-11 13:43:07 +01001939 if (!bts) {
1940 vty_out(vty, "%% Unable to allocate BTS %u%s",
1941 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001942 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001943 }
Harald Welte5258fc42009-03-28 19:07:53 +00001944
1945 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001946 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001947 vty->node = BTS_NODE;
1948
1949 return CMD_SUCCESS;
1950}
1951
1952DEFUN(cfg_bts_type,
1953 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001954 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001955 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001956{
1957 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001958 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001959
Max7507aef2017-04-10 13:59:14 +02001960 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001961 if (rc < 0)
1962 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001963
Harald Welte5258fc42009-03-28 19:07:53 +00001964 return CMD_SUCCESS;
1965}
1966
Harald Weltefcd24452009-06-20 18:15:19 +02001967DEFUN(cfg_bts_band,
1968 cfg_bts_band_cmd,
1969 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001970 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001971{
1972 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001973 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001974
1975 if (band < 0) {
1976 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1977 band, VTY_NEWLINE);
1978 return CMD_WARNING;
1979 }
1980
1981 bts->band = band;
1982
1983 return CMD_SUCCESS;
1984}
1985
Maxc08ee712016-05-11 12:45:13 +02001986DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1987 "Configure discontinuous transmission\n"
1988 "Enable Uplink DTX for this BTS\n"
1989 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1990 "older phones).\n")
1991{
1992 struct gsm_bts *bts = vty->index;
1993
1994 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001995 if (!is_ipaccess_bts(bts))
1996 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1997 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001998 return CMD_SUCCESS;
1999}
2000
2001DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
2002 NO_STR
2003 "Configure discontinuous transmission\n"
2004 "Disable Uplink DTX for this BTS\n")
2005{
2006 struct gsm_bts *bts = vty->index;
2007
2008 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
2009
2010 return CMD_SUCCESS;
2011}
2012
2013DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
2014 "Configure discontinuous transmission\n"
2015 "Enable Downlink DTX for this BTS\n")
2016{
2017 struct gsm_bts *bts = vty->index;
2018
2019 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02002020 if (!is_ipaccess_bts(bts))
2021 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
2022 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02002023 return CMD_SUCCESS;
2024}
2025
2026DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
2027 NO_STR
2028 "Configure discontinuous transmission\n"
2029 "Disable Downlink DTX for this BTS\n")
2030{
2031 struct gsm_bts *bts = vty->index;
2032
2033 bts->dtxd = false;
2034
2035 return CMD_SUCCESS;
2036}
2037
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02002038DEFUN(cfg_bts_ci,
2039 cfg_bts_ci_cmd,
2040 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002041 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02002042{
2043 struct gsm_bts *bts = vty->index;
2044 int ci = atoi(argv[0]);
2045
2046 if (ci < 0 || ci > 0xffff) {
2047 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
2048 ci, VTY_NEWLINE);
2049 return CMD_WARNING;
2050 }
2051 bts->cell_identity = ci;
2052
2053 return CMD_SUCCESS;
2054}
2055
Harald Welte5258fc42009-03-28 19:07:53 +00002056DEFUN(cfg_bts_lac,
2057 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02002058 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002059 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00002060{
2061 struct gsm_bts *bts = vty->index;
2062 int lac = atoi(argv[0]);
2063
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02002064 if (lac < 0 || lac > 0xffff) {
2065 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00002066 lac, VTY_NEWLINE);
2067 return CMD_WARNING;
2068 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02002069
2070 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
2071 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
2072 lac, VTY_NEWLINE);
2073 return CMD_WARNING;
2074 }
2075
Harald Welte5258fc42009-03-28 19:07:53 +00002076 bts->location_area_code = lac;
2077
2078 return CMD_SUCCESS;
2079}
2080
Harald Weltea43f7892009-12-01 18:04:30 +05302081
Harald Weltea2bbc5e2015-11-20 10:43:31 +01002082/* compatibility wrapper for old config files */
2083DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00002084 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02002085 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002086 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00002087{
Harald Welte5258fc42009-03-28 19:07:53 +00002088 return CMD_SUCCESS;
2089}
2090
Harald Welte78f2f502009-05-23 16:56:52 +00002091DEFUN(cfg_bts_bsic,
2092 cfg_bts_bsic_cmd,
2093 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002094 "Set the Base Station Identity Code (BSIC) of this BTS\n"
2095 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00002096{
2097 struct gsm_bts *bts = vty->index;
2098 int bsic = atoi(argv[0]);
2099
2100 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02002101 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00002102 bsic, VTY_NEWLINE);
2103 return CMD_WARNING;
2104 }
2105 bts->bsic = bsic;
2106
2107 return CMD_SUCCESS;
2108}
2109
Harald Welte4cc34222009-05-01 15:12:31 +00002110DEFUN(cfg_bts_unit_id,
2111 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02002112 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002113 "Abis/IP specific options\n"
2114 "Set the IPA BTS Unit ID\n"
2115 "Unit ID (Site)\n"
2116 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00002117{
2118 struct gsm_bts *bts = vty->index;
2119 int site_id = atoi(argv[0]);
2120 int bts_id = atoi(argv[1]);
2121
Harald Welte07dc73d2009-08-07 13:27:09 +02002122 if (!is_ipaccess_bts(bts)) {
2123 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2124 return CMD_WARNING;
2125 }
2126
Harald Welte4cc34222009-05-01 15:12:31 +00002127 bts->ip_access.site_id = site_id;
2128 bts->ip_access.bts_id = bts_id;
2129
2130 return CMD_SUCCESS;
2131}
2132
Harald Welte8b291802013-03-12 13:57:05 +01002133DEFUN(cfg_bts_rsl_ip,
2134 cfg_bts_rsl_ip_cmd,
2135 "ip.access rsl-ip A.B.C.D",
2136 "Abis/IP specific options\n"
2137 "Set the IPA RSL IP Address of the BSC\n"
2138 "Destination IP address for RSL connection\n")
2139{
2140 struct gsm_bts *bts = vty->index;
2141 struct in_addr ia;
2142
2143 if (!is_ipaccess_bts(bts)) {
2144 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2145 return CMD_WARNING;
2146 }
2147
2148 inet_aton(argv[0], &ia);
2149 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
2150
2151 return CMD_SUCCESS;
2152}
2153
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002154#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01002155
Sylvain Munautc9519462011-10-17 14:04:55 +02002156DEFUN(cfg_bts_nokia_site_skip_reset,
2157 cfg_bts_nokia_site_skip_reset_cmd,
2158 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002159 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002160 "Skip the reset step during bootstrap process of this BTS\n"
2161 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02002162{
2163 struct gsm_bts *bts = vty->index;
2164
2165 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
2166 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
2167 return CMD_WARNING;
2168 }
2169
2170 bts->nokia.skip_reset = atoi(argv[0]);
2171
2172 return CMD_SUCCESS;
2173}
2174
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002175DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
2176 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
2177 "nokia_site no-local-rel-conf (0|1)",
2178 NOKIA_STR
2179 "Do not wait for RELease CONFirm message when releasing channel locally\n"
2180 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\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.no_loc_rel_cnf = atoi(argv[0]);
2191
2192 return CMD_SUCCESS;
2193}
2194
Sipos Csaba56e17662015-02-07 13:27:36 +01002195DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
2196 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
2197 "nokia_site bts-reset-timer <15-100>",
2198 NOKIA_STR
2199 "The amount of time (in sec.) between BTS_RESET is sent,\n"
2200 "and the BTS is being bootstrapped.\n")
2201{
2202 struct gsm_bts *bts = vty->index;
2203
2204 if (!is_nokia_bts(bts)) {
2205 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2206 VTY_NEWLINE);
2207 return CMD_WARNING;
2208 }
2209
2210 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
2211
2212 return CMD_SUCCESS;
2213}
Harald Welte8f0ed552010-05-11 21:53:49 +02002214#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002215#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02002216
Harald Welte8175e952009-10-20 00:22:00 +02002217DEFUN(cfg_bts_stream_id,
2218 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002219 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02002220 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002221 "Set the ip.access Stream ID of the OML link of this BTS\n"
2222 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02002223{
2224 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002225 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02002226
2227 if (!is_ipaccess_bts(bts)) {
2228 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2229 return CMD_WARNING;
2230 }
2231
2232 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002233 /* This is used by e1inp_bind_ops callback for each BTS model. */
2234 bts->oml_e1_link.e1_nr = linenr;
2235
2236 return CMD_SUCCESS;
2237}
2238
Harald Welted13e0cd2012-08-17 09:52:03 +02002239#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02002240
Harald Welte42581822009-08-08 16:12:58 +02002241DEFUN(cfg_bts_oml_e1,
2242 cfg_bts_oml_e1_cmd,
2243 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02002244 OML_E1_STR
2245 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002246 "E1/T1 line number to be used for OML\n"
2247 "E1/T1 timeslot to be used for OML\n"
2248 "E1/T1 timeslot to be used for OML\n"
2249 "E1/T1 sub-slot to be used for OML\n"
2250 "Use E1/T1 sub-slot 0\n"
2251 "Use E1/T1 sub-slot 1\n"
2252 "Use E1/T1 sub-slot 2\n"
2253 "Use E1/T1 sub-slot 3\n"
2254 "Use full E1 slot 3\n"
2255 )
Harald Welte42581822009-08-08 16:12:58 +02002256{
2257 struct gsm_bts *bts = vty->index;
2258
2259 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2260
2261 return CMD_SUCCESS;
2262}
2263
2264
2265DEFUN(cfg_bts_oml_e1_tei,
2266 cfg_bts_oml_e1_tei_cmd,
2267 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002268 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002269 "Set the TEI to be used for OML\n"
2270 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002271{
2272 struct gsm_bts *bts = vty->index;
2273
2274 bts->oml_tei = atoi(argv[0]);
2275
2276 return CMD_SUCCESS;
2277}
2278
Harald Welte7a8fa412009-08-10 13:48:16 +02002279DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2280 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002281 "Channnel Allocator\n" "Channel Allocator\n"
2282 "Allocate Timeslots and Transceivers in ascending order\n"
2283 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002284{
2285 struct gsm_bts *bts = vty->index;
2286
2287 if (!strcmp(argv[0], "ascending"))
2288 bts->chan_alloc_reverse = 0;
2289 else
2290 bts->chan_alloc_reverse = 1;
2291
2292 return CMD_SUCCESS;
2293}
2294
Harald Welte8f0ed552010-05-11 21:53:49 +02002295#define RACH_STR "Random Access Control Channel\n"
2296
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002297DEFUN(cfg_bts_rach_tx_integer,
2298 cfg_bts_rach_tx_integer_cmd,
2299 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002300 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002301 "Set the raw tx integer value in RACH Control parameters IE\n"
2302 "Set the raw tx integer value in RACH Control parameters IE\n"
2303 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002304{
2305 struct gsm_bts *bts = vty->index;
2306 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2307 return CMD_SUCCESS;
2308}
2309
2310DEFUN(cfg_bts_rach_max_trans,
2311 cfg_bts_rach_max_trans_cmd,
2312 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002313 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002314 "Set the maximum number of RACH burst transmissions\n"
2315 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002316 "Maximum number of 1 RACH burst transmissions\n"
2317 "Maximum number of 2 RACH burst transmissions\n"
2318 "Maximum number of 4 RACH burst transmissions\n"
2319 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002320{
2321 struct gsm_bts *bts = vty->index;
2322 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2323 return CMD_SUCCESS;
2324}
2325
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002326#define CD_STR "Channel Description\n"
2327
2328DEFUN(cfg_bts_chan_desc_att,
2329 cfg_bts_chan_desc_att_cmd,
2330 "channel-descrption attach (0|1)",
2331 CD_STR
2332 "Set if attachment is required\n"
2333 "Attachment is NOT required\n"
2334 "Attachment is required (standard)\n")
2335{
2336 struct gsm_bts *bts = vty->index;
2337 bts->si_common.chan_desc.att = atoi(argv[0]);
2338 return CMD_SUCCESS;
2339}
2340
2341DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2342 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2343 "channel-descrption bs-pa-mfrms <2-9>",
2344 CD_STR
2345 "Set number of multiframe periods for paging groups\n"
2346 "Number of multiframe periods for paging groups\n")
2347{
2348 struct gsm_bts *bts = vty->index;
2349 int bs_pa_mfrms = atoi(argv[0]);
2350
2351 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2352 return CMD_SUCCESS;
2353}
2354
2355DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2356 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2357 "channel-descrption bs-ag-blks-res <0-7>",
2358 CD_STR
2359 "Set number of blocks reserved for access grant\n"
2360 "Number of blocks reserved for access grant\n")
2361{
2362 struct gsm_bts *bts = vty->index;
2363 int bs_ag_blks_res = atoi(argv[0]);
2364
2365 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2366 return CMD_SUCCESS;
2367}
2368
Harald Welte8f0ed552010-05-11 21:53:49 +02002369#define NM_STR "Network Management\n"
2370
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002371DEFUN(cfg_bts_rach_nm_b_thresh,
2372 cfg_bts_rach_nm_b_thresh_cmd,
2373 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002374 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002375 "Set the NM Busy Threshold\n"
2376 "Set the NM Busy Threshold\n"
2377 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002378{
2379 struct gsm_bts *bts = vty->index;
2380 bts->rach_b_thresh = atoi(argv[0]);
2381 return CMD_SUCCESS;
2382}
2383
2384DEFUN(cfg_bts_rach_nm_ldavg,
2385 cfg_bts_rach_nm_ldavg_cmd,
2386 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002387 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002388 "Set the NM Loadaverage Slots value\n"
2389 "Set the NM Loadaverage Slots value\n"
2390 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002391{
2392 struct gsm_bts *bts = vty->index;
2393 bts->rach_ldavg_slots = atoi(argv[0]);
2394 return CMD_SUCCESS;
2395}
2396
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002397DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2398 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002399 "Should this cell be barred from access?\n"
2400 "Should this cell be barred from access?\n"
2401 "Cell should NOT be barred\n"
2402 "Cell should be barred\n")
2403
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002404{
2405 struct gsm_bts *bts = vty->index;
2406
Harald Welte71355012009-12-21 23:08:18 +01002407 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002408
2409 return CMD_SUCCESS;
2410}
2411
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002412DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2413 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002414 RACH_STR
2415 "Should this cell allow emergency calls?\n"
2416 "Should this cell allow emergency calls?\n"
2417 "Should this cell allow emergency calls?\n"
2418 "Do NOT allow emergency calls\n"
2419 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002420{
2421 struct gsm_bts *bts = vty->index;
2422
2423 if (atoi(argv[0]) == 0)
2424 bts->si_common.rach_control.t2 |= 0x4;
2425 else
2426 bts->si_common.rach_control.t2 &= ~0x4;
2427
2428 return CMD_SUCCESS;
2429}
2430
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002431DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2432 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2433 RACH_STR
2434 "Set access control class\n"
2435 "Access control class 0\n"
2436 "Access control class 1\n"
2437 "Access control class 2\n"
2438 "Access control class 3\n"
2439 "Access control class 4\n"
2440 "Access control class 5\n"
2441 "Access control class 6\n"
2442 "Access control class 7\n"
2443 "Access control class 8\n"
2444 "Access control class 9\n"
2445 "Access control class 11 for PLMN use\n"
2446 "Access control class 12 for security services\n"
2447 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2448 "Access control class 14 for emergency services\n"
2449 "Access control class 15 for PLMN staff\n"
2450 "barred to use access control class\n"
2451 "allowed to use access control class\n")
2452{
2453 struct gsm_bts *bts = vty->index;
2454
2455 uint8_t control_class;
2456 uint8_t allowed = 0;
2457
2458 if (strcmp(argv[1], "allowed") == 0)
2459 allowed = 1;
2460
2461 control_class = atoi(argv[0]);
2462 if (control_class < 8)
2463 if (allowed)
2464 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2465 else
2466 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2467 else
2468 if (allowed)
2469 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2470 else
2471 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2472
2473 return CMD_SUCCESS;
2474}
2475
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002476DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2477 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002478 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002479 "Maximum transmit power of the MS\n"
2480 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002481 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002482{
2483 struct gsm_bts *bts = vty->index;
2484
2485 bts->ms_max_power = atoi(argv[0]);
2486
2487 return CMD_SUCCESS;
2488}
2489
Harald Weltecfaabbb2012-08-16 23:23:50 +02002490#define CELL_STR "Cell Parameters\n"
2491
Harald Welte73225282009-12-12 18:17:25 +01002492DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2493 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002494 CELL_STR "Cell re-selection parameters\n"
2495 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002496 "Cell Re-Selection Hysteresis in dB")
2497{
2498 struct gsm_bts *bts = vty->index;
2499
2500 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2501
2502 return CMD_SUCCESS;
2503}
2504
2505DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2506 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002507 "Minimum RxLev needed for cell access\n"
2508 "Minimum RxLev needed for cell access\n"
2509 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002510 "Minimum RxLev needed for cell access (better than -110dBm)")
2511{
2512 struct gsm_bts *bts = vty->index;
2513
2514 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2515
2516 return CMD_SUCCESS;
2517}
2518
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002519DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2520 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002521 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2522 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002523{
2524 struct gsm_bts *bts = vty->index;
2525
2526 bts->si_common.cell_ro_sel_par.present = 1;
2527 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2528
2529 return CMD_SUCCESS;
2530}
2531
2532DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2533 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002534 CELL_STR "Cell Re-Selection Parameters\n"
2535 "Cell Re-Selection Offset (CRO) in dB\n"
2536 "Cell Re-Selection Offset (CRO) in dB\n"
2537 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002538{
2539 struct gsm_bts *bts = vty->index;
2540
2541 bts->si_common.cell_ro_sel_par.present = 1;
2542 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2543
2544 return CMD_SUCCESS;
2545}
2546
2547DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2548 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002549 "Cell selection temporary negative offset\n"
2550 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002551 "Cell selection temporary negative offset in dB")
2552{
2553 struct gsm_bts *bts = vty->index;
2554
2555 bts->si_common.cell_ro_sel_par.present = 1;
2556 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2557
2558 return CMD_SUCCESS;
2559}
2560
2561DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2562 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002563 "Cell selection temporary negative offset\n"
2564 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002565 "Sets cell selection temporary negative offset to infinity")
2566{
2567 struct gsm_bts *bts = vty->index;
2568
2569 bts->si_common.cell_ro_sel_par.present = 1;
2570 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2571
2572 return CMD_SUCCESS;
2573}
2574
2575DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2576 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002577 "Cell selection penalty time\n"
2578 "Cell selection penalty time\n"
2579 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002580{
2581 struct gsm_bts *bts = vty->index;
2582
2583 bts->si_common.cell_ro_sel_par.present = 1;
2584 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2585
2586 return CMD_SUCCESS;
2587}
2588
2589DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2590 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002591 "Cell selection penalty time\n"
2592 "Cell selection penalty time\n"
2593 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002594 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2595 "and TEMPORARY_OFFSET is ignored)")
2596{
2597 struct gsm_bts *bts = vty->index;
2598
2599 bts->si_common.cell_ro_sel_par.present = 1;
2600 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2601
2602 return CMD_SUCCESS;
2603}
2604
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002605DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2606 "radio-link-timeout <4-64>",
2607 "Radio link timeout criterion (BTS side)\n"
2608 "Radio link timeout value (lost SACCH block)\n")
2609{
2610 struct gsm_bts *bts = vty->index;
2611
Harald Welte2f8b9d22017-06-18 11:12:13 +03002612 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2613
2614 return CMD_SUCCESS;
2615}
2616
2617DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2618 "radio-link-timeout infinite",
2619 "Radio link timeout criterion (BTS side)\n"
2620 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2621{
2622 struct gsm_bts *bts = vty->index;
2623
2624 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2625 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2626 return CMD_WARNING;
2627 }
2628
2629 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2630 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002631
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002632 return CMD_SUCCESS;
2633}
2634
Harald Welte8f0ed552010-05-11 21:53:49 +02002635#define GPRS_TEXT "GPRS Packet Network\n"
2636
Harald Welteaf387632010-03-14 23:30:30 +08002637DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002638 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002639 GPRS_TEXT
2640 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002641 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002642 "GPRS BSSGP VC Identifier")
2643{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002644 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002645 struct gsm_bts *bts = vty->index;
2646
Harald Welte4511d892010-04-18 15:51:20 +02002647 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002648 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2649 return CMD_WARNING;
2650 }
2651
Harald Welte97a282b2010-03-14 15:37:43 +08002652 bts->gprs.cell.bvci = atoi(argv[0]);
2653
2654 return CMD_SUCCESS;
2655}
2656
Harald Weltea5731cf2010-03-22 11:48:36 +08002657DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2658 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002659 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002660 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002661 "GPRS NS Entity Identifier")
2662{
2663 struct gsm_bts *bts = vty->index;
2664
Harald Welte4511d892010-04-18 15:51:20 +02002665 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002666 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2667 return CMD_WARNING;
2668 }
2669
2670 bts->gprs.nse.nsei = atoi(argv[0]);
2671
2672 return CMD_SUCCESS;
2673}
2674
Harald Welte8f0ed552010-05-11 21:53:49 +02002675#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2676 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002677
Harald Welte97a282b2010-03-14 15:37:43 +08002678DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2679 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002680 GPRS_TEXT NSVC_TEXT
2681 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002682 "GPRS NS VC Identifier")
2683{
2684 struct gsm_bts *bts = vty->index;
2685 int idx = atoi(argv[0]);
2686
Harald Welte4511d892010-04-18 15:51:20 +02002687 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002688 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2689 return CMD_WARNING;
2690 }
2691
Harald Welte97a282b2010-03-14 15:37:43 +08002692 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2693
2694 return CMD_SUCCESS;
2695}
2696
Harald Welteaf387632010-03-14 23:30:30 +08002697DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2698 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002699 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002700 "GPRS NS Local UDP Port\n"
2701 "GPRS NS Local UDP Port\n"
2702 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002703 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002704{
2705 struct gsm_bts *bts = vty->index;
2706 int idx = atoi(argv[0]);
2707
Harald Welte4511d892010-04-18 15:51:20 +02002708 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002709 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2710 return CMD_WARNING;
2711 }
2712
Harald Welteaf387632010-03-14 23:30:30 +08002713 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2714
2715 return CMD_SUCCESS;
2716}
2717
2718DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2719 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002720 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002721 "GPRS NS Remote UDP Port\n"
2722 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002723 "GPRS NS Remote UDP Port\n"
2724 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002725{
2726 struct gsm_bts *bts = vty->index;
2727 int idx = atoi(argv[0]);
2728
Harald Welte4511d892010-04-18 15:51:20 +02002729 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002730 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2731 return CMD_WARNING;
2732 }
2733
Harald Welteaf387632010-03-14 23:30:30 +08002734 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2735
2736 return CMD_SUCCESS;
2737}
2738
2739DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2740 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002741 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002742 "GPRS NS Remote IP Address\n"
2743 "GPRS NS Remote IP Address\n"
2744 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002745{
2746 struct gsm_bts *bts = vty->index;
2747 int idx = atoi(argv[0]);
2748 struct in_addr ia;
2749
Harald Welte4511d892010-04-18 15:51:20 +02002750 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002751 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2752 return CMD_WARNING;
2753 }
2754
Harald Welteaf387632010-03-14 23:30:30 +08002755 inet_aton(argv[1], &ia);
2756 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2757
2758 return CMD_SUCCESS;
2759}
2760
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002761DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002762 "paging free <-1-1024>",
2763 "Paging options\n"
2764 "Only page when having a certain amount of free slots\n"
2765 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002766{
2767 struct gsm_bts *bts = vty->index;
2768
2769 bts->paging.free_chans_need = atoi(argv[0]);
2770 return CMD_SUCCESS;
2771}
2772
Harald Welte615e9562010-05-11 23:50:21 +02002773DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2774 "gprs ns timer " NS_TIMERS " <0-255>",
2775 GPRS_TEXT "Network Service\n"
2776 "Network Service Timer\n"
2777 NS_TIMERS_HELP "Timer Value\n")
2778{
2779 struct gsm_bts *bts = vty->index;
2780 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2781 int val = atoi(argv[1]);
2782
2783 if (bts->gprs.mode == BTS_GPRS_NONE) {
2784 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2785 return CMD_WARNING;
2786 }
2787
2788 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2789 return CMD_WARNING;
2790
2791 bts->gprs.nse.timer[idx] = val;
2792
2793 return CMD_SUCCESS;
2794}
2795
2796#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 +02002797#define BSSGP_TIMERS_HELP \
2798 "Tbvc-block timeout\n" \
2799 "Tbvc-block retries\n" \
2800 "Tbvc-unblock retries\n" \
2801 "Tbvcc-reset timeout\n" \
2802 "Tbvc-reset retries\n" \
2803 "Tbvc-suspend timeout\n" \
2804 "Tbvc-suspend retries\n" \
2805 "Tbvc-resume timeout\n" \
2806 "Tbvc-resume retries\n" \
2807 "Tbvc-capa-update timeout\n" \
2808 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002809
2810DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2811 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2812 GPRS_TEXT "Cell / BSSGP\n"
2813 "Cell/BSSGP Timer\n"
2814 BSSGP_TIMERS_HELP "Timer Value\n")
2815{
2816 struct gsm_bts *bts = vty->index;
2817 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2818 int val = atoi(argv[1]);
2819
2820 if (bts->gprs.mode == BTS_GPRS_NONE) {
2821 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2822 return CMD_WARNING;
2823 }
2824
2825 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2826 return CMD_WARNING;
2827
2828 bts->gprs.cell.timer[idx] = val;
2829
2830 return CMD_SUCCESS;
2831}
2832
Harald Welte97a282b2010-03-14 15:37:43 +08002833DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2834 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002835 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002836 "GPRS Routing Area Code\n"
2837 "GPRS Routing Area Code\n"
2838 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002839{
2840 struct gsm_bts *bts = vty->index;
2841
Harald Welte4511d892010-04-18 15:51:20 +02002842 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002843 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2844 return CMD_WARNING;
2845 }
2846
Harald Welte97a282b2010-03-14 15:37:43 +08002847 bts->gprs.rac = atoi(argv[0]);
2848
2849 return CMD_SUCCESS;
2850}
2851
Max292ec582016-07-28 11:55:37 +02002852DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2853 "gprs control-ack-type-rach", GPRS_TEXT
2854 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2855 "four access bursts format instead of default RLC/MAC control block\n")
2856{
2857 struct gsm_bts *bts = vty->index;
2858
2859 if (bts->gprs.mode == BTS_GPRS_NONE) {
2860 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2861 return CMD_WARNING;
2862 }
2863
2864 bts->gprs.ctrl_ack_type_use_block = false;
2865
2866 return CMD_SUCCESS;
2867}
2868
2869DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2870 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2871 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2872 "four access bursts format instead of default RLC/MAC control block\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.ctrl_ack_type_use_block = true;
2882
2883 return CMD_SUCCESS;
2884}
2885
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002886DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2887 "gprs network-control-order (nc0|nc1|nc2)",
2888 GPRS_TEXT
2889 "GPRS Network Control Order\n"
2890 "MS controlled cell re-selection, no measurement reporting\n"
2891 "MS controlled cell re-selection, MS sends measurement reports\n"
2892 "Network controlled cell re-selection, MS sends measurement reports\n")
2893{
2894 struct gsm_bts *bts = vty->index;
2895
2896 if (bts->gprs.mode == BTS_GPRS_NONE) {
2897 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2898 return CMD_WARNING;
2899 }
2900
2901 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2902
2903 return CMD_SUCCESS;
2904}
2905
Harald Welte4511d892010-04-18 15:51:20 +02002906DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2907 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002908 GPRS_TEXT
2909 "GPRS Mode for this BTS\n"
2910 "GPRS Disabled on this BTS\n"
2911 "GPRS Enabled on this BTS\n"
2912 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002913{
2914 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002915 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002916
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002917 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002918 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2919 VTY_NEWLINE);
2920 return CMD_WARNING;
2921 }
2922
2923 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002924
2925 return CMD_SUCCESS;
2926}
2927
bhargava350533c2016-07-21 11:14:34 +05302928DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2929 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2930 "gprs 11bit_rach_support_for_egprs (0|1)",
2931 GPRS_TEXT "11 bit RACH options\n"
2932 "Disable 11 bit RACH for EGPRS\n"
2933 "Enable 11 bit RACH for EGPRS")
2934{
2935 struct gsm_bts *bts = vty->index;
2936
2937 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2938
2939 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2940 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2941 return CMD_WARNING;
2942 }
2943
2944 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2945 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2946 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2947 " enabled%s", VTY_NEWLINE);
2948 return CMD_WARNING;
2949 }
2950
2951 return CMD_SUCCESS;
2952}
2953
Harald Welte9fbff4a2010-07-30 11:50:09 +02002954#define SI_TEXT "System Information Messages\n"
2955#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)"
2956#define SI_TYPE_HELP "System Information Type 1\n" \
2957 "System Information Type 2\n" \
2958 "System Information Type 3\n" \
2959 "System Information Type 4\n" \
2960 "System Information Type 5\n" \
2961 "System Information Type 6\n" \
2962 "System Information Type 7\n" \
2963 "System Information Type 8\n" \
2964 "System Information Type 9\n" \
2965 "System Information Type 10\n" \
2966 "System Information Type 13\n" \
2967 "System Information Type 16\n" \
2968 "System Information Type 17\n" \
2969 "System Information Type 18\n" \
2970 "System Information Type 19\n" \
2971 "System Information Type 20\n" \
2972 "System Information Type 2bis\n" \
2973 "System Information Type 2ter\n" \
2974 "System Information Type 2quater\n" \
2975 "System Information Type 5bis\n" \
2976 "System Information Type 5ter\n"
2977
2978DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2979 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2980 SI_TEXT SI_TYPE_HELP
2981 "System Information Mode\n"
2982 "Static user-specified\n"
2983 "Dynamic, BSC-computed\n")
2984{
2985 struct gsm_bts *bts = vty->index;
2986 int type;
2987
2988 type = get_string_value(osmo_sitype_strs, argv[0]);
2989 if (type < 0) {
2990 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2991 return CMD_WARNING;
2992 }
2993
2994 if (!strcmp(argv[1], "static"))
2995 bts->si_mode_static |= (1 << type);
2996 else
2997 bts->si_mode_static &= ~(1 << type);
2998
2999 return CMD_SUCCESS;
3000}
3001
3002DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
3003 "system-information " SI_TYPE_TEXT " static HEXSTRING",
3004 SI_TEXT SI_TYPE_HELP
3005 "Static System Information filling\n"
3006 "Static user-specified SI content in HEX notation\n")
3007{
3008 struct gsm_bts *bts = vty->index;
3009 int rc, type;
3010
3011 type = get_string_value(osmo_sitype_strs, argv[0]);
3012 if (type < 0) {
3013 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
3014 return CMD_WARNING;
3015 }
3016
3017 if (!(bts->si_mode_static & (1 << type))) {
3018 vty_out(vty, "SI Type %s is not configured in static mode%s",
3019 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
3020 return CMD_WARNING;
3021 }
3022
Harald Welte290aaed2010-07-30 11:53:18 +02003023 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02003024 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02003025
3026 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02003027 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
3028 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02003029 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3030 return CMD_WARNING;
3031 }
3032
3033 /* Mark this SI as present */
3034 bts->si_valid |= (1 << type);
3035
3036 return CMD_SUCCESS;
3037}
3038
Harald Welte42def722017-01-13 00:10:32 +01003039DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
3040 "early-classmark-sending (allowed|forbidden)",
3041 "Early Classmark Sending\n"
3042 "Early Classmark Sending is allowed\n"
3043 "Early Classmark Sending is forbidden\n")
3044{
3045 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01003046
3047 if (!strcmp(argv[0], "allowed"))
3048 bts->early_classmark_allowed = true;
3049 else
3050 bts->early_classmark_allowed = false;
3051
3052 return CMD_SUCCESS;
3053}
3054
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01003055DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
3056 "early-classmark-sending-3g (allowed|forbidden)",
3057 "3G Early Classmark Sending\n"
3058 "3G Early Classmark Sending is allowed\n"
3059 "3G Early Classmark Sending is forbidden\n")
3060{
3061 struct gsm_bts *bts = vty->index;
3062
3063 if (!strcmp(argv[0], "allowed"))
3064 bts->early_classmark_allowed_3g = true;
3065 else
3066 bts->early_classmark_allowed_3g = false;
3067
3068 return CMD_SUCCESS;
3069}
3070
Harald Welte32c09622011-01-11 23:44:56 +01003071DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01003072 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01003073 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003074 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
3075 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01003076{
3077 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01003078 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01003079
Harald Welte64c07d22011-02-15 11:43:27 +01003080 switch (mode) {
3081 case NL_MODE_MANUAL_SI5SEP:
3082 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01003083 /* make sure we clear the current list when switching to
3084 * manual mode */
3085 if (bts->neigh_list_manual_mode == 0)
3086 memset(&bts->si_common.data.neigh_list, 0,
3087 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01003088 break;
3089 default:
3090 break;
3091 }
3092
3093 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01003094
3095 return CMD_SUCCESS;
3096}
3097
3098DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003099 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01003100 "Neighbor List\n" "Add to manual neighbor list\n"
3101 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
3102 "ARFCN of neighbor\n")
3103{
3104 struct gsm_bts *bts = vty->index;
3105 struct bitvec *bv = &bts->si_common.neigh_list;
3106 uint16_t arfcn = atoi(argv[1]);
3107
3108 if (!bts->neigh_list_manual_mode) {
3109 vty_out(vty, "%% Cannot configure neighbor list in "
3110 "automatic mode%s", VTY_NEWLINE);
3111 return CMD_WARNING;
3112 }
3113
3114 if (!strcmp(argv[0], "add"))
3115 bitvec_set_bit_pos(bv, arfcn, 1);
3116 else
3117 bitvec_set_bit_pos(bv, arfcn, 0);
3118
3119 return CMD_SUCCESS;
3120}
3121
Max70fdd242017-06-15 15:10:53 +02003122/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02003123DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01003124 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
3125 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
3126 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
3127 "Add to manual SI2quater neighbor list\n"
3128 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
3129 "threshold high bits\n" "threshold high bits\n"
3130 "threshold low bits\n" "threshold low bits (32 means NA)\n"
3131 "priority\n" "priority (8 means NA)\n"
3132 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
3133 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02003134{
3135 struct gsm_bts *bts = vty->index;
3136 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
3137 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01003138 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
3139 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02003140 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02003141
Max70fdd242017-06-15 15:10:53 +02003142 switch (r) {
3143 case 1:
3144 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
3145 thresh_hi, VTY_NEWLINE);
3146 break;
3147 case EARFCN_THRESH_LOW_INVALID:
3148 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
3149 thresh_lo, VTY_NEWLINE);
3150 break;
3151 case EARFCN_QRXLV_INVALID + 1:
3152 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
3153 qrx, VTY_NEWLINE);
3154 break;
3155 case EARFCN_PRIO_INVALID:
3156 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
3157 prio, VTY_NEWLINE);
3158 break;
3159 default:
3160 if (r < 0) {
3161 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
3162 return CMD_WARNING;
3163 }
Max59a1bf32016-04-15 16:04:46 +02003164 }
3165
Max70fdd242017-06-15 15:10:53 +02003166 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01003167 return CMD_SUCCESS;
3168
Maxf39d03a2017-05-12 17:00:30 +02003169 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02003170 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02003171 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01003172
Maxaafff962016-04-20 15:57:14 +02003173 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02003174}
3175
3176DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02003177 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02003178 "SI2quater Neighbor List\n"
3179 "SI2quater Neighbor List\n"
3180 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02003181 "EARFCN of neighbor\n"
3182 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02003183{
3184 struct gsm_bts *bts = vty->index;
3185 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02003186 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02003187 int r = osmo_earfcn_del(e, arfcn);
3188 if (r < 0) {
3189 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02003190 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02003191 return CMD_WARNING;
3192 }
3193
3194 return CMD_SUCCESS;
3195}
3196
Max26679e02016-04-20 15:57:13 +02003197DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02003198 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02003199 "SI2quater Neighbor List\n"
3200 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
3201 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
3202 "diversity bit\n")
3203{
3204 struct gsm_bts *bts = vty->index;
3205 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
3206
3207 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
3208 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02003209 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 +01003210 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02003211 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02003212 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
3213 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01003214 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02003215 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02003216 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02003217 return CMD_WARNING;
3218 }
3219
3220 return CMD_SUCCESS;
3221}
3222
3223DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02003224 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02003225 "SI2quater Neighbor List\n"
3226 "SI2quater Neighbor List\n"
3227 "Delete from SI2quater manual neighbor list\n"
3228 "UARFCN of neighbor\n"
3229 "UARFCN\n"
3230 "scrambling code\n")
3231{
3232 struct gsm_bts *bts = vty->index;
3233
3234 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
3235 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
3236 VTY_NEWLINE);
3237 return CMD_WARNING;
3238 }
3239
3240 return CMD_SUCCESS;
3241}
3242
Harald Welte64c07d22011-02-15 11:43:27 +01003243DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003244 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003245 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003246 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
3247 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
3248 "ARFCN of neighbor\n")
3249{
3250 struct gsm_bts *bts = vty->index;
3251 struct bitvec *bv = &bts->si_common.si5_neigh_list;
3252 uint16_t arfcn = atoi(argv[1]);
3253
3254 if (!bts->neigh_list_manual_mode) {
3255 vty_out(vty, "%% Cannot configure neighbor list in "
3256 "automatic mode%s", VTY_NEWLINE);
3257 return CMD_WARNING;
3258 }
3259
3260 if (!strcmp(argv[0], "add"))
3261 bitvec_set_bit_pos(bv, arfcn, 1);
3262 else
3263 bitvec_set_bit_pos(bv, arfcn, 0);
3264
3265 return CMD_SUCCESS;
3266}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003267
Harald Welte8254cf72017-05-29 13:42:19 +02003268DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3269 "pcu-socket PATH",
3270 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3271 "Path in the file system for the unix-domain PCU socket\n")
3272{
3273 struct gsm_bts *bts = vty->index;
3274 int rc;
3275
Harald Welte4a824ca2017-05-29 13:54:27 +02003276 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003277 pcu_sock_exit(bts);
3278 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3279 if (rc < 0) {
3280 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3281 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3282 return CMD_WARNING;
3283 }
3284
3285 return CMD_SUCCESS;
3286}
3287
Stefan Sperling6442e432018-02-06 14:44:54 +01003288DEFUN(cfg_bts_acc_ramping,
3289 cfg_bts_acc_ramping_cmd,
3290 "access-control-class-ramping",
3291 "Enable Access Control Class ramping\n")
3292{
3293 struct gsm_bts *bts = vty->index;
3294
Stefan Sperlingea333412018-04-10 16:36:54 +02003295 if (!acc_ramp_is_enabled(&bts->acc_ramp))
3296 acc_ramp_set_enabled(&bts->acc_ramp, true);
Stefan Sperling6442e432018-02-06 14:44:54 +01003297
Stefan Sperling60ecdef2018-04-10 17:55:08 +02003298 /*
3299 * ACC ramping takes effect either when the BTS reconnects RSL,
3300 * or when RF administrative state changes to 'unlocked'.
3301 */
Stefan Sperling6442e432018-02-06 14:44:54 +01003302 return CMD_SUCCESS;
3303}
3304
3305DEFUN(cfg_bts_no_acc_ramping, cfg_bts_no_acc_ramping_cmd,
3306 "no access-control-class-ramping",
3307 NO_STR
3308 "Disable Access Control Class ramping\n")
3309{
3310 struct gsm_bts *bts = vty->index;
3311
3312 if (acc_ramp_is_enabled(&bts->acc_ramp)) {
3313 acc_ramp_abort(&bts->acc_ramp);
Stefan Sperlingea333412018-04-10 16:36:54 +02003314 acc_ramp_set_enabled(&bts->acc_ramp, false);
Stefan Sperling6442e432018-02-06 14:44:54 +01003315 gsm_bts_set_system_infos(bts);
3316 }
3317
3318 return CMD_SUCCESS;
3319}
3320
3321DEFUN(cfg_bts_acc_ramping_step_interval,
3322 cfg_bts_acc_ramping_step_interval_cmd,
3323 "access-control-class-ramping-step-interval (<"
3324 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MIN) "-"
3325 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MAX) ">|dynamic)",
3326 "Configure Access Control Class ramping step interval\n"
3327 "Set a fixed step interval (in seconds)\n"
3328 "Use dynamic step interval based on BTS channel load\n")
3329{
3330 struct gsm_bts *bts = vty->index;
3331 bool dynamic = (strcmp(argv[0], "dynamic") == 0);
3332 int error;
3333
3334 if (dynamic) {
3335 acc_ramp_set_step_interval_dynamic(&bts->acc_ramp);
3336 return CMD_SUCCESS;
3337 }
3338
3339 error = acc_ramp_set_step_interval(&bts->acc_ramp, atoi(argv[0]));
3340 if (error != 0) {
3341 if (error == -ERANGE)
3342 vty_out(vty, "Unable to set ACC ramp step interval: value out of range%s", VTY_NEWLINE);
3343 else
3344 vty_out(vty, "Unable to set ACC ramp step interval: unknown error%s", VTY_NEWLINE);
3345 return CMD_WARNING;
3346 }
3347
3348 return CMD_SUCCESS;
3349}
3350
3351DEFUN(cfg_bts_acc_ramping_step_size,
3352 cfg_bts_acc_ramping_step_size_cmd,
3353 "access-control-class-ramping-step-size (<"
3354 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MIN) "-"
3355 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MAX) ">)",
3356 "Configure Access Control Class ramping step size\n"
3357 "Set the number of Access Control Classes to enable per ramping step\n")
3358{
3359 struct gsm_bts *bts = vty->index;
3360 int error;
3361
3362 error = acc_ramp_set_step_size(&bts->acc_ramp, atoi(argv[0]));
3363 if (error != 0) {
3364 if (error == -ERANGE)
3365 vty_out(vty, "Unable to set ACC ramp step size: value out of range%s", VTY_NEWLINE);
3366 else
3367 vty_out(vty, "Unable to set ACC ramp step size: unknown error%s", VTY_NEWLINE);
3368 return CMD_WARNING;
3369 }
3370
3371 return CMD_SUCCESS;
3372}
3373
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003374#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3375
3376DEFUN(cfg_bts_excl_rf_lock,
3377 cfg_bts_excl_rf_lock_cmd,
3378 "rf-lock-exclude",
3379 EXCL_RFLOCK_STR)
3380{
3381 struct gsm_bts *bts = vty->index;
3382 bts->excl_from_rf_lock = 1;
3383 return CMD_SUCCESS;
3384}
3385
3386DEFUN(cfg_bts_no_excl_rf_lock,
3387 cfg_bts_no_excl_rf_lock_cmd,
3388 "no rf-lock-exclude",
3389 NO_STR EXCL_RFLOCK_STR)
3390{
3391 struct gsm_bts *bts = vty->index;
3392 bts->excl_from_rf_lock = 0;
3393 return CMD_SUCCESS;
3394}
3395
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003396#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3397
3398DEFUN(cfg_bts_force_comb_si,
3399 cfg_bts_force_comb_si_cmd,
3400 "force-combined-si",
3401 FORCE_COMB_SI_STR)
3402{
3403 struct gsm_bts *bts = vty->index;
3404 bts->force_combined_si = 1;
3405 return CMD_SUCCESS;
3406}
3407
3408DEFUN(cfg_bts_no_force_comb_si,
3409 cfg_bts_no_force_comb_si_cmd,
3410 "no force-combined-si",
3411 NO_STR FORCE_COMB_SI_STR)
3412{
3413 struct gsm_bts *bts = vty->index;
3414 bts->force_combined_si = 0;
3415 return CMD_SUCCESS;
3416}
3417
Andreas Eversberga83d5112013-12-07 18:32:28 +01003418static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3419{
3420 struct gsm_bts *bts = vty->index;
3421 struct bts_codec_conf *codec = &bts->codec;
3422 int i;
3423
3424 codec->hr = 0;
3425 codec->efr = 0;
3426 codec->amr = 0;
3427 for (i = 0; i < argc; i++) {
3428 if (!strcmp(argv[i], "hr"))
3429 codec->hr = 1;
3430 if (!strcmp(argv[i], "efr"))
3431 codec->efr = 1;
3432 if (!strcmp(argv[i], "amr"))
3433 codec->amr = 1;
3434 }
3435}
3436
3437#define CODEC_PAR_STR " (hr|efr|amr)"
3438#define CODEC_HELP_STR "Half Rate\n" \
3439 "Enhanced Full Rate\nAdaptive Multirate\n"
3440
3441DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3442 "codec-support fr",
3443 "Codec Support settings\nFullrate\n")
3444{
3445 _get_codec_from_arg(vty, 0, argv);
3446 return CMD_SUCCESS;
3447}
3448
3449DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3450 "codec-support fr" CODEC_PAR_STR,
3451 "Codec Support settings\nFullrate\n"
3452 CODEC_HELP_STR)
3453{
3454 _get_codec_from_arg(vty, 1, argv);
3455 return CMD_SUCCESS;
3456}
3457
3458DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3459 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3460 "Codec Support settings\nFullrate\n"
3461 CODEC_HELP_STR CODEC_HELP_STR)
3462{
3463 _get_codec_from_arg(vty, 2, argv);
3464 return CMD_SUCCESS;
3465}
3466
3467DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3468 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3469 "Codec Support settings\nFullrate\n"
3470 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3471{
3472 _get_codec_from_arg(vty, 3, argv);
3473 return CMD_SUCCESS;
3474}
3475
3476DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3477 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3478 "Codec Support settings\nFullrate\n"
3479 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3480{
3481 _get_codec_from_arg(vty, 4, argv);
3482 return CMD_SUCCESS;
3483}
3484
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003485DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3486 "depends-on-bts <0-255>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003487 "This BTS can only be started if another one is up\n"
3488 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003489{
3490 struct gsm_bts *bts = vty->index;
3491 struct gsm_bts *other_bts;
3492 int dep = atoi(argv[0]);
3493
3494
3495 if (!is_ipaccess_bts(bts)) {
3496 vty_out(vty, "This feature is only available for IP systems.%s",
3497 VTY_NEWLINE);
3498 return CMD_WARNING;
3499 }
3500
3501 other_bts = gsm_bts_num(bts->network, dep);
3502 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3503 vty_out(vty, "This feature is only available for IP systems.%s",
3504 VTY_NEWLINE);
3505 return CMD_WARNING;
3506 }
3507
3508 if (dep >= bts->nr) {
3509 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3510 VTY_NEWLINE);
3511 return CMD_WARNING;
3512 }
3513
3514 bts_depend_mark(bts, dep);
3515 return CMD_SUCCESS;
3516}
3517
3518DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3519 "depeneds-on-bts <0-255>",
3520 NO_STR "This BTS can only be started if another one is up\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003521 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003522{
3523 struct gsm_bts *bts = vty->index;
3524 int dep = atoi(argv[0]);
3525
3526 bts_depend_clear(bts, dep);
3527 return CMD_SUCCESS;
3528}
3529
Andreas Eversberg73266522014-01-19 11:47:44 +01003530#define AMR_TEXT "Adaptive Multi Rate settings\n"
3531#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3532#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3533 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3534#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3535#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3536
3537static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3538{
3539 struct gsm_bts *bts = vty->index;
3540 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3541 struct gsm48_multi_rate_conf *mr_conf =
3542 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3543 int i;
3544
3545 mr->gsm48_ie[1] = 0;
3546 for (i = 0; i < argc; i++)
3547 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3548 mr_conf->icmi = 0;
3549}
3550
3551static void get_amr_th_from_arg(struct vty *vty, int argc, 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;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003555 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003556 int i;
3557
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003558 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3559 for (i = 0; i < argc - 1; i++)
3560 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003561}
3562
3563static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3564{
3565 struct gsm_bts *bts = vty->index;
3566 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003567 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003568 int i;
3569
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003570 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3571 for (i = 0; i < argc - 1; i++)
3572 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003573}
3574
3575static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3576{
3577 struct gsm_bts *bts = vty->index;
3578 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3579 struct gsm48_multi_rate_conf *mr_conf =
3580 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3581 int num = 0, i;
3582
3583 for (i = 0; i < ((full) ? 8 : 6); i++) {
3584 if ((mr->gsm48_ie[1] & (1 << i))) {
3585 num++;
3586 }
3587 }
3588
3589 if (argv[0][0] == 'a' || num == 0)
3590 mr_conf->icmi = 0;
3591 else {
3592 mr_conf->icmi = 1;
3593 if (num < atoi(argv[0]))
3594 mr_conf->smod = num - 1;
3595 else
3596 mr_conf->smod = atoi(argv[0]) - 1;
3597 }
3598}
3599
3600#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3601#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3602 "10,2k\n12,2k\n"
3603
3604#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3605#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3606
3607#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3608#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3609
3610DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3611 "amr tch-f modes" AMR_TCHF_PAR_STR,
3612 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3613 AMR_TCHF_HELP_STR)
3614{
3615 get_amr_from_arg(vty, 1, argv, 1);
3616 return CMD_SUCCESS;
3617}
3618
3619DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3620 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3621 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3622 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3623{
3624 get_amr_from_arg(vty, 2, argv, 1);
3625 return CMD_SUCCESS;
3626}
3627
3628DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3629 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3630 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3631 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3632{
3633 get_amr_from_arg(vty, 3, argv, 1);
3634 return CMD_SUCCESS;
3635}
3636
3637DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3638 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3639 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3640 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3641{
3642 get_amr_from_arg(vty, 4, argv, 1);
3643 return CMD_SUCCESS;
3644}
3645
3646DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3647 "amr tch-f start-mode (auto|1|2|3|4)",
3648 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3649{
3650 get_amr_start_from_arg(vty, argv, 1);
3651 return CMD_SUCCESS;
3652}
3653
3654DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3655 "amr tch-f threshold (ms|bts) <0-63>",
3656 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3657 AMR_TH_HELP_STR)
3658{
3659 get_amr_th_from_arg(vty, 2, argv, 1);
3660 return CMD_SUCCESS;
3661}
3662
3663DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3664 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3665 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3666 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3667{
3668 get_amr_th_from_arg(vty, 3, argv, 1);
3669 return CMD_SUCCESS;
3670}
3671
3672DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3673 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3674 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3675 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3676{
3677 get_amr_th_from_arg(vty, 4, argv, 1);
3678 return CMD_SUCCESS;
3679}
3680
3681DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3682 "amr tch-f hysteresis (ms|bts) <0-15>",
3683 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3684 AMR_HY_HELP_STR)
3685{
3686 get_amr_hy_from_arg(vty, 2, argv, 1);
3687 return CMD_SUCCESS;
3688}
3689
3690DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3691 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3692 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3693 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3694{
3695 get_amr_hy_from_arg(vty, 3, argv, 1);
3696 return CMD_SUCCESS;
3697}
3698
3699DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3700 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3701 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3702 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3703{
3704 get_amr_hy_from_arg(vty, 4, argv, 1);
3705 return CMD_SUCCESS;
3706}
3707
3708DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3709 "amr tch-h modes" AMR_TCHH_PAR_STR,
3710 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3711 AMR_TCHH_HELP_STR)
3712{
3713 get_amr_from_arg(vty, 1, argv, 0);
3714 return CMD_SUCCESS;
3715}
3716
3717DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3718 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3719 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3720 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3721{
3722 get_amr_from_arg(vty, 2, argv, 0);
3723 return CMD_SUCCESS;
3724}
3725
3726DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3727 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3728 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3729 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3730{
3731 get_amr_from_arg(vty, 3, argv, 0);
3732 return CMD_SUCCESS;
3733}
3734
3735DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3736 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3737 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3738 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3739{
3740 get_amr_from_arg(vty, 4, argv, 0);
3741 return CMD_SUCCESS;
3742}
3743
3744DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3745 "amr tch-h start-mode (auto|1|2|3|4)",
3746 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3747{
3748 get_amr_start_from_arg(vty, argv, 0);
3749 return CMD_SUCCESS;
3750}
3751
3752DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3753 "amr tch-h threshold (ms|bts) <0-63>",
3754 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3755 AMR_TH_HELP_STR)
3756{
3757 get_amr_th_from_arg(vty, 2, argv, 0);
3758 return CMD_SUCCESS;
3759}
3760
3761DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3762 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3763 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3764 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3765{
3766 get_amr_th_from_arg(vty, 3, argv, 0);
3767 return CMD_SUCCESS;
3768}
3769
3770DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3771 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3772 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3773 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3774{
3775 get_amr_th_from_arg(vty, 4, argv, 0);
3776 return CMD_SUCCESS;
3777}
3778
3779DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3780 "amr tch-h hysteresis (ms|bts) <0-15>",
3781 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3782 AMR_HY_HELP_STR)
3783{
3784 get_amr_hy_from_arg(vty, 2, argv, 0);
3785 return CMD_SUCCESS;
3786}
3787
3788DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3789 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3790 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3791 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3792{
3793 get_amr_hy_from_arg(vty, 3, argv, 0);
3794 return CMD_SUCCESS;
3795}
3796
3797DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3798 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3799 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3800 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3801{
3802 get_amr_hy_from_arg(vty, 4, argv, 0);
3803 return CMD_SUCCESS;
3804}
3805
Harald Welte8f0ed552010-05-11 21:53:49 +02003806#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003807
Harald Welte5258fc42009-03-28 19:07:53 +00003808/* per TRX configuration */
3809DEFUN(cfg_trx,
3810 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003811 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003812 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003813 "Select a TRX to configure")
3814{
3815 int trx_nr = atoi(argv[0]);
3816 struct gsm_bts *bts = vty->index;
3817 struct gsm_bts_trx *trx;
3818
Harald Weltee441d9c2009-06-21 16:17:15 +02003819 if (trx_nr > bts->num_trx) {
3820 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3821 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003822 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003823 } else if (trx_nr == bts->num_trx) {
3824 /* we need to allocate a new one */
3825 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003826 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003827 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003828
Harald Weltee441d9c2009-06-21 16:17:15 +02003829 if (!trx)
3830 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003831
3832 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003833 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003834 vty->node = TRX_NODE;
3835
3836 return CMD_SUCCESS;
3837}
3838
3839DEFUN(cfg_trx_arfcn,
3840 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003841 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003842 "Set the ARFCN for this TRX\n"
3843 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003844{
3845 int arfcn = atoi(argv[0]);
3846 struct gsm_bts_trx *trx = vty->index;
3847
3848 /* FIXME: check if this ARFCN is supported by this TRX */
3849
3850 trx->arfcn = arfcn;
3851
3852 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3853 /* FIXME: use OML layer to update the ARFCN */
3854 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3855
3856 return CMD_SUCCESS;
3857}
3858
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003859DEFUN(cfg_trx_nominal_power,
3860 cfg_trx_nominal_power_cmd,
3861 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003862 "Nominal TRX RF Power in dBm\n"
3863 "Nominal TRX RF Power in dBm\n"
3864 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003865{
3866 struct gsm_bts_trx *trx = vty->index;
3867
3868 trx->nominal_power = atoi(argv[0]);
3869
3870 return CMD_SUCCESS;
3871}
3872
Harald Weltefcd24452009-06-20 18:15:19 +02003873DEFUN(cfg_trx_max_power_red,
3874 cfg_trx_max_power_red_cmd,
3875 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003876 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003877 "Reduction of maximum BS RF Power in dB\n")
3878{
3879 int maxpwr_r = atoi(argv[0]);
3880 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003881 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003882
3883 /* FIXME: check if our BTS type supports more than 12 */
3884 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3885 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3886 maxpwr_r, VTY_NEWLINE);
3887 return CMD_WARNING;
3888 }
3889 if (maxpwr_r & 1) {
3890 vty_out(vty, "%% Power %d dB is not an even value%s",
3891 maxpwr_r, VTY_NEWLINE);
3892 return CMD_WARNING;
3893 }
3894
3895 trx->max_power_red = maxpwr_r;
3896
3897 /* FIXME: make sure we update this using OML */
3898
3899 return CMD_SUCCESS;
3900}
3901
Harald Welte42581822009-08-08 16:12:58 +02003902DEFUN(cfg_trx_rsl_e1,
3903 cfg_trx_rsl_e1_cmd,
3904 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003905 "RSL Parameters\n"
3906 "E1/T1 interface to be used for RSL\n"
3907 "E1/T1 interface to be used for RSL\n"
3908 "E1/T1 Line Number to be used for RSL\n"
3909 "E1/T1 Timeslot to be used for RSL\n"
3910 "E1/T1 Timeslot to be used for RSL\n"
3911 "E1/T1 Sub-slot to be used for RSL\n"
3912 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3913 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3914 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3915 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3916 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003917{
3918 struct gsm_bts_trx *trx = vty->index;
3919
3920 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3921
3922 return CMD_SUCCESS;
3923}
3924
3925DEFUN(cfg_trx_rsl_e1_tei,
3926 cfg_trx_rsl_e1_tei_cmd,
3927 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003928 "RSL Parameters\n"
3929 "Set the TEI to be used for RSL\n"
3930 "Set the TEI to be used for RSL\n"
3931 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003932{
3933 struct gsm_bts_trx *trx = vty->index;
3934
3935 trx->rsl_tei = atoi(argv[0]);
3936
3937 return CMD_SUCCESS;
3938}
3939
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003940DEFUN(cfg_trx_rf_locked,
3941 cfg_trx_rf_locked_cmd,
3942 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003943 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3944 "TRX is NOT RF locked (active)\n"
3945 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003946{
3947 int locked = atoi(argv[0]);
3948 struct gsm_bts_trx *trx = vty->index;
3949
Maxbe356ed2017-09-07 19:10:09 +02003950 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003951 return CMD_SUCCESS;
3952}
Harald Welte42581822009-08-08 16:12:58 +02003953
Harald Welte5258fc42009-03-28 19:07:53 +00003954/* per TS configuration */
3955DEFUN(cfg_ts,
3956 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003957 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003958 "Select a Timeslot to configure\n"
3959 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003960{
3961 int ts_nr = atoi(argv[0]);
3962 struct gsm_bts_trx *trx = vty->index;
3963 struct gsm_bts_trx_ts *ts;
3964
3965 if (ts_nr >= TRX_NR_TS) {
3966 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3967 TRX_NR_TS, VTY_NEWLINE);
3968 return CMD_WARNING;
3969 }
3970
3971 ts = &trx->ts[ts_nr];
3972
3973 vty->index = ts;
3974 vty->node = TS_NODE;
3975
3976 return CMD_SUCCESS;
3977}
3978
Harald Weltea6fd58e2009-08-07 00:25:23 +02003979DEFUN(cfg_ts_pchan,
3980 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003981 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003982 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003983{
3984 struct gsm_bts_trx_ts *ts = vty->index;
3985 int pchanc;
3986
3987 pchanc = gsm_pchan_parse(argv[0]);
3988 if (pchanc < 0)
3989 return CMD_WARNING;
3990
3991 ts->pchan = pchanc;
3992
3993 return CMD_SUCCESS;
3994}
3995
3996/* used for backwards compatibility with old config files that still
3997 * have uppercase pchan type names */
3998DEFUN_HIDDEN(cfg_ts_pchan_compat,
3999 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02004000 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01004001 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02004002{
4003 struct gsm_bts_trx_ts *ts = vty->index;
4004 int pchanc;
4005
4006 pchanc = gsm_pchan_parse(argv[0]);
4007 if (pchanc < 0)
4008 return CMD_WARNING;
4009
4010 ts->pchan = pchanc;
4011
4012 return CMD_SUCCESS;
4013}
4014
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004015
4016
Harald Welte135a6482011-05-30 12:09:13 +02004017DEFUN(cfg_ts_tsc,
4018 cfg_ts_tsc_cmd,
4019 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02004020 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02004021{
4022 struct gsm_bts_trx_ts *ts = vty->index;
4023
Philipp Maier8c498fc2018-02-21 13:24:36 +01004024 if (!osmo_bts_has_feature(&ts->trx->bts->model->features, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01004025 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
4026 "falling back to BCC%s", VTY_NEWLINE);
4027 ts->tsc = -1;
4028 return CMD_WARNING;
4029 }
4030
Harald Welte135a6482011-05-30 12:09:13 +02004031 ts->tsc = atoi(argv[0]);
4032
4033 return CMD_SUCCESS;
4034}
4035
Harald Weltea39b0f22010-06-14 22:26:10 +02004036#define HOPPING_STR "Configure frequency hopping\n"
4037
4038DEFUN(cfg_ts_hopping,
4039 cfg_ts_hopping_cmd,
4040 "hopping enabled (0|1)",
4041 HOPPING_STR "Enable or disable frequency hopping\n"
4042 "Disable frequency hopping\n" "Enable frequency hopping\n")
4043{
4044 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02004045 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02004046
Philipp Maier8c498fc2018-02-21 13:24:36 +01004047 if (enabled && !osmo_bts_has_feature(&ts->trx->bts->model->features, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02004048 vty_out(vty, "BTS model does not support hopping%s",
4049 VTY_NEWLINE);
4050 return CMD_WARNING;
4051 }
4052
4053 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02004054
4055 return CMD_SUCCESS;
4056}
4057
Harald Welte6e0cd042009-09-12 13:05:33 +02004058DEFUN(cfg_ts_hsn,
4059 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02004060 "hopping sequence-number <0-63>",
4061 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02004062 "Which hopping sequence to use for this channel\n"
4063 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004064{
4065 struct gsm_bts_trx_ts *ts = vty->index;
4066
4067 ts->hopping.hsn = atoi(argv[0]);
4068
4069 return CMD_SUCCESS;
4070}
4071
4072DEFUN(cfg_ts_maio,
4073 cfg_ts_maio_cmd,
4074 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02004075 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02004076 "Which hopping MAIO to use for this channel\n"
4077 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004078{
4079 struct gsm_bts_trx_ts *ts = vty->index;
4080
4081 ts->hopping.maio = atoi(argv[0]);
4082
4083 return CMD_SUCCESS;
4084}
4085
4086DEFUN(cfg_ts_arfcn_add,
4087 cfg_ts_arfcn_add_cmd,
4088 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02004089 HOPPING_STR "Configure hopping ARFCN list\n"
4090 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004091{
4092 struct gsm_bts_trx_ts *ts = vty->index;
4093 int arfcn = atoi(argv[0]);
4094
Harald Weltea39b0f22010-06-14 22:26:10 +02004095 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
4096
Harald Welte6e0cd042009-09-12 13:05:33 +02004097 return CMD_SUCCESS;
4098}
4099
4100DEFUN(cfg_ts_arfcn_del,
4101 cfg_ts_arfcn_del_cmd,
4102 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02004103 HOPPING_STR "Configure hopping ARFCN list\n"
4104 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004105{
4106 struct gsm_bts_trx_ts *ts = vty->index;
4107 int arfcn = atoi(argv[0]);
4108
Harald Weltea39b0f22010-06-14 22:26:10 +02004109 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
4110
Harald Welte6e0cd042009-09-12 13:05:33 +02004111 return CMD_SUCCESS;
4112}
4113
Harald Weltea6fd58e2009-08-07 00:25:23 +02004114DEFUN(cfg_ts_e1_subslot,
4115 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02004116 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02004117 "E1/T1 channel connected to this on-air timeslot\n"
4118 "E1/T1 channel connected to this on-air timeslot\n"
4119 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02004120 "E1/T1 timeslot connected to this on-air timeslot\n"
4121 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02004122 "E1/T1 sub-slot connected to this on-air timeslot\n"
4123 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
4124 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
4125 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
4126 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
4127 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02004128{
4129 struct gsm_bts_trx_ts *ts = vty->index;
4130
Harald Welte42581822009-08-08 16:12:58 +02004131 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004132
4133 return CMD_SUCCESS;
4134}
Harald Welte5258fc42009-03-28 19:07:53 +00004135
Harald Welte4f10c252010-05-16 21:47:13 +02004136void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
4137{
Harald Weltecf9d4312017-12-13 23:17:16 +01004138 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02004139 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01004140 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02004141 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02004142}
4143
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004144DEFUN(drop_bts,
4145 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02004146 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02004147 "Debug/Simulation command to drop Abis/IP BTS\n"
4148 "Debug/Simulation command to drop Abis/IP BTS\n"
4149 "Debug/Simulation command to drop Abis/IP BTS\n"
4150 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004151{
4152 struct gsm_network *gsmnet;
4153 struct gsm_bts_trx *trx;
4154 struct gsm_bts *bts;
4155 unsigned int bts_nr;
4156
4157 gsmnet = gsmnet_from_vty(vty);
4158
4159 bts_nr = atoi(argv[0]);
4160 if (bts_nr >= gsmnet->num_bts) {
4161 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4162 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4163 return CMD_WARNING;
4164 }
4165
4166 bts = gsm_bts_num(gsmnet, bts_nr);
4167 if (!bts) {
4168 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4169 return CMD_WARNING;
4170 }
4171
4172 if (!is_ipaccess_bts(bts)) {
4173 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
4174 return CMD_WARNING;
4175 }
4176
4177
4178 /* close all connections */
4179 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004180 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004181 } else if (strcmp(argv[1], "rsl") == 0) {
4182 /* close all rsl connections */
4183 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004184 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004185 }
4186 } else {
4187 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
4188 return CMD_WARNING;
4189 }
4190
4191 return CMD_SUCCESS;
4192}
4193
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004194DEFUN(restart_bts, restart_bts_cmd,
4195 "restart-bts <0-65535>",
4196 "Restart ip.access nanoBTS through OML\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004197 BTS_NR_STR)
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004198{
4199 struct gsm_network *gsmnet;
4200 struct gsm_bts_trx *trx;
4201 struct gsm_bts *bts;
4202 unsigned int bts_nr;
4203
4204 gsmnet = gsmnet_from_vty(vty);
4205
4206 bts_nr = atoi(argv[0]);
4207 if (bts_nr >= gsmnet->num_bts) {
4208 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4209 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4210 return CMD_WARNING;
4211 }
4212
4213 bts = gsm_bts_num(gsmnet, bts_nr);
4214 if (!bts) {
4215 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4216 return CMD_WARNING;
4217 }
4218
4219 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
4220 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
4221 VTY_NEWLINE);
4222 return CMD_WARNING;
4223 }
4224
4225 /* go from last TRX to c0 */
4226 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4227 abis_nm_ipaccess_restart(trx);
4228
4229 return CMD_SUCCESS;
4230}
4231
Harald Welte8e2e22f2017-07-10 20:25:10 +02004232DEFUN(bts_resend, bts_resend_cmd,
4233 "bts <0-255> resend-system-information",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004234 "BTS Specific Commands\n" BTS_NR_STR
Harald Welte8e2e22f2017-07-10 20:25:10 +02004235 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
4236{
4237 struct gsm_network *gsmnet;
4238 struct gsm_bts_trx *trx;
4239 struct gsm_bts *bts;
4240 unsigned int bts_nr;
4241
4242 gsmnet = gsmnet_from_vty(vty);
4243
4244 bts_nr = atoi(argv[0]);
4245 if (bts_nr >= gsmnet->num_bts) {
4246 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4247 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4248 return CMD_WARNING;
4249 }
4250
4251 bts = gsm_bts_num(gsmnet, bts_nr);
4252 if (!bts) {
4253 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4254 return CMD_WARNING;
4255 }
4256
4257 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4258 gsm_bts_trx_set_system_infos(trx);
4259
4260 return CMD_SUCCESS;
4261}
4262
4263
Harald Welte30f1f372014-12-28 15:00:45 +01004264DEFUN(smscb_cmd, smscb_cmd_cmd,
4265 "bts <0-255> smscb-command <1-4> HEXSTRING",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004266 "BTS related commands\n" BTS_NR_STR
Harald Welte30f1f372014-12-28 15:00:45 +01004267 "SMS Cell Broadcast\n" "Last Valid Block\n"
4268 "Hex Encoded SMSCB message (up to 88 octets)\n")
4269{
4270 struct gsm_bts *bts;
4271 int bts_nr = atoi(argv[0]);
4272 int last_block = atoi(argv[1]);
4273 struct rsl_ie_cb_cmd_type cb_cmd;
4274 uint8_t buf[88];
4275 int rc;
4276
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02004277 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01004278 if (!bts) {
4279 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4280 return CMD_WARNING;
4281 }
4282 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
4283 if (rc < 0 || rc > sizeof(buf)) {
4284 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
4285 return CMD_WARNING;
4286 }
4287
4288 cb_cmd.spare = 0;
4289 cb_cmd.def_bcast = 0;
4290 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
4291
4292 switch (last_block) {
4293 case 1:
4294 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
4295 break;
4296 case 2:
4297 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
4298 break;
4299 case 3:
4300 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
4301 break;
4302 case 4:
4303 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
4304 break;
Vadim Yanitskiy56dec0c2018-03-06 17:18:25 +07004305 default:
4306 vty_out(vty, "Error parsing LASTBLOCK%s", VTY_NEWLINE);
4307 return CMD_WARNING;
Harald Welte30f1f372014-12-28 15:00:45 +01004308 }
4309
4310 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
4311
4312 return CMD_SUCCESS;
4313}
4314
Harald Welte7fe00fb2017-05-27 14:09:50 +02004315/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02004316static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
4317 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02004318{
Harald Welte645eb622017-05-27 15:52:58 +02004319 int bts_nr = atoi(bts_str);
4320 int trx_nr = atoi(trx_str);
4321 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004322 struct gsm_bts *bts;
4323 struct gsm_bts_trx *trx;
4324 struct gsm_bts_trx_ts *ts;
4325
4326 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
4327 if (!bts) {
4328 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4329 return NULL;
4330 }
4331
4332 trx = gsm_bts_trx_num(bts, trx_nr);
4333 if (!trx) {
4334 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
4335 return NULL;
4336 }
4337
4338 ts = &trx->ts[ts_nr];
4339
4340 return ts;
4341}
Harald Welte30f1f372014-12-28 15:00:45 +01004342
Harald Welted0d2b0b2010-12-23 13:18:07 +01004343DEFUN(pdch_act, pdch_act_cmd,
4344 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
Harald Welte0bfd8d92018-02-12 18:06:53 +01004345 BTS_NR_TRX_TS_STR2
4346 "Packet Data Channel\n"
Harald Welted0d2b0b2010-12-23 13:18:07 +01004347 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4348 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4349{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004350 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004351 int activate;
4352
Harald Welte645eb622017-05-27 15:52:58 +02004353 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004354 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004355 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004356
Harald Welte7fe00fb2017-05-27 14:09:50 +02004357 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004358 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4359 VTY_NEWLINE);
4360 return CMD_WARNING;
4361 }
4362
Harald Welted0d2b0b2010-12-23 13:18:07 +01004363 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4364 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004365 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004366 return CMD_WARNING;
4367 }
4368
4369 if (!strcmp(argv[3], "activate"))
4370 activate = 1;
4371 else
4372 activate = 0;
4373
4374 rsl_ipacc_pdch_activate(ts, activate);
4375
4376 return CMD_SUCCESS;
4377
4378}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004379
Harald Welte2abd5e12017-05-27 14:10:40 +02004380/* determine the logical channel type based on the physical channel type */
4381static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4382{
4383 switch (pchan) {
4384 case GSM_PCHAN_TCH_F:
4385 return GSM_LCHAN_TCH_F;
4386 case GSM_PCHAN_TCH_H:
4387 return GSM_LCHAN_TCH_H;
4388 case GSM_PCHAN_SDCCH8_SACCH8C:
4389 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4390 case GSM_PCHAN_CCCH_SDCCH4:
4391 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4392 return GSM_LCHAN_SDCCH;
4393 default:
4394 return -1;
4395 }
4396}
4397
4398/* configure the lchan for a single AMR mode (as specified) */
4399static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4400{
4401 struct amr_multirate_conf mr;
4402 struct gsm48_multi_rate_conf *mr_conf;
4403 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4404
4405 if (amr_mode > 7)
4406 return -1;
4407
4408 memset(&mr, 0, sizeof(mr));
4409 mr_conf->ver = 1;
4410 /* bit-mask of supported modes, only one bit is set. Reflects
4411 * Figure 10.5.2.47a where there are no thershold and only a
4412 * single mode */
4413 mr.gsm48_ie[1] = 1 << amr_mode;
4414
4415 mr.ms_mode[0].mode = amr_mode;
4416 mr.bts_mode[0].mode = amr_mode;
4417
4418 /* encode this configuration into the lchan for both uplink and
4419 * downlink direction */
4420 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4421 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4422
4423 return 0;
4424}
4425
4426/* Debug/Measurement command to activate a given logical channel
4427 * manually in a given mode/codec. This is useful for receiver
4428 * performance testing (FER/RBER/...) */
4429DEFUN(lchan_act, lchan_act_cmd,
4430 "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 +01004431 BTS_NR_TRX_TS_SS_STR2
Harald Welte2abd5e12017-05-27 14:10:40 +02004432 "Manual Channel Activation (e.g. for BER test)\n"
4433 "Manual Channel Deactivation (e.g. for BER test)\n"
4434 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4435{
4436 struct gsm_bts_trx_ts *ts;
4437 struct gsm_lchan *lchan;
4438 int ss_nr = atoi(argv[3]);
4439 const char *act_str = argv[4];
4440 const char *codec_str = argv[5];
4441 int activate;
4442
4443 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4444 if (!ts)
4445 return CMD_WARNING;
4446
4447 lchan = &ts->lchan[ss_nr];
4448
4449 if (!strcmp(act_str, "activate"))
4450 activate = 1;
4451 else
4452 activate = 0;
4453
4454 if (ss_nr >= ts_subslots(ts)) {
4455 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4456 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4457 return CMD_WARNING;
4458 }
4459
4460 if (activate) {
4461 int lchan_t;
4462 if (lchan->state != LCHAN_S_NONE) {
4463 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4464 return CMD_WARNING;
4465 }
4466 lchan_t = lchan_type_by_pchan(ts->pchan);
4467 if (lchan_t < 0)
4468 return CMD_WARNING;
4469 /* configure the lchan */
4470 lchan->type = lchan_t;
4471 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4472 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4473 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4474 else if (!strcmp(codec_str, "efr"))
4475 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4476 else if (!strcmp(codec_str, "amr")) {
4477 int amr_mode;
4478 if (argc < 7) {
4479 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4480 return CMD_WARNING;
4481 }
4482 amr_mode = atoi(argv[6]);
4483 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4484 lchan_set_single_amr_mode(lchan, amr_mode);
4485 }
4486 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4487 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4488 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004489 } else {
4490 rsl_direct_rf_release(lchan);
4491 }
4492
4493 return CMD_SUCCESS;
4494}
4495
Harald Welte3f86c522017-05-27 15:53:28 +02004496DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4497 "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 +01004498 BTS_NR_TRX_TS_SS_STR2
Harald Welte3f86c522017-05-27 15:53:28 +02004499 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4500{
4501 struct gsm_bts_trx_ts *ts;
4502 struct gsm_lchan *lchan;
4503 int ss_nr = atoi(argv[3]);
4504 int port = atoi(argv[5]);
4505 struct in_addr ia;
4506 inet_aton(argv[4], &ia);
4507
4508 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4509 if (!ts)
4510 return CMD_WARNING;
4511
4512 lchan = &ts->lchan[ss_nr];
4513
4514 if (ss_nr >= ts_subslots(ts)) {
4515 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4516 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4517 return CMD_WARNING;
4518 }
4519
4520 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4521 inet_ntoa(ia), port, VTY_NEWLINE);
4522 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4523 return CMD_SUCCESS;
4524}
Harald Welteb71147a2017-07-18 19:11:49 +02004525
4526DEFUN(ctrl_trap, ctrl_trap_cmd,
4527 "ctrl-interface generate-trap TRAP VALUE",
4528 "Commands related to the CTRL Interface\n"
4529 "Generate a TRAP for test purpose\n"
4530 "Identity/Name of the TRAP variable\n"
4531 "Value of the TRAP variable\n")
4532{
4533 struct gsm_network *net = gsmnet_from_vty(vty);
4534
4535 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4536 return CMD_SUCCESS;
4537}
4538
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004539#define NETWORK_STR "Configure the GSM network\n"
4540#define CODE_CMD_STR "Code commands\n"
4541#define NAME_CMD_STR "Name Commands\n"
4542#define NAME_STR "Name to use\n"
4543
4544DEFUN(cfg_net,
4545 cfg_net_cmd,
4546 "network", NETWORK_STR)
4547{
4548 vty->index = gsmnet_from_vty(vty);
4549 vty->node = GSMNET_NODE;
4550
4551 return CMD_SUCCESS;
4552}
4553
4554DEFUN(cfg_net_ncc,
4555 cfg_net_ncc_cmd,
4556 "network country code <1-999>",
4557 "Set the GSM network country code\n"
4558 "Country commands\n"
4559 CODE_CMD_STR
4560 "Network Country Code to use\n")
4561{
4562 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004563 uint16_t mcc;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004564
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004565 if (osmo_mcc_from_str(argv[0], &mcc)) {
4566 vty_out(vty, "%% Error decoding MCC: %s%s", argv[0], VTY_NEWLINE);
4567 return CMD_WARNING;
4568 }
4569
4570 gsmnet->plmn.mcc = mcc;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004571
4572 return CMD_SUCCESS;
4573}
4574
4575DEFUN(cfg_net_mnc,
4576 cfg_net_mnc_cmd,
4577 "mobile network code <0-999>",
4578 "Set the GSM mobile network code\n"
4579 "Network Commands\n"
4580 CODE_CMD_STR
4581 "Mobile Network Code to use\n")
4582{
4583 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004584 uint16_t mnc;
4585 bool mnc_3_digits;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004586
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004587 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
4588 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
4589 return CMD_WARNING;
4590 }
4591
4592 gsmnet->plmn.mnc = mnc;
4593 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004594
4595 return CMD_SUCCESS;
4596}
4597
4598DEFUN(cfg_net_encryption,
4599 cfg_net_encryption_cmd,
Harald Welte51e4bf32017-12-23 17:30:18 +01004600 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
4601 "Encryption options\n"
4602 "GSM A5 Air Interface Encryption\n"
4603 "A5/n Algorithm Number\n"
4604 "A5/n Algorithm Number\n"
4605 "A5/n Algorithm Number\n"
4606 "A5/n Algorithm Number\n")
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004607{
4608 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte51e4bf32017-12-23 17:30:18 +01004609 unsigned int i;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004610
Harald Welte51e4bf32017-12-23 17:30:18 +01004611 gsmnet->a5_encryption_mask = 0;
4612 for (i = 0; i < argc; i++)
4613 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004614
4615 return CMD_SUCCESS;
4616}
4617
Neels Hofmeyr78faf702018-05-10 05:22:50 +02004618DEFUN_DEPRECATED(cfg_net_dyn_ts_allow_tch_f,
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004619 cfg_net_dyn_ts_allow_tch_f_cmd,
4620 "dyn_ts_allow_tch_f (0|1)",
4621 "Allow or disallow allocating TCH/F on TCH_F_TCH_H_PDCH timeslots\n"
4622 "Disallow TCH/F on TCH_F_TCH_H_PDCH (default)\n"
4623 "Allow TCH/F on TCH_F_TCH_H_PDCH\n")
4624{
4625 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4626 gsmnet->dyn_ts_allow_tch_f = atoi(argv[0]) ? true : false;
Neels Hofmeyr78faf702018-05-10 05:22:50 +02004627 vty_out(vty, "%% dyn_ts_allow_tch_f is deprecated, rather use msc/codec-list to pick codecs%s",
4628 VTY_NEWLINE);
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004629 return CMD_SUCCESS;
4630}
4631
4632DEFUN(cfg_net_timezone,
4633 cfg_net_timezone_cmd,
4634 "timezone <-19-19> (0|15|30|45)",
4635 "Set the Timezone Offset of the network\n"
4636 "Timezone offset (hours)\n"
4637 "Timezone offset (00 minutes)\n"
4638 "Timezone offset (15 minutes)\n"
4639 "Timezone offset (30 minutes)\n"
4640 "Timezone offset (45 minutes)\n"
4641 )
4642{
4643 struct gsm_network *net = vty->index;
4644 int tzhr = atoi(argv[0]);
4645 int tzmn = atoi(argv[1]);
4646
4647 net->tz.hr = tzhr;
4648 net->tz.mn = tzmn;
4649 net->tz.dst = 0;
4650 net->tz.override = 1;
4651
4652 return CMD_SUCCESS;
4653}
4654
4655DEFUN(cfg_net_timezone_dst,
4656 cfg_net_timezone_dst_cmd,
4657 "timezone <-19-19> (0|15|30|45) <0-2>",
4658 "Set the Timezone Offset of the network\n"
4659 "Timezone offset (hours)\n"
4660 "Timezone offset (00 minutes)\n"
4661 "Timezone offset (15 minutes)\n"
4662 "Timezone offset (30 minutes)\n"
4663 "Timezone offset (45 minutes)\n"
4664 "DST offset (hours)\n"
4665 )
4666{
4667 struct gsm_network *net = vty->index;
4668 int tzhr = atoi(argv[0]);
4669 int tzmn = atoi(argv[1]);
4670 int tzdst = atoi(argv[2]);
4671
4672 net->tz.hr = tzhr;
4673 net->tz.mn = tzmn;
4674 net->tz.dst = tzdst;
4675 net->tz.override = 1;
4676
4677 return CMD_SUCCESS;
4678}
4679
4680DEFUN(cfg_net_no_timezone,
4681 cfg_net_no_timezone_cmd,
4682 "no timezone",
4683 NO_STR
4684 "Disable network timezone override, use system tz\n")
4685{
4686 struct gsm_network *net = vty->index;
4687
4688 net->tz.override = 0;
4689
4690 return CMD_SUCCESS;
4691}
4692
4693DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
4694 "periodic location update <6-1530>",
4695 "Periodic Location Updating Interval\n"
4696 "Periodic Location Updating Interval\n"
4697 "Periodic Location Updating Interval\n"
4698 "Periodic Location Updating Interval in Minutes\n")
4699{
4700 struct gsm_network *net = vty->index;
4701
4702 net->t3212 = atoi(argv[0]) / 6;
4703
4704 return CMD_SUCCESS;
4705}
4706
4707DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
4708 "no periodic location update",
4709 NO_STR
4710 "Periodic Location Updating Interval\n"
4711 "Periodic Location Updating Interval\n"
4712 "Periodic Location Updating Interval\n")
4713{
4714 struct gsm_network *net = vty->index;
4715
4716 net->t3212 = 0;
4717
4718 return CMD_SUCCESS;
4719}
4720
Neels Hofmeyrf28f1ef2018-04-20 15:53:53 +02004721#define MEAS_FEED_STR "Measurement Report export\n"
4722
4723DEFUN(cfg_net_meas_feed_dest, cfg_net_meas_feed_dest_cmd,
4724 "meas-feed destination ADDR <0-65535>",
4725 MEAS_FEED_STR "Where to forward Measurement Report feeds\n" "address or hostname\n" "port number\n")
4726{
4727 int rc;
4728 const char *host = argv[0];
4729 uint16_t port = atoi(argv[1]);
4730
4731 rc = meas_feed_cfg_set(host, port);
4732 if (rc < 0)
4733 return CMD_WARNING;
4734
4735 return CMD_SUCCESS;
4736}
4737
4738DEFUN(cfg_net_meas_feed_scenario, cfg_net_meas_feed_scenario_cmd,
4739 "meas-feed scenario NAME",
4740 MEAS_FEED_STR "Set a name to include in the Measurement Report feeds\n" "Name string, up to 31 characters\n")
4741{
4742 meas_feed_scenario_set(argv[0]);
4743
4744 return CMD_SUCCESS;
4745}
4746
Harald Weltedcccb182010-05-16 20:52:23 +02004747extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004748
Maxdb0e3802017-01-12 19:35:11 +01004749int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004750{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004751 cfg_ts_pchan_cmd.string =
4752 vty_cmd_string_from_valstr(tall_bsc_ctx,
4753 gsm_pchant_names,
4754 "phys_chan_config (", "|", ")",
4755 VTY_DO_LOWER);
4756 cfg_ts_pchan_cmd.doc =
4757 vty_cmd_string_from_valstr(tall_bsc_ctx,
4758 gsm_pchant_descs,
4759 "Physical Channel Combination\n",
4760 "\n", "", 0);
4761
Harald Weltee555c2b2012-08-17 13:02:12 +02004762 cfg_bts_type_cmd.string =
4763 vty_cmd_string_from_valstr(tall_bsc_ctx,
4764 bts_type_names,
4765 "type (", "|", ")",
4766 VTY_DO_LOWER);
4767 cfg_bts_type_cmd.doc =
4768 vty_cmd_string_from_valstr(tall_bsc_ctx,
4769 bts_type_descs,
4770 "BTS Vendor/Type\n",
4771 "\n", "", 0);
4772
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004773 OSMO_ASSERT(vty_global_gsm_network == NULL);
4774 vty_global_gsm_network = network;
4775
4776 osmo_stats_vty_add_cmds();
4777
4778 install_element(CONFIG_NODE, &cfg_net_cmd);
4779 install_node(&net_node, config_write_net);
4780 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
4781 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
4782 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
4783 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
4784 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
4785 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
4786 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
4787 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
4788 install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);
Neels Hofmeyrf28f1ef2018-04-20 15:53:53 +02004789 install_element(GSMNET_NODE, &cfg_net_meas_feed_dest_cmd);
4790 install_element(GSMNET_NODE, &cfg_net_meas_feed_scenario_cmd);
Harald Weltee555c2b2012-08-17 13:02:12 +02004791
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004792 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004793 install_element_ve(&show_bts_cmd);
4794 install_element_ve(&show_trx_cmd);
4795 install_element_ve(&show_ts_cmd);
4796 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004797 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004798
Philipp Maier39f62bb2017-04-09 12:32:51 +02004799 install_element_ve(&show_subscr_conn_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004800 install_element_ve(&handover_any_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004801 install_element_ve(&assignment_any_cmd);
Philipp Maier39f62bb2017-04-09 12:32:51 +02004802
Harald Welteb4d5b172010-05-12 16:10:35 +00004803 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004804 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004805
Maxdb0e3802017-01-12 19:35:11 +01004806 logging_vty_add_cmds(NULL);
Harald Welte2f4f4b82018-02-14 00:50:27 +01004807 osmo_talloc_vty_add_cmds();
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004808
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004809 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004810 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004811 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4812 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4813 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4814 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4815 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4816 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4817 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4818 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4819 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004820 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004821 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004822 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004823 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004824 /* See also handover commands added on net level from handover_vty.c */
Harald Welte5013b2a2009-08-07 13:29:14 +02004825
4826 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004827 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004828 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004829 install_element(BTS_NODE, &cfg_description_cmd);
4830 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004831 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004832 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004833 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4834 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4835 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4836 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004837 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4838 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004839 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004840 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004841 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004842 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004843 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004844 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004845 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004846 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4847 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004848 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004849 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4850 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004851 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4852 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4853 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004854 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4855 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004856 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004857 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004858 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004859 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004860 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4861 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004862 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4863 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4864 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4865 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4866 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4867 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004868 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004869 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004870 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304871 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004872 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004873 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004874 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004875 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4876 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004877 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004878 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004879 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004880 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004881 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4882 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4883 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004884 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004885 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4886 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004887 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004888 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004889 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4890 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004891 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004892 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4893 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004894 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4895 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004896 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4897 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004898 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4899 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004900 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4901 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4902 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4903 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4904 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004905 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4906 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004907 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4908 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4909 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4910 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4911 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4912 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4913 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4914 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4915 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4916 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4917 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4918 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4919 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4920 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4921 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4922 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4923 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4924 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4925 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4926 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4927 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4928 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004929 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Stefan Sperling6442e432018-02-06 14:44:54 +01004930 install_element(BTS_NODE, &cfg_bts_acc_ramping_cmd);
4931 install_element(BTS_NODE, &cfg_bts_no_acc_ramping_cmd);
4932 install_element(BTS_NODE, &cfg_bts_acc_ramping_step_interval_cmd);
4933 install_element(BTS_NODE, &cfg_bts_acc_ramping_step_size_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004934 /* See also handover commands added on bts level from handover_vty.c */
Harald Welte68628e82009-03-10 12:17:57 +00004935
Harald Welte5258fc42009-03-28 19:07:53 +00004936 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004937 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004938 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004939 install_element(TRX_NODE, &cfg_description_cmd);
4940 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004941 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004942 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004943 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4944 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004945 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004946
Harald Welte5258fc42009-03-28 19:07:53 +00004947 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004948 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004949 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004950 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004951 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004952 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004953 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4954 install_element(TS_NODE, &cfg_ts_maio_cmd);
4955 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4956 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004957 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004958
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004959 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004960 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004961 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004962 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004963 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004964 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welteb22dcb82018-02-12 17:57:57 +01004965 install_element(ENABLE_NODE, &handover_subscr_conn_cmd);
4966 install_element(ENABLE_NODE, &assignment_subscr_conn_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004967 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004968 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004969
Harald Welte81c9b9c2010-05-31 16:40:40 +02004970 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004971 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004972 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004973 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004974
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004975 ho_vty_init();
4976
Harald Weltedcccb182010-05-16 20:52:23 +02004977 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004978
Harald Welte68628e82009-03-10 12:17:57 +00004979 return 0;
4980}