blob: abfff0cd533236d34408b5c94158cf458966049d [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 Welteb71147a2017-07-18 19:11:49 +020033#include <osmocom/ctrl/control_if.h>
Neels Hofmeyr7b656882017-07-09 22:09:18 +020034#include <osmocom/gsm/gsm48.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010035
Harald Welte68628e82009-03-10 12:17:57 +000036#include <arpa/inet.h>
37
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010038#include <osmocom/core/linuxlist.h>
Harald Welte68628e82009-03-10 12:17:57 +000039#include <openbsc/gsm_data.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020040#include <osmocom/abis/e1_input.h>
Harald Welte1bc77352009-03-10 19:47:51 +000041#include <openbsc/abis_nm.h>
Harald Welte4d54d0b2011-02-19 16:48:17 +010042#include <openbsc/abis_om2000.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010043#include <osmocom/core/utils.h>
44#include <osmocom/gsm/gsm_utils.h>
Harald Weltecdc59ff2011-05-23 20:42:26 +020045#include <osmocom/gsm/abis_nm.h>
Harald Welteb908cb72009-12-22 13:09:29 +010046#include <openbsc/chan_alloc.h>
Harald Welte8387a492009-12-22 21:43:14 +010047#include <openbsc/meas_rep.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>
Philipp Maier39f62bb2017-04-09 12:32:51 +020059#include <openbsc/handover.h>
Neels Hofmeyr7b656882017-07-09 22:09:18 +020060#include <openbsc/gsm_04_08_utils.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 Hofmeyrce4d88b2017-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 Weltea0d324b2017-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 Weltea43e0b42016-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 Weltea0d324b2017-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 Hofmeyrce4d88b2017-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
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001024static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1025{
1026 if (strlen(bsub->imsi))
1027 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1028 if (bsub->tmsi != GSM_RESERVED_TMSI)
1029 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1030 VTY_NEWLINE);
1031 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1032}
1033
Harald Welte8387a492009-12-22 21:43:14 +01001034static void meas_rep_dump_uni_vty(struct vty *vty,
1035 struct gsm_meas_rep_unidir *mru,
1036 const char *prefix,
1037 const char *dir)
1038{
1039 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1040 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1041 dir, rxlev2dbm(mru->sub.rx_lev));
1042 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1043 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1044 VTY_NEWLINE);
1045}
1046
1047static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1048 const char *prefix)
1049{
1050 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1051 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1052 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1053 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1054 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1055 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1056 VTY_NEWLINE);
1057 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001058 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001059 if (mr->flags & MEAS_REP_F_MS_L1)
1060 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1061 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1062 if (mr->flags & MEAS_REP_F_DL_VALID)
1063 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1064 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1065}
1066
Harald Welte0a8cf322015-12-05 17:22:49 +01001067/* FIXME: move this to libosmogsm */
1068static const struct value_string gsm48_cmode_names[] = {
1069 { GSM48_CMODE_SIGN, "signalling" },
1070 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1071 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1072 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1073 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1074 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1075 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1076 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1077 { 0, NULL }
1078};
1079
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001080/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1081 * Don't do anything if the ts is not dynamic. */
1082static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1083{
1084 switch (ts->pchan) {
1085 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1086 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1087 vty_out(vty, " as %s",
1088 gsm_pchan_name(ts->dyn.pchan_is));
1089 else
1090 vty_out(vty, " switching %s -> %s",
1091 gsm_pchan_name(ts->dyn.pchan_is),
1092 gsm_pchan_name(ts->dyn.pchan_want));
1093 break;
1094 case GSM_PCHAN_TCH_F_PDCH:
1095 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1096 vty_out(vty, " as %s",
1097 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1098 : "TCH/F");
1099 else
1100 vty_out(vty, " switching %s -> %s",
1101 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1102 : "TCH/F",
1103 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1104 : "TCH/F");
1105 break;
1106 default:
1107 /* no dyn ts */
1108 break;
1109 }
1110}
1111
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001112static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001113{
Harald Welte8387a492009-12-22 21:43:14 +01001114 int idx;
1115
Harald Welte85bded82010-12-24 12:22:34 +01001116 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1117 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1118 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001119 /* show dyn TS details, if applicable */
1120 switch (lchan->ts->pchan) {
1121 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1122 vty_out(vty, " Osmocom Dyn TS:");
1123 vty_out_dyn_ts_status(vty, lchan->ts);
1124 vty_out(vty, VTY_NEWLINE);
1125 break;
1126 case GSM_PCHAN_TCH_F_PDCH:
1127 vty_out(vty, " IPACC Dyn PDCH TS:");
1128 vty_out_dyn_ts_status(vty, lchan->ts);
1129 vty_out(vty, VTY_NEWLINE);
1130 break;
1131 default:
1132 /* no dyn ts */
1133 break;
1134 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001135 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001136 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001137 gsm_lchans_name(lchan->state),
1138 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1139 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1140 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001141 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1142 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1143 - lchan->bs_power*2,
1144 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1145 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001146 vty_out(vty, " Channel Mode / Codec: %s%s",
1147 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1148 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001149 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001150 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001151 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001152 } else
1153 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301154 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1155 struct in_addr ia;
Holger Hans Peter Freyther54fa7992010-04-07 15:39:16 +02001156 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte2c828992009-12-02 01:56:49 +05301157 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1158 inet_ntoa(ia), lchan->abis_ip.bound_port,
1159 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1160 VTY_NEWLINE);
1161 }
Harald Welte8387a492009-12-22 21:43:14 +01001162
1163 /* we want to report the last measurement report */
1164 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1165 lchan->meas_rep_idx, 1);
1166 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001167}
1168
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001169static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1170{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001171 struct gsm_meas_rep *mr;
1172 int idx;
1173
1174 /* we want to report the last measurement report */
1175 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1176 lchan->meas_rep_idx, 1);
1177 mr = &lchan->meas_rep[idx];
1178
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001179 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001180 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001181 gsm_pchan_name(lchan->ts->pchan));
1182 vty_out_dyn_ts_status(vty, lchan->ts);
1183 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1184 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001185 lchan->nr,
1186 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1187 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001188 rxlev2dbm(mr->dl.full.rx_lev),
1189 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001190 VTY_NEWLINE);
1191}
1192
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001193
1194static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1195 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1196{
1197 int lchan_nr;
1198 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1199 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1200 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1201 continue;
1202 dump_cb(vty, lchan);
1203 }
1204
1205 return CMD_SUCCESS;
1206}
1207
1208static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1209 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1210{
1211 int ts_nr;
1212
1213 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1214 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1215 dump_lchan_trx_ts(ts, vty, dump_cb);
1216 }
1217
1218 return CMD_SUCCESS;
1219}
1220
1221static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1222 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1223{
1224 int trx_nr;
1225
1226 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1227 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1228 dump_lchan_trx(trx, vty, dump_cb);
1229 }
1230
1231 return CMD_SUCCESS;
1232}
1233
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001234static int lchan_summary(struct vty *vty, int argc, const char **argv,
1235 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001236{
Harald Weltedcccb182010-05-16 20:52:23 +02001237 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001238 struct gsm_bts *bts;
1239 struct gsm_bts_trx *trx;
1240 struct gsm_bts_trx_ts *ts;
1241 struct gsm_lchan *lchan;
1242 int bts_nr, trx_nr, ts_nr, lchan_nr;
1243
1244 if (argc >= 1) {
1245 /* use the BTS number that the user has specified */
1246 bts_nr = atoi(argv[0]);
1247 if (bts_nr >= net->num_bts) {
1248 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1249 VTY_NEWLINE);
1250 return CMD_WARNING;
1251 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001252 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001253
1254 if (argc == 1)
1255 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001256 }
1257 if (argc >= 2) {
1258 trx_nr = atoi(argv[1]);
1259 if (trx_nr >= bts->num_trx) {
1260 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1261 VTY_NEWLINE);
1262 return CMD_WARNING;
1263 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001264 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001265
1266 if (argc == 2)
1267 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001268 }
1269 if (argc >= 3) {
1270 ts_nr = atoi(argv[2]);
1271 if (ts_nr >= TRX_NR_TS) {
1272 vty_out(vty, "%% can't find TS %s%s", argv[2],
1273 VTY_NEWLINE);
1274 return CMD_WARNING;
1275 }
1276 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001277
1278 if (argc == 3)
1279 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001280 }
1281 if (argc >= 4) {
1282 lchan_nr = atoi(argv[3]);
1283 if (lchan_nr >= TS_MAX_LCHAN) {
1284 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1285 VTY_NEWLINE);
1286 return CMD_WARNING;
1287 }
1288 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001289 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001290 return CMD_SUCCESS;
1291 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001292
1293
Harald Welte68628e82009-03-10 12:17:57 +00001294 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001295 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001296 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001297 }
1298
1299 return CMD_SUCCESS;
1300}
1301
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001302
1303DEFUN(show_lchan,
1304 show_lchan_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001305 "show lchan [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001306 SHOW_STR "Display information about a logical channel\n"
1307 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001308 LCHAN_NR_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001309
1310{
1311 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1312}
1313
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001314DEFUN(show_lchan_summary,
1315 show_lchan_summary_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001316 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001317 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001318 "Short summary\n"
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001319 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001320 LCHAN_NR_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001321{
1322 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1323}
1324
Philipp Maier39f62bb2017-04-09 12:32:51 +02001325DEFUN(show_subscr_conn,
1326 show_subscr_conn_cmd,
1327 "show conns",
1328 SHOW_STR "Display currently active subscriber connections\n")
1329{
1330 struct gsm_subscriber_connection *conn;
1331 struct gsm_network *net = gsmnet_from_vty(vty);
1332 bool no_conns = true;
1333 unsigned int count = 0;
1334
1335 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1336
1337 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1338 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1339 lchan_dump_full_vty(vty, conn->lchan);
1340 no_conns = false;
1341 count++;
1342 }
1343
1344 if (no_conns)
1345 vty_out(vty, "None%s", VTY_NEWLINE);
1346
1347 return CMD_SUCCESS;
1348}
1349
1350DEFUN(handover_subscr_conn,
1351 handover_subscr_conn_cmd,
1352 "handover <0-255> <0-255> <0-7> LCHAN_NR <0-255>",
1353 "Handover subscriber connection to other BTS\n"
1354 "BTS Number (current)\n" "TRX Number\n" "Timeslot Number\n"
1355 LCHAN_NR_STR "BTS Number (new)\n")
1356{
1357 struct gsm_network *net = gsmnet_from_vty(vty);
1358 struct gsm_subscriber_connection *conn;
1359 struct gsm_bts *bts;
1360 struct gsm_bts *new_bts = NULL;
1361 unsigned int bts_nr = atoi(argv[0]);
1362 unsigned int trx_nr = atoi(argv[1]);
1363 unsigned int ts_nr = atoi(argv[2]);
1364 unsigned int ss_nr = atoi(argv[3]);
1365 unsigned int bts_nr_new = atoi(argv[4]);
1366
1367 /* Lookup the BTS where we want to handover to */
1368 llist_for_each_entry(bts, &net->bts_list, list) {
1369 if (bts->nr == bts_nr_new) {
1370 new_bts = bts;
1371 break;
1372 }
1373 }
1374
1375 if (!new_bts) {
1376 vty_out(vty, "Unable to trigger handover,"
1377 "specified bts #%u does not exist %s", bts_nr_new,
1378 VTY_NEWLINE);
1379 return CMD_WARNING;
1380 }
1381
1382 /* Find the connection/lchan that we want to handover */
1383 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1384 if (conn->bts->nr == bts_nr &&
1385 conn->lchan->ts->trx->nr == trx_nr &&
1386 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
1387 vty_out(vty, "starting handover for lchan %s...%s",
1388 conn->lchan->name, VTY_NEWLINE);
1389 lchan_dump_full_vty(vty, conn->lchan);
1390 bsc_handover_start(conn->lchan, new_bts);
1391 return CMD_SUCCESS;
1392 }
1393 }
1394
1395 vty_out(vty, "Unable to trigger handover,"
1396 "specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1397 bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
1398
1399 return CMD_WARNING;
1400}
1401
Harald Weltebe4b7302009-05-23 16:59:33 +00001402static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001403{
1404 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001405 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001406}
1407
Harald Weltebe4b7302009-05-23 16:59:33 +00001408static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001409{
1410 struct gsm_paging_request *pag;
1411
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001412 if (!bts->paging.bts)
1413 return;
1414
Harald Weltef5025b62009-03-28 16:55:11 +00001415 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1416 paging_dump_vty(vty, pag);
1417}
1418
1419DEFUN(show_paging,
1420 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001421 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001422 SHOW_STR "Display information about paging reuqests of a BTS\n"
1423 "BTS Number\n")
Harald Weltef5025b62009-03-28 16:55:11 +00001424{
Harald Weltedcccb182010-05-16 20:52:23 +02001425 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001426 struct gsm_bts *bts;
1427 int bts_nr;
1428
1429 if (argc >= 1) {
1430 /* use the BTS number that the user has specified */
1431 bts_nr = atoi(argv[0]);
1432 if (bts_nr >= net->num_bts) {
1433 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1434 VTY_NEWLINE);
1435 return CMD_WARNING;
1436 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001437 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001438 bts_paging_dump_vty(vty, bts);
1439
1440 return CMD_SUCCESS;
1441 }
1442 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001443 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001444 bts_paging_dump_vty(vty, bts);
1445 }
1446
1447 return CMD_SUCCESS;
1448}
1449
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001450DEFUN(show_paging_group,
1451 show_paging_group_cmd,
1452 "show paging-group <0-255> IMSI",
1453 SHOW_STR "Display the paging group\n"
1454 "BTS Number\n" "IMSI\n")
1455{
1456 struct gsm_network *net = gsmnet_from_vty(vty);
1457 struct gsm_bts *bts;
1458 unsigned int page_group;
1459 int bts_nr = atoi(argv[0]);
1460
1461 if (bts_nr >= net->num_bts) {
1462 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1463 return CMD_WARNING;
1464 }
1465
1466 bts = gsm_bts_num(net, bts_nr);
1467 if (!bts) {
1468 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1469 return CMD_WARNING;
1470 }
1471
1472 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1473 str_to_imsi(argv[1]));
1474 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1475 str_to_imsi(argv[1]), bts->nr,
1476 page_group, VTY_NEWLINE);
1477 return CMD_SUCCESS;
1478}
1479
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001480DEFUN(cfg_net_neci,
1481 cfg_net_neci_cmd,
1482 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001483 "New Establish Cause Indication\n"
1484 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001485{
Harald Weltedcccb182010-05-16 20:52:23 +02001486 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1487
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001488 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001489 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001490 return CMD_SUCCESS;
1491}
1492
Harald Welte8f0ed552010-05-11 21:53:49 +02001493#define HANDOVER_STR "Handover Options\n"
1494
Harald Weltebc814502009-12-19 21:41:52 +01001495DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1496 "handover (0|1)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001497 HANDOVER_STR
1498 "Don't perform in-call handover\n"
1499 "Perform in-call handover\n")
Harald Weltebc814502009-12-19 21:41:52 +01001500{
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001501 int enable = atoi(argv[0]);
Harald Weltedcccb182010-05-16 20:52:23 +02001502 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001503
1504 if (enable && ipacc_rtp_direct) {
Harald Weltefe03f0d2009-12-20 13:51:01 +01001505 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1506 "is enabled by using the -P command line option%s",
1507 VTY_NEWLINE);
1508 return CMD_WARNING;
1509 }
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001510 gsmnet->handover.active = enable;
Harald Weltebc814502009-12-19 21:41:52 +01001511
1512 return CMD_SUCCESS;
1513}
1514
Harald Welte8f0ed552010-05-11 21:53:49 +02001515#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1516#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1517#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1518#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001519#define HO_AVG_COUNT_STR "Amount to use for Averaging\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001520
Harald Welteb720bd32009-12-21 16:51:50 +01001521DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1522 "handover window rxlev averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001523 HO_WIN_RXLEV_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001524 "How many RxLev measurements are used for averaging\n"
1525 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001526{
Harald Weltedcccb182010-05-16 20:52:23 +02001527 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001528 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1529 return CMD_SUCCESS;
1530}
1531
1532DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1533 "handover window rxqual averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001534 HO_WIN_RXQUAL_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001535 "How many RxQual measurements are used for averaging\n"
1536 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001537{
Harald Weltedcccb182010-05-16 20:52:23 +02001538 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001539 gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
1540 return CMD_SUCCESS;
1541}
1542
1543DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1544 "handover window rxlev neighbor averaging <1-10>",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001545 HO_WIN_RXLEV_STR "Neighbor\n"
1546 "How many RxQual measurements are used for averaging\n"
1547 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001548{
Harald Weltedcccb182010-05-16 20:52:23 +02001549 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001550 gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
1551 return CMD_SUCCESS;
1552}
1553
1554DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1555 "handover power budget interval <1-99>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001556 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001557 "How often to check if we have a better cell (SACCH frames)\n"
1558 "Interval\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001559{
Harald Weltedcccb182010-05-16 20:52:23 +02001560 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001561 gsmnet->handover.pwr_interval = atoi(argv[0]);
1562 return CMD_SUCCESS;
1563}
1564
1565DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1566 "handover power budget hysteresis <0-999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001567 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001568 "How many dB does a neighbor to be stronger to become a HO candidate\n"
1569 "Hysteresis\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001570{
Harald Weltedcccb182010-05-16 20:52:23 +02001571 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001572 gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
1573 return CMD_SUCCESS;
1574}
1575
1576DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1577 "handover maximum distance <0-9999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001578 HANDOVER_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001579 "How big is the maximum timing advance before HO is forced\n"
1580 "Distance\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001581{
Harald Weltedcccb182010-05-16 20:52:23 +02001582 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001583 gsmnet->handover.max_distance = atoi(argv[0]);
1584 return CMD_SUCCESS;
1585}
Harald Weltebc814502009-12-19 21:41:52 +01001586
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001587DEFUN(cfg_net_pag_any_tch,
1588 cfg_net_pag_any_tch_cmd,
1589 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001590 "Assign a TCH when receiving a Paging Any request\n"
1591 "Any Channel\n" "Use\n" "TCH\n"
1592 "Do not use TCH for Paging Request Any\n"
1593 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001594{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001595 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001596 gsmnet->pag_any_tch = atoi(argv[0]);
1597 gsm_net_update_ctype(gsmnet);
1598 return CMD_SUCCESS;
1599}
1600
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001601#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1602/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1603#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1604
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001605#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001606 DEFUN(cfg_net_T##number, \
1607 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001608 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001609 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001610 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001611 "Set to default timer value" \
1612 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1613 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001614{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001615 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001616 int value; \
1617 if (strcmp(argv[0], "default") == 0) \
1618 value = DEFAULT_TIMER(number); \
1619 else \
1620 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001621 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001622 gsmnet->T##number = value; \
1623 return CMD_SUCCESS; \
1624}
1625
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001626DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1627DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1628DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1629DECLARE_TIMER(3107, "Currently not used")
1630DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1631DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1632DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1633DECLARE_TIMER(3115, "Currently not used")
1634DECLARE_TIMER(3117, "Currently not used")
1635DECLARE_TIMER(3119, "Currently not used")
1636DECLARE_TIMER(3122, "Waiting time (seconds) after IMM ASS REJECT")
1637DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001638
Maxc08ee712016-05-11 12:45:13 +02001639DEFUN_DEPRECATED(cfg_net_dtx,
1640 cfg_net_dtx_cmd,
1641 "dtx-used (0|1)",
1642 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001643{
Maxc08ee712016-05-11 12:45:13 +02001644 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1645 "configuration options of BTS instead%s", VTY_NEWLINE);
1646 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001647}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001648
Harald Welte5258fc42009-03-28 19:07:53 +00001649/* per-BTS configuration */
1650DEFUN(cfg_bts,
1651 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001652 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001653 "Select a BTS to configure\n"
1654 "BTS Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001655{
Harald Weltedcccb182010-05-16 20:52:23 +02001656 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001657 int bts_nr = atoi(argv[0]);
1658 struct gsm_bts *bts;
1659
Harald Weltee441d9c2009-06-21 16:17:15 +02001660 if (bts_nr > gsmnet->num_bts) {
1661 vty_out(vty, "%% The next unused BTS number is %u%s",
1662 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001663 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001664 } else if (bts_nr == gsmnet->num_bts) {
1665 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001666 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001667 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001668 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001669 bts = gsm_bts_num(gsmnet, bts_nr);
1670
Daniel Willmannf15c2762010-01-11 13:43:07 +01001671 if (!bts) {
1672 vty_out(vty, "%% Unable to allocate BTS %u%s",
1673 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001674 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001675 }
Harald Welte5258fc42009-03-28 19:07:53 +00001676
1677 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001678 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001679 vty->node = BTS_NODE;
1680
1681 return CMD_SUCCESS;
1682}
1683
1684DEFUN(cfg_bts_type,
1685 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001686 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001687 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001688{
1689 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001690 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001691
Max7507aef2017-04-10 13:59:14 +02001692 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001693 if (rc < 0)
1694 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001695
Harald Welte5258fc42009-03-28 19:07:53 +00001696 return CMD_SUCCESS;
1697}
1698
Harald Weltefcd24452009-06-20 18:15:19 +02001699DEFUN(cfg_bts_band,
1700 cfg_bts_band_cmd,
1701 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001702 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001703{
1704 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001705 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001706
1707 if (band < 0) {
1708 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1709 band, VTY_NEWLINE);
1710 return CMD_WARNING;
1711 }
1712
1713 bts->band = band;
1714
1715 return CMD_SUCCESS;
1716}
1717
Maxc08ee712016-05-11 12:45:13 +02001718DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1719 "Configure discontinuous transmission\n"
1720 "Enable Uplink DTX for this BTS\n"
1721 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1722 "older phones).\n")
1723{
1724 struct gsm_bts *bts = vty->index;
1725
1726 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001727 if (!is_ipaccess_bts(bts))
1728 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1729 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001730 return CMD_SUCCESS;
1731}
1732
1733DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1734 NO_STR
1735 "Configure discontinuous transmission\n"
1736 "Disable Uplink DTX for this BTS\n")
1737{
1738 struct gsm_bts *bts = vty->index;
1739
1740 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1741
1742 return CMD_SUCCESS;
1743}
1744
1745DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1746 "Configure discontinuous transmission\n"
1747 "Enable Downlink DTX for this BTS\n")
1748{
1749 struct gsm_bts *bts = vty->index;
1750
1751 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001752 if (!is_ipaccess_bts(bts))
1753 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1754 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001755 return CMD_SUCCESS;
1756}
1757
1758DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1759 NO_STR
1760 "Configure discontinuous transmission\n"
1761 "Disable Downlink DTX for this BTS\n")
1762{
1763 struct gsm_bts *bts = vty->index;
1764
1765 bts->dtxd = false;
1766
1767 return CMD_SUCCESS;
1768}
1769
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001770DEFUN(cfg_bts_ci,
1771 cfg_bts_ci_cmd,
1772 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001773 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001774{
1775 struct gsm_bts *bts = vty->index;
1776 int ci = atoi(argv[0]);
1777
1778 if (ci < 0 || ci > 0xffff) {
1779 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1780 ci, VTY_NEWLINE);
1781 return CMD_WARNING;
1782 }
1783 bts->cell_identity = ci;
1784
1785 return CMD_SUCCESS;
1786}
1787
Harald Welte5258fc42009-03-28 19:07:53 +00001788DEFUN(cfg_bts_lac,
1789 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001790 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001791 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001792{
1793 struct gsm_bts *bts = vty->index;
1794 int lac = atoi(argv[0]);
1795
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001796 if (lac < 0 || lac > 0xffff) {
1797 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001798 lac, VTY_NEWLINE);
1799 return CMD_WARNING;
1800 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001801
1802 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1803 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1804 lac, VTY_NEWLINE);
1805 return CMD_WARNING;
1806 }
1807
Harald Welte5258fc42009-03-28 19:07:53 +00001808 bts->location_area_code = lac;
1809
1810 return CMD_SUCCESS;
1811}
1812
Harald Weltea43f7892009-12-01 18:04:30 +05301813
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001814/* compatibility wrapper for old config files */
1815DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001816 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001817 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001818 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001819{
Harald Welte5258fc42009-03-28 19:07:53 +00001820 return CMD_SUCCESS;
1821}
1822
Harald Welte78f2f502009-05-23 16:56:52 +00001823DEFUN(cfg_bts_bsic,
1824 cfg_bts_bsic_cmd,
1825 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001826 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1827 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001828{
1829 struct gsm_bts *bts = vty->index;
1830 int bsic = atoi(argv[0]);
1831
1832 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001833 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001834 bsic, VTY_NEWLINE);
1835 return CMD_WARNING;
1836 }
1837 bts->bsic = bsic;
1838
1839 return CMD_SUCCESS;
1840}
1841
Harald Welte4cc34222009-05-01 15:12:31 +00001842DEFUN(cfg_bts_unit_id,
1843 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001844 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001845 "Abis/IP specific options\n"
1846 "Set the IPA BTS Unit ID\n"
1847 "Unit ID (Site)\n"
1848 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001849{
1850 struct gsm_bts *bts = vty->index;
1851 int site_id = atoi(argv[0]);
1852 int bts_id = atoi(argv[1]);
1853
Harald Welte07dc73d2009-08-07 13:27:09 +02001854 if (!is_ipaccess_bts(bts)) {
1855 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1856 return CMD_WARNING;
1857 }
1858
Harald Welte4cc34222009-05-01 15:12:31 +00001859 bts->ip_access.site_id = site_id;
1860 bts->ip_access.bts_id = bts_id;
1861
1862 return CMD_SUCCESS;
1863}
1864
Harald Welte8b291802013-03-12 13:57:05 +01001865DEFUN(cfg_bts_rsl_ip,
1866 cfg_bts_rsl_ip_cmd,
1867 "ip.access rsl-ip A.B.C.D",
1868 "Abis/IP specific options\n"
1869 "Set the IPA RSL IP Address of the BSC\n"
1870 "Destination IP address for RSL connection\n")
1871{
1872 struct gsm_bts *bts = vty->index;
1873 struct in_addr ia;
1874
1875 if (!is_ipaccess_bts(bts)) {
1876 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1877 return CMD_WARNING;
1878 }
1879
1880 inet_aton(argv[0], &ia);
1881 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1882
1883 return CMD_SUCCESS;
1884}
1885
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001886#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001887
Sylvain Munautc9519462011-10-17 14:04:55 +02001888DEFUN(cfg_bts_nokia_site_skip_reset,
1889 cfg_bts_nokia_site_skip_reset_cmd,
1890 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001891 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001892 "Skip the reset step during bootstrap process of this BTS\n"
1893 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02001894{
1895 struct gsm_bts *bts = vty->index;
1896
1897 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
1898 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
1899 return CMD_WARNING;
1900 }
1901
1902 bts->nokia.skip_reset = atoi(argv[0]);
1903
1904 return CMD_SUCCESS;
1905}
1906
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001907DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
1908 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
1909 "nokia_site no-local-rel-conf (0|1)",
1910 NOKIA_STR
1911 "Do not wait for RELease CONFirm message when releasing channel locally\n"
1912 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
1913{
1914 struct gsm_bts *bts = vty->index;
1915
1916 if (!is_nokia_bts(bts)) {
1917 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1918 VTY_NEWLINE);
1919 return CMD_WARNING;
1920 }
1921
1922 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
1923
1924 return CMD_SUCCESS;
1925}
1926
Sipos Csaba56e17662015-02-07 13:27:36 +01001927DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
1928 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
1929 "nokia_site bts-reset-timer <15-100>",
1930 NOKIA_STR
1931 "The amount of time (in sec.) between BTS_RESET is sent,\n"
1932 "and the BTS is being bootstrapped.\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.bts_reset_timer_cnf = atoi(argv[0]);
1943
1944 return CMD_SUCCESS;
1945}
Harald Welte8f0ed552010-05-11 21:53:49 +02001946#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001947#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001948
Harald Welte8175e952009-10-20 00:22:00 +02001949DEFUN(cfg_bts_stream_id,
1950 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001951 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02001952 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001953 "Set the ip.access Stream ID of the OML link of this BTS\n"
1954 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02001955{
1956 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001957 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02001958
1959 if (!is_ipaccess_bts(bts)) {
1960 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1961 return CMD_WARNING;
1962 }
1963
1964 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001965 /* This is used by e1inp_bind_ops callback for each BTS model. */
1966 bts->oml_e1_link.e1_nr = linenr;
1967
1968 return CMD_SUCCESS;
1969}
1970
Harald Welted13e0cd2012-08-17 09:52:03 +02001971#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02001972
Harald Welte42581822009-08-08 16:12:58 +02001973DEFUN(cfg_bts_oml_e1,
1974 cfg_bts_oml_e1_cmd,
1975 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02001976 OML_E1_STR
1977 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001978 "E1/T1 line number to be used for OML\n"
1979 "E1/T1 timeslot to be used for OML\n"
1980 "E1/T1 timeslot to be used for OML\n"
1981 "E1/T1 sub-slot to be used for OML\n"
1982 "Use E1/T1 sub-slot 0\n"
1983 "Use E1/T1 sub-slot 1\n"
1984 "Use E1/T1 sub-slot 2\n"
1985 "Use E1/T1 sub-slot 3\n"
1986 "Use full E1 slot 3\n"
1987 )
Harald Welte42581822009-08-08 16:12:58 +02001988{
1989 struct gsm_bts *bts = vty->index;
1990
1991 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
1992
1993 return CMD_SUCCESS;
1994}
1995
1996
1997DEFUN(cfg_bts_oml_e1_tei,
1998 cfg_bts_oml_e1_tei_cmd,
1999 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002000 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002001 "Set the TEI to be used for OML\n"
2002 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002003{
2004 struct gsm_bts *bts = vty->index;
2005
2006 bts->oml_tei = atoi(argv[0]);
2007
2008 return CMD_SUCCESS;
2009}
2010
Harald Welte7a8fa412009-08-10 13:48:16 +02002011DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2012 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002013 "Channnel Allocator\n" "Channel Allocator\n"
2014 "Allocate Timeslots and Transceivers in ascending order\n"
2015 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002016{
2017 struct gsm_bts *bts = vty->index;
2018
2019 if (!strcmp(argv[0], "ascending"))
2020 bts->chan_alloc_reverse = 0;
2021 else
2022 bts->chan_alloc_reverse = 1;
2023
2024 return CMD_SUCCESS;
2025}
2026
Harald Welte8f0ed552010-05-11 21:53:49 +02002027#define RACH_STR "Random Access Control Channel\n"
2028
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002029DEFUN(cfg_bts_rach_tx_integer,
2030 cfg_bts_rach_tx_integer_cmd,
2031 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002032 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002033 "Set the raw tx integer value in RACH Control parameters IE\n"
2034 "Set the raw tx integer value in RACH Control parameters IE\n"
2035 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002036{
2037 struct gsm_bts *bts = vty->index;
2038 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2039 return CMD_SUCCESS;
2040}
2041
2042DEFUN(cfg_bts_rach_max_trans,
2043 cfg_bts_rach_max_trans_cmd,
2044 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002045 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002046 "Set the maximum number of RACH burst transmissions\n"
2047 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002048 "Maximum number of 1 RACH burst transmissions\n"
2049 "Maximum number of 2 RACH burst transmissions\n"
2050 "Maximum number of 4 RACH burst transmissions\n"
2051 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002052{
2053 struct gsm_bts *bts = vty->index;
2054 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2055 return CMD_SUCCESS;
2056}
2057
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002058#define CD_STR "Channel Description\n"
2059
2060DEFUN(cfg_bts_chan_desc_att,
2061 cfg_bts_chan_desc_att_cmd,
2062 "channel-descrption attach (0|1)",
2063 CD_STR
2064 "Set if attachment is required\n"
2065 "Attachment is NOT required\n"
2066 "Attachment is required (standard)\n")
2067{
2068 struct gsm_bts *bts = vty->index;
2069 bts->si_common.chan_desc.att = atoi(argv[0]);
2070 return CMD_SUCCESS;
2071}
2072
2073DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2074 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2075 "channel-descrption bs-pa-mfrms <2-9>",
2076 CD_STR
2077 "Set number of multiframe periods for paging groups\n"
2078 "Number of multiframe periods for paging groups\n")
2079{
2080 struct gsm_bts *bts = vty->index;
2081 int bs_pa_mfrms = atoi(argv[0]);
2082
2083 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2084 return CMD_SUCCESS;
2085}
2086
2087DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2088 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2089 "channel-descrption bs-ag-blks-res <0-7>",
2090 CD_STR
2091 "Set number of blocks reserved for access grant\n"
2092 "Number of blocks reserved for access grant\n")
2093{
2094 struct gsm_bts *bts = vty->index;
2095 int bs_ag_blks_res = atoi(argv[0]);
2096
2097 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2098 return CMD_SUCCESS;
2099}
2100
Harald Welte8f0ed552010-05-11 21:53:49 +02002101#define NM_STR "Network Management\n"
2102
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002103DEFUN(cfg_bts_rach_nm_b_thresh,
2104 cfg_bts_rach_nm_b_thresh_cmd,
2105 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002106 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002107 "Set the NM Busy Threshold\n"
2108 "Set the NM Busy Threshold\n"
2109 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002110{
2111 struct gsm_bts *bts = vty->index;
2112 bts->rach_b_thresh = atoi(argv[0]);
2113 return CMD_SUCCESS;
2114}
2115
2116DEFUN(cfg_bts_rach_nm_ldavg,
2117 cfg_bts_rach_nm_ldavg_cmd,
2118 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002119 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002120 "Set the NM Loadaverage Slots value\n"
2121 "Set the NM Loadaverage Slots value\n"
2122 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002123{
2124 struct gsm_bts *bts = vty->index;
2125 bts->rach_ldavg_slots = atoi(argv[0]);
2126 return CMD_SUCCESS;
2127}
2128
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002129DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2130 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002131 "Should this cell be barred from access?\n"
2132 "Should this cell be barred from access?\n"
2133 "Cell should NOT be barred\n"
2134 "Cell should be barred\n")
2135
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002136{
2137 struct gsm_bts *bts = vty->index;
2138
Harald Welte71355012009-12-21 23:08:18 +01002139 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002140
2141 return CMD_SUCCESS;
2142}
2143
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002144DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2145 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002146 RACH_STR
2147 "Should this cell allow emergency calls?\n"
2148 "Should this cell allow emergency calls?\n"
2149 "Should this cell allow emergency calls?\n"
2150 "Do NOT allow emergency calls\n"
2151 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002152{
2153 struct gsm_bts *bts = vty->index;
2154
2155 if (atoi(argv[0]) == 0)
2156 bts->si_common.rach_control.t2 |= 0x4;
2157 else
2158 bts->si_common.rach_control.t2 &= ~0x4;
2159
2160 return CMD_SUCCESS;
2161}
2162
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002163DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2164 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2165 RACH_STR
2166 "Set access control class\n"
2167 "Access control class 0\n"
2168 "Access control class 1\n"
2169 "Access control class 2\n"
2170 "Access control class 3\n"
2171 "Access control class 4\n"
2172 "Access control class 5\n"
2173 "Access control class 6\n"
2174 "Access control class 7\n"
2175 "Access control class 8\n"
2176 "Access control class 9\n"
2177 "Access control class 11 for PLMN use\n"
2178 "Access control class 12 for security services\n"
2179 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2180 "Access control class 14 for emergency services\n"
2181 "Access control class 15 for PLMN staff\n"
2182 "barred to use access control class\n"
2183 "allowed to use access control class\n")
2184{
2185 struct gsm_bts *bts = vty->index;
2186
2187 uint8_t control_class;
2188 uint8_t allowed = 0;
2189
2190 if (strcmp(argv[1], "allowed") == 0)
2191 allowed = 1;
2192
2193 control_class = atoi(argv[0]);
2194 if (control_class < 8)
2195 if (allowed)
2196 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2197 else
2198 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2199 else
2200 if (allowed)
2201 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2202 else
2203 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2204
2205 return CMD_SUCCESS;
2206}
2207
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002208DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2209 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002210 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002211 "Maximum transmit power of the MS\n"
2212 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002213 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002214{
2215 struct gsm_bts *bts = vty->index;
2216
2217 bts->ms_max_power = atoi(argv[0]);
2218
2219 return CMD_SUCCESS;
2220}
2221
Harald Weltecfaabbb2012-08-16 23:23:50 +02002222#define CELL_STR "Cell Parameters\n"
2223
Harald Welte73225282009-12-12 18:17:25 +01002224DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2225 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002226 CELL_STR "Cell re-selection parameters\n"
2227 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002228 "Cell Re-Selection Hysteresis in dB")
2229{
2230 struct gsm_bts *bts = vty->index;
2231
2232 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2233
2234 return CMD_SUCCESS;
2235}
2236
2237DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2238 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002239 "Minimum RxLev needed for cell access\n"
2240 "Minimum RxLev needed for cell access\n"
2241 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002242 "Minimum RxLev needed for cell access (better than -110dBm)")
2243{
2244 struct gsm_bts *bts = vty->index;
2245
2246 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2247
2248 return CMD_SUCCESS;
2249}
2250
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002251DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2252 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002253 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2254 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002255{
2256 struct gsm_bts *bts = vty->index;
2257
2258 bts->si_common.cell_ro_sel_par.present = 1;
2259 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2260
2261 return CMD_SUCCESS;
2262}
2263
2264DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2265 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002266 CELL_STR "Cell Re-Selection Parameters\n"
2267 "Cell Re-Selection Offset (CRO) in dB\n"
2268 "Cell Re-Selection Offset (CRO) in dB\n"
2269 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002270{
2271 struct gsm_bts *bts = vty->index;
2272
2273 bts->si_common.cell_ro_sel_par.present = 1;
2274 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2275
2276 return CMD_SUCCESS;
2277}
2278
2279DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2280 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002281 "Cell selection temporary negative offset\n"
2282 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002283 "Cell selection temporary negative offset in dB")
2284{
2285 struct gsm_bts *bts = vty->index;
2286
2287 bts->si_common.cell_ro_sel_par.present = 1;
2288 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2289
2290 return CMD_SUCCESS;
2291}
2292
2293DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2294 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002295 "Cell selection temporary negative offset\n"
2296 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002297 "Sets cell selection temporary negative offset to infinity")
2298{
2299 struct gsm_bts *bts = vty->index;
2300
2301 bts->si_common.cell_ro_sel_par.present = 1;
2302 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2303
2304 return CMD_SUCCESS;
2305}
2306
2307DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2308 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002309 "Cell selection penalty time\n"
2310 "Cell selection penalty time\n"
2311 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002312{
2313 struct gsm_bts *bts = vty->index;
2314
2315 bts->si_common.cell_ro_sel_par.present = 1;
2316 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2317
2318 return CMD_SUCCESS;
2319}
2320
2321DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2322 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002323 "Cell selection penalty time\n"
2324 "Cell selection penalty time\n"
2325 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002326 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2327 "and TEMPORARY_OFFSET is ignored)")
2328{
2329 struct gsm_bts *bts = vty->index;
2330
2331 bts->si_common.cell_ro_sel_par.present = 1;
2332 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2333
2334 return CMD_SUCCESS;
2335}
2336
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002337DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2338 "radio-link-timeout <4-64>",
2339 "Radio link timeout criterion (BTS side)\n"
2340 "Radio link timeout value (lost SACCH block)\n")
2341{
2342 struct gsm_bts *bts = vty->index;
2343
Harald Welte2f8b9d22017-06-18 11:12:13 +03002344 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2345
2346 return CMD_SUCCESS;
2347}
2348
2349DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2350 "radio-link-timeout infinite",
2351 "Radio link timeout criterion (BTS side)\n"
2352 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2353{
2354 struct gsm_bts *bts = vty->index;
2355
2356 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2357 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2358 return CMD_WARNING;
2359 }
2360
2361 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2362 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002363
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002364 return CMD_SUCCESS;
2365}
2366
Harald Welte8f0ed552010-05-11 21:53:49 +02002367#define GPRS_TEXT "GPRS Packet Network\n"
2368
Harald Welteaf387632010-03-14 23:30:30 +08002369DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002370 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002371 GPRS_TEXT
2372 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002373 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002374 "GPRS BSSGP VC Identifier")
2375{
2376 struct gsm_bts *bts = vty->index;
2377
Harald Welte4511d892010-04-18 15:51:20 +02002378 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002379 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2380 return CMD_WARNING;
2381 }
2382
Harald Welte97a282b2010-03-14 15:37:43 +08002383 bts->gprs.cell.bvci = atoi(argv[0]);
2384
2385 return CMD_SUCCESS;
2386}
2387
Harald Weltea5731cf2010-03-22 11:48:36 +08002388DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2389 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002390 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002391 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002392 "GPRS NS Entity Identifier")
2393{
2394 struct gsm_bts *bts = vty->index;
2395
Harald Welte4511d892010-04-18 15:51:20 +02002396 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002397 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2398 return CMD_WARNING;
2399 }
2400
2401 bts->gprs.nse.nsei = atoi(argv[0]);
2402
2403 return CMD_SUCCESS;
2404}
2405
Harald Welte8f0ed552010-05-11 21:53:49 +02002406#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2407 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002408
Harald Welte97a282b2010-03-14 15:37:43 +08002409DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2410 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002411 GPRS_TEXT NSVC_TEXT
2412 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002413 "GPRS NS VC Identifier")
2414{
2415 struct gsm_bts *bts = vty->index;
2416 int idx = atoi(argv[0]);
2417
Harald Welte4511d892010-04-18 15:51:20 +02002418 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002419 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2420 return CMD_WARNING;
2421 }
2422
Harald Welte97a282b2010-03-14 15:37:43 +08002423 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2424
2425 return CMD_SUCCESS;
2426}
2427
Harald Welteaf387632010-03-14 23:30:30 +08002428DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2429 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002430 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002431 "GPRS NS Local UDP Port\n"
2432 "GPRS NS Local UDP Port\n"
2433 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002434 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002435{
2436 struct gsm_bts *bts = vty->index;
2437 int idx = atoi(argv[0]);
2438
Harald Welte4511d892010-04-18 15:51:20 +02002439 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002440 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2441 return CMD_WARNING;
2442 }
2443
Harald Welteaf387632010-03-14 23:30:30 +08002444 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2445
2446 return CMD_SUCCESS;
2447}
2448
2449DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2450 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002451 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002452 "GPRS NS Remote UDP Port\n"
2453 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002454 "GPRS NS Remote UDP Port\n"
2455 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002456{
2457 struct gsm_bts *bts = vty->index;
2458 int idx = atoi(argv[0]);
2459
Harald Welte4511d892010-04-18 15:51:20 +02002460 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002461 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2462 return CMD_WARNING;
2463 }
2464
Harald Welteaf387632010-03-14 23:30:30 +08002465 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2466
2467 return CMD_SUCCESS;
2468}
2469
2470DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2471 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002472 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002473 "GPRS NS Remote IP Address\n"
2474 "GPRS NS Remote IP Address\n"
2475 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002476{
2477 struct gsm_bts *bts = vty->index;
2478 int idx = atoi(argv[0]);
2479 struct in_addr ia;
2480
Harald Welte4511d892010-04-18 15:51:20 +02002481 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002482 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2483 return CMD_WARNING;
2484 }
2485
Harald Welteaf387632010-03-14 23:30:30 +08002486 inet_aton(argv[1], &ia);
2487 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2488
2489 return CMD_SUCCESS;
2490}
2491
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002492DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002493 "paging free <-1-1024>",
2494 "Paging options\n"
2495 "Only page when having a certain amount of free slots\n"
2496 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002497{
2498 struct gsm_bts *bts = vty->index;
2499
2500 bts->paging.free_chans_need = atoi(argv[0]);
2501 return CMD_SUCCESS;
2502}
2503
Harald Welte615e9562010-05-11 23:50:21 +02002504DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2505 "gprs ns timer " NS_TIMERS " <0-255>",
2506 GPRS_TEXT "Network Service\n"
2507 "Network Service Timer\n"
2508 NS_TIMERS_HELP "Timer Value\n")
2509{
2510 struct gsm_bts *bts = vty->index;
2511 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2512 int val = atoi(argv[1]);
2513
2514 if (bts->gprs.mode == BTS_GPRS_NONE) {
2515 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2516 return CMD_WARNING;
2517 }
2518
2519 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2520 return CMD_WARNING;
2521
2522 bts->gprs.nse.timer[idx] = val;
2523
2524 return CMD_SUCCESS;
2525}
2526
2527#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 +02002528#define BSSGP_TIMERS_HELP \
2529 "Tbvc-block timeout\n" \
2530 "Tbvc-block retries\n" \
2531 "Tbvc-unblock retries\n" \
2532 "Tbvcc-reset timeout\n" \
2533 "Tbvc-reset retries\n" \
2534 "Tbvc-suspend timeout\n" \
2535 "Tbvc-suspend retries\n" \
2536 "Tbvc-resume timeout\n" \
2537 "Tbvc-resume retries\n" \
2538 "Tbvc-capa-update timeout\n" \
2539 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002540
2541DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2542 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2543 GPRS_TEXT "Cell / BSSGP\n"
2544 "Cell/BSSGP Timer\n"
2545 BSSGP_TIMERS_HELP "Timer Value\n")
2546{
2547 struct gsm_bts *bts = vty->index;
2548 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2549 int val = atoi(argv[1]);
2550
2551 if (bts->gprs.mode == BTS_GPRS_NONE) {
2552 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2553 return CMD_WARNING;
2554 }
2555
2556 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2557 return CMD_WARNING;
2558
2559 bts->gprs.cell.timer[idx] = val;
2560
2561 return CMD_SUCCESS;
2562}
2563
Harald Welte97a282b2010-03-14 15:37:43 +08002564DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2565 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002566 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002567 "GPRS Routing Area Code\n"
2568 "GPRS Routing Area Code\n"
2569 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002570{
2571 struct gsm_bts *bts = vty->index;
2572
Harald Welte4511d892010-04-18 15:51:20 +02002573 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002574 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2575 return CMD_WARNING;
2576 }
2577
Harald Welte97a282b2010-03-14 15:37:43 +08002578 bts->gprs.rac = atoi(argv[0]);
2579
2580 return CMD_SUCCESS;
2581}
2582
Max292ec582016-07-28 11:55:37 +02002583DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2584 "gprs control-ack-type-rach", GPRS_TEXT
2585 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2586 "four access bursts format instead of default RLC/MAC control block\n")
2587{
2588 struct gsm_bts *bts = vty->index;
2589
2590 if (bts->gprs.mode == BTS_GPRS_NONE) {
2591 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2592 return CMD_WARNING;
2593 }
2594
2595 bts->gprs.ctrl_ack_type_use_block = false;
2596
2597 return CMD_SUCCESS;
2598}
2599
2600DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2601 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2602 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2603 "four access bursts format instead of default RLC/MAC control block\n")
2604{
2605 struct gsm_bts *bts = vty->index;
2606
2607 if (bts->gprs.mode == BTS_GPRS_NONE) {
2608 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2609 return CMD_WARNING;
2610 }
2611
2612 bts->gprs.ctrl_ack_type_use_block = true;
2613
2614 return CMD_SUCCESS;
2615}
2616
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002617DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2618 "gprs network-control-order (nc0|nc1|nc2)",
2619 GPRS_TEXT
2620 "GPRS Network Control Order\n"
2621 "MS controlled cell re-selection, no measurement reporting\n"
2622 "MS controlled cell re-selection, MS sends measurement reports\n"
2623 "Network controlled cell re-selection, MS sends measurement reports\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.net_ctrl_ord = atoi(argv[0] + 2);
2633
2634 return CMD_SUCCESS;
2635}
2636
Harald Welte4511d892010-04-18 15:51:20 +02002637DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2638 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002639 GPRS_TEXT
2640 "GPRS Mode for this BTS\n"
2641 "GPRS Disabled on this BTS\n"
2642 "GPRS Enabled on this BTS\n"
2643 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002644{
2645 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002646 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002647
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002648 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002649 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2650 VTY_NEWLINE);
2651 return CMD_WARNING;
2652 }
2653
2654 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002655
2656 return CMD_SUCCESS;
2657}
2658
bhargava350533c2016-07-21 11:14:34 +05302659DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2660 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2661 "gprs 11bit_rach_support_for_egprs (0|1)",
2662 GPRS_TEXT "11 bit RACH options\n"
2663 "Disable 11 bit RACH for EGPRS\n"
2664 "Enable 11 bit RACH for EGPRS")
2665{
2666 struct gsm_bts *bts = vty->index;
2667
2668 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2669
2670 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2671 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2672 return CMD_WARNING;
2673 }
2674
2675 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2676 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2677 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2678 " enabled%s", VTY_NEWLINE);
2679 return CMD_WARNING;
2680 }
2681
2682 return CMD_SUCCESS;
2683}
2684
Harald Welte9fbff4a2010-07-30 11:50:09 +02002685#define SI_TEXT "System Information Messages\n"
2686#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)"
2687#define SI_TYPE_HELP "System Information Type 1\n" \
2688 "System Information Type 2\n" \
2689 "System Information Type 3\n" \
2690 "System Information Type 4\n" \
2691 "System Information Type 5\n" \
2692 "System Information Type 6\n" \
2693 "System Information Type 7\n" \
2694 "System Information Type 8\n" \
2695 "System Information Type 9\n" \
2696 "System Information Type 10\n" \
2697 "System Information Type 13\n" \
2698 "System Information Type 16\n" \
2699 "System Information Type 17\n" \
2700 "System Information Type 18\n" \
2701 "System Information Type 19\n" \
2702 "System Information Type 20\n" \
2703 "System Information Type 2bis\n" \
2704 "System Information Type 2ter\n" \
2705 "System Information Type 2quater\n" \
2706 "System Information Type 5bis\n" \
2707 "System Information Type 5ter\n"
2708
2709DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2710 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2711 SI_TEXT SI_TYPE_HELP
2712 "System Information Mode\n"
2713 "Static user-specified\n"
2714 "Dynamic, BSC-computed\n")
2715{
2716 struct gsm_bts *bts = vty->index;
2717 int type;
2718
2719 type = get_string_value(osmo_sitype_strs, argv[0]);
2720 if (type < 0) {
2721 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2722 return CMD_WARNING;
2723 }
2724
2725 if (!strcmp(argv[1], "static"))
2726 bts->si_mode_static |= (1 << type);
2727 else
2728 bts->si_mode_static &= ~(1 << type);
2729
2730 return CMD_SUCCESS;
2731}
2732
2733DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2734 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2735 SI_TEXT SI_TYPE_HELP
2736 "Static System Information filling\n"
2737 "Static user-specified SI content in HEX notation\n")
2738{
2739 struct gsm_bts *bts = vty->index;
2740 int rc, type;
2741
2742 type = get_string_value(osmo_sitype_strs, argv[0]);
2743 if (type < 0) {
2744 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2745 return CMD_WARNING;
2746 }
2747
2748 if (!(bts->si_mode_static & (1 << type))) {
2749 vty_out(vty, "SI Type %s is not configured in static mode%s",
2750 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2751 return CMD_WARNING;
2752 }
2753
Harald Welte290aaed2010-07-30 11:53:18 +02002754 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002755 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002756
2757 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002758 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2759 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002760 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2761 return CMD_WARNING;
2762 }
2763
2764 /* Mark this SI as present */
2765 bts->si_valid |= (1 << type);
2766
2767 return CMD_SUCCESS;
2768}
2769
Harald Welte42def722017-01-13 00:10:32 +01002770DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2771 "early-classmark-sending (allowed|forbidden)",
2772 "Early Classmark Sending\n"
2773 "Early Classmark Sending is allowed\n"
2774 "Early Classmark Sending is forbidden\n")
2775{
2776 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002777
2778 if (!strcmp(argv[0], "allowed"))
2779 bts->early_classmark_allowed = true;
2780 else
2781 bts->early_classmark_allowed = false;
2782
2783 return CMD_SUCCESS;
2784}
2785
Harald Welte32c09622011-01-11 23:44:56 +01002786DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002787 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002788 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002789 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2790 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002791{
2792 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002793 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002794
Harald Welte64c07d22011-02-15 11:43:27 +01002795 switch (mode) {
2796 case NL_MODE_MANUAL_SI5SEP:
2797 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002798 /* make sure we clear the current list when switching to
2799 * manual mode */
2800 if (bts->neigh_list_manual_mode == 0)
2801 memset(&bts->si_common.data.neigh_list, 0,
2802 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002803 break;
2804 default:
2805 break;
2806 }
2807
2808 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002809
2810 return CMD_SUCCESS;
2811}
2812
2813DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002814 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002815 "Neighbor List\n" "Add to manual neighbor list\n"
2816 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2817 "ARFCN of neighbor\n")
2818{
2819 struct gsm_bts *bts = vty->index;
2820 struct bitvec *bv = &bts->si_common.neigh_list;
2821 uint16_t arfcn = atoi(argv[1]);
2822
2823 if (!bts->neigh_list_manual_mode) {
2824 vty_out(vty, "%% Cannot configure neighbor list in "
2825 "automatic mode%s", VTY_NEWLINE);
2826 return CMD_WARNING;
2827 }
2828
2829 if (!strcmp(argv[0], "add"))
2830 bitvec_set_bit_pos(bv, arfcn, 1);
2831 else
2832 bitvec_set_bit_pos(bv, arfcn, 0);
2833
2834 return CMD_SUCCESS;
2835}
2836
Max70fdd242017-06-15 15:10:53 +02002837/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002838DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002839 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2840 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2841 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2842 "Add to manual SI2quater neighbor list\n"
2843 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2844 "threshold high bits\n" "threshold high bits\n"
2845 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2846 "priority\n" "priority (8 means NA)\n"
2847 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2848 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002849{
2850 struct gsm_bts *bts = vty->index;
2851 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2852 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002853 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2854 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002855 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002856
Max70fdd242017-06-15 15:10:53 +02002857 switch (r) {
2858 case 1:
2859 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2860 thresh_hi, VTY_NEWLINE);
2861 break;
2862 case EARFCN_THRESH_LOW_INVALID:
2863 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2864 thresh_lo, VTY_NEWLINE);
2865 break;
2866 case EARFCN_QRXLV_INVALID + 1:
2867 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2868 qrx, VTY_NEWLINE);
2869 break;
2870 case EARFCN_PRIO_INVALID:
2871 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
2872 prio, VTY_NEWLINE);
2873 break;
2874 default:
2875 if (r < 0) {
2876 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
2877 return CMD_WARNING;
2878 }
Max59a1bf32016-04-15 16:04:46 +02002879 }
2880
Max70fdd242017-06-15 15:10:53 +02002881 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01002882 return CMD_SUCCESS;
2883
Maxf39d03a2017-05-12 17:00:30 +02002884 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02002885 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02002886 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01002887
Maxaafff962016-04-20 15:57:14 +02002888 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02002889}
2890
2891DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02002892 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02002893 "SI2quater Neighbor List\n"
2894 "SI2quater Neighbor List\n"
2895 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02002896 "EARFCN of neighbor\n"
2897 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02002898{
2899 struct gsm_bts *bts = vty->index;
2900 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02002901 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02002902 int r = osmo_earfcn_del(e, arfcn);
2903 if (r < 0) {
2904 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02002905 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02002906 return CMD_WARNING;
2907 }
2908
2909 return CMD_SUCCESS;
2910}
2911
Max26679e02016-04-20 15:57:13 +02002912DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02002913 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02002914 "SI2quater Neighbor List\n"
2915 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
2916 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
2917 "diversity bit\n")
2918{
2919 struct gsm_bts *bts = vty->index;
2920 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
2921
2922 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
2923 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02002924 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 +01002925 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02002926 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02002927 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
2928 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01002929 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02002930 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02002931 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02002932 return CMD_WARNING;
2933 }
2934
2935 return CMD_SUCCESS;
2936}
2937
2938DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02002939 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02002940 "SI2quater Neighbor List\n"
2941 "SI2quater Neighbor List\n"
2942 "Delete from SI2quater manual neighbor list\n"
2943 "UARFCN of neighbor\n"
2944 "UARFCN\n"
2945 "scrambling code\n")
2946{
2947 struct gsm_bts *bts = vty->index;
2948
2949 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
2950 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
2951 VTY_NEWLINE);
2952 return CMD_WARNING;
2953 }
2954
2955 return CMD_SUCCESS;
2956}
2957
Harald Welte64c07d22011-02-15 11:43:27 +01002958DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002959 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002960 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002961 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
2962 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
2963 "ARFCN of neighbor\n")
2964{
2965 struct gsm_bts *bts = vty->index;
2966 struct bitvec *bv = &bts->si_common.si5_neigh_list;
2967 uint16_t arfcn = atoi(argv[1]);
2968
2969 if (!bts->neigh_list_manual_mode) {
2970 vty_out(vty, "%% Cannot configure neighbor list in "
2971 "automatic mode%s", VTY_NEWLINE);
2972 return CMD_WARNING;
2973 }
2974
2975 if (!strcmp(argv[0], "add"))
2976 bitvec_set_bit_pos(bv, arfcn, 1);
2977 else
2978 bitvec_set_bit_pos(bv, arfcn, 0);
2979
2980 return CMD_SUCCESS;
2981}
Harald Welte9fbff4a2010-07-30 11:50:09 +02002982
Harald Welte8254cf72017-05-29 13:42:19 +02002983DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
2984 "pcu-socket PATH",
2985 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
2986 "Path in the file system for the unix-domain PCU socket\n")
2987{
2988 struct gsm_bts *bts = vty->index;
2989 int rc;
2990
Harald Welte4a824ca2017-05-29 13:54:27 +02002991 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02002992 pcu_sock_exit(bts);
2993 rc = pcu_sock_init(bts->pcu_sock_path, bts);
2994 if (rc < 0) {
2995 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
2996 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
2997 return CMD_WARNING;
2998 }
2999
3000 return CMD_SUCCESS;
3001}
3002
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003003#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3004
3005DEFUN(cfg_bts_excl_rf_lock,
3006 cfg_bts_excl_rf_lock_cmd,
3007 "rf-lock-exclude",
3008 EXCL_RFLOCK_STR)
3009{
3010 struct gsm_bts *bts = vty->index;
3011 bts->excl_from_rf_lock = 1;
3012 return CMD_SUCCESS;
3013}
3014
3015DEFUN(cfg_bts_no_excl_rf_lock,
3016 cfg_bts_no_excl_rf_lock_cmd,
3017 "no rf-lock-exclude",
3018 NO_STR EXCL_RFLOCK_STR)
3019{
3020 struct gsm_bts *bts = vty->index;
3021 bts->excl_from_rf_lock = 0;
3022 return CMD_SUCCESS;
3023}
3024
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003025#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3026
3027DEFUN(cfg_bts_force_comb_si,
3028 cfg_bts_force_comb_si_cmd,
3029 "force-combined-si",
3030 FORCE_COMB_SI_STR)
3031{
3032 struct gsm_bts *bts = vty->index;
3033 bts->force_combined_si = 1;
3034 return CMD_SUCCESS;
3035}
3036
3037DEFUN(cfg_bts_no_force_comb_si,
3038 cfg_bts_no_force_comb_si_cmd,
3039 "no force-combined-si",
3040 NO_STR FORCE_COMB_SI_STR)
3041{
3042 struct gsm_bts *bts = vty->index;
3043 bts->force_combined_si = 0;
3044 return CMD_SUCCESS;
3045}
3046
Andreas Eversberga83d5112013-12-07 18:32:28 +01003047static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3048{
3049 struct gsm_bts *bts = vty->index;
3050 struct bts_codec_conf *codec = &bts->codec;
3051 int i;
3052
3053 codec->hr = 0;
3054 codec->efr = 0;
3055 codec->amr = 0;
3056 for (i = 0; i < argc; i++) {
3057 if (!strcmp(argv[i], "hr"))
3058 codec->hr = 1;
3059 if (!strcmp(argv[i], "efr"))
3060 codec->efr = 1;
3061 if (!strcmp(argv[i], "amr"))
3062 codec->amr = 1;
3063 }
3064}
3065
3066#define CODEC_PAR_STR " (hr|efr|amr)"
3067#define CODEC_HELP_STR "Half Rate\n" \
3068 "Enhanced Full Rate\nAdaptive Multirate\n"
3069
3070DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3071 "codec-support fr",
3072 "Codec Support settings\nFullrate\n")
3073{
3074 _get_codec_from_arg(vty, 0, argv);
3075 return CMD_SUCCESS;
3076}
3077
3078DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3079 "codec-support fr" CODEC_PAR_STR,
3080 "Codec Support settings\nFullrate\n"
3081 CODEC_HELP_STR)
3082{
3083 _get_codec_from_arg(vty, 1, argv);
3084 return CMD_SUCCESS;
3085}
3086
3087DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3088 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3089 "Codec Support settings\nFullrate\n"
3090 CODEC_HELP_STR CODEC_HELP_STR)
3091{
3092 _get_codec_from_arg(vty, 2, argv);
3093 return CMD_SUCCESS;
3094}
3095
3096DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3097 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3098 "Codec Support settings\nFullrate\n"
3099 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3100{
3101 _get_codec_from_arg(vty, 3, argv);
3102 return CMD_SUCCESS;
3103}
3104
3105DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3106 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3107 "Codec Support settings\nFullrate\n"
3108 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3109{
3110 _get_codec_from_arg(vty, 4, argv);
3111 return CMD_SUCCESS;
3112}
3113
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003114DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3115 "depends-on-bts <0-255>",
3116 "This BTS can only be started if another one is up\n" "BTS Number\n")
3117{
3118 struct gsm_bts *bts = vty->index;
3119 struct gsm_bts *other_bts;
3120 int dep = atoi(argv[0]);
3121
3122
3123 if (!is_ipaccess_bts(bts)) {
3124 vty_out(vty, "This feature is only available for IP systems.%s",
3125 VTY_NEWLINE);
3126 return CMD_WARNING;
3127 }
3128
3129 other_bts = gsm_bts_num(bts->network, dep);
3130 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3131 vty_out(vty, "This feature is only available for IP systems.%s",
3132 VTY_NEWLINE);
3133 return CMD_WARNING;
3134 }
3135
3136 if (dep >= bts->nr) {
3137 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3138 VTY_NEWLINE);
3139 return CMD_WARNING;
3140 }
3141
3142 bts_depend_mark(bts, dep);
3143 return CMD_SUCCESS;
3144}
3145
3146DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3147 "depeneds-on-bts <0-255>",
3148 NO_STR "This BTS can only be started if another one is up\n"
3149 "BTS Number\n")
3150{
3151 struct gsm_bts *bts = vty->index;
3152 int dep = atoi(argv[0]);
3153
3154 bts_depend_clear(bts, dep);
3155 return CMD_SUCCESS;
3156}
3157
Andreas Eversberg73266522014-01-19 11:47:44 +01003158#define AMR_TEXT "Adaptive Multi Rate settings\n"
3159#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3160#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3161 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3162#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3163#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3164
3165static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3166{
3167 struct gsm_bts *bts = vty->index;
3168 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3169 struct gsm48_multi_rate_conf *mr_conf =
3170 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3171 int i;
3172
3173 mr->gsm48_ie[1] = 0;
3174 for (i = 0; i < argc; i++)
3175 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3176 mr_conf->icmi = 0;
3177}
3178
3179static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3180{
3181 struct gsm_bts *bts = vty->index;
3182 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003183 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003184 int i;
3185
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003186 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3187 for (i = 0; i < argc - 1; i++)
3188 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003189}
3190
3191static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3192{
3193 struct gsm_bts *bts = vty->index;
3194 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003195 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003196 int i;
3197
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003198 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3199 for (i = 0; i < argc - 1; i++)
3200 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003201}
3202
3203static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3204{
3205 struct gsm_bts *bts = vty->index;
3206 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3207 struct gsm48_multi_rate_conf *mr_conf =
3208 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3209 int num = 0, i;
3210
3211 for (i = 0; i < ((full) ? 8 : 6); i++) {
3212 if ((mr->gsm48_ie[1] & (1 << i))) {
3213 num++;
3214 }
3215 }
3216
3217 if (argv[0][0] == 'a' || num == 0)
3218 mr_conf->icmi = 0;
3219 else {
3220 mr_conf->icmi = 1;
3221 if (num < atoi(argv[0]))
3222 mr_conf->smod = num - 1;
3223 else
3224 mr_conf->smod = atoi(argv[0]) - 1;
3225 }
3226}
3227
3228#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3229#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3230 "10,2k\n12,2k\n"
3231
3232#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3233#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3234
3235#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3236#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3237
3238DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3239 "amr tch-f modes" AMR_TCHF_PAR_STR,
3240 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3241 AMR_TCHF_HELP_STR)
3242{
3243 get_amr_from_arg(vty, 1, argv, 1);
3244 return CMD_SUCCESS;
3245}
3246
3247DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3248 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3249 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3250 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3251{
3252 get_amr_from_arg(vty, 2, argv, 1);
3253 return CMD_SUCCESS;
3254}
3255
3256DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3257 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3258 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3259 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3260{
3261 get_amr_from_arg(vty, 3, argv, 1);
3262 return CMD_SUCCESS;
3263}
3264
3265DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3266 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3267 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3268 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3269{
3270 get_amr_from_arg(vty, 4, argv, 1);
3271 return CMD_SUCCESS;
3272}
3273
3274DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3275 "amr tch-f start-mode (auto|1|2|3|4)",
3276 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3277{
3278 get_amr_start_from_arg(vty, argv, 1);
3279 return CMD_SUCCESS;
3280}
3281
3282DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3283 "amr tch-f threshold (ms|bts) <0-63>",
3284 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3285 AMR_TH_HELP_STR)
3286{
3287 get_amr_th_from_arg(vty, 2, argv, 1);
3288 return CMD_SUCCESS;
3289}
3290
3291DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3292 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3293 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3294 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3295{
3296 get_amr_th_from_arg(vty, 3, argv, 1);
3297 return CMD_SUCCESS;
3298}
3299
3300DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3301 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3302 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3303 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3304{
3305 get_amr_th_from_arg(vty, 4, argv, 1);
3306 return CMD_SUCCESS;
3307}
3308
3309DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3310 "amr tch-f hysteresis (ms|bts) <0-15>",
3311 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3312 AMR_HY_HELP_STR)
3313{
3314 get_amr_hy_from_arg(vty, 2, argv, 1);
3315 return CMD_SUCCESS;
3316}
3317
3318DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3319 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3320 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3321 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3322{
3323 get_amr_hy_from_arg(vty, 3, argv, 1);
3324 return CMD_SUCCESS;
3325}
3326
3327DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3328 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3329 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3330 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3331{
3332 get_amr_hy_from_arg(vty, 4, argv, 1);
3333 return CMD_SUCCESS;
3334}
3335
3336DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3337 "amr tch-h modes" AMR_TCHH_PAR_STR,
3338 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3339 AMR_TCHH_HELP_STR)
3340{
3341 get_amr_from_arg(vty, 1, argv, 0);
3342 return CMD_SUCCESS;
3343}
3344
3345DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3346 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3347 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3348 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3349{
3350 get_amr_from_arg(vty, 2, argv, 0);
3351 return CMD_SUCCESS;
3352}
3353
3354DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3355 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3356 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3357 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3358{
3359 get_amr_from_arg(vty, 3, argv, 0);
3360 return CMD_SUCCESS;
3361}
3362
3363DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3364 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3365 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3366 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3367{
3368 get_amr_from_arg(vty, 4, argv, 0);
3369 return CMD_SUCCESS;
3370}
3371
3372DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3373 "amr tch-h start-mode (auto|1|2|3|4)",
3374 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3375{
3376 get_amr_start_from_arg(vty, argv, 0);
3377 return CMD_SUCCESS;
3378}
3379
3380DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3381 "amr tch-h threshold (ms|bts) <0-63>",
3382 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3383 AMR_TH_HELP_STR)
3384{
3385 get_amr_th_from_arg(vty, 2, argv, 0);
3386 return CMD_SUCCESS;
3387}
3388
3389DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3390 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3391 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3392 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3393{
3394 get_amr_th_from_arg(vty, 3, argv, 0);
3395 return CMD_SUCCESS;
3396}
3397
3398DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3399 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3400 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3401 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3402{
3403 get_amr_th_from_arg(vty, 4, argv, 0);
3404 return CMD_SUCCESS;
3405}
3406
3407DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3408 "amr tch-h hysteresis (ms|bts) <0-15>",
3409 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3410 AMR_HY_HELP_STR)
3411{
3412 get_amr_hy_from_arg(vty, 2, argv, 0);
3413 return CMD_SUCCESS;
3414}
3415
3416DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3417 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3418 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3419 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3420{
3421 get_amr_hy_from_arg(vty, 3, argv, 0);
3422 return CMD_SUCCESS;
3423}
3424
3425DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3426 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3427 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3428 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3429{
3430 get_amr_hy_from_arg(vty, 4, argv, 0);
3431 return CMD_SUCCESS;
3432}
3433
Harald Welte8f0ed552010-05-11 21:53:49 +02003434#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003435
Harald Welte5258fc42009-03-28 19:07:53 +00003436/* per TRX configuration */
3437DEFUN(cfg_trx,
3438 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003439 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003440 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003441 "Select a TRX to configure")
3442{
3443 int trx_nr = atoi(argv[0]);
3444 struct gsm_bts *bts = vty->index;
3445 struct gsm_bts_trx *trx;
3446
Harald Weltee441d9c2009-06-21 16:17:15 +02003447 if (trx_nr > bts->num_trx) {
3448 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3449 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003450 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003451 } else if (trx_nr == bts->num_trx) {
3452 /* we need to allocate a new one */
3453 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003454 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003455 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003456
Harald Weltee441d9c2009-06-21 16:17:15 +02003457 if (!trx)
3458 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003459
3460 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003461 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003462 vty->node = TRX_NODE;
3463
3464 return CMD_SUCCESS;
3465}
3466
3467DEFUN(cfg_trx_arfcn,
3468 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003469 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003470 "Set the ARFCN for this TRX\n"
3471 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003472{
3473 int arfcn = atoi(argv[0]);
3474 struct gsm_bts_trx *trx = vty->index;
3475
3476 /* FIXME: check if this ARFCN is supported by this TRX */
3477
3478 trx->arfcn = arfcn;
3479
3480 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3481 /* FIXME: use OML layer to update the ARFCN */
3482 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3483
3484 return CMD_SUCCESS;
3485}
3486
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003487DEFUN(cfg_trx_nominal_power,
3488 cfg_trx_nominal_power_cmd,
3489 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003490 "Nominal TRX RF Power in dBm\n"
3491 "Nominal TRX RF Power in dBm\n"
3492 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003493{
3494 struct gsm_bts_trx *trx = vty->index;
3495
3496 trx->nominal_power = atoi(argv[0]);
3497
3498 return CMD_SUCCESS;
3499}
3500
Harald Weltefcd24452009-06-20 18:15:19 +02003501DEFUN(cfg_trx_max_power_red,
3502 cfg_trx_max_power_red_cmd,
3503 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003504 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003505 "Reduction of maximum BS RF Power in dB\n")
3506{
3507 int maxpwr_r = atoi(argv[0]);
3508 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003509 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003510
3511 /* FIXME: check if our BTS type supports more than 12 */
3512 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3513 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3514 maxpwr_r, VTY_NEWLINE);
3515 return CMD_WARNING;
3516 }
3517 if (maxpwr_r & 1) {
3518 vty_out(vty, "%% Power %d dB is not an even value%s",
3519 maxpwr_r, VTY_NEWLINE);
3520 return CMD_WARNING;
3521 }
3522
3523 trx->max_power_red = maxpwr_r;
3524
3525 /* FIXME: make sure we update this using OML */
3526
3527 return CMD_SUCCESS;
3528}
3529
Harald Welte42581822009-08-08 16:12:58 +02003530DEFUN(cfg_trx_rsl_e1,
3531 cfg_trx_rsl_e1_cmd,
3532 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003533 "RSL Parameters\n"
3534 "E1/T1 interface to be used for RSL\n"
3535 "E1/T1 interface to be used for RSL\n"
3536 "E1/T1 Line Number to be used for RSL\n"
3537 "E1/T1 Timeslot to be used for RSL\n"
3538 "E1/T1 Timeslot to be used for RSL\n"
3539 "E1/T1 Sub-slot to be used for RSL\n"
3540 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3541 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3542 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3543 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3544 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003545{
3546 struct gsm_bts_trx *trx = vty->index;
3547
3548 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3549
3550 return CMD_SUCCESS;
3551}
3552
3553DEFUN(cfg_trx_rsl_e1_tei,
3554 cfg_trx_rsl_e1_tei_cmd,
3555 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003556 "RSL Parameters\n"
3557 "Set the TEI to be used for RSL\n"
3558 "Set the TEI to be used for RSL\n"
3559 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003560{
3561 struct gsm_bts_trx *trx = vty->index;
3562
3563 trx->rsl_tei = atoi(argv[0]);
3564
3565 return CMD_SUCCESS;
3566}
3567
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003568DEFUN(cfg_trx_rf_locked,
3569 cfg_trx_rf_locked_cmd,
3570 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003571 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3572 "TRX is NOT RF locked (active)\n"
3573 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003574{
3575 int locked = atoi(argv[0]);
3576 struct gsm_bts_trx *trx = vty->index;
3577
3578 gsm_trx_lock_rf(trx, locked);
3579 return CMD_SUCCESS;
3580}
Harald Welte42581822009-08-08 16:12:58 +02003581
Harald Welte5258fc42009-03-28 19:07:53 +00003582/* per TS configuration */
3583DEFUN(cfg_ts,
3584 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003585 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003586 "Select a Timeslot to configure\n"
3587 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003588{
3589 int ts_nr = atoi(argv[0]);
3590 struct gsm_bts_trx *trx = vty->index;
3591 struct gsm_bts_trx_ts *ts;
3592
3593 if (ts_nr >= TRX_NR_TS) {
3594 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3595 TRX_NR_TS, VTY_NEWLINE);
3596 return CMD_WARNING;
3597 }
3598
3599 ts = &trx->ts[ts_nr];
3600
3601 vty->index = ts;
3602 vty->node = TS_NODE;
3603
3604 return CMD_SUCCESS;
3605}
3606
Harald Weltea6fd58e2009-08-07 00:25:23 +02003607DEFUN(cfg_ts_pchan,
3608 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003609 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003610 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003611{
3612 struct gsm_bts_trx_ts *ts = vty->index;
3613 int pchanc;
3614
3615 pchanc = gsm_pchan_parse(argv[0]);
3616 if (pchanc < 0)
3617 return CMD_WARNING;
3618
3619 ts->pchan = pchanc;
3620
3621 return CMD_SUCCESS;
3622}
3623
3624/* used for backwards compatibility with old config files that still
3625 * have uppercase pchan type names */
3626DEFUN_HIDDEN(cfg_ts_pchan_compat,
3627 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003628 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003629 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003630{
3631 struct gsm_bts_trx_ts *ts = vty->index;
3632 int pchanc;
3633
3634 pchanc = gsm_pchan_parse(argv[0]);
3635 if (pchanc < 0)
3636 return CMD_WARNING;
3637
3638 ts->pchan = pchanc;
3639
3640 return CMD_SUCCESS;
3641}
3642
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003643
3644
Harald Welte135a6482011-05-30 12:09:13 +02003645DEFUN(cfg_ts_tsc,
3646 cfg_ts_tsc_cmd,
3647 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003648 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003649{
3650 struct gsm_bts_trx_ts *ts = vty->index;
3651
Max71d082b2017-05-30 15:03:38 +02003652 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003653 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3654 "falling back to BCC%s", VTY_NEWLINE);
3655 ts->tsc = -1;
3656 return CMD_WARNING;
3657 }
3658
Harald Welte135a6482011-05-30 12:09:13 +02003659 ts->tsc = atoi(argv[0]);
3660
3661 return CMD_SUCCESS;
3662}
3663
Harald Weltea39b0f22010-06-14 22:26:10 +02003664#define HOPPING_STR "Configure frequency hopping\n"
3665
3666DEFUN(cfg_ts_hopping,
3667 cfg_ts_hopping_cmd,
3668 "hopping enabled (0|1)",
3669 HOPPING_STR "Enable or disable frequency hopping\n"
3670 "Disable frequency hopping\n" "Enable frequency hopping\n")
3671{
3672 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003673 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003674
Max71d082b2017-05-30 15:03:38 +02003675 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003676 vty_out(vty, "BTS model does not support hopping%s",
3677 VTY_NEWLINE);
3678 return CMD_WARNING;
3679 }
3680
3681 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003682
3683 return CMD_SUCCESS;
3684}
3685
Harald Welte6e0cd042009-09-12 13:05:33 +02003686DEFUN(cfg_ts_hsn,
3687 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003688 "hopping sequence-number <0-63>",
3689 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003690 "Which hopping sequence to use for this channel\n"
3691 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003692{
3693 struct gsm_bts_trx_ts *ts = vty->index;
3694
3695 ts->hopping.hsn = atoi(argv[0]);
3696
3697 return CMD_SUCCESS;
3698}
3699
3700DEFUN(cfg_ts_maio,
3701 cfg_ts_maio_cmd,
3702 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003703 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003704 "Which hopping MAIO to use for this channel\n"
3705 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003706{
3707 struct gsm_bts_trx_ts *ts = vty->index;
3708
3709 ts->hopping.maio = atoi(argv[0]);
3710
3711 return CMD_SUCCESS;
3712}
3713
3714DEFUN(cfg_ts_arfcn_add,
3715 cfg_ts_arfcn_add_cmd,
3716 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003717 HOPPING_STR "Configure hopping ARFCN list\n"
3718 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003719{
3720 struct gsm_bts_trx_ts *ts = vty->index;
3721 int arfcn = atoi(argv[0]);
3722
Harald Weltea39b0f22010-06-14 22:26:10 +02003723 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3724
Harald Welte6e0cd042009-09-12 13:05:33 +02003725 return CMD_SUCCESS;
3726}
3727
3728DEFUN(cfg_ts_arfcn_del,
3729 cfg_ts_arfcn_del_cmd,
3730 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003731 HOPPING_STR "Configure hopping ARFCN list\n"
3732 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003733{
3734 struct gsm_bts_trx_ts *ts = vty->index;
3735 int arfcn = atoi(argv[0]);
3736
Harald Weltea39b0f22010-06-14 22:26:10 +02003737 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3738
Harald Welte6e0cd042009-09-12 13:05:33 +02003739 return CMD_SUCCESS;
3740}
3741
Harald Weltea6fd58e2009-08-07 00:25:23 +02003742DEFUN(cfg_ts_e1_subslot,
3743 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003744 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003745 "E1/T1 channel connected to this on-air timeslot\n"
3746 "E1/T1 channel connected to this on-air timeslot\n"
3747 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003748 "E1/T1 timeslot connected to this on-air timeslot\n"
3749 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003750 "E1/T1 sub-slot connected to this on-air timeslot\n"
3751 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3752 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3753 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3754 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3755 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003756{
3757 struct gsm_bts_trx_ts *ts = vty->index;
3758
Harald Welte42581822009-08-08 16:12:58 +02003759 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003760
3761 return CMD_SUCCESS;
3762}
Harald Welte5258fc42009-03-28 19:07:53 +00003763
Harald Welte4f10c252010-05-16 21:47:13 +02003764void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3765{
3766 vty_out(vty, "Channel Requests : %lu total, %lu no channel%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003767 net->bsc_ctrs->ctr[BSC_CTR_CHREQ_TOTAL].current,
3768 net->bsc_ctrs->ctr[BSC_CTR_CHREQ_NO_CHANNEL].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003769 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003770 vty_out(vty, "Channel Failures : %lu rf_failures, %lu rll failures%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003771 net->bsc_ctrs->ctr[BSC_CTR_CHAN_RF_FAIL].current,
3772 net->bsc_ctrs->ctr[BSC_CTR_CHAN_RLL_ERR].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003773 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003774 vty_out(vty, "Paging : %lu attempted, %lu complete, %lu expired%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003775 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
3776 net->bsc_ctrs->ctr[BSC_CTR_PAGING_COMPLETED].current,
3777 net->bsc_ctrs->ctr[BSC_CTR_PAGING_EXPIRED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003778 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003779 vty_out(vty, "BTS failures : %lu OML, %lu RSL%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003780 net->bsc_ctrs->ctr[BSC_CTR_BTS_OML_FAIL].current,
3781 net->bsc_ctrs->ctr[BSC_CTR_BTS_RSL_FAIL].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003782 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003783}
3784
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003785DEFUN(drop_bts,
3786 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003787 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003788 "Debug/Simulation command to drop Abis/IP BTS\n"
3789 "Debug/Simulation command to drop Abis/IP BTS\n"
3790 "Debug/Simulation command to drop Abis/IP BTS\n"
3791 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003792{
3793 struct gsm_network *gsmnet;
3794 struct gsm_bts_trx *trx;
3795 struct gsm_bts *bts;
3796 unsigned int bts_nr;
3797
3798 gsmnet = gsmnet_from_vty(vty);
3799
3800 bts_nr = atoi(argv[0]);
3801 if (bts_nr >= gsmnet->num_bts) {
3802 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3803 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3804 return CMD_WARNING;
3805 }
3806
3807 bts = gsm_bts_num(gsmnet, bts_nr);
3808 if (!bts) {
3809 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3810 return CMD_WARNING;
3811 }
3812
3813 if (!is_ipaccess_bts(bts)) {
3814 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3815 return CMD_WARNING;
3816 }
3817
3818
3819 /* close all connections */
3820 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003821 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003822 } else if (strcmp(argv[1], "rsl") == 0) {
3823 /* close all rsl connections */
3824 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003825 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003826 }
3827 } else {
3828 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3829 return CMD_WARNING;
3830 }
3831
3832 return CMD_SUCCESS;
3833}
3834
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003835DEFUN(restart_bts, restart_bts_cmd,
3836 "restart-bts <0-65535>",
3837 "Restart ip.access nanoBTS through OML\n"
3838 "BTS Number\n")
3839{
3840 struct gsm_network *gsmnet;
3841 struct gsm_bts_trx *trx;
3842 struct gsm_bts *bts;
3843 unsigned int bts_nr;
3844
3845 gsmnet = gsmnet_from_vty(vty);
3846
3847 bts_nr = atoi(argv[0]);
3848 if (bts_nr >= gsmnet->num_bts) {
3849 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3850 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3851 return CMD_WARNING;
3852 }
3853
3854 bts = gsm_bts_num(gsmnet, bts_nr);
3855 if (!bts) {
3856 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3857 return CMD_WARNING;
3858 }
3859
3860 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3861 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3862 VTY_NEWLINE);
3863 return CMD_WARNING;
3864 }
3865
3866 /* go from last TRX to c0 */
3867 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3868 abis_nm_ipaccess_restart(trx);
3869
3870 return CMD_SUCCESS;
3871}
3872
Harald Welte8e2e22f2017-07-10 20:25:10 +02003873DEFUN(bts_resend, bts_resend_cmd,
3874 "bts <0-255> resend-system-information",
3875 "BTS Specific Commands\n" "BTS Number\n"
3876 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3877{
3878 struct gsm_network *gsmnet;
3879 struct gsm_bts_trx *trx;
3880 struct gsm_bts *bts;
3881 unsigned int bts_nr;
3882
3883 gsmnet = gsmnet_from_vty(vty);
3884
3885 bts_nr = atoi(argv[0]);
3886 if (bts_nr >= gsmnet->num_bts) {
3887 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3888 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3889 return CMD_WARNING;
3890 }
3891
3892 bts = gsm_bts_num(gsmnet, bts_nr);
3893 if (!bts) {
3894 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3895 return CMD_WARNING;
3896 }
3897
3898 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3899 gsm_bts_trx_set_system_infos(trx);
3900
3901 return CMD_SUCCESS;
3902}
3903
3904
Harald Welte30f1f372014-12-28 15:00:45 +01003905DEFUN(smscb_cmd, smscb_cmd_cmd,
3906 "bts <0-255> smscb-command <1-4> HEXSTRING",
3907 "BTS related commands\n" "BTS Number\n"
3908 "SMS Cell Broadcast\n" "Last Valid Block\n"
3909 "Hex Encoded SMSCB message (up to 88 octets)\n")
3910{
3911 struct gsm_bts *bts;
3912 int bts_nr = atoi(argv[0]);
3913 int last_block = atoi(argv[1]);
3914 struct rsl_ie_cb_cmd_type cb_cmd;
3915 uint8_t buf[88];
3916 int rc;
3917
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02003918 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01003919 if (!bts) {
3920 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3921 return CMD_WARNING;
3922 }
3923 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
3924 if (rc < 0 || rc > sizeof(buf)) {
3925 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3926 return CMD_WARNING;
3927 }
3928
3929 cb_cmd.spare = 0;
3930 cb_cmd.def_bcast = 0;
3931 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
3932
3933 switch (last_block) {
3934 case 1:
3935 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
3936 break;
3937 case 2:
3938 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
3939 break;
3940 case 3:
3941 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
3942 break;
3943 case 4:
3944 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
3945 break;
3946 }
3947
3948 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
3949
3950 return CMD_SUCCESS;
3951}
3952
Harald Welte7fe00fb2017-05-27 14:09:50 +02003953/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02003954static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
3955 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02003956{
Harald Welte645eb622017-05-27 15:52:58 +02003957 int bts_nr = atoi(bts_str);
3958 int trx_nr = atoi(trx_str);
3959 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003960 struct gsm_bts *bts;
3961 struct gsm_bts_trx *trx;
3962 struct gsm_bts_trx_ts *ts;
3963
3964 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
3965 if (!bts) {
3966 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3967 return NULL;
3968 }
3969
3970 trx = gsm_bts_trx_num(bts, trx_nr);
3971 if (!trx) {
3972 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
3973 return NULL;
3974 }
3975
3976 ts = &trx->ts[ts_nr];
3977
3978 return ts;
3979}
Harald Welte30f1f372014-12-28 15:00:45 +01003980
Harald Welted0d2b0b2010-12-23 13:18:07 +01003981DEFUN(pdch_act, pdch_act_cmd,
3982 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
3983 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
3984 "TRX Timeslot\n" "Timeslot Number\n" "Packet Data Channel\n"
3985 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
3986 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
3987{
Harald Welted0d2b0b2010-12-23 13:18:07 +01003988 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01003989 int activate;
3990
Harald Welte645eb622017-05-27 15:52:58 +02003991 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003992 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01003993 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01003994
Harald Welte7fe00fb2017-05-27 14:09:50 +02003995 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01003996 vty_out(vty, "%% This command only works for ipaccess BTS%s",
3997 VTY_NEWLINE);
3998 return CMD_WARNING;
3999 }
4000
Harald Welted0d2b0b2010-12-23 13:18:07 +01004001 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4002 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004003 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004004 return CMD_WARNING;
4005 }
4006
4007 if (!strcmp(argv[3], "activate"))
4008 activate = 1;
4009 else
4010 activate = 0;
4011
4012 rsl_ipacc_pdch_activate(ts, activate);
4013
4014 return CMD_SUCCESS;
4015
4016}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004017
Harald Welte2abd5e12017-05-27 14:10:40 +02004018/* determine the logical channel type based on the physical channel type */
4019static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4020{
4021 switch (pchan) {
4022 case GSM_PCHAN_TCH_F:
4023 return GSM_LCHAN_TCH_F;
4024 case GSM_PCHAN_TCH_H:
4025 return GSM_LCHAN_TCH_H;
4026 case GSM_PCHAN_SDCCH8_SACCH8C:
4027 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4028 case GSM_PCHAN_CCCH_SDCCH4:
4029 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4030 return GSM_LCHAN_SDCCH;
4031 default:
4032 return -1;
4033 }
4034}
4035
4036/* configure the lchan for a single AMR mode (as specified) */
4037static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4038{
4039 struct amr_multirate_conf mr;
4040 struct gsm48_multi_rate_conf *mr_conf;
4041 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4042
4043 if (amr_mode > 7)
4044 return -1;
4045
4046 memset(&mr, 0, sizeof(mr));
4047 mr_conf->ver = 1;
4048 /* bit-mask of supported modes, only one bit is set. Reflects
4049 * Figure 10.5.2.47a where there are no thershold and only a
4050 * single mode */
4051 mr.gsm48_ie[1] = 1 << amr_mode;
4052
4053 mr.ms_mode[0].mode = amr_mode;
4054 mr.bts_mode[0].mode = amr_mode;
4055
4056 /* encode this configuration into the lchan for both uplink and
4057 * downlink direction */
4058 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4059 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4060
4061 return 0;
4062}
4063
4064/* Debug/Measurement command to activate a given logical channel
4065 * manually in a given mode/codec. This is useful for receiver
4066 * performance testing (FER/RBER/...) */
4067DEFUN(lchan_act, lchan_act_cmd,
4068 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
4069 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4070 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot Number\n" "Sub-Slot Number\n"
4071 "Manual Channel Activation (e.g. for BER test)\n"
4072 "Manual Channel Deactivation (e.g. for BER test)\n"
4073 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4074{
4075 struct gsm_bts_trx_ts *ts;
4076 struct gsm_lchan *lchan;
4077 int ss_nr = atoi(argv[3]);
4078 const char *act_str = argv[4];
4079 const char *codec_str = argv[5];
4080 int activate;
4081
4082 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4083 if (!ts)
4084 return CMD_WARNING;
4085
4086 lchan = &ts->lchan[ss_nr];
4087
4088 if (!strcmp(act_str, "activate"))
4089 activate = 1;
4090 else
4091 activate = 0;
4092
4093 if (ss_nr >= ts_subslots(ts)) {
4094 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4095 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4096 return CMD_WARNING;
4097 }
4098
4099 if (activate) {
4100 int lchan_t;
4101 if (lchan->state != LCHAN_S_NONE) {
4102 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4103 return CMD_WARNING;
4104 }
4105 lchan_t = lchan_type_by_pchan(ts->pchan);
4106 if (lchan_t < 0)
4107 return CMD_WARNING;
4108 /* configure the lchan */
4109 lchan->type = lchan_t;
4110 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4111 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4112 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4113 else if (!strcmp(codec_str, "efr"))
4114 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4115 else if (!strcmp(codec_str, "amr")) {
4116 int amr_mode;
4117 if (argc < 7) {
4118 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4119 return CMD_WARNING;
4120 }
4121 amr_mode = atoi(argv[6]);
4122 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4123 lchan_set_single_amr_mode(lchan, amr_mode);
4124 }
4125 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4126 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4127 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004128 } else {
4129 rsl_direct_rf_release(lchan);
4130 }
4131
4132 return CMD_SUCCESS;
4133}
4134
Harald Welte3f86c522017-05-27 15:53:28 +02004135DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4136 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
4137 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4138 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot\n" "Sub-Slot Number\n"
4139 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4140{
4141 struct gsm_bts_trx_ts *ts;
4142 struct gsm_lchan *lchan;
4143 int ss_nr = atoi(argv[3]);
4144 int port = atoi(argv[5]);
4145 struct in_addr ia;
4146 inet_aton(argv[4], &ia);
4147
4148 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4149 if (!ts)
4150 return CMD_WARNING;
4151
4152 lchan = &ts->lchan[ss_nr];
4153
4154 if (ss_nr >= ts_subslots(ts)) {
4155 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4156 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4157 return CMD_WARNING;
4158 }
4159
4160 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4161 inet_ntoa(ia), port, VTY_NEWLINE);
4162 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4163 return CMD_SUCCESS;
4164}
Harald Welteb71147a2017-07-18 19:11:49 +02004165
4166DEFUN(ctrl_trap, ctrl_trap_cmd,
4167 "ctrl-interface generate-trap TRAP VALUE",
4168 "Commands related to the CTRL Interface\n"
4169 "Generate a TRAP for test purpose\n"
4170 "Identity/Name of the TRAP variable\n"
4171 "Value of the TRAP variable\n")
4172{
4173 struct gsm_network *net = gsmnet_from_vty(vty);
4174
4175 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4176 return CMD_SUCCESS;
4177}
4178
Harald Weltedcccb182010-05-16 20:52:23 +02004179extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004180
Maxdb0e3802017-01-12 19:35:11 +01004181int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004182{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004183 cfg_ts_pchan_cmd.string =
4184 vty_cmd_string_from_valstr(tall_bsc_ctx,
4185 gsm_pchant_names,
4186 "phys_chan_config (", "|", ")",
4187 VTY_DO_LOWER);
4188 cfg_ts_pchan_cmd.doc =
4189 vty_cmd_string_from_valstr(tall_bsc_ctx,
4190 gsm_pchant_descs,
4191 "Physical Channel Combination\n",
4192 "\n", "", 0);
4193
Harald Weltee555c2b2012-08-17 13:02:12 +02004194 cfg_bts_type_cmd.string =
4195 vty_cmd_string_from_valstr(tall_bsc_ctx,
4196 bts_type_names,
4197 "type (", "|", ")",
4198 VTY_DO_LOWER);
4199 cfg_bts_type_cmd.doc =
4200 vty_cmd_string_from_valstr(tall_bsc_ctx,
4201 bts_type_descs,
4202 "BTS Vendor/Type\n",
4203 "\n", "", 0);
4204
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +02004205 common_cs_vty_init(network, config_write_net);
Harald Weltee555c2b2012-08-17 13:02:12 +02004206
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004207 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004208 install_element_ve(&show_bts_cmd);
4209 install_element_ve(&show_trx_cmd);
4210 install_element_ve(&show_ts_cmd);
4211 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004212 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004213
Philipp Maier39f62bb2017-04-09 12:32:51 +02004214 install_element_ve(&show_subscr_conn_cmd);
4215 install_element_ve(&handover_subscr_conn_cmd);
4216
Harald Welteb4d5b172010-05-12 16:10:35 +00004217 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004218 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004219
Maxdb0e3802017-01-12 19:35:11 +01004220 logging_vty_add_cmds(NULL);
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004221
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004222 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Weltebc814502009-12-19 21:41:52 +01004223 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Welteb720bd32009-12-21 16:51:50 +01004224 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
4225 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
4226 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
4227 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
4228 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
4229 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004230 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004231 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4232 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4233 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4234 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4235 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4236 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4237 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4238 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4239 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004240 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004241 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004242 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004243 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02004244
4245 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004246 install_node(&bts_node, config_write_bts);
Jacob Erlbeck36722e12013-10-29 09:30:30 +01004247 vty_install_default(BTS_NODE);
Harald Welte5258fc42009-03-28 19:07:53 +00004248 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004249 install_element(BTS_NODE, &cfg_description_cmd);
4250 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004251 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004252 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004253 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4254 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4255 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4256 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004257 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4258 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004259 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004260 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004261 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004262 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004263 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004264 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004265 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004266 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4267 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004268 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004269 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4270 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004271 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4272 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4273 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004274 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4275 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004276 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004277 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004278 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004279 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004280 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4281 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004282 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4283 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4284 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4285 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4286 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4287 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004288 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004289 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004290 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304291 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004292 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004293 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004294 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004295 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4296 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004297 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004298 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004299 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004300 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004301 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4302 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4303 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004304 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004305 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4306 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004307 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004308 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4309 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004310 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004311 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4312 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004313 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4314 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004315 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4316 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004317 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4318 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004319 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4320 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4321 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4322 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4323 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004324 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4325 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004326 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4327 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4328 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4329 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4330 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4331 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4332 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4333 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4334 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4335 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4336 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4337 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4338 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4339 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4340 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4341 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4342 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4343 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4344 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4345 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4346 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4347 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004348 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004349
Harald Welte5258fc42009-03-28 19:07:53 +00004350 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004351 install_node(&trx_node, dummy_config_write);
Jacob Erlbeck36722e12013-10-29 09:30:30 +01004352 vty_install_default(TRX_NODE);
Harald Welte5258fc42009-03-28 19:07:53 +00004353 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004354 install_element(TRX_NODE, &cfg_description_cmd);
4355 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004356 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004357 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004358 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4359 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004360 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004361
Harald Welte5258fc42009-03-28 19:07:53 +00004362 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004363 install_node(&ts_node, dummy_config_write);
Jacob Erlbeck36722e12013-10-29 09:30:30 +01004364 vty_install_default(TS_NODE);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004365 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004366 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004367 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004368 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004369 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4370 install_element(TS_NODE, &cfg_ts_maio_cmd);
4371 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4372 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004373 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004374
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004375 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004376 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004377 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004378 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004379 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004380 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004381 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004382 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004383
Harald Welte81c9b9c2010-05-31 16:40:40 +02004384 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004385 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004386 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004387 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004388
Harald Weltedcccb182010-05-16 20:52:23 +02004389 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004390
Harald Welte68628e82009-03-10 12:17:57 +00004391 return 0;
4392}