blob: a71935878a7f06d29417a64fd1c5ee726be65006 [file] [log] [blame]
Harald Welte68628e82009-03-10 12:17:57 +00001/* OpenBSC interface to quagga VTY */
Harald Welteaf387632010-03-14 23:30:30 +08002/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte68628e82009-03-10 12:17:57 +00003 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01006 * it under the terms of the GNU Affero General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
Harald Welte68628e82009-03-10 12:17:57 +00008 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010013 * GNU Affero General Public License for more details.
Harald Welte68628e82009-03-10 12:17:57 +000014 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010015 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte68628e82009-03-10 12:17:57 +000017 *
18 */
19
20#include <stdlib.h>
Maxc08ee712016-05-11 12:45:13 +020021#include <stdbool.h>
Harald Welte68628e82009-03-10 12:17:57 +000022#include <unistd.h>
Maxd1f70ed2017-09-21 16:15:32 +020023#include <time.h>
Harald Welte68628e82009-03-10 12:17:57 +000024
Harald Welte4b037e42010-05-19 19:45:32 +020025#include <osmocom/vty/command.h>
26#include <osmocom/vty/buffer.h>
27#include <osmocom/vty/vty.h>
28#include <osmocom/vty/logging.h>
Jacob Erlbeck64630cc2015-10-26 16:25:37 +010029#include <osmocom/vty/stats.h>
Harald Welte4b037e42010-05-19 19:45:32 +020030#include <osmocom/vty/telnet_interface.h>
Harald Welte4ab9d7c2012-08-17 12:42:06 +020031#include <osmocom/vty/misc.h>
Maxc08ee712016-05-11 12:45:13 +020032#include <osmocom/gsm/protocol/gsm_04_08.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010033#include <osmocom/gsm/gsm0502.h>
Harald Welteb71147a2017-07-18 19:11:49 +020034#include <osmocom/ctrl/control_if.h>
Neels Hofmeyr7b656882017-07-09 22:09:18 +020035#include <osmocom/gsm/gsm48.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010036
Harald Welte68628e82009-03-10 12:17:57 +000037#include <arpa/inet.h>
38
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010039#include <osmocom/core/linuxlist.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020040#include <osmocom/bsc/gsm_data.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020041#include <osmocom/abis/e1_input.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020042#include <osmocom/bsc/abis_nm.h>
43#include <osmocom/bsc/abis_om2000.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010044#include <osmocom/core/utils.h>
45#include <osmocom/gsm/gsm_utils.h>
Harald Weltecdc59ff2011-05-23 20:42:26 +020046#include <osmocom/gsm/abis_nm.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020047#include <osmocom/bsc/chan_alloc.h>
48#include <osmocom/bsc/meas_rep.h>
49#include <osmocom/bsc/vty.h>
Harald Welteea34a4e2012-06-16 14:59:56 +080050#include <osmocom/gprs/gprs_ns.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020051#include <osmocom/bsc/system_information.h>
52#include <osmocom/bsc/debug.h>
53#include <osmocom/bsc/paging.h>
54#include <osmocom/bsc/ipaccess.h>
55#include <osmocom/bsc/abis_rsl.h>
56#include <osmocom/bsc/bsc_msc_data.h>
57#include <osmocom/bsc/osmo_bsc_rf.h>
58#include <osmocom/bsc/pcu_if.h>
59#include <osmocom/bsc/common_cs.h>
60#include <osmocom/bsc/handover.h>
Neels Hofmeyre25018b2017-11-27 21:29:33 +010061#include <osmocom/bsc/handover_cfg.h>
62#include <osmocom/bsc/handover_vty.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020063#include <osmocom/bsc/gsm_04_08_utils.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020064
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010065#include <inttypes.h>
66
Harald Weltec08e8be2011-03-04 13:53:51 +010067#include "../../bscconfig.h"
Harald Welte1353f962010-05-16 19:20:24 +020068
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010069#define BTS_NR_STR "BTS Number\n"
70#define TRX_NR_STR "TRX Number\n"
71#define TS_NR_STR "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020072#define LCHAN_NR_STR "Logical Channel Number\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010073#define BTS_TRX_STR BTS_NR_STR TRX_NR_STR
74#define BTS_TRX_TS_STR BTS_TRX_STR TS_NR_STR
75#define BTS_TRX_TS_LCHAN_STR BTS_TRX_TS_STR LCHAN_NR_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020076
Harald Welteea4647d2010-05-12 17:19:53 +000077/* FIXME: this should go to some common file */
78static const struct value_string gprs_ns_timer_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020079 { 0, "tns-block" },
80 { 1, "tns-block-retries" },
81 { 2, "tns-reset" },
82 { 3, "tns-reset-retries" },
83 { 4, "tns-test" },
84 { 5, "tns-alive" },
85 { 6, "tns-alive-retries" },
86 { 0, NULL }
87};
88
Harald Welteea4647d2010-05-12 17:19:53 +000089static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020090 { 0, "blocking-timer" },
91 { 1, "blocking-retries" },
92 { 2, "unblocking-retries" },
93 { 3, "reset-timer" },
94 { 4, "reset-retries" },
95 { 5, "suspend-timer" },
96 { 6, "suspend-retries" },
97 { 7, "resume-timer" },
98 { 8, "resume-retries" },
99 { 9, "capability-update-timer" },
100 { 10, "capability-update-retries" },
101 { 0, NULL }
102};
103
Harald Welte64c07d22011-02-15 11:43:27 +0100104static const struct value_string bts_neigh_mode_strs[] = {
105 { NL_MODE_AUTOMATIC, "automatic" },
106 { NL_MODE_MANUAL, "manual" },
107 { NL_MODE_MANUAL_SI5SEP, "manual-si5" },
108 { 0, NULL }
109};
110
Daniel Willmann7d109832012-05-14 18:43:23 +0200111const struct value_string bts_loc_fix_names[] = {
112 { BTS_LOC_FIX_INVALID, "invalid" },
113 { BTS_LOC_FIX_2D, "fix2d" },
114 { BTS_LOC_FIX_3D, "fix3d" },
115 { 0, NULL }
116};
117
Harald Welte68628e82009-03-10 12:17:57 +0000118struct cmd_node bts_node = {
119 BTS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200120 "%s(config-net-bts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000121 1,
122};
123
124struct cmd_node trx_node = {
125 TRX_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200126 "%s(config-net-bts-trx)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000127 1,
128};
129
130struct cmd_node ts_node = {
131 TS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200132 "%s(config-net-bts-trx-ts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000133 1,
134};
135
136static int dummy_config_write(struct vty *v)
137{
138 return CMD_SUCCESS;
139}
140
141static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
142{
Harald Welte1304b352013-03-15 16:57:33 +0100143 vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
144 abis_nm_opstate_name(nms->operational),
145 get_value_string(abis_nm_adm_state_names, nms->administrative),
Harald Welte867d9f32011-05-23 20:30:39 +0200146 abis_nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000147}
148
Harald Welteb908cb72009-12-22 13:09:29 +0100149static void dump_pchan_load_vty(struct vty *vty, char *prefix,
150 const struct pchan_load *pl)
151{
152 int i;
153
154 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
155 const struct load_counter *lc = &pl->pchan[i];
156 unsigned int percent;
157
158 if (lc->total == 0)
159 continue;
160
161 percent = (lc->used * 100) / lc->total;
162
163 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
164 gsm_pchan_name(i), percent, lc->used, lc->total,
165 VTY_NEWLINE);
166 }
167}
168
Harald Welte68628e82009-03-10 12:17:57 +0000169static void net_dump_vty(struct vty *vty, struct gsm_network *net)
170{
Harald Welteb908cb72009-12-22 13:09:29 +0100171 struct pchan_load pl;
172
Harald Welteef235b52009-03-10 12:34:02 +0000173 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
174 "and has %u BTS%s", net->country_code, net->network_code,
175 net->num_bts, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200176 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900177 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
178 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100179 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
180 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800181 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
182 VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100183
184 {
185 struct gsm_bts *bts;
186 unsigned int ho_active_count = 0;
187 unsigned int ho_inactive_count = 0;
188
189 llist_for_each_entry(bts, &net->bts_list, list) {
190 if (ho_get_ho_active(bts->ho))
191 ho_active_count ++;
192 else
193 ho_inactive_count ++;
194 }
195
196 if (ho_active_count && ho_inactive_count)
197 vty_out(vty, " Handover: On at %u BTS, Off at %u BTS%s",
198 ho_active_count, ho_inactive_count, VTY_NEWLINE);
199 else
200 vty_out(vty, " Handover: %s%s", ho_active_count ? "On" : "Off",
201 VTY_NEWLINE);
202 }
203
Harald Welteb908cb72009-12-22 13:09:29 +0100204 network_chan_load(&pl, net);
205 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
206 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100207
208 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100209 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100210 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200211 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100212 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100213 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200214 vty_out(vty, " Last RF Lock Command: %s%s",
215 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
216 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000217}
218
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200219DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000220 SHOW_STR "Display information about a GSM NETWORK\n")
221{
Harald Weltedcccb182010-05-16 20:52:23 +0200222 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000223 net_dump_vty(vty, net);
224
225 return CMD_SUCCESS;
226}
227
228static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
229{
Harald Welteedb37782009-05-01 14:59:07 +0000230 struct e1inp_line *line;
231
232 if (!e1l) {
233 vty_out(vty, " None%s", VTY_NEWLINE);
234 return;
235 }
236
237 line = e1l->ts->line;
238
239 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
240 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000241 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000242 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000243 e1l->tei, e1l->sapi, VTY_NEWLINE);
244}
245
246static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
247{
Harald Welteb908cb72009-12-22 13:09:29 +0100248 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200249 unsigned long long sec;
Harald Welteb908cb72009-12-22 13:09:29 +0100250
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200251 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100252 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200253 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200254 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100255 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100256 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200257 bts->num_trx, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200258 vty_out(vty, "Description: %s%s",
259 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Maxf9685c12017-03-23 12:01:07 +0100260 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
261 vty_out(vty, "PCU version %s connected%s", bts->pcu_version,
262 VTY_NEWLINE);
Harald Welte1d8dbc42009-12-12 15:38:16 +0100263 vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100264 vty_out(vty, "Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100265 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
266 VTY_NEWLINE);
267 vty_out(vty, "Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100268 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100269 vty_out(vty, "RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
270 VTY_NEWLINE);
271 vty_out(vty, "RACH Max transmissions: %u%s",
272 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
273 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100274 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200275 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200276 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
277 vty_out(vty, "Uplink DTX: %s%s",
278 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
279 "enabled" : "forced", VTY_NEWLINE);
280 else
281 vty_out(vty, "Uplink DTX: not enabled%s", VTY_NEWLINE);
282 vty_out(vty, "Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
283 VTY_NEWLINE);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200284 vty_out(vty, "Channel Description Attachment: %s%s",
285 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
286 vty_out(vty, "Channel Description BS-PA-MFRMS: %u%s",
287 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
288 vty_out(vty, "Channel Description BS-AG_BLKS-RES: %u%s",
289 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200290 vty_out(vty, "System Information present: 0x%08x, static: 0x%08x%s",
291 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100292 vty_out(vty, "Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100293 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100294 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
295 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
296 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100297 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200298 if (bts->pcu_sock_path)
299 vty_out(vty, "PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000300 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200301 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000302 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200303 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200304 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
305 vty_out(vty, " Skip Reset: %d%s",
306 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000307 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200308 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000309 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200310 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200311 vty_out(vty, " GPRS NSE: ");
312 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
313 vty_out(vty, " GPRS CELL: ");
314 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
315 vty_out(vty, " GPRS NSVC0: ");
316 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
317 vty_out(vty, " GPRS NSVC1: ");
318 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200319 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
320 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000321 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100322 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200323 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200324 sec = bts_uptime(bts);
325 if (sec)
Maxff3fad12018-01-07 16:50:42 +0100326 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.",
327 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60);
328 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100329 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200330 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
331 e1isl_dump_vty(vty, bts->oml_link);
332 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100333
334 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100335 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200336 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100337 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
338 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100339
340 vty_out(vty, "Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
341 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
342 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
343 VTY_NEWLINE);
344 vty_out(vty, "Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
345 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
346 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
347 VTY_NEWLINE);
348 vty_out(vty, "BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
349 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
350 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
351 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000352}
353
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100354DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000355 SHOW_STR "Display information about a BTS\n"
356 "BTS number")
357{
Harald Weltedcccb182010-05-16 20:52:23 +0200358 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000359 int bts_nr;
360
361 if (argc != 0) {
362 /* use the BTS number that the user has specified */
363 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100364 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000365 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000366 VTY_NEWLINE);
367 return CMD_WARNING;
368 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200369 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000370 return CMD_SUCCESS;
371 }
372 /* print all BTS's */
373 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200374 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000375
376 return CMD_SUCCESS;
377}
378
Harald Welte42581822009-08-08 16:12:58 +0200379/* utility functions */
380static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
381 const char *ts, const char *ss)
382{
383 e1_link->e1_nr = atoi(line);
384 e1_link->e1_ts = atoi(ts);
385 if (!strcmp(ss, "full"))
386 e1_link->e1_ts_ss = 255;
387 else
388 e1_link->e1_ts_ss = atoi(ss);
389}
390
391static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
392 const char *prefix)
393{
394 if (!e1_link->e1_ts)
395 return;
396
397 if (e1_link->e1_ts_ss == 255)
398 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
399 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
400 else
401 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
402 prefix, e1_link->e1_nr, e1_link->e1_ts,
403 e1_link->e1_ts_ss, VTY_NEWLINE);
404}
405
406
Harald Welte67ce0732009-08-06 19:06:46 +0200407static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
408{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100409 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100410 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100411 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200412 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100413 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200414 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100415 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200416 ts->hopping.enabled, VTY_NEWLINE);
417 if (ts->hopping.enabled) {
418 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100419 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200420 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100421 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200422 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200423 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
424 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
425 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100426 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200427 i, VTY_NEWLINE);
428 }
Harald Welte127af342010-12-24 12:07:07 +0100429 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100430 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100431
432 if (ts->trx->bts->model->config_write_ts)
433 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200434}
435
436static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
437{
438 int i;
439
Harald Welte5013b2a2009-08-07 13:29:14 +0200440 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200441 if (trx->description)
442 vty_out(vty, " description %s%s", trx->description,
443 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200444 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200445 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200446 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200447 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100448 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200449 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200450 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
451 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200452
Harald Welteface7ed2011-02-14 16:15:21 +0100453 if (trx->bts->model->config_write_trx)
454 trx->bts->model->config_write_trx(vty, trx);
455
Harald Welte67ce0732009-08-06 19:06:46 +0200456 for (i = 0; i < TRX_NR_TS; i++)
457 config_write_ts_single(vty, &trx->ts[i]);
458}
459
Harald Welte615e9562010-05-11 23:50:21 +0200460static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
461{
462 unsigned int i;
463 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
464 VTY_NEWLINE);
465 if (bts->gprs.mode == BTS_GPRS_NONE)
466 return;
467
bhargava350533c2016-07-21 11:14:34 +0530468 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
469 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
470
Harald Welte615e9562010-05-11 23:50:21 +0200471 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
472 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100473 vty_out(vty, " gprs network-control-order nc%u%s",
474 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200475 if (!bts->gprs.ctrl_ack_type_use_block)
476 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200477 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
478 VTY_NEWLINE);
479 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
480 vty_out(vty, " gprs cell timer %s %u%s",
481 get_value_string(gprs_bssgp_cfg_strs, i),
482 bts->gprs.cell.timer[i], VTY_NEWLINE);
483 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
484 VTY_NEWLINE);
485 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
486 vty_out(vty, " gprs ns timer %s %u%s",
487 get_value_string(gprs_ns_timer_strs, i),
488 bts->gprs.nse.timer[i], VTY_NEWLINE);
489 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
490 struct gsm_bts_gprs_nsvc *nsvc =
491 &bts->gprs.nsvc[i];
492 struct in_addr ia;
493
494 ia.s_addr = htonl(nsvc->remote_ip);
495 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
496 nsvc->nsvci, VTY_NEWLINE);
497 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
498 nsvc->local_port, VTY_NEWLINE);
499 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
500 nsvc->remote_port, VTY_NEWLINE);
501 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
502 inet_ntoa(ia), VTY_NEWLINE);
503 }
504}
505
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200506/* Write the model data if there is one */
507static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200508{
509 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200510
511 if (!bts->model)
512 return;
513
514 if (bts->model->config_write_bts)
515 bts->model->config_write_bts(vty, bts);
516
517 llist_for_each_entry(trx, &bts->trx_list, list)
518 config_write_trx_single(vty, trx);
519}
520
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200521static void write_amr_modes(struct vty *vty, const char *prefix,
522 const char *name, struct amr_mode *modes, int num)
523{
524 int i;
525
526 vty_out(vty, " %s threshold %s", prefix, name);
527 for (i = 0; i < num - 1; i++)
528 vty_out(vty, " %d", modes[i].threshold);
529 vty_out(vty, "%s", VTY_NEWLINE);
530 vty_out(vty, " %s hysteresis %s", prefix, name);
531 for (i = 0; i < num - 1; i++)
532 vty_out(vty, " %d", modes[i].hysteresis);
533 vty_out(vty, "%s", VTY_NEWLINE);
534}
535
Andreas Eversberg73266522014-01-19 11:47:44 +0100536static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
537 struct amr_multirate_conf *mr, int full)
538{
539 struct gsm48_multi_rate_conf *mr_conf;
540 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
541 int i, num;
542
543 if (!(mr->gsm48_ie[1]))
544 return;
545
546 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
547
548 num = 0;
549 vty_out(vty, " %s modes", prefix);
550 for (i = 0; i < ((full) ? 8 : 6); i++) {
551 if ((mr->gsm48_ie[1] & (1 << i))) {
552 vty_out(vty, " %d", i);
553 num++;
554 }
555 }
556 vty_out(vty, "%s", VTY_NEWLINE);
557 if (num > 4)
558 num = 4;
559 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200560 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
561 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100562 }
563 vty_out(vty, " %s start-mode ", prefix);
564 if (mr_conf->icmi) {
565 num = 0;
566 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
567 if ((mr->gsm48_ie[1] & (1 << i)))
568 num++;
569 if (mr_conf->smod == num - 1) {
570 vty_out(vty, "%d%s", num, VTY_NEWLINE);
571 break;
572 }
573 }
574 } else
575 vty_out(vty, "auto%s", VTY_NEWLINE);
576}
577
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200578static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
579{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200580 int i;
Max2c16bee2017-02-15 13:51:37 +0100581 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200582
Harald Welte5013b2a2009-08-07 13:29:14 +0200583 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
584 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200585 if (bts->description)
586 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200587 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100588 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200589 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200590 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200591 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
592 vty_out(vty, " dtx uplink%s%s",
593 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
594 VTY_NEWLINE);
595 if (bts->dtxd)
596 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200597 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200598 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100599 vty_out(vty, " cell reselection hysteresis %u%s",
600 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
601 vty_out(vty, " rxlev access min %u%s",
602 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100603
604 if (bts->si_common.cell_ro_sel_par.present) {
605 struct gsm48_si_selection_params *sp;
606 sp = &bts->si_common.cell_ro_sel_par;
607
608 if (sp->cbq)
609 vty_out(vty, " cell bar qualify %u%s",
610 sp->cbq, VTY_NEWLINE);
611
612 if (sp->cell_resel_off)
613 vty_out(vty, " cell reselection offset %u%s",
614 sp->cell_resel_off*2, VTY_NEWLINE);
615
616 if (sp->temp_offs == 7)
617 vty_out(vty, " temporary offset infinite%s",
618 VTY_NEWLINE);
619 else if (sp->temp_offs)
620 vty_out(vty, " temporary offset %u%s",
621 sp->temp_offs*10, VTY_NEWLINE);
622
623 if (sp->penalty_time == 31)
624 vty_out(vty, " penalty time reserved%s",
625 VTY_NEWLINE);
626 else if (sp->penalty_time)
627 vty_out(vty, " penalty time %u%s",
628 (sp->penalty_time*20)+20, VTY_NEWLINE);
629 }
630
Harald Welte2f8b9d22017-06-18 11:12:13 +0300631 if (gsm_bts_get_radio_link_timeout(bts) < 0)
632 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
633 else
634 vty_out(vty, " radio-link-timeout %d%s",
635 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100636
Harald Welte7a8fa412009-08-10 13:48:16 +0200637 vty_out(vty, " channel allocator %s%s",
638 bts->chan_alloc_reverse ? "descending" : "ascending",
639 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100640 vty_out(vty, " rach tx integer %u%s",
641 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
642 vty_out(vty, " rach max transmission %u%s",
643 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
644 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800645
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200646 vty_out(vty, " channel-descrption attach %u%s",
647 bts->si_common.chan_desc.att, VTY_NEWLINE);
648 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
649 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
650 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
651 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
652
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800653 if (bts->rach_b_thresh != -1)
654 vty_out(vty, " rach nm busy threshold %u%s",
655 bts->rach_b_thresh, VTY_NEWLINE);
656 if (bts->rach_ldavg_slots != -1)
657 vty_out(vty, " rach nm load average %u%s",
658 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100659 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200660 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800661 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
662 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400663 if ((bts->si_common.rach_control.t3) != 0)
664 for (i = 0; i < 8; i++)
665 if (bts->si_common.rach_control.t3 & (0x1 << i))
666 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
667 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
668 for (i = 0; i < 8; i++)
669 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
670 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200671 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
672 if (bts->si_mode_static & (1 << i)) {
673 vty_out(vty, " system-information %s mode static%s",
674 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
675 vty_out(vty, " system-information %s static %s%s",
676 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200677 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200678 VTY_NEWLINE);
679 }
680 }
Harald Welte42def722017-01-13 00:10:32 +0100681 vty_out(vty, " early-classmark-sending %s%s",
682 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100683 vty_out(vty, " early-classmark-sending-3g %s%s",
684 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100685 switch (bts->type) {
686 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100687 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200688 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200689 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100690 if (bts->ip_access.rsl_ip) {
691 struct in_addr ia;
692 ia.s_addr = htonl(bts->ip_access.rsl_ip);
693 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
694 VTY_NEWLINE);
695 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200696 vty_out(vty, " oml ip.access stream_id %u line %u%s",
697 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100698 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200699 case GSM_BTS_TYPE_NOKIA_SITE:
700 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100701 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
702 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100703 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 +0100704 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100705 default:
Harald Welte42581822009-08-08 16:12:58 +0200706 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
707 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100708 break;
Harald Welte42581822009-08-08 16:12:58 +0200709 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800710
711 /* if we have a limit, write it */
712 if (bts->paging.free_chans_need >= 0)
713 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
714
Harald Welte32c09622011-01-11 23:44:56 +0100715 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100716 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
717 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100718 for (i = 0; i < 1024; i++) {
719 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
720 vty_out(vty, " neighbor-list add arfcn %u%s",
721 i, VTY_NEWLINE);
722 }
723 }
Harald Welte64c07d22011-02-15 11:43:27 +0100724 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
725 for (i = 0; i < 1024; i++) {
726 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
727 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
728 i, VTY_NEWLINE);
729 }
730 }
Harald Welte32c09622011-01-11 23:44:56 +0100731
Max59a1bf32016-04-15 16:04:46 +0200732 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100733 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
734 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
735 vty_out(vty, " si2quater neighbor-list add earfcn %u "
736 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
737
738 vty_out(vty, " thresh-lo %u",
739 e->thresh_lo_valid ? e->thresh_lo : 32);
740
741 vty_out(vty, " prio %u",
742 e->prio_valid ? e->prio : 8);
743
744 vty_out(vty, " qrxlv %u",
745 e->qrxlm_valid ? e->qrxlm : 32);
746
747 tmp = e->meas_bw[i];
748 vty_out(vty, " meas %u",
749 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200750
751 vty_out(vty, "%s", VTY_NEWLINE);
752 }
753 }
754
Max26679e02016-04-20 15:57:13 +0200755 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
756 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
757 bts->si_common.data.uarfcn_list[i],
758 bts->si_common.data.scramble_list[i] & ~(1 << 9),
759 (bts->si_common.data.scramble_list[i] >> 9) & 1,
760 VTY_NEWLINE);
761 }
762
Andreas Eversberga83d5112013-12-07 18:32:28 +0100763 vty_out(vty, " codec-support fr");
764 if (bts->codec.hr)
765 vty_out(vty, " hr");
766 if (bts->codec.efr)
767 vty_out(vty, " efr");
768 if (bts->codec.amr)
769 vty_out(vty, " amr");
770 vty_out(vty, "%s", VTY_NEWLINE);
771
Andreas Eversberg73266522014-01-19 11:47:44 +0100772 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
773 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
774
Harald Welte615e9562010-05-11 23:50:21 +0200775 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200776
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200777 if (bts->excl_from_rf_lock)
778 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
779
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100780 vty_out(vty, " %sforce-combined-si%s",
781 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
782
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100783 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
784 int j;
785
786 if (bts->depends_on[i] == 0)
787 continue;
788
789 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
790 int bts_nr;
791
792 if ((bts->depends_on[i] & (1<<j)) == 0)
793 continue;
794
795 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
796 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
797 }
798 }
Harald Welte8254cf72017-05-29 13:42:19 +0200799 if (bts->pcu_sock_path)
800 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100801
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100802 ho_vty_write(vty, " ", bts->ho);
803
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200804 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200805}
806
807static int config_write_bts(struct vty *v)
808{
Harald Weltedcccb182010-05-16 20:52:23 +0200809 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200810 struct gsm_bts *bts;
811
812 llist_for_each_entry(bts, &gsmnet->bts_list, list)
813 config_write_bts_single(v, bts);
814
815 return CMD_SUCCESS;
816}
817
Harald Weltea0d324b2017-07-20 01:47:39 +0200818/* small helper macro for conditional dumping of timer */
819#define VTY_OUT_TIMER(number) \
820 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
821 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
822
Harald Welte5013b2a2009-08-07 13:29:14 +0200823static int config_write_net(struct vty *vty)
824{
Harald Weltedcccb182010-05-16 20:52:23 +0200825 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
826
Harald Welte5013b2a2009-08-07 13:29:14 +0200827 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200828 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200829 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900830 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100831 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800832 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100833
834 ho_vty_write(vty, " ", gsmnet->ho);
835
Harald Weltea0d324b2017-07-20 01:47:39 +0200836 VTY_OUT_TIMER(3101);
837 VTY_OUT_TIMER(3103);
838 VTY_OUT_TIMER(3105);
839 VTY_OUT_TIMER(3107);
840 VTY_OUT_TIMER(3109);
841 VTY_OUT_TIMER(3111);
842 VTY_OUT_TIMER(3113);
843 VTY_OUT_TIMER(3115);
844 VTY_OUT_TIMER(3117);
845 VTY_OUT_TIMER(3119);
846 VTY_OUT_TIMER(3122);
847 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700848 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
849 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200850 if (gsmnet->tz.override != 0) {
851 if (gsmnet->tz.dst)
852 vty_out(vty, " timezone %d %d %d%s",
853 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
854 VTY_NEWLINE);
855 else
856 vty_out(vty, " timezone %d %d%s",
857 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
858 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200859 if (gsmnet->t3212 == 0)
860 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
861 else
862 vty_out(vty, " periodic location update %u%s",
863 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200864
865 return CMD_SUCCESS;
866}
Harald Welte67ce0732009-08-06 19:06:46 +0200867
Harald Welte68628e82009-03-10 12:17:57 +0000868static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
869{
870 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
871 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200872 vty_out(vty, "Description: %s%s",
873 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200874 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200875 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200876 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200877 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000878 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200879 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +0100880 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000881 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200882 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200883 if (is_ipaccess_bts(trx->bts)) {
884 vty_out(vty, " ip.access stream ID: 0x%02x%s",
885 trx->rsl_tei, VTY_NEWLINE);
886 } else {
887 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
888 e1isl_dump_vty(vty, trx->rsl_link);
889 }
Harald Welte68628e82009-03-10 12:17:57 +0000890}
891
Max6e4f1842018-01-07 16:45:42 +0100892static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
893{
894 uint8_t trx_nr;
895 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
896 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
897}
898
Harald Welte68628e82009-03-10 12:17:57 +0000899DEFUN(show_trx,
900 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100901 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200902 SHOW_STR "Display information about a TRX\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +0100903 BTS_TRX_STR)
Harald Welte68628e82009-03-10 12:17:57 +0000904{
Harald Weltedcccb182010-05-16 20:52:23 +0200905 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000906 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000907 int bts_nr, trx_nr;
908
909 if (argc >= 1) {
910 /* use the BTS number that the user has specified */
911 bts_nr = atoi(argv[0]);
912 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000913 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000914 VTY_NEWLINE);
915 return CMD_WARNING;
916 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200917 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000918 }
919 if (argc >= 2) {
920 trx_nr = atoi(argv[1]);
921 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000922 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000923 VTY_NEWLINE);
924 return CMD_WARNING;
925 }
Max6e4f1842018-01-07 16:45:42 +0100926 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000927 return CMD_SUCCESS;
928 }
929 if (bts) {
930 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +0100931 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +0000932 return CMD_SUCCESS;
933 }
934
Max6e4f1842018-01-07 16:45:42 +0100935 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
936 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000937
938 return CMD_SUCCESS;
939}
940
Harald Welte67ce0732009-08-06 19:06:46 +0200941
Harald Welte68628e82009-03-10 12:17:57 +0000942static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
943{
Harald Welte135a6482011-05-30 12:09:13 +0200944 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +0100945 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +0100946 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +0100947 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +0100948 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +0200949 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +0100950 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000951 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200952 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +0530953 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +0000954 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
955 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
956 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000957}
958
959DEFUN(show_ts,
960 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100961 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200962 SHOW_STR "Display information about a TS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +0100963 BTS_TRX_TS_STR)
Harald Welte68628e82009-03-10 12:17:57 +0000964{
Harald Weltedcccb182010-05-16 20:52:23 +0200965 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +0100966 struct gsm_bts *bts = NULL;
967 struct gsm_bts_trx *trx = NULL;
968 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000969 int bts_nr, trx_nr, ts_nr;
970
971 if (argc >= 1) {
972 /* use the BTS number that the user has specified */
973 bts_nr = atoi(argv[0]);
974 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000975 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000976 VTY_NEWLINE);
977 return CMD_WARNING;
978 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200979 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000980 }
981 if (argc >= 2) {
982 trx_nr = atoi(argv[1]);
983 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000984 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000985 VTY_NEWLINE);
986 return CMD_WARNING;
987 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200988 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000989 }
990 if (argc >= 3) {
991 ts_nr = atoi(argv[2]);
992 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +0000993 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +0000994 VTY_NEWLINE);
995 return CMD_WARNING;
996 }
Harald Welte274d0152010-12-24 12:05:03 +0100997 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +0000998 ts = &trx->ts[ts_nr];
999 ts_dump_vty(vty, ts);
1000 return CMD_SUCCESS;
1001 }
Harald Welte274d0152010-12-24 12:05:03 +01001002
1003 if (bts && trx) {
1004 /* Iterate over all TS in this TRX */
1005 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1006 ts = &trx->ts[ts_nr];
1007 ts_dump_vty(vty, ts);
1008 }
1009 } else if (bts) {
1010 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001011 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001012 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001013 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1014 ts = &trx->ts[ts_nr];
1015 ts_dump_vty(vty, ts);
1016 }
1017 }
Harald Welte274d0152010-12-24 12:05:03 +01001018 } else {
1019 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1020 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1021 bts = gsm_bts_num(net, bts_nr);
1022 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1023 trx = gsm_bts_trx_num(bts, trx_nr);
1024 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1025 ts = &trx->ts[ts_nr];
1026 ts_dump_vty(vty, ts);
1027 }
1028 }
1029 }
Harald Welte68628e82009-03-10 12:17:57 +00001030 }
1031
1032 return CMD_SUCCESS;
1033}
1034
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001035static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1036{
1037 if (strlen(bsub->imsi))
1038 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1039 if (bsub->tmsi != GSM_RESERVED_TMSI)
1040 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1041 VTY_NEWLINE);
1042 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1043}
1044
Harald Welte8387a492009-12-22 21:43:14 +01001045static void meas_rep_dump_uni_vty(struct vty *vty,
1046 struct gsm_meas_rep_unidir *mru,
1047 const char *prefix,
1048 const char *dir)
1049{
1050 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1051 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1052 dir, rxlev2dbm(mru->sub.rx_lev));
1053 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1054 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1055 VTY_NEWLINE);
1056}
1057
1058static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1059 const char *prefix)
1060{
1061 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1062 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1063 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1064 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1065 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1066 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1067 VTY_NEWLINE);
1068 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001069 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001070 if (mr->flags & MEAS_REP_F_MS_L1)
1071 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1072 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1073 if (mr->flags & MEAS_REP_F_DL_VALID)
1074 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1075 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1076}
1077
Harald Welte0a8cf322015-12-05 17:22:49 +01001078/* FIXME: move this to libosmogsm */
1079static const struct value_string gsm48_cmode_names[] = {
1080 { GSM48_CMODE_SIGN, "signalling" },
1081 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1082 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1083 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1084 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1085 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1086 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1087 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1088 { 0, NULL }
1089};
1090
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001091/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1092 * Don't do anything if the ts is not dynamic. */
1093static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1094{
1095 switch (ts->pchan) {
1096 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1097 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1098 vty_out(vty, " as %s",
1099 gsm_pchan_name(ts->dyn.pchan_is));
1100 else
1101 vty_out(vty, " switching %s -> %s",
1102 gsm_pchan_name(ts->dyn.pchan_is),
1103 gsm_pchan_name(ts->dyn.pchan_want));
1104 break;
1105 case GSM_PCHAN_TCH_F_PDCH:
1106 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1107 vty_out(vty, " as %s",
1108 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1109 : "TCH/F");
1110 else
1111 vty_out(vty, " switching %s -> %s",
1112 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1113 : "TCH/F",
1114 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1115 : "TCH/F");
1116 break;
1117 default:
1118 /* no dyn ts */
1119 break;
1120 }
1121}
1122
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001123static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001124{
Harald Welte8387a492009-12-22 21:43:14 +01001125 int idx;
1126
Harald Welte85bded82010-12-24 12:22:34 +01001127 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1128 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1129 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001130 /* show dyn TS details, if applicable */
1131 switch (lchan->ts->pchan) {
1132 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1133 vty_out(vty, " Osmocom Dyn TS:");
1134 vty_out_dyn_ts_status(vty, lchan->ts);
1135 vty_out(vty, VTY_NEWLINE);
1136 break;
1137 case GSM_PCHAN_TCH_F_PDCH:
1138 vty_out(vty, " IPACC Dyn PDCH TS:");
1139 vty_out_dyn_ts_status(vty, lchan->ts);
1140 vty_out(vty, VTY_NEWLINE);
1141 break;
1142 default:
1143 /* no dyn ts */
1144 break;
1145 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001146 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001147 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001148 gsm_lchans_name(lchan->state),
1149 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1150 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1151 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001152 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1153 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1154 - lchan->bs_power*2,
1155 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1156 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001157 vty_out(vty, " Channel Mode / Codec: %s%s",
1158 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1159 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001160 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001161 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001162 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001163 } else
1164 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301165 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1166 struct in_addr ia;
Harald Welte5f45a4a2018-02-05 21:33:34 +01001167 if (lchan->abis_ip.bound_ip) {
1168 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
1169 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1170 inet_ntoa(ia), lchan->abis_ip.bound_port,
1171 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1172 VTY_NEWLINE);
1173 }
1174 if (lchan->abis_ip.connect_ip) {
1175 ia.s_addr = htonl(lchan->abis_ip.connect_ip);
1176 vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02x%s",
1177 inet_ntoa(ia), lchan->abis_ip.connect_port,
1178 lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode,
1179 VTY_NEWLINE);
1180 }
1181
Harald Welte2c828992009-12-02 01:56:49 +05301182 }
Harald Welte8387a492009-12-22 21:43:14 +01001183
1184 /* we want to report the last measurement report */
1185 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1186 lchan->meas_rep_idx, 1);
1187 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001188}
1189
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001190static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1191{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001192 struct gsm_meas_rep *mr;
1193 int idx;
1194
1195 /* we want to report the last measurement report */
1196 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1197 lchan->meas_rep_idx, 1);
1198 mr = &lchan->meas_rep[idx];
1199
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001200 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001201 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001202 gsm_pchan_name(lchan->ts->pchan));
1203 vty_out_dyn_ts_status(vty, lchan->ts);
1204 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1205 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001206 lchan->nr,
1207 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1208 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001209 rxlev2dbm(mr->dl.full.rx_lev),
1210 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001211 VTY_NEWLINE);
1212}
1213
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001214
1215static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1216 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1217{
1218 int lchan_nr;
1219 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1220 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1221 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1222 continue;
1223 dump_cb(vty, lchan);
1224 }
1225
1226 return CMD_SUCCESS;
1227}
1228
1229static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1230 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1231{
1232 int ts_nr;
1233
1234 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1235 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1236 dump_lchan_trx_ts(ts, vty, dump_cb);
1237 }
1238
1239 return CMD_SUCCESS;
1240}
1241
1242static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1243 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1244{
1245 int trx_nr;
1246
1247 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1248 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1249 dump_lchan_trx(trx, vty, dump_cb);
1250 }
1251
1252 return CMD_SUCCESS;
1253}
1254
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001255static int lchan_summary(struct vty *vty, int argc, const char **argv,
1256 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001257{
Harald Weltedcccb182010-05-16 20:52:23 +02001258 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001259 struct gsm_bts *bts;
1260 struct gsm_bts_trx *trx;
1261 struct gsm_bts_trx_ts *ts;
1262 struct gsm_lchan *lchan;
1263 int bts_nr, trx_nr, ts_nr, lchan_nr;
1264
1265 if (argc >= 1) {
1266 /* use the BTS number that the user has specified */
1267 bts_nr = atoi(argv[0]);
1268 if (bts_nr >= net->num_bts) {
1269 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1270 VTY_NEWLINE);
1271 return CMD_WARNING;
1272 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001273 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001274
1275 if (argc == 1)
1276 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001277 }
1278 if (argc >= 2) {
1279 trx_nr = atoi(argv[1]);
1280 if (trx_nr >= bts->num_trx) {
1281 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1282 VTY_NEWLINE);
1283 return CMD_WARNING;
1284 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001285 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001286
1287 if (argc == 2)
1288 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001289 }
1290 if (argc >= 3) {
1291 ts_nr = atoi(argv[2]);
1292 if (ts_nr >= TRX_NR_TS) {
1293 vty_out(vty, "%% can't find TS %s%s", argv[2],
1294 VTY_NEWLINE);
1295 return CMD_WARNING;
1296 }
1297 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001298
1299 if (argc == 3)
1300 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001301 }
1302 if (argc >= 4) {
1303 lchan_nr = atoi(argv[3]);
1304 if (lchan_nr >= TS_MAX_LCHAN) {
1305 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1306 VTY_NEWLINE);
1307 return CMD_WARNING;
1308 }
1309 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001310 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001311 return CMD_SUCCESS;
1312 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001313
1314
Harald Welte68628e82009-03-10 12:17:57 +00001315 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001316 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001317 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001318 }
1319
1320 return CMD_SUCCESS;
1321}
1322
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001323
1324DEFUN(show_lchan,
1325 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001326 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001327 SHOW_STR "Display information about a logical channel\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001328 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001329{
1330 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1331}
1332
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001333DEFUN(show_lchan_summary,
1334 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001335 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001336 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001337 "Short summary\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001338 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001339{
1340 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1341}
1342
Philipp Maier39f62bb2017-04-09 12:32:51 +02001343DEFUN(show_subscr_conn,
1344 show_subscr_conn_cmd,
1345 "show conns",
1346 SHOW_STR "Display currently active subscriber connections\n")
1347{
1348 struct gsm_subscriber_connection *conn;
1349 struct gsm_network *net = gsmnet_from_vty(vty);
1350 bool no_conns = true;
1351 unsigned int count = 0;
1352
1353 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1354
1355 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1356 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1357 lchan_dump_full_vty(vty, conn->lchan);
1358 no_conns = false;
1359 count++;
1360 }
1361
1362 if (no_conns)
1363 vty_out(vty, "None%s", VTY_NEWLINE);
1364
1365 return CMD_SUCCESS;
1366}
1367
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001368static int trigger_ho_or_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_bts *to_bts)
1369{
1370 int rc;
1371
1372 if (!to_bts || from_lchan->ts->trx->bts == to_bts) {
1373 LOGP(DHO, LOGL_NOTICE, "%s Manually triggering Assignment from VTY\n",
1374 gsm_lchan_name(from_lchan));
1375 to_bts = from_lchan->ts->trx->bts;
1376 } else
1377 LOGP(DHO, LOGL_NOTICE, "%s (ARFCN %u) --> BTS %u Manually triggering Handover from VTY\n",
1378 gsm_lchan_name(from_lchan), from_lchan->ts->trx->arfcn, to_bts->nr);
1379 rc = bsc_handover_start(from_lchan, to_bts);
1380 if (rc) {
1381 vty_out(vty, "bsc_handover_start() returned %d=%s%s", rc,
1382 strerror(-rc), VTY_NEWLINE);
1383 return CMD_WARNING;
1384 }
1385 return CMD_SUCCESS;
1386}
1387
1388static int ho_or_as(struct vty *vty, const char *argv[], int argc)
Philipp Maier39f62bb2017-04-09 12:32:51 +02001389{
1390 struct gsm_network *net = gsmnet_from_vty(vty);
1391 struct gsm_subscriber_connection *conn;
1392 struct gsm_bts *bts;
1393 struct gsm_bts *new_bts = NULL;
1394 unsigned int bts_nr = atoi(argv[0]);
1395 unsigned int trx_nr = atoi(argv[1]);
1396 unsigned int ts_nr = atoi(argv[2]);
1397 unsigned int ss_nr = atoi(argv[3]);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001398 unsigned int bts_nr_new;
1399 const char *action;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001400
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001401 if (argc > 4) {
1402 bts_nr_new = atoi(argv[4]);
1403
1404 /* Lookup the BTS where we want to handover to */
1405 llist_for_each_entry(bts, &net->bts_list, list) {
1406 if (bts->nr == bts_nr_new) {
1407 new_bts = bts;
1408 break;
1409 }
1410 }
1411
1412 if (!new_bts) {
1413 vty_out(vty, "Unable to trigger handover, specified bts #%u does not exist %s",
1414 bts_nr_new, VTY_NEWLINE);
1415 return CMD_WARNING;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001416 }
1417 }
1418
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001419 action = new_bts ? "handover" : "assignment";
Philipp Maier39f62bb2017-04-09 12:32:51 +02001420
1421 /* Find the connection/lchan that we want to handover */
1422 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001423 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001424 conn->lchan->ts->trx->nr == trx_nr &&
1425 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001426 vty_out(vty, "starting %s for lchan %s...%s", action, conn->lchan->name, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001427 lchan_dump_full_vty(vty, conn->lchan);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001428 return trigger_ho_or_as(vty, conn->lchan, new_bts);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001429 }
1430 }
1431
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001432 vty_out(vty, "Unable to trigger %s, specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1433 action, bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001434
1435 return CMD_WARNING;
1436}
1437
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001438#define MANUAL_HANDOVER_STR "Manually trigger handover (for debugging)\n"
1439#define MANUAL_ASSIGNMENT_STR "Manually trigger assignment (for debugging)\n"
1440
1441DEFUN(handover_subscr_conn,
1442 handover_subscr_conn_cmd,
1443 "handover <0-255> <0-255> <0-7> <0-7> <0-255>",
1444 MANUAL_HANDOVER_STR
1445 "Current " BTS_TRX_TS_LCHAN_STR
1446 "New " BTS_NR_STR)
1447{
1448 return ho_or_as(vty, argv, argc);
1449}
1450
1451DEFUN(assignment_subscr_conn,
1452 assignment_subscr_conn_cmd,
1453 "assignment <0-255> <0-255> <0-7> <0-7>",
1454 MANUAL_ASSIGNMENT_STR
1455 "Current " BTS_TRX_TS_LCHAN_STR)
1456{
1457 return ho_or_as(vty, argv, argc);
1458}
1459
1460static struct gsm_lchan *find_used_voice_lchan(struct vty *vty)
1461{
1462 struct gsm_bts *bts;
1463 struct gsm_network *network = gsmnet_from_vty(vty);
1464
1465 llist_for_each_entry(bts, &network->bts_list, list) {
1466 struct gsm_bts_trx *trx;
1467
1468 llist_for_each_entry(trx, &bts->trx_list, list) {
1469 int i;
1470 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1471 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1472 int j;
1473 int subslots;
1474
1475 /* skip administratively deactivated timeslots */
1476 if (!nm_is_running(&ts->mo.nm_state))
1477 continue;
1478
1479 subslots = ts_subslots(ts);
1480 for (j = 0; j < subslots; j++) {
1481 struct gsm_lchan *lchan = &ts->lchan[j];
1482
1483 if (lchan->state == LCHAN_S_ACTIVE
1484 && (lchan->type == GSM_LCHAN_TCH_F
1485 || lchan->type == GSM_LCHAN_TCH_H)) {
1486
1487 vty_out(vty, "Found voice call: %s%s",
1488 gsm_lchan_name(lchan), VTY_NEWLINE);
1489 lchan_dump_full_vty(vty, lchan);
1490 return lchan;
1491 }
1492 }
1493 }
1494 }
1495 }
1496
1497 vty_out(vty, "Cannot find any ongoing voice calls%s", VTY_NEWLINE);
1498 return NULL;
1499}
1500
1501static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gsm_bts *not_this_bts,
1502 enum gsm_phys_chan_config free_type)
1503{
1504 struct gsm_bts *bts;
1505 struct gsm_network *network = gsmnet_from_vty(vty);
1506
1507 llist_for_each_entry(bts, &network->bts_list, list) {
1508 struct gsm_bts_trx *trx;
1509
1510 if (bts == not_this_bts)
1511 continue;
1512
1513 llist_for_each_entry(trx, &bts->trx_list, list) {
1514 int i;
1515 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1516 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1517 int j;
1518 int subslots;
1519
1520 /* skip administratively deactivated timeslots */
1521 if (!nm_is_running(&ts->mo.nm_state))
1522 continue;
1523
1524 if (ts->pchan != free_type)
1525 continue;
1526
1527 subslots = ts_subslots(ts);
1528 for (j = 0; j < subslots; j++) {
1529 struct gsm_lchan *lchan = &ts->lchan[j];
1530
1531 if (lchan->state == LCHAN_S_NONE) {
1532 vty_out(vty, "Found unused %s slot: %s%s",
1533 gsm_pchan_name(free_type),
1534 gsm_lchan_name(lchan),
1535 VTY_NEWLINE);
1536 lchan_dump_full_vty(vty, lchan);
1537 return bts;
1538 }
1539 }
1540 }
1541 }
1542 }
1543 vty_out(vty, "Cannot find any BTS (other than BTS %u) with free %s lchan%s",
1544 not_this_bts? not_this_bts->nr : 255, gsm_lchant_name(free_type), VTY_NEWLINE);
1545 return NULL;
1546}
1547
1548DEFUN(handover_any, handover_any_cmd,
1549 "handover any",
1550 MANUAL_HANDOVER_STR
1551 "Pick any actively used TCH/F or TCH/H lchan and handover to any other BTS."
1552 " This is likely to fail if not all BTS are guaranteed to be reachable by the MS.\n")
1553{
1554 struct gsm_lchan *from_lchan;
1555 struct gsm_bts *to_bts;
1556
1557 from_lchan = find_used_voice_lchan(vty);
1558 if (!from_lchan)
1559 return CMD_WARNING;
1560
1561 to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts,
1562 ts_pchan(from_lchan->ts));
1563 if (!to_bts)
1564 return CMD_WARNING;
1565
1566 return trigger_ho_or_as(vty, from_lchan, to_bts);
1567}
1568
1569DEFUN(assignment_any, assignment_any_cmd,
1570 "assignment any",
1571 MANUAL_ASSIGNMENT_STR
1572 "Pick any actively used TCH/F or TCH/H lchan and re-assign within the same BTS."
1573 " This will fail if no lchans of the same type are available besides the used one.\n")
1574{
1575 struct gsm_lchan *from_lchan;
1576
1577 from_lchan = find_used_voice_lchan(vty);
1578 if (!from_lchan)
1579 return CMD_WARNING;
1580
1581 return trigger_ho_or_as(vty, from_lchan, NULL);
1582}
1583
Harald Weltebe4b7302009-05-23 16:59:33 +00001584static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001585{
1586 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001587 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001588}
1589
Harald Weltebe4b7302009-05-23 16:59:33 +00001590static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001591{
1592 struct gsm_paging_request *pag;
1593
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001594 if (!bts->paging.bts)
1595 return;
1596
Harald Weltef5025b62009-03-28 16:55:11 +00001597 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1598 paging_dump_vty(vty, pag);
1599}
1600
1601DEFUN(show_paging,
1602 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001603 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001604 SHOW_STR "Display information about paging reuqests of a BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001605 BTS_NR_STR)
Harald Weltef5025b62009-03-28 16:55:11 +00001606{
Harald Weltedcccb182010-05-16 20:52:23 +02001607 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001608 struct gsm_bts *bts;
1609 int bts_nr;
1610
1611 if (argc >= 1) {
1612 /* use the BTS number that the user has specified */
1613 bts_nr = atoi(argv[0]);
1614 if (bts_nr >= net->num_bts) {
1615 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1616 VTY_NEWLINE);
1617 return CMD_WARNING;
1618 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001619 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001620 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001621
Harald Weltef5025b62009-03-28 16:55:11 +00001622 return CMD_SUCCESS;
1623 }
1624 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001625 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001626 bts_paging_dump_vty(vty, bts);
1627 }
1628
1629 return CMD_SUCCESS;
1630}
1631
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001632DEFUN(show_paging_group,
1633 show_paging_group_cmd,
1634 "show paging-group <0-255> IMSI",
1635 SHOW_STR "Display the paging group\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001636 BTS_NR_STR "IMSI\n")
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001637{
1638 struct gsm_network *net = gsmnet_from_vty(vty);
1639 struct gsm_bts *bts;
1640 unsigned int page_group;
1641 int bts_nr = atoi(argv[0]);
1642
1643 if (bts_nr >= net->num_bts) {
1644 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1645 return CMD_WARNING;
1646 }
1647
1648 bts = gsm_bts_num(net, bts_nr);
1649 if (!bts) {
1650 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1651 return CMD_WARNING;
1652 }
1653
1654 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1655 str_to_imsi(argv[1]));
1656 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1657 str_to_imsi(argv[1]), bts->nr,
1658 page_group, VTY_NEWLINE);
1659 return CMD_SUCCESS;
1660}
1661
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001662DEFUN(cfg_net_neci,
1663 cfg_net_neci_cmd,
1664 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001665 "New Establish Cause Indication\n"
1666 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001667{
Harald Weltedcccb182010-05-16 20:52:23 +02001668 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1669
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001670 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001671 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001672 return CMD_SUCCESS;
1673}
1674
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001675DEFUN(cfg_net_pag_any_tch,
1676 cfg_net_pag_any_tch_cmd,
1677 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001678 "Assign a TCH when receiving a Paging Any request\n"
1679 "Any Channel\n" "Use\n" "TCH\n"
1680 "Do not use TCH for Paging Request Any\n"
1681 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001682{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001683 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001684 gsmnet->pag_any_tch = atoi(argv[0]);
1685 gsm_net_update_ctype(gsmnet);
1686 return CMD_SUCCESS;
1687}
1688
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001689#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1690/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1691#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1692
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001693#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001694 DEFUN(cfg_net_T##number, \
1695 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001696 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001697 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001698 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001699 "Set to default timer value" \
1700 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1701 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001702{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001703 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001704 int value; \
1705 if (strcmp(argv[0], "default") == 0) \
1706 value = DEFAULT_TIMER(number); \
1707 else \
1708 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001709 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001710 gsmnet->T##number = value; \
1711 return CMD_SUCCESS; \
1712}
1713
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001714DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1715DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1716DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1717DECLARE_TIMER(3107, "Currently not used")
1718DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1719DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1720DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1721DECLARE_TIMER(3115, "Currently not used")
1722DECLARE_TIMER(3117, "Currently not used")
1723DECLARE_TIMER(3119, "Currently not used")
Stefan Sperling6cee8932018-01-30 18:14:22 +01001724DECLARE_TIMER(3122, "Default waiting time (seconds) after IMM ASS REJECT")
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001725DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001726
Maxc08ee712016-05-11 12:45:13 +02001727DEFUN_DEPRECATED(cfg_net_dtx,
1728 cfg_net_dtx_cmd,
1729 "dtx-used (0|1)",
1730 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001731{
Maxc08ee712016-05-11 12:45:13 +02001732 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1733 "configuration options of BTS instead%s", VTY_NEWLINE);
1734 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001735}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001736
Harald Welte5258fc42009-03-28 19:07:53 +00001737/* per-BTS configuration */
1738DEFUN(cfg_bts,
1739 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001740 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001741 "Select a BTS to configure\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001742 BTS_NR_STR)
Harald Welte5258fc42009-03-28 19:07:53 +00001743{
Harald Weltedcccb182010-05-16 20:52:23 +02001744 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001745 int bts_nr = atoi(argv[0]);
1746 struct gsm_bts *bts;
1747
Harald Weltee441d9c2009-06-21 16:17:15 +02001748 if (bts_nr > gsmnet->num_bts) {
1749 vty_out(vty, "%% The next unused BTS number is %u%s",
1750 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001751 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001752 } else if (bts_nr == gsmnet->num_bts) {
1753 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001754 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001755 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001756 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001757 bts = gsm_bts_num(gsmnet, bts_nr);
1758
Daniel Willmannf15c2762010-01-11 13:43:07 +01001759 if (!bts) {
1760 vty_out(vty, "%% Unable to allocate BTS %u%s",
1761 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001762 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001763 }
Harald Welte5258fc42009-03-28 19:07:53 +00001764
1765 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001766 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001767 vty->node = BTS_NODE;
1768
1769 return CMD_SUCCESS;
1770}
1771
1772DEFUN(cfg_bts_type,
1773 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001774 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001775 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001776{
1777 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001778 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001779
Max7507aef2017-04-10 13:59:14 +02001780 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001781 if (rc < 0)
1782 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001783
Harald Welte5258fc42009-03-28 19:07:53 +00001784 return CMD_SUCCESS;
1785}
1786
Harald Weltefcd24452009-06-20 18:15:19 +02001787DEFUN(cfg_bts_band,
1788 cfg_bts_band_cmd,
1789 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001790 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001791{
1792 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001793 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001794
1795 if (band < 0) {
1796 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1797 band, VTY_NEWLINE);
1798 return CMD_WARNING;
1799 }
1800
1801 bts->band = band;
1802
1803 return CMD_SUCCESS;
1804}
1805
Maxc08ee712016-05-11 12:45:13 +02001806DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1807 "Configure discontinuous transmission\n"
1808 "Enable Uplink DTX for this BTS\n"
1809 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1810 "older phones).\n")
1811{
1812 struct gsm_bts *bts = vty->index;
1813
1814 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001815 if (!is_ipaccess_bts(bts))
1816 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1817 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001818 return CMD_SUCCESS;
1819}
1820
1821DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1822 NO_STR
1823 "Configure discontinuous transmission\n"
1824 "Disable Uplink DTX for this BTS\n")
1825{
1826 struct gsm_bts *bts = vty->index;
1827
1828 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1829
1830 return CMD_SUCCESS;
1831}
1832
1833DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1834 "Configure discontinuous transmission\n"
1835 "Enable Downlink DTX for this BTS\n")
1836{
1837 struct gsm_bts *bts = vty->index;
1838
1839 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001840 if (!is_ipaccess_bts(bts))
1841 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1842 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001843 return CMD_SUCCESS;
1844}
1845
1846DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1847 NO_STR
1848 "Configure discontinuous transmission\n"
1849 "Disable Downlink DTX for this BTS\n")
1850{
1851 struct gsm_bts *bts = vty->index;
1852
1853 bts->dtxd = false;
1854
1855 return CMD_SUCCESS;
1856}
1857
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001858DEFUN(cfg_bts_ci,
1859 cfg_bts_ci_cmd,
1860 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001861 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001862{
1863 struct gsm_bts *bts = vty->index;
1864 int ci = atoi(argv[0]);
1865
1866 if (ci < 0 || ci > 0xffff) {
1867 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1868 ci, VTY_NEWLINE);
1869 return CMD_WARNING;
1870 }
1871 bts->cell_identity = ci;
1872
1873 return CMD_SUCCESS;
1874}
1875
Harald Welte5258fc42009-03-28 19:07:53 +00001876DEFUN(cfg_bts_lac,
1877 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001878 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001879 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001880{
1881 struct gsm_bts *bts = vty->index;
1882 int lac = atoi(argv[0]);
1883
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001884 if (lac < 0 || lac > 0xffff) {
1885 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001886 lac, VTY_NEWLINE);
1887 return CMD_WARNING;
1888 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001889
1890 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1891 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1892 lac, VTY_NEWLINE);
1893 return CMD_WARNING;
1894 }
1895
Harald Welte5258fc42009-03-28 19:07:53 +00001896 bts->location_area_code = lac;
1897
1898 return CMD_SUCCESS;
1899}
1900
Harald Weltea43f7892009-12-01 18:04:30 +05301901
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001902/* compatibility wrapper for old config files */
1903DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001904 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001905 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001906 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001907{
Harald Welte5258fc42009-03-28 19:07:53 +00001908 return CMD_SUCCESS;
1909}
1910
Harald Welte78f2f502009-05-23 16:56:52 +00001911DEFUN(cfg_bts_bsic,
1912 cfg_bts_bsic_cmd,
1913 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001914 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1915 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001916{
1917 struct gsm_bts *bts = vty->index;
1918 int bsic = atoi(argv[0]);
1919
1920 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001921 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001922 bsic, VTY_NEWLINE);
1923 return CMD_WARNING;
1924 }
1925 bts->bsic = bsic;
1926
1927 return CMD_SUCCESS;
1928}
1929
Harald Welte4cc34222009-05-01 15:12:31 +00001930DEFUN(cfg_bts_unit_id,
1931 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001932 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001933 "Abis/IP specific options\n"
1934 "Set the IPA BTS Unit ID\n"
1935 "Unit ID (Site)\n"
1936 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001937{
1938 struct gsm_bts *bts = vty->index;
1939 int site_id = atoi(argv[0]);
1940 int bts_id = atoi(argv[1]);
1941
Harald Welte07dc73d2009-08-07 13:27:09 +02001942 if (!is_ipaccess_bts(bts)) {
1943 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1944 return CMD_WARNING;
1945 }
1946
Harald Welte4cc34222009-05-01 15:12:31 +00001947 bts->ip_access.site_id = site_id;
1948 bts->ip_access.bts_id = bts_id;
1949
1950 return CMD_SUCCESS;
1951}
1952
Harald Welte8b291802013-03-12 13:57:05 +01001953DEFUN(cfg_bts_rsl_ip,
1954 cfg_bts_rsl_ip_cmd,
1955 "ip.access rsl-ip A.B.C.D",
1956 "Abis/IP specific options\n"
1957 "Set the IPA RSL IP Address of the BSC\n"
1958 "Destination IP address for RSL connection\n")
1959{
1960 struct gsm_bts *bts = vty->index;
1961 struct in_addr ia;
1962
1963 if (!is_ipaccess_bts(bts)) {
1964 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
1965 return CMD_WARNING;
1966 }
1967
1968 inet_aton(argv[0], &ia);
1969 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
1970
1971 return CMD_SUCCESS;
1972}
1973
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001974#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01001975
Sylvain Munautc9519462011-10-17 14:04:55 +02001976DEFUN(cfg_bts_nokia_site_skip_reset,
1977 cfg_bts_nokia_site_skip_reset_cmd,
1978 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001979 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02001980 "Skip the reset step during bootstrap process of this BTS\n"
1981 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02001982{
1983 struct gsm_bts *bts = vty->index;
1984
1985 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
1986 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
1987 return CMD_WARNING;
1988 }
1989
1990 bts->nokia.skip_reset = atoi(argv[0]);
1991
1992 return CMD_SUCCESS;
1993}
1994
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01001995DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
1996 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
1997 "nokia_site no-local-rel-conf (0|1)",
1998 NOKIA_STR
1999 "Do not wait for RELease CONFirm message when releasing channel locally\n"
2000 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
2001{
2002 struct gsm_bts *bts = vty->index;
2003
2004 if (!is_nokia_bts(bts)) {
2005 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2006 VTY_NEWLINE);
2007 return CMD_WARNING;
2008 }
2009
2010 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
2011
2012 return CMD_SUCCESS;
2013}
2014
Sipos Csaba56e17662015-02-07 13:27:36 +01002015DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
2016 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
2017 "nokia_site bts-reset-timer <15-100>",
2018 NOKIA_STR
2019 "The amount of time (in sec.) between BTS_RESET is sent,\n"
2020 "and the BTS is being bootstrapped.\n")
2021{
2022 struct gsm_bts *bts = vty->index;
2023
2024 if (!is_nokia_bts(bts)) {
2025 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2026 VTY_NEWLINE);
2027 return CMD_WARNING;
2028 }
2029
2030 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
2031
2032 return CMD_SUCCESS;
2033}
Harald Welte8f0ed552010-05-11 21:53:49 +02002034#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002035#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02002036
Harald Welte8175e952009-10-20 00:22:00 +02002037DEFUN(cfg_bts_stream_id,
2038 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002039 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02002040 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002041 "Set the ip.access Stream ID of the OML link of this BTS\n"
2042 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02002043{
2044 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002045 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02002046
2047 if (!is_ipaccess_bts(bts)) {
2048 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2049 return CMD_WARNING;
2050 }
2051
2052 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002053 /* This is used by e1inp_bind_ops callback for each BTS model. */
2054 bts->oml_e1_link.e1_nr = linenr;
2055
2056 return CMD_SUCCESS;
2057}
2058
Harald Welted13e0cd2012-08-17 09:52:03 +02002059#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02002060
Harald Welte42581822009-08-08 16:12:58 +02002061DEFUN(cfg_bts_oml_e1,
2062 cfg_bts_oml_e1_cmd,
2063 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02002064 OML_E1_STR
2065 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002066 "E1/T1 line number to be used for OML\n"
2067 "E1/T1 timeslot to be used for OML\n"
2068 "E1/T1 timeslot to be used for OML\n"
2069 "E1/T1 sub-slot to be used for OML\n"
2070 "Use E1/T1 sub-slot 0\n"
2071 "Use E1/T1 sub-slot 1\n"
2072 "Use E1/T1 sub-slot 2\n"
2073 "Use E1/T1 sub-slot 3\n"
2074 "Use full E1 slot 3\n"
2075 )
Harald Welte42581822009-08-08 16:12:58 +02002076{
2077 struct gsm_bts *bts = vty->index;
2078
2079 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2080
2081 return CMD_SUCCESS;
2082}
2083
2084
2085DEFUN(cfg_bts_oml_e1_tei,
2086 cfg_bts_oml_e1_tei_cmd,
2087 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002088 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002089 "Set the TEI to be used for OML\n"
2090 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002091{
2092 struct gsm_bts *bts = vty->index;
2093
2094 bts->oml_tei = atoi(argv[0]);
2095
2096 return CMD_SUCCESS;
2097}
2098
Harald Welte7a8fa412009-08-10 13:48:16 +02002099DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2100 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002101 "Channnel Allocator\n" "Channel Allocator\n"
2102 "Allocate Timeslots and Transceivers in ascending order\n"
2103 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002104{
2105 struct gsm_bts *bts = vty->index;
2106
2107 if (!strcmp(argv[0], "ascending"))
2108 bts->chan_alloc_reverse = 0;
2109 else
2110 bts->chan_alloc_reverse = 1;
2111
2112 return CMD_SUCCESS;
2113}
2114
Harald Welte8f0ed552010-05-11 21:53:49 +02002115#define RACH_STR "Random Access Control Channel\n"
2116
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002117DEFUN(cfg_bts_rach_tx_integer,
2118 cfg_bts_rach_tx_integer_cmd,
2119 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002120 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002121 "Set the raw tx integer value in RACH Control parameters IE\n"
2122 "Set the raw tx integer value in RACH Control parameters IE\n"
2123 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002124{
2125 struct gsm_bts *bts = vty->index;
2126 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2127 return CMD_SUCCESS;
2128}
2129
2130DEFUN(cfg_bts_rach_max_trans,
2131 cfg_bts_rach_max_trans_cmd,
2132 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002133 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002134 "Set the maximum number of RACH burst transmissions\n"
2135 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002136 "Maximum number of 1 RACH burst transmissions\n"
2137 "Maximum number of 2 RACH burst transmissions\n"
2138 "Maximum number of 4 RACH burst transmissions\n"
2139 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002140{
2141 struct gsm_bts *bts = vty->index;
2142 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2143 return CMD_SUCCESS;
2144}
2145
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002146#define CD_STR "Channel Description\n"
2147
2148DEFUN(cfg_bts_chan_desc_att,
2149 cfg_bts_chan_desc_att_cmd,
2150 "channel-descrption attach (0|1)",
2151 CD_STR
2152 "Set if attachment is required\n"
2153 "Attachment is NOT required\n"
2154 "Attachment is required (standard)\n")
2155{
2156 struct gsm_bts *bts = vty->index;
2157 bts->si_common.chan_desc.att = atoi(argv[0]);
2158 return CMD_SUCCESS;
2159}
2160
2161DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2162 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2163 "channel-descrption bs-pa-mfrms <2-9>",
2164 CD_STR
2165 "Set number of multiframe periods for paging groups\n"
2166 "Number of multiframe periods for paging groups\n")
2167{
2168 struct gsm_bts *bts = vty->index;
2169 int bs_pa_mfrms = atoi(argv[0]);
2170
2171 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2172 return CMD_SUCCESS;
2173}
2174
2175DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2176 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2177 "channel-descrption bs-ag-blks-res <0-7>",
2178 CD_STR
2179 "Set number of blocks reserved for access grant\n"
2180 "Number of blocks reserved for access grant\n")
2181{
2182 struct gsm_bts *bts = vty->index;
2183 int bs_ag_blks_res = atoi(argv[0]);
2184
2185 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2186 return CMD_SUCCESS;
2187}
2188
Harald Welte8f0ed552010-05-11 21:53:49 +02002189#define NM_STR "Network Management\n"
2190
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002191DEFUN(cfg_bts_rach_nm_b_thresh,
2192 cfg_bts_rach_nm_b_thresh_cmd,
2193 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002194 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002195 "Set the NM Busy Threshold\n"
2196 "Set the NM Busy Threshold\n"
2197 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002198{
2199 struct gsm_bts *bts = vty->index;
2200 bts->rach_b_thresh = atoi(argv[0]);
2201 return CMD_SUCCESS;
2202}
2203
2204DEFUN(cfg_bts_rach_nm_ldavg,
2205 cfg_bts_rach_nm_ldavg_cmd,
2206 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002207 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002208 "Set the NM Loadaverage Slots value\n"
2209 "Set the NM Loadaverage Slots value\n"
2210 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002211{
2212 struct gsm_bts *bts = vty->index;
2213 bts->rach_ldavg_slots = atoi(argv[0]);
2214 return CMD_SUCCESS;
2215}
2216
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002217DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2218 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002219 "Should this cell be barred from access?\n"
2220 "Should this cell be barred from access?\n"
2221 "Cell should NOT be barred\n"
2222 "Cell should be barred\n")
2223
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002224{
2225 struct gsm_bts *bts = vty->index;
2226
Harald Welte71355012009-12-21 23:08:18 +01002227 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002228
2229 return CMD_SUCCESS;
2230}
2231
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002232DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2233 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002234 RACH_STR
2235 "Should this cell allow emergency calls?\n"
2236 "Should this cell allow emergency calls?\n"
2237 "Should this cell allow emergency calls?\n"
2238 "Do NOT allow emergency calls\n"
2239 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002240{
2241 struct gsm_bts *bts = vty->index;
2242
2243 if (atoi(argv[0]) == 0)
2244 bts->si_common.rach_control.t2 |= 0x4;
2245 else
2246 bts->si_common.rach_control.t2 &= ~0x4;
2247
2248 return CMD_SUCCESS;
2249}
2250
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002251DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2252 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2253 RACH_STR
2254 "Set access control class\n"
2255 "Access control class 0\n"
2256 "Access control class 1\n"
2257 "Access control class 2\n"
2258 "Access control class 3\n"
2259 "Access control class 4\n"
2260 "Access control class 5\n"
2261 "Access control class 6\n"
2262 "Access control class 7\n"
2263 "Access control class 8\n"
2264 "Access control class 9\n"
2265 "Access control class 11 for PLMN use\n"
2266 "Access control class 12 for security services\n"
2267 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2268 "Access control class 14 for emergency services\n"
2269 "Access control class 15 for PLMN staff\n"
2270 "barred to use access control class\n"
2271 "allowed to use access control class\n")
2272{
2273 struct gsm_bts *bts = vty->index;
2274
2275 uint8_t control_class;
2276 uint8_t allowed = 0;
2277
2278 if (strcmp(argv[1], "allowed") == 0)
2279 allowed = 1;
2280
2281 control_class = atoi(argv[0]);
2282 if (control_class < 8)
2283 if (allowed)
2284 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2285 else
2286 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2287 else
2288 if (allowed)
2289 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2290 else
2291 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2292
2293 return CMD_SUCCESS;
2294}
2295
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002296DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2297 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002298 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002299 "Maximum transmit power of the MS\n"
2300 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002301 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002302{
2303 struct gsm_bts *bts = vty->index;
2304
2305 bts->ms_max_power = atoi(argv[0]);
2306
2307 return CMD_SUCCESS;
2308}
2309
Harald Weltecfaabbb2012-08-16 23:23:50 +02002310#define CELL_STR "Cell Parameters\n"
2311
Harald Welte73225282009-12-12 18:17:25 +01002312DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2313 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002314 CELL_STR "Cell re-selection parameters\n"
2315 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002316 "Cell Re-Selection Hysteresis in dB")
2317{
2318 struct gsm_bts *bts = vty->index;
2319
2320 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2321
2322 return CMD_SUCCESS;
2323}
2324
2325DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2326 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002327 "Minimum RxLev needed for cell access\n"
2328 "Minimum RxLev needed for cell access\n"
2329 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002330 "Minimum RxLev needed for cell access (better than -110dBm)")
2331{
2332 struct gsm_bts *bts = vty->index;
2333
2334 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2335
2336 return CMD_SUCCESS;
2337}
2338
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002339DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2340 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002341 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2342 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002343{
2344 struct gsm_bts *bts = vty->index;
2345
2346 bts->si_common.cell_ro_sel_par.present = 1;
2347 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2348
2349 return CMD_SUCCESS;
2350}
2351
2352DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2353 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002354 CELL_STR "Cell Re-Selection Parameters\n"
2355 "Cell Re-Selection Offset (CRO) in dB\n"
2356 "Cell Re-Selection Offset (CRO) in dB\n"
2357 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002358{
2359 struct gsm_bts *bts = vty->index;
2360
2361 bts->si_common.cell_ro_sel_par.present = 1;
2362 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2363
2364 return CMD_SUCCESS;
2365}
2366
2367DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2368 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002369 "Cell selection temporary negative offset\n"
2370 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002371 "Cell selection temporary negative offset in dB")
2372{
2373 struct gsm_bts *bts = vty->index;
2374
2375 bts->si_common.cell_ro_sel_par.present = 1;
2376 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2377
2378 return CMD_SUCCESS;
2379}
2380
2381DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2382 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002383 "Cell selection temporary negative offset\n"
2384 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002385 "Sets cell selection temporary negative offset to infinity")
2386{
2387 struct gsm_bts *bts = vty->index;
2388
2389 bts->si_common.cell_ro_sel_par.present = 1;
2390 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2391
2392 return CMD_SUCCESS;
2393}
2394
2395DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2396 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002397 "Cell selection penalty time\n"
2398 "Cell selection penalty time\n"
2399 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002400{
2401 struct gsm_bts *bts = vty->index;
2402
2403 bts->si_common.cell_ro_sel_par.present = 1;
2404 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2405
2406 return CMD_SUCCESS;
2407}
2408
2409DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2410 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002411 "Cell selection penalty time\n"
2412 "Cell selection penalty time\n"
2413 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002414 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2415 "and TEMPORARY_OFFSET is ignored)")
2416{
2417 struct gsm_bts *bts = vty->index;
2418
2419 bts->si_common.cell_ro_sel_par.present = 1;
2420 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2421
2422 return CMD_SUCCESS;
2423}
2424
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002425DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2426 "radio-link-timeout <4-64>",
2427 "Radio link timeout criterion (BTS side)\n"
2428 "Radio link timeout value (lost SACCH block)\n")
2429{
2430 struct gsm_bts *bts = vty->index;
2431
Harald Welte2f8b9d22017-06-18 11:12:13 +03002432 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2433
2434 return CMD_SUCCESS;
2435}
2436
2437DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2438 "radio-link-timeout infinite",
2439 "Radio link timeout criterion (BTS side)\n"
2440 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2441{
2442 struct gsm_bts *bts = vty->index;
2443
2444 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2445 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2446 return CMD_WARNING;
2447 }
2448
2449 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2450 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002451
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002452 return CMD_SUCCESS;
2453}
2454
Harald Welte8f0ed552010-05-11 21:53:49 +02002455#define GPRS_TEXT "GPRS Packet Network\n"
2456
Harald Welteaf387632010-03-14 23:30:30 +08002457DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002458 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002459 GPRS_TEXT
2460 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002461 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002462 "GPRS BSSGP VC Identifier")
2463{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002464 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002465 struct gsm_bts *bts = vty->index;
2466
Harald Welte4511d892010-04-18 15:51:20 +02002467 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002468 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2469 return CMD_WARNING;
2470 }
2471
Harald Welte97a282b2010-03-14 15:37:43 +08002472 bts->gprs.cell.bvci = atoi(argv[0]);
2473
2474 return CMD_SUCCESS;
2475}
2476
Harald Weltea5731cf2010-03-22 11:48:36 +08002477DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2478 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002479 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002480 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002481 "GPRS NS Entity Identifier")
2482{
2483 struct gsm_bts *bts = vty->index;
2484
Harald Welte4511d892010-04-18 15:51:20 +02002485 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002486 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2487 return CMD_WARNING;
2488 }
2489
2490 bts->gprs.nse.nsei = atoi(argv[0]);
2491
2492 return CMD_SUCCESS;
2493}
2494
Harald Welte8f0ed552010-05-11 21:53:49 +02002495#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2496 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002497
Harald Welte97a282b2010-03-14 15:37:43 +08002498DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2499 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002500 GPRS_TEXT NSVC_TEXT
2501 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002502 "GPRS NS VC Identifier")
2503{
2504 struct gsm_bts *bts = vty->index;
2505 int idx = atoi(argv[0]);
2506
Harald Welte4511d892010-04-18 15:51:20 +02002507 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002508 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2509 return CMD_WARNING;
2510 }
2511
Harald Welte97a282b2010-03-14 15:37:43 +08002512 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2513
2514 return CMD_SUCCESS;
2515}
2516
Harald Welteaf387632010-03-14 23:30:30 +08002517DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2518 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002519 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002520 "GPRS NS Local UDP Port\n"
2521 "GPRS NS Local UDP Port\n"
2522 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002523 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002524{
2525 struct gsm_bts *bts = vty->index;
2526 int idx = atoi(argv[0]);
2527
Harald Welte4511d892010-04-18 15:51:20 +02002528 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002529 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2530 return CMD_WARNING;
2531 }
2532
Harald Welteaf387632010-03-14 23:30:30 +08002533 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2534
2535 return CMD_SUCCESS;
2536}
2537
2538DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2539 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002540 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002541 "GPRS NS Remote UDP Port\n"
2542 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002543 "GPRS NS Remote UDP Port\n"
2544 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002545{
2546 struct gsm_bts *bts = vty->index;
2547 int idx = atoi(argv[0]);
2548
Harald Welte4511d892010-04-18 15:51:20 +02002549 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002550 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2551 return CMD_WARNING;
2552 }
2553
Harald Welteaf387632010-03-14 23:30:30 +08002554 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2555
2556 return CMD_SUCCESS;
2557}
2558
2559DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2560 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002561 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002562 "GPRS NS Remote IP Address\n"
2563 "GPRS NS Remote IP Address\n"
2564 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002565{
2566 struct gsm_bts *bts = vty->index;
2567 int idx = atoi(argv[0]);
2568 struct in_addr ia;
2569
Harald Welte4511d892010-04-18 15:51:20 +02002570 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002571 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2572 return CMD_WARNING;
2573 }
2574
Harald Welteaf387632010-03-14 23:30:30 +08002575 inet_aton(argv[1], &ia);
2576 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2577
2578 return CMD_SUCCESS;
2579}
2580
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002581DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002582 "paging free <-1-1024>",
2583 "Paging options\n"
2584 "Only page when having a certain amount of free slots\n"
2585 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002586{
2587 struct gsm_bts *bts = vty->index;
2588
2589 bts->paging.free_chans_need = atoi(argv[0]);
2590 return CMD_SUCCESS;
2591}
2592
Harald Welte615e9562010-05-11 23:50:21 +02002593DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2594 "gprs ns timer " NS_TIMERS " <0-255>",
2595 GPRS_TEXT "Network Service\n"
2596 "Network Service Timer\n"
2597 NS_TIMERS_HELP "Timer Value\n")
2598{
2599 struct gsm_bts *bts = vty->index;
2600 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2601 int val = atoi(argv[1]);
2602
2603 if (bts->gprs.mode == BTS_GPRS_NONE) {
2604 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2605 return CMD_WARNING;
2606 }
2607
2608 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2609 return CMD_WARNING;
2610
2611 bts->gprs.nse.timer[idx] = val;
2612
2613 return CMD_SUCCESS;
2614}
2615
2616#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 +02002617#define BSSGP_TIMERS_HELP \
2618 "Tbvc-block timeout\n" \
2619 "Tbvc-block retries\n" \
2620 "Tbvc-unblock retries\n" \
2621 "Tbvcc-reset timeout\n" \
2622 "Tbvc-reset retries\n" \
2623 "Tbvc-suspend timeout\n" \
2624 "Tbvc-suspend retries\n" \
2625 "Tbvc-resume timeout\n" \
2626 "Tbvc-resume retries\n" \
2627 "Tbvc-capa-update timeout\n" \
2628 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002629
2630DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2631 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2632 GPRS_TEXT "Cell / BSSGP\n"
2633 "Cell/BSSGP Timer\n"
2634 BSSGP_TIMERS_HELP "Timer Value\n")
2635{
2636 struct gsm_bts *bts = vty->index;
2637 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2638 int val = atoi(argv[1]);
2639
2640 if (bts->gprs.mode == BTS_GPRS_NONE) {
2641 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2642 return CMD_WARNING;
2643 }
2644
2645 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2646 return CMD_WARNING;
2647
2648 bts->gprs.cell.timer[idx] = val;
2649
2650 return CMD_SUCCESS;
2651}
2652
Harald Welte97a282b2010-03-14 15:37:43 +08002653DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2654 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002655 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002656 "GPRS Routing Area Code\n"
2657 "GPRS Routing Area Code\n"
2658 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002659{
2660 struct gsm_bts *bts = vty->index;
2661
Harald Welte4511d892010-04-18 15:51:20 +02002662 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002663 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2664 return CMD_WARNING;
2665 }
2666
Harald Welte97a282b2010-03-14 15:37:43 +08002667 bts->gprs.rac = atoi(argv[0]);
2668
2669 return CMD_SUCCESS;
2670}
2671
Max292ec582016-07-28 11:55:37 +02002672DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2673 "gprs control-ack-type-rach", GPRS_TEXT
2674 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2675 "four access bursts format instead of default RLC/MAC control block\n")
2676{
2677 struct gsm_bts *bts = vty->index;
2678
2679 if (bts->gprs.mode == BTS_GPRS_NONE) {
2680 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2681 return CMD_WARNING;
2682 }
2683
2684 bts->gprs.ctrl_ack_type_use_block = false;
2685
2686 return CMD_SUCCESS;
2687}
2688
2689DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2690 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2691 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2692 "four access bursts format instead of default RLC/MAC control block\n")
2693{
2694 struct gsm_bts *bts = vty->index;
2695
2696 if (bts->gprs.mode == BTS_GPRS_NONE) {
2697 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2698 return CMD_WARNING;
2699 }
2700
2701 bts->gprs.ctrl_ack_type_use_block = true;
2702
2703 return CMD_SUCCESS;
2704}
2705
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002706DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2707 "gprs network-control-order (nc0|nc1|nc2)",
2708 GPRS_TEXT
2709 "GPRS Network Control Order\n"
2710 "MS controlled cell re-selection, no measurement reporting\n"
2711 "MS controlled cell re-selection, MS sends measurement reports\n"
2712 "Network controlled cell re-selection, MS sends measurement reports\n")
2713{
2714 struct gsm_bts *bts = vty->index;
2715
2716 if (bts->gprs.mode == BTS_GPRS_NONE) {
2717 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2718 return CMD_WARNING;
2719 }
2720
2721 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2722
2723 return CMD_SUCCESS;
2724}
2725
Harald Welte4511d892010-04-18 15:51:20 +02002726DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2727 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002728 GPRS_TEXT
2729 "GPRS Mode for this BTS\n"
2730 "GPRS Disabled on this BTS\n"
2731 "GPRS Enabled on this BTS\n"
2732 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002733{
2734 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002735 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002736
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002737 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002738 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2739 VTY_NEWLINE);
2740 return CMD_WARNING;
2741 }
2742
2743 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002744
2745 return CMD_SUCCESS;
2746}
2747
bhargava350533c2016-07-21 11:14:34 +05302748DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2749 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2750 "gprs 11bit_rach_support_for_egprs (0|1)",
2751 GPRS_TEXT "11 bit RACH options\n"
2752 "Disable 11 bit RACH for EGPRS\n"
2753 "Enable 11 bit RACH for EGPRS")
2754{
2755 struct gsm_bts *bts = vty->index;
2756
2757 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2758
2759 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2760 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2761 return CMD_WARNING;
2762 }
2763
2764 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2765 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2766 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2767 " enabled%s", VTY_NEWLINE);
2768 return CMD_WARNING;
2769 }
2770
2771 return CMD_SUCCESS;
2772}
2773
Harald Welte9fbff4a2010-07-30 11:50:09 +02002774#define SI_TEXT "System Information Messages\n"
2775#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)"
2776#define SI_TYPE_HELP "System Information Type 1\n" \
2777 "System Information Type 2\n" \
2778 "System Information Type 3\n" \
2779 "System Information Type 4\n" \
2780 "System Information Type 5\n" \
2781 "System Information Type 6\n" \
2782 "System Information Type 7\n" \
2783 "System Information Type 8\n" \
2784 "System Information Type 9\n" \
2785 "System Information Type 10\n" \
2786 "System Information Type 13\n" \
2787 "System Information Type 16\n" \
2788 "System Information Type 17\n" \
2789 "System Information Type 18\n" \
2790 "System Information Type 19\n" \
2791 "System Information Type 20\n" \
2792 "System Information Type 2bis\n" \
2793 "System Information Type 2ter\n" \
2794 "System Information Type 2quater\n" \
2795 "System Information Type 5bis\n" \
2796 "System Information Type 5ter\n"
2797
2798DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2799 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2800 SI_TEXT SI_TYPE_HELP
2801 "System Information Mode\n"
2802 "Static user-specified\n"
2803 "Dynamic, BSC-computed\n")
2804{
2805 struct gsm_bts *bts = vty->index;
2806 int type;
2807
2808 type = get_string_value(osmo_sitype_strs, argv[0]);
2809 if (type < 0) {
2810 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2811 return CMD_WARNING;
2812 }
2813
2814 if (!strcmp(argv[1], "static"))
2815 bts->si_mode_static |= (1 << type);
2816 else
2817 bts->si_mode_static &= ~(1 << type);
2818
2819 return CMD_SUCCESS;
2820}
2821
2822DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2823 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2824 SI_TEXT SI_TYPE_HELP
2825 "Static System Information filling\n"
2826 "Static user-specified SI content in HEX notation\n")
2827{
2828 struct gsm_bts *bts = vty->index;
2829 int rc, 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 (!(bts->si_mode_static & (1 << type))) {
2838 vty_out(vty, "SI Type %s is not configured in static mode%s",
2839 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2840 return CMD_WARNING;
2841 }
2842
Harald Welte290aaed2010-07-30 11:53:18 +02002843 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002844 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002845
2846 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002847 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2848 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002849 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2850 return CMD_WARNING;
2851 }
2852
2853 /* Mark this SI as present */
2854 bts->si_valid |= (1 << type);
2855
2856 return CMD_SUCCESS;
2857}
2858
Harald Welte42def722017-01-13 00:10:32 +01002859DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2860 "early-classmark-sending (allowed|forbidden)",
2861 "Early Classmark Sending\n"
2862 "Early Classmark Sending is allowed\n"
2863 "Early Classmark Sending is forbidden\n")
2864{
2865 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002866
2867 if (!strcmp(argv[0], "allowed"))
2868 bts->early_classmark_allowed = true;
2869 else
2870 bts->early_classmark_allowed = false;
2871
2872 return CMD_SUCCESS;
2873}
2874
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002875DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2876 "early-classmark-sending-3g (allowed|forbidden)",
2877 "3G Early Classmark Sending\n"
2878 "3G Early Classmark Sending is allowed\n"
2879 "3G Early Classmark Sending is forbidden\n")
2880{
2881 struct gsm_bts *bts = vty->index;
2882
2883 if (!strcmp(argv[0], "allowed"))
2884 bts->early_classmark_allowed_3g = true;
2885 else
2886 bts->early_classmark_allowed_3g = false;
2887
2888 return CMD_SUCCESS;
2889}
2890
Harald Welte32c09622011-01-11 23:44:56 +01002891DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002892 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002893 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002894 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2895 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002896{
2897 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002898 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002899
Harald Welte64c07d22011-02-15 11:43:27 +01002900 switch (mode) {
2901 case NL_MODE_MANUAL_SI5SEP:
2902 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002903 /* make sure we clear the current list when switching to
2904 * manual mode */
2905 if (bts->neigh_list_manual_mode == 0)
2906 memset(&bts->si_common.data.neigh_list, 0,
2907 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002908 break;
2909 default:
2910 break;
2911 }
2912
2913 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002914
2915 return CMD_SUCCESS;
2916}
2917
2918DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002919 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002920 "Neighbor List\n" "Add to manual neighbor list\n"
2921 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2922 "ARFCN of neighbor\n")
2923{
2924 struct gsm_bts *bts = vty->index;
2925 struct bitvec *bv = &bts->si_common.neigh_list;
2926 uint16_t arfcn = atoi(argv[1]);
2927
2928 if (!bts->neigh_list_manual_mode) {
2929 vty_out(vty, "%% Cannot configure neighbor list in "
2930 "automatic mode%s", VTY_NEWLINE);
2931 return CMD_WARNING;
2932 }
2933
2934 if (!strcmp(argv[0], "add"))
2935 bitvec_set_bit_pos(bv, arfcn, 1);
2936 else
2937 bitvec_set_bit_pos(bv, arfcn, 0);
2938
2939 return CMD_SUCCESS;
2940}
2941
Max70fdd242017-06-15 15:10:53 +02002942/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002943DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01002944 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
2945 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
2946 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
2947 "Add to manual SI2quater neighbor list\n"
2948 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
2949 "threshold high bits\n" "threshold high bits\n"
2950 "threshold low bits\n" "threshold low bits (32 means NA)\n"
2951 "priority\n" "priority (8 means NA)\n"
2952 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
2953 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02002954{
2955 struct gsm_bts *bts = vty->index;
2956 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
2957 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01002958 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
2959 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02002960 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02002961
Max70fdd242017-06-15 15:10:53 +02002962 switch (r) {
2963 case 1:
2964 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
2965 thresh_hi, VTY_NEWLINE);
2966 break;
2967 case EARFCN_THRESH_LOW_INVALID:
2968 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
2969 thresh_lo, VTY_NEWLINE);
2970 break;
2971 case EARFCN_QRXLV_INVALID + 1:
2972 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
2973 qrx, VTY_NEWLINE);
2974 break;
2975 case EARFCN_PRIO_INVALID:
2976 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
2977 prio, VTY_NEWLINE);
2978 break;
2979 default:
2980 if (r < 0) {
2981 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
2982 return CMD_WARNING;
2983 }
Max59a1bf32016-04-15 16:04:46 +02002984 }
2985
Max70fdd242017-06-15 15:10:53 +02002986 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01002987 return CMD_SUCCESS;
2988
Maxf39d03a2017-05-12 17:00:30 +02002989 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02002990 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02002991 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01002992
Maxaafff962016-04-20 15:57:14 +02002993 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02002994}
2995
2996DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02002997 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02002998 "SI2quater Neighbor List\n"
2999 "SI2quater Neighbor List\n"
3000 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02003001 "EARFCN of neighbor\n"
3002 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02003003{
3004 struct gsm_bts *bts = vty->index;
3005 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02003006 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02003007 int r = osmo_earfcn_del(e, arfcn);
3008 if (r < 0) {
3009 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02003010 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02003011 return CMD_WARNING;
3012 }
3013
3014 return CMD_SUCCESS;
3015}
3016
Max26679e02016-04-20 15:57:13 +02003017DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02003018 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02003019 "SI2quater Neighbor List\n"
3020 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
3021 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
3022 "diversity bit\n")
3023{
3024 struct gsm_bts *bts = vty->index;
3025 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
3026
3027 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
3028 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02003029 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 +01003030 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02003031 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02003032 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
3033 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01003034 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02003035 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02003036 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02003037 return CMD_WARNING;
3038 }
3039
3040 return CMD_SUCCESS;
3041}
3042
3043DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02003044 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02003045 "SI2quater Neighbor List\n"
3046 "SI2quater Neighbor List\n"
3047 "Delete from SI2quater manual neighbor list\n"
3048 "UARFCN of neighbor\n"
3049 "UARFCN\n"
3050 "scrambling code\n")
3051{
3052 struct gsm_bts *bts = vty->index;
3053
3054 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
3055 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
3056 VTY_NEWLINE);
3057 return CMD_WARNING;
3058 }
3059
3060 return CMD_SUCCESS;
3061}
3062
Harald Welte64c07d22011-02-15 11:43:27 +01003063DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003064 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003065 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003066 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
3067 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
3068 "ARFCN of neighbor\n")
3069{
3070 struct gsm_bts *bts = vty->index;
3071 struct bitvec *bv = &bts->si_common.si5_neigh_list;
3072 uint16_t arfcn = atoi(argv[1]);
3073
3074 if (!bts->neigh_list_manual_mode) {
3075 vty_out(vty, "%% Cannot configure neighbor list in "
3076 "automatic mode%s", VTY_NEWLINE);
3077 return CMD_WARNING;
3078 }
3079
3080 if (!strcmp(argv[0], "add"))
3081 bitvec_set_bit_pos(bv, arfcn, 1);
3082 else
3083 bitvec_set_bit_pos(bv, arfcn, 0);
3084
3085 return CMD_SUCCESS;
3086}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003087
Harald Welte8254cf72017-05-29 13:42:19 +02003088DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3089 "pcu-socket PATH",
3090 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3091 "Path in the file system for the unix-domain PCU socket\n")
3092{
3093 struct gsm_bts *bts = vty->index;
3094 int rc;
3095
Harald Welte4a824ca2017-05-29 13:54:27 +02003096 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003097 pcu_sock_exit(bts);
3098 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3099 if (rc < 0) {
3100 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3101 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3102 return CMD_WARNING;
3103 }
3104
3105 return CMD_SUCCESS;
3106}
3107
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003108#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3109
3110DEFUN(cfg_bts_excl_rf_lock,
3111 cfg_bts_excl_rf_lock_cmd,
3112 "rf-lock-exclude",
3113 EXCL_RFLOCK_STR)
3114{
3115 struct gsm_bts *bts = vty->index;
3116 bts->excl_from_rf_lock = 1;
3117 return CMD_SUCCESS;
3118}
3119
3120DEFUN(cfg_bts_no_excl_rf_lock,
3121 cfg_bts_no_excl_rf_lock_cmd,
3122 "no rf-lock-exclude",
3123 NO_STR EXCL_RFLOCK_STR)
3124{
3125 struct gsm_bts *bts = vty->index;
3126 bts->excl_from_rf_lock = 0;
3127 return CMD_SUCCESS;
3128}
3129
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003130#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3131
3132DEFUN(cfg_bts_force_comb_si,
3133 cfg_bts_force_comb_si_cmd,
3134 "force-combined-si",
3135 FORCE_COMB_SI_STR)
3136{
3137 struct gsm_bts *bts = vty->index;
3138 bts->force_combined_si = 1;
3139 return CMD_SUCCESS;
3140}
3141
3142DEFUN(cfg_bts_no_force_comb_si,
3143 cfg_bts_no_force_comb_si_cmd,
3144 "no force-combined-si",
3145 NO_STR FORCE_COMB_SI_STR)
3146{
3147 struct gsm_bts *bts = vty->index;
3148 bts->force_combined_si = 0;
3149 return CMD_SUCCESS;
3150}
3151
Andreas Eversberga83d5112013-12-07 18:32:28 +01003152static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3153{
3154 struct gsm_bts *bts = vty->index;
3155 struct bts_codec_conf *codec = &bts->codec;
3156 int i;
3157
3158 codec->hr = 0;
3159 codec->efr = 0;
3160 codec->amr = 0;
3161 for (i = 0; i < argc; i++) {
3162 if (!strcmp(argv[i], "hr"))
3163 codec->hr = 1;
3164 if (!strcmp(argv[i], "efr"))
3165 codec->efr = 1;
3166 if (!strcmp(argv[i], "amr"))
3167 codec->amr = 1;
3168 }
3169}
3170
3171#define CODEC_PAR_STR " (hr|efr|amr)"
3172#define CODEC_HELP_STR "Half Rate\n" \
3173 "Enhanced Full Rate\nAdaptive Multirate\n"
3174
3175DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3176 "codec-support fr",
3177 "Codec Support settings\nFullrate\n")
3178{
3179 _get_codec_from_arg(vty, 0, argv);
3180 return CMD_SUCCESS;
3181}
3182
3183DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3184 "codec-support fr" CODEC_PAR_STR,
3185 "Codec Support settings\nFullrate\n"
3186 CODEC_HELP_STR)
3187{
3188 _get_codec_from_arg(vty, 1, argv);
3189 return CMD_SUCCESS;
3190}
3191
3192DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3193 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3194 "Codec Support settings\nFullrate\n"
3195 CODEC_HELP_STR CODEC_HELP_STR)
3196{
3197 _get_codec_from_arg(vty, 2, argv);
3198 return CMD_SUCCESS;
3199}
3200
3201DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3202 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3203 "Codec Support settings\nFullrate\n"
3204 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3205{
3206 _get_codec_from_arg(vty, 3, argv);
3207 return CMD_SUCCESS;
3208}
3209
3210DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3211 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3212 "Codec Support settings\nFullrate\n"
3213 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3214{
3215 _get_codec_from_arg(vty, 4, argv);
3216 return CMD_SUCCESS;
3217}
3218
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003219DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3220 "depends-on-bts <0-255>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003221 "This BTS can only be started if another one is up\n"
3222 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003223{
3224 struct gsm_bts *bts = vty->index;
3225 struct gsm_bts *other_bts;
3226 int dep = atoi(argv[0]);
3227
3228
3229 if (!is_ipaccess_bts(bts)) {
3230 vty_out(vty, "This feature is only available for IP systems.%s",
3231 VTY_NEWLINE);
3232 return CMD_WARNING;
3233 }
3234
3235 other_bts = gsm_bts_num(bts->network, dep);
3236 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3237 vty_out(vty, "This feature is only available for IP systems.%s",
3238 VTY_NEWLINE);
3239 return CMD_WARNING;
3240 }
3241
3242 if (dep >= bts->nr) {
3243 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3244 VTY_NEWLINE);
3245 return CMD_WARNING;
3246 }
3247
3248 bts_depend_mark(bts, dep);
3249 return CMD_SUCCESS;
3250}
3251
3252DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3253 "depeneds-on-bts <0-255>",
3254 NO_STR "This BTS can only be started if another one is up\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003255 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003256{
3257 struct gsm_bts *bts = vty->index;
3258 int dep = atoi(argv[0]);
3259
3260 bts_depend_clear(bts, dep);
3261 return CMD_SUCCESS;
3262}
3263
Andreas Eversberg73266522014-01-19 11:47:44 +01003264#define AMR_TEXT "Adaptive Multi Rate settings\n"
3265#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3266#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3267 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3268#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3269#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3270
3271static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3272{
3273 struct gsm_bts *bts = vty->index;
3274 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3275 struct gsm48_multi_rate_conf *mr_conf =
3276 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3277 int i;
3278
3279 mr->gsm48_ie[1] = 0;
3280 for (i = 0; i < argc; i++)
3281 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3282 mr_conf->icmi = 0;
3283}
3284
3285static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3286{
3287 struct gsm_bts *bts = vty->index;
3288 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003289 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003290 int i;
3291
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003292 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3293 for (i = 0; i < argc - 1; i++)
3294 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003295}
3296
3297static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3298{
3299 struct gsm_bts *bts = vty->index;
3300 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003301 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003302 int i;
3303
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003304 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3305 for (i = 0; i < argc - 1; i++)
3306 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003307}
3308
3309static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3310{
3311 struct gsm_bts *bts = vty->index;
3312 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3313 struct gsm48_multi_rate_conf *mr_conf =
3314 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3315 int num = 0, i;
3316
3317 for (i = 0; i < ((full) ? 8 : 6); i++) {
3318 if ((mr->gsm48_ie[1] & (1 << i))) {
3319 num++;
3320 }
3321 }
3322
3323 if (argv[0][0] == 'a' || num == 0)
3324 mr_conf->icmi = 0;
3325 else {
3326 mr_conf->icmi = 1;
3327 if (num < atoi(argv[0]))
3328 mr_conf->smod = num - 1;
3329 else
3330 mr_conf->smod = atoi(argv[0]) - 1;
3331 }
3332}
3333
3334#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3335#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3336 "10,2k\n12,2k\n"
3337
3338#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3339#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3340
3341#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3342#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3343
3344DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3345 "amr tch-f modes" AMR_TCHF_PAR_STR,
3346 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3347 AMR_TCHF_HELP_STR)
3348{
3349 get_amr_from_arg(vty, 1, argv, 1);
3350 return CMD_SUCCESS;
3351}
3352
3353DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3354 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3355 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3356 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3357{
3358 get_amr_from_arg(vty, 2, argv, 1);
3359 return CMD_SUCCESS;
3360}
3361
3362DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3363 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3364 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3365 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3366{
3367 get_amr_from_arg(vty, 3, argv, 1);
3368 return CMD_SUCCESS;
3369}
3370
3371DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3372 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3373 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3374 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3375{
3376 get_amr_from_arg(vty, 4, argv, 1);
3377 return CMD_SUCCESS;
3378}
3379
3380DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3381 "amr tch-f start-mode (auto|1|2|3|4)",
3382 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3383{
3384 get_amr_start_from_arg(vty, argv, 1);
3385 return CMD_SUCCESS;
3386}
3387
3388DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3389 "amr tch-f threshold (ms|bts) <0-63>",
3390 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3391 AMR_TH_HELP_STR)
3392{
3393 get_amr_th_from_arg(vty, 2, argv, 1);
3394 return CMD_SUCCESS;
3395}
3396
3397DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3398 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3399 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3400 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3401{
3402 get_amr_th_from_arg(vty, 3, argv, 1);
3403 return CMD_SUCCESS;
3404}
3405
3406DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3407 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3408 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3409 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3410{
3411 get_amr_th_from_arg(vty, 4, argv, 1);
3412 return CMD_SUCCESS;
3413}
3414
3415DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3416 "amr tch-f hysteresis (ms|bts) <0-15>",
3417 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3418 AMR_HY_HELP_STR)
3419{
3420 get_amr_hy_from_arg(vty, 2, argv, 1);
3421 return CMD_SUCCESS;
3422}
3423
3424DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3425 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3426 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3427 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3428{
3429 get_amr_hy_from_arg(vty, 3, argv, 1);
3430 return CMD_SUCCESS;
3431}
3432
3433DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3434 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3435 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3436 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3437{
3438 get_amr_hy_from_arg(vty, 4, argv, 1);
3439 return CMD_SUCCESS;
3440}
3441
3442DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3443 "amr tch-h modes" AMR_TCHH_PAR_STR,
3444 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3445 AMR_TCHH_HELP_STR)
3446{
3447 get_amr_from_arg(vty, 1, argv, 0);
3448 return CMD_SUCCESS;
3449}
3450
3451DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3452 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3453 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3454 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3455{
3456 get_amr_from_arg(vty, 2, argv, 0);
3457 return CMD_SUCCESS;
3458}
3459
3460DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3461 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3462 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3463 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3464{
3465 get_amr_from_arg(vty, 3, argv, 0);
3466 return CMD_SUCCESS;
3467}
3468
3469DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3470 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3471 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3472 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3473{
3474 get_amr_from_arg(vty, 4, argv, 0);
3475 return CMD_SUCCESS;
3476}
3477
3478DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3479 "amr tch-h start-mode (auto|1|2|3|4)",
3480 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3481{
3482 get_amr_start_from_arg(vty, argv, 0);
3483 return CMD_SUCCESS;
3484}
3485
3486DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3487 "amr tch-h threshold (ms|bts) <0-63>",
3488 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3489 AMR_TH_HELP_STR)
3490{
3491 get_amr_th_from_arg(vty, 2, argv, 0);
3492 return CMD_SUCCESS;
3493}
3494
3495DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3496 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3497 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3498 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3499{
3500 get_amr_th_from_arg(vty, 3, argv, 0);
3501 return CMD_SUCCESS;
3502}
3503
3504DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3505 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3506 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3507 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3508{
3509 get_amr_th_from_arg(vty, 4, argv, 0);
3510 return CMD_SUCCESS;
3511}
3512
3513DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3514 "amr tch-h hysteresis (ms|bts) <0-15>",
3515 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3516 AMR_HY_HELP_STR)
3517{
3518 get_amr_hy_from_arg(vty, 2, argv, 0);
3519 return CMD_SUCCESS;
3520}
3521
3522DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3523 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3524 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3525 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3526{
3527 get_amr_hy_from_arg(vty, 3, argv, 0);
3528 return CMD_SUCCESS;
3529}
3530
3531DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3532 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3533 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3534 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3535{
3536 get_amr_hy_from_arg(vty, 4, argv, 0);
3537 return CMD_SUCCESS;
3538}
3539
Harald Welte8f0ed552010-05-11 21:53:49 +02003540#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003541
Harald Welte5258fc42009-03-28 19:07:53 +00003542/* per TRX configuration */
3543DEFUN(cfg_trx,
3544 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003545 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003546 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003547 "Select a TRX to configure")
3548{
3549 int trx_nr = atoi(argv[0]);
3550 struct gsm_bts *bts = vty->index;
3551 struct gsm_bts_trx *trx;
3552
Harald Weltee441d9c2009-06-21 16:17:15 +02003553 if (trx_nr > bts->num_trx) {
3554 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3555 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003556 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003557 } else if (trx_nr == bts->num_trx) {
3558 /* we need to allocate a new one */
3559 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003560 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003561 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003562
Harald Weltee441d9c2009-06-21 16:17:15 +02003563 if (!trx)
3564 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003565
3566 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003567 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003568 vty->node = TRX_NODE;
3569
3570 return CMD_SUCCESS;
3571}
3572
3573DEFUN(cfg_trx_arfcn,
3574 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003575 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003576 "Set the ARFCN for this TRX\n"
3577 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003578{
3579 int arfcn = atoi(argv[0]);
3580 struct gsm_bts_trx *trx = vty->index;
3581
3582 /* FIXME: check if this ARFCN is supported by this TRX */
3583
3584 trx->arfcn = arfcn;
3585
3586 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3587 /* FIXME: use OML layer to update the ARFCN */
3588 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3589
3590 return CMD_SUCCESS;
3591}
3592
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003593DEFUN(cfg_trx_nominal_power,
3594 cfg_trx_nominal_power_cmd,
3595 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003596 "Nominal TRX RF Power in dBm\n"
3597 "Nominal TRX RF Power in dBm\n"
3598 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003599{
3600 struct gsm_bts_trx *trx = vty->index;
3601
3602 trx->nominal_power = atoi(argv[0]);
3603
3604 return CMD_SUCCESS;
3605}
3606
Harald Weltefcd24452009-06-20 18:15:19 +02003607DEFUN(cfg_trx_max_power_red,
3608 cfg_trx_max_power_red_cmd,
3609 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003610 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003611 "Reduction of maximum BS RF Power in dB\n")
3612{
3613 int maxpwr_r = atoi(argv[0]);
3614 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003615 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003616
3617 /* FIXME: check if our BTS type supports more than 12 */
3618 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3619 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3620 maxpwr_r, VTY_NEWLINE);
3621 return CMD_WARNING;
3622 }
3623 if (maxpwr_r & 1) {
3624 vty_out(vty, "%% Power %d dB is not an even value%s",
3625 maxpwr_r, VTY_NEWLINE);
3626 return CMD_WARNING;
3627 }
3628
3629 trx->max_power_red = maxpwr_r;
3630
3631 /* FIXME: make sure we update this using OML */
3632
3633 return CMD_SUCCESS;
3634}
3635
Harald Welte42581822009-08-08 16:12:58 +02003636DEFUN(cfg_trx_rsl_e1,
3637 cfg_trx_rsl_e1_cmd,
3638 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003639 "RSL Parameters\n"
3640 "E1/T1 interface to be used for RSL\n"
3641 "E1/T1 interface to be used for RSL\n"
3642 "E1/T1 Line Number to be used for RSL\n"
3643 "E1/T1 Timeslot to be used for RSL\n"
3644 "E1/T1 Timeslot to be used for RSL\n"
3645 "E1/T1 Sub-slot to be used for RSL\n"
3646 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3647 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3648 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3649 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3650 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003651{
3652 struct gsm_bts_trx *trx = vty->index;
3653
3654 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3655
3656 return CMD_SUCCESS;
3657}
3658
3659DEFUN(cfg_trx_rsl_e1_tei,
3660 cfg_trx_rsl_e1_tei_cmd,
3661 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003662 "RSL Parameters\n"
3663 "Set the TEI to be used for RSL\n"
3664 "Set the TEI to be used for RSL\n"
3665 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003666{
3667 struct gsm_bts_trx *trx = vty->index;
3668
3669 trx->rsl_tei = atoi(argv[0]);
3670
3671 return CMD_SUCCESS;
3672}
3673
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003674DEFUN(cfg_trx_rf_locked,
3675 cfg_trx_rf_locked_cmd,
3676 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003677 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3678 "TRX is NOT RF locked (active)\n"
3679 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003680{
3681 int locked = atoi(argv[0]);
3682 struct gsm_bts_trx *trx = vty->index;
3683
Maxbe356ed2017-09-07 19:10:09 +02003684 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003685 return CMD_SUCCESS;
3686}
Harald Welte42581822009-08-08 16:12:58 +02003687
Harald Welte5258fc42009-03-28 19:07:53 +00003688/* per TS configuration */
3689DEFUN(cfg_ts,
3690 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003691 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003692 "Select a Timeslot to configure\n"
3693 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003694{
3695 int ts_nr = atoi(argv[0]);
3696 struct gsm_bts_trx *trx = vty->index;
3697 struct gsm_bts_trx_ts *ts;
3698
3699 if (ts_nr >= TRX_NR_TS) {
3700 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3701 TRX_NR_TS, VTY_NEWLINE);
3702 return CMD_WARNING;
3703 }
3704
3705 ts = &trx->ts[ts_nr];
3706
3707 vty->index = ts;
3708 vty->node = TS_NODE;
3709
3710 return CMD_SUCCESS;
3711}
3712
Harald Weltea6fd58e2009-08-07 00:25:23 +02003713DEFUN(cfg_ts_pchan,
3714 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003715 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003716 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003717{
3718 struct gsm_bts_trx_ts *ts = vty->index;
3719 int pchanc;
3720
3721 pchanc = gsm_pchan_parse(argv[0]);
3722 if (pchanc < 0)
3723 return CMD_WARNING;
3724
3725 ts->pchan = pchanc;
3726
3727 return CMD_SUCCESS;
3728}
3729
3730/* used for backwards compatibility with old config files that still
3731 * have uppercase pchan type names */
3732DEFUN_HIDDEN(cfg_ts_pchan_compat,
3733 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003734 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003735 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003736{
3737 struct gsm_bts_trx_ts *ts = vty->index;
3738 int pchanc;
3739
3740 pchanc = gsm_pchan_parse(argv[0]);
3741 if (pchanc < 0)
3742 return CMD_WARNING;
3743
3744 ts->pchan = pchanc;
3745
3746 return CMD_SUCCESS;
3747}
3748
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003749
3750
Harald Welte135a6482011-05-30 12:09:13 +02003751DEFUN(cfg_ts_tsc,
3752 cfg_ts_tsc_cmd,
3753 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003754 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003755{
3756 struct gsm_bts_trx_ts *ts = vty->index;
3757
Max71d082b2017-05-30 15:03:38 +02003758 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003759 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3760 "falling back to BCC%s", VTY_NEWLINE);
3761 ts->tsc = -1;
3762 return CMD_WARNING;
3763 }
3764
Harald Welte135a6482011-05-30 12:09:13 +02003765 ts->tsc = atoi(argv[0]);
3766
3767 return CMD_SUCCESS;
3768}
3769
Harald Weltea39b0f22010-06-14 22:26:10 +02003770#define HOPPING_STR "Configure frequency hopping\n"
3771
3772DEFUN(cfg_ts_hopping,
3773 cfg_ts_hopping_cmd,
3774 "hopping enabled (0|1)",
3775 HOPPING_STR "Enable or disable frequency hopping\n"
3776 "Disable frequency hopping\n" "Enable frequency hopping\n")
3777{
3778 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003779 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003780
Max71d082b2017-05-30 15:03:38 +02003781 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003782 vty_out(vty, "BTS model does not support hopping%s",
3783 VTY_NEWLINE);
3784 return CMD_WARNING;
3785 }
3786
3787 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003788
3789 return CMD_SUCCESS;
3790}
3791
Harald Welte6e0cd042009-09-12 13:05:33 +02003792DEFUN(cfg_ts_hsn,
3793 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003794 "hopping sequence-number <0-63>",
3795 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003796 "Which hopping sequence to use for this channel\n"
3797 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003798{
3799 struct gsm_bts_trx_ts *ts = vty->index;
3800
3801 ts->hopping.hsn = atoi(argv[0]);
3802
3803 return CMD_SUCCESS;
3804}
3805
3806DEFUN(cfg_ts_maio,
3807 cfg_ts_maio_cmd,
3808 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003809 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003810 "Which hopping MAIO to use for this channel\n"
3811 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003812{
3813 struct gsm_bts_trx_ts *ts = vty->index;
3814
3815 ts->hopping.maio = atoi(argv[0]);
3816
3817 return CMD_SUCCESS;
3818}
3819
3820DEFUN(cfg_ts_arfcn_add,
3821 cfg_ts_arfcn_add_cmd,
3822 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003823 HOPPING_STR "Configure hopping ARFCN list\n"
3824 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003825{
3826 struct gsm_bts_trx_ts *ts = vty->index;
3827 int arfcn = atoi(argv[0]);
3828
Harald Weltea39b0f22010-06-14 22:26:10 +02003829 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3830
Harald Welte6e0cd042009-09-12 13:05:33 +02003831 return CMD_SUCCESS;
3832}
3833
3834DEFUN(cfg_ts_arfcn_del,
3835 cfg_ts_arfcn_del_cmd,
3836 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003837 HOPPING_STR "Configure hopping ARFCN list\n"
3838 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003839{
3840 struct gsm_bts_trx_ts *ts = vty->index;
3841 int arfcn = atoi(argv[0]);
3842
Harald Weltea39b0f22010-06-14 22:26:10 +02003843 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3844
Harald Welte6e0cd042009-09-12 13:05:33 +02003845 return CMD_SUCCESS;
3846}
3847
Harald Weltea6fd58e2009-08-07 00:25:23 +02003848DEFUN(cfg_ts_e1_subslot,
3849 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003850 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003851 "E1/T1 channel connected to this on-air timeslot\n"
3852 "E1/T1 channel connected to this on-air timeslot\n"
3853 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003854 "E1/T1 timeslot connected to this on-air timeslot\n"
3855 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003856 "E1/T1 sub-slot connected to this on-air timeslot\n"
3857 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3858 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3859 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3860 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3861 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003862{
3863 struct gsm_bts_trx_ts *ts = vty->index;
3864
Harald Welte42581822009-08-08 16:12:58 +02003865 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003866
3867 return CMD_SUCCESS;
3868}
Harald Welte5258fc42009-03-28 19:07:53 +00003869
Harald Welte4f10c252010-05-16 21:47:13 +02003870void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3871{
Harald Weltecf9d4312017-12-13 23:17:16 +01003872 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003873 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003874 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003875 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003876}
3877
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003878DEFUN(drop_bts,
3879 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003880 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003881 "Debug/Simulation command to drop Abis/IP BTS\n"
3882 "Debug/Simulation command to drop Abis/IP BTS\n"
3883 "Debug/Simulation command to drop Abis/IP BTS\n"
3884 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003885{
3886 struct gsm_network *gsmnet;
3887 struct gsm_bts_trx *trx;
3888 struct gsm_bts *bts;
3889 unsigned int bts_nr;
3890
3891 gsmnet = gsmnet_from_vty(vty);
3892
3893 bts_nr = atoi(argv[0]);
3894 if (bts_nr >= gsmnet->num_bts) {
3895 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3896 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3897 return CMD_WARNING;
3898 }
3899
3900 bts = gsm_bts_num(gsmnet, bts_nr);
3901 if (!bts) {
3902 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3903 return CMD_WARNING;
3904 }
3905
3906 if (!is_ipaccess_bts(bts)) {
3907 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3908 return CMD_WARNING;
3909 }
3910
3911
3912 /* close all connections */
3913 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003914 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003915 } else if (strcmp(argv[1], "rsl") == 0) {
3916 /* close all rsl connections */
3917 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003918 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003919 }
3920 } else {
3921 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3922 return CMD_WARNING;
3923 }
3924
3925 return CMD_SUCCESS;
3926}
3927
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003928DEFUN(restart_bts, restart_bts_cmd,
3929 "restart-bts <0-65535>",
3930 "Restart ip.access nanoBTS through OML\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003931 BTS_NR_STR)
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003932{
3933 struct gsm_network *gsmnet;
3934 struct gsm_bts_trx *trx;
3935 struct gsm_bts *bts;
3936 unsigned int bts_nr;
3937
3938 gsmnet = gsmnet_from_vty(vty);
3939
3940 bts_nr = atoi(argv[0]);
3941 if (bts_nr >= gsmnet->num_bts) {
3942 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3943 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3944 return CMD_WARNING;
3945 }
3946
3947 bts = gsm_bts_num(gsmnet, bts_nr);
3948 if (!bts) {
3949 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3950 return CMD_WARNING;
3951 }
3952
3953 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
3954 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
3955 VTY_NEWLINE);
3956 return CMD_WARNING;
3957 }
3958
3959 /* go from last TRX to c0 */
3960 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3961 abis_nm_ipaccess_restart(trx);
3962
3963 return CMD_SUCCESS;
3964}
3965
Harald Welte8e2e22f2017-07-10 20:25:10 +02003966DEFUN(bts_resend, bts_resend_cmd,
3967 "bts <0-255> resend-system-information",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003968 "BTS Specific Commands\n" BTS_NR_STR
Harald Welte8e2e22f2017-07-10 20:25:10 +02003969 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
3970{
3971 struct gsm_network *gsmnet;
3972 struct gsm_bts_trx *trx;
3973 struct gsm_bts *bts;
3974 unsigned int bts_nr;
3975
3976 gsmnet = gsmnet_from_vty(vty);
3977
3978 bts_nr = atoi(argv[0]);
3979 if (bts_nr >= gsmnet->num_bts) {
3980 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3981 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3982 return CMD_WARNING;
3983 }
3984
3985 bts = gsm_bts_num(gsmnet, bts_nr);
3986 if (!bts) {
3987 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3988 return CMD_WARNING;
3989 }
3990
3991 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
3992 gsm_bts_trx_set_system_infos(trx);
3993
3994 return CMD_SUCCESS;
3995}
3996
3997
Harald Welte30f1f372014-12-28 15:00:45 +01003998DEFUN(smscb_cmd, smscb_cmd_cmd,
3999 "bts <0-255> smscb-command <1-4> HEXSTRING",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004000 "BTS related commands\n" BTS_NR_STR
Harald Welte30f1f372014-12-28 15:00:45 +01004001 "SMS Cell Broadcast\n" "Last Valid Block\n"
4002 "Hex Encoded SMSCB message (up to 88 octets)\n")
4003{
4004 struct gsm_bts *bts;
4005 int bts_nr = atoi(argv[0]);
4006 int last_block = atoi(argv[1]);
4007 struct rsl_ie_cb_cmd_type cb_cmd;
4008 uint8_t buf[88];
4009 int rc;
4010
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02004011 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01004012 if (!bts) {
4013 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4014 return CMD_WARNING;
4015 }
4016 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
4017 if (rc < 0 || rc > sizeof(buf)) {
4018 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
4019 return CMD_WARNING;
4020 }
4021
4022 cb_cmd.spare = 0;
4023 cb_cmd.def_bcast = 0;
4024 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
4025
4026 switch (last_block) {
4027 case 1:
4028 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
4029 break;
4030 case 2:
4031 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
4032 break;
4033 case 3:
4034 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
4035 break;
4036 case 4:
4037 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
4038 break;
4039 }
4040
4041 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
4042
4043 return CMD_SUCCESS;
4044}
4045
Harald Welte7fe00fb2017-05-27 14:09:50 +02004046/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02004047static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
4048 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02004049{
Harald Welte645eb622017-05-27 15:52:58 +02004050 int bts_nr = atoi(bts_str);
4051 int trx_nr = atoi(trx_str);
4052 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004053 struct gsm_bts *bts;
4054 struct gsm_bts_trx *trx;
4055 struct gsm_bts_trx_ts *ts;
4056
4057 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
4058 if (!bts) {
4059 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4060 return NULL;
4061 }
4062
4063 trx = gsm_bts_trx_num(bts, trx_nr);
4064 if (!trx) {
4065 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
4066 return NULL;
4067 }
4068
4069 ts = &trx->ts[ts_nr];
4070
4071 return ts;
4072}
Harald Welte30f1f372014-12-28 15:00:45 +01004073
Harald Welted0d2b0b2010-12-23 13:18:07 +01004074DEFUN(pdch_act, pdch_act_cmd,
4075 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004076 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4077 "TRX Timeslot\n" TS_NR_STR "Packet Data Channel\n"
Harald Welted0d2b0b2010-12-23 13:18:07 +01004078 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4079 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4080{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004081 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004082 int activate;
4083
Harald Welte645eb622017-05-27 15:52:58 +02004084 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004085 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004086 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004087
Harald Welte7fe00fb2017-05-27 14:09:50 +02004088 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004089 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4090 VTY_NEWLINE);
4091 return CMD_WARNING;
4092 }
4093
Harald Welted0d2b0b2010-12-23 13:18:07 +01004094 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4095 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004096 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004097 return CMD_WARNING;
4098 }
4099
4100 if (!strcmp(argv[3], "activate"))
4101 activate = 1;
4102 else
4103 activate = 0;
4104
4105 rsl_ipacc_pdch_activate(ts, activate);
4106
4107 return CMD_SUCCESS;
4108
4109}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004110
Harald Welte2abd5e12017-05-27 14:10:40 +02004111/* determine the logical channel type based on the physical channel type */
4112static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4113{
4114 switch (pchan) {
4115 case GSM_PCHAN_TCH_F:
4116 return GSM_LCHAN_TCH_F;
4117 case GSM_PCHAN_TCH_H:
4118 return GSM_LCHAN_TCH_H;
4119 case GSM_PCHAN_SDCCH8_SACCH8C:
4120 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4121 case GSM_PCHAN_CCCH_SDCCH4:
4122 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4123 return GSM_LCHAN_SDCCH;
4124 default:
4125 return -1;
4126 }
4127}
4128
4129/* configure the lchan for a single AMR mode (as specified) */
4130static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4131{
4132 struct amr_multirate_conf mr;
4133 struct gsm48_multi_rate_conf *mr_conf;
4134 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4135
4136 if (amr_mode > 7)
4137 return -1;
4138
4139 memset(&mr, 0, sizeof(mr));
4140 mr_conf->ver = 1;
4141 /* bit-mask of supported modes, only one bit is set. Reflects
4142 * Figure 10.5.2.47a where there are no thershold and only a
4143 * single mode */
4144 mr.gsm48_ie[1] = 1 << amr_mode;
4145
4146 mr.ms_mode[0].mode = amr_mode;
4147 mr.bts_mode[0].mode = amr_mode;
4148
4149 /* encode this configuration into the lchan for both uplink and
4150 * downlink direction */
4151 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4152 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4153
4154 return 0;
4155}
4156
4157/* Debug/Measurement command to activate a given logical channel
4158 * manually in a given mode/codec. This is useful for receiver
4159 * performance testing (FER/RBER/...) */
4160DEFUN(lchan_act, lchan_act_cmd,
4161 "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 +01004162 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4163 "TRX Timeslot\n" TS_NR_STR "Sub-Slot Number\n" LCHAN_NR_STR
Harald Welte2abd5e12017-05-27 14:10:40 +02004164 "Manual Channel Activation (e.g. for BER test)\n"
4165 "Manual Channel Deactivation (e.g. for BER test)\n"
4166 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4167{
4168 struct gsm_bts_trx_ts *ts;
4169 struct gsm_lchan *lchan;
4170 int ss_nr = atoi(argv[3]);
4171 const char *act_str = argv[4];
4172 const char *codec_str = argv[5];
4173 int activate;
4174
4175 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4176 if (!ts)
4177 return CMD_WARNING;
4178
4179 lchan = &ts->lchan[ss_nr];
4180
4181 if (!strcmp(act_str, "activate"))
4182 activate = 1;
4183 else
4184 activate = 0;
4185
4186 if (ss_nr >= ts_subslots(ts)) {
4187 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4188 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4189 return CMD_WARNING;
4190 }
4191
4192 if (activate) {
4193 int lchan_t;
4194 if (lchan->state != LCHAN_S_NONE) {
4195 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4196 return CMD_WARNING;
4197 }
4198 lchan_t = lchan_type_by_pchan(ts->pchan);
4199 if (lchan_t < 0)
4200 return CMD_WARNING;
4201 /* configure the lchan */
4202 lchan->type = lchan_t;
4203 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4204 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4205 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4206 else if (!strcmp(codec_str, "efr"))
4207 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4208 else if (!strcmp(codec_str, "amr")) {
4209 int amr_mode;
4210 if (argc < 7) {
4211 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4212 return CMD_WARNING;
4213 }
4214 amr_mode = atoi(argv[6]);
4215 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4216 lchan_set_single_amr_mode(lchan, amr_mode);
4217 }
4218 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4219 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4220 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004221 } else {
4222 rsl_direct_rf_release(lchan);
4223 }
4224
4225 return CMD_SUCCESS;
4226}
4227
Harald Welte3f86c522017-05-27 15:53:28 +02004228DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4229 "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 +01004230 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4231 "TRX Timeslot\n" TS_NR_STR "Sub-Slot\n" LCHAN_NR_STR
Harald Welte3f86c522017-05-27 15:53:28 +02004232 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4233{
4234 struct gsm_bts_trx_ts *ts;
4235 struct gsm_lchan *lchan;
4236 int ss_nr = atoi(argv[3]);
4237 int port = atoi(argv[5]);
4238 struct in_addr ia;
4239 inet_aton(argv[4], &ia);
4240
4241 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4242 if (!ts)
4243 return CMD_WARNING;
4244
4245 lchan = &ts->lchan[ss_nr];
4246
4247 if (ss_nr >= ts_subslots(ts)) {
4248 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4249 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4250 return CMD_WARNING;
4251 }
4252
4253 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4254 inet_ntoa(ia), port, VTY_NEWLINE);
4255 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4256 return CMD_SUCCESS;
4257}
Harald Welteb71147a2017-07-18 19:11:49 +02004258
4259DEFUN(ctrl_trap, ctrl_trap_cmd,
4260 "ctrl-interface generate-trap TRAP VALUE",
4261 "Commands related to the CTRL Interface\n"
4262 "Generate a TRAP for test purpose\n"
4263 "Identity/Name of the TRAP variable\n"
4264 "Value of the TRAP variable\n")
4265{
4266 struct gsm_network *net = gsmnet_from_vty(vty);
4267
4268 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4269 return CMD_SUCCESS;
4270}
4271
Harald Weltedcccb182010-05-16 20:52:23 +02004272extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004273
Maxdb0e3802017-01-12 19:35:11 +01004274int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004275{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004276 cfg_ts_pchan_cmd.string =
4277 vty_cmd_string_from_valstr(tall_bsc_ctx,
4278 gsm_pchant_names,
4279 "phys_chan_config (", "|", ")",
4280 VTY_DO_LOWER);
4281 cfg_ts_pchan_cmd.doc =
4282 vty_cmd_string_from_valstr(tall_bsc_ctx,
4283 gsm_pchant_descs,
4284 "Physical Channel Combination\n",
4285 "\n", "", 0);
4286
Harald Weltee555c2b2012-08-17 13:02:12 +02004287 cfg_bts_type_cmd.string =
4288 vty_cmd_string_from_valstr(tall_bsc_ctx,
4289 bts_type_names,
4290 "type (", "|", ")",
4291 VTY_DO_LOWER);
4292 cfg_bts_type_cmd.doc =
4293 vty_cmd_string_from_valstr(tall_bsc_ctx,
4294 bts_type_descs,
4295 "BTS Vendor/Type\n",
4296 "\n", "", 0);
4297
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +02004298 common_cs_vty_init(network, config_write_net);
Harald Weltee555c2b2012-08-17 13:02:12 +02004299
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004300 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004301 install_element_ve(&show_bts_cmd);
4302 install_element_ve(&show_trx_cmd);
4303 install_element_ve(&show_ts_cmd);
4304 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004305 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004306
Philipp Maier39f62bb2017-04-09 12:32:51 +02004307 install_element_ve(&show_subscr_conn_cmd);
4308 install_element_ve(&handover_subscr_conn_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004309 install_element_ve(&handover_any_cmd);
4310 install_element_ve(&assignment_subscr_conn_cmd);
4311 install_element_ve(&assignment_any_cmd);
Philipp Maier39f62bb2017-04-09 12:32:51 +02004312
Harald Welteb4d5b172010-05-12 16:10:35 +00004313 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004314 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004315
Maxdb0e3802017-01-12 19:35:11 +01004316 logging_vty_add_cmds(NULL);
Harald Welte2f4f4b82018-02-14 00:50:27 +01004317 osmo_talloc_vty_add_cmds();
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004318
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004319 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004320 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004321 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4322 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4323 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4324 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4325 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4326 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4327 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4328 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4329 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004330 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004331 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004332 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004333 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004334 /* See also handover commands added on net level from handover_vty.c */
Harald Welte5013b2a2009-08-07 13:29:14 +02004335
4336 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004337 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004338 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004339 install_element(BTS_NODE, &cfg_description_cmd);
4340 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004341 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004342 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004343 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4344 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4345 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4346 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004347 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4348 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004349 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004350 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004351 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004352 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004353 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004354 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004355 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004356 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4357 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004358 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004359 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4360 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004361 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4362 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4363 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004364 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4365 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004366 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004367 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004368 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004369 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004370 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4371 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004372 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4373 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4374 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4375 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4376 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4377 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004378 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004379 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004380 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304381 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004382 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004383 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004384 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004385 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4386 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004387 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004388 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004389 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004390 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004391 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4392 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4393 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004394 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004395 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4396 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004397 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004398 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004399 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4400 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004401 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004402 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4403 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004404 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4405 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004406 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4407 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004408 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4409 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004410 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4411 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4412 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4413 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4414 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004415 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4416 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004417 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4418 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4419 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4420 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4421 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4422 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4423 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4424 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4425 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4426 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4427 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4428 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4429 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4430 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4431 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4432 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4433 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4434 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4435 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4436 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4437 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4438 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004439 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004440 /* See also handover commands added on bts level from handover_vty.c */
Harald Welte68628e82009-03-10 12:17:57 +00004441
Harald Welte5258fc42009-03-28 19:07:53 +00004442 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004443 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004444 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004445 install_element(TRX_NODE, &cfg_description_cmd);
4446 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004447 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004448 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004449 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4450 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004451 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004452
Harald Welte5258fc42009-03-28 19:07:53 +00004453 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004454 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004455 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004456 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004457 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004458 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004459 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4460 install_element(TS_NODE, &cfg_ts_maio_cmd);
4461 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4462 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004463 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004464
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004465 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004466 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004467 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004468 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004469 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004470 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004471 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004472 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004473
Harald Welte81c9b9c2010-05-31 16:40:40 +02004474 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004475 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004476 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004477 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004478
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004479 ho_vty_init();
4480
Harald Weltedcccb182010-05-16 20:52:23 +02004481 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004482
Harald Welte68628e82009-03-10 12:17:57 +00004483 return 0;
4484}