blob: 77a534d5145c36ce9a3bd39ed51ef4312c60967e [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 Hofmeyr0c1ac9f2018-06-05 15:37:59 +02001004 VTY_OUT_TIMER(10);
Neels Hofmeyr0abe84e2018-05-14 18:14:29 +02001005 VTY_OUT_TIMER(7);
1006 VTY_OUT_TIMER(8);
1007 VTY_OUT_TIMER(101);
1008
Neels Hofmeyr78faf702018-05-10 05:22:50 +02001009 if (!gsmnet->dyn_ts_allow_tch_f)
1010 vty_out(vty, " dyn_ts_allow_tch_f 0%s", VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +02001011 if (gsmnet->tz.override != 0) {
1012 if (gsmnet->tz.dst)
1013 vty_out(vty, " timezone %d %d %d%s",
1014 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
1015 VTY_NEWLINE);
1016 else
1017 vty_out(vty, " timezone %d %d%s",
1018 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
1019 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +02001020 if (gsmnet->t3212 == 0)
1021 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
1022 else
1023 vty_out(vty, " periodic location update %u%s",
1024 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +02001025
Neels Hofmeyrf28f1ef2018-04-20 15:53:53 +02001026 {
1027 uint16_t meas_port;
1028 char *meas_host;
1029 const char *meas_scenario;
1030
1031 meas_feed_cfg_get(&meas_host, &meas_port);
1032 meas_scenario = meas_feed_scenario_get();
1033
1034 if (meas_port)
1035 vty_out(vty, " meas-feed destination %s %u%s",
1036 meas_host, meas_port, VTY_NEWLINE);
1037 if (strlen(meas_scenario) > 0)
1038 vty_out(vty, " meas-feed scenario %s%s",
1039 meas_scenario, VTY_NEWLINE);
1040 }
1041
Harald Welte5013b2a2009-08-07 13:29:14 +02001042 return CMD_SUCCESS;
1043}
Harald Welte67ce0732009-08-06 19:06:46 +02001044
Harald Welte68628e82009-03-10 12:17:57 +00001045static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
1046{
1047 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
1048 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +02001049 vty_out(vty, "Description: %s%s",
1050 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +02001051 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +02001052 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +02001053 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +02001054 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001055 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001056 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +01001057 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001058 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001059 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +02001060 if (is_ipaccess_bts(trx->bts)) {
1061 vty_out(vty, " ip.access stream ID: 0x%02x%s",
1062 trx->rsl_tei, VTY_NEWLINE);
1063 } else {
1064 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
1065 e1isl_dump_vty(vty, trx->rsl_link);
1066 }
Harald Welte68628e82009-03-10 12:17:57 +00001067}
1068
Max6e4f1842018-01-07 16:45:42 +01001069static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
1070{
1071 uint8_t trx_nr;
1072 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
1073 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
1074}
1075
Harald Welte68628e82009-03-10 12:17:57 +00001076DEFUN(show_trx,
1077 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001078 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001079 SHOW_STR "Display information about a TRX\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001080 BTS_TRX_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001081{
Harald Weltedcccb182010-05-16 20:52:23 +02001082 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001083 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001084 int bts_nr, trx_nr;
1085
1086 if (argc >= 1) {
1087 /* use the BTS number that the user has specified */
1088 bts_nr = atoi(argv[0]);
1089 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001090 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001091 VTY_NEWLINE);
1092 return CMD_WARNING;
1093 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001094 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001095 }
1096 if (argc >= 2) {
1097 trx_nr = atoi(argv[1]);
1098 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001099 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001100 VTY_NEWLINE);
1101 return CMD_WARNING;
1102 }
Max6e4f1842018-01-07 16:45:42 +01001103 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001104 return CMD_SUCCESS;
1105 }
1106 if (bts) {
1107 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +01001108 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +00001109 return CMD_SUCCESS;
1110 }
1111
Max6e4f1842018-01-07 16:45:42 +01001112 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
1113 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001114
1115 return CMD_SUCCESS;
1116}
1117
Harald Welte67ce0732009-08-06 19:06:46 +02001118
Harald Welte68628e82009-03-10 12:17:57 +00001119static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
1120{
Harald Welte135a6482011-05-30 12:09:13 +02001121 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +01001122 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +01001123 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Welte0383a092018-04-07 19:02:33 +02001124 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH) {
Harald Welteb29cea12010-12-24 12:26:13 +01001125 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001126 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Welte0383a092018-04-07 19:02:33 +02001127 } else if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
1128 vty_out(vty, " (%s mode)", gsm_pchan_name(ts->dyn.pchan_is));
1129 }
Harald Weltecd103a92010-12-24 12:14:52 +01001130 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001131 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001132 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +05301133 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +00001134 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
1135 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
1136 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001137}
1138
1139DEFUN(show_ts,
1140 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001141 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001142 SHOW_STR "Display information about a TS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001143 BTS_TRX_TS_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001144{
Harald Weltedcccb182010-05-16 20:52:23 +02001145 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +01001146 struct gsm_bts *bts = NULL;
1147 struct gsm_bts_trx *trx = NULL;
1148 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001149 int bts_nr, trx_nr, ts_nr;
1150
1151 if (argc >= 1) {
1152 /* use the BTS number that the user has specified */
1153 bts_nr = atoi(argv[0]);
1154 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001155 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001156 VTY_NEWLINE);
1157 return CMD_WARNING;
1158 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001159 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001160 }
1161 if (argc >= 2) {
1162 trx_nr = atoi(argv[1]);
1163 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001164 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001165 VTY_NEWLINE);
1166 return CMD_WARNING;
1167 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001168 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001169 }
1170 if (argc >= 3) {
1171 ts_nr = atoi(argv[2]);
1172 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +00001173 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +00001174 VTY_NEWLINE);
1175 return CMD_WARNING;
1176 }
Harald Welte274d0152010-12-24 12:05:03 +01001177 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +00001178 ts = &trx->ts[ts_nr];
1179 ts_dump_vty(vty, ts);
1180 return CMD_SUCCESS;
1181 }
Harald Welte274d0152010-12-24 12:05:03 +01001182
1183 if (bts && trx) {
1184 /* Iterate over all TS in this TRX */
1185 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1186 ts = &trx->ts[ts_nr];
1187 ts_dump_vty(vty, ts);
1188 }
1189 } else if (bts) {
1190 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001191 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001192 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001193 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1194 ts = &trx->ts[ts_nr];
1195 ts_dump_vty(vty, ts);
1196 }
1197 }
Harald Welte274d0152010-12-24 12:05:03 +01001198 } else {
1199 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1200 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1201 bts = gsm_bts_num(net, bts_nr);
1202 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1203 trx = gsm_bts_trx_num(bts, trx_nr);
1204 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1205 ts = &trx->ts[ts_nr];
1206 ts_dump_vty(vty, ts);
1207 }
1208 }
1209 }
Harald Welte68628e82009-03-10 12:17:57 +00001210 }
1211
1212 return CMD_SUCCESS;
1213}
1214
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001215static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1216{
1217 if (strlen(bsub->imsi))
1218 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1219 if (bsub->tmsi != GSM_RESERVED_TMSI)
1220 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1221 VTY_NEWLINE);
1222 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1223}
1224
Harald Welte8387a492009-12-22 21:43:14 +01001225static void meas_rep_dump_uni_vty(struct vty *vty,
1226 struct gsm_meas_rep_unidir *mru,
1227 const char *prefix,
1228 const char *dir)
1229{
1230 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1231 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1232 dir, rxlev2dbm(mru->sub.rx_lev));
1233 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1234 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1235 VTY_NEWLINE);
1236}
1237
1238static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1239 const char *prefix)
1240{
1241 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1242 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1243 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1244 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1245 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1246 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1247 VTY_NEWLINE);
1248 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001249 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001250 if (mr->flags & MEAS_REP_F_MS_L1)
1251 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1252 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1253 if (mr->flags & MEAS_REP_F_DL_VALID)
1254 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1255 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1256}
1257
Harald Welte0a8cf322015-12-05 17:22:49 +01001258/* FIXME: move this to libosmogsm */
1259static const struct value_string gsm48_cmode_names[] = {
1260 { GSM48_CMODE_SIGN, "signalling" },
1261 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1262 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1263 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1264 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1265 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1266 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1267 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1268 { 0, NULL }
1269};
1270
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001271/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1272 * Don't do anything if the ts is not dynamic. */
1273static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1274{
1275 switch (ts->pchan) {
1276 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1277 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1278 vty_out(vty, " as %s",
1279 gsm_pchan_name(ts->dyn.pchan_is));
1280 else
1281 vty_out(vty, " switching %s -> %s",
1282 gsm_pchan_name(ts->dyn.pchan_is),
1283 gsm_pchan_name(ts->dyn.pchan_want));
1284 break;
1285 case GSM_PCHAN_TCH_F_PDCH:
1286 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1287 vty_out(vty, " as %s",
1288 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1289 : "TCH/F");
1290 else
1291 vty_out(vty, " switching %s -> %s",
1292 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1293 : "TCH/F",
1294 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1295 : "TCH/F");
1296 break;
1297 default:
1298 /* no dyn ts */
1299 break;
1300 }
1301}
1302
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001303static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001304{
Harald Welte8387a492009-12-22 21:43:14 +01001305 int idx;
1306
Harald Welte85bded82010-12-24 12:22:34 +01001307 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1308 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1309 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001310 /* show dyn TS details, if applicable */
1311 switch (lchan->ts->pchan) {
1312 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1313 vty_out(vty, " Osmocom Dyn TS:");
1314 vty_out_dyn_ts_status(vty, lchan->ts);
1315 vty_out(vty, VTY_NEWLINE);
1316 break;
1317 case GSM_PCHAN_TCH_F_PDCH:
1318 vty_out(vty, " IPACC Dyn PDCH TS:");
1319 vty_out_dyn_ts_status(vty, lchan->ts);
1320 vty_out(vty, VTY_NEWLINE);
1321 break;
1322 default:
1323 /* no dyn ts */
1324 break;
1325 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001326 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001327 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001328 gsm_lchans_name(lchan->state),
1329 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1330 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1331 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001332 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1333 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1334 - lchan->bs_power*2,
1335 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1336 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001337 vty_out(vty, " Channel Mode / Codec: %s%s",
1338 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1339 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001340 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001341 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001342 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001343 } else
1344 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301345 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1346 struct in_addr ia;
Harald Welte5f45a4a2018-02-05 21:33:34 +01001347 if (lchan->abis_ip.bound_ip) {
1348 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
1349 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1350 inet_ntoa(ia), lchan->abis_ip.bound_port,
1351 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1352 VTY_NEWLINE);
1353 }
1354 if (lchan->abis_ip.connect_ip) {
1355 ia.s_addr = htonl(lchan->abis_ip.connect_ip);
1356 vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02x%s",
1357 inet_ntoa(ia), lchan->abis_ip.connect_port,
1358 lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode,
1359 VTY_NEWLINE);
1360 }
1361
Harald Welte2c828992009-12-02 01:56:49 +05301362 }
Harald Welte8387a492009-12-22 21:43:14 +01001363
1364 /* we want to report the last measurement report */
1365 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1366 lchan->meas_rep_idx, 1);
1367 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001368}
1369
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001370static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1371{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001372 struct gsm_meas_rep *mr;
1373 int idx;
1374
1375 /* we want to report the last measurement report */
1376 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1377 lchan->meas_rep_idx, 1);
1378 mr = &lchan->meas_rep[idx];
1379
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001380 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001381 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001382 gsm_pchan_name(lchan->ts->pchan));
1383 vty_out_dyn_ts_status(vty, lchan->ts);
1384 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1385 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001386 lchan->nr,
1387 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1388 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001389 rxlev2dbm(mr->dl.full.rx_lev),
1390 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001391 VTY_NEWLINE);
1392}
1393
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001394
1395static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1396 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1397{
1398 int lchan_nr;
1399 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1400 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1401 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1402 continue;
1403 dump_cb(vty, lchan);
1404 }
1405
1406 return CMD_SUCCESS;
1407}
1408
1409static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1410 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1411{
1412 int ts_nr;
1413
1414 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1415 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1416 dump_lchan_trx_ts(ts, vty, dump_cb);
1417 }
1418
1419 return CMD_SUCCESS;
1420}
1421
1422static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1423 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1424{
1425 int trx_nr;
1426
1427 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1428 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1429 dump_lchan_trx(trx, vty, dump_cb);
1430 }
1431
1432 return CMD_SUCCESS;
1433}
1434
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001435static int lchan_summary(struct vty *vty, int argc, const char **argv,
1436 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001437{
Harald Weltedcccb182010-05-16 20:52:23 +02001438 struct gsm_network *net = gsmnet_from_vty(vty);
Pau Espin Pedrolcf48c542018-03-26 18:20:34 +02001439 struct gsm_bts *bts = NULL;
1440 struct gsm_bts_trx *trx = NULL;
1441 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001442 struct gsm_lchan *lchan;
1443 int bts_nr, trx_nr, ts_nr, lchan_nr;
1444
1445 if (argc >= 1) {
1446 /* use the BTS number that the user has specified */
1447 bts_nr = atoi(argv[0]);
1448 if (bts_nr >= net->num_bts) {
1449 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1450 VTY_NEWLINE);
1451 return CMD_WARNING;
1452 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001453 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001454
1455 if (argc == 1)
1456 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001457 }
1458 if (argc >= 2) {
1459 trx_nr = atoi(argv[1]);
1460 if (trx_nr >= bts->num_trx) {
1461 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1462 VTY_NEWLINE);
1463 return CMD_WARNING;
1464 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001465 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001466
1467 if (argc == 2)
1468 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001469 }
1470 if (argc >= 3) {
1471 ts_nr = atoi(argv[2]);
1472 if (ts_nr >= TRX_NR_TS) {
1473 vty_out(vty, "%% can't find TS %s%s", argv[2],
1474 VTY_NEWLINE);
1475 return CMD_WARNING;
1476 }
1477 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001478
1479 if (argc == 3)
1480 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001481 }
1482 if (argc >= 4) {
1483 lchan_nr = atoi(argv[3]);
1484 if (lchan_nr >= TS_MAX_LCHAN) {
1485 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1486 VTY_NEWLINE);
1487 return CMD_WARNING;
1488 }
1489 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001490 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001491 return CMD_SUCCESS;
1492 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001493
1494
Harald Welte68628e82009-03-10 12:17:57 +00001495 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001496 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001497 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001498 }
1499
1500 return CMD_SUCCESS;
1501}
1502
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001503
1504DEFUN(show_lchan,
1505 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001506 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001507 SHOW_STR "Display information about a logical channel\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001508 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001509{
1510 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1511}
1512
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001513DEFUN(show_lchan_summary,
1514 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001515 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001516 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001517 "Short summary\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001518 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001519{
1520 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1521}
1522
Harald Welte00965dc2018-05-30 23:45:53 +02001523static void dump_one_subscr_conn(struct vty *vty, const struct gsm_subscriber_connection *conn)
1524{
1525 vty_out(vty, "conn ID=%u, MSC=%u, hodec2_fail=%d, mode=%s, mgw_ep=%s%s",
1526 conn->sccp.conn_id, conn->sccp.msc->nr, conn->hodec2.failures,
1527 get_value_string(gsm48_chan_mode_names, conn->user_plane.chan_mode),
1528 conn->user_plane.mgw_endpoint, VTY_NEWLINE);
Harald Weltec997ceb2018-05-30 01:39:43 +02001529 if (conn->lcls.global_call_ref_len) {
1530 vty_out(vty, " LCLS GCR: %s%s",
1531 osmo_hexdump_nospc(conn->lcls.global_call_ref, conn->lcls.global_call_ref_len),
1532 VTY_NEWLINE);
1533 vty_out(vty, " LCLS Config: 0x%02x, LCLS Control: 0x%02x, LCLS BSS Status: %s%s",
1534 conn->lcls.config, conn->lcls.control, osmo_fsm_inst_state_name(conn->lcls.fi),
1535 VTY_NEWLINE);
1536 }
Harald Welte00965dc2018-05-30 23:45:53 +02001537 if (conn->lchan)
1538 lchan_dump_full_vty(vty, conn->lchan);
1539 if (conn->secondary_lchan)
1540 lchan_dump_full_vty(vty, conn->secondary_lchan);
1541}
1542
Philipp Maier39f62bb2017-04-09 12:32:51 +02001543DEFUN(show_subscr_conn,
1544 show_subscr_conn_cmd,
1545 "show conns",
1546 SHOW_STR "Display currently active subscriber connections\n")
1547{
1548 struct gsm_subscriber_connection *conn;
1549 struct gsm_network *net = gsmnet_from_vty(vty);
1550 bool no_conns = true;
1551 unsigned int count = 0;
1552
1553 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1554
1555 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte00965dc2018-05-30 23:45:53 +02001556 dump_one_subscr_conn(vty, conn);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001557 no_conns = false;
1558 count++;
1559 }
1560
1561 if (no_conns)
1562 vty_out(vty, "None%s", VTY_NEWLINE);
1563
1564 return CMD_SUCCESS;
1565}
1566
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001567static int trigger_ho_or_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_bts *to_bts)
1568{
1569 int rc;
1570
1571 if (!to_bts || from_lchan->ts->trx->bts == to_bts) {
1572 LOGP(DHO, LOGL_NOTICE, "%s Manually triggering Assignment from VTY\n",
1573 gsm_lchan_name(from_lchan));
1574 to_bts = from_lchan->ts->trx->bts;
1575 } else
1576 LOGP(DHO, LOGL_NOTICE, "%s (ARFCN %u) --> BTS %u Manually triggering Handover from VTY\n",
1577 gsm_lchan_name(from_lchan), from_lchan->ts->trx->arfcn, to_bts->nr);
Neels Hofmeyr45e46d22018-02-15 14:10:12 +01001578 rc = bsc_handover_start(HODEC_NONE, from_lchan, to_bts, from_lchan->type);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001579 if (rc) {
1580 vty_out(vty, "bsc_handover_start() returned %d=%s%s", rc,
1581 strerror(-rc), VTY_NEWLINE);
1582 return CMD_WARNING;
1583 }
1584 return CMD_SUCCESS;
1585}
1586
1587static int ho_or_as(struct vty *vty, const char *argv[], int argc)
Philipp Maier39f62bb2017-04-09 12:32:51 +02001588{
1589 struct gsm_network *net = gsmnet_from_vty(vty);
1590 struct gsm_subscriber_connection *conn;
1591 struct gsm_bts *bts;
1592 struct gsm_bts *new_bts = NULL;
1593 unsigned int bts_nr = atoi(argv[0]);
1594 unsigned int trx_nr = atoi(argv[1]);
1595 unsigned int ts_nr = atoi(argv[2]);
1596 unsigned int ss_nr = atoi(argv[3]);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001597 unsigned int bts_nr_new;
1598 const char *action;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001599
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001600 if (argc > 4) {
1601 bts_nr_new = atoi(argv[4]);
1602
1603 /* Lookup the BTS where we want to handover to */
1604 llist_for_each_entry(bts, &net->bts_list, list) {
1605 if (bts->nr == bts_nr_new) {
1606 new_bts = bts;
1607 break;
1608 }
1609 }
1610
1611 if (!new_bts) {
1612 vty_out(vty, "Unable to trigger handover, specified bts #%u does not exist %s",
1613 bts_nr_new, VTY_NEWLINE);
1614 return CMD_WARNING;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001615 }
1616 }
1617
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001618 action = new_bts ? "handover" : "assignment";
Philipp Maier39f62bb2017-04-09 12:32:51 +02001619
1620 /* Find the connection/lchan that we want to handover */
1621 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001622 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001623 conn->lchan->ts->trx->nr == trx_nr &&
1624 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001625 vty_out(vty, "starting %s for lchan %s...%s", action, conn->lchan->name, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001626 lchan_dump_full_vty(vty, conn->lchan);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001627 return trigger_ho_or_as(vty, conn->lchan, new_bts);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001628 }
1629 }
1630
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001631 vty_out(vty, "Unable to trigger %s, specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1632 action, bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001633
1634 return CMD_WARNING;
1635}
1636
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001637#define MANUAL_HANDOVER_STR "Manually trigger handover (for debugging)\n"
1638#define MANUAL_ASSIGNMENT_STR "Manually trigger assignment (for debugging)\n"
1639
1640DEFUN(handover_subscr_conn,
1641 handover_subscr_conn_cmd,
Harald Welteb22dcb82018-02-12 17:57:57 +01001642 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> handover <0-255>",
Harald Welte0bfd8d92018-02-12 18:06:53 +01001643 BTS_NR_TRX_TS_SS_STR2
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001644 MANUAL_HANDOVER_STR
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001645 "New " BTS_NR_STR)
1646{
1647 return ho_or_as(vty, argv, argc);
1648}
1649
1650DEFUN(assignment_subscr_conn,
1651 assignment_subscr_conn_cmd,
Harald Welteb22dcb82018-02-12 17:57:57 +01001652 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> assignment",
Harald Welte0bfd8d92018-02-12 18:06:53 +01001653 BTS_NR_TRX_TS_SS_STR2
Harald Welteb22dcb82018-02-12 17:57:57 +01001654 MANUAL_ASSIGNMENT_STR)
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001655{
1656 return ho_or_as(vty, argv, argc);
1657}
1658
1659static struct gsm_lchan *find_used_voice_lchan(struct vty *vty)
1660{
1661 struct gsm_bts *bts;
1662 struct gsm_network *network = gsmnet_from_vty(vty);
1663
1664 llist_for_each_entry(bts, &network->bts_list, list) {
1665 struct gsm_bts_trx *trx;
1666
1667 llist_for_each_entry(trx, &bts->trx_list, list) {
1668 int i;
1669 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1670 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1671 int j;
1672 int subslots;
1673
1674 /* skip administratively deactivated timeslots */
1675 if (!nm_is_running(&ts->mo.nm_state))
1676 continue;
1677
1678 subslots = ts_subslots(ts);
1679 for (j = 0; j < subslots; j++) {
1680 struct gsm_lchan *lchan = &ts->lchan[j];
1681
1682 if (lchan->state == LCHAN_S_ACTIVE
1683 && (lchan->type == GSM_LCHAN_TCH_F
1684 || lchan->type == GSM_LCHAN_TCH_H)) {
1685
1686 vty_out(vty, "Found voice call: %s%s",
1687 gsm_lchan_name(lchan), VTY_NEWLINE);
1688 lchan_dump_full_vty(vty, lchan);
1689 return lchan;
1690 }
1691 }
1692 }
1693 }
1694 }
1695
1696 vty_out(vty, "Cannot find any ongoing voice calls%s", VTY_NEWLINE);
1697 return NULL;
1698}
1699
1700static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gsm_bts *not_this_bts,
1701 enum gsm_phys_chan_config free_type)
1702{
1703 struct gsm_bts *bts;
1704 struct gsm_network *network = gsmnet_from_vty(vty);
1705
1706 llist_for_each_entry(bts, &network->bts_list, list) {
1707 struct gsm_bts_trx *trx;
1708
1709 if (bts == not_this_bts)
1710 continue;
1711
1712 llist_for_each_entry(trx, &bts->trx_list, list) {
1713 int i;
1714 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1715 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1716 int j;
1717 int subslots;
1718
1719 /* skip administratively deactivated timeslots */
1720 if (!nm_is_running(&ts->mo.nm_state))
1721 continue;
1722
1723 if (ts->pchan != free_type)
1724 continue;
1725
1726 subslots = ts_subslots(ts);
1727 for (j = 0; j < subslots; j++) {
1728 struct gsm_lchan *lchan = &ts->lchan[j];
1729
1730 if (lchan->state == LCHAN_S_NONE) {
1731 vty_out(vty, "Found unused %s slot: %s%s",
1732 gsm_pchan_name(free_type),
1733 gsm_lchan_name(lchan),
1734 VTY_NEWLINE);
1735 lchan_dump_full_vty(vty, lchan);
1736 return bts;
1737 }
1738 }
1739 }
1740 }
1741 }
1742 vty_out(vty, "Cannot find any BTS (other than BTS %u) with free %s lchan%s",
1743 not_this_bts? not_this_bts->nr : 255, gsm_lchant_name(free_type), VTY_NEWLINE);
1744 return NULL;
1745}
1746
1747DEFUN(handover_any, handover_any_cmd,
1748 "handover any",
1749 MANUAL_HANDOVER_STR
1750 "Pick any actively used TCH/F or TCH/H lchan and handover to any other BTS."
1751 " This is likely to fail if not all BTS are guaranteed to be reachable by the MS.\n")
1752{
1753 struct gsm_lchan *from_lchan;
1754 struct gsm_bts *to_bts;
1755
1756 from_lchan = find_used_voice_lchan(vty);
1757 if (!from_lchan)
1758 return CMD_WARNING;
1759
1760 to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts,
1761 ts_pchan(from_lchan->ts));
1762 if (!to_bts)
1763 return CMD_WARNING;
1764
1765 return trigger_ho_or_as(vty, from_lchan, to_bts);
1766}
1767
1768DEFUN(assignment_any, assignment_any_cmd,
1769 "assignment any",
1770 MANUAL_ASSIGNMENT_STR
1771 "Pick any actively used TCH/F or TCH/H lchan and re-assign within the same BTS."
1772 " This will fail if no lchans of the same type are available besides the used one.\n")
1773{
1774 struct gsm_lchan *from_lchan;
1775
1776 from_lchan = find_used_voice_lchan(vty);
1777 if (!from_lchan)
1778 return CMD_WARNING;
1779
1780 return trigger_ho_or_as(vty, from_lchan, NULL);
1781}
1782
Harald Weltebe4b7302009-05-23 16:59:33 +00001783static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001784{
1785 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001786 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001787}
1788
Harald Weltebe4b7302009-05-23 16:59:33 +00001789static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001790{
1791 struct gsm_paging_request *pag;
1792
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001793 if (!bts->paging.bts)
1794 return;
1795
Harald Weltef5025b62009-03-28 16:55:11 +00001796 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1797 paging_dump_vty(vty, pag);
1798}
1799
1800DEFUN(show_paging,
1801 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001802 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001803 SHOW_STR "Display information about paging reuqests of a BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001804 BTS_NR_STR)
Harald Weltef5025b62009-03-28 16:55:11 +00001805{
Harald Weltedcccb182010-05-16 20:52:23 +02001806 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001807 struct gsm_bts *bts;
1808 int bts_nr;
1809
1810 if (argc >= 1) {
1811 /* use the BTS number that the user has specified */
1812 bts_nr = atoi(argv[0]);
1813 if (bts_nr >= net->num_bts) {
1814 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1815 VTY_NEWLINE);
1816 return CMD_WARNING;
1817 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001818 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001819 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001820
Harald Weltef5025b62009-03-28 16:55:11 +00001821 return CMD_SUCCESS;
1822 }
1823 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001824 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001825 bts_paging_dump_vty(vty, bts);
1826 }
1827
1828 return CMD_SUCCESS;
1829}
1830
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001831DEFUN(show_paging_group,
1832 show_paging_group_cmd,
1833 "show paging-group <0-255> IMSI",
1834 SHOW_STR "Display the paging group\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001835 BTS_NR_STR "IMSI\n")
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001836{
1837 struct gsm_network *net = gsmnet_from_vty(vty);
1838 struct gsm_bts *bts;
1839 unsigned int page_group;
1840 int bts_nr = atoi(argv[0]);
1841
1842 if (bts_nr >= net->num_bts) {
1843 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1844 return CMD_WARNING;
1845 }
1846
1847 bts = gsm_bts_num(net, bts_nr);
1848 if (!bts) {
1849 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1850 return CMD_WARNING;
1851 }
1852
1853 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1854 str_to_imsi(argv[1]));
1855 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1856 str_to_imsi(argv[1]), bts->nr,
1857 page_group, VTY_NEWLINE);
1858 return CMD_SUCCESS;
1859}
1860
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001861DEFUN(cfg_net_neci,
1862 cfg_net_neci_cmd,
1863 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001864 "New Establish Cause Indication\n"
1865 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001866{
Harald Weltedcccb182010-05-16 20:52:23 +02001867 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1868
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001869 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001870 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001871 return CMD_SUCCESS;
1872}
1873
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001874DEFUN(cfg_net_pag_any_tch,
1875 cfg_net_pag_any_tch_cmd,
1876 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001877 "Assign a TCH when receiving a Paging Any request\n"
1878 "Any Channel\n" "Use\n" "TCH\n"
1879 "Do not use TCH for Paging Request Any\n"
1880 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001881{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001882 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001883 gsmnet->pag_any_tch = atoi(argv[0]);
1884 gsm_net_update_ctype(gsmnet);
1885 return CMD_SUCCESS;
1886}
1887
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001888#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1889/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1890#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1891
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001892#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001893 DEFUN(cfg_net_T##number, \
1894 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001895 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001896 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001897 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001898 "Set to default timer value" \
1899 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1900 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001901{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001902 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001903 int value; \
1904 if (strcmp(argv[0], "default") == 0) \
1905 value = DEFAULT_TIMER(number); \
1906 else \
1907 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001908 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001909 gsmnet->T##number = value; \
1910 return CMD_SUCCESS; \
1911}
1912
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001913DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1914DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1915DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1916DECLARE_TIMER(3107, "Currently not used")
1917DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1918DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1919DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1920DECLARE_TIMER(3115, "Currently not used")
1921DECLARE_TIMER(3117, "Currently not used")
1922DECLARE_TIMER(3119, "Currently not used")
Stefan Sperling6cee8932018-01-30 18:14:22 +01001923DECLARE_TIMER(3122, "Default waiting time (seconds) after IMM ASS REJECT")
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001924DECLARE_TIMER(3141, "Currently not used")
Neels Hofmeyr0c1ac9f2018-06-05 15:37:59 +02001925DECLARE_TIMER(10, "Assignment Command timeout in seconds")
Neels Hofmeyr0abe84e2018-05-14 18:14:29 +02001926DECLARE_TIMER(7, "Set the outgoing inter-BSC Handover timeout, from Handover Required to Handover Command")
1927DECLARE_TIMER(8, "Set the outgoing inter-BSC Handover timeout, from Handover Command to final Clear")
1928DECLARE_TIMER(101, "Set the incoming inter-BSC Handover timeout, from Handover Request to Accept")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001929
Maxc08ee712016-05-11 12:45:13 +02001930DEFUN_DEPRECATED(cfg_net_dtx,
1931 cfg_net_dtx_cmd,
1932 "dtx-used (0|1)",
1933 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001934{
Maxc08ee712016-05-11 12:45:13 +02001935 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1936 "configuration options of BTS instead%s", VTY_NEWLINE);
1937 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001938}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001939
Harald Welte5258fc42009-03-28 19:07:53 +00001940/* per-BTS configuration */
1941DEFUN(cfg_bts,
1942 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001943 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001944 "Select a BTS to configure\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001945 BTS_NR_STR)
Harald Welte5258fc42009-03-28 19:07:53 +00001946{
Harald Weltedcccb182010-05-16 20:52:23 +02001947 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001948 int bts_nr = atoi(argv[0]);
1949 struct gsm_bts *bts;
1950
Harald Weltee441d9c2009-06-21 16:17:15 +02001951 if (bts_nr > gsmnet->num_bts) {
1952 vty_out(vty, "%% The next unused BTS number is %u%s",
1953 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001954 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001955 } else if (bts_nr == gsmnet->num_bts) {
1956 /* allocate a new one */
Neels Hofmeyr958f2592018-05-27 01:26:31 +02001957 bts = bsc_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001958 HARDCODED_BSIC);
Stefan Sperling6442e432018-02-06 14:44:54 +01001959 /*
1960 * Initalize bts->acc_ramp here. Else we could segfault while
1961 * processing a configuration file with ACC ramping settings.
1962 */
Stefan Sperlingea333412018-04-10 16:36:54 +02001963 acc_ramp_init(&bts->acc_ramp, bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001964 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001965 bts = gsm_bts_num(gsmnet, bts_nr);
1966
Daniel Willmannf15c2762010-01-11 13:43:07 +01001967 if (!bts) {
1968 vty_out(vty, "%% Unable to allocate BTS %u%s",
1969 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001970 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001971 }
Harald Welte5258fc42009-03-28 19:07:53 +00001972
1973 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001974 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001975 vty->node = BTS_NODE;
1976
1977 return CMD_SUCCESS;
1978}
1979
1980DEFUN(cfg_bts_type,
1981 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001982 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001983 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001984{
1985 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001986 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001987
Max7507aef2017-04-10 13:59:14 +02001988 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001989 if (rc < 0)
1990 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001991
Harald Welte5258fc42009-03-28 19:07:53 +00001992 return CMD_SUCCESS;
1993}
1994
Harald Weltefcd24452009-06-20 18:15:19 +02001995DEFUN(cfg_bts_band,
1996 cfg_bts_band_cmd,
1997 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001998 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001999{
2000 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02002001 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02002002
2003 if (band < 0) {
2004 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
2005 band, VTY_NEWLINE);
2006 return CMD_WARNING;
2007 }
2008
2009 bts->band = band;
2010
2011 return CMD_SUCCESS;
2012}
2013
Maxc08ee712016-05-11 12:45:13 +02002014DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
2015 "Configure discontinuous transmission\n"
2016 "Enable Uplink DTX for this BTS\n"
2017 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
2018 "older phones).\n")
2019{
2020 struct gsm_bts *bts = vty->index;
2021
2022 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02002023 if (!is_ipaccess_bts(bts))
2024 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
2025 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02002026 return CMD_SUCCESS;
2027}
2028
2029DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
2030 NO_STR
2031 "Configure discontinuous transmission\n"
2032 "Disable Uplink DTX for this BTS\n")
2033{
2034 struct gsm_bts *bts = vty->index;
2035
2036 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
2037
2038 return CMD_SUCCESS;
2039}
2040
2041DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
2042 "Configure discontinuous transmission\n"
2043 "Enable Downlink DTX for this BTS\n")
2044{
2045 struct gsm_bts *bts = vty->index;
2046
2047 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02002048 if (!is_ipaccess_bts(bts))
2049 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
2050 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02002051 return CMD_SUCCESS;
2052}
2053
2054DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
2055 NO_STR
2056 "Configure discontinuous transmission\n"
2057 "Disable Downlink DTX for this BTS\n")
2058{
2059 struct gsm_bts *bts = vty->index;
2060
2061 bts->dtxd = false;
2062
2063 return CMD_SUCCESS;
2064}
2065
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02002066DEFUN(cfg_bts_ci,
2067 cfg_bts_ci_cmd,
2068 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002069 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02002070{
2071 struct gsm_bts *bts = vty->index;
2072 int ci = atoi(argv[0]);
2073
2074 if (ci < 0 || ci > 0xffff) {
2075 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
2076 ci, VTY_NEWLINE);
2077 return CMD_WARNING;
2078 }
2079 bts->cell_identity = ci;
2080
2081 return CMD_SUCCESS;
2082}
2083
Harald Welte5258fc42009-03-28 19:07:53 +00002084DEFUN(cfg_bts_lac,
2085 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02002086 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002087 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00002088{
2089 struct gsm_bts *bts = vty->index;
2090 int lac = atoi(argv[0]);
2091
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02002092 if (lac < 0 || lac > 0xffff) {
2093 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00002094 lac, VTY_NEWLINE);
2095 return CMD_WARNING;
2096 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02002097
2098 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
2099 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
2100 lac, VTY_NEWLINE);
2101 return CMD_WARNING;
2102 }
2103
Harald Welte5258fc42009-03-28 19:07:53 +00002104 bts->location_area_code = lac;
2105
2106 return CMD_SUCCESS;
2107}
2108
Harald Weltea43f7892009-12-01 18:04:30 +05302109
Harald Weltea2bbc5e2015-11-20 10:43:31 +01002110/* compatibility wrapper for old config files */
2111DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00002112 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02002113 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002114 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00002115{
Harald Welte5258fc42009-03-28 19:07:53 +00002116 return CMD_SUCCESS;
2117}
2118
Harald Welte78f2f502009-05-23 16:56:52 +00002119DEFUN(cfg_bts_bsic,
2120 cfg_bts_bsic_cmd,
2121 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002122 "Set the Base Station Identity Code (BSIC) of this BTS\n"
2123 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00002124{
2125 struct gsm_bts *bts = vty->index;
2126 int bsic = atoi(argv[0]);
2127
2128 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02002129 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00002130 bsic, VTY_NEWLINE);
2131 return CMD_WARNING;
2132 }
2133 bts->bsic = bsic;
2134
2135 return CMD_SUCCESS;
2136}
2137
Harald Welte4cc34222009-05-01 15:12:31 +00002138DEFUN(cfg_bts_unit_id,
2139 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02002140 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002141 "Abis/IP specific options\n"
2142 "Set the IPA BTS Unit ID\n"
2143 "Unit ID (Site)\n"
2144 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00002145{
2146 struct gsm_bts *bts = vty->index;
2147 int site_id = atoi(argv[0]);
2148 int bts_id = atoi(argv[1]);
2149
Harald Welte07dc73d2009-08-07 13:27:09 +02002150 if (!is_ipaccess_bts(bts)) {
2151 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2152 return CMD_WARNING;
2153 }
2154
Harald Welte4cc34222009-05-01 15:12:31 +00002155 bts->ip_access.site_id = site_id;
2156 bts->ip_access.bts_id = bts_id;
2157
2158 return CMD_SUCCESS;
2159}
2160
Harald Welte8b291802013-03-12 13:57:05 +01002161DEFUN(cfg_bts_rsl_ip,
2162 cfg_bts_rsl_ip_cmd,
2163 "ip.access rsl-ip A.B.C.D",
2164 "Abis/IP specific options\n"
2165 "Set the IPA RSL IP Address of the BSC\n"
2166 "Destination IP address for RSL connection\n")
2167{
2168 struct gsm_bts *bts = vty->index;
2169 struct in_addr ia;
2170
2171 if (!is_ipaccess_bts(bts)) {
2172 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2173 return CMD_WARNING;
2174 }
2175
2176 inet_aton(argv[0], &ia);
2177 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
2178
2179 return CMD_SUCCESS;
2180}
2181
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002182#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01002183
Sylvain Munautc9519462011-10-17 14:04:55 +02002184DEFUN(cfg_bts_nokia_site_skip_reset,
2185 cfg_bts_nokia_site_skip_reset_cmd,
2186 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002187 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002188 "Skip the reset step during bootstrap process of this BTS\n"
2189 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02002190{
2191 struct gsm_bts *bts = vty->index;
2192
2193 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
2194 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
2195 return CMD_WARNING;
2196 }
2197
2198 bts->nokia.skip_reset = atoi(argv[0]);
2199
2200 return CMD_SUCCESS;
2201}
2202
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002203DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
2204 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
2205 "nokia_site no-local-rel-conf (0|1)",
2206 NOKIA_STR
2207 "Do not wait for RELease CONFirm message when releasing channel locally\n"
2208 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
2209{
2210 struct gsm_bts *bts = vty->index;
2211
2212 if (!is_nokia_bts(bts)) {
2213 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2214 VTY_NEWLINE);
2215 return CMD_WARNING;
2216 }
2217
2218 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
2219
2220 return CMD_SUCCESS;
2221}
2222
Sipos Csaba56e17662015-02-07 13:27:36 +01002223DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
2224 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
2225 "nokia_site bts-reset-timer <15-100>",
2226 NOKIA_STR
2227 "The amount of time (in sec.) between BTS_RESET is sent,\n"
2228 "and the BTS is being bootstrapped.\n")
2229{
2230 struct gsm_bts *bts = vty->index;
2231
2232 if (!is_nokia_bts(bts)) {
2233 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2234 VTY_NEWLINE);
2235 return CMD_WARNING;
2236 }
2237
2238 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
2239
2240 return CMD_SUCCESS;
2241}
Harald Welte8f0ed552010-05-11 21:53:49 +02002242#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002243#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02002244
Harald Welte8175e952009-10-20 00:22:00 +02002245DEFUN(cfg_bts_stream_id,
2246 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002247 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02002248 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002249 "Set the ip.access Stream ID of the OML link of this BTS\n"
2250 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02002251{
2252 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002253 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02002254
2255 if (!is_ipaccess_bts(bts)) {
2256 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2257 return CMD_WARNING;
2258 }
2259
2260 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002261 /* This is used by e1inp_bind_ops callback for each BTS model. */
2262 bts->oml_e1_link.e1_nr = linenr;
2263
2264 return CMD_SUCCESS;
2265}
2266
Harald Welted13e0cd2012-08-17 09:52:03 +02002267#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02002268
Harald Welte42581822009-08-08 16:12:58 +02002269DEFUN(cfg_bts_oml_e1,
2270 cfg_bts_oml_e1_cmd,
2271 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02002272 OML_E1_STR
2273 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002274 "E1/T1 line number to be used for OML\n"
2275 "E1/T1 timeslot to be used for OML\n"
2276 "E1/T1 timeslot to be used for OML\n"
2277 "E1/T1 sub-slot to be used for OML\n"
2278 "Use E1/T1 sub-slot 0\n"
2279 "Use E1/T1 sub-slot 1\n"
2280 "Use E1/T1 sub-slot 2\n"
2281 "Use E1/T1 sub-slot 3\n"
2282 "Use full E1 slot 3\n"
2283 )
Harald Welte42581822009-08-08 16:12:58 +02002284{
2285 struct gsm_bts *bts = vty->index;
2286
2287 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2288
2289 return CMD_SUCCESS;
2290}
2291
2292
2293DEFUN(cfg_bts_oml_e1_tei,
2294 cfg_bts_oml_e1_tei_cmd,
2295 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002296 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002297 "Set the TEI to be used for OML\n"
2298 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002299{
2300 struct gsm_bts *bts = vty->index;
2301
2302 bts->oml_tei = atoi(argv[0]);
2303
2304 return CMD_SUCCESS;
2305}
2306
Harald Welte7a8fa412009-08-10 13:48:16 +02002307DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2308 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002309 "Channnel Allocator\n" "Channel Allocator\n"
2310 "Allocate Timeslots and Transceivers in ascending order\n"
2311 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002312{
2313 struct gsm_bts *bts = vty->index;
2314
2315 if (!strcmp(argv[0], "ascending"))
2316 bts->chan_alloc_reverse = 0;
2317 else
2318 bts->chan_alloc_reverse = 1;
2319
2320 return CMD_SUCCESS;
2321}
2322
Harald Welte8f0ed552010-05-11 21:53:49 +02002323#define RACH_STR "Random Access Control Channel\n"
2324
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002325DEFUN(cfg_bts_rach_tx_integer,
2326 cfg_bts_rach_tx_integer_cmd,
2327 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002328 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002329 "Set the raw tx integer value in RACH Control parameters IE\n"
2330 "Set the raw tx integer value in RACH Control parameters IE\n"
2331 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002332{
2333 struct gsm_bts *bts = vty->index;
2334 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2335 return CMD_SUCCESS;
2336}
2337
2338DEFUN(cfg_bts_rach_max_trans,
2339 cfg_bts_rach_max_trans_cmd,
2340 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002341 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002342 "Set the maximum number of RACH burst transmissions\n"
2343 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002344 "Maximum number of 1 RACH burst transmissions\n"
2345 "Maximum number of 2 RACH burst transmissions\n"
2346 "Maximum number of 4 RACH burst transmissions\n"
2347 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002348{
2349 struct gsm_bts *bts = vty->index;
2350 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2351 return CMD_SUCCESS;
2352}
2353
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002354#define CD_STR "Channel Description\n"
2355
2356DEFUN(cfg_bts_chan_desc_att,
2357 cfg_bts_chan_desc_att_cmd,
2358 "channel-descrption attach (0|1)",
2359 CD_STR
2360 "Set if attachment is required\n"
2361 "Attachment is NOT required\n"
2362 "Attachment is required (standard)\n")
2363{
2364 struct gsm_bts *bts = vty->index;
2365 bts->si_common.chan_desc.att = atoi(argv[0]);
2366 return CMD_SUCCESS;
2367}
2368
2369DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2370 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2371 "channel-descrption bs-pa-mfrms <2-9>",
2372 CD_STR
2373 "Set number of multiframe periods for paging groups\n"
2374 "Number of multiframe periods for paging groups\n")
2375{
2376 struct gsm_bts *bts = vty->index;
2377 int bs_pa_mfrms = atoi(argv[0]);
2378
2379 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2380 return CMD_SUCCESS;
2381}
2382
2383DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2384 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2385 "channel-descrption bs-ag-blks-res <0-7>",
2386 CD_STR
2387 "Set number of blocks reserved for access grant\n"
2388 "Number of blocks reserved for access grant\n")
2389{
2390 struct gsm_bts *bts = vty->index;
2391 int bs_ag_blks_res = atoi(argv[0]);
2392
2393 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2394 return CMD_SUCCESS;
2395}
2396
Harald Welte8f0ed552010-05-11 21:53:49 +02002397#define NM_STR "Network Management\n"
2398
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002399DEFUN(cfg_bts_rach_nm_b_thresh,
2400 cfg_bts_rach_nm_b_thresh_cmd,
2401 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002402 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002403 "Set the NM Busy Threshold\n"
2404 "Set the NM Busy Threshold\n"
2405 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002406{
2407 struct gsm_bts *bts = vty->index;
2408 bts->rach_b_thresh = atoi(argv[0]);
2409 return CMD_SUCCESS;
2410}
2411
2412DEFUN(cfg_bts_rach_nm_ldavg,
2413 cfg_bts_rach_nm_ldavg_cmd,
2414 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002415 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002416 "Set the NM Loadaverage Slots value\n"
2417 "Set the NM Loadaverage Slots value\n"
2418 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002419{
2420 struct gsm_bts *bts = vty->index;
2421 bts->rach_ldavg_slots = atoi(argv[0]);
2422 return CMD_SUCCESS;
2423}
2424
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002425DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2426 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002427 "Should this cell be barred from access?\n"
2428 "Should this cell be barred from access?\n"
2429 "Cell should NOT be barred\n"
2430 "Cell should be barred\n")
2431
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002432{
2433 struct gsm_bts *bts = vty->index;
2434
Harald Welte71355012009-12-21 23:08:18 +01002435 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002436
2437 return CMD_SUCCESS;
2438}
2439
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002440DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2441 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002442 RACH_STR
2443 "Should this cell allow emergency calls?\n"
2444 "Should this cell allow emergency calls?\n"
2445 "Should this cell allow emergency calls?\n"
2446 "Do NOT allow emergency calls\n"
2447 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002448{
2449 struct gsm_bts *bts = vty->index;
2450
2451 if (atoi(argv[0]) == 0)
2452 bts->si_common.rach_control.t2 |= 0x4;
2453 else
2454 bts->si_common.rach_control.t2 &= ~0x4;
2455
2456 return CMD_SUCCESS;
2457}
2458
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002459DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2460 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2461 RACH_STR
2462 "Set access control class\n"
2463 "Access control class 0\n"
2464 "Access control class 1\n"
2465 "Access control class 2\n"
2466 "Access control class 3\n"
2467 "Access control class 4\n"
2468 "Access control class 5\n"
2469 "Access control class 6\n"
2470 "Access control class 7\n"
2471 "Access control class 8\n"
2472 "Access control class 9\n"
2473 "Access control class 11 for PLMN use\n"
2474 "Access control class 12 for security services\n"
2475 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2476 "Access control class 14 for emergency services\n"
2477 "Access control class 15 for PLMN staff\n"
2478 "barred to use access control class\n"
2479 "allowed to use access control class\n")
2480{
2481 struct gsm_bts *bts = vty->index;
2482
2483 uint8_t control_class;
2484 uint8_t allowed = 0;
2485
2486 if (strcmp(argv[1], "allowed") == 0)
2487 allowed = 1;
2488
2489 control_class = atoi(argv[0]);
2490 if (control_class < 8)
2491 if (allowed)
2492 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2493 else
2494 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2495 else
2496 if (allowed)
2497 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2498 else
2499 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2500
2501 return CMD_SUCCESS;
2502}
2503
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002504DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2505 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002506 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002507 "Maximum transmit power of the MS\n"
2508 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002509 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002510{
2511 struct gsm_bts *bts = vty->index;
2512
2513 bts->ms_max_power = atoi(argv[0]);
2514
2515 return CMD_SUCCESS;
2516}
2517
Harald Weltecfaabbb2012-08-16 23:23:50 +02002518#define CELL_STR "Cell Parameters\n"
2519
Harald Welte73225282009-12-12 18:17:25 +01002520DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2521 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002522 CELL_STR "Cell re-selection parameters\n"
2523 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002524 "Cell Re-Selection Hysteresis in dB")
2525{
2526 struct gsm_bts *bts = vty->index;
2527
2528 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2529
2530 return CMD_SUCCESS;
2531}
2532
2533DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2534 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002535 "Minimum RxLev needed for cell access\n"
2536 "Minimum RxLev needed for cell access\n"
2537 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002538 "Minimum RxLev needed for cell access (better than -110dBm)")
2539{
2540 struct gsm_bts *bts = vty->index;
2541
2542 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2543
2544 return CMD_SUCCESS;
2545}
2546
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002547DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2548 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002549 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2550 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002551{
2552 struct gsm_bts *bts = vty->index;
2553
2554 bts->si_common.cell_ro_sel_par.present = 1;
2555 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2556
2557 return CMD_SUCCESS;
2558}
2559
2560DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2561 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002562 CELL_STR "Cell Re-Selection Parameters\n"
2563 "Cell Re-Selection Offset (CRO) in dB\n"
2564 "Cell Re-Selection Offset (CRO) in dB\n"
2565 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002566{
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.cell_resel_off = atoi(argv[0])/2;
2571
2572 return CMD_SUCCESS;
2573}
2574
2575DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2576 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002577 "Cell selection temporary negative offset\n"
2578 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002579 "Cell selection temporary negative offset in dB")
2580{
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.temp_offs = atoi(argv[0])/10;
2585
2586 return CMD_SUCCESS;
2587}
2588
2589DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2590 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002591 "Cell selection temporary negative offset\n"
2592 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002593 "Sets cell selection temporary negative offset to infinity")
2594{
2595 struct gsm_bts *bts = vty->index;
2596
2597 bts->si_common.cell_ro_sel_par.present = 1;
2598 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2599
2600 return CMD_SUCCESS;
2601}
2602
2603DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2604 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002605 "Cell selection penalty time\n"
2606 "Cell selection penalty time\n"
2607 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002608{
2609 struct gsm_bts *bts = vty->index;
2610
2611 bts->si_common.cell_ro_sel_par.present = 1;
2612 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2613
2614 return CMD_SUCCESS;
2615}
2616
2617DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2618 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002619 "Cell selection penalty time\n"
2620 "Cell selection penalty time\n"
2621 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002622 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2623 "and TEMPORARY_OFFSET is ignored)")
2624{
2625 struct gsm_bts *bts = vty->index;
2626
2627 bts->si_common.cell_ro_sel_par.present = 1;
2628 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2629
2630 return CMD_SUCCESS;
2631}
2632
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002633DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2634 "radio-link-timeout <4-64>",
2635 "Radio link timeout criterion (BTS side)\n"
2636 "Radio link timeout value (lost SACCH block)\n")
2637{
2638 struct gsm_bts *bts = vty->index;
2639
Harald Welte2f8b9d22017-06-18 11:12:13 +03002640 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2641
2642 return CMD_SUCCESS;
2643}
2644
2645DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2646 "radio-link-timeout infinite",
2647 "Radio link timeout criterion (BTS side)\n"
2648 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2649{
2650 struct gsm_bts *bts = vty->index;
2651
2652 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2653 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2654 return CMD_WARNING;
2655 }
2656
2657 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2658 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002659
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002660 return CMD_SUCCESS;
2661}
2662
Harald Welte8f0ed552010-05-11 21:53:49 +02002663#define GPRS_TEXT "GPRS Packet Network\n"
2664
Harald Welteaf387632010-03-14 23:30:30 +08002665DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002666 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002667 GPRS_TEXT
2668 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002669 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002670 "GPRS BSSGP VC Identifier")
2671{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002672 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002673 struct gsm_bts *bts = vty->index;
2674
Harald Welte4511d892010-04-18 15:51:20 +02002675 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002676 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2677 return CMD_WARNING;
2678 }
2679
Harald Welte97a282b2010-03-14 15:37:43 +08002680 bts->gprs.cell.bvci = atoi(argv[0]);
2681
2682 return CMD_SUCCESS;
2683}
2684
Harald Weltea5731cf2010-03-22 11:48:36 +08002685DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2686 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002687 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002688 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002689 "GPRS NS Entity Identifier")
2690{
2691 struct gsm_bts *bts = vty->index;
2692
Harald Welte4511d892010-04-18 15:51:20 +02002693 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002694 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2695 return CMD_WARNING;
2696 }
2697
2698 bts->gprs.nse.nsei = atoi(argv[0]);
2699
2700 return CMD_SUCCESS;
2701}
2702
Harald Welte8f0ed552010-05-11 21:53:49 +02002703#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2704 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002705
Harald Welte97a282b2010-03-14 15:37:43 +08002706DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2707 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002708 GPRS_TEXT NSVC_TEXT
2709 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002710 "GPRS NS VC Identifier")
2711{
2712 struct gsm_bts *bts = vty->index;
2713 int idx = atoi(argv[0]);
2714
Harald Welte4511d892010-04-18 15:51:20 +02002715 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002716 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2717 return CMD_WARNING;
2718 }
2719
Harald Welte97a282b2010-03-14 15:37:43 +08002720 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2721
2722 return CMD_SUCCESS;
2723}
2724
Harald Welteaf387632010-03-14 23:30:30 +08002725DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2726 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002727 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002728 "GPRS NS Local UDP Port\n"
2729 "GPRS NS Local UDP Port\n"
2730 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002731 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002732{
2733 struct gsm_bts *bts = vty->index;
2734 int idx = atoi(argv[0]);
2735
Harald Welte4511d892010-04-18 15:51:20 +02002736 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002737 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2738 return CMD_WARNING;
2739 }
2740
Harald Welteaf387632010-03-14 23:30:30 +08002741 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2742
2743 return CMD_SUCCESS;
2744}
2745
2746DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2747 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002748 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002749 "GPRS NS Remote UDP Port\n"
2750 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002751 "GPRS NS Remote UDP Port\n"
2752 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002753{
2754 struct gsm_bts *bts = vty->index;
2755 int idx = atoi(argv[0]);
2756
Harald Welte4511d892010-04-18 15:51:20 +02002757 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002758 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2759 return CMD_WARNING;
2760 }
2761
Harald Welteaf387632010-03-14 23:30:30 +08002762 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2763
2764 return CMD_SUCCESS;
2765}
2766
2767DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2768 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002769 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002770 "GPRS NS Remote IP Address\n"
2771 "GPRS NS Remote IP Address\n"
2772 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002773{
2774 struct gsm_bts *bts = vty->index;
2775 int idx = atoi(argv[0]);
2776 struct in_addr ia;
2777
Harald Welte4511d892010-04-18 15:51:20 +02002778 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002779 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2780 return CMD_WARNING;
2781 }
2782
Harald Welteaf387632010-03-14 23:30:30 +08002783 inet_aton(argv[1], &ia);
2784 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2785
2786 return CMD_SUCCESS;
2787}
2788
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002789DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002790 "paging free <-1-1024>",
2791 "Paging options\n"
2792 "Only page when having a certain amount of free slots\n"
2793 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002794{
2795 struct gsm_bts *bts = vty->index;
2796
2797 bts->paging.free_chans_need = atoi(argv[0]);
2798 return CMD_SUCCESS;
2799}
2800
Harald Welte615e9562010-05-11 23:50:21 +02002801DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2802 "gprs ns timer " NS_TIMERS " <0-255>",
2803 GPRS_TEXT "Network Service\n"
2804 "Network Service Timer\n"
2805 NS_TIMERS_HELP "Timer Value\n")
2806{
2807 struct gsm_bts *bts = vty->index;
2808 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2809 int val = atoi(argv[1]);
2810
2811 if (bts->gprs.mode == BTS_GPRS_NONE) {
2812 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2813 return CMD_WARNING;
2814 }
2815
2816 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2817 return CMD_WARNING;
2818
2819 bts->gprs.nse.timer[idx] = val;
2820
2821 return CMD_SUCCESS;
2822}
2823
2824#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 +02002825#define BSSGP_TIMERS_HELP \
2826 "Tbvc-block timeout\n" \
2827 "Tbvc-block retries\n" \
2828 "Tbvc-unblock retries\n" \
2829 "Tbvcc-reset timeout\n" \
2830 "Tbvc-reset retries\n" \
2831 "Tbvc-suspend timeout\n" \
2832 "Tbvc-suspend retries\n" \
2833 "Tbvc-resume timeout\n" \
2834 "Tbvc-resume retries\n" \
2835 "Tbvc-capa-update timeout\n" \
2836 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002837
2838DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2839 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2840 GPRS_TEXT "Cell / BSSGP\n"
2841 "Cell/BSSGP Timer\n"
2842 BSSGP_TIMERS_HELP "Timer Value\n")
2843{
2844 struct gsm_bts *bts = vty->index;
2845 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2846 int val = atoi(argv[1]);
2847
2848 if (bts->gprs.mode == BTS_GPRS_NONE) {
2849 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2850 return CMD_WARNING;
2851 }
2852
2853 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2854 return CMD_WARNING;
2855
2856 bts->gprs.cell.timer[idx] = val;
2857
2858 return CMD_SUCCESS;
2859}
2860
Harald Welte97a282b2010-03-14 15:37:43 +08002861DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2862 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002863 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002864 "GPRS Routing Area Code\n"
2865 "GPRS Routing Area Code\n"
2866 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002867{
2868 struct gsm_bts *bts = vty->index;
2869
Harald Welte4511d892010-04-18 15:51:20 +02002870 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002871 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2872 return CMD_WARNING;
2873 }
2874
Harald Welte97a282b2010-03-14 15:37:43 +08002875 bts->gprs.rac = atoi(argv[0]);
2876
2877 return CMD_SUCCESS;
2878}
2879
Max292ec582016-07-28 11:55:37 +02002880DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2881 "gprs control-ack-type-rach", GPRS_TEXT
2882 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2883 "four access bursts format instead of default RLC/MAC control block\n")
2884{
2885 struct gsm_bts *bts = vty->index;
2886
2887 if (bts->gprs.mode == BTS_GPRS_NONE) {
2888 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2889 return CMD_WARNING;
2890 }
2891
2892 bts->gprs.ctrl_ack_type_use_block = false;
2893
2894 return CMD_SUCCESS;
2895}
2896
2897DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2898 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2899 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2900 "four access bursts format instead of default RLC/MAC control block\n")
2901{
2902 struct gsm_bts *bts = vty->index;
2903
2904 if (bts->gprs.mode == BTS_GPRS_NONE) {
2905 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2906 return CMD_WARNING;
2907 }
2908
2909 bts->gprs.ctrl_ack_type_use_block = true;
2910
2911 return CMD_SUCCESS;
2912}
2913
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002914DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2915 "gprs network-control-order (nc0|nc1|nc2)",
2916 GPRS_TEXT
2917 "GPRS Network Control Order\n"
2918 "MS controlled cell re-selection, no measurement reporting\n"
2919 "MS controlled cell re-selection, MS sends measurement reports\n"
2920 "Network controlled cell re-selection, MS sends measurement reports\n")
2921{
2922 struct gsm_bts *bts = vty->index;
2923
2924 if (bts->gprs.mode == BTS_GPRS_NONE) {
2925 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2926 return CMD_WARNING;
2927 }
2928
2929 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2930
2931 return CMD_SUCCESS;
2932}
2933
Harald Welte4511d892010-04-18 15:51:20 +02002934DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2935 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002936 GPRS_TEXT
2937 "GPRS Mode for this BTS\n"
2938 "GPRS Disabled on this BTS\n"
2939 "GPRS Enabled on this BTS\n"
2940 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002941{
2942 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002943 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002944
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002945 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002946 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2947 VTY_NEWLINE);
2948 return CMD_WARNING;
2949 }
2950
2951 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002952
2953 return CMD_SUCCESS;
2954}
2955
bhargava350533c2016-07-21 11:14:34 +05302956DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2957 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2958 "gprs 11bit_rach_support_for_egprs (0|1)",
2959 GPRS_TEXT "11 bit RACH options\n"
2960 "Disable 11 bit RACH for EGPRS\n"
2961 "Enable 11 bit RACH for EGPRS")
2962{
2963 struct gsm_bts *bts = vty->index;
2964
2965 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2966
2967 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2968 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2969 return CMD_WARNING;
2970 }
2971
2972 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2973 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2974 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2975 " enabled%s", VTY_NEWLINE);
2976 return CMD_WARNING;
2977 }
2978
2979 return CMD_SUCCESS;
2980}
2981
Harald Welte9fbff4a2010-07-30 11:50:09 +02002982#define SI_TEXT "System Information Messages\n"
2983#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)"
2984#define SI_TYPE_HELP "System Information Type 1\n" \
2985 "System Information Type 2\n" \
2986 "System Information Type 3\n" \
2987 "System Information Type 4\n" \
2988 "System Information Type 5\n" \
2989 "System Information Type 6\n" \
2990 "System Information Type 7\n" \
2991 "System Information Type 8\n" \
2992 "System Information Type 9\n" \
2993 "System Information Type 10\n" \
2994 "System Information Type 13\n" \
2995 "System Information Type 16\n" \
2996 "System Information Type 17\n" \
2997 "System Information Type 18\n" \
2998 "System Information Type 19\n" \
2999 "System Information Type 20\n" \
3000 "System Information Type 2bis\n" \
3001 "System Information Type 2ter\n" \
3002 "System Information Type 2quater\n" \
3003 "System Information Type 5bis\n" \
3004 "System Information Type 5ter\n"
3005
3006DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
3007 "system-information " SI_TYPE_TEXT " mode (static|computed)",
3008 SI_TEXT SI_TYPE_HELP
3009 "System Information Mode\n"
3010 "Static user-specified\n"
3011 "Dynamic, BSC-computed\n")
3012{
3013 struct gsm_bts *bts = vty->index;
3014 int type;
3015
3016 type = get_string_value(osmo_sitype_strs, argv[0]);
3017 if (type < 0) {
3018 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
3019 return CMD_WARNING;
3020 }
3021
3022 if (!strcmp(argv[1], "static"))
3023 bts->si_mode_static |= (1 << type);
3024 else
3025 bts->si_mode_static &= ~(1 << type);
3026
3027 return CMD_SUCCESS;
3028}
3029
3030DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
3031 "system-information " SI_TYPE_TEXT " static HEXSTRING",
3032 SI_TEXT SI_TYPE_HELP
3033 "Static System Information filling\n"
3034 "Static user-specified SI content in HEX notation\n")
3035{
3036 struct gsm_bts *bts = vty->index;
3037 int rc, type;
3038
3039 type = get_string_value(osmo_sitype_strs, argv[0]);
3040 if (type < 0) {
3041 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
3042 return CMD_WARNING;
3043 }
3044
3045 if (!(bts->si_mode_static & (1 << type))) {
3046 vty_out(vty, "SI Type %s is not configured in static mode%s",
3047 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
3048 return CMD_WARNING;
3049 }
3050
Harald Welte290aaed2010-07-30 11:53:18 +02003051 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02003052 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02003053
3054 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02003055 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
3056 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02003057 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3058 return CMD_WARNING;
3059 }
3060
3061 /* Mark this SI as present */
3062 bts->si_valid |= (1 << type);
3063
3064 return CMD_SUCCESS;
3065}
3066
Harald Welte42def722017-01-13 00:10:32 +01003067DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
3068 "early-classmark-sending (allowed|forbidden)",
3069 "Early Classmark Sending\n"
3070 "Early Classmark Sending is allowed\n"
3071 "Early Classmark Sending is forbidden\n")
3072{
3073 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01003074
3075 if (!strcmp(argv[0], "allowed"))
3076 bts->early_classmark_allowed = true;
3077 else
3078 bts->early_classmark_allowed = false;
3079
3080 return CMD_SUCCESS;
3081}
3082
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01003083DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
3084 "early-classmark-sending-3g (allowed|forbidden)",
3085 "3G Early Classmark Sending\n"
3086 "3G Early Classmark Sending is allowed\n"
3087 "3G Early Classmark Sending is forbidden\n")
3088{
3089 struct gsm_bts *bts = vty->index;
3090
3091 if (!strcmp(argv[0], "allowed"))
3092 bts->early_classmark_allowed_3g = true;
3093 else
3094 bts->early_classmark_allowed_3g = false;
3095
3096 return CMD_SUCCESS;
3097}
3098
Harald Welte32c09622011-01-11 23:44:56 +01003099DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01003100 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01003101 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003102 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
3103 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01003104{
3105 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01003106 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01003107
Harald Welte64c07d22011-02-15 11:43:27 +01003108 switch (mode) {
3109 case NL_MODE_MANUAL_SI5SEP:
3110 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01003111 /* make sure we clear the current list when switching to
3112 * manual mode */
3113 if (bts->neigh_list_manual_mode == 0)
3114 memset(&bts->si_common.data.neigh_list, 0,
3115 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01003116 break;
3117 default:
3118 break;
3119 }
3120
3121 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01003122
3123 return CMD_SUCCESS;
3124}
3125
3126DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003127 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01003128 "Neighbor List\n" "Add to manual neighbor list\n"
3129 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
3130 "ARFCN of neighbor\n")
3131{
3132 struct gsm_bts *bts = vty->index;
3133 struct bitvec *bv = &bts->si_common.neigh_list;
3134 uint16_t arfcn = atoi(argv[1]);
3135
3136 if (!bts->neigh_list_manual_mode) {
3137 vty_out(vty, "%% Cannot configure neighbor list in "
3138 "automatic mode%s", VTY_NEWLINE);
3139 return CMD_WARNING;
3140 }
3141
3142 if (!strcmp(argv[0], "add"))
3143 bitvec_set_bit_pos(bv, arfcn, 1);
3144 else
3145 bitvec_set_bit_pos(bv, arfcn, 0);
3146
3147 return CMD_SUCCESS;
3148}
3149
Max70fdd242017-06-15 15:10:53 +02003150/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02003151DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01003152 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
3153 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
3154 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
3155 "Add to manual SI2quater neighbor list\n"
3156 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
3157 "threshold high bits\n" "threshold high bits\n"
3158 "threshold low bits\n" "threshold low bits (32 means NA)\n"
3159 "priority\n" "priority (8 means NA)\n"
3160 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
3161 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02003162{
3163 struct gsm_bts *bts = vty->index;
3164 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
3165 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01003166 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
3167 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02003168 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02003169
Max70fdd242017-06-15 15:10:53 +02003170 switch (r) {
3171 case 1:
3172 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
3173 thresh_hi, VTY_NEWLINE);
3174 break;
3175 case EARFCN_THRESH_LOW_INVALID:
3176 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
3177 thresh_lo, VTY_NEWLINE);
3178 break;
3179 case EARFCN_QRXLV_INVALID + 1:
3180 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
3181 qrx, VTY_NEWLINE);
3182 break;
3183 case EARFCN_PRIO_INVALID:
3184 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
3185 prio, VTY_NEWLINE);
3186 break;
3187 default:
3188 if (r < 0) {
3189 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
3190 return CMD_WARNING;
3191 }
Max59a1bf32016-04-15 16:04:46 +02003192 }
3193
Max70fdd242017-06-15 15:10:53 +02003194 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01003195 return CMD_SUCCESS;
3196
Maxf39d03a2017-05-12 17:00:30 +02003197 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02003198 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02003199 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01003200
Maxaafff962016-04-20 15:57:14 +02003201 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02003202}
3203
3204DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02003205 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02003206 "SI2quater Neighbor List\n"
3207 "SI2quater Neighbor List\n"
3208 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02003209 "EARFCN of neighbor\n"
3210 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02003211{
3212 struct gsm_bts *bts = vty->index;
3213 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02003214 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02003215 int r = osmo_earfcn_del(e, arfcn);
3216 if (r < 0) {
3217 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02003218 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02003219 return CMD_WARNING;
3220 }
3221
3222 return CMD_SUCCESS;
3223}
3224
Max26679e02016-04-20 15:57:13 +02003225DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02003226 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02003227 "SI2quater Neighbor List\n"
3228 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
3229 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
3230 "diversity bit\n")
3231{
3232 struct gsm_bts *bts = vty->index;
3233 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
3234
3235 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
3236 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02003237 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 +01003238 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02003239 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02003240 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
3241 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01003242 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02003243 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02003244 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02003245 return CMD_WARNING;
3246 }
3247
3248 return CMD_SUCCESS;
3249}
3250
3251DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02003252 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02003253 "SI2quater Neighbor List\n"
3254 "SI2quater Neighbor List\n"
3255 "Delete from SI2quater manual neighbor list\n"
3256 "UARFCN of neighbor\n"
3257 "UARFCN\n"
3258 "scrambling code\n")
3259{
3260 struct gsm_bts *bts = vty->index;
3261
3262 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
3263 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
3264 VTY_NEWLINE);
3265 return CMD_WARNING;
3266 }
3267
3268 return CMD_SUCCESS;
3269}
3270
Harald Welte64c07d22011-02-15 11:43:27 +01003271DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003272 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003273 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003274 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
3275 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
3276 "ARFCN of neighbor\n")
3277{
3278 struct gsm_bts *bts = vty->index;
3279 struct bitvec *bv = &bts->si_common.si5_neigh_list;
3280 uint16_t arfcn = atoi(argv[1]);
3281
3282 if (!bts->neigh_list_manual_mode) {
3283 vty_out(vty, "%% Cannot configure neighbor list in "
3284 "automatic mode%s", VTY_NEWLINE);
3285 return CMD_WARNING;
3286 }
3287
3288 if (!strcmp(argv[0], "add"))
3289 bitvec_set_bit_pos(bv, arfcn, 1);
3290 else
3291 bitvec_set_bit_pos(bv, arfcn, 0);
3292
3293 return CMD_SUCCESS;
3294}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003295
Harald Welte8254cf72017-05-29 13:42:19 +02003296DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3297 "pcu-socket PATH",
3298 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3299 "Path in the file system for the unix-domain PCU socket\n")
3300{
3301 struct gsm_bts *bts = vty->index;
3302 int rc;
3303
Harald Welte4a824ca2017-05-29 13:54:27 +02003304 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003305 pcu_sock_exit(bts);
3306 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3307 if (rc < 0) {
3308 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3309 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3310 return CMD_WARNING;
3311 }
3312
3313 return CMD_SUCCESS;
3314}
3315
Stefan Sperling6442e432018-02-06 14:44:54 +01003316DEFUN(cfg_bts_acc_ramping,
3317 cfg_bts_acc_ramping_cmd,
3318 "access-control-class-ramping",
3319 "Enable Access Control Class ramping\n")
3320{
3321 struct gsm_bts *bts = vty->index;
3322
Stefan Sperlingea333412018-04-10 16:36:54 +02003323 if (!acc_ramp_is_enabled(&bts->acc_ramp))
3324 acc_ramp_set_enabled(&bts->acc_ramp, true);
Stefan Sperling6442e432018-02-06 14:44:54 +01003325
Stefan Sperling60ecdef2018-04-10 17:55:08 +02003326 /*
3327 * ACC ramping takes effect either when the BTS reconnects RSL,
3328 * or when RF administrative state changes to 'unlocked'.
3329 */
Stefan Sperling6442e432018-02-06 14:44:54 +01003330 return CMD_SUCCESS;
3331}
3332
3333DEFUN(cfg_bts_no_acc_ramping, cfg_bts_no_acc_ramping_cmd,
3334 "no access-control-class-ramping",
3335 NO_STR
3336 "Disable Access Control Class ramping\n")
3337{
3338 struct gsm_bts *bts = vty->index;
3339
3340 if (acc_ramp_is_enabled(&bts->acc_ramp)) {
3341 acc_ramp_abort(&bts->acc_ramp);
Stefan Sperlingea333412018-04-10 16:36:54 +02003342 acc_ramp_set_enabled(&bts->acc_ramp, false);
Stefan Sperling6442e432018-02-06 14:44:54 +01003343 gsm_bts_set_system_infos(bts);
3344 }
3345
3346 return CMD_SUCCESS;
3347}
3348
3349DEFUN(cfg_bts_acc_ramping_step_interval,
3350 cfg_bts_acc_ramping_step_interval_cmd,
3351 "access-control-class-ramping-step-interval (<"
3352 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MIN) "-"
3353 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MAX) ">|dynamic)",
3354 "Configure Access Control Class ramping step interval\n"
3355 "Set a fixed step interval (in seconds)\n"
3356 "Use dynamic step interval based on BTS channel load\n")
3357{
3358 struct gsm_bts *bts = vty->index;
3359 bool dynamic = (strcmp(argv[0], "dynamic") == 0);
3360 int error;
3361
3362 if (dynamic) {
3363 acc_ramp_set_step_interval_dynamic(&bts->acc_ramp);
3364 return CMD_SUCCESS;
3365 }
3366
3367 error = acc_ramp_set_step_interval(&bts->acc_ramp, atoi(argv[0]));
3368 if (error != 0) {
3369 if (error == -ERANGE)
3370 vty_out(vty, "Unable to set ACC ramp step interval: value out of range%s", VTY_NEWLINE);
3371 else
3372 vty_out(vty, "Unable to set ACC ramp step interval: unknown error%s", VTY_NEWLINE);
3373 return CMD_WARNING;
3374 }
3375
3376 return CMD_SUCCESS;
3377}
3378
3379DEFUN(cfg_bts_acc_ramping_step_size,
3380 cfg_bts_acc_ramping_step_size_cmd,
3381 "access-control-class-ramping-step-size (<"
3382 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MIN) "-"
3383 OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MAX) ">)",
3384 "Configure Access Control Class ramping step size\n"
3385 "Set the number of Access Control Classes to enable per ramping step\n")
3386{
3387 struct gsm_bts *bts = vty->index;
3388 int error;
3389
3390 error = acc_ramp_set_step_size(&bts->acc_ramp, atoi(argv[0]));
3391 if (error != 0) {
3392 if (error == -ERANGE)
3393 vty_out(vty, "Unable to set ACC ramp step size: value out of range%s", VTY_NEWLINE);
3394 else
3395 vty_out(vty, "Unable to set ACC ramp step size: unknown error%s", VTY_NEWLINE);
3396 return CMD_WARNING;
3397 }
3398
3399 return CMD_SUCCESS;
3400}
3401
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003402#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3403
3404DEFUN(cfg_bts_excl_rf_lock,
3405 cfg_bts_excl_rf_lock_cmd,
3406 "rf-lock-exclude",
3407 EXCL_RFLOCK_STR)
3408{
3409 struct gsm_bts *bts = vty->index;
3410 bts->excl_from_rf_lock = 1;
3411 return CMD_SUCCESS;
3412}
3413
3414DEFUN(cfg_bts_no_excl_rf_lock,
3415 cfg_bts_no_excl_rf_lock_cmd,
3416 "no rf-lock-exclude",
3417 NO_STR EXCL_RFLOCK_STR)
3418{
3419 struct gsm_bts *bts = vty->index;
3420 bts->excl_from_rf_lock = 0;
3421 return CMD_SUCCESS;
3422}
3423
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003424#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3425
3426DEFUN(cfg_bts_force_comb_si,
3427 cfg_bts_force_comb_si_cmd,
3428 "force-combined-si",
3429 FORCE_COMB_SI_STR)
3430{
3431 struct gsm_bts *bts = vty->index;
3432 bts->force_combined_si = 1;
3433 return CMD_SUCCESS;
3434}
3435
3436DEFUN(cfg_bts_no_force_comb_si,
3437 cfg_bts_no_force_comb_si_cmd,
3438 "no force-combined-si",
3439 NO_STR FORCE_COMB_SI_STR)
3440{
3441 struct gsm_bts *bts = vty->index;
3442 bts->force_combined_si = 0;
3443 return CMD_SUCCESS;
3444}
3445
Andreas Eversberga83d5112013-12-07 18:32:28 +01003446static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3447{
3448 struct gsm_bts *bts = vty->index;
3449 struct bts_codec_conf *codec = &bts->codec;
3450 int i;
3451
3452 codec->hr = 0;
3453 codec->efr = 0;
3454 codec->amr = 0;
3455 for (i = 0; i < argc; i++) {
3456 if (!strcmp(argv[i], "hr"))
3457 codec->hr = 1;
3458 if (!strcmp(argv[i], "efr"))
3459 codec->efr = 1;
3460 if (!strcmp(argv[i], "amr"))
3461 codec->amr = 1;
3462 }
3463}
3464
3465#define CODEC_PAR_STR " (hr|efr|amr)"
3466#define CODEC_HELP_STR "Half Rate\n" \
3467 "Enhanced Full Rate\nAdaptive Multirate\n"
3468
3469DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3470 "codec-support fr",
3471 "Codec Support settings\nFullrate\n")
3472{
3473 _get_codec_from_arg(vty, 0, argv);
3474 return CMD_SUCCESS;
3475}
3476
3477DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3478 "codec-support fr" CODEC_PAR_STR,
3479 "Codec Support settings\nFullrate\n"
3480 CODEC_HELP_STR)
3481{
3482 _get_codec_from_arg(vty, 1, argv);
3483 return CMD_SUCCESS;
3484}
3485
3486DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3487 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3488 "Codec Support settings\nFullrate\n"
3489 CODEC_HELP_STR CODEC_HELP_STR)
3490{
3491 _get_codec_from_arg(vty, 2, argv);
3492 return CMD_SUCCESS;
3493}
3494
3495DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3496 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3497 "Codec Support settings\nFullrate\n"
3498 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3499{
3500 _get_codec_from_arg(vty, 3, argv);
3501 return CMD_SUCCESS;
3502}
3503
3504DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3505 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3506 "Codec Support settings\nFullrate\n"
3507 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3508{
3509 _get_codec_from_arg(vty, 4, argv);
3510 return CMD_SUCCESS;
3511}
3512
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003513DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3514 "depends-on-bts <0-255>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003515 "This BTS can only be started if another one is up\n"
3516 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003517{
3518 struct gsm_bts *bts = vty->index;
3519 struct gsm_bts *other_bts;
3520 int dep = atoi(argv[0]);
3521
3522
3523 if (!is_ipaccess_bts(bts)) {
3524 vty_out(vty, "This feature is only available for IP systems.%s",
3525 VTY_NEWLINE);
3526 return CMD_WARNING;
3527 }
3528
3529 other_bts = gsm_bts_num(bts->network, dep);
3530 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3531 vty_out(vty, "This feature is only available for IP systems.%s",
3532 VTY_NEWLINE);
3533 return CMD_WARNING;
3534 }
3535
3536 if (dep >= bts->nr) {
3537 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3538 VTY_NEWLINE);
3539 return CMD_WARNING;
3540 }
3541
3542 bts_depend_mark(bts, dep);
3543 return CMD_SUCCESS;
3544}
3545
3546DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3547 "depeneds-on-bts <0-255>",
3548 NO_STR "This BTS can only be started if another one is up\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003549 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003550{
3551 struct gsm_bts *bts = vty->index;
3552 int dep = atoi(argv[0]);
3553
3554 bts_depend_clear(bts, dep);
3555 return CMD_SUCCESS;
3556}
3557
Andreas Eversberg73266522014-01-19 11:47:44 +01003558#define AMR_TEXT "Adaptive Multi Rate settings\n"
3559#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3560#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3561 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3562#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3563#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3564
3565static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3566{
3567 struct gsm_bts *bts = vty->index;
3568 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3569 struct gsm48_multi_rate_conf *mr_conf =
3570 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3571 int i;
3572
3573 mr->gsm48_ie[1] = 0;
3574 for (i = 0; i < argc; i++)
3575 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3576 mr_conf->icmi = 0;
3577}
3578
3579static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3580{
3581 struct gsm_bts *bts = vty->index;
3582 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003583 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003584 int i;
3585
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003586 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3587 for (i = 0; i < argc - 1; i++)
3588 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003589}
3590
3591static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3592{
3593 struct gsm_bts *bts = vty->index;
3594 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003595 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003596 int i;
3597
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003598 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3599 for (i = 0; i < argc - 1; i++)
3600 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003601}
3602
3603static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3604{
3605 struct gsm_bts *bts = vty->index;
3606 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3607 struct gsm48_multi_rate_conf *mr_conf =
3608 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3609 int num = 0, i;
3610
3611 for (i = 0; i < ((full) ? 8 : 6); i++) {
3612 if ((mr->gsm48_ie[1] & (1 << i))) {
3613 num++;
3614 }
3615 }
3616
3617 if (argv[0][0] == 'a' || num == 0)
3618 mr_conf->icmi = 0;
3619 else {
3620 mr_conf->icmi = 1;
3621 if (num < atoi(argv[0]))
3622 mr_conf->smod = num - 1;
3623 else
3624 mr_conf->smod = atoi(argv[0]) - 1;
3625 }
3626}
3627
3628#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3629#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3630 "10,2k\n12,2k\n"
3631
3632#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3633#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3634
3635#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3636#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3637
3638DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3639 "amr tch-f modes" AMR_TCHF_PAR_STR,
3640 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3641 AMR_TCHF_HELP_STR)
3642{
3643 get_amr_from_arg(vty, 1, argv, 1);
3644 return CMD_SUCCESS;
3645}
3646
3647DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3648 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3649 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3650 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3651{
3652 get_amr_from_arg(vty, 2, argv, 1);
3653 return CMD_SUCCESS;
3654}
3655
3656DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3657 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3658 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3659 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3660{
3661 get_amr_from_arg(vty, 3, argv, 1);
3662 return CMD_SUCCESS;
3663}
3664
3665DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3666 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3667 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3668 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3669{
3670 get_amr_from_arg(vty, 4, argv, 1);
3671 return CMD_SUCCESS;
3672}
3673
3674DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3675 "amr tch-f start-mode (auto|1|2|3|4)",
3676 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3677{
3678 get_amr_start_from_arg(vty, argv, 1);
3679 return CMD_SUCCESS;
3680}
3681
3682DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3683 "amr tch-f threshold (ms|bts) <0-63>",
3684 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3685 AMR_TH_HELP_STR)
3686{
3687 get_amr_th_from_arg(vty, 2, argv, 1);
3688 return CMD_SUCCESS;
3689}
3690
3691DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3692 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3693 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3694 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3695{
3696 get_amr_th_from_arg(vty, 3, argv, 1);
3697 return CMD_SUCCESS;
3698}
3699
3700DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3701 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3702 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3703 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3704{
3705 get_amr_th_from_arg(vty, 4, argv, 1);
3706 return CMD_SUCCESS;
3707}
3708
3709DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3710 "amr tch-f hysteresis (ms|bts) <0-15>",
3711 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3712 AMR_HY_HELP_STR)
3713{
3714 get_amr_hy_from_arg(vty, 2, argv, 1);
3715 return CMD_SUCCESS;
3716}
3717
3718DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3719 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3720 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3721 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3722{
3723 get_amr_hy_from_arg(vty, 3, argv, 1);
3724 return CMD_SUCCESS;
3725}
3726
3727DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3728 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3729 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3730 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3731{
3732 get_amr_hy_from_arg(vty, 4, argv, 1);
3733 return CMD_SUCCESS;
3734}
3735
3736DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3737 "amr tch-h modes" AMR_TCHH_PAR_STR,
3738 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3739 AMR_TCHH_HELP_STR)
3740{
3741 get_amr_from_arg(vty, 1, argv, 0);
3742 return CMD_SUCCESS;
3743}
3744
3745DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3746 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3747 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3748 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3749{
3750 get_amr_from_arg(vty, 2, argv, 0);
3751 return CMD_SUCCESS;
3752}
3753
3754DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3755 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3756 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3757 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3758{
3759 get_amr_from_arg(vty, 3, argv, 0);
3760 return CMD_SUCCESS;
3761}
3762
3763DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3764 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3765 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3766 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3767{
3768 get_amr_from_arg(vty, 4, argv, 0);
3769 return CMD_SUCCESS;
3770}
3771
3772DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3773 "amr tch-h start-mode (auto|1|2|3|4)",
3774 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3775{
3776 get_amr_start_from_arg(vty, argv, 0);
3777 return CMD_SUCCESS;
3778}
3779
3780DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3781 "amr tch-h threshold (ms|bts) <0-63>",
3782 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3783 AMR_TH_HELP_STR)
3784{
3785 get_amr_th_from_arg(vty, 2, argv, 0);
3786 return CMD_SUCCESS;
3787}
3788
3789DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3790 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3791 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3792 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3793{
3794 get_amr_th_from_arg(vty, 3, argv, 0);
3795 return CMD_SUCCESS;
3796}
3797
3798DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3799 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3800 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3801 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3802{
3803 get_amr_th_from_arg(vty, 4, argv, 0);
3804 return CMD_SUCCESS;
3805}
3806
3807DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3808 "amr tch-h hysteresis (ms|bts) <0-15>",
3809 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3810 AMR_HY_HELP_STR)
3811{
3812 get_amr_hy_from_arg(vty, 2, argv, 0);
3813 return CMD_SUCCESS;
3814}
3815
3816DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3817 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3818 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3819 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3820{
3821 get_amr_hy_from_arg(vty, 3, argv, 0);
3822 return CMD_SUCCESS;
3823}
3824
3825DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3826 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3827 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3828 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3829{
3830 get_amr_hy_from_arg(vty, 4, argv, 0);
3831 return CMD_SUCCESS;
3832}
3833
Harald Welte8f0ed552010-05-11 21:53:49 +02003834#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003835
Harald Welte5258fc42009-03-28 19:07:53 +00003836/* per TRX configuration */
3837DEFUN(cfg_trx,
3838 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003839 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003840 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003841 "Select a TRX to configure")
3842{
3843 int trx_nr = atoi(argv[0]);
3844 struct gsm_bts *bts = vty->index;
3845 struct gsm_bts_trx *trx;
3846
Harald Weltee441d9c2009-06-21 16:17:15 +02003847 if (trx_nr > bts->num_trx) {
3848 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3849 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003850 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003851 } else if (trx_nr == bts->num_trx) {
3852 /* we need to allocate a new one */
3853 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003854 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003855 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003856
Harald Weltee441d9c2009-06-21 16:17:15 +02003857 if (!trx)
3858 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003859
3860 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003861 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003862 vty->node = TRX_NODE;
3863
3864 return CMD_SUCCESS;
3865}
3866
3867DEFUN(cfg_trx_arfcn,
3868 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003869 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003870 "Set the ARFCN for this TRX\n"
3871 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003872{
3873 int arfcn = atoi(argv[0]);
3874 struct gsm_bts_trx *trx = vty->index;
3875
3876 /* FIXME: check if this ARFCN is supported by this TRX */
3877
3878 trx->arfcn = arfcn;
3879
3880 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3881 /* FIXME: use OML layer to update the ARFCN */
3882 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3883
3884 return CMD_SUCCESS;
3885}
3886
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003887DEFUN(cfg_trx_nominal_power,
3888 cfg_trx_nominal_power_cmd,
3889 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003890 "Nominal TRX RF Power in dBm\n"
3891 "Nominal TRX RF Power in dBm\n"
3892 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003893{
3894 struct gsm_bts_trx *trx = vty->index;
3895
3896 trx->nominal_power = atoi(argv[0]);
3897
3898 return CMD_SUCCESS;
3899}
3900
Harald Weltefcd24452009-06-20 18:15:19 +02003901DEFUN(cfg_trx_max_power_red,
3902 cfg_trx_max_power_red_cmd,
3903 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003904 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003905 "Reduction of maximum BS RF Power in dB\n")
3906{
3907 int maxpwr_r = atoi(argv[0]);
3908 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003909 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003910
3911 /* FIXME: check if our BTS type supports more than 12 */
3912 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3913 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3914 maxpwr_r, VTY_NEWLINE);
3915 return CMD_WARNING;
3916 }
3917 if (maxpwr_r & 1) {
3918 vty_out(vty, "%% Power %d dB is not an even value%s",
3919 maxpwr_r, VTY_NEWLINE);
3920 return CMD_WARNING;
3921 }
3922
3923 trx->max_power_red = maxpwr_r;
3924
3925 /* FIXME: make sure we update this using OML */
3926
3927 return CMD_SUCCESS;
3928}
3929
Harald Welte42581822009-08-08 16:12:58 +02003930DEFUN(cfg_trx_rsl_e1,
3931 cfg_trx_rsl_e1_cmd,
3932 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003933 "RSL Parameters\n"
3934 "E1/T1 interface to be used for RSL\n"
3935 "E1/T1 interface to be used for RSL\n"
3936 "E1/T1 Line Number to be used for RSL\n"
3937 "E1/T1 Timeslot to be used for RSL\n"
3938 "E1/T1 Timeslot to be used for RSL\n"
3939 "E1/T1 Sub-slot to be used for RSL\n"
3940 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3941 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3942 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3943 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3944 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003945{
3946 struct gsm_bts_trx *trx = vty->index;
3947
3948 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3949
3950 return CMD_SUCCESS;
3951}
3952
3953DEFUN(cfg_trx_rsl_e1_tei,
3954 cfg_trx_rsl_e1_tei_cmd,
3955 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003956 "RSL Parameters\n"
3957 "Set the TEI to be used for RSL\n"
3958 "Set the TEI to be used for RSL\n"
3959 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003960{
3961 struct gsm_bts_trx *trx = vty->index;
3962
3963 trx->rsl_tei = atoi(argv[0]);
3964
3965 return CMD_SUCCESS;
3966}
3967
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003968DEFUN(cfg_trx_rf_locked,
3969 cfg_trx_rf_locked_cmd,
3970 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003971 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3972 "TRX is NOT RF locked (active)\n"
3973 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003974{
3975 int locked = atoi(argv[0]);
3976 struct gsm_bts_trx *trx = vty->index;
3977
Maxbe356ed2017-09-07 19:10:09 +02003978 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003979 return CMD_SUCCESS;
3980}
Harald Welte42581822009-08-08 16:12:58 +02003981
Harald Welte5258fc42009-03-28 19:07:53 +00003982/* per TS configuration */
3983DEFUN(cfg_ts,
3984 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003985 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003986 "Select a Timeslot to configure\n"
3987 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003988{
3989 int ts_nr = atoi(argv[0]);
3990 struct gsm_bts_trx *trx = vty->index;
3991 struct gsm_bts_trx_ts *ts;
3992
3993 if (ts_nr >= TRX_NR_TS) {
3994 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3995 TRX_NR_TS, VTY_NEWLINE);
3996 return CMD_WARNING;
3997 }
3998
3999 ts = &trx->ts[ts_nr];
4000
4001 vty->index = ts;
4002 vty->node = TS_NODE;
4003
4004 return CMD_SUCCESS;
4005}
4006
Harald Weltea6fd58e2009-08-07 00:25:23 +02004007DEFUN(cfg_ts_pchan,
4008 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004009 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01004010 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004011{
4012 struct gsm_bts_trx_ts *ts = vty->index;
4013 int pchanc;
4014
4015 pchanc = gsm_pchan_parse(argv[0]);
4016 if (pchanc < 0)
4017 return CMD_WARNING;
4018
4019 ts->pchan = pchanc;
4020
4021 return CMD_SUCCESS;
4022}
4023
4024/* used for backwards compatibility with old config files that still
4025 * have uppercase pchan type names */
4026DEFUN_HIDDEN(cfg_ts_pchan_compat,
4027 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02004028 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01004029 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02004030{
4031 struct gsm_bts_trx_ts *ts = vty->index;
4032 int pchanc;
4033
4034 pchanc = gsm_pchan_parse(argv[0]);
Stefan Sperlinge67ebf02018-07-17 16:03:07 +02004035 if (pchanc < 0) {
4036 vty_out(vty, "Unknown physical channel name '%s'%s", argv[0], VTY_NEWLINE);
4037 return CMD_ERR_NO_MATCH;
4038 }
Harald Weltea6fd58e2009-08-07 00:25:23 +02004039
4040 ts->pchan = pchanc;
4041
4042 return CMD_SUCCESS;
4043}
4044
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004045
4046
Harald Welte135a6482011-05-30 12:09:13 +02004047DEFUN(cfg_ts_tsc,
4048 cfg_ts_tsc_cmd,
4049 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02004050 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02004051{
4052 struct gsm_bts_trx_ts *ts = vty->index;
4053
Philipp Maier8c498fc2018-02-21 13:24:36 +01004054 if (!osmo_bts_has_feature(&ts->trx->bts->model->features, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01004055 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
4056 "falling back to BCC%s", VTY_NEWLINE);
4057 ts->tsc = -1;
4058 return CMD_WARNING;
4059 }
4060
Harald Welte135a6482011-05-30 12:09:13 +02004061 ts->tsc = atoi(argv[0]);
4062
4063 return CMD_SUCCESS;
4064}
4065
Harald Weltea39b0f22010-06-14 22:26:10 +02004066#define HOPPING_STR "Configure frequency hopping\n"
4067
4068DEFUN(cfg_ts_hopping,
4069 cfg_ts_hopping_cmd,
4070 "hopping enabled (0|1)",
4071 HOPPING_STR "Enable or disable frequency hopping\n"
4072 "Disable frequency hopping\n" "Enable frequency hopping\n")
4073{
4074 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02004075 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02004076
Philipp Maier8c498fc2018-02-21 13:24:36 +01004077 if (enabled && !osmo_bts_has_feature(&ts->trx->bts->model->features, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02004078 vty_out(vty, "BTS model does not support hopping%s",
4079 VTY_NEWLINE);
4080 return CMD_WARNING;
4081 }
4082
4083 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02004084
4085 return CMD_SUCCESS;
4086}
4087
Harald Welte6e0cd042009-09-12 13:05:33 +02004088DEFUN(cfg_ts_hsn,
4089 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02004090 "hopping sequence-number <0-63>",
4091 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02004092 "Which hopping sequence to use for this channel\n"
4093 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004094{
4095 struct gsm_bts_trx_ts *ts = vty->index;
4096
4097 ts->hopping.hsn = atoi(argv[0]);
4098
4099 return CMD_SUCCESS;
4100}
4101
4102DEFUN(cfg_ts_maio,
4103 cfg_ts_maio_cmd,
4104 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02004105 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02004106 "Which hopping MAIO to use for this channel\n"
4107 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004108{
4109 struct gsm_bts_trx_ts *ts = vty->index;
4110
4111 ts->hopping.maio = atoi(argv[0]);
4112
4113 return CMD_SUCCESS;
4114}
4115
4116DEFUN(cfg_ts_arfcn_add,
4117 cfg_ts_arfcn_add_cmd,
4118 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02004119 HOPPING_STR "Configure hopping ARFCN list\n"
4120 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004121{
4122 struct gsm_bts_trx_ts *ts = vty->index;
4123 int arfcn = atoi(argv[0]);
4124
Harald Weltea39b0f22010-06-14 22:26:10 +02004125 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
4126
Harald Welte6e0cd042009-09-12 13:05:33 +02004127 return CMD_SUCCESS;
4128}
4129
4130DEFUN(cfg_ts_arfcn_del,
4131 cfg_ts_arfcn_del_cmd,
4132 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02004133 HOPPING_STR "Configure hopping ARFCN list\n"
4134 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02004135{
4136 struct gsm_bts_trx_ts *ts = vty->index;
4137 int arfcn = atoi(argv[0]);
4138
Harald Weltea39b0f22010-06-14 22:26:10 +02004139 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
4140
Harald Welte6e0cd042009-09-12 13:05:33 +02004141 return CMD_SUCCESS;
4142}
4143
Harald Weltea6fd58e2009-08-07 00:25:23 +02004144DEFUN(cfg_ts_e1_subslot,
4145 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02004146 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02004147 "E1/T1 channel connected to this on-air timeslot\n"
4148 "E1/T1 channel connected to this on-air timeslot\n"
4149 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02004150 "E1/T1 timeslot connected to this on-air timeslot\n"
4151 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02004152 "E1/T1 sub-slot connected to this on-air timeslot\n"
4153 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
4154 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
4155 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
4156 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
4157 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02004158{
4159 struct gsm_bts_trx_ts *ts = vty->index;
4160
Harald Welte42581822009-08-08 16:12:58 +02004161 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004162
4163 return CMD_SUCCESS;
4164}
Harald Welte5258fc42009-03-28 19:07:53 +00004165
Stefan Sperling71d524c2018-05-17 14:38:27 +02004166int print_counter(struct rate_ctr_group *bsc_ctrs, struct rate_ctr *ctr, const struct rate_ctr_desc *desc, void *data)
4167{
4168 struct vty *vty = data;
4169 vty_out(vty, "%25s: %10"PRIu64" %s%s", desc->name, ctr->current, desc->description, VTY_NEWLINE);
4170 return 0;
4171}
4172
Harald Welte4f10c252010-05-16 21:47:13 +02004173void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
4174{
Stefan Sperling71d524c2018-05-17 14:38:27 +02004175 rate_ctr_for_each_counter(net->bsc_ctrs, print_counter, vty);
Harald Welte4f10c252010-05-16 21:47:13 +02004176}
4177
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004178DEFUN(drop_bts,
4179 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02004180 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02004181 "Debug/Simulation command to drop Abis/IP BTS\n"
4182 "Debug/Simulation command to drop Abis/IP BTS\n"
4183 "Debug/Simulation command to drop Abis/IP BTS\n"
4184 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004185{
4186 struct gsm_network *gsmnet;
4187 struct gsm_bts_trx *trx;
4188 struct gsm_bts *bts;
4189 unsigned int bts_nr;
4190
4191 gsmnet = gsmnet_from_vty(vty);
4192
4193 bts_nr = atoi(argv[0]);
4194 if (bts_nr >= gsmnet->num_bts) {
4195 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4196 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4197 return CMD_WARNING;
4198 }
4199
4200 bts = gsm_bts_num(gsmnet, bts_nr);
4201 if (!bts) {
4202 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4203 return CMD_WARNING;
4204 }
4205
4206 if (!is_ipaccess_bts(bts)) {
4207 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
4208 return CMD_WARNING;
4209 }
4210
4211
4212 /* close all connections */
4213 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004214 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004215 } else if (strcmp(argv[1], "rsl") == 0) {
4216 /* close all rsl connections */
4217 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004218 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004219 }
4220 } else {
4221 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
4222 return CMD_WARNING;
4223 }
4224
4225 return CMD_SUCCESS;
4226}
4227
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004228DEFUN(restart_bts, restart_bts_cmd,
4229 "restart-bts <0-65535>",
4230 "Restart ip.access nanoBTS through OML\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004231 BTS_NR_STR)
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004232{
4233 struct gsm_network *gsmnet;
4234 struct gsm_bts_trx *trx;
4235 struct gsm_bts *bts;
4236 unsigned int bts_nr;
4237
4238 gsmnet = gsmnet_from_vty(vty);
4239
4240 bts_nr = atoi(argv[0]);
4241 if (bts_nr >= gsmnet->num_bts) {
4242 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4243 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4244 return CMD_WARNING;
4245 }
4246
4247 bts = gsm_bts_num(gsmnet, bts_nr);
4248 if (!bts) {
4249 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4250 return CMD_WARNING;
4251 }
4252
4253 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
4254 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
4255 VTY_NEWLINE);
4256 return CMD_WARNING;
4257 }
4258
4259 /* go from last TRX to c0 */
4260 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4261 abis_nm_ipaccess_restart(trx);
4262
4263 return CMD_SUCCESS;
4264}
4265
Harald Welte8e2e22f2017-07-10 20:25:10 +02004266DEFUN(bts_resend, bts_resend_cmd,
4267 "bts <0-255> resend-system-information",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004268 "BTS Specific Commands\n" BTS_NR_STR
Harald Welte8e2e22f2017-07-10 20:25:10 +02004269 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
4270{
4271 struct gsm_network *gsmnet;
4272 struct gsm_bts_trx *trx;
4273 struct gsm_bts *bts;
4274 unsigned int bts_nr;
4275
4276 gsmnet = gsmnet_from_vty(vty);
4277
4278 bts_nr = atoi(argv[0]);
4279 if (bts_nr >= gsmnet->num_bts) {
4280 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4281 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4282 return CMD_WARNING;
4283 }
4284
4285 bts = gsm_bts_num(gsmnet, bts_nr);
4286 if (!bts) {
4287 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4288 return CMD_WARNING;
4289 }
4290
4291 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4292 gsm_bts_trx_set_system_infos(trx);
4293
4294 return CMD_SUCCESS;
4295}
4296
4297
Harald Welte30f1f372014-12-28 15:00:45 +01004298DEFUN(smscb_cmd, smscb_cmd_cmd,
4299 "bts <0-255> smscb-command <1-4> HEXSTRING",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004300 "BTS related commands\n" BTS_NR_STR
Harald Welte30f1f372014-12-28 15:00:45 +01004301 "SMS Cell Broadcast\n" "Last Valid Block\n"
4302 "Hex Encoded SMSCB message (up to 88 octets)\n")
4303{
4304 struct gsm_bts *bts;
4305 int bts_nr = atoi(argv[0]);
4306 int last_block = atoi(argv[1]);
4307 struct rsl_ie_cb_cmd_type cb_cmd;
4308 uint8_t buf[88];
4309 int rc;
4310
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02004311 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01004312 if (!bts) {
4313 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4314 return CMD_WARNING;
4315 }
4316 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
4317 if (rc < 0 || rc > sizeof(buf)) {
4318 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
4319 return CMD_WARNING;
4320 }
4321
4322 cb_cmd.spare = 0;
4323 cb_cmd.def_bcast = 0;
4324 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
4325
4326 switch (last_block) {
4327 case 1:
4328 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
4329 break;
4330 case 2:
4331 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
4332 break;
4333 case 3:
4334 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
4335 break;
4336 case 4:
4337 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
4338 break;
Vadim Yanitskiy56dec0c2018-03-06 17:18:25 +07004339 default:
4340 vty_out(vty, "Error parsing LASTBLOCK%s", VTY_NEWLINE);
4341 return CMD_WARNING;
Harald Welte30f1f372014-12-28 15:00:45 +01004342 }
4343
4344 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
4345
4346 return CMD_SUCCESS;
4347}
4348
Harald Welte7fe00fb2017-05-27 14:09:50 +02004349/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02004350static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
4351 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02004352{
Harald Welte645eb622017-05-27 15:52:58 +02004353 int bts_nr = atoi(bts_str);
4354 int trx_nr = atoi(trx_str);
4355 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004356 struct gsm_bts *bts;
4357 struct gsm_bts_trx *trx;
4358 struct gsm_bts_trx_ts *ts;
4359
4360 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
4361 if (!bts) {
4362 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4363 return NULL;
4364 }
4365
4366 trx = gsm_bts_trx_num(bts, trx_nr);
4367 if (!trx) {
4368 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
4369 return NULL;
4370 }
4371
4372 ts = &trx->ts[ts_nr];
4373
4374 return ts;
4375}
Harald Welte30f1f372014-12-28 15:00:45 +01004376
Harald Welted0d2b0b2010-12-23 13:18:07 +01004377DEFUN(pdch_act, pdch_act_cmd,
4378 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
Harald Welte0bfd8d92018-02-12 18:06:53 +01004379 BTS_NR_TRX_TS_STR2
4380 "Packet Data Channel\n"
Harald Welted0d2b0b2010-12-23 13:18:07 +01004381 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4382 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4383{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004384 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004385 int activate;
4386
Harald Welte645eb622017-05-27 15:52:58 +02004387 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004388 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004389 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004390
Harald Welte7fe00fb2017-05-27 14:09:50 +02004391 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004392 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4393 VTY_NEWLINE);
4394 return CMD_WARNING;
4395 }
4396
Harald Welted0d2b0b2010-12-23 13:18:07 +01004397 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4398 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004399 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004400 return CMD_WARNING;
4401 }
4402
4403 if (!strcmp(argv[3], "activate"))
4404 activate = 1;
4405 else
4406 activate = 0;
4407
4408 rsl_ipacc_pdch_activate(ts, activate);
4409
4410 return CMD_SUCCESS;
4411
4412}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004413
Harald Welte2abd5e12017-05-27 14:10:40 +02004414/* determine the logical channel type based on the physical channel type */
4415static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4416{
4417 switch (pchan) {
4418 case GSM_PCHAN_TCH_F:
4419 return GSM_LCHAN_TCH_F;
4420 case GSM_PCHAN_TCH_H:
4421 return GSM_LCHAN_TCH_H;
4422 case GSM_PCHAN_SDCCH8_SACCH8C:
4423 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4424 case GSM_PCHAN_CCCH_SDCCH4:
4425 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4426 return GSM_LCHAN_SDCCH;
4427 default:
4428 return -1;
4429 }
4430}
4431
4432/* configure the lchan for a single AMR mode (as specified) */
4433static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4434{
4435 struct amr_multirate_conf mr;
4436 struct gsm48_multi_rate_conf *mr_conf;
4437 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4438
4439 if (amr_mode > 7)
4440 return -1;
4441
4442 memset(&mr, 0, sizeof(mr));
4443 mr_conf->ver = 1;
4444 /* bit-mask of supported modes, only one bit is set. Reflects
4445 * Figure 10.5.2.47a where there are no thershold and only a
4446 * single mode */
4447 mr.gsm48_ie[1] = 1 << amr_mode;
4448
4449 mr.ms_mode[0].mode = amr_mode;
4450 mr.bts_mode[0].mode = amr_mode;
4451
4452 /* encode this configuration into the lchan for both uplink and
4453 * downlink direction */
4454 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4455 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4456
4457 return 0;
4458}
4459
4460/* Debug/Measurement command to activate a given logical channel
4461 * manually in a given mode/codec. This is useful for receiver
4462 * performance testing (FER/RBER/...) */
4463DEFUN(lchan_act, lchan_act_cmd,
4464 "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 +01004465 BTS_NR_TRX_TS_SS_STR2
Harald Welte2abd5e12017-05-27 14:10:40 +02004466 "Manual Channel Activation (e.g. for BER test)\n"
4467 "Manual Channel Deactivation (e.g. for BER test)\n"
4468 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4469{
4470 struct gsm_bts_trx_ts *ts;
4471 struct gsm_lchan *lchan;
4472 int ss_nr = atoi(argv[3]);
4473 const char *act_str = argv[4];
4474 const char *codec_str = argv[5];
4475 int activate;
4476
4477 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4478 if (!ts)
4479 return CMD_WARNING;
4480
4481 lchan = &ts->lchan[ss_nr];
4482
4483 if (!strcmp(act_str, "activate"))
4484 activate = 1;
4485 else
4486 activate = 0;
4487
4488 if (ss_nr >= ts_subslots(ts)) {
4489 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4490 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4491 return CMD_WARNING;
4492 }
4493
4494 if (activate) {
4495 int lchan_t;
4496 if (lchan->state != LCHAN_S_NONE) {
4497 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4498 return CMD_WARNING;
4499 }
4500 lchan_t = lchan_type_by_pchan(ts->pchan);
4501 if (lchan_t < 0)
4502 return CMD_WARNING;
4503 /* configure the lchan */
4504 lchan->type = lchan_t;
4505 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4506 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4507 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4508 else if (!strcmp(codec_str, "efr"))
4509 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4510 else if (!strcmp(codec_str, "amr")) {
4511 int amr_mode;
4512 if (argc < 7) {
4513 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4514 return CMD_WARNING;
4515 }
4516 amr_mode = atoi(argv[6]);
4517 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4518 lchan_set_single_amr_mode(lchan, amr_mode);
4519 }
4520 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4521 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4522 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004523 } else {
4524 rsl_direct_rf_release(lchan);
4525 }
4526
4527 return CMD_SUCCESS;
4528}
4529
Harald Welte3f86c522017-05-27 15:53:28 +02004530DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4531 "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 +01004532 BTS_NR_TRX_TS_SS_STR2
Harald Welte3f86c522017-05-27 15:53:28 +02004533 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4534{
4535 struct gsm_bts_trx_ts *ts;
4536 struct gsm_lchan *lchan;
4537 int ss_nr = atoi(argv[3]);
4538 int port = atoi(argv[5]);
4539 struct in_addr ia;
4540 inet_aton(argv[4], &ia);
4541
4542 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4543 if (!ts)
4544 return CMD_WARNING;
4545
4546 lchan = &ts->lchan[ss_nr];
4547
4548 if (ss_nr >= ts_subslots(ts)) {
4549 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4550 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4551 return CMD_WARNING;
4552 }
4553
4554 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4555 inet_ntoa(ia), port, VTY_NEWLINE);
4556 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4557 return CMD_SUCCESS;
4558}
Harald Welteb71147a2017-07-18 19:11:49 +02004559
4560DEFUN(ctrl_trap, ctrl_trap_cmd,
4561 "ctrl-interface generate-trap TRAP VALUE",
4562 "Commands related to the CTRL Interface\n"
4563 "Generate a TRAP for test purpose\n"
4564 "Identity/Name of the TRAP variable\n"
4565 "Value of the TRAP variable\n")
4566{
4567 struct gsm_network *net = gsmnet_from_vty(vty);
4568
4569 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4570 return CMD_SUCCESS;
4571}
4572
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004573#define NETWORK_STR "Configure the GSM network\n"
4574#define CODE_CMD_STR "Code commands\n"
4575#define NAME_CMD_STR "Name Commands\n"
4576#define NAME_STR "Name to use\n"
4577
4578DEFUN(cfg_net,
4579 cfg_net_cmd,
4580 "network", NETWORK_STR)
4581{
4582 vty->index = gsmnet_from_vty(vty);
4583 vty->node = GSMNET_NODE;
4584
4585 return CMD_SUCCESS;
4586}
4587
4588DEFUN(cfg_net_ncc,
4589 cfg_net_ncc_cmd,
4590 "network country code <1-999>",
4591 "Set the GSM network country code\n"
4592 "Country commands\n"
4593 CODE_CMD_STR
4594 "Network Country Code to use\n")
4595{
4596 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004597 uint16_t mcc;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004598
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004599 if (osmo_mcc_from_str(argv[0], &mcc)) {
4600 vty_out(vty, "%% Error decoding MCC: %s%s", argv[0], VTY_NEWLINE);
4601 return CMD_WARNING;
4602 }
4603
4604 gsmnet->plmn.mcc = mcc;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004605
4606 return CMD_SUCCESS;
4607}
4608
4609DEFUN(cfg_net_mnc,
4610 cfg_net_mnc_cmd,
4611 "mobile network code <0-999>",
4612 "Set the GSM mobile network code\n"
4613 "Network Commands\n"
4614 CODE_CMD_STR
4615 "Mobile Network Code to use\n")
4616{
4617 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004618 uint16_t mnc;
4619 bool mnc_3_digits;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004620
Neels Hofmeyrf93970b2018-03-05 02:09:40 +01004621 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
4622 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
4623 return CMD_WARNING;
4624 }
4625
4626 gsmnet->plmn.mnc = mnc;
4627 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004628
4629 return CMD_SUCCESS;
4630}
4631
4632DEFUN(cfg_net_encryption,
4633 cfg_net_encryption_cmd,
Harald Welte51e4bf32017-12-23 17:30:18 +01004634 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
4635 "Encryption options\n"
4636 "GSM A5 Air Interface Encryption\n"
4637 "A5/n Algorithm Number\n"
4638 "A5/n Algorithm Number\n"
4639 "A5/n Algorithm Number\n"
4640 "A5/n Algorithm Number\n")
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004641{
4642 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte51e4bf32017-12-23 17:30:18 +01004643 unsigned int i;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004644
Harald Welte51e4bf32017-12-23 17:30:18 +01004645 gsmnet->a5_encryption_mask = 0;
4646 for (i = 0; i < argc; i++)
4647 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004648
4649 return CMD_SUCCESS;
4650}
4651
Neels Hofmeyr78faf702018-05-10 05:22:50 +02004652DEFUN_DEPRECATED(cfg_net_dyn_ts_allow_tch_f,
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004653 cfg_net_dyn_ts_allow_tch_f_cmd,
4654 "dyn_ts_allow_tch_f (0|1)",
4655 "Allow or disallow allocating TCH/F on TCH_F_TCH_H_PDCH timeslots\n"
4656 "Disallow TCH/F on TCH_F_TCH_H_PDCH (default)\n"
4657 "Allow TCH/F on TCH_F_TCH_H_PDCH\n")
4658{
4659 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4660 gsmnet->dyn_ts_allow_tch_f = atoi(argv[0]) ? true : false;
Neels Hofmeyr78faf702018-05-10 05:22:50 +02004661 vty_out(vty, "%% dyn_ts_allow_tch_f is deprecated, rather use msc/codec-list to pick codecs%s",
4662 VTY_NEWLINE);
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004663 return CMD_SUCCESS;
4664}
4665
4666DEFUN(cfg_net_timezone,
4667 cfg_net_timezone_cmd,
4668 "timezone <-19-19> (0|15|30|45)",
4669 "Set the Timezone Offset of the network\n"
4670 "Timezone offset (hours)\n"
4671 "Timezone offset (00 minutes)\n"
4672 "Timezone offset (15 minutes)\n"
4673 "Timezone offset (30 minutes)\n"
4674 "Timezone offset (45 minutes)\n"
4675 )
4676{
4677 struct gsm_network *net = vty->index;
4678 int tzhr = atoi(argv[0]);
4679 int tzmn = atoi(argv[1]);
4680
4681 net->tz.hr = tzhr;
4682 net->tz.mn = tzmn;
4683 net->tz.dst = 0;
4684 net->tz.override = 1;
4685
4686 return CMD_SUCCESS;
4687}
4688
4689DEFUN(cfg_net_timezone_dst,
4690 cfg_net_timezone_dst_cmd,
4691 "timezone <-19-19> (0|15|30|45) <0-2>",
4692 "Set the Timezone Offset of the network\n"
4693 "Timezone offset (hours)\n"
4694 "Timezone offset (00 minutes)\n"
4695 "Timezone offset (15 minutes)\n"
4696 "Timezone offset (30 minutes)\n"
4697 "Timezone offset (45 minutes)\n"
4698 "DST offset (hours)\n"
4699 )
4700{
4701 struct gsm_network *net = vty->index;
4702 int tzhr = atoi(argv[0]);
4703 int tzmn = atoi(argv[1]);
4704 int tzdst = atoi(argv[2]);
4705
4706 net->tz.hr = tzhr;
4707 net->tz.mn = tzmn;
4708 net->tz.dst = tzdst;
4709 net->tz.override = 1;
4710
4711 return CMD_SUCCESS;
4712}
4713
4714DEFUN(cfg_net_no_timezone,
4715 cfg_net_no_timezone_cmd,
4716 "no timezone",
4717 NO_STR
4718 "Disable network timezone override, use system tz\n")
4719{
4720 struct gsm_network *net = vty->index;
4721
4722 net->tz.override = 0;
4723
4724 return CMD_SUCCESS;
4725}
4726
4727DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
4728 "periodic location update <6-1530>",
4729 "Periodic Location Updating Interval\n"
4730 "Periodic Location Updating Interval\n"
4731 "Periodic Location Updating Interval\n"
4732 "Periodic Location Updating Interval in Minutes\n")
4733{
4734 struct gsm_network *net = vty->index;
4735
4736 net->t3212 = atoi(argv[0]) / 6;
4737
4738 return CMD_SUCCESS;
4739}
4740
4741DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
4742 "no periodic location update",
4743 NO_STR
4744 "Periodic Location Updating Interval\n"
4745 "Periodic Location Updating Interval\n"
4746 "Periodic Location Updating Interval\n")
4747{
4748 struct gsm_network *net = vty->index;
4749
4750 net->t3212 = 0;
4751
4752 return CMD_SUCCESS;
4753}
4754
Neels Hofmeyrf28f1ef2018-04-20 15:53:53 +02004755#define MEAS_FEED_STR "Measurement Report export\n"
4756
4757DEFUN(cfg_net_meas_feed_dest, cfg_net_meas_feed_dest_cmd,
4758 "meas-feed destination ADDR <0-65535>",
4759 MEAS_FEED_STR "Where to forward Measurement Report feeds\n" "address or hostname\n" "port number\n")
4760{
4761 int rc;
4762 const char *host = argv[0];
4763 uint16_t port = atoi(argv[1]);
4764
4765 rc = meas_feed_cfg_set(host, port);
4766 if (rc < 0)
4767 return CMD_WARNING;
4768
4769 return CMD_SUCCESS;
4770}
4771
4772DEFUN(cfg_net_meas_feed_scenario, cfg_net_meas_feed_scenario_cmd,
4773 "meas-feed scenario NAME",
4774 MEAS_FEED_STR "Set a name to include in the Measurement Report feeds\n" "Name string, up to 31 characters\n")
4775{
4776 meas_feed_scenario_set(argv[0]);
4777
4778 return CMD_SUCCESS;
4779}
4780
Harald Weltedcccb182010-05-16 20:52:23 +02004781extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004782
Maxdb0e3802017-01-12 19:35:11 +01004783int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004784{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004785 cfg_ts_pchan_cmd.string =
4786 vty_cmd_string_from_valstr(tall_bsc_ctx,
4787 gsm_pchant_names,
4788 "phys_chan_config (", "|", ")",
4789 VTY_DO_LOWER);
4790 cfg_ts_pchan_cmd.doc =
4791 vty_cmd_string_from_valstr(tall_bsc_ctx,
4792 gsm_pchant_descs,
4793 "Physical Channel Combination\n",
4794 "\n", "", 0);
4795
Harald Weltee555c2b2012-08-17 13:02:12 +02004796 cfg_bts_type_cmd.string =
4797 vty_cmd_string_from_valstr(tall_bsc_ctx,
4798 bts_type_names,
4799 "type (", "|", ")",
4800 VTY_DO_LOWER);
4801 cfg_bts_type_cmd.doc =
4802 vty_cmd_string_from_valstr(tall_bsc_ctx,
4803 bts_type_descs,
4804 "BTS Vendor/Type\n",
4805 "\n", "", 0);
4806
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004807 OSMO_ASSERT(vty_global_gsm_network == NULL);
4808 vty_global_gsm_network = network;
4809
4810 osmo_stats_vty_add_cmds();
4811
4812 install_element(CONFIG_NODE, &cfg_net_cmd);
4813 install_node(&net_node, config_write_net);
4814 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
4815 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
4816 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
4817 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
4818 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
4819 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
4820 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
4821 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
4822 install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);
Neels Hofmeyrf28f1ef2018-04-20 15:53:53 +02004823 install_element(GSMNET_NODE, &cfg_net_meas_feed_dest_cmd);
4824 install_element(GSMNET_NODE, &cfg_net_meas_feed_scenario_cmd);
Harald Weltee555c2b2012-08-17 13:02:12 +02004825
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004826 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004827 install_element_ve(&show_bts_cmd);
4828 install_element_ve(&show_trx_cmd);
4829 install_element_ve(&show_ts_cmd);
4830 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004831 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004832
Philipp Maier39f62bb2017-04-09 12:32:51 +02004833 install_element_ve(&show_subscr_conn_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004834 install_element_ve(&handover_any_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004835 install_element_ve(&assignment_any_cmd);
Philipp Maier39f62bb2017-04-09 12:32:51 +02004836
Harald Welteb4d5b172010-05-12 16:10:35 +00004837 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004838 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004839
Maxdb0e3802017-01-12 19:35:11 +01004840 logging_vty_add_cmds(NULL);
Harald Welte2f4f4b82018-02-14 00:50:27 +01004841 osmo_talloc_vty_add_cmds();
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004842
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004843 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004844 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004845 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4846 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4847 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4848 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4849 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4850 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4851 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4852 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4853 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004854 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004855 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Neels Hofmeyr0c1ac9f2018-06-05 15:37:59 +02004856 install_element(GSMNET_NODE, &cfg_net_T10_cmd);
Neels Hofmeyr0abe84e2018-05-14 18:14:29 +02004857 install_element(GSMNET_NODE, &cfg_net_T7_cmd);
4858 install_element(GSMNET_NODE, &cfg_net_T8_cmd);
4859 install_element(GSMNET_NODE, &cfg_net_T101_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004860 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004861 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004862 /* See also handover commands added on net level from handover_vty.c */
Harald Welte5013b2a2009-08-07 13:29:14 +02004863
4864 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004865 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004866 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004867 install_element(BTS_NODE, &cfg_description_cmd);
4868 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004869 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004870 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004871 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4872 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4873 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4874 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004875 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4876 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004877 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004878 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004879 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004880 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004881 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004882 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004883 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004884 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4885 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004886 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004887 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4888 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004889 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4890 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4891 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004892 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4893 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004894 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004895 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004896 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004897 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004898 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4899 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004900 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4901 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4902 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4903 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4904 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4905 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004906 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004907 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004908 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304909 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004910 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004911 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004912 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004913 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4914 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004915 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004916 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004917 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004918 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004919 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4920 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4921 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004922 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004923 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4924 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004925 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004926 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004927 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4928 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004929 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004930 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4931 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004932 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4933 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004934 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4935 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004936 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4937 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004938 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4939 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4940 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4941 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4942 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004943 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4944 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004945 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4946 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4947 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4948 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4949 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4950 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4951 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4952 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4953 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4954 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4955 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4956 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4957 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4958 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4959 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4960 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4961 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4962 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4963 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4964 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4965 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4966 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004967 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Stefan Sperling6442e432018-02-06 14:44:54 +01004968 install_element(BTS_NODE, &cfg_bts_acc_ramping_cmd);
4969 install_element(BTS_NODE, &cfg_bts_no_acc_ramping_cmd);
4970 install_element(BTS_NODE, &cfg_bts_acc_ramping_step_interval_cmd);
4971 install_element(BTS_NODE, &cfg_bts_acc_ramping_step_size_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004972 /* See also handover commands added on bts level from handover_vty.c */
Harald Welte68628e82009-03-10 12:17:57 +00004973
Harald Welte5258fc42009-03-28 19:07:53 +00004974 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004975 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004976 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004977 install_element(TRX_NODE, &cfg_description_cmd);
4978 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004979 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004980 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004981 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4982 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004983 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004984
Harald Welte5258fc42009-03-28 19:07:53 +00004985 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004986 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004987 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004988 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004989 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004990 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004991 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4992 install_element(TS_NODE, &cfg_ts_maio_cmd);
4993 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4994 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004995 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004996
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004997 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004998 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004999 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01005000 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02005001 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02005002 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welteb22dcb82018-02-12 17:57:57 +01005003 install_element(ENABLE_NODE, &handover_subscr_conn_cmd);
5004 install_element(ENABLE_NODE, &assignment_subscr_conn_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01005005 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02005006 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02005007
Harald Welte81c9b9c2010-05-31 16:40:40 +02005008 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01005009 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01005010 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01005011 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02005012
Neels Hofmeyre25018b2017-11-27 21:29:33 +01005013 ho_vty_init();
5014
Harald Weltedcccb182010-05-16 20:52:23 +02005015 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00005016
Harald Welte68628e82009-03-10 12:17:57 +00005017 return 0;
5018}