blob: 6415df9c74b2120b028e60607f5734a64925b920 [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>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020059#include <osmocom/bsc/handover.h>
Neels Hofmeyre25018b2017-11-27 21:29:33 +010060#include <osmocom/bsc/handover_cfg.h>
61#include <osmocom/bsc/handover_vty.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020062#include <osmocom/bsc/gsm_04_08_utils.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020063
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010064#include <inttypes.h>
65
Harald Weltec08e8be2011-03-04 13:53:51 +010066#include "../../bscconfig.h"
Harald Welte1353f962010-05-16 19:20:24 +020067
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010068#define BTS_NR_STR "BTS Number\n"
69#define TRX_NR_STR "TRX Number\n"
70#define TS_NR_STR "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020071#define LCHAN_NR_STR "Logical Channel Number\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010072#define BTS_TRX_STR BTS_NR_STR TRX_NR_STR
73#define BTS_TRX_TS_STR BTS_TRX_STR TS_NR_STR
74#define BTS_TRX_TS_LCHAN_STR BTS_TRX_TS_STR LCHAN_NR_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020075
Harald Welteea4647d2010-05-12 17:19:53 +000076/* FIXME: this should go to some common file */
77static const struct value_string gprs_ns_timer_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020078 { 0, "tns-block" },
79 { 1, "tns-block-retries" },
80 { 2, "tns-reset" },
81 { 3, "tns-reset-retries" },
82 { 4, "tns-test" },
83 { 5, "tns-alive" },
84 { 6, "tns-alive-retries" },
85 { 0, NULL }
86};
87
Harald Welteea4647d2010-05-12 17:19:53 +000088static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020089 { 0, "blocking-timer" },
90 { 1, "blocking-retries" },
91 { 2, "unblocking-retries" },
92 { 3, "reset-timer" },
93 { 4, "reset-retries" },
94 { 5, "suspend-timer" },
95 { 6, "suspend-retries" },
96 { 7, "resume-timer" },
97 { 8, "resume-retries" },
98 { 9, "capability-update-timer" },
99 { 10, "capability-update-retries" },
100 { 0, NULL }
101};
102
Harald Welte64c07d22011-02-15 11:43:27 +0100103static const struct value_string bts_neigh_mode_strs[] = {
104 { NL_MODE_AUTOMATIC, "automatic" },
105 { NL_MODE_MANUAL, "manual" },
106 { NL_MODE_MANUAL_SI5SEP, "manual-si5" },
107 { 0, NULL }
108};
109
Daniel Willmann7d109832012-05-14 18:43:23 +0200110const struct value_string bts_loc_fix_names[] = {
111 { BTS_LOC_FIX_INVALID, "invalid" },
112 { BTS_LOC_FIX_2D, "fix2d" },
113 { BTS_LOC_FIX_3D, "fix3d" },
114 { 0, NULL }
115};
116
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100117struct cmd_node net_node = {
118 GSMNET_NODE,
119 "%s(config-net)# ",
120 1,
121};
122
Harald Welte68628e82009-03-10 12:17:57 +0000123struct cmd_node bts_node = {
124 BTS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200125 "%s(config-net-bts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000126 1,
127};
128
129struct cmd_node trx_node = {
130 TRX_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200131 "%s(config-net-bts-trx)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000132 1,
133};
134
135struct cmd_node ts_node = {
136 TS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200137 "%s(config-net-bts-trx-ts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000138 1,
139};
140
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100141static struct gsm_network *vty_global_gsm_network = NULL;
142
143struct gsm_network *gsmnet_from_vty(struct vty *v)
144{
145 /* It can't hurt to force callers to continue to pass the vty instance
146 * to this function, in case we'd like to retrieve the global
147 * gsm_network instance from the vty at some point in the future. But
148 * until then, just return the global pointer, which should have been
149 * initialized by common_cs_vty_init().
150 */
151 OSMO_ASSERT(vty_global_gsm_network);
152 return vty_global_gsm_network;
153}
154
Harald Welte68628e82009-03-10 12:17:57 +0000155static int dummy_config_write(struct vty *v)
156{
157 return CMD_SUCCESS;
158}
159
160static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
161{
Harald Welte1304b352013-03-15 16:57:33 +0100162 vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
163 abis_nm_opstate_name(nms->operational),
164 get_value_string(abis_nm_adm_state_names, nms->administrative),
Harald Welte867d9f32011-05-23 20:30:39 +0200165 abis_nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000166}
167
Harald Welteb908cb72009-12-22 13:09:29 +0100168static void dump_pchan_load_vty(struct vty *vty, char *prefix,
169 const struct pchan_load *pl)
170{
171 int i;
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100172 int dumped = 0;
Harald Welteb908cb72009-12-22 13:09:29 +0100173
174 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
175 const struct load_counter *lc = &pl->pchan[i];
176 unsigned int percent;
177
178 if (lc->total == 0)
179 continue;
180
181 percent = (lc->used * 100) / lc->total;
182
183 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
184 gsm_pchan_name(i), percent, lc->used, lc->total,
185 VTY_NEWLINE);
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100186 dumped ++;
Harald Welteb908cb72009-12-22 13:09:29 +0100187 }
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100188 if (!dumped)
189 vty_out(vty, "%s(none)%s", prefix, VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100190}
191
Harald Welte68628e82009-03-10 12:17:57 +0000192static void net_dump_vty(struct vty *vty, struct gsm_network *net)
193{
Harald Welteb908cb72009-12-22 13:09:29 +0100194 struct pchan_load pl;
195
Harald Welteef235b52009-03-10 12:34:02 +0000196 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
197 "and has %u BTS%s", net->country_code, net->network_code,
198 net->num_bts, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200199 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900200 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
201 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100202 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
203 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800204 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
205 VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100206
207 {
208 struct gsm_bts *bts;
209 unsigned int ho_active_count = 0;
210 unsigned int ho_inactive_count = 0;
211
212 llist_for_each_entry(bts, &net->bts_list, list) {
213 if (ho_get_ho_active(bts->ho))
214 ho_active_count ++;
215 else
216 ho_inactive_count ++;
217 }
218
219 if (ho_active_count && ho_inactive_count)
220 vty_out(vty, " Handover: On at %u BTS, Off at %u BTS%s",
221 ho_active_count, ho_inactive_count, VTY_NEWLINE);
222 else
223 vty_out(vty, " Handover: %s%s", ho_active_count ? "On" : "Off",
224 VTY_NEWLINE);
225 }
226
Harald Welteb908cb72009-12-22 13:09:29 +0100227 network_chan_load(&pl, net);
228 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
229 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100230
231 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100232 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100233 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200234 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100235 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100236 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200237 vty_out(vty, " Last RF Lock Command: %s%s",
238 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
239 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000240}
241
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200242DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000243 SHOW_STR "Display information about a GSM NETWORK\n")
244{
Harald Weltedcccb182010-05-16 20:52:23 +0200245 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000246 net_dump_vty(vty, net);
247
248 return CMD_SUCCESS;
249}
250
251static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
252{
Harald Welteedb37782009-05-01 14:59:07 +0000253 struct e1inp_line *line;
254
255 if (!e1l) {
256 vty_out(vty, " None%s", VTY_NEWLINE);
257 return;
258 }
259
260 line = e1l->ts->line;
261
262 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
263 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000264 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000265 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000266 e1l->tei, e1l->sapi, VTY_NEWLINE);
267}
268
269static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
270{
Harald Welteb908cb72009-12-22 13:09:29 +0100271 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200272 unsigned long long sec;
Harald Welteb908cb72009-12-22 13:09:29 +0100273
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200274 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100275 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200276 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200277 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100278 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100279 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200280 bts->num_trx, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200281 vty_out(vty, "Description: %s%s",
282 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Maxf9685c12017-03-23 12:01:07 +0100283 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
284 vty_out(vty, "PCU version %s connected%s", bts->pcu_version,
285 VTY_NEWLINE);
Harald Welte1d8dbc42009-12-12 15:38:16 +0100286 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100287 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100288 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
289 VTY_NEWLINE);
290 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100291 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100292 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
293 VTY_NEWLINE);
294 vty_out(vty, "RACH Max transmissions: %u%s",
295 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
296 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100297 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200298 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200299 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
300 vty_out(vty, "Uplink DTX: %s%s",
301 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
302 "enabled" : "forced", VTY_NEWLINE);
303 else
304 vty_out(vty, "Uplink DTX: not enabled%s", VTY_NEWLINE);
305 vty_out(vty, "Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
306 VTY_NEWLINE);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200307 vty_out(vty, "Channel Description Attachment: %s%s",
308 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
309 vty_out(vty, "Channel Description BS-PA-MFRMS: %u%s",
310 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
311 vty_out(vty, "Channel Description BS-AG_BLKS-RES: %u%s",
312 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200313 vty_out(vty, "System Information present: 0x%08x, static: 0x%08x%s",
314 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100315 vty_out(vty, "Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100316 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100317 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
318 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
319 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100320 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200321 if (bts->pcu_sock_path)
322 vty_out(vty, "PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000323 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200324 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000325 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200326 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200327 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
328 vty_out(vty, " Skip Reset: %d%s",
329 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000330 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200331 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000332 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200333 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200334 vty_out(vty, " GPRS NSE: ");
335 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
336 vty_out(vty, " GPRS CELL: ");
337 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
338 vty_out(vty, " GPRS NSVC0: ");
339 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
340 vty_out(vty, " GPRS NSVC1: ");
341 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200342 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
343 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000344 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100345 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200346 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200347 sec = bts_uptime(bts);
348 if (sec)
Maxff3fad12018-01-07 16:50:42 +0100349 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.",
350 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60);
351 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100352 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200353 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
354 e1isl_dump_vty(vty, bts->oml_link);
355 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100356
357 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100358 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200359 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100360 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
361 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100362
363 vty_out(vty, "Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
364 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
365 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
366 VTY_NEWLINE);
367 vty_out(vty, "Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
368 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
369 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
370 VTY_NEWLINE);
371 vty_out(vty, "BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
372 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
373 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
374 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000375}
376
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100377DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000378 SHOW_STR "Display information about a BTS\n"
379 "BTS number")
380{
Harald Weltedcccb182010-05-16 20:52:23 +0200381 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000382 int bts_nr;
383
384 if (argc != 0) {
385 /* use the BTS number that the user has specified */
386 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100387 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000388 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000389 VTY_NEWLINE);
390 return CMD_WARNING;
391 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200392 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000393 return CMD_SUCCESS;
394 }
395 /* print all BTS's */
396 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200397 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000398
399 return CMD_SUCCESS;
400}
401
Harald Welte42581822009-08-08 16:12:58 +0200402/* utility functions */
403static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
404 const char *ts, const char *ss)
405{
406 e1_link->e1_nr = atoi(line);
407 e1_link->e1_ts = atoi(ts);
408 if (!strcmp(ss, "full"))
409 e1_link->e1_ts_ss = 255;
410 else
411 e1_link->e1_ts_ss = atoi(ss);
412}
413
414static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
415 const char *prefix)
416{
417 if (!e1_link->e1_ts)
418 return;
419
420 if (e1_link->e1_ts_ss == 255)
421 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
422 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
423 else
424 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
425 prefix, e1_link->e1_nr, e1_link->e1_ts,
426 e1_link->e1_ts_ss, VTY_NEWLINE);
427}
428
429
Harald Welte67ce0732009-08-06 19:06:46 +0200430static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
431{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100432 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100433 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100434 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200435 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100436 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200437 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100438 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200439 ts->hopping.enabled, VTY_NEWLINE);
440 if (ts->hopping.enabled) {
441 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100442 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200443 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100444 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200445 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200446 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
447 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
448 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100449 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200450 i, VTY_NEWLINE);
451 }
Harald Welte127af342010-12-24 12:07:07 +0100452 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100453 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100454
455 if (ts->trx->bts->model->config_write_ts)
456 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200457}
458
459static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
460{
461 int i;
462
Harald Welte5013b2a2009-08-07 13:29:14 +0200463 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200464 if (trx->description)
465 vty_out(vty, " description %s%s", trx->description,
466 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200467 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200468 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200469 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200470 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100471 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200472 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200473 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
474 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200475
Harald Welteface7ed2011-02-14 16:15:21 +0100476 if (trx->bts->model->config_write_trx)
477 trx->bts->model->config_write_trx(vty, trx);
478
Harald Welte67ce0732009-08-06 19:06:46 +0200479 for (i = 0; i < TRX_NR_TS; i++)
480 config_write_ts_single(vty, &trx->ts[i]);
481}
482
Harald Welte615e9562010-05-11 23:50:21 +0200483static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
484{
485 unsigned int i;
486 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
487 VTY_NEWLINE);
488 if (bts->gprs.mode == BTS_GPRS_NONE)
489 return;
490
bhargava350533c2016-07-21 11:14:34 +0530491 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
492 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
493
Harald Welte615e9562010-05-11 23:50:21 +0200494 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
495 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100496 vty_out(vty, " gprs network-control-order nc%u%s",
497 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200498 if (!bts->gprs.ctrl_ack_type_use_block)
499 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200500 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
501 VTY_NEWLINE);
502 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
503 vty_out(vty, " gprs cell timer %s %u%s",
504 get_value_string(gprs_bssgp_cfg_strs, i),
505 bts->gprs.cell.timer[i], VTY_NEWLINE);
506 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
507 VTY_NEWLINE);
508 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
509 vty_out(vty, " gprs ns timer %s %u%s",
510 get_value_string(gprs_ns_timer_strs, i),
511 bts->gprs.nse.timer[i], VTY_NEWLINE);
512 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
513 struct gsm_bts_gprs_nsvc *nsvc =
514 &bts->gprs.nsvc[i];
515 struct in_addr ia;
516
517 ia.s_addr = htonl(nsvc->remote_ip);
518 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
519 nsvc->nsvci, VTY_NEWLINE);
520 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
521 nsvc->local_port, VTY_NEWLINE);
522 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
523 nsvc->remote_port, VTY_NEWLINE);
524 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
525 inet_ntoa(ia), VTY_NEWLINE);
526 }
527}
528
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200529/* Write the model data if there is one */
530static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200531{
532 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200533
534 if (!bts->model)
535 return;
536
537 if (bts->model->config_write_bts)
538 bts->model->config_write_bts(vty, bts);
539
540 llist_for_each_entry(trx, &bts->trx_list, list)
541 config_write_trx_single(vty, trx);
542}
543
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200544static void write_amr_modes(struct vty *vty, const char *prefix,
545 const char *name, struct amr_mode *modes, int num)
546{
547 int i;
548
549 vty_out(vty, " %s threshold %s", prefix, name);
550 for (i = 0; i < num - 1; i++)
551 vty_out(vty, " %d", modes[i].threshold);
552 vty_out(vty, "%s", VTY_NEWLINE);
553 vty_out(vty, " %s hysteresis %s", prefix, name);
554 for (i = 0; i < num - 1; i++)
555 vty_out(vty, " %d", modes[i].hysteresis);
556 vty_out(vty, "%s", VTY_NEWLINE);
557}
558
Andreas Eversberg73266522014-01-19 11:47:44 +0100559static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
560 struct amr_multirate_conf *mr, int full)
561{
562 struct gsm48_multi_rate_conf *mr_conf;
563 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
564 int i, num;
565
566 if (!(mr->gsm48_ie[1]))
567 return;
568
569 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
570
571 num = 0;
572 vty_out(vty, " %s modes", prefix);
573 for (i = 0; i < ((full) ? 8 : 6); i++) {
574 if ((mr->gsm48_ie[1] & (1 << i))) {
575 vty_out(vty, " %d", i);
576 num++;
577 }
578 }
579 vty_out(vty, "%s", VTY_NEWLINE);
580 if (num > 4)
581 num = 4;
582 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200583 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
584 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100585 }
586 vty_out(vty, " %s start-mode ", prefix);
587 if (mr_conf->icmi) {
588 num = 0;
589 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
590 if ((mr->gsm48_ie[1] & (1 << i)))
591 num++;
592 if (mr_conf->smod == num - 1) {
593 vty_out(vty, "%d%s", num, VTY_NEWLINE);
594 break;
595 }
596 }
597 } else
598 vty_out(vty, "auto%s", VTY_NEWLINE);
599}
600
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200601static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
602{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200603 int i;
Max2c16bee2017-02-15 13:51:37 +0100604 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200605
Harald Welte5013b2a2009-08-07 13:29:14 +0200606 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
607 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200608 if (bts->description)
609 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200610 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100611 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200612 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200613 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200614 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
615 vty_out(vty, " dtx uplink%s%s",
616 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
617 VTY_NEWLINE);
618 if (bts->dtxd)
619 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200620 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200621 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100622 vty_out(vty, " cell reselection hysteresis %u%s",
623 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
624 vty_out(vty, " rxlev access min %u%s",
625 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100626
627 if (bts->si_common.cell_ro_sel_par.present) {
628 struct gsm48_si_selection_params *sp;
629 sp = &bts->si_common.cell_ro_sel_par;
630
631 if (sp->cbq)
632 vty_out(vty, " cell bar qualify %u%s",
633 sp->cbq, VTY_NEWLINE);
634
635 if (sp->cell_resel_off)
636 vty_out(vty, " cell reselection offset %u%s",
637 sp->cell_resel_off*2, VTY_NEWLINE);
638
639 if (sp->temp_offs == 7)
640 vty_out(vty, " temporary offset infinite%s",
641 VTY_NEWLINE);
642 else if (sp->temp_offs)
643 vty_out(vty, " temporary offset %u%s",
644 sp->temp_offs*10, VTY_NEWLINE);
645
646 if (sp->penalty_time == 31)
647 vty_out(vty, " penalty time reserved%s",
648 VTY_NEWLINE);
649 else if (sp->penalty_time)
650 vty_out(vty, " penalty time %u%s",
651 (sp->penalty_time*20)+20, VTY_NEWLINE);
652 }
653
Harald Welte2f8b9d22017-06-18 11:12:13 +0300654 if (gsm_bts_get_radio_link_timeout(bts) < 0)
655 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
656 else
657 vty_out(vty, " radio-link-timeout %d%s",
658 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100659
Harald Welte7a8fa412009-08-10 13:48:16 +0200660 vty_out(vty, " channel allocator %s%s",
661 bts->chan_alloc_reverse ? "descending" : "ascending",
662 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100663 vty_out(vty, " rach tx integer %u%s",
664 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
665 vty_out(vty, " rach max transmission %u%s",
666 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
667 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800668
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200669 vty_out(vty, " channel-descrption attach %u%s",
670 bts->si_common.chan_desc.att, VTY_NEWLINE);
671 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
672 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
673 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
674 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
675
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800676 if (bts->rach_b_thresh != -1)
677 vty_out(vty, " rach nm busy threshold %u%s",
678 bts->rach_b_thresh, VTY_NEWLINE);
679 if (bts->rach_ldavg_slots != -1)
680 vty_out(vty, " rach nm load average %u%s",
681 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100682 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200683 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800684 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
685 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400686 if ((bts->si_common.rach_control.t3) != 0)
687 for (i = 0; i < 8; i++)
688 if (bts->si_common.rach_control.t3 & (0x1 << i))
689 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
690 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
691 for (i = 0; i < 8; i++)
692 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
693 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200694 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
695 if (bts->si_mode_static & (1 << i)) {
696 vty_out(vty, " system-information %s mode static%s",
697 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
698 vty_out(vty, " system-information %s static %s%s",
699 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200700 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200701 VTY_NEWLINE);
702 }
703 }
Harald Welte42def722017-01-13 00:10:32 +0100704 vty_out(vty, " early-classmark-sending %s%s",
705 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100706 vty_out(vty, " early-classmark-sending-3g %s%s",
707 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100708 switch (bts->type) {
709 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100710 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200711 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200712 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100713 if (bts->ip_access.rsl_ip) {
714 struct in_addr ia;
715 ia.s_addr = htonl(bts->ip_access.rsl_ip);
716 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
717 VTY_NEWLINE);
718 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200719 vty_out(vty, " oml ip.access stream_id %u line %u%s",
720 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100721 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200722 case GSM_BTS_TYPE_NOKIA_SITE:
723 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100724 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
725 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100726 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 +0100727 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100728 default:
Harald Welte42581822009-08-08 16:12:58 +0200729 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
730 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100731 break;
Harald Welte42581822009-08-08 16:12:58 +0200732 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800733
734 /* if we have a limit, write it */
735 if (bts->paging.free_chans_need >= 0)
736 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
737
Harald Welte32c09622011-01-11 23:44:56 +0100738 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100739 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
740 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100741 for (i = 0; i < 1024; i++) {
742 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
743 vty_out(vty, " neighbor-list add arfcn %u%s",
744 i, VTY_NEWLINE);
745 }
746 }
Harald Welte64c07d22011-02-15 11:43:27 +0100747 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
748 for (i = 0; i < 1024; i++) {
749 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
750 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
751 i, VTY_NEWLINE);
752 }
753 }
Harald Welte32c09622011-01-11 23:44:56 +0100754
Max59a1bf32016-04-15 16:04:46 +0200755 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100756 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
757 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
758 vty_out(vty, " si2quater neighbor-list add earfcn %u "
759 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
760
761 vty_out(vty, " thresh-lo %u",
762 e->thresh_lo_valid ? e->thresh_lo : 32);
763
764 vty_out(vty, " prio %u",
765 e->prio_valid ? e->prio : 8);
766
767 vty_out(vty, " qrxlv %u",
768 e->qrxlm_valid ? e->qrxlm : 32);
769
770 tmp = e->meas_bw[i];
771 vty_out(vty, " meas %u",
772 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200773
774 vty_out(vty, "%s", VTY_NEWLINE);
775 }
776 }
777
Max26679e02016-04-20 15:57:13 +0200778 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
779 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
780 bts->si_common.data.uarfcn_list[i],
781 bts->si_common.data.scramble_list[i] & ~(1 << 9),
782 (bts->si_common.data.scramble_list[i] >> 9) & 1,
783 VTY_NEWLINE);
784 }
785
Andreas Eversberga83d5112013-12-07 18:32:28 +0100786 vty_out(vty, " codec-support fr");
787 if (bts->codec.hr)
788 vty_out(vty, " hr");
789 if (bts->codec.efr)
790 vty_out(vty, " efr");
791 if (bts->codec.amr)
792 vty_out(vty, " amr");
793 vty_out(vty, "%s", VTY_NEWLINE);
794
Andreas Eversberg73266522014-01-19 11:47:44 +0100795 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
796 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
797
Harald Welte615e9562010-05-11 23:50:21 +0200798 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200799
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200800 if (bts->excl_from_rf_lock)
801 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
802
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100803 vty_out(vty, " %sforce-combined-si%s",
804 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
805
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100806 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
807 int j;
808
809 if (bts->depends_on[i] == 0)
810 continue;
811
812 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
813 int bts_nr;
814
815 if ((bts->depends_on[i] & (1<<j)) == 0)
816 continue;
817
818 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
819 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
820 }
821 }
Harald Welte8254cf72017-05-29 13:42:19 +0200822 if (bts->pcu_sock_path)
823 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100824
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100825 ho_vty_write(vty, " ", bts->ho);
826
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200827 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200828}
829
830static int config_write_bts(struct vty *v)
831{
Harald Weltedcccb182010-05-16 20:52:23 +0200832 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200833 struct gsm_bts *bts;
834
835 llist_for_each_entry(bts, &gsmnet->bts_list, list)
836 config_write_bts_single(v, bts);
837
838 return CMD_SUCCESS;
839}
840
Harald Weltea0d324b2017-07-20 01:47:39 +0200841/* small helper macro for conditional dumping of timer */
842#define VTY_OUT_TIMER(number) \
843 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
844 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
845
Harald Welte5013b2a2009-08-07 13:29:14 +0200846static int config_write_net(struct vty *vty)
847{
Harald Weltedcccb182010-05-16 20:52:23 +0200848 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
849
Harald Welte5013b2a2009-08-07 13:29:14 +0200850 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200851 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200852 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900853 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100854 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800855 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100856
857 ho_vty_write(vty, " ", gsmnet->ho);
858
Harald Weltea0d324b2017-07-20 01:47:39 +0200859 VTY_OUT_TIMER(3101);
860 VTY_OUT_TIMER(3103);
861 VTY_OUT_TIMER(3105);
862 VTY_OUT_TIMER(3107);
863 VTY_OUT_TIMER(3109);
864 VTY_OUT_TIMER(3111);
865 VTY_OUT_TIMER(3113);
866 VTY_OUT_TIMER(3115);
867 VTY_OUT_TIMER(3117);
868 VTY_OUT_TIMER(3119);
869 VTY_OUT_TIMER(3122);
870 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700871 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
872 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200873 if (gsmnet->tz.override != 0) {
874 if (gsmnet->tz.dst)
875 vty_out(vty, " timezone %d %d %d%s",
876 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
877 VTY_NEWLINE);
878 else
879 vty_out(vty, " timezone %d %d%s",
880 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
881 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200882 if (gsmnet->t3212 == 0)
883 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
884 else
885 vty_out(vty, " periodic location update %u%s",
886 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200887
888 return CMD_SUCCESS;
889}
Harald Welte67ce0732009-08-06 19:06:46 +0200890
Harald Welte68628e82009-03-10 12:17:57 +0000891static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
892{
893 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
894 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200895 vty_out(vty, "Description: %s%s",
896 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200897 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200898 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200899 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200900 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000901 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200902 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +0100903 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000904 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200905 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200906 if (is_ipaccess_bts(trx->bts)) {
907 vty_out(vty, " ip.access stream ID: 0x%02x%s",
908 trx->rsl_tei, VTY_NEWLINE);
909 } else {
910 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
911 e1isl_dump_vty(vty, trx->rsl_link);
912 }
Harald Welte68628e82009-03-10 12:17:57 +0000913}
914
Max6e4f1842018-01-07 16:45:42 +0100915static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
916{
917 uint8_t trx_nr;
918 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
919 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
920}
921
Harald Welte68628e82009-03-10 12:17:57 +0000922DEFUN(show_trx,
923 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100924 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200925 SHOW_STR "Display information about a TRX\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +0100926 BTS_TRX_STR)
Harald Welte68628e82009-03-10 12:17:57 +0000927{
Harald Weltedcccb182010-05-16 20:52:23 +0200928 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000929 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000930 int bts_nr, trx_nr;
931
932 if (argc >= 1) {
933 /* use the BTS number that the user has specified */
934 bts_nr = atoi(argv[0]);
935 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000936 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000937 VTY_NEWLINE);
938 return CMD_WARNING;
939 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200940 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000941 }
942 if (argc >= 2) {
943 trx_nr = atoi(argv[1]);
944 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000945 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000946 VTY_NEWLINE);
947 return CMD_WARNING;
948 }
Max6e4f1842018-01-07 16:45:42 +0100949 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000950 return CMD_SUCCESS;
951 }
952 if (bts) {
953 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +0100954 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +0000955 return CMD_SUCCESS;
956 }
957
Max6e4f1842018-01-07 16:45:42 +0100958 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
959 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000960
961 return CMD_SUCCESS;
962}
963
Harald Welte67ce0732009-08-06 19:06:46 +0200964
Harald Welte68628e82009-03-10 12:17:57 +0000965static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
966{
Harald Welte135a6482011-05-30 12:09:13 +0200967 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +0100968 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +0100969 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +0100970 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +0100971 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200972 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +0100973 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000974 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200975 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530976 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000977 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
978 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
979 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000980}
981
982DEFUN(show_ts,
983 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100984 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200985 SHOW_STR "Display information about a TS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +0100986 BTS_TRX_TS_STR)
Harald Welte68628e82009-03-10 12:17:57 +0000987{
Harald Weltedcccb182010-05-16 20:52:23 +0200988 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +0100989 struct gsm_bts *bts = NULL;
990 struct gsm_bts_trx *trx = NULL;
991 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000992 int bts_nr, trx_nr, ts_nr;
993
994 if (argc >= 1) {
995 /* use the BTS number that the user has specified */
996 bts_nr = atoi(argv[0]);
997 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000998 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000999 VTY_NEWLINE);
1000 return CMD_WARNING;
1001 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001002 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001003 }
1004 if (argc >= 2) {
1005 trx_nr = atoi(argv[1]);
1006 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001007 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001008 VTY_NEWLINE);
1009 return CMD_WARNING;
1010 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001011 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001012 }
1013 if (argc >= 3) {
1014 ts_nr = atoi(argv[2]);
1015 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +00001016 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +00001017 VTY_NEWLINE);
1018 return CMD_WARNING;
1019 }
Harald Welte274d0152010-12-24 12:05:03 +01001020 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +00001021 ts = &trx->ts[ts_nr];
1022 ts_dump_vty(vty, ts);
1023 return CMD_SUCCESS;
1024 }
Harald Welte274d0152010-12-24 12:05:03 +01001025
1026 if (bts && trx) {
1027 /* Iterate over all TS in this TRX */
1028 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1029 ts = &trx->ts[ts_nr];
1030 ts_dump_vty(vty, ts);
1031 }
1032 } else if (bts) {
1033 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001034 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001035 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001036 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1037 ts = &trx->ts[ts_nr];
1038 ts_dump_vty(vty, ts);
1039 }
1040 }
Harald Welte274d0152010-12-24 12:05:03 +01001041 } else {
1042 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1043 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1044 bts = gsm_bts_num(net, bts_nr);
1045 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1046 trx = gsm_bts_trx_num(bts, trx_nr);
1047 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1048 ts = &trx->ts[ts_nr];
1049 ts_dump_vty(vty, ts);
1050 }
1051 }
1052 }
Harald Welte68628e82009-03-10 12:17:57 +00001053 }
1054
1055 return CMD_SUCCESS;
1056}
1057
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001058static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1059{
1060 if (strlen(bsub->imsi))
1061 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1062 if (bsub->tmsi != GSM_RESERVED_TMSI)
1063 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1064 VTY_NEWLINE);
1065 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1066}
1067
Harald Welte8387a492009-12-22 21:43:14 +01001068static void meas_rep_dump_uni_vty(struct vty *vty,
1069 struct gsm_meas_rep_unidir *mru,
1070 const char *prefix,
1071 const char *dir)
1072{
1073 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1074 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1075 dir, rxlev2dbm(mru->sub.rx_lev));
1076 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1077 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1078 VTY_NEWLINE);
1079}
1080
1081static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1082 const char *prefix)
1083{
1084 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1085 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1086 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1087 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1088 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1089 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1090 VTY_NEWLINE);
1091 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001092 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001093 if (mr->flags & MEAS_REP_F_MS_L1)
1094 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1095 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1096 if (mr->flags & MEAS_REP_F_DL_VALID)
1097 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1098 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1099}
1100
Harald Welte0a8cf322015-12-05 17:22:49 +01001101/* FIXME: move this to libosmogsm */
1102static const struct value_string gsm48_cmode_names[] = {
1103 { GSM48_CMODE_SIGN, "signalling" },
1104 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1105 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1106 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1107 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1108 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1109 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1110 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1111 { 0, NULL }
1112};
1113
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001114/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1115 * Don't do anything if the ts is not dynamic. */
1116static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1117{
1118 switch (ts->pchan) {
1119 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1120 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1121 vty_out(vty, " as %s",
1122 gsm_pchan_name(ts->dyn.pchan_is));
1123 else
1124 vty_out(vty, " switching %s -> %s",
1125 gsm_pchan_name(ts->dyn.pchan_is),
1126 gsm_pchan_name(ts->dyn.pchan_want));
1127 break;
1128 case GSM_PCHAN_TCH_F_PDCH:
1129 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1130 vty_out(vty, " as %s",
1131 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1132 : "TCH/F");
1133 else
1134 vty_out(vty, " switching %s -> %s",
1135 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1136 : "TCH/F",
1137 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1138 : "TCH/F");
1139 break;
1140 default:
1141 /* no dyn ts */
1142 break;
1143 }
1144}
1145
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001146static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001147{
Harald Welte8387a492009-12-22 21:43:14 +01001148 int idx;
1149
Harald Welte85bded82010-12-24 12:22:34 +01001150 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1151 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1152 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001153 /* show dyn TS details, if applicable */
1154 switch (lchan->ts->pchan) {
1155 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1156 vty_out(vty, " Osmocom Dyn TS:");
1157 vty_out_dyn_ts_status(vty, lchan->ts);
1158 vty_out(vty, VTY_NEWLINE);
1159 break;
1160 case GSM_PCHAN_TCH_F_PDCH:
1161 vty_out(vty, " IPACC Dyn PDCH TS:");
1162 vty_out_dyn_ts_status(vty, lchan->ts);
1163 vty_out(vty, VTY_NEWLINE);
1164 break;
1165 default:
1166 /* no dyn ts */
1167 break;
1168 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001169 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001170 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001171 gsm_lchans_name(lchan->state),
1172 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1173 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1174 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001175 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1176 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1177 - lchan->bs_power*2,
1178 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1179 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001180 vty_out(vty, " Channel Mode / Codec: %s%s",
1181 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1182 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001183 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001184 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001185 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001186 } else
1187 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301188 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1189 struct in_addr ia;
Harald Welte5f45a4a2018-02-05 21:33:34 +01001190 if (lchan->abis_ip.bound_ip) {
1191 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
1192 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1193 inet_ntoa(ia), lchan->abis_ip.bound_port,
1194 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1195 VTY_NEWLINE);
1196 }
1197 if (lchan->abis_ip.connect_ip) {
1198 ia.s_addr = htonl(lchan->abis_ip.connect_ip);
1199 vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02x%s",
1200 inet_ntoa(ia), lchan->abis_ip.connect_port,
1201 lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode,
1202 VTY_NEWLINE);
1203 }
1204
Harald Welte2c828992009-12-02 01:56:49 +05301205 }
Harald Welte8387a492009-12-22 21:43:14 +01001206
1207 /* we want to report the last measurement report */
1208 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1209 lchan->meas_rep_idx, 1);
1210 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001211}
1212
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001213static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1214{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001215 struct gsm_meas_rep *mr;
1216 int idx;
1217
1218 /* we want to report the last measurement report */
1219 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1220 lchan->meas_rep_idx, 1);
1221 mr = &lchan->meas_rep[idx];
1222
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001223 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001224 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001225 gsm_pchan_name(lchan->ts->pchan));
1226 vty_out_dyn_ts_status(vty, lchan->ts);
1227 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1228 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001229 lchan->nr,
1230 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1231 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001232 rxlev2dbm(mr->dl.full.rx_lev),
1233 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001234 VTY_NEWLINE);
1235}
1236
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001237
1238static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1239 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1240{
1241 int lchan_nr;
1242 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1243 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1244 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1245 continue;
1246 dump_cb(vty, lchan);
1247 }
1248
1249 return CMD_SUCCESS;
1250}
1251
1252static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1253 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1254{
1255 int ts_nr;
1256
1257 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1258 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1259 dump_lchan_trx_ts(ts, vty, dump_cb);
1260 }
1261
1262 return CMD_SUCCESS;
1263}
1264
1265static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1266 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1267{
1268 int trx_nr;
1269
1270 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1271 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1272 dump_lchan_trx(trx, vty, dump_cb);
1273 }
1274
1275 return CMD_SUCCESS;
1276}
1277
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001278static int lchan_summary(struct vty *vty, int argc, const char **argv,
1279 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001280{
Harald Weltedcccb182010-05-16 20:52:23 +02001281 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001282 struct gsm_bts *bts;
1283 struct gsm_bts_trx *trx;
1284 struct gsm_bts_trx_ts *ts;
1285 struct gsm_lchan *lchan;
1286 int bts_nr, trx_nr, ts_nr, lchan_nr;
1287
1288 if (argc >= 1) {
1289 /* use the BTS number that the user has specified */
1290 bts_nr = atoi(argv[0]);
1291 if (bts_nr >= net->num_bts) {
1292 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1293 VTY_NEWLINE);
1294 return CMD_WARNING;
1295 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001296 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001297
1298 if (argc == 1)
1299 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001300 }
1301 if (argc >= 2) {
1302 trx_nr = atoi(argv[1]);
1303 if (trx_nr >= bts->num_trx) {
1304 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1305 VTY_NEWLINE);
1306 return CMD_WARNING;
1307 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001308 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001309
1310 if (argc == 2)
1311 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001312 }
1313 if (argc >= 3) {
1314 ts_nr = atoi(argv[2]);
1315 if (ts_nr >= TRX_NR_TS) {
1316 vty_out(vty, "%% can't find TS %s%s", argv[2],
1317 VTY_NEWLINE);
1318 return CMD_WARNING;
1319 }
1320 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001321
1322 if (argc == 3)
1323 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001324 }
1325 if (argc >= 4) {
1326 lchan_nr = atoi(argv[3]);
1327 if (lchan_nr >= TS_MAX_LCHAN) {
1328 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1329 VTY_NEWLINE);
1330 return CMD_WARNING;
1331 }
1332 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001333 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001334 return CMD_SUCCESS;
1335 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001336
1337
Harald Welte68628e82009-03-10 12:17:57 +00001338 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001339 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001340 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001341 }
1342
1343 return CMD_SUCCESS;
1344}
1345
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001346
1347DEFUN(show_lchan,
1348 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001349 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001350 SHOW_STR "Display information about a logical channel\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001351 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001352{
1353 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1354}
1355
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001356DEFUN(show_lchan_summary,
1357 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001358 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001359 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001360 "Short summary\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001361 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001362{
1363 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1364}
1365
Philipp Maier39f62bb2017-04-09 12:32:51 +02001366DEFUN(show_subscr_conn,
1367 show_subscr_conn_cmd,
1368 "show conns",
1369 SHOW_STR "Display currently active subscriber connections\n")
1370{
1371 struct gsm_subscriber_connection *conn;
1372 struct gsm_network *net = gsmnet_from_vty(vty);
1373 bool no_conns = true;
1374 unsigned int count = 0;
1375
1376 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1377
1378 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1379 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1380 lchan_dump_full_vty(vty, conn->lchan);
1381 no_conns = false;
1382 count++;
1383 }
1384
1385 if (no_conns)
1386 vty_out(vty, "None%s", VTY_NEWLINE);
1387
1388 return CMD_SUCCESS;
1389}
1390
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001391static int trigger_ho_or_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_bts *to_bts)
1392{
1393 int rc;
1394
1395 if (!to_bts || from_lchan->ts->trx->bts == to_bts) {
1396 LOGP(DHO, LOGL_NOTICE, "%s Manually triggering Assignment from VTY\n",
1397 gsm_lchan_name(from_lchan));
1398 to_bts = from_lchan->ts->trx->bts;
1399 } else
1400 LOGP(DHO, LOGL_NOTICE, "%s (ARFCN %u) --> BTS %u Manually triggering Handover from VTY\n",
1401 gsm_lchan_name(from_lchan), from_lchan->ts->trx->arfcn, to_bts->nr);
1402 rc = bsc_handover_start(from_lchan, to_bts);
1403 if (rc) {
1404 vty_out(vty, "bsc_handover_start() returned %d=%s%s", rc,
1405 strerror(-rc), VTY_NEWLINE);
1406 return CMD_WARNING;
1407 }
1408 return CMD_SUCCESS;
1409}
1410
1411static int ho_or_as(struct vty *vty, const char *argv[], int argc)
Philipp Maier39f62bb2017-04-09 12:32:51 +02001412{
1413 struct gsm_network *net = gsmnet_from_vty(vty);
1414 struct gsm_subscriber_connection *conn;
1415 struct gsm_bts *bts;
1416 struct gsm_bts *new_bts = NULL;
1417 unsigned int bts_nr = atoi(argv[0]);
1418 unsigned int trx_nr = atoi(argv[1]);
1419 unsigned int ts_nr = atoi(argv[2]);
1420 unsigned int ss_nr = atoi(argv[3]);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001421 unsigned int bts_nr_new;
1422 const char *action;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001423
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001424 if (argc > 4) {
1425 bts_nr_new = atoi(argv[4]);
1426
1427 /* Lookup the BTS where we want to handover to */
1428 llist_for_each_entry(bts, &net->bts_list, list) {
1429 if (bts->nr == bts_nr_new) {
1430 new_bts = bts;
1431 break;
1432 }
1433 }
1434
1435 if (!new_bts) {
1436 vty_out(vty, "Unable to trigger handover, specified bts #%u does not exist %s",
1437 bts_nr_new, VTY_NEWLINE);
1438 return CMD_WARNING;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001439 }
1440 }
1441
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001442 action = new_bts ? "handover" : "assignment";
Philipp Maier39f62bb2017-04-09 12:32:51 +02001443
1444 /* Find the connection/lchan that we want to handover */
1445 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001446 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001447 conn->lchan->ts->trx->nr == trx_nr &&
1448 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001449 vty_out(vty, "starting %s for lchan %s...%s", action, conn->lchan->name, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001450 lchan_dump_full_vty(vty, conn->lchan);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001451 return trigger_ho_or_as(vty, conn->lchan, new_bts);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001452 }
1453 }
1454
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001455 vty_out(vty, "Unable to trigger %s, specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1456 action, bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001457
1458 return CMD_WARNING;
1459}
1460
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001461#define MANUAL_HANDOVER_STR "Manually trigger handover (for debugging)\n"
1462#define MANUAL_ASSIGNMENT_STR "Manually trigger assignment (for debugging)\n"
1463
1464DEFUN(handover_subscr_conn,
1465 handover_subscr_conn_cmd,
1466 "handover <0-255> <0-255> <0-7> <0-7> <0-255>",
1467 MANUAL_HANDOVER_STR
1468 "Current " BTS_TRX_TS_LCHAN_STR
1469 "New " BTS_NR_STR)
1470{
1471 return ho_or_as(vty, argv, argc);
1472}
1473
1474DEFUN(assignment_subscr_conn,
1475 assignment_subscr_conn_cmd,
1476 "assignment <0-255> <0-255> <0-7> <0-7>",
1477 MANUAL_ASSIGNMENT_STR
1478 "Current " BTS_TRX_TS_LCHAN_STR)
1479{
1480 return ho_or_as(vty, argv, argc);
1481}
1482
1483static struct gsm_lchan *find_used_voice_lchan(struct vty *vty)
1484{
1485 struct gsm_bts *bts;
1486 struct gsm_network *network = gsmnet_from_vty(vty);
1487
1488 llist_for_each_entry(bts, &network->bts_list, list) {
1489 struct gsm_bts_trx *trx;
1490
1491 llist_for_each_entry(trx, &bts->trx_list, list) {
1492 int i;
1493 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1494 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1495 int j;
1496 int subslots;
1497
1498 /* skip administratively deactivated timeslots */
1499 if (!nm_is_running(&ts->mo.nm_state))
1500 continue;
1501
1502 subslots = ts_subslots(ts);
1503 for (j = 0; j < subslots; j++) {
1504 struct gsm_lchan *lchan = &ts->lchan[j];
1505
1506 if (lchan->state == LCHAN_S_ACTIVE
1507 && (lchan->type == GSM_LCHAN_TCH_F
1508 || lchan->type == GSM_LCHAN_TCH_H)) {
1509
1510 vty_out(vty, "Found voice call: %s%s",
1511 gsm_lchan_name(lchan), VTY_NEWLINE);
1512 lchan_dump_full_vty(vty, lchan);
1513 return lchan;
1514 }
1515 }
1516 }
1517 }
1518 }
1519
1520 vty_out(vty, "Cannot find any ongoing voice calls%s", VTY_NEWLINE);
1521 return NULL;
1522}
1523
1524static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gsm_bts *not_this_bts,
1525 enum gsm_phys_chan_config free_type)
1526{
1527 struct gsm_bts *bts;
1528 struct gsm_network *network = gsmnet_from_vty(vty);
1529
1530 llist_for_each_entry(bts, &network->bts_list, list) {
1531 struct gsm_bts_trx *trx;
1532
1533 if (bts == not_this_bts)
1534 continue;
1535
1536 llist_for_each_entry(trx, &bts->trx_list, list) {
1537 int i;
1538 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1539 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1540 int j;
1541 int subslots;
1542
1543 /* skip administratively deactivated timeslots */
1544 if (!nm_is_running(&ts->mo.nm_state))
1545 continue;
1546
1547 if (ts->pchan != free_type)
1548 continue;
1549
1550 subslots = ts_subslots(ts);
1551 for (j = 0; j < subslots; j++) {
1552 struct gsm_lchan *lchan = &ts->lchan[j];
1553
1554 if (lchan->state == LCHAN_S_NONE) {
1555 vty_out(vty, "Found unused %s slot: %s%s",
1556 gsm_pchan_name(free_type),
1557 gsm_lchan_name(lchan),
1558 VTY_NEWLINE);
1559 lchan_dump_full_vty(vty, lchan);
1560 return bts;
1561 }
1562 }
1563 }
1564 }
1565 }
1566 vty_out(vty, "Cannot find any BTS (other than BTS %u) with free %s lchan%s",
1567 not_this_bts? not_this_bts->nr : 255, gsm_lchant_name(free_type), VTY_NEWLINE);
1568 return NULL;
1569}
1570
1571DEFUN(handover_any, handover_any_cmd,
1572 "handover any",
1573 MANUAL_HANDOVER_STR
1574 "Pick any actively used TCH/F or TCH/H lchan and handover to any other BTS."
1575 " This is likely to fail if not all BTS are guaranteed to be reachable by the MS.\n")
1576{
1577 struct gsm_lchan *from_lchan;
1578 struct gsm_bts *to_bts;
1579
1580 from_lchan = find_used_voice_lchan(vty);
1581 if (!from_lchan)
1582 return CMD_WARNING;
1583
1584 to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts,
1585 ts_pchan(from_lchan->ts));
1586 if (!to_bts)
1587 return CMD_WARNING;
1588
1589 return trigger_ho_or_as(vty, from_lchan, to_bts);
1590}
1591
1592DEFUN(assignment_any, assignment_any_cmd,
1593 "assignment any",
1594 MANUAL_ASSIGNMENT_STR
1595 "Pick any actively used TCH/F or TCH/H lchan and re-assign within the same BTS."
1596 " This will fail if no lchans of the same type are available besides the used one.\n")
1597{
1598 struct gsm_lchan *from_lchan;
1599
1600 from_lchan = find_used_voice_lchan(vty);
1601 if (!from_lchan)
1602 return CMD_WARNING;
1603
1604 return trigger_ho_or_as(vty, from_lchan, NULL);
1605}
1606
Harald Weltebe4b7302009-05-23 16:59:33 +00001607static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001608{
1609 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001610 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001611}
1612
Harald Weltebe4b7302009-05-23 16:59:33 +00001613static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001614{
1615 struct gsm_paging_request *pag;
1616
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001617 if (!bts->paging.bts)
1618 return;
1619
Harald Weltef5025b62009-03-28 16:55:11 +00001620 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1621 paging_dump_vty(vty, pag);
1622}
1623
1624DEFUN(show_paging,
1625 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001626 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001627 SHOW_STR "Display information about paging reuqests of a BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001628 BTS_NR_STR)
Harald Weltef5025b62009-03-28 16:55:11 +00001629{
Harald Weltedcccb182010-05-16 20:52:23 +02001630 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001631 struct gsm_bts *bts;
1632 int bts_nr;
1633
1634 if (argc >= 1) {
1635 /* use the BTS number that the user has specified */
1636 bts_nr = atoi(argv[0]);
1637 if (bts_nr >= net->num_bts) {
1638 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1639 VTY_NEWLINE);
1640 return CMD_WARNING;
1641 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001642 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001643 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001644
Harald Weltef5025b62009-03-28 16:55:11 +00001645 return CMD_SUCCESS;
1646 }
1647 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001648 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001649 bts_paging_dump_vty(vty, bts);
1650 }
1651
1652 return CMD_SUCCESS;
1653}
1654
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001655DEFUN(show_paging_group,
1656 show_paging_group_cmd,
1657 "show paging-group <0-255> IMSI",
1658 SHOW_STR "Display the paging group\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001659 BTS_NR_STR "IMSI\n")
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001660{
1661 struct gsm_network *net = gsmnet_from_vty(vty);
1662 struct gsm_bts *bts;
1663 unsigned int page_group;
1664 int bts_nr = atoi(argv[0]);
1665
1666 if (bts_nr >= net->num_bts) {
1667 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1668 return CMD_WARNING;
1669 }
1670
1671 bts = gsm_bts_num(net, bts_nr);
1672 if (!bts) {
1673 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1674 return CMD_WARNING;
1675 }
1676
1677 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1678 str_to_imsi(argv[1]));
1679 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1680 str_to_imsi(argv[1]), bts->nr,
1681 page_group, VTY_NEWLINE);
1682 return CMD_SUCCESS;
1683}
1684
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001685DEFUN(cfg_net_neci,
1686 cfg_net_neci_cmd,
1687 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001688 "New Establish Cause Indication\n"
1689 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001690{
Harald Weltedcccb182010-05-16 20:52:23 +02001691 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1692
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001693 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001694 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001695 return CMD_SUCCESS;
1696}
1697
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001698DEFUN(cfg_net_pag_any_tch,
1699 cfg_net_pag_any_tch_cmd,
1700 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001701 "Assign a TCH when receiving a Paging Any request\n"
1702 "Any Channel\n" "Use\n" "TCH\n"
1703 "Do not use TCH for Paging Request Any\n"
1704 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001705{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001706 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001707 gsmnet->pag_any_tch = atoi(argv[0]);
1708 gsm_net_update_ctype(gsmnet);
1709 return CMD_SUCCESS;
1710}
1711
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001712#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1713/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1714#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1715
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001716#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001717 DEFUN(cfg_net_T##number, \
1718 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001719 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001720 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001721 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001722 "Set to default timer value" \
1723 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1724 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001725{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001726 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001727 int value; \
1728 if (strcmp(argv[0], "default") == 0) \
1729 value = DEFAULT_TIMER(number); \
1730 else \
1731 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001732 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001733 gsmnet->T##number = value; \
1734 return CMD_SUCCESS; \
1735}
1736
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001737DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1738DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1739DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1740DECLARE_TIMER(3107, "Currently not used")
1741DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1742DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1743DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1744DECLARE_TIMER(3115, "Currently not used")
1745DECLARE_TIMER(3117, "Currently not used")
1746DECLARE_TIMER(3119, "Currently not used")
Stefan Sperling6cee8932018-01-30 18:14:22 +01001747DECLARE_TIMER(3122, "Default waiting time (seconds) after IMM ASS REJECT")
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001748DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001749
Maxc08ee712016-05-11 12:45:13 +02001750DEFUN_DEPRECATED(cfg_net_dtx,
1751 cfg_net_dtx_cmd,
1752 "dtx-used (0|1)",
1753 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001754{
Maxc08ee712016-05-11 12:45:13 +02001755 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1756 "configuration options of BTS instead%s", VTY_NEWLINE);
1757 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001758}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001759
Harald Welte5258fc42009-03-28 19:07:53 +00001760/* per-BTS configuration */
1761DEFUN(cfg_bts,
1762 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001763 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001764 "Select a BTS to configure\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001765 BTS_NR_STR)
Harald Welte5258fc42009-03-28 19:07:53 +00001766{
Harald Weltedcccb182010-05-16 20:52:23 +02001767 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001768 int bts_nr = atoi(argv[0]);
1769 struct gsm_bts *bts;
1770
Harald Weltee441d9c2009-06-21 16:17:15 +02001771 if (bts_nr > gsmnet->num_bts) {
1772 vty_out(vty, "%% The next unused BTS number is %u%s",
1773 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001774 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001775 } else if (bts_nr == gsmnet->num_bts) {
1776 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001777 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001778 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001779 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001780 bts = gsm_bts_num(gsmnet, bts_nr);
1781
Daniel Willmannf15c2762010-01-11 13:43:07 +01001782 if (!bts) {
1783 vty_out(vty, "%% Unable to allocate BTS %u%s",
1784 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001785 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001786 }
Harald Welte5258fc42009-03-28 19:07:53 +00001787
1788 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001789 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001790 vty->node = BTS_NODE;
1791
1792 return CMD_SUCCESS;
1793}
1794
1795DEFUN(cfg_bts_type,
1796 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001797 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001798 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001799{
1800 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001801 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001802
Max7507aef2017-04-10 13:59:14 +02001803 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001804 if (rc < 0)
1805 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001806
Harald Welte5258fc42009-03-28 19:07:53 +00001807 return CMD_SUCCESS;
1808}
1809
Harald Weltefcd24452009-06-20 18:15:19 +02001810DEFUN(cfg_bts_band,
1811 cfg_bts_band_cmd,
1812 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001813 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001814{
1815 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001816 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001817
1818 if (band < 0) {
1819 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1820 band, VTY_NEWLINE);
1821 return CMD_WARNING;
1822 }
1823
1824 bts->band = band;
1825
1826 return CMD_SUCCESS;
1827}
1828
Maxc08ee712016-05-11 12:45:13 +02001829DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1830 "Configure discontinuous transmission\n"
1831 "Enable Uplink DTX for this BTS\n"
1832 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1833 "older phones).\n")
1834{
1835 struct gsm_bts *bts = vty->index;
1836
1837 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001838 if (!is_ipaccess_bts(bts))
1839 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1840 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001841 return CMD_SUCCESS;
1842}
1843
1844DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1845 NO_STR
1846 "Configure discontinuous transmission\n"
1847 "Disable Uplink DTX for this BTS\n")
1848{
1849 struct gsm_bts *bts = vty->index;
1850
1851 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1852
1853 return CMD_SUCCESS;
1854}
1855
1856DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1857 "Configure discontinuous transmission\n"
1858 "Enable Downlink DTX for this BTS\n")
1859{
1860 struct gsm_bts *bts = vty->index;
1861
1862 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001863 if (!is_ipaccess_bts(bts))
1864 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1865 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001866 return CMD_SUCCESS;
1867}
1868
1869DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1870 NO_STR
1871 "Configure discontinuous transmission\n"
1872 "Disable Downlink DTX for this BTS\n")
1873{
1874 struct gsm_bts *bts = vty->index;
1875
1876 bts->dtxd = false;
1877
1878 return CMD_SUCCESS;
1879}
1880
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001881DEFUN(cfg_bts_ci,
1882 cfg_bts_ci_cmd,
1883 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001884 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001885{
1886 struct gsm_bts *bts = vty->index;
1887 int ci = atoi(argv[0]);
1888
1889 if (ci < 0 || ci > 0xffff) {
1890 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1891 ci, VTY_NEWLINE);
1892 return CMD_WARNING;
1893 }
1894 bts->cell_identity = ci;
1895
1896 return CMD_SUCCESS;
1897}
1898
Harald Welte5258fc42009-03-28 19:07:53 +00001899DEFUN(cfg_bts_lac,
1900 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001901 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001902 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001903{
1904 struct gsm_bts *bts = vty->index;
1905 int lac = atoi(argv[0]);
1906
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001907 if (lac < 0 || lac > 0xffff) {
1908 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001909 lac, VTY_NEWLINE);
1910 return CMD_WARNING;
1911 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001912
1913 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1914 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1915 lac, VTY_NEWLINE);
1916 return CMD_WARNING;
1917 }
1918
Harald Welte5258fc42009-03-28 19:07:53 +00001919 bts->location_area_code = lac;
1920
1921 return CMD_SUCCESS;
1922}
1923
Harald Weltea43f7892009-12-01 18:04:30 +05301924
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001925/* compatibility wrapper for old config files */
1926DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001927 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001928 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001929 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001930{
Harald Welte5258fc42009-03-28 19:07:53 +00001931 return CMD_SUCCESS;
1932}
1933
Harald Welte78f2f502009-05-23 16:56:52 +00001934DEFUN(cfg_bts_bsic,
1935 cfg_bts_bsic_cmd,
1936 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001937 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1938 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001939{
1940 struct gsm_bts *bts = vty->index;
1941 int bsic = atoi(argv[0]);
1942
1943 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001944 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001945 bsic, VTY_NEWLINE);
1946 return CMD_WARNING;
1947 }
1948 bts->bsic = bsic;
1949
1950 return CMD_SUCCESS;
1951}
1952
Harald Welte4cc34222009-05-01 15:12:31 +00001953DEFUN(cfg_bts_unit_id,
1954 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001955 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001956 "Abis/IP specific options\n"
1957 "Set the IPA BTS Unit ID\n"
1958 "Unit ID (Site)\n"
1959 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001960{
1961 struct gsm_bts *bts = vty->index;
1962 int site_id = atoi(argv[0]);
1963 int bts_id = atoi(argv[1]);
1964
Harald Welte07dc73d2009-08-07 13:27:09 +02001965 if (!is_ipaccess_bts(bts)) {
1966 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1967 return CMD_WARNING;
1968 }
1969
Harald Welte4cc34222009-05-01 15:12:31 +00001970 bts->ip_access.site_id = site_id;
1971 bts->ip_access.bts_id = bts_id;
1972
1973 return CMD_SUCCESS;
1974}
1975
Harald Welte8b291802013-03-12 13:57:05 +01001976DEFUN(cfg_bts_rsl_ip,
1977 cfg_bts_rsl_ip_cmd,
1978 "ip.access rsl-ip A.B.C.D",
1979 "Abis/IP specific options\n"
1980 "Set the IPA RSL IP Address of the BSC\n"
1981 "Destination IP address for RSL connection\n")
1982{
1983 struct gsm_bts *bts = vty->index;
1984 struct in_addr ia;
1985
1986 if (!is_ipaccess_bts(bts)) {
1987 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1988 return CMD_WARNING;
1989 }
1990
1991 inet_aton(argv[0], &ia);
1992 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1993
1994 return CMD_SUCCESS;
1995}
1996
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001997#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001998
Sylvain Munautc9519462011-10-17 14:04:55 +02001999DEFUN(cfg_bts_nokia_site_skip_reset,
2000 cfg_bts_nokia_site_skip_reset_cmd,
2001 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002002 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002003 "Skip the reset step during bootstrap process of this BTS\n"
2004 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02002005{
2006 struct gsm_bts *bts = vty->index;
2007
2008 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
2009 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
2010 return CMD_WARNING;
2011 }
2012
2013 bts->nokia.skip_reset = atoi(argv[0]);
2014
2015 return CMD_SUCCESS;
2016}
2017
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002018DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
2019 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
2020 "nokia_site no-local-rel-conf (0|1)",
2021 NOKIA_STR
2022 "Do not wait for RELease CONFirm message when releasing channel locally\n"
2023 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
2024{
2025 struct gsm_bts *bts = vty->index;
2026
2027 if (!is_nokia_bts(bts)) {
2028 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2029 VTY_NEWLINE);
2030 return CMD_WARNING;
2031 }
2032
2033 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
2034
2035 return CMD_SUCCESS;
2036}
2037
Sipos Csaba56e17662015-02-07 13:27:36 +01002038DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
2039 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
2040 "nokia_site bts-reset-timer <15-100>",
2041 NOKIA_STR
2042 "The amount of time (in sec.) between BTS_RESET is sent,\n"
2043 "and the BTS is being bootstrapped.\n")
2044{
2045 struct gsm_bts *bts = vty->index;
2046
2047 if (!is_nokia_bts(bts)) {
2048 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2049 VTY_NEWLINE);
2050 return CMD_WARNING;
2051 }
2052
2053 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
2054
2055 return CMD_SUCCESS;
2056}
Harald Welte8f0ed552010-05-11 21:53:49 +02002057#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002058#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02002059
Harald Welte8175e952009-10-20 00:22:00 +02002060DEFUN(cfg_bts_stream_id,
2061 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002062 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02002063 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002064 "Set the ip.access Stream ID of the OML link of this BTS\n"
2065 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02002066{
2067 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002068 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02002069
2070 if (!is_ipaccess_bts(bts)) {
2071 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2072 return CMD_WARNING;
2073 }
2074
2075 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002076 /* This is used by e1inp_bind_ops callback for each BTS model. */
2077 bts->oml_e1_link.e1_nr = linenr;
2078
2079 return CMD_SUCCESS;
2080}
2081
Harald Welted13e0cd2012-08-17 09:52:03 +02002082#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02002083
Harald Welte42581822009-08-08 16:12:58 +02002084DEFUN(cfg_bts_oml_e1,
2085 cfg_bts_oml_e1_cmd,
2086 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02002087 OML_E1_STR
2088 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002089 "E1/T1 line number to be used for OML\n"
2090 "E1/T1 timeslot to be used for OML\n"
2091 "E1/T1 timeslot to be used for OML\n"
2092 "E1/T1 sub-slot to be used for OML\n"
2093 "Use E1/T1 sub-slot 0\n"
2094 "Use E1/T1 sub-slot 1\n"
2095 "Use E1/T1 sub-slot 2\n"
2096 "Use E1/T1 sub-slot 3\n"
2097 "Use full E1 slot 3\n"
2098 )
Harald Welte42581822009-08-08 16:12:58 +02002099{
2100 struct gsm_bts *bts = vty->index;
2101
2102 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2103
2104 return CMD_SUCCESS;
2105}
2106
2107
2108DEFUN(cfg_bts_oml_e1_tei,
2109 cfg_bts_oml_e1_tei_cmd,
2110 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002111 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002112 "Set the TEI to be used for OML\n"
2113 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002114{
2115 struct gsm_bts *bts = vty->index;
2116
2117 bts->oml_tei = atoi(argv[0]);
2118
2119 return CMD_SUCCESS;
2120}
2121
Harald Welte7a8fa412009-08-10 13:48:16 +02002122DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2123 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002124 "Channnel Allocator\n" "Channel Allocator\n"
2125 "Allocate Timeslots and Transceivers in ascending order\n"
2126 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002127{
2128 struct gsm_bts *bts = vty->index;
2129
2130 if (!strcmp(argv[0], "ascending"))
2131 bts->chan_alloc_reverse = 0;
2132 else
2133 bts->chan_alloc_reverse = 1;
2134
2135 return CMD_SUCCESS;
2136}
2137
Harald Welte8f0ed552010-05-11 21:53:49 +02002138#define RACH_STR "Random Access Control Channel\n"
2139
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002140DEFUN(cfg_bts_rach_tx_integer,
2141 cfg_bts_rach_tx_integer_cmd,
2142 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002143 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002144 "Set the raw tx integer value in RACH Control parameters IE\n"
2145 "Set the raw tx integer value in RACH Control parameters IE\n"
2146 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002147{
2148 struct gsm_bts *bts = vty->index;
2149 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2150 return CMD_SUCCESS;
2151}
2152
2153DEFUN(cfg_bts_rach_max_trans,
2154 cfg_bts_rach_max_trans_cmd,
2155 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002156 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002157 "Set the maximum number of RACH burst transmissions\n"
2158 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002159 "Maximum number of 1 RACH burst transmissions\n"
2160 "Maximum number of 2 RACH burst transmissions\n"
2161 "Maximum number of 4 RACH burst transmissions\n"
2162 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002163{
2164 struct gsm_bts *bts = vty->index;
2165 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2166 return CMD_SUCCESS;
2167}
2168
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002169#define CD_STR "Channel Description\n"
2170
2171DEFUN(cfg_bts_chan_desc_att,
2172 cfg_bts_chan_desc_att_cmd,
2173 "channel-descrption attach (0|1)",
2174 CD_STR
2175 "Set if attachment is required\n"
2176 "Attachment is NOT required\n"
2177 "Attachment is required (standard)\n")
2178{
2179 struct gsm_bts *bts = vty->index;
2180 bts->si_common.chan_desc.att = atoi(argv[0]);
2181 return CMD_SUCCESS;
2182}
2183
2184DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2185 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2186 "channel-descrption bs-pa-mfrms <2-9>",
2187 CD_STR
2188 "Set number of multiframe periods for paging groups\n"
2189 "Number of multiframe periods for paging groups\n")
2190{
2191 struct gsm_bts *bts = vty->index;
2192 int bs_pa_mfrms = atoi(argv[0]);
2193
2194 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2195 return CMD_SUCCESS;
2196}
2197
2198DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2199 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2200 "channel-descrption bs-ag-blks-res <0-7>",
2201 CD_STR
2202 "Set number of blocks reserved for access grant\n"
2203 "Number of blocks reserved for access grant\n")
2204{
2205 struct gsm_bts *bts = vty->index;
2206 int bs_ag_blks_res = atoi(argv[0]);
2207
2208 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2209 return CMD_SUCCESS;
2210}
2211
Harald Welte8f0ed552010-05-11 21:53:49 +02002212#define NM_STR "Network Management\n"
2213
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002214DEFUN(cfg_bts_rach_nm_b_thresh,
2215 cfg_bts_rach_nm_b_thresh_cmd,
2216 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002217 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002218 "Set the NM Busy Threshold\n"
2219 "Set the NM Busy Threshold\n"
2220 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002221{
2222 struct gsm_bts *bts = vty->index;
2223 bts->rach_b_thresh = atoi(argv[0]);
2224 return CMD_SUCCESS;
2225}
2226
2227DEFUN(cfg_bts_rach_nm_ldavg,
2228 cfg_bts_rach_nm_ldavg_cmd,
2229 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002230 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002231 "Set the NM Loadaverage Slots value\n"
2232 "Set the NM Loadaverage Slots value\n"
2233 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002234{
2235 struct gsm_bts *bts = vty->index;
2236 bts->rach_ldavg_slots = atoi(argv[0]);
2237 return CMD_SUCCESS;
2238}
2239
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002240DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2241 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002242 "Should this cell be barred from access?\n"
2243 "Should this cell be barred from access?\n"
2244 "Cell should NOT be barred\n"
2245 "Cell should be barred\n")
2246
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002247{
2248 struct gsm_bts *bts = vty->index;
2249
Harald Welte71355012009-12-21 23:08:18 +01002250 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002251
2252 return CMD_SUCCESS;
2253}
2254
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002255DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2256 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002257 RACH_STR
2258 "Should this cell allow emergency calls?\n"
2259 "Should this cell allow emergency calls?\n"
2260 "Should this cell allow emergency calls?\n"
2261 "Do NOT allow emergency calls\n"
2262 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002263{
2264 struct gsm_bts *bts = vty->index;
2265
2266 if (atoi(argv[0]) == 0)
2267 bts->si_common.rach_control.t2 |= 0x4;
2268 else
2269 bts->si_common.rach_control.t2 &= ~0x4;
2270
2271 return CMD_SUCCESS;
2272}
2273
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002274DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2275 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2276 RACH_STR
2277 "Set access control class\n"
2278 "Access control class 0\n"
2279 "Access control class 1\n"
2280 "Access control class 2\n"
2281 "Access control class 3\n"
2282 "Access control class 4\n"
2283 "Access control class 5\n"
2284 "Access control class 6\n"
2285 "Access control class 7\n"
2286 "Access control class 8\n"
2287 "Access control class 9\n"
2288 "Access control class 11 for PLMN use\n"
2289 "Access control class 12 for security services\n"
2290 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2291 "Access control class 14 for emergency services\n"
2292 "Access control class 15 for PLMN staff\n"
2293 "barred to use access control class\n"
2294 "allowed to use access control class\n")
2295{
2296 struct gsm_bts *bts = vty->index;
2297
2298 uint8_t control_class;
2299 uint8_t allowed = 0;
2300
2301 if (strcmp(argv[1], "allowed") == 0)
2302 allowed = 1;
2303
2304 control_class = atoi(argv[0]);
2305 if (control_class < 8)
2306 if (allowed)
2307 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2308 else
2309 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2310 else
2311 if (allowed)
2312 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2313 else
2314 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2315
2316 return CMD_SUCCESS;
2317}
2318
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002319DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2320 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002321 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002322 "Maximum transmit power of the MS\n"
2323 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002324 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002325{
2326 struct gsm_bts *bts = vty->index;
2327
2328 bts->ms_max_power = atoi(argv[0]);
2329
2330 return CMD_SUCCESS;
2331}
2332
Harald Weltecfaabbb2012-08-16 23:23:50 +02002333#define CELL_STR "Cell Parameters\n"
2334
Harald Welte73225282009-12-12 18:17:25 +01002335DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2336 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002337 CELL_STR "Cell re-selection parameters\n"
2338 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002339 "Cell Re-Selection Hysteresis in dB")
2340{
2341 struct gsm_bts *bts = vty->index;
2342
2343 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2344
2345 return CMD_SUCCESS;
2346}
2347
2348DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2349 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002350 "Minimum RxLev needed for cell access\n"
2351 "Minimum RxLev needed for cell access\n"
2352 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002353 "Minimum RxLev needed for cell access (better than -110dBm)")
2354{
2355 struct gsm_bts *bts = vty->index;
2356
2357 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2358
2359 return CMD_SUCCESS;
2360}
2361
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002362DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2363 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002364 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2365 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002366{
2367 struct gsm_bts *bts = vty->index;
2368
2369 bts->si_common.cell_ro_sel_par.present = 1;
2370 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2371
2372 return CMD_SUCCESS;
2373}
2374
2375DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2376 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002377 CELL_STR "Cell Re-Selection Parameters\n"
2378 "Cell Re-Selection Offset (CRO) in dB\n"
2379 "Cell Re-Selection Offset (CRO) in dB\n"
2380 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002381{
2382 struct gsm_bts *bts = vty->index;
2383
2384 bts->si_common.cell_ro_sel_par.present = 1;
2385 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2386
2387 return CMD_SUCCESS;
2388}
2389
2390DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2391 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002392 "Cell selection temporary negative offset\n"
2393 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002394 "Cell selection temporary negative offset in dB")
2395{
2396 struct gsm_bts *bts = vty->index;
2397
2398 bts->si_common.cell_ro_sel_par.present = 1;
2399 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2400
2401 return CMD_SUCCESS;
2402}
2403
2404DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2405 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002406 "Cell selection temporary negative offset\n"
2407 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002408 "Sets cell selection temporary negative offset to infinity")
2409{
2410 struct gsm_bts *bts = vty->index;
2411
2412 bts->si_common.cell_ro_sel_par.present = 1;
2413 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2414
2415 return CMD_SUCCESS;
2416}
2417
2418DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2419 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002420 "Cell selection penalty time\n"
2421 "Cell selection penalty time\n"
2422 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002423{
2424 struct gsm_bts *bts = vty->index;
2425
2426 bts->si_common.cell_ro_sel_par.present = 1;
2427 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2428
2429 return CMD_SUCCESS;
2430}
2431
2432DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2433 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002434 "Cell selection penalty time\n"
2435 "Cell selection penalty time\n"
2436 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002437 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2438 "and TEMPORARY_OFFSET is ignored)")
2439{
2440 struct gsm_bts *bts = vty->index;
2441
2442 bts->si_common.cell_ro_sel_par.present = 1;
2443 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2444
2445 return CMD_SUCCESS;
2446}
2447
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002448DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2449 "radio-link-timeout <4-64>",
2450 "Radio link timeout criterion (BTS side)\n"
2451 "Radio link timeout value (lost SACCH block)\n")
2452{
2453 struct gsm_bts *bts = vty->index;
2454
Harald Welte2f8b9d22017-06-18 11:12:13 +03002455 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2456
2457 return CMD_SUCCESS;
2458}
2459
2460DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2461 "radio-link-timeout infinite",
2462 "Radio link timeout criterion (BTS side)\n"
2463 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2464{
2465 struct gsm_bts *bts = vty->index;
2466
2467 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2468 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2469 return CMD_WARNING;
2470 }
2471
2472 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2473 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002474
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002475 return CMD_SUCCESS;
2476}
2477
Harald Welte8f0ed552010-05-11 21:53:49 +02002478#define GPRS_TEXT "GPRS Packet Network\n"
2479
Harald Welteaf387632010-03-14 23:30:30 +08002480DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002481 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002482 GPRS_TEXT
2483 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002484 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002485 "GPRS BSSGP VC Identifier")
2486{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002487 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002488 struct gsm_bts *bts = vty->index;
2489
Harald Welte4511d892010-04-18 15:51:20 +02002490 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002491 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2492 return CMD_WARNING;
2493 }
2494
Harald Welte97a282b2010-03-14 15:37:43 +08002495 bts->gprs.cell.bvci = atoi(argv[0]);
2496
2497 return CMD_SUCCESS;
2498}
2499
Harald Weltea5731cf2010-03-22 11:48:36 +08002500DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2501 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002502 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002503 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002504 "GPRS NS Entity Identifier")
2505{
2506 struct gsm_bts *bts = vty->index;
2507
Harald Welte4511d892010-04-18 15:51:20 +02002508 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002509 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2510 return CMD_WARNING;
2511 }
2512
2513 bts->gprs.nse.nsei = atoi(argv[0]);
2514
2515 return CMD_SUCCESS;
2516}
2517
Harald Welte8f0ed552010-05-11 21:53:49 +02002518#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2519 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002520
Harald Welte97a282b2010-03-14 15:37:43 +08002521DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2522 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002523 GPRS_TEXT NSVC_TEXT
2524 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002525 "GPRS NS VC Identifier")
2526{
2527 struct gsm_bts *bts = vty->index;
2528 int idx = atoi(argv[0]);
2529
Harald Welte4511d892010-04-18 15:51:20 +02002530 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002531 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2532 return CMD_WARNING;
2533 }
2534
Harald Welte97a282b2010-03-14 15:37:43 +08002535 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2536
2537 return CMD_SUCCESS;
2538}
2539
Harald Welteaf387632010-03-14 23:30:30 +08002540DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2541 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002542 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002543 "GPRS NS Local UDP Port\n"
2544 "GPRS NS Local UDP Port\n"
2545 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002546 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002547{
2548 struct gsm_bts *bts = vty->index;
2549 int idx = atoi(argv[0]);
2550
Harald Welte4511d892010-04-18 15:51:20 +02002551 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002552 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2553 return CMD_WARNING;
2554 }
2555
Harald Welteaf387632010-03-14 23:30:30 +08002556 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2557
2558 return CMD_SUCCESS;
2559}
2560
2561DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2562 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002563 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002564 "GPRS NS Remote UDP Port\n"
2565 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002566 "GPRS NS Remote UDP Port\n"
2567 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002568{
2569 struct gsm_bts *bts = vty->index;
2570 int idx = atoi(argv[0]);
2571
Harald Welte4511d892010-04-18 15:51:20 +02002572 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002573 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2574 return CMD_WARNING;
2575 }
2576
Harald Welteaf387632010-03-14 23:30:30 +08002577 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2578
2579 return CMD_SUCCESS;
2580}
2581
2582DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2583 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002584 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002585 "GPRS NS Remote IP Address\n"
2586 "GPRS NS Remote IP Address\n"
2587 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002588{
2589 struct gsm_bts *bts = vty->index;
2590 int idx = atoi(argv[0]);
2591 struct in_addr ia;
2592
Harald Welte4511d892010-04-18 15:51:20 +02002593 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002594 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2595 return CMD_WARNING;
2596 }
2597
Harald Welteaf387632010-03-14 23:30:30 +08002598 inet_aton(argv[1], &ia);
2599 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2600
2601 return CMD_SUCCESS;
2602}
2603
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002604DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002605 "paging free <-1-1024>",
2606 "Paging options\n"
2607 "Only page when having a certain amount of free slots\n"
2608 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002609{
2610 struct gsm_bts *bts = vty->index;
2611
2612 bts->paging.free_chans_need = atoi(argv[0]);
2613 return CMD_SUCCESS;
2614}
2615
Harald Welte615e9562010-05-11 23:50:21 +02002616DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2617 "gprs ns timer " NS_TIMERS " <0-255>",
2618 GPRS_TEXT "Network Service\n"
2619 "Network Service Timer\n"
2620 NS_TIMERS_HELP "Timer Value\n")
2621{
2622 struct gsm_bts *bts = vty->index;
2623 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2624 int val = atoi(argv[1]);
2625
2626 if (bts->gprs.mode == BTS_GPRS_NONE) {
2627 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2628 return CMD_WARNING;
2629 }
2630
2631 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2632 return CMD_WARNING;
2633
2634 bts->gprs.nse.timer[idx] = val;
2635
2636 return CMD_SUCCESS;
2637}
2638
2639#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 +02002640#define BSSGP_TIMERS_HELP \
2641 "Tbvc-block timeout\n" \
2642 "Tbvc-block retries\n" \
2643 "Tbvc-unblock retries\n" \
2644 "Tbvcc-reset timeout\n" \
2645 "Tbvc-reset retries\n" \
2646 "Tbvc-suspend timeout\n" \
2647 "Tbvc-suspend retries\n" \
2648 "Tbvc-resume timeout\n" \
2649 "Tbvc-resume retries\n" \
2650 "Tbvc-capa-update timeout\n" \
2651 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002652
2653DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2654 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2655 GPRS_TEXT "Cell / BSSGP\n"
2656 "Cell/BSSGP Timer\n"
2657 BSSGP_TIMERS_HELP "Timer Value\n")
2658{
2659 struct gsm_bts *bts = vty->index;
2660 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2661 int val = atoi(argv[1]);
2662
2663 if (bts->gprs.mode == BTS_GPRS_NONE) {
2664 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2665 return CMD_WARNING;
2666 }
2667
2668 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2669 return CMD_WARNING;
2670
2671 bts->gprs.cell.timer[idx] = val;
2672
2673 return CMD_SUCCESS;
2674}
2675
Harald Welte97a282b2010-03-14 15:37:43 +08002676DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2677 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002678 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002679 "GPRS Routing Area Code\n"
2680 "GPRS Routing Area Code\n"
2681 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002682{
2683 struct gsm_bts *bts = vty->index;
2684
Harald Welte4511d892010-04-18 15:51:20 +02002685 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002686 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2687 return CMD_WARNING;
2688 }
2689
Harald Welte97a282b2010-03-14 15:37:43 +08002690 bts->gprs.rac = atoi(argv[0]);
2691
2692 return CMD_SUCCESS;
2693}
2694
Max292ec582016-07-28 11:55:37 +02002695DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2696 "gprs control-ack-type-rach", GPRS_TEXT
2697 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2698 "four access bursts format instead of default RLC/MAC control block\n")
2699{
2700 struct gsm_bts *bts = vty->index;
2701
2702 if (bts->gprs.mode == BTS_GPRS_NONE) {
2703 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2704 return CMD_WARNING;
2705 }
2706
2707 bts->gprs.ctrl_ack_type_use_block = false;
2708
2709 return CMD_SUCCESS;
2710}
2711
2712DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2713 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2714 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2715 "four access bursts format instead of default RLC/MAC control block\n")
2716{
2717 struct gsm_bts *bts = vty->index;
2718
2719 if (bts->gprs.mode == BTS_GPRS_NONE) {
2720 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2721 return CMD_WARNING;
2722 }
2723
2724 bts->gprs.ctrl_ack_type_use_block = true;
2725
2726 return CMD_SUCCESS;
2727}
2728
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002729DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2730 "gprs network-control-order (nc0|nc1|nc2)",
2731 GPRS_TEXT
2732 "GPRS Network Control Order\n"
2733 "MS controlled cell re-selection, no measurement reporting\n"
2734 "MS controlled cell re-selection, MS sends measurement reports\n"
2735 "Network controlled cell re-selection, MS sends measurement reports\n")
2736{
2737 struct gsm_bts *bts = vty->index;
2738
2739 if (bts->gprs.mode == BTS_GPRS_NONE) {
2740 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2741 return CMD_WARNING;
2742 }
2743
2744 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2745
2746 return CMD_SUCCESS;
2747}
2748
Harald Welte4511d892010-04-18 15:51:20 +02002749DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2750 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002751 GPRS_TEXT
2752 "GPRS Mode for this BTS\n"
2753 "GPRS Disabled on this BTS\n"
2754 "GPRS Enabled on this BTS\n"
2755 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002756{
2757 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002758 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002759
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002760 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002761 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2762 VTY_NEWLINE);
2763 return CMD_WARNING;
2764 }
2765
2766 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002767
2768 return CMD_SUCCESS;
2769}
2770
bhargava350533c2016-07-21 11:14:34 +05302771DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2772 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2773 "gprs 11bit_rach_support_for_egprs (0|1)",
2774 GPRS_TEXT "11 bit RACH options\n"
2775 "Disable 11 bit RACH for EGPRS\n"
2776 "Enable 11 bit RACH for EGPRS")
2777{
2778 struct gsm_bts *bts = vty->index;
2779
2780 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2781
2782 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2783 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2784 return CMD_WARNING;
2785 }
2786
2787 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2788 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2789 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2790 " enabled%s", VTY_NEWLINE);
2791 return CMD_WARNING;
2792 }
2793
2794 return CMD_SUCCESS;
2795}
2796
Harald Welte9fbff4a2010-07-30 11:50:09 +02002797#define SI_TEXT "System Information Messages\n"
2798#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)"
2799#define SI_TYPE_HELP "System Information Type 1\n" \
2800 "System Information Type 2\n" \
2801 "System Information Type 3\n" \
2802 "System Information Type 4\n" \
2803 "System Information Type 5\n" \
2804 "System Information Type 6\n" \
2805 "System Information Type 7\n" \
2806 "System Information Type 8\n" \
2807 "System Information Type 9\n" \
2808 "System Information Type 10\n" \
2809 "System Information Type 13\n" \
2810 "System Information Type 16\n" \
2811 "System Information Type 17\n" \
2812 "System Information Type 18\n" \
2813 "System Information Type 19\n" \
2814 "System Information Type 20\n" \
2815 "System Information Type 2bis\n" \
2816 "System Information Type 2ter\n" \
2817 "System Information Type 2quater\n" \
2818 "System Information Type 5bis\n" \
2819 "System Information Type 5ter\n"
2820
2821DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2822 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2823 SI_TEXT SI_TYPE_HELP
2824 "System Information Mode\n"
2825 "Static user-specified\n"
2826 "Dynamic, BSC-computed\n")
2827{
2828 struct gsm_bts *bts = vty->index;
2829 int type;
2830
2831 type = get_string_value(osmo_sitype_strs, argv[0]);
2832 if (type < 0) {
2833 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2834 return CMD_WARNING;
2835 }
2836
2837 if (!strcmp(argv[1], "static"))
2838 bts->si_mode_static |= (1 << type);
2839 else
2840 bts->si_mode_static &= ~(1 << type);
2841
2842 return CMD_SUCCESS;
2843}
2844
2845DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2846 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2847 SI_TEXT SI_TYPE_HELP
2848 "Static System Information filling\n"
2849 "Static user-specified SI content in HEX notation\n")
2850{
2851 struct gsm_bts *bts = vty->index;
2852 int rc, type;
2853
2854 type = get_string_value(osmo_sitype_strs, argv[0]);
2855 if (type < 0) {
2856 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2857 return CMD_WARNING;
2858 }
2859
2860 if (!(bts->si_mode_static & (1 << type))) {
2861 vty_out(vty, "SI Type %s is not configured in static mode%s",
2862 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2863 return CMD_WARNING;
2864 }
2865
Harald Welte290aaed2010-07-30 11:53:18 +02002866 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002867 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002868
2869 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002870 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2871 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002872 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2873 return CMD_WARNING;
2874 }
2875
2876 /* Mark this SI as present */
2877 bts->si_valid |= (1 << type);
2878
2879 return CMD_SUCCESS;
2880}
2881
Harald Welte42def722017-01-13 00:10:32 +01002882DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2883 "early-classmark-sending (allowed|forbidden)",
2884 "Early Classmark Sending\n"
2885 "Early Classmark Sending is allowed\n"
2886 "Early Classmark Sending is forbidden\n")
2887{
2888 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002889
2890 if (!strcmp(argv[0], "allowed"))
2891 bts->early_classmark_allowed = true;
2892 else
2893 bts->early_classmark_allowed = false;
2894
2895 return CMD_SUCCESS;
2896}
2897
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002898DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2899 "early-classmark-sending-3g (allowed|forbidden)",
2900 "3G Early Classmark Sending\n"
2901 "3G Early Classmark Sending is allowed\n"
2902 "3G Early Classmark Sending is forbidden\n")
2903{
2904 struct gsm_bts *bts = vty->index;
2905
2906 if (!strcmp(argv[0], "allowed"))
2907 bts->early_classmark_allowed_3g = true;
2908 else
2909 bts->early_classmark_allowed_3g = false;
2910
2911 return CMD_SUCCESS;
2912}
2913
Harald Welte32c09622011-01-11 23:44:56 +01002914DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002915 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002916 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002917 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2918 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002919{
2920 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002921 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002922
Harald Welte64c07d22011-02-15 11:43:27 +01002923 switch (mode) {
2924 case NL_MODE_MANUAL_SI5SEP:
2925 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002926 /* make sure we clear the current list when switching to
2927 * manual mode */
2928 if (bts->neigh_list_manual_mode == 0)
2929 memset(&bts->si_common.data.neigh_list, 0,
2930 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002931 break;
2932 default:
2933 break;
2934 }
2935
2936 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002937
2938 return CMD_SUCCESS;
2939}
2940
2941DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002942 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002943 "Neighbor List\n" "Add to manual neighbor list\n"
2944 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2945 "ARFCN of neighbor\n")
2946{
2947 struct gsm_bts *bts = vty->index;
2948 struct bitvec *bv = &bts->si_common.neigh_list;
2949 uint16_t arfcn = atoi(argv[1]);
2950
2951 if (!bts->neigh_list_manual_mode) {
2952 vty_out(vty, "%% Cannot configure neighbor list in "
2953 "automatic mode%s", VTY_NEWLINE);
2954 return CMD_WARNING;
2955 }
2956
2957 if (!strcmp(argv[0], "add"))
2958 bitvec_set_bit_pos(bv, arfcn, 1);
2959 else
2960 bitvec_set_bit_pos(bv, arfcn, 0);
2961
2962 return CMD_SUCCESS;
2963}
2964
Max70fdd242017-06-15 15:10:53 +02002965/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002966DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002967 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2968 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2969 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2970 "Add to manual SI2quater neighbor list\n"
2971 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2972 "threshold high bits\n" "threshold high bits\n"
2973 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2974 "priority\n" "priority (8 means NA)\n"
2975 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2976 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002977{
2978 struct gsm_bts *bts = vty->index;
2979 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2980 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002981 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2982 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002983 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002984
Max70fdd242017-06-15 15:10:53 +02002985 switch (r) {
2986 case 1:
2987 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2988 thresh_hi, VTY_NEWLINE);
2989 break;
2990 case EARFCN_THRESH_LOW_INVALID:
2991 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2992 thresh_lo, VTY_NEWLINE);
2993 break;
2994 case EARFCN_QRXLV_INVALID + 1:
2995 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2996 qrx, VTY_NEWLINE);
2997 break;
2998 case EARFCN_PRIO_INVALID:
2999 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
3000 prio, VTY_NEWLINE);
3001 break;
3002 default:
3003 if (r < 0) {
3004 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
3005 return CMD_WARNING;
3006 }
Max59a1bf32016-04-15 16:04:46 +02003007 }
3008
Max70fdd242017-06-15 15:10:53 +02003009 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01003010 return CMD_SUCCESS;
3011
Maxf39d03a2017-05-12 17:00:30 +02003012 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02003013 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02003014 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01003015
Maxaafff962016-04-20 15:57:14 +02003016 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02003017}
3018
3019DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02003020 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02003021 "SI2quater Neighbor List\n"
3022 "SI2quater Neighbor List\n"
3023 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02003024 "EARFCN of neighbor\n"
3025 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02003026{
3027 struct gsm_bts *bts = vty->index;
3028 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02003029 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02003030 int r = osmo_earfcn_del(e, arfcn);
3031 if (r < 0) {
3032 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02003033 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02003034 return CMD_WARNING;
3035 }
3036
3037 return CMD_SUCCESS;
3038}
3039
Max26679e02016-04-20 15:57:13 +02003040DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02003041 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02003042 "SI2quater Neighbor List\n"
3043 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
3044 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
3045 "diversity bit\n")
3046{
3047 struct gsm_bts *bts = vty->index;
3048 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
3049
3050 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
3051 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02003052 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 +01003053 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02003054 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02003055 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
3056 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01003057 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02003058 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02003059 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02003060 return CMD_WARNING;
3061 }
3062
3063 return CMD_SUCCESS;
3064}
3065
3066DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02003067 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02003068 "SI2quater Neighbor List\n"
3069 "SI2quater Neighbor List\n"
3070 "Delete from SI2quater manual neighbor list\n"
3071 "UARFCN of neighbor\n"
3072 "UARFCN\n"
3073 "scrambling code\n")
3074{
3075 struct gsm_bts *bts = vty->index;
3076
3077 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
3078 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
3079 VTY_NEWLINE);
3080 return CMD_WARNING;
3081 }
3082
3083 return CMD_SUCCESS;
3084}
3085
Harald Welte64c07d22011-02-15 11:43:27 +01003086DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003087 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003088 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003089 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
3090 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
3091 "ARFCN of neighbor\n")
3092{
3093 struct gsm_bts *bts = vty->index;
3094 struct bitvec *bv = &bts->si_common.si5_neigh_list;
3095 uint16_t arfcn = atoi(argv[1]);
3096
3097 if (!bts->neigh_list_manual_mode) {
3098 vty_out(vty, "%% Cannot configure neighbor list in "
3099 "automatic mode%s", VTY_NEWLINE);
3100 return CMD_WARNING;
3101 }
3102
3103 if (!strcmp(argv[0], "add"))
3104 bitvec_set_bit_pos(bv, arfcn, 1);
3105 else
3106 bitvec_set_bit_pos(bv, arfcn, 0);
3107
3108 return CMD_SUCCESS;
3109}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003110
Harald Welte8254cf72017-05-29 13:42:19 +02003111DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3112 "pcu-socket PATH",
3113 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3114 "Path in the file system for the unix-domain PCU socket\n")
3115{
3116 struct gsm_bts *bts = vty->index;
3117 int rc;
3118
Harald Welte4a824ca2017-05-29 13:54:27 +02003119 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003120 pcu_sock_exit(bts);
3121 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3122 if (rc < 0) {
3123 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3124 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3125 return CMD_WARNING;
3126 }
3127
3128 return CMD_SUCCESS;
3129}
3130
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003131#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3132
3133DEFUN(cfg_bts_excl_rf_lock,
3134 cfg_bts_excl_rf_lock_cmd,
3135 "rf-lock-exclude",
3136 EXCL_RFLOCK_STR)
3137{
3138 struct gsm_bts *bts = vty->index;
3139 bts->excl_from_rf_lock = 1;
3140 return CMD_SUCCESS;
3141}
3142
3143DEFUN(cfg_bts_no_excl_rf_lock,
3144 cfg_bts_no_excl_rf_lock_cmd,
3145 "no rf-lock-exclude",
3146 NO_STR EXCL_RFLOCK_STR)
3147{
3148 struct gsm_bts *bts = vty->index;
3149 bts->excl_from_rf_lock = 0;
3150 return CMD_SUCCESS;
3151}
3152
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003153#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3154
3155DEFUN(cfg_bts_force_comb_si,
3156 cfg_bts_force_comb_si_cmd,
3157 "force-combined-si",
3158 FORCE_COMB_SI_STR)
3159{
3160 struct gsm_bts *bts = vty->index;
3161 bts->force_combined_si = 1;
3162 return CMD_SUCCESS;
3163}
3164
3165DEFUN(cfg_bts_no_force_comb_si,
3166 cfg_bts_no_force_comb_si_cmd,
3167 "no force-combined-si",
3168 NO_STR FORCE_COMB_SI_STR)
3169{
3170 struct gsm_bts *bts = vty->index;
3171 bts->force_combined_si = 0;
3172 return CMD_SUCCESS;
3173}
3174
Andreas Eversberga83d5112013-12-07 18:32:28 +01003175static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3176{
3177 struct gsm_bts *bts = vty->index;
3178 struct bts_codec_conf *codec = &bts->codec;
3179 int i;
3180
3181 codec->hr = 0;
3182 codec->efr = 0;
3183 codec->amr = 0;
3184 for (i = 0; i < argc; i++) {
3185 if (!strcmp(argv[i], "hr"))
3186 codec->hr = 1;
3187 if (!strcmp(argv[i], "efr"))
3188 codec->efr = 1;
3189 if (!strcmp(argv[i], "amr"))
3190 codec->amr = 1;
3191 }
3192}
3193
3194#define CODEC_PAR_STR " (hr|efr|amr)"
3195#define CODEC_HELP_STR "Half Rate\n" \
3196 "Enhanced Full Rate\nAdaptive Multirate\n"
3197
3198DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3199 "codec-support fr",
3200 "Codec Support settings\nFullrate\n")
3201{
3202 _get_codec_from_arg(vty, 0, argv);
3203 return CMD_SUCCESS;
3204}
3205
3206DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3207 "codec-support fr" CODEC_PAR_STR,
3208 "Codec Support settings\nFullrate\n"
3209 CODEC_HELP_STR)
3210{
3211 _get_codec_from_arg(vty, 1, argv);
3212 return CMD_SUCCESS;
3213}
3214
3215DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3216 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3217 "Codec Support settings\nFullrate\n"
3218 CODEC_HELP_STR CODEC_HELP_STR)
3219{
3220 _get_codec_from_arg(vty, 2, argv);
3221 return CMD_SUCCESS;
3222}
3223
3224DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3225 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3226 "Codec Support settings\nFullrate\n"
3227 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3228{
3229 _get_codec_from_arg(vty, 3, argv);
3230 return CMD_SUCCESS;
3231}
3232
3233DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3234 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3235 "Codec Support settings\nFullrate\n"
3236 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3237{
3238 _get_codec_from_arg(vty, 4, argv);
3239 return CMD_SUCCESS;
3240}
3241
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003242DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3243 "depends-on-bts <0-255>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003244 "This BTS can only be started if another one is up\n"
3245 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003246{
3247 struct gsm_bts *bts = vty->index;
3248 struct gsm_bts *other_bts;
3249 int dep = atoi(argv[0]);
3250
3251
3252 if (!is_ipaccess_bts(bts)) {
3253 vty_out(vty, "This feature is only available for IP systems.%s",
3254 VTY_NEWLINE);
3255 return CMD_WARNING;
3256 }
3257
3258 other_bts = gsm_bts_num(bts->network, dep);
3259 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3260 vty_out(vty, "This feature is only available for IP systems.%s",
3261 VTY_NEWLINE);
3262 return CMD_WARNING;
3263 }
3264
3265 if (dep >= bts->nr) {
3266 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3267 VTY_NEWLINE);
3268 return CMD_WARNING;
3269 }
3270
3271 bts_depend_mark(bts, dep);
3272 return CMD_SUCCESS;
3273}
3274
3275DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3276 "depeneds-on-bts <0-255>",
3277 NO_STR "This BTS can only be started if another one is up\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003278 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003279{
3280 struct gsm_bts *bts = vty->index;
3281 int dep = atoi(argv[0]);
3282
3283 bts_depend_clear(bts, dep);
3284 return CMD_SUCCESS;
3285}
3286
Andreas Eversberg73266522014-01-19 11:47:44 +01003287#define AMR_TEXT "Adaptive Multi Rate settings\n"
3288#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3289#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3290 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3291#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3292#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3293
3294static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3295{
3296 struct gsm_bts *bts = vty->index;
3297 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3298 struct gsm48_multi_rate_conf *mr_conf =
3299 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3300 int i;
3301
3302 mr->gsm48_ie[1] = 0;
3303 for (i = 0; i < argc; i++)
3304 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3305 mr_conf->icmi = 0;
3306}
3307
3308static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3309{
3310 struct gsm_bts *bts = vty->index;
3311 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003312 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003313 int i;
3314
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003315 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3316 for (i = 0; i < argc - 1; i++)
3317 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003318}
3319
3320static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3321{
3322 struct gsm_bts *bts = vty->index;
3323 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003324 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003325 int i;
3326
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003327 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3328 for (i = 0; i < argc - 1; i++)
3329 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003330}
3331
3332static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3333{
3334 struct gsm_bts *bts = vty->index;
3335 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3336 struct gsm48_multi_rate_conf *mr_conf =
3337 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3338 int num = 0, i;
3339
3340 for (i = 0; i < ((full) ? 8 : 6); i++) {
3341 if ((mr->gsm48_ie[1] & (1 << i))) {
3342 num++;
3343 }
3344 }
3345
3346 if (argv[0][0] == 'a' || num == 0)
3347 mr_conf->icmi = 0;
3348 else {
3349 mr_conf->icmi = 1;
3350 if (num < atoi(argv[0]))
3351 mr_conf->smod = num - 1;
3352 else
3353 mr_conf->smod = atoi(argv[0]) - 1;
3354 }
3355}
3356
3357#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3358#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3359 "10,2k\n12,2k\n"
3360
3361#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3362#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3363
3364#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3365#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3366
3367DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3368 "amr tch-f modes" AMR_TCHF_PAR_STR,
3369 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3370 AMR_TCHF_HELP_STR)
3371{
3372 get_amr_from_arg(vty, 1, argv, 1);
3373 return CMD_SUCCESS;
3374}
3375
3376DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3377 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3378 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3379 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3380{
3381 get_amr_from_arg(vty, 2, argv, 1);
3382 return CMD_SUCCESS;
3383}
3384
3385DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3386 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3387 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3388 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3389{
3390 get_amr_from_arg(vty, 3, argv, 1);
3391 return CMD_SUCCESS;
3392}
3393
3394DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3395 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3396 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3397 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3398{
3399 get_amr_from_arg(vty, 4, argv, 1);
3400 return CMD_SUCCESS;
3401}
3402
3403DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3404 "amr tch-f start-mode (auto|1|2|3|4)",
3405 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3406{
3407 get_amr_start_from_arg(vty, argv, 1);
3408 return CMD_SUCCESS;
3409}
3410
3411DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3412 "amr tch-f threshold (ms|bts) <0-63>",
3413 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3414 AMR_TH_HELP_STR)
3415{
3416 get_amr_th_from_arg(vty, 2, argv, 1);
3417 return CMD_SUCCESS;
3418}
3419
3420DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3421 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3422 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3423 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3424{
3425 get_amr_th_from_arg(vty, 3, argv, 1);
3426 return CMD_SUCCESS;
3427}
3428
3429DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3430 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3431 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3432 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3433{
3434 get_amr_th_from_arg(vty, 4, argv, 1);
3435 return CMD_SUCCESS;
3436}
3437
3438DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3439 "amr tch-f hysteresis (ms|bts) <0-15>",
3440 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3441 AMR_HY_HELP_STR)
3442{
3443 get_amr_hy_from_arg(vty, 2, argv, 1);
3444 return CMD_SUCCESS;
3445}
3446
3447DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3448 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3449 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3450 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3451{
3452 get_amr_hy_from_arg(vty, 3, argv, 1);
3453 return CMD_SUCCESS;
3454}
3455
3456DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3457 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3458 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3459 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3460{
3461 get_amr_hy_from_arg(vty, 4, argv, 1);
3462 return CMD_SUCCESS;
3463}
3464
3465DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3466 "amr tch-h modes" AMR_TCHH_PAR_STR,
3467 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3468 AMR_TCHH_HELP_STR)
3469{
3470 get_amr_from_arg(vty, 1, argv, 0);
3471 return CMD_SUCCESS;
3472}
3473
3474DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3475 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3476 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3477 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3478{
3479 get_amr_from_arg(vty, 2, argv, 0);
3480 return CMD_SUCCESS;
3481}
3482
3483DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3484 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3485 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3486 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3487{
3488 get_amr_from_arg(vty, 3, argv, 0);
3489 return CMD_SUCCESS;
3490}
3491
3492DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3493 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3494 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3495 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3496{
3497 get_amr_from_arg(vty, 4, argv, 0);
3498 return CMD_SUCCESS;
3499}
3500
3501DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3502 "amr tch-h start-mode (auto|1|2|3|4)",
3503 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3504{
3505 get_amr_start_from_arg(vty, argv, 0);
3506 return CMD_SUCCESS;
3507}
3508
3509DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3510 "amr tch-h threshold (ms|bts) <0-63>",
3511 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3512 AMR_TH_HELP_STR)
3513{
3514 get_amr_th_from_arg(vty, 2, argv, 0);
3515 return CMD_SUCCESS;
3516}
3517
3518DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3519 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3520 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3521 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3522{
3523 get_amr_th_from_arg(vty, 3, argv, 0);
3524 return CMD_SUCCESS;
3525}
3526
3527DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3528 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3529 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3530 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3531{
3532 get_amr_th_from_arg(vty, 4, argv, 0);
3533 return CMD_SUCCESS;
3534}
3535
3536DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3537 "amr tch-h hysteresis (ms|bts) <0-15>",
3538 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3539 AMR_HY_HELP_STR)
3540{
3541 get_amr_hy_from_arg(vty, 2, argv, 0);
3542 return CMD_SUCCESS;
3543}
3544
3545DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3546 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3547 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3548 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3549{
3550 get_amr_hy_from_arg(vty, 3, argv, 0);
3551 return CMD_SUCCESS;
3552}
3553
3554DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3555 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3556 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3557 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3558{
3559 get_amr_hy_from_arg(vty, 4, argv, 0);
3560 return CMD_SUCCESS;
3561}
3562
Harald Welte8f0ed552010-05-11 21:53:49 +02003563#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003564
Harald Welte5258fc42009-03-28 19:07:53 +00003565/* per TRX configuration */
3566DEFUN(cfg_trx,
3567 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003568 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003569 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003570 "Select a TRX to configure")
3571{
3572 int trx_nr = atoi(argv[0]);
3573 struct gsm_bts *bts = vty->index;
3574 struct gsm_bts_trx *trx;
3575
Harald Weltee441d9c2009-06-21 16:17:15 +02003576 if (trx_nr > bts->num_trx) {
3577 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3578 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003579 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003580 } else if (trx_nr == bts->num_trx) {
3581 /* we need to allocate a new one */
3582 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003583 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003584 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003585
Harald Weltee441d9c2009-06-21 16:17:15 +02003586 if (!trx)
3587 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003588
3589 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003590 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003591 vty->node = TRX_NODE;
3592
3593 return CMD_SUCCESS;
3594}
3595
3596DEFUN(cfg_trx_arfcn,
3597 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003598 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003599 "Set the ARFCN for this TRX\n"
3600 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003601{
3602 int arfcn = atoi(argv[0]);
3603 struct gsm_bts_trx *trx = vty->index;
3604
3605 /* FIXME: check if this ARFCN is supported by this TRX */
3606
3607 trx->arfcn = arfcn;
3608
3609 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3610 /* FIXME: use OML layer to update the ARFCN */
3611 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3612
3613 return CMD_SUCCESS;
3614}
3615
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003616DEFUN(cfg_trx_nominal_power,
3617 cfg_trx_nominal_power_cmd,
3618 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003619 "Nominal TRX RF Power in dBm\n"
3620 "Nominal TRX RF Power in dBm\n"
3621 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003622{
3623 struct gsm_bts_trx *trx = vty->index;
3624
3625 trx->nominal_power = atoi(argv[0]);
3626
3627 return CMD_SUCCESS;
3628}
3629
Harald Weltefcd24452009-06-20 18:15:19 +02003630DEFUN(cfg_trx_max_power_red,
3631 cfg_trx_max_power_red_cmd,
3632 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003633 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003634 "Reduction of maximum BS RF Power in dB\n")
3635{
3636 int maxpwr_r = atoi(argv[0]);
3637 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003638 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003639
3640 /* FIXME: check if our BTS type supports more than 12 */
3641 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3642 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3643 maxpwr_r, VTY_NEWLINE);
3644 return CMD_WARNING;
3645 }
3646 if (maxpwr_r & 1) {
3647 vty_out(vty, "%% Power %d dB is not an even value%s",
3648 maxpwr_r, VTY_NEWLINE);
3649 return CMD_WARNING;
3650 }
3651
3652 trx->max_power_red = maxpwr_r;
3653
3654 /* FIXME: make sure we update this using OML */
3655
3656 return CMD_SUCCESS;
3657}
3658
Harald Welte42581822009-08-08 16:12:58 +02003659DEFUN(cfg_trx_rsl_e1,
3660 cfg_trx_rsl_e1_cmd,
3661 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003662 "RSL Parameters\n"
3663 "E1/T1 interface to be used for RSL\n"
3664 "E1/T1 interface to be used for RSL\n"
3665 "E1/T1 Line Number to be used for RSL\n"
3666 "E1/T1 Timeslot to be used for RSL\n"
3667 "E1/T1 Timeslot to be used for RSL\n"
3668 "E1/T1 Sub-slot to be used for RSL\n"
3669 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3670 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3671 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3672 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3673 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003674{
3675 struct gsm_bts_trx *trx = vty->index;
3676
3677 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3678
3679 return CMD_SUCCESS;
3680}
3681
3682DEFUN(cfg_trx_rsl_e1_tei,
3683 cfg_trx_rsl_e1_tei_cmd,
3684 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003685 "RSL Parameters\n"
3686 "Set the TEI to be used for RSL\n"
3687 "Set the TEI to be used for RSL\n"
3688 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003689{
3690 struct gsm_bts_trx *trx = vty->index;
3691
3692 trx->rsl_tei = atoi(argv[0]);
3693
3694 return CMD_SUCCESS;
3695}
3696
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003697DEFUN(cfg_trx_rf_locked,
3698 cfg_trx_rf_locked_cmd,
3699 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003700 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3701 "TRX is NOT RF locked (active)\n"
3702 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003703{
3704 int locked = atoi(argv[0]);
3705 struct gsm_bts_trx *trx = vty->index;
3706
Maxbe356ed2017-09-07 19:10:09 +02003707 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003708 return CMD_SUCCESS;
3709}
Harald Welte42581822009-08-08 16:12:58 +02003710
Harald Welte5258fc42009-03-28 19:07:53 +00003711/* per TS configuration */
3712DEFUN(cfg_ts,
3713 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003714 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003715 "Select a Timeslot to configure\n"
3716 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003717{
3718 int ts_nr = atoi(argv[0]);
3719 struct gsm_bts_trx *trx = vty->index;
3720 struct gsm_bts_trx_ts *ts;
3721
3722 if (ts_nr >= TRX_NR_TS) {
3723 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3724 TRX_NR_TS, VTY_NEWLINE);
3725 return CMD_WARNING;
3726 }
3727
3728 ts = &trx->ts[ts_nr];
3729
3730 vty->index = ts;
3731 vty->node = TS_NODE;
3732
3733 return CMD_SUCCESS;
3734}
3735
Harald Weltea6fd58e2009-08-07 00:25:23 +02003736DEFUN(cfg_ts_pchan,
3737 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003738 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003739 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003740{
3741 struct gsm_bts_trx_ts *ts = vty->index;
3742 int pchanc;
3743
3744 pchanc = gsm_pchan_parse(argv[0]);
3745 if (pchanc < 0)
3746 return CMD_WARNING;
3747
3748 ts->pchan = pchanc;
3749
3750 return CMD_SUCCESS;
3751}
3752
3753/* used for backwards compatibility with old config files that still
3754 * have uppercase pchan type names */
3755DEFUN_HIDDEN(cfg_ts_pchan_compat,
3756 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003757 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003758 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003759{
3760 struct gsm_bts_trx_ts *ts = vty->index;
3761 int pchanc;
3762
3763 pchanc = gsm_pchan_parse(argv[0]);
3764 if (pchanc < 0)
3765 return CMD_WARNING;
3766
3767 ts->pchan = pchanc;
3768
3769 return CMD_SUCCESS;
3770}
3771
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003772
3773
Harald Welte135a6482011-05-30 12:09:13 +02003774DEFUN(cfg_ts_tsc,
3775 cfg_ts_tsc_cmd,
3776 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003777 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003778{
3779 struct gsm_bts_trx_ts *ts = vty->index;
3780
Max71d082b2017-05-30 15:03:38 +02003781 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003782 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3783 "falling back to BCC%s", VTY_NEWLINE);
3784 ts->tsc = -1;
3785 return CMD_WARNING;
3786 }
3787
Harald Welte135a6482011-05-30 12:09:13 +02003788 ts->tsc = atoi(argv[0]);
3789
3790 return CMD_SUCCESS;
3791}
3792
Harald Weltea39b0f22010-06-14 22:26:10 +02003793#define HOPPING_STR "Configure frequency hopping\n"
3794
3795DEFUN(cfg_ts_hopping,
3796 cfg_ts_hopping_cmd,
3797 "hopping enabled (0|1)",
3798 HOPPING_STR "Enable or disable frequency hopping\n"
3799 "Disable frequency hopping\n" "Enable frequency hopping\n")
3800{
3801 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003802 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003803
Max71d082b2017-05-30 15:03:38 +02003804 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003805 vty_out(vty, "BTS model does not support hopping%s",
3806 VTY_NEWLINE);
3807 return CMD_WARNING;
3808 }
3809
3810 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003811
3812 return CMD_SUCCESS;
3813}
3814
Harald Welte6e0cd042009-09-12 13:05:33 +02003815DEFUN(cfg_ts_hsn,
3816 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003817 "hopping sequence-number <0-63>",
3818 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003819 "Which hopping sequence to use for this channel\n"
3820 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003821{
3822 struct gsm_bts_trx_ts *ts = vty->index;
3823
3824 ts->hopping.hsn = atoi(argv[0]);
3825
3826 return CMD_SUCCESS;
3827}
3828
3829DEFUN(cfg_ts_maio,
3830 cfg_ts_maio_cmd,
3831 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003832 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003833 "Which hopping MAIO to use for this channel\n"
3834 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003835{
3836 struct gsm_bts_trx_ts *ts = vty->index;
3837
3838 ts->hopping.maio = atoi(argv[0]);
3839
3840 return CMD_SUCCESS;
3841}
3842
3843DEFUN(cfg_ts_arfcn_add,
3844 cfg_ts_arfcn_add_cmd,
3845 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003846 HOPPING_STR "Configure hopping ARFCN list\n"
3847 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003848{
3849 struct gsm_bts_trx_ts *ts = vty->index;
3850 int arfcn = atoi(argv[0]);
3851
Harald Weltea39b0f22010-06-14 22:26:10 +02003852 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3853
Harald Welte6e0cd042009-09-12 13:05:33 +02003854 return CMD_SUCCESS;
3855}
3856
3857DEFUN(cfg_ts_arfcn_del,
3858 cfg_ts_arfcn_del_cmd,
3859 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003860 HOPPING_STR "Configure hopping ARFCN list\n"
3861 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003862{
3863 struct gsm_bts_trx_ts *ts = vty->index;
3864 int arfcn = atoi(argv[0]);
3865
Harald Weltea39b0f22010-06-14 22:26:10 +02003866 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3867
Harald Welte6e0cd042009-09-12 13:05:33 +02003868 return CMD_SUCCESS;
3869}
3870
Harald Weltea6fd58e2009-08-07 00:25:23 +02003871DEFUN(cfg_ts_e1_subslot,
3872 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003873 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003874 "E1/T1 channel connected to this on-air timeslot\n"
3875 "E1/T1 channel connected to this on-air timeslot\n"
3876 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003877 "E1/T1 timeslot connected to this on-air timeslot\n"
3878 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003879 "E1/T1 sub-slot connected to this on-air timeslot\n"
3880 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3881 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3882 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3883 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3884 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003885{
3886 struct gsm_bts_trx_ts *ts = vty->index;
3887
Harald Welte42581822009-08-08 16:12:58 +02003888 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003889
3890 return CMD_SUCCESS;
3891}
Harald Welte5258fc42009-03-28 19:07:53 +00003892
Harald Welte4f10c252010-05-16 21:47:13 +02003893void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3894{
Harald Weltecf9d4312017-12-13 23:17:16 +01003895 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003896 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003897 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003898 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003899}
3900
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003901DEFUN(drop_bts,
3902 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003903 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003904 "Debug/Simulation command to drop Abis/IP BTS\n"
3905 "Debug/Simulation command to drop Abis/IP BTS\n"
3906 "Debug/Simulation command to drop Abis/IP BTS\n"
3907 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003908{
3909 struct gsm_network *gsmnet;
3910 struct gsm_bts_trx *trx;
3911 struct gsm_bts *bts;
3912 unsigned int bts_nr;
3913
3914 gsmnet = gsmnet_from_vty(vty);
3915
3916 bts_nr = atoi(argv[0]);
3917 if (bts_nr >= gsmnet->num_bts) {
3918 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3919 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3920 return CMD_WARNING;
3921 }
3922
3923 bts = gsm_bts_num(gsmnet, bts_nr);
3924 if (!bts) {
3925 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3926 return CMD_WARNING;
3927 }
3928
3929 if (!is_ipaccess_bts(bts)) {
3930 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3931 return CMD_WARNING;
3932 }
3933
3934
3935 /* close all connections */
3936 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003937 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003938 } else if (strcmp(argv[1], "rsl") == 0) {
3939 /* close all rsl connections */
3940 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003941 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003942 }
3943 } else {
3944 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3945 return CMD_WARNING;
3946 }
3947
3948 return CMD_SUCCESS;
3949}
3950
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003951DEFUN(restart_bts, restart_bts_cmd,
3952 "restart-bts <0-65535>",
3953 "Restart ip.access nanoBTS through OML\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003954 BTS_NR_STR)
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003955{
3956 struct gsm_network *gsmnet;
3957 struct gsm_bts_trx *trx;
3958 struct gsm_bts *bts;
3959 unsigned int bts_nr;
3960
3961 gsmnet = gsmnet_from_vty(vty);
3962
3963 bts_nr = atoi(argv[0]);
3964 if (bts_nr >= gsmnet->num_bts) {
3965 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3966 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3967 return CMD_WARNING;
3968 }
3969
3970 bts = gsm_bts_num(gsmnet, bts_nr);
3971 if (!bts) {
3972 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3973 return CMD_WARNING;
3974 }
3975
3976 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3977 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3978 VTY_NEWLINE);
3979 return CMD_WARNING;
3980 }
3981
3982 /* go from last TRX to c0 */
3983 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3984 abis_nm_ipaccess_restart(trx);
3985
3986 return CMD_SUCCESS;
3987}
3988
Harald Welte8e2e22f2017-07-10 20:25:10 +02003989DEFUN(bts_resend, bts_resend_cmd,
3990 "bts <0-255> resend-system-information",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003991 "BTS Specific Commands\n" BTS_NR_STR
Harald Welte8e2e22f2017-07-10 20:25:10 +02003992 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3993{
3994 struct gsm_network *gsmnet;
3995 struct gsm_bts_trx *trx;
3996 struct gsm_bts *bts;
3997 unsigned int bts_nr;
3998
3999 gsmnet = gsmnet_from_vty(vty);
4000
4001 bts_nr = atoi(argv[0]);
4002 if (bts_nr >= gsmnet->num_bts) {
4003 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4004 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4005 return CMD_WARNING;
4006 }
4007
4008 bts = gsm_bts_num(gsmnet, bts_nr);
4009 if (!bts) {
4010 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4011 return CMD_WARNING;
4012 }
4013
4014 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4015 gsm_bts_trx_set_system_infos(trx);
4016
4017 return CMD_SUCCESS;
4018}
4019
4020
Harald Welte30f1f372014-12-28 15:00:45 +01004021DEFUN(smscb_cmd, smscb_cmd_cmd,
4022 "bts <0-255> smscb-command <1-4> HEXSTRING",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004023 "BTS related commands\n" BTS_NR_STR
Harald Welte30f1f372014-12-28 15:00:45 +01004024 "SMS Cell Broadcast\n" "Last Valid Block\n"
4025 "Hex Encoded SMSCB message (up to 88 octets)\n")
4026{
4027 struct gsm_bts *bts;
4028 int bts_nr = atoi(argv[0]);
4029 int last_block = atoi(argv[1]);
4030 struct rsl_ie_cb_cmd_type cb_cmd;
4031 uint8_t buf[88];
4032 int rc;
4033
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02004034 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01004035 if (!bts) {
4036 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4037 return CMD_WARNING;
4038 }
4039 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
4040 if (rc < 0 || rc > sizeof(buf)) {
4041 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
4042 return CMD_WARNING;
4043 }
4044
4045 cb_cmd.spare = 0;
4046 cb_cmd.def_bcast = 0;
4047 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
4048
4049 switch (last_block) {
4050 case 1:
4051 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
4052 break;
4053 case 2:
4054 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
4055 break;
4056 case 3:
4057 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
4058 break;
4059 case 4:
4060 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
4061 break;
4062 }
4063
4064 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
4065
4066 return CMD_SUCCESS;
4067}
4068
Harald Welte7fe00fb2017-05-27 14:09:50 +02004069/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02004070static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
4071 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02004072{
Harald Welte645eb622017-05-27 15:52:58 +02004073 int bts_nr = atoi(bts_str);
4074 int trx_nr = atoi(trx_str);
4075 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004076 struct gsm_bts *bts;
4077 struct gsm_bts_trx *trx;
4078 struct gsm_bts_trx_ts *ts;
4079
4080 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
4081 if (!bts) {
4082 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4083 return NULL;
4084 }
4085
4086 trx = gsm_bts_trx_num(bts, trx_nr);
4087 if (!trx) {
4088 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
4089 return NULL;
4090 }
4091
4092 ts = &trx->ts[ts_nr];
4093
4094 return ts;
4095}
Harald Welte30f1f372014-12-28 15:00:45 +01004096
Harald Welted0d2b0b2010-12-23 13:18:07 +01004097DEFUN(pdch_act, pdch_act_cmd,
4098 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004099 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4100 "TRX Timeslot\n" TS_NR_STR "Packet Data Channel\n"
Harald Welted0d2b0b2010-12-23 13:18:07 +01004101 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4102 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4103{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004104 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004105 int activate;
4106
Harald Welte645eb622017-05-27 15:52:58 +02004107 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004108 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004109 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004110
Harald Welte7fe00fb2017-05-27 14:09:50 +02004111 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004112 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4113 VTY_NEWLINE);
4114 return CMD_WARNING;
4115 }
4116
Harald Welted0d2b0b2010-12-23 13:18:07 +01004117 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4118 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004119 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004120 return CMD_WARNING;
4121 }
4122
4123 if (!strcmp(argv[3], "activate"))
4124 activate = 1;
4125 else
4126 activate = 0;
4127
4128 rsl_ipacc_pdch_activate(ts, activate);
4129
4130 return CMD_SUCCESS;
4131
4132}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004133
Harald Welte2abd5e12017-05-27 14:10:40 +02004134/* determine the logical channel type based on the physical channel type */
4135static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4136{
4137 switch (pchan) {
4138 case GSM_PCHAN_TCH_F:
4139 return GSM_LCHAN_TCH_F;
4140 case GSM_PCHAN_TCH_H:
4141 return GSM_LCHAN_TCH_H;
4142 case GSM_PCHAN_SDCCH8_SACCH8C:
4143 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4144 case GSM_PCHAN_CCCH_SDCCH4:
4145 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4146 return GSM_LCHAN_SDCCH;
4147 default:
4148 return -1;
4149 }
4150}
4151
4152/* configure the lchan for a single AMR mode (as specified) */
4153static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4154{
4155 struct amr_multirate_conf mr;
4156 struct gsm48_multi_rate_conf *mr_conf;
4157 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4158
4159 if (amr_mode > 7)
4160 return -1;
4161
4162 memset(&mr, 0, sizeof(mr));
4163 mr_conf->ver = 1;
4164 /* bit-mask of supported modes, only one bit is set. Reflects
4165 * Figure 10.5.2.47a where there are no thershold and only a
4166 * single mode */
4167 mr.gsm48_ie[1] = 1 << amr_mode;
4168
4169 mr.ms_mode[0].mode = amr_mode;
4170 mr.bts_mode[0].mode = amr_mode;
4171
4172 /* encode this configuration into the lchan for both uplink and
4173 * downlink direction */
4174 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4175 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4176
4177 return 0;
4178}
4179
4180/* Debug/Measurement command to activate a given logical channel
4181 * manually in a given mode/codec. This is useful for receiver
4182 * performance testing (FER/RBER/...) */
4183DEFUN(lchan_act, lchan_act_cmd,
4184 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (activate|deactivate) (hr|fr|efr|amr) [<0-7>]",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004185 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4186 "TRX Timeslot\n" TS_NR_STR "Sub-Slot Number\n" LCHAN_NR_STR
Harald Welte2abd5e12017-05-27 14:10:40 +02004187 "Manual Channel Activation (e.g. for BER test)\n"
4188 "Manual Channel Deactivation (e.g. for BER test)\n"
4189 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4190{
4191 struct gsm_bts_trx_ts *ts;
4192 struct gsm_lchan *lchan;
4193 int ss_nr = atoi(argv[3]);
4194 const char *act_str = argv[4];
4195 const char *codec_str = argv[5];
4196 int activate;
4197
4198 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4199 if (!ts)
4200 return CMD_WARNING;
4201
4202 lchan = &ts->lchan[ss_nr];
4203
4204 if (!strcmp(act_str, "activate"))
4205 activate = 1;
4206 else
4207 activate = 0;
4208
4209 if (ss_nr >= ts_subslots(ts)) {
4210 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4211 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4212 return CMD_WARNING;
4213 }
4214
4215 if (activate) {
4216 int lchan_t;
4217 if (lchan->state != LCHAN_S_NONE) {
4218 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4219 return CMD_WARNING;
4220 }
4221 lchan_t = lchan_type_by_pchan(ts->pchan);
4222 if (lchan_t < 0)
4223 return CMD_WARNING;
4224 /* configure the lchan */
4225 lchan->type = lchan_t;
4226 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4227 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4228 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4229 else if (!strcmp(codec_str, "efr"))
4230 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4231 else if (!strcmp(codec_str, "amr")) {
4232 int amr_mode;
4233 if (argc < 7) {
4234 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4235 return CMD_WARNING;
4236 }
4237 amr_mode = atoi(argv[6]);
4238 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4239 lchan_set_single_amr_mode(lchan, amr_mode);
4240 }
4241 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4242 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4243 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004244 } else {
4245 rsl_direct_rf_release(lchan);
4246 }
4247
4248 return CMD_SUCCESS;
4249}
4250
Harald Welte3f86c522017-05-27 15:53:28 +02004251DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4252 "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004253 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4254 "TRX Timeslot\n" TS_NR_STR "Sub-Slot\n" LCHAN_NR_STR
Harald Welte3f86c522017-05-27 15:53:28 +02004255 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4256{
4257 struct gsm_bts_trx_ts *ts;
4258 struct gsm_lchan *lchan;
4259 int ss_nr = atoi(argv[3]);
4260 int port = atoi(argv[5]);
4261 struct in_addr ia;
4262 inet_aton(argv[4], &ia);
4263
4264 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4265 if (!ts)
4266 return CMD_WARNING;
4267
4268 lchan = &ts->lchan[ss_nr];
4269
4270 if (ss_nr >= ts_subslots(ts)) {
4271 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4272 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4273 return CMD_WARNING;
4274 }
4275
4276 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4277 inet_ntoa(ia), port, VTY_NEWLINE);
4278 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4279 return CMD_SUCCESS;
4280}
Harald Welteb71147a2017-07-18 19:11:49 +02004281
4282DEFUN(ctrl_trap, ctrl_trap_cmd,
4283 "ctrl-interface generate-trap TRAP VALUE",
4284 "Commands related to the CTRL Interface\n"
4285 "Generate a TRAP for test purpose\n"
4286 "Identity/Name of the TRAP variable\n"
4287 "Value of the TRAP variable\n")
4288{
4289 struct gsm_network *net = gsmnet_from_vty(vty);
4290
4291 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4292 return CMD_SUCCESS;
4293}
4294
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004295#define NETWORK_STR "Configure the GSM network\n"
4296#define CODE_CMD_STR "Code commands\n"
4297#define NAME_CMD_STR "Name Commands\n"
4298#define NAME_STR "Name to use\n"
4299
4300DEFUN(cfg_net,
4301 cfg_net_cmd,
4302 "network", NETWORK_STR)
4303{
4304 vty->index = gsmnet_from_vty(vty);
4305 vty->node = GSMNET_NODE;
4306
4307 return CMD_SUCCESS;
4308}
4309
4310DEFUN(cfg_net_ncc,
4311 cfg_net_ncc_cmd,
4312 "network country code <1-999>",
4313 "Set the GSM network country code\n"
4314 "Country commands\n"
4315 CODE_CMD_STR
4316 "Network Country Code to use\n")
4317{
4318 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4319
4320 gsmnet->country_code = atoi(argv[0]);
4321
4322 return CMD_SUCCESS;
4323}
4324
4325DEFUN(cfg_net_mnc,
4326 cfg_net_mnc_cmd,
4327 "mobile network code <0-999>",
4328 "Set the GSM mobile network code\n"
4329 "Network Commands\n"
4330 CODE_CMD_STR
4331 "Mobile Network Code to use\n")
4332{
4333 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4334
4335 gsmnet->network_code = atoi(argv[0]);
4336
4337 return CMD_SUCCESS;
4338}
4339
4340DEFUN(cfg_net_encryption,
4341 cfg_net_encryption_cmd,
4342 "encryption a5 (0|1|2|3)",
4343 "Encryption options\n"
4344 "A5 encryption\n" "A5/0: No encryption\n"
4345 "A5/1: Encryption\n" "A5/2: Export-grade Encryption\n"
4346 "A5/3: 'New' Secure Encryption\n")
4347{
4348 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4349
4350 gsmnet->a5_encryption = atoi(argv[0]);
4351
4352 return CMD_SUCCESS;
4353}
4354
4355DEFUN(cfg_net_dyn_ts_allow_tch_f,
4356 cfg_net_dyn_ts_allow_tch_f_cmd,
4357 "dyn_ts_allow_tch_f (0|1)",
4358 "Allow or disallow allocating TCH/F on TCH_F_TCH_H_PDCH timeslots\n"
4359 "Disallow TCH/F on TCH_F_TCH_H_PDCH (default)\n"
4360 "Allow TCH/F on TCH_F_TCH_H_PDCH\n")
4361{
4362 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4363 gsmnet->dyn_ts_allow_tch_f = atoi(argv[0]) ? true : false;
4364 return CMD_SUCCESS;
4365}
4366
4367DEFUN(cfg_net_timezone,
4368 cfg_net_timezone_cmd,
4369 "timezone <-19-19> (0|15|30|45)",
4370 "Set the Timezone Offset of the network\n"
4371 "Timezone offset (hours)\n"
4372 "Timezone offset (00 minutes)\n"
4373 "Timezone offset (15 minutes)\n"
4374 "Timezone offset (30 minutes)\n"
4375 "Timezone offset (45 minutes)\n"
4376 )
4377{
4378 struct gsm_network *net = vty->index;
4379 int tzhr = atoi(argv[0]);
4380 int tzmn = atoi(argv[1]);
4381
4382 net->tz.hr = tzhr;
4383 net->tz.mn = tzmn;
4384 net->tz.dst = 0;
4385 net->tz.override = 1;
4386
4387 return CMD_SUCCESS;
4388}
4389
4390DEFUN(cfg_net_timezone_dst,
4391 cfg_net_timezone_dst_cmd,
4392 "timezone <-19-19> (0|15|30|45) <0-2>",
4393 "Set the Timezone Offset of the network\n"
4394 "Timezone offset (hours)\n"
4395 "Timezone offset (00 minutes)\n"
4396 "Timezone offset (15 minutes)\n"
4397 "Timezone offset (30 minutes)\n"
4398 "Timezone offset (45 minutes)\n"
4399 "DST offset (hours)\n"
4400 )
4401{
4402 struct gsm_network *net = vty->index;
4403 int tzhr = atoi(argv[0]);
4404 int tzmn = atoi(argv[1]);
4405 int tzdst = atoi(argv[2]);
4406
4407 net->tz.hr = tzhr;
4408 net->tz.mn = tzmn;
4409 net->tz.dst = tzdst;
4410 net->tz.override = 1;
4411
4412 return CMD_SUCCESS;
4413}
4414
4415DEFUN(cfg_net_no_timezone,
4416 cfg_net_no_timezone_cmd,
4417 "no timezone",
4418 NO_STR
4419 "Disable network timezone override, use system tz\n")
4420{
4421 struct gsm_network *net = vty->index;
4422
4423 net->tz.override = 0;
4424
4425 return CMD_SUCCESS;
4426}
4427
4428DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
4429 "periodic location update <6-1530>",
4430 "Periodic Location Updating Interval\n"
4431 "Periodic Location Updating Interval\n"
4432 "Periodic Location Updating Interval\n"
4433 "Periodic Location Updating Interval in Minutes\n")
4434{
4435 struct gsm_network *net = vty->index;
4436
4437 net->t3212 = atoi(argv[0]) / 6;
4438
4439 return CMD_SUCCESS;
4440}
4441
4442DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
4443 "no periodic location update",
4444 NO_STR
4445 "Periodic Location Updating Interval\n"
4446 "Periodic Location Updating Interval\n"
4447 "Periodic Location Updating Interval\n")
4448{
4449 struct gsm_network *net = vty->index;
4450
4451 net->t3212 = 0;
4452
4453 return CMD_SUCCESS;
4454}
4455
Harald Weltedcccb182010-05-16 20:52:23 +02004456extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004457
Maxdb0e3802017-01-12 19:35:11 +01004458int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004459{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004460 cfg_ts_pchan_cmd.string =
4461 vty_cmd_string_from_valstr(tall_bsc_ctx,
4462 gsm_pchant_names,
4463 "phys_chan_config (", "|", ")",
4464 VTY_DO_LOWER);
4465 cfg_ts_pchan_cmd.doc =
4466 vty_cmd_string_from_valstr(tall_bsc_ctx,
4467 gsm_pchant_descs,
4468 "Physical Channel Combination\n",
4469 "\n", "", 0);
4470
Harald Weltee555c2b2012-08-17 13:02:12 +02004471 cfg_bts_type_cmd.string =
4472 vty_cmd_string_from_valstr(tall_bsc_ctx,
4473 bts_type_names,
4474 "type (", "|", ")",
4475 VTY_DO_LOWER);
4476 cfg_bts_type_cmd.doc =
4477 vty_cmd_string_from_valstr(tall_bsc_ctx,
4478 bts_type_descs,
4479 "BTS Vendor/Type\n",
4480 "\n", "", 0);
4481
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004482 OSMO_ASSERT(vty_global_gsm_network == NULL);
4483 vty_global_gsm_network = network;
4484
4485 osmo_stats_vty_add_cmds();
4486
4487 install_element(CONFIG_NODE, &cfg_net_cmd);
4488 install_node(&net_node, config_write_net);
4489 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
4490 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
4491 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
4492 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
4493 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
4494 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
4495 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
4496 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
4497 install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);
Harald Weltee555c2b2012-08-17 13:02:12 +02004498
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004499 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004500 install_element_ve(&show_bts_cmd);
4501 install_element_ve(&show_trx_cmd);
4502 install_element_ve(&show_ts_cmd);
4503 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004504 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004505
Philipp Maier39f62bb2017-04-09 12:32:51 +02004506 install_element_ve(&show_subscr_conn_cmd);
4507 install_element_ve(&handover_subscr_conn_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004508 install_element_ve(&handover_any_cmd);
4509 install_element_ve(&assignment_subscr_conn_cmd);
4510 install_element_ve(&assignment_any_cmd);
Philipp Maier39f62bb2017-04-09 12:32:51 +02004511
Harald Welteb4d5b172010-05-12 16:10:35 +00004512 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004513 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004514
Maxdb0e3802017-01-12 19:35:11 +01004515 logging_vty_add_cmds(NULL);
Harald Welte2f4f4b82018-02-14 00:50:27 +01004516 osmo_talloc_vty_add_cmds();
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004517
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004518 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004519 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004520 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4521 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4522 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4523 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4524 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4525 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4526 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4527 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4528 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004529 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004530 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004531 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004532 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004533 /* See also handover commands added on net level from handover_vty.c */
Harald Welte5013b2a2009-08-07 13:29:14 +02004534
4535 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004536 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004537 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004538 install_element(BTS_NODE, &cfg_description_cmd);
4539 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004540 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004541 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004542 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4543 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4544 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4545 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004546 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4547 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004548 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004549 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004550 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004551 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004552 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004553 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004554 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004555 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4556 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004557 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004558 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4559 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004560 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4561 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4562 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004563 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4564 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004565 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004566 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004567 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004568 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004569 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4570 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004571 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4572 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4573 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4574 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4575 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4576 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004577 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004578 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004579 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304580 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004581 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004582 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004583 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004584 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4585 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004586 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004587 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004588 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004589 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004590 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4591 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4592 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004593 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004594 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4595 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004596 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004597 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004598 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4599 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004600 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004601 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4602 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004603 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4604 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004605 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4606 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004607 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4608 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004609 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4610 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4611 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4612 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4613 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004614 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4615 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004616 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4617 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4618 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4619 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4620 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4621 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4622 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4623 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4624 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4625 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4626 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4627 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4628 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4629 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4630 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4631 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4632 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4633 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4634 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4635 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4636 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4637 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004638 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004639 /* See also handover commands added on bts level from handover_vty.c */
Harald Welte68628e82009-03-10 12:17:57 +00004640
Harald Welte5258fc42009-03-28 19:07:53 +00004641 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004642 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004643 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004644 install_element(TRX_NODE, &cfg_description_cmd);
4645 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004646 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004647 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004648 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4649 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004650 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004651
Harald Welte5258fc42009-03-28 19:07:53 +00004652 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004653 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004654 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004655 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004656 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004657 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004658 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4659 install_element(TS_NODE, &cfg_ts_maio_cmd);
4660 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4661 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004662 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004663
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004664 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004665 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004666 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004667 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004668 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004669 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004670 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004671 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004672
Harald Welte81c9b9c2010-05-31 16:40:40 +02004673 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004674 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004675 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004676 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004677
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004678 ho_vty_init();
4679
Harald Weltedcccb182010-05-16 20:52:23 +02004680 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004681
Harald Welte68628e82009-03-10 12:17:57 +00004682 return 0;
4683}