blob: a73c6a471b9fc7288c812c848af16013fdcf0cde [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 Welte4381cfe2009-08-30 15:47:06 +0900175 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
176 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100177 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
178 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800179 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
180 VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100181 vty_out(vty, " MM Info: %s%s", net->send_mm_info ? "On" : "Off",
182 VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100183 vty_out(vty, " Handover: %s%s", net->handover.active ? "On" : "Off",
184 VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100185 network_chan_load(&pl, net);
186 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
187 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100188
189 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100190 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100191 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200192 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100193 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100194 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200195 vty_out(vty, " Last RF Lock Command: %s%s",
196 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
197 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000198}
199
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200200DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000201 SHOW_STR "Display information about a GSM NETWORK\n")
202{
Harald Weltedcccb182010-05-16 20:52:23 +0200203 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000204 net_dump_vty(vty, net);
205
206 return CMD_SUCCESS;
207}
208
209static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
210{
Harald Welteedb37782009-05-01 14:59:07 +0000211 struct e1inp_line *line;
212
213 if (!e1l) {
214 vty_out(vty, " None%s", VTY_NEWLINE);
215 return;
216 }
217
218 line = e1l->ts->line;
219
220 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
221 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000222 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000223 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000224 e1l->tei, e1l->sapi, VTY_NEWLINE);
225}
226
227static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
228{
Harald Welteb908cb72009-12-22 13:09:29 +0100229 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200230 unsigned long long sec;
Harald Welteb908cb72009-12-22 13:09:29 +0100231
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200232 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100233 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200234 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200235 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100236 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100237 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200238 bts->num_trx, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200239 vty_out(vty, "Description: %s%s",
240 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Maxf9685c12017-03-23 12:01:07 +0100241 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
242 vty_out(vty, "PCU version %s connected%s", bts->pcu_version,
243 VTY_NEWLINE);
Harald Welte1d8dbc42009-12-12 15:38:16 +0100244 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100245 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100246 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
247 VTY_NEWLINE);
248 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100249 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100250 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
251 VTY_NEWLINE);
252 vty_out(vty, "RACH Max transmissions: %u%s",
253 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
254 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100255 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200256 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200257 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
258 vty_out(vty, "Uplink DTX: %s%s",
259 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
260 "enabled" : "forced", VTY_NEWLINE);
261 else
262 vty_out(vty, "Uplink DTX: not enabled%s", VTY_NEWLINE);
263 vty_out(vty, "Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
264 VTY_NEWLINE);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200265 vty_out(vty, "Channel Description Attachment: %s%s",
266 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
267 vty_out(vty, "Channel Description BS-PA-MFRMS: %u%s",
268 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
269 vty_out(vty, "Channel Description BS-AG_BLKS-RES: %u%s",
270 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200271 vty_out(vty, "System Information present: 0x%08x, static: 0x%08x%s",
272 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100273 vty_out(vty, "Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100274 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100275 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
276 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
277 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100278 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200279 if (bts->pcu_sock_path)
280 vty_out(vty, "PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000281 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200282 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000283 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200284 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200285 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
286 vty_out(vty, " Skip Reset: %d%s",
287 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000288 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200289 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000290 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200291 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200292 vty_out(vty, " GPRS NSE: ");
293 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
294 vty_out(vty, " GPRS CELL: ");
295 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
296 vty_out(vty, " GPRS NSVC0: ");
297 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
298 vty_out(vty, " GPRS NSVC1: ");
299 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200300 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
301 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000302 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100303 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200304 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200305 sec = bts_uptime(bts);
306 if (sec)
307 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.%s",
308 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60,
309 VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100310 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200311 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
312 e1isl_dump_vty(vty, bts->oml_link);
313 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100314
315 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100316 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200317 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100318 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
319 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100320
321 vty_out(vty, "Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
322 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
323 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
324 VTY_NEWLINE);
325 vty_out(vty, "Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
326 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
327 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
328 VTY_NEWLINE);
329 vty_out(vty, "BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
330 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
331 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
332 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000333}
334
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100335DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000336 SHOW_STR "Display information about a BTS\n"
337 "BTS number")
338{
Harald Weltedcccb182010-05-16 20:52:23 +0200339 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000340 int bts_nr;
341
342 if (argc != 0) {
343 /* use the BTS number that the user has specified */
344 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100345 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000346 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000347 VTY_NEWLINE);
348 return CMD_WARNING;
349 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200350 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000351 return CMD_SUCCESS;
352 }
353 /* print all BTS's */
354 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200355 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000356
357 return CMD_SUCCESS;
358}
359
Harald Welte42581822009-08-08 16:12:58 +0200360/* utility functions */
361static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
362 const char *ts, const char *ss)
363{
364 e1_link->e1_nr = atoi(line);
365 e1_link->e1_ts = atoi(ts);
366 if (!strcmp(ss, "full"))
367 e1_link->e1_ts_ss = 255;
368 else
369 e1_link->e1_ts_ss = atoi(ss);
370}
371
372static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
373 const char *prefix)
374{
375 if (!e1_link->e1_ts)
376 return;
377
378 if (e1_link->e1_ts_ss == 255)
379 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
380 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
381 else
382 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
383 prefix, e1_link->e1_nr, e1_link->e1_ts,
384 e1_link->e1_ts_ss, VTY_NEWLINE);
385}
386
387
Harald Welte67ce0732009-08-06 19:06:46 +0200388static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
389{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100390 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100391 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100392 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200393 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100394 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200395 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100396 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200397 ts->hopping.enabled, VTY_NEWLINE);
398 if (ts->hopping.enabled) {
399 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100400 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200401 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100402 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200403 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200404 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
405 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
406 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100407 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200408 i, VTY_NEWLINE);
409 }
Harald Welte127af342010-12-24 12:07:07 +0100410 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100411 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100412
413 if (ts->trx->bts->model->config_write_ts)
414 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200415}
416
417static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
418{
419 int i;
420
Harald Welte5013b2a2009-08-07 13:29:14 +0200421 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200422 if (trx->description)
423 vty_out(vty, " description %s%s", trx->description,
424 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200425 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200426 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200427 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200428 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100429 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200430 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200431 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
432 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200433
Harald Welteface7ed2011-02-14 16:15:21 +0100434 if (trx->bts->model->config_write_trx)
435 trx->bts->model->config_write_trx(vty, trx);
436
Harald Welte67ce0732009-08-06 19:06:46 +0200437 for (i = 0; i < TRX_NR_TS; i++)
438 config_write_ts_single(vty, &trx->ts[i]);
439}
440
Harald Welte615e9562010-05-11 23:50:21 +0200441static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
442{
443 unsigned int i;
444 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
445 VTY_NEWLINE);
446 if (bts->gprs.mode == BTS_GPRS_NONE)
447 return;
448
bhargava350533c2016-07-21 11:14:34 +0530449 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
450 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
451
Harald Welte615e9562010-05-11 23:50:21 +0200452 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
453 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100454 vty_out(vty, " gprs network-control-order nc%u%s",
455 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200456 if (!bts->gprs.ctrl_ack_type_use_block)
457 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200458 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
459 VTY_NEWLINE);
460 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
461 vty_out(vty, " gprs cell timer %s %u%s",
462 get_value_string(gprs_bssgp_cfg_strs, i),
463 bts->gprs.cell.timer[i], VTY_NEWLINE);
464 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
465 VTY_NEWLINE);
466 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
467 vty_out(vty, " gprs ns timer %s %u%s",
468 get_value_string(gprs_ns_timer_strs, i),
469 bts->gprs.nse.timer[i], VTY_NEWLINE);
470 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
471 struct gsm_bts_gprs_nsvc *nsvc =
472 &bts->gprs.nsvc[i];
473 struct in_addr ia;
474
475 ia.s_addr = htonl(nsvc->remote_ip);
476 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
477 nsvc->nsvci, VTY_NEWLINE);
478 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
479 nsvc->local_port, VTY_NEWLINE);
480 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
481 nsvc->remote_port, VTY_NEWLINE);
482 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
483 inet_ntoa(ia), VTY_NEWLINE);
484 }
485}
486
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200487/* Write the model data if there is one */
488static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200489{
490 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200491
492 if (!bts->model)
493 return;
494
495 if (bts->model->config_write_bts)
496 bts->model->config_write_bts(vty, bts);
497
498 llist_for_each_entry(trx, &bts->trx_list, list)
499 config_write_trx_single(vty, trx);
500}
501
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200502static void write_amr_modes(struct vty *vty, const char *prefix,
503 const char *name, struct amr_mode *modes, int num)
504{
505 int i;
506
507 vty_out(vty, " %s threshold %s", prefix, name);
508 for (i = 0; i < num - 1; i++)
509 vty_out(vty, " %d", modes[i].threshold);
510 vty_out(vty, "%s", VTY_NEWLINE);
511 vty_out(vty, " %s hysteresis %s", prefix, name);
512 for (i = 0; i < num - 1; i++)
513 vty_out(vty, " %d", modes[i].hysteresis);
514 vty_out(vty, "%s", VTY_NEWLINE);
515}
516
Andreas Eversberg73266522014-01-19 11:47:44 +0100517static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
518 struct amr_multirate_conf *mr, int full)
519{
520 struct gsm48_multi_rate_conf *mr_conf;
521 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
522 int i, num;
523
524 if (!(mr->gsm48_ie[1]))
525 return;
526
527 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
528
529 num = 0;
530 vty_out(vty, " %s modes", prefix);
531 for (i = 0; i < ((full) ? 8 : 6); i++) {
532 if ((mr->gsm48_ie[1] & (1 << i))) {
533 vty_out(vty, " %d", i);
534 num++;
535 }
536 }
537 vty_out(vty, "%s", VTY_NEWLINE);
538 if (num > 4)
539 num = 4;
540 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200541 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
542 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100543 }
544 vty_out(vty, " %s start-mode ", prefix);
545 if (mr_conf->icmi) {
546 num = 0;
547 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
548 if ((mr->gsm48_ie[1] & (1 << i)))
549 num++;
550 if (mr_conf->smod == num - 1) {
551 vty_out(vty, "%d%s", num, VTY_NEWLINE);
552 break;
553 }
554 }
555 } else
556 vty_out(vty, "auto%s", VTY_NEWLINE);
557}
558
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200559static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
560{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200561 int i;
Max2c16bee2017-02-15 13:51:37 +0100562 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200563
Harald Welte5013b2a2009-08-07 13:29:14 +0200564 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
565 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200566 if (bts->description)
567 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200568 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100569 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200570 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200571 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200572 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
573 vty_out(vty, " dtx uplink%s%s",
574 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
575 VTY_NEWLINE);
576 if (bts->dtxd)
577 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200578 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200579 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100580 vty_out(vty, " cell reselection hysteresis %u%s",
581 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
582 vty_out(vty, " rxlev access min %u%s",
583 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100584
585 if (bts->si_common.cell_ro_sel_par.present) {
586 struct gsm48_si_selection_params *sp;
587 sp = &bts->si_common.cell_ro_sel_par;
588
589 if (sp->cbq)
590 vty_out(vty, " cell bar qualify %u%s",
591 sp->cbq, VTY_NEWLINE);
592
593 if (sp->cell_resel_off)
594 vty_out(vty, " cell reselection offset %u%s",
595 sp->cell_resel_off*2, VTY_NEWLINE);
596
597 if (sp->temp_offs == 7)
598 vty_out(vty, " temporary offset infinite%s",
599 VTY_NEWLINE);
600 else if (sp->temp_offs)
601 vty_out(vty, " temporary offset %u%s",
602 sp->temp_offs*10, VTY_NEWLINE);
603
604 if (sp->penalty_time == 31)
605 vty_out(vty, " penalty time reserved%s",
606 VTY_NEWLINE);
607 else if (sp->penalty_time)
608 vty_out(vty, " penalty time %u%s",
609 (sp->penalty_time*20)+20, VTY_NEWLINE);
610 }
611
Harald Welte2f8b9d22017-06-18 11:12:13 +0300612 if (gsm_bts_get_radio_link_timeout(bts) < 0)
613 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
614 else
615 vty_out(vty, " radio-link-timeout %d%s",
616 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100617
Harald Welte7a8fa412009-08-10 13:48:16 +0200618 vty_out(vty, " channel allocator %s%s",
619 bts->chan_alloc_reverse ? "descending" : "ascending",
620 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100621 vty_out(vty, " rach tx integer %u%s",
622 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
623 vty_out(vty, " rach max transmission %u%s",
624 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
625 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800626
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200627 vty_out(vty, " channel-descrption attach %u%s",
628 bts->si_common.chan_desc.att, VTY_NEWLINE);
629 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
630 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
631 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
632 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
633
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800634 if (bts->rach_b_thresh != -1)
635 vty_out(vty, " rach nm busy threshold %u%s",
636 bts->rach_b_thresh, VTY_NEWLINE);
637 if (bts->rach_ldavg_slots != -1)
638 vty_out(vty, " rach nm load average %u%s",
639 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100640 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200641 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800642 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
643 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400644 if ((bts->si_common.rach_control.t3) != 0)
645 for (i = 0; i < 8; i++)
646 if (bts->si_common.rach_control.t3 & (0x1 << i))
647 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
648 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
649 for (i = 0; i < 8; i++)
650 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
651 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200652 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
653 if (bts->si_mode_static & (1 << i)) {
654 vty_out(vty, " system-information %s mode static%s",
655 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
656 vty_out(vty, " system-information %s static %s%s",
657 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200658 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200659 VTY_NEWLINE);
660 }
661 }
Harald Welte42def722017-01-13 00:10:32 +0100662 vty_out(vty, " early-classmark-sending %s%s",
663 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100664 vty_out(vty, " early-classmark-sending-3g %s%s",
665 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100666 switch (bts->type) {
667 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100668 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200669 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200670 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100671 if (bts->ip_access.rsl_ip) {
672 struct in_addr ia;
673 ia.s_addr = htonl(bts->ip_access.rsl_ip);
674 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
675 VTY_NEWLINE);
676 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200677 vty_out(vty, " oml ip.access stream_id %u line %u%s",
678 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100679 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200680 case GSM_BTS_TYPE_NOKIA_SITE:
681 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100682 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
683 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100684 vty_out(vty, " nokia_site bts-reset-timer %d%s", bts->nokia.bts_reset_timer_cnf, VTY_NEWLINE);
Andreas Eversbergb6f95162013-12-05 16:02:37 +0100685 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100686 default:
Harald Welte42581822009-08-08 16:12:58 +0200687 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
688 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100689 break;
Harald Welte42581822009-08-08 16:12:58 +0200690 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800691
692 /* if we have a limit, write it */
693 if (bts->paging.free_chans_need >= 0)
694 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
695
Harald Welte32c09622011-01-11 23:44:56 +0100696 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100697 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
698 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100699 for (i = 0; i < 1024; i++) {
700 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
701 vty_out(vty, " neighbor-list add arfcn %u%s",
702 i, VTY_NEWLINE);
703 }
704 }
Harald Welte64c07d22011-02-15 11:43:27 +0100705 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
706 for (i = 0; i < 1024; i++) {
707 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
708 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
709 i, VTY_NEWLINE);
710 }
711 }
Harald Welte32c09622011-01-11 23:44:56 +0100712
Max59a1bf32016-04-15 16:04:46 +0200713 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100714 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
715 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
716 vty_out(vty, " si2quater neighbor-list add earfcn %u "
717 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
718
719 vty_out(vty, " thresh-lo %u",
720 e->thresh_lo_valid ? e->thresh_lo : 32);
721
722 vty_out(vty, " prio %u",
723 e->prio_valid ? e->prio : 8);
724
725 vty_out(vty, " qrxlv %u",
726 e->qrxlm_valid ? e->qrxlm : 32);
727
728 tmp = e->meas_bw[i];
729 vty_out(vty, " meas %u",
730 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200731
732 vty_out(vty, "%s", VTY_NEWLINE);
733 }
734 }
735
Max26679e02016-04-20 15:57:13 +0200736 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
737 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
738 bts->si_common.data.uarfcn_list[i],
739 bts->si_common.data.scramble_list[i] & ~(1 << 9),
740 (bts->si_common.data.scramble_list[i] >> 9) & 1,
741 VTY_NEWLINE);
742 }
743
Andreas Eversberga83d5112013-12-07 18:32:28 +0100744 vty_out(vty, " codec-support fr");
745 if (bts->codec.hr)
746 vty_out(vty, " hr");
747 if (bts->codec.efr)
748 vty_out(vty, " efr");
749 if (bts->codec.amr)
750 vty_out(vty, " amr");
751 vty_out(vty, "%s", VTY_NEWLINE);
752
Andreas Eversberg73266522014-01-19 11:47:44 +0100753 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
754 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
755
Harald Welte615e9562010-05-11 23:50:21 +0200756 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200757
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200758 if (bts->excl_from_rf_lock)
759 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
760
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100761 vty_out(vty, " %sforce-combined-si%s",
762 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
763
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100764 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
765 int j;
766
767 if (bts->depends_on[i] == 0)
768 continue;
769
770 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
771 int bts_nr;
772
773 if ((bts->depends_on[i] & (1<<j)) == 0)
774 continue;
775
776 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
777 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
778 }
779 }
Harald Welte8254cf72017-05-29 13:42:19 +0200780 if (bts->pcu_sock_path)
781 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100782
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200783 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200784}
785
786static int config_write_bts(struct vty *v)
787{
Harald Weltedcccb182010-05-16 20:52:23 +0200788 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200789 struct gsm_bts *bts;
790
791 llist_for_each_entry(bts, &gsmnet->bts_list, list)
792 config_write_bts_single(v, bts);
793
794 return CMD_SUCCESS;
795}
796
Harald Weltea0d324b2017-07-20 01:47:39 +0200797/* small helper macro for conditional dumping of timer */
798#define VTY_OUT_TIMER(number) \
799 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
800 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
801
Harald Welte5013b2a2009-08-07 13:29:14 +0200802static int config_write_net(struct vty *vty)
803{
Harald Weltedcccb182010-05-16 20:52:23 +0200804 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
805
Harald Welte5013b2a2009-08-07 13:29:14 +0200806 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200807 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200808 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200809 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
810 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900811 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100812 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800813 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Harald Welte648b6ce2009-12-14 09:00:24 +0100814 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100815 vty_out(vty, " handover %u%s", gsmnet->handover.active, VTY_NEWLINE);
Harald Welteb720bd32009-12-21 16:51:50 +0100816 vty_out(vty, " handover window rxlev averaging %u%s",
817 gsmnet->handover.win_rxlev_avg, VTY_NEWLINE);
818 vty_out(vty, " handover window rxqual averaging %u%s",
819 gsmnet->handover.win_rxqual_avg, VTY_NEWLINE);
820 vty_out(vty, " handover window rxlev neighbor averaging %u%s",
821 gsmnet->handover.win_rxlev_avg_neigh, VTY_NEWLINE);
822 vty_out(vty, " handover power budget interval %u%s",
823 gsmnet->handover.pwr_interval, VTY_NEWLINE);
824 vty_out(vty, " handover power budget hysteresis %u%s",
825 gsmnet->handover.pwr_hysteresis, VTY_NEWLINE);
826 vty_out(vty, " handover maximum distance %u%s",
827 gsmnet->handover.max_distance, VTY_NEWLINE);
Harald Weltea0d324b2017-07-20 01:47:39 +0200828 VTY_OUT_TIMER(3101);
829 VTY_OUT_TIMER(3103);
830 VTY_OUT_TIMER(3105);
831 VTY_OUT_TIMER(3107);
832 VTY_OUT_TIMER(3109);
833 VTY_OUT_TIMER(3111);
834 VTY_OUT_TIMER(3113);
835 VTY_OUT_TIMER(3115);
836 VTY_OUT_TIMER(3117);
837 VTY_OUT_TIMER(3119);
838 VTY_OUT_TIMER(3122);
839 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700840 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
841 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200842 if (gsmnet->tz.override != 0) {
843 if (gsmnet->tz.dst)
844 vty_out(vty, " timezone %d %d %d%s",
845 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
846 VTY_NEWLINE);
847 else
848 vty_out(vty, " timezone %d %d%s",
849 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
850 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200851 if (gsmnet->t3212 == 0)
852 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
853 else
854 vty_out(vty, " periodic location update %u%s",
855 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200856
857 return CMD_SUCCESS;
858}
Harald Welte67ce0732009-08-06 19:06:46 +0200859
Harald Welte68628e82009-03-10 12:17:57 +0000860static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
861{
862 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
863 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200864 vty_out(vty, "Description: %s%s",
865 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200866 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200867 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200868 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200869 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000870 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200871 net_dump_nmstate(vty, &trx->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000872 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200873 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200874 if (is_ipaccess_bts(trx->bts)) {
875 vty_out(vty, " ip.access stream ID: 0x%02x%s",
876 trx->rsl_tei, VTY_NEWLINE);
877 } else {
878 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
879 e1isl_dump_vty(vty, trx->rsl_link);
880 }
Harald Welte68628e82009-03-10 12:17:57 +0000881}
882
883DEFUN(show_trx,
884 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100885 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200886 SHOW_STR "Display information about a TRX\n"
887 "BTS Number\n"
888 "TRX Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000889{
Harald Weltedcccb182010-05-16 20:52:23 +0200890 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000891 struct gsm_bts *bts = NULL;
892 struct gsm_bts_trx *trx;
893 int bts_nr, trx_nr;
894
895 if (argc >= 1) {
896 /* use the BTS number that the user has specified */
897 bts_nr = atoi(argv[0]);
898 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000899 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000900 VTY_NEWLINE);
901 return CMD_WARNING;
902 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200903 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000904 }
905 if (argc >= 2) {
906 trx_nr = atoi(argv[1]);
907 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000908 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000909 VTY_NEWLINE);
910 return CMD_WARNING;
911 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200912 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000913 trx_dump_vty(vty, trx);
914 return CMD_SUCCESS;
915 }
916 if (bts) {
917 /* print all TRX in this BTS */
918 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200919 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000920 trx_dump_vty(vty, trx);
921 }
922 return CMD_SUCCESS;
923 }
924
925 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200926 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000927 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200928 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000929 trx_dump_vty(vty, trx);
930 }
931 }
932
933 return CMD_SUCCESS;
934}
935
Harald Welte67ce0732009-08-06 19:06:46 +0200936
Harald Welte68628e82009-03-10 12:17:57 +0000937static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
938{
Harald Welte135a6482011-05-30 12:09:13 +0200939 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +0100940 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +0100941 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +0100942 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +0100943 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200944 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +0100945 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000946 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200947 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530948 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000949 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
950 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
951 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000952}
953
954DEFUN(show_ts,
955 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100956 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200957 SHOW_STR "Display information about a TS\n"
958 "BTS Number\n" "TRX Number\n" "Timeslot Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000959{
Harald Weltedcccb182010-05-16 20:52:23 +0200960 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +0100961 struct gsm_bts *bts = NULL;
962 struct gsm_bts_trx *trx = NULL;
963 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000964 int bts_nr, trx_nr, ts_nr;
965
966 if (argc >= 1) {
967 /* use the BTS number that the user has specified */
968 bts_nr = atoi(argv[0]);
969 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000970 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000971 VTY_NEWLINE);
972 return CMD_WARNING;
973 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200974 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000975 }
976 if (argc >= 2) {
977 trx_nr = atoi(argv[1]);
978 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000979 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000980 VTY_NEWLINE);
981 return CMD_WARNING;
982 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200983 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000984 }
985 if (argc >= 3) {
986 ts_nr = atoi(argv[2]);
987 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +0000988 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +0000989 VTY_NEWLINE);
990 return CMD_WARNING;
991 }
Harald Welte274d0152010-12-24 12:05:03 +0100992 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +0000993 ts = &trx->ts[ts_nr];
994 ts_dump_vty(vty, ts);
995 return CMD_SUCCESS;
996 }
Harald Welte274d0152010-12-24 12:05:03 +0100997
998 if (bts && trx) {
999 /* Iterate over all TS in this TRX */
1000 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1001 ts = &trx->ts[ts_nr];
1002 ts_dump_vty(vty, ts);
1003 }
1004 } else if (bts) {
1005 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001006 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001007 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001008 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1009 ts = &trx->ts[ts_nr];
1010 ts_dump_vty(vty, ts);
1011 }
1012 }
Harald Welte274d0152010-12-24 12:05:03 +01001013 } else {
1014 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1015 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1016 bts = gsm_bts_num(net, bts_nr);
1017 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1018 trx = gsm_bts_trx_num(bts, trx_nr);
1019 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1020 ts = &trx->ts[ts_nr];
1021 ts_dump_vty(vty, ts);
1022 }
1023 }
1024 }
Harald Welte68628e82009-03-10 12:17:57 +00001025 }
1026
1027 return CMD_SUCCESS;
1028}
1029
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001030static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1031{
1032 if (strlen(bsub->imsi))
1033 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1034 if (bsub->tmsi != GSM_RESERVED_TMSI)
1035 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1036 VTY_NEWLINE);
1037 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1038}
1039
Harald Welte8387a492009-12-22 21:43:14 +01001040static void meas_rep_dump_uni_vty(struct vty *vty,
1041 struct gsm_meas_rep_unidir *mru,
1042 const char *prefix,
1043 const char *dir)
1044{
1045 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1046 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1047 dir, rxlev2dbm(mru->sub.rx_lev));
1048 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1049 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1050 VTY_NEWLINE);
1051}
1052
1053static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1054 const char *prefix)
1055{
1056 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1057 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1058 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1059 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1060 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1061 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1062 VTY_NEWLINE);
1063 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001064 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001065 if (mr->flags & MEAS_REP_F_MS_L1)
1066 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1067 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1068 if (mr->flags & MEAS_REP_F_DL_VALID)
1069 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1070 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1071}
1072
Harald Welte0a8cf322015-12-05 17:22:49 +01001073/* FIXME: move this to libosmogsm */
1074static const struct value_string gsm48_cmode_names[] = {
1075 { GSM48_CMODE_SIGN, "signalling" },
1076 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1077 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1078 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1079 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1080 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1081 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1082 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1083 { 0, NULL }
1084};
1085
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001086/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1087 * Don't do anything if the ts is not dynamic. */
1088static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1089{
1090 switch (ts->pchan) {
1091 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1092 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1093 vty_out(vty, " as %s",
1094 gsm_pchan_name(ts->dyn.pchan_is));
1095 else
1096 vty_out(vty, " switching %s -> %s",
1097 gsm_pchan_name(ts->dyn.pchan_is),
1098 gsm_pchan_name(ts->dyn.pchan_want));
1099 break;
1100 case GSM_PCHAN_TCH_F_PDCH:
1101 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1102 vty_out(vty, " as %s",
1103 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1104 : "TCH/F");
1105 else
1106 vty_out(vty, " switching %s -> %s",
1107 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1108 : "TCH/F",
1109 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1110 : "TCH/F");
1111 break;
1112 default:
1113 /* no dyn ts */
1114 break;
1115 }
1116}
1117
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001118static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001119{
Harald Welte8387a492009-12-22 21:43:14 +01001120 int idx;
1121
Harald Welte85bded82010-12-24 12:22:34 +01001122 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1123 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1124 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001125 /* show dyn TS details, if applicable */
1126 switch (lchan->ts->pchan) {
1127 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1128 vty_out(vty, " Osmocom Dyn TS:");
1129 vty_out_dyn_ts_status(vty, lchan->ts);
1130 vty_out(vty, VTY_NEWLINE);
1131 break;
1132 case GSM_PCHAN_TCH_F_PDCH:
1133 vty_out(vty, " IPACC Dyn PDCH TS:");
1134 vty_out_dyn_ts_status(vty, lchan->ts);
1135 vty_out(vty, VTY_NEWLINE);
1136 break;
1137 default:
1138 /* no dyn ts */
1139 break;
1140 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001141 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001142 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001143 gsm_lchans_name(lchan->state),
1144 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1145 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1146 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001147 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1148 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1149 - lchan->bs_power*2,
1150 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1151 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001152 vty_out(vty, " Channel Mode / Codec: %s%s",
1153 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1154 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001155 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001156 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001157 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001158 } else
1159 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301160 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1161 struct in_addr ia;
Holger Hans Peter Freyther54fa7992010-04-07 15:39:16 +02001162 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte2c828992009-12-02 01:56:49 +05301163 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1164 inet_ntoa(ia), lchan->abis_ip.bound_port,
1165 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1166 VTY_NEWLINE);
1167 }
Harald Welte8387a492009-12-22 21:43:14 +01001168
1169 /* we want to report the last measurement report */
1170 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1171 lchan->meas_rep_idx, 1);
1172 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001173}
1174
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001175static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1176{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001177 struct gsm_meas_rep *mr;
1178 int idx;
1179
1180 /* we want to report the last measurement report */
1181 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1182 lchan->meas_rep_idx, 1);
1183 mr = &lchan->meas_rep[idx];
1184
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001185 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001186 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001187 gsm_pchan_name(lchan->ts->pchan));
1188 vty_out_dyn_ts_status(vty, lchan->ts);
1189 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1190 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001191 lchan->nr,
1192 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1193 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001194 rxlev2dbm(mr->dl.full.rx_lev),
1195 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001196 VTY_NEWLINE);
1197}
1198
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001199
1200static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1201 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1202{
1203 int lchan_nr;
1204 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1205 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1206 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1207 continue;
1208 dump_cb(vty, lchan);
1209 }
1210
1211 return CMD_SUCCESS;
1212}
1213
1214static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1215 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1216{
1217 int ts_nr;
1218
1219 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1220 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1221 dump_lchan_trx_ts(ts, vty, dump_cb);
1222 }
1223
1224 return CMD_SUCCESS;
1225}
1226
1227static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1228 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1229{
1230 int trx_nr;
1231
1232 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1233 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1234 dump_lchan_trx(trx, vty, dump_cb);
1235 }
1236
1237 return CMD_SUCCESS;
1238}
1239
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001240static int lchan_summary(struct vty *vty, int argc, const char **argv,
1241 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001242{
Harald Weltedcccb182010-05-16 20:52:23 +02001243 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001244 struct gsm_bts *bts;
1245 struct gsm_bts_trx *trx;
1246 struct gsm_bts_trx_ts *ts;
1247 struct gsm_lchan *lchan;
1248 int bts_nr, trx_nr, ts_nr, lchan_nr;
1249
1250 if (argc >= 1) {
1251 /* use the BTS number that the user has specified */
1252 bts_nr = atoi(argv[0]);
1253 if (bts_nr >= net->num_bts) {
1254 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1255 VTY_NEWLINE);
1256 return CMD_WARNING;
1257 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001258 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001259
1260 if (argc == 1)
1261 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001262 }
1263 if (argc >= 2) {
1264 trx_nr = atoi(argv[1]);
1265 if (trx_nr >= bts->num_trx) {
1266 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1267 VTY_NEWLINE);
1268 return CMD_WARNING;
1269 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001270 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001271
1272 if (argc == 2)
1273 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001274 }
1275 if (argc >= 3) {
1276 ts_nr = atoi(argv[2]);
1277 if (ts_nr >= TRX_NR_TS) {
1278 vty_out(vty, "%% can't find TS %s%s", argv[2],
1279 VTY_NEWLINE);
1280 return CMD_WARNING;
1281 }
1282 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001283
1284 if (argc == 3)
1285 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001286 }
1287 if (argc >= 4) {
1288 lchan_nr = atoi(argv[3]);
1289 if (lchan_nr >= TS_MAX_LCHAN) {
1290 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1291 VTY_NEWLINE);
1292 return CMD_WARNING;
1293 }
1294 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001295 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001296 return CMD_SUCCESS;
1297 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001298
1299
Harald Welte68628e82009-03-10 12:17:57 +00001300 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001301 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001302 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001303 }
1304
1305 return CMD_SUCCESS;
1306}
1307
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001308
1309DEFUN(show_lchan,
1310 show_lchan_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001311 "show lchan [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001312 SHOW_STR "Display information about a logical channel\n"
1313 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001314 LCHAN_NR_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001315
1316{
1317 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1318}
1319
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001320DEFUN(show_lchan_summary,
1321 show_lchan_summary_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001322 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001323 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001324 "Short summary\n"
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001325 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001326 LCHAN_NR_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001327{
1328 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1329}
1330
Philipp Maier39f62bb2017-04-09 12:32:51 +02001331DEFUN(show_subscr_conn,
1332 show_subscr_conn_cmd,
1333 "show conns",
1334 SHOW_STR "Display currently active subscriber connections\n")
1335{
1336 struct gsm_subscriber_connection *conn;
1337 struct gsm_network *net = gsmnet_from_vty(vty);
1338 bool no_conns = true;
1339 unsigned int count = 0;
1340
1341 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1342
1343 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1344 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1345 lchan_dump_full_vty(vty, conn->lchan);
1346 no_conns = false;
1347 count++;
1348 }
1349
1350 if (no_conns)
1351 vty_out(vty, "None%s", VTY_NEWLINE);
1352
1353 return CMD_SUCCESS;
1354}
1355
1356DEFUN(handover_subscr_conn,
1357 handover_subscr_conn_cmd,
1358 "handover <0-255> <0-255> <0-7> LCHAN_NR <0-255>",
1359 "Handover subscriber connection to other BTS\n"
1360 "BTS Number (current)\n" "TRX Number\n" "Timeslot Number\n"
1361 LCHAN_NR_STR "BTS Number (new)\n")
1362{
1363 struct gsm_network *net = gsmnet_from_vty(vty);
1364 struct gsm_subscriber_connection *conn;
1365 struct gsm_bts *bts;
1366 struct gsm_bts *new_bts = NULL;
1367 unsigned int bts_nr = atoi(argv[0]);
1368 unsigned int trx_nr = atoi(argv[1]);
1369 unsigned int ts_nr = atoi(argv[2]);
1370 unsigned int ss_nr = atoi(argv[3]);
1371 unsigned int bts_nr_new = atoi(argv[4]);
1372
1373 /* Lookup the BTS where we want to handover to */
1374 llist_for_each_entry(bts, &net->bts_list, list) {
1375 if (bts->nr == bts_nr_new) {
1376 new_bts = bts;
1377 break;
1378 }
1379 }
1380
1381 if (!new_bts) {
1382 vty_out(vty, "Unable to trigger handover,"
1383 "specified bts #%u does not exist %s", bts_nr_new,
1384 VTY_NEWLINE);
1385 return CMD_WARNING;
1386 }
1387
1388 /* Find the connection/lchan that we want to handover */
1389 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1390 if (conn->bts->nr == bts_nr &&
1391 conn->lchan->ts->trx->nr == trx_nr &&
1392 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
1393 vty_out(vty, "starting handover for lchan %s...%s",
1394 conn->lchan->name, VTY_NEWLINE);
1395 lchan_dump_full_vty(vty, conn->lchan);
1396 bsc_handover_start(conn->lchan, new_bts);
1397 return CMD_SUCCESS;
1398 }
1399 }
1400
1401 vty_out(vty, "Unable to trigger handover,"
1402 "specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1403 bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
1404
1405 return CMD_WARNING;
1406}
1407
Harald Weltebe4b7302009-05-23 16:59:33 +00001408static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001409{
1410 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001411 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001412}
1413
Harald Weltebe4b7302009-05-23 16:59:33 +00001414static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001415{
1416 struct gsm_paging_request *pag;
1417
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001418 if (!bts->paging.bts)
1419 return;
1420
Harald Weltef5025b62009-03-28 16:55:11 +00001421 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1422 paging_dump_vty(vty, pag);
1423}
1424
1425DEFUN(show_paging,
1426 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001427 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001428 SHOW_STR "Display information about paging reuqests of a BTS\n"
1429 "BTS Number\n")
Harald Weltef5025b62009-03-28 16:55:11 +00001430{
Harald Weltedcccb182010-05-16 20:52:23 +02001431 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001432 struct gsm_bts *bts;
1433 int bts_nr;
1434
1435 if (argc >= 1) {
1436 /* use the BTS number that the user has specified */
1437 bts_nr = atoi(argv[0]);
1438 if (bts_nr >= net->num_bts) {
1439 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1440 VTY_NEWLINE);
1441 return CMD_WARNING;
1442 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001443 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001444 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001445
Harald Weltef5025b62009-03-28 16:55:11 +00001446 return CMD_SUCCESS;
1447 }
1448 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001449 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001450 bts_paging_dump_vty(vty, bts);
1451 }
1452
1453 return CMD_SUCCESS;
1454}
1455
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001456DEFUN(show_paging_group,
1457 show_paging_group_cmd,
1458 "show paging-group <0-255> IMSI",
1459 SHOW_STR "Display the paging group\n"
1460 "BTS Number\n" "IMSI\n")
1461{
1462 struct gsm_network *net = gsmnet_from_vty(vty);
1463 struct gsm_bts *bts;
1464 unsigned int page_group;
1465 int bts_nr = atoi(argv[0]);
1466
1467 if (bts_nr >= net->num_bts) {
1468 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1469 return CMD_WARNING;
1470 }
1471
1472 bts = gsm_bts_num(net, bts_nr);
1473 if (!bts) {
1474 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1475 return CMD_WARNING;
1476 }
1477
1478 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1479 str_to_imsi(argv[1]));
1480 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1481 str_to_imsi(argv[1]), bts->nr,
1482 page_group, VTY_NEWLINE);
1483 return CMD_SUCCESS;
1484}
1485
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001486DEFUN(cfg_net_neci,
1487 cfg_net_neci_cmd,
1488 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001489 "New Establish Cause Indication\n"
1490 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001491{
Harald Weltedcccb182010-05-16 20:52:23 +02001492 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1493
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001494 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001495 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001496 return CMD_SUCCESS;
1497}
1498
Harald Welte8f0ed552010-05-11 21:53:49 +02001499#define HANDOVER_STR "Handover Options\n"
1500
Harald Weltebc814502009-12-19 21:41:52 +01001501DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1502 "handover (0|1)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001503 HANDOVER_STR
1504 "Don't perform in-call handover\n"
1505 "Perform in-call handover\n")
Harald Weltebc814502009-12-19 21:41:52 +01001506{
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001507 int enable = atoi(argv[0]);
Harald Weltedcccb182010-05-16 20:52:23 +02001508 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001509
1510 if (enable && ipacc_rtp_direct) {
Harald Weltefe03f0d2009-12-20 13:51:01 +01001511 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1512 "is enabled by using the -P command line option%s",
1513 VTY_NEWLINE);
1514 return CMD_WARNING;
1515 }
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001516 gsmnet->handover.active = enable;
Harald Weltebc814502009-12-19 21:41:52 +01001517
1518 return CMD_SUCCESS;
1519}
1520
Harald Welte8f0ed552010-05-11 21:53:49 +02001521#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1522#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1523#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1524#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001525#define HO_AVG_COUNT_STR "Amount to use for Averaging\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001526
Harald Welteb720bd32009-12-21 16:51:50 +01001527DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1528 "handover window rxlev averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001529 HO_WIN_RXLEV_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001530 "How many RxLev measurements are used for averaging\n"
1531 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001532{
Harald Weltedcccb182010-05-16 20:52:23 +02001533 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001534 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1535 return CMD_SUCCESS;
1536}
1537
1538DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1539 "handover window rxqual averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001540 HO_WIN_RXQUAL_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001541 "How many RxQual measurements are used for averaging\n"
1542 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001543{
Harald Weltedcccb182010-05-16 20:52:23 +02001544 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001545 gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
1546 return CMD_SUCCESS;
1547}
1548
1549DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1550 "handover window rxlev neighbor averaging <1-10>",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001551 HO_WIN_RXLEV_STR "Neighbor\n"
1552 "How many RxQual measurements are used for averaging\n"
1553 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001554{
Harald Weltedcccb182010-05-16 20:52:23 +02001555 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001556 gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
1557 return CMD_SUCCESS;
1558}
1559
1560DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1561 "handover power budget interval <1-99>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001562 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001563 "How often to check if we have a better cell (SACCH frames)\n"
1564 "Interval\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001565{
Harald Weltedcccb182010-05-16 20:52:23 +02001566 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001567 gsmnet->handover.pwr_interval = atoi(argv[0]);
1568 return CMD_SUCCESS;
1569}
1570
1571DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1572 "handover power budget hysteresis <0-999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001573 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001574 "How many dB does a neighbor to be stronger to become a HO candidate\n"
1575 "Hysteresis\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001576{
Harald Weltedcccb182010-05-16 20:52:23 +02001577 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001578 gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
1579 return CMD_SUCCESS;
1580}
1581
1582DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1583 "handover maximum distance <0-9999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001584 HANDOVER_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001585 "How big is the maximum timing advance before HO is forced\n"
1586 "Distance\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001587{
Harald Weltedcccb182010-05-16 20:52:23 +02001588 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001589 gsmnet->handover.max_distance = atoi(argv[0]);
1590 return CMD_SUCCESS;
1591}
Harald Weltebc814502009-12-19 21:41:52 +01001592
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001593DEFUN(cfg_net_pag_any_tch,
1594 cfg_net_pag_any_tch_cmd,
1595 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001596 "Assign a TCH when receiving a Paging Any request\n"
1597 "Any Channel\n" "Use\n" "TCH\n"
1598 "Do not use TCH for Paging Request Any\n"
1599 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001600{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001601 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001602 gsmnet->pag_any_tch = atoi(argv[0]);
1603 gsm_net_update_ctype(gsmnet);
1604 return CMD_SUCCESS;
1605}
1606
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001607#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1608/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1609#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1610
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001611#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001612 DEFUN(cfg_net_T##number, \
1613 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001614 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001615 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001616 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001617 "Set to default timer value" \
1618 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1619 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001620{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001621 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001622 int value; \
1623 if (strcmp(argv[0], "default") == 0) \
1624 value = DEFAULT_TIMER(number); \
1625 else \
1626 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001627 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001628 gsmnet->T##number = value; \
1629 return CMD_SUCCESS; \
1630}
1631
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001632DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1633DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1634DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1635DECLARE_TIMER(3107, "Currently not used")
1636DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1637DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1638DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1639DECLARE_TIMER(3115, "Currently not used")
1640DECLARE_TIMER(3117, "Currently not used")
1641DECLARE_TIMER(3119, "Currently not used")
1642DECLARE_TIMER(3122, "Waiting time (seconds) after IMM ASS REJECT")
1643DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001644
Maxc08ee712016-05-11 12:45:13 +02001645DEFUN_DEPRECATED(cfg_net_dtx,
1646 cfg_net_dtx_cmd,
1647 "dtx-used (0|1)",
1648 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001649{
Maxc08ee712016-05-11 12:45:13 +02001650 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1651 "configuration options of BTS instead%s", VTY_NEWLINE);
1652 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001653}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001654
Harald Welte5258fc42009-03-28 19:07:53 +00001655/* per-BTS configuration */
1656DEFUN(cfg_bts,
1657 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001658 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001659 "Select a BTS to configure\n"
1660 "BTS Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001661{
Harald Weltedcccb182010-05-16 20:52:23 +02001662 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001663 int bts_nr = atoi(argv[0]);
1664 struct gsm_bts *bts;
1665
Harald Weltee441d9c2009-06-21 16:17:15 +02001666 if (bts_nr > gsmnet->num_bts) {
1667 vty_out(vty, "%% The next unused BTS number is %u%s",
1668 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001669 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001670 } else if (bts_nr == gsmnet->num_bts) {
1671 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001672 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001673 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001674 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001675 bts = gsm_bts_num(gsmnet, bts_nr);
1676
Daniel Willmannf15c2762010-01-11 13:43:07 +01001677 if (!bts) {
1678 vty_out(vty, "%% Unable to allocate BTS %u%s",
1679 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001680 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001681 }
Harald Welte5258fc42009-03-28 19:07:53 +00001682
1683 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001684 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001685 vty->node = BTS_NODE;
1686
1687 return CMD_SUCCESS;
1688}
1689
1690DEFUN(cfg_bts_type,
1691 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001692 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001693 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001694{
1695 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001696 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001697
Max7507aef2017-04-10 13:59:14 +02001698 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001699 if (rc < 0)
1700 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001701
Harald Welte5258fc42009-03-28 19:07:53 +00001702 return CMD_SUCCESS;
1703}
1704
Harald Weltefcd24452009-06-20 18:15:19 +02001705DEFUN(cfg_bts_band,
1706 cfg_bts_band_cmd,
1707 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001708 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001709{
1710 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001711 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001712
1713 if (band < 0) {
1714 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1715 band, VTY_NEWLINE);
1716 return CMD_WARNING;
1717 }
1718
1719 bts->band = band;
1720
1721 return CMD_SUCCESS;
1722}
1723
Maxc08ee712016-05-11 12:45:13 +02001724DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1725 "Configure discontinuous transmission\n"
1726 "Enable Uplink DTX for this BTS\n"
1727 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1728 "older phones).\n")
1729{
1730 struct gsm_bts *bts = vty->index;
1731
1732 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001733 if (!is_ipaccess_bts(bts))
1734 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1735 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001736 return CMD_SUCCESS;
1737}
1738
1739DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1740 NO_STR
1741 "Configure discontinuous transmission\n"
1742 "Disable Uplink DTX for this BTS\n")
1743{
1744 struct gsm_bts *bts = vty->index;
1745
1746 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1747
1748 return CMD_SUCCESS;
1749}
1750
1751DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1752 "Configure discontinuous transmission\n"
1753 "Enable Downlink DTX for this BTS\n")
1754{
1755 struct gsm_bts *bts = vty->index;
1756
1757 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001758 if (!is_ipaccess_bts(bts))
1759 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1760 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001761 return CMD_SUCCESS;
1762}
1763
1764DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1765 NO_STR
1766 "Configure discontinuous transmission\n"
1767 "Disable Downlink DTX for this BTS\n")
1768{
1769 struct gsm_bts *bts = vty->index;
1770
1771 bts->dtxd = false;
1772
1773 return CMD_SUCCESS;
1774}
1775
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001776DEFUN(cfg_bts_ci,
1777 cfg_bts_ci_cmd,
1778 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001779 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001780{
1781 struct gsm_bts *bts = vty->index;
1782 int ci = atoi(argv[0]);
1783
1784 if (ci < 0 || ci > 0xffff) {
1785 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1786 ci, VTY_NEWLINE);
1787 return CMD_WARNING;
1788 }
1789 bts->cell_identity = ci;
1790
1791 return CMD_SUCCESS;
1792}
1793
Harald Welte5258fc42009-03-28 19:07:53 +00001794DEFUN(cfg_bts_lac,
1795 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001796 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001797 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001798{
1799 struct gsm_bts *bts = vty->index;
1800 int lac = atoi(argv[0]);
1801
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001802 if (lac < 0 || lac > 0xffff) {
1803 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001804 lac, VTY_NEWLINE);
1805 return CMD_WARNING;
1806 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001807
1808 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1809 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1810 lac, VTY_NEWLINE);
1811 return CMD_WARNING;
1812 }
1813
Harald Welte5258fc42009-03-28 19:07:53 +00001814 bts->location_area_code = lac;
1815
1816 return CMD_SUCCESS;
1817}
1818
Harald Weltea43f7892009-12-01 18:04:30 +05301819
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001820/* compatibility wrapper for old config files */
1821DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001822 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001823 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001824 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001825{
Harald Welte5258fc42009-03-28 19:07:53 +00001826 return CMD_SUCCESS;
1827}
1828
Harald Welte78f2f502009-05-23 16:56:52 +00001829DEFUN(cfg_bts_bsic,
1830 cfg_bts_bsic_cmd,
1831 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001832 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1833 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001834{
1835 struct gsm_bts *bts = vty->index;
1836 int bsic = atoi(argv[0]);
1837
1838 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001839 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001840 bsic, VTY_NEWLINE);
1841 return CMD_WARNING;
1842 }
1843 bts->bsic = bsic;
1844
1845 return CMD_SUCCESS;
1846}
1847
Harald Welte4cc34222009-05-01 15:12:31 +00001848DEFUN(cfg_bts_unit_id,
1849 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001850 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001851 "Abis/IP specific options\n"
1852 "Set the IPA BTS Unit ID\n"
1853 "Unit ID (Site)\n"
1854 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001855{
1856 struct gsm_bts *bts = vty->index;
1857 int site_id = atoi(argv[0]);
1858 int bts_id = atoi(argv[1]);
1859
Harald Welte07dc73d2009-08-07 13:27:09 +02001860 if (!is_ipaccess_bts(bts)) {
1861 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1862 return CMD_WARNING;
1863 }
1864
Harald Welte4cc34222009-05-01 15:12:31 +00001865 bts->ip_access.site_id = site_id;
1866 bts->ip_access.bts_id = bts_id;
1867
1868 return CMD_SUCCESS;
1869}
1870
Harald Welte8b291802013-03-12 13:57:05 +01001871DEFUN(cfg_bts_rsl_ip,
1872 cfg_bts_rsl_ip_cmd,
1873 "ip.access rsl-ip A.B.C.D",
1874 "Abis/IP specific options\n"
1875 "Set the IPA RSL IP Address of the BSC\n"
1876 "Destination IP address for RSL connection\n")
1877{
1878 struct gsm_bts *bts = vty->index;
1879 struct in_addr ia;
1880
1881 if (!is_ipaccess_bts(bts)) {
1882 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1883 return CMD_WARNING;
1884 }
1885
1886 inet_aton(argv[0], &ia);
1887 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1888
1889 return CMD_SUCCESS;
1890}
1891
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001892#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001893
Sylvain Munautc9519462011-10-17 14:04:55 +02001894DEFUN(cfg_bts_nokia_site_skip_reset,
1895 cfg_bts_nokia_site_skip_reset_cmd,
1896 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001897 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001898 "Skip the reset step during bootstrap process of this BTS\n"
1899 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02001900{
1901 struct gsm_bts *bts = vty->index;
1902
1903 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
1904 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
1905 return CMD_WARNING;
1906 }
1907
1908 bts->nokia.skip_reset = atoi(argv[0]);
1909
1910 return CMD_SUCCESS;
1911}
1912
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001913DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
1914 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
1915 "nokia_site no-local-rel-conf (0|1)",
1916 NOKIA_STR
1917 "Do not wait for RELease CONFirm message when releasing channel locally\n"
1918 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
1919{
1920 struct gsm_bts *bts = vty->index;
1921
1922 if (!is_nokia_bts(bts)) {
1923 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1924 VTY_NEWLINE);
1925 return CMD_WARNING;
1926 }
1927
1928 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
1929
1930 return CMD_SUCCESS;
1931}
1932
Sipos Csaba56e17662015-02-07 13:27:36 +01001933DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
1934 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
1935 "nokia_site bts-reset-timer <15-100>",
1936 NOKIA_STR
1937 "The amount of time (in sec.) between BTS_RESET is sent,\n"
1938 "and the BTS is being bootstrapped.\n")
1939{
1940 struct gsm_bts *bts = vty->index;
1941
1942 if (!is_nokia_bts(bts)) {
1943 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1944 VTY_NEWLINE);
1945 return CMD_WARNING;
1946 }
1947
1948 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
1949
1950 return CMD_SUCCESS;
1951}
Harald Welte8f0ed552010-05-11 21:53:49 +02001952#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001953#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001954
Harald Welte8175e952009-10-20 00:22:00 +02001955DEFUN(cfg_bts_stream_id,
1956 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001957 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02001958 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001959 "Set the ip.access Stream ID of the OML link of this BTS\n"
1960 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02001961{
1962 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001963 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02001964
1965 if (!is_ipaccess_bts(bts)) {
1966 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1967 return CMD_WARNING;
1968 }
1969
1970 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001971 /* This is used by e1inp_bind_ops callback for each BTS model. */
1972 bts->oml_e1_link.e1_nr = linenr;
1973
1974 return CMD_SUCCESS;
1975}
1976
Harald Welted13e0cd2012-08-17 09:52:03 +02001977#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02001978
Harald Welte42581822009-08-08 16:12:58 +02001979DEFUN(cfg_bts_oml_e1,
1980 cfg_bts_oml_e1_cmd,
1981 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02001982 OML_E1_STR
1983 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001984 "E1/T1 line number to be used for OML\n"
1985 "E1/T1 timeslot to be used for OML\n"
1986 "E1/T1 timeslot to be used for OML\n"
1987 "E1/T1 sub-slot to be used for OML\n"
1988 "Use E1/T1 sub-slot 0\n"
1989 "Use E1/T1 sub-slot 1\n"
1990 "Use E1/T1 sub-slot 2\n"
1991 "Use E1/T1 sub-slot 3\n"
1992 "Use full E1 slot 3\n"
1993 )
Harald Welte42581822009-08-08 16:12:58 +02001994{
1995 struct gsm_bts *bts = vty->index;
1996
1997 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
1998
1999 return CMD_SUCCESS;
2000}
2001
2002
2003DEFUN(cfg_bts_oml_e1_tei,
2004 cfg_bts_oml_e1_tei_cmd,
2005 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002006 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002007 "Set the TEI to be used for OML\n"
2008 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002009{
2010 struct gsm_bts *bts = vty->index;
2011
2012 bts->oml_tei = atoi(argv[0]);
2013
2014 return CMD_SUCCESS;
2015}
2016
Harald Welte7a8fa412009-08-10 13:48:16 +02002017DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2018 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002019 "Channnel Allocator\n" "Channel Allocator\n"
2020 "Allocate Timeslots and Transceivers in ascending order\n"
2021 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002022{
2023 struct gsm_bts *bts = vty->index;
2024
2025 if (!strcmp(argv[0], "ascending"))
2026 bts->chan_alloc_reverse = 0;
2027 else
2028 bts->chan_alloc_reverse = 1;
2029
2030 return CMD_SUCCESS;
2031}
2032
Harald Welte8f0ed552010-05-11 21:53:49 +02002033#define RACH_STR "Random Access Control Channel\n"
2034
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002035DEFUN(cfg_bts_rach_tx_integer,
2036 cfg_bts_rach_tx_integer_cmd,
2037 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002038 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002039 "Set the raw tx integer value in RACH Control parameters IE\n"
2040 "Set the raw tx integer value in RACH Control parameters IE\n"
2041 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002042{
2043 struct gsm_bts *bts = vty->index;
2044 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2045 return CMD_SUCCESS;
2046}
2047
2048DEFUN(cfg_bts_rach_max_trans,
2049 cfg_bts_rach_max_trans_cmd,
2050 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002051 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002052 "Set the maximum number of RACH burst transmissions\n"
2053 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002054 "Maximum number of 1 RACH burst transmissions\n"
2055 "Maximum number of 2 RACH burst transmissions\n"
2056 "Maximum number of 4 RACH burst transmissions\n"
2057 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002058{
2059 struct gsm_bts *bts = vty->index;
2060 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2061 return CMD_SUCCESS;
2062}
2063
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002064#define CD_STR "Channel Description\n"
2065
2066DEFUN(cfg_bts_chan_desc_att,
2067 cfg_bts_chan_desc_att_cmd,
2068 "channel-descrption attach (0|1)",
2069 CD_STR
2070 "Set if attachment is required\n"
2071 "Attachment is NOT required\n"
2072 "Attachment is required (standard)\n")
2073{
2074 struct gsm_bts *bts = vty->index;
2075 bts->si_common.chan_desc.att = atoi(argv[0]);
2076 return CMD_SUCCESS;
2077}
2078
2079DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2080 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2081 "channel-descrption bs-pa-mfrms <2-9>",
2082 CD_STR
2083 "Set number of multiframe periods for paging groups\n"
2084 "Number of multiframe periods for paging groups\n")
2085{
2086 struct gsm_bts *bts = vty->index;
2087 int bs_pa_mfrms = atoi(argv[0]);
2088
2089 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2090 return CMD_SUCCESS;
2091}
2092
2093DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2094 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2095 "channel-descrption bs-ag-blks-res <0-7>",
2096 CD_STR
2097 "Set number of blocks reserved for access grant\n"
2098 "Number of blocks reserved for access grant\n")
2099{
2100 struct gsm_bts *bts = vty->index;
2101 int bs_ag_blks_res = atoi(argv[0]);
2102
2103 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2104 return CMD_SUCCESS;
2105}
2106
Harald Welte8f0ed552010-05-11 21:53:49 +02002107#define NM_STR "Network Management\n"
2108
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002109DEFUN(cfg_bts_rach_nm_b_thresh,
2110 cfg_bts_rach_nm_b_thresh_cmd,
2111 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002112 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002113 "Set the NM Busy Threshold\n"
2114 "Set the NM Busy Threshold\n"
2115 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002116{
2117 struct gsm_bts *bts = vty->index;
2118 bts->rach_b_thresh = atoi(argv[0]);
2119 return CMD_SUCCESS;
2120}
2121
2122DEFUN(cfg_bts_rach_nm_ldavg,
2123 cfg_bts_rach_nm_ldavg_cmd,
2124 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002125 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002126 "Set the NM Loadaverage Slots value\n"
2127 "Set the NM Loadaverage Slots value\n"
2128 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002129{
2130 struct gsm_bts *bts = vty->index;
2131 bts->rach_ldavg_slots = atoi(argv[0]);
2132 return CMD_SUCCESS;
2133}
2134
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002135DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2136 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002137 "Should this cell be barred from access?\n"
2138 "Should this cell be barred from access?\n"
2139 "Cell should NOT be barred\n"
2140 "Cell should be barred\n")
2141
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002142{
2143 struct gsm_bts *bts = vty->index;
2144
Harald Welte71355012009-12-21 23:08:18 +01002145 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002146
2147 return CMD_SUCCESS;
2148}
2149
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002150DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2151 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002152 RACH_STR
2153 "Should this cell allow emergency calls?\n"
2154 "Should this cell allow emergency calls?\n"
2155 "Should this cell allow emergency calls?\n"
2156 "Do NOT allow emergency calls\n"
2157 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002158{
2159 struct gsm_bts *bts = vty->index;
2160
2161 if (atoi(argv[0]) == 0)
2162 bts->si_common.rach_control.t2 |= 0x4;
2163 else
2164 bts->si_common.rach_control.t2 &= ~0x4;
2165
2166 return CMD_SUCCESS;
2167}
2168
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002169DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2170 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2171 RACH_STR
2172 "Set access control class\n"
2173 "Access control class 0\n"
2174 "Access control class 1\n"
2175 "Access control class 2\n"
2176 "Access control class 3\n"
2177 "Access control class 4\n"
2178 "Access control class 5\n"
2179 "Access control class 6\n"
2180 "Access control class 7\n"
2181 "Access control class 8\n"
2182 "Access control class 9\n"
2183 "Access control class 11 for PLMN use\n"
2184 "Access control class 12 for security services\n"
2185 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2186 "Access control class 14 for emergency services\n"
2187 "Access control class 15 for PLMN staff\n"
2188 "barred to use access control class\n"
2189 "allowed to use access control class\n")
2190{
2191 struct gsm_bts *bts = vty->index;
2192
2193 uint8_t control_class;
2194 uint8_t allowed = 0;
2195
2196 if (strcmp(argv[1], "allowed") == 0)
2197 allowed = 1;
2198
2199 control_class = atoi(argv[0]);
2200 if (control_class < 8)
2201 if (allowed)
2202 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2203 else
2204 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2205 else
2206 if (allowed)
2207 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2208 else
2209 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2210
2211 return CMD_SUCCESS;
2212}
2213
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002214DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2215 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002216 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002217 "Maximum transmit power of the MS\n"
2218 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002219 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002220{
2221 struct gsm_bts *bts = vty->index;
2222
2223 bts->ms_max_power = atoi(argv[0]);
2224
2225 return CMD_SUCCESS;
2226}
2227
Harald Weltecfaabbb2012-08-16 23:23:50 +02002228#define CELL_STR "Cell Parameters\n"
2229
Harald Welte73225282009-12-12 18:17:25 +01002230DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2231 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002232 CELL_STR "Cell re-selection parameters\n"
2233 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002234 "Cell Re-Selection Hysteresis in dB")
2235{
2236 struct gsm_bts *bts = vty->index;
2237
2238 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2239
2240 return CMD_SUCCESS;
2241}
2242
2243DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2244 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002245 "Minimum RxLev needed for cell access\n"
2246 "Minimum RxLev needed for cell access\n"
2247 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002248 "Minimum RxLev needed for cell access (better than -110dBm)")
2249{
2250 struct gsm_bts *bts = vty->index;
2251
2252 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2253
2254 return CMD_SUCCESS;
2255}
2256
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002257DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2258 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002259 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2260 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002261{
2262 struct gsm_bts *bts = vty->index;
2263
2264 bts->si_common.cell_ro_sel_par.present = 1;
2265 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2266
2267 return CMD_SUCCESS;
2268}
2269
2270DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2271 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002272 CELL_STR "Cell Re-Selection Parameters\n"
2273 "Cell Re-Selection Offset (CRO) in dB\n"
2274 "Cell Re-Selection Offset (CRO) in dB\n"
2275 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002276{
2277 struct gsm_bts *bts = vty->index;
2278
2279 bts->si_common.cell_ro_sel_par.present = 1;
2280 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2281
2282 return CMD_SUCCESS;
2283}
2284
2285DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2286 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002287 "Cell selection temporary negative offset\n"
2288 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002289 "Cell selection temporary negative offset in dB")
2290{
2291 struct gsm_bts *bts = vty->index;
2292
2293 bts->si_common.cell_ro_sel_par.present = 1;
2294 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2295
2296 return CMD_SUCCESS;
2297}
2298
2299DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2300 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002301 "Cell selection temporary negative offset\n"
2302 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002303 "Sets cell selection temporary negative offset to infinity")
2304{
2305 struct gsm_bts *bts = vty->index;
2306
2307 bts->si_common.cell_ro_sel_par.present = 1;
2308 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2309
2310 return CMD_SUCCESS;
2311}
2312
2313DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2314 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002315 "Cell selection penalty time\n"
2316 "Cell selection penalty time\n"
2317 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002318{
2319 struct gsm_bts *bts = vty->index;
2320
2321 bts->si_common.cell_ro_sel_par.present = 1;
2322 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2323
2324 return CMD_SUCCESS;
2325}
2326
2327DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2328 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002329 "Cell selection penalty time\n"
2330 "Cell selection penalty time\n"
2331 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002332 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2333 "and TEMPORARY_OFFSET is ignored)")
2334{
2335 struct gsm_bts *bts = vty->index;
2336
2337 bts->si_common.cell_ro_sel_par.present = 1;
2338 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2339
2340 return CMD_SUCCESS;
2341}
2342
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002343DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2344 "radio-link-timeout <4-64>",
2345 "Radio link timeout criterion (BTS side)\n"
2346 "Radio link timeout value (lost SACCH block)\n")
2347{
2348 struct gsm_bts *bts = vty->index;
2349
Harald Welte2f8b9d22017-06-18 11:12:13 +03002350 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2351
2352 return CMD_SUCCESS;
2353}
2354
2355DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2356 "radio-link-timeout infinite",
2357 "Radio link timeout criterion (BTS side)\n"
2358 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2359{
2360 struct gsm_bts *bts = vty->index;
2361
2362 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2363 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2364 return CMD_WARNING;
2365 }
2366
2367 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2368 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002369
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002370 return CMD_SUCCESS;
2371}
2372
Harald Welte8f0ed552010-05-11 21:53:49 +02002373#define GPRS_TEXT "GPRS Packet Network\n"
2374
Harald Welteaf387632010-03-14 23:30:30 +08002375DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002376 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002377 GPRS_TEXT
2378 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002379 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002380 "GPRS BSSGP VC Identifier")
2381{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002382 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002383 struct gsm_bts *bts = vty->index;
2384
Harald Welte4511d892010-04-18 15:51:20 +02002385 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002386 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2387 return CMD_WARNING;
2388 }
2389
Harald Welte97a282b2010-03-14 15:37:43 +08002390 bts->gprs.cell.bvci = atoi(argv[0]);
2391
2392 return CMD_SUCCESS;
2393}
2394
Harald Weltea5731cf2010-03-22 11:48:36 +08002395DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2396 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002397 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002398 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002399 "GPRS NS Entity Identifier")
2400{
2401 struct gsm_bts *bts = vty->index;
2402
Harald Welte4511d892010-04-18 15:51:20 +02002403 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002404 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2405 return CMD_WARNING;
2406 }
2407
2408 bts->gprs.nse.nsei = atoi(argv[0]);
2409
2410 return CMD_SUCCESS;
2411}
2412
Harald Welte8f0ed552010-05-11 21:53:49 +02002413#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2414 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002415
Harald Welte97a282b2010-03-14 15:37:43 +08002416DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2417 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002418 GPRS_TEXT NSVC_TEXT
2419 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002420 "GPRS NS VC Identifier")
2421{
2422 struct gsm_bts *bts = vty->index;
2423 int idx = atoi(argv[0]);
2424
Harald Welte4511d892010-04-18 15:51:20 +02002425 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002426 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2427 return CMD_WARNING;
2428 }
2429
Harald Welte97a282b2010-03-14 15:37:43 +08002430 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2431
2432 return CMD_SUCCESS;
2433}
2434
Harald Welteaf387632010-03-14 23:30:30 +08002435DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2436 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002437 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002438 "GPRS NS Local UDP Port\n"
2439 "GPRS NS Local UDP Port\n"
2440 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002441 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002442{
2443 struct gsm_bts *bts = vty->index;
2444 int idx = atoi(argv[0]);
2445
Harald Welte4511d892010-04-18 15:51:20 +02002446 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002447 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2448 return CMD_WARNING;
2449 }
2450
Harald Welteaf387632010-03-14 23:30:30 +08002451 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2452
2453 return CMD_SUCCESS;
2454}
2455
2456DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2457 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002458 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002459 "GPRS NS Remote UDP Port\n"
2460 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002461 "GPRS NS Remote UDP Port\n"
2462 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002463{
2464 struct gsm_bts *bts = vty->index;
2465 int idx = atoi(argv[0]);
2466
Harald Welte4511d892010-04-18 15:51:20 +02002467 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002468 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2469 return CMD_WARNING;
2470 }
2471
Harald Welteaf387632010-03-14 23:30:30 +08002472 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2473
2474 return CMD_SUCCESS;
2475}
2476
2477DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2478 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002479 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002480 "GPRS NS Remote IP Address\n"
2481 "GPRS NS Remote IP Address\n"
2482 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002483{
2484 struct gsm_bts *bts = vty->index;
2485 int idx = atoi(argv[0]);
2486 struct in_addr ia;
2487
Harald Welte4511d892010-04-18 15:51:20 +02002488 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002489 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2490 return CMD_WARNING;
2491 }
2492
Harald Welteaf387632010-03-14 23:30:30 +08002493 inet_aton(argv[1], &ia);
2494 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2495
2496 return CMD_SUCCESS;
2497}
2498
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002499DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002500 "paging free <-1-1024>",
2501 "Paging options\n"
2502 "Only page when having a certain amount of free slots\n"
2503 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002504{
2505 struct gsm_bts *bts = vty->index;
2506
2507 bts->paging.free_chans_need = atoi(argv[0]);
2508 return CMD_SUCCESS;
2509}
2510
Harald Welte615e9562010-05-11 23:50:21 +02002511DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2512 "gprs ns timer " NS_TIMERS " <0-255>",
2513 GPRS_TEXT "Network Service\n"
2514 "Network Service Timer\n"
2515 NS_TIMERS_HELP "Timer Value\n")
2516{
2517 struct gsm_bts *bts = vty->index;
2518 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2519 int val = atoi(argv[1]);
2520
2521 if (bts->gprs.mode == BTS_GPRS_NONE) {
2522 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2523 return CMD_WARNING;
2524 }
2525
2526 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2527 return CMD_WARNING;
2528
2529 bts->gprs.nse.timer[idx] = val;
2530
2531 return CMD_SUCCESS;
2532}
2533
2534#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 +02002535#define BSSGP_TIMERS_HELP \
2536 "Tbvc-block timeout\n" \
2537 "Tbvc-block retries\n" \
2538 "Tbvc-unblock retries\n" \
2539 "Tbvcc-reset timeout\n" \
2540 "Tbvc-reset retries\n" \
2541 "Tbvc-suspend timeout\n" \
2542 "Tbvc-suspend retries\n" \
2543 "Tbvc-resume timeout\n" \
2544 "Tbvc-resume retries\n" \
2545 "Tbvc-capa-update timeout\n" \
2546 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002547
2548DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2549 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2550 GPRS_TEXT "Cell / BSSGP\n"
2551 "Cell/BSSGP Timer\n"
2552 BSSGP_TIMERS_HELP "Timer Value\n")
2553{
2554 struct gsm_bts *bts = vty->index;
2555 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2556 int val = atoi(argv[1]);
2557
2558 if (bts->gprs.mode == BTS_GPRS_NONE) {
2559 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2560 return CMD_WARNING;
2561 }
2562
2563 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2564 return CMD_WARNING;
2565
2566 bts->gprs.cell.timer[idx] = val;
2567
2568 return CMD_SUCCESS;
2569}
2570
Harald Welte97a282b2010-03-14 15:37:43 +08002571DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2572 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002573 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002574 "GPRS Routing Area Code\n"
2575 "GPRS Routing Area Code\n"
2576 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002577{
2578 struct gsm_bts *bts = vty->index;
2579
Harald Welte4511d892010-04-18 15:51:20 +02002580 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002581 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2582 return CMD_WARNING;
2583 }
2584
Harald Welte97a282b2010-03-14 15:37:43 +08002585 bts->gprs.rac = atoi(argv[0]);
2586
2587 return CMD_SUCCESS;
2588}
2589
Max292ec582016-07-28 11:55:37 +02002590DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2591 "gprs control-ack-type-rach", GPRS_TEXT
2592 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2593 "four access bursts format instead of default RLC/MAC control block\n")
2594{
2595 struct gsm_bts *bts = vty->index;
2596
2597 if (bts->gprs.mode == BTS_GPRS_NONE) {
2598 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2599 return CMD_WARNING;
2600 }
2601
2602 bts->gprs.ctrl_ack_type_use_block = false;
2603
2604 return CMD_SUCCESS;
2605}
2606
2607DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2608 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2609 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2610 "four access bursts format instead of default RLC/MAC control block\n")
2611{
2612 struct gsm_bts *bts = vty->index;
2613
2614 if (bts->gprs.mode == BTS_GPRS_NONE) {
2615 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2616 return CMD_WARNING;
2617 }
2618
2619 bts->gprs.ctrl_ack_type_use_block = true;
2620
2621 return CMD_SUCCESS;
2622}
2623
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002624DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2625 "gprs network-control-order (nc0|nc1|nc2)",
2626 GPRS_TEXT
2627 "GPRS Network Control Order\n"
2628 "MS controlled cell re-selection, no measurement reporting\n"
2629 "MS controlled cell re-selection, MS sends measurement reports\n"
2630 "Network controlled cell re-selection, MS sends measurement reports\n")
2631{
2632 struct gsm_bts *bts = vty->index;
2633
2634 if (bts->gprs.mode == BTS_GPRS_NONE) {
2635 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2636 return CMD_WARNING;
2637 }
2638
2639 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2640
2641 return CMD_SUCCESS;
2642}
2643
Harald Welte4511d892010-04-18 15:51:20 +02002644DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2645 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002646 GPRS_TEXT
2647 "GPRS Mode for this BTS\n"
2648 "GPRS Disabled on this BTS\n"
2649 "GPRS Enabled on this BTS\n"
2650 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002651{
2652 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002653 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002654
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002655 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002656 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2657 VTY_NEWLINE);
2658 return CMD_WARNING;
2659 }
2660
2661 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002662
2663 return CMD_SUCCESS;
2664}
2665
bhargava350533c2016-07-21 11:14:34 +05302666DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2667 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2668 "gprs 11bit_rach_support_for_egprs (0|1)",
2669 GPRS_TEXT "11 bit RACH options\n"
2670 "Disable 11 bit RACH for EGPRS\n"
2671 "Enable 11 bit RACH for EGPRS")
2672{
2673 struct gsm_bts *bts = vty->index;
2674
2675 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2676
2677 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2678 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2679 return CMD_WARNING;
2680 }
2681
2682 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2683 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2684 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2685 " enabled%s", VTY_NEWLINE);
2686 return CMD_WARNING;
2687 }
2688
2689 return CMD_SUCCESS;
2690}
2691
Harald Welte9fbff4a2010-07-30 11:50:09 +02002692#define SI_TEXT "System Information Messages\n"
2693#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)"
2694#define SI_TYPE_HELP "System Information Type 1\n" \
2695 "System Information Type 2\n" \
2696 "System Information Type 3\n" \
2697 "System Information Type 4\n" \
2698 "System Information Type 5\n" \
2699 "System Information Type 6\n" \
2700 "System Information Type 7\n" \
2701 "System Information Type 8\n" \
2702 "System Information Type 9\n" \
2703 "System Information Type 10\n" \
2704 "System Information Type 13\n" \
2705 "System Information Type 16\n" \
2706 "System Information Type 17\n" \
2707 "System Information Type 18\n" \
2708 "System Information Type 19\n" \
2709 "System Information Type 20\n" \
2710 "System Information Type 2bis\n" \
2711 "System Information Type 2ter\n" \
2712 "System Information Type 2quater\n" \
2713 "System Information Type 5bis\n" \
2714 "System Information Type 5ter\n"
2715
2716DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2717 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2718 SI_TEXT SI_TYPE_HELP
2719 "System Information Mode\n"
2720 "Static user-specified\n"
2721 "Dynamic, BSC-computed\n")
2722{
2723 struct gsm_bts *bts = vty->index;
2724 int type;
2725
2726 type = get_string_value(osmo_sitype_strs, argv[0]);
2727 if (type < 0) {
2728 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2729 return CMD_WARNING;
2730 }
2731
2732 if (!strcmp(argv[1], "static"))
2733 bts->si_mode_static |= (1 << type);
2734 else
2735 bts->si_mode_static &= ~(1 << type);
2736
2737 return CMD_SUCCESS;
2738}
2739
2740DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2741 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2742 SI_TEXT SI_TYPE_HELP
2743 "Static System Information filling\n"
2744 "Static user-specified SI content in HEX notation\n")
2745{
2746 struct gsm_bts *bts = vty->index;
2747 int rc, type;
2748
2749 type = get_string_value(osmo_sitype_strs, argv[0]);
2750 if (type < 0) {
2751 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2752 return CMD_WARNING;
2753 }
2754
2755 if (!(bts->si_mode_static & (1 << type))) {
2756 vty_out(vty, "SI Type %s is not configured in static mode%s",
2757 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2758 return CMD_WARNING;
2759 }
2760
Harald Welte290aaed2010-07-30 11:53:18 +02002761 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002762 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002763
2764 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002765 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2766 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002767 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2768 return CMD_WARNING;
2769 }
2770
2771 /* Mark this SI as present */
2772 bts->si_valid |= (1 << type);
2773
2774 return CMD_SUCCESS;
2775}
2776
Harald Welte42def722017-01-13 00:10:32 +01002777DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2778 "early-classmark-sending (allowed|forbidden)",
2779 "Early Classmark Sending\n"
2780 "Early Classmark Sending is allowed\n"
2781 "Early Classmark Sending is forbidden\n")
2782{
2783 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002784
2785 if (!strcmp(argv[0], "allowed"))
2786 bts->early_classmark_allowed = true;
2787 else
2788 bts->early_classmark_allowed = false;
2789
2790 return CMD_SUCCESS;
2791}
2792
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002793DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2794 "early-classmark-sending-3g (allowed|forbidden)",
2795 "3G Early Classmark Sending\n"
2796 "3G Early Classmark Sending is allowed\n"
2797 "3G Early Classmark Sending is forbidden\n")
2798{
2799 struct gsm_bts *bts = vty->index;
2800
2801 if (!strcmp(argv[0], "allowed"))
2802 bts->early_classmark_allowed_3g = true;
2803 else
2804 bts->early_classmark_allowed_3g = false;
2805
2806 return CMD_SUCCESS;
2807}
2808
Harald Welte32c09622011-01-11 23:44:56 +01002809DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002810 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002811 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002812 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2813 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002814{
2815 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002816 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002817
Harald Welte64c07d22011-02-15 11:43:27 +01002818 switch (mode) {
2819 case NL_MODE_MANUAL_SI5SEP:
2820 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002821 /* make sure we clear the current list when switching to
2822 * manual mode */
2823 if (bts->neigh_list_manual_mode == 0)
2824 memset(&bts->si_common.data.neigh_list, 0,
2825 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002826 break;
2827 default:
2828 break;
2829 }
2830
2831 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002832
2833 return CMD_SUCCESS;
2834}
2835
2836DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002837 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002838 "Neighbor List\n" "Add to manual neighbor list\n"
2839 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2840 "ARFCN of neighbor\n")
2841{
2842 struct gsm_bts *bts = vty->index;
2843 struct bitvec *bv = &bts->si_common.neigh_list;
2844 uint16_t arfcn = atoi(argv[1]);
2845
2846 if (!bts->neigh_list_manual_mode) {
2847 vty_out(vty, "%% Cannot configure neighbor list in "
2848 "automatic mode%s", VTY_NEWLINE);
2849 return CMD_WARNING;
2850 }
2851
2852 if (!strcmp(argv[0], "add"))
2853 bitvec_set_bit_pos(bv, arfcn, 1);
2854 else
2855 bitvec_set_bit_pos(bv, arfcn, 0);
2856
2857 return CMD_SUCCESS;
2858}
2859
Max70fdd242017-06-15 15:10:53 +02002860/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002861DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002862 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2863 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2864 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2865 "Add to manual SI2quater neighbor list\n"
2866 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2867 "threshold high bits\n" "threshold high bits\n"
2868 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2869 "priority\n" "priority (8 means NA)\n"
2870 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2871 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002872{
2873 struct gsm_bts *bts = vty->index;
2874 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2875 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002876 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2877 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002878 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002879
Max70fdd242017-06-15 15:10:53 +02002880 switch (r) {
2881 case 1:
2882 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2883 thresh_hi, VTY_NEWLINE);
2884 break;
2885 case EARFCN_THRESH_LOW_INVALID:
2886 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2887 thresh_lo, VTY_NEWLINE);
2888 break;
2889 case EARFCN_QRXLV_INVALID + 1:
2890 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2891 qrx, VTY_NEWLINE);
2892 break;
2893 case EARFCN_PRIO_INVALID:
2894 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
2895 prio, VTY_NEWLINE);
2896 break;
2897 default:
2898 if (r < 0) {
2899 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
2900 return CMD_WARNING;
2901 }
Max59a1bf32016-04-15 16:04:46 +02002902 }
2903
Max70fdd242017-06-15 15:10:53 +02002904 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01002905 return CMD_SUCCESS;
2906
Maxf39d03a2017-05-12 17:00:30 +02002907 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02002908 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02002909 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01002910
Maxaafff962016-04-20 15:57:14 +02002911 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02002912}
2913
2914DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02002915 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02002916 "SI2quater Neighbor List\n"
2917 "SI2quater Neighbor List\n"
2918 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02002919 "EARFCN of neighbor\n"
2920 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02002921{
2922 struct gsm_bts *bts = vty->index;
2923 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02002924 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02002925 int r = osmo_earfcn_del(e, arfcn);
2926 if (r < 0) {
2927 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02002928 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02002929 return CMD_WARNING;
2930 }
2931
2932 return CMD_SUCCESS;
2933}
2934
Max26679e02016-04-20 15:57:13 +02002935DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02002936 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02002937 "SI2quater Neighbor List\n"
2938 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
2939 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
2940 "diversity bit\n")
2941{
2942 struct gsm_bts *bts = vty->index;
2943 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
2944
2945 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
2946 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02002947 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 +01002948 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02002949 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02002950 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
2951 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01002952 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02002953 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02002954 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02002955 return CMD_WARNING;
2956 }
2957
2958 return CMD_SUCCESS;
2959}
2960
2961DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02002962 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02002963 "SI2quater Neighbor List\n"
2964 "SI2quater Neighbor List\n"
2965 "Delete from SI2quater manual neighbor list\n"
2966 "UARFCN of neighbor\n"
2967 "UARFCN\n"
2968 "scrambling code\n")
2969{
2970 struct gsm_bts *bts = vty->index;
2971
2972 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
2973 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
2974 VTY_NEWLINE);
2975 return CMD_WARNING;
2976 }
2977
2978 return CMD_SUCCESS;
2979}
2980
Harald Welte64c07d22011-02-15 11:43:27 +01002981DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002982 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002983 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002984 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
2985 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
2986 "ARFCN of neighbor\n")
2987{
2988 struct gsm_bts *bts = vty->index;
2989 struct bitvec *bv = &bts->si_common.si5_neigh_list;
2990 uint16_t arfcn = atoi(argv[1]);
2991
2992 if (!bts->neigh_list_manual_mode) {
2993 vty_out(vty, "%% Cannot configure neighbor list in "
2994 "automatic mode%s", VTY_NEWLINE);
2995 return CMD_WARNING;
2996 }
2997
2998 if (!strcmp(argv[0], "add"))
2999 bitvec_set_bit_pos(bv, arfcn, 1);
3000 else
3001 bitvec_set_bit_pos(bv, arfcn, 0);
3002
3003 return CMD_SUCCESS;
3004}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003005
Harald Welte8254cf72017-05-29 13:42:19 +02003006DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3007 "pcu-socket PATH",
3008 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3009 "Path in the file system for the unix-domain PCU socket\n")
3010{
3011 struct gsm_bts *bts = vty->index;
3012 int rc;
3013
Harald Welte4a824ca2017-05-29 13:54:27 +02003014 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003015 pcu_sock_exit(bts);
3016 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3017 if (rc < 0) {
3018 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3019 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3020 return CMD_WARNING;
3021 }
3022
3023 return CMD_SUCCESS;
3024}
3025
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003026#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3027
3028DEFUN(cfg_bts_excl_rf_lock,
3029 cfg_bts_excl_rf_lock_cmd,
3030 "rf-lock-exclude",
3031 EXCL_RFLOCK_STR)
3032{
3033 struct gsm_bts *bts = vty->index;
3034 bts->excl_from_rf_lock = 1;
3035 return CMD_SUCCESS;
3036}
3037
3038DEFUN(cfg_bts_no_excl_rf_lock,
3039 cfg_bts_no_excl_rf_lock_cmd,
3040 "no rf-lock-exclude",
3041 NO_STR EXCL_RFLOCK_STR)
3042{
3043 struct gsm_bts *bts = vty->index;
3044 bts->excl_from_rf_lock = 0;
3045 return CMD_SUCCESS;
3046}
3047
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003048#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3049
3050DEFUN(cfg_bts_force_comb_si,
3051 cfg_bts_force_comb_si_cmd,
3052 "force-combined-si",
3053 FORCE_COMB_SI_STR)
3054{
3055 struct gsm_bts *bts = vty->index;
3056 bts->force_combined_si = 1;
3057 return CMD_SUCCESS;
3058}
3059
3060DEFUN(cfg_bts_no_force_comb_si,
3061 cfg_bts_no_force_comb_si_cmd,
3062 "no force-combined-si",
3063 NO_STR FORCE_COMB_SI_STR)
3064{
3065 struct gsm_bts *bts = vty->index;
3066 bts->force_combined_si = 0;
3067 return CMD_SUCCESS;
3068}
3069
Andreas Eversberga83d5112013-12-07 18:32:28 +01003070static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3071{
3072 struct gsm_bts *bts = vty->index;
3073 struct bts_codec_conf *codec = &bts->codec;
3074 int i;
3075
3076 codec->hr = 0;
3077 codec->efr = 0;
3078 codec->amr = 0;
3079 for (i = 0; i < argc; i++) {
3080 if (!strcmp(argv[i], "hr"))
3081 codec->hr = 1;
3082 if (!strcmp(argv[i], "efr"))
3083 codec->efr = 1;
3084 if (!strcmp(argv[i], "amr"))
3085 codec->amr = 1;
3086 }
3087}
3088
3089#define CODEC_PAR_STR " (hr|efr|amr)"
3090#define CODEC_HELP_STR "Half Rate\n" \
3091 "Enhanced Full Rate\nAdaptive Multirate\n"
3092
3093DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3094 "codec-support fr",
3095 "Codec Support settings\nFullrate\n")
3096{
3097 _get_codec_from_arg(vty, 0, argv);
3098 return CMD_SUCCESS;
3099}
3100
3101DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3102 "codec-support fr" CODEC_PAR_STR,
3103 "Codec Support settings\nFullrate\n"
3104 CODEC_HELP_STR)
3105{
3106 _get_codec_from_arg(vty, 1, argv);
3107 return CMD_SUCCESS;
3108}
3109
3110DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3111 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3112 "Codec Support settings\nFullrate\n"
3113 CODEC_HELP_STR CODEC_HELP_STR)
3114{
3115 _get_codec_from_arg(vty, 2, argv);
3116 return CMD_SUCCESS;
3117}
3118
3119DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3120 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3121 "Codec Support settings\nFullrate\n"
3122 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3123{
3124 _get_codec_from_arg(vty, 3, argv);
3125 return CMD_SUCCESS;
3126}
3127
3128DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3129 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3130 "Codec Support settings\nFullrate\n"
3131 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3132{
3133 _get_codec_from_arg(vty, 4, argv);
3134 return CMD_SUCCESS;
3135}
3136
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003137DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3138 "depends-on-bts <0-255>",
3139 "This BTS can only be started if another one is up\n" "BTS Number\n")
3140{
3141 struct gsm_bts *bts = vty->index;
3142 struct gsm_bts *other_bts;
3143 int dep = atoi(argv[0]);
3144
3145
3146 if (!is_ipaccess_bts(bts)) {
3147 vty_out(vty, "This feature is only available for IP systems.%s",
3148 VTY_NEWLINE);
3149 return CMD_WARNING;
3150 }
3151
3152 other_bts = gsm_bts_num(bts->network, dep);
3153 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3154 vty_out(vty, "This feature is only available for IP systems.%s",
3155 VTY_NEWLINE);
3156 return CMD_WARNING;
3157 }
3158
3159 if (dep >= bts->nr) {
3160 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3161 VTY_NEWLINE);
3162 return CMD_WARNING;
3163 }
3164
3165 bts_depend_mark(bts, dep);
3166 return CMD_SUCCESS;
3167}
3168
3169DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3170 "depeneds-on-bts <0-255>",
3171 NO_STR "This BTS can only be started if another one is up\n"
3172 "BTS Number\n")
3173{
3174 struct gsm_bts *bts = vty->index;
3175 int dep = atoi(argv[0]);
3176
3177 bts_depend_clear(bts, dep);
3178 return CMD_SUCCESS;
3179}
3180
Andreas Eversberg73266522014-01-19 11:47:44 +01003181#define AMR_TEXT "Adaptive Multi Rate settings\n"
3182#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3183#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3184 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3185#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3186#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3187
3188static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3189{
3190 struct gsm_bts *bts = vty->index;
3191 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3192 struct gsm48_multi_rate_conf *mr_conf =
3193 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3194 int i;
3195
3196 mr->gsm48_ie[1] = 0;
3197 for (i = 0; i < argc; i++)
3198 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3199 mr_conf->icmi = 0;
3200}
3201
3202static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3203{
3204 struct gsm_bts *bts = vty->index;
3205 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003206 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003207 int i;
3208
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003209 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3210 for (i = 0; i < argc - 1; i++)
3211 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003212}
3213
3214static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3215{
3216 struct gsm_bts *bts = vty->index;
3217 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003218 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003219 int i;
3220
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003221 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3222 for (i = 0; i < argc - 1; i++)
3223 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003224}
3225
3226static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3227{
3228 struct gsm_bts *bts = vty->index;
3229 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3230 struct gsm48_multi_rate_conf *mr_conf =
3231 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3232 int num = 0, i;
3233
3234 for (i = 0; i < ((full) ? 8 : 6); i++) {
3235 if ((mr->gsm48_ie[1] & (1 << i))) {
3236 num++;
3237 }
3238 }
3239
3240 if (argv[0][0] == 'a' || num == 0)
3241 mr_conf->icmi = 0;
3242 else {
3243 mr_conf->icmi = 1;
3244 if (num < atoi(argv[0]))
3245 mr_conf->smod = num - 1;
3246 else
3247 mr_conf->smod = atoi(argv[0]) - 1;
3248 }
3249}
3250
3251#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3252#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3253 "10,2k\n12,2k\n"
3254
3255#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3256#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3257
3258#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3259#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3260
3261DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3262 "amr tch-f modes" AMR_TCHF_PAR_STR,
3263 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3264 AMR_TCHF_HELP_STR)
3265{
3266 get_amr_from_arg(vty, 1, argv, 1);
3267 return CMD_SUCCESS;
3268}
3269
3270DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3271 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3272 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3273 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3274{
3275 get_amr_from_arg(vty, 2, argv, 1);
3276 return CMD_SUCCESS;
3277}
3278
3279DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3280 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3281 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3282 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3283{
3284 get_amr_from_arg(vty, 3, argv, 1);
3285 return CMD_SUCCESS;
3286}
3287
3288DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3289 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3290 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3291 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3292{
3293 get_amr_from_arg(vty, 4, argv, 1);
3294 return CMD_SUCCESS;
3295}
3296
3297DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3298 "amr tch-f start-mode (auto|1|2|3|4)",
3299 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3300{
3301 get_amr_start_from_arg(vty, argv, 1);
3302 return CMD_SUCCESS;
3303}
3304
3305DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3306 "amr tch-f threshold (ms|bts) <0-63>",
3307 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3308 AMR_TH_HELP_STR)
3309{
3310 get_amr_th_from_arg(vty, 2, argv, 1);
3311 return CMD_SUCCESS;
3312}
3313
3314DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3315 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3316 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3317 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3318{
3319 get_amr_th_from_arg(vty, 3, argv, 1);
3320 return CMD_SUCCESS;
3321}
3322
3323DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3324 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3325 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3326 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3327{
3328 get_amr_th_from_arg(vty, 4, argv, 1);
3329 return CMD_SUCCESS;
3330}
3331
3332DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3333 "amr tch-f hysteresis (ms|bts) <0-15>",
3334 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3335 AMR_HY_HELP_STR)
3336{
3337 get_amr_hy_from_arg(vty, 2, argv, 1);
3338 return CMD_SUCCESS;
3339}
3340
3341DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3342 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3343 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3344 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3345{
3346 get_amr_hy_from_arg(vty, 3, argv, 1);
3347 return CMD_SUCCESS;
3348}
3349
3350DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3351 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3352 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3353 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3354{
3355 get_amr_hy_from_arg(vty, 4, argv, 1);
3356 return CMD_SUCCESS;
3357}
3358
3359DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3360 "amr tch-h modes" AMR_TCHH_PAR_STR,
3361 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3362 AMR_TCHH_HELP_STR)
3363{
3364 get_amr_from_arg(vty, 1, argv, 0);
3365 return CMD_SUCCESS;
3366}
3367
3368DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3369 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3370 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3371 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3372{
3373 get_amr_from_arg(vty, 2, argv, 0);
3374 return CMD_SUCCESS;
3375}
3376
3377DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3378 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3379 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3380 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3381{
3382 get_amr_from_arg(vty, 3, argv, 0);
3383 return CMD_SUCCESS;
3384}
3385
3386DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3387 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3388 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3389 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3390{
3391 get_amr_from_arg(vty, 4, argv, 0);
3392 return CMD_SUCCESS;
3393}
3394
3395DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3396 "amr tch-h start-mode (auto|1|2|3|4)",
3397 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3398{
3399 get_amr_start_from_arg(vty, argv, 0);
3400 return CMD_SUCCESS;
3401}
3402
3403DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3404 "amr tch-h threshold (ms|bts) <0-63>",
3405 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3406 AMR_TH_HELP_STR)
3407{
3408 get_amr_th_from_arg(vty, 2, argv, 0);
3409 return CMD_SUCCESS;
3410}
3411
3412DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3413 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3414 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3415 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3416{
3417 get_amr_th_from_arg(vty, 3, argv, 0);
3418 return CMD_SUCCESS;
3419}
3420
3421DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3422 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3423 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3424 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3425{
3426 get_amr_th_from_arg(vty, 4, argv, 0);
3427 return CMD_SUCCESS;
3428}
3429
3430DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3431 "amr tch-h hysteresis (ms|bts) <0-15>",
3432 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3433 AMR_HY_HELP_STR)
3434{
3435 get_amr_hy_from_arg(vty, 2, argv, 0);
3436 return CMD_SUCCESS;
3437}
3438
3439DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3440 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3441 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3442 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3443{
3444 get_amr_hy_from_arg(vty, 3, argv, 0);
3445 return CMD_SUCCESS;
3446}
3447
3448DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3449 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3450 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3451 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3452{
3453 get_amr_hy_from_arg(vty, 4, argv, 0);
3454 return CMD_SUCCESS;
3455}
3456
Harald Welte8f0ed552010-05-11 21:53:49 +02003457#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003458
Harald Welte5258fc42009-03-28 19:07:53 +00003459/* per TRX configuration */
3460DEFUN(cfg_trx,
3461 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003462 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003463 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003464 "Select a TRX to configure")
3465{
3466 int trx_nr = atoi(argv[0]);
3467 struct gsm_bts *bts = vty->index;
3468 struct gsm_bts_trx *trx;
3469
Harald Weltee441d9c2009-06-21 16:17:15 +02003470 if (trx_nr > bts->num_trx) {
3471 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3472 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003473 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003474 } else if (trx_nr == bts->num_trx) {
3475 /* we need to allocate a new one */
3476 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003477 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003478 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003479
Harald Weltee441d9c2009-06-21 16:17:15 +02003480 if (!trx)
3481 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003482
3483 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003484 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003485 vty->node = TRX_NODE;
3486
3487 return CMD_SUCCESS;
3488}
3489
3490DEFUN(cfg_trx_arfcn,
3491 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003492 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003493 "Set the ARFCN for this TRX\n"
3494 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003495{
3496 int arfcn = atoi(argv[0]);
3497 struct gsm_bts_trx *trx = vty->index;
3498
3499 /* FIXME: check if this ARFCN is supported by this TRX */
3500
3501 trx->arfcn = arfcn;
3502
3503 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3504 /* FIXME: use OML layer to update the ARFCN */
3505 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3506
3507 return CMD_SUCCESS;
3508}
3509
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003510DEFUN(cfg_trx_nominal_power,
3511 cfg_trx_nominal_power_cmd,
3512 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003513 "Nominal TRX RF Power in dBm\n"
3514 "Nominal TRX RF Power in dBm\n"
3515 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003516{
3517 struct gsm_bts_trx *trx = vty->index;
3518
3519 trx->nominal_power = atoi(argv[0]);
3520
3521 return CMD_SUCCESS;
3522}
3523
Harald Weltefcd24452009-06-20 18:15:19 +02003524DEFUN(cfg_trx_max_power_red,
3525 cfg_trx_max_power_red_cmd,
3526 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003527 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003528 "Reduction of maximum BS RF Power in dB\n")
3529{
3530 int maxpwr_r = atoi(argv[0]);
3531 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003532 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003533
3534 /* FIXME: check if our BTS type supports more than 12 */
3535 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3536 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3537 maxpwr_r, VTY_NEWLINE);
3538 return CMD_WARNING;
3539 }
3540 if (maxpwr_r & 1) {
3541 vty_out(vty, "%% Power %d dB is not an even value%s",
3542 maxpwr_r, VTY_NEWLINE);
3543 return CMD_WARNING;
3544 }
3545
3546 trx->max_power_red = maxpwr_r;
3547
3548 /* FIXME: make sure we update this using OML */
3549
3550 return CMD_SUCCESS;
3551}
3552
Harald Welte42581822009-08-08 16:12:58 +02003553DEFUN(cfg_trx_rsl_e1,
3554 cfg_trx_rsl_e1_cmd,
3555 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003556 "RSL Parameters\n"
3557 "E1/T1 interface to be used for RSL\n"
3558 "E1/T1 interface to be used for RSL\n"
3559 "E1/T1 Line Number to be used for RSL\n"
3560 "E1/T1 Timeslot to be used for RSL\n"
3561 "E1/T1 Timeslot to be used for RSL\n"
3562 "E1/T1 Sub-slot to be used for RSL\n"
3563 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3564 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3565 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3566 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3567 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003568{
3569 struct gsm_bts_trx *trx = vty->index;
3570
3571 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3572
3573 return CMD_SUCCESS;
3574}
3575
3576DEFUN(cfg_trx_rsl_e1_tei,
3577 cfg_trx_rsl_e1_tei_cmd,
3578 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003579 "RSL Parameters\n"
3580 "Set the TEI to be used for RSL\n"
3581 "Set the TEI to be used for RSL\n"
3582 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003583{
3584 struct gsm_bts_trx *trx = vty->index;
3585
3586 trx->rsl_tei = atoi(argv[0]);
3587
3588 return CMD_SUCCESS;
3589}
3590
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003591DEFUN(cfg_trx_rf_locked,
3592 cfg_trx_rf_locked_cmd,
3593 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003594 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3595 "TRX is NOT RF locked (active)\n"
3596 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003597{
3598 int locked = atoi(argv[0]);
3599 struct gsm_bts_trx *trx = vty->index;
3600
Maxbe356ed2017-09-07 19:10:09 +02003601 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003602 return CMD_SUCCESS;
3603}
Harald Welte42581822009-08-08 16:12:58 +02003604
Harald Welte5258fc42009-03-28 19:07:53 +00003605/* per TS configuration */
3606DEFUN(cfg_ts,
3607 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003608 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003609 "Select a Timeslot to configure\n"
3610 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003611{
3612 int ts_nr = atoi(argv[0]);
3613 struct gsm_bts_trx *trx = vty->index;
3614 struct gsm_bts_trx_ts *ts;
3615
3616 if (ts_nr >= TRX_NR_TS) {
3617 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3618 TRX_NR_TS, VTY_NEWLINE);
3619 return CMD_WARNING;
3620 }
3621
3622 ts = &trx->ts[ts_nr];
3623
3624 vty->index = ts;
3625 vty->node = TS_NODE;
3626
3627 return CMD_SUCCESS;
3628}
3629
Harald Weltea6fd58e2009-08-07 00:25:23 +02003630DEFUN(cfg_ts_pchan,
3631 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003632 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003633 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003634{
3635 struct gsm_bts_trx_ts *ts = vty->index;
3636 int pchanc;
3637
3638 pchanc = gsm_pchan_parse(argv[0]);
3639 if (pchanc < 0)
3640 return CMD_WARNING;
3641
3642 ts->pchan = pchanc;
3643
3644 return CMD_SUCCESS;
3645}
3646
3647/* used for backwards compatibility with old config files that still
3648 * have uppercase pchan type names */
3649DEFUN_HIDDEN(cfg_ts_pchan_compat,
3650 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003651 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003652 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003653{
3654 struct gsm_bts_trx_ts *ts = vty->index;
3655 int pchanc;
3656
3657 pchanc = gsm_pchan_parse(argv[0]);
3658 if (pchanc < 0)
3659 return CMD_WARNING;
3660
3661 ts->pchan = pchanc;
3662
3663 return CMD_SUCCESS;
3664}
3665
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003666
3667
Harald Welte135a6482011-05-30 12:09:13 +02003668DEFUN(cfg_ts_tsc,
3669 cfg_ts_tsc_cmd,
3670 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003671 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003672{
3673 struct gsm_bts_trx_ts *ts = vty->index;
3674
Max71d082b2017-05-30 15:03:38 +02003675 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003676 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3677 "falling back to BCC%s", VTY_NEWLINE);
3678 ts->tsc = -1;
3679 return CMD_WARNING;
3680 }
3681
Harald Welte135a6482011-05-30 12:09:13 +02003682 ts->tsc = atoi(argv[0]);
3683
3684 return CMD_SUCCESS;
3685}
3686
Harald Weltea39b0f22010-06-14 22:26:10 +02003687#define HOPPING_STR "Configure frequency hopping\n"
3688
3689DEFUN(cfg_ts_hopping,
3690 cfg_ts_hopping_cmd,
3691 "hopping enabled (0|1)",
3692 HOPPING_STR "Enable or disable frequency hopping\n"
3693 "Disable frequency hopping\n" "Enable frequency hopping\n")
3694{
3695 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003696 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003697
Max71d082b2017-05-30 15:03:38 +02003698 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003699 vty_out(vty, "BTS model does not support hopping%s",
3700 VTY_NEWLINE);
3701 return CMD_WARNING;
3702 }
3703
3704 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003705
3706 return CMD_SUCCESS;
3707}
3708
Harald Welte6e0cd042009-09-12 13:05:33 +02003709DEFUN(cfg_ts_hsn,
3710 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003711 "hopping sequence-number <0-63>",
3712 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003713 "Which hopping sequence to use for this channel\n"
3714 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003715{
3716 struct gsm_bts_trx_ts *ts = vty->index;
3717
3718 ts->hopping.hsn = atoi(argv[0]);
3719
3720 return CMD_SUCCESS;
3721}
3722
3723DEFUN(cfg_ts_maio,
3724 cfg_ts_maio_cmd,
3725 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003726 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003727 "Which hopping MAIO to use for this channel\n"
3728 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003729{
3730 struct gsm_bts_trx_ts *ts = vty->index;
3731
3732 ts->hopping.maio = atoi(argv[0]);
3733
3734 return CMD_SUCCESS;
3735}
3736
3737DEFUN(cfg_ts_arfcn_add,
3738 cfg_ts_arfcn_add_cmd,
3739 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003740 HOPPING_STR "Configure hopping ARFCN list\n"
3741 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003742{
3743 struct gsm_bts_trx_ts *ts = vty->index;
3744 int arfcn = atoi(argv[0]);
3745
Harald Weltea39b0f22010-06-14 22:26:10 +02003746 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3747
Harald Welte6e0cd042009-09-12 13:05:33 +02003748 return CMD_SUCCESS;
3749}
3750
3751DEFUN(cfg_ts_arfcn_del,
3752 cfg_ts_arfcn_del_cmd,
3753 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003754 HOPPING_STR "Configure hopping ARFCN list\n"
3755 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003756{
3757 struct gsm_bts_trx_ts *ts = vty->index;
3758 int arfcn = atoi(argv[0]);
3759
Harald Weltea39b0f22010-06-14 22:26:10 +02003760 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3761
Harald Welte6e0cd042009-09-12 13:05:33 +02003762 return CMD_SUCCESS;
3763}
3764
Harald Weltea6fd58e2009-08-07 00:25:23 +02003765DEFUN(cfg_ts_e1_subslot,
3766 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003767 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003768 "E1/T1 channel connected to this on-air timeslot\n"
3769 "E1/T1 channel connected to this on-air timeslot\n"
3770 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003771 "E1/T1 timeslot connected to this on-air timeslot\n"
3772 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003773 "E1/T1 sub-slot connected to this on-air timeslot\n"
3774 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3775 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3776 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3777 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3778 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003779{
3780 struct gsm_bts_trx_ts *ts = vty->index;
3781
Harald Welte42581822009-08-08 16:12:58 +02003782 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003783
3784 return CMD_SUCCESS;
3785}
Harald Welte5258fc42009-03-28 19:07:53 +00003786
Harald Welte4f10c252010-05-16 21:47:13 +02003787void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3788{
Harald Weltecf9d4312017-12-13 23:17:16 +01003789 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003790 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003791 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003792 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003793}
3794
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003795DEFUN(drop_bts,
3796 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003797 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003798 "Debug/Simulation command to drop Abis/IP BTS\n"
3799 "Debug/Simulation command to drop Abis/IP BTS\n"
3800 "Debug/Simulation command to drop Abis/IP BTS\n"
3801 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003802{
3803 struct gsm_network *gsmnet;
3804 struct gsm_bts_trx *trx;
3805 struct gsm_bts *bts;
3806 unsigned int bts_nr;
3807
3808 gsmnet = gsmnet_from_vty(vty);
3809
3810 bts_nr = atoi(argv[0]);
3811 if (bts_nr >= gsmnet->num_bts) {
3812 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3813 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3814 return CMD_WARNING;
3815 }
3816
3817 bts = gsm_bts_num(gsmnet, bts_nr);
3818 if (!bts) {
3819 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3820 return CMD_WARNING;
3821 }
3822
3823 if (!is_ipaccess_bts(bts)) {
3824 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3825 return CMD_WARNING;
3826 }
3827
3828
3829 /* close all connections */
3830 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003831 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003832 } else if (strcmp(argv[1], "rsl") == 0) {
3833 /* close all rsl connections */
3834 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003835 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003836 }
3837 } else {
3838 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3839 return CMD_WARNING;
3840 }
3841
3842 return CMD_SUCCESS;
3843}
3844
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003845DEFUN(restart_bts, restart_bts_cmd,
3846 "restart-bts <0-65535>",
3847 "Restart ip.access nanoBTS through OML\n"
3848 "BTS Number\n")
3849{
3850 struct gsm_network *gsmnet;
3851 struct gsm_bts_trx *trx;
3852 struct gsm_bts *bts;
3853 unsigned int bts_nr;
3854
3855 gsmnet = gsmnet_from_vty(vty);
3856
3857 bts_nr = atoi(argv[0]);
3858 if (bts_nr >= gsmnet->num_bts) {
3859 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3860 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3861 return CMD_WARNING;
3862 }
3863
3864 bts = gsm_bts_num(gsmnet, bts_nr);
3865 if (!bts) {
3866 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3867 return CMD_WARNING;
3868 }
3869
3870 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3871 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3872 VTY_NEWLINE);
3873 return CMD_WARNING;
3874 }
3875
3876 /* go from last TRX to c0 */
3877 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3878 abis_nm_ipaccess_restart(trx);
3879
3880 return CMD_SUCCESS;
3881}
3882
Harald Welte8e2e22f2017-07-10 20:25:10 +02003883DEFUN(bts_resend, bts_resend_cmd,
3884 "bts <0-255> resend-system-information",
3885 "BTS Specific Commands\n" "BTS Number\n"
3886 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3887{
3888 struct gsm_network *gsmnet;
3889 struct gsm_bts_trx *trx;
3890 struct gsm_bts *bts;
3891 unsigned int bts_nr;
3892
3893 gsmnet = gsmnet_from_vty(vty);
3894
3895 bts_nr = atoi(argv[0]);
3896 if (bts_nr >= gsmnet->num_bts) {
3897 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3898 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3899 return CMD_WARNING;
3900 }
3901
3902 bts = gsm_bts_num(gsmnet, bts_nr);
3903 if (!bts) {
3904 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3905 return CMD_WARNING;
3906 }
3907
3908 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3909 gsm_bts_trx_set_system_infos(trx);
3910
3911 return CMD_SUCCESS;
3912}
3913
3914
Harald Welte30f1f372014-12-28 15:00:45 +01003915DEFUN(smscb_cmd, smscb_cmd_cmd,
3916 "bts <0-255> smscb-command <1-4> HEXSTRING",
3917 "BTS related commands\n" "BTS Number\n"
3918 "SMS Cell Broadcast\n" "Last Valid Block\n"
3919 "Hex Encoded SMSCB message (up to 88 octets)\n")
3920{
3921 struct gsm_bts *bts;
3922 int bts_nr = atoi(argv[0]);
3923 int last_block = atoi(argv[1]);
3924 struct rsl_ie_cb_cmd_type cb_cmd;
3925 uint8_t buf[88];
3926 int rc;
3927
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02003928 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01003929 if (!bts) {
3930 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3931 return CMD_WARNING;
3932 }
3933 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
3934 if (rc < 0 || rc > sizeof(buf)) {
3935 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3936 return CMD_WARNING;
3937 }
3938
3939 cb_cmd.spare = 0;
3940 cb_cmd.def_bcast = 0;
3941 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
3942
3943 switch (last_block) {
3944 case 1:
3945 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
3946 break;
3947 case 2:
3948 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
3949 break;
3950 case 3:
3951 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
3952 break;
3953 case 4:
3954 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
3955 break;
3956 }
3957
3958 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
3959
3960 return CMD_SUCCESS;
3961}
3962
Harald Welte7fe00fb2017-05-27 14:09:50 +02003963/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02003964static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
3965 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02003966{
Harald Welte645eb622017-05-27 15:52:58 +02003967 int bts_nr = atoi(bts_str);
3968 int trx_nr = atoi(trx_str);
3969 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003970 struct gsm_bts *bts;
3971 struct gsm_bts_trx *trx;
3972 struct gsm_bts_trx_ts *ts;
3973
3974 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
3975 if (!bts) {
3976 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3977 return NULL;
3978 }
3979
3980 trx = gsm_bts_trx_num(bts, trx_nr);
3981 if (!trx) {
3982 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
3983 return NULL;
3984 }
3985
3986 ts = &trx->ts[ts_nr];
3987
3988 return ts;
3989}
Harald Welte30f1f372014-12-28 15:00:45 +01003990
Harald Welted0d2b0b2010-12-23 13:18:07 +01003991DEFUN(pdch_act, pdch_act_cmd,
3992 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
3993 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
3994 "TRX Timeslot\n" "Timeslot Number\n" "Packet Data Channel\n"
3995 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
3996 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
3997{
Harald Welted0d2b0b2010-12-23 13:18:07 +01003998 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01003999 int activate;
4000
Harald Welte645eb622017-05-27 15:52:58 +02004001 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004002 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004003 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004004
Harald Welte7fe00fb2017-05-27 14:09:50 +02004005 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004006 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4007 VTY_NEWLINE);
4008 return CMD_WARNING;
4009 }
4010
Harald Welted0d2b0b2010-12-23 13:18:07 +01004011 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4012 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004013 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004014 return CMD_WARNING;
4015 }
4016
4017 if (!strcmp(argv[3], "activate"))
4018 activate = 1;
4019 else
4020 activate = 0;
4021
4022 rsl_ipacc_pdch_activate(ts, activate);
4023
4024 return CMD_SUCCESS;
4025
4026}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004027
Harald Welte2abd5e12017-05-27 14:10:40 +02004028/* determine the logical channel type based on the physical channel type */
4029static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4030{
4031 switch (pchan) {
4032 case GSM_PCHAN_TCH_F:
4033 return GSM_LCHAN_TCH_F;
4034 case GSM_PCHAN_TCH_H:
4035 return GSM_LCHAN_TCH_H;
4036 case GSM_PCHAN_SDCCH8_SACCH8C:
4037 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4038 case GSM_PCHAN_CCCH_SDCCH4:
4039 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4040 return GSM_LCHAN_SDCCH;
4041 default:
4042 return -1;
4043 }
4044}
4045
4046/* configure the lchan for a single AMR mode (as specified) */
4047static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4048{
4049 struct amr_multirate_conf mr;
4050 struct gsm48_multi_rate_conf *mr_conf;
4051 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4052
4053 if (amr_mode > 7)
4054 return -1;
4055
4056 memset(&mr, 0, sizeof(mr));
4057 mr_conf->ver = 1;
4058 /* bit-mask of supported modes, only one bit is set. Reflects
4059 * Figure 10.5.2.47a where there are no thershold and only a
4060 * single mode */
4061 mr.gsm48_ie[1] = 1 << amr_mode;
4062
4063 mr.ms_mode[0].mode = amr_mode;
4064 mr.bts_mode[0].mode = amr_mode;
4065
4066 /* encode this configuration into the lchan for both uplink and
4067 * downlink direction */
4068 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4069 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4070
4071 return 0;
4072}
4073
4074/* Debug/Measurement command to activate a given logical channel
4075 * manually in a given mode/codec. This is useful for receiver
4076 * performance testing (FER/RBER/...) */
4077DEFUN(lchan_act, lchan_act_cmd,
4078 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
4079 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4080 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot Number\n" "Sub-Slot Number\n"
4081 "Manual Channel Activation (e.g. for BER test)\n"
4082 "Manual Channel Deactivation (e.g. for BER test)\n"
4083 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4084{
4085 struct gsm_bts_trx_ts *ts;
4086 struct gsm_lchan *lchan;
4087 int ss_nr = atoi(argv[3]);
4088 const char *act_str = argv[4];
4089 const char *codec_str = argv[5];
4090 int activate;
4091
4092 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4093 if (!ts)
4094 return CMD_WARNING;
4095
4096 lchan = &ts->lchan[ss_nr];
4097
4098 if (!strcmp(act_str, "activate"))
4099 activate = 1;
4100 else
4101 activate = 0;
4102
4103 if (ss_nr >= ts_subslots(ts)) {
4104 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4105 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4106 return CMD_WARNING;
4107 }
4108
4109 if (activate) {
4110 int lchan_t;
4111 if (lchan->state != LCHAN_S_NONE) {
4112 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4113 return CMD_WARNING;
4114 }
4115 lchan_t = lchan_type_by_pchan(ts->pchan);
4116 if (lchan_t < 0)
4117 return CMD_WARNING;
4118 /* configure the lchan */
4119 lchan->type = lchan_t;
4120 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4121 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4122 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4123 else if (!strcmp(codec_str, "efr"))
4124 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4125 else if (!strcmp(codec_str, "amr")) {
4126 int amr_mode;
4127 if (argc < 7) {
4128 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4129 return CMD_WARNING;
4130 }
4131 amr_mode = atoi(argv[6]);
4132 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4133 lchan_set_single_amr_mode(lchan, amr_mode);
4134 }
4135 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4136 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4137 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004138 } else {
4139 rsl_direct_rf_release(lchan);
4140 }
4141
4142 return CMD_SUCCESS;
4143}
4144
Harald Welte3f86c522017-05-27 15:53:28 +02004145DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4146 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
4147 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4148 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot\n" "Sub-Slot Number\n"
4149 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4150{
4151 struct gsm_bts_trx_ts *ts;
4152 struct gsm_lchan *lchan;
4153 int ss_nr = atoi(argv[3]);
4154 int port = atoi(argv[5]);
4155 struct in_addr ia;
4156 inet_aton(argv[4], &ia);
4157
4158 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4159 if (!ts)
4160 return CMD_WARNING;
4161
4162 lchan = &ts->lchan[ss_nr];
4163
4164 if (ss_nr >= ts_subslots(ts)) {
4165 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4166 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4167 return CMD_WARNING;
4168 }
4169
4170 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4171 inet_ntoa(ia), port, VTY_NEWLINE);
4172 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4173 return CMD_SUCCESS;
4174}
Harald Welteb71147a2017-07-18 19:11:49 +02004175
4176DEFUN(ctrl_trap, ctrl_trap_cmd,
4177 "ctrl-interface generate-trap TRAP VALUE",
4178 "Commands related to the CTRL Interface\n"
4179 "Generate a TRAP for test purpose\n"
4180 "Identity/Name of the TRAP variable\n"
4181 "Value of the TRAP variable\n")
4182{
4183 struct gsm_network *net = gsmnet_from_vty(vty);
4184
4185 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4186 return CMD_SUCCESS;
4187}
4188
Harald Weltedcccb182010-05-16 20:52:23 +02004189extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004190
Maxdb0e3802017-01-12 19:35:11 +01004191int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004192{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004193 cfg_ts_pchan_cmd.string =
4194 vty_cmd_string_from_valstr(tall_bsc_ctx,
4195 gsm_pchant_names,
4196 "phys_chan_config (", "|", ")",
4197 VTY_DO_LOWER);
4198 cfg_ts_pchan_cmd.doc =
4199 vty_cmd_string_from_valstr(tall_bsc_ctx,
4200 gsm_pchant_descs,
4201 "Physical Channel Combination\n",
4202 "\n", "", 0);
4203
Harald Weltee555c2b2012-08-17 13:02:12 +02004204 cfg_bts_type_cmd.string =
4205 vty_cmd_string_from_valstr(tall_bsc_ctx,
4206 bts_type_names,
4207 "type (", "|", ")",
4208 VTY_DO_LOWER);
4209 cfg_bts_type_cmd.doc =
4210 vty_cmd_string_from_valstr(tall_bsc_ctx,
4211 bts_type_descs,
4212 "BTS Vendor/Type\n",
4213 "\n", "", 0);
4214
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +02004215 common_cs_vty_init(network, config_write_net);
Harald Weltee555c2b2012-08-17 13:02:12 +02004216
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004217 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004218 install_element_ve(&show_bts_cmd);
4219 install_element_ve(&show_trx_cmd);
4220 install_element_ve(&show_ts_cmd);
4221 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004222 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004223
Philipp Maier39f62bb2017-04-09 12:32:51 +02004224 install_element_ve(&show_subscr_conn_cmd);
4225 install_element_ve(&handover_subscr_conn_cmd);
4226
Harald Welteb4d5b172010-05-12 16:10:35 +00004227 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004228 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004229
Maxdb0e3802017-01-12 19:35:11 +01004230 logging_vty_add_cmds(NULL);
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004231
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004232 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Weltebc814502009-12-19 21:41:52 +01004233 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Welteb720bd32009-12-21 16:51:50 +01004234 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
4235 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
4236 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
4237 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
4238 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
4239 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004240 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004241 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4242 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4243 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4244 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4245 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4246 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4247 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4248 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4249 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004250 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004251 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004252 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004253 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02004254
4255 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004256 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004257 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004258 install_element(BTS_NODE, &cfg_description_cmd);
4259 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004260 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004261 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004262 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4263 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4264 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4265 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004266 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4267 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004268 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004269 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004270 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004271 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004272 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004273 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004274 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004275 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4276 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004277 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004278 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4279 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004280 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4281 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4282 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004283 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4284 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004285 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004286 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004287 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004288 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004289 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4290 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004291 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4292 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4293 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4294 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4295 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4296 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004297 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004298 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004299 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304300 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004301 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004302 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004303 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004304 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4305 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004306 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004307 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004308 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004309 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004310 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4311 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4312 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004313 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004314 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4315 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004316 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004317 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004318 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4319 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004320 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004321 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4322 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004323 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4324 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004325 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4326 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004327 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4328 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004329 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4330 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4331 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4332 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4333 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004334 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4335 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004336 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4337 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4338 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4339 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4340 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4341 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4342 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4343 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4344 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4345 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4346 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4347 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4348 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4349 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4350 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4351 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4352 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4353 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4354 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4355 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4356 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4357 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004358 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004359
Harald Welte5258fc42009-03-28 19:07:53 +00004360 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004361 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004362 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004363 install_element(TRX_NODE, &cfg_description_cmd);
4364 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004365 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004366 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004367 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4368 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004369 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004370
Harald Welte5258fc42009-03-28 19:07:53 +00004371 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004372 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004373 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004374 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004375 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004376 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004377 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4378 install_element(TS_NODE, &cfg_ts_maio_cmd);
4379 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4380 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004381 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004382
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004383 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004384 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004385 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004386 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004387 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004388 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004389 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004390 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004391
Harald Welte81c9b9c2010-05-31 16:40:40 +02004392 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004393 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004394 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004395 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004396
Harald Weltedcccb182010-05-16 20:52:23 +02004397 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004398
Harald Welte68628e82009-03-10 12:17:57 +00004399 return 0;
4400}