blob: 7612edaac71c834ed3e80d3e07e4365f2f9aaf31 [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)
301 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.%s",
302 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60,
303 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);
Harald Welte68628e82009-03-10 12:17:57 +0000863 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200864 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200865 if (is_ipaccess_bts(trx->bts)) {
866 vty_out(vty, " ip.access stream ID: 0x%02x%s",
867 trx->rsl_tei, VTY_NEWLINE);
868 } else {
869 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
870 e1isl_dump_vty(vty, trx->rsl_link);
871 }
Harald Welte68628e82009-03-10 12:17:57 +0000872}
873
874DEFUN(show_trx,
875 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100876 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200877 SHOW_STR "Display information about a TRX\n"
878 "BTS Number\n"
879 "TRX Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000880{
Harald Weltedcccb182010-05-16 20:52:23 +0200881 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000882 struct gsm_bts *bts = NULL;
883 struct gsm_bts_trx *trx;
884 int bts_nr, trx_nr;
885
886 if (argc >= 1) {
887 /* use the BTS number that the user has specified */
888 bts_nr = atoi(argv[0]);
889 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000890 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000891 VTY_NEWLINE);
892 return CMD_WARNING;
893 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200894 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000895 }
896 if (argc >= 2) {
897 trx_nr = atoi(argv[1]);
898 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000899 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000900 VTY_NEWLINE);
901 return CMD_WARNING;
902 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200903 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000904 trx_dump_vty(vty, trx);
905 return CMD_SUCCESS;
906 }
907 if (bts) {
908 /* print all TRX in this BTS */
909 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200910 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000911 trx_dump_vty(vty, trx);
912 }
913 return CMD_SUCCESS;
914 }
915
916 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200917 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000918 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200919 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000920 trx_dump_vty(vty, trx);
921 }
922 }
923
924 return CMD_SUCCESS;
925}
926
Harald Welte67ce0732009-08-06 19:06:46 +0200927
Harald Welte68628e82009-03-10 12:17:57 +0000928static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
929{
Harald Welte135a6482011-05-30 12:09:13 +0200930 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +0100931 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +0100932 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +0100933 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +0100934 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200935 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +0100936 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000937 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200938 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530939 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000940 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
941 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
942 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000943}
944
945DEFUN(show_ts,
946 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100947 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200948 SHOW_STR "Display information about a TS\n"
949 "BTS Number\n" "TRX Number\n" "Timeslot Number\n")
Harald Welte68628e82009-03-10 12:17:57 +0000950{
Harald Weltedcccb182010-05-16 20:52:23 +0200951 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +0100952 struct gsm_bts *bts = NULL;
953 struct gsm_bts_trx *trx = NULL;
954 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000955 int bts_nr, trx_nr, ts_nr;
956
957 if (argc >= 1) {
958 /* use the BTS number that the user has specified */
959 bts_nr = atoi(argv[0]);
960 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000961 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000962 VTY_NEWLINE);
963 return CMD_WARNING;
964 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200965 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000966 }
967 if (argc >= 2) {
968 trx_nr = atoi(argv[1]);
969 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000970 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000971 VTY_NEWLINE);
972 return CMD_WARNING;
973 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200974 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000975 }
976 if (argc >= 3) {
977 ts_nr = atoi(argv[2]);
978 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +0000979 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +0000980 VTY_NEWLINE);
981 return CMD_WARNING;
982 }
Harald Welte274d0152010-12-24 12:05:03 +0100983 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +0000984 ts = &trx->ts[ts_nr];
985 ts_dump_vty(vty, ts);
986 return CMD_SUCCESS;
987 }
Harald Welte274d0152010-12-24 12:05:03 +0100988
989 if (bts && trx) {
990 /* Iterate over all TS in this TRX */
991 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
992 ts = &trx->ts[ts_nr];
993 ts_dump_vty(vty, ts);
994 }
995 } else if (bts) {
996 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +0000997 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +0200998 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000999 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1000 ts = &trx->ts[ts_nr];
1001 ts_dump_vty(vty, ts);
1002 }
1003 }
Harald Welte274d0152010-12-24 12:05:03 +01001004 } else {
1005 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1006 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1007 bts = gsm_bts_num(net, bts_nr);
1008 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1009 trx = gsm_bts_trx_num(bts, trx_nr);
1010 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1011 ts = &trx->ts[ts_nr];
1012 ts_dump_vty(vty, ts);
1013 }
1014 }
1015 }
Harald Welte68628e82009-03-10 12:17:57 +00001016 }
1017
1018 return CMD_SUCCESS;
1019}
1020
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001021static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1022{
1023 if (strlen(bsub->imsi))
1024 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1025 if (bsub->tmsi != GSM_RESERVED_TMSI)
1026 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1027 VTY_NEWLINE);
1028 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1029}
1030
Harald Welte8387a492009-12-22 21:43:14 +01001031static void meas_rep_dump_uni_vty(struct vty *vty,
1032 struct gsm_meas_rep_unidir *mru,
1033 const char *prefix,
1034 const char *dir)
1035{
1036 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1037 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1038 dir, rxlev2dbm(mru->sub.rx_lev));
1039 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1040 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1041 VTY_NEWLINE);
1042}
1043
1044static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1045 const char *prefix)
1046{
1047 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1048 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1049 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1050 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1051 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1052 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1053 VTY_NEWLINE);
1054 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001055 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001056 if (mr->flags & MEAS_REP_F_MS_L1)
1057 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1058 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1059 if (mr->flags & MEAS_REP_F_DL_VALID)
1060 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1061 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1062}
1063
Harald Welte0a8cf322015-12-05 17:22:49 +01001064/* FIXME: move this to libosmogsm */
1065static const struct value_string gsm48_cmode_names[] = {
1066 { GSM48_CMODE_SIGN, "signalling" },
1067 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1068 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1069 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1070 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1071 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1072 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1073 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1074 { 0, NULL }
1075};
1076
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001077/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1078 * Don't do anything if the ts is not dynamic. */
1079static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1080{
1081 switch (ts->pchan) {
1082 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1083 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1084 vty_out(vty, " as %s",
1085 gsm_pchan_name(ts->dyn.pchan_is));
1086 else
1087 vty_out(vty, " switching %s -> %s",
1088 gsm_pchan_name(ts->dyn.pchan_is),
1089 gsm_pchan_name(ts->dyn.pchan_want));
1090 break;
1091 case GSM_PCHAN_TCH_F_PDCH:
1092 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1093 vty_out(vty, " as %s",
1094 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1095 : "TCH/F");
1096 else
1097 vty_out(vty, " switching %s -> %s",
1098 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1099 : "TCH/F",
1100 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1101 : "TCH/F");
1102 break;
1103 default:
1104 /* no dyn ts */
1105 break;
1106 }
1107}
1108
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001109static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001110{
Harald Welte8387a492009-12-22 21:43:14 +01001111 int idx;
1112
Harald Welte85bded82010-12-24 12:22:34 +01001113 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1114 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1115 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001116 /* show dyn TS details, if applicable */
1117 switch (lchan->ts->pchan) {
1118 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1119 vty_out(vty, " Osmocom Dyn TS:");
1120 vty_out_dyn_ts_status(vty, lchan->ts);
1121 vty_out(vty, VTY_NEWLINE);
1122 break;
1123 case GSM_PCHAN_TCH_F_PDCH:
1124 vty_out(vty, " IPACC Dyn PDCH TS:");
1125 vty_out_dyn_ts_status(vty, lchan->ts);
1126 vty_out(vty, VTY_NEWLINE);
1127 break;
1128 default:
1129 /* no dyn ts */
1130 break;
1131 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001132 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001133 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001134 gsm_lchans_name(lchan->state),
1135 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1136 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1137 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001138 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1139 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1140 - lchan->bs_power*2,
1141 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1142 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001143 vty_out(vty, " Channel Mode / Codec: %s%s",
1144 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1145 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001146 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001147 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001148 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001149 } else
1150 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301151 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1152 struct in_addr ia;
Holger Hans Peter Freyther54fa7992010-04-07 15:39:16 +02001153 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
Harald Welte2c828992009-12-02 01:56:49 +05301154 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1155 inet_ntoa(ia), lchan->abis_ip.bound_port,
1156 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1157 VTY_NEWLINE);
1158 }
Harald Welte8387a492009-12-22 21:43:14 +01001159
1160 /* we want to report the last measurement report */
1161 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1162 lchan->meas_rep_idx, 1);
1163 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001164}
1165
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001166static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1167{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001168 struct gsm_meas_rep *mr;
1169 int idx;
1170
1171 /* we want to report the last measurement report */
1172 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1173 lchan->meas_rep_idx, 1);
1174 mr = &lchan->meas_rep[idx];
1175
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001176 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001177 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001178 gsm_pchan_name(lchan->ts->pchan));
1179 vty_out_dyn_ts_status(vty, lchan->ts);
1180 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1181 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001182 lchan->nr,
1183 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1184 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001185 rxlev2dbm(mr->dl.full.rx_lev),
1186 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001187 VTY_NEWLINE);
1188}
1189
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001190
1191static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1192 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1193{
1194 int lchan_nr;
1195 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1196 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1197 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1198 continue;
1199 dump_cb(vty, lchan);
1200 }
1201
1202 return CMD_SUCCESS;
1203}
1204
1205static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1206 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1207{
1208 int ts_nr;
1209
1210 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1211 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1212 dump_lchan_trx_ts(ts, vty, dump_cb);
1213 }
1214
1215 return CMD_SUCCESS;
1216}
1217
1218static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1219 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1220{
1221 int trx_nr;
1222
1223 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1224 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1225 dump_lchan_trx(trx, vty, dump_cb);
1226 }
1227
1228 return CMD_SUCCESS;
1229}
1230
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001231static int lchan_summary(struct vty *vty, int argc, const char **argv,
1232 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001233{
Harald Weltedcccb182010-05-16 20:52:23 +02001234 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001235 struct gsm_bts *bts;
1236 struct gsm_bts_trx *trx;
1237 struct gsm_bts_trx_ts *ts;
1238 struct gsm_lchan *lchan;
1239 int bts_nr, trx_nr, ts_nr, lchan_nr;
1240
1241 if (argc >= 1) {
1242 /* use the BTS number that the user has specified */
1243 bts_nr = atoi(argv[0]);
1244 if (bts_nr >= net->num_bts) {
1245 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1246 VTY_NEWLINE);
1247 return CMD_WARNING;
1248 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001249 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001250
1251 if (argc == 1)
1252 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001253 }
1254 if (argc >= 2) {
1255 trx_nr = atoi(argv[1]);
1256 if (trx_nr >= bts->num_trx) {
1257 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1258 VTY_NEWLINE);
1259 return CMD_WARNING;
1260 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001261 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001262
1263 if (argc == 2)
1264 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001265 }
1266 if (argc >= 3) {
1267 ts_nr = atoi(argv[2]);
1268 if (ts_nr >= TRX_NR_TS) {
1269 vty_out(vty, "%% can't find TS %s%s", argv[2],
1270 VTY_NEWLINE);
1271 return CMD_WARNING;
1272 }
1273 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001274
1275 if (argc == 3)
1276 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001277 }
1278 if (argc >= 4) {
1279 lchan_nr = atoi(argv[3]);
1280 if (lchan_nr >= TS_MAX_LCHAN) {
1281 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1282 VTY_NEWLINE);
1283 return CMD_WARNING;
1284 }
1285 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001286 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001287 return CMD_SUCCESS;
1288 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001289
1290
Harald Welte68628e82009-03-10 12:17:57 +00001291 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001292 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001293 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001294 }
1295
1296 return CMD_SUCCESS;
1297}
1298
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001299
1300DEFUN(show_lchan,
1301 show_lchan_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001302 "show lchan [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001303 SHOW_STR "Display information about a logical channel\n"
1304 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001305 LCHAN_NR_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001306
1307{
1308 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1309}
1310
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001311DEFUN(show_lchan_summary,
1312 show_lchan_summary_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001313 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [lchan_nr]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001314 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001315 "Short summary\n"
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001316 "BTS Number\n" "TRX Number\n" "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001317 LCHAN_NR_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001318{
1319 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1320}
1321
Philipp Maier39f62bb2017-04-09 12:32:51 +02001322DEFUN(show_subscr_conn,
1323 show_subscr_conn_cmd,
1324 "show conns",
1325 SHOW_STR "Display currently active subscriber connections\n")
1326{
1327 struct gsm_subscriber_connection *conn;
1328 struct gsm_network *net = gsmnet_from_vty(vty);
1329 bool no_conns = true;
1330 unsigned int count = 0;
1331
1332 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1333
1334 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1335 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1336 lchan_dump_full_vty(vty, conn->lchan);
1337 no_conns = false;
1338 count++;
1339 }
1340
1341 if (no_conns)
1342 vty_out(vty, "None%s", VTY_NEWLINE);
1343
1344 return CMD_SUCCESS;
1345}
1346
1347DEFUN(handover_subscr_conn,
1348 handover_subscr_conn_cmd,
1349 "handover <0-255> <0-255> <0-7> LCHAN_NR <0-255>",
1350 "Handover subscriber connection to other BTS\n"
1351 "BTS Number (current)\n" "TRX Number\n" "Timeslot Number\n"
1352 LCHAN_NR_STR "BTS Number (new)\n")
1353{
1354 struct gsm_network *net = gsmnet_from_vty(vty);
1355 struct gsm_subscriber_connection *conn;
1356 struct gsm_bts *bts;
1357 struct gsm_bts *new_bts = NULL;
1358 unsigned int bts_nr = atoi(argv[0]);
1359 unsigned int trx_nr = atoi(argv[1]);
1360 unsigned int ts_nr = atoi(argv[2]);
1361 unsigned int ss_nr = atoi(argv[3]);
1362 unsigned int bts_nr_new = atoi(argv[4]);
1363
1364 /* Lookup the BTS where we want to handover to */
1365 llist_for_each_entry(bts, &net->bts_list, list) {
1366 if (bts->nr == bts_nr_new) {
1367 new_bts = bts;
1368 break;
1369 }
1370 }
1371
1372 if (!new_bts) {
1373 vty_out(vty, "Unable to trigger handover,"
1374 "specified bts #%u does not exist %s", bts_nr_new,
1375 VTY_NEWLINE);
1376 return CMD_WARNING;
1377 }
1378
1379 /* Find the connection/lchan that we want to handover */
1380 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1381 if (conn->bts->nr == bts_nr &&
1382 conn->lchan->ts->trx->nr == trx_nr &&
1383 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
1384 vty_out(vty, "starting handover for lchan %s...%s",
1385 conn->lchan->name, VTY_NEWLINE);
1386 lchan_dump_full_vty(vty, conn->lchan);
1387 bsc_handover_start(conn->lchan, new_bts);
1388 return CMD_SUCCESS;
1389 }
1390 }
1391
1392 vty_out(vty, "Unable to trigger handover,"
1393 "specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1394 bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
1395
1396 return CMD_WARNING;
1397}
1398
Harald Weltebe4b7302009-05-23 16:59:33 +00001399static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001400{
1401 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001402 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001403}
1404
Harald Weltebe4b7302009-05-23 16:59:33 +00001405static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001406{
1407 struct gsm_paging_request *pag;
1408
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001409 if (!bts->paging.bts)
1410 return;
1411
Harald Weltef5025b62009-03-28 16:55:11 +00001412 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1413 paging_dump_vty(vty, pag);
1414}
1415
1416DEFUN(show_paging,
1417 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001418 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001419 SHOW_STR "Display information about paging reuqests of a BTS\n"
1420 "BTS Number\n")
Harald Weltef5025b62009-03-28 16:55:11 +00001421{
Harald Weltedcccb182010-05-16 20:52:23 +02001422 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001423 struct gsm_bts *bts;
1424 int bts_nr;
1425
1426 if (argc >= 1) {
1427 /* use the BTS number that the user has specified */
1428 bts_nr = atoi(argv[0]);
1429 if (bts_nr >= net->num_bts) {
1430 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1431 VTY_NEWLINE);
1432 return CMD_WARNING;
1433 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001434 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001435 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001436
Harald Weltef5025b62009-03-28 16:55:11 +00001437 return CMD_SUCCESS;
1438 }
1439 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001440 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001441 bts_paging_dump_vty(vty, bts);
1442 }
1443
1444 return CMD_SUCCESS;
1445}
1446
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001447DEFUN(show_paging_group,
1448 show_paging_group_cmd,
1449 "show paging-group <0-255> IMSI",
1450 SHOW_STR "Display the paging group\n"
1451 "BTS Number\n" "IMSI\n")
1452{
1453 struct gsm_network *net = gsmnet_from_vty(vty);
1454 struct gsm_bts *bts;
1455 unsigned int page_group;
1456 int bts_nr = atoi(argv[0]);
1457
1458 if (bts_nr >= net->num_bts) {
1459 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1460 return CMD_WARNING;
1461 }
1462
1463 bts = gsm_bts_num(net, bts_nr);
1464 if (!bts) {
1465 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1466 return CMD_WARNING;
1467 }
1468
1469 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1470 str_to_imsi(argv[1]));
1471 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1472 str_to_imsi(argv[1]), bts->nr,
1473 page_group, VTY_NEWLINE);
1474 return CMD_SUCCESS;
1475}
1476
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001477DEFUN(cfg_net_neci,
1478 cfg_net_neci_cmd,
1479 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001480 "New Establish Cause Indication\n"
1481 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001482{
Harald Weltedcccb182010-05-16 20:52:23 +02001483 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1484
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001485 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001486 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001487 return CMD_SUCCESS;
1488}
1489
Harald Welte8f0ed552010-05-11 21:53:49 +02001490#define HANDOVER_STR "Handover Options\n"
1491
Harald Weltebc814502009-12-19 21:41:52 +01001492DEFUN(cfg_net_handover, cfg_net_handover_cmd,
1493 "handover (0|1)",
Harald Welte8f0ed552010-05-11 21:53:49 +02001494 HANDOVER_STR
1495 "Don't perform in-call handover\n"
1496 "Perform in-call handover\n")
Harald Weltebc814502009-12-19 21:41:52 +01001497{
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001498 int enable = atoi(argv[0]);
Harald Weltedcccb182010-05-16 20:52:23 +02001499 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001500
1501 if (enable && ipacc_rtp_direct) {
Harald Weltefe03f0d2009-12-20 13:51:01 +01001502 vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
1503 "is enabled by using the -P command line option%s",
1504 VTY_NEWLINE);
1505 return CMD_WARNING;
1506 }
Holger Hans Peter Freythercbcfe242010-01-07 16:14:38 +01001507 gsmnet->handover.active = enable;
Harald Weltebc814502009-12-19 21:41:52 +01001508
1509 return CMD_SUCCESS;
1510}
1511
Harald Welte8f0ed552010-05-11 21:53:49 +02001512#define HO_WIN_STR HANDOVER_STR "Measurement Window\n"
1513#define HO_WIN_RXLEV_STR HO_WIN_STR "Received Level Averaging\n"
1514#define HO_WIN_RXQUAL_STR HO_WIN_STR "Received Quality Averaging\n"
1515#define HO_PBUDGET_STR HANDOVER_STR "Power Budget\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001516#define HO_AVG_COUNT_STR "Amount to use for Averaging\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001517
Harald Welteb720bd32009-12-21 16:51:50 +01001518DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
1519 "handover window rxlev averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001520 HO_WIN_RXLEV_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001521 "How many RxLev measurements are used for averaging\n"
1522 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001523{
Harald Weltedcccb182010-05-16 20:52:23 +02001524 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001525 gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
1526 return CMD_SUCCESS;
1527}
1528
1529DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
1530 "handover window rxqual averaging <1-10>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001531 HO_WIN_RXQUAL_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001532 "How many RxQual measurements are used for averaging\n"
1533 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001534{
Harald Weltedcccb182010-05-16 20:52:23 +02001535 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001536 gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
1537 return CMD_SUCCESS;
1538}
1539
1540DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
1541 "handover window rxlev neighbor averaging <1-10>",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001542 HO_WIN_RXLEV_STR "Neighbor\n"
1543 "How many RxQual measurements are used for averaging\n"
1544 HO_AVG_COUNT_STR)
Harald Welteb720bd32009-12-21 16:51:50 +01001545{
Harald Weltedcccb182010-05-16 20:52:23 +02001546 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001547 gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
1548 return CMD_SUCCESS;
1549}
1550
1551DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
1552 "handover power budget interval <1-99>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001553 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001554 "How often to check if we have a better cell (SACCH frames)\n"
1555 "Interval\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001556{
Harald Weltedcccb182010-05-16 20:52:23 +02001557 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001558 gsmnet->handover.pwr_interval = atoi(argv[0]);
1559 return CMD_SUCCESS;
1560}
1561
1562DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
1563 "handover power budget hysteresis <0-999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001564 HO_PBUDGET_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001565 "How many dB does a neighbor to be stronger to become a HO candidate\n"
1566 "Hysteresis\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001567{
Harald Weltedcccb182010-05-16 20:52:23 +02001568 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001569 gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
1570 return CMD_SUCCESS;
1571}
1572
1573DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
1574 "handover maximum distance <0-9999>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001575 HANDOVER_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001576 "How big is the maximum timing advance before HO is forced\n"
1577 "Distance\n" "Number\n")
Harald Welteb720bd32009-12-21 16:51:50 +01001578{
Harald Weltedcccb182010-05-16 20:52:23 +02001579 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welteb720bd32009-12-21 16:51:50 +01001580 gsmnet->handover.max_distance = atoi(argv[0]);
1581 return CMD_SUCCESS;
1582}
Harald Weltebc814502009-12-19 21:41:52 +01001583
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001584DEFUN(cfg_net_pag_any_tch,
1585 cfg_net_pag_any_tch_cmd,
1586 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001587 "Assign a TCH when receiving a Paging Any request\n"
1588 "Any Channel\n" "Use\n" "TCH\n"
1589 "Do not use TCH for Paging Request Any\n"
1590 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001591{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001592 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001593 gsmnet->pag_any_tch = atoi(argv[0]);
1594 gsm_net_update_ctype(gsmnet);
1595 return CMD_SUCCESS;
1596}
1597
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001598#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1599/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1600#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1601
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001602#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001603 DEFUN(cfg_net_T##number, \
1604 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001605 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001606 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001607 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001608 "Set to default timer value" \
1609 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1610 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001611{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001612 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001613 int value; \
1614 if (strcmp(argv[0], "default") == 0) \
1615 value = DEFAULT_TIMER(number); \
1616 else \
1617 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001618 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001619 gsmnet->T##number = value; \
1620 return CMD_SUCCESS; \
1621}
1622
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001623DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1624DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1625DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1626DECLARE_TIMER(3107, "Currently not used")
1627DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1628DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1629DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1630DECLARE_TIMER(3115, "Currently not used")
1631DECLARE_TIMER(3117, "Currently not used")
1632DECLARE_TIMER(3119, "Currently not used")
1633DECLARE_TIMER(3122, "Waiting time (seconds) after IMM ASS REJECT")
1634DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001635
Maxc08ee712016-05-11 12:45:13 +02001636DEFUN_DEPRECATED(cfg_net_dtx,
1637 cfg_net_dtx_cmd,
1638 "dtx-used (0|1)",
1639 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001640{
Maxc08ee712016-05-11 12:45:13 +02001641 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1642 "configuration options of BTS instead%s", VTY_NEWLINE);
1643 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001644}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001645
Harald Welte5258fc42009-03-28 19:07:53 +00001646/* per-BTS configuration */
1647DEFUN(cfg_bts,
1648 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001649 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001650 "Select a BTS to configure\n"
1651 "BTS Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001652{
Harald Weltedcccb182010-05-16 20:52:23 +02001653 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001654 int bts_nr = atoi(argv[0]);
1655 struct gsm_bts *bts;
1656
Harald Weltee441d9c2009-06-21 16:17:15 +02001657 if (bts_nr > gsmnet->num_bts) {
1658 vty_out(vty, "%% The next unused BTS number is %u%s",
1659 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001660 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001661 } else if (bts_nr == gsmnet->num_bts) {
1662 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001663 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001664 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001665 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001666 bts = gsm_bts_num(gsmnet, bts_nr);
1667
Daniel Willmannf15c2762010-01-11 13:43:07 +01001668 if (!bts) {
1669 vty_out(vty, "%% Unable to allocate BTS %u%s",
1670 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001671 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001672 }
Harald Welte5258fc42009-03-28 19:07:53 +00001673
1674 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001675 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001676 vty->node = BTS_NODE;
1677
1678 return CMD_SUCCESS;
1679}
1680
1681DEFUN(cfg_bts_type,
1682 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001683 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001684 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001685{
1686 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001687 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001688
Max7507aef2017-04-10 13:59:14 +02001689 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001690 if (rc < 0)
1691 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001692
Harald Welte5258fc42009-03-28 19:07:53 +00001693 return CMD_SUCCESS;
1694}
1695
Harald Weltefcd24452009-06-20 18:15:19 +02001696DEFUN(cfg_bts_band,
1697 cfg_bts_band_cmd,
1698 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001699 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001700{
1701 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001702 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001703
1704 if (band < 0) {
1705 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1706 band, VTY_NEWLINE);
1707 return CMD_WARNING;
1708 }
1709
1710 bts->band = band;
1711
1712 return CMD_SUCCESS;
1713}
1714
Maxc08ee712016-05-11 12:45:13 +02001715DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1716 "Configure discontinuous transmission\n"
1717 "Enable Uplink DTX for this BTS\n"
1718 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1719 "older phones).\n")
1720{
1721 struct gsm_bts *bts = vty->index;
1722
1723 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001724 if (!is_ipaccess_bts(bts))
1725 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1726 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001727 return CMD_SUCCESS;
1728}
1729
1730DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1731 NO_STR
1732 "Configure discontinuous transmission\n"
1733 "Disable Uplink DTX for this BTS\n")
1734{
1735 struct gsm_bts *bts = vty->index;
1736
1737 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1738
1739 return CMD_SUCCESS;
1740}
1741
1742DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1743 "Configure discontinuous transmission\n"
1744 "Enable Downlink DTX for this BTS\n")
1745{
1746 struct gsm_bts *bts = vty->index;
1747
1748 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001749 if (!is_ipaccess_bts(bts))
1750 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1751 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001752 return CMD_SUCCESS;
1753}
1754
1755DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1756 NO_STR
1757 "Configure discontinuous transmission\n"
1758 "Disable Downlink DTX for this BTS\n")
1759{
1760 struct gsm_bts *bts = vty->index;
1761
1762 bts->dtxd = false;
1763
1764 return CMD_SUCCESS;
1765}
1766
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001767DEFUN(cfg_bts_ci,
1768 cfg_bts_ci_cmd,
1769 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001770 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001771{
1772 struct gsm_bts *bts = vty->index;
1773 int ci = atoi(argv[0]);
1774
1775 if (ci < 0 || ci > 0xffff) {
1776 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1777 ci, VTY_NEWLINE);
1778 return CMD_WARNING;
1779 }
1780 bts->cell_identity = ci;
1781
1782 return CMD_SUCCESS;
1783}
1784
Harald Welte5258fc42009-03-28 19:07:53 +00001785DEFUN(cfg_bts_lac,
1786 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001787 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001788 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001789{
1790 struct gsm_bts *bts = vty->index;
1791 int lac = atoi(argv[0]);
1792
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001793 if (lac < 0 || lac > 0xffff) {
1794 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001795 lac, VTY_NEWLINE);
1796 return CMD_WARNING;
1797 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001798
1799 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1800 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1801 lac, VTY_NEWLINE);
1802 return CMD_WARNING;
1803 }
1804
Harald Welte5258fc42009-03-28 19:07:53 +00001805 bts->location_area_code = lac;
1806
1807 return CMD_SUCCESS;
1808}
1809
Harald Weltea43f7892009-12-01 18:04:30 +05301810
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001811/* compatibility wrapper for old config files */
1812DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001813 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001814 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001815 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001816{
Harald Welte5258fc42009-03-28 19:07:53 +00001817 return CMD_SUCCESS;
1818}
1819
Harald Welte78f2f502009-05-23 16:56:52 +00001820DEFUN(cfg_bts_bsic,
1821 cfg_bts_bsic_cmd,
1822 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001823 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1824 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001825{
1826 struct gsm_bts *bts = vty->index;
1827 int bsic = atoi(argv[0]);
1828
1829 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001830 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001831 bsic, VTY_NEWLINE);
1832 return CMD_WARNING;
1833 }
1834 bts->bsic = bsic;
1835
1836 return CMD_SUCCESS;
1837}
1838
Harald Welte4cc34222009-05-01 15:12:31 +00001839DEFUN(cfg_bts_unit_id,
1840 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001841 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001842 "Abis/IP specific options\n"
1843 "Set the IPA BTS Unit ID\n"
1844 "Unit ID (Site)\n"
1845 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001846{
1847 struct gsm_bts *bts = vty->index;
1848 int site_id = atoi(argv[0]);
1849 int bts_id = atoi(argv[1]);
1850
Harald Welte07dc73d2009-08-07 13:27:09 +02001851 if (!is_ipaccess_bts(bts)) {
1852 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1853 return CMD_WARNING;
1854 }
1855
Harald Welte4cc34222009-05-01 15:12:31 +00001856 bts->ip_access.site_id = site_id;
1857 bts->ip_access.bts_id = bts_id;
1858
1859 return CMD_SUCCESS;
1860}
1861
Harald Welte8b291802013-03-12 13:57:05 +01001862DEFUN(cfg_bts_rsl_ip,
1863 cfg_bts_rsl_ip_cmd,
1864 "ip.access rsl-ip A.B.C.D",
1865 "Abis/IP specific options\n"
1866 "Set the IPA RSL IP Address of the BSC\n"
1867 "Destination IP address for RSL connection\n")
1868{
1869 struct gsm_bts *bts = vty->index;
1870 struct in_addr ia;
1871
1872 if (!is_ipaccess_bts(bts)) {
1873 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1874 return CMD_WARNING;
1875 }
1876
1877 inet_aton(argv[0], &ia);
1878 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1879
1880 return CMD_SUCCESS;
1881}
1882
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001883#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001884
Sylvain Munautc9519462011-10-17 14:04:55 +02001885DEFUN(cfg_bts_nokia_site_skip_reset,
1886 cfg_bts_nokia_site_skip_reset_cmd,
1887 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001888 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001889 "Skip the reset step during bootstrap process of this BTS\n"
1890 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02001891{
1892 struct gsm_bts *bts = vty->index;
1893
1894 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
1895 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
1896 return CMD_WARNING;
1897 }
1898
1899 bts->nokia.skip_reset = atoi(argv[0]);
1900
1901 return CMD_SUCCESS;
1902}
1903
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001904DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
1905 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
1906 "nokia_site no-local-rel-conf (0|1)",
1907 NOKIA_STR
1908 "Do not wait for RELease CONFirm message when releasing channel locally\n"
1909 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
1910{
1911 struct gsm_bts *bts = vty->index;
1912
1913 if (!is_nokia_bts(bts)) {
1914 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1915 VTY_NEWLINE);
1916 return CMD_WARNING;
1917 }
1918
1919 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
1920
1921 return CMD_SUCCESS;
1922}
1923
Sipos Csaba56e17662015-02-07 13:27:36 +01001924DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
1925 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
1926 "nokia_site bts-reset-timer <15-100>",
1927 NOKIA_STR
1928 "The amount of time (in sec.) between BTS_RESET is sent,\n"
1929 "and the BTS is being bootstrapped.\n")
1930{
1931 struct gsm_bts *bts = vty->index;
1932
1933 if (!is_nokia_bts(bts)) {
1934 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
1935 VTY_NEWLINE);
1936 return CMD_WARNING;
1937 }
1938
1939 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
1940
1941 return CMD_SUCCESS;
1942}
Harald Welte8f0ed552010-05-11 21:53:49 +02001943#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001944#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02001945
Harald Welte8175e952009-10-20 00:22:00 +02001946DEFUN(cfg_bts_stream_id,
1947 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001948 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02001949 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001950 "Set the ip.access Stream ID of the OML link of this BTS\n"
1951 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02001952{
1953 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001954 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02001955
1956 if (!is_ipaccess_bts(bts)) {
1957 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1958 return CMD_WARNING;
1959 }
1960
1961 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02001962 /* This is used by e1inp_bind_ops callback for each BTS model. */
1963 bts->oml_e1_link.e1_nr = linenr;
1964
1965 return CMD_SUCCESS;
1966}
1967
Harald Welted13e0cd2012-08-17 09:52:03 +02001968#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02001969
Harald Welte42581822009-08-08 16:12:58 +02001970DEFUN(cfg_bts_oml_e1,
1971 cfg_bts_oml_e1_cmd,
1972 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02001973 OML_E1_STR
1974 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02001975 "E1/T1 line number to be used for OML\n"
1976 "E1/T1 timeslot to be used for OML\n"
1977 "E1/T1 timeslot to be used for OML\n"
1978 "E1/T1 sub-slot to be used for OML\n"
1979 "Use E1/T1 sub-slot 0\n"
1980 "Use E1/T1 sub-slot 1\n"
1981 "Use E1/T1 sub-slot 2\n"
1982 "Use E1/T1 sub-slot 3\n"
1983 "Use full E1 slot 3\n"
1984 )
Harald Welte42581822009-08-08 16:12:58 +02001985{
1986 struct gsm_bts *bts = vty->index;
1987
1988 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
1989
1990 return CMD_SUCCESS;
1991}
1992
1993
1994DEFUN(cfg_bts_oml_e1_tei,
1995 cfg_bts_oml_e1_tei_cmd,
1996 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001997 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001998 "Set the TEI to be used for OML\n"
1999 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002000{
2001 struct gsm_bts *bts = vty->index;
2002
2003 bts->oml_tei = atoi(argv[0]);
2004
2005 return CMD_SUCCESS;
2006}
2007
Harald Welte7a8fa412009-08-10 13:48:16 +02002008DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2009 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002010 "Channnel Allocator\n" "Channel Allocator\n"
2011 "Allocate Timeslots and Transceivers in ascending order\n"
2012 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002013{
2014 struct gsm_bts *bts = vty->index;
2015
2016 if (!strcmp(argv[0], "ascending"))
2017 bts->chan_alloc_reverse = 0;
2018 else
2019 bts->chan_alloc_reverse = 1;
2020
2021 return CMD_SUCCESS;
2022}
2023
Harald Welte8f0ed552010-05-11 21:53:49 +02002024#define RACH_STR "Random Access Control Channel\n"
2025
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002026DEFUN(cfg_bts_rach_tx_integer,
2027 cfg_bts_rach_tx_integer_cmd,
2028 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002029 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002030 "Set the raw tx integer value in RACH Control parameters IE\n"
2031 "Set the raw tx integer value in RACH Control parameters IE\n"
2032 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002033{
2034 struct gsm_bts *bts = vty->index;
2035 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2036 return CMD_SUCCESS;
2037}
2038
2039DEFUN(cfg_bts_rach_max_trans,
2040 cfg_bts_rach_max_trans_cmd,
2041 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002042 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002043 "Set the maximum number of RACH burst transmissions\n"
2044 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002045 "Maximum number of 1 RACH burst transmissions\n"
2046 "Maximum number of 2 RACH burst transmissions\n"
2047 "Maximum number of 4 RACH burst transmissions\n"
2048 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002049{
2050 struct gsm_bts *bts = vty->index;
2051 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2052 return CMD_SUCCESS;
2053}
2054
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002055#define CD_STR "Channel Description\n"
2056
2057DEFUN(cfg_bts_chan_desc_att,
2058 cfg_bts_chan_desc_att_cmd,
2059 "channel-descrption attach (0|1)",
2060 CD_STR
2061 "Set if attachment is required\n"
2062 "Attachment is NOT required\n"
2063 "Attachment is required (standard)\n")
2064{
2065 struct gsm_bts *bts = vty->index;
2066 bts->si_common.chan_desc.att = atoi(argv[0]);
2067 return CMD_SUCCESS;
2068}
2069
2070DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2071 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2072 "channel-descrption bs-pa-mfrms <2-9>",
2073 CD_STR
2074 "Set number of multiframe periods for paging groups\n"
2075 "Number of multiframe periods for paging groups\n")
2076{
2077 struct gsm_bts *bts = vty->index;
2078 int bs_pa_mfrms = atoi(argv[0]);
2079
2080 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2081 return CMD_SUCCESS;
2082}
2083
2084DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2085 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2086 "channel-descrption bs-ag-blks-res <0-7>",
2087 CD_STR
2088 "Set number of blocks reserved for access grant\n"
2089 "Number of blocks reserved for access grant\n")
2090{
2091 struct gsm_bts *bts = vty->index;
2092 int bs_ag_blks_res = atoi(argv[0]);
2093
2094 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2095 return CMD_SUCCESS;
2096}
2097
Harald Welte8f0ed552010-05-11 21:53:49 +02002098#define NM_STR "Network Management\n"
2099
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002100DEFUN(cfg_bts_rach_nm_b_thresh,
2101 cfg_bts_rach_nm_b_thresh_cmd,
2102 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002103 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002104 "Set the NM Busy Threshold\n"
2105 "Set the NM Busy Threshold\n"
2106 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002107{
2108 struct gsm_bts *bts = vty->index;
2109 bts->rach_b_thresh = atoi(argv[0]);
2110 return CMD_SUCCESS;
2111}
2112
2113DEFUN(cfg_bts_rach_nm_ldavg,
2114 cfg_bts_rach_nm_ldavg_cmd,
2115 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002116 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002117 "Set the NM Loadaverage Slots value\n"
2118 "Set the NM Loadaverage Slots value\n"
2119 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002120{
2121 struct gsm_bts *bts = vty->index;
2122 bts->rach_ldavg_slots = atoi(argv[0]);
2123 return CMD_SUCCESS;
2124}
2125
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002126DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2127 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002128 "Should this cell be barred from access?\n"
2129 "Should this cell be barred from access?\n"
2130 "Cell should NOT be barred\n"
2131 "Cell should be barred\n")
2132
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002133{
2134 struct gsm_bts *bts = vty->index;
2135
Harald Welte71355012009-12-21 23:08:18 +01002136 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002137
2138 return CMD_SUCCESS;
2139}
2140
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002141DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2142 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002143 RACH_STR
2144 "Should this cell allow emergency calls?\n"
2145 "Should this cell allow emergency calls?\n"
2146 "Should this cell allow emergency calls?\n"
2147 "Do NOT allow emergency calls\n"
2148 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002149{
2150 struct gsm_bts *bts = vty->index;
2151
2152 if (atoi(argv[0]) == 0)
2153 bts->si_common.rach_control.t2 |= 0x4;
2154 else
2155 bts->si_common.rach_control.t2 &= ~0x4;
2156
2157 return CMD_SUCCESS;
2158}
2159
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002160DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2161 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2162 RACH_STR
2163 "Set access control class\n"
2164 "Access control class 0\n"
2165 "Access control class 1\n"
2166 "Access control class 2\n"
2167 "Access control class 3\n"
2168 "Access control class 4\n"
2169 "Access control class 5\n"
2170 "Access control class 6\n"
2171 "Access control class 7\n"
2172 "Access control class 8\n"
2173 "Access control class 9\n"
2174 "Access control class 11 for PLMN use\n"
2175 "Access control class 12 for security services\n"
2176 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2177 "Access control class 14 for emergency services\n"
2178 "Access control class 15 for PLMN staff\n"
2179 "barred to use access control class\n"
2180 "allowed to use access control class\n")
2181{
2182 struct gsm_bts *bts = vty->index;
2183
2184 uint8_t control_class;
2185 uint8_t allowed = 0;
2186
2187 if (strcmp(argv[1], "allowed") == 0)
2188 allowed = 1;
2189
2190 control_class = atoi(argv[0]);
2191 if (control_class < 8)
2192 if (allowed)
2193 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2194 else
2195 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2196 else
2197 if (allowed)
2198 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2199 else
2200 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2201
2202 return CMD_SUCCESS;
2203}
2204
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002205DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2206 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002207 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002208 "Maximum transmit power of the MS\n"
2209 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002210 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002211{
2212 struct gsm_bts *bts = vty->index;
2213
2214 bts->ms_max_power = atoi(argv[0]);
2215
2216 return CMD_SUCCESS;
2217}
2218
Harald Weltecfaabbb2012-08-16 23:23:50 +02002219#define CELL_STR "Cell Parameters\n"
2220
Harald Welte73225282009-12-12 18:17:25 +01002221DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2222 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002223 CELL_STR "Cell re-selection parameters\n"
2224 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002225 "Cell Re-Selection Hysteresis in dB")
2226{
2227 struct gsm_bts *bts = vty->index;
2228
2229 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2230
2231 return CMD_SUCCESS;
2232}
2233
2234DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2235 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002236 "Minimum RxLev needed for cell access\n"
2237 "Minimum RxLev needed for cell access\n"
2238 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002239 "Minimum RxLev needed for cell access (better than -110dBm)")
2240{
2241 struct gsm_bts *bts = vty->index;
2242
2243 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2244
2245 return CMD_SUCCESS;
2246}
2247
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002248DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2249 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002250 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2251 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002252{
2253 struct gsm_bts *bts = vty->index;
2254
2255 bts->si_common.cell_ro_sel_par.present = 1;
2256 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2257
2258 return CMD_SUCCESS;
2259}
2260
2261DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2262 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002263 CELL_STR "Cell Re-Selection Parameters\n"
2264 "Cell Re-Selection Offset (CRO) in dB\n"
2265 "Cell Re-Selection Offset (CRO) in dB\n"
2266 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002267{
2268 struct gsm_bts *bts = vty->index;
2269
2270 bts->si_common.cell_ro_sel_par.present = 1;
2271 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2272
2273 return CMD_SUCCESS;
2274}
2275
2276DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2277 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002278 "Cell selection temporary negative offset\n"
2279 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002280 "Cell selection temporary negative offset in dB")
2281{
2282 struct gsm_bts *bts = vty->index;
2283
2284 bts->si_common.cell_ro_sel_par.present = 1;
2285 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2286
2287 return CMD_SUCCESS;
2288}
2289
2290DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2291 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002292 "Cell selection temporary negative offset\n"
2293 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002294 "Sets cell selection temporary negative offset to infinity")
2295{
2296 struct gsm_bts *bts = vty->index;
2297
2298 bts->si_common.cell_ro_sel_par.present = 1;
2299 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2300
2301 return CMD_SUCCESS;
2302}
2303
2304DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2305 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002306 "Cell selection penalty time\n"
2307 "Cell selection penalty time\n"
2308 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002309{
2310 struct gsm_bts *bts = vty->index;
2311
2312 bts->si_common.cell_ro_sel_par.present = 1;
2313 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2314
2315 return CMD_SUCCESS;
2316}
2317
2318DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2319 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002320 "Cell selection penalty time\n"
2321 "Cell selection penalty time\n"
2322 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002323 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2324 "and TEMPORARY_OFFSET is ignored)")
2325{
2326 struct gsm_bts *bts = vty->index;
2327
2328 bts->si_common.cell_ro_sel_par.present = 1;
2329 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2330
2331 return CMD_SUCCESS;
2332}
2333
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002334DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2335 "radio-link-timeout <4-64>",
2336 "Radio link timeout criterion (BTS side)\n"
2337 "Radio link timeout value (lost SACCH block)\n")
2338{
2339 struct gsm_bts *bts = vty->index;
2340
Harald Welte2f8b9d22017-06-18 11:12:13 +03002341 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2342
2343 return CMD_SUCCESS;
2344}
2345
2346DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2347 "radio-link-timeout infinite",
2348 "Radio link timeout criterion (BTS side)\n"
2349 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2350{
2351 struct gsm_bts *bts = vty->index;
2352
2353 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2354 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2355 return CMD_WARNING;
2356 }
2357
2358 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2359 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002360
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002361 return CMD_SUCCESS;
2362}
2363
Harald Welte8f0ed552010-05-11 21:53:49 +02002364#define GPRS_TEXT "GPRS Packet Network\n"
2365
Harald Welteaf387632010-03-14 23:30:30 +08002366DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002367 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002368 GPRS_TEXT
2369 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002370 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002371 "GPRS BSSGP VC Identifier")
2372{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002373 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002374 struct gsm_bts *bts = vty->index;
2375
Harald Welte4511d892010-04-18 15:51:20 +02002376 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002377 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2378 return CMD_WARNING;
2379 }
2380
Harald Welte97a282b2010-03-14 15:37:43 +08002381 bts->gprs.cell.bvci = atoi(argv[0]);
2382
2383 return CMD_SUCCESS;
2384}
2385
Harald Weltea5731cf2010-03-22 11:48:36 +08002386DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2387 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002388 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002389 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002390 "GPRS NS Entity Identifier")
2391{
2392 struct gsm_bts *bts = vty->index;
2393
Harald Welte4511d892010-04-18 15:51:20 +02002394 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002395 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2396 return CMD_WARNING;
2397 }
2398
2399 bts->gprs.nse.nsei = atoi(argv[0]);
2400
2401 return CMD_SUCCESS;
2402}
2403
Harald Welte8f0ed552010-05-11 21:53:49 +02002404#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2405 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002406
Harald Welte97a282b2010-03-14 15:37:43 +08002407DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2408 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002409 GPRS_TEXT NSVC_TEXT
2410 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002411 "GPRS NS VC Identifier")
2412{
2413 struct gsm_bts *bts = vty->index;
2414 int idx = atoi(argv[0]);
2415
Harald Welte4511d892010-04-18 15:51:20 +02002416 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002417 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2418 return CMD_WARNING;
2419 }
2420
Harald Welte97a282b2010-03-14 15:37:43 +08002421 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2422
2423 return CMD_SUCCESS;
2424}
2425
Harald Welteaf387632010-03-14 23:30:30 +08002426DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2427 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002428 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002429 "GPRS NS Local UDP Port\n"
2430 "GPRS NS Local UDP Port\n"
2431 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002432 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002433{
2434 struct gsm_bts *bts = vty->index;
2435 int idx = atoi(argv[0]);
2436
Harald Welte4511d892010-04-18 15:51:20 +02002437 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002438 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2439 return CMD_WARNING;
2440 }
2441
Harald Welteaf387632010-03-14 23:30:30 +08002442 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2443
2444 return CMD_SUCCESS;
2445}
2446
2447DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2448 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002449 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002450 "GPRS NS Remote UDP Port\n"
2451 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002452 "GPRS NS Remote UDP Port\n"
2453 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002454{
2455 struct gsm_bts *bts = vty->index;
2456 int idx = atoi(argv[0]);
2457
Harald Welte4511d892010-04-18 15:51:20 +02002458 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002459 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2460 return CMD_WARNING;
2461 }
2462
Harald Welteaf387632010-03-14 23:30:30 +08002463 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2464
2465 return CMD_SUCCESS;
2466}
2467
2468DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2469 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002470 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002471 "GPRS NS Remote IP Address\n"
2472 "GPRS NS Remote IP Address\n"
2473 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002474{
2475 struct gsm_bts *bts = vty->index;
2476 int idx = atoi(argv[0]);
2477 struct in_addr ia;
2478
Harald Welte4511d892010-04-18 15:51:20 +02002479 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002480 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2481 return CMD_WARNING;
2482 }
2483
Harald Welteaf387632010-03-14 23:30:30 +08002484 inet_aton(argv[1], &ia);
2485 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2486
2487 return CMD_SUCCESS;
2488}
2489
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002490DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002491 "paging free <-1-1024>",
2492 "Paging options\n"
2493 "Only page when having a certain amount of free slots\n"
2494 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002495{
2496 struct gsm_bts *bts = vty->index;
2497
2498 bts->paging.free_chans_need = atoi(argv[0]);
2499 return CMD_SUCCESS;
2500}
2501
Harald Welte615e9562010-05-11 23:50:21 +02002502DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2503 "gprs ns timer " NS_TIMERS " <0-255>",
2504 GPRS_TEXT "Network Service\n"
2505 "Network Service Timer\n"
2506 NS_TIMERS_HELP "Timer Value\n")
2507{
2508 struct gsm_bts *bts = vty->index;
2509 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2510 int val = atoi(argv[1]);
2511
2512 if (bts->gprs.mode == BTS_GPRS_NONE) {
2513 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2514 return CMD_WARNING;
2515 }
2516
2517 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2518 return CMD_WARNING;
2519
2520 bts->gprs.nse.timer[idx] = val;
2521
2522 return CMD_SUCCESS;
2523}
2524
2525#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 +02002526#define BSSGP_TIMERS_HELP \
2527 "Tbvc-block timeout\n" \
2528 "Tbvc-block retries\n" \
2529 "Tbvc-unblock retries\n" \
2530 "Tbvcc-reset timeout\n" \
2531 "Tbvc-reset retries\n" \
2532 "Tbvc-suspend timeout\n" \
2533 "Tbvc-suspend retries\n" \
2534 "Tbvc-resume timeout\n" \
2535 "Tbvc-resume retries\n" \
2536 "Tbvc-capa-update timeout\n" \
2537 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002538
2539DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2540 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2541 GPRS_TEXT "Cell / BSSGP\n"
2542 "Cell/BSSGP Timer\n"
2543 BSSGP_TIMERS_HELP "Timer Value\n")
2544{
2545 struct gsm_bts *bts = vty->index;
2546 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2547 int val = atoi(argv[1]);
2548
2549 if (bts->gprs.mode == BTS_GPRS_NONE) {
2550 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2551 return CMD_WARNING;
2552 }
2553
2554 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2555 return CMD_WARNING;
2556
2557 bts->gprs.cell.timer[idx] = val;
2558
2559 return CMD_SUCCESS;
2560}
2561
Harald Welte97a282b2010-03-14 15:37:43 +08002562DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2563 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002564 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002565 "GPRS Routing Area Code\n"
2566 "GPRS Routing Area Code\n"
2567 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002568{
2569 struct gsm_bts *bts = vty->index;
2570
Harald Welte4511d892010-04-18 15:51:20 +02002571 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002572 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2573 return CMD_WARNING;
2574 }
2575
Harald Welte97a282b2010-03-14 15:37:43 +08002576 bts->gprs.rac = atoi(argv[0]);
2577
2578 return CMD_SUCCESS;
2579}
2580
Max292ec582016-07-28 11:55:37 +02002581DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2582 "gprs control-ack-type-rach", GPRS_TEXT
2583 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2584 "four access bursts format instead of default RLC/MAC control block\n")
2585{
2586 struct gsm_bts *bts = vty->index;
2587
2588 if (bts->gprs.mode == BTS_GPRS_NONE) {
2589 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2590 return CMD_WARNING;
2591 }
2592
2593 bts->gprs.ctrl_ack_type_use_block = false;
2594
2595 return CMD_SUCCESS;
2596}
2597
2598DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2599 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2600 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2601 "four access bursts format instead of default RLC/MAC control block\n")
2602{
2603 struct gsm_bts *bts = vty->index;
2604
2605 if (bts->gprs.mode == BTS_GPRS_NONE) {
2606 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2607 return CMD_WARNING;
2608 }
2609
2610 bts->gprs.ctrl_ack_type_use_block = true;
2611
2612 return CMD_SUCCESS;
2613}
2614
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002615DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2616 "gprs network-control-order (nc0|nc1|nc2)",
2617 GPRS_TEXT
2618 "GPRS Network Control Order\n"
2619 "MS controlled cell re-selection, no measurement reporting\n"
2620 "MS controlled cell re-selection, MS sends measurement reports\n"
2621 "Network controlled cell re-selection, MS sends measurement reports\n")
2622{
2623 struct gsm_bts *bts = vty->index;
2624
2625 if (bts->gprs.mode == BTS_GPRS_NONE) {
2626 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2627 return CMD_WARNING;
2628 }
2629
2630 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2631
2632 return CMD_SUCCESS;
2633}
2634
Harald Welte4511d892010-04-18 15:51:20 +02002635DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2636 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002637 GPRS_TEXT
2638 "GPRS Mode for this BTS\n"
2639 "GPRS Disabled on this BTS\n"
2640 "GPRS Enabled on this BTS\n"
2641 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002642{
2643 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002644 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002645
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002646 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002647 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2648 VTY_NEWLINE);
2649 return CMD_WARNING;
2650 }
2651
2652 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002653
2654 return CMD_SUCCESS;
2655}
2656
bhargava350533c2016-07-21 11:14:34 +05302657DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2658 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2659 "gprs 11bit_rach_support_for_egprs (0|1)",
2660 GPRS_TEXT "11 bit RACH options\n"
2661 "Disable 11 bit RACH for EGPRS\n"
2662 "Enable 11 bit RACH for EGPRS")
2663{
2664 struct gsm_bts *bts = vty->index;
2665
2666 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2667
2668 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2669 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2670 return CMD_WARNING;
2671 }
2672
2673 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2674 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2675 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2676 " enabled%s", VTY_NEWLINE);
2677 return CMD_WARNING;
2678 }
2679
2680 return CMD_SUCCESS;
2681}
2682
Harald Welte9fbff4a2010-07-30 11:50:09 +02002683#define SI_TEXT "System Information Messages\n"
2684#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)"
2685#define SI_TYPE_HELP "System Information Type 1\n" \
2686 "System Information Type 2\n" \
2687 "System Information Type 3\n" \
2688 "System Information Type 4\n" \
2689 "System Information Type 5\n" \
2690 "System Information Type 6\n" \
2691 "System Information Type 7\n" \
2692 "System Information Type 8\n" \
2693 "System Information Type 9\n" \
2694 "System Information Type 10\n" \
2695 "System Information Type 13\n" \
2696 "System Information Type 16\n" \
2697 "System Information Type 17\n" \
2698 "System Information Type 18\n" \
2699 "System Information Type 19\n" \
2700 "System Information Type 20\n" \
2701 "System Information Type 2bis\n" \
2702 "System Information Type 2ter\n" \
2703 "System Information Type 2quater\n" \
2704 "System Information Type 5bis\n" \
2705 "System Information Type 5ter\n"
2706
2707DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2708 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2709 SI_TEXT SI_TYPE_HELP
2710 "System Information Mode\n"
2711 "Static user-specified\n"
2712 "Dynamic, BSC-computed\n")
2713{
2714 struct gsm_bts *bts = vty->index;
2715 int type;
2716
2717 type = get_string_value(osmo_sitype_strs, argv[0]);
2718 if (type < 0) {
2719 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2720 return CMD_WARNING;
2721 }
2722
2723 if (!strcmp(argv[1], "static"))
2724 bts->si_mode_static |= (1 << type);
2725 else
2726 bts->si_mode_static &= ~(1 << type);
2727
2728 return CMD_SUCCESS;
2729}
2730
2731DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2732 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2733 SI_TEXT SI_TYPE_HELP
2734 "Static System Information filling\n"
2735 "Static user-specified SI content in HEX notation\n")
2736{
2737 struct gsm_bts *bts = vty->index;
2738 int rc, type;
2739
2740 type = get_string_value(osmo_sitype_strs, argv[0]);
2741 if (type < 0) {
2742 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2743 return CMD_WARNING;
2744 }
2745
2746 if (!(bts->si_mode_static & (1 << type))) {
2747 vty_out(vty, "SI Type %s is not configured in static mode%s",
2748 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2749 return CMD_WARNING;
2750 }
2751
Harald Welte290aaed2010-07-30 11:53:18 +02002752 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002753 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002754
2755 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002756 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2757 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002758 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2759 return CMD_WARNING;
2760 }
2761
2762 /* Mark this SI as present */
2763 bts->si_valid |= (1 << type);
2764
2765 return CMD_SUCCESS;
2766}
2767
Harald Welte42def722017-01-13 00:10:32 +01002768DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2769 "early-classmark-sending (allowed|forbidden)",
2770 "Early Classmark Sending\n"
2771 "Early Classmark Sending is allowed\n"
2772 "Early Classmark Sending is forbidden\n")
2773{
2774 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002775
2776 if (!strcmp(argv[0], "allowed"))
2777 bts->early_classmark_allowed = true;
2778 else
2779 bts->early_classmark_allowed = false;
2780
2781 return CMD_SUCCESS;
2782}
2783
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002784DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2785 "early-classmark-sending-3g (allowed|forbidden)",
2786 "3G Early Classmark Sending\n"
2787 "3G Early Classmark Sending is allowed\n"
2788 "3G Early Classmark Sending is forbidden\n")
2789{
2790 struct gsm_bts *bts = vty->index;
2791
2792 if (!strcmp(argv[0], "allowed"))
2793 bts->early_classmark_allowed_3g = true;
2794 else
2795 bts->early_classmark_allowed_3g = false;
2796
2797 return CMD_SUCCESS;
2798}
2799
Harald Welte32c09622011-01-11 23:44:56 +01002800DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002801 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002802 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002803 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2804 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002805{
2806 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002807 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002808
Harald Welte64c07d22011-02-15 11:43:27 +01002809 switch (mode) {
2810 case NL_MODE_MANUAL_SI5SEP:
2811 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002812 /* make sure we clear the current list when switching to
2813 * manual mode */
2814 if (bts->neigh_list_manual_mode == 0)
2815 memset(&bts->si_common.data.neigh_list, 0,
2816 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002817 break;
2818 default:
2819 break;
2820 }
2821
2822 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002823
2824 return CMD_SUCCESS;
2825}
2826
2827DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002828 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002829 "Neighbor List\n" "Add to manual neighbor list\n"
2830 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2831 "ARFCN of neighbor\n")
2832{
2833 struct gsm_bts *bts = vty->index;
2834 struct bitvec *bv = &bts->si_common.neigh_list;
2835 uint16_t arfcn = atoi(argv[1]);
2836
2837 if (!bts->neigh_list_manual_mode) {
2838 vty_out(vty, "%% Cannot configure neighbor list in "
2839 "automatic mode%s", VTY_NEWLINE);
2840 return CMD_WARNING;
2841 }
2842
2843 if (!strcmp(argv[0], "add"))
2844 bitvec_set_bit_pos(bv, arfcn, 1);
2845 else
2846 bitvec_set_bit_pos(bv, arfcn, 0);
2847
2848 return CMD_SUCCESS;
2849}
2850
Max70fdd242017-06-15 15:10:53 +02002851/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002852DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002853 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2854 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2855 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2856 "Add to manual SI2quater neighbor list\n"
2857 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2858 "threshold high bits\n" "threshold high bits\n"
2859 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2860 "priority\n" "priority (8 means NA)\n"
2861 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2862 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002863{
2864 struct gsm_bts *bts = vty->index;
2865 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2866 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002867 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2868 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002869 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002870
Max70fdd242017-06-15 15:10:53 +02002871 switch (r) {
2872 case 1:
2873 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2874 thresh_hi, VTY_NEWLINE);
2875 break;
2876 case EARFCN_THRESH_LOW_INVALID:
2877 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2878 thresh_lo, VTY_NEWLINE);
2879 break;
2880 case EARFCN_QRXLV_INVALID + 1:
2881 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2882 qrx, VTY_NEWLINE);
2883 break;
2884 case EARFCN_PRIO_INVALID:
2885 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
2886 prio, VTY_NEWLINE);
2887 break;
2888 default:
2889 if (r < 0) {
2890 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
2891 return CMD_WARNING;
2892 }
Max59a1bf32016-04-15 16:04:46 +02002893 }
2894
Max70fdd242017-06-15 15:10:53 +02002895 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01002896 return CMD_SUCCESS;
2897
Maxf39d03a2017-05-12 17:00:30 +02002898 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02002899 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02002900 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01002901
Maxaafff962016-04-20 15:57:14 +02002902 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02002903}
2904
2905DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02002906 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02002907 "SI2quater Neighbor List\n"
2908 "SI2quater Neighbor List\n"
2909 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02002910 "EARFCN of neighbor\n"
2911 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02002912{
2913 struct gsm_bts *bts = vty->index;
2914 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02002915 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02002916 int r = osmo_earfcn_del(e, arfcn);
2917 if (r < 0) {
2918 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02002919 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02002920 return CMD_WARNING;
2921 }
2922
2923 return CMD_SUCCESS;
2924}
2925
Max26679e02016-04-20 15:57:13 +02002926DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02002927 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02002928 "SI2quater Neighbor List\n"
2929 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
2930 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
2931 "diversity bit\n")
2932{
2933 struct gsm_bts *bts = vty->index;
2934 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
2935
2936 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
2937 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02002938 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 +01002939 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02002940 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02002941 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
2942 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01002943 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02002944 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02002945 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02002946 return CMD_WARNING;
2947 }
2948
2949 return CMD_SUCCESS;
2950}
2951
2952DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02002953 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02002954 "SI2quater Neighbor List\n"
2955 "SI2quater Neighbor List\n"
2956 "Delete from SI2quater manual neighbor list\n"
2957 "UARFCN of neighbor\n"
2958 "UARFCN\n"
2959 "scrambling code\n")
2960{
2961 struct gsm_bts *bts = vty->index;
2962
2963 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
2964 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
2965 VTY_NEWLINE);
2966 return CMD_WARNING;
2967 }
2968
2969 return CMD_SUCCESS;
2970}
2971
Harald Welte64c07d22011-02-15 11:43:27 +01002972DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002973 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002974 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002975 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
2976 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
2977 "ARFCN of neighbor\n")
2978{
2979 struct gsm_bts *bts = vty->index;
2980 struct bitvec *bv = &bts->si_common.si5_neigh_list;
2981 uint16_t arfcn = atoi(argv[1]);
2982
2983 if (!bts->neigh_list_manual_mode) {
2984 vty_out(vty, "%% Cannot configure neighbor list in "
2985 "automatic mode%s", VTY_NEWLINE);
2986 return CMD_WARNING;
2987 }
2988
2989 if (!strcmp(argv[0], "add"))
2990 bitvec_set_bit_pos(bv, arfcn, 1);
2991 else
2992 bitvec_set_bit_pos(bv, arfcn, 0);
2993
2994 return CMD_SUCCESS;
2995}
Harald Welte9fbff4a2010-07-30 11:50:09 +02002996
Harald Welte8254cf72017-05-29 13:42:19 +02002997DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
2998 "pcu-socket PATH",
2999 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3000 "Path in the file system for the unix-domain PCU socket\n")
3001{
3002 struct gsm_bts *bts = vty->index;
3003 int rc;
3004
Harald Welte4a824ca2017-05-29 13:54:27 +02003005 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003006 pcu_sock_exit(bts);
3007 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3008 if (rc < 0) {
3009 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3010 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3011 return CMD_WARNING;
3012 }
3013
3014 return CMD_SUCCESS;
3015}
3016
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003017#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3018
3019DEFUN(cfg_bts_excl_rf_lock,
3020 cfg_bts_excl_rf_lock_cmd,
3021 "rf-lock-exclude",
3022 EXCL_RFLOCK_STR)
3023{
3024 struct gsm_bts *bts = vty->index;
3025 bts->excl_from_rf_lock = 1;
3026 return CMD_SUCCESS;
3027}
3028
3029DEFUN(cfg_bts_no_excl_rf_lock,
3030 cfg_bts_no_excl_rf_lock_cmd,
3031 "no rf-lock-exclude",
3032 NO_STR EXCL_RFLOCK_STR)
3033{
3034 struct gsm_bts *bts = vty->index;
3035 bts->excl_from_rf_lock = 0;
3036 return CMD_SUCCESS;
3037}
3038
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003039#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3040
3041DEFUN(cfg_bts_force_comb_si,
3042 cfg_bts_force_comb_si_cmd,
3043 "force-combined-si",
3044 FORCE_COMB_SI_STR)
3045{
3046 struct gsm_bts *bts = vty->index;
3047 bts->force_combined_si = 1;
3048 return CMD_SUCCESS;
3049}
3050
3051DEFUN(cfg_bts_no_force_comb_si,
3052 cfg_bts_no_force_comb_si_cmd,
3053 "no force-combined-si",
3054 NO_STR FORCE_COMB_SI_STR)
3055{
3056 struct gsm_bts *bts = vty->index;
3057 bts->force_combined_si = 0;
3058 return CMD_SUCCESS;
3059}
3060
Andreas Eversberga83d5112013-12-07 18:32:28 +01003061static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3062{
3063 struct gsm_bts *bts = vty->index;
3064 struct bts_codec_conf *codec = &bts->codec;
3065 int i;
3066
3067 codec->hr = 0;
3068 codec->efr = 0;
3069 codec->amr = 0;
3070 for (i = 0; i < argc; i++) {
3071 if (!strcmp(argv[i], "hr"))
3072 codec->hr = 1;
3073 if (!strcmp(argv[i], "efr"))
3074 codec->efr = 1;
3075 if (!strcmp(argv[i], "amr"))
3076 codec->amr = 1;
3077 }
3078}
3079
3080#define CODEC_PAR_STR " (hr|efr|amr)"
3081#define CODEC_HELP_STR "Half Rate\n" \
3082 "Enhanced Full Rate\nAdaptive Multirate\n"
3083
3084DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3085 "codec-support fr",
3086 "Codec Support settings\nFullrate\n")
3087{
3088 _get_codec_from_arg(vty, 0, argv);
3089 return CMD_SUCCESS;
3090}
3091
3092DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3093 "codec-support fr" CODEC_PAR_STR,
3094 "Codec Support settings\nFullrate\n"
3095 CODEC_HELP_STR)
3096{
3097 _get_codec_from_arg(vty, 1, argv);
3098 return CMD_SUCCESS;
3099}
3100
3101DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3102 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3103 "Codec Support settings\nFullrate\n"
3104 CODEC_HELP_STR CODEC_HELP_STR)
3105{
3106 _get_codec_from_arg(vty, 2, argv);
3107 return CMD_SUCCESS;
3108}
3109
3110DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3111 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3112 "Codec Support settings\nFullrate\n"
3113 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3114{
3115 _get_codec_from_arg(vty, 3, argv);
3116 return CMD_SUCCESS;
3117}
3118
3119DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3120 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3121 "Codec Support settings\nFullrate\n"
3122 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3123{
3124 _get_codec_from_arg(vty, 4, argv);
3125 return CMD_SUCCESS;
3126}
3127
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003128DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3129 "depends-on-bts <0-255>",
3130 "This BTS can only be started if another one is up\n" "BTS Number\n")
3131{
3132 struct gsm_bts *bts = vty->index;
3133 struct gsm_bts *other_bts;
3134 int dep = atoi(argv[0]);
3135
3136
3137 if (!is_ipaccess_bts(bts)) {
3138 vty_out(vty, "This feature is only available for IP systems.%s",
3139 VTY_NEWLINE);
3140 return CMD_WARNING;
3141 }
3142
3143 other_bts = gsm_bts_num(bts->network, dep);
3144 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3145 vty_out(vty, "This feature is only available for IP systems.%s",
3146 VTY_NEWLINE);
3147 return CMD_WARNING;
3148 }
3149
3150 if (dep >= bts->nr) {
3151 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3152 VTY_NEWLINE);
3153 return CMD_WARNING;
3154 }
3155
3156 bts_depend_mark(bts, dep);
3157 return CMD_SUCCESS;
3158}
3159
3160DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3161 "depeneds-on-bts <0-255>",
3162 NO_STR "This BTS can only be started if another one is up\n"
3163 "BTS Number\n")
3164{
3165 struct gsm_bts *bts = vty->index;
3166 int dep = atoi(argv[0]);
3167
3168 bts_depend_clear(bts, dep);
3169 return CMD_SUCCESS;
3170}
3171
Andreas Eversberg73266522014-01-19 11:47:44 +01003172#define AMR_TEXT "Adaptive Multi Rate settings\n"
3173#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3174#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3175 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3176#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3177#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3178
3179static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3180{
3181 struct gsm_bts *bts = vty->index;
3182 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3183 struct gsm48_multi_rate_conf *mr_conf =
3184 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3185 int i;
3186
3187 mr->gsm48_ie[1] = 0;
3188 for (i = 0; i < argc; i++)
3189 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3190 mr_conf->icmi = 0;
3191}
3192
3193static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3194{
3195 struct gsm_bts *bts = vty->index;
3196 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003197 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003198 int i;
3199
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003200 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3201 for (i = 0; i < argc - 1; i++)
3202 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003203}
3204
3205static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3206{
3207 struct gsm_bts *bts = vty->index;
3208 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003209 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003210 int i;
3211
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003212 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3213 for (i = 0; i < argc - 1; i++)
3214 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003215}
3216
3217static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3218{
3219 struct gsm_bts *bts = vty->index;
3220 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3221 struct gsm48_multi_rate_conf *mr_conf =
3222 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3223 int num = 0, i;
3224
3225 for (i = 0; i < ((full) ? 8 : 6); i++) {
3226 if ((mr->gsm48_ie[1] & (1 << i))) {
3227 num++;
3228 }
3229 }
3230
3231 if (argv[0][0] == 'a' || num == 0)
3232 mr_conf->icmi = 0;
3233 else {
3234 mr_conf->icmi = 1;
3235 if (num < atoi(argv[0]))
3236 mr_conf->smod = num - 1;
3237 else
3238 mr_conf->smod = atoi(argv[0]) - 1;
3239 }
3240}
3241
3242#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3243#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3244 "10,2k\n12,2k\n"
3245
3246#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3247#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3248
3249#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3250#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3251
3252DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3253 "amr tch-f modes" AMR_TCHF_PAR_STR,
3254 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3255 AMR_TCHF_HELP_STR)
3256{
3257 get_amr_from_arg(vty, 1, argv, 1);
3258 return CMD_SUCCESS;
3259}
3260
3261DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3262 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3263 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3264 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3265{
3266 get_amr_from_arg(vty, 2, argv, 1);
3267 return CMD_SUCCESS;
3268}
3269
3270DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3271 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3272 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3273 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3274{
3275 get_amr_from_arg(vty, 3, argv, 1);
3276 return CMD_SUCCESS;
3277}
3278
3279DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3280 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3281 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3282 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3283{
3284 get_amr_from_arg(vty, 4, argv, 1);
3285 return CMD_SUCCESS;
3286}
3287
3288DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3289 "amr tch-f start-mode (auto|1|2|3|4)",
3290 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3291{
3292 get_amr_start_from_arg(vty, argv, 1);
3293 return CMD_SUCCESS;
3294}
3295
3296DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3297 "amr tch-f threshold (ms|bts) <0-63>",
3298 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3299 AMR_TH_HELP_STR)
3300{
3301 get_amr_th_from_arg(vty, 2, argv, 1);
3302 return CMD_SUCCESS;
3303}
3304
3305DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3306 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3307 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3308 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3309{
3310 get_amr_th_from_arg(vty, 3, argv, 1);
3311 return CMD_SUCCESS;
3312}
3313
3314DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3315 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3316 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3317 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3318{
3319 get_amr_th_from_arg(vty, 4, argv, 1);
3320 return CMD_SUCCESS;
3321}
3322
3323DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3324 "amr tch-f hysteresis (ms|bts) <0-15>",
3325 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3326 AMR_HY_HELP_STR)
3327{
3328 get_amr_hy_from_arg(vty, 2, argv, 1);
3329 return CMD_SUCCESS;
3330}
3331
3332DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3333 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3334 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3335 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3336{
3337 get_amr_hy_from_arg(vty, 3, argv, 1);
3338 return CMD_SUCCESS;
3339}
3340
3341DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3342 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3343 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3344 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3345{
3346 get_amr_hy_from_arg(vty, 4, argv, 1);
3347 return CMD_SUCCESS;
3348}
3349
3350DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3351 "amr tch-h modes" AMR_TCHH_PAR_STR,
3352 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3353 AMR_TCHH_HELP_STR)
3354{
3355 get_amr_from_arg(vty, 1, argv, 0);
3356 return CMD_SUCCESS;
3357}
3358
3359DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3360 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3361 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3362 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3363{
3364 get_amr_from_arg(vty, 2, argv, 0);
3365 return CMD_SUCCESS;
3366}
3367
3368DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3369 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3370 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3371 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3372{
3373 get_amr_from_arg(vty, 3, argv, 0);
3374 return CMD_SUCCESS;
3375}
3376
3377DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3378 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3379 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3380 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3381{
3382 get_amr_from_arg(vty, 4, argv, 0);
3383 return CMD_SUCCESS;
3384}
3385
3386DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3387 "amr tch-h start-mode (auto|1|2|3|4)",
3388 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3389{
3390 get_amr_start_from_arg(vty, argv, 0);
3391 return CMD_SUCCESS;
3392}
3393
3394DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3395 "amr tch-h threshold (ms|bts) <0-63>",
3396 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3397 AMR_TH_HELP_STR)
3398{
3399 get_amr_th_from_arg(vty, 2, argv, 0);
3400 return CMD_SUCCESS;
3401}
3402
3403DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3404 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3405 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3406 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3407{
3408 get_amr_th_from_arg(vty, 3, argv, 0);
3409 return CMD_SUCCESS;
3410}
3411
3412DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3413 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3414 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3415 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3416{
3417 get_amr_th_from_arg(vty, 4, argv, 0);
3418 return CMD_SUCCESS;
3419}
3420
3421DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3422 "amr tch-h hysteresis (ms|bts) <0-15>",
3423 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3424 AMR_HY_HELP_STR)
3425{
3426 get_amr_hy_from_arg(vty, 2, argv, 0);
3427 return CMD_SUCCESS;
3428}
3429
3430DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3431 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3432 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3433 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3434{
3435 get_amr_hy_from_arg(vty, 3, argv, 0);
3436 return CMD_SUCCESS;
3437}
3438
3439DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3440 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3441 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3442 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3443{
3444 get_amr_hy_from_arg(vty, 4, argv, 0);
3445 return CMD_SUCCESS;
3446}
3447
Harald Welte8f0ed552010-05-11 21:53:49 +02003448#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003449
Harald Welte5258fc42009-03-28 19:07:53 +00003450/* per TRX configuration */
3451DEFUN(cfg_trx,
3452 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003453 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003454 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003455 "Select a TRX to configure")
3456{
3457 int trx_nr = atoi(argv[0]);
3458 struct gsm_bts *bts = vty->index;
3459 struct gsm_bts_trx *trx;
3460
Harald Weltee441d9c2009-06-21 16:17:15 +02003461 if (trx_nr > bts->num_trx) {
3462 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3463 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003464 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003465 } else if (trx_nr == bts->num_trx) {
3466 /* we need to allocate a new one */
3467 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003468 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003469 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003470
Harald Weltee441d9c2009-06-21 16:17:15 +02003471 if (!trx)
3472 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003473
3474 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003475 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003476 vty->node = TRX_NODE;
3477
3478 return CMD_SUCCESS;
3479}
3480
3481DEFUN(cfg_trx_arfcn,
3482 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003483 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003484 "Set the ARFCN for this TRX\n"
3485 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003486{
3487 int arfcn = atoi(argv[0]);
3488 struct gsm_bts_trx *trx = vty->index;
3489
3490 /* FIXME: check if this ARFCN is supported by this TRX */
3491
3492 trx->arfcn = arfcn;
3493
3494 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3495 /* FIXME: use OML layer to update the ARFCN */
3496 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3497
3498 return CMD_SUCCESS;
3499}
3500
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003501DEFUN(cfg_trx_nominal_power,
3502 cfg_trx_nominal_power_cmd,
3503 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003504 "Nominal TRX RF Power in dBm\n"
3505 "Nominal TRX RF Power in dBm\n"
3506 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003507{
3508 struct gsm_bts_trx *trx = vty->index;
3509
3510 trx->nominal_power = atoi(argv[0]);
3511
3512 return CMD_SUCCESS;
3513}
3514
Harald Weltefcd24452009-06-20 18:15:19 +02003515DEFUN(cfg_trx_max_power_red,
3516 cfg_trx_max_power_red_cmd,
3517 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003518 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003519 "Reduction of maximum BS RF Power in dB\n")
3520{
3521 int maxpwr_r = atoi(argv[0]);
3522 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003523 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003524
3525 /* FIXME: check if our BTS type supports more than 12 */
3526 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3527 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3528 maxpwr_r, VTY_NEWLINE);
3529 return CMD_WARNING;
3530 }
3531 if (maxpwr_r & 1) {
3532 vty_out(vty, "%% Power %d dB is not an even value%s",
3533 maxpwr_r, VTY_NEWLINE);
3534 return CMD_WARNING;
3535 }
3536
3537 trx->max_power_red = maxpwr_r;
3538
3539 /* FIXME: make sure we update this using OML */
3540
3541 return CMD_SUCCESS;
3542}
3543
Harald Welte42581822009-08-08 16:12:58 +02003544DEFUN(cfg_trx_rsl_e1,
3545 cfg_trx_rsl_e1_cmd,
3546 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003547 "RSL Parameters\n"
3548 "E1/T1 interface to be used for RSL\n"
3549 "E1/T1 interface to be used for RSL\n"
3550 "E1/T1 Line Number to be used for RSL\n"
3551 "E1/T1 Timeslot to be used for RSL\n"
3552 "E1/T1 Timeslot to be used for RSL\n"
3553 "E1/T1 Sub-slot to be used for RSL\n"
3554 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3555 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3556 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3557 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3558 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003559{
3560 struct gsm_bts_trx *trx = vty->index;
3561
3562 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3563
3564 return CMD_SUCCESS;
3565}
3566
3567DEFUN(cfg_trx_rsl_e1_tei,
3568 cfg_trx_rsl_e1_tei_cmd,
3569 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003570 "RSL Parameters\n"
3571 "Set the TEI to be used for RSL\n"
3572 "Set the TEI to be used for RSL\n"
3573 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003574{
3575 struct gsm_bts_trx *trx = vty->index;
3576
3577 trx->rsl_tei = atoi(argv[0]);
3578
3579 return CMD_SUCCESS;
3580}
3581
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003582DEFUN(cfg_trx_rf_locked,
3583 cfg_trx_rf_locked_cmd,
3584 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003585 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3586 "TRX is NOT RF locked (active)\n"
3587 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003588{
3589 int locked = atoi(argv[0]);
3590 struct gsm_bts_trx *trx = vty->index;
3591
Maxbe356ed2017-09-07 19:10:09 +02003592 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003593 return CMD_SUCCESS;
3594}
Harald Welte42581822009-08-08 16:12:58 +02003595
Harald Welte5258fc42009-03-28 19:07:53 +00003596/* per TS configuration */
3597DEFUN(cfg_ts,
3598 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003599 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003600 "Select a Timeslot to configure\n"
3601 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003602{
3603 int ts_nr = atoi(argv[0]);
3604 struct gsm_bts_trx *trx = vty->index;
3605 struct gsm_bts_trx_ts *ts;
3606
3607 if (ts_nr >= TRX_NR_TS) {
3608 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3609 TRX_NR_TS, VTY_NEWLINE);
3610 return CMD_WARNING;
3611 }
3612
3613 ts = &trx->ts[ts_nr];
3614
3615 vty->index = ts;
3616 vty->node = TS_NODE;
3617
3618 return CMD_SUCCESS;
3619}
3620
Harald Weltea6fd58e2009-08-07 00:25:23 +02003621DEFUN(cfg_ts_pchan,
3622 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003623 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003624 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003625{
3626 struct gsm_bts_trx_ts *ts = vty->index;
3627 int pchanc;
3628
3629 pchanc = gsm_pchan_parse(argv[0]);
3630 if (pchanc < 0)
3631 return CMD_WARNING;
3632
3633 ts->pchan = pchanc;
3634
3635 return CMD_SUCCESS;
3636}
3637
3638/* used for backwards compatibility with old config files that still
3639 * have uppercase pchan type names */
3640DEFUN_HIDDEN(cfg_ts_pchan_compat,
3641 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003642 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003643 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003644{
3645 struct gsm_bts_trx_ts *ts = vty->index;
3646 int pchanc;
3647
3648 pchanc = gsm_pchan_parse(argv[0]);
3649 if (pchanc < 0)
3650 return CMD_WARNING;
3651
3652 ts->pchan = pchanc;
3653
3654 return CMD_SUCCESS;
3655}
3656
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003657
3658
Harald Welte135a6482011-05-30 12:09:13 +02003659DEFUN(cfg_ts_tsc,
3660 cfg_ts_tsc_cmd,
3661 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003662 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003663{
3664 struct gsm_bts_trx_ts *ts = vty->index;
3665
Max71d082b2017-05-30 15:03:38 +02003666 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003667 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3668 "falling back to BCC%s", VTY_NEWLINE);
3669 ts->tsc = -1;
3670 return CMD_WARNING;
3671 }
3672
Harald Welte135a6482011-05-30 12:09:13 +02003673 ts->tsc = atoi(argv[0]);
3674
3675 return CMD_SUCCESS;
3676}
3677
Harald Weltea39b0f22010-06-14 22:26:10 +02003678#define HOPPING_STR "Configure frequency hopping\n"
3679
3680DEFUN(cfg_ts_hopping,
3681 cfg_ts_hopping_cmd,
3682 "hopping enabled (0|1)",
3683 HOPPING_STR "Enable or disable frequency hopping\n"
3684 "Disable frequency hopping\n" "Enable frequency hopping\n")
3685{
3686 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003687 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003688
Max71d082b2017-05-30 15:03:38 +02003689 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003690 vty_out(vty, "BTS model does not support hopping%s",
3691 VTY_NEWLINE);
3692 return CMD_WARNING;
3693 }
3694
3695 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003696
3697 return CMD_SUCCESS;
3698}
3699
Harald Welte6e0cd042009-09-12 13:05:33 +02003700DEFUN(cfg_ts_hsn,
3701 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003702 "hopping sequence-number <0-63>",
3703 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003704 "Which hopping sequence to use for this channel\n"
3705 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003706{
3707 struct gsm_bts_trx_ts *ts = vty->index;
3708
3709 ts->hopping.hsn = atoi(argv[0]);
3710
3711 return CMD_SUCCESS;
3712}
3713
3714DEFUN(cfg_ts_maio,
3715 cfg_ts_maio_cmd,
3716 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003717 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003718 "Which hopping MAIO to use for this channel\n"
3719 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003720{
3721 struct gsm_bts_trx_ts *ts = vty->index;
3722
3723 ts->hopping.maio = atoi(argv[0]);
3724
3725 return CMD_SUCCESS;
3726}
3727
3728DEFUN(cfg_ts_arfcn_add,
3729 cfg_ts_arfcn_add_cmd,
3730 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003731 HOPPING_STR "Configure hopping ARFCN list\n"
3732 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003733{
3734 struct gsm_bts_trx_ts *ts = vty->index;
3735 int arfcn = atoi(argv[0]);
3736
Harald Weltea39b0f22010-06-14 22:26:10 +02003737 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3738
Harald Welte6e0cd042009-09-12 13:05:33 +02003739 return CMD_SUCCESS;
3740}
3741
3742DEFUN(cfg_ts_arfcn_del,
3743 cfg_ts_arfcn_del_cmd,
3744 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003745 HOPPING_STR "Configure hopping ARFCN list\n"
3746 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003747{
3748 struct gsm_bts_trx_ts *ts = vty->index;
3749 int arfcn = atoi(argv[0]);
3750
Harald Weltea39b0f22010-06-14 22:26:10 +02003751 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3752
Harald Welte6e0cd042009-09-12 13:05:33 +02003753 return CMD_SUCCESS;
3754}
3755
Harald Weltea6fd58e2009-08-07 00:25:23 +02003756DEFUN(cfg_ts_e1_subslot,
3757 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003758 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003759 "E1/T1 channel connected to this on-air timeslot\n"
3760 "E1/T1 channel connected to this on-air timeslot\n"
3761 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003762 "E1/T1 timeslot connected to this on-air timeslot\n"
3763 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003764 "E1/T1 sub-slot connected to this on-air timeslot\n"
3765 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3766 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3767 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3768 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3769 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003770{
3771 struct gsm_bts_trx_ts *ts = vty->index;
3772
Harald Welte42581822009-08-08 16:12:58 +02003773 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003774
3775 return CMD_SUCCESS;
3776}
Harald Welte5258fc42009-03-28 19:07:53 +00003777
Harald Welte4f10c252010-05-16 21:47:13 +02003778void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3779{
Harald Weltecf9d4312017-12-13 23:17:16 +01003780 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003781 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003782 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003783 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003784}
3785
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003786DEFUN(drop_bts,
3787 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003788 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003789 "Debug/Simulation command to drop Abis/IP BTS\n"
3790 "Debug/Simulation command to drop Abis/IP BTS\n"
3791 "Debug/Simulation command to drop Abis/IP BTS\n"
3792 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003793{
3794 struct gsm_network *gsmnet;
3795 struct gsm_bts_trx *trx;
3796 struct gsm_bts *bts;
3797 unsigned int bts_nr;
3798
3799 gsmnet = gsmnet_from_vty(vty);
3800
3801 bts_nr = atoi(argv[0]);
3802 if (bts_nr >= gsmnet->num_bts) {
3803 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3804 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3805 return CMD_WARNING;
3806 }
3807
3808 bts = gsm_bts_num(gsmnet, bts_nr);
3809 if (!bts) {
3810 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3811 return CMD_WARNING;
3812 }
3813
3814 if (!is_ipaccess_bts(bts)) {
3815 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3816 return CMD_WARNING;
3817 }
3818
3819
3820 /* close all connections */
3821 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003822 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003823 } else if (strcmp(argv[1], "rsl") == 0) {
3824 /* close all rsl connections */
3825 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003826 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003827 }
3828 } else {
3829 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3830 return CMD_WARNING;
3831 }
3832
3833 return CMD_SUCCESS;
3834}
3835
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003836DEFUN(restart_bts, restart_bts_cmd,
3837 "restart-bts <0-65535>",
3838 "Restart ip.access nanoBTS through OML\n"
3839 "BTS Number\n")
3840{
3841 struct gsm_network *gsmnet;
3842 struct gsm_bts_trx *trx;
3843 struct gsm_bts *bts;
3844 unsigned int bts_nr;
3845
3846 gsmnet = gsmnet_from_vty(vty);
3847
3848 bts_nr = atoi(argv[0]);
3849 if (bts_nr >= gsmnet->num_bts) {
3850 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3851 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3852 return CMD_WARNING;
3853 }
3854
3855 bts = gsm_bts_num(gsmnet, bts_nr);
3856 if (!bts) {
3857 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3858 return CMD_WARNING;
3859 }
3860
3861 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3862 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3863 VTY_NEWLINE);
3864 return CMD_WARNING;
3865 }
3866
3867 /* go from last TRX to c0 */
3868 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3869 abis_nm_ipaccess_restart(trx);
3870
3871 return CMD_SUCCESS;
3872}
3873
Harald Welte8e2e22f2017-07-10 20:25:10 +02003874DEFUN(bts_resend, bts_resend_cmd,
3875 "bts <0-255> resend-system-information",
3876 "BTS Specific Commands\n" "BTS Number\n"
3877 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3878{
3879 struct gsm_network *gsmnet;
3880 struct gsm_bts_trx *trx;
3881 struct gsm_bts *bts;
3882 unsigned int bts_nr;
3883
3884 gsmnet = gsmnet_from_vty(vty);
3885
3886 bts_nr = atoi(argv[0]);
3887 if (bts_nr >= gsmnet->num_bts) {
3888 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3889 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3890 return CMD_WARNING;
3891 }
3892
3893 bts = gsm_bts_num(gsmnet, bts_nr);
3894 if (!bts) {
3895 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3896 return CMD_WARNING;
3897 }
3898
3899 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3900 gsm_bts_trx_set_system_infos(trx);
3901
3902 return CMD_SUCCESS;
3903}
3904
3905
Harald Welte30f1f372014-12-28 15:00:45 +01003906DEFUN(smscb_cmd, smscb_cmd_cmd,
3907 "bts <0-255> smscb-command <1-4> HEXSTRING",
3908 "BTS related commands\n" "BTS Number\n"
3909 "SMS Cell Broadcast\n" "Last Valid Block\n"
3910 "Hex Encoded SMSCB message (up to 88 octets)\n")
3911{
3912 struct gsm_bts *bts;
3913 int bts_nr = atoi(argv[0]);
3914 int last_block = atoi(argv[1]);
3915 struct rsl_ie_cb_cmd_type cb_cmd;
3916 uint8_t buf[88];
3917 int rc;
3918
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02003919 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01003920 if (!bts) {
3921 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3922 return CMD_WARNING;
3923 }
3924 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
3925 if (rc < 0 || rc > sizeof(buf)) {
3926 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
3927 return CMD_WARNING;
3928 }
3929
3930 cb_cmd.spare = 0;
3931 cb_cmd.def_bcast = 0;
3932 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
3933
3934 switch (last_block) {
3935 case 1:
3936 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
3937 break;
3938 case 2:
3939 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
3940 break;
3941 case 3:
3942 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
3943 break;
3944 case 4:
3945 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
3946 break;
3947 }
3948
3949 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
3950
3951 return CMD_SUCCESS;
3952}
3953
Harald Welte7fe00fb2017-05-27 14:09:50 +02003954/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02003955static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
3956 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02003957{
Harald Welte645eb622017-05-27 15:52:58 +02003958 int bts_nr = atoi(bts_str);
3959 int trx_nr = atoi(trx_str);
3960 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003961 struct gsm_bts *bts;
3962 struct gsm_bts_trx *trx;
3963 struct gsm_bts_trx_ts *ts;
3964
3965 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
3966 if (!bts) {
3967 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
3968 return NULL;
3969 }
3970
3971 trx = gsm_bts_trx_num(bts, trx_nr);
3972 if (!trx) {
3973 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
3974 return NULL;
3975 }
3976
3977 ts = &trx->ts[ts_nr];
3978
3979 return ts;
3980}
Harald Welte30f1f372014-12-28 15:00:45 +01003981
Harald Welted0d2b0b2010-12-23 13:18:07 +01003982DEFUN(pdch_act, pdch_act_cmd,
3983 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
3984 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
3985 "TRX Timeslot\n" "Timeslot Number\n" "Packet Data Channel\n"
3986 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
3987 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
3988{
Harald Welted0d2b0b2010-12-23 13:18:07 +01003989 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01003990 int activate;
3991
Harald Welte645eb622017-05-27 15:52:58 +02003992 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02003993 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01003994 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01003995
Harald Welte7fe00fb2017-05-27 14:09:50 +02003996 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01003997 vty_out(vty, "%% This command only works for ipaccess BTS%s",
3998 VTY_NEWLINE);
3999 return CMD_WARNING;
4000 }
4001
Harald Welted0d2b0b2010-12-23 13:18:07 +01004002 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4003 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004004 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004005 return CMD_WARNING;
4006 }
4007
4008 if (!strcmp(argv[3], "activate"))
4009 activate = 1;
4010 else
4011 activate = 0;
4012
4013 rsl_ipacc_pdch_activate(ts, activate);
4014
4015 return CMD_SUCCESS;
4016
4017}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004018
Harald Welte2abd5e12017-05-27 14:10:40 +02004019/* determine the logical channel type based on the physical channel type */
4020static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4021{
4022 switch (pchan) {
4023 case GSM_PCHAN_TCH_F:
4024 return GSM_LCHAN_TCH_F;
4025 case GSM_PCHAN_TCH_H:
4026 return GSM_LCHAN_TCH_H;
4027 case GSM_PCHAN_SDCCH8_SACCH8C:
4028 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4029 case GSM_PCHAN_CCCH_SDCCH4:
4030 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4031 return GSM_LCHAN_SDCCH;
4032 default:
4033 return -1;
4034 }
4035}
4036
4037/* configure the lchan for a single AMR mode (as specified) */
4038static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4039{
4040 struct amr_multirate_conf mr;
4041 struct gsm48_multi_rate_conf *mr_conf;
4042 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4043
4044 if (amr_mode > 7)
4045 return -1;
4046
4047 memset(&mr, 0, sizeof(mr));
4048 mr_conf->ver = 1;
4049 /* bit-mask of supported modes, only one bit is set. Reflects
4050 * Figure 10.5.2.47a where there are no thershold and only a
4051 * single mode */
4052 mr.gsm48_ie[1] = 1 << amr_mode;
4053
4054 mr.ms_mode[0].mode = amr_mode;
4055 mr.bts_mode[0].mode = amr_mode;
4056
4057 /* encode this configuration into the lchan for both uplink and
4058 * downlink direction */
4059 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4060 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4061
4062 return 0;
4063}
4064
4065/* Debug/Measurement command to activate a given logical channel
4066 * manually in a given mode/codec. This is useful for receiver
4067 * performance testing (FER/RBER/...) */
4068DEFUN(lchan_act, lchan_act_cmd,
4069 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
4070 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4071 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot Number\n" "Sub-Slot Number\n"
4072 "Manual Channel Activation (e.g. for BER test)\n"
4073 "Manual Channel Deactivation (e.g. for BER test)\n"
4074 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4075{
4076 struct gsm_bts_trx_ts *ts;
4077 struct gsm_lchan *lchan;
4078 int ss_nr = atoi(argv[3]);
4079 const char *act_str = argv[4];
4080 const char *codec_str = argv[5];
4081 int activate;
4082
4083 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4084 if (!ts)
4085 return CMD_WARNING;
4086
4087 lchan = &ts->lchan[ss_nr];
4088
4089 if (!strcmp(act_str, "activate"))
4090 activate = 1;
4091 else
4092 activate = 0;
4093
4094 if (ss_nr >= ts_subslots(ts)) {
4095 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4096 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4097 return CMD_WARNING;
4098 }
4099
4100 if (activate) {
4101 int lchan_t;
4102 if (lchan->state != LCHAN_S_NONE) {
4103 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4104 return CMD_WARNING;
4105 }
4106 lchan_t = lchan_type_by_pchan(ts->pchan);
4107 if (lchan_t < 0)
4108 return CMD_WARNING;
4109 /* configure the lchan */
4110 lchan->type = lchan_t;
4111 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4112 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4113 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4114 else if (!strcmp(codec_str, "efr"))
4115 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4116 else if (!strcmp(codec_str, "amr")) {
4117 int amr_mode;
4118 if (argc < 7) {
4119 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4120 return CMD_WARNING;
4121 }
4122 amr_mode = atoi(argv[6]);
4123 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4124 lchan_set_single_amr_mode(lchan, amr_mode);
4125 }
4126 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4127 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4128 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004129 } else {
4130 rsl_direct_rf_release(lchan);
4131 }
4132
4133 return CMD_SUCCESS;
4134}
4135
Harald Welte3f86c522017-05-27 15:53:28 +02004136DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4137 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
4138 "BTS related commands\n" "BTS Number\n" "Transceiver\n" "Transceiver Number\n"
4139 "TRX Timeslot\n" "Timeslot Number\n" "Sub-Slot\n" "Sub-Slot Number\n"
4140 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4141{
4142 struct gsm_bts_trx_ts *ts;
4143 struct gsm_lchan *lchan;
4144 int ss_nr = atoi(argv[3]);
4145 int port = atoi(argv[5]);
4146 struct in_addr ia;
4147 inet_aton(argv[4], &ia);
4148
4149 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4150 if (!ts)
4151 return CMD_WARNING;
4152
4153 lchan = &ts->lchan[ss_nr];
4154
4155 if (ss_nr >= ts_subslots(ts)) {
4156 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4157 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4158 return CMD_WARNING;
4159 }
4160
4161 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4162 inet_ntoa(ia), port, VTY_NEWLINE);
4163 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4164 return CMD_SUCCESS;
4165}
Harald Welteb71147a2017-07-18 19:11:49 +02004166
4167DEFUN(ctrl_trap, ctrl_trap_cmd,
4168 "ctrl-interface generate-trap TRAP VALUE",
4169 "Commands related to the CTRL Interface\n"
4170 "Generate a TRAP for test purpose\n"
4171 "Identity/Name of the TRAP variable\n"
4172 "Value of the TRAP variable\n")
4173{
4174 struct gsm_network *net = gsmnet_from_vty(vty);
4175
4176 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4177 return CMD_SUCCESS;
4178}
4179
Harald Weltedcccb182010-05-16 20:52:23 +02004180extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004181
Maxdb0e3802017-01-12 19:35:11 +01004182int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004183{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004184 cfg_ts_pchan_cmd.string =
4185 vty_cmd_string_from_valstr(tall_bsc_ctx,
4186 gsm_pchant_names,
4187 "phys_chan_config (", "|", ")",
4188 VTY_DO_LOWER);
4189 cfg_ts_pchan_cmd.doc =
4190 vty_cmd_string_from_valstr(tall_bsc_ctx,
4191 gsm_pchant_descs,
4192 "Physical Channel Combination\n",
4193 "\n", "", 0);
4194
Harald Weltee555c2b2012-08-17 13:02:12 +02004195 cfg_bts_type_cmd.string =
4196 vty_cmd_string_from_valstr(tall_bsc_ctx,
4197 bts_type_names,
4198 "type (", "|", ")",
4199 VTY_DO_LOWER);
4200 cfg_bts_type_cmd.doc =
4201 vty_cmd_string_from_valstr(tall_bsc_ctx,
4202 bts_type_descs,
4203 "BTS Vendor/Type\n",
4204 "\n", "", 0);
4205
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +02004206 common_cs_vty_init(network, config_write_net);
Harald Weltee555c2b2012-08-17 13:02:12 +02004207
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004208 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004209 install_element_ve(&show_bts_cmd);
4210 install_element_ve(&show_trx_cmd);
4211 install_element_ve(&show_ts_cmd);
4212 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004213 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004214
Philipp Maier39f62bb2017-04-09 12:32:51 +02004215 install_element_ve(&show_subscr_conn_cmd);
4216 install_element_ve(&handover_subscr_conn_cmd);
4217
Harald Welteb4d5b172010-05-12 16:10:35 +00004218 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004219 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004220
Maxdb0e3802017-01-12 19:35:11 +01004221 logging_vty_add_cmds(NULL);
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004222
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004223 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Harald Weltebc814502009-12-19 21:41:52 +01004224 install_element(GSMNET_NODE, &cfg_net_handover_cmd);
Harald Welteb720bd32009-12-21 16:51:50 +01004225 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_cmd);
4226 install_element(GSMNET_NODE, &cfg_net_ho_win_rxqual_avg_cmd);
4227 install_element(GSMNET_NODE, &cfg_net_ho_win_rxlev_avg_neigh_cmd);
4228 install_element(GSMNET_NODE, &cfg_net_ho_pwr_interval_cmd);
4229 install_element(GSMNET_NODE, &cfg_net_ho_pwr_hysteresis_cmd);
4230 install_element(GSMNET_NODE, &cfg_net_ho_max_distance_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004231 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004232 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4233 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4234 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4235 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4236 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4237 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4238 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4239 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4240 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004241 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004242 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004243 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004244 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Harald Welte5013b2a2009-08-07 13:29:14 +02004245
4246 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004247 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004248 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004249 install_element(BTS_NODE, &cfg_description_cmd);
4250 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004251 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004252 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004253 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4254 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4255 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4256 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004257 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4258 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004259 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004260 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004261 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004262 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004263 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004264 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004265 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004266 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4267 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004268 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004269 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4270 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004271 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4272 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4273 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004274 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4275 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004276 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004277 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004278 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004279 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004280 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4281 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004282 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4283 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4284 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4285 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4286 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4287 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004288 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004289 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004290 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304291 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004292 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004293 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004294 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004295 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4296 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004297 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004298 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004299 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004300 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004301 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4302 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4303 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004304 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004305 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4306 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004307 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004308 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004309 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4310 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004311 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004312 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4313 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004314 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4315 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004316 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4317 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004318 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4319 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004320 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4321 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4322 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4323 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4324 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004325 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4326 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004327 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4328 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4329 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4330 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4331 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4332 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4333 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4334 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4335 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4336 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4337 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4338 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4339 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4340 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4341 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4342 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4343 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4344 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4345 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4346 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4347 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4348 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004349 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004350
Harald Welte5258fc42009-03-28 19:07:53 +00004351 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004352 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004353 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004354 install_element(TRX_NODE, &cfg_description_cmd);
4355 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004356 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004357 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004358 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4359 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004360 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004361
Harald Welte5258fc42009-03-28 19:07:53 +00004362 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004363 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004364 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004365 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004366 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004367 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004368 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4369 install_element(TS_NODE, &cfg_ts_maio_cmd);
4370 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4371 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004372 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004373
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004374 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004375 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004376 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004377 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004378 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004379 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004380 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004381 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004382
Harald Welte81c9b9c2010-05-31 16:40:40 +02004383 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004384 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004385 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004386 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004387
Harald Weltedcccb182010-05-16 20:52:23 +02004388 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004389
Harald Welte68628e82009-03-10 12:17:57 +00004390 return 0;
4391}