blob: aafdd2d6573313bff359e5660ed168c5b606df76 [file] [log] [blame]
Harald Welte68628e82009-03-10 12:17:57 +00001/* OpenBSC interface to quagga VTY */
Harald Welteaf387632010-03-14 23:30:30 +08002/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte68628e82009-03-10 12:17:57 +00003 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01006 * it under the terms of the GNU Affero General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
Harald Welte68628e82009-03-10 12:17:57 +00008 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010013 * GNU Affero General Public License for more details.
Harald Welte68628e82009-03-10 12:17:57 +000014 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010015 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte68628e82009-03-10 12:17:57 +000017 *
18 */
19
20#include <stdlib.h>
Maxc08ee712016-05-11 12:45:13 +020021#include <stdbool.h>
Harald Welte68628e82009-03-10 12:17:57 +000022#include <unistd.h>
Maxd1f70ed2017-09-21 16:15:32 +020023#include <time.h>
Harald Welte68628e82009-03-10 12:17:57 +000024
Harald Welte4b037e42010-05-19 19:45:32 +020025#include <osmocom/vty/command.h>
26#include <osmocom/vty/buffer.h>
27#include <osmocom/vty/vty.h>
28#include <osmocom/vty/logging.h>
Jacob Erlbeck64630cc2015-10-26 16:25:37 +010029#include <osmocom/vty/stats.h>
Harald Welte4b037e42010-05-19 19:45:32 +020030#include <osmocom/vty/telnet_interface.h>
Harald Welte4ab9d7c2012-08-17 12:42:06 +020031#include <osmocom/vty/misc.h>
Maxc08ee712016-05-11 12:45:13 +020032#include <osmocom/gsm/protocol/gsm_04_08.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010033#include <osmocom/gsm/gsm0502.h>
Harald Welteb71147a2017-07-18 19:11:49 +020034#include <osmocom/ctrl/control_if.h>
Neels Hofmeyr7b656882017-07-09 22:09:18 +020035#include <osmocom/gsm/gsm48.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010036
Harald Welte68628e82009-03-10 12:17:57 +000037#include <arpa/inet.h>
38
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010039#include <osmocom/core/linuxlist.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020040#include <osmocom/bsc/gsm_data.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020041#include <osmocom/abis/e1_input.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020042#include <osmocom/bsc/abis_nm.h>
43#include <osmocom/bsc/abis_om2000.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010044#include <osmocom/core/utils.h>
45#include <osmocom/gsm/gsm_utils.h>
Harald Weltecdc59ff2011-05-23 20:42:26 +020046#include <osmocom/gsm/abis_nm.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020047#include <osmocom/bsc/chan_alloc.h>
48#include <osmocom/bsc/meas_rep.h>
49#include <osmocom/bsc/vty.h>
Harald Welteea34a4e2012-06-16 14:59:56 +080050#include <osmocom/gprs/gprs_ns.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020051#include <osmocom/bsc/system_information.h>
52#include <osmocom/bsc/debug.h>
53#include <osmocom/bsc/paging.h>
54#include <osmocom/bsc/ipaccess.h>
55#include <osmocom/bsc/abis_rsl.h>
56#include <osmocom/bsc/bsc_msc_data.h>
57#include <osmocom/bsc/osmo_bsc_rf.h>
58#include <osmocom/bsc/pcu_if.h>
59#include <osmocom/bsc/common_cs.h>
60#include <osmocom/bsc/handover.h>
61#include <osmocom/bsc/gsm_04_08_utils.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020062
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010063#include <inttypes.h>
64
Harald Weltec08e8be2011-03-04 13:53:51 +010065#include "../../bscconfig.h"
Harald Welte1353f962010-05-16 19:20:24 +020066
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010067#define BTS_NR_STR "BTS Number\n"
68#define TRX_NR_STR "TRX Number\n"
69#define TS_NR_STR "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020070#define LCHAN_NR_STR "Logical Channel Number\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010071#define BTS_TRX_STR BTS_NR_STR TRX_NR_STR
72#define BTS_TRX_TS_STR BTS_TRX_STR TS_NR_STR
73#define BTS_TRX_TS_LCHAN_STR BTS_TRX_TS_STR LCHAN_NR_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020074
Harald Welteea4647d2010-05-12 17:19:53 +000075/* FIXME: this should go to some common file */
76static const struct value_string gprs_ns_timer_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020077 { 0, "tns-block" },
78 { 1, "tns-block-retries" },
79 { 2, "tns-reset" },
80 { 3, "tns-reset-retries" },
81 { 4, "tns-test" },
82 { 5, "tns-alive" },
83 { 6, "tns-alive-retries" },
84 { 0, NULL }
85};
86
Harald Welteea4647d2010-05-12 17:19:53 +000087static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020088 { 0, "blocking-timer" },
89 { 1, "blocking-retries" },
90 { 2, "unblocking-retries" },
91 { 3, "reset-timer" },
92 { 4, "reset-retries" },
93 { 5, "suspend-timer" },
94 { 6, "suspend-retries" },
95 { 7, "resume-timer" },
96 { 8, "resume-retries" },
97 { 9, "capability-update-timer" },
98 { 10, "capability-update-retries" },
99 { 0, NULL }
100};
101
Harald Welte64c07d22011-02-15 11:43:27 +0100102static const struct value_string bts_neigh_mode_strs[] = {
103 { NL_MODE_AUTOMATIC, "automatic" },
104 { NL_MODE_MANUAL, "manual" },
105 { NL_MODE_MANUAL_SI5SEP, "manual-si5" },
106 { 0, NULL }
107};
108
Daniel Willmann7d109832012-05-14 18:43:23 +0200109const struct value_string bts_loc_fix_names[] = {
110 { BTS_LOC_FIX_INVALID, "invalid" },
111 { BTS_LOC_FIX_2D, "fix2d" },
112 { BTS_LOC_FIX_3D, "fix3d" },
113 { 0, NULL }
114};
115
Harald Welte68628e82009-03-10 12:17:57 +0000116struct cmd_node bts_node = {
117 BTS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200118 "%s(config-net-bts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000119 1,
120};
121
122struct cmd_node trx_node = {
123 TRX_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200124 "%s(config-net-bts-trx)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000125 1,
126};
127
128struct cmd_node ts_node = {
129 TS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200130 "%s(config-net-bts-trx-ts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000131 1,
132};
133
134static int dummy_config_write(struct vty *v)
135{
136 return CMD_SUCCESS;
137}
138
139static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
140{
Harald Welte1304b352013-03-15 16:57:33 +0100141 vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
142 abis_nm_opstate_name(nms->operational),
143 get_value_string(abis_nm_adm_state_names, nms->administrative),
Harald Welte867d9f32011-05-23 20:30:39 +0200144 abis_nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000145}
146
Harald Welteb908cb72009-12-22 13:09:29 +0100147static void dump_pchan_load_vty(struct vty *vty, char *prefix,
148 const struct pchan_load *pl)
149{
150 int i;
151
152 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
153 const struct load_counter *lc = &pl->pchan[i];
154 unsigned int percent;
155
156 if (lc->total == 0)
157 continue;
158
159 percent = (lc->used * 100) / lc->total;
160
161 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
162 gsm_pchan_name(i), percent, lc->used, lc->total,
163 VTY_NEWLINE);
164 }
165}
166
Harald Welte68628e82009-03-10 12:17:57 +0000167static void net_dump_vty(struct vty *vty, struct gsm_network *net)
168{
Harald Welteb908cb72009-12-22 13:09:29 +0100169 struct pchan_load pl;
170
Harald Welteef235b52009-03-10 12:34:02 +0000171 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
172 "and has %u BTS%s", net->country_code, net->network_code,
173 net->num_bts, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200174 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900175 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
176 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100177 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
178 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800179 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
180 VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100181 vty_out(vty, " Handover: %s%s", net->handover.active ? "On" : "Off",
182 VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100183 network_chan_load(&pl, net);
184 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
185 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100186
187 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100188 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100189 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200190 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100191 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100192 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200193 vty_out(vty, " Last RF Lock Command: %s%s",
194 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
195 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000196}
197
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200198DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000199 SHOW_STR "Display information about a GSM NETWORK\n")
200{
Harald Weltedcccb182010-05-16 20:52:23 +0200201 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000202 net_dump_vty(vty, net);
203
204 return CMD_SUCCESS;
205}
206
207static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
208{
Harald Welteedb37782009-05-01 14:59:07 +0000209 struct e1inp_line *line;
210
211 if (!e1l) {
212 vty_out(vty, " None%s", VTY_NEWLINE);
213 return;
214 }
215
216 line = e1l->ts->line;
217
218 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
219 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000220 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000221 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000222 e1l->tei, e1l->sapi, VTY_NEWLINE);
223}
224
225static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
226{
Harald Welteb908cb72009-12-22 13:09:29 +0100227 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200228 unsigned long long sec;
Harald Welteb908cb72009-12-22 13:09:29 +0100229
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200230 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100231 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200232 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200233 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100234 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100235 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200236 bts->num_trx, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200237 vty_out(vty, "Description: %s%s",
238 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Maxf9685c12017-03-23 12:01:07 +0100239 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
240 vty_out(vty, "PCU version %s connected%s", bts->pcu_version,
241 VTY_NEWLINE);
Harald Welte1d8dbc42009-12-12 15:38:16 +0100242 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100243 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100244 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
245 VTY_NEWLINE);
246 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100247 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100248 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
249 VTY_NEWLINE);
250 vty_out(vty, "RACH Max transmissions: %u%s",
251 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
252 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100253 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200254 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200255 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
256 vty_out(vty, "Uplink DTX: %s%s",
257 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
258 "enabled" : "forced", VTY_NEWLINE);
259 else
260 vty_out(vty, "Uplink DTX: not enabled%s", VTY_NEWLINE);
261 vty_out(vty, "Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
262 VTY_NEWLINE);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200263 vty_out(vty, "Channel Description Attachment: %s%s",
264 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
265 vty_out(vty, "Channel Description BS-PA-MFRMS: %u%s",
266 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
267 vty_out(vty, "Channel Description BS-AG_BLKS-RES: %u%s",
268 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200269 vty_out(vty, "System Information present: 0x%08x, static: 0x%08x%s",
270 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100271 vty_out(vty, "Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100272 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100273 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
274 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
275 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100276 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200277 if (bts->pcu_sock_path)
278 vty_out(vty, "PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000279 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200280 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000281 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200282 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200283 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
284 vty_out(vty, " Skip Reset: %d%s",
285 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000286 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200287 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000288 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200289 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200290 vty_out(vty, " GPRS NSE: ");
291 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
292 vty_out(vty, " GPRS CELL: ");
293 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
294 vty_out(vty, " GPRS NSVC0: ");
295 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
296 vty_out(vty, " GPRS NSVC1: ");
297 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200298 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
299 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000300 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100301 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200302 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200303 sec = bts_uptime(bts);
304 if (sec)
Maxff3fad12018-01-07 16:50:42 +0100305 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.",
306 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60);
307 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100308 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200309 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
310 e1isl_dump_vty(vty, bts->oml_link);
311 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100312
313 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100314 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200315 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100316 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
317 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100318
319 vty_out(vty, "Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
320 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
321 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
322 VTY_NEWLINE);
323 vty_out(vty, "Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
324 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
325 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
326 VTY_NEWLINE);
327 vty_out(vty, "BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
328 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
329 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
330 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000331}
332
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100333DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000334 SHOW_STR "Display information about a BTS\n"
335 "BTS number")
336{
Harald Weltedcccb182010-05-16 20:52:23 +0200337 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000338 int bts_nr;
339
340 if (argc != 0) {
341 /* use the BTS number that the user has specified */
342 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100343 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000344 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000345 VTY_NEWLINE);
346 return CMD_WARNING;
347 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200348 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000349 return CMD_SUCCESS;
350 }
351 /* print all BTS's */
352 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200353 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000354
355 return CMD_SUCCESS;
356}
357
Harald Welte42581822009-08-08 16:12:58 +0200358/* utility functions */
359static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
360 const char *ts, const char *ss)
361{
362 e1_link->e1_nr = atoi(line);
363 e1_link->e1_ts = atoi(ts);
364 if (!strcmp(ss, "full"))
365 e1_link->e1_ts_ss = 255;
366 else
367 e1_link->e1_ts_ss = atoi(ss);
368}
369
370static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
371 const char *prefix)
372{
373 if (!e1_link->e1_ts)
374 return;
375
376 if (e1_link->e1_ts_ss == 255)
377 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
378 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
379 else
380 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
381 prefix, e1_link->e1_nr, e1_link->e1_ts,
382 e1_link->e1_ts_ss, VTY_NEWLINE);
383}
384
385
Harald Welte67ce0732009-08-06 19:06:46 +0200386static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
387{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100388 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100389 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100390 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200391 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100392 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200393 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100394 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200395 ts->hopping.enabled, VTY_NEWLINE);
396 if (ts->hopping.enabled) {
397 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100398 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200399 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100400 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200401 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200402 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
403 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
404 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100405 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200406 i, VTY_NEWLINE);
407 }
Harald Welte127af342010-12-24 12:07:07 +0100408 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100409 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100410
411 if (ts->trx->bts->model->config_write_ts)
412 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200413}
414
415static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
416{
417 int i;
418
Harald Welte5013b2a2009-08-07 13:29:14 +0200419 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200420 if (trx->description)
421 vty_out(vty, " description %s%s", trx->description,
422 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200423 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200424 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200425 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200426 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100427 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200428 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200429 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
430 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200431
Harald Welteface7ed2011-02-14 16:15:21 +0100432 if (trx->bts->model->config_write_trx)
433 trx->bts->model->config_write_trx(vty, trx);
434
Harald Welte67ce0732009-08-06 19:06:46 +0200435 for (i = 0; i < TRX_NR_TS; i++)
436 config_write_ts_single(vty, &trx->ts[i]);
437}
438
Harald Welte615e9562010-05-11 23:50:21 +0200439static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
440{
441 unsigned int i;
442 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
443 VTY_NEWLINE);
444 if (bts->gprs.mode == BTS_GPRS_NONE)
445 return;
446
bhargava350533c2016-07-21 11:14:34 +0530447 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
448 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
449
Harald Welte615e9562010-05-11 23:50:21 +0200450 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
451 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100452 vty_out(vty, " gprs network-control-order nc%u%s",
453 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200454 if (!bts->gprs.ctrl_ack_type_use_block)
455 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200456 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
457 VTY_NEWLINE);
458 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
459 vty_out(vty, " gprs cell timer %s %u%s",
460 get_value_string(gprs_bssgp_cfg_strs, i),
461 bts->gprs.cell.timer[i], VTY_NEWLINE);
462 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
463 VTY_NEWLINE);
464 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
465 vty_out(vty, " gprs ns timer %s %u%s",
466 get_value_string(gprs_ns_timer_strs, i),
467 bts->gprs.nse.timer[i], VTY_NEWLINE);
468 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
469 struct gsm_bts_gprs_nsvc *nsvc =
470 &bts->gprs.nsvc[i];
471 struct in_addr ia;
472
473 ia.s_addr = htonl(nsvc->remote_ip);
474 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
475 nsvc->nsvci, VTY_NEWLINE);
476 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
477 nsvc->local_port, VTY_NEWLINE);
478 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
479 nsvc->remote_port, VTY_NEWLINE);
480 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
481 inet_ntoa(ia), VTY_NEWLINE);
482 }
483}
484
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200485/* Write the model data if there is one */
486static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200487{
488 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200489
490 if (!bts->model)
491 return;
492
493 if (bts->model->config_write_bts)
494 bts->model->config_write_bts(vty, bts);
495
496 llist_for_each_entry(trx, &bts->trx_list, list)
497 config_write_trx_single(vty, trx);
498}
499
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200500static void write_amr_modes(struct vty *vty, const char *prefix,
501 const char *name, struct amr_mode *modes, int num)
502{
503 int i;
504
505 vty_out(vty, " %s threshold %s", prefix, name);
506 for (i = 0; i < num - 1; i++)
507 vty_out(vty, " %d", modes[i].threshold);
508 vty_out(vty, "%s", VTY_NEWLINE);
509 vty_out(vty, " %s hysteresis %s", prefix, name);
510 for (i = 0; i < num - 1; i++)
511 vty_out(vty, " %d", modes[i].hysteresis);
512 vty_out(vty, "%s", VTY_NEWLINE);
513}
514
Andreas Eversberg73266522014-01-19 11:47:44 +0100515static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
516 struct amr_multirate_conf *mr, int full)
517{
518 struct gsm48_multi_rate_conf *mr_conf;
519 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
520 int i, num;
521
522 if (!(mr->gsm48_ie[1]))
523 return;
524
525 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
526
527 num = 0;
528 vty_out(vty, " %s modes", prefix);
529 for (i = 0; i < ((full) ? 8 : 6); i++) {
530 if ((mr->gsm48_ie[1] & (1 << i))) {
531 vty_out(vty, " %d", i);
532 num++;
533 }
534 }
535 vty_out(vty, "%s", VTY_NEWLINE);
536 if (num > 4)
537 num = 4;
538 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200539 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
540 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100541 }
542 vty_out(vty, " %s start-mode ", prefix);
543 if (mr_conf->icmi) {
544 num = 0;
545 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
546 if ((mr->gsm48_ie[1] & (1 << i)))
547 num++;
548 if (mr_conf->smod == num - 1) {
549 vty_out(vty, "%d%s", num, VTY_NEWLINE);
550 break;
551 }
552 }
553 } else
554 vty_out(vty, "auto%s", VTY_NEWLINE);
555}
556
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200557static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
558{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200559 int i;
Max2c16bee2017-02-15 13:51:37 +0100560 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200561
Harald Welte5013b2a2009-08-07 13:29:14 +0200562 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
563 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200564 if (bts->description)
565 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200566 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100567 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200568 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200569 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200570 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
571 vty_out(vty, " dtx uplink%s%s",
572 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
573 VTY_NEWLINE);
574 if (bts->dtxd)
575 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200576 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200577 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100578 vty_out(vty, " cell reselection hysteresis %u%s",
579 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
580 vty_out(vty, " rxlev access min %u%s",
581 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100582
583 if (bts->si_common.cell_ro_sel_par.present) {
584 struct gsm48_si_selection_params *sp;
585 sp = &bts->si_common.cell_ro_sel_par;
586
587 if (sp->cbq)
588 vty_out(vty, " cell bar qualify %u%s",
589 sp->cbq, VTY_NEWLINE);
590
591 if (sp->cell_resel_off)
592 vty_out(vty, " cell reselection offset %u%s",
593 sp->cell_resel_off*2, VTY_NEWLINE);
594
595 if (sp->temp_offs == 7)
596 vty_out(vty, " temporary offset infinite%s",
597 VTY_NEWLINE);
598 else if (sp->temp_offs)
599 vty_out(vty, " temporary offset %u%s",
600 sp->temp_offs*10, VTY_NEWLINE);
601
602 if (sp->penalty_time == 31)
603 vty_out(vty, " penalty time reserved%s",
604 VTY_NEWLINE);
605 else if (sp->penalty_time)
606 vty_out(vty, " penalty time %u%s",
607 (sp->penalty_time*20)+20, VTY_NEWLINE);
608 }
609
Harald Welte2f8b9d22017-06-18 11:12:13 +0300610 if (gsm_bts_get_radio_link_timeout(bts) < 0)
611 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
612 else
613 vty_out(vty, " radio-link-timeout %d%s",
614 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100615
Harald Welte7a8fa412009-08-10 13:48:16 +0200616 vty_out(vty, " channel allocator %s%s",
617 bts->chan_alloc_reverse ? "descending" : "ascending",
618 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100619 vty_out(vty, " rach tx integer %u%s",
620 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
621 vty_out(vty, " rach max transmission %u%s",
622 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
623 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800624
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200625 vty_out(vty, " channel-descrption attach %u%s",
626 bts->si_common.chan_desc.att, VTY_NEWLINE);
627 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
628 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
629 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
630 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
631
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800632 if (bts->rach_b_thresh != -1)
633 vty_out(vty, " rach nm busy threshold %u%s",
634 bts->rach_b_thresh, VTY_NEWLINE);
635 if (bts->rach_ldavg_slots != -1)
636 vty_out(vty, " rach nm load average %u%s",
637 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100638 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200639 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800640 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
641 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400642 if ((bts->si_common.rach_control.t3) != 0)
643 for (i = 0; i < 8; i++)
644 if (bts->si_common.rach_control.t3 & (0x1 << i))
645 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
646 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
647 for (i = 0; i < 8; i++)
648 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
649 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200650 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
651 if (bts->si_mode_static & (1 << i)) {
652 vty_out(vty, " system-information %s mode static%s",
653 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
654 vty_out(vty, " system-information %s static %s%s",
655 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200656 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200657 VTY_NEWLINE);
658 }
659 }
Harald Welte42def722017-01-13 00:10:32 +0100660 vty_out(vty, " early-classmark-sending %s%s",
661 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100662 vty_out(vty, " early-classmark-sending-3g %s%s",
663 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100664 switch (bts->type) {
665 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100666 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200667 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200668 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100669 if (bts->ip_access.rsl_ip) {
670 struct in_addr ia;
671 ia.s_addr = htonl(bts->ip_access.rsl_ip);
672 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
673 VTY_NEWLINE);
674 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200675 vty_out(vty, " oml ip.access stream_id %u line %u%s",
676 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100677 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200678 case GSM_BTS_TYPE_NOKIA_SITE:
679 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100680 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
681 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100682 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 +0100683 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100684 default:
Harald Welte42581822009-08-08 16:12:58 +0200685 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
686 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100687 break;
Harald Welte42581822009-08-08 16:12:58 +0200688 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800689
690 /* if we have a limit, write it */
691 if (bts->paging.free_chans_need >= 0)
692 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
693
Harald Welte32c09622011-01-11 23:44:56 +0100694 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100695 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
696 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100697 for (i = 0; i < 1024; i++) {
698 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
699 vty_out(vty, " neighbor-list add arfcn %u%s",
700 i, VTY_NEWLINE);
701 }
702 }
Harald Welte64c07d22011-02-15 11:43:27 +0100703 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
704 for (i = 0; i < 1024; i++) {
705 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
706 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
707 i, VTY_NEWLINE);
708 }
709 }
Harald Welte32c09622011-01-11 23:44:56 +0100710
Max59a1bf32016-04-15 16:04:46 +0200711 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100712 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
713 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
714 vty_out(vty, " si2quater neighbor-list add earfcn %u "
715 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
716
717 vty_out(vty, " thresh-lo %u",
718 e->thresh_lo_valid ? e->thresh_lo : 32);
719
720 vty_out(vty, " prio %u",
721 e->prio_valid ? e->prio : 8);
722
723 vty_out(vty, " qrxlv %u",
724 e->qrxlm_valid ? e->qrxlm : 32);
725
726 tmp = e->meas_bw[i];
727 vty_out(vty, " meas %u",
728 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200729
730 vty_out(vty, "%s", VTY_NEWLINE);
731 }
732 }
733
Max26679e02016-04-20 15:57:13 +0200734 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
735 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
736 bts->si_common.data.uarfcn_list[i],
737 bts->si_common.data.scramble_list[i] & ~(1 << 9),
738 (bts->si_common.data.scramble_list[i] >> 9) & 1,
739 VTY_NEWLINE);
740 }
741
Andreas Eversberga83d5112013-12-07 18:32:28 +0100742 vty_out(vty, " codec-support fr");
743 if (bts->codec.hr)
744 vty_out(vty, " hr");
745 if (bts->codec.efr)
746 vty_out(vty, " efr");
747 if (bts->codec.amr)
748 vty_out(vty, " amr");
749 vty_out(vty, "%s", VTY_NEWLINE);
750
Andreas Eversberg73266522014-01-19 11:47:44 +0100751 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
752 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
753
Harald Welte615e9562010-05-11 23:50:21 +0200754 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200755
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200756 if (bts->excl_from_rf_lock)
757 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
758
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100759 vty_out(vty, " %sforce-combined-si%s",
760 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
761
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100762 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
763 int j;
764
765 if (bts->depends_on[i] == 0)
766 continue;
767
768 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
769 int bts_nr;
770
771 if ((bts->depends_on[i] & (1<<j)) == 0)
772 continue;
773
774 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
775 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
776 }
777 }
Harald Welte8254cf72017-05-29 13:42:19 +0200778 if (bts->pcu_sock_path)
779 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100780
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200781 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200782}
783
784static int config_write_bts(struct vty *v)
785{
Harald Weltedcccb182010-05-16 20:52:23 +0200786 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200787 struct gsm_bts *bts;
788
789 llist_for_each_entry(bts, &gsmnet->bts_list, list)
790 config_write_bts_single(v, bts);
791
792 return CMD_SUCCESS;
793}
794
Harald Weltea0d324b2017-07-20 01:47:39 +0200795/* small helper macro for conditional dumping of timer */
796#define VTY_OUT_TIMER(number) \
797 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
798 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
799
Harald Welte5013b2a2009-08-07 13:29:14 +0200800static int config_write_net(struct vty *vty)
801{
Harald Weltedcccb182010-05-16 20:52:23 +0200802 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
803
Harald Welte5013b2a2009-08-07 13:29:14 +0200804 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200805 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200806 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900807 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100808 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800809 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100810 vty_out(vty, " handover %u%s", gsmnet->handover.active, VTY_NEWLINE);
Harald Welteb720bd32009-12-21 16:51:50 +0100811 vty_out(vty, " handover window rxlev averaging %u%s",
812 gsmnet->handover.win_rxlev_avg, VTY_NEWLINE);
813 vty_out(vty, " handover window rxqual averaging %u%s",
814 gsmnet->handover.win_rxqual_avg, VTY_NEWLINE);
815 vty_out(vty, " handover window rxlev neighbor averaging %u%s",
816 gsmnet->handover.win_rxlev_avg_neigh, VTY_NEWLINE);
817 vty_out(vty, " handover power budget interval %u%s",
818 gsmnet->handover.pwr_interval, VTY_NEWLINE);
819 vty_out(vty, " handover power budget hysteresis %u%s",
820 gsmnet->handover.pwr_hysteresis, VTY_NEWLINE);
821 vty_out(vty, " handover maximum distance %u%s",
822 gsmnet->handover.max_distance, VTY_NEWLINE);
Harald Weltea0d324b2017-07-20 01:47:39 +0200823 VTY_OUT_TIMER(3101);
824 VTY_OUT_TIMER(3103);
825 VTY_OUT_TIMER(3105);
826 VTY_OUT_TIMER(3107);
827 VTY_OUT_TIMER(3109);
828 VTY_OUT_TIMER(3111);
829 VTY_OUT_TIMER(3113);
830 VTY_OUT_TIMER(3115);
831 VTY_OUT_TIMER(3117);
832 VTY_OUT_TIMER(3119);
833 VTY_OUT_TIMER(3122);
834 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700835 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
836 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200837 if (gsmnet->tz.override != 0) {
838 if (gsmnet->tz.dst)
839 vty_out(vty, " timezone %d %d %d%s",
840 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
841 VTY_NEWLINE);
842 else
843 vty_out(vty, " timezone %d %d%s",
844 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
845 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200846 if (gsmnet->t3212 == 0)
847 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
848 else
849 vty_out(vty, " periodic location update %u%s",
850 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200851
852 return CMD_SUCCESS;
853}
Harald Welte67ce0732009-08-06 19:06:46 +0200854
Harald Welte68628e82009-03-10 12:17:57 +0000855static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
856{
857 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
858 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200859 vty_out(vty, "Description: %s%s",
860 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200861 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200862 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200863 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200864 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000865 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200866 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +0100867 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000868 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200869 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200870 if (is_ipaccess_bts(trx->bts)) {
871 vty_out(vty, " ip.access stream ID: 0x%02x%s",
872 trx->rsl_tei, VTY_NEWLINE);
873 } else {
874 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
875 e1isl_dump_vty(vty, trx->rsl_link);
876 }
Harald Welte68628e82009-03-10 12:17:57 +0000877}
878
Max6e4f1842018-01-07 16:45:42 +0100879static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
880{
881 uint8_t trx_nr;
882 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
883 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
884}
885
Harald Welte68628e82009-03-10 12:17:57 +0000886DEFUN(show_trx,
887 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100888 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200889 SHOW_STR "Display information about a TRX\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +0100890 BTS_TRX_STR)
Harald Welte68628e82009-03-10 12:17:57 +0000891{
Harald Weltedcccb182010-05-16 20:52:23 +0200892 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000893 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000894 int bts_nr, trx_nr;
895
896 if (argc >= 1) {
897 /* use the BTS number that the user has specified */
898 bts_nr = atoi(argv[0]);
899 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000900 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000901 VTY_NEWLINE);
902 return CMD_WARNING;
903 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200904 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000905 }
906 if (argc >= 2) {
907 trx_nr = atoi(argv[1]);
908 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000909 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000910 VTY_NEWLINE);
911 return CMD_WARNING;
912 }
Max6e4f1842018-01-07 16:45:42 +0100913 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000914 return CMD_SUCCESS;
915 }
916 if (bts) {
917 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +0100918 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +0000919 return CMD_SUCCESS;
920 }
921
Max6e4f1842018-01-07 16:45:42 +0100922 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
923 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000924
925 return CMD_SUCCESS;
926}
927
Harald Welte67ce0732009-08-06 19:06:46 +0200928
Harald Welte68628e82009-03-10 12:17:57 +0000929static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
930{
Harald Welte135a6482011-05-30 12:09:13 +0200931 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +0100932 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +0100933 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +0100934 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +0100935 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200936 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +0100937 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000938 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200939 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530940 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000941 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
942 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
943 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000944}
945
946DEFUN(show_ts,
947 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100948 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200949 SHOW_STR "Display information about a TS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +0100950 BTS_TRX_TS_STR)
Harald Welte68628e82009-03-10 12:17:57 +0000951{
Harald Weltedcccb182010-05-16 20:52:23 +0200952 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +0100953 struct gsm_bts *bts = NULL;
954 struct gsm_bts_trx *trx = NULL;
955 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000956 int bts_nr, trx_nr, ts_nr;
957
958 if (argc >= 1) {
959 /* use the BTS number that the user has specified */
960 bts_nr = atoi(argv[0]);
961 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000962 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000963 VTY_NEWLINE);
964 return CMD_WARNING;
965 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200966 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000967 }
968 if (argc >= 2) {
969 trx_nr = atoi(argv[1]);
970 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000971 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000972 VTY_NEWLINE);
973 return CMD_WARNING;
974 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200975 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000976 }
977 if (argc >= 3) {
978 ts_nr = atoi(argv[2]);
979 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +0000980 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +0000981 VTY_NEWLINE);
982 return CMD_WARNING;
983 }
Harald Welte274d0152010-12-24 12:05:03 +0100984 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +0000985 ts = &trx->ts[ts_nr];
986 ts_dump_vty(vty, ts);
987 return CMD_SUCCESS;
988 }
Harald Welte274d0152010-12-24 12:05:03 +0100989
990 if (bts && trx) {
991 /* Iterate over all TS in this TRX */
992 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
993 ts = &trx->ts[ts_nr];
994 ts_dump_vty(vty, ts);
995 }
996 } else if (bts) {
997 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +0000998 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200999 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001000 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1001 ts = &trx->ts[ts_nr];
1002 ts_dump_vty(vty, ts);
1003 }
1004 }
Harald Welte274d0152010-12-24 12:05:03 +01001005 } else {
1006 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1007 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1008 bts = gsm_bts_num(net, bts_nr);
1009 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1010 trx = gsm_bts_trx_num(bts, trx_nr);
1011 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1012 ts = &trx->ts[ts_nr];
1013 ts_dump_vty(vty, ts);
1014 }
1015 }
1016 }
Harald Welte68628e82009-03-10 12:17:57 +00001017 }
1018
1019 return CMD_SUCCESS;
1020}
1021
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001022static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1023{
1024 if (strlen(bsub->imsi))
1025 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1026 if (bsub->tmsi != GSM_RESERVED_TMSI)
1027 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1028 VTY_NEWLINE);
1029 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1030}
1031
Harald Welte8387a492009-12-22 21:43:14 +01001032static void meas_rep_dump_uni_vty(struct vty *vty,
1033 struct gsm_meas_rep_unidir *mru,
1034 const char *prefix,
1035 const char *dir)
1036{
1037 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1038 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1039 dir, rxlev2dbm(mru->sub.rx_lev));
1040 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1041 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1042 VTY_NEWLINE);
1043}
1044
1045static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1046 const char *prefix)
1047{
1048 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1049 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1050 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1051 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1052 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1053 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1054 VTY_NEWLINE);
1055 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001056 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001057 if (mr->flags & MEAS_REP_F_MS_L1)
1058 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1059 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1060 if (mr->flags & MEAS_REP_F_DL_VALID)
1061 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1062 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1063}
1064
Harald Welte0a8cf322015-12-05 17:22:49 +01001065/* FIXME: move this to libosmogsm */
1066static const struct value_string gsm48_cmode_names[] = {
1067 { GSM48_CMODE_SIGN, "signalling" },
1068 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1069 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1070 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1071 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1072 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1073 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1074 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1075 { 0, NULL }
1076};
1077
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001078/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1079 * Don't do anything if the ts is not dynamic. */
1080static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1081{
1082 switch (ts->pchan) {
1083 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1084 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1085 vty_out(vty, " as %s",
1086 gsm_pchan_name(ts->dyn.pchan_is));
1087 else
1088 vty_out(vty, " switching %s -> %s",
1089 gsm_pchan_name(ts->dyn.pchan_is),
1090 gsm_pchan_name(ts->dyn.pchan_want));
1091 break;
1092 case GSM_PCHAN_TCH_F_PDCH:
1093 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1094 vty_out(vty, " as %s",
1095 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1096 : "TCH/F");
1097 else
1098 vty_out(vty, " switching %s -> %s",
1099 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1100 : "TCH/F",
1101 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1102 : "TCH/F");
1103 break;
1104 default:
1105 /* no dyn ts */
1106 break;
1107 }
1108}
1109
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001110static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001111{
Harald Welte8387a492009-12-22 21:43:14 +01001112 int idx;
1113
Harald Welte85bded82010-12-24 12:22:34 +01001114 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1115 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1116 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001117 /* show dyn TS details, if applicable */
1118 switch (lchan->ts->pchan) {
1119 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1120 vty_out(vty, " Osmocom Dyn TS:");
1121 vty_out_dyn_ts_status(vty, lchan->ts);
1122 vty_out(vty, VTY_NEWLINE);
1123 break;
1124 case GSM_PCHAN_TCH_F_PDCH:
1125 vty_out(vty, " IPACC Dyn PDCH TS:");
1126 vty_out_dyn_ts_status(vty, lchan->ts);
1127 vty_out(vty, VTY_NEWLINE);
1128 break;
1129 default:
1130 /* no dyn ts */
1131 break;
1132 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001133 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001134 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001135 gsm_lchans_name(lchan->state),
1136 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1137 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1138 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001139 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1140 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1141 - lchan->bs_power*2,
1142 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1143 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001144 vty_out(vty, " Channel Mode / Codec: %s%s",
1145 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1146 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001147 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001148 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001149 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001150 } else
1151 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301152 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1153 struct in_addr ia;
Holger Hans Peter Freyther54fa7992010-04-07 15:39:16 +02001154 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte2c828992009-12-02 01:56:49 +05301155 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1156 inet_ntoa(ia), lchan->abis_ip.bound_port,
1157 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1158 VTY_NEWLINE);
1159 }
Harald Welte8387a492009-12-22 21:43:14 +01001160
1161 /* we want to report the last measurement report */
1162 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1163 lchan->meas_rep_idx, 1);
1164 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001165}
1166
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001167static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1168{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001169 struct gsm_meas_rep *mr;
1170 int idx;
1171
1172 /* we want to report the last measurement report */
1173 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1174 lchan->meas_rep_idx, 1);
1175 mr = &lchan->meas_rep[idx];
1176
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001177 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001178 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001179 gsm_pchan_name(lchan->ts->pchan));
1180 vty_out_dyn_ts_status(vty, lchan->ts);
1181 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1182 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001183 lchan->nr,
1184 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1185 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001186 rxlev2dbm(mr->dl.full.rx_lev),
1187 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001188 VTY_NEWLINE);
1189}
1190
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001191
1192static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1193 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1194{
1195 int lchan_nr;
1196 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1197 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1198 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1199 continue;
1200 dump_cb(vty, lchan);
1201 }
1202
1203 return CMD_SUCCESS;
1204}
1205
1206static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1207 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1208{
1209 int ts_nr;
1210
1211 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1212 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1213 dump_lchan_trx_ts(ts, vty, dump_cb);
1214 }
1215
1216 return CMD_SUCCESS;
1217}
1218
1219static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1220 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1221{
1222 int trx_nr;
1223
1224 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1225 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1226 dump_lchan_trx(trx, vty, dump_cb);
1227 }
1228
1229 return CMD_SUCCESS;
1230}
1231
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001232static int lchan_summary(struct vty *vty, int argc, const char **argv,
1233 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001234{
Harald Weltedcccb182010-05-16 20:52:23 +02001235 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001236 struct gsm_bts *bts;
1237 struct gsm_bts_trx *trx;
1238 struct gsm_bts_trx_ts *ts;
1239 struct gsm_lchan *lchan;
1240 int bts_nr, trx_nr, ts_nr, lchan_nr;
1241
1242 if (argc >= 1) {
1243 /* use the BTS number that the user has specified */
1244 bts_nr = atoi(argv[0]);
1245 if (bts_nr >= net->num_bts) {
1246 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1247 VTY_NEWLINE);
1248 return CMD_WARNING;
1249 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001250 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001251
1252 if (argc == 1)
1253 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001254 }
1255 if (argc >= 2) {
1256 trx_nr = atoi(argv[1]);
1257 if (trx_nr >= bts->num_trx) {
1258 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1259 VTY_NEWLINE);
1260 return CMD_WARNING;
1261 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001262 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001263
1264 if (argc == 2)
1265 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001266 }
1267 if (argc >= 3) {
1268 ts_nr = atoi(argv[2]);
1269 if (ts_nr >= TRX_NR_TS) {
1270 vty_out(vty, "%% can't find TS %s%s", argv[2],
1271 VTY_NEWLINE);
1272 return CMD_WARNING;
1273 }
1274 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001275
1276 if (argc == 3)
1277 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001278 }
1279 if (argc >= 4) {
1280 lchan_nr = atoi(argv[3]);
1281 if (lchan_nr >= TS_MAX_LCHAN) {
1282 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1283 VTY_NEWLINE);
1284 return CMD_WARNING;
1285 }
1286 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001287 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001288 return CMD_SUCCESS;
1289 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001290
1291
Harald Welte68628e82009-03-10 12:17:57 +00001292 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001293 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001294 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001295 }
1296
1297 return CMD_SUCCESS;
1298}
1299
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001300
1301DEFUN(show_lchan,
1302 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001303 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001304 SHOW_STR "Display information about a logical channel\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001305 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001306{
1307 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1308}
1309
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001310DEFUN(show_lchan_summary,
1311 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001312 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001313 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001314 "Short summary\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001315 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001316{
1317 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1318}
1319
Philipp Maier39f62bb2017-04-09 12:32:51 +02001320DEFUN(show_subscr_conn,
1321 show_subscr_conn_cmd,
1322 "show conns",
1323 SHOW_STR "Display currently active subscriber connections\n")
1324{
1325 struct gsm_subscriber_connection *conn;
1326 struct gsm_network *net = gsmnet_from_vty(vty);
1327 bool no_conns = true;
1328 unsigned int count = 0;
1329
1330 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1331
1332 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1333 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1334 lchan_dump_full_vty(vty, conn->lchan);
1335 no_conns = false;
1336 count++;
1337 }
1338
1339 if (no_conns)
1340 vty_out(vty, "None%s", VTY_NEWLINE);
1341
1342 return CMD_SUCCESS;
1343}
1344
1345DEFUN(handover_subscr_conn,
1346 handover_subscr_conn_cmd,
Neels Hofmeyr0f483f62018-01-19 15:46:01 +01001347 "handover <0-255> <0-255> <0-7> <0-7> <0-255>",
Philipp Maier39f62bb2017-04-09 12:32:51 +02001348 "Handover subscriber connection to other BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001349 "Current " BTS_TRX_TS_LCHAN_STR
1350 "New " BTS_NR_STR)
Philipp Maier39f62bb2017-04-09 12:32:51 +02001351{
1352 struct gsm_network *net = gsmnet_from_vty(vty);
1353 struct gsm_subscriber_connection *conn;
1354 struct gsm_bts *bts;
1355 struct gsm_bts *new_bts = NULL;
1356 unsigned int bts_nr = atoi(argv[0]);
1357 unsigned int trx_nr = atoi(argv[1]);
1358 unsigned int ts_nr = atoi(argv[2]);
1359 unsigned int ss_nr = atoi(argv[3]);
1360 unsigned int bts_nr_new = atoi(argv[4]);
1361
1362 /* Lookup the BTS where we want to handover to */
1363 llist_for_each_entry(bts, &net->bts_list, list) {
1364 if (bts->nr == bts_nr_new) {
1365 new_bts = bts;
1366 break;
1367 }
1368 }
1369
1370 if (!new_bts) {
1371 vty_out(vty, "Unable to trigger handover,"
1372 "specified bts #%u does not exist %s", bts_nr_new,
1373 VTY_NEWLINE);
1374 return CMD_WARNING;
1375 }
1376
1377 /* Find the connection/lchan that we want to handover */
1378 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001379 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001380 conn->lchan->ts->trx->nr == trx_nr &&
1381 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
1382 vty_out(vty, "starting handover for lchan %s...%s",
1383 conn->lchan->name, VTY_NEWLINE);
1384 lchan_dump_full_vty(vty, conn->lchan);
1385 bsc_handover_start(conn->lchan, new_bts);
1386 return CMD_SUCCESS;
1387 }
1388 }
1389
1390 vty_out(vty, "Unable to trigger handover,"
1391 "specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1392 bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
1393
1394 return CMD_WARNING;
1395}
1396
Harald Weltebe4b7302009-05-23 16:59:33 +00001397static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001398{
1399 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001400 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001401}
1402
Harald Weltebe4b7302009-05-23 16:59:33 +00001403static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001404{
1405 struct gsm_paging_request *pag;
1406
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001407 if (!bts->paging.bts)
1408 return;
1409
Harald Weltef5025b62009-03-28 16:55:11 +00001410 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1411 paging_dump_vty(vty, pag);
1412}
1413
1414DEFUN(show_paging,
1415 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001416 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001417 SHOW_STR "Display information about paging reuqests of a BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001418 BTS_NR_STR)
Harald Weltef5025b62009-03-28 16:55:11 +00001419{
Harald Weltedcccb182010-05-16 20:52:23 +02001420 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001421 struct gsm_bts *bts;
1422 int bts_nr;
1423
1424 if (argc >= 1) {
1425 /* use the BTS number that the user has specified */
1426 bts_nr = atoi(argv[0]);
1427 if (bts_nr >= net->num_bts) {
1428 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1429 VTY_NEWLINE);
1430 return CMD_WARNING;
1431 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001432 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001433 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001434
Harald Weltef5025b62009-03-28 16:55:11 +00001435 return CMD_SUCCESS;
1436 }
1437 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001438 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001439 bts_paging_dump_vty(vty, bts);
1440 }
1441
1442 return CMD_SUCCESS;
1443}
1444
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001445DEFUN(show_paging_group,
1446 show_paging_group_cmd,
1447 "show paging-group <0-255> IMSI",
1448 SHOW_STR "Display the paging group\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001449 BTS_NR_STR "IMSI\n")
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001450{
1451 struct gsm_network *net = gsmnet_from_vty(vty);
1452 struct gsm_bts *bts;
1453 unsigned int page_group;
1454 int bts_nr = atoi(argv[0]);
1455
1456 if (bts_nr >= net->num_bts) {
1457 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1458 return CMD_WARNING;
1459 }
1460
1461 bts = gsm_bts_num(net, bts_nr);
1462 if (!bts) {
1463 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1464 return CMD_WARNING;
1465 }
1466
1467 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1468 str_to_imsi(argv[1]));
1469 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1470 str_to_imsi(argv[1]), bts->nr,
1471 page_group, VTY_NEWLINE);
1472 return CMD_SUCCESS;
1473}
1474
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001475DEFUN(cfg_net_neci,
1476 cfg_net_neci_cmd,
1477 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001478 "New Establish Cause Indication\n"
1479 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001480{
Harald Weltedcccb182010-05-16 20:52:23 +02001481 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1482
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001483 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001484 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001485 return CMD_SUCCESS;
1486}
1487
Harald Welte8f0ed552010-05-11 21:53:49 +02001488#define HANDOVER_STR "Handover Options\n"
1489
Harald Weltebc814502009-12-19 21:41:52 +01001490DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1491 "handover (0|1)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001492 HANDOVER_STR
1493 "Don't perform in-call handover\n"
1494 "Perform in-call handover\n")
Harald Weltebc814502009-12-19 21:41:52 +01001495{
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001496 int enable = atoi(argv[0]);
Harald Weltedcccb182010-05-16 20:52:23 +02001497 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001498
1499 if (enable && ipacc_rtp_direct) {
Harald Weltefe03f0d2009-12-20 13:51:01 +01001500 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1501 "is enabled by using the -P command line option%s",
1502 VTY_NEWLINE);
1503 return CMD_WARNING;
1504 }
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001505 gsmnet->handover.active = enable;
Harald Weltebc814502009-12-19 21:41:52 +01001506
1507 return CMD_SUCCESS;
1508}
1509
Harald Welte8f0ed552010-05-11 21:53:49 +02001510#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1511#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1512#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1513#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001514#define HO_AVG_COUNT_STR "Amount to use for Averaging\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001515
Harald Welteb720bd32009-12-21 16:51:50 +01001516DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1517 "handover window rxlev averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001518 HO_WIN_RXLEV_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001519 "How many RxLev measurements are used for averaging\n"
1520 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001521{
Harald Weltedcccb182010-05-16 20:52:23 +02001522 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001523 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1524 return CMD_SUCCESS;
1525}
1526
1527DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1528 "handover window rxqual averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001529 HO_WIN_RXQUAL_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001530 "How many RxQual measurements are used for averaging\n"
1531 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001532{
Harald Weltedcccb182010-05-16 20:52:23 +02001533 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001534 gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
1535 return CMD_SUCCESS;
1536}
1537
1538DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1539 "handover window rxlev neighbor averaging <1-10>",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001540 HO_WIN_RXLEV_STR "Neighbor\n"
1541 "How many RxQual measurements are used for averaging\n"
1542 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001543{
Harald Weltedcccb182010-05-16 20:52:23 +02001544 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001545 gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
1546 return CMD_SUCCESS;
1547}
1548
1549DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1550 "handover power budget interval <1-99>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001551 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001552 "How often to check if we have a better cell (SACCH frames)\n"
1553 "Interval\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001554{
Harald Weltedcccb182010-05-16 20:52:23 +02001555 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001556 gsmnet->handover.pwr_interval = atoi(argv[0]);
1557 return CMD_SUCCESS;
1558}
1559
1560DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1561 "handover power budget hysteresis <0-999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001562 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001563 "How many dB does a neighbor to be stronger to become a HO candidate\n"
1564 "Hysteresis\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001565{
Harald Weltedcccb182010-05-16 20:52:23 +02001566 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001567 gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
1568 return CMD_SUCCESS;
1569}
1570
1571DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1572 "handover maximum distance <0-9999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001573 HANDOVER_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001574 "How big is the maximum timing advance before HO is forced\n"
1575 "Distance\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001576{
Harald Weltedcccb182010-05-16 20:52:23 +02001577 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001578 gsmnet->handover.max_distance = atoi(argv[0]);
1579 return CMD_SUCCESS;
1580}
Harald Weltebc814502009-12-19 21:41:52 +01001581
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001582DEFUN(cfg_net_pag_any_tch,
1583 cfg_net_pag_any_tch_cmd,
1584 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001585 "Assign a TCH when receiving a Paging Any request\n"
1586 "Any Channel\n" "Use\n" "TCH\n"
1587 "Do not use TCH for Paging Request Any\n"
1588 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001589{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001590 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001591 gsmnet->pag_any_tch = atoi(argv[0]);
1592 gsm_net_update_ctype(gsmnet);
1593 return CMD_SUCCESS;
1594}
1595
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001596#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1597/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1598#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1599
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001600#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001601 DEFUN(cfg_net_T##number, \
1602 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001603 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001604 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001605 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001606 "Set to default timer value" \
1607 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1608 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001609{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001610 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001611 int value; \
1612 if (strcmp(argv[0], "default") == 0) \
1613 value = DEFAULT_TIMER(number); \
1614 else \
1615 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001616 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001617 gsmnet->T##number = value; \
1618 return CMD_SUCCESS; \
1619}
1620
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001621DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1622DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1623DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1624DECLARE_TIMER(3107, "Currently not used")
1625DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1626DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1627DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1628DECLARE_TIMER(3115, "Currently not used")
1629DECLARE_TIMER(3117, "Currently not used")
1630DECLARE_TIMER(3119, "Currently not used")
1631DECLARE_TIMER(3122, "Waiting time (seconds) after IMM ASS REJECT")
1632DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001633
Maxc08ee712016-05-11 12:45:13 +02001634DEFUN_DEPRECATED(cfg_net_dtx,
1635 cfg_net_dtx_cmd,
1636 "dtx-used (0|1)",
1637 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001638{
Maxc08ee712016-05-11 12:45:13 +02001639 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1640 "configuration options of BTS instead%s", VTY_NEWLINE);
1641 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001642}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001643
Harald Welte5258fc42009-03-28 19:07:53 +00001644/* per-BTS configuration */
1645DEFUN(cfg_bts,
1646 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001647 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001648 "Select a BTS to configure\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001649 BTS_NR_STR)
Harald Welte5258fc42009-03-28 19:07:53 +00001650{
Harald Weltedcccb182010-05-16 20:52:23 +02001651 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001652 int bts_nr = atoi(argv[0]);
1653 struct gsm_bts *bts;
1654
Harald Weltee441d9c2009-06-21 16:17:15 +02001655 if (bts_nr > gsmnet->num_bts) {
1656 vty_out(vty, "%% The next unused BTS number is %u%s",
1657 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001658 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001659 } else if (bts_nr == gsmnet->num_bts) {
1660 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001661 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001662 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001663 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001664 bts = gsm_bts_num(gsmnet, bts_nr);
1665
Daniel Willmannf15c2762010-01-11 13:43:07 +01001666 if (!bts) {
1667 vty_out(vty, "%% Unable to allocate BTS %u%s",
1668 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001669 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001670 }
Harald Welte5258fc42009-03-28 19:07:53 +00001671
1672 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001673 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001674 vty->node = BTS_NODE;
1675
1676 return CMD_SUCCESS;
1677}
1678
1679DEFUN(cfg_bts_type,
1680 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001681 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001682 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001683{
1684 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001685 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001686
Max7507aef2017-04-10 13:59:14 +02001687 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001688 if (rc < 0)
1689 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001690
Harald Welte5258fc42009-03-28 19:07:53 +00001691 return CMD_SUCCESS;
1692}
1693
Harald Weltefcd24452009-06-20 18:15:19 +02001694DEFUN(cfg_bts_band,
1695 cfg_bts_band_cmd,
1696 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001697 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001698{
1699 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001700 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001701
1702 if (band < 0) {
1703 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1704 band, VTY_NEWLINE);
1705 return CMD_WARNING;
1706 }
1707
1708 bts->band = band;
1709
1710 return CMD_SUCCESS;
1711}
1712
Maxc08ee712016-05-11 12:45:13 +02001713DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1714 "Configure discontinuous transmission\n"
1715 "Enable Uplink DTX for this BTS\n"
1716 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1717 "older phones).\n")
1718{
1719 struct gsm_bts *bts = vty->index;
1720
1721 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001722 if (!is_ipaccess_bts(bts))
1723 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1724 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001725 return CMD_SUCCESS;
1726}
1727
1728DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1729 NO_STR
1730 "Configure discontinuous transmission\n"
1731 "Disable Uplink DTX for this BTS\n")
1732{
1733 struct gsm_bts *bts = vty->index;
1734
1735 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1736
1737 return CMD_SUCCESS;
1738}
1739
1740DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1741 "Configure discontinuous transmission\n"
1742 "Enable Downlink DTX for this BTS\n")
1743{
1744 struct gsm_bts *bts = vty->index;
1745
1746 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001747 if (!is_ipaccess_bts(bts))
1748 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1749 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001750 return CMD_SUCCESS;
1751}
1752
1753DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1754 NO_STR
1755 "Configure discontinuous transmission\n"
1756 "Disable Downlink DTX for this BTS\n")
1757{
1758 struct gsm_bts *bts = vty->index;
1759
1760 bts->dtxd = false;
1761
1762 return CMD_SUCCESS;
1763}
1764
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001765DEFUN(cfg_bts_ci,
1766 cfg_bts_ci_cmd,
1767 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001768 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001769{
1770 struct gsm_bts *bts = vty->index;
1771 int ci = atoi(argv[0]);
1772
1773 if (ci < 0 || ci > 0xffff) {
1774 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1775 ci, VTY_NEWLINE);
1776 return CMD_WARNING;
1777 }
1778 bts->cell_identity = ci;
1779
1780 return CMD_SUCCESS;
1781}
1782
Harald Welte5258fc42009-03-28 19:07:53 +00001783DEFUN(cfg_bts_lac,
1784 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001785 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001786 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001787{
1788 struct gsm_bts *bts = vty->index;
1789 int lac = atoi(argv[0]);
1790
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001791 if (lac < 0 || lac > 0xffff) {
1792 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001793 lac, VTY_NEWLINE);
1794 return CMD_WARNING;
1795 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001796
1797 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1798 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1799 lac, VTY_NEWLINE);
1800 return CMD_WARNING;
1801 }
1802
Harald Welte5258fc42009-03-28 19:07:53 +00001803 bts->location_area_code = lac;
1804
1805 return CMD_SUCCESS;
1806}
1807
Harald Weltea43f7892009-12-01 18:04:30 +05301808
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001809/* compatibility wrapper for old config files */
1810DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001811 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001812 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001813 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001814{
Harald Welte5258fc42009-03-28 19:07:53 +00001815 return CMD_SUCCESS;
1816}
1817
Harald Welte78f2f502009-05-23 16:56:52 +00001818DEFUN(cfg_bts_bsic,
1819 cfg_bts_bsic_cmd,
1820 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001821 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1822 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001823{
1824 struct gsm_bts *bts = vty->index;
1825 int bsic = atoi(argv[0]);
1826
1827 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001828 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001829 bsic, VTY_NEWLINE);
1830 return CMD_WARNING;
1831 }
1832 bts->bsic = bsic;
1833
1834 return CMD_SUCCESS;
1835}
1836
Harald Welte4cc34222009-05-01 15:12:31 +00001837DEFUN(cfg_bts_unit_id,
1838 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001839 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001840 "Abis/IP specific options\n"
1841 "Set the IPA BTS Unit ID\n"
1842 "Unit ID (Site)\n"
1843 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001844{
1845 struct gsm_bts *bts = vty->index;
1846 int site_id = atoi(argv[0]);
1847 int bts_id = atoi(argv[1]);
1848
Harald Welte07dc73d2009-08-07 13:27:09 +02001849 if (!is_ipaccess_bts(bts)) {
1850 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1851 return CMD_WARNING;
1852 }
1853
Harald Welte4cc34222009-05-01 15:12:31 +00001854 bts->ip_access.site_id = site_id;
1855 bts->ip_access.bts_id = bts_id;
1856
1857 return CMD_SUCCESS;
1858}
1859
Harald Welte8b291802013-03-12 13:57:05 +01001860DEFUN(cfg_bts_rsl_ip,
1861 cfg_bts_rsl_ip_cmd,
1862 "ip.access rsl-ip A.B.C.D",
1863 "Abis/IP specific options\n"
1864 "Set the IPA RSL IP Address of the BSC\n"
1865 "Destination IP address for RSL connection\n")
1866{
1867 struct gsm_bts *bts = vty->index;
1868 struct in_addr ia;
1869
1870 if (!is_ipaccess_bts(bts)) {
1871 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1872 return CMD_WARNING;
1873 }
1874
1875 inet_aton(argv[0], &ia);
1876 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1877
1878 return CMD_SUCCESS;
1879}
1880
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001881#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001882
Sylvain Munautc9519462011-10-17 14:04:55 +02001883DEFUN(cfg_bts_nokia_site_skip_reset,
1884 cfg_bts_nokia_site_skip_reset_cmd,
1885 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001886 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001887 "Skip the reset step during bootstrap process of this BTS\n"
1888 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02001889{
1890 struct gsm_bts *bts = vty->index;
1891
1892 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
1893 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
1894 return CMD_WARNING;
1895 }
1896
1897 bts->nokia.skip_reset = atoi(argv[0]);
1898
1899 return CMD_SUCCESS;
1900}
1901
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001902DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
1903 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
1904 "nokia_site no-local-rel-conf (0|1)",
1905 NOKIA_STR
1906 "Do not wait for RELease CONFirm message when releasing channel locally\n"
1907 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
1908{
1909 struct gsm_bts *bts = vty->index;
1910
1911 if (!is_nokia_bts(bts)) {
1912 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1913 VTY_NEWLINE);
1914 return CMD_WARNING;
1915 }
1916
1917 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
1918
1919 return CMD_SUCCESS;
1920}
1921
Sipos Csaba56e17662015-02-07 13:27:36 +01001922DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
1923 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
1924 "nokia_site bts-reset-timer <15-100>",
1925 NOKIA_STR
1926 "The amount of time (in sec.) between BTS_RESET is sent,\n"
1927 "and the BTS is being bootstrapped.\n")
1928{
1929 struct gsm_bts *bts = vty->index;
1930
1931 if (!is_nokia_bts(bts)) {
1932 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1933 VTY_NEWLINE);
1934 return CMD_WARNING;
1935 }
1936
1937 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
1938
1939 return CMD_SUCCESS;
1940}
Harald Welte8f0ed552010-05-11 21:53:49 +02001941#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001942#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001943
Harald Welte8175e952009-10-20 00:22:00 +02001944DEFUN(cfg_bts_stream_id,
1945 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001946 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02001947 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001948 "Set the ip.access Stream ID of the OML link of this BTS\n"
1949 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02001950{
1951 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001952 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02001953
1954 if (!is_ipaccess_bts(bts)) {
1955 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1956 return CMD_WARNING;
1957 }
1958
1959 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001960 /* This is used by e1inp_bind_ops callback for each BTS model. */
1961 bts->oml_e1_link.e1_nr = linenr;
1962
1963 return CMD_SUCCESS;
1964}
1965
Harald Welted13e0cd2012-08-17 09:52:03 +02001966#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02001967
Harald Welte42581822009-08-08 16:12:58 +02001968DEFUN(cfg_bts_oml_e1,
1969 cfg_bts_oml_e1_cmd,
1970 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02001971 OML_E1_STR
1972 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001973 "E1/T1 line number to be used for OML\n"
1974 "E1/T1 timeslot to be used for OML\n"
1975 "E1/T1 timeslot to be used for OML\n"
1976 "E1/T1 sub-slot to be used for OML\n"
1977 "Use E1/T1 sub-slot 0\n"
1978 "Use E1/T1 sub-slot 1\n"
1979 "Use E1/T1 sub-slot 2\n"
1980 "Use E1/T1 sub-slot 3\n"
1981 "Use full E1 slot 3\n"
1982 )
Harald Welte42581822009-08-08 16:12:58 +02001983{
1984 struct gsm_bts *bts = vty->index;
1985
1986 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
1987
1988 return CMD_SUCCESS;
1989}
1990
1991
1992DEFUN(cfg_bts_oml_e1_tei,
1993 cfg_bts_oml_e1_tei_cmd,
1994 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001995 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001996 "Set the TEI to be used for OML\n"
1997 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02001998{
1999 struct gsm_bts *bts = vty->index;
2000
2001 bts->oml_tei = atoi(argv[0]);
2002
2003 return CMD_SUCCESS;
2004}
2005
Harald Welte7a8fa412009-08-10 13:48:16 +02002006DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2007 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002008 "Channnel Allocator\n" "Channel Allocator\n"
2009 "Allocate Timeslots and Transceivers in ascending order\n"
2010 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002011{
2012 struct gsm_bts *bts = vty->index;
2013
2014 if (!strcmp(argv[0], "ascending"))
2015 bts->chan_alloc_reverse = 0;
2016 else
2017 bts->chan_alloc_reverse = 1;
2018
2019 return CMD_SUCCESS;
2020}
2021
Harald Welte8f0ed552010-05-11 21:53:49 +02002022#define RACH_STR "Random Access Control Channel\n"
2023
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002024DEFUN(cfg_bts_rach_tx_integer,
2025 cfg_bts_rach_tx_integer_cmd,
2026 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002027 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002028 "Set the raw tx integer value in RACH Control parameters IE\n"
2029 "Set the raw tx integer value in RACH Control parameters IE\n"
2030 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002031{
2032 struct gsm_bts *bts = vty->index;
2033 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2034 return CMD_SUCCESS;
2035}
2036
2037DEFUN(cfg_bts_rach_max_trans,
2038 cfg_bts_rach_max_trans_cmd,
2039 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002040 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002041 "Set the maximum number of RACH burst transmissions\n"
2042 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002043 "Maximum number of 1 RACH burst transmissions\n"
2044 "Maximum number of 2 RACH burst transmissions\n"
2045 "Maximum number of 4 RACH burst transmissions\n"
2046 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002047{
2048 struct gsm_bts *bts = vty->index;
2049 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2050 return CMD_SUCCESS;
2051}
2052
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002053#define CD_STR "Channel Description\n"
2054
2055DEFUN(cfg_bts_chan_desc_att,
2056 cfg_bts_chan_desc_att_cmd,
2057 "channel-descrption attach (0|1)",
2058 CD_STR
2059 "Set if attachment is required\n"
2060 "Attachment is NOT required\n"
2061 "Attachment is required (standard)\n")
2062{
2063 struct gsm_bts *bts = vty->index;
2064 bts->si_common.chan_desc.att = atoi(argv[0]);
2065 return CMD_SUCCESS;
2066}
2067
2068DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2069 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2070 "channel-descrption bs-pa-mfrms <2-9>",
2071 CD_STR
2072 "Set number of multiframe periods for paging groups\n"
2073 "Number of multiframe periods for paging groups\n")
2074{
2075 struct gsm_bts *bts = vty->index;
2076 int bs_pa_mfrms = atoi(argv[0]);
2077
2078 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2079 return CMD_SUCCESS;
2080}
2081
2082DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2083 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2084 "channel-descrption bs-ag-blks-res <0-7>",
2085 CD_STR
2086 "Set number of blocks reserved for access grant\n"
2087 "Number of blocks reserved for access grant\n")
2088{
2089 struct gsm_bts *bts = vty->index;
2090 int bs_ag_blks_res = atoi(argv[0]);
2091
2092 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2093 return CMD_SUCCESS;
2094}
2095
Harald Welte8f0ed552010-05-11 21:53:49 +02002096#define NM_STR "Network Management\n"
2097
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002098DEFUN(cfg_bts_rach_nm_b_thresh,
2099 cfg_bts_rach_nm_b_thresh_cmd,
2100 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002101 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002102 "Set the NM Busy Threshold\n"
2103 "Set the NM Busy Threshold\n"
2104 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002105{
2106 struct gsm_bts *bts = vty->index;
2107 bts->rach_b_thresh = atoi(argv[0]);
2108 return CMD_SUCCESS;
2109}
2110
2111DEFUN(cfg_bts_rach_nm_ldavg,
2112 cfg_bts_rach_nm_ldavg_cmd,
2113 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002114 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002115 "Set the NM Loadaverage Slots value\n"
2116 "Set the NM Loadaverage Slots value\n"
2117 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002118{
2119 struct gsm_bts *bts = vty->index;
2120 bts->rach_ldavg_slots = atoi(argv[0]);
2121 return CMD_SUCCESS;
2122}
2123
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002124DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2125 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002126 "Should this cell be barred from access?\n"
2127 "Should this cell be barred from access?\n"
2128 "Cell should NOT be barred\n"
2129 "Cell should be barred\n")
2130
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002131{
2132 struct gsm_bts *bts = vty->index;
2133
Harald Welte71355012009-12-21 23:08:18 +01002134 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002135
2136 return CMD_SUCCESS;
2137}
2138
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002139DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2140 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002141 RACH_STR
2142 "Should this cell allow emergency calls?\n"
2143 "Should this cell allow emergency calls?\n"
2144 "Should this cell allow emergency calls?\n"
2145 "Do NOT allow emergency calls\n"
2146 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002147{
2148 struct gsm_bts *bts = vty->index;
2149
2150 if (atoi(argv[0]) == 0)
2151 bts->si_common.rach_control.t2 |= 0x4;
2152 else
2153 bts->si_common.rach_control.t2 &= ~0x4;
2154
2155 return CMD_SUCCESS;
2156}
2157
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002158DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2159 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2160 RACH_STR
2161 "Set access control class\n"
2162 "Access control class 0\n"
2163 "Access control class 1\n"
2164 "Access control class 2\n"
2165 "Access control class 3\n"
2166 "Access control class 4\n"
2167 "Access control class 5\n"
2168 "Access control class 6\n"
2169 "Access control class 7\n"
2170 "Access control class 8\n"
2171 "Access control class 9\n"
2172 "Access control class 11 for PLMN use\n"
2173 "Access control class 12 for security services\n"
2174 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2175 "Access control class 14 for emergency services\n"
2176 "Access control class 15 for PLMN staff\n"
2177 "barred to use access control class\n"
2178 "allowed to use access control class\n")
2179{
2180 struct gsm_bts *bts = vty->index;
2181
2182 uint8_t control_class;
2183 uint8_t allowed = 0;
2184
2185 if (strcmp(argv[1], "allowed") == 0)
2186 allowed = 1;
2187
2188 control_class = atoi(argv[0]);
2189 if (control_class < 8)
2190 if (allowed)
2191 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2192 else
2193 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2194 else
2195 if (allowed)
2196 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2197 else
2198 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2199
2200 return CMD_SUCCESS;
2201}
2202
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002203DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2204 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002205 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002206 "Maximum transmit power of the MS\n"
2207 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002208 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002209{
2210 struct gsm_bts *bts = vty->index;
2211
2212 bts->ms_max_power = atoi(argv[0]);
2213
2214 return CMD_SUCCESS;
2215}
2216
Harald Weltecfaabbb2012-08-16 23:23:50 +02002217#define CELL_STR "Cell Parameters\n"
2218
Harald Welte73225282009-12-12 18:17:25 +01002219DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2220 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002221 CELL_STR "Cell re-selection parameters\n"
2222 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002223 "Cell Re-Selection Hysteresis in dB")
2224{
2225 struct gsm_bts *bts = vty->index;
2226
2227 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2228
2229 return CMD_SUCCESS;
2230}
2231
2232DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2233 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002234 "Minimum RxLev needed for cell access\n"
2235 "Minimum RxLev needed for cell access\n"
2236 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002237 "Minimum RxLev needed for cell access (better than -110dBm)")
2238{
2239 struct gsm_bts *bts = vty->index;
2240
2241 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2242
2243 return CMD_SUCCESS;
2244}
2245
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002246DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2247 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002248 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2249 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002250{
2251 struct gsm_bts *bts = vty->index;
2252
2253 bts->si_common.cell_ro_sel_par.present = 1;
2254 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2255
2256 return CMD_SUCCESS;
2257}
2258
2259DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2260 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002261 CELL_STR "Cell Re-Selection Parameters\n"
2262 "Cell Re-Selection Offset (CRO) in dB\n"
2263 "Cell Re-Selection Offset (CRO) in dB\n"
2264 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002265{
2266 struct gsm_bts *bts = vty->index;
2267
2268 bts->si_common.cell_ro_sel_par.present = 1;
2269 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2270
2271 return CMD_SUCCESS;
2272}
2273
2274DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2275 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002276 "Cell selection temporary negative offset\n"
2277 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002278 "Cell selection temporary negative offset in dB")
2279{
2280 struct gsm_bts *bts = vty->index;
2281
2282 bts->si_common.cell_ro_sel_par.present = 1;
2283 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2284
2285 return CMD_SUCCESS;
2286}
2287
2288DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2289 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002290 "Cell selection temporary negative offset\n"
2291 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002292 "Sets cell selection temporary negative offset to infinity")
2293{
2294 struct gsm_bts *bts = vty->index;
2295
2296 bts->si_common.cell_ro_sel_par.present = 1;
2297 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2298
2299 return CMD_SUCCESS;
2300}
2301
2302DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2303 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002304 "Cell selection penalty time\n"
2305 "Cell selection penalty time\n"
2306 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002307{
2308 struct gsm_bts *bts = vty->index;
2309
2310 bts->si_common.cell_ro_sel_par.present = 1;
2311 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2312
2313 return CMD_SUCCESS;
2314}
2315
2316DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2317 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002318 "Cell selection penalty time\n"
2319 "Cell selection penalty time\n"
2320 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002321 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2322 "and TEMPORARY_OFFSET is ignored)")
2323{
2324 struct gsm_bts *bts = vty->index;
2325
2326 bts->si_common.cell_ro_sel_par.present = 1;
2327 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2328
2329 return CMD_SUCCESS;
2330}
2331
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002332DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2333 "radio-link-timeout <4-64>",
2334 "Radio link timeout criterion (BTS side)\n"
2335 "Radio link timeout value (lost SACCH block)\n")
2336{
2337 struct gsm_bts *bts = vty->index;
2338
Harald Welte2f8b9d22017-06-18 11:12:13 +03002339 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2340
2341 return CMD_SUCCESS;
2342}
2343
2344DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2345 "radio-link-timeout infinite",
2346 "Radio link timeout criterion (BTS side)\n"
2347 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2348{
2349 struct gsm_bts *bts = vty->index;
2350
2351 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2352 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2353 return CMD_WARNING;
2354 }
2355
2356 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2357 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002358
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002359 return CMD_SUCCESS;
2360}
2361
Harald Welte8f0ed552010-05-11 21:53:49 +02002362#define GPRS_TEXT "GPRS Packet Network\n"
2363
Harald Welteaf387632010-03-14 23:30:30 +08002364DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002365 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002366 GPRS_TEXT
2367 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002368 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002369 "GPRS BSSGP VC Identifier")
2370{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002371 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002372 struct gsm_bts *bts = vty->index;
2373
Harald Welte4511d892010-04-18 15:51:20 +02002374 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002375 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2376 return CMD_WARNING;
2377 }
2378
Harald Welte97a282b2010-03-14 15:37:43 +08002379 bts->gprs.cell.bvci = atoi(argv[0]);
2380
2381 return CMD_SUCCESS;
2382}
2383
Harald Weltea5731cf2010-03-22 11:48:36 +08002384DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2385 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002386 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002387 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002388 "GPRS NS Entity Identifier")
2389{
2390 struct gsm_bts *bts = vty->index;
2391
Harald Welte4511d892010-04-18 15:51:20 +02002392 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002393 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2394 return CMD_WARNING;
2395 }
2396
2397 bts->gprs.nse.nsei = atoi(argv[0]);
2398
2399 return CMD_SUCCESS;
2400}
2401
Harald Welte8f0ed552010-05-11 21:53:49 +02002402#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2403 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002404
Harald Welte97a282b2010-03-14 15:37:43 +08002405DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2406 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002407 GPRS_TEXT NSVC_TEXT
2408 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002409 "GPRS NS VC Identifier")
2410{
2411 struct gsm_bts *bts = vty->index;
2412 int idx = atoi(argv[0]);
2413
Harald Welte4511d892010-04-18 15:51:20 +02002414 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002415 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2416 return CMD_WARNING;
2417 }
2418
Harald Welte97a282b2010-03-14 15:37:43 +08002419 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2420
2421 return CMD_SUCCESS;
2422}
2423
Harald Welteaf387632010-03-14 23:30:30 +08002424DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2425 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002426 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002427 "GPRS NS Local UDP Port\n"
2428 "GPRS NS Local UDP Port\n"
2429 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002430 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002431{
2432 struct gsm_bts *bts = vty->index;
2433 int idx = atoi(argv[0]);
2434
Harald Welte4511d892010-04-18 15:51:20 +02002435 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002436 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2437 return CMD_WARNING;
2438 }
2439
Harald Welteaf387632010-03-14 23:30:30 +08002440 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2441
2442 return CMD_SUCCESS;
2443}
2444
2445DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2446 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002447 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002448 "GPRS NS Remote UDP Port\n"
2449 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002450 "GPRS NS Remote UDP Port\n"
2451 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002452{
2453 struct gsm_bts *bts = vty->index;
2454 int idx = atoi(argv[0]);
2455
Harald Welte4511d892010-04-18 15:51:20 +02002456 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002457 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2458 return CMD_WARNING;
2459 }
2460
Harald Welteaf387632010-03-14 23:30:30 +08002461 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2462
2463 return CMD_SUCCESS;
2464}
2465
2466DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2467 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002468 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002469 "GPRS NS Remote IP Address\n"
2470 "GPRS NS Remote IP Address\n"
2471 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002472{
2473 struct gsm_bts *bts = vty->index;
2474 int idx = atoi(argv[0]);
2475 struct in_addr ia;
2476
Harald Welte4511d892010-04-18 15:51:20 +02002477 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002478 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2479 return CMD_WARNING;
2480 }
2481
Harald Welteaf387632010-03-14 23:30:30 +08002482 inet_aton(argv[1], &ia);
2483 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2484
2485 return CMD_SUCCESS;
2486}
2487
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002488DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002489 "paging free <-1-1024>",
2490 "Paging options\n"
2491 "Only page when having a certain amount of free slots\n"
2492 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002493{
2494 struct gsm_bts *bts = vty->index;
2495
2496 bts->paging.free_chans_need = atoi(argv[0]);
2497 return CMD_SUCCESS;
2498}
2499
Harald Welte615e9562010-05-11 23:50:21 +02002500DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2501 "gprs ns timer " NS_TIMERS " <0-255>",
2502 GPRS_TEXT "Network Service\n"
2503 "Network Service Timer\n"
2504 NS_TIMERS_HELP "Timer Value\n")
2505{
2506 struct gsm_bts *bts = vty->index;
2507 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2508 int val = atoi(argv[1]);
2509
2510 if (bts->gprs.mode == BTS_GPRS_NONE) {
2511 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2512 return CMD_WARNING;
2513 }
2514
2515 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2516 return CMD_WARNING;
2517
2518 bts->gprs.nse.timer[idx] = val;
2519
2520 return CMD_SUCCESS;
2521}
2522
2523#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 +02002524#define BSSGP_TIMERS_HELP \
2525 "Tbvc-block timeout\n" \
2526 "Tbvc-block retries\n" \
2527 "Tbvc-unblock retries\n" \
2528 "Tbvcc-reset timeout\n" \
2529 "Tbvc-reset retries\n" \
2530 "Tbvc-suspend timeout\n" \
2531 "Tbvc-suspend retries\n" \
2532 "Tbvc-resume timeout\n" \
2533 "Tbvc-resume retries\n" \
2534 "Tbvc-capa-update timeout\n" \
2535 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002536
2537DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2538 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2539 GPRS_TEXT "Cell / BSSGP\n"
2540 "Cell/BSSGP Timer\n"
2541 BSSGP_TIMERS_HELP "Timer Value\n")
2542{
2543 struct gsm_bts *bts = vty->index;
2544 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2545 int val = atoi(argv[1]);
2546
2547 if (bts->gprs.mode == BTS_GPRS_NONE) {
2548 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2549 return CMD_WARNING;
2550 }
2551
2552 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2553 return CMD_WARNING;
2554
2555 bts->gprs.cell.timer[idx] = val;
2556
2557 return CMD_SUCCESS;
2558}
2559
Harald Welte97a282b2010-03-14 15:37:43 +08002560DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2561 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002562 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002563 "GPRS Routing Area Code\n"
2564 "GPRS Routing Area Code\n"
2565 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002566{
2567 struct gsm_bts *bts = vty->index;
2568
Harald Welte4511d892010-04-18 15:51:20 +02002569 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002570 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2571 return CMD_WARNING;
2572 }
2573
Harald Welte97a282b2010-03-14 15:37:43 +08002574 bts->gprs.rac = atoi(argv[0]);
2575
2576 return CMD_SUCCESS;
2577}
2578
Max292ec582016-07-28 11:55:37 +02002579DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2580 "gprs control-ack-type-rach", GPRS_TEXT
2581 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2582 "four access bursts format instead of default RLC/MAC control block\n")
2583{
2584 struct gsm_bts *bts = vty->index;
2585
2586 if (bts->gprs.mode == BTS_GPRS_NONE) {
2587 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2588 return CMD_WARNING;
2589 }
2590
2591 bts->gprs.ctrl_ack_type_use_block = false;
2592
2593 return CMD_SUCCESS;
2594}
2595
2596DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2597 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2598 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2599 "four access bursts format instead of default RLC/MAC control block\n")
2600{
2601 struct gsm_bts *bts = vty->index;
2602
2603 if (bts->gprs.mode == BTS_GPRS_NONE) {
2604 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2605 return CMD_WARNING;
2606 }
2607
2608 bts->gprs.ctrl_ack_type_use_block = true;
2609
2610 return CMD_SUCCESS;
2611}
2612
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002613DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2614 "gprs network-control-order (nc0|nc1|nc2)",
2615 GPRS_TEXT
2616 "GPRS Network Control Order\n"
2617 "MS controlled cell re-selection, no measurement reporting\n"
2618 "MS controlled cell re-selection, MS sends measurement reports\n"
2619 "Network controlled cell re-selection, MS sends measurement reports\n")
2620{
2621 struct gsm_bts *bts = vty->index;
2622
2623 if (bts->gprs.mode == BTS_GPRS_NONE) {
2624 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2625 return CMD_WARNING;
2626 }
2627
2628 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2629
2630 return CMD_SUCCESS;
2631}
2632
Harald Welte4511d892010-04-18 15:51:20 +02002633DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2634 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002635 GPRS_TEXT
2636 "GPRS Mode for this BTS\n"
2637 "GPRS Disabled on this BTS\n"
2638 "GPRS Enabled on this BTS\n"
2639 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002640{
2641 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002642 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002643
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002644 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002645 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2646 VTY_NEWLINE);
2647 return CMD_WARNING;
2648 }
2649
2650 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002651
2652 return CMD_SUCCESS;
2653}
2654
bhargava350533c2016-07-21 11:14:34 +05302655DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2656 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2657 "gprs 11bit_rach_support_for_egprs (0|1)",
2658 GPRS_TEXT "11 bit RACH options\n"
2659 "Disable 11 bit RACH for EGPRS\n"
2660 "Enable 11 bit RACH for EGPRS")
2661{
2662 struct gsm_bts *bts = vty->index;
2663
2664 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2665
2666 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2667 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2668 return CMD_WARNING;
2669 }
2670
2671 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2672 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2673 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2674 " enabled%s", VTY_NEWLINE);
2675 return CMD_WARNING;
2676 }
2677
2678 return CMD_SUCCESS;
2679}
2680
Harald Welte9fbff4a2010-07-30 11:50:09 +02002681#define SI_TEXT "System Information Messages\n"
2682#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)"
2683#define SI_TYPE_HELP "System Information Type 1\n" \
2684 "System Information Type 2\n" \
2685 "System Information Type 3\n" \
2686 "System Information Type 4\n" \
2687 "System Information Type 5\n" \
2688 "System Information Type 6\n" \
2689 "System Information Type 7\n" \
2690 "System Information Type 8\n" \
2691 "System Information Type 9\n" \
2692 "System Information Type 10\n" \
2693 "System Information Type 13\n" \
2694 "System Information Type 16\n" \
2695 "System Information Type 17\n" \
2696 "System Information Type 18\n" \
2697 "System Information Type 19\n" \
2698 "System Information Type 20\n" \
2699 "System Information Type 2bis\n" \
2700 "System Information Type 2ter\n" \
2701 "System Information Type 2quater\n" \
2702 "System Information Type 5bis\n" \
2703 "System Information Type 5ter\n"
2704
2705DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2706 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2707 SI_TEXT SI_TYPE_HELP
2708 "System Information Mode\n"
2709 "Static user-specified\n"
2710 "Dynamic, BSC-computed\n")
2711{
2712 struct gsm_bts *bts = vty->index;
2713 int type;
2714
2715 type = get_string_value(osmo_sitype_strs, argv[0]);
2716 if (type < 0) {
2717 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2718 return CMD_WARNING;
2719 }
2720
2721 if (!strcmp(argv[1], "static"))
2722 bts->si_mode_static |= (1 << type);
2723 else
2724 bts->si_mode_static &= ~(1 << type);
2725
2726 return CMD_SUCCESS;
2727}
2728
2729DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2730 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2731 SI_TEXT SI_TYPE_HELP
2732 "Static System Information filling\n"
2733 "Static user-specified SI content in HEX notation\n")
2734{
2735 struct gsm_bts *bts = vty->index;
2736 int rc, type;
2737
2738 type = get_string_value(osmo_sitype_strs, argv[0]);
2739 if (type < 0) {
2740 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2741 return CMD_WARNING;
2742 }
2743
2744 if (!(bts->si_mode_static & (1 << type))) {
2745 vty_out(vty, "SI Type %s is not configured in static mode%s",
2746 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2747 return CMD_WARNING;
2748 }
2749
Harald Welte290aaed2010-07-30 11:53:18 +02002750 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002751 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002752
2753 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002754 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2755 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002756 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2757 return CMD_WARNING;
2758 }
2759
2760 /* Mark this SI as present */
2761 bts->si_valid |= (1 << type);
2762
2763 return CMD_SUCCESS;
2764}
2765
Harald Welte42def722017-01-13 00:10:32 +01002766DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2767 "early-classmark-sending (allowed|forbidden)",
2768 "Early Classmark Sending\n"
2769 "Early Classmark Sending is allowed\n"
2770 "Early Classmark Sending is forbidden\n")
2771{
2772 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002773
2774 if (!strcmp(argv[0], "allowed"))
2775 bts->early_classmark_allowed = true;
2776 else
2777 bts->early_classmark_allowed = false;
2778
2779 return CMD_SUCCESS;
2780}
2781
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002782DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2783 "early-classmark-sending-3g (allowed|forbidden)",
2784 "3G Early Classmark Sending\n"
2785 "3G Early Classmark Sending is allowed\n"
2786 "3G Early Classmark Sending is forbidden\n")
2787{
2788 struct gsm_bts *bts = vty->index;
2789
2790 if (!strcmp(argv[0], "allowed"))
2791 bts->early_classmark_allowed_3g = true;
2792 else
2793 bts->early_classmark_allowed_3g = false;
2794
2795 return CMD_SUCCESS;
2796}
2797
Harald Welte32c09622011-01-11 23:44:56 +01002798DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002799 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002800 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002801 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2802 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002803{
2804 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002805 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002806
Harald Welte64c07d22011-02-15 11:43:27 +01002807 switch (mode) {
2808 case NL_MODE_MANUAL_SI5SEP:
2809 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002810 /* make sure we clear the current list when switching to
2811 * manual mode */
2812 if (bts->neigh_list_manual_mode == 0)
2813 memset(&bts->si_common.data.neigh_list, 0,
2814 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002815 break;
2816 default:
2817 break;
2818 }
2819
2820 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002821
2822 return CMD_SUCCESS;
2823}
2824
2825DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002826 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002827 "Neighbor List\n" "Add to manual neighbor list\n"
2828 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2829 "ARFCN of neighbor\n")
2830{
2831 struct gsm_bts *bts = vty->index;
2832 struct bitvec *bv = &bts->si_common.neigh_list;
2833 uint16_t arfcn = atoi(argv[1]);
2834
2835 if (!bts->neigh_list_manual_mode) {
2836 vty_out(vty, "%% Cannot configure neighbor list in "
2837 "automatic mode%s", VTY_NEWLINE);
2838 return CMD_WARNING;
2839 }
2840
2841 if (!strcmp(argv[0], "add"))
2842 bitvec_set_bit_pos(bv, arfcn, 1);
2843 else
2844 bitvec_set_bit_pos(bv, arfcn, 0);
2845
2846 return CMD_SUCCESS;
2847}
2848
Max70fdd242017-06-15 15:10:53 +02002849/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002850DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002851 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2852 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2853 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2854 "Add to manual SI2quater neighbor list\n"
2855 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2856 "threshold high bits\n" "threshold high bits\n"
2857 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2858 "priority\n" "priority (8 means NA)\n"
2859 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2860 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002861{
2862 struct gsm_bts *bts = vty->index;
2863 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2864 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002865 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2866 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002867 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002868
Max70fdd242017-06-15 15:10:53 +02002869 switch (r) {
2870 case 1:
2871 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2872 thresh_hi, VTY_NEWLINE);
2873 break;
2874 case EARFCN_THRESH_LOW_INVALID:
2875 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2876 thresh_lo, VTY_NEWLINE);
2877 break;
2878 case EARFCN_QRXLV_INVALID + 1:
2879 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2880 qrx, VTY_NEWLINE);
2881 break;
2882 case EARFCN_PRIO_INVALID:
2883 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
2884 prio, VTY_NEWLINE);
2885 break;
2886 default:
2887 if (r < 0) {
2888 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
2889 return CMD_WARNING;
2890 }
Max59a1bf32016-04-15 16:04:46 +02002891 }
2892
Max70fdd242017-06-15 15:10:53 +02002893 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01002894 return CMD_SUCCESS;
2895
Maxf39d03a2017-05-12 17:00:30 +02002896 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02002897 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02002898 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01002899
Maxaafff962016-04-20 15:57:14 +02002900 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02002901}
2902
2903DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02002904 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02002905 "SI2quater Neighbor List\n"
2906 "SI2quater Neighbor List\n"
2907 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02002908 "EARFCN of neighbor\n"
2909 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02002910{
2911 struct gsm_bts *bts = vty->index;
2912 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02002913 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02002914 int r = osmo_earfcn_del(e, arfcn);
2915 if (r < 0) {
2916 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02002917 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02002918 return CMD_WARNING;
2919 }
2920
2921 return CMD_SUCCESS;
2922}
2923
Max26679e02016-04-20 15:57:13 +02002924DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02002925 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02002926 "SI2quater Neighbor List\n"
2927 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
2928 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
2929 "diversity bit\n")
2930{
2931 struct gsm_bts *bts = vty->index;
2932 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
2933
2934 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
2935 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02002936 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 +01002937 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02002938 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02002939 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
2940 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01002941 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02002942 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02002943 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02002944 return CMD_WARNING;
2945 }
2946
2947 return CMD_SUCCESS;
2948}
2949
2950DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02002951 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02002952 "SI2quater Neighbor List\n"
2953 "SI2quater Neighbor List\n"
2954 "Delete from SI2quater manual neighbor list\n"
2955 "UARFCN of neighbor\n"
2956 "UARFCN\n"
2957 "scrambling code\n")
2958{
2959 struct gsm_bts *bts = vty->index;
2960
2961 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
2962 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
2963 VTY_NEWLINE);
2964 return CMD_WARNING;
2965 }
2966
2967 return CMD_SUCCESS;
2968}
2969
Harald Welte64c07d22011-02-15 11:43:27 +01002970DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002971 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002972 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002973 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
2974 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
2975 "ARFCN of neighbor\n")
2976{
2977 struct gsm_bts *bts = vty->index;
2978 struct bitvec *bv = &bts->si_common.si5_neigh_list;
2979 uint16_t arfcn = atoi(argv[1]);
2980
2981 if (!bts->neigh_list_manual_mode) {
2982 vty_out(vty, "%% Cannot configure neighbor list in "
2983 "automatic mode%s", VTY_NEWLINE);
2984 return CMD_WARNING;
2985 }
2986
2987 if (!strcmp(argv[0], "add"))
2988 bitvec_set_bit_pos(bv, arfcn, 1);
2989 else
2990 bitvec_set_bit_pos(bv, arfcn, 0);
2991
2992 return CMD_SUCCESS;
2993}
Harald Welte9fbff4a2010-07-30 11:50:09 +02002994
Harald Welte8254cf72017-05-29 13:42:19 +02002995DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
2996 "pcu-socket PATH",
2997 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
2998 "Path in the file system for the unix-domain PCU socket\n")
2999{
3000 struct gsm_bts *bts = vty->index;
3001 int rc;
3002
Harald Welte4a824ca2017-05-29 13:54:27 +02003003 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003004 pcu_sock_exit(bts);
3005 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3006 if (rc < 0) {
3007 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3008 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3009 return CMD_WARNING;
3010 }
3011
3012 return CMD_SUCCESS;
3013}
3014
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003015#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3016
3017DEFUN(cfg_bts_excl_rf_lock,
3018 cfg_bts_excl_rf_lock_cmd,
3019 "rf-lock-exclude",
3020 EXCL_RFLOCK_STR)
3021{
3022 struct gsm_bts *bts = vty->index;
3023 bts->excl_from_rf_lock = 1;
3024 return CMD_SUCCESS;
3025}
3026
3027DEFUN(cfg_bts_no_excl_rf_lock,
3028 cfg_bts_no_excl_rf_lock_cmd,
3029 "no rf-lock-exclude",
3030 NO_STR EXCL_RFLOCK_STR)
3031{
3032 struct gsm_bts *bts = vty->index;
3033 bts->excl_from_rf_lock = 0;
3034 return CMD_SUCCESS;
3035}
3036
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003037#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3038
3039DEFUN(cfg_bts_force_comb_si,
3040 cfg_bts_force_comb_si_cmd,
3041 "force-combined-si",
3042 FORCE_COMB_SI_STR)
3043{
3044 struct gsm_bts *bts = vty->index;
3045 bts->force_combined_si = 1;
3046 return CMD_SUCCESS;
3047}
3048
3049DEFUN(cfg_bts_no_force_comb_si,
3050 cfg_bts_no_force_comb_si_cmd,
3051 "no force-combined-si",
3052 NO_STR FORCE_COMB_SI_STR)
3053{
3054 struct gsm_bts *bts = vty->index;
3055 bts->force_combined_si = 0;
3056 return CMD_SUCCESS;
3057}
3058
Andreas Eversberga83d5112013-12-07 18:32:28 +01003059static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3060{
3061 struct gsm_bts *bts = vty->index;
3062 struct bts_codec_conf *codec = &bts->codec;
3063 int i;
3064
3065 codec->hr = 0;
3066 codec->efr = 0;
3067 codec->amr = 0;
3068 for (i = 0; i < argc; i++) {
3069 if (!strcmp(argv[i], "hr"))
3070 codec->hr = 1;
3071 if (!strcmp(argv[i], "efr"))
3072 codec->efr = 1;
3073 if (!strcmp(argv[i], "amr"))
3074 codec->amr = 1;
3075 }
3076}
3077
3078#define CODEC_PAR_STR " (hr|efr|amr)"
3079#define CODEC_HELP_STR "Half Rate\n" \
3080 "Enhanced Full Rate\nAdaptive Multirate\n"
3081
3082DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3083 "codec-support fr",
3084 "Codec Support settings\nFullrate\n")
3085{
3086 _get_codec_from_arg(vty, 0, argv);
3087 return CMD_SUCCESS;
3088}
3089
3090DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3091 "codec-support fr" CODEC_PAR_STR,
3092 "Codec Support settings\nFullrate\n"
3093 CODEC_HELP_STR)
3094{
3095 _get_codec_from_arg(vty, 1, argv);
3096 return CMD_SUCCESS;
3097}
3098
3099DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3100 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3101 "Codec Support settings\nFullrate\n"
3102 CODEC_HELP_STR CODEC_HELP_STR)
3103{
3104 _get_codec_from_arg(vty, 2, argv);
3105 return CMD_SUCCESS;
3106}
3107
3108DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3109 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3110 "Codec Support settings\nFullrate\n"
3111 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3112{
3113 _get_codec_from_arg(vty, 3, argv);
3114 return CMD_SUCCESS;
3115}
3116
3117DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3118 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3119 "Codec Support settings\nFullrate\n"
3120 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3121{
3122 _get_codec_from_arg(vty, 4, argv);
3123 return CMD_SUCCESS;
3124}
3125
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003126DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3127 "depends-on-bts <0-255>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003128 "This BTS can only be started if another one is up\n"
3129 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003130{
3131 struct gsm_bts *bts = vty->index;
3132 struct gsm_bts *other_bts;
3133 int dep = atoi(argv[0]);
3134
3135
3136 if (!is_ipaccess_bts(bts)) {
3137 vty_out(vty, "This feature is only available for IP systems.%s",
3138 VTY_NEWLINE);
3139 return CMD_WARNING;
3140 }
3141
3142 other_bts = gsm_bts_num(bts->network, dep);
3143 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3144 vty_out(vty, "This feature is only available for IP systems.%s",
3145 VTY_NEWLINE);
3146 return CMD_WARNING;
3147 }
3148
3149 if (dep >= bts->nr) {
3150 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3151 VTY_NEWLINE);
3152 return CMD_WARNING;
3153 }
3154
3155 bts_depend_mark(bts, dep);
3156 return CMD_SUCCESS;
3157}
3158
3159DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3160 "depeneds-on-bts <0-255>",
3161 NO_STR "This BTS can only be started if another one is up\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003162 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003163{
3164 struct gsm_bts *bts = vty->index;
3165 int dep = atoi(argv[0]);
3166
3167 bts_depend_clear(bts, dep);
3168 return CMD_SUCCESS;
3169}
3170
Andreas Eversberg73266522014-01-19 11:47:44 +01003171#define AMR_TEXT "Adaptive Multi Rate settings\n"
3172#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3173#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3174 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3175#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3176#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3177
3178static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3179{
3180 struct gsm_bts *bts = vty->index;
3181 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3182 struct gsm48_multi_rate_conf *mr_conf =
3183 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3184 int i;
3185
3186 mr->gsm48_ie[1] = 0;
3187 for (i = 0; i < argc; i++)
3188 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3189 mr_conf->icmi = 0;
3190}
3191
3192static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3193{
3194 struct gsm_bts *bts = vty->index;
3195 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003196 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003197 int i;
3198
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003199 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3200 for (i = 0; i < argc - 1; i++)
3201 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003202}
3203
3204static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3205{
3206 struct gsm_bts *bts = vty->index;
3207 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003208 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003209 int i;
3210
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003211 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3212 for (i = 0; i < argc - 1; i++)
3213 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003214}
3215
3216static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3217{
3218 struct gsm_bts *bts = vty->index;
3219 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3220 struct gsm48_multi_rate_conf *mr_conf =
3221 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3222 int num = 0, i;
3223
3224 for (i = 0; i < ((full) ? 8 : 6); i++) {
3225 if ((mr->gsm48_ie[1] & (1 << i))) {
3226 num++;
3227 }
3228 }
3229
3230 if (argv[0][0] == 'a' || num == 0)
3231 mr_conf->icmi = 0;
3232 else {
3233 mr_conf->icmi = 1;
3234 if (num < atoi(argv[0]))
3235 mr_conf->smod = num - 1;
3236 else
3237 mr_conf->smod = atoi(argv[0]) - 1;
3238 }
3239}
3240
3241#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3242#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3243 "10,2k\n12,2k\n"
3244
3245#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3246#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3247
3248#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3249#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3250
3251DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3252 "amr tch-f modes" AMR_TCHF_PAR_STR,
3253 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3254 AMR_TCHF_HELP_STR)
3255{
3256 get_amr_from_arg(vty, 1, argv, 1);
3257 return CMD_SUCCESS;
3258}
3259
3260DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3261 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3262 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3263 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3264{
3265 get_amr_from_arg(vty, 2, argv, 1);
3266 return CMD_SUCCESS;
3267}
3268
3269DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3270 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3271 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3272 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3273{
3274 get_amr_from_arg(vty, 3, argv, 1);
3275 return CMD_SUCCESS;
3276}
3277
3278DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3279 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3280 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3281 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3282{
3283 get_amr_from_arg(vty, 4, argv, 1);
3284 return CMD_SUCCESS;
3285}
3286
3287DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3288 "amr tch-f start-mode (auto|1|2|3|4)",
3289 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3290{
3291 get_amr_start_from_arg(vty, argv, 1);
3292 return CMD_SUCCESS;
3293}
3294
3295DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3296 "amr tch-f threshold (ms|bts) <0-63>",
3297 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3298 AMR_TH_HELP_STR)
3299{
3300 get_amr_th_from_arg(vty, 2, argv, 1);
3301 return CMD_SUCCESS;
3302}
3303
3304DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3305 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3306 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3307 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3308{
3309 get_amr_th_from_arg(vty, 3, argv, 1);
3310 return CMD_SUCCESS;
3311}
3312
3313DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3314 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3315 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3316 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3317{
3318 get_amr_th_from_arg(vty, 4, argv, 1);
3319 return CMD_SUCCESS;
3320}
3321
3322DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3323 "amr tch-f hysteresis (ms|bts) <0-15>",
3324 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3325 AMR_HY_HELP_STR)
3326{
3327 get_amr_hy_from_arg(vty, 2, argv, 1);
3328 return CMD_SUCCESS;
3329}
3330
3331DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3332 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3333 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3334 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3335{
3336 get_amr_hy_from_arg(vty, 3, argv, 1);
3337 return CMD_SUCCESS;
3338}
3339
3340DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3341 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3342 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3343 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3344{
3345 get_amr_hy_from_arg(vty, 4, argv, 1);
3346 return CMD_SUCCESS;
3347}
3348
3349DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3350 "amr tch-h modes" AMR_TCHH_PAR_STR,
3351 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3352 AMR_TCHH_HELP_STR)
3353{
3354 get_amr_from_arg(vty, 1, argv, 0);
3355 return CMD_SUCCESS;
3356}
3357
3358DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3359 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3360 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3361 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3362{
3363 get_amr_from_arg(vty, 2, argv, 0);
3364 return CMD_SUCCESS;
3365}
3366
3367DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3368 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3369 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3370 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3371{
3372 get_amr_from_arg(vty, 3, argv, 0);
3373 return CMD_SUCCESS;
3374}
3375
3376DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3377 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3378 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3379 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3380{
3381 get_amr_from_arg(vty, 4, argv, 0);
3382 return CMD_SUCCESS;
3383}
3384
3385DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3386 "amr tch-h start-mode (auto|1|2|3|4)",
3387 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3388{
3389 get_amr_start_from_arg(vty, argv, 0);
3390 return CMD_SUCCESS;
3391}
3392
3393DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3394 "amr tch-h threshold (ms|bts) <0-63>",
3395 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3396 AMR_TH_HELP_STR)
3397{
3398 get_amr_th_from_arg(vty, 2, argv, 0);
3399 return CMD_SUCCESS;
3400}
3401
3402DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3403 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3404 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3405 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3406{
3407 get_amr_th_from_arg(vty, 3, argv, 0);
3408 return CMD_SUCCESS;
3409}
3410
3411DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3412 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3413 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3414 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3415{
3416 get_amr_th_from_arg(vty, 4, argv, 0);
3417 return CMD_SUCCESS;
3418}
3419
3420DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3421 "amr tch-h hysteresis (ms|bts) <0-15>",
3422 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3423 AMR_HY_HELP_STR)
3424{
3425 get_amr_hy_from_arg(vty, 2, argv, 0);
3426 return CMD_SUCCESS;
3427}
3428
3429DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3430 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3431 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3432 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3433{
3434 get_amr_hy_from_arg(vty, 3, argv, 0);
3435 return CMD_SUCCESS;
3436}
3437
3438DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3439 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3440 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3441 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3442{
3443 get_amr_hy_from_arg(vty, 4, argv, 0);
3444 return CMD_SUCCESS;
3445}
3446
Harald Welte8f0ed552010-05-11 21:53:49 +02003447#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003448
Harald Welte5258fc42009-03-28 19:07:53 +00003449/* per TRX configuration */
3450DEFUN(cfg_trx,
3451 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003452 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003453 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003454 "Select a TRX to configure")
3455{
3456 int trx_nr = atoi(argv[0]);
3457 struct gsm_bts *bts = vty->index;
3458 struct gsm_bts_trx *trx;
3459
Harald Weltee441d9c2009-06-21 16:17:15 +02003460 if (trx_nr > bts->num_trx) {
3461 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3462 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003463 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003464 } else if (trx_nr == bts->num_trx) {
3465 /* we need to allocate a new one */
3466 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003467 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003468 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003469
Harald Weltee441d9c2009-06-21 16:17:15 +02003470 if (!trx)
3471 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003472
3473 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003474 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003475 vty->node = TRX_NODE;
3476
3477 return CMD_SUCCESS;
3478}
3479
3480DEFUN(cfg_trx_arfcn,
3481 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003482 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003483 "Set the ARFCN for this TRX\n"
3484 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003485{
3486 int arfcn = atoi(argv[0]);
3487 struct gsm_bts_trx *trx = vty->index;
3488
3489 /* FIXME: check if this ARFCN is supported by this TRX */
3490
3491 trx->arfcn = arfcn;
3492
3493 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3494 /* FIXME: use OML layer to update the ARFCN */
3495 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3496
3497 return CMD_SUCCESS;
3498}
3499
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003500DEFUN(cfg_trx_nominal_power,
3501 cfg_trx_nominal_power_cmd,
3502 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003503 "Nominal TRX RF Power in dBm\n"
3504 "Nominal TRX RF Power in dBm\n"
3505 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003506{
3507 struct gsm_bts_trx *trx = vty->index;
3508
3509 trx->nominal_power = atoi(argv[0]);
3510
3511 return CMD_SUCCESS;
3512}
3513
Harald Weltefcd24452009-06-20 18:15:19 +02003514DEFUN(cfg_trx_max_power_red,
3515 cfg_trx_max_power_red_cmd,
3516 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003517 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003518 "Reduction of maximum BS RF Power in dB\n")
3519{
3520 int maxpwr_r = atoi(argv[0]);
3521 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003522 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003523
3524 /* FIXME: check if our BTS type supports more than 12 */
3525 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3526 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3527 maxpwr_r, VTY_NEWLINE);
3528 return CMD_WARNING;
3529 }
3530 if (maxpwr_r & 1) {
3531 vty_out(vty, "%% Power %d dB is not an even value%s",
3532 maxpwr_r, VTY_NEWLINE);
3533 return CMD_WARNING;
3534 }
3535
3536 trx->max_power_red = maxpwr_r;
3537
3538 /* FIXME: make sure we update this using OML */
3539
3540 return CMD_SUCCESS;
3541}
3542
Harald Welte42581822009-08-08 16:12:58 +02003543DEFUN(cfg_trx_rsl_e1,
3544 cfg_trx_rsl_e1_cmd,
3545 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003546 "RSL Parameters\n"
3547 "E1/T1 interface to be used for RSL\n"
3548 "E1/T1 interface to be used for RSL\n"
3549 "E1/T1 Line Number to be used for RSL\n"
3550 "E1/T1 Timeslot to be used for RSL\n"
3551 "E1/T1 Timeslot to be used for RSL\n"
3552 "E1/T1 Sub-slot to be used for RSL\n"
3553 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3554 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3555 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3556 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3557 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003558{
3559 struct gsm_bts_trx *trx = vty->index;
3560
3561 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3562
3563 return CMD_SUCCESS;
3564}
3565
3566DEFUN(cfg_trx_rsl_e1_tei,
3567 cfg_trx_rsl_e1_tei_cmd,
3568 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003569 "RSL Parameters\n"
3570 "Set the TEI to be used for RSL\n"
3571 "Set the TEI to be used for RSL\n"
3572 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003573{
3574 struct gsm_bts_trx *trx = vty->index;
3575
3576 trx->rsl_tei = atoi(argv[0]);
3577
3578 return CMD_SUCCESS;
3579}
3580
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003581DEFUN(cfg_trx_rf_locked,
3582 cfg_trx_rf_locked_cmd,
3583 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003584 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3585 "TRX is NOT RF locked (active)\n"
3586 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003587{
3588 int locked = atoi(argv[0]);
3589 struct gsm_bts_trx *trx = vty->index;
3590
Maxbe356ed2017-09-07 19:10:09 +02003591 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003592 return CMD_SUCCESS;
3593}
Harald Welte42581822009-08-08 16:12:58 +02003594
Harald Welte5258fc42009-03-28 19:07:53 +00003595/* per TS configuration */
3596DEFUN(cfg_ts,
3597 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003598 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003599 "Select a Timeslot to configure\n"
3600 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003601{
3602 int ts_nr = atoi(argv[0]);
3603 struct gsm_bts_trx *trx = vty->index;
3604 struct gsm_bts_trx_ts *ts;
3605
3606 if (ts_nr >= TRX_NR_TS) {
3607 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3608 TRX_NR_TS, VTY_NEWLINE);
3609 return CMD_WARNING;
3610 }
3611
3612 ts = &trx->ts[ts_nr];
3613
3614 vty->index = ts;
3615 vty->node = TS_NODE;
3616
3617 return CMD_SUCCESS;
3618}
3619
Harald Weltea6fd58e2009-08-07 00:25:23 +02003620DEFUN(cfg_ts_pchan,
3621 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003622 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003623 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003624{
3625 struct gsm_bts_trx_ts *ts = vty->index;
3626 int pchanc;
3627
3628 pchanc = gsm_pchan_parse(argv[0]);
3629 if (pchanc < 0)
3630 return CMD_WARNING;
3631
3632 ts->pchan = pchanc;
3633
3634 return CMD_SUCCESS;
3635}
3636
3637/* used for backwards compatibility with old config files that still
3638 * have uppercase pchan type names */
3639DEFUN_HIDDEN(cfg_ts_pchan_compat,
3640 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003641 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003642 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003643{
3644 struct gsm_bts_trx_ts *ts = vty->index;
3645 int pchanc;
3646
3647 pchanc = gsm_pchan_parse(argv[0]);
3648 if (pchanc < 0)
3649 return CMD_WARNING;
3650
3651 ts->pchan = pchanc;
3652
3653 return CMD_SUCCESS;
3654}
3655
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003656
3657
Harald Welte135a6482011-05-30 12:09:13 +02003658DEFUN(cfg_ts_tsc,
3659 cfg_ts_tsc_cmd,
3660 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003661 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003662{
3663 struct gsm_bts_trx_ts *ts = vty->index;
3664
Max71d082b2017-05-30 15:03:38 +02003665 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003666 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3667 "falling back to BCC%s", VTY_NEWLINE);
3668 ts->tsc = -1;
3669 return CMD_WARNING;
3670 }
3671
Harald Welte135a6482011-05-30 12:09:13 +02003672 ts->tsc = atoi(argv[0]);
3673
3674 return CMD_SUCCESS;
3675}
3676
Harald Weltea39b0f22010-06-14 22:26:10 +02003677#define HOPPING_STR "Configure frequency hopping\n"
3678
3679DEFUN(cfg_ts_hopping,
3680 cfg_ts_hopping_cmd,
3681 "hopping enabled (0|1)",
3682 HOPPING_STR "Enable or disable frequency hopping\n"
3683 "Disable frequency hopping\n" "Enable frequency hopping\n")
3684{
3685 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003686 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003687
Max71d082b2017-05-30 15:03:38 +02003688 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003689 vty_out(vty, "BTS model does not support hopping%s",
3690 VTY_NEWLINE);
3691 return CMD_WARNING;
3692 }
3693
3694 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003695
3696 return CMD_SUCCESS;
3697}
3698
Harald Welte6e0cd042009-09-12 13:05:33 +02003699DEFUN(cfg_ts_hsn,
3700 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003701 "hopping sequence-number <0-63>",
3702 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003703 "Which hopping sequence to use for this channel\n"
3704 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003705{
3706 struct gsm_bts_trx_ts *ts = vty->index;
3707
3708 ts->hopping.hsn = atoi(argv[0]);
3709
3710 return CMD_SUCCESS;
3711}
3712
3713DEFUN(cfg_ts_maio,
3714 cfg_ts_maio_cmd,
3715 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003716 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003717 "Which hopping MAIO to use for this channel\n"
3718 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003719{
3720 struct gsm_bts_trx_ts *ts = vty->index;
3721
3722 ts->hopping.maio = atoi(argv[0]);
3723
3724 return CMD_SUCCESS;
3725}
3726
3727DEFUN(cfg_ts_arfcn_add,
3728 cfg_ts_arfcn_add_cmd,
3729 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003730 HOPPING_STR "Configure hopping ARFCN list\n"
3731 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003732{
3733 struct gsm_bts_trx_ts *ts = vty->index;
3734 int arfcn = atoi(argv[0]);
3735
Harald Weltea39b0f22010-06-14 22:26:10 +02003736 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3737
Harald Welte6e0cd042009-09-12 13:05:33 +02003738 return CMD_SUCCESS;
3739}
3740
3741DEFUN(cfg_ts_arfcn_del,
3742 cfg_ts_arfcn_del_cmd,
3743 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003744 HOPPING_STR "Configure hopping ARFCN list\n"
3745 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003746{
3747 struct gsm_bts_trx_ts *ts = vty->index;
3748 int arfcn = atoi(argv[0]);
3749
Harald Weltea39b0f22010-06-14 22:26:10 +02003750 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3751
Harald Welte6e0cd042009-09-12 13:05:33 +02003752 return CMD_SUCCESS;
3753}
3754
Harald Weltea6fd58e2009-08-07 00:25:23 +02003755DEFUN(cfg_ts_e1_subslot,
3756 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003757 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003758 "E1/T1 channel connected to this on-air timeslot\n"
3759 "E1/T1 channel connected to this on-air timeslot\n"
3760 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003761 "E1/T1 timeslot connected to this on-air timeslot\n"
3762 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003763 "E1/T1 sub-slot connected to this on-air timeslot\n"
3764 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3765 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3766 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3767 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3768 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003769{
3770 struct gsm_bts_trx_ts *ts = vty->index;
3771
Harald Welte42581822009-08-08 16:12:58 +02003772 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003773
3774 return CMD_SUCCESS;
3775}
Harald Welte5258fc42009-03-28 19:07:53 +00003776
Harald Welte4f10c252010-05-16 21:47:13 +02003777void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3778{
Harald Weltecf9d4312017-12-13 23:17:16 +01003779 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003780 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003781 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003782 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003783}
3784
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003785DEFUN(drop_bts,
3786 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003787 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003788 "Debug/Simulation command to drop Abis/IP BTS\n"
3789 "Debug/Simulation command to drop Abis/IP BTS\n"
3790 "Debug/Simulation command to drop Abis/IP BTS\n"
3791 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003792{
3793 struct gsm_network *gsmnet;
3794 struct gsm_bts_trx *trx;
3795 struct gsm_bts *bts;
3796 unsigned int bts_nr;
3797
3798 gsmnet = gsmnet_from_vty(vty);
3799
3800 bts_nr = atoi(argv[0]);
3801 if (bts_nr >= gsmnet->num_bts) {
3802 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3803 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3804 return CMD_WARNING;
3805 }
3806
3807 bts = gsm_bts_num(gsmnet, bts_nr);
3808 if (!bts) {
3809 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3810 return CMD_WARNING;
3811 }
3812
3813 if (!is_ipaccess_bts(bts)) {
3814 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3815 return CMD_WARNING;
3816 }
3817
3818
3819 /* close all connections */
3820 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003821 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003822 } else if (strcmp(argv[1], "rsl") == 0) {
3823 /* close all rsl connections */
3824 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003825 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003826 }
3827 } else {
3828 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3829 return CMD_WARNING;
3830 }
3831
3832 return CMD_SUCCESS;
3833}
3834
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003835DEFUN(restart_bts, restart_bts_cmd,
3836 "restart-bts <0-65535>",
3837 "Restart ip.access nanoBTS through OML\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003838 BTS_NR_STR)
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003839{
3840 struct gsm_network *gsmnet;
3841 struct gsm_bts_trx *trx;
3842 struct gsm_bts *bts;
3843 unsigned int bts_nr;
3844
3845 gsmnet = gsmnet_from_vty(vty);
3846
3847 bts_nr = atoi(argv[0]);
3848 if (bts_nr >= gsmnet->num_bts) {
3849 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3850 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3851 return CMD_WARNING;
3852 }
3853
3854 bts = gsm_bts_num(gsmnet, bts_nr);
3855 if (!bts) {
3856 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3857 return CMD_WARNING;
3858 }
3859
3860 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3861 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3862 VTY_NEWLINE);
3863 return CMD_WARNING;
3864 }
3865
3866 /* go from last TRX to c0 */
3867 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3868 abis_nm_ipaccess_restart(trx);
3869
3870 return CMD_SUCCESS;
3871}
3872
Harald Welte8e2e22f2017-07-10 20:25:10 +02003873DEFUN(bts_resend, bts_resend_cmd,
3874 "bts <0-255> resend-system-information",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003875 "BTS Specific Commands\n" BTS_NR_STR
Harald Welte8e2e22f2017-07-10 20:25:10 +02003876 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3877{
3878 struct gsm_network *gsmnet;
3879 struct gsm_bts_trx *trx;
3880 struct gsm_bts *bts;
3881 unsigned int bts_nr;
3882
3883 gsmnet = gsmnet_from_vty(vty);
3884
3885 bts_nr = atoi(argv[0]);
3886 if (bts_nr >= gsmnet->num_bts) {
3887 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3888 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3889 return CMD_WARNING;
3890 }
3891
3892 bts = gsm_bts_num(gsmnet, bts_nr);
3893 if (!bts) {
3894 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3895 return CMD_WARNING;
3896 }
3897
3898 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3899 gsm_bts_trx_set_system_infos(trx);
3900
3901 return CMD_SUCCESS;
3902}
3903
3904
Harald Welte30f1f372014-12-28 15:00:45 +01003905DEFUN(smscb_cmd, smscb_cmd_cmd,
3906 "bts <0-255> smscb-command <1-4> HEXSTRING",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003907 "BTS related commands\n" BTS_NR_STR
Harald Welte30f1f372014-12-28 15:00:45 +01003908 "SMS Cell Broadcast\n" "Last Valid Block\n"
3909 "Hex Encoded SMSCB message (up to 88 octets)\n")
3910{
3911 struct gsm_bts *bts;
3912 int bts_nr = atoi(argv[0]);
3913 int last_block = atoi(argv[1]);
3914 struct rsl_ie_cb_cmd_type cb_cmd;
3915 uint8_t buf[88];
3916 int rc;
3917
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02003918 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01003919 if (!bts) {
3920 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3921 return CMD_WARNING;
3922 }
3923 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
3924 if (rc < 0 || rc > sizeof(buf)) {
3925 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3926 return CMD_WARNING;
3927 }
3928
3929 cb_cmd.spare = 0;
3930 cb_cmd.def_bcast = 0;
3931 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
3932
3933 switch (last_block) {
3934 case 1:
3935 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
3936 break;
3937 case 2:
3938 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
3939 break;
3940 case 3:
3941 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
3942 break;
3943 case 4:
3944 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
3945 break;
3946 }
3947
3948 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
3949
3950 return CMD_SUCCESS;
3951}
3952
Harald Welte7fe00fb2017-05-27 14:09:50 +02003953/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02003954static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
3955 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02003956{
Harald Welte645eb622017-05-27 15:52:58 +02003957 int bts_nr = atoi(bts_str);
3958 int trx_nr = atoi(trx_str);
3959 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003960 struct gsm_bts *bts;
3961 struct gsm_bts_trx *trx;
3962 struct gsm_bts_trx_ts *ts;
3963
3964 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
3965 if (!bts) {
3966 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3967 return NULL;
3968 }
3969
3970 trx = gsm_bts_trx_num(bts, trx_nr);
3971 if (!trx) {
3972 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
3973 return NULL;
3974 }
3975
3976 ts = &trx->ts[ts_nr];
3977
3978 return ts;
3979}
Harald Welte30f1f372014-12-28 15:00:45 +01003980
Harald Welted0d2b0b2010-12-23 13:18:07 +01003981DEFUN(pdch_act, pdch_act_cmd,
3982 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003983 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
3984 "TRX Timeslot\n" TS_NR_STR "Packet Data Channel\n"
Harald Welted0d2b0b2010-12-23 13:18:07 +01003985 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
3986 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
3987{
Harald Welted0d2b0b2010-12-23 13:18:07 +01003988 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01003989 int activate;
3990
Harald Welte645eb622017-05-27 15:52:58 +02003991 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003992 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01003993 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01003994
Harald Welte7fe00fb2017-05-27 14:09:50 +02003995 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01003996 vty_out(vty, "%% This command only works for ipaccess BTS%s",
3997 VTY_NEWLINE);
3998 return CMD_WARNING;
3999 }
4000
Harald Welted0d2b0b2010-12-23 13:18:07 +01004001 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4002 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004003 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004004 return CMD_WARNING;
4005 }
4006
4007 if (!strcmp(argv[3], "activate"))
4008 activate = 1;
4009 else
4010 activate = 0;
4011
4012 rsl_ipacc_pdch_activate(ts, activate);
4013
4014 return CMD_SUCCESS;
4015
4016}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004017
Harald Welte2abd5e12017-05-27 14:10:40 +02004018/* determine the logical channel type based on the physical channel type */
4019static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4020{
4021 switch (pchan) {
4022 case GSM_PCHAN_TCH_F:
4023 return GSM_LCHAN_TCH_F;
4024 case GSM_PCHAN_TCH_H:
4025 return GSM_LCHAN_TCH_H;
4026 case GSM_PCHAN_SDCCH8_SACCH8C:
4027 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4028 case GSM_PCHAN_CCCH_SDCCH4:
4029 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4030 return GSM_LCHAN_SDCCH;
4031 default:
4032 return -1;
4033 }
4034}
4035
4036/* configure the lchan for a single AMR mode (as specified) */
4037static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4038{
4039 struct amr_multirate_conf mr;
4040 struct gsm48_multi_rate_conf *mr_conf;
4041 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4042
4043 if (amr_mode > 7)
4044 return -1;
4045
4046 memset(&mr, 0, sizeof(mr));
4047 mr_conf->ver = 1;
4048 /* bit-mask of supported modes, only one bit is set. Reflects
4049 * Figure 10.5.2.47a where there are no thershold and only a
4050 * single mode */
4051 mr.gsm48_ie[1] = 1 << amr_mode;
4052
4053 mr.ms_mode[0].mode = amr_mode;
4054 mr.bts_mode[0].mode = amr_mode;
4055
4056 /* encode this configuration into the lchan for both uplink and
4057 * downlink direction */
4058 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4059 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4060
4061 return 0;
4062}
4063
4064/* Debug/Measurement command to activate a given logical channel
4065 * manually in a given mode/codec. This is useful for receiver
4066 * performance testing (FER/RBER/...) */
4067DEFUN(lchan_act, lchan_act_cmd,
4068 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004069 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4070 "TRX Timeslot\n" TS_NR_STR "Sub-Slot Number\n" LCHAN_NR_STR
Harald Welte2abd5e12017-05-27 14:10:40 +02004071 "Manual Channel Activation (e.g. for BER test)\n"
4072 "Manual Channel Deactivation (e.g. for BER test)\n"
4073 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4074{
4075 struct gsm_bts_trx_ts *ts;
4076 struct gsm_lchan *lchan;
4077 int ss_nr = atoi(argv[3]);
4078 const char *act_str = argv[4];
4079 const char *codec_str = argv[5];
4080 int activate;
4081
4082 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4083 if (!ts)
4084 return CMD_WARNING;
4085
4086 lchan = &ts->lchan[ss_nr];
4087
4088 if (!strcmp(act_str, "activate"))
4089 activate = 1;
4090 else
4091 activate = 0;
4092
4093 if (ss_nr >= ts_subslots(ts)) {
4094 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4095 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4096 return CMD_WARNING;
4097 }
4098
4099 if (activate) {
4100 int lchan_t;
4101 if (lchan->state != LCHAN_S_NONE) {
4102 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4103 return CMD_WARNING;
4104 }
4105 lchan_t = lchan_type_by_pchan(ts->pchan);
4106 if (lchan_t < 0)
4107 return CMD_WARNING;
4108 /* configure the lchan */
4109 lchan->type = lchan_t;
4110 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4111 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4112 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4113 else if (!strcmp(codec_str, "efr"))
4114 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4115 else if (!strcmp(codec_str, "amr")) {
4116 int amr_mode;
4117 if (argc < 7) {
4118 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4119 return CMD_WARNING;
4120 }
4121 amr_mode = atoi(argv[6]);
4122 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4123 lchan_set_single_amr_mode(lchan, amr_mode);
4124 }
4125 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4126 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4127 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004128 } else {
4129 rsl_direct_rf_release(lchan);
4130 }
4131
4132 return CMD_SUCCESS;
4133}
4134
Harald Welte3f86c522017-05-27 15:53:28 +02004135DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4136 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004137 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4138 "TRX Timeslot\n" TS_NR_STR "Sub-Slot\n" LCHAN_NR_STR
Harald Welte3f86c522017-05-27 15:53:28 +02004139 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4140{
4141 struct gsm_bts_trx_ts *ts;
4142 struct gsm_lchan *lchan;
4143 int ss_nr = atoi(argv[3]);
4144 int port = atoi(argv[5]);
4145 struct in_addr ia;
4146 inet_aton(argv[4], &ia);
4147
4148 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4149 if (!ts)
4150 return CMD_WARNING;
4151
4152 lchan = &ts->lchan[ss_nr];
4153
4154 if (ss_nr >= ts_subslots(ts)) {
4155 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4156 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4157 return CMD_WARNING;
4158 }
4159
4160 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4161 inet_ntoa(ia), port, VTY_NEWLINE);
4162 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4163 return CMD_SUCCESS;
4164}
Harald Welteb71147a2017-07-18 19:11:49 +02004165
4166DEFUN(ctrl_trap, ctrl_trap_cmd,
4167 "ctrl-interface generate-trap TRAP VALUE",
4168 "Commands related to the CTRL Interface\n"
4169 "Generate a TRAP for test purpose\n"
4170 "Identity/Name of the TRAP variable\n"
4171 "Value of the TRAP variable\n")
4172{
4173 struct gsm_network *net = gsmnet_from_vty(vty);
4174
4175 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4176 return CMD_SUCCESS;
4177}
4178
Harald Weltedcccb182010-05-16 20:52:23 +02004179extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004180
Maxdb0e3802017-01-12 19:35:11 +01004181int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004182{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004183 cfg_ts_pchan_cmd.string =
4184 vty_cmd_string_from_valstr(tall_bsc_ctx,
4185 gsm_pchant_names,
4186 "phys_chan_config (", "|", ")",
4187 VTY_DO_LOWER);
4188 cfg_ts_pchan_cmd.doc =
4189 vty_cmd_string_from_valstr(tall_bsc_ctx,
4190 gsm_pchant_descs,
4191 "Physical Channel Combination\n",
4192 "\n", "", 0);
4193
Harald Weltee555c2b2012-08-17 13:02:12 +02004194 cfg_bts_type_cmd.string =
4195 vty_cmd_string_from_valstr(tall_bsc_ctx,
4196 bts_type_names,
4197 "type (", "|", ")",
4198 VTY_DO_LOWER);
4199 cfg_bts_type_cmd.doc =
4200 vty_cmd_string_from_valstr(tall_bsc_ctx,
4201 bts_type_descs,
4202 "BTS Vendor/Type\n",
4203 "\n", "", 0);
4204
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +02004205 common_cs_vty_init(network, config_write_net);
Harald Weltee555c2b2012-08-17 13:02:12 +02004206
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004207 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004208 install_element_ve(&show_bts_cmd);
4209 install_element_ve(&show_trx_cmd);
4210 install_element_ve(&show_ts_cmd);
4211 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004212 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004213
Philipp Maier39f62bb2017-04-09 12:32:51 +02004214 install_element_ve(&show_subscr_conn_cmd);
4215 install_element_ve(&handover_subscr_conn_cmd);
4216
Harald Welteb4d5b172010-05-12 16:10:35 +00004217 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004218 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004219
Maxdb0e3802017-01-12 19:35:11 +01004220 logging_vty_add_cmds(NULL);
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004221
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004222 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Weltebc814502009-12-19 21:41:52 +01004223 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Welteb720bd32009-12-21 16:51:50 +01004224 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
4225 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
4226 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
4227 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
4228 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
4229 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004230 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004231 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4232 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4233 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4234 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4235 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4236 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4237 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4238 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4239 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004240 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004241 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004242 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004243 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02004244
4245 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004246 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004247 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004248 install_element(BTS_NODE, &cfg_description_cmd);
4249 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004250 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004251 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004252 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4253 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4254 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4255 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004256 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4257 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004258 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004259 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004260 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004261 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004262 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004263 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004264 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004265 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4266 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004267 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004268 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4269 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004270 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4271 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4272 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004273 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4274 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004275 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004276 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004277 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004278 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004279 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4280 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004281 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4282 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4283 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4284 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4285 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4286 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004287 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004288 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004289 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304290 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004291 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004292 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004293 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004294 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4295 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004296 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004297 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004298 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004299 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004300 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4301 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4302 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004303 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004304 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4305 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004306 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004307 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004308 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4309 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004310 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004311 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4312 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004313 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4314 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004315 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4316 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004317 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4318 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004319 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4320 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4321 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4322 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4323 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004324 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4325 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004326 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4327 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4328 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4329 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4330 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4331 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4332 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4333 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4334 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4335 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4336 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4337 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4338 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4339 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4340 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4341 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4342 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4343 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4344 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4345 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4346 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4347 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004348 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004349
Harald Welte5258fc42009-03-28 19:07:53 +00004350 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004351 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004352 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004353 install_element(TRX_NODE, &cfg_description_cmd);
4354 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004355 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004356 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004357 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4358 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004359 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004360
Harald Welte5258fc42009-03-28 19:07:53 +00004361 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004362 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004363 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004364 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004365 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004366 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004367 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4368 install_element(TS_NODE, &cfg_ts_maio_cmd);
4369 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4370 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004371 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004372
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004373 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004374 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004375 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004376 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004377 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004378 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004379 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004380 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004381
Harald Welte81c9b9c2010-05-31 16:40:40 +02004382 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004383 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004384 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004385 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004386
Harald Weltedcccb182010-05-16 20:52:23 +02004387 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004388
Harald Welte68628e82009-03-10 12:17:57 +00004389 return 0;
4390}