blob: dcdd28a2d03ed621a2cae01255c0d25b679ae9a1 [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);
Maxddee01f2016-05-24 14:23:27 +0200170 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900171 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
172 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100173 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
174 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800175 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
176 VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100177 vty_out(vty, " Handover: %s%s", net->handover.active ? "On" : "Off",
178 VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100179 network_chan_load(&pl, net);
180 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
181 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100182
183 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100184 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100185 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200186 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100187 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100188 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200189 vty_out(vty, " Last RF Lock Command: %s%s",
190 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
191 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000192}
193
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200194DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000195 SHOW_STR "Display information about a GSM NETWORK\n")
196{
Harald Weltedcccb182010-05-16 20:52:23 +0200197 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000198 net_dump_vty(vty, net);
199
200 return CMD_SUCCESS;
201}
202
203static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
204{
Harald Welteedb37782009-05-01 14:59:07 +0000205 struct e1inp_line *line;
206
207 if (!e1l) {
208 vty_out(vty, " None%s", VTY_NEWLINE);
209 return;
210 }
211
212 line = e1l->ts->line;
213
214 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
215 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000216 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000217 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000218 e1l->tei, e1l->sapi, VTY_NEWLINE);
219}
220
221static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
222{
Harald Welteb908cb72009-12-22 13:09:29 +0100223 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200224 unsigned long long sec;
Harald Welteb908cb72009-12-22 13:09:29 +0100225
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200226 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100227 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200228 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200229 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100230 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100231 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200232 bts->num_trx, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200233 vty_out(vty, "Description: %s%s",
234 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Maxf9685c12017-03-23 12:01:07 +0100235 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
236 vty_out(vty, "PCU version %s connected%s", bts->pcu_version,
237 VTY_NEWLINE);
Harald Welte1d8dbc42009-12-12 15:38:16 +0100238 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100239 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100240 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
241 VTY_NEWLINE);
242 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100243 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100244 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
245 VTY_NEWLINE);
246 vty_out(vty, "RACH Max transmissions: %u%s",
247 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
248 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100249 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200250 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200251 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
252 vty_out(vty, "Uplink DTX: %s%s",
253 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
254 "enabled" : "forced", VTY_NEWLINE);
255 else
256 vty_out(vty, "Uplink DTX: not enabled%s", VTY_NEWLINE);
257 vty_out(vty, "Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
258 VTY_NEWLINE);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200259 vty_out(vty, "Channel Description Attachment: %s%s",
260 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
261 vty_out(vty, "Channel Description BS-PA-MFRMS: %u%s",
262 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
263 vty_out(vty, "Channel Description BS-AG_BLKS-RES: %u%s",
264 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200265 vty_out(vty, "System Information present: 0x%08x, static: 0x%08x%s",
266 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100267 vty_out(vty, "Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100268 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100269 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
270 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
271 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100272 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200273 if (bts->pcu_sock_path)
274 vty_out(vty, "PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000275 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200276 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000277 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200278 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200279 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
280 vty_out(vty, " Skip Reset: %d%s",
281 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000282 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200283 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000284 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200285 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200286 vty_out(vty, " GPRS NSE: ");
287 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
288 vty_out(vty, " GPRS CELL: ");
289 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
290 vty_out(vty, " GPRS NSVC0: ");
291 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
292 vty_out(vty, " GPRS NSVC1: ");
293 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200294 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
295 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000296 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100297 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200298 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200299 sec = bts_uptime(bts);
300 if (sec)
Maxff3fad12018-01-07 16:50:42 +0100301 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.",
302 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60);
303 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100304 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200305 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
306 e1isl_dump_vty(vty, bts->oml_link);
307 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100308
309 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100310 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200311 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100312 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
313 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100314
315 vty_out(vty, "Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
316 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
317 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
318 VTY_NEWLINE);
319 vty_out(vty, "Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
320 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
321 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
322 VTY_NEWLINE);
323 vty_out(vty, "BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
324 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
325 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
326 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000327}
328
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100329DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000330 SHOW_STR "Display information about a BTS\n"
331 "BTS number")
332{
Harald Weltedcccb182010-05-16 20:52:23 +0200333 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000334 int bts_nr;
335
336 if (argc != 0) {
337 /* use the BTS number that the user has specified */
338 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100339 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000340 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000341 VTY_NEWLINE);
342 return CMD_WARNING;
343 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200344 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000345 return CMD_SUCCESS;
346 }
347 /* print all BTS's */
348 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200349 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000350
351 return CMD_SUCCESS;
352}
353
Harald Welte42581822009-08-08 16:12:58 +0200354/* utility functions */
355static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
356 const char *ts, const char *ss)
357{
358 e1_link->e1_nr = atoi(line);
359 e1_link->e1_ts = atoi(ts);
360 if (!strcmp(ss, "full"))
361 e1_link->e1_ts_ss = 255;
362 else
363 e1_link->e1_ts_ss = atoi(ss);
364}
365
366static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
367 const char *prefix)
368{
369 if (!e1_link->e1_ts)
370 return;
371
372 if (e1_link->e1_ts_ss == 255)
373 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
374 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
375 else
376 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
377 prefix, e1_link->e1_nr, e1_link->e1_ts,
378 e1_link->e1_ts_ss, VTY_NEWLINE);
379}
380
381
Harald Welte67ce0732009-08-06 19:06:46 +0200382static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
383{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100384 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100385 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100386 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200387 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100388 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200389 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100390 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200391 ts->hopping.enabled, VTY_NEWLINE);
392 if (ts->hopping.enabled) {
393 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100394 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200395 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100396 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200397 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200398 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
399 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
400 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100401 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200402 i, VTY_NEWLINE);
403 }
Harald Welte127af342010-12-24 12:07:07 +0100404 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100405 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100406
407 if (ts->trx->bts->model->config_write_ts)
408 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200409}
410
411static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
412{
413 int i;
414
Harald Welte5013b2a2009-08-07 13:29:14 +0200415 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200416 if (trx->description)
417 vty_out(vty, " description %s%s", trx->description,
418 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200419 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200420 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200421 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200422 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100423 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200424 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200425 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
426 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200427
Harald Welteface7ed2011-02-14 16:15:21 +0100428 if (trx->bts->model->config_write_trx)
429 trx->bts->model->config_write_trx(vty, trx);
430
Harald Welte67ce0732009-08-06 19:06:46 +0200431 for (i = 0; i < TRX_NR_TS; i++)
432 config_write_ts_single(vty, &trx->ts[i]);
433}
434
Harald Welte615e9562010-05-11 23:50:21 +0200435static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
436{
437 unsigned int i;
438 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
439 VTY_NEWLINE);
440 if (bts->gprs.mode == BTS_GPRS_NONE)
441 return;
442
bhargava350533c2016-07-21 11:14:34 +0530443 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
444 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
445
Harald Welte615e9562010-05-11 23:50:21 +0200446 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
447 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100448 vty_out(vty, " gprs network-control-order nc%u%s",
449 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200450 if (!bts->gprs.ctrl_ack_type_use_block)
451 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200452 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
453 VTY_NEWLINE);
454 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
455 vty_out(vty, " gprs cell timer %s %u%s",
456 get_value_string(gprs_bssgp_cfg_strs, i),
457 bts->gprs.cell.timer[i], VTY_NEWLINE);
458 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
459 VTY_NEWLINE);
460 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
461 vty_out(vty, " gprs ns timer %s %u%s",
462 get_value_string(gprs_ns_timer_strs, i),
463 bts->gprs.nse.timer[i], VTY_NEWLINE);
464 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
465 struct gsm_bts_gprs_nsvc *nsvc =
466 &bts->gprs.nsvc[i];
467 struct in_addr ia;
468
469 ia.s_addr = htonl(nsvc->remote_ip);
470 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
471 nsvc->nsvci, VTY_NEWLINE);
472 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
473 nsvc->local_port, VTY_NEWLINE);
474 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
475 nsvc->remote_port, VTY_NEWLINE);
476 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
477 inet_ntoa(ia), VTY_NEWLINE);
478 }
479}
480
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200481/* Write the model data if there is one */
482static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200483{
484 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200485
486 if (!bts->model)
487 return;
488
489 if (bts->model->config_write_bts)
490 bts->model->config_write_bts(vty, bts);
491
492 llist_for_each_entry(trx, &bts->trx_list, list)
493 config_write_trx_single(vty, trx);
494}
495
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200496static void write_amr_modes(struct vty *vty, const char *prefix,
497 const char *name, struct amr_mode *modes, int num)
498{
499 int i;
500
501 vty_out(vty, " %s threshold %s", prefix, name);
502 for (i = 0; i < num - 1; i++)
503 vty_out(vty, " %d", modes[i].threshold);
504 vty_out(vty, "%s", VTY_NEWLINE);
505 vty_out(vty, " %s hysteresis %s", prefix, name);
506 for (i = 0; i < num - 1; i++)
507 vty_out(vty, " %d", modes[i].hysteresis);
508 vty_out(vty, "%s", VTY_NEWLINE);
509}
510
Andreas Eversberg73266522014-01-19 11:47:44 +0100511static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
512 struct amr_multirate_conf *mr, int full)
513{
514 struct gsm48_multi_rate_conf *mr_conf;
515 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
516 int i, num;
517
518 if (!(mr->gsm48_ie[1]))
519 return;
520
521 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
522
523 num = 0;
524 vty_out(vty, " %s modes", prefix);
525 for (i = 0; i < ((full) ? 8 : 6); i++) {
526 if ((mr->gsm48_ie[1] & (1 << i))) {
527 vty_out(vty, " %d", i);
528 num++;
529 }
530 }
531 vty_out(vty, "%s", VTY_NEWLINE);
532 if (num > 4)
533 num = 4;
534 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200535 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
536 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100537 }
538 vty_out(vty, " %s start-mode ", prefix);
539 if (mr_conf->icmi) {
540 num = 0;
541 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
542 if ((mr->gsm48_ie[1] & (1 << i)))
543 num++;
544 if (mr_conf->smod == num - 1) {
545 vty_out(vty, "%d%s", num, VTY_NEWLINE);
546 break;
547 }
548 }
549 } else
550 vty_out(vty, "auto%s", VTY_NEWLINE);
551}
552
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200553static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
554{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200555 int i;
Max2c16bee2017-02-15 13:51:37 +0100556 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200557
Harald Welte5013b2a2009-08-07 13:29:14 +0200558 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
559 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200560 if (bts->description)
561 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200562 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100563 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200564 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200565 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200566 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
567 vty_out(vty, " dtx uplink%s%s",
568 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
569 VTY_NEWLINE);
570 if (bts->dtxd)
571 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200572 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200573 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100574 vty_out(vty, " cell reselection hysteresis %u%s",
575 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
576 vty_out(vty, " rxlev access min %u%s",
577 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100578
579 if (bts->si_common.cell_ro_sel_par.present) {
580 struct gsm48_si_selection_params *sp;
581 sp = &bts->si_common.cell_ro_sel_par;
582
583 if (sp->cbq)
584 vty_out(vty, " cell bar qualify %u%s",
585 sp->cbq, VTY_NEWLINE);
586
587 if (sp->cell_resel_off)
588 vty_out(vty, " cell reselection offset %u%s",
589 sp->cell_resel_off*2, VTY_NEWLINE);
590
591 if (sp->temp_offs == 7)
592 vty_out(vty, " temporary offset infinite%s",
593 VTY_NEWLINE);
594 else if (sp->temp_offs)
595 vty_out(vty, " temporary offset %u%s",
596 sp->temp_offs*10, VTY_NEWLINE);
597
598 if (sp->penalty_time == 31)
599 vty_out(vty, " penalty time reserved%s",
600 VTY_NEWLINE);
601 else if (sp->penalty_time)
602 vty_out(vty, " penalty time %u%s",
603 (sp->penalty_time*20)+20, VTY_NEWLINE);
604 }
605
Harald Welte2f8b9d22017-06-18 11:12:13 +0300606 if (gsm_bts_get_radio_link_timeout(bts) < 0)
607 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
608 else
609 vty_out(vty, " radio-link-timeout %d%s",
610 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100611
Harald Welte7a8fa412009-08-10 13:48:16 +0200612 vty_out(vty, " channel allocator %s%s",
613 bts->chan_alloc_reverse ? "descending" : "ascending",
614 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100615 vty_out(vty, " rach tx integer %u%s",
616 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
617 vty_out(vty, " rach max transmission %u%s",
618 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
619 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800620
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200621 vty_out(vty, " channel-descrption attach %u%s",
622 bts->si_common.chan_desc.att, VTY_NEWLINE);
623 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
624 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
625 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
626 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
627
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800628 if (bts->rach_b_thresh != -1)
629 vty_out(vty, " rach nm busy threshold %u%s",
630 bts->rach_b_thresh, VTY_NEWLINE);
631 if (bts->rach_ldavg_slots != -1)
632 vty_out(vty, " rach nm load average %u%s",
633 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100634 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200635 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800636 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
637 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400638 if ((bts->si_common.rach_control.t3) != 0)
639 for (i = 0; i < 8; i++)
640 if (bts->si_common.rach_control.t3 & (0x1 << i))
641 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
642 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
643 for (i = 0; i < 8; i++)
644 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
645 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200646 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
647 if (bts->si_mode_static & (1 << i)) {
648 vty_out(vty, " system-information %s mode static%s",
649 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
650 vty_out(vty, " system-information %s static %s%s",
651 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200652 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200653 VTY_NEWLINE);
654 }
655 }
Harald Welte42def722017-01-13 00:10:32 +0100656 vty_out(vty, " early-classmark-sending %s%s",
657 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100658 vty_out(vty, " early-classmark-sending-3g %s%s",
659 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100660 switch (bts->type) {
661 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100662 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200663 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200664 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100665 if (bts->ip_access.rsl_ip) {
666 struct in_addr ia;
667 ia.s_addr = htonl(bts->ip_access.rsl_ip);
668 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
669 VTY_NEWLINE);
670 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200671 vty_out(vty, " oml ip.access stream_id %u line %u%s",
672 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100673 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200674 case GSM_BTS_TYPE_NOKIA_SITE:
675 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100676 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
677 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100678 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 +0100679 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100680 default:
Harald Welte42581822009-08-08 16:12:58 +0200681 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
682 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100683 break;
Harald Welte42581822009-08-08 16:12:58 +0200684 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800685
686 /* if we have a limit, write it */
687 if (bts->paging.free_chans_need >= 0)
688 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
689
Harald Welte32c09622011-01-11 23:44:56 +0100690 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100691 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
692 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100693 for (i = 0; i < 1024; i++) {
694 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
695 vty_out(vty, " neighbor-list add arfcn %u%s",
696 i, VTY_NEWLINE);
697 }
698 }
Harald Welte64c07d22011-02-15 11:43:27 +0100699 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
700 for (i = 0; i < 1024; i++) {
701 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
702 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
703 i, VTY_NEWLINE);
704 }
705 }
Harald Welte32c09622011-01-11 23:44:56 +0100706
Max59a1bf32016-04-15 16:04:46 +0200707 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100708 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
709 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
710 vty_out(vty, " si2quater neighbor-list add earfcn %u "
711 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
712
713 vty_out(vty, " thresh-lo %u",
714 e->thresh_lo_valid ? e->thresh_lo : 32);
715
716 vty_out(vty, " prio %u",
717 e->prio_valid ? e->prio : 8);
718
719 vty_out(vty, " qrxlv %u",
720 e->qrxlm_valid ? e->qrxlm : 32);
721
722 tmp = e->meas_bw[i];
723 vty_out(vty, " meas %u",
724 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200725
726 vty_out(vty, "%s", VTY_NEWLINE);
727 }
728 }
729
Max26679e02016-04-20 15:57:13 +0200730 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
731 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
732 bts->si_common.data.uarfcn_list[i],
733 bts->si_common.data.scramble_list[i] & ~(1 << 9),
734 (bts->si_common.data.scramble_list[i] >> 9) & 1,
735 VTY_NEWLINE);
736 }
737
Andreas Eversberga83d5112013-12-07 18:32:28 +0100738 vty_out(vty, " codec-support fr");
739 if (bts->codec.hr)
740 vty_out(vty, " hr");
741 if (bts->codec.efr)
742 vty_out(vty, " efr");
743 if (bts->codec.amr)
744 vty_out(vty, " amr");
745 vty_out(vty, "%s", VTY_NEWLINE);
746
Andreas Eversberg73266522014-01-19 11:47:44 +0100747 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
748 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
749
Harald Welte615e9562010-05-11 23:50:21 +0200750 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200751
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200752 if (bts->excl_from_rf_lock)
753 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
754
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100755 vty_out(vty, " %sforce-combined-si%s",
756 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
757
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100758 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
759 int j;
760
761 if (bts->depends_on[i] == 0)
762 continue;
763
764 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
765 int bts_nr;
766
767 if ((bts->depends_on[i] & (1<<j)) == 0)
768 continue;
769
770 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
771 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
772 }
773 }
Harald Welte8254cf72017-05-29 13:42:19 +0200774 if (bts->pcu_sock_path)
775 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100776
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200777 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200778}
779
780static int config_write_bts(struct vty *v)
781{
Harald Weltedcccb182010-05-16 20:52:23 +0200782 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200783 struct gsm_bts *bts;
784
785 llist_for_each_entry(bts, &gsmnet->bts_list, list)
786 config_write_bts_single(v, bts);
787
788 return CMD_SUCCESS;
789}
790
Harald Weltea0d324b2017-07-20 01:47:39 +0200791/* small helper macro for conditional dumping of timer */
792#define VTY_OUT_TIMER(number) \
793 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
794 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
795
Harald Welte5013b2a2009-08-07 13:29:14 +0200796static int config_write_net(struct vty *vty)
797{
Harald Weltedcccb182010-05-16 20:52:23 +0200798 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
799
Harald Welte5013b2a2009-08-07 13:29:14 +0200800 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200801 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200802 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900803 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100804 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800805 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Harald Weltebc814502009-12-19 21:41:52 +0100806 vty_out(vty, " handover %u%s", gsmnet->handover.active, VTY_NEWLINE);
Harald Welteb720bd32009-12-21 16:51:50 +0100807 vty_out(vty, " handover window rxlev averaging %u%s",
808 gsmnet->handover.win_rxlev_avg, VTY_NEWLINE);
809 vty_out(vty, " handover window rxqual averaging %u%s",
810 gsmnet->handover.win_rxqual_avg, VTY_NEWLINE);
811 vty_out(vty, " handover window rxlev neighbor averaging %u%s",
812 gsmnet->handover.win_rxlev_avg_neigh, VTY_NEWLINE);
813 vty_out(vty, " handover power budget interval %u%s",
814 gsmnet->handover.pwr_interval, VTY_NEWLINE);
815 vty_out(vty, " handover power budget hysteresis %u%s",
816 gsmnet->handover.pwr_hysteresis, VTY_NEWLINE);
817 vty_out(vty, " handover maximum distance %u%s",
818 gsmnet->handover.max_distance, VTY_NEWLINE);
Harald Weltea0d324b2017-07-20 01:47:39 +0200819 VTY_OUT_TIMER(3101);
820 VTY_OUT_TIMER(3103);
821 VTY_OUT_TIMER(3105);
822 VTY_OUT_TIMER(3107);
823 VTY_OUT_TIMER(3109);
824 VTY_OUT_TIMER(3111);
825 VTY_OUT_TIMER(3113);
826 VTY_OUT_TIMER(3115);
827 VTY_OUT_TIMER(3117);
828 VTY_OUT_TIMER(3119);
829 VTY_OUT_TIMER(3122);
830 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700831 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
832 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200833 if (gsmnet->tz.override != 0) {
834 if (gsmnet->tz.dst)
835 vty_out(vty, " timezone %d %d %d%s",
836 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
837 VTY_NEWLINE);
838 else
839 vty_out(vty, " timezone %d %d%s",
840 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
841 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200842 if (gsmnet->t3212 == 0)
843 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
844 else
845 vty_out(vty, " periodic location update %u%s",
846 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200847
848 return CMD_SUCCESS;
849}
Harald Welte67ce0732009-08-06 19:06:46 +0200850
Harald Welte68628e82009-03-10 12:17:57 +0000851static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
852{
853 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
854 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200855 vty_out(vty, "Description: %s%s",
856 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200857 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200858 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200859 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200860 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000861 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200862 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +0100863 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000864 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200865 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200866 if (is_ipaccess_bts(trx->bts)) {
867 vty_out(vty, " ip.access stream ID: 0x%02x%s",
868 trx->rsl_tei, VTY_NEWLINE);
869 } else {
870 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
871 e1isl_dump_vty(vty, trx->rsl_link);
872 }
Harald Welte68628e82009-03-10 12:17:57 +0000873}
874
Max6e4f1842018-01-07 16:45:42 +0100875static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
876{
877 uint8_t trx_nr;
878 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
879 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
880}
881
Harald Welte68628e82009-03-10 12:17:57 +0000882DEFUN(show_trx,
883 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100884 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200885 SHOW_STR "Display information about a TRX\n"
886 "BTS Number\n"
887 "TRX Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000888{
Harald Weltedcccb182010-05-16 20:52:23 +0200889 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000890 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000891 int bts_nr, trx_nr;
892
893 if (argc >= 1) {
894 /* use the BTS number that the user has specified */
895 bts_nr = atoi(argv[0]);
896 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000897 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000898 VTY_NEWLINE);
899 return CMD_WARNING;
900 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200901 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000902 }
903 if (argc >= 2) {
904 trx_nr = atoi(argv[1]);
905 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000906 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000907 VTY_NEWLINE);
908 return CMD_WARNING;
909 }
Max6e4f1842018-01-07 16:45:42 +0100910 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000911 return CMD_SUCCESS;
912 }
913 if (bts) {
914 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +0100915 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +0000916 return CMD_SUCCESS;
917 }
918
Max6e4f1842018-01-07 16:45:42 +0100919 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
920 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000921
922 return CMD_SUCCESS;
923}
924
Harald Welte67ce0732009-08-06 19:06:46 +0200925
Harald Welte68628e82009-03-10 12:17:57 +0000926static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
927{
Harald Welte135a6482011-05-30 12:09:13 +0200928 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +0100929 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +0100930 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +0100931 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +0100932 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200933 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +0100934 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000935 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200936 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530937 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000938 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
939 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
940 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000941}
942
943DEFUN(show_ts,
944 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100945 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200946 SHOW_STR "Display information about a TS\n"
947 "BTS Number\n" "TRX Number\n" "Timeslot Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000948{
Harald Weltedcccb182010-05-16 20:52:23 +0200949 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +0100950 struct gsm_bts *bts = NULL;
951 struct gsm_bts_trx *trx = NULL;
952 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000953 int bts_nr, trx_nr, ts_nr;
954
955 if (argc >= 1) {
956 /* use the BTS number that the user has specified */
957 bts_nr = atoi(argv[0]);
958 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000959 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000960 VTY_NEWLINE);
961 return CMD_WARNING;
962 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200963 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000964 }
965 if (argc >= 2) {
966 trx_nr = atoi(argv[1]);
967 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000968 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000969 VTY_NEWLINE);
970 return CMD_WARNING;
971 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200972 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000973 }
974 if (argc >= 3) {
975 ts_nr = atoi(argv[2]);
976 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +0000977 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +0000978 VTY_NEWLINE);
979 return CMD_WARNING;
980 }
Harald Welte274d0152010-12-24 12:05:03 +0100981 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +0000982 ts = &trx->ts[ts_nr];
983 ts_dump_vty(vty, ts);
984 return CMD_SUCCESS;
985 }
Harald Welte274d0152010-12-24 12:05:03 +0100986
987 if (bts && trx) {
988 /* Iterate over all TS in this TRX */
989 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
990 ts = &trx->ts[ts_nr];
991 ts_dump_vty(vty, ts);
992 }
993 } else if (bts) {
994 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +0000995 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200996 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000997 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
998 ts = &trx->ts[ts_nr];
999 ts_dump_vty(vty, ts);
1000 }
1001 }
Harald Welte274d0152010-12-24 12:05:03 +01001002 } else {
1003 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1004 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1005 bts = gsm_bts_num(net, bts_nr);
1006 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1007 trx = gsm_bts_trx_num(bts, trx_nr);
1008 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 }
1013 }
Harald Welte68628e82009-03-10 12:17:57 +00001014 }
1015
1016 return CMD_SUCCESS;
1017}
1018
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001019static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1020{
1021 if (strlen(bsub->imsi))
1022 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1023 if (bsub->tmsi != GSM_RESERVED_TMSI)
1024 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1025 VTY_NEWLINE);
1026 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1027}
1028
Harald Welte8387a492009-12-22 21:43:14 +01001029static void meas_rep_dump_uni_vty(struct vty *vty,
1030 struct gsm_meas_rep_unidir *mru,
1031 const char *prefix,
1032 const char *dir)
1033{
1034 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1035 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1036 dir, rxlev2dbm(mru->sub.rx_lev));
1037 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1038 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1039 VTY_NEWLINE);
1040}
1041
1042static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1043 const char *prefix)
1044{
1045 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1046 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1047 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1048 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1049 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1050 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1051 VTY_NEWLINE);
1052 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001053 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001054 if (mr->flags & MEAS_REP_F_MS_L1)
1055 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1056 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1057 if (mr->flags & MEAS_REP_F_DL_VALID)
1058 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1059 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1060}
1061
Harald Welte0a8cf322015-12-05 17:22:49 +01001062/* FIXME: move this to libosmogsm */
1063static const struct value_string gsm48_cmode_names[] = {
1064 { GSM48_CMODE_SIGN, "signalling" },
1065 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1066 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1067 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1068 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1069 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1070 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1071 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1072 { 0, NULL }
1073};
1074
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001075/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1076 * Don't do anything if the ts is not dynamic. */
1077static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1078{
1079 switch (ts->pchan) {
1080 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1081 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1082 vty_out(vty, " as %s",
1083 gsm_pchan_name(ts->dyn.pchan_is));
1084 else
1085 vty_out(vty, " switching %s -> %s",
1086 gsm_pchan_name(ts->dyn.pchan_is),
1087 gsm_pchan_name(ts->dyn.pchan_want));
1088 break;
1089 case GSM_PCHAN_TCH_F_PDCH:
1090 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1091 vty_out(vty, " as %s",
1092 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1093 : "TCH/F");
1094 else
1095 vty_out(vty, " switching %s -> %s",
1096 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1097 : "TCH/F",
1098 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1099 : "TCH/F");
1100 break;
1101 default:
1102 /* no dyn ts */
1103 break;
1104 }
1105}
1106
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001107static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001108{
Harald Welte8387a492009-12-22 21:43:14 +01001109 int idx;
1110
Harald Welte85bded82010-12-24 12:22:34 +01001111 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1112 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1113 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001114 /* show dyn TS details, if applicable */
1115 switch (lchan->ts->pchan) {
1116 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1117 vty_out(vty, " Osmocom Dyn TS:");
1118 vty_out_dyn_ts_status(vty, lchan->ts);
1119 vty_out(vty, VTY_NEWLINE);
1120 break;
1121 case GSM_PCHAN_TCH_F_PDCH:
1122 vty_out(vty, " IPACC Dyn PDCH TS:");
1123 vty_out_dyn_ts_status(vty, lchan->ts);
1124 vty_out(vty, VTY_NEWLINE);
1125 break;
1126 default:
1127 /* no dyn ts */
1128 break;
1129 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001130 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001131 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001132 gsm_lchans_name(lchan->state),
1133 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1134 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1135 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001136 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1137 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1138 - lchan->bs_power*2,
1139 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1140 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001141 vty_out(vty, " Channel Mode / Codec: %s%s",
1142 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1143 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001144 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001145 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001146 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001147 } else
1148 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301149 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1150 struct in_addr ia;
Holger Hans Peter Freyther54fa7992010-04-07 15:39:16 +02001151 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte2c828992009-12-02 01:56:49 +05301152 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1153 inet_ntoa(ia), lchan->abis_ip.bound_port,
1154 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1155 VTY_NEWLINE);
1156 }
Harald Welte8387a492009-12-22 21:43:14 +01001157
1158 /* we want to report the last measurement report */
1159 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1160 lchan->meas_rep_idx, 1);
1161 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001162}
1163
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001164static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1165{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001166 struct gsm_meas_rep *mr;
1167 int idx;
1168
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 mr = &lchan->meas_rep[idx];
1173
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001174 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001175 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001176 gsm_pchan_name(lchan->ts->pchan));
1177 vty_out_dyn_ts_status(vty, lchan->ts);
1178 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1179 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001180 lchan->nr,
1181 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1182 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001183 rxlev2dbm(mr->dl.full.rx_lev),
1184 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001185 VTY_NEWLINE);
1186}
1187
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001188
1189static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1190 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1191{
1192 int lchan_nr;
1193 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1194 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1195 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1196 continue;
1197 dump_cb(vty, lchan);
1198 }
1199
1200 return CMD_SUCCESS;
1201}
1202
1203static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1204 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1205{
1206 int ts_nr;
1207
1208 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1209 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1210 dump_lchan_trx_ts(ts, vty, dump_cb);
1211 }
1212
1213 return CMD_SUCCESS;
1214}
1215
1216static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1217 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1218{
1219 int trx_nr;
1220
1221 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1222 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1223 dump_lchan_trx(trx, vty, dump_cb);
1224 }
1225
1226 return CMD_SUCCESS;
1227}
1228
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001229static int lchan_summary(struct vty *vty, int argc, const char **argv,
1230 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001231{
Harald Weltedcccb182010-05-16 20:52:23 +02001232 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001233 struct gsm_bts *bts;
1234 struct gsm_bts_trx *trx;
1235 struct gsm_bts_trx_ts *ts;
1236 struct gsm_lchan *lchan;
1237 int bts_nr, trx_nr, ts_nr, lchan_nr;
1238
1239 if (argc >= 1) {
1240 /* use the BTS number that the user has specified */
1241 bts_nr = atoi(argv[0]);
1242 if (bts_nr >= net->num_bts) {
1243 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1244 VTY_NEWLINE);
1245 return CMD_WARNING;
1246 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001247 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001248
1249 if (argc == 1)
1250 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001251 }
1252 if (argc >= 2) {
1253 trx_nr = atoi(argv[1]);
1254 if (trx_nr >= bts->num_trx) {
1255 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1256 VTY_NEWLINE);
1257 return CMD_WARNING;
1258 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001259 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001260
1261 if (argc == 2)
1262 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001263 }
1264 if (argc >= 3) {
1265 ts_nr = atoi(argv[2]);
1266 if (ts_nr >= TRX_NR_TS) {
1267 vty_out(vty, "%% can't find TS %s%s", argv[2],
1268 VTY_NEWLINE);
1269 return CMD_WARNING;
1270 }
1271 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001272
1273 if (argc == 3)
1274 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001275 }
1276 if (argc >= 4) {
1277 lchan_nr = atoi(argv[3]);
1278 if (lchan_nr >= TS_MAX_LCHAN) {
1279 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1280 VTY_NEWLINE);
1281 return CMD_WARNING;
1282 }
1283 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001284 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001285 return CMD_SUCCESS;
1286 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001287
1288
Harald Welte68628e82009-03-10 12:17:57 +00001289 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001290 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001291 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001292 }
1293
1294 return CMD_SUCCESS;
1295}
1296
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001297
1298DEFUN(show_lchan,
1299 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001300 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001301 SHOW_STR "Display information about a logical channel\n"
1302 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001303 LCHAN_NR_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001304
1305{
1306 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1307}
1308
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001309DEFUN(show_lchan_summary,
1310 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001311 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001312 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001313 "Short summary\n"
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001314 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001315 LCHAN_NR_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001316{
1317 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1318}
1319
Philipp Maier39f62bb2017-04-09 12:32:51 +02001320DEFUN(show_subscr_conn,
1321 show_subscr_conn_cmd,
1322 "show conns",
1323 SHOW_STR "Display currently active subscriber connections\n")
1324{
1325 struct gsm_subscriber_connection *conn;
1326 struct gsm_network *net = gsmnet_from_vty(vty);
1327 bool no_conns = true;
1328 unsigned int count = 0;
1329
1330 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1331
1332 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1333 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1334 lchan_dump_full_vty(vty, conn->lchan);
1335 no_conns = false;
1336 count++;
1337 }
1338
1339 if (no_conns)
1340 vty_out(vty, "None%s", VTY_NEWLINE);
1341
1342 return CMD_SUCCESS;
1343}
1344
1345DEFUN(handover_subscr_conn,
1346 handover_subscr_conn_cmd,
1347 "handover <0-255> <0-255> <0-7> LCHAN_NR <0-255>",
1348 "Handover subscriber connection to other BTS\n"
1349 "BTS Number (current)\n" "TRX Number\n" "Timeslot Number\n"
1350 LCHAN_NR_STR "BTS Number (new)\n")
1351{
1352 struct gsm_network *net = gsmnet_from_vty(vty);
1353 struct gsm_subscriber_connection *conn;
1354 struct gsm_bts *bts;
1355 struct gsm_bts *new_bts = NULL;
1356 unsigned int bts_nr = atoi(argv[0]);
1357 unsigned int trx_nr = atoi(argv[1]);
1358 unsigned int ts_nr = atoi(argv[2]);
1359 unsigned int ss_nr = atoi(argv[3]);
1360 unsigned int bts_nr_new = atoi(argv[4]);
1361
1362 /* Lookup the BTS where we want to handover to */
1363 llist_for_each_entry(bts, &net->bts_list, list) {
1364 if (bts->nr == bts_nr_new) {
1365 new_bts = bts;
1366 break;
1367 }
1368 }
1369
1370 if (!new_bts) {
1371 vty_out(vty, "Unable to trigger handover,"
1372 "specified bts #%u does not exist %s", bts_nr_new,
1373 VTY_NEWLINE);
1374 return CMD_WARNING;
1375 }
1376
1377 /* Find the connection/lchan that we want to handover */
1378 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001379 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001380 conn->lchan->ts->trx->nr == trx_nr &&
1381 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
1382 vty_out(vty, "starting handover for lchan %s...%s",
1383 conn->lchan->name, VTY_NEWLINE);
1384 lchan_dump_full_vty(vty, conn->lchan);
1385 bsc_handover_start(conn->lchan, new_bts);
1386 return CMD_SUCCESS;
1387 }
1388 }
1389
1390 vty_out(vty, "Unable to trigger handover,"
1391 "specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1392 bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
1393
1394 return CMD_WARNING;
1395}
1396
Harald Weltebe4b7302009-05-23 16:59:33 +00001397static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001398{
1399 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001400 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001401}
1402
Harald Weltebe4b7302009-05-23 16:59:33 +00001403static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001404{
1405 struct gsm_paging_request *pag;
1406
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001407 if (!bts->paging.bts)
1408 return;
1409
Harald Weltef5025b62009-03-28 16:55:11 +00001410 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1411 paging_dump_vty(vty, pag);
1412}
1413
1414DEFUN(show_paging,
1415 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001416 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001417 SHOW_STR "Display information about paging reuqests of a BTS\n"
1418 "BTS Number\n")
Harald Weltef5025b62009-03-28 16:55:11 +00001419{
Harald Weltedcccb182010-05-16 20:52:23 +02001420 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001421 struct gsm_bts *bts;
1422 int bts_nr;
1423
1424 if (argc >= 1) {
1425 /* use the BTS number that the user has specified */
1426 bts_nr = atoi(argv[0]);
1427 if (bts_nr >= net->num_bts) {
1428 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1429 VTY_NEWLINE);
1430 return CMD_WARNING;
1431 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001432 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001433 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001434
Harald Weltef5025b62009-03-28 16:55:11 +00001435 return CMD_SUCCESS;
1436 }
1437 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001438 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001439 bts_paging_dump_vty(vty, bts);
1440 }
1441
1442 return CMD_SUCCESS;
1443}
1444
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001445DEFUN(show_paging_group,
1446 show_paging_group_cmd,
1447 "show paging-group <0-255> IMSI",
1448 SHOW_STR "Display the paging group\n"
1449 "BTS Number\n" "IMSI\n")
1450{
1451 struct gsm_network *net = gsmnet_from_vty(vty);
1452 struct gsm_bts *bts;
1453 unsigned int page_group;
1454 int bts_nr = atoi(argv[0]);
1455
1456 if (bts_nr >= net->num_bts) {
1457 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1458 return CMD_WARNING;
1459 }
1460
1461 bts = gsm_bts_num(net, bts_nr);
1462 if (!bts) {
1463 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1464 return CMD_WARNING;
1465 }
1466
1467 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1468 str_to_imsi(argv[1]));
1469 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1470 str_to_imsi(argv[1]), bts->nr,
1471 page_group, VTY_NEWLINE);
1472 return CMD_SUCCESS;
1473}
1474
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001475DEFUN(cfg_net_neci,
1476 cfg_net_neci_cmd,
1477 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001478 "New Establish Cause Indication\n"
1479 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001480{
Harald Weltedcccb182010-05-16 20:52:23 +02001481 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1482
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001483 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001484 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001485 return CMD_SUCCESS;
1486}
1487
Harald Welte8f0ed552010-05-11 21:53:49 +02001488#define HANDOVER_STR "Handover Options\n"
1489
Harald Weltebc814502009-12-19 21:41:52 +01001490DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1491 "handover (0|1)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001492 HANDOVER_STR
1493 "Don't perform in-call handover\n"
1494 "Perform in-call handover\n")
Harald Weltebc814502009-12-19 21:41:52 +01001495{
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001496 int enable = atoi(argv[0]);
Harald Weltedcccb182010-05-16 20:52:23 +02001497 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001498
1499 if (enable && ipacc_rtp_direct) {
Harald Weltefe03f0d2009-12-20 13:51:01 +01001500 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1501 "is enabled by using the -P command line option%s",
1502 VTY_NEWLINE);
1503 return CMD_WARNING;
1504 }
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001505 gsmnet->handover.active = enable;
Harald Weltebc814502009-12-19 21:41:52 +01001506
1507 return CMD_SUCCESS;
1508}
1509
Harald Welte8f0ed552010-05-11 21:53:49 +02001510#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1511#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1512#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1513#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001514#define HO_AVG_COUNT_STR "Amount to use for Averaging\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001515
Harald Welteb720bd32009-12-21 16:51:50 +01001516DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1517 "handover window rxlev averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001518 HO_WIN_RXLEV_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001519 "How many RxLev measurements are used for averaging\n"
1520 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001521{
Harald Weltedcccb182010-05-16 20:52:23 +02001522 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001523 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1524 return CMD_SUCCESS;
1525}
1526
1527DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1528 "handover window rxqual averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001529 HO_WIN_RXQUAL_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001530 "How many RxQual 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_rxqual_avg = atoi(argv[0]);
1535 return CMD_SUCCESS;
1536}
1537
1538DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1539 "handover window rxlev neighbor averaging <1-10>",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001540 HO_WIN_RXLEV_STR "Neighbor\n"
1541 "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_rxlev_avg_neigh = atoi(argv[0]);
1546 return CMD_SUCCESS;
1547}
1548
1549DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1550 "handover power budget interval <1-99>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001551 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001552 "How often to check if we have a better cell (SACCH frames)\n"
1553 "Interval\n" "Number\n")
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.pwr_interval = atoi(argv[0]);
1557 return CMD_SUCCESS;
1558}
1559
1560DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1561 "handover power budget hysteresis <0-999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001562 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001563 "How many dB does a neighbor to be stronger to become a HO candidate\n"
1564 "Hysteresis\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_hysteresis = atoi(argv[0]);
1568 return CMD_SUCCESS;
1569}
1570
1571DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1572 "handover maximum distance <0-9999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001573 HANDOVER_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001574 "How big is the maximum timing advance before HO is forced\n"
1575 "Distance\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.max_distance = atoi(argv[0]);
1579 return CMD_SUCCESS;
1580}
Harald Weltebc814502009-12-19 21:41:52 +01001581
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001582DEFUN(cfg_net_pag_any_tch,
1583 cfg_net_pag_any_tch_cmd,
1584 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001585 "Assign a TCH when receiving a Paging Any request\n"
1586 "Any Channel\n" "Use\n" "TCH\n"
1587 "Do not use TCH for Paging Request Any\n"
1588 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001589{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001590 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001591 gsmnet->pag_any_tch = atoi(argv[0]);
1592 gsm_net_update_ctype(gsmnet);
1593 return CMD_SUCCESS;
1594}
1595
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001596#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1597/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1598#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1599
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001600#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001601 DEFUN(cfg_net_T##number, \
1602 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001603 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001604 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001605 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001606 "Set to default timer value" \
1607 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1608 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001609{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001610 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001611 int value; \
1612 if (strcmp(argv[0], "default") == 0) \
1613 value = DEFAULT_TIMER(number); \
1614 else \
1615 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001616 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001617 gsmnet->T##number = value; \
1618 return CMD_SUCCESS; \
1619}
1620
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001621DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1622DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1623DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1624DECLARE_TIMER(3107, "Currently not used")
1625DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1626DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1627DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1628DECLARE_TIMER(3115, "Currently not used")
1629DECLARE_TIMER(3117, "Currently not used")
1630DECLARE_TIMER(3119, "Currently not used")
1631DECLARE_TIMER(3122, "Waiting time (seconds) after IMM ASS REJECT")
1632DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001633
Maxc08ee712016-05-11 12:45:13 +02001634DEFUN_DEPRECATED(cfg_net_dtx,
1635 cfg_net_dtx_cmd,
1636 "dtx-used (0|1)",
1637 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001638{
Maxc08ee712016-05-11 12:45:13 +02001639 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1640 "configuration options of BTS instead%s", VTY_NEWLINE);
1641 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001642}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001643
Harald Welte5258fc42009-03-28 19:07:53 +00001644/* per-BTS configuration */
1645DEFUN(cfg_bts,
1646 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001647 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001648 "Select a BTS to configure\n"
1649 "BTS Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001650{
Harald Weltedcccb182010-05-16 20:52:23 +02001651 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001652 int bts_nr = atoi(argv[0]);
1653 struct gsm_bts *bts;
1654
Harald Weltee441d9c2009-06-21 16:17:15 +02001655 if (bts_nr > gsmnet->num_bts) {
1656 vty_out(vty, "%% The next unused BTS number is %u%s",
1657 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001658 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001659 } else if (bts_nr == gsmnet->num_bts) {
1660 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001661 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001662 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001663 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001664 bts = gsm_bts_num(gsmnet, bts_nr);
1665
Daniel Willmannf15c2762010-01-11 13:43:07 +01001666 if (!bts) {
1667 vty_out(vty, "%% Unable to allocate BTS %u%s",
1668 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001669 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001670 }
Harald Welte5258fc42009-03-28 19:07:53 +00001671
1672 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001673 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001674 vty->node = BTS_NODE;
1675
1676 return CMD_SUCCESS;
1677}
1678
1679DEFUN(cfg_bts_type,
1680 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001681 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001682 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001683{
1684 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001685 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001686
Max7507aef2017-04-10 13:59:14 +02001687 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001688 if (rc < 0)
1689 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001690
Harald Welte5258fc42009-03-28 19:07:53 +00001691 return CMD_SUCCESS;
1692}
1693
Harald Weltefcd24452009-06-20 18:15:19 +02001694DEFUN(cfg_bts_band,
1695 cfg_bts_band_cmd,
1696 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001697 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001698{
1699 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001700 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001701
1702 if (band < 0) {
1703 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1704 band, VTY_NEWLINE);
1705 return CMD_WARNING;
1706 }
1707
1708 bts->band = band;
1709
1710 return CMD_SUCCESS;
1711}
1712
Maxc08ee712016-05-11 12:45:13 +02001713DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1714 "Configure discontinuous transmission\n"
1715 "Enable Uplink DTX for this BTS\n"
1716 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1717 "older phones).\n")
1718{
1719 struct gsm_bts *bts = vty->index;
1720
1721 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001722 if (!is_ipaccess_bts(bts))
1723 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1724 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001725 return CMD_SUCCESS;
1726}
1727
1728DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1729 NO_STR
1730 "Configure discontinuous transmission\n"
1731 "Disable Uplink DTX for this BTS\n")
1732{
1733 struct gsm_bts *bts = vty->index;
1734
1735 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1736
1737 return CMD_SUCCESS;
1738}
1739
1740DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1741 "Configure discontinuous transmission\n"
1742 "Enable Downlink DTX for this BTS\n")
1743{
1744 struct gsm_bts *bts = vty->index;
1745
1746 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001747 if (!is_ipaccess_bts(bts))
1748 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1749 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001750 return CMD_SUCCESS;
1751}
1752
1753DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1754 NO_STR
1755 "Configure discontinuous transmission\n"
1756 "Disable Downlink DTX for this BTS\n")
1757{
1758 struct gsm_bts *bts = vty->index;
1759
1760 bts->dtxd = false;
1761
1762 return CMD_SUCCESS;
1763}
1764
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001765DEFUN(cfg_bts_ci,
1766 cfg_bts_ci_cmd,
1767 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001768 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001769{
1770 struct gsm_bts *bts = vty->index;
1771 int ci = atoi(argv[0]);
1772
1773 if (ci < 0 || ci > 0xffff) {
1774 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1775 ci, VTY_NEWLINE);
1776 return CMD_WARNING;
1777 }
1778 bts->cell_identity = ci;
1779
1780 return CMD_SUCCESS;
1781}
1782
Harald Welte5258fc42009-03-28 19:07:53 +00001783DEFUN(cfg_bts_lac,
1784 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001785 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001786 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001787{
1788 struct gsm_bts *bts = vty->index;
1789 int lac = atoi(argv[0]);
1790
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001791 if (lac < 0 || lac > 0xffff) {
1792 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001793 lac, VTY_NEWLINE);
1794 return CMD_WARNING;
1795 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001796
1797 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1798 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1799 lac, VTY_NEWLINE);
1800 return CMD_WARNING;
1801 }
1802
Harald Welte5258fc42009-03-28 19:07:53 +00001803 bts->location_area_code = lac;
1804
1805 return CMD_SUCCESS;
1806}
1807
Harald Weltea43f7892009-12-01 18:04:30 +05301808
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001809/* compatibility wrapper for old config files */
1810DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001811 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001812 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001813 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001814{
Harald Welte5258fc42009-03-28 19:07:53 +00001815 return CMD_SUCCESS;
1816}
1817
Harald Welte78f2f502009-05-23 16:56:52 +00001818DEFUN(cfg_bts_bsic,
1819 cfg_bts_bsic_cmd,
1820 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001821 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1822 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001823{
1824 struct gsm_bts *bts = vty->index;
1825 int bsic = atoi(argv[0]);
1826
1827 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001828 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001829 bsic, VTY_NEWLINE);
1830 return CMD_WARNING;
1831 }
1832 bts->bsic = bsic;
1833
1834 return CMD_SUCCESS;
1835}
1836
Harald Welte4cc34222009-05-01 15:12:31 +00001837DEFUN(cfg_bts_unit_id,
1838 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001839 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001840 "Abis/IP specific options\n"
1841 "Set the IPA BTS Unit ID\n"
1842 "Unit ID (Site)\n"
1843 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001844{
1845 struct gsm_bts *bts = vty->index;
1846 int site_id = atoi(argv[0]);
1847 int bts_id = atoi(argv[1]);
1848
Harald Welte07dc73d2009-08-07 13:27:09 +02001849 if (!is_ipaccess_bts(bts)) {
1850 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1851 return CMD_WARNING;
1852 }
1853
Harald Welte4cc34222009-05-01 15:12:31 +00001854 bts->ip_access.site_id = site_id;
1855 bts->ip_access.bts_id = bts_id;
1856
1857 return CMD_SUCCESS;
1858}
1859
Harald Welte8b291802013-03-12 13:57:05 +01001860DEFUN(cfg_bts_rsl_ip,
1861 cfg_bts_rsl_ip_cmd,
1862 "ip.access rsl-ip A.B.C.D",
1863 "Abis/IP specific options\n"
1864 "Set the IPA RSL IP Address of the BSC\n"
1865 "Destination IP address for RSL connection\n")
1866{
1867 struct gsm_bts *bts = vty->index;
1868 struct in_addr ia;
1869
1870 if (!is_ipaccess_bts(bts)) {
1871 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1872 return CMD_WARNING;
1873 }
1874
1875 inet_aton(argv[0], &ia);
1876 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1877
1878 return CMD_SUCCESS;
1879}
1880
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001881#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001882
Sylvain Munautc9519462011-10-17 14:04:55 +02001883DEFUN(cfg_bts_nokia_site_skip_reset,
1884 cfg_bts_nokia_site_skip_reset_cmd,
1885 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001886 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001887 "Skip the reset step during bootstrap process of this BTS\n"
1888 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02001889{
1890 struct gsm_bts *bts = vty->index;
1891
1892 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
1893 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
1894 return CMD_WARNING;
1895 }
1896
1897 bts->nokia.skip_reset = atoi(argv[0]);
1898
1899 return CMD_SUCCESS;
1900}
1901
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001902DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
1903 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
1904 "nokia_site no-local-rel-conf (0|1)",
1905 NOKIA_STR
1906 "Do not wait for RELease CONFirm message when releasing channel locally\n"
1907 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
1908{
1909 struct gsm_bts *bts = vty->index;
1910
1911 if (!is_nokia_bts(bts)) {
1912 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1913 VTY_NEWLINE);
1914 return CMD_WARNING;
1915 }
1916
1917 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
1918
1919 return CMD_SUCCESS;
1920}
1921
Sipos Csaba56e17662015-02-07 13:27:36 +01001922DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
1923 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
1924 "nokia_site bts-reset-timer <15-100>",
1925 NOKIA_STR
1926 "The amount of time (in sec.) between BTS_RESET is sent,\n"
1927 "and the BTS is being bootstrapped.\n")
1928{
1929 struct gsm_bts *bts = vty->index;
1930
1931 if (!is_nokia_bts(bts)) {
1932 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1933 VTY_NEWLINE);
1934 return CMD_WARNING;
1935 }
1936
1937 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
1938
1939 return CMD_SUCCESS;
1940}
Harald Welte8f0ed552010-05-11 21:53:49 +02001941#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001942#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001943
Harald Welte8175e952009-10-20 00:22:00 +02001944DEFUN(cfg_bts_stream_id,
1945 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001946 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02001947 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001948 "Set the ip.access Stream ID of the OML link of this BTS\n"
1949 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02001950{
1951 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001952 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02001953
1954 if (!is_ipaccess_bts(bts)) {
1955 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1956 return CMD_WARNING;
1957 }
1958
1959 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001960 /* This is used by e1inp_bind_ops callback for each BTS model. */
1961 bts->oml_e1_link.e1_nr = linenr;
1962
1963 return CMD_SUCCESS;
1964}
1965
Harald Welted13e0cd2012-08-17 09:52:03 +02001966#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02001967
Harald Welte42581822009-08-08 16:12:58 +02001968DEFUN(cfg_bts_oml_e1,
1969 cfg_bts_oml_e1_cmd,
1970 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02001971 OML_E1_STR
1972 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001973 "E1/T1 line number to be used for OML\n"
1974 "E1/T1 timeslot to be used for OML\n"
1975 "E1/T1 timeslot to be used for OML\n"
1976 "E1/T1 sub-slot to be used for OML\n"
1977 "Use E1/T1 sub-slot 0\n"
1978 "Use E1/T1 sub-slot 1\n"
1979 "Use E1/T1 sub-slot 2\n"
1980 "Use E1/T1 sub-slot 3\n"
1981 "Use full E1 slot 3\n"
1982 )
Harald Welte42581822009-08-08 16:12:58 +02001983{
1984 struct gsm_bts *bts = vty->index;
1985
1986 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
1987
1988 return CMD_SUCCESS;
1989}
1990
1991
1992DEFUN(cfg_bts_oml_e1_tei,
1993 cfg_bts_oml_e1_tei_cmd,
1994 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001995 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001996 "Set the TEI to be used for OML\n"
1997 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02001998{
1999 struct gsm_bts *bts = vty->index;
2000
2001 bts->oml_tei = atoi(argv[0]);
2002
2003 return CMD_SUCCESS;
2004}
2005
Harald Welte7a8fa412009-08-10 13:48:16 +02002006DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2007 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002008 "Channnel Allocator\n" "Channel Allocator\n"
2009 "Allocate Timeslots and Transceivers in ascending order\n"
2010 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002011{
2012 struct gsm_bts *bts = vty->index;
2013
2014 if (!strcmp(argv[0], "ascending"))
2015 bts->chan_alloc_reverse = 0;
2016 else
2017 bts->chan_alloc_reverse = 1;
2018
2019 return CMD_SUCCESS;
2020}
2021
Harald Welte8f0ed552010-05-11 21:53:49 +02002022#define RACH_STR "Random Access Control Channel\n"
2023
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002024DEFUN(cfg_bts_rach_tx_integer,
2025 cfg_bts_rach_tx_integer_cmd,
2026 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002027 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002028 "Set the raw tx integer value in RACH Control parameters IE\n"
2029 "Set the raw tx integer value in RACH Control parameters IE\n"
2030 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002031{
2032 struct gsm_bts *bts = vty->index;
2033 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2034 return CMD_SUCCESS;
2035}
2036
2037DEFUN(cfg_bts_rach_max_trans,
2038 cfg_bts_rach_max_trans_cmd,
2039 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002040 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002041 "Set the maximum number of RACH burst transmissions\n"
2042 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002043 "Maximum number of 1 RACH burst transmissions\n"
2044 "Maximum number of 2 RACH burst transmissions\n"
2045 "Maximum number of 4 RACH burst transmissions\n"
2046 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002047{
2048 struct gsm_bts *bts = vty->index;
2049 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2050 return CMD_SUCCESS;
2051}
2052
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002053#define CD_STR "Channel Description\n"
2054
2055DEFUN(cfg_bts_chan_desc_att,
2056 cfg_bts_chan_desc_att_cmd,
2057 "channel-descrption attach (0|1)",
2058 CD_STR
2059 "Set if attachment is required\n"
2060 "Attachment is NOT required\n"
2061 "Attachment is required (standard)\n")
2062{
2063 struct gsm_bts *bts = vty->index;
2064 bts->si_common.chan_desc.att = atoi(argv[0]);
2065 return CMD_SUCCESS;
2066}
2067
2068DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2069 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2070 "channel-descrption bs-pa-mfrms <2-9>",
2071 CD_STR
2072 "Set number of multiframe periods for paging groups\n"
2073 "Number of multiframe periods for paging groups\n")
2074{
2075 struct gsm_bts *bts = vty->index;
2076 int bs_pa_mfrms = atoi(argv[0]);
2077
2078 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2079 return CMD_SUCCESS;
2080}
2081
2082DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2083 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2084 "channel-descrption bs-ag-blks-res <0-7>",
2085 CD_STR
2086 "Set number of blocks reserved for access grant\n"
2087 "Number of blocks reserved for access grant\n")
2088{
2089 struct gsm_bts *bts = vty->index;
2090 int bs_ag_blks_res = atoi(argv[0]);
2091
2092 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2093 return CMD_SUCCESS;
2094}
2095
Harald Welte8f0ed552010-05-11 21:53:49 +02002096#define NM_STR "Network Management\n"
2097
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002098DEFUN(cfg_bts_rach_nm_b_thresh,
2099 cfg_bts_rach_nm_b_thresh_cmd,
2100 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002101 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002102 "Set the NM Busy Threshold\n"
2103 "Set the NM Busy Threshold\n"
2104 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002105{
2106 struct gsm_bts *bts = vty->index;
2107 bts->rach_b_thresh = atoi(argv[0]);
2108 return CMD_SUCCESS;
2109}
2110
2111DEFUN(cfg_bts_rach_nm_ldavg,
2112 cfg_bts_rach_nm_ldavg_cmd,
2113 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002114 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002115 "Set the NM Loadaverage Slots value\n"
2116 "Set the NM Loadaverage Slots value\n"
2117 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002118{
2119 struct gsm_bts *bts = vty->index;
2120 bts->rach_ldavg_slots = atoi(argv[0]);
2121 return CMD_SUCCESS;
2122}
2123
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002124DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2125 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002126 "Should this cell be barred from access?\n"
2127 "Should this cell be barred from access?\n"
2128 "Cell should NOT be barred\n"
2129 "Cell should be barred\n")
2130
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002131{
2132 struct gsm_bts *bts = vty->index;
2133
Harald Welte71355012009-12-21 23:08:18 +01002134 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002135
2136 return CMD_SUCCESS;
2137}
2138
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002139DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2140 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002141 RACH_STR
2142 "Should this cell allow emergency calls?\n"
2143 "Should this cell allow emergency calls?\n"
2144 "Should this cell allow emergency calls?\n"
2145 "Do NOT allow emergency calls\n"
2146 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002147{
2148 struct gsm_bts *bts = vty->index;
2149
2150 if (atoi(argv[0]) == 0)
2151 bts->si_common.rach_control.t2 |= 0x4;
2152 else
2153 bts->si_common.rach_control.t2 &= ~0x4;
2154
2155 return CMD_SUCCESS;
2156}
2157
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002158DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2159 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2160 RACH_STR
2161 "Set access control class\n"
2162 "Access control class 0\n"
2163 "Access control class 1\n"
2164 "Access control class 2\n"
2165 "Access control class 3\n"
2166 "Access control class 4\n"
2167 "Access control class 5\n"
2168 "Access control class 6\n"
2169 "Access control class 7\n"
2170 "Access control class 8\n"
2171 "Access control class 9\n"
2172 "Access control class 11 for PLMN use\n"
2173 "Access control class 12 for security services\n"
2174 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2175 "Access control class 14 for emergency services\n"
2176 "Access control class 15 for PLMN staff\n"
2177 "barred to use access control class\n"
2178 "allowed to use access control class\n")
2179{
2180 struct gsm_bts *bts = vty->index;
2181
2182 uint8_t control_class;
2183 uint8_t allowed = 0;
2184
2185 if (strcmp(argv[1], "allowed") == 0)
2186 allowed = 1;
2187
2188 control_class = atoi(argv[0]);
2189 if (control_class < 8)
2190 if (allowed)
2191 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2192 else
2193 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2194 else
2195 if (allowed)
2196 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2197 else
2198 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2199
2200 return CMD_SUCCESS;
2201}
2202
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002203DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2204 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002205 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002206 "Maximum transmit power of the MS\n"
2207 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002208 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002209{
2210 struct gsm_bts *bts = vty->index;
2211
2212 bts->ms_max_power = atoi(argv[0]);
2213
2214 return CMD_SUCCESS;
2215}
2216
Harald Weltecfaabbb2012-08-16 23:23:50 +02002217#define CELL_STR "Cell Parameters\n"
2218
Harald Welte73225282009-12-12 18:17:25 +01002219DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2220 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002221 CELL_STR "Cell re-selection parameters\n"
2222 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002223 "Cell Re-Selection Hysteresis in dB")
2224{
2225 struct gsm_bts *bts = vty->index;
2226
2227 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2228
2229 return CMD_SUCCESS;
2230}
2231
2232DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2233 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002234 "Minimum RxLev needed for cell access\n"
2235 "Minimum RxLev needed for cell access\n"
2236 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002237 "Minimum RxLev needed for cell access (better than -110dBm)")
2238{
2239 struct gsm_bts *bts = vty->index;
2240
2241 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2242
2243 return CMD_SUCCESS;
2244}
2245
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002246DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2247 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002248 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2249 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002250{
2251 struct gsm_bts *bts = vty->index;
2252
2253 bts->si_common.cell_ro_sel_par.present = 1;
2254 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2255
2256 return CMD_SUCCESS;
2257}
2258
2259DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2260 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002261 CELL_STR "Cell Re-Selection Parameters\n"
2262 "Cell Re-Selection Offset (CRO) in dB\n"
2263 "Cell Re-Selection Offset (CRO) in dB\n"
2264 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002265{
2266 struct gsm_bts *bts = vty->index;
2267
2268 bts->si_common.cell_ro_sel_par.present = 1;
2269 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2270
2271 return CMD_SUCCESS;
2272}
2273
2274DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2275 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002276 "Cell selection temporary negative offset\n"
2277 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002278 "Cell selection temporary negative offset in dB")
2279{
2280 struct gsm_bts *bts = vty->index;
2281
2282 bts->si_common.cell_ro_sel_par.present = 1;
2283 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2284
2285 return CMD_SUCCESS;
2286}
2287
2288DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2289 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002290 "Cell selection temporary negative offset\n"
2291 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002292 "Sets cell selection temporary negative offset to infinity")
2293{
2294 struct gsm_bts *bts = vty->index;
2295
2296 bts->si_common.cell_ro_sel_par.present = 1;
2297 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2298
2299 return CMD_SUCCESS;
2300}
2301
2302DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2303 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002304 "Cell selection penalty time\n"
2305 "Cell selection penalty time\n"
2306 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002307{
2308 struct gsm_bts *bts = vty->index;
2309
2310 bts->si_common.cell_ro_sel_par.present = 1;
2311 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2312
2313 return CMD_SUCCESS;
2314}
2315
2316DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2317 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002318 "Cell selection penalty time\n"
2319 "Cell selection penalty time\n"
2320 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002321 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2322 "and TEMPORARY_OFFSET is ignored)")
2323{
2324 struct gsm_bts *bts = vty->index;
2325
2326 bts->si_common.cell_ro_sel_par.present = 1;
2327 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2328
2329 return CMD_SUCCESS;
2330}
2331
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002332DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2333 "radio-link-timeout <4-64>",
2334 "Radio link timeout criterion (BTS side)\n"
2335 "Radio link timeout value (lost SACCH block)\n")
2336{
2337 struct gsm_bts *bts = vty->index;
2338
Harald Welte2f8b9d22017-06-18 11:12:13 +03002339 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2340
2341 return CMD_SUCCESS;
2342}
2343
2344DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2345 "radio-link-timeout infinite",
2346 "Radio link timeout criterion (BTS side)\n"
2347 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2348{
2349 struct gsm_bts *bts = vty->index;
2350
2351 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2352 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2353 return CMD_WARNING;
2354 }
2355
2356 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2357 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002358
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002359 return CMD_SUCCESS;
2360}
2361
Harald Welte8f0ed552010-05-11 21:53:49 +02002362#define GPRS_TEXT "GPRS Packet Network\n"
2363
Harald Welteaf387632010-03-14 23:30:30 +08002364DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002365 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002366 GPRS_TEXT
2367 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002368 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002369 "GPRS BSSGP VC Identifier")
2370{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002371 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002372 struct gsm_bts *bts = vty->index;
2373
Harald Welte4511d892010-04-18 15:51:20 +02002374 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002375 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2376 return CMD_WARNING;
2377 }
2378
Harald Welte97a282b2010-03-14 15:37:43 +08002379 bts->gprs.cell.bvci = atoi(argv[0]);
2380
2381 return CMD_SUCCESS;
2382}
2383
Harald Weltea5731cf2010-03-22 11:48:36 +08002384DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2385 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002386 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002387 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002388 "GPRS NS Entity Identifier")
2389{
2390 struct gsm_bts *bts = vty->index;
2391
Harald Welte4511d892010-04-18 15:51:20 +02002392 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002393 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2394 return CMD_WARNING;
2395 }
2396
2397 bts->gprs.nse.nsei = atoi(argv[0]);
2398
2399 return CMD_SUCCESS;
2400}
2401
Harald Welte8f0ed552010-05-11 21:53:49 +02002402#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2403 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002404
Harald Welte97a282b2010-03-14 15:37:43 +08002405DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2406 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002407 GPRS_TEXT NSVC_TEXT
2408 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002409 "GPRS NS VC Identifier")
2410{
2411 struct gsm_bts *bts = vty->index;
2412 int idx = atoi(argv[0]);
2413
Harald Welte4511d892010-04-18 15:51:20 +02002414 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002415 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2416 return CMD_WARNING;
2417 }
2418
Harald Welte97a282b2010-03-14 15:37:43 +08002419 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2420
2421 return CMD_SUCCESS;
2422}
2423
Harald Welteaf387632010-03-14 23:30:30 +08002424DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2425 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002426 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002427 "GPRS NS Local UDP Port\n"
2428 "GPRS NS Local UDP Port\n"
2429 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002430 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002431{
2432 struct gsm_bts *bts = vty->index;
2433 int idx = atoi(argv[0]);
2434
Harald Welte4511d892010-04-18 15:51:20 +02002435 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002436 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2437 return CMD_WARNING;
2438 }
2439
Harald Welteaf387632010-03-14 23:30:30 +08002440 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2441
2442 return CMD_SUCCESS;
2443}
2444
2445DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2446 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002447 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002448 "GPRS NS Remote UDP Port\n"
2449 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002450 "GPRS NS Remote UDP Port\n"
2451 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002452{
2453 struct gsm_bts *bts = vty->index;
2454 int idx = atoi(argv[0]);
2455
Harald Welte4511d892010-04-18 15:51:20 +02002456 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002457 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2458 return CMD_WARNING;
2459 }
2460
Harald Welteaf387632010-03-14 23:30:30 +08002461 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2462
2463 return CMD_SUCCESS;
2464}
2465
2466DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2467 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002468 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002469 "GPRS NS Remote IP Address\n"
2470 "GPRS NS Remote IP Address\n"
2471 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002472{
2473 struct gsm_bts *bts = vty->index;
2474 int idx = atoi(argv[0]);
2475 struct in_addr ia;
2476
Harald Welte4511d892010-04-18 15:51:20 +02002477 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002478 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2479 return CMD_WARNING;
2480 }
2481
Harald Welteaf387632010-03-14 23:30:30 +08002482 inet_aton(argv[1], &ia);
2483 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2484
2485 return CMD_SUCCESS;
2486}
2487
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002488DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002489 "paging free <-1-1024>",
2490 "Paging options\n"
2491 "Only page when having a certain amount of free slots\n"
2492 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002493{
2494 struct gsm_bts *bts = vty->index;
2495
2496 bts->paging.free_chans_need = atoi(argv[0]);
2497 return CMD_SUCCESS;
2498}
2499
Harald Welte615e9562010-05-11 23:50:21 +02002500DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2501 "gprs ns timer " NS_TIMERS " <0-255>",
2502 GPRS_TEXT "Network Service\n"
2503 "Network Service Timer\n"
2504 NS_TIMERS_HELP "Timer Value\n")
2505{
2506 struct gsm_bts *bts = vty->index;
2507 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2508 int val = atoi(argv[1]);
2509
2510 if (bts->gprs.mode == BTS_GPRS_NONE) {
2511 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2512 return CMD_WARNING;
2513 }
2514
2515 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2516 return CMD_WARNING;
2517
2518 bts->gprs.nse.timer[idx] = val;
2519
2520 return CMD_SUCCESS;
2521}
2522
2523#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 +02002524#define BSSGP_TIMERS_HELP \
2525 "Tbvc-block timeout\n" \
2526 "Tbvc-block retries\n" \
2527 "Tbvc-unblock retries\n" \
2528 "Tbvcc-reset timeout\n" \
2529 "Tbvc-reset retries\n" \
2530 "Tbvc-suspend timeout\n" \
2531 "Tbvc-suspend retries\n" \
2532 "Tbvc-resume timeout\n" \
2533 "Tbvc-resume retries\n" \
2534 "Tbvc-capa-update timeout\n" \
2535 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002536
2537DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2538 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2539 GPRS_TEXT "Cell / BSSGP\n"
2540 "Cell/BSSGP Timer\n"
2541 BSSGP_TIMERS_HELP "Timer Value\n")
2542{
2543 struct gsm_bts *bts = vty->index;
2544 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2545 int val = atoi(argv[1]);
2546
2547 if (bts->gprs.mode == BTS_GPRS_NONE) {
2548 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2549 return CMD_WARNING;
2550 }
2551
2552 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2553 return CMD_WARNING;
2554
2555 bts->gprs.cell.timer[idx] = val;
2556
2557 return CMD_SUCCESS;
2558}
2559
Harald Welte97a282b2010-03-14 15:37:43 +08002560DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2561 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002562 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002563 "GPRS Routing Area Code\n"
2564 "GPRS Routing Area Code\n"
2565 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002566{
2567 struct gsm_bts *bts = vty->index;
2568
Harald Welte4511d892010-04-18 15:51:20 +02002569 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002570 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2571 return CMD_WARNING;
2572 }
2573
Harald Welte97a282b2010-03-14 15:37:43 +08002574 bts->gprs.rac = atoi(argv[0]);
2575
2576 return CMD_SUCCESS;
2577}
2578
Max292ec582016-07-28 11:55:37 +02002579DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2580 "gprs control-ack-type-rach", GPRS_TEXT
2581 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2582 "four access bursts format instead of default RLC/MAC control block\n")
2583{
2584 struct gsm_bts *bts = vty->index;
2585
2586 if (bts->gprs.mode == BTS_GPRS_NONE) {
2587 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2588 return CMD_WARNING;
2589 }
2590
2591 bts->gprs.ctrl_ack_type_use_block = false;
2592
2593 return CMD_SUCCESS;
2594}
2595
2596DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2597 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2598 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2599 "four access bursts format instead of default RLC/MAC control block\n")
2600{
2601 struct gsm_bts *bts = vty->index;
2602
2603 if (bts->gprs.mode == BTS_GPRS_NONE) {
2604 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2605 return CMD_WARNING;
2606 }
2607
2608 bts->gprs.ctrl_ack_type_use_block = true;
2609
2610 return CMD_SUCCESS;
2611}
2612
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002613DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2614 "gprs network-control-order (nc0|nc1|nc2)",
2615 GPRS_TEXT
2616 "GPRS Network Control Order\n"
2617 "MS controlled cell re-selection, no measurement reporting\n"
2618 "MS controlled cell re-selection, MS sends measurement reports\n"
2619 "Network controlled cell re-selection, MS sends measurement reports\n")
2620{
2621 struct gsm_bts *bts = vty->index;
2622
2623 if (bts->gprs.mode == BTS_GPRS_NONE) {
2624 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2625 return CMD_WARNING;
2626 }
2627
2628 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2629
2630 return CMD_SUCCESS;
2631}
2632
Harald Welte4511d892010-04-18 15:51:20 +02002633DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2634 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002635 GPRS_TEXT
2636 "GPRS Mode for this BTS\n"
2637 "GPRS Disabled on this BTS\n"
2638 "GPRS Enabled on this BTS\n"
2639 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002640{
2641 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002642 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002643
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002644 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002645 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2646 VTY_NEWLINE);
2647 return CMD_WARNING;
2648 }
2649
2650 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002651
2652 return CMD_SUCCESS;
2653}
2654
bhargava350533c2016-07-21 11:14:34 +05302655DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2656 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2657 "gprs 11bit_rach_support_for_egprs (0|1)",
2658 GPRS_TEXT "11 bit RACH options\n"
2659 "Disable 11 bit RACH for EGPRS\n"
2660 "Enable 11 bit RACH for EGPRS")
2661{
2662 struct gsm_bts *bts = vty->index;
2663
2664 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2665
2666 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2667 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2668 return CMD_WARNING;
2669 }
2670
2671 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2672 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2673 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2674 " enabled%s", VTY_NEWLINE);
2675 return CMD_WARNING;
2676 }
2677
2678 return CMD_SUCCESS;
2679}
2680
Harald Welte9fbff4a2010-07-30 11:50:09 +02002681#define SI_TEXT "System Information Messages\n"
2682#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)"
2683#define SI_TYPE_HELP "System Information Type 1\n" \
2684 "System Information Type 2\n" \
2685 "System Information Type 3\n" \
2686 "System Information Type 4\n" \
2687 "System Information Type 5\n" \
2688 "System Information Type 6\n" \
2689 "System Information Type 7\n" \
2690 "System Information Type 8\n" \
2691 "System Information Type 9\n" \
2692 "System Information Type 10\n" \
2693 "System Information Type 13\n" \
2694 "System Information Type 16\n" \
2695 "System Information Type 17\n" \
2696 "System Information Type 18\n" \
2697 "System Information Type 19\n" \
2698 "System Information Type 20\n" \
2699 "System Information Type 2bis\n" \
2700 "System Information Type 2ter\n" \
2701 "System Information Type 2quater\n" \
2702 "System Information Type 5bis\n" \
2703 "System Information Type 5ter\n"
2704
2705DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2706 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2707 SI_TEXT SI_TYPE_HELP
2708 "System Information Mode\n"
2709 "Static user-specified\n"
2710 "Dynamic, BSC-computed\n")
2711{
2712 struct gsm_bts *bts = vty->index;
2713 int type;
2714
2715 type = get_string_value(osmo_sitype_strs, argv[0]);
2716 if (type < 0) {
2717 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2718 return CMD_WARNING;
2719 }
2720
2721 if (!strcmp(argv[1], "static"))
2722 bts->si_mode_static |= (1 << type);
2723 else
2724 bts->si_mode_static &= ~(1 << type);
2725
2726 return CMD_SUCCESS;
2727}
2728
2729DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2730 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2731 SI_TEXT SI_TYPE_HELP
2732 "Static System Information filling\n"
2733 "Static user-specified SI content in HEX notation\n")
2734{
2735 struct gsm_bts *bts = vty->index;
2736 int rc, type;
2737
2738 type = get_string_value(osmo_sitype_strs, argv[0]);
2739 if (type < 0) {
2740 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2741 return CMD_WARNING;
2742 }
2743
2744 if (!(bts->si_mode_static & (1 << type))) {
2745 vty_out(vty, "SI Type %s is not configured in static mode%s",
2746 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2747 return CMD_WARNING;
2748 }
2749
Harald Welte290aaed2010-07-30 11:53:18 +02002750 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002751 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002752
2753 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002754 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2755 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002756 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2757 return CMD_WARNING;
2758 }
2759
2760 /* Mark this SI as present */
2761 bts->si_valid |= (1 << type);
2762
2763 return CMD_SUCCESS;
2764}
2765
Harald Welte42def722017-01-13 00:10:32 +01002766DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2767 "early-classmark-sending (allowed|forbidden)",
2768 "Early Classmark Sending\n"
2769 "Early Classmark Sending is allowed\n"
2770 "Early Classmark Sending is forbidden\n")
2771{
2772 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002773
2774 if (!strcmp(argv[0], "allowed"))
2775 bts->early_classmark_allowed = true;
2776 else
2777 bts->early_classmark_allowed = false;
2778
2779 return CMD_SUCCESS;
2780}
2781
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002782DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2783 "early-classmark-sending-3g (allowed|forbidden)",
2784 "3G Early Classmark Sending\n"
2785 "3G Early Classmark Sending is allowed\n"
2786 "3G Early Classmark Sending is forbidden\n")
2787{
2788 struct gsm_bts *bts = vty->index;
2789
2790 if (!strcmp(argv[0], "allowed"))
2791 bts->early_classmark_allowed_3g = true;
2792 else
2793 bts->early_classmark_allowed_3g = false;
2794
2795 return CMD_SUCCESS;
2796}
2797
Harald Welte32c09622011-01-11 23:44:56 +01002798DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002799 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002800 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002801 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2802 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002803{
2804 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002805 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002806
Harald Welte64c07d22011-02-15 11:43:27 +01002807 switch (mode) {
2808 case NL_MODE_MANUAL_SI5SEP:
2809 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002810 /* make sure we clear the current list when switching to
2811 * manual mode */
2812 if (bts->neigh_list_manual_mode == 0)
2813 memset(&bts->si_common.data.neigh_list, 0,
2814 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002815 break;
2816 default:
2817 break;
2818 }
2819
2820 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002821
2822 return CMD_SUCCESS;
2823}
2824
2825DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002826 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002827 "Neighbor List\n" "Add to manual neighbor list\n"
2828 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2829 "ARFCN of neighbor\n")
2830{
2831 struct gsm_bts *bts = vty->index;
2832 struct bitvec *bv = &bts->si_common.neigh_list;
2833 uint16_t arfcn = atoi(argv[1]);
2834
2835 if (!bts->neigh_list_manual_mode) {
2836 vty_out(vty, "%% Cannot configure neighbor list in "
2837 "automatic mode%s", VTY_NEWLINE);
2838 return CMD_WARNING;
2839 }
2840
2841 if (!strcmp(argv[0], "add"))
2842 bitvec_set_bit_pos(bv, arfcn, 1);
2843 else
2844 bitvec_set_bit_pos(bv, arfcn, 0);
2845
2846 return CMD_SUCCESS;
2847}
2848
Max70fdd242017-06-15 15:10:53 +02002849/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002850DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002851 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2852 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2853 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2854 "Add to manual SI2quater neighbor list\n"
2855 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2856 "threshold high bits\n" "threshold high bits\n"
2857 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2858 "priority\n" "priority (8 means NA)\n"
2859 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2860 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002861{
2862 struct gsm_bts *bts = vty->index;
2863 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2864 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002865 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2866 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002867 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002868
Max70fdd242017-06-15 15:10:53 +02002869 switch (r) {
2870 case 1:
2871 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2872 thresh_hi, VTY_NEWLINE);
2873 break;
2874 case EARFCN_THRESH_LOW_INVALID:
2875 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2876 thresh_lo, VTY_NEWLINE);
2877 break;
2878 case EARFCN_QRXLV_INVALID + 1:
2879 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2880 qrx, VTY_NEWLINE);
2881 break;
2882 case EARFCN_PRIO_INVALID:
2883 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
2884 prio, VTY_NEWLINE);
2885 break;
2886 default:
2887 if (r < 0) {
2888 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
2889 return CMD_WARNING;
2890 }
Max59a1bf32016-04-15 16:04:46 +02002891 }
2892
Max70fdd242017-06-15 15:10:53 +02002893 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01002894 return CMD_SUCCESS;
2895
Maxf39d03a2017-05-12 17:00:30 +02002896 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02002897 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02002898 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01002899
Maxaafff962016-04-20 15:57:14 +02002900 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02002901}
2902
2903DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02002904 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02002905 "SI2quater Neighbor List\n"
2906 "SI2quater Neighbor List\n"
2907 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02002908 "EARFCN of neighbor\n"
2909 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02002910{
2911 struct gsm_bts *bts = vty->index;
2912 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02002913 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02002914 int r = osmo_earfcn_del(e, arfcn);
2915 if (r < 0) {
2916 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02002917 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02002918 return CMD_WARNING;
2919 }
2920
2921 return CMD_SUCCESS;
2922}
2923
Max26679e02016-04-20 15:57:13 +02002924DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02002925 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02002926 "SI2quater Neighbor List\n"
2927 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
2928 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
2929 "diversity bit\n")
2930{
2931 struct gsm_bts *bts = vty->index;
2932 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
2933
2934 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
2935 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02002936 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 +01002937 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02002938 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02002939 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
2940 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01002941 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02002942 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02002943 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02002944 return CMD_WARNING;
2945 }
2946
2947 return CMD_SUCCESS;
2948}
2949
2950DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02002951 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02002952 "SI2quater Neighbor List\n"
2953 "SI2quater Neighbor List\n"
2954 "Delete from SI2quater manual neighbor list\n"
2955 "UARFCN of neighbor\n"
2956 "UARFCN\n"
2957 "scrambling code\n")
2958{
2959 struct gsm_bts *bts = vty->index;
2960
2961 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
2962 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
2963 VTY_NEWLINE);
2964 return CMD_WARNING;
2965 }
2966
2967 return CMD_SUCCESS;
2968}
2969
Harald Welte64c07d22011-02-15 11:43:27 +01002970DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002971 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002972 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002973 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
2974 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
2975 "ARFCN of neighbor\n")
2976{
2977 struct gsm_bts *bts = vty->index;
2978 struct bitvec *bv = &bts->si_common.si5_neigh_list;
2979 uint16_t arfcn = atoi(argv[1]);
2980
2981 if (!bts->neigh_list_manual_mode) {
2982 vty_out(vty, "%% Cannot configure neighbor list in "
2983 "automatic mode%s", VTY_NEWLINE);
2984 return CMD_WARNING;
2985 }
2986
2987 if (!strcmp(argv[0], "add"))
2988 bitvec_set_bit_pos(bv, arfcn, 1);
2989 else
2990 bitvec_set_bit_pos(bv, arfcn, 0);
2991
2992 return CMD_SUCCESS;
2993}
Harald Welte9fbff4a2010-07-30 11:50:09 +02002994
Harald Welte8254cf72017-05-29 13:42:19 +02002995DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
2996 "pcu-socket PATH",
2997 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
2998 "Path in the file system for the unix-domain PCU socket\n")
2999{
3000 struct gsm_bts *bts = vty->index;
3001 int rc;
3002
Harald Welte4a824ca2017-05-29 13:54:27 +02003003 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003004 pcu_sock_exit(bts);
3005 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3006 if (rc < 0) {
3007 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3008 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3009 return CMD_WARNING;
3010 }
3011
3012 return CMD_SUCCESS;
3013}
3014
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003015#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3016
3017DEFUN(cfg_bts_excl_rf_lock,
3018 cfg_bts_excl_rf_lock_cmd,
3019 "rf-lock-exclude",
3020 EXCL_RFLOCK_STR)
3021{
3022 struct gsm_bts *bts = vty->index;
3023 bts->excl_from_rf_lock = 1;
3024 return CMD_SUCCESS;
3025}
3026
3027DEFUN(cfg_bts_no_excl_rf_lock,
3028 cfg_bts_no_excl_rf_lock_cmd,
3029 "no rf-lock-exclude",
3030 NO_STR EXCL_RFLOCK_STR)
3031{
3032 struct gsm_bts *bts = vty->index;
3033 bts->excl_from_rf_lock = 0;
3034 return CMD_SUCCESS;
3035}
3036
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003037#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3038
3039DEFUN(cfg_bts_force_comb_si,
3040 cfg_bts_force_comb_si_cmd,
3041 "force-combined-si",
3042 FORCE_COMB_SI_STR)
3043{
3044 struct gsm_bts *bts = vty->index;
3045 bts->force_combined_si = 1;
3046 return CMD_SUCCESS;
3047}
3048
3049DEFUN(cfg_bts_no_force_comb_si,
3050 cfg_bts_no_force_comb_si_cmd,
3051 "no force-combined-si",
3052 NO_STR FORCE_COMB_SI_STR)
3053{
3054 struct gsm_bts *bts = vty->index;
3055 bts->force_combined_si = 0;
3056 return CMD_SUCCESS;
3057}
3058
Andreas Eversberga83d5112013-12-07 18:32:28 +01003059static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3060{
3061 struct gsm_bts *bts = vty->index;
3062 struct bts_codec_conf *codec = &bts->codec;
3063 int i;
3064
3065 codec->hr = 0;
3066 codec->efr = 0;
3067 codec->amr = 0;
3068 for (i = 0; i < argc; i++) {
3069 if (!strcmp(argv[i], "hr"))
3070 codec->hr = 1;
3071 if (!strcmp(argv[i], "efr"))
3072 codec->efr = 1;
3073 if (!strcmp(argv[i], "amr"))
3074 codec->amr = 1;
3075 }
3076}
3077
3078#define CODEC_PAR_STR " (hr|efr|amr)"
3079#define CODEC_HELP_STR "Half Rate\n" \
3080 "Enhanced Full Rate\nAdaptive Multirate\n"
3081
3082DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3083 "codec-support fr",
3084 "Codec Support settings\nFullrate\n")
3085{
3086 _get_codec_from_arg(vty, 0, argv);
3087 return CMD_SUCCESS;
3088}
3089
3090DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3091 "codec-support fr" CODEC_PAR_STR,
3092 "Codec Support settings\nFullrate\n"
3093 CODEC_HELP_STR)
3094{
3095 _get_codec_from_arg(vty, 1, argv);
3096 return CMD_SUCCESS;
3097}
3098
3099DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3100 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3101 "Codec Support settings\nFullrate\n"
3102 CODEC_HELP_STR CODEC_HELP_STR)
3103{
3104 _get_codec_from_arg(vty, 2, argv);
3105 return CMD_SUCCESS;
3106}
3107
3108DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3109 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3110 "Codec Support settings\nFullrate\n"
3111 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3112{
3113 _get_codec_from_arg(vty, 3, argv);
3114 return CMD_SUCCESS;
3115}
3116
3117DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3118 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3119 "Codec Support settings\nFullrate\n"
3120 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3121{
3122 _get_codec_from_arg(vty, 4, argv);
3123 return CMD_SUCCESS;
3124}
3125
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003126DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3127 "depends-on-bts <0-255>",
3128 "This BTS can only be started if another one is up\n" "BTS Number\n")
3129{
3130 struct gsm_bts *bts = vty->index;
3131 struct gsm_bts *other_bts;
3132 int dep = atoi(argv[0]);
3133
3134
3135 if (!is_ipaccess_bts(bts)) {
3136 vty_out(vty, "This feature is only available for IP systems.%s",
3137 VTY_NEWLINE);
3138 return CMD_WARNING;
3139 }
3140
3141 other_bts = gsm_bts_num(bts->network, dep);
3142 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3143 vty_out(vty, "This feature is only available for IP systems.%s",
3144 VTY_NEWLINE);
3145 return CMD_WARNING;
3146 }
3147
3148 if (dep >= bts->nr) {
3149 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3150 VTY_NEWLINE);
3151 return CMD_WARNING;
3152 }
3153
3154 bts_depend_mark(bts, dep);
3155 return CMD_SUCCESS;
3156}
3157
3158DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3159 "depeneds-on-bts <0-255>",
3160 NO_STR "This BTS can only be started if another one is up\n"
3161 "BTS Number\n")
3162{
3163 struct gsm_bts *bts = vty->index;
3164 int dep = atoi(argv[0]);
3165
3166 bts_depend_clear(bts, dep);
3167 return CMD_SUCCESS;
3168}
3169
Andreas Eversberg73266522014-01-19 11:47:44 +01003170#define AMR_TEXT "Adaptive Multi Rate settings\n"
3171#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3172#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3173 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3174#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3175#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3176
3177static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3178{
3179 struct gsm_bts *bts = vty->index;
3180 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3181 struct gsm48_multi_rate_conf *mr_conf =
3182 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3183 int i;
3184
3185 mr->gsm48_ie[1] = 0;
3186 for (i = 0; i < argc; i++)
3187 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3188 mr_conf->icmi = 0;
3189}
3190
3191static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3192{
3193 struct gsm_bts *bts = vty->index;
3194 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003195 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003196 int i;
3197
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003198 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3199 for (i = 0; i < argc - 1; i++)
3200 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003201}
3202
3203static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3204{
3205 struct gsm_bts *bts = vty->index;
3206 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003207 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003208 int i;
3209
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003210 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3211 for (i = 0; i < argc - 1; i++)
3212 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003213}
3214
3215static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3216{
3217 struct gsm_bts *bts = vty->index;
3218 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3219 struct gsm48_multi_rate_conf *mr_conf =
3220 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3221 int num = 0, i;
3222
3223 for (i = 0; i < ((full) ? 8 : 6); i++) {
3224 if ((mr->gsm48_ie[1] & (1 << i))) {
3225 num++;
3226 }
3227 }
3228
3229 if (argv[0][0] == 'a' || num == 0)
3230 mr_conf->icmi = 0;
3231 else {
3232 mr_conf->icmi = 1;
3233 if (num < atoi(argv[0]))
3234 mr_conf->smod = num - 1;
3235 else
3236 mr_conf->smod = atoi(argv[0]) - 1;
3237 }
3238}
3239
3240#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3241#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3242 "10,2k\n12,2k\n"
3243
3244#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3245#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3246
3247#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3248#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3249
3250DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3251 "amr tch-f modes" AMR_TCHF_PAR_STR,
3252 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3253 AMR_TCHF_HELP_STR)
3254{
3255 get_amr_from_arg(vty, 1, argv, 1);
3256 return CMD_SUCCESS;
3257}
3258
3259DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3260 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3261 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3262 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3263{
3264 get_amr_from_arg(vty, 2, argv, 1);
3265 return CMD_SUCCESS;
3266}
3267
3268DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3269 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3270 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3271 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3272{
3273 get_amr_from_arg(vty, 3, argv, 1);
3274 return CMD_SUCCESS;
3275}
3276
3277DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3278 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3279 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3280 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3281{
3282 get_amr_from_arg(vty, 4, argv, 1);
3283 return CMD_SUCCESS;
3284}
3285
3286DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3287 "amr tch-f start-mode (auto|1|2|3|4)",
3288 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3289{
3290 get_amr_start_from_arg(vty, argv, 1);
3291 return CMD_SUCCESS;
3292}
3293
3294DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3295 "amr tch-f threshold (ms|bts) <0-63>",
3296 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3297 AMR_TH_HELP_STR)
3298{
3299 get_amr_th_from_arg(vty, 2, argv, 1);
3300 return CMD_SUCCESS;
3301}
3302
3303DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3304 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3305 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3306 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3307{
3308 get_amr_th_from_arg(vty, 3, argv, 1);
3309 return CMD_SUCCESS;
3310}
3311
3312DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3313 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3314 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3315 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3316{
3317 get_amr_th_from_arg(vty, 4, argv, 1);
3318 return CMD_SUCCESS;
3319}
3320
3321DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3322 "amr tch-f hysteresis (ms|bts) <0-15>",
3323 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3324 AMR_HY_HELP_STR)
3325{
3326 get_amr_hy_from_arg(vty, 2, argv, 1);
3327 return CMD_SUCCESS;
3328}
3329
3330DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3331 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3332 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3333 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3334{
3335 get_amr_hy_from_arg(vty, 3, argv, 1);
3336 return CMD_SUCCESS;
3337}
3338
3339DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3340 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3341 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3342 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3343{
3344 get_amr_hy_from_arg(vty, 4, argv, 1);
3345 return CMD_SUCCESS;
3346}
3347
3348DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3349 "amr tch-h modes" AMR_TCHH_PAR_STR,
3350 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3351 AMR_TCHH_HELP_STR)
3352{
3353 get_amr_from_arg(vty, 1, argv, 0);
3354 return CMD_SUCCESS;
3355}
3356
3357DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3358 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3359 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3360 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3361{
3362 get_amr_from_arg(vty, 2, argv, 0);
3363 return CMD_SUCCESS;
3364}
3365
3366DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3367 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3368 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3369 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3370{
3371 get_amr_from_arg(vty, 3, argv, 0);
3372 return CMD_SUCCESS;
3373}
3374
3375DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3376 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3377 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3378 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3379{
3380 get_amr_from_arg(vty, 4, argv, 0);
3381 return CMD_SUCCESS;
3382}
3383
3384DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3385 "amr tch-h start-mode (auto|1|2|3|4)",
3386 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3387{
3388 get_amr_start_from_arg(vty, argv, 0);
3389 return CMD_SUCCESS;
3390}
3391
3392DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3393 "amr tch-h threshold (ms|bts) <0-63>",
3394 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3395 AMR_TH_HELP_STR)
3396{
3397 get_amr_th_from_arg(vty, 2, argv, 0);
3398 return CMD_SUCCESS;
3399}
3400
3401DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3402 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3403 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3404 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3405{
3406 get_amr_th_from_arg(vty, 3, argv, 0);
3407 return CMD_SUCCESS;
3408}
3409
3410DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3411 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3412 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3413 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3414{
3415 get_amr_th_from_arg(vty, 4, argv, 0);
3416 return CMD_SUCCESS;
3417}
3418
3419DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3420 "amr tch-h hysteresis (ms|bts) <0-15>",
3421 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3422 AMR_HY_HELP_STR)
3423{
3424 get_amr_hy_from_arg(vty, 2, argv, 0);
3425 return CMD_SUCCESS;
3426}
3427
3428DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3429 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3430 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3431 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3432{
3433 get_amr_hy_from_arg(vty, 3, argv, 0);
3434 return CMD_SUCCESS;
3435}
3436
3437DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3438 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3439 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3440 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3441{
3442 get_amr_hy_from_arg(vty, 4, argv, 0);
3443 return CMD_SUCCESS;
3444}
3445
Harald Welte8f0ed552010-05-11 21:53:49 +02003446#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003447
Harald Welte5258fc42009-03-28 19:07:53 +00003448/* per TRX configuration */
3449DEFUN(cfg_trx,
3450 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003451 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003452 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003453 "Select a TRX to configure")
3454{
3455 int trx_nr = atoi(argv[0]);
3456 struct gsm_bts *bts = vty->index;
3457 struct gsm_bts_trx *trx;
3458
Harald Weltee441d9c2009-06-21 16:17:15 +02003459 if (trx_nr > bts->num_trx) {
3460 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3461 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003462 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003463 } else if (trx_nr == bts->num_trx) {
3464 /* we need to allocate a new one */
3465 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003466 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003467 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003468
Harald Weltee441d9c2009-06-21 16:17:15 +02003469 if (!trx)
3470 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003471
3472 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003473 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003474 vty->node = TRX_NODE;
3475
3476 return CMD_SUCCESS;
3477}
3478
3479DEFUN(cfg_trx_arfcn,
3480 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003481 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003482 "Set the ARFCN for this TRX\n"
3483 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003484{
3485 int arfcn = atoi(argv[0]);
3486 struct gsm_bts_trx *trx = vty->index;
3487
3488 /* FIXME: check if this ARFCN is supported by this TRX */
3489
3490 trx->arfcn = arfcn;
3491
3492 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3493 /* FIXME: use OML layer to update the ARFCN */
3494 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3495
3496 return CMD_SUCCESS;
3497}
3498
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003499DEFUN(cfg_trx_nominal_power,
3500 cfg_trx_nominal_power_cmd,
3501 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003502 "Nominal TRX RF Power in dBm\n"
3503 "Nominal TRX RF Power in dBm\n"
3504 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003505{
3506 struct gsm_bts_trx *trx = vty->index;
3507
3508 trx->nominal_power = atoi(argv[0]);
3509
3510 return CMD_SUCCESS;
3511}
3512
Harald Weltefcd24452009-06-20 18:15:19 +02003513DEFUN(cfg_trx_max_power_red,
3514 cfg_trx_max_power_red_cmd,
3515 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003516 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003517 "Reduction of maximum BS RF Power in dB\n")
3518{
3519 int maxpwr_r = atoi(argv[0]);
3520 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003521 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003522
3523 /* FIXME: check if our BTS type supports more than 12 */
3524 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3525 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3526 maxpwr_r, VTY_NEWLINE);
3527 return CMD_WARNING;
3528 }
3529 if (maxpwr_r & 1) {
3530 vty_out(vty, "%% Power %d dB is not an even value%s",
3531 maxpwr_r, VTY_NEWLINE);
3532 return CMD_WARNING;
3533 }
3534
3535 trx->max_power_red = maxpwr_r;
3536
3537 /* FIXME: make sure we update this using OML */
3538
3539 return CMD_SUCCESS;
3540}
3541
Harald Welte42581822009-08-08 16:12:58 +02003542DEFUN(cfg_trx_rsl_e1,
3543 cfg_trx_rsl_e1_cmd,
3544 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003545 "RSL Parameters\n"
3546 "E1/T1 interface to be used for RSL\n"
3547 "E1/T1 interface to be used for RSL\n"
3548 "E1/T1 Line Number to be used for RSL\n"
3549 "E1/T1 Timeslot to be used for RSL\n"
3550 "E1/T1 Timeslot to be used for RSL\n"
3551 "E1/T1 Sub-slot to be used for RSL\n"
3552 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3553 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3554 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3555 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3556 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003557{
3558 struct gsm_bts_trx *trx = vty->index;
3559
3560 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3561
3562 return CMD_SUCCESS;
3563}
3564
3565DEFUN(cfg_trx_rsl_e1_tei,
3566 cfg_trx_rsl_e1_tei_cmd,
3567 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003568 "RSL Parameters\n"
3569 "Set the TEI to be used for RSL\n"
3570 "Set the TEI to be used for RSL\n"
3571 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003572{
3573 struct gsm_bts_trx *trx = vty->index;
3574
3575 trx->rsl_tei = atoi(argv[0]);
3576
3577 return CMD_SUCCESS;
3578}
3579
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003580DEFUN(cfg_trx_rf_locked,
3581 cfg_trx_rf_locked_cmd,
3582 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003583 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3584 "TRX is NOT RF locked (active)\n"
3585 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003586{
3587 int locked = atoi(argv[0]);
3588 struct gsm_bts_trx *trx = vty->index;
3589
Maxbe356ed2017-09-07 19:10:09 +02003590 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003591 return CMD_SUCCESS;
3592}
Harald Welte42581822009-08-08 16:12:58 +02003593
Harald Welte5258fc42009-03-28 19:07:53 +00003594/* per TS configuration */
3595DEFUN(cfg_ts,
3596 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003597 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003598 "Select a Timeslot to configure\n"
3599 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003600{
3601 int ts_nr = atoi(argv[0]);
3602 struct gsm_bts_trx *trx = vty->index;
3603 struct gsm_bts_trx_ts *ts;
3604
3605 if (ts_nr >= TRX_NR_TS) {
3606 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3607 TRX_NR_TS, VTY_NEWLINE);
3608 return CMD_WARNING;
3609 }
3610
3611 ts = &trx->ts[ts_nr];
3612
3613 vty->index = ts;
3614 vty->node = TS_NODE;
3615
3616 return CMD_SUCCESS;
3617}
3618
Harald Weltea6fd58e2009-08-07 00:25:23 +02003619DEFUN(cfg_ts_pchan,
3620 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003621 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003622 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003623{
3624 struct gsm_bts_trx_ts *ts = vty->index;
3625 int pchanc;
3626
3627 pchanc = gsm_pchan_parse(argv[0]);
3628 if (pchanc < 0)
3629 return CMD_WARNING;
3630
3631 ts->pchan = pchanc;
3632
3633 return CMD_SUCCESS;
3634}
3635
3636/* used for backwards compatibility with old config files that still
3637 * have uppercase pchan type names */
3638DEFUN_HIDDEN(cfg_ts_pchan_compat,
3639 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003640 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003641 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003642{
3643 struct gsm_bts_trx_ts *ts = vty->index;
3644 int pchanc;
3645
3646 pchanc = gsm_pchan_parse(argv[0]);
3647 if (pchanc < 0)
3648 return CMD_WARNING;
3649
3650 ts->pchan = pchanc;
3651
3652 return CMD_SUCCESS;
3653}
3654
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003655
3656
Harald Welte135a6482011-05-30 12:09:13 +02003657DEFUN(cfg_ts_tsc,
3658 cfg_ts_tsc_cmd,
3659 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003660 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003661{
3662 struct gsm_bts_trx_ts *ts = vty->index;
3663
Max71d082b2017-05-30 15:03:38 +02003664 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003665 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3666 "falling back to BCC%s", VTY_NEWLINE);
3667 ts->tsc = -1;
3668 return CMD_WARNING;
3669 }
3670
Harald Welte135a6482011-05-30 12:09:13 +02003671 ts->tsc = atoi(argv[0]);
3672
3673 return CMD_SUCCESS;
3674}
3675
Harald Weltea39b0f22010-06-14 22:26:10 +02003676#define HOPPING_STR "Configure frequency hopping\n"
3677
3678DEFUN(cfg_ts_hopping,
3679 cfg_ts_hopping_cmd,
3680 "hopping enabled (0|1)",
3681 HOPPING_STR "Enable or disable frequency hopping\n"
3682 "Disable frequency hopping\n" "Enable frequency hopping\n")
3683{
3684 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003685 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003686
Max71d082b2017-05-30 15:03:38 +02003687 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003688 vty_out(vty, "BTS model does not support hopping%s",
3689 VTY_NEWLINE);
3690 return CMD_WARNING;
3691 }
3692
3693 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003694
3695 return CMD_SUCCESS;
3696}
3697
Harald Welte6e0cd042009-09-12 13:05:33 +02003698DEFUN(cfg_ts_hsn,
3699 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003700 "hopping sequence-number <0-63>",
3701 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003702 "Which hopping sequence to use for this channel\n"
3703 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003704{
3705 struct gsm_bts_trx_ts *ts = vty->index;
3706
3707 ts->hopping.hsn = atoi(argv[0]);
3708
3709 return CMD_SUCCESS;
3710}
3711
3712DEFUN(cfg_ts_maio,
3713 cfg_ts_maio_cmd,
3714 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003715 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003716 "Which hopping MAIO to use for this channel\n"
3717 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003718{
3719 struct gsm_bts_trx_ts *ts = vty->index;
3720
3721 ts->hopping.maio = atoi(argv[0]);
3722
3723 return CMD_SUCCESS;
3724}
3725
3726DEFUN(cfg_ts_arfcn_add,
3727 cfg_ts_arfcn_add_cmd,
3728 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003729 HOPPING_STR "Configure hopping ARFCN list\n"
3730 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003731{
3732 struct gsm_bts_trx_ts *ts = vty->index;
3733 int arfcn = atoi(argv[0]);
3734
Harald Weltea39b0f22010-06-14 22:26:10 +02003735 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3736
Harald Welte6e0cd042009-09-12 13:05:33 +02003737 return CMD_SUCCESS;
3738}
3739
3740DEFUN(cfg_ts_arfcn_del,
3741 cfg_ts_arfcn_del_cmd,
3742 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003743 HOPPING_STR "Configure hopping ARFCN list\n"
3744 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003745{
3746 struct gsm_bts_trx_ts *ts = vty->index;
3747 int arfcn = atoi(argv[0]);
3748
Harald Weltea39b0f22010-06-14 22:26:10 +02003749 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3750
Harald Welte6e0cd042009-09-12 13:05:33 +02003751 return CMD_SUCCESS;
3752}
3753
Harald Weltea6fd58e2009-08-07 00:25:23 +02003754DEFUN(cfg_ts_e1_subslot,
3755 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003756 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003757 "E1/T1 channel connected to this on-air timeslot\n"
3758 "E1/T1 channel connected to this on-air timeslot\n"
3759 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003760 "E1/T1 timeslot connected to this on-air timeslot\n"
3761 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003762 "E1/T1 sub-slot connected to this on-air timeslot\n"
3763 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3764 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3765 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3766 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3767 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003768{
3769 struct gsm_bts_trx_ts *ts = vty->index;
3770
Harald Welte42581822009-08-08 16:12:58 +02003771 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003772
3773 return CMD_SUCCESS;
3774}
Harald Welte5258fc42009-03-28 19:07:53 +00003775
Harald Welte4f10c252010-05-16 21:47:13 +02003776void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3777{
Harald Weltecf9d4312017-12-13 23:17:16 +01003778 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003779 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003780 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003781 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003782}
3783
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003784DEFUN(drop_bts,
3785 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003786 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003787 "Debug/Simulation command to drop Abis/IP BTS\n"
3788 "Debug/Simulation command to drop Abis/IP BTS\n"
3789 "Debug/Simulation command to drop Abis/IP BTS\n"
3790 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003791{
3792 struct gsm_network *gsmnet;
3793 struct gsm_bts_trx *trx;
3794 struct gsm_bts *bts;
3795 unsigned int bts_nr;
3796
3797 gsmnet = gsmnet_from_vty(vty);
3798
3799 bts_nr = atoi(argv[0]);
3800 if (bts_nr >= gsmnet->num_bts) {
3801 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3802 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3803 return CMD_WARNING;
3804 }
3805
3806 bts = gsm_bts_num(gsmnet, bts_nr);
3807 if (!bts) {
3808 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3809 return CMD_WARNING;
3810 }
3811
3812 if (!is_ipaccess_bts(bts)) {
3813 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3814 return CMD_WARNING;
3815 }
3816
3817
3818 /* close all connections */
3819 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003820 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003821 } else if (strcmp(argv[1], "rsl") == 0) {
3822 /* close all rsl connections */
3823 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003824 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003825 }
3826 } else {
3827 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3828 return CMD_WARNING;
3829 }
3830
3831 return CMD_SUCCESS;
3832}
3833
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003834DEFUN(restart_bts, restart_bts_cmd,
3835 "restart-bts <0-65535>",
3836 "Restart ip.access nanoBTS through OML\n"
3837 "BTS Number\n")
3838{
3839 struct gsm_network *gsmnet;
3840 struct gsm_bts_trx *trx;
3841 struct gsm_bts *bts;
3842 unsigned int bts_nr;
3843
3844 gsmnet = gsmnet_from_vty(vty);
3845
3846 bts_nr = atoi(argv[0]);
3847 if (bts_nr >= gsmnet->num_bts) {
3848 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3849 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3850 return CMD_WARNING;
3851 }
3852
3853 bts = gsm_bts_num(gsmnet, bts_nr);
3854 if (!bts) {
3855 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3856 return CMD_WARNING;
3857 }
3858
3859 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3860 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3861 VTY_NEWLINE);
3862 return CMD_WARNING;
3863 }
3864
3865 /* go from last TRX to c0 */
3866 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3867 abis_nm_ipaccess_restart(trx);
3868
3869 return CMD_SUCCESS;
3870}
3871
Harald Welte8e2e22f2017-07-10 20:25:10 +02003872DEFUN(bts_resend, bts_resend_cmd,
3873 "bts <0-255> resend-system-information",
3874 "BTS Specific Commands\n" "BTS Number\n"
3875 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3876{
3877 struct gsm_network *gsmnet;
3878 struct gsm_bts_trx *trx;
3879 struct gsm_bts *bts;
3880 unsigned int bts_nr;
3881
3882 gsmnet = gsmnet_from_vty(vty);
3883
3884 bts_nr = atoi(argv[0]);
3885 if (bts_nr >= gsmnet->num_bts) {
3886 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3887 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3888 return CMD_WARNING;
3889 }
3890
3891 bts = gsm_bts_num(gsmnet, bts_nr);
3892 if (!bts) {
3893 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3894 return CMD_WARNING;
3895 }
3896
3897 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3898 gsm_bts_trx_set_system_infos(trx);
3899
3900 return CMD_SUCCESS;
3901}
3902
3903
Harald Welte30f1f372014-12-28 15:00:45 +01003904DEFUN(smscb_cmd, smscb_cmd_cmd,
3905 "bts <0-255> smscb-command <1-4> HEXSTRING",
3906 "BTS related commands\n" "BTS Number\n"
3907 "SMS Cell Broadcast\n" "Last Valid Block\n"
3908 "Hex Encoded SMSCB message (up to 88 octets)\n")
3909{
3910 struct gsm_bts *bts;
3911 int bts_nr = atoi(argv[0]);
3912 int last_block = atoi(argv[1]);
3913 struct rsl_ie_cb_cmd_type cb_cmd;
3914 uint8_t buf[88];
3915 int rc;
3916
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02003917 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01003918 if (!bts) {
3919 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3920 return CMD_WARNING;
3921 }
3922 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
3923 if (rc < 0 || rc > sizeof(buf)) {
3924 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3925 return CMD_WARNING;
3926 }
3927
3928 cb_cmd.spare = 0;
3929 cb_cmd.def_bcast = 0;
3930 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
3931
3932 switch (last_block) {
3933 case 1:
3934 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
3935 break;
3936 case 2:
3937 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
3938 break;
3939 case 3:
3940 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
3941 break;
3942 case 4:
3943 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
3944 break;
3945 }
3946
3947 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
3948
3949 return CMD_SUCCESS;
3950}
3951
Harald Welte7fe00fb2017-05-27 14:09:50 +02003952/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02003953static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
3954 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02003955{
Harald Welte645eb622017-05-27 15:52:58 +02003956 int bts_nr = atoi(bts_str);
3957 int trx_nr = atoi(trx_str);
3958 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003959 struct gsm_bts *bts;
3960 struct gsm_bts_trx *trx;
3961 struct gsm_bts_trx_ts *ts;
3962
3963 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
3964 if (!bts) {
3965 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3966 return NULL;
3967 }
3968
3969 trx = gsm_bts_trx_num(bts, trx_nr);
3970 if (!trx) {
3971 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
3972 return NULL;
3973 }
3974
3975 ts = &trx->ts[ts_nr];
3976
3977 return ts;
3978}
Harald Welte30f1f372014-12-28 15:00:45 +01003979
Harald Welted0d2b0b2010-12-23 13:18:07 +01003980DEFUN(pdch_act, pdch_act_cmd,
3981 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
3982 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
3983 "TRX Timeslot\n" "Timeslot Number\n" "Packet Data Channel\n"
3984 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
3985 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
3986{
Harald Welted0d2b0b2010-12-23 13:18:07 +01003987 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01003988 int activate;
3989
Harald Welte645eb622017-05-27 15:52:58 +02003990 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003991 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01003992 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01003993
Harald Welte7fe00fb2017-05-27 14:09:50 +02003994 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01003995 vty_out(vty, "%% This command only works for ipaccess BTS%s",
3996 VTY_NEWLINE);
3997 return CMD_WARNING;
3998 }
3999
Harald Welted0d2b0b2010-12-23 13:18:07 +01004000 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4001 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004002 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004003 return CMD_WARNING;
4004 }
4005
4006 if (!strcmp(argv[3], "activate"))
4007 activate = 1;
4008 else
4009 activate = 0;
4010
4011 rsl_ipacc_pdch_activate(ts, activate);
4012
4013 return CMD_SUCCESS;
4014
4015}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004016
Harald Welte2abd5e12017-05-27 14:10:40 +02004017/* determine the logical channel type based on the physical channel type */
4018static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4019{
4020 switch (pchan) {
4021 case GSM_PCHAN_TCH_F:
4022 return GSM_LCHAN_TCH_F;
4023 case GSM_PCHAN_TCH_H:
4024 return GSM_LCHAN_TCH_H;
4025 case GSM_PCHAN_SDCCH8_SACCH8C:
4026 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4027 case GSM_PCHAN_CCCH_SDCCH4:
4028 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4029 return GSM_LCHAN_SDCCH;
4030 default:
4031 return -1;
4032 }
4033}
4034
4035/* configure the lchan for a single AMR mode (as specified) */
4036static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4037{
4038 struct amr_multirate_conf mr;
4039 struct gsm48_multi_rate_conf *mr_conf;
4040 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4041
4042 if (amr_mode > 7)
4043 return -1;
4044
4045 memset(&mr, 0, sizeof(mr));
4046 mr_conf->ver = 1;
4047 /* bit-mask of supported modes, only one bit is set. Reflects
4048 * Figure 10.5.2.47a where there are no thershold and only a
4049 * single mode */
4050 mr.gsm48_ie[1] = 1 << amr_mode;
4051
4052 mr.ms_mode[0].mode = amr_mode;
4053 mr.bts_mode[0].mode = amr_mode;
4054
4055 /* encode this configuration into the lchan for both uplink and
4056 * downlink direction */
4057 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4058 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4059
4060 return 0;
4061}
4062
4063/* Debug/Measurement command to activate a given logical channel
4064 * manually in a given mode/codec. This is useful for receiver
4065 * performance testing (FER/RBER/...) */
4066DEFUN(lchan_act, lchan_act_cmd,
4067 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
4068 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4069 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot Number\n" "Sub-Slot Number\n"
4070 "Manual Channel Activation (e.g. for BER test)\n"
4071 "Manual Channel Deactivation (e.g. for BER test)\n"
4072 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4073{
4074 struct gsm_bts_trx_ts *ts;
4075 struct gsm_lchan *lchan;
4076 int ss_nr = atoi(argv[3]);
4077 const char *act_str = argv[4];
4078 const char *codec_str = argv[5];
4079 int activate;
4080
4081 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4082 if (!ts)
4083 return CMD_WARNING;
4084
4085 lchan = &ts->lchan[ss_nr];
4086
4087 if (!strcmp(act_str, "activate"))
4088 activate = 1;
4089 else
4090 activate = 0;
4091
4092 if (ss_nr >= ts_subslots(ts)) {
4093 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4094 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4095 return CMD_WARNING;
4096 }
4097
4098 if (activate) {
4099 int lchan_t;
4100 if (lchan->state != LCHAN_S_NONE) {
4101 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4102 return CMD_WARNING;
4103 }
4104 lchan_t = lchan_type_by_pchan(ts->pchan);
4105 if (lchan_t < 0)
4106 return CMD_WARNING;
4107 /* configure the lchan */
4108 lchan->type = lchan_t;
4109 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4110 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4111 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4112 else if (!strcmp(codec_str, "efr"))
4113 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4114 else if (!strcmp(codec_str, "amr")) {
4115 int amr_mode;
4116 if (argc < 7) {
4117 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4118 return CMD_WARNING;
4119 }
4120 amr_mode = atoi(argv[6]);
4121 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4122 lchan_set_single_amr_mode(lchan, amr_mode);
4123 }
4124 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4125 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4126 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004127 } else {
4128 rsl_direct_rf_release(lchan);
4129 }
4130
4131 return CMD_SUCCESS;
4132}
4133
Harald Welte3f86c522017-05-27 15:53:28 +02004134DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4135 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
4136 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4137 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot\n" "Sub-Slot Number\n"
4138 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4139{
4140 struct gsm_bts_trx_ts *ts;
4141 struct gsm_lchan *lchan;
4142 int ss_nr = atoi(argv[3]);
4143 int port = atoi(argv[5]);
4144 struct in_addr ia;
4145 inet_aton(argv[4], &ia);
4146
4147 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4148 if (!ts)
4149 return CMD_WARNING;
4150
4151 lchan = &ts->lchan[ss_nr];
4152
4153 if (ss_nr >= ts_subslots(ts)) {
4154 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4155 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4156 return CMD_WARNING;
4157 }
4158
4159 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4160 inet_ntoa(ia), port, VTY_NEWLINE);
4161 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4162 return CMD_SUCCESS;
4163}
Harald Welteb71147a2017-07-18 19:11:49 +02004164
4165DEFUN(ctrl_trap, ctrl_trap_cmd,
4166 "ctrl-interface generate-trap TRAP VALUE",
4167 "Commands related to the CTRL Interface\n"
4168 "Generate a TRAP for test purpose\n"
4169 "Identity/Name of the TRAP variable\n"
4170 "Value of the TRAP variable\n")
4171{
4172 struct gsm_network *net = gsmnet_from_vty(vty);
4173
4174 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4175 return CMD_SUCCESS;
4176}
4177
Harald Weltedcccb182010-05-16 20:52:23 +02004178extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004179
Maxdb0e3802017-01-12 19:35:11 +01004180int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004181{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004182 cfg_ts_pchan_cmd.string =
4183 vty_cmd_string_from_valstr(tall_bsc_ctx,
4184 gsm_pchant_names,
4185 "phys_chan_config (", "|", ")",
4186 VTY_DO_LOWER);
4187 cfg_ts_pchan_cmd.doc =
4188 vty_cmd_string_from_valstr(tall_bsc_ctx,
4189 gsm_pchant_descs,
4190 "Physical Channel Combination\n",
4191 "\n", "", 0);
4192
Harald Weltee555c2b2012-08-17 13:02:12 +02004193 cfg_bts_type_cmd.string =
4194 vty_cmd_string_from_valstr(tall_bsc_ctx,
4195 bts_type_names,
4196 "type (", "|", ")",
4197 VTY_DO_LOWER);
4198 cfg_bts_type_cmd.doc =
4199 vty_cmd_string_from_valstr(tall_bsc_ctx,
4200 bts_type_descs,
4201 "BTS Vendor/Type\n",
4202 "\n", "", 0);
4203
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +02004204 common_cs_vty_init(network, config_write_net);
Harald Weltee555c2b2012-08-17 13:02:12 +02004205
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004206 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004207 install_element_ve(&show_bts_cmd);
4208 install_element_ve(&show_trx_cmd);
4209 install_element_ve(&show_ts_cmd);
4210 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004211 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004212
Philipp Maier39f62bb2017-04-09 12:32:51 +02004213 install_element_ve(&show_subscr_conn_cmd);
4214 install_element_ve(&handover_subscr_conn_cmd);
4215
Harald Welteb4d5b172010-05-12 16:10:35 +00004216 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004217 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004218
Maxdb0e3802017-01-12 19:35:11 +01004219 logging_vty_add_cmds(NULL);
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004220
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004221 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Weltebc814502009-12-19 21:41:52 +01004222 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Welteb720bd32009-12-21 16:51:50 +01004223 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
4224 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
4225 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
4226 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
4227 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
4228 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004229 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004230 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4231 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4232 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4233 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4234 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4235 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4236 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4237 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4238 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004239 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004240 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004241 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004242 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02004243
4244 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004245 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004246 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004247 install_element(BTS_NODE, &cfg_description_cmd);
4248 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004249 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004250 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004251 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4252 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4253 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4254 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004255 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4256 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004257 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004258 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004259 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004260 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004261 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004262 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004263 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004264 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4265 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004266 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004267 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4268 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004269 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4270 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4271 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004272 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4273 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004274 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004275 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004276 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004277 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004278 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4279 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004280 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4281 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4282 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4283 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4284 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4285 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004286 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004287 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004288 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304289 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004290 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004291 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004292 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004293 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4294 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004295 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004296 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004297 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004298 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004299 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4300 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4301 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004302 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004303 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4304 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004305 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004306 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004307 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4308 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004309 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004310 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4311 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004312 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4313 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004314 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4315 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004316 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4317 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004318 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4319 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4320 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4321 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4322 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004323 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4324 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004325 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4326 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4327 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4328 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4329 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4330 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4331 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4332 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4333 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4334 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4335 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4336 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4337 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4338 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4339 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4340 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4341 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4342 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4343 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4344 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4345 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4346 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004347 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004348
Harald Welte5258fc42009-03-28 19:07:53 +00004349 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004350 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004351 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004352 install_element(TRX_NODE, &cfg_description_cmd);
4353 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004354 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004355 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004356 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4357 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004358 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004359
Harald Welte5258fc42009-03-28 19:07:53 +00004360 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004361 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004362 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004363 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004364 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004365 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004366 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4367 install_element(TS_NODE, &cfg_ts_maio_cmd);
4368 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4369 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004370 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004371
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004372 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004373 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004374 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004375 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004376 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004377 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004378 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004379 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004380
Harald Welte81c9b9c2010-05-31 16:40:40 +02004381 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004382 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004383 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004384 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004385
Harald Weltedcccb182010-05-16 20:52:23 +02004386 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004387
Harald Welte68628e82009-03-10 12:17:57 +00004388 return 0;
4389}