blob: d55c6eb30ab522571caf67d68be11549677ccd6d [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>
Harald Welte68628e82009-03-10 12:17:57 +000023
Harald Welte4b037e42010-05-19 19:45:32 +020024#include <osmocom/vty/command.h>
25#include <osmocom/vty/buffer.h>
26#include <osmocom/vty/vty.h>
27#include <osmocom/vty/logging.h>
Jacob Erlbeck64630cc2015-10-26 16:25:37 +010028#include <osmocom/vty/stats.h>
Harald Welte4b037e42010-05-19 19:45:32 +020029#include <osmocom/vty/telnet_interface.h>
Harald Welte4ab9d7c2012-08-17 12:42:06 +020030#include <osmocom/vty/misc.h>
Maxc08ee712016-05-11 12:45:13 +020031#include <osmocom/gsm/protocol/gsm_04_08.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010032#include <osmocom/gsm/gsm0502.h>
Harald Welte3fb8a7b2017-07-18 19:11:49 +020033#include <osmocom/ctrl/control_if.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010034
Harald Welte68628e82009-03-10 12:17:57 +000035#include <arpa/inet.h>
36
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010037#include <osmocom/core/linuxlist.h>
Harald Welte68628e82009-03-10 12:17:57 +000038#include <openbsc/gsm_data.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020039#include <osmocom/abis/e1_input.h>
Harald Welte1bc77352009-03-10 19:47:51 +000040#include <openbsc/abis_nm.h>
Harald Welte4d54d0b2011-02-19 16:48:17 +010041#include <openbsc/abis_om2000.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010042#include <osmocom/core/utils.h>
43#include <osmocom/gsm/gsm_utils.h>
Harald Weltecdc59ff2011-05-23 20:42:26 +020044#include <osmocom/gsm/abis_nm.h>
Harald Welteb908cb72009-12-22 13:09:29 +010045#include <openbsc/chan_alloc.h>
Harald Welte8387a492009-12-22 21:43:14 +010046#include <openbsc/meas_rep.h>
Harald Welte40f82892009-05-23 17:31:39 +000047#include <openbsc/db.h>
Holger Hans Peter Freyther3c712322010-04-06 11:55:37 +020048#include <openbsc/vty.h>
Harald Welteea34a4e2012-06-16 14:59:56 +080049#include <osmocom/gprs/gprs_ns.h>
Harald Welte9fbff4a2010-07-30 11:50:09 +020050#include <openbsc/system_information.h>
Harald Welte5bc61dc2010-05-16 22:02:16 +020051#include <openbsc/debug.h>
Holger Hans Peter Freyther85334f12010-11-09 17:00:42 +010052#include <openbsc/paging.h>
Harald Weltef7a2b192011-08-20 18:25:02 +020053#include <openbsc/ipaccess.h>
Harald Welted0d2b0b2010-12-23 13:18:07 +010054#include <openbsc/abis_rsl.h>
Neels Hofmeyra42855f2017-02-23 21:49:55 +010055#include <openbsc/bsc_msc_data.h>
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +010056#include <openbsc/osmo_bsc_rf.h>
Harald Welte8254cf72017-05-29 13:42:19 +020057#include <openbsc/pcu_if.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020058#include <openbsc/common_cs.h>
Harald Welte7b423ed2016-06-19 18:06:02 +020059#include <openbsc/vlr.h>
Philipp Maier4b60d072017-04-09 12:32:51 +020060#include <openbsc/handover.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020061
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010062#include <inttypes.h>
63
Harald Weltec08e8be2011-03-04 13:53:51 +010064#include "../../bscconfig.h"
Harald Welte1353f962010-05-16 19:20:24 +020065
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020066
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020067#define LCHAN_NR_STR "Logical Channel Number\n"
68
69
Harald Welteea4647d2010-05-12 17:19:53 +000070/* FIXME: this should go to some common file */
71static const struct value_string gprs_ns_timer_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020072 { 0, "tns-block" },
73 { 1, "tns-block-retries" },
74 { 2, "tns-reset" },
75 { 3, "tns-reset-retries" },
76 { 4, "tns-test" },
77 { 5, "tns-alive" },
78 { 6, "tns-alive-retries" },
79 { 0, NULL }
80};
81
Harald Welteea4647d2010-05-12 17:19:53 +000082static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020083 { 0, "blocking-timer" },
84 { 1, "blocking-retries" },
85 { 2, "unblocking-retries" },
86 { 3, "reset-timer" },
87 { 4, "reset-retries" },
88 { 5, "suspend-timer" },
89 { 6, "suspend-retries" },
90 { 7, "resume-timer" },
91 { 8, "resume-retries" },
92 { 9, "capability-update-timer" },
93 { 10, "capability-update-retries" },
94 { 0, NULL }
95};
96
Harald Welte64c07d22011-02-15 11:43:27 +010097static const struct value_string bts_neigh_mode_strs[] = {
98 { NL_MODE_AUTOMATIC, "automatic" },
99 { NL_MODE_MANUAL, "manual" },
100 { NL_MODE_MANUAL_SI5SEP, "manual-si5" },
101 { 0, NULL }
102};
103
Daniel Willmann7d109832012-05-14 18:43:23 +0200104const struct value_string bts_loc_fix_names[] = {
105 { BTS_LOC_FIX_INVALID, "invalid" },
106 { BTS_LOC_FIX_2D, "fix2d" },
107 { BTS_LOC_FIX_3D, "fix3d" },
108 { 0, NULL }
109};
110
Harald Welte68628e82009-03-10 12:17:57 +0000111struct cmd_node bts_node = {
112 BTS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200113 "%s(config-net-bts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000114 1,
115};
116
117struct cmd_node trx_node = {
118 TRX_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200119 "%s(config-net-bts-trx)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000120 1,
121};
122
123struct cmd_node ts_node = {
124 TS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200125 "%s(config-net-bts-trx-ts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000126 1,
127};
128
129static int dummy_config_write(struct vty *v)
130{
131 return CMD_SUCCESS;
132}
133
134static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
135{
Harald Welte1304b352013-03-15 16:57:33 +0100136 vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
137 abis_nm_opstate_name(nms->operational),
138 get_value_string(abis_nm_adm_state_names, nms->administrative),
Harald Welte867d9f32011-05-23 20:30:39 +0200139 abis_nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000140}
141
Harald Welteb908cb72009-12-22 13:09:29 +0100142static void dump_pchan_load_vty(struct vty *vty, char *prefix,
143 const struct pchan_load *pl)
144{
145 int i;
146
147 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
148 const struct load_counter *lc = &pl->pchan[i];
149 unsigned int percent;
150
151 if (lc->total == 0)
152 continue;
153
154 percent = (lc->used * 100) / lc->total;
155
156 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
157 gsm_pchan_name(i), percent, lc->used, lc->total,
158 VTY_NEWLINE);
159 }
160}
161
Harald Welte68628e82009-03-10 12:17:57 +0000162static void net_dump_vty(struct vty *vty, struct gsm_network *net)
163{
Harald Welteb908cb72009-12-22 13:09:29 +0100164 struct pchan_load pl;
165
Harald Welteef235b52009-03-10 12:34:02 +0000166 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
167 "and has %u BTS%s", net->country_code, net->network_code,
168 net->num_bts, VTY_NEWLINE);
Harald Welte1bc77352009-03-10 19:47:51 +0000169 vty_out(vty, " Long network name: '%s'%s",
Harald Welte68628e82009-03-10 12:17:57 +0000170 net->name_long, VTY_NEWLINE);
Harald Welte1bc77352009-03-10 19:47:51 +0000171 vty_out(vty, " Short network name: '%s'%s",
Harald Welte68628e82009-03-10 12:17:57 +0000172 net->name_short, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200173 vty_out(vty, " Authentication policy: %s",
174 gsm_auth_policy_name(net->auth_policy));
175 if (net->authorized_reg_str)
176 vty_out(vty, ", authorized regexp: %s", net->authorized_reg_str);
177 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte1085c092009-11-18 20:33:19 +0100178 vty_out(vty, " Location updating reject cause: %u%s",
179 net->reject_cause, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900180 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
181 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100182 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
183 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800184 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
185 VTY_NEWLINE);
Harald Welteeab84a12009-12-13 10:53:12 +0100186 vty_out(vty, " RRLP Mode: %s%s", rrlp_mode_name(net->rrlp.mode),
187 VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100188 vty_out(vty, " MM Info: %s%s", net->send_mm_info ? "On" : "Off",
189 VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100190 vty_out(vty, " Handover: %s%s", net->handover.active ? "On" : "Off",
191 VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100192 network_chan_load(&pl, net);
193 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
194 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100195
196 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100197 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100198 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200199 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100200 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100201 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200202 vty_out(vty, " Last RF Lock Command: %s%s",
203 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
204 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000205}
206
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200207DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000208 SHOW_STR "Display information about a GSM NETWORK\n")
209{
Harald Weltedcccb182010-05-16 20:52:23 +0200210 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000211 net_dump_vty(vty, net);
212
213 return CMD_SUCCESS;
214}
215
216static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
217{
Harald Welteedb37782009-05-01 14:59:07 +0000218 struct e1inp_line *line;
219
220 if (!e1l) {
221 vty_out(vty, " None%s", VTY_NEWLINE);
222 return;
223 }
224
225 line = e1l->ts->line;
226
227 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
228 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000229 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000230 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000231 e1l->tei, e1l->sapi, VTY_NEWLINE);
232}
233
234static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
235{
Harald Welteb908cb72009-12-22 13:09:29 +0100236 struct pchan_load pl;
237
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200238 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100239 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200240 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200241 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100242 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100243 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200244 bts->num_trx, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200245 vty_out(vty, "Description: %s%s",
246 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Maxf9685c12017-03-23 12:01:07 +0100247 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
248 vty_out(vty, "PCU version %s connected%s", bts->pcu_version,
249 VTY_NEWLINE);
Harald Welte1d8dbc42009-12-12 15:38:16 +0100250 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100251 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100252 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
253 VTY_NEWLINE);
254 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100255 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100256 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
257 VTY_NEWLINE);
258 vty_out(vty, "RACH Max transmissions: %u%s",
259 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
260 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100261 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200262 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200263 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
264 vty_out(vty, "Uplink DTX: %s%s",
265 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
266 "enabled" : "forced", VTY_NEWLINE);
267 else
268 vty_out(vty, "Uplink DTX: not enabled%s", VTY_NEWLINE);
269 vty_out(vty, "Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
270 VTY_NEWLINE);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200271 vty_out(vty, "Channel Description Attachment: %s%s",
272 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
273 vty_out(vty, "Channel Description BS-PA-MFRMS: %u%s",
274 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
275 vty_out(vty, "Channel Description BS-AG_BLKS-RES: %u%s",
276 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200277 vty_out(vty, "System Information present: 0x%08x, static: 0x%08x%s",
278 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Harald Welte42def722017-01-13 00:10:32 +0100279 vty_out(vty, "Early Classmark Sending: %s%s",
280 bts->early_classmark_allowed ? "allowed" : "forbidden",
281 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200282 if (bts->pcu_sock_path)
283 vty_out(vty, "PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000284 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200285 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000286 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200287 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200288 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
289 vty_out(vty, " Skip Reset: %d%s",
290 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000291 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200292 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000293 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200294 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200295 vty_out(vty, " GPRS NSE: ");
296 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
297 vty_out(vty, " GPRS CELL: ");
298 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
299 vty_out(vty, " GPRS NSVC0: ");
300 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
301 vty_out(vty, " GPRS NSVC1: ");
302 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200303 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
304 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000305 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100306 if (is_ipaccess_bts(bts)) {
307 vty_out(vty, " OML Link state: %s.%s",
308 bts->oml_link ? "connected" : "disconnected", VTY_NEWLINE);
309 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200310 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
311 e1isl_dump_vty(vty, bts->oml_link);
312 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100313
314 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100315 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200316 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100317 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
318 dump_pchan_load_vty(vty, " ", &pl);
Harald Welte68628e82009-03-10 12:17:57 +0000319}
320
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100321DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000322 SHOW_STR "Display information about a BTS\n"
323 "BTS number")
324{
Harald Weltedcccb182010-05-16 20:52:23 +0200325 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000326 int bts_nr;
327
328 if (argc != 0) {
329 /* use the BTS number that the user has specified */
330 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100331 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000332 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000333 VTY_NEWLINE);
334 return CMD_WARNING;
335 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200336 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000337 return CMD_SUCCESS;
338 }
339 /* print all BTS's */
340 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200341 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000342
343 return CMD_SUCCESS;
344}
345
Harald Welte42581822009-08-08 16:12:58 +0200346/* utility functions */
347static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
348 const char *ts, const char *ss)
349{
350 e1_link->e1_nr = atoi(line);
351 e1_link->e1_ts = atoi(ts);
352 if (!strcmp(ss, "full"))
353 e1_link->e1_ts_ss = 255;
354 else
355 e1_link->e1_ts_ss = atoi(ss);
356}
357
358static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
359 const char *prefix)
360{
361 if (!e1_link->e1_ts)
362 return;
363
364 if (e1_link->e1_ts_ss == 255)
365 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
366 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
367 else
368 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
369 prefix, e1_link->e1_nr, e1_link->e1_ts,
370 e1_link->e1_ts_ss, VTY_NEWLINE);
371}
372
373
Harald Welte67ce0732009-08-06 19:06:46 +0200374static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
375{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100376 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100377 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100378 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200379 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100380 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200381 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100382 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200383 ts->hopping.enabled, VTY_NEWLINE);
384 if (ts->hopping.enabled) {
385 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100386 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200387 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100388 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200389 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200390 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
391 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
392 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100393 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200394 i, VTY_NEWLINE);
395 }
Harald Welte127af342010-12-24 12:07:07 +0100396 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100397 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100398
399 if (ts->trx->bts->model->config_write_ts)
400 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200401}
402
403static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
404{
405 int i;
406
Harald Welte5013b2a2009-08-07 13:29:14 +0200407 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200408 if (trx->description)
409 vty_out(vty, " description %s%s", trx->description,
410 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200411 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200412 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200413 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200414 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100415 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200416 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200417 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
418 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200419
Harald Welteface7ed2011-02-14 16:15:21 +0100420 if (trx->bts->model->config_write_trx)
421 trx->bts->model->config_write_trx(vty, trx);
422
Harald Welte67ce0732009-08-06 19:06:46 +0200423 for (i = 0; i < TRX_NR_TS; i++)
424 config_write_ts_single(vty, &trx->ts[i]);
425}
426
Harald Welte615e9562010-05-11 23:50:21 +0200427static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
428{
429 unsigned int i;
430 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
431 VTY_NEWLINE);
432 if (bts->gprs.mode == BTS_GPRS_NONE)
433 return;
434
bhargava350533c2016-07-21 11:14:34 +0530435 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
436 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
437
Harald Welte615e9562010-05-11 23:50:21 +0200438 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
439 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100440 vty_out(vty, " gprs network-control-order nc%u%s",
441 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200442 if (!bts->gprs.ctrl_ack_type_use_block)
443 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200444 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
445 VTY_NEWLINE);
446 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
447 vty_out(vty, " gprs cell timer %s %u%s",
448 get_value_string(gprs_bssgp_cfg_strs, i),
449 bts->gprs.cell.timer[i], VTY_NEWLINE);
450 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
451 VTY_NEWLINE);
452 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
453 vty_out(vty, " gprs ns timer %s %u%s",
454 get_value_string(gprs_ns_timer_strs, i),
455 bts->gprs.nse.timer[i], VTY_NEWLINE);
456 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
457 struct gsm_bts_gprs_nsvc *nsvc =
458 &bts->gprs.nsvc[i];
459 struct in_addr ia;
460
461 ia.s_addr = htonl(nsvc->remote_ip);
462 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
463 nsvc->nsvci, VTY_NEWLINE);
464 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
465 nsvc->local_port, VTY_NEWLINE);
466 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
467 nsvc->remote_port, VTY_NEWLINE);
468 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
469 inet_ntoa(ia), VTY_NEWLINE);
470 }
471}
472
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200473/* Write the model data if there is one */
474static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200475{
476 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200477
478 if (!bts->model)
479 return;
480
481 if (bts->model->config_write_bts)
482 bts->model->config_write_bts(vty, bts);
483
484 llist_for_each_entry(trx, &bts->trx_list, list)
485 config_write_trx_single(vty, trx);
486}
487
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200488static void write_amr_modes(struct vty *vty, const char *prefix,
489 const char *name, struct amr_mode *modes, int num)
490{
491 int i;
492
493 vty_out(vty, " %s threshold %s", prefix, name);
494 for (i = 0; i < num - 1; i++)
495 vty_out(vty, " %d", modes[i].threshold);
496 vty_out(vty, "%s", VTY_NEWLINE);
497 vty_out(vty, " %s hysteresis %s", prefix, name);
498 for (i = 0; i < num - 1; i++)
499 vty_out(vty, " %d", modes[i].hysteresis);
500 vty_out(vty, "%s", VTY_NEWLINE);
501}
502
Andreas Eversberg73266522014-01-19 11:47:44 +0100503static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
504 struct amr_multirate_conf *mr, int full)
505{
506 struct gsm48_multi_rate_conf *mr_conf;
507 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
508 int i, num;
509
510 if (!(mr->gsm48_ie[1]))
511 return;
512
513 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
514
515 num = 0;
516 vty_out(vty, " %s modes", prefix);
517 for (i = 0; i < ((full) ? 8 : 6); i++) {
518 if ((mr->gsm48_ie[1] & (1 << i))) {
519 vty_out(vty, " %d", i);
520 num++;
521 }
522 }
523 vty_out(vty, "%s", VTY_NEWLINE);
524 if (num > 4)
525 num = 4;
526 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200527 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
528 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100529 }
530 vty_out(vty, " %s start-mode ", prefix);
531 if (mr_conf->icmi) {
532 num = 0;
533 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
534 if ((mr->gsm48_ie[1] & (1 << i)))
535 num++;
536 if (mr_conf->smod == num - 1) {
537 vty_out(vty, "%d%s", num, VTY_NEWLINE);
538 break;
539 }
540 }
541 } else
542 vty_out(vty, "auto%s", VTY_NEWLINE);
543}
544
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200545static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
546{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200547 int i;
Max2c16bee2017-02-15 13:51:37 +0100548 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200549
Harald Welte5013b2a2009-08-07 13:29:14 +0200550 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
551 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200552 if (bts->description)
553 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200554 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100555 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200556 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200557 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200558 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
559 vty_out(vty, " dtx uplink%s%s",
560 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
561 VTY_NEWLINE);
562 if (bts->dtxd)
563 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200564 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200565 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100566 vty_out(vty, " cell reselection hysteresis %u%s",
567 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
568 vty_out(vty, " rxlev access min %u%s",
569 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100570
571 if (bts->si_common.cell_ro_sel_par.present) {
572 struct gsm48_si_selection_params *sp;
573 sp = &bts->si_common.cell_ro_sel_par;
574
575 if (sp->cbq)
576 vty_out(vty, " cell bar qualify %u%s",
577 sp->cbq, VTY_NEWLINE);
578
579 if (sp->cell_resel_off)
580 vty_out(vty, " cell reselection offset %u%s",
581 sp->cell_resel_off*2, VTY_NEWLINE);
582
583 if (sp->temp_offs == 7)
584 vty_out(vty, " temporary offset infinite%s",
585 VTY_NEWLINE);
586 else if (sp->temp_offs)
587 vty_out(vty, " temporary offset %u%s",
588 sp->temp_offs*10, VTY_NEWLINE);
589
590 if (sp->penalty_time == 31)
591 vty_out(vty, " penalty time reserved%s",
592 VTY_NEWLINE);
593 else if (sp->penalty_time)
594 vty_out(vty, " penalty time %u%s",
595 (sp->penalty_time*20)+20, VTY_NEWLINE);
596 }
597
Harald Welte2f8b9d22017-06-18 11:12:13 +0300598 if (gsm_bts_get_radio_link_timeout(bts) < 0)
599 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
600 else
601 vty_out(vty, " radio-link-timeout %d%s",
602 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Neels Hofmeyr0e5a7c42017-05-08 15:12:20 +0200603
Harald Welte7a8fa412009-08-10 13:48:16 +0200604 vty_out(vty, " channel allocator %s%s",
605 bts->chan_alloc_reverse ? "descending" : "ascending",
606 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100607 vty_out(vty, " rach tx integer %u%s",
608 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
609 vty_out(vty, " rach max transmission %u%s",
610 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
611 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800612
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200613 vty_out(vty, " channel-descrption attach %u%s",
614 bts->si_common.chan_desc.att, VTY_NEWLINE);
615 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
616 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
617 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
618 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
619
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800620 if (bts->rach_b_thresh != -1)
621 vty_out(vty, " rach nm busy threshold %u%s",
622 bts->rach_b_thresh, VTY_NEWLINE);
623 if (bts->rach_ldavg_slots != -1)
624 vty_out(vty, " rach nm load average %u%s",
625 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100626 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200627 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800628 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
629 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400630 if ((bts->si_common.rach_control.t3) != 0)
631 for (i = 0; i < 8; i++)
632 if (bts->si_common.rach_control.t3 & (0x1 << i))
633 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
634 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
635 for (i = 0; i < 8; i++)
636 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
637 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200638 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
639 if (bts->si_mode_static & (1 << i)) {
640 vty_out(vty, " system-information %s mode static%s",
641 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
642 vty_out(vty, " system-information %s static %s%s",
643 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200644 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200645 VTY_NEWLINE);
646 }
647 }
Harald Welte42def722017-01-13 00:10:32 +0100648 vty_out(vty, " early-classmark-sending %s%s",
649 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100650 switch (bts->type) {
651 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100652 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200653 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200654 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100655 if (bts->ip_access.rsl_ip) {
656 struct in_addr ia;
657 ia.s_addr = htonl(bts->ip_access.rsl_ip);
658 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
659 VTY_NEWLINE);
660 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200661 vty_out(vty, " oml ip.access stream_id %u line %u%s",
662 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100663 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200664 case GSM_BTS_TYPE_NOKIA_SITE:
665 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100666 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
667 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100668 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 +0100669 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100670 default:
Harald Welte42581822009-08-08 16:12:58 +0200671 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
672 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100673 break;
Harald Welte42581822009-08-08 16:12:58 +0200674 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800675
676 /* if we have a limit, write it */
677 if (bts->paging.free_chans_need >= 0)
678 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
679
Harald Welte32c09622011-01-11 23:44:56 +0100680 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100681 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
682 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100683 for (i = 0; i < 1024; i++) {
684 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
685 vty_out(vty, " neighbor-list add arfcn %u%s",
686 i, VTY_NEWLINE);
687 }
688 }
Harald Welte64c07d22011-02-15 11:43:27 +0100689 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
690 for (i = 0; i < 1024; i++) {
691 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
692 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
693 i, VTY_NEWLINE);
694 }
695 }
Harald Welte32c09622011-01-11 23:44:56 +0100696
Max59a1bf32016-04-15 16:04:46 +0200697 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100698 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
699 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
700 vty_out(vty, " si2quater neighbor-list add earfcn %u "
701 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
702
703 vty_out(vty, " thresh-lo %u",
704 e->thresh_lo_valid ? e->thresh_lo : 32);
705
706 vty_out(vty, " prio %u",
707 e->prio_valid ? e->prio : 8);
708
709 vty_out(vty, " qrxlv %u",
710 e->qrxlm_valid ? e->qrxlm : 32);
711
712 tmp = e->meas_bw[i];
713 vty_out(vty, " meas %u",
714 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200715
716 vty_out(vty, "%s", VTY_NEWLINE);
717 }
718 }
719
Max26679e02016-04-20 15:57:13 +0200720 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
721 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
722 bts->si_common.data.uarfcn_list[i],
723 bts->si_common.data.scramble_list[i] & ~(1 << 9),
724 (bts->si_common.data.scramble_list[i] >> 9) & 1,
725 VTY_NEWLINE);
726 }
727
Andreas Eversberga83d5112013-12-07 18:32:28 +0100728 vty_out(vty, " codec-support fr");
729 if (bts->codec.hr)
730 vty_out(vty, " hr");
731 if (bts->codec.efr)
732 vty_out(vty, " efr");
733 if (bts->codec.amr)
734 vty_out(vty, " amr");
735 vty_out(vty, "%s", VTY_NEWLINE);
736
Andreas Eversberg73266522014-01-19 11:47:44 +0100737 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
738 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
739
Harald Welte615e9562010-05-11 23:50:21 +0200740 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200741
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200742 if (bts->excl_from_rf_lock)
743 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
744
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100745 vty_out(vty, " %sforce-combined-si%s",
746 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
747
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100748 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
749 int j;
750
751 if (bts->depends_on[i] == 0)
752 continue;
753
754 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
755 int bts_nr;
756
757 if ((bts->depends_on[i] & (1<<j)) == 0)
758 continue;
759
760 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
761 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
762 }
763 }
Harald Welte8254cf72017-05-29 13:42:19 +0200764 if (bts->pcu_sock_path)
765 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100766
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200767 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200768}
769
770static int config_write_bts(struct vty *v)
771{
Harald Weltedcccb182010-05-16 20:52:23 +0200772 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200773 struct gsm_bts *bts;
774
775 llist_for_each_entry(bts, &gsmnet->bts_list, list)
776 config_write_bts_single(v, bts);
777
778 return CMD_SUCCESS;
779}
780
Harald Welted5429bb2017-07-20 01:47:39 +0200781/* small helper macro for conditional dumping of timer */
782#define VTY_OUT_TIMER(number) \
783 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
784 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
785
Harald Welte5013b2a2009-08-07 13:29:14 +0200786static int config_write_net(struct vty *vty)
787{
Harald Weltedcccb182010-05-16 20:52:23 +0200788 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
789
Harald Welte5013b2a2009-08-07 13:29:14 +0200790 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200791 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200792 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200793 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
794 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
Harald Welte (local)69de3972009-08-12 14:42:23 +0200795 vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200796 if (gsmnet->authorized_reg_str)
797 vty_out(vty, " authorized-regexp %s%s", gsmnet->authorized_reg_str, VTY_NEWLINE);
Harald Welte1085c092009-11-18 20:33:19 +0100798 vty_out(vty, " location updating reject cause %u%s",
799 gsmnet->reject_cause, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900800 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Harald Welte7b423ed2016-06-19 18:06:02 +0200801 vty_out(vty, " authentication %s%s",
802 gsmnet->authentication_required ? "required" : "optional",
803 VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100804 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800805 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Harald Welteeab84a12009-12-13 10:53:12 +0100806 vty_out(vty, " rrlp mode %s%s", rrlp_mode_name(gsmnet->rrlp.mode),
807 VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100808 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100809 vty_out(vty, " handover %u%s", gsmnet->handover.active, VTY_NEWLINE);
Harald Welteb720bd32009-12-21 16:51:50 +0100810 vty_out(vty, " handover window rxlev averaging %u%s",
811 gsmnet->handover.win_rxlev_avg, VTY_NEWLINE);
812 vty_out(vty, " handover window rxqual averaging %u%s",
813 gsmnet->handover.win_rxqual_avg, VTY_NEWLINE);
814 vty_out(vty, " handover window rxlev neighbor averaging %u%s",
815 gsmnet->handover.win_rxlev_avg_neigh, VTY_NEWLINE);
816 vty_out(vty, " handover power budget interval %u%s",
817 gsmnet->handover.pwr_interval, VTY_NEWLINE);
818 vty_out(vty, " handover power budget hysteresis %u%s",
819 gsmnet->handover.pwr_hysteresis, VTY_NEWLINE);
820 vty_out(vty, " handover maximum distance %u%s",
821 gsmnet->handover.max_distance, VTY_NEWLINE);
Harald Welted5429bb2017-07-20 01:47:39 +0200822 VTY_OUT_TIMER(3101);
823 VTY_OUT_TIMER(3103);
824 VTY_OUT_TIMER(3105);
825 VTY_OUT_TIMER(3107);
826 VTY_OUT_TIMER(3109);
827 VTY_OUT_TIMER(3111);
828 VTY_OUT_TIMER(3113);
829 VTY_OUT_TIMER(3115);
830 VTY_OUT_TIMER(3117);
831 VTY_OUT_TIMER(3119);
832 VTY_OUT_TIMER(3122);
833 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700834 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
835 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200836 if (gsmnet->tz.override != 0) {
837 if (gsmnet->tz.dst)
838 vty_out(vty, " timezone %d %d %d%s",
839 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
840 VTY_NEWLINE);
841 else
842 vty_out(vty, " timezone %d %d%s",
843 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
844 }
Neels Hofmeyr0e5a7c42017-05-08 15:12:20 +0200845 if (gsmnet->t3212 == 0)
846 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
847 else
848 vty_out(vty, " periodic location update %u%s",
849 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200850
851 return CMD_SUCCESS;
852}
Harald Welte67ce0732009-08-06 19:06:46 +0200853
Harald Welte68628e82009-03-10 12:17:57 +0000854static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
855{
856 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
857 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200858 vty_out(vty, "Description: %s%s",
859 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200860 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200861 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200862 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200863 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000864 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200865 net_dump_nmstate(vty, &trx->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000866 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200867 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200868 if (is_ipaccess_bts(trx->bts)) {
869 vty_out(vty, " ip.access stream ID: 0x%02x%s",
870 trx->rsl_tei, VTY_NEWLINE);
871 } else {
872 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
873 e1isl_dump_vty(vty, trx->rsl_link);
874 }
Harald Welte68628e82009-03-10 12:17:57 +0000875}
876
877DEFUN(show_trx,
878 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100879 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200880 SHOW_STR "Display information about a TRX\n"
881 "BTS Number\n"
882 "TRX Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000883{
Harald Weltedcccb182010-05-16 20:52:23 +0200884 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000885 struct gsm_bts *bts = NULL;
886 struct gsm_bts_trx *trx;
887 int bts_nr, trx_nr;
888
889 if (argc >= 1) {
890 /* use the BTS number that the user has specified */
891 bts_nr = atoi(argv[0]);
892 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000893 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000894 VTY_NEWLINE);
895 return CMD_WARNING;
896 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200897 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000898 }
899 if (argc >= 2) {
900 trx_nr = atoi(argv[1]);
901 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000902 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000903 VTY_NEWLINE);
904 return CMD_WARNING;
905 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200906 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000907 trx_dump_vty(vty, trx);
908 return CMD_SUCCESS;
909 }
910 if (bts) {
911 /* print all TRX in this BTS */
912 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200913 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000914 trx_dump_vty(vty, trx);
915 }
916 return CMD_SUCCESS;
917 }
918
919 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200920 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000921 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200922 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000923 trx_dump_vty(vty, trx);
924 }
925 }
926
927 return CMD_SUCCESS;
928}
929
Harald Welte67ce0732009-08-06 19:06:46 +0200930
Harald Welte68628e82009-03-10 12:17:57 +0000931static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
932{
Harald Welte135a6482011-05-30 12:09:13 +0200933 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +0100934 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +0100935 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +0100936 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +0100937 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200938 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +0100939 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000940 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200941 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530942 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000943 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
944 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
945 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000946}
947
948DEFUN(show_ts,
949 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100950 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200951 SHOW_STR "Display information about a TS\n"
952 "BTS Number\n" "TRX Number\n" "Timeslot Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000953{
Harald Weltedcccb182010-05-16 20:52:23 +0200954 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +0100955 struct gsm_bts *bts = NULL;
956 struct gsm_bts_trx *trx = NULL;
957 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000958 int bts_nr, trx_nr, ts_nr;
959
960 if (argc >= 1) {
961 /* use the BTS number that the user has specified */
962 bts_nr = atoi(argv[0]);
963 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000964 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000965 VTY_NEWLINE);
966 return CMD_WARNING;
967 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200968 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000969 }
970 if (argc >= 2) {
971 trx_nr = atoi(argv[1]);
972 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000973 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000974 VTY_NEWLINE);
975 return CMD_WARNING;
976 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200977 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000978 }
979 if (argc >= 3) {
980 ts_nr = atoi(argv[2]);
981 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +0000982 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +0000983 VTY_NEWLINE);
984 return CMD_WARNING;
985 }
Harald Welte274d0152010-12-24 12:05:03 +0100986 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +0000987 ts = &trx->ts[ts_nr];
988 ts_dump_vty(vty, ts);
989 return CMD_SUCCESS;
990 }
Harald Welte274d0152010-12-24 12:05:03 +0100991
992 if (bts && trx) {
993 /* Iterate over all TS in this TRX */
994 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
995 ts = &trx->ts[ts_nr];
996 ts_dump_vty(vty, ts);
997 }
998 } else if (bts) {
999 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001000 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001001 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001002 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1003 ts = &trx->ts[ts_nr];
1004 ts_dump_vty(vty, ts);
1005 }
1006 }
Harald Welte274d0152010-12-24 12:05:03 +01001007 } else {
1008 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1009 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1010 bts = gsm_bts_num(net, bts_nr);
1011 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1012 trx = gsm_bts_trx_num(bts, trx_nr);
1013 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1014 ts = &trx->ts[ts_nr];
1015 ts_dump_vty(vty, ts);
1016 }
1017 }
1018 }
Harald Welte68628e82009-03-10 12:17:57 +00001019 }
1020
1021 return CMD_SUCCESS;
1022}
1023
Harald Welte7b423ed2016-06-19 18:06:02 +02001024static void subscr_dump_vty(struct vty *vty, struct vlr_subscr *vsub)
Harald Welte68628e82009-03-10 12:17:57 +00001025{
Harald Welte7b423ed2016-06-19 18:06:02 +02001026 OSMO_ASSERT(vsub);
1027 if (strlen(vsub->name))
1028 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
1029 if (strlen(vsub->msisdn))
1030 vty_out(vty, " Extension: %s%s", vsub->msisdn,
Harald Welte68628e82009-03-10 12:17:57 +00001031 VTY_NEWLINE);
Harald Welte7b423ed2016-06-19 18:06:02 +02001032 if (strlen(vsub->imsi))
1033 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
1034 if (vsub->tmsi != GSM_RESERVED_TMSI)
1035 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
1036 VTY_NEWLINE);
1037 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
1038 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
Harald Welte731fd912009-08-15 03:24:51 +02001039 VTY_NEWLINE);
Sylvain Munautaf292642009-12-27 19:29:28 +01001040
Harald Welte7b423ed2016-06-19 18:06:02 +02001041 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001042}
1043
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001044static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1045{
1046 if (strlen(bsub->imsi))
1047 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1048 if (bsub->tmsi != GSM_RESERVED_TMSI)
1049 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1050 VTY_NEWLINE);
1051 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1052}
1053
Harald Welte8387a492009-12-22 21:43:14 +01001054static void meas_rep_dump_uni_vty(struct vty *vty,
1055 struct gsm_meas_rep_unidir *mru,
1056 const char *prefix,
1057 const char *dir)
1058{
1059 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1060 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1061 dir, rxlev2dbm(mru->sub.rx_lev));
1062 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1063 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1064 VTY_NEWLINE);
1065}
1066
1067static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1068 const char *prefix)
1069{
1070 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1071 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1072 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1073 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1074 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1075 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1076 VTY_NEWLINE);
1077 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001078 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001079 if (mr->flags & MEAS_REP_F_MS_L1)
1080 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1081 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1082 if (mr->flags & MEAS_REP_F_DL_VALID)
1083 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1084 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1085}
1086
Harald Welte0a8cf322015-12-05 17:22:49 +01001087/* FIXME: move this to libosmogsm */
1088static const struct value_string gsm48_cmode_names[] = {
1089 { GSM48_CMODE_SIGN, "signalling" },
1090 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1091 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1092 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1093 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1094 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1095 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1096 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1097 { 0, NULL }
1098};
1099
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001100/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1101 * Don't do anything if the ts is not dynamic. */
1102static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1103{
1104 switch (ts->pchan) {
1105 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1106 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1107 vty_out(vty, " as %s",
1108 gsm_pchan_name(ts->dyn.pchan_is));
1109 else
1110 vty_out(vty, " switching %s -> %s",
1111 gsm_pchan_name(ts->dyn.pchan_is),
1112 gsm_pchan_name(ts->dyn.pchan_want));
1113 break;
1114 case GSM_PCHAN_TCH_F_PDCH:
1115 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1116 vty_out(vty, " as %s",
1117 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1118 : "TCH/F");
1119 else
1120 vty_out(vty, " switching %s -> %s",
1121 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1122 : "TCH/F",
1123 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1124 : "TCH/F");
1125 break;
1126 default:
1127 /* no dyn ts */
1128 break;
1129 }
1130}
1131
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001132static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001133{
Harald Welte8387a492009-12-22 21:43:14 +01001134 int idx;
1135
Harald Welte85bded82010-12-24 12:22:34 +01001136 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1137 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1138 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001139 /* show dyn TS details, if applicable */
1140 switch (lchan->ts->pchan) {
1141 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1142 vty_out(vty, " Osmocom Dyn TS:");
1143 vty_out_dyn_ts_status(vty, lchan->ts);
1144 vty_out(vty, VTY_NEWLINE);
1145 break;
1146 case GSM_PCHAN_TCH_F_PDCH:
1147 vty_out(vty, " IPACC Dyn PDCH TS:");
1148 vty_out_dyn_ts_status(vty, lchan->ts);
1149 vty_out(vty, VTY_NEWLINE);
1150 break;
1151 default:
1152 /* no dyn ts */
1153 break;
1154 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001155 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001156 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001157 gsm_lchans_name(lchan->state),
1158 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1159 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1160 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001161 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1162 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1163 - lchan->bs_power*2,
1164 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1165 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001166 vty_out(vty, " Channel Mode / Codec: %s%s",
1167 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1168 VTY_NEWLINE);
Harald Welte7b423ed2016-06-19 18:06:02 +02001169 if (lchan->conn && lchan->conn->vsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001170 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Harald Welte7b423ed2016-06-19 18:06:02 +02001171 subscr_dump_vty(vty, lchan->conn->vsub);
Harald Welte68628e82009-03-10 12:17:57 +00001172 } else
1173 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301174 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1175 struct in_addr ia;
Holger Hans Peter Freyther54fa7992010-04-07 15:39:16 +02001176 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte2c828992009-12-02 01:56:49 +05301177 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1178 inet_ntoa(ia), lchan->abis_ip.bound_port,
1179 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1180 VTY_NEWLINE);
1181 }
Harald Welte8387a492009-12-22 21:43:14 +01001182
1183 /* we want to report the last measurement report */
1184 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1185 lchan->meas_rep_idx, 1);
1186 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001187}
1188
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001189static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1190{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001191 struct gsm_meas_rep *mr;
1192 int idx;
1193
1194 /* we want to report the last measurement report */
1195 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1196 lchan->meas_rep_idx, 1);
1197 mr = &lchan->meas_rep[idx];
1198
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001199 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001200 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001201 gsm_pchan_name(lchan->ts->pchan));
1202 vty_out_dyn_ts_status(vty, lchan->ts);
1203 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1204 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001205 lchan->nr,
1206 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1207 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001208 rxlev2dbm(mr->dl.full.rx_lev),
1209 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001210 VTY_NEWLINE);
1211}
1212
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001213
1214static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1215 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1216{
1217 int lchan_nr;
1218 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1219 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1220 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1221 continue;
1222 dump_cb(vty, lchan);
1223 }
1224
1225 return CMD_SUCCESS;
1226}
1227
1228static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1229 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1230{
1231 int ts_nr;
1232
1233 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1234 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1235 dump_lchan_trx_ts(ts, vty, dump_cb);
1236 }
1237
1238 return CMD_SUCCESS;
1239}
1240
1241static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1242 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1243{
1244 int trx_nr;
1245
1246 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1247 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1248 dump_lchan_trx(trx, vty, dump_cb);
1249 }
1250
1251 return CMD_SUCCESS;
1252}
1253
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001254static int lchan_summary(struct vty *vty, int argc, const char **argv,
1255 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001256{
Harald Weltedcccb182010-05-16 20:52:23 +02001257 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001258 struct gsm_bts *bts;
1259 struct gsm_bts_trx *trx;
1260 struct gsm_bts_trx_ts *ts;
1261 struct gsm_lchan *lchan;
1262 int bts_nr, trx_nr, ts_nr, lchan_nr;
1263
1264 if (argc >= 1) {
1265 /* use the BTS number that the user has specified */
1266 bts_nr = atoi(argv[0]);
1267 if (bts_nr >= net->num_bts) {
1268 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1269 VTY_NEWLINE);
1270 return CMD_WARNING;
1271 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001272 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001273
1274 if (argc == 1)
1275 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001276 }
1277 if (argc >= 2) {
1278 trx_nr = atoi(argv[1]);
1279 if (trx_nr >= bts->num_trx) {
1280 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1281 VTY_NEWLINE);
1282 return CMD_WARNING;
1283 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001284 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001285
1286 if (argc == 2)
1287 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001288 }
1289 if (argc >= 3) {
1290 ts_nr = atoi(argv[2]);
1291 if (ts_nr >= TRX_NR_TS) {
1292 vty_out(vty, "%% can't find TS %s%s", argv[2],
1293 VTY_NEWLINE);
1294 return CMD_WARNING;
1295 }
1296 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001297
1298 if (argc == 3)
1299 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001300 }
1301 if (argc >= 4) {
1302 lchan_nr = atoi(argv[3]);
1303 if (lchan_nr >= TS_MAX_LCHAN) {
1304 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1305 VTY_NEWLINE);
1306 return CMD_WARNING;
1307 }
1308 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001309 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001310 return CMD_SUCCESS;
1311 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001312
1313
Harald Welte68628e82009-03-10 12:17:57 +00001314 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001315 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001316 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001317 }
1318
1319 return CMD_SUCCESS;
1320}
1321
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001322
1323DEFUN(show_lchan,
1324 show_lchan_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001325 "show lchan [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001326 SHOW_STR "Display information about a logical channel\n"
1327 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001328 LCHAN_NR_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001329
1330{
1331 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1332}
1333
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001334DEFUN(show_lchan_summary,
1335 show_lchan_summary_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001336 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001337 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001338 "Short summary\n"
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001339 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001340 LCHAN_NR_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001341{
1342 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1343}
1344
Philipp Maier4b60d072017-04-09 12:32:51 +02001345DEFUN(show_subscr_conn,
1346 show_subscr_conn_cmd,
1347 "show conns",
1348 SHOW_STR "Display currently active subscriber connections\n")
1349{
1350 struct gsm_subscriber_connection *conn;
1351 struct gsm_network *net = gsmnet_from_vty(vty);
1352 bool no_conns = true;
1353 unsigned int count = 0;
1354
1355 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1356
1357 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1358 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1359 lchan_dump_full_vty(vty, conn->lchan);
1360 no_conns = false;
1361 count++;
1362 }
1363
1364 if (no_conns)
1365 vty_out(vty, "None%s", VTY_NEWLINE);
1366
1367 return CMD_SUCCESS;
1368}
1369
1370DEFUN(handover_subscr_conn,
1371 handover_subscr_conn_cmd,
1372 "handover <0-255> <0-255> <0-7> LCHAN_NR <0-255>",
1373 "Handover subscriber connection to other BTS\n"
1374 "BTS Number (current)\n" "TRX Number\n" "Timeslot Number\n"
1375 LCHAN_NR_STR "BTS Number (new)\n")
1376{
1377 struct gsm_network *net = gsmnet_from_vty(vty);
1378 struct gsm_subscriber_connection *conn;
1379 struct gsm_bts *bts;
1380 struct gsm_bts *new_bts = NULL;
1381 unsigned int bts_nr = atoi(argv[0]);
1382 unsigned int trx_nr = atoi(argv[1]);
1383 unsigned int ts_nr = atoi(argv[2]);
1384 unsigned int ss_nr = atoi(argv[3]);
1385 unsigned int bts_nr_new = atoi(argv[4]);
1386
1387 /* Lookup the BTS where we want to handover to */
1388 llist_for_each_entry(bts, &net->bts_list, list) {
1389 if (bts->nr == bts_nr_new) {
1390 new_bts = bts;
1391 break;
1392 }
1393 }
1394
1395 if (!new_bts) {
1396 vty_out(vty, "Unable to trigger handover,"
1397 "specified bts #%u does not exist %s", bts_nr_new,
1398 VTY_NEWLINE);
1399 return CMD_WARNING;
1400 }
1401
1402 /* Find the connection/lchan that we want to handover */
1403 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1404 if (conn->bts->nr == bts_nr &&
1405 conn->lchan->ts->trx->nr == trx_nr &&
1406 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
1407 vty_out(vty, "starting handover for lchan %s...%s",
1408 conn->lchan->name, VTY_NEWLINE);
1409 lchan_dump_full_vty(vty, conn->lchan);
1410 bsc_handover_start(conn->lchan, new_bts);
1411 return CMD_SUCCESS;
1412 }
1413 }
1414
1415 vty_out(vty, "Unable to trigger handover,"
1416 "specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1417 bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
1418
1419 return CMD_WARNING;
1420}
1421
Harald Weltebe4b7302009-05-23 16:59:33 +00001422static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001423{
1424 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001425 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001426}
1427
Harald Weltebe4b7302009-05-23 16:59:33 +00001428static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001429{
1430 struct gsm_paging_request *pag;
1431
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001432 if (!bts->paging.bts)
1433 return;
1434
Harald Weltef5025b62009-03-28 16:55:11 +00001435 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1436 paging_dump_vty(vty, pag);
1437}
1438
1439DEFUN(show_paging,
1440 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001441 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001442 SHOW_STR "Display information about paging reuqests of a BTS\n"
1443 "BTS Number\n")
Harald Weltef5025b62009-03-28 16:55:11 +00001444{
Harald Weltedcccb182010-05-16 20:52:23 +02001445 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001446 struct gsm_bts *bts;
1447 int bts_nr;
1448
1449 if (argc >= 1) {
1450 /* use the BTS number that the user has specified */
1451 bts_nr = atoi(argv[0]);
1452 if (bts_nr >= net->num_bts) {
1453 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1454 VTY_NEWLINE);
1455 return CMD_WARNING;
1456 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001457 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001458 bts_paging_dump_vty(vty, bts);
1459
1460 return CMD_SUCCESS;
1461 }
1462 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001463 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001464 bts_paging_dump_vty(vty, bts);
1465 }
1466
1467 return CMD_SUCCESS;
1468}
1469
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001470DEFUN(show_paging_group,
1471 show_paging_group_cmd,
1472 "show paging-group <0-255> IMSI",
1473 SHOW_STR "Display the paging group\n"
1474 "BTS Number\n" "IMSI\n")
1475{
1476 struct gsm_network *net = gsmnet_from_vty(vty);
1477 struct gsm_bts *bts;
1478 unsigned int page_group;
1479 int bts_nr = atoi(argv[0]);
1480
1481 if (bts_nr >= net->num_bts) {
1482 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1483 return CMD_WARNING;
1484 }
1485
1486 bts = gsm_bts_num(net, bts_nr);
1487 if (!bts) {
1488 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1489 return CMD_WARNING;
1490 }
1491
1492 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1493 str_to_imsi(argv[1]));
1494 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1495 str_to_imsi(argv[1]), bts->nr,
1496 page_group, VTY_NEWLINE);
1497 return CMD_SUCCESS;
1498}
1499
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001500DEFUN(cfg_net_neci,
1501 cfg_net_neci_cmd,
1502 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001503 "New Establish Cause Indication\n"
1504 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001505{
Harald Weltedcccb182010-05-16 20:52:23 +02001506 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1507
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001508 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001509 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001510 return CMD_SUCCESS;
1511}
1512
Harald Welte8f0ed552010-05-11 21:53:49 +02001513#define HANDOVER_STR "Handover Options\n"
1514
Harald Weltebc814502009-12-19 21:41:52 +01001515DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1516 "handover (0|1)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001517 HANDOVER_STR
1518 "Don't perform in-call handover\n"
1519 "Perform in-call handover\n")
Harald Weltebc814502009-12-19 21:41:52 +01001520{
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001521 int enable = atoi(argv[0]);
Harald Weltedcccb182010-05-16 20:52:23 +02001522 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001523
1524 if (enable && ipacc_rtp_direct) {
Harald Weltefe03f0d2009-12-20 13:51:01 +01001525 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1526 "is enabled by using the -P command line option%s",
1527 VTY_NEWLINE);
1528 return CMD_WARNING;
1529 }
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001530 gsmnet->handover.active = enable;
Harald Weltebc814502009-12-19 21:41:52 +01001531
1532 return CMD_SUCCESS;
1533}
1534
Harald Welte8f0ed552010-05-11 21:53:49 +02001535#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1536#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1537#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1538#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001539#define HO_AVG_COUNT_STR "Amount to use for Averaging\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001540
Harald Welteb720bd32009-12-21 16:51:50 +01001541DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1542 "handover window rxlev averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001543 HO_WIN_RXLEV_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001544 "How many RxLev measurements are used for averaging\n"
1545 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001546{
Harald Weltedcccb182010-05-16 20:52:23 +02001547 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001548 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1549 return CMD_SUCCESS;
1550}
1551
1552DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1553 "handover window rxqual averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001554 HO_WIN_RXQUAL_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001555 "How many RxQual measurements are used for averaging\n"
1556 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001557{
Harald Weltedcccb182010-05-16 20:52:23 +02001558 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001559 gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
1560 return CMD_SUCCESS;
1561}
1562
1563DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1564 "handover window rxlev neighbor averaging <1-10>",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001565 HO_WIN_RXLEV_STR "Neighbor\n"
1566 "How many RxQual measurements are used for averaging\n"
1567 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001568{
Harald Weltedcccb182010-05-16 20:52:23 +02001569 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001570 gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
1571 return CMD_SUCCESS;
1572}
1573
1574DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1575 "handover power budget interval <1-99>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001576 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001577 "How often to check if we have a better cell (SACCH frames)\n"
1578 "Interval\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001579{
Harald Weltedcccb182010-05-16 20:52:23 +02001580 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001581 gsmnet->handover.pwr_interval = atoi(argv[0]);
1582 return CMD_SUCCESS;
1583}
1584
1585DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1586 "handover power budget hysteresis <0-999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001587 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001588 "How many dB does a neighbor to be stronger to become a HO candidate\n"
1589 "Hysteresis\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001590{
Harald Weltedcccb182010-05-16 20:52:23 +02001591 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001592 gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
1593 return CMD_SUCCESS;
1594}
1595
1596DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1597 "handover maximum distance <0-9999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001598 HANDOVER_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001599 "How big is the maximum timing advance before HO is forced\n"
1600 "Distance\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001601{
Harald Weltedcccb182010-05-16 20:52:23 +02001602 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001603 gsmnet->handover.max_distance = atoi(argv[0]);
1604 return CMD_SUCCESS;
1605}
Harald Weltebc814502009-12-19 21:41:52 +01001606
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001607DEFUN(cfg_net_pag_any_tch,
1608 cfg_net_pag_any_tch_cmd,
1609 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001610 "Assign a TCH when receiving a Paging Any request\n"
1611 "Any Channel\n" "Use\n" "TCH\n"
1612 "Do not use TCH for Paging Request Any\n"
1613 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001614{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001615 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001616 gsmnet->pag_any_tch = atoi(argv[0]);
1617 gsm_net_update_ctype(gsmnet);
1618 return CMD_SUCCESS;
1619}
1620
Neels Hofmeyr06e14c62017-07-24 13:06:45 +02001621#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1622/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1623#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1624
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001625#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001626 DEFUN(cfg_net_T##number, \
1627 cfg_net_T##number##_cmd, \
Neels Hofmeyr06e14c62017-07-24 13:06:45 +02001628 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001629 "Configure GSM Timers\n" \
Neels Hofmeyrf6940332017-07-24 13:36:42 +02001630 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyr06e14c62017-07-24 13:06:45 +02001631 "Set to default timer value" \
1632 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1633 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001634{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001635 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyr06e14c62017-07-24 13:06:45 +02001636 int value; \
1637 if (strcmp(argv[0], "default") == 0) \
1638 value = DEFAULT_TIMER(number); \
1639 else \
1640 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001641 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001642 gsmnet->T##number = value; \
1643 return CMD_SUCCESS; \
1644}
1645
Neels Hofmeyrf6940332017-07-24 13:36:42 +02001646DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1647DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1648DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1649DECLARE_TIMER(3107, "Currently not used")
1650DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1651DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1652DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1653DECLARE_TIMER(3115, "Currently not used")
1654DECLARE_TIMER(3117, "Currently not used")
1655DECLARE_TIMER(3119, "Currently not used")
1656DECLARE_TIMER(3122, "Waiting time (seconds) after IMM ASS REJECT")
1657DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001658
Maxc08ee712016-05-11 12:45:13 +02001659DEFUN_DEPRECATED(cfg_net_dtx,
1660 cfg_net_dtx_cmd,
1661 "dtx-used (0|1)",
1662 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001663{
Maxc08ee712016-05-11 12:45:13 +02001664 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1665 "configuration options of BTS instead%s", VTY_NEWLINE);
1666 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001667}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001668
Harald Welte5258fc42009-03-28 19:07:53 +00001669/* per-BTS configuration */
1670DEFUN(cfg_bts,
1671 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001672 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001673 "Select a BTS to configure\n"
1674 "BTS Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001675{
Harald Weltedcccb182010-05-16 20:52:23 +02001676 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001677 int bts_nr = atoi(argv[0]);
1678 struct gsm_bts *bts;
1679
Harald Weltee441d9c2009-06-21 16:17:15 +02001680 if (bts_nr > gsmnet->num_bts) {
1681 vty_out(vty, "%% The next unused BTS number is %u%s",
1682 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001683 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001684 } else if (bts_nr == gsmnet->num_bts) {
1685 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001686 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001687 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001688 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001689 bts = gsm_bts_num(gsmnet, bts_nr);
1690
Daniel Willmannf15c2762010-01-11 13:43:07 +01001691 if (!bts) {
1692 vty_out(vty, "%% Unable to allocate BTS %u%s",
1693 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001694 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001695 }
Harald Welte5258fc42009-03-28 19:07:53 +00001696
1697 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001698 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001699 vty->node = BTS_NODE;
1700
1701 return CMD_SUCCESS;
1702}
1703
1704DEFUN(cfg_bts_type,
1705 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001706 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001707 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001708{
1709 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001710 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001711
Max7507aef2017-04-10 13:59:14 +02001712 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001713 if (rc < 0)
1714 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001715
Harald Welte5258fc42009-03-28 19:07:53 +00001716 return CMD_SUCCESS;
1717}
1718
Harald Weltefcd24452009-06-20 18:15:19 +02001719DEFUN(cfg_bts_band,
1720 cfg_bts_band_cmd,
1721 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001722 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001723{
1724 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001725 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001726
1727 if (band < 0) {
1728 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1729 band, VTY_NEWLINE);
1730 return CMD_WARNING;
1731 }
1732
1733 bts->band = band;
1734
1735 return CMD_SUCCESS;
1736}
1737
Maxc08ee712016-05-11 12:45:13 +02001738DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1739 "Configure discontinuous transmission\n"
1740 "Enable Uplink DTX for this BTS\n"
1741 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1742 "older phones).\n")
1743{
1744 struct gsm_bts *bts = vty->index;
1745
1746 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
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_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1754 NO_STR
1755 "Configure discontinuous transmission\n"
1756 "Disable Uplink DTX for this BTS\n")
1757{
1758 struct gsm_bts *bts = vty->index;
1759
1760 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1761
1762 return CMD_SUCCESS;
1763}
1764
1765DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1766 "Configure discontinuous transmission\n"
1767 "Enable Downlink DTX for this BTS\n")
1768{
1769 struct gsm_bts *bts = vty->index;
1770
1771 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001772 if (!is_ipaccess_bts(bts))
1773 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1774 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001775 return CMD_SUCCESS;
1776}
1777
1778DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1779 NO_STR
1780 "Configure discontinuous transmission\n"
1781 "Disable Downlink DTX for this BTS\n")
1782{
1783 struct gsm_bts *bts = vty->index;
1784
1785 bts->dtxd = false;
1786
1787 return CMD_SUCCESS;
1788}
1789
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001790DEFUN(cfg_bts_ci,
1791 cfg_bts_ci_cmd,
1792 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001793 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001794{
1795 struct gsm_bts *bts = vty->index;
1796 int ci = atoi(argv[0]);
1797
1798 if (ci < 0 || ci > 0xffff) {
1799 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1800 ci, VTY_NEWLINE);
1801 return CMD_WARNING;
1802 }
1803 bts->cell_identity = ci;
1804
1805 return CMD_SUCCESS;
1806}
1807
Harald Welte5258fc42009-03-28 19:07:53 +00001808DEFUN(cfg_bts_lac,
1809 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001810 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001811 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001812{
1813 struct gsm_bts *bts = vty->index;
1814 int lac = atoi(argv[0]);
1815
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001816 if (lac < 0 || lac > 0xffff) {
1817 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001818 lac, VTY_NEWLINE);
1819 return CMD_WARNING;
1820 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001821
1822 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1823 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1824 lac, VTY_NEWLINE);
1825 return CMD_WARNING;
1826 }
1827
Harald Welte5258fc42009-03-28 19:07:53 +00001828 bts->location_area_code = lac;
1829
1830 return CMD_SUCCESS;
1831}
1832
Harald Weltea43f7892009-12-01 18:04:30 +05301833
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001834/* compatibility wrapper for old config files */
1835DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001836 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001837 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001838 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001839{
Harald Welte5258fc42009-03-28 19:07:53 +00001840 return CMD_SUCCESS;
1841}
1842
Harald Welte78f2f502009-05-23 16:56:52 +00001843DEFUN(cfg_bts_bsic,
1844 cfg_bts_bsic_cmd,
1845 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001846 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1847 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001848{
1849 struct gsm_bts *bts = vty->index;
1850 int bsic = atoi(argv[0]);
1851
1852 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001853 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001854 bsic, VTY_NEWLINE);
1855 return CMD_WARNING;
1856 }
1857 bts->bsic = bsic;
1858
1859 return CMD_SUCCESS;
1860}
1861
Harald Welte4cc34222009-05-01 15:12:31 +00001862DEFUN(cfg_bts_unit_id,
1863 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001864 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001865 "Abis/IP specific options\n"
1866 "Set the IPA BTS Unit ID\n"
1867 "Unit ID (Site)\n"
1868 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001869{
1870 struct gsm_bts *bts = vty->index;
1871 int site_id = atoi(argv[0]);
1872 int bts_id = atoi(argv[1]);
1873
Harald Welte07dc73d2009-08-07 13:27:09 +02001874 if (!is_ipaccess_bts(bts)) {
1875 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1876 return CMD_WARNING;
1877 }
1878
Harald Welte4cc34222009-05-01 15:12:31 +00001879 bts->ip_access.site_id = site_id;
1880 bts->ip_access.bts_id = bts_id;
1881
1882 return CMD_SUCCESS;
1883}
1884
Harald Welte8b291802013-03-12 13:57:05 +01001885DEFUN(cfg_bts_rsl_ip,
1886 cfg_bts_rsl_ip_cmd,
1887 "ip.access rsl-ip A.B.C.D",
1888 "Abis/IP specific options\n"
1889 "Set the IPA RSL IP Address of the BSC\n"
1890 "Destination IP address for RSL connection\n")
1891{
1892 struct gsm_bts *bts = vty->index;
1893 struct in_addr ia;
1894
1895 if (!is_ipaccess_bts(bts)) {
1896 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1897 return CMD_WARNING;
1898 }
1899
1900 inet_aton(argv[0], &ia);
1901 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1902
1903 return CMD_SUCCESS;
1904}
1905
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001906#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001907
Sylvain Munautc9519462011-10-17 14:04:55 +02001908DEFUN(cfg_bts_nokia_site_skip_reset,
1909 cfg_bts_nokia_site_skip_reset_cmd,
1910 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001911 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001912 "Skip the reset step during bootstrap process of this BTS\n"
1913 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02001914{
1915 struct gsm_bts *bts = vty->index;
1916
1917 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
1918 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
1919 return CMD_WARNING;
1920 }
1921
1922 bts->nokia.skip_reset = atoi(argv[0]);
1923
1924 return CMD_SUCCESS;
1925}
1926
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001927DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
1928 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
1929 "nokia_site no-local-rel-conf (0|1)",
1930 NOKIA_STR
1931 "Do not wait for RELease CONFirm message when releasing channel locally\n"
1932 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
1933{
1934 struct gsm_bts *bts = vty->index;
1935
1936 if (!is_nokia_bts(bts)) {
1937 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1938 VTY_NEWLINE);
1939 return CMD_WARNING;
1940 }
1941
1942 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
1943
1944 return CMD_SUCCESS;
1945}
1946
Sipos Csaba56e17662015-02-07 13:27:36 +01001947DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
1948 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
1949 "nokia_site bts-reset-timer <15-100>",
1950 NOKIA_STR
1951 "The amount of time (in sec.) between BTS_RESET is sent,\n"
1952 "and the BTS is being bootstrapped.\n")
1953{
1954 struct gsm_bts *bts = vty->index;
1955
1956 if (!is_nokia_bts(bts)) {
1957 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1958 VTY_NEWLINE);
1959 return CMD_WARNING;
1960 }
1961
1962 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
1963
1964 return CMD_SUCCESS;
1965}
Harald Welte8f0ed552010-05-11 21:53:49 +02001966#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001967#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001968
Harald Welte8175e952009-10-20 00:22:00 +02001969DEFUN(cfg_bts_stream_id,
1970 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001971 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02001972 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001973 "Set the ip.access Stream ID of the OML link of this BTS\n"
1974 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02001975{
1976 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001977 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02001978
1979 if (!is_ipaccess_bts(bts)) {
1980 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1981 return CMD_WARNING;
1982 }
1983
1984 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001985 /* This is used by e1inp_bind_ops callback for each BTS model. */
1986 bts->oml_e1_link.e1_nr = linenr;
1987
1988 return CMD_SUCCESS;
1989}
1990
Harald Welted13e0cd2012-08-17 09:52:03 +02001991#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02001992
Harald Welte42581822009-08-08 16:12:58 +02001993DEFUN(cfg_bts_oml_e1,
1994 cfg_bts_oml_e1_cmd,
1995 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02001996 OML_E1_STR
1997 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001998 "E1/T1 line number to be used for OML\n"
1999 "E1/T1 timeslot to be used for OML\n"
2000 "E1/T1 timeslot to be used for OML\n"
2001 "E1/T1 sub-slot to be used for OML\n"
2002 "Use E1/T1 sub-slot 0\n"
2003 "Use E1/T1 sub-slot 1\n"
2004 "Use E1/T1 sub-slot 2\n"
2005 "Use E1/T1 sub-slot 3\n"
2006 "Use full E1 slot 3\n"
2007 )
Harald Welte42581822009-08-08 16:12:58 +02002008{
2009 struct gsm_bts *bts = vty->index;
2010
2011 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2012
2013 return CMD_SUCCESS;
2014}
2015
2016
2017DEFUN(cfg_bts_oml_e1_tei,
2018 cfg_bts_oml_e1_tei_cmd,
2019 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002020 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002021 "Set the TEI to be used for OML\n"
2022 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002023{
2024 struct gsm_bts *bts = vty->index;
2025
2026 bts->oml_tei = atoi(argv[0]);
2027
2028 return CMD_SUCCESS;
2029}
2030
Harald Welte7a8fa412009-08-10 13:48:16 +02002031DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2032 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002033 "Channnel Allocator\n" "Channel Allocator\n"
2034 "Allocate Timeslots and Transceivers in ascending order\n"
2035 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002036{
2037 struct gsm_bts *bts = vty->index;
2038
2039 if (!strcmp(argv[0], "ascending"))
2040 bts->chan_alloc_reverse = 0;
2041 else
2042 bts->chan_alloc_reverse = 1;
2043
2044 return CMD_SUCCESS;
2045}
2046
Harald Welte8f0ed552010-05-11 21:53:49 +02002047#define RACH_STR "Random Access Control Channel\n"
2048
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002049DEFUN(cfg_bts_rach_tx_integer,
2050 cfg_bts_rach_tx_integer_cmd,
2051 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002052 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002053 "Set the raw tx integer value in RACH Control parameters IE\n"
2054 "Set the raw tx integer value in RACH Control parameters IE\n"
2055 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002056{
2057 struct gsm_bts *bts = vty->index;
2058 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2059 return CMD_SUCCESS;
2060}
2061
2062DEFUN(cfg_bts_rach_max_trans,
2063 cfg_bts_rach_max_trans_cmd,
2064 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002065 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002066 "Set the maximum number of RACH burst transmissions\n"
2067 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002068 "Maximum number of 1 RACH burst transmissions\n"
2069 "Maximum number of 2 RACH burst transmissions\n"
2070 "Maximum number of 4 RACH burst transmissions\n"
2071 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002072{
2073 struct gsm_bts *bts = vty->index;
2074 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2075 return CMD_SUCCESS;
2076}
2077
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002078#define CD_STR "Channel Description\n"
2079
2080DEFUN(cfg_bts_chan_desc_att,
2081 cfg_bts_chan_desc_att_cmd,
2082 "channel-descrption attach (0|1)",
2083 CD_STR
2084 "Set if attachment is required\n"
2085 "Attachment is NOT required\n"
2086 "Attachment is required (standard)\n")
2087{
2088 struct gsm_bts *bts = vty->index;
2089 bts->si_common.chan_desc.att = atoi(argv[0]);
2090 return CMD_SUCCESS;
2091}
2092
2093DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2094 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2095 "channel-descrption bs-pa-mfrms <2-9>",
2096 CD_STR
2097 "Set number of multiframe periods for paging groups\n"
2098 "Number of multiframe periods for paging groups\n")
2099{
2100 struct gsm_bts *bts = vty->index;
2101 int bs_pa_mfrms = atoi(argv[0]);
2102
2103 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2104 return CMD_SUCCESS;
2105}
2106
2107DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2108 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2109 "channel-descrption bs-ag-blks-res <0-7>",
2110 CD_STR
2111 "Set number of blocks reserved for access grant\n"
2112 "Number of blocks reserved for access grant\n")
2113{
2114 struct gsm_bts *bts = vty->index;
2115 int bs_ag_blks_res = atoi(argv[0]);
2116
2117 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2118 return CMD_SUCCESS;
2119}
2120
Harald Welte8f0ed552010-05-11 21:53:49 +02002121#define NM_STR "Network Management\n"
2122
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002123DEFUN(cfg_bts_rach_nm_b_thresh,
2124 cfg_bts_rach_nm_b_thresh_cmd,
2125 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002126 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002127 "Set the NM Busy Threshold\n"
2128 "Set the NM Busy Threshold\n"
2129 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002130{
2131 struct gsm_bts *bts = vty->index;
2132 bts->rach_b_thresh = atoi(argv[0]);
2133 return CMD_SUCCESS;
2134}
2135
2136DEFUN(cfg_bts_rach_nm_ldavg,
2137 cfg_bts_rach_nm_ldavg_cmd,
2138 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002139 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002140 "Set the NM Loadaverage Slots value\n"
2141 "Set the NM Loadaverage Slots value\n"
2142 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002143{
2144 struct gsm_bts *bts = vty->index;
2145 bts->rach_ldavg_slots = atoi(argv[0]);
2146 return CMD_SUCCESS;
2147}
2148
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002149DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2150 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002151 "Should this cell be barred from access?\n"
2152 "Should this cell be barred from access?\n"
2153 "Cell should NOT be barred\n"
2154 "Cell should be barred\n")
2155
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002156{
2157 struct gsm_bts *bts = vty->index;
2158
Harald Welte71355012009-12-21 23:08:18 +01002159 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002160
2161 return CMD_SUCCESS;
2162}
2163
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002164DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2165 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002166 RACH_STR
2167 "Should this cell allow emergency calls?\n"
2168 "Should this cell allow emergency calls?\n"
2169 "Should this cell allow emergency calls?\n"
2170 "Do NOT allow emergency calls\n"
2171 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002172{
2173 struct gsm_bts *bts = vty->index;
2174
2175 if (atoi(argv[0]) == 0)
2176 bts->si_common.rach_control.t2 |= 0x4;
2177 else
2178 bts->si_common.rach_control.t2 &= ~0x4;
2179
2180 return CMD_SUCCESS;
2181}
2182
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002183DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2184 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2185 RACH_STR
2186 "Set access control class\n"
2187 "Access control class 0\n"
2188 "Access control class 1\n"
2189 "Access control class 2\n"
2190 "Access control class 3\n"
2191 "Access control class 4\n"
2192 "Access control class 5\n"
2193 "Access control class 6\n"
2194 "Access control class 7\n"
2195 "Access control class 8\n"
2196 "Access control class 9\n"
2197 "Access control class 11 for PLMN use\n"
2198 "Access control class 12 for security services\n"
2199 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2200 "Access control class 14 for emergency services\n"
2201 "Access control class 15 for PLMN staff\n"
2202 "barred to use access control class\n"
2203 "allowed to use access control class\n")
2204{
2205 struct gsm_bts *bts = vty->index;
2206
2207 uint8_t control_class;
2208 uint8_t allowed = 0;
2209
2210 if (strcmp(argv[1], "allowed") == 0)
2211 allowed = 1;
2212
2213 control_class = atoi(argv[0]);
2214 if (control_class < 8)
2215 if (allowed)
2216 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2217 else
2218 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2219 else
2220 if (allowed)
2221 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2222 else
2223 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2224
2225 return CMD_SUCCESS;
2226}
2227
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002228DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2229 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002230 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002231 "Maximum transmit power of the MS\n"
2232 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002233 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002234{
2235 struct gsm_bts *bts = vty->index;
2236
2237 bts->ms_max_power = atoi(argv[0]);
2238
2239 return CMD_SUCCESS;
2240}
2241
Harald Weltecfaabbb2012-08-16 23:23:50 +02002242#define CELL_STR "Cell Parameters\n"
2243
Harald Welte73225282009-12-12 18:17:25 +01002244DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2245 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002246 CELL_STR "Cell re-selection parameters\n"
2247 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002248 "Cell Re-Selection Hysteresis in dB")
2249{
2250 struct gsm_bts *bts = vty->index;
2251
2252 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2253
2254 return CMD_SUCCESS;
2255}
2256
2257DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2258 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002259 "Minimum RxLev needed for cell access\n"
2260 "Minimum RxLev needed for cell access\n"
2261 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002262 "Minimum RxLev needed for cell access (better than -110dBm)")
2263{
2264 struct gsm_bts *bts = vty->index;
2265
2266 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2267
2268 return CMD_SUCCESS;
2269}
2270
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002271DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2272 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002273 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2274 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002275{
2276 struct gsm_bts *bts = vty->index;
2277
2278 bts->si_common.cell_ro_sel_par.present = 1;
2279 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2280
2281 return CMD_SUCCESS;
2282}
2283
2284DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2285 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002286 CELL_STR "Cell Re-Selection Parameters\n"
2287 "Cell Re-Selection Offset (CRO) in dB\n"
2288 "Cell Re-Selection Offset (CRO) in dB\n"
2289 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002290{
2291 struct gsm_bts *bts = vty->index;
2292
2293 bts->si_common.cell_ro_sel_par.present = 1;
2294 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2295
2296 return CMD_SUCCESS;
2297}
2298
2299DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2300 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002301 "Cell selection temporary negative offset\n"
2302 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002303 "Cell selection temporary negative offset in dB")
2304{
2305 struct gsm_bts *bts = vty->index;
2306
2307 bts->si_common.cell_ro_sel_par.present = 1;
2308 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2309
2310 return CMD_SUCCESS;
2311}
2312
2313DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2314 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002315 "Cell selection temporary negative offset\n"
2316 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002317 "Sets cell selection temporary negative offset to infinity")
2318{
2319 struct gsm_bts *bts = vty->index;
2320
2321 bts->si_common.cell_ro_sel_par.present = 1;
2322 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2323
2324 return CMD_SUCCESS;
2325}
2326
2327DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2328 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002329 "Cell selection penalty time\n"
2330 "Cell selection penalty time\n"
2331 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002332{
2333 struct gsm_bts *bts = vty->index;
2334
2335 bts->si_common.cell_ro_sel_par.present = 1;
2336 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2337
2338 return CMD_SUCCESS;
2339}
2340
2341DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2342 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002343 "Cell selection penalty time\n"
2344 "Cell selection penalty time\n"
2345 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002346 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2347 "and TEMPORARY_OFFSET is ignored)")
2348{
2349 struct gsm_bts *bts = vty->index;
2350
2351 bts->si_common.cell_ro_sel_par.present = 1;
2352 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2353
2354 return CMD_SUCCESS;
2355}
2356
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002357DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2358 "radio-link-timeout <4-64>",
2359 "Radio link timeout criterion (BTS side)\n"
2360 "Radio link timeout value (lost SACCH block)\n")
2361{
2362 struct gsm_bts *bts = vty->index;
2363
Harald Welte2f8b9d22017-06-18 11:12:13 +03002364 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2365
2366 return CMD_SUCCESS;
2367}
2368
2369DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2370 "radio-link-timeout infinite",
2371 "Radio link timeout criterion (BTS side)\n"
2372 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2373{
2374 struct gsm_bts *bts = vty->index;
2375
2376 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2377 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2378 return CMD_WARNING;
2379 }
2380
2381 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2382 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002383
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002384 return CMD_SUCCESS;
2385}
2386
Harald Welte8f0ed552010-05-11 21:53:49 +02002387#define GPRS_TEXT "GPRS Packet Network\n"
2388
Harald Welteaf387632010-03-14 23:30:30 +08002389DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002390 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002391 GPRS_TEXT
2392 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002393 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002394 "GPRS BSSGP VC Identifier")
2395{
2396 struct gsm_bts *bts = vty->index;
2397
Harald Welte4511d892010-04-18 15:51:20 +02002398 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002399 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2400 return CMD_WARNING;
2401 }
2402
Harald Welte97a282b2010-03-14 15:37:43 +08002403 bts->gprs.cell.bvci = atoi(argv[0]);
2404
2405 return CMD_SUCCESS;
2406}
2407
Harald Weltea5731cf2010-03-22 11:48:36 +08002408DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2409 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002410 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002411 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002412 "GPRS NS Entity Identifier")
2413{
2414 struct gsm_bts *bts = vty->index;
2415
Harald Welte4511d892010-04-18 15:51:20 +02002416 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002417 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2418 return CMD_WARNING;
2419 }
2420
2421 bts->gprs.nse.nsei = atoi(argv[0]);
2422
2423 return CMD_SUCCESS;
2424}
2425
Harald Welte8f0ed552010-05-11 21:53:49 +02002426#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2427 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002428
Harald Welte97a282b2010-03-14 15:37:43 +08002429DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2430 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002431 GPRS_TEXT NSVC_TEXT
2432 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002433 "GPRS NS VC Identifier")
2434{
2435 struct gsm_bts *bts = vty->index;
2436 int idx = atoi(argv[0]);
2437
Harald Welte4511d892010-04-18 15:51:20 +02002438 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002439 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2440 return CMD_WARNING;
2441 }
2442
Harald Welte97a282b2010-03-14 15:37:43 +08002443 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2444
2445 return CMD_SUCCESS;
2446}
2447
Harald Welteaf387632010-03-14 23:30:30 +08002448DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2449 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002450 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002451 "GPRS NS Local UDP Port\n"
2452 "GPRS NS Local UDP Port\n"
2453 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002454 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002455{
2456 struct gsm_bts *bts = vty->index;
2457 int idx = atoi(argv[0]);
2458
Harald Welte4511d892010-04-18 15:51:20 +02002459 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002460 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2461 return CMD_WARNING;
2462 }
2463
Harald Welteaf387632010-03-14 23:30:30 +08002464 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2465
2466 return CMD_SUCCESS;
2467}
2468
2469DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2470 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002471 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002472 "GPRS NS Remote UDP Port\n"
2473 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002474 "GPRS NS Remote UDP Port\n"
2475 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002476{
2477 struct gsm_bts *bts = vty->index;
2478 int idx = atoi(argv[0]);
2479
Harald Welte4511d892010-04-18 15:51:20 +02002480 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002481 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2482 return CMD_WARNING;
2483 }
2484
Harald Welteaf387632010-03-14 23:30:30 +08002485 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2486
2487 return CMD_SUCCESS;
2488}
2489
2490DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2491 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002492 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002493 "GPRS NS Remote IP Address\n"
2494 "GPRS NS Remote IP Address\n"
2495 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002496{
2497 struct gsm_bts *bts = vty->index;
2498 int idx = atoi(argv[0]);
2499 struct in_addr ia;
2500
Harald Welte4511d892010-04-18 15:51:20 +02002501 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002502 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2503 return CMD_WARNING;
2504 }
2505
Harald Welteaf387632010-03-14 23:30:30 +08002506 inet_aton(argv[1], &ia);
2507 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2508
2509 return CMD_SUCCESS;
2510}
2511
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002512DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002513 "paging free <-1-1024>",
2514 "Paging options\n"
2515 "Only page when having a certain amount of free slots\n"
2516 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002517{
2518 struct gsm_bts *bts = vty->index;
2519
2520 bts->paging.free_chans_need = atoi(argv[0]);
2521 return CMD_SUCCESS;
2522}
2523
Harald Welte615e9562010-05-11 23:50:21 +02002524DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2525 "gprs ns timer " NS_TIMERS " <0-255>",
2526 GPRS_TEXT "Network Service\n"
2527 "Network Service Timer\n"
2528 NS_TIMERS_HELP "Timer Value\n")
2529{
2530 struct gsm_bts *bts = vty->index;
2531 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2532 int val = atoi(argv[1]);
2533
2534 if (bts->gprs.mode == BTS_GPRS_NONE) {
2535 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2536 return CMD_WARNING;
2537 }
2538
2539 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2540 return CMD_WARNING;
2541
2542 bts->gprs.nse.timer[idx] = val;
2543
2544 return CMD_SUCCESS;
2545}
2546
2547#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 +02002548#define BSSGP_TIMERS_HELP \
2549 "Tbvc-block timeout\n" \
2550 "Tbvc-block retries\n" \
2551 "Tbvc-unblock retries\n" \
2552 "Tbvcc-reset timeout\n" \
2553 "Tbvc-reset retries\n" \
2554 "Tbvc-suspend timeout\n" \
2555 "Tbvc-suspend retries\n" \
2556 "Tbvc-resume timeout\n" \
2557 "Tbvc-resume retries\n" \
2558 "Tbvc-capa-update timeout\n" \
2559 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002560
2561DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2562 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2563 GPRS_TEXT "Cell / BSSGP\n"
2564 "Cell/BSSGP Timer\n"
2565 BSSGP_TIMERS_HELP "Timer Value\n")
2566{
2567 struct gsm_bts *bts = vty->index;
2568 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2569 int val = atoi(argv[1]);
2570
2571 if (bts->gprs.mode == BTS_GPRS_NONE) {
2572 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2573 return CMD_WARNING;
2574 }
2575
2576 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2577 return CMD_WARNING;
2578
2579 bts->gprs.cell.timer[idx] = val;
2580
2581 return CMD_SUCCESS;
2582}
2583
Harald Welte97a282b2010-03-14 15:37:43 +08002584DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2585 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002586 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002587 "GPRS Routing Area Code\n"
2588 "GPRS Routing Area Code\n"
2589 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002590{
2591 struct gsm_bts *bts = vty->index;
2592
Harald Welte4511d892010-04-18 15:51:20 +02002593 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002594 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2595 return CMD_WARNING;
2596 }
2597
Harald Welte97a282b2010-03-14 15:37:43 +08002598 bts->gprs.rac = atoi(argv[0]);
2599
2600 return CMD_SUCCESS;
2601}
2602
Max292ec582016-07-28 11:55:37 +02002603DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2604 "gprs control-ack-type-rach", GPRS_TEXT
2605 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2606 "four access bursts format instead of default RLC/MAC control block\n")
2607{
2608 struct gsm_bts *bts = vty->index;
2609
2610 if (bts->gprs.mode == BTS_GPRS_NONE) {
2611 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2612 return CMD_WARNING;
2613 }
2614
2615 bts->gprs.ctrl_ack_type_use_block = false;
2616
2617 return CMD_SUCCESS;
2618}
2619
2620DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2621 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2622 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2623 "four access bursts format instead of default RLC/MAC control block\n")
2624{
2625 struct gsm_bts *bts = vty->index;
2626
2627 if (bts->gprs.mode == BTS_GPRS_NONE) {
2628 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2629 return CMD_WARNING;
2630 }
2631
2632 bts->gprs.ctrl_ack_type_use_block = true;
2633
2634 return CMD_SUCCESS;
2635}
2636
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002637DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2638 "gprs network-control-order (nc0|nc1|nc2)",
2639 GPRS_TEXT
2640 "GPRS Network Control Order\n"
2641 "MS controlled cell re-selection, no measurement reporting\n"
2642 "MS controlled cell re-selection, MS sends measurement reports\n"
2643 "Network controlled cell re-selection, MS sends measurement reports\n")
2644{
2645 struct gsm_bts *bts = vty->index;
2646
2647 if (bts->gprs.mode == BTS_GPRS_NONE) {
2648 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2649 return CMD_WARNING;
2650 }
2651
2652 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2653
2654 return CMD_SUCCESS;
2655}
2656
Harald Welte4511d892010-04-18 15:51:20 +02002657DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2658 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002659 GPRS_TEXT
2660 "GPRS Mode for this BTS\n"
2661 "GPRS Disabled on this BTS\n"
2662 "GPRS Enabled on this BTS\n"
2663 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002664{
2665 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002666 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002667
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002668 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002669 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2670 VTY_NEWLINE);
2671 return CMD_WARNING;
2672 }
2673
2674 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002675
2676 return CMD_SUCCESS;
2677}
2678
bhargava350533c2016-07-21 11:14:34 +05302679DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2680 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2681 "gprs 11bit_rach_support_for_egprs (0|1)",
2682 GPRS_TEXT "11 bit RACH options\n"
2683 "Disable 11 bit RACH for EGPRS\n"
2684 "Enable 11 bit RACH for EGPRS")
2685{
2686 struct gsm_bts *bts = vty->index;
2687
2688 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2689
2690 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2691 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2692 return CMD_WARNING;
2693 }
2694
2695 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2696 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2697 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2698 " enabled%s", VTY_NEWLINE);
2699 return CMD_WARNING;
2700 }
2701
2702 return CMD_SUCCESS;
2703}
2704
Harald Welte9fbff4a2010-07-30 11:50:09 +02002705#define SI_TEXT "System Information Messages\n"
2706#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)"
2707#define SI_TYPE_HELP "System Information Type 1\n" \
2708 "System Information Type 2\n" \
2709 "System Information Type 3\n" \
2710 "System Information Type 4\n" \
2711 "System Information Type 5\n" \
2712 "System Information Type 6\n" \
2713 "System Information Type 7\n" \
2714 "System Information Type 8\n" \
2715 "System Information Type 9\n" \
2716 "System Information Type 10\n" \
2717 "System Information Type 13\n" \
2718 "System Information Type 16\n" \
2719 "System Information Type 17\n" \
2720 "System Information Type 18\n" \
2721 "System Information Type 19\n" \
2722 "System Information Type 20\n" \
2723 "System Information Type 2bis\n" \
2724 "System Information Type 2ter\n" \
2725 "System Information Type 2quater\n" \
2726 "System Information Type 5bis\n" \
2727 "System Information Type 5ter\n"
2728
2729DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2730 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2731 SI_TEXT SI_TYPE_HELP
2732 "System Information Mode\n"
2733 "Static user-specified\n"
2734 "Dynamic, BSC-computed\n")
2735{
2736 struct gsm_bts *bts = vty->index;
2737 int type;
2738
2739 type = get_string_value(osmo_sitype_strs, argv[0]);
2740 if (type < 0) {
2741 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2742 return CMD_WARNING;
2743 }
2744
2745 if (!strcmp(argv[1], "static"))
2746 bts->si_mode_static |= (1 << type);
2747 else
2748 bts->si_mode_static &= ~(1 << type);
2749
2750 return CMD_SUCCESS;
2751}
2752
2753DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2754 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2755 SI_TEXT SI_TYPE_HELP
2756 "Static System Information filling\n"
2757 "Static user-specified SI content in HEX notation\n")
2758{
2759 struct gsm_bts *bts = vty->index;
2760 int rc, type;
2761
2762 type = get_string_value(osmo_sitype_strs, argv[0]);
2763 if (type < 0) {
2764 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2765 return CMD_WARNING;
2766 }
2767
2768 if (!(bts->si_mode_static & (1 << type))) {
2769 vty_out(vty, "SI Type %s is not configured in static mode%s",
2770 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2771 return CMD_WARNING;
2772 }
2773
Harald Welte290aaed2010-07-30 11:53:18 +02002774 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002775 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002776
2777 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002778 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2779 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002780 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2781 return CMD_WARNING;
2782 }
2783
2784 /* Mark this SI as present */
2785 bts->si_valid |= (1 << type);
2786
2787 return CMD_SUCCESS;
2788}
2789
Harald Welte42def722017-01-13 00:10:32 +01002790DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2791 "early-classmark-sending (allowed|forbidden)",
2792 "Early Classmark Sending\n"
2793 "Early Classmark Sending is allowed\n"
2794 "Early Classmark Sending is forbidden\n")
2795{
2796 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002797
2798 if (!strcmp(argv[0], "allowed"))
2799 bts->early_classmark_allowed = true;
2800 else
2801 bts->early_classmark_allowed = false;
2802
2803 return CMD_SUCCESS;
2804}
2805
Harald Welte32c09622011-01-11 23:44:56 +01002806DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002807 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002808 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002809 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2810 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002811{
2812 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002813 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002814
Harald Welte64c07d22011-02-15 11:43:27 +01002815 switch (mode) {
2816 case NL_MODE_MANUAL_SI5SEP:
2817 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002818 /* make sure we clear the current list when switching to
2819 * manual mode */
2820 if (bts->neigh_list_manual_mode == 0)
2821 memset(&bts->si_common.data.neigh_list, 0,
2822 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002823 break;
2824 default:
2825 break;
2826 }
2827
2828 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002829
2830 return CMD_SUCCESS;
2831}
2832
2833DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002834 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002835 "Neighbor List\n" "Add to manual neighbor list\n"
2836 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2837 "ARFCN of neighbor\n")
2838{
2839 struct gsm_bts *bts = vty->index;
2840 struct bitvec *bv = &bts->si_common.neigh_list;
2841 uint16_t arfcn = atoi(argv[1]);
2842
2843 if (!bts->neigh_list_manual_mode) {
2844 vty_out(vty, "%% Cannot configure neighbor list in "
2845 "automatic mode%s", VTY_NEWLINE);
2846 return CMD_WARNING;
2847 }
2848
2849 if (!strcmp(argv[0], "add"))
2850 bitvec_set_bit_pos(bv, arfcn, 1);
2851 else
2852 bitvec_set_bit_pos(bv, arfcn, 0);
2853
2854 return CMD_SUCCESS;
2855}
2856
Max70fdd242017-06-15 15:10:53 +02002857/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002858DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002859 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2860 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2861 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2862 "Add to manual SI2quater neighbor list\n"
2863 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2864 "threshold high bits\n" "threshold high bits\n"
2865 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2866 "priority\n" "priority (8 means NA)\n"
2867 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2868 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002869{
2870 struct gsm_bts *bts = vty->index;
2871 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2872 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002873 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2874 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002875 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002876
Max70fdd242017-06-15 15:10:53 +02002877 switch (r) {
2878 case 1:
2879 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2880 thresh_hi, VTY_NEWLINE);
2881 break;
2882 case EARFCN_THRESH_LOW_INVALID:
2883 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2884 thresh_lo, VTY_NEWLINE);
2885 break;
2886 case EARFCN_QRXLV_INVALID + 1:
2887 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2888 qrx, VTY_NEWLINE);
2889 break;
2890 case EARFCN_PRIO_INVALID:
2891 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
2892 prio, VTY_NEWLINE);
2893 break;
2894 default:
2895 if (r < 0) {
2896 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
2897 return CMD_WARNING;
2898 }
Max59a1bf32016-04-15 16:04:46 +02002899 }
2900
Max70fdd242017-06-15 15:10:53 +02002901 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01002902 return CMD_SUCCESS;
2903
Maxf39d03a2017-05-12 17:00:30 +02002904 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02002905 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02002906 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01002907
Maxaafff962016-04-20 15:57:14 +02002908 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02002909}
2910
2911DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02002912 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02002913 "SI2quater Neighbor List\n"
2914 "SI2quater Neighbor List\n"
2915 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02002916 "EARFCN of neighbor\n"
2917 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02002918{
2919 struct gsm_bts *bts = vty->index;
2920 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02002921 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02002922 int r = osmo_earfcn_del(e, arfcn);
2923 if (r < 0) {
2924 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02002925 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02002926 return CMD_WARNING;
2927 }
2928
2929 return CMD_SUCCESS;
2930}
2931
Max26679e02016-04-20 15:57:13 +02002932DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02002933 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02002934 "SI2quater Neighbor List\n"
2935 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
2936 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
2937 "diversity bit\n")
2938{
2939 struct gsm_bts *bts = vty->index;
2940 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
2941
2942 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
2943 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02002944 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 +01002945 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02002946 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02002947 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
2948 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01002949 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02002950 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02002951 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02002952 return CMD_WARNING;
2953 }
2954
2955 return CMD_SUCCESS;
2956}
2957
2958DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02002959 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02002960 "SI2quater Neighbor List\n"
2961 "SI2quater Neighbor List\n"
2962 "Delete from SI2quater manual neighbor list\n"
2963 "UARFCN of neighbor\n"
2964 "UARFCN\n"
2965 "scrambling code\n")
2966{
2967 struct gsm_bts *bts = vty->index;
2968
2969 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
2970 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
2971 VTY_NEWLINE);
2972 return CMD_WARNING;
2973 }
2974
2975 return CMD_SUCCESS;
2976}
2977
Harald Welte64c07d22011-02-15 11:43:27 +01002978DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002979 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002980 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002981 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
2982 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
2983 "ARFCN of neighbor\n")
2984{
2985 struct gsm_bts *bts = vty->index;
2986 struct bitvec *bv = &bts->si_common.si5_neigh_list;
2987 uint16_t arfcn = atoi(argv[1]);
2988
2989 if (!bts->neigh_list_manual_mode) {
2990 vty_out(vty, "%% Cannot configure neighbor list in "
2991 "automatic mode%s", VTY_NEWLINE);
2992 return CMD_WARNING;
2993 }
2994
2995 if (!strcmp(argv[0], "add"))
2996 bitvec_set_bit_pos(bv, arfcn, 1);
2997 else
2998 bitvec_set_bit_pos(bv, arfcn, 0);
2999
3000 return CMD_SUCCESS;
3001}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003002
Harald Welte8254cf72017-05-29 13:42:19 +02003003DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3004 "pcu-socket PATH",
3005 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3006 "Path in the file system for the unix-domain PCU socket\n")
3007{
3008 struct gsm_bts *bts = vty->index;
3009 int rc;
3010
Harald Welte4a824ca2017-05-29 13:54:27 +02003011 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003012 pcu_sock_exit(bts);
3013 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3014 if (rc < 0) {
3015 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3016 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3017 return CMD_WARNING;
3018 }
3019
3020 return CMD_SUCCESS;
3021}
3022
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003023#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3024
3025DEFUN(cfg_bts_excl_rf_lock,
3026 cfg_bts_excl_rf_lock_cmd,
3027 "rf-lock-exclude",
3028 EXCL_RFLOCK_STR)
3029{
3030 struct gsm_bts *bts = vty->index;
3031 bts->excl_from_rf_lock = 1;
3032 return CMD_SUCCESS;
3033}
3034
3035DEFUN(cfg_bts_no_excl_rf_lock,
3036 cfg_bts_no_excl_rf_lock_cmd,
3037 "no rf-lock-exclude",
3038 NO_STR EXCL_RFLOCK_STR)
3039{
3040 struct gsm_bts *bts = vty->index;
3041 bts->excl_from_rf_lock = 0;
3042 return CMD_SUCCESS;
3043}
3044
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003045#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3046
3047DEFUN(cfg_bts_force_comb_si,
3048 cfg_bts_force_comb_si_cmd,
3049 "force-combined-si",
3050 FORCE_COMB_SI_STR)
3051{
3052 struct gsm_bts *bts = vty->index;
3053 bts->force_combined_si = 1;
3054 return CMD_SUCCESS;
3055}
3056
3057DEFUN(cfg_bts_no_force_comb_si,
3058 cfg_bts_no_force_comb_si_cmd,
3059 "no force-combined-si",
3060 NO_STR FORCE_COMB_SI_STR)
3061{
3062 struct gsm_bts *bts = vty->index;
3063 bts->force_combined_si = 0;
3064 return CMD_SUCCESS;
3065}
3066
Andreas Eversberga83d5112013-12-07 18:32:28 +01003067static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3068{
3069 struct gsm_bts *bts = vty->index;
3070 struct bts_codec_conf *codec = &bts->codec;
3071 int i;
3072
3073 codec->hr = 0;
3074 codec->efr = 0;
3075 codec->amr = 0;
3076 for (i = 0; i < argc; i++) {
3077 if (!strcmp(argv[i], "hr"))
3078 codec->hr = 1;
3079 if (!strcmp(argv[i], "efr"))
3080 codec->efr = 1;
3081 if (!strcmp(argv[i], "amr"))
3082 codec->amr = 1;
3083 }
3084}
3085
3086#define CODEC_PAR_STR " (hr|efr|amr)"
3087#define CODEC_HELP_STR "Half Rate\n" \
3088 "Enhanced Full Rate\nAdaptive Multirate\n"
3089
3090DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3091 "codec-support fr",
3092 "Codec Support settings\nFullrate\n")
3093{
3094 _get_codec_from_arg(vty, 0, argv);
3095 return CMD_SUCCESS;
3096}
3097
3098DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3099 "codec-support fr" CODEC_PAR_STR,
3100 "Codec Support settings\nFullrate\n"
3101 CODEC_HELP_STR)
3102{
3103 _get_codec_from_arg(vty, 1, argv);
3104 return CMD_SUCCESS;
3105}
3106
3107DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3108 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3109 "Codec Support settings\nFullrate\n"
3110 CODEC_HELP_STR CODEC_HELP_STR)
3111{
3112 _get_codec_from_arg(vty, 2, argv);
3113 return CMD_SUCCESS;
3114}
3115
3116DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3117 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3118 "Codec Support settings\nFullrate\n"
3119 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3120{
3121 _get_codec_from_arg(vty, 3, argv);
3122 return CMD_SUCCESS;
3123}
3124
3125DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3126 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3127 "Codec Support settings\nFullrate\n"
3128 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3129{
3130 _get_codec_from_arg(vty, 4, argv);
3131 return CMD_SUCCESS;
3132}
3133
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003134DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3135 "depends-on-bts <0-255>",
3136 "This BTS can only be started if another one is up\n" "BTS Number\n")
3137{
3138 struct gsm_bts *bts = vty->index;
3139 struct gsm_bts *other_bts;
3140 int dep = atoi(argv[0]);
3141
3142
3143 if (!is_ipaccess_bts(bts)) {
3144 vty_out(vty, "This feature is only available for IP systems.%s",
3145 VTY_NEWLINE);
3146 return CMD_WARNING;
3147 }
3148
3149 other_bts = gsm_bts_num(bts->network, dep);
3150 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3151 vty_out(vty, "This feature is only available for IP systems.%s",
3152 VTY_NEWLINE);
3153 return CMD_WARNING;
3154 }
3155
3156 if (dep >= bts->nr) {
3157 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3158 VTY_NEWLINE);
3159 return CMD_WARNING;
3160 }
3161
3162 bts_depend_mark(bts, dep);
3163 return CMD_SUCCESS;
3164}
3165
3166DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3167 "depeneds-on-bts <0-255>",
3168 NO_STR "This BTS can only be started if another one is up\n"
3169 "BTS Number\n")
3170{
3171 struct gsm_bts *bts = vty->index;
3172 int dep = atoi(argv[0]);
3173
3174 bts_depend_clear(bts, dep);
3175 return CMD_SUCCESS;
3176}
3177
Andreas Eversberg73266522014-01-19 11:47:44 +01003178#define AMR_TEXT "Adaptive Multi Rate settings\n"
3179#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3180#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3181 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3182#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3183#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3184
3185static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3186{
3187 struct gsm_bts *bts = vty->index;
3188 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3189 struct gsm48_multi_rate_conf *mr_conf =
3190 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3191 int i;
3192
3193 mr->gsm48_ie[1] = 0;
3194 for (i = 0; i < argc; i++)
3195 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3196 mr_conf->icmi = 0;
3197}
3198
3199static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3200{
3201 struct gsm_bts *bts = vty->index;
3202 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003203 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003204 int i;
3205
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003206 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3207 for (i = 0; i < argc - 1; i++)
3208 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003209}
3210
3211static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3212{
3213 struct gsm_bts *bts = vty->index;
3214 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003215 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003216 int i;
3217
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003218 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3219 for (i = 0; i < argc - 1; i++)
3220 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003221}
3222
3223static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3224{
3225 struct gsm_bts *bts = vty->index;
3226 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3227 struct gsm48_multi_rate_conf *mr_conf =
3228 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3229 int num = 0, i;
3230
3231 for (i = 0; i < ((full) ? 8 : 6); i++) {
3232 if ((mr->gsm48_ie[1] & (1 << i))) {
3233 num++;
3234 }
3235 }
3236
3237 if (argv[0][0] == 'a' || num == 0)
3238 mr_conf->icmi = 0;
3239 else {
3240 mr_conf->icmi = 1;
3241 if (num < atoi(argv[0]))
3242 mr_conf->smod = num - 1;
3243 else
3244 mr_conf->smod = atoi(argv[0]) - 1;
3245 }
3246}
3247
3248#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3249#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3250 "10,2k\n12,2k\n"
3251
3252#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3253#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3254
3255#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3256#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3257
3258DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3259 "amr tch-f modes" AMR_TCHF_PAR_STR,
3260 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3261 AMR_TCHF_HELP_STR)
3262{
3263 get_amr_from_arg(vty, 1, argv, 1);
3264 return CMD_SUCCESS;
3265}
3266
3267DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3268 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3269 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3270 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3271{
3272 get_amr_from_arg(vty, 2, argv, 1);
3273 return CMD_SUCCESS;
3274}
3275
3276DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3277 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3278 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3279 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3280{
3281 get_amr_from_arg(vty, 3, argv, 1);
3282 return CMD_SUCCESS;
3283}
3284
3285DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3286 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3287 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3288 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3289{
3290 get_amr_from_arg(vty, 4, argv, 1);
3291 return CMD_SUCCESS;
3292}
3293
3294DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3295 "amr tch-f start-mode (auto|1|2|3|4)",
3296 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3297{
3298 get_amr_start_from_arg(vty, argv, 1);
3299 return CMD_SUCCESS;
3300}
3301
3302DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3303 "amr tch-f threshold (ms|bts) <0-63>",
3304 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3305 AMR_TH_HELP_STR)
3306{
3307 get_amr_th_from_arg(vty, 2, argv, 1);
3308 return CMD_SUCCESS;
3309}
3310
3311DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3312 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3313 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3314 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3315{
3316 get_amr_th_from_arg(vty, 3, argv, 1);
3317 return CMD_SUCCESS;
3318}
3319
3320DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3321 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3322 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3323 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3324{
3325 get_amr_th_from_arg(vty, 4, argv, 1);
3326 return CMD_SUCCESS;
3327}
3328
3329DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3330 "amr tch-f hysteresis (ms|bts) <0-15>",
3331 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3332 AMR_HY_HELP_STR)
3333{
3334 get_amr_hy_from_arg(vty, 2, argv, 1);
3335 return CMD_SUCCESS;
3336}
3337
3338DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3339 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3340 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3341 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3342{
3343 get_amr_hy_from_arg(vty, 3, argv, 1);
3344 return CMD_SUCCESS;
3345}
3346
3347DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3348 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3349 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3350 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3351{
3352 get_amr_hy_from_arg(vty, 4, argv, 1);
3353 return CMD_SUCCESS;
3354}
3355
3356DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3357 "amr tch-h modes" AMR_TCHH_PAR_STR,
3358 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3359 AMR_TCHH_HELP_STR)
3360{
3361 get_amr_from_arg(vty, 1, argv, 0);
3362 return CMD_SUCCESS;
3363}
3364
3365DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3366 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3367 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3368 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3369{
3370 get_amr_from_arg(vty, 2, argv, 0);
3371 return CMD_SUCCESS;
3372}
3373
3374DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3375 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3376 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3377 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3378{
3379 get_amr_from_arg(vty, 3, argv, 0);
3380 return CMD_SUCCESS;
3381}
3382
3383DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3384 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3385 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3386 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3387{
3388 get_amr_from_arg(vty, 4, argv, 0);
3389 return CMD_SUCCESS;
3390}
3391
3392DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3393 "amr tch-h start-mode (auto|1|2|3|4)",
3394 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3395{
3396 get_amr_start_from_arg(vty, argv, 0);
3397 return CMD_SUCCESS;
3398}
3399
3400DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3401 "amr tch-h threshold (ms|bts) <0-63>",
3402 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3403 AMR_TH_HELP_STR)
3404{
3405 get_amr_th_from_arg(vty, 2, argv, 0);
3406 return CMD_SUCCESS;
3407}
3408
3409DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3410 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3411 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3412 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3413{
3414 get_amr_th_from_arg(vty, 3, argv, 0);
3415 return CMD_SUCCESS;
3416}
3417
3418DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3419 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3420 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3421 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3422{
3423 get_amr_th_from_arg(vty, 4, argv, 0);
3424 return CMD_SUCCESS;
3425}
3426
3427DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3428 "amr tch-h hysteresis (ms|bts) <0-15>",
3429 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3430 AMR_HY_HELP_STR)
3431{
3432 get_amr_hy_from_arg(vty, 2, argv, 0);
3433 return CMD_SUCCESS;
3434}
3435
3436DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3437 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3438 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3439 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3440{
3441 get_amr_hy_from_arg(vty, 3, argv, 0);
3442 return CMD_SUCCESS;
3443}
3444
3445DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3446 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3447 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3448 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3449{
3450 get_amr_hy_from_arg(vty, 4, argv, 0);
3451 return CMD_SUCCESS;
3452}
3453
Harald Welte8f0ed552010-05-11 21:53:49 +02003454#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003455
Harald Welte5258fc42009-03-28 19:07:53 +00003456/* per TRX configuration */
3457DEFUN(cfg_trx,
3458 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003459 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003460 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003461 "Select a TRX to configure")
3462{
3463 int trx_nr = atoi(argv[0]);
3464 struct gsm_bts *bts = vty->index;
3465 struct gsm_bts_trx *trx;
3466
Harald Weltee441d9c2009-06-21 16:17:15 +02003467 if (trx_nr > bts->num_trx) {
3468 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3469 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003470 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003471 } else if (trx_nr == bts->num_trx) {
3472 /* we need to allocate a new one */
3473 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003474 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003475 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003476
Harald Weltee441d9c2009-06-21 16:17:15 +02003477 if (!trx)
3478 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003479
3480 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003481 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003482 vty->node = TRX_NODE;
3483
3484 return CMD_SUCCESS;
3485}
3486
3487DEFUN(cfg_trx_arfcn,
3488 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003489 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003490 "Set the ARFCN for this TRX\n"
3491 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003492{
3493 int arfcn = atoi(argv[0]);
3494 struct gsm_bts_trx *trx = vty->index;
3495
3496 /* FIXME: check if this ARFCN is supported by this TRX */
3497
3498 trx->arfcn = arfcn;
3499
3500 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3501 /* FIXME: use OML layer to update the ARFCN */
3502 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3503
3504 return CMD_SUCCESS;
3505}
3506
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003507DEFUN(cfg_trx_nominal_power,
3508 cfg_trx_nominal_power_cmd,
3509 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003510 "Nominal TRX RF Power in dBm\n"
3511 "Nominal TRX RF Power in dBm\n"
3512 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003513{
3514 struct gsm_bts_trx *trx = vty->index;
3515
3516 trx->nominal_power = atoi(argv[0]);
3517
3518 return CMD_SUCCESS;
3519}
3520
Harald Weltefcd24452009-06-20 18:15:19 +02003521DEFUN(cfg_trx_max_power_red,
3522 cfg_trx_max_power_red_cmd,
3523 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003524 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003525 "Reduction of maximum BS RF Power in dB\n")
3526{
3527 int maxpwr_r = atoi(argv[0]);
3528 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003529 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003530
3531 /* FIXME: check if our BTS type supports more than 12 */
3532 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3533 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3534 maxpwr_r, VTY_NEWLINE);
3535 return CMD_WARNING;
3536 }
3537 if (maxpwr_r & 1) {
3538 vty_out(vty, "%% Power %d dB is not an even value%s",
3539 maxpwr_r, VTY_NEWLINE);
3540 return CMD_WARNING;
3541 }
3542
3543 trx->max_power_red = maxpwr_r;
3544
3545 /* FIXME: make sure we update this using OML */
3546
3547 return CMD_SUCCESS;
3548}
3549
Harald Welte42581822009-08-08 16:12:58 +02003550DEFUN(cfg_trx_rsl_e1,
3551 cfg_trx_rsl_e1_cmd,
3552 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003553 "RSL Parameters\n"
3554 "E1/T1 interface to be used for RSL\n"
3555 "E1/T1 interface to be used for RSL\n"
3556 "E1/T1 Line Number to be used for RSL\n"
3557 "E1/T1 Timeslot to be used for RSL\n"
3558 "E1/T1 Timeslot to be used for RSL\n"
3559 "E1/T1 Sub-slot to be used for RSL\n"
3560 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3561 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3562 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3563 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3564 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003565{
3566 struct gsm_bts_trx *trx = vty->index;
3567
3568 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3569
3570 return CMD_SUCCESS;
3571}
3572
3573DEFUN(cfg_trx_rsl_e1_tei,
3574 cfg_trx_rsl_e1_tei_cmd,
3575 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003576 "RSL Parameters\n"
3577 "Set the TEI to be used for RSL\n"
3578 "Set the TEI to be used for RSL\n"
3579 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003580{
3581 struct gsm_bts_trx *trx = vty->index;
3582
3583 trx->rsl_tei = atoi(argv[0]);
3584
3585 return CMD_SUCCESS;
3586}
3587
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003588DEFUN(cfg_trx_rf_locked,
3589 cfg_trx_rf_locked_cmd,
3590 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003591 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3592 "TRX is NOT RF locked (active)\n"
3593 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003594{
3595 int locked = atoi(argv[0]);
3596 struct gsm_bts_trx *trx = vty->index;
3597
3598 gsm_trx_lock_rf(trx, locked);
3599 return CMD_SUCCESS;
3600}
Harald Welte42581822009-08-08 16:12:58 +02003601
Harald Welte5258fc42009-03-28 19:07:53 +00003602/* per TS configuration */
3603DEFUN(cfg_ts,
3604 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003605 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003606 "Select a Timeslot to configure\n"
3607 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003608{
3609 int ts_nr = atoi(argv[0]);
3610 struct gsm_bts_trx *trx = vty->index;
3611 struct gsm_bts_trx_ts *ts;
3612
3613 if (ts_nr >= TRX_NR_TS) {
3614 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3615 TRX_NR_TS, VTY_NEWLINE);
3616 return CMD_WARNING;
3617 }
3618
3619 ts = &trx->ts[ts_nr];
3620
3621 vty->index = ts;
3622 vty->node = TS_NODE;
3623
3624 return CMD_SUCCESS;
3625}
3626
Harald Weltea6fd58e2009-08-07 00:25:23 +02003627DEFUN(cfg_ts_pchan,
3628 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003629 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003630 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003631{
3632 struct gsm_bts_trx_ts *ts = vty->index;
3633 int pchanc;
3634
3635 pchanc = gsm_pchan_parse(argv[0]);
3636 if (pchanc < 0)
3637 return CMD_WARNING;
3638
3639 ts->pchan = pchanc;
3640
3641 return CMD_SUCCESS;
3642}
3643
3644/* used for backwards compatibility with old config files that still
3645 * have uppercase pchan type names */
3646DEFUN_HIDDEN(cfg_ts_pchan_compat,
3647 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003648 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003649 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003650{
3651 struct gsm_bts_trx_ts *ts = vty->index;
3652 int pchanc;
3653
3654 pchanc = gsm_pchan_parse(argv[0]);
3655 if (pchanc < 0)
3656 return CMD_WARNING;
3657
3658 ts->pchan = pchanc;
3659
3660 return CMD_SUCCESS;
3661}
3662
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003663
3664
Harald Welte135a6482011-05-30 12:09:13 +02003665DEFUN(cfg_ts_tsc,
3666 cfg_ts_tsc_cmd,
3667 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003668 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003669{
3670 struct gsm_bts_trx_ts *ts = vty->index;
3671
Max71d082b2017-05-30 15:03:38 +02003672 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003673 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3674 "falling back to BCC%s", VTY_NEWLINE);
3675 ts->tsc = -1;
3676 return CMD_WARNING;
3677 }
3678
Harald Welte135a6482011-05-30 12:09:13 +02003679 ts->tsc = atoi(argv[0]);
3680
3681 return CMD_SUCCESS;
3682}
3683
Harald Weltea39b0f22010-06-14 22:26:10 +02003684#define HOPPING_STR "Configure frequency hopping\n"
3685
3686DEFUN(cfg_ts_hopping,
3687 cfg_ts_hopping_cmd,
3688 "hopping enabled (0|1)",
3689 HOPPING_STR "Enable or disable frequency hopping\n"
3690 "Disable frequency hopping\n" "Enable frequency hopping\n")
3691{
3692 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003693 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003694
Max71d082b2017-05-30 15:03:38 +02003695 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003696 vty_out(vty, "BTS model does not support hopping%s",
3697 VTY_NEWLINE);
3698 return CMD_WARNING;
3699 }
3700
3701 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003702
3703 return CMD_SUCCESS;
3704}
3705
Harald Welte6e0cd042009-09-12 13:05:33 +02003706DEFUN(cfg_ts_hsn,
3707 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003708 "hopping sequence-number <0-63>",
3709 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003710 "Which hopping sequence to use for this channel\n"
3711 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003712{
3713 struct gsm_bts_trx_ts *ts = vty->index;
3714
3715 ts->hopping.hsn = atoi(argv[0]);
3716
3717 return CMD_SUCCESS;
3718}
3719
3720DEFUN(cfg_ts_maio,
3721 cfg_ts_maio_cmd,
3722 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003723 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003724 "Which hopping MAIO to use for this channel\n"
3725 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003726{
3727 struct gsm_bts_trx_ts *ts = vty->index;
3728
3729 ts->hopping.maio = atoi(argv[0]);
3730
3731 return CMD_SUCCESS;
3732}
3733
3734DEFUN(cfg_ts_arfcn_add,
3735 cfg_ts_arfcn_add_cmd,
3736 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003737 HOPPING_STR "Configure hopping ARFCN list\n"
3738 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003739{
3740 struct gsm_bts_trx_ts *ts = vty->index;
3741 int arfcn = atoi(argv[0]);
3742
Harald Weltea39b0f22010-06-14 22:26:10 +02003743 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3744
Harald Welte6e0cd042009-09-12 13:05:33 +02003745 return CMD_SUCCESS;
3746}
3747
3748DEFUN(cfg_ts_arfcn_del,
3749 cfg_ts_arfcn_del_cmd,
3750 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003751 HOPPING_STR "Configure hopping ARFCN list\n"
3752 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003753{
3754 struct gsm_bts_trx_ts *ts = vty->index;
3755 int arfcn = atoi(argv[0]);
3756
Harald Weltea39b0f22010-06-14 22:26:10 +02003757 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3758
Harald Welte6e0cd042009-09-12 13:05:33 +02003759 return CMD_SUCCESS;
3760}
3761
Harald Weltea6fd58e2009-08-07 00:25:23 +02003762DEFUN(cfg_ts_e1_subslot,
3763 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003764 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003765 "E1/T1 channel connected to this on-air timeslot\n"
3766 "E1/T1 channel connected to this on-air timeslot\n"
3767 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003768 "E1/T1 timeslot connected to this on-air timeslot\n"
3769 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003770 "E1/T1 sub-slot connected to this on-air timeslot\n"
3771 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3772 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3773 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3774 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3775 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003776{
3777 struct gsm_bts_trx_ts *ts = vty->index;
3778
Harald Welte42581822009-08-08 16:12:58 +02003779 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003780
3781 return CMD_SUCCESS;
3782}
Harald Welte5258fc42009-03-28 19:07:53 +00003783
Harald Welte4f10c252010-05-16 21:47:13 +02003784void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3785{
3786 vty_out(vty, "Channel Requests : %lu total, %lu no channel%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003787 net->bsc_ctrs->ctr[BSC_CTR_CHREQ_TOTAL].current,
3788 net->bsc_ctrs->ctr[BSC_CTR_CHREQ_NO_CHANNEL].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003789 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003790 vty_out(vty, "Channel Failures : %lu rf_failures, %lu rll failures%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003791 net->bsc_ctrs->ctr[BSC_CTR_CHAN_RF_FAIL].current,
3792 net->bsc_ctrs->ctr[BSC_CTR_CHAN_RLL_ERR].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003793 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003794 vty_out(vty, "Paging : %lu attempted, %lu complete, %lu expired%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003795 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
3796 net->bsc_ctrs->ctr[BSC_CTR_PAGING_COMPLETED].current,
3797 net->bsc_ctrs->ctr[BSC_CTR_PAGING_EXPIRED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003798 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003799 vty_out(vty, "BTS failures : %lu OML, %lu RSL%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003800 net->bsc_ctrs->ctr[BSC_CTR_BTS_OML_FAIL].current,
3801 net->bsc_ctrs->ctr[BSC_CTR_BTS_RSL_FAIL].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003802 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003803}
3804
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003805DEFUN(drop_bts,
3806 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003807 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003808 "Debug/Simulation command to drop Abis/IP BTS\n"
3809 "Debug/Simulation command to drop Abis/IP BTS\n"
3810 "Debug/Simulation command to drop Abis/IP BTS\n"
3811 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003812{
3813 struct gsm_network *gsmnet;
3814 struct gsm_bts_trx *trx;
3815 struct gsm_bts *bts;
3816 unsigned int bts_nr;
3817
3818 gsmnet = gsmnet_from_vty(vty);
3819
3820 bts_nr = atoi(argv[0]);
3821 if (bts_nr >= gsmnet->num_bts) {
3822 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3823 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3824 return CMD_WARNING;
3825 }
3826
3827 bts = gsm_bts_num(gsmnet, bts_nr);
3828 if (!bts) {
3829 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3830 return CMD_WARNING;
3831 }
3832
3833 if (!is_ipaccess_bts(bts)) {
3834 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3835 return CMD_WARNING;
3836 }
3837
3838
3839 /* close all connections */
3840 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003841 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003842 } else if (strcmp(argv[1], "rsl") == 0) {
3843 /* close all rsl connections */
3844 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003845 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003846 }
3847 } else {
3848 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3849 return CMD_WARNING;
3850 }
3851
3852 return CMD_SUCCESS;
3853}
3854
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003855DEFUN(restart_bts, restart_bts_cmd,
3856 "restart-bts <0-65535>",
3857 "Restart ip.access nanoBTS through OML\n"
3858 "BTS Number\n")
3859{
3860 struct gsm_network *gsmnet;
3861 struct gsm_bts_trx *trx;
3862 struct gsm_bts *bts;
3863 unsigned int bts_nr;
3864
3865 gsmnet = gsmnet_from_vty(vty);
3866
3867 bts_nr = atoi(argv[0]);
3868 if (bts_nr >= gsmnet->num_bts) {
3869 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3870 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3871 return CMD_WARNING;
3872 }
3873
3874 bts = gsm_bts_num(gsmnet, bts_nr);
3875 if (!bts) {
3876 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3877 return CMD_WARNING;
3878 }
3879
3880 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3881 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3882 VTY_NEWLINE);
3883 return CMD_WARNING;
3884 }
3885
3886 /* go from last TRX to c0 */
3887 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3888 abis_nm_ipaccess_restart(trx);
3889
3890 return CMD_SUCCESS;
3891}
3892
Harald Welted36641a2017-07-10 20:25:10 +02003893DEFUN(bts_resend, bts_resend_cmd,
3894 "bts <0-255> resend-system-information",
3895 "BTS Specific Commands\n" "BTS Number\n"
3896 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3897{
3898 struct gsm_network *gsmnet;
3899 struct gsm_bts_trx *trx;
3900 struct gsm_bts *bts;
3901 unsigned int bts_nr;
3902
3903 gsmnet = gsmnet_from_vty(vty);
3904
3905 bts_nr = atoi(argv[0]);
3906 if (bts_nr >= gsmnet->num_bts) {
3907 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3908 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3909 return CMD_WARNING;
3910 }
3911
3912 bts = gsm_bts_num(gsmnet, bts_nr);
3913 if (!bts) {
3914 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3915 return CMD_WARNING;
3916 }
3917
3918 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3919 gsm_bts_trx_set_system_infos(trx);
3920
3921 return CMD_SUCCESS;
3922}
3923
3924
Harald Welte30f1f372014-12-28 15:00:45 +01003925DEFUN(smscb_cmd, smscb_cmd_cmd,
3926 "bts <0-255> smscb-command <1-4> HEXSTRING",
3927 "BTS related commands\n" "BTS Number\n"
3928 "SMS Cell Broadcast\n" "Last Valid Block\n"
3929 "Hex Encoded SMSCB message (up to 88 octets)\n")
3930{
3931 struct gsm_bts *bts;
3932 int bts_nr = atoi(argv[0]);
3933 int last_block = atoi(argv[1]);
3934 struct rsl_ie_cb_cmd_type cb_cmd;
3935 uint8_t buf[88];
3936 int rc;
3937
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02003938 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01003939 if (!bts) {
3940 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3941 return CMD_WARNING;
3942 }
3943 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
3944 if (rc < 0 || rc > sizeof(buf)) {
3945 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3946 return CMD_WARNING;
3947 }
3948
3949 cb_cmd.spare = 0;
3950 cb_cmd.def_bcast = 0;
3951 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
3952
3953 switch (last_block) {
3954 case 1:
3955 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
3956 break;
3957 case 2:
3958 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
3959 break;
3960 case 3:
3961 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
3962 break;
3963 case 4:
3964 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
3965 break;
3966 }
3967
3968 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
3969
3970 return CMD_SUCCESS;
3971}
3972
Harald Welte7fe00fb2017-05-27 14:09:50 +02003973/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02003974static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
3975 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02003976{
Harald Welte645eb622017-05-27 15:52:58 +02003977 int bts_nr = atoi(bts_str);
3978 int trx_nr = atoi(trx_str);
3979 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003980 struct gsm_bts *bts;
3981 struct gsm_bts_trx *trx;
3982 struct gsm_bts_trx_ts *ts;
3983
3984 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
3985 if (!bts) {
3986 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3987 return NULL;
3988 }
3989
3990 trx = gsm_bts_trx_num(bts, trx_nr);
3991 if (!trx) {
3992 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
3993 return NULL;
3994 }
3995
3996 ts = &trx->ts[ts_nr];
3997
3998 return ts;
3999}
Harald Welte30f1f372014-12-28 15:00:45 +01004000
Harald Welted0d2b0b2010-12-23 13:18:07 +01004001DEFUN(pdch_act, pdch_act_cmd,
4002 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
4003 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4004 "TRX Timeslot\n" "Timeslot Number\n" "Packet Data Channel\n"
4005 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4006 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4007{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004008 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004009 int activate;
4010
Harald Welte645eb622017-05-27 15:52:58 +02004011 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004012 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004013 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004014
Harald Welte7fe00fb2017-05-27 14:09:50 +02004015 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004016 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4017 VTY_NEWLINE);
4018 return CMD_WARNING;
4019 }
4020
Harald Welted0d2b0b2010-12-23 13:18:07 +01004021 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4022 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004023 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004024 return CMD_WARNING;
4025 }
4026
4027 if (!strcmp(argv[3], "activate"))
4028 activate = 1;
4029 else
4030 activate = 0;
4031
4032 rsl_ipacc_pdch_activate(ts, activate);
4033
4034 return CMD_SUCCESS;
4035
4036}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004037
Harald Welte2abd5e12017-05-27 14:10:40 +02004038/* determine the logical channel type based on the physical channel type */
4039static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4040{
4041 switch (pchan) {
4042 case GSM_PCHAN_TCH_F:
4043 return GSM_LCHAN_TCH_F;
4044 case GSM_PCHAN_TCH_H:
4045 return GSM_LCHAN_TCH_H;
4046 case GSM_PCHAN_SDCCH8_SACCH8C:
4047 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4048 case GSM_PCHAN_CCCH_SDCCH4:
4049 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4050 return GSM_LCHAN_SDCCH;
4051 default:
4052 return -1;
4053 }
4054}
4055
4056/* configure the lchan for a single AMR mode (as specified) */
4057static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4058{
4059 struct amr_multirate_conf mr;
4060 struct gsm48_multi_rate_conf *mr_conf;
4061 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4062
4063 if (amr_mode > 7)
4064 return -1;
4065
4066 memset(&mr, 0, sizeof(mr));
4067 mr_conf->ver = 1;
4068 /* bit-mask of supported modes, only one bit is set. Reflects
4069 * Figure 10.5.2.47a where there are no thershold and only a
4070 * single mode */
4071 mr.gsm48_ie[1] = 1 << amr_mode;
4072
4073 mr.ms_mode[0].mode = amr_mode;
4074 mr.bts_mode[0].mode = amr_mode;
4075
4076 /* encode this configuration into the lchan for both uplink and
4077 * downlink direction */
4078 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4079 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4080
4081 return 0;
4082}
4083
4084/* Debug/Measurement command to activate a given logical channel
4085 * manually in a given mode/codec. This is useful for receiver
4086 * performance testing (FER/RBER/...) */
4087DEFUN(lchan_act, lchan_act_cmd,
4088 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
4089 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4090 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot Number\n" "Sub-Slot Number\n"
4091 "Manual Channel Activation (e.g. for BER test)\n"
4092 "Manual Channel Deactivation (e.g. for BER test)\n"
4093 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4094{
4095 struct gsm_bts_trx_ts *ts;
4096 struct gsm_lchan *lchan;
4097 int ss_nr = atoi(argv[3]);
4098 const char *act_str = argv[4];
4099 const char *codec_str = argv[5];
4100 int activate;
4101
4102 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4103 if (!ts)
4104 return CMD_WARNING;
4105
4106 lchan = &ts->lchan[ss_nr];
4107
4108 if (!strcmp(act_str, "activate"))
4109 activate = 1;
4110 else
4111 activate = 0;
4112
4113 if (ss_nr >= ts_subslots(ts)) {
4114 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4115 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4116 return CMD_WARNING;
4117 }
4118
4119 if (activate) {
4120 int lchan_t;
4121 if (lchan->state != LCHAN_S_NONE) {
4122 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4123 return CMD_WARNING;
4124 }
4125 lchan_t = lchan_type_by_pchan(ts->pchan);
4126 if (lchan_t < 0)
4127 return CMD_WARNING;
4128 /* configure the lchan */
4129 lchan->type = lchan_t;
4130 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4131 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4132 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4133 else if (!strcmp(codec_str, "efr"))
4134 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4135 else if (!strcmp(codec_str, "amr")) {
4136 int amr_mode;
4137 if (argc < 7) {
4138 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4139 return CMD_WARNING;
4140 }
4141 amr_mode = atoi(argv[6]);
4142 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4143 lchan_set_single_amr_mode(lchan, amr_mode);
4144 }
4145 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4146 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4147 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004148 } else {
4149 rsl_direct_rf_release(lchan);
4150 }
4151
4152 return CMD_SUCCESS;
4153}
4154
Harald Welte3f86c522017-05-27 15:53:28 +02004155DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4156 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
4157 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4158 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot\n" "Sub-Slot Number\n"
4159 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4160{
4161 struct gsm_bts_trx_ts *ts;
4162 struct gsm_lchan *lchan;
4163 int ss_nr = atoi(argv[3]);
4164 int port = atoi(argv[5]);
4165 struct in_addr ia;
4166 inet_aton(argv[4], &ia);
4167
4168 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4169 if (!ts)
4170 return CMD_WARNING;
4171
4172 lchan = &ts->lchan[ss_nr];
4173
4174 if (ss_nr >= ts_subslots(ts)) {
4175 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4176 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4177 return CMD_WARNING;
4178 }
4179
4180 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4181 inet_ntoa(ia), port, VTY_NEWLINE);
4182 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4183 return CMD_SUCCESS;
4184}
Harald Welte3fb8a7b2017-07-18 19:11:49 +02004185
4186DEFUN(ctrl_trap, ctrl_trap_cmd,
4187 "ctrl-interface generate-trap TRAP VALUE",
4188 "Commands related to the CTRL Interface\n"
4189 "Generate a TRAP for test purpose\n"
4190 "Identity/Name of the TRAP variable\n"
4191 "Value of the TRAP variable\n")
4192{
4193 struct gsm_network *net = gsmnet_from_vty(vty);
4194
4195 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4196 return CMD_SUCCESS;
4197}
4198
Harald Weltedcccb182010-05-16 20:52:23 +02004199extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004200
Maxdb0e3802017-01-12 19:35:11 +01004201int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004202{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004203 cfg_ts_pchan_cmd.string =
4204 vty_cmd_string_from_valstr(tall_bsc_ctx,
4205 gsm_pchant_names,
4206 "phys_chan_config (", "|", ")",
4207 VTY_DO_LOWER);
4208 cfg_ts_pchan_cmd.doc =
4209 vty_cmd_string_from_valstr(tall_bsc_ctx,
4210 gsm_pchant_descs,
4211 "Physical Channel Combination\n",
4212 "\n", "", 0);
4213
Harald Weltee555c2b2012-08-17 13:02:12 +02004214 cfg_bts_type_cmd.string =
4215 vty_cmd_string_from_valstr(tall_bsc_ctx,
4216 bts_type_names,
4217 "type (", "|", ")",
4218 VTY_DO_LOWER);
4219 cfg_bts_type_cmd.doc =
4220 vty_cmd_string_from_valstr(tall_bsc_ctx,
4221 bts_type_descs,
4222 "BTS Vendor/Type\n",
4223 "\n", "", 0);
4224
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +02004225 common_cs_vty_init(network, config_write_net);
Harald Weltee555c2b2012-08-17 13:02:12 +02004226
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004227 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004228 install_element_ve(&show_bts_cmd);
4229 install_element_ve(&show_trx_cmd);
4230 install_element_ve(&show_ts_cmd);
4231 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004232 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004233
Philipp Maier4b60d072017-04-09 12:32:51 +02004234 install_element_ve(&show_subscr_conn_cmd);
4235 install_element_ve(&handover_subscr_conn_cmd);
4236
Harald Welteb4d5b172010-05-12 16:10:35 +00004237 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004238 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004239
Maxdb0e3802017-01-12 19:35:11 +01004240 logging_vty_add_cmds(NULL);
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004241
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004242 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Weltebc814502009-12-19 21:41:52 +01004243 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Welteb720bd32009-12-21 16:51:50 +01004244 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
4245 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
4246 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
4247 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
4248 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
4249 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004250 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004251 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4252 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4253 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4254 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4255 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4256 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4257 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4258 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4259 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004260 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004261 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004262 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004263 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02004264
4265 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004266 install_node(&bts_node, config_write_bts);
Jacob Erlbeck36722e12013-10-29 09:30:30 +01004267 vty_install_default(BTS_NODE);
Harald Welte5258fc42009-03-28 19:07:53 +00004268 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004269 install_element(BTS_NODE, &cfg_description_cmd);
4270 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004271 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004272 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004273 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4274 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4275 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4276 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004277 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4278 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004279 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004280 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004281 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004282 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004283 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004284 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004285 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004286 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4287 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004288 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004289 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4290 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004291 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4292 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4293 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004294 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4295 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004296 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004297 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004298 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004299 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004300 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4301 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004302 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4303 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4304 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4305 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4306 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4307 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004308 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004309 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004310 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304311 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004312 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004313 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004314 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004315 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4316 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004317 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004318 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004319 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004320 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004321 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4322 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4323 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004324 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004325 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4326 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004327 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004328 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4329 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004330 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004331 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4332 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004333 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4334 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004335 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4336 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004337 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4338 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004339 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4340 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4341 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4342 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4343 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004344 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4345 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004346 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4347 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4348 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4349 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4350 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4351 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4352 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4353 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4354 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4355 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4356 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4357 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4358 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4359 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4360 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4361 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4362 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4363 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4364 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4365 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4366 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4367 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004368 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004369
Harald Welte5258fc42009-03-28 19:07:53 +00004370 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004371 install_node(&trx_node, dummy_config_write);
Jacob Erlbeck36722e12013-10-29 09:30:30 +01004372 vty_install_default(TRX_NODE);
Harald Welte5258fc42009-03-28 19:07:53 +00004373 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004374 install_element(TRX_NODE, &cfg_description_cmd);
4375 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004376 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004377 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004378 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4379 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004380 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004381
Harald Welte5258fc42009-03-28 19:07:53 +00004382 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004383 install_node(&ts_node, dummy_config_write);
Jacob Erlbeck36722e12013-10-29 09:30:30 +01004384 vty_install_default(TS_NODE);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004385 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004386 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004387 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004388 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004389 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4390 install_element(TS_NODE, &cfg_ts_maio_cmd);
4391 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4392 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004393 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004394
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004395 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004396 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welted36641a2017-07-10 20:25:10 +02004397 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004398 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004399 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004400 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004401 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welte3fb8a7b2017-07-18 19:11:49 +02004402 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004403
Harald Welte81c9b9c2010-05-31 16:40:40 +02004404 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004405 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004406 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004407 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004408
Harald Weltedcccb182010-05-16 20:52:23 +02004409 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004410
Harald Welte68628e82009-03-10 12:17:57 +00004411 return 0;
4412}