blob: f1c78c8d8326bf8011e3fff778782d080567a8c4 [file] [log] [blame]
Harald Welte68628e82009-03-10 12:17:57 +00001/* OpenBSC interface to quagga VTY */
Harald Welteaf387632010-03-14 23:30:30 +08002/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte68628e82009-03-10 12:17:57 +00003 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01006 * it under the terms of the GNU Affero General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
Harald Welte68628e82009-03-10 12:17:57 +00008 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010013 * GNU Affero General Public License for more details.
Harald Welte68628e82009-03-10 12:17:57 +000014 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010015 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte68628e82009-03-10 12:17:57 +000017 *
18 */
19
20#include <stdlib.h>
Maxc08ee712016-05-11 12:45:13 +020021#include <stdbool.h>
Harald Welte68628e82009-03-10 12:17:57 +000022#include <unistd.h>
Maxd1f70ed2017-09-21 16:15:32 +020023#include <time.h>
Harald Welte68628e82009-03-10 12:17:57 +000024
Harald Welte4b037e42010-05-19 19:45:32 +020025#include <osmocom/vty/command.h>
26#include <osmocom/vty/buffer.h>
27#include <osmocom/vty/vty.h>
28#include <osmocom/vty/logging.h>
Jacob Erlbeck64630cc2015-10-26 16:25:37 +010029#include <osmocom/vty/stats.h>
Harald Welte4b037e42010-05-19 19:45:32 +020030#include <osmocom/vty/telnet_interface.h>
Harald Welte4ab9d7c2012-08-17 12:42:06 +020031#include <osmocom/vty/misc.h>
Maxc08ee712016-05-11 12:45:13 +020032#include <osmocom/gsm/protocol/gsm_04_08.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010033#include <osmocom/gsm/gsm0502.h>
Harald Welteb71147a2017-07-18 19:11:49 +020034#include <osmocom/ctrl/control_if.h>
Neels Hofmeyr7b656882017-07-09 22:09:18 +020035#include <osmocom/gsm/gsm48.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010036
Harald Welte68628e82009-03-10 12:17:57 +000037#include <arpa/inet.h>
38
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010039#include <osmocom/core/linuxlist.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020040#include <osmocom/bsc/gsm_data.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020041#include <osmocom/abis/e1_input.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020042#include <osmocom/bsc/abis_nm.h>
43#include <osmocom/bsc/abis_om2000.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010044#include <osmocom/core/utils.h>
45#include <osmocom/gsm/gsm_utils.h>
Harald Weltecdc59ff2011-05-23 20:42:26 +020046#include <osmocom/gsm/abis_nm.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020047#include <osmocom/bsc/chan_alloc.h>
48#include <osmocom/bsc/meas_rep.h>
49#include <osmocom/bsc/vty.h>
Harald Welteea34a4e2012-06-16 14:59:56 +080050#include <osmocom/gprs/gprs_ns.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020051#include <osmocom/bsc/system_information.h>
52#include <osmocom/bsc/debug.h>
53#include <osmocom/bsc/paging.h>
54#include <osmocom/bsc/ipaccess.h>
55#include <osmocom/bsc/abis_rsl.h>
56#include <osmocom/bsc/bsc_msc_data.h>
57#include <osmocom/bsc/osmo_bsc_rf.h>
58#include <osmocom/bsc/pcu_if.h>
59#include <osmocom/bsc/common_cs.h>
60#include <osmocom/bsc/handover.h>
61#include <osmocom/bsc/gsm_04_08_utils.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020062
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010063#include <inttypes.h>
64
Harald Weltec08e8be2011-03-04 13:53:51 +010065#include "../../bscconfig.h"
Harald Welte1353f962010-05-16 19:20:24 +020066
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020067
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020068#define LCHAN_NR_STR "Logical Channel Number\n"
69
70
Harald Welteea4647d2010-05-12 17:19:53 +000071/* FIXME: this should go to some common file */
72static const struct value_string gprs_ns_timer_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020073 { 0, "tns-block" },
74 { 1, "tns-block-retries" },
75 { 2, "tns-reset" },
76 { 3, "tns-reset-retries" },
77 { 4, "tns-test" },
78 { 5, "tns-alive" },
79 { 6, "tns-alive-retries" },
80 { 0, NULL }
81};
82
Harald Welteea4647d2010-05-12 17:19:53 +000083static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020084 { 0, "blocking-timer" },
85 { 1, "blocking-retries" },
86 { 2, "unblocking-retries" },
87 { 3, "reset-timer" },
88 { 4, "reset-retries" },
89 { 5, "suspend-timer" },
90 { 6, "suspend-retries" },
91 { 7, "resume-timer" },
92 { 8, "resume-retries" },
93 { 9, "capability-update-timer" },
94 { 10, "capability-update-retries" },
95 { 0, NULL }
96};
97
Harald Welte64c07d22011-02-15 11:43:27 +010098static const struct value_string bts_neigh_mode_strs[] = {
99 { NL_MODE_AUTOMATIC, "automatic" },
100 { NL_MODE_MANUAL, "manual" },
101 { NL_MODE_MANUAL_SI5SEP, "manual-si5" },
102 { 0, NULL }
103};
104
Daniel Willmann7d109832012-05-14 18:43:23 +0200105const struct value_string bts_loc_fix_names[] = {
106 { BTS_LOC_FIX_INVALID, "invalid" },
107 { BTS_LOC_FIX_2D, "fix2d" },
108 { BTS_LOC_FIX_3D, "fix3d" },
109 { 0, NULL }
110};
111
Harald Welte68628e82009-03-10 12:17:57 +0000112struct cmd_node bts_node = {
113 BTS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200114 "%s(config-net-bts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000115 1,
116};
117
118struct cmd_node trx_node = {
119 TRX_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200120 "%s(config-net-bts-trx)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000121 1,
122};
123
124struct cmd_node ts_node = {
125 TS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200126 "%s(config-net-bts-trx-ts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000127 1,
128};
129
130static int dummy_config_write(struct vty *v)
131{
132 return CMD_SUCCESS;
133}
134
135static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
136{
Harald Welte1304b352013-03-15 16:57:33 +0100137 vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
138 abis_nm_opstate_name(nms->operational),
139 get_value_string(abis_nm_adm_state_names, nms->administrative),
Harald Welte867d9f32011-05-23 20:30:39 +0200140 abis_nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000141}
142
Harald Welteb908cb72009-12-22 13:09:29 +0100143static void dump_pchan_load_vty(struct vty *vty, char *prefix,
144 const struct pchan_load *pl)
145{
146 int i;
147
148 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
149 const struct load_counter *lc = &pl->pchan[i];
150 unsigned int percent;
151
152 if (lc->total == 0)
153 continue;
154
155 percent = (lc->used * 100) / lc->total;
156
157 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
158 gsm_pchan_name(i), percent, lc->used, lc->total,
159 VTY_NEWLINE);
160 }
161}
162
Harald Welte68628e82009-03-10 12:17:57 +0000163static void net_dump_vty(struct vty *vty, struct gsm_network *net)
164{
Harald Welteb908cb72009-12-22 13:09:29 +0100165 struct pchan_load pl;
166
Harald Welteef235b52009-03-10 12:34:02 +0000167 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
168 "and has %u BTS%s", net->country_code, net->network_code,
169 net->num_bts, VTY_NEWLINE);
Harald Welte1bc77352009-03-10 19:47:51 +0000170 vty_out(vty, " Long network name: '%s'%s",
Harald Welte68628e82009-03-10 12:17:57 +0000171 net->name_long, VTY_NEWLINE);
Harald Welte1bc77352009-03-10 19:47:51 +0000172 vty_out(vty, " Short network name: '%s'%s",
Harald Welte68628e82009-03-10 12:17:57 +0000173 net->name_short, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200174 vty_out(vty, " Authentication policy: %s",
175 gsm_auth_policy_name(net->auth_policy));
176 if (net->authorized_reg_str)
177 vty_out(vty, ", authorized regexp: %s", net->authorized_reg_str);
178 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte1085c092009-11-18 20:33:19 +0100179 vty_out(vty, " Location updating reject cause: %u%s",
180 net->reject_cause, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900181 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
182 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100183 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
184 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800185 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
186 VTY_NEWLINE);
Harald Welteeab84a12009-12-13 10:53:12 +0100187 vty_out(vty, " RRLP Mode: %s%s", rrlp_mode_name(net->rrlp.mode),
188 VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100189 vty_out(vty, " MM Info: %s%s", net->send_mm_info ? "On" : "Off",
190 VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100191 vty_out(vty, " Handover: %s%s", net->handover.active ? "On" : "Off",
192 VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100193 network_chan_load(&pl, net);
194 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
195 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100196
197 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100198 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100199 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200200 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100201 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100202 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200203 vty_out(vty, " Last RF Lock Command: %s%s",
204 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
205 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000206}
207
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200208DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000209 SHOW_STR "Display information about a GSM NETWORK\n")
210{
Harald Weltedcccb182010-05-16 20:52:23 +0200211 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000212 net_dump_vty(vty, net);
213
214 return CMD_SUCCESS;
215}
216
217static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
218{
Harald Welteedb37782009-05-01 14:59:07 +0000219 struct e1inp_line *line;
220
221 if (!e1l) {
222 vty_out(vty, " None%s", VTY_NEWLINE);
223 return;
224 }
225
226 line = e1l->ts->line;
227
228 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
229 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000230 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000231 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000232 e1l->tei, e1l->sapi, VTY_NEWLINE);
233}
234
235static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
236{
Harald Welteb908cb72009-12-22 13:09:29 +0100237 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200238 unsigned long long sec;
239 struct timespec tp;
240 int rc;
Harald Welteb908cb72009-12-22 13:09:29 +0100241
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200242 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100243 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200244 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200245 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100246 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100247 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200248 bts->num_trx, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200249 vty_out(vty, "Description: %s%s",
250 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Maxf9685c12017-03-23 12:01:07 +0100251 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
252 vty_out(vty, "PCU version %s connected%s", bts->pcu_version,
253 VTY_NEWLINE);
Harald Welte1d8dbc42009-12-12 15:38:16 +0100254 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100255 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100256 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
257 VTY_NEWLINE);
258 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100259 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100260 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
261 VTY_NEWLINE);
262 vty_out(vty, "RACH Max transmissions: %u%s",
263 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
264 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100265 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200266 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200267 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
268 vty_out(vty, "Uplink DTX: %s%s",
269 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
270 "enabled" : "forced", VTY_NEWLINE);
271 else
272 vty_out(vty, "Uplink DTX: not enabled%s", VTY_NEWLINE);
273 vty_out(vty, "Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
274 VTY_NEWLINE);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200275 vty_out(vty, "Channel Description Attachment: %s%s",
276 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
277 vty_out(vty, "Channel Description BS-PA-MFRMS: %u%s",
278 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
279 vty_out(vty, "Channel Description BS-AG_BLKS-RES: %u%s",
280 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200281 vty_out(vty, "System Information present: 0x%08x, static: 0x%08x%s",
282 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Harald Welte42def722017-01-13 00:10:32 +0100283 vty_out(vty, "Early Classmark Sending: %s%s",
284 bts->early_classmark_allowed ? "allowed" : "forbidden",
285 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200286 if (bts->pcu_sock_path)
287 vty_out(vty, "PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000288 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200289 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000290 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200291 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200292 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
293 vty_out(vty, " Skip Reset: %d%s",
294 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000295 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200296 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000297 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200298 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200299 vty_out(vty, " GPRS NSE: ");
300 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
301 vty_out(vty, " GPRS CELL: ");
302 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
303 vty_out(vty, " GPRS NSVC0: ");
304 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
305 vty_out(vty, " GPRS NSVC1: ");
306 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200307 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
308 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000309 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100310 if (is_ipaccess_bts(bts)) {
Maxd1f70ed2017-09-21 16:15:32 +0200311 vty_out(vty, " OML Link state: ");
312 if (bts->oml_link) {
313 vty_out(vty, "connected");
314 if (bts->uptime) {
315 rc = clock_gettime(CLOCK_MONOTONIC, &tp);
316 if (rc == 0) { /* monotonic clock helps to ensure that conversion below is valid */
317 sec = (unsigned long long)difftime(tp.tv_sec, bts->uptime);
318 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.%s",
319 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec),
320 sec % 60, VTY_NEWLINE);
321 }
322 }
323 } else
324 vty_out(vty, "disconnected.%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100325 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200326 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
327 e1isl_dump_vty(vty, bts->oml_link);
328 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100329
330 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100331 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200332 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100333 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
334 dump_pchan_load_vty(vty, " ", &pl);
Harald Welte68628e82009-03-10 12:17:57 +0000335}
336
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100337DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000338 SHOW_STR "Display information about a BTS\n"
339 "BTS number")
340{
Harald Weltedcccb182010-05-16 20:52:23 +0200341 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000342 int bts_nr;
343
344 if (argc != 0) {
345 /* use the BTS number that the user has specified */
346 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100347 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000348 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000349 VTY_NEWLINE);
350 return CMD_WARNING;
351 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200352 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000353 return CMD_SUCCESS;
354 }
355 /* print all BTS's */
356 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200357 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000358
359 return CMD_SUCCESS;
360}
361
Harald Welte42581822009-08-08 16:12:58 +0200362/* utility functions */
363static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
364 const char *ts, const char *ss)
365{
366 e1_link->e1_nr = atoi(line);
367 e1_link->e1_ts = atoi(ts);
368 if (!strcmp(ss, "full"))
369 e1_link->e1_ts_ss = 255;
370 else
371 e1_link->e1_ts_ss = atoi(ss);
372}
373
374static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
375 const char *prefix)
376{
377 if (!e1_link->e1_ts)
378 return;
379
380 if (e1_link->e1_ts_ss == 255)
381 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
382 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
383 else
384 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
385 prefix, e1_link->e1_nr, e1_link->e1_ts,
386 e1_link->e1_ts_ss, VTY_NEWLINE);
387}
388
389
Harald Welte67ce0732009-08-06 19:06:46 +0200390static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
391{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100392 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100393 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100394 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200395 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100396 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200397 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100398 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200399 ts->hopping.enabled, VTY_NEWLINE);
400 if (ts->hopping.enabled) {
401 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100402 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200403 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100404 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200405 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200406 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
407 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
408 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100409 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200410 i, VTY_NEWLINE);
411 }
Harald Welte127af342010-12-24 12:07:07 +0100412 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100413 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100414
415 if (ts->trx->bts->model->config_write_ts)
416 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200417}
418
419static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
420{
421 int i;
422
Harald Welte5013b2a2009-08-07 13:29:14 +0200423 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200424 if (trx->description)
425 vty_out(vty, " description %s%s", trx->description,
426 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200427 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200428 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200429 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200430 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100431 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200432 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200433 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
434 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200435
Harald Welteface7ed2011-02-14 16:15:21 +0100436 if (trx->bts->model->config_write_trx)
437 trx->bts->model->config_write_trx(vty, trx);
438
Harald Welte67ce0732009-08-06 19:06:46 +0200439 for (i = 0; i < TRX_NR_TS; i++)
440 config_write_ts_single(vty, &trx->ts[i]);
441}
442
Harald Welte615e9562010-05-11 23:50:21 +0200443static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
444{
445 unsigned int i;
446 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
447 VTY_NEWLINE);
448 if (bts->gprs.mode == BTS_GPRS_NONE)
449 return;
450
bhargava350533c2016-07-21 11:14:34 +0530451 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
452 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
453
Harald Welte615e9562010-05-11 23:50:21 +0200454 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
455 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100456 vty_out(vty, " gprs network-control-order nc%u%s",
457 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200458 if (!bts->gprs.ctrl_ack_type_use_block)
459 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200460 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
461 VTY_NEWLINE);
462 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
463 vty_out(vty, " gprs cell timer %s %u%s",
464 get_value_string(gprs_bssgp_cfg_strs, i),
465 bts->gprs.cell.timer[i], VTY_NEWLINE);
466 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
467 VTY_NEWLINE);
468 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
469 vty_out(vty, " gprs ns timer %s %u%s",
470 get_value_string(gprs_ns_timer_strs, i),
471 bts->gprs.nse.timer[i], VTY_NEWLINE);
472 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
473 struct gsm_bts_gprs_nsvc *nsvc =
474 &bts->gprs.nsvc[i];
475 struct in_addr ia;
476
477 ia.s_addr = htonl(nsvc->remote_ip);
478 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
479 nsvc->nsvci, VTY_NEWLINE);
480 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
481 nsvc->local_port, VTY_NEWLINE);
482 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
483 nsvc->remote_port, VTY_NEWLINE);
484 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
485 inet_ntoa(ia), VTY_NEWLINE);
486 }
487}
488
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200489/* Write the model data if there is one */
490static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200491{
492 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200493
494 if (!bts->model)
495 return;
496
497 if (bts->model->config_write_bts)
498 bts->model->config_write_bts(vty, bts);
499
500 llist_for_each_entry(trx, &bts->trx_list, list)
501 config_write_trx_single(vty, trx);
502}
503
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200504static void write_amr_modes(struct vty *vty, const char *prefix,
505 const char *name, struct amr_mode *modes, int num)
506{
507 int i;
508
509 vty_out(vty, " %s threshold %s", prefix, name);
510 for (i = 0; i < num - 1; i++)
511 vty_out(vty, " %d", modes[i].threshold);
512 vty_out(vty, "%s", VTY_NEWLINE);
513 vty_out(vty, " %s hysteresis %s", prefix, name);
514 for (i = 0; i < num - 1; i++)
515 vty_out(vty, " %d", modes[i].hysteresis);
516 vty_out(vty, "%s", VTY_NEWLINE);
517}
518
Andreas Eversberg73266522014-01-19 11:47:44 +0100519static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
520 struct amr_multirate_conf *mr, int full)
521{
522 struct gsm48_multi_rate_conf *mr_conf;
523 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
524 int i, num;
525
526 if (!(mr->gsm48_ie[1]))
527 return;
528
529 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
530
531 num = 0;
532 vty_out(vty, " %s modes", prefix);
533 for (i = 0; i < ((full) ? 8 : 6); i++) {
534 if ((mr->gsm48_ie[1] & (1 << i))) {
535 vty_out(vty, " %d", i);
536 num++;
537 }
538 }
539 vty_out(vty, "%s", VTY_NEWLINE);
540 if (num > 4)
541 num = 4;
542 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200543 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
544 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100545 }
546 vty_out(vty, " %s start-mode ", prefix);
547 if (mr_conf->icmi) {
548 num = 0;
549 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
550 if ((mr->gsm48_ie[1] & (1 << i)))
551 num++;
552 if (mr_conf->smod == num - 1) {
553 vty_out(vty, "%d%s", num, VTY_NEWLINE);
554 break;
555 }
556 }
557 } else
558 vty_out(vty, "auto%s", VTY_NEWLINE);
559}
560
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200561static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
562{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200563 int i;
Max2c16bee2017-02-15 13:51:37 +0100564 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200565
Harald Welte5013b2a2009-08-07 13:29:14 +0200566 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
567 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200568 if (bts->description)
569 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200570 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100571 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200572 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200573 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200574 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
575 vty_out(vty, " dtx uplink%s%s",
576 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
577 VTY_NEWLINE);
578 if (bts->dtxd)
579 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200580 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200581 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100582 vty_out(vty, " cell reselection hysteresis %u%s",
583 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
584 vty_out(vty, " rxlev access min %u%s",
585 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100586
587 if (bts->si_common.cell_ro_sel_par.present) {
588 struct gsm48_si_selection_params *sp;
589 sp = &bts->si_common.cell_ro_sel_par;
590
591 if (sp->cbq)
592 vty_out(vty, " cell bar qualify %u%s",
593 sp->cbq, VTY_NEWLINE);
594
595 if (sp->cell_resel_off)
596 vty_out(vty, " cell reselection offset %u%s",
597 sp->cell_resel_off*2, VTY_NEWLINE);
598
599 if (sp->temp_offs == 7)
600 vty_out(vty, " temporary offset infinite%s",
601 VTY_NEWLINE);
602 else if (sp->temp_offs)
603 vty_out(vty, " temporary offset %u%s",
604 sp->temp_offs*10, VTY_NEWLINE);
605
606 if (sp->penalty_time == 31)
607 vty_out(vty, " penalty time reserved%s",
608 VTY_NEWLINE);
609 else if (sp->penalty_time)
610 vty_out(vty, " penalty time %u%s",
611 (sp->penalty_time*20)+20, VTY_NEWLINE);
612 }
613
Harald Welte2f8b9d22017-06-18 11:12:13 +0300614 if (gsm_bts_get_radio_link_timeout(bts) < 0)
615 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
616 else
617 vty_out(vty, " radio-link-timeout %d%s",
618 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200619
Harald Welte7a8fa412009-08-10 13:48:16 +0200620 vty_out(vty, " channel allocator %s%s",
621 bts->chan_alloc_reverse ? "descending" : "ascending",
622 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100623 vty_out(vty, " rach tx integer %u%s",
624 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
625 vty_out(vty, " rach max transmission %u%s",
626 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
627 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800628
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200629 vty_out(vty, " channel-descrption attach %u%s",
630 bts->si_common.chan_desc.att, VTY_NEWLINE);
631 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
632 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
633 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
634 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
635
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800636 if (bts->rach_b_thresh != -1)
637 vty_out(vty, " rach nm busy threshold %u%s",
638 bts->rach_b_thresh, VTY_NEWLINE);
639 if (bts->rach_ldavg_slots != -1)
640 vty_out(vty, " rach nm load average %u%s",
641 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100642 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200643 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800644 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
645 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400646 if ((bts->si_common.rach_control.t3) != 0)
647 for (i = 0; i < 8; i++)
648 if (bts->si_common.rach_control.t3 & (0x1 << i))
649 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
650 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
651 for (i = 0; i < 8; i++)
652 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
653 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200654 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
655 if (bts->si_mode_static & (1 << i)) {
656 vty_out(vty, " system-information %s mode static%s",
657 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
658 vty_out(vty, " system-information %s static %s%s",
659 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200660 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200661 VTY_NEWLINE);
662 }
663 }
Harald Welte42def722017-01-13 00:10:32 +0100664 vty_out(vty, " early-classmark-sending %s%s",
665 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100666 switch (bts->type) {
667 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100668 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200669 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200670 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100671 if (bts->ip_access.rsl_ip) {
672 struct in_addr ia;
673 ia.s_addr = htonl(bts->ip_access.rsl_ip);
674 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
675 VTY_NEWLINE);
676 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200677 vty_out(vty, " oml ip.access stream_id %u line %u%s",
678 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100679 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200680 case GSM_BTS_TYPE_NOKIA_SITE:
681 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100682 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
683 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100684 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 +0100685 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100686 default:
Harald Welte42581822009-08-08 16:12:58 +0200687 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
688 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100689 break;
Harald Welte42581822009-08-08 16:12:58 +0200690 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800691
692 /* if we have a limit, write it */
693 if (bts->paging.free_chans_need >= 0)
694 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
695
Harald Welte32c09622011-01-11 23:44:56 +0100696 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100697 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
698 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100699 for (i = 0; i < 1024; i++) {
700 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
701 vty_out(vty, " neighbor-list add arfcn %u%s",
702 i, VTY_NEWLINE);
703 }
704 }
Harald Welte64c07d22011-02-15 11:43:27 +0100705 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
706 for (i = 0; i < 1024; i++) {
707 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
708 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
709 i, VTY_NEWLINE);
710 }
711 }
Harald Welte32c09622011-01-11 23:44:56 +0100712
Max59a1bf32016-04-15 16:04:46 +0200713 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100714 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
715 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
716 vty_out(vty, " si2quater neighbor-list add earfcn %u "
717 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
718
719 vty_out(vty, " thresh-lo %u",
720 e->thresh_lo_valid ? e->thresh_lo : 32);
721
722 vty_out(vty, " prio %u",
723 e->prio_valid ? e->prio : 8);
724
725 vty_out(vty, " qrxlv %u",
726 e->qrxlm_valid ? e->qrxlm : 32);
727
728 tmp = e->meas_bw[i];
729 vty_out(vty, " meas %u",
730 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200731
732 vty_out(vty, "%s", VTY_NEWLINE);
733 }
734 }
735
Max26679e02016-04-20 15:57:13 +0200736 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
737 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
738 bts->si_common.data.uarfcn_list[i],
739 bts->si_common.data.scramble_list[i] & ~(1 << 9),
740 (bts->si_common.data.scramble_list[i] >> 9) & 1,
741 VTY_NEWLINE);
742 }
743
Andreas Eversberga83d5112013-12-07 18:32:28 +0100744 vty_out(vty, " codec-support fr");
745 if (bts->codec.hr)
746 vty_out(vty, " hr");
747 if (bts->codec.efr)
748 vty_out(vty, " efr");
749 if (bts->codec.amr)
750 vty_out(vty, " amr");
751 vty_out(vty, "%s", VTY_NEWLINE);
752
Andreas Eversberg73266522014-01-19 11:47:44 +0100753 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
754 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
755
Harald Welte615e9562010-05-11 23:50:21 +0200756 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200757
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200758 if (bts->excl_from_rf_lock)
759 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
760
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100761 vty_out(vty, " %sforce-combined-si%s",
762 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
763
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100764 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
765 int j;
766
767 if (bts->depends_on[i] == 0)
768 continue;
769
770 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
771 int bts_nr;
772
773 if ((bts->depends_on[i] & (1<<j)) == 0)
774 continue;
775
776 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
777 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
778 }
779 }
Harald Welte8254cf72017-05-29 13:42:19 +0200780 if (bts->pcu_sock_path)
781 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100782
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200783 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200784}
785
786static int config_write_bts(struct vty *v)
787{
Harald Weltedcccb182010-05-16 20:52:23 +0200788 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200789 struct gsm_bts *bts;
790
791 llist_for_each_entry(bts, &gsmnet->bts_list, list)
792 config_write_bts_single(v, bts);
793
794 return CMD_SUCCESS;
795}
796
Harald Weltea0d324b2017-07-20 01:47:39 +0200797/* small helper macro for conditional dumping of timer */
798#define VTY_OUT_TIMER(number) \
799 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
800 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
801
Harald Welte5013b2a2009-08-07 13:29:14 +0200802static int config_write_net(struct vty *vty)
803{
Harald Weltedcccb182010-05-16 20:52:23 +0200804 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
805
Harald Welte5013b2a2009-08-07 13:29:14 +0200806 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200807 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200808 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200809 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
810 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
Harald Welte (local)69de3972009-08-12 14:42:23 +0200811 vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200812 if (gsmnet->authorized_reg_str)
813 vty_out(vty, " authorized-regexp %s%s", gsmnet->authorized_reg_str, VTY_NEWLINE);
Harald Welte1085c092009-11-18 20:33:19 +0100814 vty_out(vty, " location updating reject cause %u%s",
815 gsmnet->reject_cause, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900816 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Harald Weltea43e0b42016-06-19 18:06:02 +0200817 vty_out(vty, " authentication %s%s",
818 gsmnet->authentication_required ? "required" : "optional",
819 VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100820 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800821 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Harald Welteeab84a12009-12-13 10:53:12 +0100822 vty_out(vty, " rrlp mode %s%s", rrlp_mode_name(gsmnet->rrlp.mode),
823 VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100824 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100825 vty_out(vty, " handover %u%s", gsmnet->handover.active, VTY_NEWLINE);
Harald Welteb720bd32009-12-21 16:51:50 +0100826 vty_out(vty, " handover window rxlev averaging %u%s",
827 gsmnet->handover.win_rxlev_avg, VTY_NEWLINE);
828 vty_out(vty, " handover window rxqual averaging %u%s",
829 gsmnet->handover.win_rxqual_avg, VTY_NEWLINE);
830 vty_out(vty, " handover window rxlev neighbor averaging %u%s",
831 gsmnet->handover.win_rxlev_avg_neigh, VTY_NEWLINE);
832 vty_out(vty, " handover power budget interval %u%s",
833 gsmnet->handover.pwr_interval, VTY_NEWLINE);
834 vty_out(vty, " handover power budget hysteresis %u%s",
835 gsmnet->handover.pwr_hysteresis, VTY_NEWLINE);
836 vty_out(vty, " handover maximum distance %u%s",
837 gsmnet->handover.max_distance, VTY_NEWLINE);
Harald Weltea0d324b2017-07-20 01:47:39 +0200838 VTY_OUT_TIMER(3101);
839 VTY_OUT_TIMER(3103);
840 VTY_OUT_TIMER(3105);
841 VTY_OUT_TIMER(3107);
842 VTY_OUT_TIMER(3109);
843 VTY_OUT_TIMER(3111);
844 VTY_OUT_TIMER(3113);
845 VTY_OUT_TIMER(3115);
846 VTY_OUT_TIMER(3117);
847 VTY_OUT_TIMER(3119);
848 VTY_OUT_TIMER(3122);
849 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700850 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
851 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200852 if (gsmnet->tz.override != 0) {
853 if (gsmnet->tz.dst)
854 vty_out(vty, " timezone %d %d %d%s",
855 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
856 VTY_NEWLINE);
857 else
858 vty_out(vty, " timezone %d %d%s",
859 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
860 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200861 if (gsmnet->t3212 == 0)
862 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
863 else
864 vty_out(vty, " periodic location update %u%s",
865 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200866
867 return CMD_SUCCESS;
868}
Harald Welte67ce0732009-08-06 19:06:46 +0200869
Harald Welte68628e82009-03-10 12:17:57 +0000870static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
871{
872 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
873 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200874 vty_out(vty, "Description: %s%s",
875 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200876 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200877 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200878 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200879 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000880 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200881 net_dump_nmstate(vty, &trx->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000882 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200883 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200884 if (is_ipaccess_bts(trx->bts)) {
885 vty_out(vty, " ip.access stream ID: 0x%02x%s",
886 trx->rsl_tei, VTY_NEWLINE);
887 } else {
888 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
889 e1isl_dump_vty(vty, trx->rsl_link);
890 }
Harald Welte68628e82009-03-10 12:17:57 +0000891}
892
893DEFUN(show_trx,
894 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100895 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200896 SHOW_STR "Display information about a TRX\n"
897 "BTS Number\n"
898 "TRX Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000899{
Harald Weltedcccb182010-05-16 20:52:23 +0200900 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000901 struct gsm_bts *bts = NULL;
902 struct gsm_bts_trx *trx;
903 int bts_nr, trx_nr;
904
905 if (argc >= 1) {
906 /* use the BTS number that the user has specified */
907 bts_nr = atoi(argv[0]);
908 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000909 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000910 VTY_NEWLINE);
911 return CMD_WARNING;
912 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200913 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000914 }
915 if (argc >= 2) {
916 trx_nr = atoi(argv[1]);
917 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000918 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000919 VTY_NEWLINE);
920 return CMD_WARNING;
921 }
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 return CMD_SUCCESS;
925 }
926 if (bts) {
927 /* print all TRX in this BTS */
928 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200929 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000930 trx_dump_vty(vty, trx);
931 }
932 return CMD_SUCCESS;
933 }
934
935 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200936 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000937 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200938 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000939 trx_dump_vty(vty, trx);
940 }
941 }
942
943 return CMD_SUCCESS;
944}
945
Harald Welte67ce0732009-08-06 19:06:46 +0200946
Harald Welte68628e82009-03-10 12:17:57 +0000947static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
948{
Harald Welte135a6482011-05-30 12:09:13 +0200949 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +0100950 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +0100951 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +0100952 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +0100953 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200954 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +0100955 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000956 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200957 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530958 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000959 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
960 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
961 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000962}
963
964DEFUN(show_ts,
965 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100966 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200967 SHOW_STR "Display information about a TS\n"
968 "BTS Number\n" "TRX Number\n" "Timeslot Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000969{
Harald Weltedcccb182010-05-16 20:52:23 +0200970 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +0100971 struct gsm_bts *bts = NULL;
972 struct gsm_bts_trx *trx = NULL;
973 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000974 int bts_nr, trx_nr, ts_nr;
975
976 if (argc >= 1) {
977 /* use the BTS number that the user has specified */
978 bts_nr = atoi(argv[0]);
979 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000980 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000981 VTY_NEWLINE);
982 return CMD_WARNING;
983 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200984 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000985 }
986 if (argc >= 2) {
987 trx_nr = atoi(argv[1]);
988 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000989 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000990 VTY_NEWLINE);
991 return CMD_WARNING;
992 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200993 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000994 }
995 if (argc >= 3) {
996 ts_nr = atoi(argv[2]);
997 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +0000998 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +0000999 VTY_NEWLINE);
1000 return CMD_WARNING;
1001 }
Harald Welte274d0152010-12-24 12:05:03 +01001002 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +00001003 ts = &trx->ts[ts_nr];
1004 ts_dump_vty(vty, ts);
1005 return CMD_SUCCESS;
1006 }
Harald Welte274d0152010-12-24 12:05:03 +01001007
1008 if (bts && trx) {
1009 /* Iterate over all TS in this TRX */
1010 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1011 ts = &trx->ts[ts_nr];
1012 ts_dump_vty(vty, ts);
1013 }
1014 } else if (bts) {
1015 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001016 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001017 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001018 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1019 ts = &trx->ts[ts_nr];
1020 ts_dump_vty(vty, ts);
1021 }
1022 }
Harald Welte274d0152010-12-24 12:05:03 +01001023 } else {
1024 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1025 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1026 bts = gsm_bts_num(net, bts_nr);
1027 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1028 trx = gsm_bts_trx_num(bts, trx_nr);
1029 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1030 ts = &trx->ts[ts_nr];
1031 ts_dump_vty(vty, ts);
1032 }
1033 }
1034 }
Harald Welte68628e82009-03-10 12:17:57 +00001035 }
1036
1037 return CMD_SUCCESS;
1038}
1039
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001040static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1041{
1042 if (strlen(bsub->imsi))
1043 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1044 if (bsub->tmsi != GSM_RESERVED_TMSI)
1045 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1046 VTY_NEWLINE);
1047 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1048}
1049
Harald Welte8387a492009-12-22 21:43:14 +01001050static void meas_rep_dump_uni_vty(struct vty *vty,
1051 struct gsm_meas_rep_unidir *mru,
1052 const char *prefix,
1053 const char *dir)
1054{
1055 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1056 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1057 dir, rxlev2dbm(mru->sub.rx_lev));
1058 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1059 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1060 VTY_NEWLINE);
1061}
1062
1063static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1064 const char *prefix)
1065{
1066 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1067 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1068 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1069 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1070 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1071 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1072 VTY_NEWLINE);
1073 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001074 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001075 if (mr->flags & MEAS_REP_F_MS_L1)
1076 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1077 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1078 if (mr->flags & MEAS_REP_F_DL_VALID)
1079 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1080 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1081}
1082
Harald Welte0a8cf322015-12-05 17:22:49 +01001083/* FIXME: move this to libosmogsm */
1084static const struct value_string gsm48_cmode_names[] = {
1085 { GSM48_CMODE_SIGN, "signalling" },
1086 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1087 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1088 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1089 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1090 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1091 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1092 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1093 { 0, NULL }
1094};
1095
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001096/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1097 * Don't do anything if the ts is not dynamic. */
1098static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1099{
1100 switch (ts->pchan) {
1101 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1102 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1103 vty_out(vty, " as %s",
1104 gsm_pchan_name(ts->dyn.pchan_is));
1105 else
1106 vty_out(vty, " switching %s -> %s",
1107 gsm_pchan_name(ts->dyn.pchan_is),
1108 gsm_pchan_name(ts->dyn.pchan_want));
1109 break;
1110 case GSM_PCHAN_TCH_F_PDCH:
1111 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1112 vty_out(vty, " as %s",
1113 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1114 : "TCH/F");
1115 else
1116 vty_out(vty, " switching %s -> %s",
1117 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1118 : "TCH/F",
1119 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1120 : "TCH/F");
1121 break;
1122 default:
1123 /* no dyn ts */
1124 break;
1125 }
1126}
1127
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001128static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001129{
Harald Welte8387a492009-12-22 21:43:14 +01001130 int idx;
1131
Harald Welte85bded82010-12-24 12:22:34 +01001132 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1133 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1134 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001135 /* show dyn TS details, if applicable */
1136 switch (lchan->ts->pchan) {
1137 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1138 vty_out(vty, " Osmocom Dyn TS:");
1139 vty_out_dyn_ts_status(vty, lchan->ts);
1140 vty_out(vty, VTY_NEWLINE);
1141 break;
1142 case GSM_PCHAN_TCH_F_PDCH:
1143 vty_out(vty, " IPACC Dyn PDCH TS:");
1144 vty_out_dyn_ts_status(vty, lchan->ts);
1145 vty_out(vty, VTY_NEWLINE);
1146 break;
1147 default:
1148 /* no dyn ts */
1149 break;
1150 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001151 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001152 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001153 gsm_lchans_name(lchan->state),
1154 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1155 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1156 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001157 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1158 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1159 - lchan->bs_power*2,
1160 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1161 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001162 vty_out(vty, " Channel Mode / Codec: %s%s",
1163 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1164 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001165 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001166 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001167 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001168 } else
1169 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301170 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1171 struct in_addr ia;
Holger Hans Peter Freyther54fa7992010-04-07 15:39:16 +02001172 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte2c828992009-12-02 01:56:49 +05301173 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1174 inet_ntoa(ia), lchan->abis_ip.bound_port,
1175 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1176 VTY_NEWLINE);
1177 }
Harald Welte8387a492009-12-22 21:43:14 +01001178
1179 /* we want to report the last measurement report */
1180 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1181 lchan->meas_rep_idx, 1);
1182 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001183}
1184
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001185static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1186{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001187 struct gsm_meas_rep *mr;
1188 int idx;
1189
1190 /* we want to report the last measurement report */
1191 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1192 lchan->meas_rep_idx, 1);
1193 mr = &lchan->meas_rep[idx];
1194
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001195 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001196 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001197 gsm_pchan_name(lchan->ts->pchan));
1198 vty_out_dyn_ts_status(vty, lchan->ts);
1199 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1200 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001201 lchan->nr,
1202 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1203 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001204 rxlev2dbm(mr->dl.full.rx_lev),
1205 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001206 VTY_NEWLINE);
1207}
1208
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001209
1210static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1211 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1212{
1213 int lchan_nr;
1214 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1215 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1216 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1217 continue;
1218 dump_cb(vty, lchan);
1219 }
1220
1221 return CMD_SUCCESS;
1222}
1223
1224static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1225 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1226{
1227 int ts_nr;
1228
1229 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1230 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1231 dump_lchan_trx_ts(ts, vty, dump_cb);
1232 }
1233
1234 return CMD_SUCCESS;
1235}
1236
1237static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1238 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1239{
1240 int trx_nr;
1241
1242 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1243 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1244 dump_lchan_trx(trx, vty, dump_cb);
1245 }
1246
1247 return CMD_SUCCESS;
1248}
1249
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001250static int lchan_summary(struct vty *vty, int argc, const char **argv,
1251 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001252{
Harald Weltedcccb182010-05-16 20:52:23 +02001253 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001254 struct gsm_bts *bts;
1255 struct gsm_bts_trx *trx;
1256 struct gsm_bts_trx_ts *ts;
1257 struct gsm_lchan *lchan;
1258 int bts_nr, trx_nr, ts_nr, lchan_nr;
1259
1260 if (argc >= 1) {
1261 /* use the BTS number that the user has specified */
1262 bts_nr = atoi(argv[0]);
1263 if (bts_nr >= net->num_bts) {
1264 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1265 VTY_NEWLINE);
1266 return CMD_WARNING;
1267 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001268 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001269
1270 if (argc == 1)
1271 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001272 }
1273 if (argc >= 2) {
1274 trx_nr = atoi(argv[1]);
1275 if (trx_nr >= bts->num_trx) {
1276 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1277 VTY_NEWLINE);
1278 return CMD_WARNING;
1279 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001280 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001281
1282 if (argc == 2)
1283 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001284 }
1285 if (argc >= 3) {
1286 ts_nr = atoi(argv[2]);
1287 if (ts_nr >= TRX_NR_TS) {
1288 vty_out(vty, "%% can't find TS %s%s", argv[2],
1289 VTY_NEWLINE);
1290 return CMD_WARNING;
1291 }
1292 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001293
1294 if (argc == 3)
1295 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001296 }
1297 if (argc >= 4) {
1298 lchan_nr = atoi(argv[3]);
1299 if (lchan_nr >= TS_MAX_LCHAN) {
1300 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1301 VTY_NEWLINE);
1302 return CMD_WARNING;
1303 }
1304 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001305 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001306 return CMD_SUCCESS;
1307 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001308
1309
Harald Welte68628e82009-03-10 12:17:57 +00001310 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001311 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001312 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001313 }
1314
1315 return CMD_SUCCESS;
1316}
1317
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001318
1319DEFUN(show_lchan,
1320 show_lchan_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001321 "show lchan [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001322 SHOW_STR "Display information about a logical channel\n"
1323 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001324 LCHAN_NR_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001325
1326{
1327 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1328}
1329
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001330DEFUN(show_lchan_summary,
1331 show_lchan_summary_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001332 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001333 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001334 "Short summary\n"
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001335 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001336 LCHAN_NR_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001337{
1338 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1339}
1340
Philipp Maier39f62bb2017-04-09 12:32:51 +02001341DEFUN(show_subscr_conn,
1342 show_subscr_conn_cmd,
1343 "show conns",
1344 SHOW_STR "Display currently active subscriber connections\n")
1345{
1346 struct gsm_subscriber_connection *conn;
1347 struct gsm_network *net = gsmnet_from_vty(vty);
1348 bool no_conns = true;
1349 unsigned int count = 0;
1350
1351 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1352
1353 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1354 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1355 lchan_dump_full_vty(vty, conn->lchan);
1356 no_conns = false;
1357 count++;
1358 }
1359
1360 if (no_conns)
1361 vty_out(vty, "None%s", VTY_NEWLINE);
1362
1363 return CMD_SUCCESS;
1364}
1365
1366DEFUN(handover_subscr_conn,
1367 handover_subscr_conn_cmd,
1368 "handover <0-255> <0-255> <0-7> LCHAN_NR <0-255>",
1369 "Handover subscriber connection to other BTS\n"
1370 "BTS Number (current)\n" "TRX Number\n" "Timeslot Number\n"
1371 LCHAN_NR_STR "BTS Number (new)\n")
1372{
1373 struct gsm_network *net = gsmnet_from_vty(vty);
1374 struct gsm_subscriber_connection *conn;
1375 struct gsm_bts *bts;
1376 struct gsm_bts *new_bts = NULL;
1377 unsigned int bts_nr = atoi(argv[0]);
1378 unsigned int trx_nr = atoi(argv[1]);
1379 unsigned int ts_nr = atoi(argv[2]);
1380 unsigned int ss_nr = atoi(argv[3]);
1381 unsigned int bts_nr_new = atoi(argv[4]);
1382
1383 /* Lookup the BTS where we want to handover to */
1384 llist_for_each_entry(bts, &net->bts_list, list) {
1385 if (bts->nr == bts_nr_new) {
1386 new_bts = bts;
1387 break;
1388 }
1389 }
1390
1391 if (!new_bts) {
1392 vty_out(vty, "Unable to trigger handover,"
1393 "specified bts #%u does not exist %s", bts_nr_new,
1394 VTY_NEWLINE);
1395 return CMD_WARNING;
1396 }
1397
1398 /* Find the connection/lchan that we want to handover */
1399 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1400 if (conn->bts->nr == bts_nr &&
1401 conn->lchan->ts->trx->nr == trx_nr &&
1402 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
1403 vty_out(vty, "starting handover for lchan %s...%s",
1404 conn->lchan->name, VTY_NEWLINE);
1405 lchan_dump_full_vty(vty, conn->lchan);
1406 bsc_handover_start(conn->lchan, new_bts);
1407 return CMD_SUCCESS;
1408 }
1409 }
1410
1411 vty_out(vty, "Unable to trigger handover,"
1412 "specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1413 bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
1414
1415 return CMD_WARNING;
1416}
1417
Harald Weltebe4b7302009-05-23 16:59:33 +00001418static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001419{
1420 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001421 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001422}
1423
Harald Weltebe4b7302009-05-23 16:59:33 +00001424static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001425{
1426 struct gsm_paging_request *pag;
1427
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001428 if (!bts->paging.bts)
1429 return;
1430
Harald Weltef5025b62009-03-28 16:55:11 +00001431 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1432 paging_dump_vty(vty, pag);
1433}
1434
1435DEFUN(show_paging,
1436 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001437 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001438 SHOW_STR "Display information about paging reuqests of a BTS\n"
1439 "BTS Number\n")
Harald Weltef5025b62009-03-28 16:55:11 +00001440{
Harald Weltedcccb182010-05-16 20:52:23 +02001441 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001442 struct gsm_bts *bts;
1443 int bts_nr;
1444
1445 if (argc >= 1) {
1446 /* use the BTS number that the user has specified */
1447 bts_nr = atoi(argv[0]);
1448 if (bts_nr >= net->num_bts) {
1449 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1450 VTY_NEWLINE);
1451 return CMD_WARNING;
1452 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001453 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001454 bts_paging_dump_vty(vty, bts);
1455
1456 return CMD_SUCCESS;
1457 }
1458 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001459 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001460 bts_paging_dump_vty(vty, bts);
1461 }
1462
1463 return CMD_SUCCESS;
1464}
1465
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001466DEFUN(show_paging_group,
1467 show_paging_group_cmd,
1468 "show paging-group <0-255> IMSI",
1469 SHOW_STR "Display the paging group\n"
1470 "BTS Number\n" "IMSI\n")
1471{
1472 struct gsm_network *net = gsmnet_from_vty(vty);
1473 struct gsm_bts *bts;
1474 unsigned int page_group;
1475 int bts_nr = atoi(argv[0]);
1476
1477 if (bts_nr >= net->num_bts) {
1478 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1479 return CMD_WARNING;
1480 }
1481
1482 bts = gsm_bts_num(net, bts_nr);
1483 if (!bts) {
1484 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1485 return CMD_WARNING;
1486 }
1487
1488 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1489 str_to_imsi(argv[1]));
1490 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1491 str_to_imsi(argv[1]), bts->nr,
1492 page_group, VTY_NEWLINE);
1493 return CMD_SUCCESS;
1494}
1495
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001496DEFUN(cfg_net_neci,
1497 cfg_net_neci_cmd,
1498 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001499 "New Establish Cause Indication\n"
1500 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001501{
Harald Weltedcccb182010-05-16 20:52:23 +02001502 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1503
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001504 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001505 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001506 return CMD_SUCCESS;
1507}
1508
Harald Welte8f0ed552010-05-11 21:53:49 +02001509#define HANDOVER_STR "Handover Options\n"
1510
Harald Weltebc814502009-12-19 21:41:52 +01001511DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1512 "handover (0|1)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001513 HANDOVER_STR
1514 "Don't perform in-call handover\n"
1515 "Perform in-call handover\n")
Harald Weltebc814502009-12-19 21:41:52 +01001516{
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001517 int enable = atoi(argv[0]);
Harald Weltedcccb182010-05-16 20:52:23 +02001518 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001519
1520 if (enable && ipacc_rtp_direct) {
Harald Weltefe03f0d2009-12-20 13:51:01 +01001521 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1522 "is enabled by using the -P command line option%s",
1523 VTY_NEWLINE);
1524 return CMD_WARNING;
1525 }
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001526 gsmnet->handover.active = enable;
Harald Weltebc814502009-12-19 21:41:52 +01001527
1528 return CMD_SUCCESS;
1529}
1530
Harald Welte8f0ed552010-05-11 21:53:49 +02001531#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1532#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1533#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1534#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001535#define HO_AVG_COUNT_STR "Amount to use for Averaging\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001536
Harald Welteb720bd32009-12-21 16:51:50 +01001537DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1538 "handover window rxlev averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001539 HO_WIN_RXLEV_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001540 "How many RxLev measurements are used for averaging\n"
1541 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001542{
Harald Weltedcccb182010-05-16 20:52:23 +02001543 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001544 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1545 return CMD_SUCCESS;
1546}
1547
1548DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1549 "handover window rxqual averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001550 HO_WIN_RXQUAL_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001551 "How many RxQual measurements are used for averaging\n"
1552 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001553{
Harald Weltedcccb182010-05-16 20:52:23 +02001554 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001555 gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
1556 return CMD_SUCCESS;
1557}
1558
1559DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1560 "handover window rxlev neighbor averaging <1-10>",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001561 HO_WIN_RXLEV_STR "Neighbor\n"
1562 "How many RxQual measurements are used for averaging\n"
1563 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001564{
Harald Weltedcccb182010-05-16 20:52:23 +02001565 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001566 gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
1567 return CMD_SUCCESS;
1568}
1569
1570DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1571 "handover power budget interval <1-99>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001572 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001573 "How often to check if we have a better cell (SACCH frames)\n"
1574 "Interval\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001575{
Harald Weltedcccb182010-05-16 20:52:23 +02001576 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001577 gsmnet->handover.pwr_interval = atoi(argv[0]);
1578 return CMD_SUCCESS;
1579}
1580
1581DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1582 "handover power budget hysteresis <0-999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001583 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001584 "How many dB does a neighbor to be stronger to become a HO candidate\n"
1585 "Hysteresis\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001586{
Harald Weltedcccb182010-05-16 20:52:23 +02001587 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001588 gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
1589 return CMD_SUCCESS;
1590}
1591
1592DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1593 "handover maximum distance <0-9999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001594 HANDOVER_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001595 "How big is the maximum timing advance before HO is forced\n"
1596 "Distance\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001597{
Harald Weltedcccb182010-05-16 20:52:23 +02001598 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001599 gsmnet->handover.max_distance = atoi(argv[0]);
1600 return CMD_SUCCESS;
1601}
Harald Weltebc814502009-12-19 21:41:52 +01001602
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001603DEFUN(cfg_net_pag_any_tch,
1604 cfg_net_pag_any_tch_cmd,
1605 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001606 "Assign a TCH when receiving a Paging Any request\n"
1607 "Any Channel\n" "Use\n" "TCH\n"
1608 "Do not use TCH for Paging Request Any\n"
1609 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001610{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001611 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001612 gsmnet->pag_any_tch = atoi(argv[0]);
1613 gsm_net_update_ctype(gsmnet);
1614 return CMD_SUCCESS;
1615}
1616
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001617#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1618/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1619#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1620
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001621#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001622 DEFUN(cfg_net_T##number, \
1623 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001624 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001625 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001626 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001627 "Set to default timer value" \
1628 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1629 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001630{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001631 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001632 int value; \
1633 if (strcmp(argv[0], "default") == 0) \
1634 value = DEFAULT_TIMER(number); \
1635 else \
1636 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001637 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001638 gsmnet->T##number = value; \
1639 return CMD_SUCCESS; \
1640}
1641
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001642DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1643DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1644DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1645DECLARE_TIMER(3107, "Currently not used")
1646DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1647DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1648DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1649DECLARE_TIMER(3115, "Currently not used")
1650DECLARE_TIMER(3117, "Currently not used")
1651DECLARE_TIMER(3119, "Currently not used")
1652DECLARE_TIMER(3122, "Waiting time (seconds) after IMM ASS REJECT")
1653DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001654
Maxc08ee712016-05-11 12:45:13 +02001655DEFUN_DEPRECATED(cfg_net_dtx,
1656 cfg_net_dtx_cmd,
1657 "dtx-used (0|1)",
1658 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001659{
Maxc08ee712016-05-11 12:45:13 +02001660 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1661 "configuration options of BTS instead%s", VTY_NEWLINE);
1662 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001663}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001664
Harald Welte5258fc42009-03-28 19:07:53 +00001665/* per-BTS configuration */
1666DEFUN(cfg_bts,
1667 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001668 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001669 "Select a BTS to configure\n"
1670 "BTS Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001671{
Harald Weltedcccb182010-05-16 20:52:23 +02001672 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001673 int bts_nr = atoi(argv[0]);
1674 struct gsm_bts *bts;
1675
Harald Weltee441d9c2009-06-21 16:17:15 +02001676 if (bts_nr > gsmnet->num_bts) {
1677 vty_out(vty, "%% The next unused BTS number is %u%s",
1678 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001679 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001680 } else if (bts_nr == gsmnet->num_bts) {
1681 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001682 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001683 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001684 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001685 bts = gsm_bts_num(gsmnet, bts_nr);
1686
Daniel Willmannf15c2762010-01-11 13:43:07 +01001687 if (!bts) {
1688 vty_out(vty, "%% Unable to allocate BTS %u%s",
1689 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001690 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001691 }
Harald Welte5258fc42009-03-28 19:07:53 +00001692
1693 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001694 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001695 vty->node = BTS_NODE;
1696
1697 return CMD_SUCCESS;
1698}
1699
1700DEFUN(cfg_bts_type,
1701 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001702 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001703 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001704{
1705 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001706 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001707
Max7507aef2017-04-10 13:59:14 +02001708 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001709 if (rc < 0)
1710 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001711
Harald Welte5258fc42009-03-28 19:07:53 +00001712 return CMD_SUCCESS;
1713}
1714
Harald Weltefcd24452009-06-20 18:15:19 +02001715DEFUN(cfg_bts_band,
1716 cfg_bts_band_cmd,
1717 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001718 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001719{
1720 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001721 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001722
1723 if (band < 0) {
1724 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1725 band, VTY_NEWLINE);
1726 return CMD_WARNING;
1727 }
1728
1729 bts->band = band;
1730
1731 return CMD_SUCCESS;
1732}
1733
Maxc08ee712016-05-11 12:45:13 +02001734DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1735 "Configure discontinuous transmission\n"
1736 "Enable Uplink DTX for this BTS\n"
1737 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1738 "older phones).\n")
1739{
1740 struct gsm_bts *bts = vty->index;
1741
1742 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001743 if (!is_ipaccess_bts(bts))
1744 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1745 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001746 return CMD_SUCCESS;
1747}
1748
1749DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1750 NO_STR
1751 "Configure discontinuous transmission\n"
1752 "Disable Uplink DTX for this BTS\n")
1753{
1754 struct gsm_bts *bts = vty->index;
1755
1756 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1757
1758 return CMD_SUCCESS;
1759}
1760
1761DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1762 "Configure discontinuous transmission\n"
1763 "Enable Downlink DTX for this BTS\n")
1764{
1765 struct gsm_bts *bts = vty->index;
1766
1767 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001768 if (!is_ipaccess_bts(bts))
1769 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1770 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001771 return CMD_SUCCESS;
1772}
1773
1774DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1775 NO_STR
1776 "Configure discontinuous transmission\n"
1777 "Disable Downlink DTX for this BTS\n")
1778{
1779 struct gsm_bts *bts = vty->index;
1780
1781 bts->dtxd = false;
1782
1783 return CMD_SUCCESS;
1784}
1785
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001786DEFUN(cfg_bts_ci,
1787 cfg_bts_ci_cmd,
1788 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001789 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001790{
1791 struct gsm_bts *bts = vty->index;
1792 int ci = atoi(argv[0]);
1793
1794 if (ci < 0 || ci > 0xffff) {
1795 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1796 ci, VTY_NEWLINE);
1797 return CMD_WARNING;
1798 }
1799 bts->cell_identity = ci;
1800
1801 return CMD_SUCCESS;
1802}
1803
Harald Welte5258fc42009-03-28 19:07:53 +00001804DEFUN(cfg_bts_lac,
1805 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001806 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001807 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001808{
1809 struct gsm_bts *bts = vty->index;
1810 int lac = atoi(argv[0]);
1811
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001812 if (lac < 0 || lac > 0xffff) {
1813 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001814 lac, VTY_NEWLINE);
1815 return CMD_WARNING;
1816 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001817
1818 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1819 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1820 lac, VTY_NEWLINE);
1821 return CMD_WARNING;
1822 }
1823
Harald Welte5258fc42009-03-28 19:07:53 +00001824 bts->location_area_code = lac;
1825
1826 return CMD_SUCCESS;
1827}
1828
Harald Weltea43f7892009-12-01 18:04:30 +05301829
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001830/* compatibility wrapper for old config files */
1831DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001832 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001833 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001834 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001835{
Harald Welte5258fc42009-03-28 19:07:53 +00001836 return CMD_SUCCESS;
1837}
1838
Harald Welte78f2f502009-05-23 16:56:52 +00001839DEFUN(cfg_bts_bsic,
1840 cfg_bts_bsic_cmd,
1841 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001842 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1843 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001844{
1845 struct gsm_bts *bts = vty->index;
1846 int bsic = atoi(argv[0]);
1847
1848 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001849 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001850 bsic, VTY_NEWLINE);
1851 return CMD_WARNING;
1852 }
1853 bts->bsic = bsic;
1854
1855 return CMD_SUCCESS;
1856}
1857
Harald Welte4cc34222009-05-01 15:12:31 +00001858DEFUN(cfg_bts_unit_id,
1859 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001860 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001861 "Abis/IP specific options\n"
1862 "Set the IPA BTS Unit ID\n"
1863 "Unit ID (Site)\n"
1864 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001865{
1866 struct gsm_bts *bts = vty->index;
1867 int site_id = atoi(argv[0]);
1868 int bts_id = atoi(argv[1]);
1869
Harald Welte07dc73d2009-08-07 13:27:09 +02001870 if (!is_ipaccess_bts(bts)) {
1871 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1872 return CMD_WARNING;
1873 }
1874
Harald Welte4cc34222009-05-01 15:12:31 +00001875 bts->ip_access.site_id = site_id;
1876 bts->ip_access.bts_id = bts_id;
1877
1878 return CMD_SUCCESS;
1879}
1880
Harald Welte8b291802013-03-12 13:57:05 +01001881DEFUN(cfg_bts_rsl_ip,
1882 cfg_bts_rsl_ip_cmd,
1883 "ip.access rsl-ip A.B.C.D",
1884 "Abis/IP specific options\n"
1885 "Set the IPA RSL IP Address of the BSC\n"
1886 "Destination IP address for RSL connection\n")
1887{
1888 struct gsm_bts *bts = vty->index;
1889 struct in_addr ia;
1890
1891 if (!is_ipaccess_bts(bts)) {
1892 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1893 return CMD_WARNING;
1894 }
1895
1896 inet_aton(argv[0], &ia);
1897 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1898
1899 return CMD_SUCCESS;
1900}
1901
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001902#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001903
Sylvain Munautc9519462011-10-17 14:04:55 +02001904DEFUN(cfg_bts_nokia_site_skip_reset,
1905 cfg_bts_nokia_site_skip_reset_cmd,
1906 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001907 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001908 "Skip the reset step during bootstrap process of this BTS\n"
1909 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02001910{
1911 struct gsm_bts *bts = vty->index;
1912
1913 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
1914 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
1915 return CMD_WARNING;
1916 }
1917
1918 bts->nokia.skip_reset = atoi(argv[0]);
1919
1920 return CMD_SUCCESS;
1921}
1922
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001923DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
1924 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
1925 "nokia_site no-local-rel-conf (0|1)",
1926 NOKIA_STR
1927 "Do not wait for RELease CONFirm message when releasing channel locally\n"
1928 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
1929{
1930 struct gsm_bts *bts = vty->index;
1931
1932 if (!is_nokia_bts(bts)) {
1933 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1934 VTY_NEWLINE);
1935 return CMD_WARNING;
1936 }
1937
1938 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
1939
1940 return CMD_SUCCESS;
1941}
1942
Sipos Csaba56e17662015-02-07 13:27:36 +01001943DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
1944 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
1945 "nokia_site bts-reset-timer <15-100>",
1946 NOKIA_STR
1947 "The amount of time (in sec.) between BTS_RESET is sent,\n"
1948 "and the BTS is being bootstrapped.\n")
1949{
1950 struct gsm_bts *bts = vty->index;
1951
1952 if (!is_nokia_bts(bts)) {
1953 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1954 VTY_NEWLINE);
1955 return CMD_WARNING;
1956 }
1957
1958 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
1959
1960 return CMD_SUCCESS;
1961}
Harald Welte8f0ed552010-05-11 21:53:49 +02001962#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001963#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001964
Harald Welte8175e952009-10-20 00:22:00 +02001965DEFUN(cfg_bts_stream_id,
1966 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001967 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02001968 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001969 "Set the ip.access Stream ID of the OML link of this BTS\n"
1970 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02001971{
1972 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001973 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02001974
1975 if (!is_ipaccess_bts(bts)) {
1976 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1977 return CMD_WARNING;
1978 }
1979
1980 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001981 /* This is used by e1inp_bind_ops callback for each BTS model. */
1982 bts->oml_e1_link.e1_nr = linenr;
1983
1984 return CMD_SUCCESS;
1985}
1986
Harald Welted13e0cd2012-08-17 09:52:03 +02001987#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02001988
Harald Welte42581822009-08-08 16:12:58 +02001989DEFUN(cfg_bts_oml_e1,
1990 cfg_bts_oml_e1_cmd,
1991 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02001992 OML_E1_STR
1993 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001994 "E1/T1 line number to be used for OML\n"
1995 "E1/T1 timeslot to be used for OML\n"
1996 "E1/T1 timeslot to be used for OML\n"
1997 "E1/T1 sub-slot to be used for OML\n"
1998 "Use E1/T1 sub-slot 0\n"
1999 "Use E1/T1 sub-slot 1\n"
2000 "Use E1/T1 sub-slot 2\n"
2001 "Use E1/T1 sub-slot 3\n"
2002 "Use full E1 slot 3\n"
2003 )
Harald Welte42581822009-08-08 16:12:58 +02002004{
2005 struct gsm_bts *bts = vty->index;
2006
2007 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2008
2009 return CMD_SUCCESS;
2010}
2011
2012
2013DEFUN(cfg_bts_oml_e1_tei,
2014 cfg_bts_oml_e1_tei_cmd,
2015 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002016 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002017 "Set the TEI to be used for OML\n"
2018 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002019{
2020 struct gsm_bts *bts = vty->index;
2021
2022 bts->oml_tei = atoi(argv[0]);
2023
2024 return CMD_SUCCESS;
2025}
2026
Harald Welte7a8fa412009-08-10 13:48:16 +02002027DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2028 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002029 "Channnel Allocator\n" "Channel Allocator\n"
2030 "Allocate Timeslots and Transceivers in ascending order\n"
2031 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002032{
2033 struct gsm_bts *bts = vty->index;
2034
2035 if (!strcmp(argv[0], "ascending"))
2036 bts->chan_alloc_reverse = 0;
2037 else
2038 bts->chan_alloc_reverse = 1;
2039
2040 return CMD_SUCCESS;
2041}
2042
Harald Welte8f0ed552010-05-11 21:53:49 +02002043#define RACH_STR "Random Access Control Channel\n"
2044
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002045DEFUN(cfg_bts_rach_tx_integer,
2046 cfg_bts_rach_tx_integer_cmd,
2047 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002048 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002049 "Set the raw tx integer value in RACH Control parameters IE\n"
2050 "Set the raw tx integer value in RACH Control parameters IE\n"
2051 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002052{
2053 struct gsm_bts *bts = vty->index;
2054 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2055 return CMD_SUCCESS;
2056}
2057
2058DEFUN(cfg_bts_rach_max_trans,
2059 cfg_bts_rach_max_trans_cmd,
2060 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002061 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002062 "Set the maximum number of RACH burst transmissions\n"
2063 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002064 "Maximum number of 1 RACH burst transmissions\n"
2065 "Maximum number of 2 RACH burst transmissions\n"
2066 "Maximum number of 4 RACH burst transmissions\n"
2067 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002068{
2069 struct gsm_bts *bts = vty->index;
2070 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2071 return CMD_SUCCESS;
2072}
2073
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002074#define CD_STR "Channel Description\n"
2075
2076DEFUN(cfg_bts_chan_desc_att,
2077 cfg_bts_chan_desc_att_cmd,
2078 "channel-descrption attach (0|1)",
2079 CD_STR
2080 "Set if attachment is required\n"
2081 "Attachment is NOT required\n"
2082 "Attachment is required (standard)\n")
2083{
2084 struct gsm_bts *bts = vty->index;
2085 bts->si_common.chan_desc.att = atoi(argv[0]);
2086 return CMD_SUCCESS;
2087}
2088
2089DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2090 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2091 "channel-descrption bs-pa-mfrms <2-9>",
2092 CD_STR
2093 "Set number of multiframe periods for paging groups\n"
2094 "Number of multiframe periods for paging groups\n")
2095{
2096 struct gsm_bts *bts = vty->index;
2097 int bs_pa_mfrms = atoi(argv[0]);
2098
2099 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2100 return CMD_SUCCESS;
2101}
2102
2103DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2104 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2105 "channel-descrption bs-ag-blks-res <0-7>",
2106 CD_STR
2107 "Set number of blocks reserved for access grant\n"
2108 "Number of blocks reserved for access grant\n")
2109{
2110 struct gsm_bts *bts = vty->index;
2111 int bs_ag_blks_res = atoi(argv[0]);
2112
2113 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2114 return CMD_SUCCESS;
2115}
2116
Harald Welte8f0ed552010-05-11 21:53:49 +02002117#define NM_STR "Network Management\n"
2118
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002119DEFUN(cfg_bts_rach_nm_b_thresh,
2120 cfg_bts_rach_nm_b_thresh_cmd,
2121 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002122 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002123 "Set the NM Busy Threshold\n"
2124 "Set the NM Busy Threshold\n"
2125 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002126{
2127 struct gsm_bts *bts = vty->index;
2128 bts->rach_b_thresh = atoi(argv[0]);
2129 return CMD_SUCCESS;
2130}
2131
2132DEFUN(cfg_bts_rach_nm_ldavg,
2133 cfg_bts_rach_nm_ldavg_cmd,
2134 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002135 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002136 "Set the NM Loadaverage Slots value\n"
2137 "Set the NM Loadaverage Slots value\n"
2138 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002139{
2140 struct gsm_bts *bts = vty->index;
2141 bts->rach_ldavg_slots = atoi(argv[0]);
2142 return CMD_SUCCESS;
2143}
2144
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002145DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2146 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002147 "Should this cell be barred from access?\n"
2148 "Should this cell be barred from access?\n"
2149 "Cell should NOT be barred\n"
2150 "Cell should be barred\n")
2151
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002152{
2153 struct gsm_bts *bts = vty->index;
2154
Harald Welte71355012009-12-21 23:08:18 +01002155 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002156
2157 return CMD_SUCCESS;
2158}
2159
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002160DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2161 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002162 RACH_STR
2163 "Should this cell allow emergency calls?\n"
2164 "Should this cell allow emergency calls?\n"
2165 "Should this cell allow emergency calls?\n"
2166 "Do NOT allow emergency calls\n"
2167 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002168{
2169 struct gsm_bts *bts = vty->index;
2170
2171 if (atoi(argv[0]) == 0)
2172 bts->si_common.rach_control.t2 |= 0x4;
2173 else
2174 bts->si_common.rach_control.t2 &= ~0x4;
2175
2176 return CMD_SUCCESS;
2177}
2178
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002179DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2180 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2181 RACH_STR
2182 "Set access control class\n"
2183 "Access control class 0\n"
2184 "Access control class 1\n"
2185 "Access control class 2\n"
2186 "Access control class 3\n"
2187 "Access control class 4\n"
2188 "Access control class 5\n"
2189 "Access control class 6\n"
2190 "Access control class 7\n"
2191 "Access control class 8\n"
2192 "Access control class 9\n"
2193 "Access control class 11 for PLMN use\n"
2194 "Access control class 12 for security services\n"
2195 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2196 "Access control class 14 for emergency services\n"
2197 "Access control class 15 for PLMN staff\n"
2198 "barred to use access control class\n"
2199 "allowed to use access control class\n")
2200{
2201 struct gsm_bts *bts = vty->index;
2202
2203 uint8_t control_class;
2204 uint8_t allowed = 0;
2205
2206 if (strcmp(argv[1], "allowed") == 0)
2207 allowed = 1;
2208
2209 control_class = atoi(argv[0]);
2210 if (control_class < 8)
2211 if (allowed)
2212 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2213 else
2214 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2215 else
2216 if (allowed)
2217 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2218 else
2219 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2220
2221 return CMD_SUCCESS;
2222}
2223
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002224DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2225 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002226 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002227 "Maximum transmit power of the MS\n"
2228 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002229 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002230{
2231 struct gsm_bts *bts = vty->index;
2232
2233 bts->ms_max_power = atoi(argv[0]);
2234
2235 return CMD_SUCCESS;
2236}
2237
Harald Weltecfaabbb2012-08-16 23:23:50 +02002238#define CELL_STR "Cell Parameters\n"
2239
Harald Welte73225282009-12-12 18:17:25 +01002240DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2241 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002242 CELL_STR "Cell re-selection parameters\n"
2243 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002244 "Cell Re-Selection Hysteresis in dB")
2245{
2246 struct gsm_bts *bts = vty->index;
2247
2248 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2249
2250 return CMD_SUCCESS;
2251}
2252
2253DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2254 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002255 "Minimum RxLev needed for cell access\n"
2256 "Minimum RxLev needed for cell access\n"
2257 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002258 "Minimum RxLev needed for cell access (better than -110dBm)")
2259{
2260 struct gsm_bts *bts = vty->index;
2261
2262 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2263
2264 return CMD_SUCCESS;
2265}
2266
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002267DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2268 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002269 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2270 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002271{
2272 struct gsm_bts *bts = vty->index;
2273
2274 bts->si_common.cell_ro_sel_par.present = 1;
2275 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2276
2277 return CMD_SUCCESS;
2278}
2279
2280DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2281 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002282 CELL_STR "Cell Re-Selection Parameters\n"
2283 "Cell Re-Selection Offset (CRO) in dB\n"
2284 "Cell Re-Selection Offset (CRO) in dB\n"
2285 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002286{
2287 struct gsm_bts *bts = vty->index;
2288
2289 bts->si_common.cell_ro_sel_par.present = 1;
2290 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2291
2292 return CMD_SUCCESS;
2293}
2294
2295DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2296 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002297 "Cell selection temporary negative offset\n"
2298 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002299 "Cell selection temporary negative offset in dB")
2300{
2301 struct gsm_bts *bts = vty->index;
2302
2303 bts->si_common.cell_ro_sel_par.present = 1;
2304 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2305
2306 return CMD_SUCCESS;
2307}
2308
2309DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2310 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002311 "Cell selection temporary negative offset\n"
2312 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002313 "Sets cell selection temporary negative offset to infinity")
2314{
2315 struct gsm_bts *bts = vty->index;
2316
2317 bts->si_common.cell_ro_sel_par.present = 1;
2318 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2319
2320 return CMD_SUCCESS;
2321}
2322
2323DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2324 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002325 "Cell selection penalty time\n"
2326 "Cell selection penalty time\n"
2327 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002328{
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 = (atoi(argv[0])-20)/20;
2333
2334 return CMD_SUCCESS;
2335}
2336
2337DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2338 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002339 "Cell selection penalty time\n"
2340 "Cell selection penalty time\n"
2341 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002342 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2343 "and TEMPORARY_OFFSET is ignored)")
2344{
2345 struct gsm_bts *bts = vty->index;
2346
2347 bts->si_common.cell_ro_sel_par.present = 1;
2348 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2349
2350 return CMD_SUCCESS;
2351}
2352
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002353DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2354 "radio-link-timeout <4-64>",
2355 "Radio link timeout criterion (BTS side)\n"
2356 "Radio link timeout value (lost SACCH block)\n")
2357{
2358 struct gsm_bts *bts = vty->index;
2359
Harald Welte2f8b9d22017-06-18 11:12:13 +03002360 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2361
2362 return CMD_SUCCESS;
2363}
2364
2365DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2366 "radio-link-timeout infinite",
2367 "Radio link timeout criterion (BTS side)\n"
2368 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2369{
2370 struct gsm_bts *bts = vty->index;
2371
2372 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2373 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2374 return CMD_WARNING;
2375 }
2376
2377 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2378 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002379
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002380 return CMD_SUCCESS;
2381}
2382
Harald Welte8f0ed552010-05-11 21:53:49 +02002383#define GPRS_TEXT "GPRS Packet Network\n"
2384
Harald Welteaf387632010-03-14 23:30:30 +08002385DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002386 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002387 GPRS_TEXT
2388 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002389 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002390 "GPRS BSSGP VC Identifier")
2391{
2392 struct gsm_bts *bts = vty->index;
2393
Harald Welte4511d892010-04-18 15:51:20 +02002394 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002395 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2396 return CMD_WARNING;
2397 }
2398
Harald Welte97a282b2010-03-14 15:37:43 +08002399 bts->gprs.cell.bvci = atoi(argv[0]);
2400
2401 return CMD_SUCCESS;
2402}
2403
Harald Weltea5731cf2010-03-22 11:48:36 +08002404DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2405 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002406 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002407 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002408 "GPRS NS Entity Identifier")
2409{
2410 struct gsm_bts *bts = vty->index;
2411
Harald Welte4511d892010-04-18 15:51:20 +02002412 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002413 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2414 return CMD_WARNING;
2415 }
2416
2417 bts->gprs.nse.nsei = atoi(argv[0]);
2418
2419 return CMD_SUCCESS;
2420}
2421
Harald Welte8f0ed552010-05-11 21:53:49 +02002422#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2423 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002424
Harald Welte97a282b2010-03-14 15:37:43 +08002425DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2426 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002427 GPRS_TEXT NSVC_TEXT
2428 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002429 "GPRS NS VC Identifier")
2430{
2431 struct gsm_bts *bts = vty->index;
2432 int idx = atoi(argv[0]);
2433
Harald Welte4511d892010-04-18 15:51:20 +02002434 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002435 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2436 return CMD_WARNING;
2437 }
2438
Harald Welte97a282b2010-03-14 15:37:43 +08002439 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2440
2441 return CMD_SUCCESS;
2442}
2443
Harald Welteaf387632010-03-14 23:30:30 +08002444DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2445 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002446 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002447 "GPRS NS Local UDP Port\n"
2448 "GPRS NS Local UDP Port\n"
2449 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002450 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002451{
2452 struct gsm_bts *bts = vty->index;
2453 int idx = atoi(argv[0]);
2454
Harald Welte4511d892010-04-18 15:51:20 +02002455 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002456 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2457 return CMD_WARNING;
2458 }
2459
Harald Welteaf387632010-03-14 23:30:30 +08002460 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2461
2462 return CMD_SUCCESS;
2463}
2464
2465DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2466 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002467 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002468 "GPRS NS Remote UDP Port\n"
2469 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002470 "GPRS NS Remote UDP Port\n"
2471 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002472{
2473 struct gsm_bts *bts = vty->index;
2474 int idx = atoi(argv[0]);
2475
Harald Welte4511d892010-04-18 15:51:20 +02002476 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002477 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2478 return CMD_WARNING;
2479 }
2480
Harald Welteaf387632010-03-14 23:30:30 +08002481 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2482
2483 return CMD_SUCCESS;
2484}
2485
2486DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2487 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002488 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002489 "GPRS NS Remote IP Address\n"
2490 "GPRS NS Remote IP Address\n"
2491 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002492{
2493 struct gsm_bts *bts = vty->index;
2494 int idx = atoi(argv[0]);
2495 struct in_addr ia;
2496
Harald Welte4511d892010-04-18 15:51:20 +02002497 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002498 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2499 return CMD_WARNING;
2500 }
2501
Harald Welteaf387632010-03-14 23:30:30 +08002502 inet_aton(argv[1], &ia);
2503 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2504
2505 return CMD_SUCCESS;
2506}
2507
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002508DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002509 "paging free <-1-1024>",
2510 "Paging options\n"
2511 "Only page when having a certain amount of free slots\n"
2512 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002513{
2514 struct gsm_bts *bts = vty->index;
2515
2516 bts->paging.free_chans_need = atoi(argv[0]);
2517 return CMD_SUCCESS;
2518}
2519
Harald Welte615e9562010-05-11 23:50:21 +02002520DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2521 "gprs ns timer " NS_TIMERS " <0-255>",
2522 GPRS_TEXT "Network Service\n"
2523 "Network Service Timer\n"
2524 NS_TIMERS_HELP "Timer Value\n")
2525{
2526 struct gsm_bts *bts = vty->index;
2527 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2528 int val = atoi(argv[1]);
2529
2530 if (bts->gprs.mode == BTS_GPRS_NONE) {
2531 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2532 return CMD_WARNING;
2533 }
2534
2535 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2536 return CMD_WARNING;
2537
2538 bts->gprs.nse.timer[idx] = val;
2539
2540 return CMD_SUCCESS;
2541}
2542
2543#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 +02002544#define BSSGP_TIMERS_HELP \
2545 "Tbvc-block timeout\n" \
2546 "Tbvc-block retries\n" \
2547 "Tbvc-unblock retries\n" \
2548 "Tbvcc-reset timeout\n" \
2549 "Tbvc-reset retries\n" \
2550 "Tbvc-suspend timeout\n" \
2551 "Tbvc-suspend retries\n" \
2552 "Tbvc-resume timeout\n" \
2553 "Tbvc-resume retries\n" \
2554 "Tbvc-capa-update timeout\n" \
2555 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002556
2557DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2558 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2559 GPRS_TEXT "Cell / BSSGP\n"
2560 "Cell/BSSGP Timer\n"
2561 BSSGP_TIMERS_HELP "Timer Value\n")
2562{
2563 struct gsm_bts *bts = vty->index;
2564 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2565 int val = atoi(argv[1]);
2566
2567 if (bts->gprs.mode == BTS_GPRS_NONE) {
2568 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2569 return CMD_WARNING;
2570 }
2571
2572 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2573 return CMD_WARNING;
2574
2575 bts->gprs.cell.timer[idx] = val;
2576
2577 return CMD_SUCCESS;
2578}
2579
Harald Welte97a282b2010-03-14 15:37:43 +08002580DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2581 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002582 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002583 "GPRS Routing Area Code\n"
2584 "GPRS Routing Area Code\n"
2585 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002586{
2587 struct gsm_bts *bts = vty->index;
2588
Harald Welte4511d892010-04-18 15:51:20 +02002589 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002590 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2591 return CMD_WARNING;
2592 }
2593
Harald Welte97a282b2010-03-14 15:37:43 +08002594 bts->gprs.rac = atoi(argv[0]);
2595
2596 return CMD_SUCCESS;
2597}
2598
Max292ec582016-07-28 11:55:37 +02002599DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2600 "gprs control-ack-type-rach", GPRS_TEXT
2601 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2602 "four access bursts format instead of default RLC/MAC control block\n")
2603{
2604 struct gsm_bts *bts = vty->index;
2605
2606 if (bts->gprs.mode == BTS_GPRS_NONE) {
2607 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2608 return CMD_WARNING;
2609 }
2610
2611 bts->gprs.ctrl_ack_type_use_block = false;
2612
2613 return CMD_SUCCESS;
2614}
2615
2616DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2617 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2618 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2619 "four access bursts format instead of default RLC/MAC control block\n")
2620{
2621 struct gsm_bts *bts = vty->index;
2622
2623 if (bts->gprs.mode == BTS_GPRS_NONE) {
2624 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2625 return CMD_WARNING;
2626 }
2627
2628 bts->gprs.ctrl_ack_type_use_block = true;
2629
2630 return CMD_SUCCESS;
2631}
2632
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002633DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2634 "gprs network-control-order (nc0|nc1|nc2)",
2635 GPRS_TEXT
2636 "GPRS Network Control Order\n"
2637 "MS controlled cell re-selection, no measurement reporting\n"
2638 "MS controlled cell re-selection, MS sends measurement reports\n"
2639 "Network controlled cell re-selection, MS sends measurement reports\n")
2640{
2641 struct gsm_bts *bts = vty->index;
2642
2643 if (bts->gprs.mode == BTS_GPRS_NONE) {
2644 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2645 return CMD_WARNING;
2646 }
2647
2648 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2649
2650 return CMD_SUCCESS;
2651}
2652
Harald Welte4511d892010-04-18 15:51:20 +02002653DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2654 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002655 GPRS_TEXT
2656 "GPRS Mode for this BTS\n"
2657 "GPRS Disabled on this BTS\n"
2658 "GPRS Enabled on this BTS\n"
2659 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002660{
2661 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002662 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002663
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002664 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002665 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2666 VTY_NEWLINE);
2667 return CMD_WARNING;
2668 }
2669
2670 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002671
2672 return CMD_SUCCESS;
2673}
2674
bhargava350533c2016-07-21 11:14:34 +05302675DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2676 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2677 "gprs 11bit_rach_support_for_egprs (0|1)",
2678 GPRS_TEXT "11 bit RACH options\n"
2679 "Disable 11 bit RACH for EGPRS\n"
2680 "Enable 11 bit RACH for EGPRS")
2681{
2682 struct gsm_bts *bts = vty->index;
2683
2684 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2685
2686 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2687 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2688 return CMD_WARNING;
2689 }
2690
2691 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2692 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2693 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2694 " enabled%s", VTY_NEWLINE);
2695 return CMD_WARNING;
2696 }
2697
2698 return CMD_SUCCESS;
2699}
2700
Harald Welte9fbff4a2010-07-30 11:50:09 +02002701#define SI_TEXT "System Information Messages\n"
2702#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)"
2703#define SI_TYPE_HELP "System Information Type 1\n" \
2704 "System Information Type 2\n" \
2705 "System Information Type 3\n" \
2706 "System Information Type 4\n" \
2707 "System Information Type 5\n" \
2708 "System Information Type 6\n" \
2709 "System Information Type 7\n" \
2710 "System Information Type 8\n" \
2711 "System Information Type 9\n" \
2712 "System Information Type 10\n" \
2713 "System Information Type 13\n" \
2714 "System Information Type 16\n" \
2715 "System Information Type 17\n" \
2716 "System Information Type 18\n" \
2717 "System Information Type 19\n" \
2718 "System Information Type 20\n" \
2719 "System Information Type 2bis\n" \
2720 "System Information Type 2ter\n" \
2721 "System Information Type 2quater\n" \
2722 "System Information Type 5bis\n" \
2723 "System Information Type 5ter\n"
2724
2725DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2726 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2727 SI_TEXT SI_TYPE_HELP
2728 "System Information Mode\n"
2729 "Static user-specified\n"
2730 "Dynamic, BSC-computed\n")
2731{
2732 struct gsm_bts *bts = vty->index;
2733 int type;
2734
2735 type = get_string_value(osmo_sitype_strs, argv[0]);
2736 if (type < 0) {
2737 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2738 return CMD_WARNING;
2739 }
2740
2741 if (!strcmp(argv[1], "static"))
2742 bts->si_mode_static |= (1 << type);
2743 else
2744 bts->si_mode_static &= ~(1 << type);
2745
2746 return CMD_SUCCESS;
2747}
2748
2749DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2750 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2751 SI_TEXT SI_TYPE_HELP
2752 "Static System Information filling\n"
2753 "Static user-specified SI content in HEX notation\n")
2754{
2755 struct gsm_bts *bts = vty->index;
2756 int rc, type;
2757
2758 type = get_string_value(osmo_sitype_strs, argv[0]);
2759 if (type < 0) {
2760 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2761 return CMD_WARNING;
2762 }
2763
2764 if (!(bts->si_mode_static & (1 << type))) {
2765 vty_out(vty, "SI Type %s is not configured in static mode%s",
2766 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2767 return CMD_WARNING;
2768 }
2769
Harald Welte290aaed2010-07-30 11:53:18 +02002770 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002771 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002772
2773 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002774 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2775 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002776 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2777 return CMD_WARNING;
2778 }
2779
2780 /* Mark this SI as present */
2781 bts->si_valid |= (1 << type);
2782
2783 return CMD_SUCCESS;
2784}
2785
Harald Welte42def722017-01-13 00:10:32 +01002786DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2787 "early-classmark-sending (allowed|forbidden)",
2788 "Early Classmark Sending\n"
2789 "Early Classmark Sending is allowed\n"
2790 "Early Classmark Sending is forbidden\n")
2791{
2792 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002793
2794 if (!strcmp(argv[0], "allowed"))
2795 bts->early_classmark_allowed = true;
2796 else
2797 bts->early_classmark_allowed = false;
2798
2799 return CMD_SUCCESS;
2800}
2801
Harald Welte32c09622011-01-11 23:44:56 +01002802DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002803 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002804 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002805 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2806 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002807{
2808 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002809 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002810
Harald Welte64c07d22011-02-15 11:43:27 +01002811 switch (mode) {
2812 case NL_MODE_MANUAL_SI5SEP:
2813 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002814 /* make sure we clear the current list when switching to
2815 * manual mode */
2816 if (bts->neigh_list_manual_mode == 0)
2817 memset(&bts->si_common.data.neigh_list, 0,
2818 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002819 break;
2820 default:
2821 break;
2822 }
2823
2824 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002825
2826 return CMD_SUCCESS;
2827}
2828
2829DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002830 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002831 "Neighbor List\n" "Add to manual neighbor list\n"
2832 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2833 "ARFCN of neighbor\n")
2834{
2835 struct gsm_bts *bts = vty->index;
2836 struct bitvec *bv = &bts->si_common.neigh_list;
2837 uint16_t arfcn = atoi(argv[1]);
2838
2839 if (!bts->neigh_list_manual_mode) {
2840 vty_out(vty, "%% Cannot configure neighbor list in "
2841 "automatic mode%s", VTY_NEWLINE);
2842 return CMD_WARNING;
2843 }
2844
2845 if (!strcmp(argv[0], "add"))
2846 bitvec_set_bit_pos(bv, arfcn, 1);
2847 else
2848 bitvec_set_bit_pos(bv, arfcn, 0);
2849
2850 return CMD_SUCCESS;
2851}
2852
Max70fdd242017-06-15 15:10:53 +02002853/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002854DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002855 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2856 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2857 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2858 "Add to manual SI2quater neighbor list\n"
2859 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2860 "threshold high bits\n" "threshold high bits\n"
2861 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2862 "priority\n" "priority (8 means NA)\n"
2863 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2864 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002865{
2866 struct gsm_bts *bts = vty->index;
2867 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2868 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002869 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2870 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002871 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002872
Max70fdd242017-06-15 15:10:53 +02002873 switch (r) {
2874 case 1:
2875 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2876 thresh_hi, VTY_NEWLINE);
2877 break;
2878 case EARFCN_THRESH_LOW_INVALID:
2879 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2880 thresh_lo, VTY_NEWLINE);
2881 break;
2882 case EARFCN_QRXLV_INVALID + 1:
2883 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2884 qrx, VTY_NEWLINE);
2885 break;
2886 case EARFCN_PRIO_INVALID:
2887 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
2888 prio, VTY_NEWLINE);
2889 break;
2890 default:
2891 if (r < 0) {
2892 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
2893 return CMD_WARNING;
2894 }
Max59a1bf32016-04-15 16:04:46 +02002895 }
2896
Max70fdd242017-06-15 15:10:53 +02002897 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01002898 return CMD_SUCCESS;
2899
Maxf39d03a2017-05-12 17:00:30 +02002900 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02002901 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02002902 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01002903
Maxaafff962016-04-20 15:57:14 +02002904 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02002905}
2906
2907DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02002908 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02002909 "SI2quater Neighbor List\n"
2910 "SI2quater Neighbor List\n"
2911 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02002912 "EARFCN of neighbor\n"
2913 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02002914{
2915 struct gsm_bts *bts = vty->index;
2916 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02002917 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02002918 int r = osmo_earfcn_del(e, arfcn);
2919 if (r < 0) {
2920 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02002921 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02002922 return CMD_WARNING;
2923 }
2924
2925 return CMD_SUCCESS;
2926}
2927
Max26679e02016-04-20 15:57:13 +02002928DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02002929 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02002930 "SI2quater Neighbor List\n"
2931 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
2932 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
2933 "diversity bit\n")
2934{
2935 struct gsm_bts *bts = vty->index;
2936 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
2937
2938 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
2939 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02002940 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 +01002941 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02002942 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02002943 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
2944 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01002945 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02002946 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02002947 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02002948 return CMD_WARNING;
2949 }
2950
2951 return CMD_SUCCESS;
2952}
2953
2954DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02002955 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02002956 "SI2quater Neighbor List\n"
2957 "SI2quater Neighbor List\n"
2958 "Delete from SI2quater manual neighbor list\n"
2959 "UARFCN of neighbor\n"
2960 "UARFCN\n"
2961 "scrambling code\n")
2962{
2963 struct gsm_bts *bts = vty->index;
2964
2965 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
2966 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
2967 VTY_NEWLINE);
2968 return CMD_WARNING;
2969 }
2970
2971 return CMD_SUCCESS;
2972}
2973
Harald Welte64c07d22011-02-15 11:43:27 +01002974DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002975 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002976 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002977 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
2978 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
2979 "ARFCN of neighbor\n")
2980{
2981 struct gsm_bts *bts = vty->index;
2982 struct bitvec *bv = &bts->si_common.si5_neigh_list;
2983 uint16_t arfcn = atoi(argv[1]);
2984
2985 if (!bts->neigh_list_manual_mode) {
2986 vty_out(vty, "%% Cannot configure neighbor list in "
2987 "automatic mode%s", VTY_NEWLINE);
2988 return CMD_WARNING;
2989 }
2990
2991 if (!strcmp(argv[0], "add"))
2992 bitvec_set_bit_pos(bv, arfcn, 1);
2993 else
2994 bitvec_set_bit_pos(bv, arfcn, 0);
2995
2996 return CMD_SUCCESS;
2997}
Harald Welte9fbff4a2010-07-30 11:50:09 +02002998
Harald Welte8254cf72017-05-29 13:42:19 +02002999DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3000 "pcu-socket PATH",
3001 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3002 "Path in the file system for the unix-domain PCU socket\n")
3003{
3004 struct gsm_bts *bts = vty->index;
3005 int rc;
3006
Harald Welte4a824ca2017-05-29 13:54:27 +02003007 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003008 pcu_sock_exit(bts);
3009 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3010 if (rc < 0) {
3011 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3012 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3013 return CMD_WARNING;
3014 }
3015
3016 return CMD_SUCCESS;
3017}
3018
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003019#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3020
3021DEFUN(cfg_bts_excl_rf_lock,
3022 cfg_bts_excl_rf_lock_cmd,
3023 "rf-lock-exclude",
3024 EXCL_RFLOCK_STR)
3025{
3026 struct gsm_bts *bts = vty->index;
3027 bts->excl_from_rf_lock = 1;
3028 return CMD_SUCCESS;
3029}
3030
3031DEFUN(cfg_bts_no_excl_rf_lock,
3032 cfg_bts_no_excl_rf_lock_cmd,
3033 "no rf-lock-exclude",
3034 NO_STR EXCL_RFLOCK_STR)
3035{
3036 struct gsm_bts *bts = vty->index;
3037 bts->excl_from_rf_lock = 0;
3038 return CMD_SUCCESS;
3039}
3040
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003041#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3042
3043DEFUN(cfg_bts_force_comb_si,
3044 cfg_bts_force_comb_si_cmd,
3045 "force-combined-si",
3046 FORCE_COMB_SI_STR)
3047{
3048 struct gsm_bts *bts = vty->index;
3049 bts->force_combined_si = 1;
3050 return CMD_SUCCESS;
3051}
3052
3053DEFUN(cfg_bts_no_force_comb_si,
3054 cfg_bts_no_force_comb_si_cmd,
3055 "no force-combined-si",
3056 NO_STR FORCE_COMB_SI_STR)
3057{
3058 struct gsm_bts *bts = vty->index;
3059 bts->force_combined_si = 0;
3060 return CMD_SUCCESS;
3061}
3062
Andreas Eversberga83d5112013-12-07 18:32:28 +01003063static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3064{
3065 struct gsm_bts *bts = vty->index;
3066 struct bts_codec_conf *codec = &bts->codec;
3067 int i;
3068
3069 codec->hr = 0;
3070 codec->efr = 0;
3071 codec->amr = 0;
3072 for (i = 0; i < argc; i++) {
3073 if (!strcmp(argv[i], "hr"))
3074 codec->hr = 1;
3075 if (!strcmp(argv[i], "efr"))
3076 codec->efr = 1;
3077 if (!strcmp(argv[i], "amr"))
3078 codec->amr = 1;
3079 }
3080}
3081
3082#define CODEC_PAR_STR " (hr|efr|amr)"
3083#define CODEC_HELP_STR "Half Rate\n" \
3084 "Enhanced Full Rate\nAdaptive Multirate\n"
3085
3086DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3087 "codec-support fr",
3088 "Codec Support settings\nFullrate\n")
3089{
3090 _get_codec_from_arg(vty, 0, argv);
3091 return CMD_SUCCESS;
3092}
3093
3094DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3095 "codec-support fr" CODEC_PAR_STR,
3096 "Codec Support settings\nFullrate\n"
3097 CODEC_HELP_STR)
3098{
3099 _get_codec_from_arg(vty, 1, argv);
3100 return CMD_SUCCESS;
3101}
3102
3103DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3104 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3105 "Codec Support settings\nFullrate\n"
3106 CODEC_HELP_STR CODEC_HELP_STR)
3107{
3108 _get_codec_from_arg(vty, 2, argv);
3109 return CMD_SUCCESS;
3110}
3111
3112DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3113 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3114 "Codec Support settings\nFullrate\n"
3115 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3116{
3117 _get_codec_from_arg(vty, 3, argv);
3118 return CMD_SUCCESS;
3119}
3120
3121DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3122 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3123 "Codec Support settings\nFullrate\n"
3124 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3125{
3126 _get_codec_from_arg(vty, 4, argv);
3127 return CMD_SUCCESS;
3128}
3129
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003130DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3131 "depends-on-bts <0-255>",
3132 "This BTS can only be started if another one is up\n" "BTS Number\n")
3133{
3134 struct gsm_bts *bts = vty->index;
3135 struct gsm_bts *other_bts;
3136 int dep = atoi(argv[0]);
3137
3138
3139 if (!is_ipaccess_bts(bts)) {
3140 vty_out(vty, "This feature is only available for IP systems.%s",
3141 VTY_NEWLINE);
3142 return CMD_WARNING;
3143 }
3144
3145 other_bts = gsm_bts_num(bts->network, dep);
3146 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3147 vty_out(vty, "This feature is only available for IP systems.%s",
3148 VTY_NEWLINE);
3149 return CMD_WARNING;
3150 }
3151
3152 if (dep >= bts->nr) {
3153 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3154 VTY_NEWLINE);
3155 return CMD_WARNING;
3156 }
3157
3158 bts_depend_mark(bts, dep);
3159 return CMD_SUCCESS;
3160}
3161
3162DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3163 "depeneds-on-bts <0-255>",
3164 NO_STR "This BTS can only be started if another one is up\n"
3165 "BTS Number\n")
3166{
3167 struct gsm_bts *bts = vty->index;
3168 int dep = atoi(argv[0]);
3169
3170 bts_depend_clear(bts, dep);
3171 return CMD_SUCCESS;
3172}
3173
Andreas Eversberg73266522014-01-19 11:47:44 +01003174#define AMR_TEXT "Adaptive Multi Rate settings\n"
3175#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3176#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3177 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3178#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3179#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3180
3181static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3182{
3183 struct gsm_bts *bts = vty->index;
3184 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3185 struct gsm48_multi_rate_conf *mr_conf =
3186 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3187 int i;
3188
3189 mr->gsm48_ie[1] = 0;
3190 for (i = 0; i < argc; i++)
3191 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3192 mr_conf->icmi = 0;
3193}
3194
3195static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3196{
3197 struct gsm_bts *bts = vty->index;
3198 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003199 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003200 int i;
3201
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003202 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3203 for (i = 0; i < argc - 1; i++)
3204 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003205}
3206
3207static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3208{
3209 struct gsm_bts *bts = vty->index;
3210 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003211 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003212 int i;
3213
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003214 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3215 for (i = 0; i < argc - 1; i++)
3216 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003217}
3218
3219static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3220{
3221 struct gsm_bts *bts = vty->index;
3222 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3223 struct gsm48_multi_rate_conf *mr_conf =
3224 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3225 int num = 0, i;
3226
3227 for (i = 0; i < ((full) ? 8 : 6); i++) {
3228 if ((mr->gsm48_ie[1] & (1 << i))) {
3229 num++;
3230 }
3231 }
3232
3233 if (argv[0][0] == 'a' || num == 0)
3234 mr_conf->icmi = 0;
3235 else {
3236 mr_conf->icmi = 1;
3237 if (num < atoi(argv[0]))
3238 mr_conf->smod = num - 1;
3239 else
3240 mr_conf->smod = atoi(argv[0]) - 1;
3241 }
3242}
3243
3244#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3245#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3246 "10,2k\n12,2k\n"
3247
3248#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3249#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3250
3251#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3252#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3253
3254DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3255 "amr tch-f modes" AMR_TCHF_PAR_STR,
3256 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3257 AMR_TCHF_HELP_STR)
3258{
3259 get_amr_from_arg(vty, 1, argv, 1);
3260 return CMD_SUCCESS;
3261}
3262
3263DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3264 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3265 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3266 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3267{
3268 get_amr_from_arg(vty, 2, argv, 1);
3269 return CMD_SUCCESS;
3270}
3271
3272DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3273 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3274 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3275 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3276{
3277 get_amr_from_arg(vty, 3, argv, 1);
3278 return CMD_SUCCESS;
3279}
3280
3281DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3282 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3283 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3284 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3285{
3286 get_amr_from_arg(vty, 4, argv, 1);
3287 return CMD_SUCCESS;
3288}
3289
3290DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3291 "amr tch-f start-mode (auto|1|2|3|4)",
3292 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3293{
3294 get_amr_start_from_arg(vty, argv, 1);
3295 return CMD_SUCCESS;
3296}
3297
3298DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3299 "amr tch-f threshold (ms|bts) <0-63>",
3300 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3301 AMR_TH_HELP_STR)
3302{
3303 get_amr_th_from_arg(vty, 2, argv, 1);
3304 return CMD_SUCCESS;
3305}
3306
3307DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3308 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3309 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3310 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3311{
3312 get_amr_th_from_arg(vty, 3, argv, 1);
3313 return CMD_SUCCESS;
3314}
3315
3316DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3317 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3318 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3319 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3320{
3321 get_amr_th_from_arg(vty, 4, argv, 1);
3322 return CMD_SUCCESS;
3323}
3324
3325DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3326 "amr tch-f hysteresis (ms|bts) <0-15>",
3327 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3328 AMR_HY_HELP_STR)
3329{
3330 get_amr_hy_from_arg(vty, 2, argv, 1);
3331 return CMD_SUCCESS;
3332}
3333
3334DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3335 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3336 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3337 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3338{
3339 get_amr_hy_from_arg(vty, 3, argv, 1);
3340 return CMD_SUCCESS;
3341}
3342
3343DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3344 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3345 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3346 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3347{
3348 get_amr_hy_from_arg(vty, 4, argv, 1);
3349 return CMD_SUCCESS;
3350}
3351
3352DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3353 "amr tch-h modes" AMR_TCHH_PAR_STR,
3354 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3355 AMR_TCHH_HELP_STR)
3356{
3357 get_amr_from_arg(vty, 1, argv, 0);
3358 return CMD_SUCCESS;
3359}
3360
3361DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3362 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3363 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3364 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3365{
3366 get_amr_from_arg(vty, 2, argv, 0);
3367 return CMD_SUCCESS;
3368}
3369
3370DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3371 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3372 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3373 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3374{
3375 get_amr_from_arg(vty, 3, argv, 0);
3376 return CMD_SUCCESS;
3377}
3378
3379DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3380 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3381 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3382 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3383{
3384 get_amr_from_arg(vty, 4, argv, 0);
3385 return CMD_SUCCESS;
3386}
3387
3388DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3389 "amr tch-h start-mode (auto|1|2|3|4)",
3390 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3391{
3392 get_amr_start_from_arg(vty, argv, 0);
3393 return CMD_SUCCESS;
3394}
3395
3396DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3397 "amr tch-h threshold (ms|bts) <0-63>",
3398 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3399 AMR_TH_HELP_STR)
3400{
3401 get_amr_th_from_arg(vty, 2, argv, 0);
3402 return CMD_SUCCESS;
3403}
3404
3405DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3406 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3407 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3408 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3409{
3410 get_amr_th_from_arg(vty, 3, argv, 0);
3411 return CMD_SUCCESS;
3412}
3413
3414DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3415 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3416 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3417 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3418{
3419 get_amr_th_from_arg(vty, 4, argv, 0);
3420 return CMD_SUCCESS;
3421}
3422
3423DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3424 "amr tch-h hysteresis (ms|bts) <0-15>",
3425 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3426 AMR_HY_HELP_STR)
3427{
3428 get_amr_hy_from_arg(vty, 2, argv, 0);
3429 return CMD_SUCCESS;
3430}
3431
3432DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3433 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3434 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3435 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3436{
3437 get_amr_hy_from_arg(vty, 3, argv, 0);
3438 return CMD_SUCCESS;
3439}
3440
3441DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3442 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3443 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3444 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3445{
3446 get_amr_hy_from_arg(vty, 4, argv, 0);
3447 return CMD_SUCCESS;
3448}
3449
Harald Welte8f0ed552010-05-11 21:53:49 +02003450#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003451
Harald Welte5258fc42009-03-28 19:07:53 +00003452/* per TRX configuration */
3453DEFUN(cfg_trx,
3454 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003455 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003456 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003457 "Select a TRX to configure")
3458{
3459 int trx_nr = atoi(argv[0]);
3460 struct gsm_bts *bts = vty->index;
3461 struct gsm_bts_trx *trx;
3462
Harald Weltee441d9c2009-06-21 16:17:15 +02003463 if (trx_nr > bts->num_trx) {
3464 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3465 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003466 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003467 } else if (trx_nr == bts->num_trx) {
3468 /* we need to allocate a new one */
3469 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003470 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003471 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003472
Harald Weltee441d9c2009-06-21 16:17:15 +02003473 if (!trx)
3474 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003475
3476 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003477 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003478 vty->node = TRX_NODE;
3479
3480 return CMD_SUCCESS;
3481}
3482
3483DEFUN(cfg_trx_arfcn,
3484 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003485 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003486 "Set the ARFCN for this TRX\n"
3487 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003488{
3489 int arfcn = atoi(argv[0]);
3490 struct gsm_bts_trx *trx = vty->index;
3491
3492 /* FIXME: check if this ARFCN is supported by this TRX */
3493
3494 trx->arfcn = arfcn;
3495
3496 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3497 /* FIXME: use OML layer to update the ARFCN */
3498 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3499
3500 return CMD_SUCCESS;
3501}
3502
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003503DEFUN(cfg_trx_nominal_power,
3504 cfg_trx_nominal_power_cmd,
3505 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003506 "Nominal TRX RF Power in dBm\n"
3507 "Nominal TRX RF Power in dBm\n"
3508 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003509{
3510 struct gsm_bts_trx *trx = vty->index;
3511
3512 trx->nominal_power = atoi(argv[0]);
3513
3514 return CMD_SUCCESS;
3515}
3516
Harald Weltefcd24452009-06-20 18:15:19 +02003517DEFUN(cfg_trx_max_power_red,
3518 cfg_trx_max_power_red_cmd,
3519 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003520 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003521 "Reduction of maximum BS RF Power in dB\n")
3522{
3523 int maxpwr_r = atoi(argv[0]);
3524 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003525 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003526
3527 /* FIXME: check if our BTS type supports more than 12 */
3528 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3529 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3530 maxpwr_r, VTY_NEWLINE);
3531 return CMD_WARNING;
3532 }
3533 if (maxpwr_r & 1) {
3534 vty_out(vty, "%% Power %d dB is not an even value%s",
3535 maxpwr_r, VTY_NEWLINE);
3536 return CMD_WARNING;
3537 }
3538
3539 trx->max_power_red = maxpwr_r;
3540
3541 /* FIXME: make sure we update this using OML */
3542
3543 return CMD_SUCCESS;
3544}
3545
Harald Welte42581822009-08-08 16:12:58 +02003546DEFUN(cfg_trx_rsl_e1,
3547 cfg_trx_rsl_e1_cmd,
3548 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003549 "RSL Parameters\n"
3550 "E1/T1 interface to be used for RSL\n"
3551 "E1/T1 interface to be used for RSL\n"
3552 "E1/T1 Line Number to be used for RSL\n"
3553 "E1/T1 Timeslot to be used for RSL\n"
3554 "E1/T1 Timeslot to be used for RSL\n"
3555 "E1/T1 Sub-slot to be used for RSL\n"
3556 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3557 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3558 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3559 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3560 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003561{
3562 struct gsm_bts_trx *trx = vty->index;
3563
3564 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3565
3566 return CMD_SUCCESS;
3567}
3568
3569DEFUN(cfg_trx_rsl_e1_tei,
3570 cfg_trx_rsl_e1_tei_cmd,
3571 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003572 "RSL Parameters\n"
3573 "Set the TEI to be used for RSL\n"
3574 "Set the TEI to be used for RSL\n"
3575 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003576{
3577 struct gsm_bts_trx *trx = vty->index;
3578
3579 trx->rsl_tei = atoi(argv[0]);
3580
3581 return CMD_SUCCESS;
3582}
3583
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003584DEFUN(cfg_trx_rf_locked,
3585 cfg_trx_rf_locked_cmd,
3586 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003587 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3588 "TRX is NOT RF locked (active)\n"
3589 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003590{
3591 int locked = atoi(argv[0]);
3592 struct gsm_bts_trx *trx = vty->index;
3593
Maxbe356ed2017-09-07 19:10:09 +02003594 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003595 return CMD_SUCCESS;
3596}
Harald Welte42581822009-08-08 16:12:58 +02003597
Harald Welte5258fc42009-03-28 19:07:53 +00003598/* per TS configuration */
3599DEFUN(cfg_ts,
3600 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003601 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003602 "Select a Timeslot to configure\n"
3603 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003604{
3605 int ts_nr = atoi(argv[0]);
3606 struct gsm_bts_trx *trx = vty->index;
3607 struct gsm_bts_trx_ts *ts;
3608
3609 if (ts_nr >= TRX_NR_TS) {
3610 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3611 TRX_NR_TS, VTY_NEWLINE);
3612 return CMD_WARNING;
3613 }
3614
3615 ts = &trx->ts[ts_nr];
3616
3617 vty->index = ts;
3618 vty->node = TS_NODE;
3619
3620 return CMD_SUCCESS;
3621}
3622
Harald Weltea6fd58e2009-08-07 00:25:23 +02003623DEFUN(cfg_ts_pchan,
3624 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003625 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003626 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003627{
3628 struct gsm_bts_trx_ts *ts = vty->index;
3629 int pchanc;
3630
3631 pchanc = gsm_pchan_parse(argv[0]);
3632 if (pchanc < 0)
3633 return CMD_WARNING;
3634
3635 ts->pchan = pchanc;
3636
3637 return CMD_SUCCESS;
3638}
3639
3640/* used for backwards compatibility with old config files that still
3641 * have uppercase pchan type names */
3642DEFUN_HIDDEN(cfg_ts_pchan_compat,
3643 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003644 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003645 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003646{
3647 struct gsm_bts_trx_ts *ts = vty->index;
3648 int pchanc;
3649
3650 pchanc = gsm_pchan_parse(argv[0]);
3651 if (pchanc < 0)
3652 return CMD_WARNING;
3653
3654 ts->pchan = pchanc;
3655
3656 return CMD_SUCCESS;
3657}
3658
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003659
3660
Harald Welte135a6482011-05-30 12:09:13 +02003661DEFUN(cfg_ts_tsc,
3662 cfg_ts_tsc_cmd,
3663 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003664 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003665{
3666 struct gsm_bts_trx_ts *ts = vty->index;
3667
Max71d082b2017-05-30 15:03:38 +02003668 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003669 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3670 "falling back to BCC%s", VTY_NEWLINE);
3671 ts->tsc = -1;
3672 return CMD_WARNING;
3673 }
3674
Harald Welte135a6482011-05-30 12:09:13 +02003675 ts->tsc = atoi(argv[0]);
3676
3677 return CMD_SUCCESS;
3678}
3679
Harald Weltea39b0f22010-06-14 22:26:10 +02003680#define HOPPING_STR "Configure frequency hopping\n"
3681
3682DEFUN(cfg_ts_hopping,
3683 cfg_ts_hopping_cmd,
3684 "hopping enabled (0|1)",
3685 HOPPING_STR "Enable or disable frequency hopping\n"
3686 "Disable frequency hopping\n" "Enable frequency hopping\n")
3687{
3688 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003689 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003690
Max71d082b2017-05-30 15:03:38 +02003691 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003692 vty_out(vty, "BTS model does not support hopping%s",
3693 VTY_NEWLINE);
3694 return CMD_WARNING;
3695 }
3696
3697 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003698
3699 return CMD_SUCCESS;
3700}
3701
Harald Welte6e0cd042009-09-12 13:05:33 +02003702DEFUN(cfg_ts_hsn,
3703 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003704 "hopping sequence-number <0-63>",
3705 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003706 "Which hopping sequence to use for this channel\n"
3707 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003708{
3709 struct gsm_bts_trx_ts *ts = vty->index;
3710
3711 ts->hopping.hsn = atoi(argv[0]);
3712
3713 return CMD_SUCCESS;
3714}
3715
3716DEFUN(cfg_ts_maio,
3717 cfg_ts_maio_cmd,
3718 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003719 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003720 "Which hopping MAIO to use for this channel\n"
3721 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003722{
3723 struct gsm_bts_trx_ts *ts = vty->index;
3724
3725 ts->hopping.maio = atoi(argv[0]);
3726
3727 return CMD_SUCCESS;
3728}
3729
3730DEFUN(cfg_ts_arfcn_add,
3731 cfg_ts_arfcn_add_cmd,
3732 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003733 HOPPING_STR "Configure hopping ARFCN list\n"
3734 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003735{
3736 struct gsm_bts_trx_ts *ts = vty->index;
3737 int arfcn = atoi(argv[0]);
3738
Harald Weltea39b0f22010-06-14 22:26:10 +02003739 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3740
Harald Welte6e0cd042009-09-12 13:05:33 +02003741 return CMD_SUCCESS;
3742}
3743
3744DEFUN(cfg_ts_arfcn_del,
3745 cfg_ts_arfcn_del_cmd,
3746 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003747 HOPPING_STR "Configure hopping ARFCN list\n"
3748 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003749{
3750 struct gsm_bts_trx_ts *ts = vty->index;
3751 int arfcn = atoi(argv[0]);
3752
Harald Weltea39b0f22010-06-14 22:26:10 +02003753 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3754
Harald Welte6e0cd042009-09-12 13:05:33 +02003755 return CMD_SUCCESS;
3756}
3757
Harald Weltea6fd58e2009-08-07 00:25:23 +02003758DEFUN(cfg_ts_e1_subslot,
3759 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003760 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003761 "E1/T1 channel connected to this on-air timeslot\n"
3762 "E1/T1 channel connected to this on-air timeslot\n"
3763 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003764 "E1/T1 timeslot connected to this on-air timeslot\n"
3765 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003766 "E1/T1 sub-slot connected to this on-air timeslot\n"
3767 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3768 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3769 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3770 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3771 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003772{
3773 struct gsm_bts_trx_ts *ts = vty->index;
3774
Harald Welte42581822009-08-08 16:12:58 +02003775 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003776
3777 return CMD_SUCCESS;
3778}
Harald Welte5258fc42009-03-28 19:07:53 +00003779
Harald Welte4f10c252010-05-16 21:47:13 +02003780void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3781{
3782 vty_out(vty, "Channel Requests : %lu total, %lu no channel%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003783 net->bsc_ctrs->ctr[BSC_CTR_CHREQ_TOTAL].current,
3784 net->bsc_ctrs->ctr[BSC_CTR_CHREQ_NO_CHANNEL].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003785 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003786 vty_out(vty, "Channel Failures : %lu rf_failures, %lu rll failures%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003787 net->bsc_ctrs->ctr[BSC_CTR_CHAN_RF_FAIL].current,
3788 net->bsc_ctrs->ctr[BSC_CTR_CHAN_RLL_ERR].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003789 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003790 vty_out(vty, "Paging : %lu attempted, %lu complete, %lu expired%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003791 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
3792 net->bsc_ctrs->ctr[BSC_CTR_PAGING_COMPLETED].current,
3793 net->bsc_ctrs->ctr[BSC_CTR_PAGING_EXPIRED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003794 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003795 vty_out(vty, "BTS failures : %lu OML, %lu RSL%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003796 net->bsc_ctrs->ctr[BSC_CTR_BTS_OML_FAIL].current,
3797 net->bsc_ctrs->ctr[BSC_CTR_BTS_RSL_FAIL].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003798 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003799}
3800
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003801DEFUN(drop_bts,
3802 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003803 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003804 "Debug/Simulation command to drop Abis/IP BTS\n"
3805 "Debug/Simulation command to drop Abis/IP BTS\n"
3806 "Debug/Simulation command to drop Abis/IP BTS\n"
3807 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003808{
3809 struct gsm_network *gsmnet;
3810 struct gsm_bts_trx *trx;
3811 struct gsm_bts *bts;
3812 unsigned int bts_nr;
3813
3814 gsmnet = gsmnet_from_vty(vty);
3815
3816 bts_nr = atoi(argv[0]);
3817 if (bts_nr >= gsmnet->num_bts) {
3818 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3819 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3820 return CMD_WARNING;
3821 }
3822
3823 bts = gsm_bts_num(gsmnet, bts_nr);
3824 if (!bts) {
3825 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3826 return CMD_WARNING;
3827 }
3828
3829 if (!is_ipaccess_bts(bts)) {
3830 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3831 return CMD_WARNING;
3832 }
3833
3834
3835 /* close all connections */
3836 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003837 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003838 } else if (strcmp(argv[1], "rsl") == 0) {
3839 /* close all rsl connections */
3840 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003841 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003842 }
3843 } else {
3844 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3845 return CMD_WARNING;
3846 }
3847
3848 return CMD_SUCCESS;
3849}
3850
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003851DEFUN(restart_bts, restart_bts_cmd,
3852 "restart-bts <0-65535>",
3853 "Restart ip.access nanoBTS through OML\n"
3854 "BTS Number\n")
3855{
3856 struct gsm_network *gsmnet;
3857 struct gsm_bts_trx *trx;
3858 struct gsm_bts *bts;
3859 unsigned int bts_nr;
3860
3861 gsmnet = gsmnet_from_vty(vty);
3862
3863 bts_nr = atoi(argv[0]);
3864 if (bts_nr >= gsmnet->num_bts) {
3865 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3866 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3867 return CMD_WARNING;
3868 }
3869
3870 bts = gsm_bts_num(gsmnet, bts_nr);
3871 if (!bts) {
3872 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3873 return CMD_WARNING;
3874 }
3875
3876 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3877 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3878 VTY_NEWLINE);
3879 return CMD_WARNING;
3880 }
3881
3882 /* go from last TRX to c0 */
3883 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3884 abis_nm_ipaccess_restart(trx);
3885
3886 return CMD_SUCCESS;
3887}
3888
Harald Welte8e2e22f2017-07-10 20:25:10 +02003889DEFUN(bts_resend, bts_resend_cmd,
3890 "bts <0-255> resend-system-information",
3891 "BTS Specific Commands\n" "BTS Number\n"
3892 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3893{
3894 struct gsm_network *gsmnet;
3895 struct gsm_bts_trx *trx;
3896 struct gsm_bts *bts;
3897 unsigned int bts_nr;
3898
3899 gsmnet = gsmnet_from_vty(vty);
3900
3901 bts_nr = atoi(argv[0]);
3902 if (bts_nr >= gsmnet->num_bts) {
3903 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3904 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3905 return CMD_WARNING;
3906 }
3907
3908 bts = gsm_bts_num(gsmnet, bts_nr);
3909 if (!bts) {
3910 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3911 return CMD_WARNING;
3912 }
3913
3914 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3915 gsm_bts_trx_set_system_infos(trx);
3916
3917 return CMD_SUCCESS;
3918}
3919
3920
Harald Welte30f1f372014-12-28 15:00:45 +01003921DEFUN(smscb_cmd, smscb_cmd_cmd,
3922 "bts <0-255> smscb-command <1-4> HEXSTRING",
3923 "BTS related commands\n" "BTS Number\n"
3924 "SMS Cell Broadcast\n" "Last Valid Block\n"
3925 "Hex Encoded SMSCB message (up to 88 octets)\n")
3926{
3927 struct gsm_bts *bts;
3928 int bts_nr = atoi(argv[0]);
3929 int last_block = atoi(argv[1]);
3930 struct rsl_ie_cb_cmd_type cb_cmd;
3931 uint8_t buf[88];
3932 int rc;
3933
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02003934 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01003935 if (!bts) {
3936 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3937 return CMD_WARNING;
3938 }
3939 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
3940 if (rc < 0 || rc > sizeof(buf)) {
3941 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3942 return CMD_WARNING;
3943 }
3944
3945 cb_cmd.spare = 0;
3946 cb_cmd.def_bcast = 0;
3947 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
3948
3949 switch (last_block) {
3950 case 1:
3951 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
3952 break;
3953 case 2:
3954 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
3955 break;
3956 case 3:
3957 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
3958 break;
3959 case 4:
3960 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
3961 break;
3962 }
3963
3964 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
3965
3966 return CMD_SUCCESS;
3967}
3968
Harald Welte7fe00fb2017-05-27 14:09:50 +02003969/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02003970static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
3971 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02003972{
Harald Welte645eb622017-05-27 15:52:58 +02003973 int bts_nr = atoi(bts_str);
3974 int trx_nr = atoi(trx_str);
3975 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003976 struct gsm_bts *bts;
3977 struct gsm_bts_trx *trx;
3978 struct gsm_bts_trx_ts *ts;
3979
3980 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
3981 if (!bts) {
3982 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3983 return NULL;
3984 }
3985
3986 trx = gsm_bts_trx_num(bts, trx_nr);
3987 if (!trx) {
3988 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
3989 return NULL;
3990 }
3991
3992 ts = &trx->ts[ts_nr];
3993
3994 return ts;
3995}
Harald Welte30f1f372014-12-28 15:00:45 +01003996
Harald Welted0d2b0b2010-12-23 13:18:07 +01003997DEFUN(pdch_act, pdch_act_cmd,
3998 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
3999 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4000 "TRX Timeslot\n" "Timeslot Number\n" "Packet Data Channel\n"
4001 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4002 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4003{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004004 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004005 int activate;
4006
Harald Welte645eb622017-05-27 15:52:58 +02004007 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004008 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004009 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004010
Harald Welte7fe00fb2017-05-27 14:09:50 +02004011 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004012 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4013 VTY_NEWLINE);
4014 return CMD_WARNING;
4015 }
4016
Harald Welted0d2b0b2010-12-23 13:18:07 +01004017 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4018 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004019 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004020 return CMD_WARNING;
4021 }
4022
4023 if (!strcmp(argv[3], "activate"))
4024 activate = 1;
4025 else
4026 activate = 0;
4027
4028 rsl_ipacc_pdch_activate(ts, activate);
4029
4030 return CMD_SUCCESS;
4031
4032}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004033
Harald Welte2abd5e12017-05-27 14:10:40 +02004034/* determine the logical channel type based on the physical channel type */
4035static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4036{
4037 switch (pchan) {
4038 case GSM_PCHAN_TCH_F:
4039 return GSM_LCHAN_TCH_F;
4040 case GSM_PCHAN_TCH_H:
4041 return GSM_LCHAN_TCH_H;
4042 case GSM_PCHAN_SDCCH8_SACCH8C:
4043 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4044 case GSM_PCHAN_CCCH_SDCCH4:
4045 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4046 return GSM_LCHAN_SDCCH;
4047 default:
4048 return -1;
4049 }
4050}
4051
4052/* configure the lchan for a single AMR mode (as specified) */
4053static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4054{
4055 struct amr_multirate_conf mr;
4056 struct gsm48_multi_rate_conf *mr_conf;
4057 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4058
4059 if (amr_mode > 7)
4060 return -1;
4061
4062 memset(&mr, 0, sizeof(mr));
4063 mr_conf->ver = 1;
4064 /* bit-mask of supported modes, only one bit is set. Reflects
4065 * Figure 10.5.2.47a where there are no thershold and only a
4066 * single mode */
4067 mr.gsm48_ie[1] = 1 << amr_mode;
4068
4069 mr.ms_mode[0].mode = amr_mode;
4070 mr.bts_mode[0].mode = amr_mode;
4071
4072 /* encode this configuration into the lchan for both uplink and
4073 * downlink direction */
4074 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4075 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4076
4077 return 0;
4078}
4079
4080/* Debug/Measurement command to activate a given logical channel
4081 * manually in a given mode/codec. This is useful for receiver
4082 * performance testing (FER/RBER/...) */
4083DEFUN(lchan_act, lchan_act_cmd,
4084 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
4085 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4086 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot Number\n" "Sub-Slot Number\n"
4087 "Manual Channel Activation (e.g. for BER test)\n"
4088 "Manual Channel Deactivation (e.g. for BER test)\n"
4089 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4090{
4091 struct gsm_bts_trx_ts *ts;
4092 struct gsm_lchan *lchan;
4093 int ss_nr = atoi(argv[3]);
4094 const char *act_str = argv[4];
4095 const char *codec_str = argv[5];
4096 int activate;
4097
4098 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4099 if (!ts)
4100 return CMD_WARNING;
4101
4102 lchan = &ts->lchan[ss_nr];
4103
4104 if (!strcmp(act_str, "activate"))
4105 activate = 1;
4106 else
4107 activate = 0;
4108
4109 if (ss_nr >= ts_subslots(ts)) {
4110 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4111 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4112 return CMD_WARNING;
4113 }
4114
4115 if (activate) {
4116 int lchan_t;
4117 if (lchan->state != LCHAN_S_NONE) {
4118 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4119 return CMD_WARNING;
4120 }
4121 lchan_t = lchan_type_by_pchan(ts->pchan);
4122 if (lchan_t < 0)
4123 return CMD_WARNING;
4124 /* configure the lchan */
4125 lchan->type = lchan_t;
4126 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4127 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4128 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4129 else if (!strcmp(codec_str, "efr"))
4130 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4131 else if (!strcmp(codec_str, "amr")) {
4132 int amr_mode;
4133 if (argc < 7) {
4134 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4135 return CMD_WARNING;
4136 }
4137 amr_mode = atoi(argv[6]);
4138 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4139 lchan_set_single_amr_mode(lchan, amr_mode);
4140 }
4141 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4142 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4143 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004144 } else {
4145 rsl_direct_rf_release(lchan);
4146 }
4147
4148 return CMD_SUCCESS;
4149}
4150
Harald Welte3f86c522017-05-27 15:53:28 +02004151DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4152 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
4153 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4154 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot\n" "Sub-Slot Number\n"
4155 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4156{
4157 struct gsm_bts_trx_ts *ts;
4158 struct gsm_lchan *lchan;
4159 int ss_nr = atoi(argv[3]);
4160 int port = atoi(argv[5]);
4161 struct in_addr ia;
4162 inet_aton(argv[4], &ia);
4163
4164 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4165 if (!ts)
4166 return CMD_WARNING;
4167
4168 lchan = &ts->lchan[ss_nr];
4169
4170 if (ss_nr >= ts_subslots(ts)) {
4171 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4172 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4173 return CMD_WARNING;
4174 }
4175
4176 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4177 inet_ntoa(ia), port, VTY_NEWLINE);
4178 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4179 return CMD_SUCCESS;
4180}
Harald Welteb71147a2017-07-18 19:11:49 +02004181
4182DEFUN(ctrl_trap, ctrl_trap_cmd,
4183 "ctrl-interface generate-trap TRAP VALUE",
4184 "Commands related to the CTRL Interface\n"
4185 "Generate a TRAP for test purpose\n"
4186 "Identity/Name of the TRAP variable\n"
4187 "Value of the TRAP variable\n")
4188{
4189 struct gsm_network *net = gsmnet_from_vty(vty);
4190
4191 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4192 return CMD_SUCCESS;
4193}
4194
Harald Weltedcccb182010-05-16 20:52:23 +02004195extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004196
Maxdb0e3802017-01-12 19:35:11 +01004197int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004198{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004199 cfg_ts_pchan_cmd.string =
4200 vty_cmd_string_from_valstr(tall_bsc_ctx,
4201 gsm_pchant_names,
4202 "phys_chan_config (", "|", ")",
4203 VTY_DO_LOWER);
4204 cfg_ts_pchan_cmd.doc =
4205 vty_cmd_string_from_valstr(tall_bsc_ctx,
4206 gsm_pchant_descs,
4207 "Physical Channel Combination\n",
4208 "\n", "", 0);
4209
Harald Weltee555c2b2012-08-17 13:02:12 +02004210 cfg_bts_type_cmd.string =
4211 vty_cmd_string_from_valstr(tall_bsc_ctx,
4212 bts_type_names,
4213 "type (", "|", ")",
4214 VTY_DO_LOWER);
4215 cfg_bts_type_cmd.doc =
4216 vty_cmd_string_from_valstr(tall_bsc_ctx,
4217 bts_type_descs,
4218 "BTS Vendor/Type\n",
4219 "\n", "", 0);
4220
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +02004221 common_cs_vty_init(network, config_write_net);
Harald Weltee555c2b2012-08-17 13:02:12 +02004222
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004223 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004224 install_element_ve(&show_bts_cmd);
4225 install_element_ve(&show_trx_cmd);
4226 install_element_ve(&show_ts_cmd);
4227 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004228 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004229
Philipp Maier39f62bb2017-04-09 12:32:51 +02004230 install_element_ve(&show_subscr_conn_cmd);
4231 install_element_ve(&handover_subscr_conn_cmd);
4232
Harald Welteb4d5b172010-05-12 16:10:35 +00004233 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004234 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004235
Maxdb0e3802017-01-12 19:35:11 +01004236 logging_vty_add_cmds(NULL);
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004237
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004238 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Weltebc814502009-12-19 21:41:52 +01004239 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Welteb720bd32009-12-21 16:51:50 +01004240 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
4241 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
4242 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
4243 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
4244 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
4245 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004246 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004247 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4248 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4249 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4250 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4251 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4252 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4253 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4254 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4255 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004256 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004257 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004258 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004259 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02004260
4261 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004262 install_node(&bts_node, config_write_bts);
Jacob Erlbeck36722e12013-10-29 09:30:30 +01004263 vty_install_default(BTS_NODE);
Harald Welte5258fc42009-03-28 19:07:53 +00004264 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004265 install_element(BTS_NODE, &cfg_description_cmd);
4266 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004267 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004268 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004269 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4270 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4271 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4272 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004273 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4274 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004275 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004276 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004277 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004278 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004279 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004280 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004281 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004282 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4283 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004284 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004285 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4286 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004287 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4288 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4289 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004290 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4291 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004292 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004293 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004294 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004295 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004296 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4297 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004298 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4299 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4300 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4301 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4302 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4303 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004304 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004305 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004306 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304307 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004308 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004309 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004310 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004311 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4312 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004313 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004314 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004315 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004316 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004317 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4318 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4319 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004320 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004321 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4322 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004323 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004324 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4325 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004326 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004327 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4328 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004329 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4330 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004331 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4332 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004333 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4334 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004335 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4336 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4337 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4338 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4339 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004340 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4341 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004342 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4343 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4344 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4345 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4346 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4347 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4348 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4349 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4350 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4351 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4352 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4353 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4354 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4355 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4356 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4357 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4358 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4359 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4360 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4361 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4362 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4363 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004364 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004365
Harald Welte5258fc42009-03-28 19:07:53 +00004366 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004367 install_node(&trx_node, dummy_config_write);
Jacob Erlbeck36722e12013-10-29 09:30:30 +01004368 vty_install_default(TRX_NODE);
Harald Welte5258fc42009-03-28 19:07:53 +00004369 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004370 install_element(TRX_NODE, &cfg_description_cmd);
4371 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004372 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004373 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004374 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4375 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004376 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004377
Harald Welte5258fc42009-03-28 19:07:53 +00004378 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004379 install_node(&ts_node, dummy_config_write);
Jacob Erlbeck36722e12013-10-29 09:30:30 +01004380 vty_install_default(TS_NODE);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004381 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004382 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004383 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004384 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004385 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4386 install_element(TS_NODE, &cfg_ts_maio_cmd);
4387 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4388 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004389 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004390
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004391 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004392 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004393 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004394 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004395 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004396 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004397 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004398 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004399
Harald Welte81c9b9c2010-05-31 16:40:40 +02004400 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004401 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004402 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004403 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004404
Harald Weltedcccb182010-05-16 20:52:23 +02004405 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004406
Harald Welte68628e82009-03-10 12:17:57 +00004407 return 0;
4408}