blob: 6fa8e0478f555fc0706d3fa7f0f33d8f0747e17a [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, "%s", VTY_NEWLINE);
Harald Welte1085c092009-11-18 20:33:19 +0100175 vty_out(vty, " Location updating reject cause: %u%s",
176 net->reject_cause, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900177 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
178 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100179 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
180 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800181 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
182 VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100183 vty_out(vty, " MM Info: %s%s", net->send_mm_info ? "On" : "Off",
184 VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100185 vty_out(vty, " Handover: %s%s", net->handover.active ? "On" : "Off",
186 VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100187 network_chan_load(&pl, net);
188 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
189 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100190
191 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100192 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100193 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200194 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100195 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100196 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200197 vty_out(vty, " Last RF Lock Command: %s%s",
198 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
199 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000200}
201
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200202DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000203 SHOW_STR "Display information about a GSM NETWORK\n")
204{
Harald Weltedcccb182010-05-16 20:52:23 +0200205 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000206 net_dump_vty(vty, net);
207
208 return CMD_SUCCESS;
209}
210
211static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
212{
Harald Welteedb37782009-05-01 14:59:07 +0000213 struct e1inp_line *line;
214
215 if (!e1l) {
216 vty_out(vty, " None%s", VTY_NEWLINE);
217 return;
218 }
219
220 line = e1l->ts->line;
221
222 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
223 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000224 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000225 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000226 e1l->tei, e1l->sapi, VTY_NEWLINE);
227}
228
229static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
230{
Harald Welteb908cb72009-12-22 13:09:29 +0100231 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200232 unsigned long long sec;
Harald Welteb908cb72009-12-22 13:09:29 +0100233
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200234 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100235 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200236 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200237 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100238 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100239 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200240 bts->num_trx, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200241 vty_out(vty, "Description: %s%s",
242 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Maxf9685c12017-03-23 12:01:07 +0100243 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
244 vty_out(vty, "PCU version %s connected%s", bts->pcu_version,
245 VTY_NEWLINE);
Harald Welte1d8dbc42009-12-12 15:38:16 +0100246 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100247 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100248 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
249 VTY_NEWLINE);
250 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100251 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100252 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
253 VTY_NEWLINE);
254 vty_out(vty, "RACH Max transmissions: %u%s",
255 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
256 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100257 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200258 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200259 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
260 vty_out(vty, "Uplink DTX: %s%s",
261 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
262 "enabled" : "forced", VTY_NEWLINE);
263 else
264 vty_out(vty, "Uplink DTX: not enabled%s", VTY_NEWLINE);
265 vty_out(vty, "Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
266 VTY_NEWLINE);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200267 vty_out(vty, "Channel Description Attachment: %s%s",
268 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
269 vty_out(vty, "Channel Description BS-PA-MFRMS: %u%s",
270 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
271 vty_out(vty, "Channel Description BS-AG_BLKS-RES: %u%s",
272 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200273 vty_out(vty, "System Information present: 0x%08x, static: 0x%08x%s",
274 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100275 vty_out(vty, "Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100276 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100277 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
278 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
279 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100280 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200281 if (bts->pcu_sock_path)
282 vty_out(vty, "PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000283 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200284 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000285 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200286 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200287 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
288 vty_out(vty, " Skip Reset: %d%s",
289 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000290 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200291 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000292 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200293 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200294 vty_out(vty, " GPRS NSE: ");
295 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
296 vty_out(vty, " GPRS CELL: ");
297 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
298 vty_out(vty, " GPRS NSVC0: ");
299 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
300 vty_out(vty, " GPRS NSVC1: ");
301 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200302 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
303 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000304 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100305 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200306 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200307 sec = bts_uptime(bts);
308 if (sec)
309 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.%s",
310 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60,
311 VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100312 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200313 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
314 e1isl_dump_vty(vty, bts->oml_link);
315 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100316
317 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100318 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200319 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100320 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
321 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100322
323 vty_out(vty, "Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
324 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
325 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
326 VTY_NEWLINE);
327 vty_out(vty, "Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
328 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
329 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
330 VTY_NEWLINE);
331 vty_out(vty, "BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
332 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
333 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
334 VTY_NEWLINE);
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);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100619
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);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100666 vty_out(vty, " early-classmark-sending-3g %s%s",
667 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100668 switch (bts->type) {
669 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100670 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200671 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200672 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100673 if (bts->ip_access.rsl_ip) {
674 struct in_addr ia;
675 ia.s_addr = htonl(bts->ip_access.rsl_ip);
676 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
677 VTY_NEWLINE);
678 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200679 vty_out(vty, " oml ip.access stream_id %u line %u%s",
680 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100681 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200682 case GSM_BTS_TYPE_NOKIA_SITE:
683 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100684 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
685 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100686 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 +0100687 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100688 default:
Harald Welte42581822009-08-08 16:12:58 +0200689 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
690 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100691 break;
Harald Welte42581822009-08-08 16:12:58 +0200692 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800693
694 /* if we have a limit, write it */
695 if (bts->paging.free_chans_need >= 0)
696 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
697
Harald Welte32c09622011-01-11 23:44:56 +0100698 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100699 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
700 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100701 for (i = 0; i < 1024; i++) {
702 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
703 vty_out(vty, " neighbor-list add arfcn %u%s",
704 i, VTY_NEWLINE);
705 }
706 }
Harald Welte64c07d22011-02-15 11:43:27 +0100707 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
708 for (i = 0; i < 1024; i++) {
709 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
710 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
711 i, VTY_NEWLINE);
712 }
713 }
Harald Welte32c09622011-01-11 23:44:56 +0100714
Max59a1bf32016-04-15 16:04:46 +0200715 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100716 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
717 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
718 vty_out(vty, " si2quater neighbor-list add earfcn %u "
719 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
720
721 vty_out(vty, " thresh-lo %u",
722 e->thresh_lo_valid ? e->thresh_lo : 32);
723
724 vty_out(vty, " prio %u",
725 e->prio_valid ? e->prio : 8);
726
727 vty_out(vty, " qrxlv %u",
728 e->qrxlm_valid ? e->qrxlm : 32);
729
730 tmp = e->meas_bw[i];
731 vty_out(vty, " meas %u",
732 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200733
734 vty_out(vty, "%s", VTY_NEWLINE);
735 }
736 }
737
Max26679e02016-04-20 15:57:13 +0200738 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
739 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
740 bts->si_common.data.uarfcn_list[i],
741 bts->si_common.data.scramble_list[i] & ~(1 << 9),
742 (bts->si_common.data.scramble_list[i] >> 9) & 1,
743 VTY_NEWLINE);
744 }
745
Andreas Eversberga83d5112013-12-07 18:32:28 +0100746 vty_out(vty, " codec-support fr");
747 if (bts->codec.hr)
748 vty_out(vty, " hr");
749 if (bts->codec.efr)
750 vty_out(vty, " efr");
751 if (bts->codec.amr)
752 vty_out(vty, " amr");
753 vty_out(vty, "%s", VTY_NEWLINE);
754
Andreas Eversberg73266522014-01-19 11:47:44 +0100755 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
756 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
757
Harald Welte615e9562010-05-11 23:50:21 +0200758 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200759
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200760 if (bts->excl_from_rf_lock)
761 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
762
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100763 vty_out(vty, " %sforce-combined-si%s",
764 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
765
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100766 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
767 int j;
768
769 if (bts->depends_on[i] == 0)
770 continue;
771
772 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
773 int bts_nr;
774
775 if ((bts->depends_on[i] & (1<<j)) == 0)
776 continue;
777
778 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
779 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
780 }
781 }
Harald Welte8254cf72017-05-29 13:42:19 +0200782 if (bts->pcu_sock_path)
783 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100784
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200785 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200786}
787
788static int config_write_bts(struct vty *v)
789{
Harald Weltedcccb182010-05-16 20:52:23 +0200790 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200791 struct gsm_bts *bts;
792
793 llist_for_each_entry(bts, &gsmnet->bts_list, list)
794 config_write_bts_single(v, bts);
795
796 return CMD_SUCCESS;
797}
798
Harald Weltea0d324b2017-07-20 01:47:39 +0200799/* small helper macro for conditional dumping of timer */
800#define VTY_OUT_TIMER(number) \
801 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
802 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
803
Harald Welte5013b2a2009-08-07 13:29:14 +0200804static int config_write_net(struct vty *vty)
805{
Harald Weltedcccb182010-05-16 20:52:23 +0200806 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
807
Harald Welte5013b2a2009-08-07 13:29:14 +0200808 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200809 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200810 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200811 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
812 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
Harald Welte1085c092009-11-18 20:33:19 +0100813 vty_out(vty, " location updating reject cause %u%s",
814 gsmnet->reject_cause, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900815 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100816 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800817 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100818 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100819 vty_out(vty, " handover %u%s", gsmnet->handover.active, VTY_NEWLINE);
Harald Welteb720bd32009-12-21 16:51:50 +0100820 vty_out(vty, " handover window rxlev averaging %u%s",
821 gsmnet->handover.win_rxlev_avg, VTY_NEWLINE);
822 vty_out(vty, " handover window rxqual averaging %u%s",
823 gsmnet->handover.win_rxqual_avg, VTY_NEWLINE);
824 vty_out(vty, " handover window rxlev neighbor averaging %u%s",
825 gsmnet->handover.win_rxlev_avg_neigh, VTY_NEWLINE);
826 vty_out(vty, " handover power budget interval %u%s",
827 gsmnet->handover.pwr_interval, VTY_NEWLINE);
828 vty_out(vty, " handover power budget hysteresis %u%s",
829 gsmnet->handover.pwr_hysteresis, VTY_NEWLINE);
830 vty_out(vty, " handover maximum distance %u%s",
831 gsmnet->handover.max_distance, VTY_NEWLINE);
Harald Weltea0d324b2017-07-20 01:47:39 +0200832 VTY_OUT_TIMER(3101);
833 VTY_OUT_TIMER(3103);
834 VTY_OUT_TIMER(3105);
835 VTY_OUT_TIMER(3107);
836 VTY_OUT_TIMER(3109);
837 VTY_OUT_TIMER(3111);
838 VTY_OUT_TIMER(3113);
839 VTY_OUT_TIMER(3115);
840 VTY_OUT_TIMER(3117);
841 VTY_OUT_TIMER(3119);
842 VTY_OUT_TIMER(3122);
843 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700844 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
845 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200846 if (gsmnet->tz.override != 0) {
847 if (gsmnet->tz.dst)
848 vty_out(vty, " timezone %d %d %d%s",
849 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
850 VTY_NEWLINE);
851 else
852 vty_out(vty, " timezone %d %d%s",
853 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
854 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200855 if (gsmnet->t3212 == 0)
856 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
857 else
858 vty_out(vty, " periodic location update %u%s",
859 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200860
861 return CMD_SUCCESS;
862}
Harald Welte67ce0732009-08-06 19:06:46 +0200863
Harald Welte68628e82009-03-10 12:17:57 +0000864static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
865{
866 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
867 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200868 vty_out(vty, "Description: %s%s",
869 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200870 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200871 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200872 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200873 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000874 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200875 net_dump_nmstate(vty, &trx->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000876 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200877 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200878 if (is_ipaccess_bts(trx->bts)) {
879 vty_out(vty, " ip.access stream ID: 0x%02x%s",
880 trx->rsl_tei, VTY_NEWLINE);
881 } else {
882 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
883 e1isl_dump_vty(vty, trx->rsl_link);
884 }
Harald Welte68628e82009-03-10 12:17:57 +0000885}
886
887DEFUN(show_trx,
888 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100889 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200890 SHOW_STR "Display information about a TRX\n"
891 "BTS Number\n"
892 "TRX Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000893{
Harald Weltedcccb182010-05-16 20:52:23 +0200894 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000895 struct gsm_bts *bts = NULL;
896 struct gsm_bts_trx *trx;
897 int bts_nr, trx_nr;
898
899 if (argc >= 1) {
900 /* use the BTS number that the user has specified */
901 bts_nr = atoi(argv[0]);
902 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000903 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000904 VTY_NEWLINE);
905 return CMD_WARNING;
906 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200907 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000908 }
909 if (argc >= 2) {
910 trx_nr = atoi(argv[1]);
911 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000912 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000913 VTY_NEWLINE);
914 return CMD_WARNING;
915 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200916 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000917 trx_dump_vty(vty, trx);
918 return CMD_SUCCESS;
919 }
920 if (bts) {
921 /* print all TRX in this BTS */
922 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200923 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000924 trx_dump_vty(vty, trx);
925 }
926 return CMD_SUCCESS;
927 }
928
929 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200930 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000931 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200932 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000933 trx_dump_vty(vty, trx);
934 }
935 }
936
937 return CMD_SUCCESS;
938}
939
Harald Welte67ce0732009-08-06 19:06:46 +0200940
Harald Welte68628e82009-03-10 12:17:57 +0000941static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
942{
Harald Welte135a6482011-05-30 12:09:13 +0200943 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +0100944 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +0100945 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +0100946 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +0100947 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200948 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +0100949 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000950 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200951 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530952 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000953 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
954 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
955 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000956}
957
958DEFUN(show_ts,
959 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100960 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200961 SHOW_STR "Display information about a TS\n"
962 "BTS Number\n" "TRX Number\n" "Timeslot Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000963{
Harald Weltedcccb182010-05-16 20:52:23 +0200964 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +0100965 struct gsm_bts *bts = NULL;
966 struct gsm_bts_trx *trx = NULL;
967 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000968 int bts_nr, trx_nr, ts_nr;
969
970 if (argc >= 1) {
971 /* use the BTS number that the user has specified */
972 bts_nr = atoi(argv[0]);
973 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000974 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000975 VTY_NEWLINE);
976 return CMD_WARNING;
977 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200978 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000979 }
980 if (argc >= 2) {
981 trx_nr = atoi(argv[1]);
982 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000983 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000984 VTY_NEWLINE);
985 return CMD_WARNING;
986 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200987 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000988 }
989 if (argc >= 3) {
990 ts_nr = atoi(argv[2]);
991 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +0000992 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +0000993 VTY_NEWLINE);
994 return CMD_WARNING;
995 }
Harald Welte274d0152010-12-24 12:05:03 +0100996 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +0000997 ts = &trx->ts[ts_nr];
998 ts_dump_vty(vty, ts);
999 return CMD_SUCCESS;
1000 }
Harald Welte274d0152010-12-24 12:05:03 +01001001
1002 if (bts && trx) {
1003 /* Iterate over all TS in this TRX */
1004 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1005 ts = &trx->ts[ts_nr];
1006 ts_dump_vty(vty, ts);
1007 }
1008 } else if (bts) {
1009 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001010 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001011 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001012 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1013 ts = &trx->ts[ts_nr];
1014 ts_dump_vty(vty, ts);
1015 }
1016 }
Harald Welte274d0152010-12-24 12:05:03 +01001017 } else {
1018 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1019 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1020 bts = gsm_bts_num(net, bts_nr);
1021 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1022 trx = gsm_bts_trx_num(bts, trx_nr);
1023 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1024 ts = &trx->ts[ts_nr];
1025 ts_dump_vty(vty, ts);
1026 }
1027 }
1028 }
Harald Welte68628e82009-03-10 12:17:57 +00001029 }
1030
1031 return CMD_SUCCESS;
1032}
1033
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001034static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1035{
1036 if (strlen(bsub->imsi))
1037 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1038 if (bsub->tmsi != GSM_RESERVED_TMSI)
1039 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1040 VTY_NEWLINE);
1041 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1042}
1043
Harald Welte8387a492009-12-22 21:43:14 +01001044static void meas_rep_dump_uni_vty(struct vty *vty,
1045 struct gsm_meas_rep_unidir *mru,
1046 const char *prefix,
1047 const char *dir)
1048{
1049 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1050 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1051 dir, rxlev2dbm(mru->sub.rx_lev));
1052 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1053 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1054 VTY_NEWLINE);
1055}
1056
1057static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1058 const char *prefix)
1059{
1060 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1061 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1062 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1063 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1064 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1065 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1066 VTY_NEWLINE);
1067 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001068 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001069 if (mr->flags & MEAS_REP_F_MS_L1)
1070 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1071 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1072 if (mr->flags & MEAS_REP_F_DL_VALID)
1073 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1074 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1075}
1076
Harald Welte0a8cf322015-12-05 17:22:49 +01001077/* FIXME: move this to libosmogsm */
1078static const struct value_string gsm48_cmode_names[] = {
1079 { GSM48_CMODE_SIGN, "signalling" },
1080 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1081 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1082 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1083 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1084 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1085 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1086 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1087 { 0, NULL }
1088};
1089
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001090/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1091 * Don't do anything if the ts is not dynamic. */
1092static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1093{
1094 switch (ts->pchan) {
1095 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1096 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1097 vty_out(vty, " as %s",
1098 gsm_pchan_name(ts->dyn.pchan_is));
1099 else
1100 vty_out(vty, " switching %s -> %s",
1101 gsm_pchan_name(ts->dyn.pchan_is),
1102 gsm_pchan_name(ts->dyn.pchan_want));
1103 break;
1104 case GSM_PCHAN_TCH_F_PDCH:
1105 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1106 vty_out(vty, " as %s",
1107 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1108 : "TCH/F");
1109 else
1110 vty_out(vty, " switching %s -> %s",
1111 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1112 : "TCH/F",
1113 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1114 : "TCH/F");
1115 break;
1116 default:
1117 /* no dyn ts */
1118 break;
1119 }
1120}
1121
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001122static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001123{
Harald Welte8387a492009-12-22 21:43:14 +01001124 int idx;
1125
Harald Welte85bded82010-12-24 12:22:34 +01001126 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1127 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1128 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001129 /* show dyn TS details, if applicable */
1130 switch (lchan->ts->pchan) {
1131 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1132 vty_out(vty, " Osmocom Dyn TS:");
1133 vty_out_dyn_ts_status(vty, lchan->ts);
1134 vty_out(vty, VTY_NEWLINE);
1135 break;
1136 case GSM_PCHAN_TCH_F_PDCH:
1137 vty_out(vty, " IPACC Dyn PDCH TS:");
1138 vty_out_dyn_ts_status(vty, lchan->ts);
1139 vty_out(vty, VTY_NEWLINE);
1140 break;
1141 default:
1142 /* no dyn ts */
1143 break;
1144 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001145 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001146 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001147 gsm_lchans_name(lchan->state),
1148 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1149 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1150 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001151 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1152 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1153 - lchan->bs_power*2,
1154 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1155 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001156 vty_out(vty, " Channel Mode / Codec: %s%s",
1157 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1158 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001159 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001160 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001161 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001162 } else
1163 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301164 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1165 struct in_addr ia;
Holger Hans Peter Freyther54fa7992010-04-07 15:39:16 +02001166 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte2c828992009-12-02 01:56:49 +05301167 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1168 inet_ntoa(ia), lchan->abis_ip.bound_port,
1169 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1170 VTY_NEWLINE);
1171 }
Harald Welte8387a492009-12-22 21:43:14 +01001172
1173 /* we want to report the last measurement report */
1174 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1175 lchan->meas_rep_idx, 1);
1176 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001177}
1178
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001179static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1180{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001181 struct gsm_meas_rep *mr;
1182 int idx;
1183
1184 /* we want to report the last measurement report */
1185 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1186 lchan->meas_rep_idx, 1);
1187 mr = &lchan->meas_rep[idx];
1188
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001189 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001190 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001191 gsm_pchan_name(lchan->ts->pchan));
1192 vty_out_dyn_ts_status(vty, lchan->ts);
1193 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1194 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001195 lchan->nr,
1196 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1197 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001198 rxlev2dbm(mr->dl.full.rx_lev),
1199 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001200 VTY_NEWLINE);
1201}
1202
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001203
1204static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1205 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1206{
1207 int lchan_nr;
1208 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1209 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1210 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1211 continue;
1212 dump_cb(vty, lchan);
1213 }
1214
1215 return CMD_SUCCESS;
1216}
1217
1218static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1219 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1220{
1221 int ts_nr;
1222
1223 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1224 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1225 dump_lchan_trx_ts(ts, vty, dump_cb);
1226 }
1227
1228 return CMD_SUCCESS;
1229}
1230
1231static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1232 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1233{
1234 int trx_nr;
1235
1236 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1237 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1238 dump_lchan_trx(trx, vty, dump_cb);
1239 }
1240
1241 return CMD_SUCCESS;
1242}
1243
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001244static int lchan_summary(struct vty *vty, int argc, const char **argv,
1245 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001246{
Harald Weltedcccb182010-05-16 20:52:23 +02001247 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001248 struct gsm_bts *bts;
1249 struct gsm_bts_trx *trx;
1250 struct gsm_bts_trx_ts *ts;
1251 struct gsm_lchan *lchan;
1252 int bts_nr, trx_nr, ts_nr, lchan_nr;
1253
1254 if (argc >= 1) {
1255 /* use the BTS number that the user has specified */
1256 bts_nr = atoi(argv[0]);
1257 if (bts_nr >= net->num_bts) {
1258 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1259 VTY_NEWLINE);
1260 return CMD_WARNING;
1261 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001262 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001263
1264 if (argc == 1)
1265 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001266 }
1267 if (argc >= 2) {
1268 trx_nr = atoi(argv[1]);
1269 if (trx_nr >= bts->num_trx) {
1270 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1271 VTY_NEWLINE);
1272 return CMD_WARNING;
1273 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001274 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001275
1276 if (argc == 2)
1277 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001278 }
1279 if (argc >= 3) {
1280 ts_nr = atoi(argv[2]);
1281 if (ts_nr >= TRX_NR_TS) {
1282 vty_out(vty, "%% can't find TS %s%s", argv[2],
1283 VTY_NEWLINE);
1284 return CMD_WARNING;
1285 }
1286 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001287
1288 if (argc == 3)
1289 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001290 }
1291 if (argc >= 4) {
1292 lchan_nr = atoi(argv[3]);
1293 if (lchan_nr >= TS_MAX_LCHAN) {
1294 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1295 VTY_NEWLINE);
1296 return CMD_WARNING;
1297 }
1298 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001299 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001300 return CMD_SUCCESS;
1301 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001302
1303
Harald Welte68628e82009-03-10 12:17:57 +00001304 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001305 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001306 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001307 }
1308
1309 return CMD_SUCCESS;
1310}
1311
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001312
1313DEFUN(show_lchan,
1314 show_lchan_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001315 "show lchan [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001316 SHOW_STR "Display information about a logical channel\n"
1317 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001318 LCHAN_NR_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001319
1320{
1321 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1322}
1323
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001324DEFUN(show_lchan_summary,
1325 show_lchan_summary_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001326 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001327 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001328 "Short summary\n"
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001329 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001330 LCHAN_NR_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001331{
1332 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1333}
1334
Philipp Maier39f62bb2017-04-09 12:32:51 +02001335DEFUN(show_subscr_conn,
1336 show_subscr_conn_cmd,
1337 "show conns",
1338 SHOW_STR "Display currently active subscriber connections\n")
1339{
1340 struct gsm_subscriber_connection *conn;
1341 struct gsm_network *net = gsmnet_from_vty(vty);
1342 bool no_conns = true;
1343 unsigned int count = 0;
1344
1345 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1346
1347 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1348 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1349 lchan_dump_full_vty(vty, conn->lchan);
1350 no_conns = false;
1351 count++;
1352 }
1353
1354 if (no_conns)
1355 vty_out(vty, "None%s", VTY_NEWLINE);
1356
1357 return CMD_SUCCESS;
1358}
1359
1360DEFUN(handover_subscr_conn,
1361 handover_subscr_conn_cmd,
1362 "handover <0-255> <0-255> <0-7> LCHAN_NR <0-255>",
1363 "Handover subscriber connection to other BTS\n"
1364 "BTS Number (current)\n" "TRX Number\n" "Timeslot Number\n"
1365 LCHAN_NR_STR "BTS Number (new)\n")
1366{
1367 struct gsm_network *net = gsmnet_from_vty(vty);
1368 struct gsm_subscriber_connection *conn;
1369 struct gsm_bts *bts;
1370 struct gsm_bts *new_bts = NULL;
1371 unsigned int bts_nr = atoi(argv[0]);
1372 unsigned int trx_nr = atoi(argv[1]);
1373 unsigned int ts_nr = atoi(argv[2]);
1374 unsigned int ss_nr = atoi(argv[3]);
1375 unsigned int bts_nr_new = atoi(argv[4]);
1376
1377 /* Lookup the BTS where we want to handover to */
1378 llist_for_each_entry(bts, &net->bts_list, list) {
1379 if (bts->nr == bts_nr_new) {
1380 new_bts = bts;
1381 break;
1382 }
1383 }
1384
1385 if (!new_bts) {
1386 vty_out(vty, "Unable to trigger handover,"
1387 "specified bts #%u does not exist %s", bts_nr_new,
1388 VTY_NEWLINE);
1389 return CMD_WARNING;
1390 }
1391
1392 /* Find the connection/lchan that we want to handover */
1393 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1394 if (conn->bts->nr == bts_nr &&
1395 conn->lchan->ts->trx->nr == trx_nr &&
1396 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
1397 vty_out(vty, "starting handover for lchan %s...%s",
1398 conn->lchan->name, VTY_NEWLINE);
1399 lchan_dump_full_vty(vty, conn->lchan);
1400 bsc_handover_start(conn->lchan, new_bts);
1401 return CMD_SUCCESS;
1402 }
1403 }
1404
1405 vty_out(vty, "Unable to trigger handover,"
1406 "specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1407 bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
1408
1409 return CMD_WARNING;
1410}
1411
Harald Weltebe4b7302009-05-23 16:59:33 +00001412static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001413{
1414 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001415 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001416}
1417
Harald Weltebe4b7302009-05-23 16:59:33 +00001418static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001419{
1420 struct gsm_paging_request *pag;
1421
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001422 if (!bts->paging.bts)
1423 return;
1424
Harald Weltef5025b62009-03-28 16:55:11 +00001425 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1426 paging_dump_vty(vty, pag);
1427}
1428
1429DEFUN(show_paging,
1430 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001431 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001432 SHOW_STR "Display information about paging reuqests of a BTS\n"
1433 "BTS Number\n")
Harald Weltef5025b62009-03-28 16:55:11 +00001434{
Harald Weltedcccb182010-05-16 20:52:23 +02001435 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001436 struct gsm_bts *bts;
1437 int bts_nr;
1438
1439 if (argc >= 1) {
1440 /* use the BTS number that the user has specified */
1441 bts_nr = atoi(argv[0]);
1442 if (bts_nr >= net->num_bts) {
1443 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1444 VTY_NEWLINE);
1445 return CMD_WARNING;
1446 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001447 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001448 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001449
Harald Weltef5025b62009-03-28 16:55:11 +00001450 return CMD_SUCCESS;
1451 }
1452 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
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
1457 return CMD_SUCCESS;
1458}
1459
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001460DEFUN(show_paging_group,
1461 show_paging_group_cmd,
1462 "show paging-group <0-255> IMSI",
1463 SHOW_STR "Display the paging group\n"
1464 "BTS Number\n" "IMSI\n")
1465{
1466 struct gsm_network *net = gsmnet_from_vty(vty);
1467 struct gsm_bts *bts;
1468 unsigned int page_group;
1469 int bts_nr = atoi(argv[0]);
1470
1471 if (bts_nr >= net->num_bts) {
1472 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1473 return CMD_WARNING;
1474 }
1475
1476 bts = gsm_bts_num(net, bts_nr);
1477 if (!bts) {
1478 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1479 return CMD_WARNING;
1480 }
1481
1482 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1483 str_to_imsi(argv[1]));
1484 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1485 str_to_imsi(argv[1]), bts->nr,
1486 page_group, VTY_NEWLINE);
1487 return CMD_SUCCESS;
1488}
1489
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001490DEFUN(cfg_net_neci,
1491 cfg_net_neci_cmd,
1492 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001493 "New Establish Cause Indication\n"
1494 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001495{
Harald Weltedcccb182010-05-16 20:52:23 +02001496 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1497
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001498 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001499 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001500 return CMD_SUCCESS;
1501}
1502
Harald Welte8f0ed552010-05-11 21:53:49 +02001503#define HANDOVER_STR "Handover Options\n"
1504
Harald Weltebc814502009-12-19 21:41:52 +01001505DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1506 "handover (0|1)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001507 HANDOVER_STR
1508 "Don't perform in-call handover\n"
1509 "Perform in-call handover\n")
Harald Weltebc814502009-12-19 21:41:52 +01001510{
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001511 int enable = atoi(argv[0]);
Harald Weltedcccb182010-05-16 20:52:23 +02001512 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001513
1514 if (enable && ipacc_rtp_direct) {
Harald Weltefe03f0d2009-12-20 13:51:01 +01001515 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1516 "is enabled by using the -P command line option%s",
1517 VTY_NEWLINE);
1518 return CMD_WARNING;
1519 }
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001520 gsmnet->handover.active = enable;
Harald Weltebc814502009-12-19 21:41:52 +01001521
1522 return CMD_SUCCESS;
1523}
1524
Harald Welte8f0ed552010-05-11 21:53:49 +02001525#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1526#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1527#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1528#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001529#define HO_AVG_COUNT_STR "Amount to use for Averaging\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001530
Harald Welteb720bd32009-12-21 16:51:50 +01001531DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1532 "handover window rxlev averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001533 HO_WIN_RXLEV_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001534 "How many RxLev measurements are used for averaging\n"
1535 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001536{
Harald Weltedcccb182010-05-16 20:52:23 +02001537 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001538 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1539 return CMD_SUCCESS;
1540}
1541
1542DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1543 "handover window rxqual averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001544 HO_WIN_RXQUAL_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001545 "How many RxQual measurements are used for averaging\n"
1546 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001547{
Harald Weltedcccb182010-05-16 20:52:23 +02001548 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001549 gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
1550 return CMD_SUCCESS;
1551}
1552
1553DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1554 "handover window rxlev neighbor averaging <1-10>",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001555 HO_WIN_RXLEV_STR "Neighbor\n"
1556 "How many RxQual measurements are used for averaging\n"
1557 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001558{
Harald Weltedcccb182010-05-16 20:52:23 +02001559 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001560 gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
1561 return CMD_SUCCESS;
1562}
1563
1564DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1565 "handover power budget interval <1-99>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001566 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001567 "How often to check if we have a better cell (SACCH frames)\n"
1568 "Interval\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001569{
Harald Weltedcccb182010-05-16 20:52:23 +02001570 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001571 gsmnet->handover.pwr_interval = atoi(argv[0]);
1572 return CMD_SUCCESS;
1573}
1574
1575DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1576 "handover power budget hysteresis <0-999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001577 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001578 "How many dB does a neighbor to be stronger to become a HO candidate\n"
1579 "Hysteresis\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001580{
Harald Weltedcccb182010-05-16 20:52:23 +02001581 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001582 gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
1583 return CMD_SUCCESS;
1584}
1585
1586DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1587 "handover maximum distance <0-9999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001588 HANDOVER_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001589 "How big is the maximum timing advance before HO is forced\n"
1590 "Distance\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001591{
Harald Weltedcccb182010-05-16 20:52:23 +02001592 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001593 gsmnet->handover.max_distance = atoi(argv[0]);
1594 return CMD_SUCCESS;
1595}
Harald Weltebc814502009-12-19 21:41:52 +01001596
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001597DEFUN(cfg_net_pag_any_tch,
1598 cfg_net_pag_any_tch_cmd,
1599 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001600 "Assign a TCH when receiving a Paging Any request\n"
1601 "Any Channel\n" "Use\n" "TCH\n"
1602 "Do not use TCH for Paging Request Any\n"
1603 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001604{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001605 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001606 gsmnet->pag_any_tch = atoi(argv[0]);
1607 gsm_net_update_ctype(gsmnet);
1608 return CMD_SUCCESS;
1609}
1610
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001611#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1612/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1613#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1614
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001615#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001616 DEFUN(cfg_net_T##number, \
1617 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001618 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001619 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001620 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001621 "Set to default timer value" \
1622 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1623 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001624{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001625 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001626 int value; \
1627 if (strcmp(argv[0], "default") == 0) \
1628 value = DEFAULT_TIMER(number); \
1629 else \
1630 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001631 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001632 gsmnet->T##number = value; \
1633 return CMD_SUCCESS; \
1634}
1635
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001636DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1637DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1638DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1639DECLARE_TIMER(3107, "Currently not used")
1640DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1641DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1642DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1643DECLARE_TIMER(3115, "Currently not used")
1644DECLARE_TIMER(3117, "Currently not used")
1645DECLARE_TIMER(3119, "Currently not used")
1646DECLARE_TIMER(3122, "Waiting time (seconds) after IMM ASS REJECT")
1647DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001648
Maxc08ee712016-05-11 12:45:13 +02001649DEFUN_DEPRECATED(cfg_net_dtx,
1650 cfg_net_dtx_cmd,
1651 "dtx-used (0|1)",
1652 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001653{
Maxc08ee712016-05-11 12:45:13 +02001654 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1655 "configuration options of BTS instead%s", VTY_NEWLINE);
1656 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001657}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001658
Harald Welte5258fc42009-03-28 19:07:53 +00001659/* per-BTS configuration */
1660DEFUN(cfg_bts,
1661 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001662 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001663 "Select a BTS to configure\n"
1664 "BTS Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001665{
Harald Weltedcccb182010-05-16 20:52:23 +02001666 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001667 int bts_nr = atoi(argv[0]);
1668 struct gsm_bts *bts;
1669
Harald Weltee441d9c2009-06-21 16:17:15 +02001670 if (bts_nr > gsmnet->num_bts) {
1671 vty_out(vty, "%% The next unused BTS number is %u%s",
1672 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001673 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001674 } else if (bts_nr == gsmnet->num_bts) {
1675 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001676 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001677 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001678 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001679 bts = gsm_bts_num(gsmnet, bts_nr);
1680
Daniel Willmannf15c2762010-01-11 13:43:07 +01001681 if (!bts) {
1682 vty_out(vty, "%% Unable to allocate BTS %u%s",
1683 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001684 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001685 }
Harald Welte5258fc42009-03-28 19:07:53 +00001686
1687 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001688 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001689 vty->node = BTS_NODE;
1690
1691 return CMD_SUCCESS;
1692}
1693
1694DEFUN(cfg_bts_type,
1695 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001696 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001697 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001698{
1699 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001700 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001701
Max7507aef2017-04-10 13:59:14 +02001702 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001703 if (rc < 0)
1704 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001705
Harald Welte5258fc42009-03-28 19:07:53 +00001706 return CMD_SUCCESS;
1707}
1708
Harald Weltefcd24452009-06-20 18:15:19 +02001709DEFUN(cfg_bts_band,
1710 cfg_bts_band_cmd,
1711 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001712 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001713{
1714 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001715 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001716
1717 if (band < 0) {
1718 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1719 band, VTY_NEWLINE);
1720 return CMD_WARNING;
1721 }
1722
1723 bts->band = band;
1724
1725 return CMD_SUCCESS;
1726}
1727
Maxc08ee712016-05-11 12:45:13 +02001728DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1729 "Configure discontinuous transmission\n"
1730 "Enable Uplink DTX for this BTS\n"
1731 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1732 "older phones).\n")
1733{
1734 struct gsm_bts *bts = vty->index;
1735
1736 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001737 if (!is_ipaccess_bts(bts))
1738 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1739 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001740 return CMD_SUCCESS;
1741}
1742
1743DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1744 NO_STR
1745 "Configure discontinuous transmission\n"
1746 "Disable Uplink DTX for this BTS\n")
1747{
1748 struct gsm_bts *bts = vty->index;
1749
1750 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1751
1752 return CMD_SUCCESS;
1753}
1754
1755DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1756 "Configure discontinuous transmission\n"
1757 "Enable Downlink DTX for this BTS\n")
1758{
1759 struct gsm_bts *bts = vty->index;
1760
1761 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001762 if (!is_ipaccess_bts(bts))
1763 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1764 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001765 return CMD_SUCCESS;
1766}
1767
1768DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1769 NO_STR
1770 "Configure discontinuous transmission\n"
1771 "Disable Downlink DTX for this BTS\n")
1772{
1773 struct gsm_bts *bts = vty->index;
1774
1775 bts->dtxd = false;
1776
1777 return CMD_SUCCESS;
1778}
1779
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001780DEFUN(cfg_bts_ci,
1781 cfg_bts_ci_cmd,
1782 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001783 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001784{
1785 struct gsm_bts *bts = vty->index;
1786 int ci = atoi(argv[0]);
1787
1788 if (ci < 0 || ci > 0xffff) {
1789 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1790 ci, VTY_NEWLINE);
1791 return CMD_WARNING;
1792 }
1793 bts->cell_identity = ci;
1794
1795 return CMD_SUCCESS;
1796}
1797
Harald Welte5258fc42009-03-28 19:07:53 +00001798DEFUN(cfg_bts_lac,
1799 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001800 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001801 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001802{
1803 struct gsm_bts *bts = vty->index;
1804 int lac = atoi(argv[0]);
1805
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001806 if (lac < 0 || lac > 0xffff) {
1807 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001808 lac, VTY_NEWLINE);
1809 return CMD_WARNING;
1810 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001811
1812 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1813 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1814 lac, VTY_NEWLINE);
1815 return CMD_WARNING;
1816 }
1817
Harald Welte5258fc42009-03-28 19:07:53 +00001818 bts->location_area_code = lac;
1819
1820 return CMD_SUCCESS;
1821}
1822
Harald Weltea43f7892009-12-01 18:04:30 +05301823
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001824/* compatibility wrapper for old config files */
1825DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001826 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001827 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001828 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001829{
Harald Welte5258fc42009-03-28 19:07:53 +00001830 return CMD_SUCCESS;
1831}
1832
Harald Welte78f2f502009-05-23 16:56:52 +00001833DEFUN(cfg_bts_bsic,
1834 cfg_bts_bsic_cmd,
1835 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001836 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1837 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001838{
1839 struct gsm_bts *bts = vty->index;
1840 int bsic = atoi(argv[0]);
1841
1842 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001843 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001844 bsic, VTY_NEWLINE);
1845 return CMD_WARNING;
1846 }
1847 bts->bsic = bsic;
1848
1849 return CMD_SUCCESS;
1850}
1851
Harald Welte4cc34222009-05-01 15:12:31 +00001852DEFUN(cfg_bts_unit_id,
1853 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001854 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001855 "Abis/IP specific options\n"
1856 "Set the IPA BTS Unit ID\n"
1857 "Unit ID (Site)\n"
1858 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001859{
1860 struct gsm_bts *bts = vty->index;
1861 int site_id = atoi(argv[0]);
1862 int bts_id = atoi(argv[1]);
1863
Harald Welte07dc73d2009-08-07 13:27:09 +02001864 if (!is_ipaccess_bts(bts)) {
1865 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1866 return CMD_WARNING;
1867 }
1868
Harald Welte4cc34222009-05-01 15:12:31 +00001869 bts->ip_access.site_id = site_id;
1870 bts->ip_access.bts_id = bts_id;
1871
1872 return CMD_SUCCESS;
1873}
1874
Harald Welte8b291802013-03-12 13:57:05 +01001875DEFUN(cfg_bts_rsl_ip,
1876 cfg_bts_rsl_ip_cmd,
1877 "ip.access rsl-ip A.B.C.D",
1878 "Abis/IP specific options\n"
1879 "Set the IPA RSL IP Address of the BSC\n"
1880 "Destination IP address for RSL connection\n")
1881{
1882 struct gsm_bts *bts = vty->index;
1883 struct in_addr ia;
1884
1885 if (!is_ipaccess_bts(bts)) {
1886 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1887 return CMD_WARNING;
1888 }
1889
1890 inet_aton(argv[0], &ia);
1891 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1892
1893 return CMD_SUCCESS;
1894}
1895
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001896#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001897
Sylvain Munautc9519462011-10-17 14:04:55 +02001898DEFUN(cfg_bts_nokia_site_skip_reset,
1899 cfg_bts_nokia_site_skip_reset_cmd,
1900 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001901 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001902 "Skip the reset step during bootstrap process of this BTS\n"
1903 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02001904{
1905 struct gsm_bts *bts = vty->index;
1906
1907 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
1908 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
1909 return CMD_WARNING;
1910 }
1911
1912 bts->nokia.skip_reset = atoi(argv[0]);
1913
1914 return CMD_SUCCESS;
1915}
1916
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001917DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
1918 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
1919 "nokia_site no-local-rel-conf (0|1)",
1920 NOKIA_STR
1921 "Do not wait for RELease CONFirm message when releasing channel locally\n"
1922 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
1923{
1924 struct gsm_bts *bts = vty->index;
1925
1926 if (!is_nokia_bts(bts)) {
1927 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1928 VTY_NEWLINE);
1929 return CMD_WARNING;
1930 }
1931
1932 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
1933
1934 return CMD_SUCCESS;
1935}
1936
Sipos Csaba56e17662015-02-07 13:27:36 +01001937DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
1938 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
1939 "nokia_site bts-reset-timer <15-100>",
1940 NOKIA_STR
1941 "The amount of time (in sec.) between BTS_RESET is sent,\n"
1942 "and the BTS is being bootstrapped.\n")
1943{
1944 struct gsm_bts *bts = vty->index;
1945
1946 if (!is_nokia_bts(bts)) {
1947 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1948 VTY_NEWLINE);
1949 return CMD_WARNING;
1950 }
1951
1952 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
1953
1954 return CMD_SUCCESS;
1955}
Harald Welte8f0ed552010-05-11 21:53:49 +02001956#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001957#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001958
Harald Welte8175e952009-10-20 00:22:00 +02001959DEFUN(cfg_bts_stream_id,
1960 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001961 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02001962 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001963 "Set the ip.access Stream ID of the OML link of this BTS\n"
1964 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02001965{
1966 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001967 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02001968
1969 if (!is_ipaccess_bts(bts)) {
1970 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1971 return CMD_WARNING;
1972 }
1973
1974 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001975 /* This is used by e1inp_bind_ops callback for each BTS model. */
1976 bts->oml_e1_link.e1_nr = linenr;
1977
1978 return CMD_SUCCESS;
1979}
1980
Harald Welted13e0cd2012-08-17 09:52:03 +02001981#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02001982
Harald Welte42581822009-08-08 16:12:58 +02001983DEFUN(cfg_bts_oml_e1,
1984 cfg_bts_oml_e1_cmd,
1985 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02001986 OML_E1_STR
1987 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001988 "E1/T1 line number to be used for OML\n"
1989 "E1/T1 timeslot to be used for OML\n"
1990 "E1/T1 timeslot to be used for OML\n"
1991 "E1/T1 sub-slot to be used for OML\n"
1992 "Use E1/T1 sub-slot 0\n"
1993 "Use E1/T1 sub-slot 1\n"
1994 "Use E1/T1 sub-slot 2\n"
1995 "Use E1/T1 sub-slot 3\n"
1996 "Use full E1 slot 3\n"
1997 )
Harald Welte42581822009-08-08 16:12:58 +02001998{
1999 struct gsm_bts *bts = vty->index;
2000
2001 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2002
2003 return CMD_SUCCESS;
2004}
2005
2006
2007DEFUN(cfg_bts_oml_e1_tei,
2008 cfg_bts_oml_e1_tei_cmd,
2009 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002010 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002011 "Set the TEI to be used for OML\n"
2012 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002013{
2014 struct gsm_bts *bts = vty->index;
2015
2016 bts->oml_tei = atoi(argv[0]);
2017
2018 return CMD_SUCCESS;
2019}
2020
Harald Welte7a8fa412009-08-10 13:48:16 +02002021DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2022 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002023 "Channnel Allocator\n" "Channel Allocator\n"
2024 "Allocate Timeslots and Transceivers in ascending order\n"
2025 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002026{
2027 struct gsm_bts *bts = vty->index;
2028
2029 if (!strcmp(argv[0], "ascending"))
2030 bts->chan_alloc_reverse = 0;
2031 else
2032 bts->chan_alloc_reverse = 1;
2033
2034 return CMD_SUCCESS;
2035}
2036
Harald Welte8f0ed552010-05-11 21:53:49 +02002037#define RACH_STR "Random Access Control Channel\n"
2038
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002039DEFUN(cfg_bts_rach_tx_integer,
2040 cfg_bts_rach_tx_integer_cmd,
2041 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002042 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002043 "Set the raw tx integer value in RACH Control parameters IE\n"
2044 "Set the raw tx integer value in RACH Control parameters IE\n"
2045 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002046{
2047 struct gsm_bts *bts = vty->index;
2048 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2049 return CMD_SUCCESS;
2050}
2051
2052DEFUN(cfg_bts_rach_max_trans,
2053 cfg_bts_rach_max_trans_cmd,
2054 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002055 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002056 "Set the maximum number of RACH burst transmissions\n"
2057 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002058 "Maximum number of 1 RACH burst transmissions\n"
2059 "Maximum number of 2 RACH burst transmissions\n"
2060 "Maximum number of 4 RACH burst transmissions\n"
2061 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002062{
2063 struct gsm_bts *bts = vty->index;
2064 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2065 return CMD_SUCCESS;
2066}
2067
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002068#define CD_STR "Channel Description\n"
2069
2070DEFUN(cfg_bts_chan_desc_att,
2071 cfg_bts_chan_desc_att_cmd,
2072 "channel-descrption attach (0|1)",
2073 CD_STR
2074 "Set if attachment is required\n"
2075 "Attachment is NOT required\n"
2076 "Attachment is required (standard)\n")
2077{
2078 struct gsm_bts *bts = vty->index;
2079 bts->si_common.chan_desc.att = atoi(argv[0]);
2080 return CMD_SUCCESS;
2081}
2082
2083DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2084 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2085 "channel-descrption bs-pa-mfrms <2-9>",
2086 CD_STR
2087 "Set number of multiframe periods for paging groups\n"
2088 "Number of multiframe periods for paging groups\n")
2089{
2090 struct gsm_bts *bts = vty->index;
2091 int bs_pa_mfrms = atoi(argv[0]);
2092
2093 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2094 return CMD_SUCCESS;
2095}
2096
2097DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2098 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2099 "channel-descrption bs-ag-blks-res <0-7>",
2100 CD_STR
2101 "Set number of blocks reserved for access grant\n"
2102 "Number of blocks reserved for access grant\n")
2103{
2104 struct gsm_bts *bts = vty->index;
2105 int bs_ag_blks_res = atoi(argv[0]);
2106
2107 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2108 return CMD_SUCCESS;
2109}
2110
Harald Welte8f0ed552010-05-11 21:53:49 +02002111#define NM_STR "Network Management\n"
2112
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002113DEFUN(cfg_bts_rach_nm_b_thresh,
2114 cfg_bts_rach_nm_b_thresh_cmd,
2115 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002116 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002117 "Set the NM Busy Threshold\n"
2118 "Set the NM Busy Threshold\n"
2119 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002120{
2121 struct gsm_bts *bts = vty->index;
2122 bts->rach_b_thresh = atoi(argv[0]);
2123 return CMD_SUCCESS;
2124}
2125
2126DEFUN(cfg_bts_rach_nm_ldavg,
2127 cfg_bts_rach_nm_ldavg_cmd,
2128 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002129 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002130 "Set the NM Loadaverage Slots value\n"
2131 "Set the NM Loadaverage Slots value\n"
2132 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002133{
2134 struct gsm_bts *bts = vty->index;
2135 bts->rach_ldavg_slots = atoi(argv[0]);
2136 return CMD_SUCCESS;
2137}
2138
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002139DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2140 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002141 "Should this cell be barred from access?\n"
2142 "Should this cell be barred from access?\n"
2143 "Cell should NOT be barred\n"
2144 "Cell should be barred\n")
2145
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002146{
2147 struct gsm_bts *bts = vty->index;
2148
Harald Welte71355012009-12-21 23:08:18 +01002149 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002150
2151 return CMD_SUCCESS;
2152}
2153
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002154DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2155 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002156 RACH_STR
2157 "Should this cell allow emergency calls?\n"
2158 "Should this cell allow emergency calls?\n"
2159 "Should this cell allow emergency calls?\n"
2160 "Do NOT allow emergency calls\n"
2161 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002162{
2163 struct gsm_bts *bts = vty->index;
2164
2165 if (atoi(argv[0]) == 0)
2166 bts->si_common.rach_control.t2 |= 0x4;
2167 else
2168 bts->si_common.rach_control.t2 &= ~0x4;
2169
2170 return CMD_SUCCESS;
2171}
2172
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002173DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2174 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2175 RACH_STR
2176 "Set access control class\n"
2177 "Access control class 0\n"
2178 "Access control class 1\n"
2179 "Access control class 2\n"
2180 "Access control class 3\n"
2181 "Access control class 4\n"
2182 "Access control class 5\n"
2183 "Access control class 6\n"
2184 "Access control class 7\n"
2185 "Access control class 8\n"
2186 "Access control class 9\n"
2187 "Access control class 11 for PLMN use\n"
2188 "Access control class 12 for security services\n"
2189 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2190 "Access control class 14 for emergency services\n"
2191 "Access control class 15 for PLMN staff\n"
2192 "barred to use access control class\n"
2193 "allowed to use access control class\n")
2194{
2195 struct gsm_bts *bts = vty->index;
2196
2197 uint8_t control_class;
2198 uint8_t allowed = 0;
2199
2200 if (strcmp(argv[1], "allowed") == 0)
2201 allowed = 1;
2202
2203 control_class = atoi(argv[0]);
2204 if (control_class < 8)
2205 if (allowed)
2206 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2207 else
2208 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2209 else
2210 if (allowed)
2211 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2212 else
2213 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2214
2215 return CMD_SUCCESS;
2216}
2217
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002218DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2219 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002220 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002221 "Maximum transmit power of the MS\n"
2222 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002223 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002224{
2225 struct gsm_bts *bts = vty->index;
2226
2227 bts->ms_max_power = atoi(argv[0]);
2228
2229 return CMD_SUCCESS;
2230}
2231
Harald Weltecfaabbb2012-08-16 23:23:50 +02002232#define CELL_STR "Cell Parameters\n"
2233
Harald Welte73225282009-12-12 18:17:25 +01002234DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2235 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002236 CELL_STR "Cell re-selection parameters\n"
2237 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002238 "Cell Re-Selection Hysteresis in dB")
2239{
2240 struct gsm_bts *bts = vty->index;
2241
2242 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2243
2244 return CMD_SUCCESS;
2245}
2246
2247DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2248 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002249 "Minimum RxLev needed for cell access\n"
2250 "Minimum RxLev needed for cell access\n"
2251 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002252 "Minimum RxLev needed for cell access (better than -110dBm)")
2253{
2254 struct gsm_bts *bts = vty->index;
2255
2256 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2257
2258 return CMD_SUCCESS;
2259}
2260
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002261DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2262 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002263 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2264 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002265{
2266 struct gsm_bts *bts = vty->index;
2267
2268 bts->si_common.cell_ro_sel_par.present = 1;
2269 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2270
2271 return CMD_SUCCESS;
2272}
2273
2274DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2275 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002276 CELL_STR "Cell Re-Selection Parameters\n"
2277 "Cell Re-Selection Offset (CRO) in dB\n"
2278 "Cell Re-Selection Offset (CRO) in dB\n"
2279 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002280{
2281 struct gsm_bts *bts = vty->index;
2282
2283 bts->si_common.cell_ro_sel_par.present = 1;
2284 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2285
2286 return CMD_SUCCESS;
2287}
2288
2289DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2290 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002291 "Cell selection temporary negative offset\n"
2292 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002293 "Cell selection temporary negative offset in dB")
2294{
2295 struct gsm_bts *bts = vty->index;
2296
2297 bts->si_common.cell_ro_sel_par.present = 1;
2298 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2299
2300 return CMD_SUCCESS;
2301}
2302
2303DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2304 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002305 "Cell selection temporary negative offset\n"
2306 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002307 "Sets cell selection temporary negative offset to infinity")
2308{
2309 struct gsm_bts *bts = vty->index;
2310
2311 bts->si_common.cell_ro_sel_par.present = 1;
2312 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2313
2314 return CMD_SUCCESS;
2315}
2316
2317DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2318 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002319 "Cell selection penalty time\n"
2320 "Cell selection penalty time\n"
2321 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002322{
2323 struct gsm_bts *bts = vty->index;
2324
2325 bts->si_common.cell_ro_sel_par.present = 1;
2326 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2327
2328 return CMD_SUCCESS;
2329}
2330
2331DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2332 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002333 "Cell selection penalty time\n"
2334 "Cell selection penalty time\n"
2335 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002336 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2337 "and TEMPORARY_OFFSET is ignored)")
2338{
2339 struct gsm_bts *bts = vty->index;
2340
2341 bts->si_common.cell_ro_sel_par.present = 1;
2342 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2343
2344 return CMD_SUCCESS;
2345}
2346
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002347DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2348 "radio-link-timeout <4-64>",
2349 "Radio link timeout criterion (BTS side)\n"
2350 "Radio link timeout value (lost SACCH block)\n")
2351{
2352 struct gsm_bts *bts = vty->index;
2353
Harald Welte2f8b9d22017-06-18 11:12:13 +03002354 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2355
2356 return CMD_SUCCESS;
2357}
2358
2359DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2360 "radio-link-timeout infinite",
2361 "Radio link timeout criterion (BTS side)\n"
2362 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2363{
2364 struct gsm_bts *bts = vty->index;
2365
2366 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2367 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2368 return CMD_WARNING;
2369 }
2370
2371 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2372 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002373
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002374 return CMD_SUCCESS;
2375}
2376
Harald Welte8f0ed552010-05-11 21:53:49 +02002377#define GPRS_TEXT "GPRS Packet Network\n"
2378
Harald Welteaf387632010-03-14 23:30:30 +08002379DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002380 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002381 GPRS_TEXT
2382 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002383 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002384 "GPRS BSSGP VC Identifier")
2385{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002386 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002387 struct gsm_bts *bts = vty->index;
2388
Harald Welte4511d892010-04-18 15:51:20 +02002389 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002390 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2391 return CMD_WARNING;
2392 }
2393
Harald Welte97a282b2010-03-14 15:37:43 +08002394 bts->gprs.cell.bvci = atoi(argv[0]);
2395
2396 return CMD_SUCCESS;
2397}
2398
Harald Weltea5731cf2010-03-22 11:48:36 +08002399DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2400 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002401 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002402 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002403 "GPRS NS Entity Identifier")
2404{
2405 struct gsm_bts *bts = vty->index;
2406
Harald Welte4511d892010-04-18 15:51:20 +02002407 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002408 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2409 return CMD_WARNING;
2410 }
2411
2412 bts->gprs.nse.nsei = atoi(argv[0]);
2413
2414 return CMD_SUCCESS;
2415}
2416
Harald Welte8f0ed552010-05-11 21:53:49 +02002417#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2418 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002419
Harald Welte97a282b2010-03-14 15:37:43 +08002420DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2421 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002422 GPRS_TEXT NSVC_TEXT
2423 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002424 "GPRS NS VC Identifier")
2425{
2426 struct gsm_bts *bts = vty->index;
2427 int idx = atoi(argv[0]);
2428
Harald Welte4511d892010-04-18 15:51:20 +02002429 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002430 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2431 return CMD_WARNING;
2432 }
2433
Harald Welte97a282b2010-03-14 15:37:43 +08002434 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2435
2436 return CMD_SUCCESS;
2437}
2438
Harald Welteaf387632010-03-14 23:30:30 +08002439DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2440 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002441 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002442 "GPRS NS Local UDP Port\n"
2443 "GPRS NS Local UDP Port\n"
2444 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002445 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002446{
2447 struct gsm_bts *bts = vty->index;
2448 int idx = atoi(argv[0]);
2449
Harald Welte4511d892010-04-18 15:51:20 +02002450 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002451 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2452 return CMD_WARNING;
2453 }
2454
Harald Welteaf387632010-03-14 23:30:30 +08002455 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2456
2457 return CMD_SUCCESS;
2458}
2459
2460DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2461 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002462 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002463 "GPRS NS Remote UDP Port\n"
2464 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002465 "GPRS NS Remote UDP Port\n"
2466 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002467{
2468 struct gsm_bts *bts = vty->index;
2469 int idx = atoi(argv[0]);
2470
Harald Welte4511d892010-04-18 15:51:20 +02002471 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002472 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2473 return CMD_WARNING;
2474 }
2475
Harald Welteaf387632010-03-14 23:30:30 +08002476 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2477
2478 return CMD_SUCCESS;
2479}
2480
2481DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2482 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002483 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002484 "GPRS NS Remote IP Address\n"
2485 "GPRS NS Remote IP Address\n"
2486 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002487{
2488 struct gsm_bts *bts = vty->index;
2489 int idx = atoi(argv[0]);
2490 struct in_addr ia;
2491
Harald Welte4511d892010-04-18 15:51:20 +02002492 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002493 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2494 return CMD_WARNING;
2495 }
2496
Harald Welteaf387632010-03-14 23:30:30 +08002497 inet_aton(argv[1], &ia);
2498 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2499
2500 return CMD_SUCCESS;
2501}
2502
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002503DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002504 "paging free <-1-1024>",
2505 "Paging options\n"
2506 "Only page when having a certain amount of free slots\n"
2507 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002508{
2509 struct gsm_bts *bts = vty->index;
2510
2511 bts->paging.free_chans_need = atoi(argv[0]);
2512 return CMD_SUCCESS;
2513}
2514
Harald Welte615e9562010-05-11 23:50:21 +02002515DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2516 "gprs ns timer " NS_TIMERS " <0-255>",
2517 GPRS_TEXT "Network Service\n"
2518 "Network Service Timer\n"
2519 NS_TIMERS_HELP "Timer Value\n")
2520{
2521 struct gsm_bts *bts = vty->index;
2522 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2523 int val = atoi(argv[1]);
2524
2525 if (bts->gprs.mode == BTS_GPRS_NONE) {
2526 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2527 return CMD_WARNING;
2528 }
2529
2530 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2531 return CMD_WARNING;
2532
2533 bts->gprs.nse.timer[idx] = val;
2534
2535 return CMD_SUCCESS;
2536}
2537
2538#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 +02002539#define BSSGP_TIMERS_HELP \
2540 "Tbvc-block timeout\n" \
2541 "Tbvc-block retries\n" \
2542 "Tbvc-unblock retries\n" \
2543 "Tbvcc-reset timeout\n" \
2544 "Tbvc-reset retries\n" \
2545 "Tbvc-suspend timeout\n" \
2546 "Tbvc-suspend retries\n" \
2547 "Tbvc-resume timeout\n" \
2548 "Tbvc-resume retries\n" \
2549 "Tbvc-capa-update timeout\n" \
2550 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002551
2552DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2553 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2554 GPRS_TEXT "Cell / BSSGP\n"
2555 "Cell/BSSGP Timer\n"
2556 BSSGP_TIMERS_HELP "Timer Value\n")
2557{
2558 struct gsm_bts *bts = vty->index;
2559 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2560 int val = atoi(argv[1]);
2561
2562 if (bts->gprs.mode == BTS_GPRS_NONE) {
2563 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2564 return CMD_WARNING;
2565 }
2566
2567 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2568 return CMD_WARNING;
2569
2570 bts->gprs.cell.timer[idx] = val;
2571
2572 return CMD_SUCCESS;
2573}
2574
Harald Welte97a282b2010-03-14 15:37:43 +08002575DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2576 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002577 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002578 "GPRS Routing Area Code\n"
2579 "GPRS Routing Area Code\n"
2580 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002581{
2582 struct gsm_bts *bts = vty->index;
2583
Harald Welte4511d892010-04-18 15:51:20 +02002584 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002585 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2586 return CMD_WARNING;
2587 }
2588
Harald Welte97a282b2010-03-14 15:37:43 +08002589 bts->gprs.rac = atoi(argv[0]);
2590
2591 return CMD_SUCCESS;
2592}
2593
Max292ec582016-07-28 11:55:37 +02002594DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2595 "gprs control-ack-type-rach", GPRS_TEXT
2596 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2597 "four access bursts format instead of default RLC/MAC control block\n")
2598{
2599 struct gsm_bts *bts = vty->index;
2600
2601 if (bts->gprs.mode == BTS_GPRS_NONE) {
2602 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2603 return CMD_WARNING;
2604 }
2605
2606 bts->gprs.ctrl_ack_type_use_block = false;
2607
2608 return CMD_SUCCESS;
2609}
2610
2611DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2612 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2613 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2614 "four access bursts format instead of default RLC/MAC control block\n")
2615{
2616 struct gsm_bts *bts = vty->index;
2617
2618 if (bts->gprs.mode == BTS_GPRS_NONE) {
2619 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2620 return CMD_WARNING;
2621 }
2622
2623 bts->gprs.ctrl_ack_type_use_block = true;
2624
2625 return CMD_SUCCESS;
2626}
2627
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002628DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2629 "gprs network-control-order (nc0|nc1|nc2)",
2630 GPRS_TEXT
2631 "GPRS Network Control Order\n"
2632 "MS controlled cell re-selection, no measurement reporting\n"
2633 "MS controlled cell re-selection, MS sends measurement reports\n"
2634 "Network controlled cell re-selection, MS sends measurement reports\n")
2635{
2636 struct gsm_bts *bts = vty->index;
2637
2638 if (bts->gprs.mode == BTS_GPRS_NONE) {
2639 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2640 return CMD_WARNING;
2641 }
2642
2643 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2644
2645 return CMD_SUCCESS;
2646}
2647
Harald Welte4511d892010-04-18 15:51:20 +02002648DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2649 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002650 GPRS_TEXT
2651 "GPRS Mode for this BTS\n"
2652 "GPRS Disabled on this BTS\n"
2653 "GPRS Enabled on this BTS\n"
2654 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002655{
2656 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002657 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002658
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002659 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002660 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2661 VTY_NEWLINE);
2662 return CMD_WARNING;
2663 }
2664
2665 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002666
2667 return CMD_SUCCESS;
2668}
2669
bhargava350533c2016-07-21 11:14:34 +05302670DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2671 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2672 "gprs 11bit_rach_support_for_egprs (0|1)",
2673 GPRS_TEXT "11 bit RACH options\n"
2674 "Disable 11 bit RACH for EGPRS\n"
2675 "Enable 11 bit RACH for EGPRS")
2676{
2677 struct gsm_bts *bts = vty->index;
2678
2679 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2680
2681 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2682 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2683 return CMD_WARNING;
2684 }
2685
2686 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2687 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2688 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2689 " enabled%s", VTY_NEWLINE);
2690 return CMD_WARNING;
2691 }
2692
2693 return CMD_SUCCESS;
2694}
2695
Harald Welte9fbff4a2010-07-30 11:50:09 +02002696#define SI_TEXT "System Information Messages\n"
2697#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)"
2698#define SI_TYPE_HELP "System Information Type 1\n" \
2699 "System Information Type 2\n" \
2700 "System Information Type 3\n" \
2701 "System Information Type 4\n" \
2702 "System Information Type 5\n" \
2703 "System Information Type 6\n" \
2704 "System Information Type 7\n" \
2705 "System Information Type 8\n" \
2706 "System Information Type 9\n" \
2707 "System Information Type 10\n" \
2708 "System Information Type 13\n" \
2709 "System Information Type 16\n" \
2710 "System Information Type 17\n" \
2711 "System Information Type 18\n" \
2712 "System Information Type 19\n" \
2713 "System Information Type 20\n" \
2714 "System Information Type 2bis\n" \
2715 "System Information Type 2ter\n" \
2716 "System Information Type 2quater\n" \
2717 "System Information Type 5bis\n" \
2718 "System Information Type 5ter\n"
2719
2720DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2721 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2722 SI_TEXT SI_TYPE_HELP
2723 "System Information Mode\n"
2724 "Static user-specified\n"
2725 "Dynamic, BSC-computed\n")
2726{
2727 struct gsm_bts *bts = vty->index;
2728 int type;
2729
2730 type = get_string_value(osmo_sitype_strs, argv[0]);
2731 if (type < 0) {
2732 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2733 return CMD_WARNING;
2734 }
2735
2736 if (!strcmp(argv[1], "static"))
2737 bts->si_mode_static |= (1 << type);
2738 else
2739 bts->si_mode_static &= ~(1 << type);
2740
2741 return CMD_SUCCESS;
2742}
2743
2744DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2745 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2746 SI_TEXT SI_TYPE_HELP
2747 "Static System Information filling\n"
2748 "Static user-specified SI content in HEX notation\n")
2749{
2750 struct gsm_bts *bts = vty->index;
2751 int rc, type;
2752
2753 type = get_string_value(osmo_sitype_strs, argv[0]);
2754 if (type < 0) {
2755 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2756 return CMD_WARNING;
2757 }
2758
2759 if (!(bts->si_mode_static & (1 << type))) {
2760 vty_out(vty, "SI Type %s is not configured in static mode%s",
2761 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2762 return CMD_WARNING;
2763 }
2764
Harald Welte290aaed2010-07-30 11:53:18 +02002765 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002766 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002767
2768 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002769 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2770 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002771 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2772 return CMD_WARNING;
2773 }
2774
2775 /* Mark this SI as present */
2776 bts->si_valid |= (1 << type);
2777
2778 return CMD_SUCCESS;
2779}
2780
Harald Welte42def722017-01-13 00:10:32 +01002781DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2782 "early-classmark-sending (allowed|forbidden)",
2783 "Early Classmark Sending\n"
2784 "Early Classmark Sending is allowed\n"
2785 "Early Classmark Sending is forbidden\n")
2786{
2787 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002788
2789 if (!strcmp(argv[0], "allowed"))
2790 bts->early_classmark_allowed = true;
2791 else
2792 bts->early_classmark_allowed = false;
2793
2794 return CMD_SUCCESS;
2795}
2796
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002797DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2798 "early-classmark-sending-3g (allowed|forbidden)",
2799 "3G Early Classmark Sending\n"
2800 "3G Early Classmark Sending is allowed\n"
2801 "3G Early Classmark Sending is forbidden\n")
2802{
2803 struct gsm_bts *bts = vty->index;
2804
2805 if (!strcmp(argv[0], "allowed"))
2806 bts->early_classmark_allowed_3g = true;
2807 else
2808 bts->early_classmark_allowed_3g = false;
2809
2810 return CMD_SUCCESS;
2811}
2812
Harald Welte32c09622011-01-11 23:44:56 +01002813DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002814 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002815 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002816 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2817 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002818{
2819 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002820 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002821
Harald Welte64c07d22011-02-15 11:43:27 +01002822 switch (mode) {
2823 case NL_MODE_MANUAL_SI5SEP:
2824 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002825 /* make sure we clear the current list when switching to
2826 * manual mode */
2827 if (bts->neigh_list_manual_mode == 0)
2828 memset(&bts->si_common.data.neigh_list, 0,
2829 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002830 break;
2831 default:
2832 break;
2833 }
2834
2835 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002836
2837 return CMD_SUCCESS;
2838}
2839
2840DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002841 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002842 "Neighbor List\n" "Add to manual neighbor list\n"
2843 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2844 "ARFCN of neighbor\n")
2845{
2846 struct gsm_bts *bts = vty->index;
2847 struct bitvec *bv = &bts->si_common.neigh_list;
2848 uint16_t arfcn = atoi(argv[1]);
2849
2850 if (!bts->neigh_list_manual_mode) {
2851 vty_out(vty, "%% Cannot configure neighbor list in "
2852 "automatic mode%s", VTY_NEWLINE);
2853 return CMD_WARNING;
2854 }
2855
2856 if (!strcmp(argv[0], "add"))
2857 bitvec_set_bit_pos(bv, arfcn, 1);
2858 else
2859 bitvec_set_bit_pos(bv, arfcn, 0);
2860
2861 return CMD_SUCCESS;
2862}
2863
Max70fdd242017-06-15 15:10:53 +02002864/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002865DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002866 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2867 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2868 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2869 "Add to manual SI2quater neighbor list\n"
2870 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2871 "threshold high bits\n" "threshold high bits\n"
2872 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2873 "priority\n" "priority (8 means NA)\n"
2874 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2875 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002876{
2877 struct gsm_bts *bts = vty->index;
2878 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2879 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002880 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2881 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002882 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002883
Max70fdd242017-06-15 15:10:53 +02002884 switch (r) {
2885 case 1:
2886 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2887 thresh_hi, VTY_NEWLINE);
2888 break;
2889 case EARFCN_THRESH_LOW_INVALID:
2890 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2891 thresh_lo, VTY_NEWLINE);
2892 break;
2893 case EARFCN_QRXLV_INVALID + 1:
2894 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2895 qrx, VTY_NEWLINE);
2896 break;
2897 case EARFCN_PRIO_INVALID:
2898 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
2899 prio, VTY_NEWLINE);
2900 break;
2901 default:
2902 if (r < 0) {
2903 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
2904 return CMD_WARNING;
2905 }
Max59a1bf32016-04-15 16:04:46 +02002906 }
2907
Max70fdd242017-06-15 15:10:53 +02002908 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01002909 return CMD_SUCCESS;
2910
Maxf39d03a2017-05-12 17:00:30 +02002911 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02002912 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02002913 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01002914
Maxaafff962016-04-20 15:57:14 +02002915 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02002916}
2917
2918DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02002919 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02002920 "SI2quater Neighbor List\n"
2921 "SI2quater Neighbor List\n"
2922 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02002923 "EARFCN of neighbor\n"
2924 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02002925{
2926 struct gsm_bts *bts = vty->index;
2927 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02002928 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02002929 int r = osmo_earfcn_del(e, arfcn);
2930 if (r < 0) {
2931 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02002932 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02002933 return CMD_WARNING;
2934 }
2935
2936 return CMD_SUCCESS;
2937}
2938
Max26679e02016-04-20 15:57:13 +02002939DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02002940 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02002941 "SI2quater Neighbor List\n"
2942 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
2943 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
2944 "diversity bit\n")
2945{
2946 struct gsm_bts *bts = vty->index;
2947 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
2948
2949 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
2950 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02002951 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 +01002952 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02002953 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02002954 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
2955 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01002956 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02002957 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02002958 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02002959 return CMD_WARNING;
2960 }
2961
2962 return CMD_SUCCESS;
2963}
2964
2965DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02002966 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02002967 "SI2quater Neighbor List\n"
2968 "SI2quater Neighbor List\n"
2969 "Delete from SI2quater manual neighbor list\n"
2970 "UARFCN of neighbor\n"
2971 "UARFCN\n"
2972 "scrambling code\n")
2973{
2974 struct gsm_bts *bts = vty->index;
2975
2976 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
2977 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
2978 VTY_NEWLINE);
2979 return CMD_WARNING;
2980 }
2981
2982 return CMD_SUCCESS;
2983}
2984
Harald Welte64c07d22011-02-15 11:43:27 +01002985DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002986 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002987 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002988 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
2989 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
2990 "ARFCN of neighbor\n")
2991{
2992 struct gsm_bts *bts = vty->index;
2993 struct bitvec *bv = &bts->si_common.si5_neigh_list;
2994 uint16_t arfcn = atoi(argv[1]);
2995
2996 if (!bts->neigh_list_manual_mode) {
2997 vty_out(vty, "%% Cannot configure neighbor list in "
2998 "automatic mode%s", VTY_NEWLINE);
2999 return CMD_WARNING;
3000 }
3001
3002 if (!strcmp(argv[0], "add"))
3003 bitvec_set_bit_pos(bv, arfcn, 1);
3004 else
3005 bitvec_set_bit_pos(bv, arfcn, 0);
3006
3007 return CMD_SUCCESS;
3008}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003009
Harald Welte8254cf72017-05-29 13:42:19 +02003010DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3011 "pcu-socket PATH",
3012 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3013 "Path in the file system for the unix-domain PCU socket\n")
3014{
3015 struct gsm_bts *bts = vty->index;
3016 int rc;
3017
Harald Welte4a824ca2017-05-29 13:54:27 +02003018 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003019 pcu_sock_exit(bts);
3020 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3021 if (rc < 0) {
3022 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3023 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3024 return CMD_WARNING;
3025 }
3026
3027 return CMD_SUCCESS;
3028}
3029
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003030#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3031
3032DEFUN(cfg_bts_excl_rf_lock,
3033 cfg_bts_excl_rf_lock_cmd,
3034 "rf-lock-exclude",
3035 EXCL_RFLOCK_STR)
3036{
3037 struct gsm_bts *bts = vty->index;
3038 bts->excl_from_rf_lock = 1;
3039 return CMD_SUCCESS;
3040}
3041
3042DEFUN(cfg_bts_no_excl_rf_lock,
3043 cfg_bts_no_excl_rf_lock_cmd,
3044 "no rf-lock-exclude",
3045 NO_STR EXCL_RFLOCK_STR)
3046{
3047 struct gsm_bts *bts = vty->index;
3048 bts->excl_from_rf_lock = 0;
3049 return CMD_SUCCESS;
3050}
3051
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003052#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3053
3054DEFUN(cfg_bts_force_comb_si,
3055 cfg_bts_force_comb_si_cmd,
3056 "force-combined-si",
3057 FORCE_COMB_SI_STR)
3058{
3059 struct gsm_bts *bts = vty->index;
3060 bts->force_combined_si = 1;
3061 return CMD_SUCCESS;
3062}
3063
3064DEFUN(cfg_bts_no_force_comb_si,
3065 cfg_bts_no_force_comb_si_cmd,
3066 "no force-combined-si",
3067 NO_STR FORCE_COMB_SI_STR)
3068{
3069 struct gsm_bts *bts = vty->index;
3070 bts->force_combined_si = 0;
3071 return CMD_SUCCESS;
3072}
3073
Andreas Eversberga83d5112013-12-07 18:32:28 +01003074static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3075{
3076 struct gsm_bts *bts = vty->index;
3077 struct bts_codec_conf *codec = &bts->codec;
3078 int i;
3079
3080 codec->hr = 0;
3081 codec->efr = 0;
3082 codec->amr = 0;
3083 for (i = 0; i < argc; i++) {
3084 if (!strcmp(argv[i], "hr"))
3085 codec->hr = 1;
3086 if (!strcmp(argv[i], "efr"))
3087 codec->efr = 1;
3088 if (!strcmp(argv[i], "amr"))
3089 codec->amr = 1;
3090 }
3091}
3092
3093#define CODEC_PAR_STR " (hr|efr|amr)"
3094#define CODEC_HELP_STR "Half Rate\n" \
3095 "Enhanced Full Rate\nAdaptive Multirate\n"
3096
3097DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3098 "codec-support fr",
3099 "Codec Support settings\nFullrate\n")
3100{
3101 _get_codec_from_arg(vty, 0, argv);
3102 return CMD_SUCCESS;
3103}
3104
3105DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3106 "codec-support fr" CODEC_PAR_STR,
3107 "Codec Support settings\nFullrate\n"
3108 CODEC_HELP_STR)
3109{
3110 _get_codec_from_arg(vty, 1, argv);
3111 return CMD_SUCCESS;
3112}
3113
3114DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3115 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3116 "Codec Support settings\nFullrate\n"
3117 CODEC_HELP_STR CODEC_HELP_STR)
3118{
3119 _get_codec_from_arg(vty, 2, argv);
3120 return CMD_SUCCESS;
3121}
3122
3123DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3124 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3125 "Codec Support settings\nFullrate\n"
3126 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3127{
3128 _get_codec_from_arg(vty, 3, argv);
3129 return CMD_SUCCESS;
3130}
3131
3132DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3133 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3134 "Codec Support settings\nFullrate\n"
3135 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3136{
3137 _get_codec_from_arg(vty, 4, argv);
3138 return CMD_SUCCESS;
3139}
3140
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003141DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3142 "depends-on-bts <0-255>",
3143 "This BTS can only be started if another one is up\n" "BTS Number\n")
3144{
3145 struct gsm_bts *bts = vty->index;
3146 struct gsm_bts *other_bts;
3147 int dep = atoi(argv[0]);
3148
3149
3150 if (!is_ipaccess_bts(bts)) {
3151 vty_out(vty, "This feature is only available for IP systems.%s",
3152 VTY_NEWLINE);
3153 return CMD_WARNING;
3154 }
3155
3156 other_bts = gsm_bts_num(bts->network, dep);
3157 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3158 vty_out(vty, "This feature is only available for IP systems.%s",
3159 VTY_NEWLINE);
3160 return CMD_WARNING;
3161 }
3162
3163 if (dep >= bts->nr) {
3164 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3165 VTY_NEWLINE);
3166 return CMD_WARNING;
3167 }
3168
3169 bts_depend_mark(bts, dep);
3170 return CMD_SUCCESS;
3171}
3172
3173DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3174 "depeneds-on-bts <0-255>",
3175 NO_STR "This BTS can only be started if another one is up\n"
3176 "BTS Number\n")
3177{
3178 struct gsm_bts *bts = vty->index;
3179 int dep = atoi(argv[0]);
3180
3181 bts_depend_clear(bts, dep);
3182 return CMD_SUCCESS;
3183}
3184
Andreas Eversberg73266522014-01-19 11:47:44 +01003185#define AMR_TEXT "Adaptive Multi Rate settings\n"
3186#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3187#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3188 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3189#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3190#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3191
3192static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3193{
3194 struct gsm_bts *bts = vty->index;
3195 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3196 struct gsm48_multi_rate_conf *mr_conf =
3197 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3198 int i;
3199
3200 mr->gsm48_ie[1] = 0;
3201 for (i = 0; i < argc; i++)
3202 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3203 mr_conf->icmi = 0;
3204}
3205
3206static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3207{
3208 struct gsm_bts *bts = vty->index;
3209 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003210 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003211 int i;
3212
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003213 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3214 for (i = 0; i < argc - 1; i++)
3215 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003216}
3217
3218static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3219{
3220 struct gsm_bts *bts = vty->index;
3221 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003222 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003223 int i;
3224
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003225 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3226 for (i = 0; i < argc - 1; i++)
3227 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003228}
3229
3230static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3231{
3232 struct gsm_bts *bts = vty->index;
3233 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3234 struct gsm48_multi_rate_conf *mr_conf =
3235 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3236 int num = 0, i;
3237
3238 for (i = 0; i < ((full) ? 8 : 6); i++) {
3239 if ((mr->gsm48_ie[1] & (1 << i))) {
3240 num++;
3241 }
3242 }
3243
3244 if (argv[0][0] == 'a' || num == 0)
3245 mr_conf->icmi = 0;
3246 else {
3247 mr_conf->icmi = 1;
3248 if (num < atoi(argv[0]))
3249 mr_conf->smod = num - 1;
3250 else
3251 mr_conf->smod = atoi(argv[0]) - 1;
3252 }
3253}
3254
3255#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3256#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3257 "10,2k\n12,2k\n"
3258
3259#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3260#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3261
3262#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3263#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3264
3265DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3266 "amr tch-f modes" AMR_TCHF_PAR_STR,
3267 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3268 AMR_TCHF_HELP_STR)
3269{
3270 get_amr_from_arg(vty, 1, argv, 1);
3271 return CMD_SUCCESS;
3272}
3273
3274DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3275 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3276 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3277 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3278{
3279 get_amr_from_arg(vty, 2, argv, 1);
3280 return CMD_SUCCESS;
3281}
3282
3283DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3284 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3285 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3286 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3287{
3288 get_amr_from_arg(vty, 3, argv, 1);
3289 return CMD_SUCCESS;
3290}
3291
3292DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3293 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3294 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3295 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3296{
3297 get_amr_from_arg(vty, 4, argv, 1);
3298 return CMD_SUCCESS;
3299}
3300
3301DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3302 "amr tch-f start-mode (auto|1|2|3|4)",
3303 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3304{
3305 get_amr_start_from_arg(vty, argv, 1);
3306 return CMD_SUCCESS;
3307}
3308
3309DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3310 "amr tch-f threshold (ms|bts) <0-63>",
3311 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3312 AMR_TH_HELP_STR)
3313{
3314 get_amr_th_from_arg(vty, 2, argv, 1);
3315 return CMD_SUCCESS;
3316}
3317
3318DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3319 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3320 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3321 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3322{
3323 get_amr_th_from_arg(vty, 3, argv, 1);
3324 return CMD_SUCCESS;
3325}
3326
3327DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3328 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3329 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3330 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3331{
3332 get_amr_th_from_arg(vty, 4, argv, 1);
3333 return CMD_SUCCESS;
3334}
3335
3336DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3337 "amr tch-f hysteresis (ms|bts) <0-15>",
3338 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3339 AMR_HY_HELP_STR)
3340{
3341 get_amr_hy_from_arg(vty, 2, argv, 1);
3342 return CMD_SUCCESS;
3343}
3344
3345DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3346 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3347 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3348 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3349{
3350 get_amr_hy_from_arg(vty, 3, argv, 1);
3351 return CMD_SUCCESS;
3352}
3353
3354DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3355 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3356 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3357 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3358{
3359 get_amr_hy_from_arg(vty, 4, argv, 1);
3360 return CMD_SUCCESS;
3361}
3362
3363DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3364 "amr tch-h modes" AMR_TCHH_PAR_STR,
3365 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3366 AMR_TCHH_HELP_STR)
3367{
3368 get_amr_from_arg(vty, 1, argv, 0);
3369 return CMD_SUCCESS;
3370}
3371
3372DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3373 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3374 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3375 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3376{
3377 get_amr_from_arg(vty, 2, argv, 0);
3378 return CMD_SUCCESS;
3379}
3380
3381DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3382 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3383 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3384 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3385{
3386 get_amr_from_arg(vty, 3, argv, 0);
3387 return CMD_SUCCESS;
3388}
3389
3390DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3391 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3392 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3393 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3394{
3395 get_amr_from_arg(vty, 4, argv, 0);
3396 return CMD_SUCCESS;
3397}
3398
3399DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3400 "amr tch-h start-mode (auto|1|2|3|4)",
3401 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3402{
3403 get_amr_start_from_arg(vty, argv, 0);
3404 return CMD_SUCCESS;
3405}
3406
3407DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3408 "amr tch-h threshold (ms|bts) <0-63>",
3409 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3410 AMR_TH_HELP_STR)
3411{
3412 get_amr_th_from_arg(vty, 2, argv, 0);
3413 return CMD_SUCCESS;
3414}
3415
3416DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3417 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3418 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3419 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3420{
3421 get_amr_th_from_arg(vty, 3, argv, 0);
3422 return CMD_SUCCESS;
3423}
3424
3425DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3426 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3427 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3428 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3429{
3430 get_amr_th_from_arg(vty, 4, argv, 0);
3431 return CMD_SUCCESS;
3432}
3433
3434DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3435 "amr tch-h hysteresis (ms|bts) <0-15>",
3436 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3437 AMR_HY_HELP_STR)
3438{
3439 get_amr_hy_from_arg(vty, 2, argv, 0);
3440 return CMD_SUCCESS;
3441}
3442
3443DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3444 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3445 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3446 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3447{
3448 get_amr_hy_from_arg(vty, 3, argv, 0);
3449 return CMD_SUCCESS;
3450}
3451
3452DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3453 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3454 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3455 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3456{
3457 get_amr_hy_from_arg(vty, 4, argv, 0);
3458 return CMD_SUCCESS;
3459}
3460
Harald Welte8f0ed552010-05-11 21:53:49 +02003461#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003462
Harald Welte5258fc42009-03-28 19:07:53 +00003463/* per TRX configuration */
3464DEFUN(cfg_trx,
3465 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003466 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003467 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003468 "Select a TRX to configure")
3469{
3470 int trx_nr = atoi(argv[0]);
3471 struct gsm_bts *bts = vty->index;
3472 struct gsm_bts_trx *trx;
3473
Harald Weltee441d9c2009-06-21 16:17:15 +02003474 if (trx_nr > bts->num_trx) {
3475 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3476 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003477 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003478 } else if (trx_nr == bts->num_trx) {
3479 /* we need to allocate a new one */
3480 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003481 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003482 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003483
Harald Weltee441d9c2009-06-21 16:17:15 +02003484 if (!trx)
3485 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003486
3487 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003488 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003489 vty->node = TRX_NODE;
3490
3491 return CMD_SUCCESS;
3492}
3493
3494DEFUN(cfg_trx_arfcn,
3495 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003496 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003497 "Set the ARFCN for this TRX\n"
3498 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003499{
3500 int arfcn = atoi(argv[0]);
3501 struct gsm_bts_trx *trx = vty->index;
3502
3503 /* FIXME: check if this ARFCN is supported by this TRX */
3504
3505 trx->arfcn = arfcn;
3506
3507 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3508 /* FIXME: use OML layer to update the ARFCN */
3509 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3510
3511 return CMD_SUCCESS;
3512}
3513
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003514DEFUN(cfg_trx_nominal_power,
3515 cfg_trx_nominal_power_cmd,
3516 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003517 "Nominal TRX RF Power in dBm\n"
3518 "Nominal TRX RF Power in dBm\n"
3519 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003520{
3521 struct gsm_bts_trx *trx = vty->index;
3522
3523 trx->nominal_power = atoi(argv[0]);
3524
3525 return CMD_SUCCESS;
3526}
3527
Harald Weltefcd24452009-06-20 18:15:19 +02003528DEFUN(cfg_trx_max_power_red,
3529 cfg_trx_max_power_red_cmd,
3530 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003531 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003532 "Reduction of maximum BS RF Power in dB\n")
3533{
3534 int maxpwr_r = atoi(argv[0]);
3535 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003536 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003537
3538 /* FIXME: check if our BTS type supports more than 12 */
3539 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3540 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3541 maxpwr_r, VTY_NEWLINE);
3542 return CMD_WARNING;
3543 }
3544 if (maxpwr_r & 1) {
3545 vty_out(vty, "%% Power %d dB is not an even value%s",
3546 maxpwr_r, VTY_NEWLINE);
3547 return CMD_WARNING;
3548 }
3549
3550 trx->max_power_red = maxpwr_r;
3551
3552 /* FIXME: make sure we update this using OML */
3553
3554 return CMD_SUCCESS;
3555}
3556
Harald Welte42581822009-08-08 16:12:58 +02003557DEFUN(cfg_trx_rsl_e1,
3558 cfg_trx_rsl_e1_cmd,
3559 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003560 "RSL Parameters\n"
3561 "E1/T1 interface to be used for RSL\n"
3562 "E1/T1 interface to be used for RSL\n"
3563 "E1/T1 Line Number to be used for RSL\n"
3564 "E1/T1 Timeslot to be used for RSL\n"
3565 "E1/T1 Timeslot to be used for RSL\n"
3566 "E1/T1 Sub-slot to be used for RSL\n"
3567 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3568 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3569 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3570 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3571 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003572{
3573 struct gsm_bts_trx *trx = vty->index;
3574
3575 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3576
3577 return CMD_SUCCESS;
3578}
3579
3580DEFUN(cfg_trx_rsl_e1_tei,
3581 cfg_trx_rsl_e1_tei_cmd,
3582 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003583 "RSL Parameters\n"
3584 "Set the TEI to be used for RSL\n"
3585 "Set the TEI to be used for RSL\n"
3586 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003587{
3588 struct gsm_bts_trx *trx = vty->index;
3589
3590 trx->rsl_tei = atoi(argv[0]);
3591
3592 return CMD_SUCCESS;
3593}
3594
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003595DEFUN(cfg_trx_rf_locked,
3596 cfg_trx_rf_locked_cmd,
3597 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003598 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3599 "TRX is NOT RF locked (active)\n"
3600 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003601{
3602 int locked = atoi(argv[0]);
3603 struct gsm_bts_trx *trx = vty->index;
3604
Maxbe356ed2017-09-07 19:10:09 +02003605 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003606 return CMD_SUCCESS;
3607}
Harald Welte42581822009-08-08 16:12:58 +02003608
Harald Welte5258fc42009-03-28 19:07:53 +00003609/* per TS configuration */
3610DEFUN(cfg_ts,
3611 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003612 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003613 "Select a Timeslot to configure\n"
3614 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003615{
3616 int ts_nr = atoi(argv[0]);
3617 struct gsm_bts_trx *trx = vty->index;
3618 struct gsm_bts_trx_ts *ts;
3619
3620 if (ts_nr >= TRX_NR_TS) {
3621 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3622 TRX_NR_TS, VTY_NEWLINE);
3623 return CMD_WARNING;
3624 }
3625
3626 ts = &trx->ts[ts_nr];
3627
3628 vty->index = ts;
3629 vty->node = TS_NODE;
3630
3631 return CMD_SUCCESS;
3632}
3633
Harald Weltea6fd58e2009-08-07 00:25:23 +02003634DEFUN(cfg_ts_pchan,
3635 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003636 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003637 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003638{
3639 struct gsm_bts_trx_ts *ts = vty->index;
3640 int pchanc;
3641
3642 pchanc = gsm_pchan_parse(argv[0]);
3643 if (pchanc < 0)
3644 return CMD_WARNING;
3645
3646 ts->pchan = pchanc;
3647
3648 return CMD_SUCCESS;
3649}
3650
3651/* used for backwards compatibility with old config files that still
3652 * have uppercase pchan type names */
3653DEFUN_HIDDEN(cfg_ts_pchan_compat,
3654 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003655 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003656 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003657{
3658 struct gsm_bts_trx_ts *ts = vty->index;
3659 int pchanc;
3660
3661 pchanc = gsm_pchan_parse(argv[0]);
3662 if (pchanc < 0)
3663 return CMD_WARNING;
3664
3665 ts->pchan = pchanc;
3666
3667 return CMD_SUCCESS;
3668}
3669
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003670
3671
Harald Welte135a6482011-05-30 12:09:13 +02003672DEFUN(cfg_ts_tsc,
3673 cfg_ts_tsc_cmd,
3674 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003675 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003676{
3677 struct gsm_bts_trx_ts *ts = vty->index;
3678
Max71d082b2017-05-30 15:03:38 +02003679 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003680 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3681 "falling back to BCC%s", VTY_NEWLINE);
3682 ts->tsc = -1;
3683 return CMD_WARNING;
3684 }
3685
Harald Welte135a6482011-05-30 12:09:13 +02003686 ts->tsc = atoi(argv[0]);
3687
3688 return CMD_SUCCESS;
3689}
3690
Harald Weltea39b0f22010-06-14 22:26:10 +02003691#define HOPPING_STR "Configure frequency hopping\n"
3692
3693DEFUN(cfg_ts_hopping,
3694 cfg_ts_hopping_cmd,
3695 "hopping enabled (0|1)",
3696 HOPPING_STR "Enable or disable frequency hopping\n"
3697 "Disable frequency hopping\n" "Enable frequency hopping\n")
3698{
3699 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003700 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003701
Max71d082b2017-05-30 15:03:38 +02003702 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003703 vty_out(vty, "BTS model does not support hopping%s",
3704 VTY_NEWLINE);
3705 return CMD_WARNING;
3706 }
3707
3708 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003709
3710 return CMD_SUCCESS;
3711}
3712
Harald Welte6e0cd042009-09-12 13:05:33 +02003713DEFUN(cfg_ts_hsn,
3714 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003715 "hopping sequence-number <0-63>",
3716 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003717 "Which hopping sequence to use for this channel\n"
3718 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003719{
3720 struct gsm_bts_trx_ts *ts = vty->index;
3721
3722 ts->hopping.hsn = atoi(argv[0]);
3723
3724 return CMD_SUCCESS;
3725}
3726
3727DEFUN(cfg_ts_maio,
3728 cfg_ts_maio_cmd,
3729 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003730 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003731 "Which hopping MAIO to use for this channel\n"
3732 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003733{
3734 struct gsm_bts_trx_ts *ts = vty->index;
3735
3736 ts->hopping.maio = atoi(argv[0]);
3737
3738 return CMD_SUCCESS;
3739}
3740
3741DEFUN(cfg_ts_arfcn_add,
3742 cfg_ts_arfcn_add_cmd,
3743 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003744 HOPPING_STR "Configure hopping ARFCN list\n"
3745 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003746{
3747 struct gsm_bts_trx_ts *ts = vty->index;
3748 int arfcn = atoi(argv[0]);
3749
Harald Weltea39b0f22010-06-14 22:26:10 +02003750 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3751
Harald Welte6e0cd042009-09-12 13:05:33 +02003752 return CMD_SUCCESS;
3753}
3754
3755DEFUN(cfg_ts_arfcn_del,
3756 cfg_ts_arfcn_del_cmd,
3757 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003758 HOPPING_STR "Configure hopping ARFCN list\n"
3759 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003760{
3761 struct gsm_bts_trx_ts *ts = vty->index;
3762 int arfcn = atoi(argv[0]);
3763
Harald Weltea39b0f22010-06-14 22:26:10 +02003764 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3765
Harald Welte6e0cd042009-09-12 13:05:33 +02003766 return CMD_SUCCESS;
3767}
3768
Harald Weltea6fd58e2009-08-07 00:25:23 +02003769DEFUN(cfg_ts_e1_subslot,
3770 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003771 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003772 "E1/T1 channel connected to this on-air timeslot\n"
3773 "E1/T1 channel connected to this on-air timeslot\n"
3774 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003775 "E1/T1 timeslot connected to this on-air timeslot\n"
3776 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003777 "E1/T1 sub-slot connected to this on-air timeslot\n"
3778 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3779 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3780 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3781 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3782 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003783{
3784 struct gsm_bts_trx_ts *ts = vty->index;
3785
Harald Welte42581822009-08-08 16:12:58 +02003786 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003787
3788 return CMD_SUCCESS;
3789}
Harald Welte5258fc42009-03-28 19:07:53 +00003790
Harald Welte4f10c252010-05-16 21:47:13 +02003791void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3792{
Harald Weltecf9d4312017-12-13 23:17:16 +01003793 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003794 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003795 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003796 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003797}
3798
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003799DEFUN(drop_bts,
3800 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003801 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003802 "Debug/Simulation command to drop Abis/IP BTS\n"
3803 "Debug/Simulation command to drop Abis/IP BTS\n"
3804 "Debug/Simulation command to drop Abis/IP BTS\n"
3805 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003806{
3807 struct gsm_network *gsmnet;
3808 struct gsm_bts_trx *trx;
3809 struct gsm_bts *bts;
3810 unsigned int bts_nr;
3811
3812 gsmnet = gsmnet_from_vty(vty);
3813
3814 bts_nr = atoi(argv[0]);
3815 if (bts_nr >= gsmnet->num_bts) {
3816 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3817 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3818 return CMD_WARNING;
3819 }
3820
3821 bts = gsm_bts_num(gsmnet, bts_nr);
3822 if (!bts) {
3823 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3824 return CMD_WARNING;
3825 }
3826
3827 if (!is_ipaccess_bts(bts)) {
3828 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3829 return CMD_WARNING;
3830 }
3831
3832
3833 /* close all connections */
3834 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003835 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003836 } else if (strcmp(argv[1], "rsl") == 0) {
3837 /* close all rsl connections */
3838 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003839 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003840 }
3841 } else {
3842 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3843 return CMD_WARNING;
3844 }
3845
3846 return CMD_SUCCESS;
3847}
3848
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003849DEFUN(restart_bts, restart_bts_cmd,
3850 "restart-bts <0-65535>",
3851 "Restart ip.access nanoBTS through OML\n"
3852 "BTS Number\n")
3853{
3854 struct gsm_network *gsmnet;
3855 struct gsm_bts_trx *trx;
3856 struct gsm_bts *bts;
3857 unsigned int bts_nr;
3858
3859 gsmnet = gsmnet_from_vty(vty);
3860
3861 bts_nr = atoi(argv[0]);
3862 if (bts_nr >= gsmnet->num_bts) {
3863 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3864 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3865 return CMD_WARNING;
3866 }
3867
3868 bts = gsm_bts_num(gsmnet, bts_nr);
3869 if (!bts) {
3870 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3871 return CMD_WARNING;
3872 }
3873
3874 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3875 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3876 VTY_NEWLINE);
3877 return CMD_WARNING;
3878 }
3879
3880 /* go from last TRX to c0 */
3881 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3882 abis_nm_ipaccess_restart(trx);
3883
3884 return CMD_SUCCESS;
3885}
3886
Harald Welte8e2e22f2017-07-10 20:25:10 +02003887DEFUN(bts_resend, bts_resend_cmd,
3888 "bts <0-255> resend-system-information",
3889 "BTS Specific Commands\n" "BTS Number\n"
3890 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3891{
3892 struct gsm_network *gsmnet;
3893 struct gsm_bts_trx *trx;
3894 struct gsm_bts *bts;
3895 unsigned int bts_nr;
3896
3897 gsmnet = gsmnet_from_vty(vty);
3898
3899 bts_nr = atoi(argv[0]);
3900 if (bts_nr >= gsmnet->num_bts) {
3901 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3902 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3903 return CMD_WARNING;
3904 }
3905
3906 bts = gsm_bts_num(gsmnet, bts_nr);
3907 if (!bts) {
3908 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3909 return CMD_WARNING;
3910 }
3911
3912 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3913 gsm_bts_trx_set_system_infos(trx);
3914
3915 return CMD_SUCCESS;
3916}
3917
3918
Harald Welte30f1f372014-12-28 15:00:45 +01003919DEFUN(smscb_cmd, smscb_cmd_cmd,
3920 "bts <0-255> smscb-command <1-4> HEXSTRING",
3921 "BTS related commands\n" "BTS Number\n"
3922 "SMS Cell Broadcast\n" "Last Valid Block\n"
3923 "Hex Encoded SMSCB message (up to 88 octets)\n")
3924{
3925 struct gsm_bts *bts;
3926 int bts_nr = atoi(argv[0]);
3927 int last_block = atoi(argv[1]);
3928 struct rsl_ie_cb_cmd_type cb_cmd;
3929 uint8_t buf[88];
3930 int rc;
3931
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02003932 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01003933 if (!bts) {
3934 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3935 return CMD_WARNING;
3936 }
3937 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
3938 if (rc < 0 || rc > sizeof(buf)) {
3939 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3940 return CMD_WARNING;
3941 }
3942
3943 cb_cmd.spare = 0;
3944 cb_cmd.def_bcast = 0;
3945 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
3946
3947 switch (last_block) {
3948 case 1:
3949 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
3950 break;
3951 case 2:
3952 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
3953 break;
3954 case 3:
3955 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
3956 break;
3957 case 4:
3958 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
3959 break;
3960 }
3961
3962 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
3963
3964 return CMD_SUCCESS;
3965}
3966
Harald Welte7fe00fb2017-05-27 14:09:50 +02003967/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02003968static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
3969 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02003970{
Harald Welte645eb622017-05-27 15:52:58 +02003971 int bts_nr = atoi(bts_str);
3972 int trx_nr = atoi(trx_str);
3973 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003974 struct gsm_bts *bts;
3975 struct gsm_bts_trx *trx;
3976 struct gsm_bts_trx_ts *ts;
3977
3978 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
3979 if (!bts) {
3980 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3981 return NULL;
3982 }
3983
3984 trx = gsm_bts_trx_num(bts, trx_nr);
3985 if (!trx) {
3986 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
3987 return NULL;
3988 }
3989
3990 ts = &trx->ts[ts_nr];
3991
3992 return ts;
3993}
Harald Welte30f1f372014-12-28 15:00:45 +01003994
Harald Welted0d2b0b2010-12-23 13:18:07 +01003995DEFUN(pdch_act, pdch_act_cmd,
3996 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
3997 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
3998 "TRX Timeslot\n" "Timeslot Number\n" "Packet Data Channel\n"
3999 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4000 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4001{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004002 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004003 int activate;
4004
Harald Welte645eb622017-05-27 15:52:58 +02004005 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004006 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004007 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004008
Harald Welte7fe00fb2017-05-27 14:09:50 +02004009 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004010 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4011 VTY_NEWLINE);
4012 return CMD_WARNING;
4013 }
4014
Harald Welted0d2b0b2010-12-23 13:18:07 +01004015 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4016 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004017 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004018 return CMD_WARNING;
4019 }
4020
4021 if (!strcmp(argv[3], "activate"))
4022 activate = 1;
4023 else
4024 activate = 0;
4025
4026 rsl_ipacc_pdch_activate(ts, activate);
4027
4028 return CMD_SUCCESS;
4029
4030}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004031
Harald Welte2abd5e12017-05-27 14:10:40 +02004032/* determine the logical channel type based on the physical channel type */
4033static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4034{
4035 switch (pchan) {
4036 case GSM_PCHAN_TCH_F:
4037 return GSM_LCHAN_TCH_F;
4038 case GSM_PCHAN_TCH_H:
4039 return GSM_LCHAN_TCH_H;
4040 case GSM_PCHAN_SDCCH8_SACCH8C:
4041 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4042 case GSM_PCHAN_CCCH_SDCCH4:
4043 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4044 return GSM_LCHAN_SDCCH;
4045 default:
4046 return -1;
4047 }
4048}
4049
4050/* configure the lchan for a single AMR mode (as specified) */
4051static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4052{
4053 struct amr_multirate_conf mr;
4054 struct gsm48_multi_rate_conf *mr_conf;
4055 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4056
4057 if (amr_mode > 7)
4058 return -1;
4059
4060 memset(&mr, 0, sizeof(mr));
4061 mr_conf->ver = 1;
4062 /* bit-mask of supported modes, only one bit is set. Reflects
4063 * Figure 10.5.2.47a where there are no thershold and only a
4064 * single mode */
4065 mr.gsm48_ie[1] = 1 << amr_mode;
4066
4067 mr.ms_mode[0].mode = amr_mode;
4068 mr.bts_mode[0].mode = amr_mode;
4069
4070 /* encode this configuration into the lchan for both uplink and
4071 * downlink direction */
4072 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4073 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4074
4075 return 0;
4076}
4077
4078/* Debug/Measurement command to activate a given logical channel
4079 * manually in a given mode/codec. This is useful for receiver
4080 * performance testing (FER/RBER/...) */
4081DEFUN(lchan_act, lchan_act_cmd,
4082 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
4083 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4084 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot Number\n" "Sub-Slot Number\n"
4085 "Manual Channel Activation (e.g. for BER test)\n"
4086 "Manual Channel Deactivation (e.g. for BER test)\n"
4087 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4088{
4089 struct gsm_bts_trx_ts *ts;
4090 struct gsm_lchan *lchan;
4091 int ss_nr = atoi(argv[3]);
4092 const char *act_str = argv[4];
4093 const char *codec_str = argv[5];
4094 int activate;
4095
4096 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4097 if (!ts)
4098 return CMD_WARNING;
4099
4100 lchan = &ts->lchan[ss_nr];
4101
4102 if (!strcmp(act_str, "activate"))
4103 activate = 1;
4104 else
4105 activate = 0;
4106
4107 if (ss_nr >= ts_subslots(ts)) {
4108 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4109 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4110 return CMD_WARNING;
4111 }
4112
4113 if (activate) {
4114 int lchan_t;
4115 if (lchan->state != LCHAN_S_NONE) {
4116 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4117 return CMD_WARNING;
4118 }
4119 lchan_t = lchan_type_by_pchan(ts->pchan);
4120 if (lchan_t < 0)
4121 return CMD_WARNING;
4122 /* configure the lchan */
4123 lchan->type = lchan_t;
4124 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4125 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4126 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4127 else if (!strcmp(codec_str, "efr"))
4128 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4129 else if (!strcmp(codec_str, "amr")) {
4130 int amr_mode;
4131 if (argc < 7) {
4132 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4133 return CMD_WARNING;
4134 }
4135 amr_mode = atoi(argv[6]);
4136 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4137 lchan_set_single_amr_mode(lchan, amr_mode);
4138 }
4139 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4140 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4141 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004142 } else {
4143 rsl_direct_rf_release(lchan);
4144 }
4145
4146 return CMD_SUCCESS;
4147}
4148
Harald Welte3f86c522017-05-27 15:53:28 +02004149DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4150 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
4151 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4152 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot\n" "Sub-Slot Number\n"
4153 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4154{
4155 struct gsm_bts_trx_ts *ts;
4156 struct gsm_lchan *lchan;
4157 int ss_nr = atoi(argv[3]);
4158 int port = atoi(argv[5]);
4159 struct in_addr ia;
4160 inet_aton(argv[4], &ia);
4161
4162 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4163 if (!ts)
4164 return CMD_WARNING;
4165
4166 lchan = &ts->lchan[ss_nr];
4167
4168 if (ss_nr >= ts_subslots(ts)) {
4169 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4170 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4171 return CMD_WARNING;
4172 }
4173
4174 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4175 inet_ntoa(ia), port, VTY_NEWLINE);
4176 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4177 return CMD_SUCCESS;
4178}
Harald Welteb71147a2017-07-18 19:11:49 +02004179
4180DEFUN(ctrl_trap, ctrl_trap_cmd,
4181 "ctrl-interface generate-trap TRAP VALUE",
4182 "Commands related to the CTRL Interface\n"
4183 "Generate a TRAP for test purpose\n"
4184 "Identity/Name of the TRAP variable\n"
4185 "Value of the TRAP variable\n")
4186{
4187 struct gsm_network *net = gsmnet_from_vty(vty);
4188
4189 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4190 return CMD_SUCCESS;
4191}
4192
Harald Weltedcccb182010-05-16 20:52:23 +02004193extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004194
Maxdb0e3802017-01-12 19:35:11 +01004195int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004196{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004197 cfg_ts_pchan_cmd.string =
4198 vty_cmd_string_from_valstr(tall_bsc_ctx,
4199 gsm_pchant_names,
4200 "phys_chan_config (", "|", ")",
4201 VTY_DO_LOWER);
4202 cfg_ts_pchan_cmd.doc =
4203 vty_cmd_string_from_valstr(tall_bsc_ctx,
4204 gsm_pchant_descs,
4205 "Physical Channel Combination\n",
4206 "\n", "", 0);
4207
Harald Weltee555c2b2012-08-17 13:02:12 +02004208 cfg_bts_type_cmd.string =
4209 vty_cmd_string_from_valstr(tall_bsc_ctx,
4210 bts_type_names,
4211 "type (", "|", ")",
4212 VTY_DO_LOWER);
4213 cfg_bts_type_cmd.doc =
4214 vty_cmd_string_from_valstr(tall_bsc_ctx,
4215 bts_type_descs,
4216 "BTS Vendor/Type\n",
4217 "\n", "", 0);
4218
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +02004219 common_cs_vty_init(network, config_write_net);
Harald Weltee555c2b2012-08-17 13:02:12 +02004220
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004221 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004222 install_element_ve(&show_bts_cmd);
4223 install_element_ve(&show_trx_cmd);
4224 install_element_ve(&show_ts_cmd);
4225 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004226 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004227
Philipp Maier39f62bb2017-04-09 12:32:51 +02004228 install_element_ve(&show_subscr_conn_cmd);
4229 install_element_ve(&handover_subscr_conn_cmd);
4230
Harald Welteb4d5b172010-05-12 16:10:35 +00004231 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004232 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004233
Maxdb0e3802017-01-12 19:35:11 +01004234 logging_vty_add_cmds(NULL);
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004235
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004236 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Weltebc814502009-12-19 21:41:52 +01004237 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Welteb720bd32009-12-21 16:51:50 +01004238 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
4239 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
4240 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
4241 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
4242 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
4243 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004244 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004245 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4246 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4247 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4248 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4249 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4250 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4251 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4252 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4253 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004254 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004255 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004256 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004257 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02004258
4259 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004260 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004261 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004262 install_element(BTS_NODE, &cfg_description_cmd);
4263 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004264 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004265 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004266 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4267 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4268 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4269 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004270 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4271 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004272 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004273 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004274 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004275 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004276 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004277 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004278 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004279 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4280 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004281 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004282 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4283 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004284 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4285 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4286 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004287 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4288 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004289 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004290 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004291 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004292 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004293 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4294 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004295 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4296 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4297 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4298 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4299 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4300 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004301 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004302 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004303 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304304 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004305 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004306 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004307 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004308 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4309 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004310 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004311 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004312 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004313 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004314 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4315 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4316 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004317 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004318 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4319 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004320 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004321 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004322 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4323 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004324 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004325 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4326 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004327 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4328 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004329 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4330 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004331 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4332 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004333 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4334 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4335 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4336 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4337 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004338 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4339 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004340 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4341 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4342 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4343 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4344 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4345 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4346 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4347 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4348 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4349 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4350 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4351 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4352 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4353 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4354 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4355 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4356 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4357 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4358 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4359 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4360 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4361 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004362 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004363
Harald Welte5258fc42009-03-28 19:07:53 +00004364 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004365 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004366 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004367 install_element(TRX_NODE, &cfg_description_cmd);
4368 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004369 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004370 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004371 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4372 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004373 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004374
Harald Welte5258fc42009-03-28 19:07:53 +00004375 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004376 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004377 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004378 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004379 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004380 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004381 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4382 install_element(TS_NODE, &cfg_ts_maio_cmd);
4383 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4384 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004385 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004386
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004387 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004388 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004389 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004390 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004391 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004392 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004393 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004394 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004395
Harald Welte81c9b9c2010-05-31 16:40:40 +02004396 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004397 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004398 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004399 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004400
Harald Weltedcccb182010-05-16 20:52:23 +02004401 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004402
Harald Welte68628e82009-03-10 12:17:57 +00004403 return 0;
4404}