blob: d3440281135eb9e3a31cf742d6d668dc8453fad1 [file] [log] [blame]
Harald Welte68628e82009-03-10 12:17:57 +00001/* OpenBSC interface to quagga VTY */
Harald Welteaf387632010-03-14 23:30:30 +08002/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Harald Welte68628e82009-03-10 12:17:57 +00003 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +01006 * it under the terms of the GNU Affero General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
Harald Welte68628e82009-03-10 12:17:57 +00008 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010013 * GNU Affero General Public License for more details.
Harald Welte68628e82009-03-10 12:17:57 +000014 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010015 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte68628e82009-03-10 12:17:57 +000017 *
18 */
19
20#include <stdlib.h>
Maxc08ee712016-05-11 12:45:13 +020021#include <stdbool.h>
Harald Welte68628e82009-03-10 12:17:57 +000022#include <unistd.h>
Maxd1f70ed2017-09-21 16:15:32 +020023#include <time.h>
Harald Welte68628e82009-03-10 12:17:57 +000024
Harald Welte4b037e42010-05-19 19:45:32 +020025#include <osmocom/vty/command.h>
26#include <osmocom/vty/buffer.h>
27#include <osmocom/vty/vty.h>
28#include <osmocom/vty/logging.h>
Jacob Erlbeck64630cc2015-10-26 16:25:37 +010029#include <osmocom/vty/stats.h>
Harald Welte4b037e42010-05-19 19:45:32 +020030#include <osmocom/vty/telnet_interface.h>
Harald Welte4ab9d7c2012-08-17 12:42:06 +020031#include <osmocom/vty/misc.h>
Maxc08ee712016-05-11 12:45:13 +020032#include <osmocom/gsm/protocol/gsm_04_08.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010033#include <osmocom/gsm/gsm0502.h>
Harald Welteb71147a2017-07-18 19:11:49 +020034#include <osmocom/ctrl/control_if.h>
Neels Hofmeyr7b656882017-07-09 22:09:18 +020035#include <osmocom/gsm/gsm48.h>
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010036
Harald Welte68628e82009-03-10 12:17:57 +000037#include <arpa/inet.h>
38
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010039#include <osmocom/core/linuxlist.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020040#include <osmocom/bsc/gsm_data.h>
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +020041#include <osmocom/abis/e1_input.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020042#include <osmocom/bsc/abis_nm.h>
43#include <osmocom/bsc/abis_om2000.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010044#include <osmocom/core/utils.h>
45#include <osmocom/gsm/gsm_utils.h>
Harald Weltecdc59ff2011-05-23 20:42:26 +020046#include <osmocom/gsm/abis_nm.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020047#include <osmocom/bsc/chan_alloc.h>
48#include <osmocom/bsc/meas_rep.h>
49#include <osmocom/bsc/vty.h>
Harald Welteea34a4e2012-06-16 14:59:56 +080050#include <osmocom/gprs/gprs_ns.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020051#include <osmocom/bsc/system_information.h>
52#include <osmocom/bsc/debug.h>
53#include <osmocom/bsc/paging.h>
54#include <osmocom/bsc/ipaccess.h>
55#include <osmocom/bsc/abis_rsl.h>
56#include <osmocom/bsc/bsc_msc_data.h>
57#include <osmocom/bsc/osmo_bsc_rf.h>
58#include <osmocom/bsc/pcu_if.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020059#include <osmocom/bsc/handover.h>
Neels Hofmeyre25018b2017-11-27 21:29:33 +010060#include <osmocom/bsc/handover_cfg.h>
61#include <osmocom/bsc/handover_vty.h>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020062#include <osmocom/bsc/gsm_04_08_utils.h>
Neels Hofmeyr06d39fd2016-05-12 01:16:58 +020063
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +010064#include <inttypes.h>
65
Harald Weltec08e8be2011-03-04 13:53:51 +010066#include "../../bscconfig.h"
Harald Welte1353f962010-05-16 19:20:24 +020067
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010068#define BTS_NR_STR "BTS Number\n"
69#define TRX_NR_STR "TRX Number\n"
70#define TS_NR_STR "Timeslot Number\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020071#define LCHAN_NR_STR "Logical Channel Number\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +010072#define BTS_TRX_STR BTS_NR_STR TRX_NR_STR
73#define BTS_TRX_TS_STR BTS_TRX_STR TS_NR_STR
74#define BTS_TRX_TS_LCHAN_STR BTS_TRX_TS_STR LCHAN_NR_STR
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +020075
Harald Welteea4647d2010-05-12 17:19:53 +000076/* FIXME: this should go to some common file */
77static const struct value_string gprs_ns_timer_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020078 { 0, "tns-block" },
79 { 1, "tns-block-retries" },
80 { 2, "tns-reset" },
81 { 3, "tns-reset-retries" },
82 { 4, "tns-test" },
83 { 5, "tns-alive" },
84 { 6, "tns-alive-retries" },
85 { 0, NULL }
86};
87
Harald Welteea4647d2010-05-12 17:19:53 +000088static const struct value_string gprs_bssgp_cfg_strs[] = {
Harald Welte615e9562010-05-11 23:50:21 +020089 { 0, "blocking-timer" },
90 { 1, "blocking-retries" },
91 { 2, "unblocking-retries" },
92 { 3, "reset-timer" },
93 { 4, "reset-retries" },
94 { 5, "suspend-timer" },
95 { 6, "suspend-retries" },
96 { 7, "resume-timer" },
97 { 8, "resume-retries" },
98 { 9, "capability-update-timer" },
99 { 10, "capability-update-retries" },
100 { 0, NULL }
101};
102
Harald Welte64c07d22011-02-15 11:43:27 +0100103static const struct value_string bts_neigh_mode_strs[] = {
104 { NL_MODE_AUTOMATIC, "automatic" },
105 { NL_MODE_MANUAL, "manual" },
106 { NL_MODE_MANUAL_SI5SEP, "manual-si5" },
107 { 0, NULL }
108};
109
Daniel Willmann7d109832012-05-14 18:43:23 +0200110const struct value_string bts_loc_fix_names[] = {
111 { BTS_LOC_FIX_INVALID, "invalid" },
112 { BTS_LOC_FIX_2D, "fix2d" },
113 { BTS_LOC_FIX_3D, "fix3d" },
114 { 0, NULL }
115};
116
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100117struct cmd_node net_node = {
118 GSMNET_NODE,
119 "%s(config-net)# ",
120 1,
121};
122
Harald Welte68628e82009-03-10 12:17:57 +0000123struct cmd_node bts_node = {
124 BTS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200125 "%s(config-net-bts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000126 1,
127};
128
129struct cmd_node trx_node = {
130 TRX_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200131 "%s(config-net-bts-trx)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000132 1,
133};
134
135struct cmd_node ts_node = {
136 TS_NODE,
Harald Welte570ce242012-08-17 13:16:10 +0200137 "%s(config-net-bts-trx-ts)# ",
Harald Welte68628e82009-03-10 12:17:57 +0000138 1,
139};
140
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +0100141static struct gsm_network *vty_global_gsm_network = NULL;
142
143struct gsm_network *gsmnet_from_vty(struct vty *v)
144{
145 /* It can't hurt to force callers to continue to pass the vty instance
146 * to this function, in case we'd like to retrieve the global
147 * gsm_network instance from the vty at some point in the future. But
148 * until then, just return the global pointer, which should have been
149 * initialized by common_cs_vty_init().
150 */
151 OSMO_ASSERT(vty_global_gsm_network);
152 return vty_global_gsm_network;
153}
154
Harald Welte68628e82009-03-10 12:17:57 +0000155static int dummy_config_write(struct vty *v)
156{
157 return CMD_SUCCESS;
158}
159
160static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
161{
Harald Welte1304b352013-03-15 16:57:33 +0100162 vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
163 abis_nm_opstate_name(nms->operational),
164 get_value_string(abis_nm_adm_state_names, nms->administrative),
Harald Welte867d9f32011-05-23 20:30:39 +0200165 abis_nm_avail_name(nms->availability), VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000166}
167
Harald Welteb908cb72009-12-22 13:09:29 +0100168static void dump_pchan_load_vty(struct vty *vty, char *prefix,
169 const struct pchan_load *pl)
170{
171 int i;
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100172 int dumped = 0;
Harald Welteb908cb72009-12-22 13:09:29 +0100173
174 for (i = 0; i < ARRAY_SIZE(pl->pchan); i++) {
175 const struct load_counter *lc = &pl->pchan[i];
176 unsigned int percent;
177
178 if (lc->total == 0)
179 continue;
180
181 percent = (lc->used * 100) / lc->total;
182
183 vty_out(vty, "%s%20s: %3u%% (%u/%u)%s", prefix,
184 gsm_pchan_name(i), percent, lc->used, lc->total,
185 VTY_NEWLINE);
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100186 dumped ++;
Harald Welteb908cb72009-12-22 13:09:29 +0100187 }
Neels Hofmeyr9abc6522018-01-19 00:59:33 +0100188 if (!dumped)
189 vty_out(vty, "%s(none)%s", prefix, VTY_NEWLINE);
Harald Welteb908cb72009-12-22 13:09:29 +0100190}
191
Harald Welte68628e82009-03-10 12:17:57 +0000192static void net_dump_vty(struct vty *vty, struct gsm_network *net)
193{
Harald Welteb908cb72009-12-22 13:09:29 +0100194 struct pchan_load pl;
195
Harald Welteef235b52009-03-10 12:34:02 +0000196 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
197 "and has %u BTS%s", net->country_code, net->network_code,
198 net->num_bts, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200199 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900200 vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption,
201 VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100202 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
203 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800204 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
205 VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100206
207 {
208 struct gsm_bts *bts;
209 unsigned int ho_active_count = 0;
210 unsigned int ho_inactive_count = 0;
211
212 llist_for_each_entry(bts, &net->bts_list, list) {
213 if (ho_get_ho_active(bts->ho))
214 ho_active_count ++;
215 else
216 ho_inactive_count ++;
217 }
218
219 if (ho_active_count && ho_inactive_count)
220 vty_out(vty, " Handover: On at %u BTS, Off at %u BTS%s",
221 ho_active_count, ho_inactive_count, VTY_NEWLINE);
222 else
223 vty_out(vty, " Handover: %s%s", ho_active_count ? "On" : "Off",
224 VTY_NEWLINE);
225 }
226
Harald Welteb908cb72009-12-22 13:09:29 +0100227 network_chan_load(&pl, net);
228 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
229 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100230
231 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100232 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100233 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200234 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100235 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100236 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200237 vty_out(vty, " Last RF Lock Command: %s%s",
238 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
239 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000240}
241
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200242DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000243 SHOW_STR "Display information about a GSM NETWORK\n")
244{
Harald Weltedcccb182010-05-16 20:52:23 +0200245 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000246 net_dump_vty(vty, net);
247
248 return CMD_SUCCESS;
249}
250
251static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
252{
Harald Welteedb37782009-05-01 14:59:07 +0000253 struct e1inp_line *line;
254
255 if (!e1l) {
256 vty_out(vty, " None%s", VTY_NEWLINE);
257 return;
258 }
259
260 line = e1l->ts->line;
261
262 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
263 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000264 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000265 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000266 e1l->tei, e1l->sapi, VTY_NEWLINE);
267}
268
269static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
270{
Harald Welteb908cb72009-12-22 13:09:29 +0100271 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200272 unsigned long long sec;
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100273 struct gsm_bts_trx *trx;
274 int ts_hopping_total;
275 int ts_non_hopping_total;
Harald Welteb908cb72009-12-22 13:09:29 +0100276
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200277 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100278 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200279 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200280 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100281 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100282 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200283 bts->num_trx, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100284 vty_out(vty, " Description: %s%s",
Harald Welte197dea92010-05-14 17:59:53 +0200285 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100286
287 vty_out(vty, " ARFCNs:");
288 ts_hopping_total = 0;
289 ts_non_hopping_total = 0;
290 llist_for_each_entry(trx, &bts->trx_list, list) {
291 int ts_nr;
292 int ts_hopping = 0;
293 int ts_non_hopping = 0;
294 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
295 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
296 if (ts->hopping.enabled)
297 ts_hopping++;
298 else
299 ts_non_hopping++;
300 }
301
302 if (ts_non_hopping)
303 vty_out(vty, " %u", trx->arfcn);
304 ts_hopping_total += ts_hopping;
305 ts_non_hopping_total += ts_non_hopping;
306 }
307 if (ts_hopping_total) {
308 if (ts_non_hopping_total)
309 vty_out(vty, " / Hopping on %d of %d timeslots",
310 ts_hopping_total, ts_hopping_total + ts_non_hopping_total);
311 else
312 vty_out(vty, " Hopping on all %d timeslots", ts_hopping_total);
313 }
314 vty_out(vty, "%s", VTY_NEWLINE);
315
Maxf9685c12017-03-23 12:01:07 +0100316 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100317 vty_out(vty, " PCU version %s connected%s", bts->pcu_version,
Maxf9685c12017-03-23 12:01:07 +0100318 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100319 vty_out(vty, " MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
320 vty_out(vty, " Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100321 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
322 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100323 vty_out(vty, " Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100324 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100325 vty_out(vty, " RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100326 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100327 vty_out(vty, " RACH Max transmissions: %u%s",
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100328 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
329 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100330 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200331 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200332 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100333 vty_out(vty, " Uplink DTX: %s%s",
Maxc08ee712016-05-11 12:45:13 +0200334 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
335 "enabled" : "forced", VTY_NEWLINE);
336 else
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100337 vty_out(vty, " Uplink DTX: not enabled%s", VTY_NEWLINE);
338 vty_out(vty, " Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
Maxc08ee712016-05-11 12:45:13 +0200339 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100340 vty_out(vty, " Channel Description Attachment: %s%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200341 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100342 vty_out(vty, " Channel Description BS-PA-MFRMS: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200343 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100344 vty_out(vty, " Channel Description BS-AG_BLKS-RES: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200345 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100346 vty_out(vty, " System Information present: 0x%08x, static: 0x%08x%s",
Harald Welte9fbff4a2010-07-30 11:50:09 +0200347 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100348 vty_out(vty, " Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100349 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100350 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
351 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
352 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100353 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200354 if (bts->pcu_sock_path)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100355 vty_out(vty, " PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000356 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200357 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000358 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200359 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200360 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
361 vty_out(vty, " Skip Reset: %d%s",
362 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000363 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200364 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000365 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200366 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200367 vty_out(vty, " GPRS NSE: ");
368 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
369 vty_out(vty, " GPRS CELL: ");
370 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
371 vty_out(vty, " GPRS NSVC0: ");
372 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
373 vty_out(vty, " GPRS NSVC1: ");
374 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200375 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
376 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000377 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100378 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200379 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200380 sec = bts_uptime(bts);
381 if (sec)
Maxff3fad12018-01-07 16:50:42 +0100382 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.",
383 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60);
384 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100385 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200386 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
387 e1isl_dump_vty(vty, bts->oml_link);
388 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100389
390 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100391 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200392 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100393 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
394 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100395
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100396 vty_out(vty, " Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
Harald Welted82101e2017-12-09 23:07:38 +0100397 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
398 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
399 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100400 vty_out(vty, " Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
Harald Welted82101e2017-12-09 23:07:38 +0100401 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
402 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
403 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100404 vty_out(vty, " BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
Harald Welted82101e2017-12-09 23:07:38 +0100405 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
406 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
407 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000408}
409
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100410DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000411 SHOW_STR "Display information about a BTS\n"
412 "BTS number")
413{
Harald Weltedcccb182010-05-16 20:52:23 +0200414 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000415 int bts_nr;
416
417 if (argc != 0) {
418 /* use the BTS number that the user has specified */
419 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100420 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000421 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000422 VTY_NEWLINE);
423 return CMD_WARNING;
424 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200425 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000426 return CMD_SUCCESS;
427 }
428 /* print all BTS's */
429 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200430 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000431
432 return CMD_SUCCESS;
433}
434
Harald Welte42581822009-08-08 16:12:58 +0200435/* utility functions */
436static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
437 const char *ts, const char *ss)
438{
439 e1_link->e1_nr = atoi(line);
440 e1_link->e1_ts = atoi(ts);
441 if (!strcmp(ss, "full"))
442 e1_link->e1_ts_ss = 255;
443 else
444 e1_link->e1_ts_ss = atoi(ss);
445}
446
447static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
448 const char *prefix)
449{
450 if (!e1_link->e1_ts)
451 return;
452
453 if (e1_link->e1_ts_ss == 255)
454 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
455 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
456 else
457 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
458 prefix, e1_link->e1_nr, e1_link->e1_ts,
459 e1_link->e1_ts_ss, VTY_NEWLINE);
460}
461
462
Harald Welte67ce0732009-08-06 19:06:46 +0200463static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
464{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100465 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100466 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100467 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200468 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100469 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200470 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100471 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200472 ts->hopping.enabled, VTY_NEWLINE);
473 if (ts->hopping.enabled) {
474 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100475 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200476 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100477 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200478 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200479 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
480 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
481 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100482 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200483 i, VTY_NEWLINE);
484 }
Harald Welte127af342010-12-24 12:07:07 +0100485 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100486 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100487
488 if (ts->trx->bts->model->config_write_ts)
489 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200490}
491
492static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
493{
494 int i;
495
Harald Welte5013b2a2009-08-07 13:29:14 +0200496 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200497 if (trx->description)
498 vty_out(vty, " description %s%s", trx->description,
499 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200500 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200501 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200502 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200503 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100504 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200505 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200506 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
507 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200508
Harald Welteface7ed2011-02-14 16:15:21 +0100509 if (trx->bts->model->config_write_trx)
510 trx->bts->model->config_write_trx(vty, trx);
511
Harald Welte67ce0732009-08-06 19:06:46 +0200512 for (i = 0; i < TRX_NR_TS; i++)
513 config_write_ts_single(vty, &trx->ts[i]);
514}
515
Harald Welte615e9562010-05-11 23:50:21 +0200516static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
517{
518 unsigned int i;
519 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
520 VTY_NEWLINE);
521 if (bts->gprs.mode == BTS_GPRS_NONE)
522 return;
523
bhargava350533c2016-07-21 11:14:34 +0530524 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
525 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
526
Harald Welte615e9562010-05-11 23:50:21 +0200527 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
528 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100529 vty_out(vty, " gprs network-control-order nc%u%s",
530 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200531 if (!bts->gprs.ctrl_ack_type_use_block)
532 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200533 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
534 VTY_NEWLINE);
535 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
536 vty_out(vty, " gprs cell timer %s %u%s",
537 get_value_string(gprs_bssgp_cfg_strs, i),
538 bts->gprs.cell.timer[i], VTY_NEWLINE);
539 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
540 VTY_NEWLINE);
541 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
542 vty_out(vty, " gprs ns timer %s %u%s",
543 get_value_string(gprs_ns_timer_strs, i),
544 bts->gprs.nse.timer[i], VTY_NEWLINE);
545 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
546 struct gsm_bts_gprs_nsvc *nsvc =
547 &bts->gprs.nsvc[i];
548 struct in_addr ia;
549
550 ia.s_addr = htonl(nsvc->remote_ip);
551 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
552 nsvc->nsvci, VTY_NEWLINE);
553 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
554 nsvc->local_port, VTY_NEWLINE);
555 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
556 nsvc->remote_port, VTY_NEWLINE);
557 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
558 inet_ntoa(ia), VTY_NEWLINE);
559 }
560}
561
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200562/* Write the model data if there is one */
563static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200564{
565 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200566
567 if (!bts->model)
568 return;
569
570 if (bts->model->config_write_bts)
571 bts->model->config_write_bts(vty, bts);
572
573 llist_for_each_entry(trx, &bts->trx_list, list)
574 config_write_trx_single(vty, trx);
575}
576
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200577static void write_amr_modes(struct vty *vty, const char *prefix,
578 const char *name, struct amr_mode *modes, int num)
579{
580 int i;
581
582 vty_out(vty, " %s threshold %s", prefix, name);
583 for (i = 0; i < num - 1; i++)
584 vty_out(vty, " %d", modes[i].threshold);
585 vty_out(vty, "%s", VTY_NEWLINE);
586 vty_out(vty, " %s hysteresis %s", prefix, name);
587 for (i = 0; i < num - 1; i++)
588 vty_out(vty, " %d", modes[i].hysteresis);
589 vty_out(vty, "%s", VTY_NEWLINE);
590}
591
Andreas Eversberg73266522014-01-19 11:47:44 +0100592static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
593 struct amr_multirate_conf *mr, int full)
594{
595 struct gsm48_multi_rate_conf *mr_conf;
596 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
597 int i, num;
598
599 if (!(mr->gsm48_ie[1]))
600 return;
601
602 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
603
604 num = 0;
605 vty_out(vty, " %s modes", prefix);
606 for (i = 0; i < ((full) ? 8 : 6); i++) {
607 if ((mr->gsm48_ie[1] & (1 << i))) {
608 vty_out(vty, " %d", i);
609 num++;
610 }
611 }
612 vty_out(vty, "%s", VTY_NEWLINE);
613 if (num > 4)
614 num = 4;
615 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200616 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
617 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100618 }
619 vty_out(vty, " %s start-mode ", prefix);
620 if (mr_conf->icmi) {
621 num = 0;
622 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
623 if ((mr->gsm48_ie[1] & (1 << i)))
624 num++;
625 if (mr_conf->smod == num - 1) {
626 vty_out(vty, "%d%s", num, VTY_NEWLINE);
627 break;
628 }
629 }
630 } else
631 vty_out(vty, "auto%s", VTY_NEWLINE);
632}
633
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200634static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
635{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200636 int i;
Max2c16bee2017-02-15 13:51:37 +0100637 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200638
Harald Welte5013b2a2009-08-07 13:29:14 +0200639 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
640 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200641 if (bts->description)
642 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200643 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100644 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200645 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200646 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200647 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
648 vty_out(vty, " dtx uplink%s%s",
649 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
650 VTY_NEWLINE);
651 if (bts->dtxd)
652 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200653 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200654 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100655 vty_out(vty, " cell reselection hysteresis %u%s",
656 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
657 vty_out(vty, " rxlev access min %u%s",
658 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100659
660 if (bts->si_common.cell_ro_sel_par.present) {
661 struct gsm48_si_selection_params *sp;
662 sp = &bts->si_common.cell_ro_sel_par;
663
664 if (sp->cbq)
665 vty_out(vty, " cell bar qualify %u%s",
666 sp->cbq, VTY_NEWLINE);
667
668 if (sp->cell_resel_off)
669 vty_out(vty, " cell reselection offset %u%s",
670 sp->cell_resel_off*2, VTY_NEWLINE);
671
672 if (sp->temp_offs == 7)
673 vty_out(vty, " temporary offset infinite%s",
674 VTY_NEWLINE);
675 else if (sp->temp_offs)
676 vty_out(vty, " temporary offset %u%s",
677 sp->temp_offs*10, VTY_NEWLINE);
678
679 if (sp->penalty_time == 31)
680 vty_out(vty, " penalty time reserved%s",
681 VTY_NEWLINE);
682 else if (sp->penalty_time)
683 vty_out(vty, " penalty time %u%s",
684 (sp->penalty_time*20)+20, VTY_NEWLINE);
685 }
686
Harald Welte2f8b9d22017-06-18 11:12:13 +0300687 if (gsm_bts_get_radio_link_timeout(bts) < 0)
688 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
689 else
690 vty_out(vty, " radio-link-timeout %d%s",
691 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100692
Harald Welte7a8fa412009-08-10 13:48:16 +0200693 vty_out(vty, " channel allocator %s%s",
694 bts->chan_alloc_reverse ? "descending" : "ascending",
695 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100696 vty_out(vty, " rach tx integer %u%s",
697 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
698 vty_out(vty, " rach max transmission %u%s",
699 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
700 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800701
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200702 vty_out(vty, " channel-descrption attach %u%s",
703 bts->si_common.chan_desc.att, VTY_NEWLINE);
704 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
705 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
706 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
707 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
708
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800709 if (bts->rach_b_thresh != -1)
710 vty_out(vty, " rach nm busy threshold %u%s",
711 bts->rach_b_thresh, VTY_NEWLINE);
712 if (bts->rach_ldavg_slots != -1)
713 vty_out(vty, " rach nm load average %u%s",
714 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100715 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200716 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800717 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
718 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400719 if ((bts->si_common.rach_control.t3) != 0)
720 for (i = 0; i < 8; i++)
721 if (bts->si_common.rach_control.t3 & (0x1 << i))
722 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
723 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
724 for (i = 0; i < 8; i++)
725 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
726 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200727 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
728 if (bts->si_mode_static & (1 << i)) {
729 vty_out(vty, " system-information %s mode static%s",
730 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
731 vty_out(vty, " system-information %s static %s%s",
732 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200733 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200734 VTY_NEWLINE);
735 }
736 }
Harald Welte42def722017-01-13 00:10:32 +0100737 vty_out(vty, " early-classmark-sending %s%s",
738 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100739 vty_out(vty, " early-classmark-sending-3g %s%s",
740 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100741 switch (bts->type) {
742 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100743 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200744 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200745 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100746 if (bts->ip_access.rsl_ip) {
747 struct in_addr ia;
748 ia.s_addr = htonl(bts->ip_access.rsl_ip);
749 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
750 VTY_NEWLINE);
751 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200752 vty_out(vty, " oml ip.access stream_id %u line %u%s",
753 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100754 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200755 case GSM_BTS_TYPE_NOKIA_SITE:
756 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100757 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
758 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100759 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 +0100760 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100761 default:
Harald Welte42581822009-08-08 16:12:58 +0200762 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
763 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100764 break;
Harald Welte42581822009-08-08 16:12:58 +0200765 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800766
767 /* if we have a limit, write it */
768 if (bts->paging.free_chans_need >= 0)
769 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
770
Harald Welte32c09622011-01-11 23:44:56 +0100771 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100772 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
773 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100774 for (i = 0; i < 1024; i++) {
775 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
776 vty_out(vty, " neighbor-list add arfcn %u%s",
777 i, VTY_NEWLINE);
778 }
779 }
Harald Welte64c07d22011-02-15 11:43:27 +0100780 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
781 for (i = 0; i < 1024; i++) {
782 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
783 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
784 i, VTY_NEWLINE);
785 }
786 }
Harald Welte32c09622011-01-11 23:44:56 +0100787
Max59a1bf32016-04-15 16:04:46 +0200788 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100789 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
790 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
791 vty_out(vty, " si2quater neighbor-list add earfcn %u "
792 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
793
794 vty_out(vty, " thresh-lo %u",
795 e->thresh_lo_valid ? e->thresh_lo : 32);
796
797 vty_out(vty, " prio %u",
798 e->prio_valid ? e->prio : 8);
799
800 vty_out(vty, " qrxlv %u",
801 e->qrxlm_valid ? e->qrxlm : 32);
802
803 tmp = e->meas_bw[i];
804 vty_out(vty, " meas %u",
805 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200806
807 vty_out(vty, "%s", VTY_NEWLINE);
808 }
809 }
810
Max26679e02016-04-20 15:57:13 +0200811 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
812 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
813 bts->si_common.data.uarfcn_list[i],
814 bts->si_common.data.scramble_list[i] & ~(1 << 9),
815 (bts->si_common.data.scramble_list[i] >> 9) & 1,
816 VTY_NEWLINE);
817 }
818
Andreas Eversberga83d5112013-12-07 18:32:28 +0100819 vty_out(vty, " codec-support fr");
820 if (bts->codec.hr)
821 vty_out(vty, " hr");
822 if (bts->codec.efr)
823 vty_out(vty, " efr");
824 if (bts->codec.amr)
825 vty_out(vty, " amr");
826 vty_out(vty, "%s", VTY_NEWLINE);
827
Andreas Eversberg73266522014-01-19 11:47:44 +0100828 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
829 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
830
Harald Welte615e9562010-05-11 23:50:21 +0200831 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200832
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200833 if (bts->excl_from_rf_lock)
834 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
835
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100836 vty_out(vty, " %sforce-combined-si%s",
837 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
838
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100839 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
840 int j;
841
842 if (bts->depends_on[i] == 0)
843 continue;
844
845 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
846 int bts_nr;
847
848 if ((bts->depends_on[i] & (1<<j)) == 0)
849 continue;
850
851 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
852 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
853 }
854 }
Harald Welte8254cf72017-05-29 13:42:19 +0200855 if (bts->pcu_sock_path)
856 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100857
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100858 ho_vty_write_bts(vty, bts);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100859
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200860 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200861}
862
863static int config_write_bts(struct vty *v)
864{
Harald Weltedcccb182010-05-16 20:52:23 +0200865 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200866 struct gsm_bts *bts;
867
868 llist_for_each_entry(bts, &gsmnet->bts_list, list)
869 config_write_bts_single(v, bts);
870
871 return CMD_SUCCESS;
872}
873
Harald Weltea0d324b2017-07-20 01:47:39 +0200874/* small helper macro for conditional dumping of timer */
875#define VTY_OUT_TIMER(number) \
876 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
877 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
878
Harald Welte5013b2a2009-08-07 13:29:14 +0200879static int config_write_net(struct vty *vty)
880{
Harald Weltedcccb182010-05-16 20:52:23 +0200881 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
882
Harald Welte5013b2a2009-08-07 13:29:14 +0200883 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200884 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200885 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte4381cfe2009-08-30 15:47:06 +0900886 vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100887 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800888 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100889
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100890 ho_vty_write_net(vty, gsmnet);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100891
Harald Weltea0d324b2017-07-20 01:47:39 +0200892 VTY_OUT_TIMER(3101);
893 VTY_OUT_TIMER(3103);
894 VTY_OUT_TIMER(3105);
895 VTY_OUT_TIMER(3107);
896 VTY_OUT_TIMER(3109);
897 VTY_OUT_TIMER(3111);
898 VTY_OUT_TIMER(3113);
899 VTY_OUT_TIMER(3115);
900 VTY_OUT_TIMER(3117);
901 VTY_OUT_TIMER(3119);
902 VTY_OUT_TIMER(3122);
903 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700904 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
905 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200906 if (gsmnet->tz.override != 0) {
907 if (gsmnet->tz.dst)
908 vty_out(vty, " timezone %d %d %d%s",
909 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
910 VTY_NEWLINE);
911 else
912 vty_out(vty, " timezone %d %d%s",
913 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
914 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200915 if (gsmnet->t3212 == 0)
916 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
917 else
918 vty_out(vty, " periodic location update %u%s",
919 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200920
921 return CMD_SUCCESS;
922}
Harald Welte67ce0732009-08-06 19:06:46 +0200923
Harald Welte68628e82009-03-10 12:17:57 +0000924static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
925{
926 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
927 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200928 vty_out(vty, "Description: %s%s",
929 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200930 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200931 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200932 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200933 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000934 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200935 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +0100936 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000937 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200938 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200939 if (is_ipaccess_bts(trx->bts)) {
940 vty_out(vty, " ip.access stream ID: 0x%02x%s",
941 trx->rsl_tei, VTY_NEWLINE);
942 } else {
943 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
944 e1isl_dump_vty(vty, trx->rsl_link);
945 }
Harald Welte68628e82009-03-10 12:17:57 +0000946}
947
Max6e4f1842018-01-07 16:45:42 +0100948static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
949{
950 uint8_t trx_nr;
951 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
952 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
953}
954
Harald Welte68628e82009-03-10 12:17:57 +0000955DEFUN(show_trx,
956 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100957 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +0200958 SHOW_STR "Display information about a TRX\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +0100959 BTS_TRX_STR)
Harald Welte68628e82009-03-10 12:17:57 +0000960{
Harald Weltedcccb182010-05-16 20:52:23 +0200961 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000962 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +0000963 int bts_nr, trx_nr;
964
965 if (argc >= 1) {
966 /* use the BTS number that the user has specified */
967 bts_nr = atoi(argv[0]);
968 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000969 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000970 VTY_NEWLINE);
971 return CMD_WARNING;
972 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200973 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +0000974 }
975 if (argc >= 2) {
976 trx_nr = atoi(argv[1]);
977 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +0000978 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +0000979 VTY_NEWLINE);
980 return CMD_WARNING;
981 }
Max6e4f1842018-01-07 16:45:42 +0100982 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000983 return CMD_SUCCESS;
984 }
985 if (bts) {
986 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +0100987 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +0000988 return CMD_SUCCESS;
989 }
990
Max6e4f1842018-01-07 16:45:42 +0100991 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
992 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000993
994 return CMD_SUCCESS;
995}
996
Harald Welte67ce0732009-08-06 19:06:46 +0200997
Harald Welte68628e82009-03-10 12:17:57 +0000998static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
999{
Harald Welte135a6482011-05-30 12:09:13 +02001000 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +01001001 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +01001002 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +01001003 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +01001004 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001005 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +01001006 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001007 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001008 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +05301009 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +00001010 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
1011 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
1012 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001013}
1014
1015DEFUN(show_ts,
1016 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001017 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001018 SHOW_STR "Display information about a TS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001019 BTS_TRX_TS_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001020{
Harald Weltedcccb182010-05-16 20:52:23 +02001021 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +01001022 struct gsm_bts *bts = NULL;
1023 struct gsm_bts_trx *trx = NULL;
1024 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001025 int bts_nr, trx_nr, ts_nr;
1026
1027 if (argc >= 1) {
1028 /* use the BTS number that the user has specified */
1029 bts_nr = atoi(argv[0]);
1030 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001031 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001032 VTY_NEWLINE);
1033 return CMD_WARNING;
1034 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001035 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001036 }
1037 if (argc >= 2) {
1038 trx_nr = atoi(argv[1]);
1039 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001040 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001041 VTY_NEWLINE);
1042 return CMD_WARNING;
1043 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001044 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001045 }
1046 if (argc >= 3) {
1047 ts_nr = atoi(argv[2]);
1048 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +00001049 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +00001050 VTY_NEWLINE);
1051 return CMD_WARNING;
1052 }
Harald Welte274d0152010-12-24 12:05:03 +01001053 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +00001054 ts = &trx->ts[ts_nr];
1055 ts_dump_vty(vty, ts);
1056 return CMD_SUCCESS;
1057 }
Harald Welte274d0152010-12-24 12:05:03 +01001058
1059 if (bts && trx) {
1060 /* Iterate over all TS in this TRX */
1061 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1062 ts = &trx->ts[ts_nr];
1063 ts_dump_vty(vty, ts);
1064 }
1065 } else if (bts) {
1066 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001067 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001068 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001069 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1070 ts = &trx->ts[ts_nr];
1071 ts_dump_vty(vty, ts);
1072 }
1073 }
Harald Welte274d0152010-12-24 12:05:03 +01001074 } else {
1075 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1076 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1077 bts = gsm_bts_num(net, bts_nr);
1078 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1079 trx = gsm_bts_trx_num(bts, trx_nr);
1080 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1081 ts = &trx->ts[ts_nr];
1082 ts_dump_vty(vty, ts);
1083 }
1084 }
1085 }
Harald Welte68628e82009-03-10 12:17:57 +00001086 }
1087
1088 return CMD_SUCCESS;
1089}
1090
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001091static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1092{
1093 if (strlen(bsub->imsi))
1094 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1095 if (bsub->tmsi != GSM_RESERVED_TMSI)
1096 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1097 VTY_NEWLINE);
1098 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1099}
1100
Harald Welte8387a492009-12-22 21:43:14 +01001101static void meas_rep_dump_uni_vty(struct vty *vty,
1102 struct gsm_meas_rep_unidir *mru,
1103 const char *prefix,
1104 const char *dir)
1105{
1106 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1107 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1108 dir, rxlev2dbm(mru->sub.rx_lev));
1109 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1110 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1111 VTY_NEWLINE);
1112}
1113
1114static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1115 const char *prefix)
1116{
1117 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1118 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1119 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1120 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1121 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1122 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1123 VTY_NEWLINE);
1124 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001125 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001126 if (mr->flags & MEAS_REP_F_MS_L1)
1127 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1128 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1129 if (mr->flags & MEAS_REP_F_DL_VALID)
1130 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1131 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1132}
1133
Harald Welte0a8cf322015-12-05 17:22:49 +01001134/* FIXME: move this to libosmogsm */
1135static const struct value_string gsm48_cmode_names[] = {
1136 { GSM48_CMODE_SIGN, "signalling" },
1137 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1138 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1139 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1140 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1141 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1142 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1143 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1144 { 0, NULL }
1145};
1146
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001147/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1148 * Don't do anything if the ts is not dynamic. */
1149static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1150{
1151 switch (ts->pchan) {
1152 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1153 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1154 vty_out(vty, " as %s",
1155 gsm_pchan_name(ts->dyn.pchan_is));
1156 else
1157 vty_out(vty, " switching %s -> %s",
1158 gsm_pchan_name(ts->dyn.pchan_is),
1159 gsm_pchan_name(ts->dyn.pchan_want));
1160 break;
1161 case GSM_PCHAN_TCH_F_PDCH:
1162 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1163 vty_out(vty, " as %s",
1164 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1165 : "TCH/F");
1166 else
1167 vty_out(vty, " switching %s -> %s",
1168 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1169 : "TCH/F",
1170 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1171 : "TCH/F");
1172 break;
1173 default:
1174 /* no dyn ts */
1175 break;
1176 }
1177}
1178
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001179static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001180{
Harald Welte8387a492009-12-22 21:43:14 +01001181 int idx;
1182
Harald Welte85bded82010-12-24 12:22:34 +01001183 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1184 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1185 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001186 /* show dyn TS details, if applicable */
1187 switch (lchan->ts->pchan) {
1188 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1189 vty_out(vty, " Osmocom Dyn TS:");
1190 vty_out_dyn_ts_status(vty, lchan->ts);
1191 vty_out(vty, VTY_NEWLINE);
1192 break;
1193 case GSM_PCHAN_TCH_F_PDCH:
1194 vty_out(vty, " IPACC Dyn PDCH TS:");
1195 vty_out_dyn_ts_status(vty, lchan->ts);
1196 vty_out(vty, VTY_NEWLINE);
1197 break;
1198 default:
1199 /* no dyn ts */
1200 break;
1201 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001202 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001203 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001204 gsm_lchans_name(lchan->state),
1205 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1206 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1207 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001208 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1209 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1210 - lchan->bs_power*2,
1211 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1212 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001213 vty_out(vty, " Channel Mode / Codec: %s%s",
1214 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1215 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001216 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001217 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001218 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001219 } else
1220 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301221 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1222 struct in_addr ia;
Harald Welte5f45a4a2018-02-05 21:33:34 +01001223 if (lchan->abis_ip.bound_ip) {
1224 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
1225 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1226 inet_ntoa(ia), lchan->abis_ip.bound_port,
1227 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1228 VTY_NEWLINE);
1229 }
1230 if (lchan->abis_ip.connect_ip) {
1231 ia.s_addr = htonl(lchan->abis_ip.connect_ip);
1232 vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02x%s",
1233 inet_ntoa(ia), lchan->abis_ip.connect_port,
1234 lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode,
1235 VTY_NEWLINE);
1236 }
1237
Harald Welte2c828992009-12-02 01:56:49 +05301238 }
Harald Welte8387a492009-12-22 21:43:14 +01001239
1240 /* we want to report the last measurement report */
1241 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1242 lchan->meas_rep_idx, 1);
1243 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001244}
1245
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001246static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1247{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001248 struct gsm_meas_rep *mr;
1249 int idx;
1250
1251 /* we want to report the last measurement report */
1252 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1253 lchan->meas_rep_idx, 1);
1254 mr = &lchan->meas_rep[idx];
1255
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001256 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001257 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001258 gsm_pchan_name(lchan->ts->pchan));
1259 vty_out_dyn_ts_status(vty, lchan->ts);
1260 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1261 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001262 lchan->nr,
1263 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1264 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001265 rxlev2dbm(mr->dl.full.rx_lev),
1266 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001267 VTY_NEWLINE);
1268}
1269
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001270
1271static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1272 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1273{
1274 int lchan_nr;
1275 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1276 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1277 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1278 continue;
1279 dump_cb(vty, lchan);
1280 }
1281
1282 return CMD_SUCCESS;
1283}
1284
1285static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1286 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1287{
1288 int ts_nr;
1289
1290 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1291 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1292 dump_lchan_trx_ts(ts, vty, dump_cb);
1293 }
1294
1295 return CMD_SUCCESS;
1296}
1297
1298static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1299 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1300{
1301 int trx_nr;
1302
1303 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1304 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1305 dump_lchan_trx(trx, vty, dump_cb);
1306 }
1307
1308 return CMD_SUCCESS;
1309}
1310
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001311static int lchan_summary(struct vty *vty, int argc, const char **argv,
1312 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001313{
Harald Weltedcccb182010-05-16 20:52:23 +02001314 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001315 struct gsm_bts *bts;
1316 struct gsm_bts_trx *trx;
1317 struct gsm_bts_trx_ts *ts;
1318 struct gsm_lchan *lchan;
1319 int bts_nr, trx_nr, ts_nr, lchan_nr;
1320
1321 if (argc >= 1) {
1322 /* use the BTS number that the user has specified */
1323 bts_nr = atoi(argv[0]);
1324 if (bts_nr >= net->num_bts) {
1325 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1326 VTY_NEWLINE);
1327 return CMD_WARNING;
1328 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001329 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001330
1331 if (argc == 1)
1332 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001333 }
1334 if (argc >= 2) {
1335 trx_nr = atoi(argv[1]);
1336 if (trx_nr >= bts->num_trx) {
1337 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1338 VTY_NEWLINE);
1339 return CMD_WARNING;
1340 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001341 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001342
1343 if (argc == 2)
1344 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001345 }
1346 if (argc >= 3) {
1347 ts_nr = atoi(argv[2]);
1348 if (ts_nr >= TRX_NR_TS) {
1349 vty_out(vty, "%% can't find TS %s%s", argv[2],
1350 VTY_NEWLINE);
1351 return CMD_WARNING;
1352 }
1353 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001354
1355 if (argc == 3)
1356 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001357 }
1358 if (argc >= 4) {
1359 lchan_nr = atoi(argv[3]);
1360 if (lchan_nr >= TS_MAX_LCHAN) {
1361 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1362 VTY_NEWLINE);
1363 return CMD_WARNING;
1364 }
1365 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001366 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001367 return CMD_SUCCESS;
1368 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001369
1370
Harald Welte68628e82009-03-10 12:17:57 +00001371 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001372 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001373 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001374 }
1375
1376 return CMD_SUCCESS;
1377}
1378
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001379
1380DEFUN(show_lchan,
1381 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001382 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001383 SHOW_STR "Display information about a logical channel\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001384 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001385{
1386 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1387}
1388
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001389DEFUN(show_lchan_summary,
1390 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001391 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001392 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001393 "Short summary\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001394 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001395{
1396 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1397}
1398
Philipp Maier39f62bb2017-04-09 12:32:51 +02001399DEFUN(show_subscr_conn,
1400 show_subscr_conn_cmd,
1401 "show conns",
1402 SHOW_STR "Display currently active subscriber connections\n")
1403{
1404 struct gsm_subscriber_connection *conn;
1405 struct gsm_network *net = gsmnet_from_vty(vty);
1406 bool no_conns = true;
1407 unsigned int count = 0;
1408
1409 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1410
1411 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1412 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1413 lchan_dump_full_vty(vty, conn->lchan);
1414 no_conns = false;
1415 count++;
1416 }
1417
1418 if (no_conns)
1419 vty_out(vty, "None%s", VTY_NEWLINE);
1420
1421 return CMD_SUCCESS;
1422}
1423
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001424static int trigger_ho_or_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_bts *to_bts)
1425{
1426 int rc;
1427
1428 if (!to_bts || from_lchan->ts->trx->bts == to_bts) {
1429 LOGP(DHO, LOGL_NOTICE, "%s Manually triggering Assignment from VTY\n",
1430 gsm_lchan_name(from_lchan));
1431 to_bts = from_lchan->ts->trx->bts;
1432 } else
1433 LOGP(DHO, LOGL_NOTICE, "%s (ARFCN %u) --> BTS %u Manually triggering Handover from VTY\n",
1434 gsm_lchan_name(from_lchan), from_lchan->ts->trx->arfcn, to_bts->nr);
Neels Hofmeyr6dff51d2018-02-12 16:56:41 +01001435 rc = bsc_handover_start(from_lchan, to_bts, from_lchan->type);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001436 if (rc) {
1437 vty_out(vty, "bsc_handover_start() returned %d=%s%s", rc,
1438 strerror(-rc), VTY_NEWLINE);
1439 return CMD_WARNING;
1440 }
1441 return CMD_SUCCESS;
1442}
1443
1444static int ho_or_as(struct vty *vty, const char *argv[], int argc)
Philipp Maier39f62bb2017-04-09 12:32:51 +02001445{
1446 struct gsm_network *net = gsmnet_from_vty(vty);
1447 struct gsm_subscriber_connection *conn;
1448 struct gsm_bts *bts;
1449 struct gsm_bts *new_bts = NULL;
1450 unsigned int bts_nr = atoi(argv[0]);
1451 unsigned int trx_nr = atoi(argv[1]);
1452 unsigned int ts_nr = atoi(argv[2]);
1453 unsigned int ss_nr = atoi(argv[3]);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001454 unsigned int bts_nr_new;
1455 const char *action;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001456
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001457 if (argc > 4) {
1458 bts_nr_new = atoi(argv[4]);
1459
1460 /* Lookup the BTS where we want to handover to */
1461 llist_for_each_entry(bts, &net->bts_list, list) {
1462 if (bts->nr == bts_nr_new) {
1463 new_bts = bts;
1464 break;
1465 }
1466 }
1467
1468 if (!new_bts) {
1469 vty_out(vty, "Unable to trigger handover, specified bts #%u does not exist %s",
1470 bts_nr_new, VTY_NEWLINE);
1471 return CMD_WARNING;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001472 }
1473 }
1474
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001475 action = new_bts ? "handover" : "assignment";
Philipp Maier39f62bb2017-04-09 12:32:51 +02001476
1477 /* Find the connection/lchan that we want to handover */
1478 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001479 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001480 conn->lchan->ts->trx->nr == trx_nr &&
1481 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001482 vty_out(vty, "starting %s for lchan %s...%s", action, conn->lchan->name, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001483 lchan_dump_full_vty(vty, conn->lchan);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001484 return trigger_ho_or_as(vty, conn->lchan, new_bts);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001485 }
1486 }
1487
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001488 vty_out(vty, "Unable to trigger %s, specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1489 action, bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001490
1491 return CMD_WARNING;
1492}
1493
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001494#define MANUAL_HANDOVER_STR "Manually trigger handover (for debugging)\n"
1495#define MANUAL_ASSIGNMENT_STR "Manually trigger assignment (for debugging)\n"
1496
1497DEFUN(handover_subscr_conn,
1498 handover_subscr_conn_cmd,
1499 "handover <0-255> <0-255> <0-7> <0-7> <0-255>",
1500 MANUAL_HANDOVER_STR
1501 "Current " BTS_TRX_TS_LCHAN_STR
1502 "New " BTS_NR_STR)
1503{
1504 return ho_or_as(vty, argv, argc);
1505}
1506
1507DEFUN(assignment_subscr_conn,
1508 assignment_subscr_conn_cmd,
1509 "assignment <0-255> <0-255> <0-7> <0-7>",
1510 MANUAL_ASSIGNMENT_STR
1511 "Current " BTS_TRX_TS_LCHAN_STR)
1512{
1513 return ho_or_as(vty, argv, argc);
1514}
1515
1516static struct gsm_lchan *find_used_voice_lchan(struct vty *vty)
1517{
1518 struct gsm_bts *bts;
1519 struct gsm_network *network = gsmnet_from_vty(vty);
1520
1521 llist_for_each_entry(bts, &network->bts_list, list) {
1522 struct gsm_bts_trx *trx;
1523
1524 llist_for_each_entry(trx, &bts->trx_list, list) {
1525 int i;
1526 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1527 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1528 int j;
1529 int subslots;
1530
1531 /* skip administratively deactivated timeslots */
1532 if (!nm_is_running(&ts->mo.nm_state))
1533 continue;
1534
1535 subslots = ts_subslots(ts);
1536 for (j = 0; j < subslots; j++) {
1537 struct gsm_lchan *lchan = &ts->lchan[j];
1538
1539 if (lchan->state == LCHAN_S_ACTIVE
1540 && (lchan->type == GSM_LCHAN_TCH_F
1541 || lchan->type == GSM_LCHAN_TCH_H)) {
1542
1543 vty_out(vty, "Found voice call: %s%s",
1544 gsm_lchan_name(lchan), VTY_NEWLINE);
1545 lchan_dump_full_vty(vty, lchan);
1546 return lchan;
1547 }
1548 }
1549 }
1550 }
1551 }
1552
1553 vty_out(vty, "Cannot find any ongoing voice calls%s", VTY_NEWLINE);
1554 return NULL;
1555}
1556
1557static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gsm_bts *not_this_bts,
1558 enum gsm_phys_chan_config free_type)
1559{
1560 struct gsm_bts *bts;
1561 struct gsm_network *network = gsmnet_from_vty(vty);
1562
1563 llist_for_each_entry(bts, &network->bts_list, list) {
1564 struct gsm_bts_trx *trx;
1565
1566 if (bts == not_this_bts)
1567 continue;
1568
1569 llist_for_each_entry(trx, &bts->trx_list, list) {
1570 int i;
1571 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1572 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1573 int j;
1574 int subslots;
1575
1576 /* skip administratively deactivated timeslots */
1577 if (!nm_is_running(&ts->mo.nm_state))
1578 continue;
1579
1580 if (ts->pchan != free_type)
1581 continue;
1582
1583 subslots = ts_subslots(ts);
1584 for (j = 0; j < subslots; j++) {
1585 struct gsm_lchan *lchan = &ts->lchan[j];
1586
1587 if (lchan->state == LCHAN_S_NONE) {
1588 vty_out(vty, "Found unused %s slot: %s%s",
1589 gsm_pchan_name(free_type),
1590 gsm_lchan_name(lchan),
1591 VTY_NEWLINE);
1592 lchan_dump_full_vty(vty, lchan);
1593 return bts;
1594 }
1595 }
1596 }
1597 }
1598 }
1599 vty_out(vty, "Cannot find any BTS (other than BTS %u) with free %s lchan%s",
1600 not_this_bts? not_this_bts->nr : 255, gsm_lchant_name(free_type), VTY_NEWLINE);
1601 return NULL;
1602}
1603
1604DEFUN(handover_any, handover_any_cmd,
1605 "handover any",
1606 MANUAL_HANDOVER_STR
1607 "Pick any actively used TCH/F or TCH/H lchan and handover to any other BTS."
1608 " This is likely to fail if not all BTS are guaranteed to be reachable by the MS.\n")
1609{
1610 struct gsm_lchan *from_lchan;
1611 struct gsm_bts *to_bts;
1612
1613 from_lchan = find_used_voice_lchan(vty);
1614 if (!from_lchan)
1615 return CMD_WARNING;
1616
1617 to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts,
1618 ts_pchan(from_lchan->ts));
1619 if (!to_bts)
1620 return CMD_WARNING;
1621
1622 return trigger_ho_or_as(vty, from_lchan, to_bts);
1623}
1624
1625DEFUN(assignment_any, assignment_any_cmd,
1626 "assignment any",
1627 MANUAL_ASSIGNMENT_STR
1628 "Pick any actively used TCH/F or TCH/H lchan and re-assign within the same BTS."
1629 " This will fail if no lchans of the same type are available besides the used one.\n")
1630{
1631 struct gsm_lchan *from_lchan;
1632
1633 from_lchan = find_used_voice_lchan(vty);
1634 if (!from_lchan)
1635 return CMD_WARNING;
1636
1637 return trigger_ho_or_as(vty, from_lchan, NULL);
1638}
1639
Harald Weltebe4b7302009-05-23 16:59:33 +00001640static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001641{
1642 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001643 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001644}
1645
Harald Weltebe4b7302009-05-23 16:59:33 +00001646static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001647{
1648 struct gsm_paging_request *pag;
1649
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001650 if (!bts->paging.bts)
1651 return;
1652
Harald Weltef5025b62009-03-28 16:55:11 +00001653 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1654 paging_dump_vty(vty, pag);
1655}
1656
1657DEFUN(show_paging,
1658 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001659 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001660 SHOW_STR "Display information about paging reuqests of a BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001661 BTS_NR_STR)
Harald Weltef5025b62009-03-28 16:55:11 +00001662{
Harald Weltedcccb182010-05-16 20:52:23 +02001663 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001664 struct gsm_bts *bts;
1665 int bts_nr;
1666
1667 if (argc >= 1) {
1668 /* use the BTS number that the user has specified */
1669 bts_nr = atoi(argv[0]);
1670 if (bts_nr >= net->num_bts) {
1671 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1672 VTY_NEWLINE);
1673 return CMD_WARNING;
1674 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001675 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001676 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001677
Harald Weltef5025b62009-03-28 16:55:11 +00001678 return CMD_SUCCESS;
1679 }
1680 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001681 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001682 bts_paging_dump_vty(vty, bts);
1683 }
1684
1685 return CMD_SUCCESS;
1686}
1687
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001688DEFUN(show_paging_group,
1689 show_paging_group_cmd,
1690 "show paging-group <0-255> IMSI",
1691 SHOW_STR "Display the paging group\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001692 BTS_NR_STR "IMSI\n")
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001693{
1694 struct gsm_network *net = gsmnet_from_vty(vty);
1695 struct gsm_bts *bts;
1696 unsigned int page_group;
1697 int bts_nr = atoi(argv[0]);
1698
1699 if (bts_nr >= net->num_bts) {
1700 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1701 return CMD_WARNING;
1702 }
1703
1704 bts = gsm_bts_num(net, bts_nr);
1705 if (!bts) {
1706 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1707 return CMD_WARNING;
1708 }
1709
1710 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1711 str_to_imsi(argv[1]));
1712 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1713 str_to_imsi(argv[1]), bts->nr,
1714 page_group, VTY_NEWLINE);
1715 return CMD_SUCCESS;
1716}
1717
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001718DEFUN(cfg_net_neci,
1719 cfg_net_neci_cmd,
1720 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001721 "New Establish Cause Indication\n"
1722 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001723{
Harald Weltedcccb182010-05-16 20:52:23 +02001724 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1725
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001726 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001727 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001728 return CMD_SUCCESS;
1729}
1730
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001731DEFUN(cfg_net_pag_any_tch,
1732 cfg_net_pag_any_tch_cmd,
1733 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001734 "Assign a TCH when receiving a Paging Any request\n"
1735 "Any Channel\n" "Use\n" "TCH\n"
1736 "Do not use TCH for Paging Request Any\n"
1737 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001738{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001739 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001740 gsmnet->pag_any_tch = atoi(argv[0]);
1741 gsm_net_update_ctype(gsmnet);
1742 return CMD_SUCCESS;
1743}
1744
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001745#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1746/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1747#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1748
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001749#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001750 DEFUN(cfg_net_T##number, \
1751 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001752 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001753 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001754 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001755 "Set to default timer value" \
1756 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1757 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001758{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001759 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001760 int value; \
1761 if (strcmp(argv[0], "default") == 0) \
1762 value = DEFAULT_TIMER(number); \
1763 else \
1764 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001765 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001766 gsmnet->T##number = value; \
1767 return CMD_SUCCESS; \
1768}
1769
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001770DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1771DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1772DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1773DECLARE_TIMER(3107, "Currently not used")
1774DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1775DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1776DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1777DECLARE_TIMER(3115, "Currently not used")
1778DECLARE_TIMER(3117, "Currently not used")
1779DECLARE_TIMER(3119, "Currently not used")
Stefan Sperling6cee8932018-01-30 18:14:22 +01001780DECLARE_TIMER(3122, "Default waiting time (seconds) after IMM ASS REJECT")
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001781DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001782
Maxc08ee712016-05-11 12:45:13 +02001783DEFUN_DEPRECATED(cfg_net_dtx,
1784 cfg_net_dtx_cmd,
1785 "dtx-used (0|1)",
1786 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001787{
Maxc08ee712016-05-11 12:45:13 +02001788 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1789 "configuration options of BTS instead%s", VTY_NEWLINE);
1790 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001791}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001792
Harald Welte5258fc42009-03-28 19:07:53 +00001793/* per-BTS configuration */
1794DEFUN(cfg_bts,
1795 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001796 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001797 "Select a BTS to configure\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001798 BTS_NR_STR)
Harald Welte5258fc42009-03-28 19:07:53 +00001799{
Harald Weltedcccb182010-05-16 20:52:23 +02001800 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001801 int bts_nr = atoi(argv[0]);
1802 struct gsm_bts *bts;
1803
Harald Weltee441d9c2009-06-21 16:17:15 +02001804 if (bts_nr > gsmnet->num_bts) {
1805 vty_out(vty, "%% The next unused BTS number is %u%s",
1806 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001807 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001808 } else if (bts_nr == gsmnet->num_bts) {
1809 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001810 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001811 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001812 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001813 bts = gsm_bts_num(gsmnet, bts_nr);
1814
Daniel Willmannf15c2762010-01-11 13:43:07 +01001815 if (!bts) {
1816 vty_out(vty, "%% Unable to allocate BTS %u%s",
1817 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001818 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001819 }
Harald Welte5258fc42009-03-28 19:07:53 +00001820
1821 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001822 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001823 vty->node = BTS_NODE;
1824
1825 return CMD_SUCCESS;
1826}
1827
1828DEFUN(cfg_bts_type,
1829 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001830 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001831 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001832{
1833 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001834 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001835
Max7507aef2017-04-10 13:59:14 +02001836 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001837 if (rc < 0)
1838 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001839
Harald Welte5258fc42009-03-28 19:07:53 +00001840 return CMD_SUCCESS;
1841}
1842
Harald Weltefcd24452009-06-20 18:15:19 +02001843DEFUN(cfg_bts_band,
1844 cfg_bts_band_cmd,
1845 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001846 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001847{
1848 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001849 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001850
1851 if (band < 0) {
1852 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1853 band, VTY_NEWLINE);
1854 return CMD_WARNING;
1855 }
1856
1857 bts->band = band;
1858
1859 return CMD_SUCCESS;
1860}
1861
Maxc08ee712016-05-11 12:45:13 +02001862DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1863 "Configure discontinuous transmission\n"
1864 "Enable Uplink DTX for this BTS\n"
1865 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1866 "older phones).\n")
1867{
1868 struct gsm_bts *bts = vty->index;
1869
1870 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001871 if (!is_ipaccess_bts(bts))
1872 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1873 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001874 return CMD_SUCCESS;
1875}
1876
1877DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1878 NO_STR
1879 "Configure discontinuous transmission\n"
1880 "Disable Uplink DTX for this BTS\n")
1881{
1882 struct gsm_bts *bts = vty->index;
1883
1884 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1885
1886 return CMD_SUCCESS;
1887}
1888
1889DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1890 "Configure discontinuous transmission\n"
1891 "Enable Downlink DTX for this BTS\n")
1892{
1893 struct gsm_bts *bts = vty->index;
1894
1895 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001896 if (!is_ipaccess_bts(bts))
1897 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1898 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001899 return CMD_SUCCESS;
1900}
1901
1902DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1903 NO_STR
1904 "Configure discontinuous transmission\n"
1905 "Disable Downlink DTX for this BTS\n")
1906{
1907 struct gsm_bts *bts = vty->index;
1908
1909 bts->dtxd = false;
1910
1911 return CMD_SUCCESS;
1912}
1913
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001914DEFUN(cfg_bts_ci,
1915 cfg_bts_ci_cmd,
1916 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001917 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001918{
1919 struct gsm_bts *bts = vty->index;
1920 int ci = atoi(argv[0]);
1921
1922 if (ci < 0 || ci > 0xffff) {
1923 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1924 ci, VTY_NEWLINE);
1925 return CMD_WARNING;
1926 }
1927 bts->cell_identity = ci;
1928
1929 return CMD_SUCCESS;
1930}
1931
Harald Welte5258fc42009-03-28 19:07:53 +00001932DEFUN(cfg_bts_lac,
1933 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001934 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001935 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001936{
1937 struct gsm_bts *bts = vty->index;
1938 int lac = atoi(argv[0]);
1939
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001940 if (lac < 0 || lac > 0xffff) {
1941 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001942 lac, VTY_NEWLINE);
1943 return CMD_WARNING;
1944 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001945
1946 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1947 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1948 lac, VTY_NEWLINE);
1949 return CMD_WARNING;
1950 }
1951
Harald Welte5258fc42009-03-28 19:07:53 +00001952 bts->location_area_code = lac;
1953
1954 return CMD_SUCCESS;
1955}
1956
Harald Weltea43f7892009-12-01 18:04:30 +05301957
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001958/* compatibility wrapper for old config files */
1959DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00001960 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02001961 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001962 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001963{
Harald Welte5258fc42009-03-28 19:07:53 +00001964 return CMD_SUCCESS;
1965}
1966
Harald Welte78f2f502009-05-23 16:56:52 +00001967DEFUN(cfg_bts_bsic,
1968 cfg_bts_bsic_cmd,
1969 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001970 "Set the Base Station Identity Code (BSIC) of this BTS\n"
1971 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00001972{
1973 struct gsm_bts *bts = vty->index;
1974 int bsic = atoi(argv[0]);
1975
1976 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02001977 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00001978 bsic, VTY_NEWLINE);
1979 return CMD_WARNING;
1980 }
1981 bts->bsic = bsic;
1982
1983 return CMD_SUCCESS;
1984}
1985
Harald Welte4cc34222009-05-01 15:12:31 +00001986DEFUN(cfg_bts_unit_id,
1987 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02001988 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02001989 "Abis/IP specific options\n"
1990 "Set the IPA BTS Unit ID\n"
1991 "Unit ID (Site)\n"
1992 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00001993{
1994 struct gsm_bts *bts = vty->index;
1995 int site_id = atoi(argv[0]);
1996 int bts_id = atoi(argv[1]);
1997
Harald Welte07dc73d2009-08-07 13:27:09 +02001998 if (!is_ipaccess_bts(bts)) {
1999 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2000 return CMD_WARNING;
2001 }
2002
Harald Welte4cc34222009-05-01 15:12:31 +00002003 bts->ip_access.site_id = site_id;
2004 bts->ip_access.bts_id = bts_id;
2005
2006 return CMD_SUCCESS;
2007}
2008
Harald Welte8b291802013-03-12 13:57:05 +01002009DEFUN(cfg_bts_rsl_ip,
2010 cfg_bts_rsl_ip_cmd,
2011 "ip.access rsl-ip A.B.C.D",
2012 "Abis/IP specific options\n"
2013 "Set the IPA RSL IP Address of the BSC\n"
2014 "Destination IP address for RSL connection\n")
2015{
2016 struct gsm_bts *bts = vty->index;
2017 struct in_addr ia;
2018
2019 if (!is_ipaccess_bts(bts)) {
2020 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2021 return CMD_WARNING;
2022 }
2023
2024 inet_aton(argv[0], &ia);
2025 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
2026
2027 return CMD_SUCCESS;
2028}
2029
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002030#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01002031
Sylvain Munautc9519462011-10-17 14:04:55 +02002032DEFUN(cfg_bts_nokia_site_skip_reset,
2033 cfg_bts_nokia_site_skip_reset_cmd,
2034 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002035 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002036 "Skip the reset step during bootstrap process of this BTS\n"
2037 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02002038{
2039 struct gsm_bts *bts = vty->index;
2040
2041 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
2042 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
2043 return CMD_WARNING;
2044 }
2045
2046 bts->nokia.skip_reset = atoi(argv[0]);
2047
2048 return CMD_SUCCESS;
2049}
2050
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002051DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
2052 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
2053 "nokia_site no-local-rel-conf (0|1)",
2054 NOKIA_STR
2055 "Do not wait for RELease CONFirm message when releasing channel locally\n"
2056 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
2057{
2058 struct gsm_bts *bts = vty->index;
2059
2060 if (!is_nokia_bts(bts)) {
2061 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2062 VTY_NEWLINE);
2063 return CMD_WARNING;
2064 }
2065
2066 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
2067
2068 return CMD_SUCCESS;
2069}
2070
Sipos Csaba56e17662015-02-07 13:27:36 +01002071DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
2072 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
2073 "nokia_site bts-reset-timer <15-100>",
2074 NOKIA_STR
2075 "The amount of time (in sec.) between BTS_RESET is sent,\n"
2076 "and the BTS is being bootstrapped.\n")
2077{
2078 struct gsm_bts *bts = vty->index;
2079
2080 if (!is_nokia_bts(bts)) {
2081 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2082 VTY_NEWLINE);
2083 return CMD_WARNING;
2084 }
2085
2086 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
2087
2088 return CMD_SUCCESS;
2089}
Harald Welte8f0ed552010-05-11 21:53:49 +02002090#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002091#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02002092
Harald Welte8175e952009-10-20 00:22:00 +02002093DEFUN(cfg_bts_stream_id,
2094 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002095 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02002096 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002097 "Set the ip.access Stream ID of the OML link of this BTS\n"
2098 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02002099{
2100 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002101 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02002102
2103 if (!is_ipaccess_bts(bts)) {
2104 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2105 return CMD_WARNING;
2106 }
2107
2108 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002109 /* This is used by e1inp_bind_ops callback for each BTS model. */
2110 bts->oml_e1_link.e1_nr = linenr;
2111
2112 return CMD_SUCCESS;
2113}
2114
Harald Welted13e0cd2012-08-17 09:52:03 +02002115#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02002116
Harald Welte42581822009-08-08 16:12:58 +02002117DEFUN(cfg_bts_oml_e1,
2118 cfg_bts_oml_e1_cmd,
2119 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02002120 OML_E1_STR
2121 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002122 "E1/T1 line number to be used for OML\n"
2123 "E1/T1 timeslot to be used for OML\n"
2124 "E1/T1 timeslot to be used for OML\n"
2125 "E1/T1 sub-slot to be used for OML\n"
2126 "Use E1/T1 sub-slot 0\n"
2127 "Use E1/T1 sub-slot 1\n"
2128 "Use E1/T1 sub-slot 2\n"
2129 "Use E1/T1 sub-slot 3\n"
2130 "Use full E1 slot 3\n"
2131 )
Harald Welte42581822009-08-08 16:12:58 +02002132{
2133 struct gsm_bts *bts = vty->index;
2134
2135 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2136
2137 return CMD_SUCCESS;
2138}
2139
2140
2141DEFUN(cfg_bts_oml_e1_tei,
2142 cfg_bts_oml_e1_tei_cmd,
2143 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002144 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002145 "Set the TEI to be used for OML\n"
2146 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002147{
2148 struct gsm_bts *bts = vty->index;
2149
2150 bts->oml_tei = atoi(argv[0]);
2151
2152 return CMD_SUCCESS;
2153}
2154
Harald Welte7a8fa412009-08-10 13:48:16 +02002155DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2156 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002157 "Channnel Allocator\n" "Channel Allocator\n"
2158 "Allocate Timeslots and Transceivers in ascending order\n"
2159 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002160{
2161 struct gsm_bts *bts = vty->index;
2162
2163 if (!strcmp(argv[0], "ascending"))
2164 bts->chan_alloc_reverse = 0;
2165 else
2166 bts->chan_alloc_reverse = 1;
2167
2168 return CMD_SUCCESS;
2169}
2170
Harald Welte8f0ed552010-05-11 21:53:49 +02002171#define RACH_STR "Random Access Control Channel\n"
2172
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002173DEFUN(cfg_bts_rach_tx_integer,
2174 cfg_bts_rach_tx_integer_cmd,
2175 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002176 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002177 "Set the raw tx integer value in RACH Control parameters IE\n"
2178 "Set the raw tx integer value in RACH Control parameters IE\n"
2179 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002180{
2181 struct gsm_bts *bts = vty->index;
2182 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2183 return CMD_SUCCESS;
2184}
2185
2186DEFUN(cfg_bts_rach_max_trans,
2187 cfg_bts_rach_max_trans_cmd,
2188 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002189 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002190 "Set the maximum number of RACH burst transmissions\n"
2191 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002192 "Maximum number of 1 RACH burst transmissions\n"
2193 "Maximum number of 2 RACH burst transmissions\n"
2194 "Maximum number of 4 RACH burst transmissions\n"
2195 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002196{
2197 struct gsm_bts *bts = vty->index;
2198 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2199 return CMD_SUCCESS;
2200}
2201
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002202#define CD_STR "Channel Description\n"
2203
2204DEFUN(cfg_bts_chan_desc_att,
2205 cfg_bts_chan_desc_att_cmd,
2206 "channel-descrption attach (0|1)",
2207 CD_STR
2208 "Set if attachment is required\n"
2209 "Attachment is NOT required\n"
2210 "Attachment is required (standard)\n")
2211{
2212 struct gsm_bts *bts = vty->index;
2213 bts->si_common.chan_desc.att = atoi(argv[0]);
2214 return CMD_SUCCESS;
2215}
2216
2217DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2218 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2219 "channel-descrption bs-pa-mfrms <2-9>",
2220 CD_STR
2221 "Set number of multiframe periods for paging groups\n"
2222 "Number of multiframe periods for paging groups\n")
2223{
2224 struct gsm_bts *bts = vty->index;
2225 int bs_pa_mfrms = atoi(argv[0]);
2226
2227 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2228 return CMD_SUCCESS;
2229}
2230
2231DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2232 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2233 "channel-descrption bs-ag-blks-res <0-7>",
2234 CD_STR
2235 "Set number of blocks reserved for access grant\n"
2236 "Number of blocks reserved for access grant\n")
2237{
2238 struct gsm_bts *bts = vty->index;
2239 int bs_ag_blks_res = atoi(argv[0]);
2240
2241 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2242 return CMD_SUCCESS;
2243}
2244
Harald Welte8f0ed552010-05-11 21:53:49 +02002245#define NM_STR "Network Management\n"
2246
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002247DEFUN(cfg_bts_rach_nm_b_thresh,
2248 cfg_bts_rach_nm_b_thresh_cmd,
2249 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002250 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002251 "Set the NM Busy Threshold\n"
2252 "Set the NM Busy Threshold\n"
2253 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002254{
2255 struct gsm_bts *bts = vty->index;
2256 bts->rach_b_thresh = atoi(argv[0]);
2257 return CMD_SUCCESS;
2258}
2259
2260DEFUN(cfg_bts_rach_nm_ldavg,
2261 cfg_bts_rach_nm_ldavg_cmd,
2262 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002263 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002264 "Set the NM Loadaverage Slots value\n"
2265 "Set the NM Loadaverage Slots value\n"
2266 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002267{
2268 struct gsm_bts *bts = vty->index;
2269 bts->rach_ldavg_slots = atoi(argv[0]);
2270 return CMD_SUCCESS;
2271}
2272
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002273DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2274 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002275 "Should this cell be barred from access?\n"
2276 "Should this cell be barred from access?\n"
2277 "Cell should NOT be barred\n"
2278 "Cell should be barred\n")
2279
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002280{
2281 struct gsm_bts *bts = vty->index;
2282
Harald Welte71355012009-12-21 23:08:18 +01002283 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002284
2285 return CMD_SUCCESS;
2286}
2287
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002288DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2289 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002290 RACH_STR
2291 "Should this cell allow emergency calls?\n"
2292 "Should this cell allow emergency calls?\n"
2293 "Should this cell allow emergency calls?\n"
2294 "Do NOT allow emergency calls\n"
2295 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002296{
2297 struct gsm_bts *bts = vty->index;
2298
2299 if (atoi(argv[0]) == 0)
2300 bts->si_common.rach_control.t2 |= 0x4;
2301 else
2302 bts->si_common.rach_control.t2 &= ~0x4;
2303
2304 return CMD_SUCCESS;
2305}
2306
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002307DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2308 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2309 RACH_STR
2310 "Set access control class\n"
2311 "Access control class 0\n"
2312 "Access control class 1\n"
2313 "Access control class 2\n"
2314 "Access control class 3\n"
2315 "Access control class 4\n"
2316 "Access control class 5\n"
2317 "Access control class 6\n"
2318 "Access control class 7\n"
2319 "Access control class 8\n"
2320 "Access control class 9\n"
2321 "Access control class 11 for PLMN use\n"
2322 "Access control class 12 for security services\n"
2323 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2324 "Access control class 14 for emergency services\n"
2325 "Access control class 15 for PLMN staff\n"
2326 "barred to use access control class\n"
2327 "allowed to use access control class\n")
2328{
2329 struct gsm_bts *bts = vty->index;
2330
2331 uint8_t control_class;
2332 uint8_t allowed = 0;
2333
2334 if (strcmp(argv[1], "allowed") == 0)
2335 allowed = 1;
2336
2337 control_class = atoi(argv[0]);
2338 if (control_class < 8)
2339 if (allowed)
2340 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2341 else
2342 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2343 else
2344 if (allowed)
2345 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2346 else
2347 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2348
2349 return CMD_SUCCESS;
2350}
2351
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002352DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2353 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002354 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002355 "Maximum transmit power of the MS\n"
2356 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002357 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002358{
2359 struct gsm_bts *bts = vty->index;
2360
2361 bts->ms_max_power = atoi(argv[0]);
2362
2363 return CMD_SUCCESS;
2364}
2365
Harald Weltecfaabbb2012-08-16 23:23:50 +02002366#define CELL_STR "Cell Parameters\n"
2367
Harald Welte73225282009-12-12 18:17:25 +01002368DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2369 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002370 CELL_STR "Cell re-selection parameters\n"
2371 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002372 "Cell Re-Selection Hysteresis in dB")
2373{
2374 struct gsm_bts *bts = vty->index;
2375
2376 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2377
2378 return CMD_SUCCESS;
2379}
2380
2381DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2382 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002383 "Minimum RxLev needed for cell access\n"
2384 "Minimum RxLev needed for cell access\n"
2385 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002386 "Minimum RxLev needed for cell access (better than -110dBm)")
2387{
2388 struct gsm_bts *bts = vty->index;
2389
2390 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2391
2392 return CMD_SUCCESS;
2393}
2394
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002395DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2396 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002397 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2398 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002399{
2400 struct gsm_bts *bts = vty->index;
2401
2402 bts->si_common.cell_ro_sel_par.present = 1;
2403 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2404
2405 return CMD_SUCCESS;
2406}
2407
2408DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2409 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002410 CELL_STR "Cell Re-Selection Parameters\n"
2411 "Cell Re-Selection Offset (CRO) in dB\n"
2412 "Cell Re-Selection Offset (CRO) in dB\n"
2413 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002414{
2415 struct gsm_bts *bts = vty->index;
2416
2417 bts->si_common.cell_ro_sel_par.present = 1;
2418 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2419
2420 return CMD_SUCCESS;
2421}
2422
2423DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2424 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002425 "Cell selection temporary negative offset\n"
2426 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002427 "Cell selection temporary negative offset in dB")
2428{
2429 struct gsm_bts *bts = vty->index;
2430
2431 bts->si_common.cell_ro_sel_par.present = 1;
2432 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2433
2434 return CMD_SUCCESS;
2435}
2436
2437DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2438 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002439 "Cell selection temporary negative offset\n"
2440 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002441 "Sets cell selection temporary negative offset to infinity")
2442{
2443 struct gsm_bts *bts = vty->index;
2444
2445 bts->si_common.cell_ro_sel_par.present = 1;
2446 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2447
2448 return CMD_SUCCESS;
2449}
2450
2451DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2452 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002453 "Cell selection penalty time\n"
2454 "Cell selection penalty time\n"
2455 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002456{
2457 struct gsm_bts *bts = vty->index;
2458
2459 bts->si_common.cell_ro_sel_par.present = 1;
2460 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2461
2462 return CMD_SUCCESS;
2463}
2464
2465DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2466 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002467 "Cell selection penalty time\n"
2468 "Cell selection penalty time\n"
2469 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002470 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2471 "and TEMPORARY_OFFSET is ignored)")
2472{
2473 struct gsm_bts *bts = vty->index;
2474
2475 bts->si_common.cell_ro_sel_par.present = 1;
2476 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2477
2478 return CMD_SUCCESS;
2479}
2480
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002481DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2482 "radio-link-timeout <4-64>",
2483 "Radio link timeout criterion (BTS side)\n"
2484 "Radio link timeout value (lost SACCH block)\n")
2485{
2486 struct gsm_bts *bts = vty->index;
2487
Harald Welte2f8b9d22017-06-18 11:12:13 +03002488 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2489
2490 return CMD_SUCCESS;
2491}
2492
2493DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2494 "radio-link-timeout infinite",
2495 "Radio link timeout criterion (BTS side)\n"
2496 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2497{
2498 struct gsm_bts *bts = vty->index;
2499
2500 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2501 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2502 return CMD_WARNING;
2503 }
2504
2505 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2506 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002507
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002508 return CMD_SUCCESS;
2509}
2510
Harald Welte8f0ed552010-05-11 21:53:49 +02002511#define GPRS_TEXT "GPRS Packet Network\n"
2512
Harald Welteaf387632010-03-14 23:30:30 +08002513DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002514 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002515 GPRS_TEXT
2516 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002517 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002518 "GPRS BSSGP VC Identifier")
2519{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002520 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002521 struct gsm_bts *bts = vty->index;
2522
Harald Welte4511d892010-04-18 15:51:20 +02002523 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002524 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2525 return CMD_WARNING;
2526 }
2527
Harald Welte97a282b2010-03-14 15:37:43 +08002528 bts->gprs.cell.bvci = atoi(argv[0]);
2529
2530 return CMD_SUCCESS;
2531}
2532
Harald Weltea5731cf2010-03-22 11:48:36 +08002533DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2534 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002535 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002536 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002537 "GPRS NS Entity Identifier")
2538{
2539 struct gsm_bts *bts = vty->index;
2540
Harald Welte4511d892010-04-18 15:51:20 +02002541 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002542 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2543 return CMD_WARNING;
2544 }
2545
2546 bts->gprs.nse.nsei = atoi(argv[0]);
2547
2548 return CMD_SUCCESS;
2549}
2550
Harald Welte8f0ed552010-05-11 21:53:49 +02002551#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2552 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002553
Harald Welte97a282b2010-03-14 15:37:43 +08002554DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2555 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002556 GPRS_TEXT NSVC_TEXT
2557 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002558 "GPRS NS VC Identifier")
2559{
2560 struct gsm_bts *bts = vty->index;
2561 int idx = atoi(argv[0]);
2562
Harald Welte4511d892010-04-18 15:51:20 +02002563 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002564 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2565 return CMD_WARNING;
2566 }
2567
Harald Welte97a282b2010-03-14 15:37:43 +08002568 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2569
2570 return CMD_SUCCESS;
2571}
2572
Harald Welteaf387632010-03-14 23:30:30 +08002573DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2574 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002575 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002576 "GPRS NS Local UDP Port\n"
2577 "GPRS NS Local UDP Port\n"
2578 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002579 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002580{
2581 struct gsm_bts *bts = vty->index;
2582 int idx = atoi(argv[0]);
2583
Harald Welte4511d892010-04-18 15:51:20 +02002584 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002585 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2586 return CMD_WARNING;
2587 }
2588
Harald Welteaf387632010-03-14 23:30:30 +08002589 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2590
2591 return CMD_SUCCESS;
2592}
2593
2594DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2595 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002596 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002597 "GPRS NS Remote UDP Port\n"
2598 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002599 "GPRS NS Remote UDP Port\n"
2600 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002601{
2602 struct gsm_bts *bts = vty->index;
2603 int idx = atoi(argv[0]);
2604
Harald Welte4511d892010-04-18 15:51:20 +02002605 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002606 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2607 return CMD_WARNING;
2608 }
2609
Harald Welteaf387632010-03-14 23:30:30 +08002610 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2611
2612 return CMD_SUCCESS;
2613}
2614
2615DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2616 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002617 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002618 "GPRS NS Remote IP Address\n"
2619 "GPRS NS Remote IP Address\n"
2620 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002621{
2622 struct gsm_bts *bts = vty->index;
2623 int idx = atoi(argv[0]);
2624 struct in_addr ia;
2625
Harald Welte4511d892010-04-18 15:51:20 +02002626 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002627 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2628 return CMD_WARNING;
2629 }
2630
Harald Welteaf387632010-03-14 23:30:30 +08002631 inet_aton(argv[1], &ia);
2632 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2633
2634 return CMD_SUCCESS;
2635}
2636
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002637DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002638 "paging free <-1-1024>",
2639 "Paging options\n"
2640 "Only page when having a certain amount of free slots\n"
2641 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002642{
2643 struct gsm_bts *bts = vty->index;
2644
2645 bts->paging.free_chans_need = atoi(argv[0]);
2646 return CMD_SUCCESS;
2647}
2648
Harald Welte615e9562010-05-11 23:50:21 +02002649DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2650 "gprs ns timer " NS_TIMERS " <0-255>",
2651 GPRS_TEXT "Network Service\n"
2652 "Network Service Timer\n"
2653 NS_TIMERS_HELP "Timer Value\n")
2654{
2655 struct gsm_bts *bts = vty->index;
2656 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2657 int val = atoi(argv[1]);
2658
2659 if (bts->gprs.mode == BTS_GPRS_NONE) {
2660 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2661 return CMD_WARNING;
2662 }
2663
2664 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2665 return CMD_WARNING;
2666
2667 bts->gprs.nse.timer[idx] = val;
2668
2669 return CMD_SUCCESS;
2670}
2671
2672#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 +02002673#define BSSGP_TIMERS_HELP \
2674 "Tbvc-block timeout\n" \
2675 "Tbvc-block retries\n" \
2676 "Tbvc-unblock retries\n" \
2677 "Tbvcc-reset timeout\n" \
2678 "Tbvc-reset retries\n" \
2679 "Tbvc-suspend timeout\n" \
2680 "Tbvc-suspend retries\n" \
2681 "Tbvc-resume timeout\n" \
2682 "Tbvc-resume retries\n" \
2683 "Tbvc-capa-update timeout\n" \
2684 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002685
2686DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2687 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2688 GPRS_TEXT "Cell / BSSGP\n"
2689 "Cell/BSSGP Timer\n"
2690 BSSGP_TIMERS_HELP "Timer Value\n")
2691{
2692 struct gsm_bts *bts = vty->index;
2693 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2694 int val = atoi(argv[1]);
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 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2702 return CMD_WARNING;
2703
2704 bts->gprs.cell.timer[idx] = val;
2705
2706 return CMD_SUCCESS;
2707}
2708
Harald Welte97a282b2010-03-14 15:37:43 +08002709DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2710 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002711 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002712 "GPRS Routing Area Code\n"
2713 "GPRS Routing Area Code\n"
2714 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002715{
2716 struct gsm_bts *bts = vty->index;
2717
Harald Welte4511d892010-04-18 15:51:20 +02002718 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002719 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2720 return CMD_WARNING;
2721 }
2722
Harald Welte97a282b2010-03-14 15:37:43 +08002723 bts->gprs.rac = atoi(argv[0]);
2724
2725 return CMD_SUCCESS;
2726}
2727
Max292ec582016-07-28 11:55:37 +02002728DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2729 "gprs control-ack-type-rach", GPRS_TEXT
2730 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2731 "four access bursts format instead of default RLC/MAC control block\n")
2732{
2733 struct gsm_bts *bts = vty->index;
2734
2735 if (bts->gprs.mode == BTS_GPRS_NONE) {
2736 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2737 return CMD_WARNING;
2738 }
2739
2740 bts->gprs.ctrl_ack_type_use_block = false;
2741
2742 return CMD_SUCCESS;
2743}
2744
2745DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2746 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2747 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2748 "four access bursts format instead of default RLC/MAC control block\n")
2749{
2750 struct gsm_bts *bts = vty->index;
2751
2752 if (bts->gprs.mode == BTS_GPRS_NONE) {
2753 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2754 return CMD_WARNING;
2755 }
2756
2757 bts->gprs.ctrl_ack_type_use_block = true;
2758
2759 return CMD_SUCCESS;
2760}
2761
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002762DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2763 "gprs network-control-order (nc0|nc1|nc2)",
2764 GPRS_TEXT
2765 "GPRS Network Control Order\n"
2766 "MS controlled cell re-selection, no measurement reporting\n"
2767 "MS controlled cell re-selection, MS sends measurement reports\n"
2768 "Network controlled cell re-selection, MS sends measurement reports\n")
2769{
2770 struct gsm_bts *bts = vty->index;
2771
2772 if (bts->gprs.mode == BTS_GPRS_NONE) {
2773 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2774 return CMD_WARNING;
2775 }
2776
2777 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2778
2779 return CMD_SUCCESS;
2780}
2781
Harald Welte4511d892010-04-18 15:51:20 +02002782DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2783 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002784 GPRS_TEXT
2785 "GPRS Mode for this BTS\n"
2786 "GPRS Disabled on this BTS\n"
2787 "GPRS Enabled on this BTS\n"
2788 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002789{
2790 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002791 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002792
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002793 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002794 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2795 VTY_NEWLINE);
2796 return CMD_WARNING;
2797 }
2798
2799 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002800
2801 return CMD_SUCCESS;
2802}
2803
bhargava350533c2016-07-21 11:14:34 +05302804DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2805 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2806 "gprs 11bit_rach_support_for_egprs (0|1)",
2807 GPRS_TEXT "11 bit RACH options\n"
2808 "Disable 11 bit RACH for EGPRS\n"
2809 "Enable 11 bit RACH for EGPRS")
2810{
2811 struct gsm_bts *bts = vty->index;
2812
2813 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2814
2815 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2816 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2817 return CMD_WARNING;
2818 }
2819
2820 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2821 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2822 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2823 " enabled%s", VTY_NEWLINE);
2824 return CMD_WARNING;
2825 }
2826
2827 return CMD_SUCCESS;
2828}
2829
Harald Welte9fbff4a2010-07-30 11:50:09 +02002830#define SI_TEXT "System Information Messages\n"
2831#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)"
2832#define SI_TYPE_HELP "System Information Type 1\n" \
2833 "System Information Type 2\n" \
2834 "System Information Type 3\n" \
2835 "System Information Type 4\n" \
2836 "System Information Type 5\n" \
2837 "System Information Type 6\n" \
2838 "System Information Type 7\n" \
2839 "System Information Type 8\n" \
2840 "System Information Type 9\n" \
2841 "System Information Type 10\n" \
2842 "System Information Type 13\n" \
2843 "System Information Type 16\n" \
2844 "System Information Type 17\n" \
2845 "System Information Type 18\n" \
2846 "System Information Type 19\n" \
2847 "System Information Type 20\n" \
2848 "System Information Type 2bis\n" \
2849 "System Information Type 2ter\n" \
2850 "System Information Type 2quater\n" \
2851 "System Information Type 5bis\n" \
2852 "System Information Type 5ter\n"
2853
2854DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2855 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2856 SI_TEXT SI_TYPE_HELP
2857 "System Information Mode\n"
2858 "Static user-specified\n"
2859 "Dynamic, BSC-computed\n")
2860{
2861 struct gsm_bts *bts = vty->index;
2862 int type;
2863
2864 type = get_string_value(osmo_sitype_strs, argv[0]);
2865 if (type < 0) {
2866 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2867 return CMD_WARNING;
2868 }
2869
2870 if (!strcmp(argv[1], "static"))
2871 bts->si_mode_static |= (1 << type);
2872 else
2873 bts->si_mode_static &= ~(1 << type);
2874
2875 return CMD_SUCCESS;
2876}
2877
2878DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2879 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2880 SI_TEXT SI_TYPE_HELP
2881 "Static System Information filling\n"
2882 "Static user-specified SI content in HEX notation\n")
2883{
2884 struct gsm_bts *bts = vty->index;
2885 int rc, type;
2886
2887 type = get_string_value(osmo_sitype_strs, argv[0]);
2888 if (type < 0) {
2889 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2890 return CMD_WARNING;
2891 }
2892
2893 if (!(bts->si_mode_static & (1 << type))) {
2894 vty_out(vty, "SI Type %s is not configured in static mode%s",
2895 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2896 return CMD_WARNING;
2897 }
2898
Harald Welte290aaed2010-07-30 11:53:18 +02002899 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002900 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002901
2902 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002903 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2904 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002905 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2906 return CMD_WARNING;
2907 }
2908
2909 /* Mark this SI as present */
2910 bts->si_valid |= (1 << type);
2911
2912 return CMD_SUCCESS;
2913}
2914
Harald Welte42def722017-01-13 00:10:32 +01002915DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2916 "early-classmark-sending (allowed|forbidden)",
2917 "Early Classmark Sending\n"
2918 "Early Classmark Sending is allowed\n"
2919 "Early Classmark Sending is forbidden\n")
2920{
2921 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002922
2923 if (!strcmp(argv[0], "allowed"))
2924 bts->early_classmark_allowed = true;
2925 else
2926 bts->early_classmark_allowed = false;
2927
2928 return CMD_SUCCESS;
2929}
2930
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002931DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2932 "early-classmark-sending-3g (allowed|forbidden)",
2933 "3G Early Classmark Sending\n"
2934 "3G Early Classmark Sending is allowed\n"
2935 "3G Early Classmark Sending is forbidden\n")
2936{
2937 struct gsm_bts *bts = vty->index;
2938
2939 if (!strcmp(argv[0], "allowed"))
2940 bts->early_classmark_allowed_3g = true;
2941 else
2942 bts->early_classmark_allowed_3g = false;
2943
2944 return CMD_SUCCESS;
2945}
2946
Harald Welte32c09622011-01-11 23:44:56 +01002947DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002948 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002949 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002950 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
2951 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01002952{
2953 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01002954 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01002955
Harald Welte64c07d22011-02-15 11:43:27 +01002956 switch (mode) {
2957 case NL_MODE_MANUAL_SI5SEP:
2958 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01002959 /* make sure we clear the current list when switching to
2960 * manual mode */
2961 if (bts->neigh_list_manual_mode == 0)
2962 memset(&bts->si_common.data.neigh_list, 0,
2963 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01002964 break;
2965 default:
2966 break;
2967 }
2968
2969 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01002970
2971 return CMD_SUCCESS;
2972}
2973
2974DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01002975 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01002976 "Neighbor List\n" "Add to manual neighbor list\n"
2977 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
2978 "ARFCN of neighbor\n")
2979{
2980 struct gsm_bts *bts = vty->index;
2981 struct bitvec *bv = &bts->si_common.neigh_list;
2982 uint16_t arfcn = atoi(argv[1]);
2983
2984 if (!bts->neigh_list_manual_mode) {
2985 vty_out(vty, "%% Cannot configure neighbor list in "
2986 "automatic mode%s", VTY_NEWLINE);
2987 return CMD_WARNING;
2988 }
2989
2990 if (!strcmp(argv[0], "add"))
2991 bitvec_set_bit_pos(bv, arfcn, 1);
2992 else
2993 bitvec_set_bit_pos(bv, arfcn, 0);
2994
2995 return CMD_SUCCESS;
2996}
2997
Max70fdd242017-06-15 15:10:53 +02002998/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02002999DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01003000 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
3001 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
3002 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
3003 "Add to manual SI2quater neighbor list\n"
3004 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
3005 "threshold high bits\n" "threshold high bits\n"
3006 "threshold low bits\n" "threshold low bits (32 means NA)\n"
3007 "priority\n" "priority (8 means NA)\n"
3008 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
3009 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
Max59a1bf32016-04-15 16:04:46 +02003010{
3011 struct gsm_bts *bts = vty->index;
3012 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
3013 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01003014 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
3015 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02003016 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02003017
Max70fdd242017-06-15 15:10:53 +02003018 switch (r) {
3019 case 1:
3020 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
3021 thresh_hi, VTY_NEWLINE);
3022 break;
3023 case EARFCN_THRESH_LOW_INVALID:
3024 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
3025 thresh_lo, VTY_NEWLINE);
3026 break;
3027 case EARFCN_QRXLV_INVALID + 1:
3028 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
3029 qrx, VTY_NEWLINE);
3030 break;
3031 case EARFCN_PRIO_INVALID:
3032 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
3033 prio, VTY_NEWLINE);
3034 break;
3035 default:
3036 if (r < 0) {
3037 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
3038 return CMD_WARNING;
3039 }
Max59a1bf32016-04-15 16:04:46 +02003040 }
3041
Max70fdd242017-06-15 15:10:53 +02003042 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01003043 return CMD_SUCCESS;
3044
Maxf39d03a2017-05-12 17:00:30 +02003045 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02003046 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02003047 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01003048
Maxaafff962016-04-20 15:57:14 +02003049 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02003050}
3051
3052DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02003053 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02003054 "SI2quater Neighbor List\n"
3055 "SI2quater Neighbor List\n"
3056 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02003057 "EARFCN of neighbor\n"
3058 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02003059{
3060 struct gsm_bts *bts = vty->index;
3061 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02003062 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02003063 int r = osmo_earfcn_del(e, arfcn);
3064 if (r < 0) {
3065 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02003066 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02003067 return CMD_WARNING;
3068 }
3069
3070 return CMD_SUCCESS;
3071}
3072
Max26679e02016-04-20 15:57:13 +02003073DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02003074 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02003075 "SI2quater Neighbor List\n"
3076 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
3077 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
3078 "diversity bit\n")
3079{
3080 struct gsm_bts *bts = vty->index;
3081 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
3082
3083 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
3084 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02003085 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 +01003086 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02003087 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02003088 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
3089 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01003090 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02003091 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02003092 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02003093 return CMD_WARNING;
3094 }
3095
3096 return CMD_SUCCESS;
3097}
3098
3099DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02003100 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02003101 "SI2quater Neighbor List\n"
3102 "SI2quater Neighbor List\n"
3103 "Delete from SI2quater manual neighbor list\n"
3104 "UARFCN of neighbor\n"
3105 "UARFCN\n"
3106 "scrambling code\n")
3107{
3108 struct gsm_bts *bts = vty->index;
3109
3110 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
3111 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
3112 VTY_NEWLINE);
3113 return CMD_WARNING;
3114 }
3115
3116 return CMD_SUCCESS;
3117}
3118
Harald Welte64c07d22011-02-15 11:43:27 +01003119DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003120 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003121 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003122 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
3123 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
3124 "ARFCN of neighbor\n")
3125{
3126 struct gsm_bts *bts = vty->index;
3127 struct bitvec *bv = &bts->si_common.si5_neigh_list;
3128 uint16_t arfcn = atoi(argv[1]);
3129
3130 if (!bts->neigh_list_manual_mode) {
3131 vty_out(vty, "%% Cannot configure neighbor list in "
3132 "automatic mode%s", VTY_NEWLINE);
3133 return CMD_WARNING;
3134 }
3135
3136 if (!strcmp(argv[0], "add"))
3137 bitvec_set_bit_pos(bv, arfcn, 1);
3138 else
3139 bitvec_set_bit_pos(bv, arfcn, 0);
3140
3141 return CMD_SUCCESS;
3142}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003143
Harald Welte8254cf72017-05-29 13:42:19 +02003144DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3145 "pcu-socket PATH",
3146 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3147 "Path in the file system for the unix-domain PCU socket\n")
3148{
3149 struct gsm_bts *bts = vty->index;
3150 int rc;
3151
Harald Welte4a824ca2017-05-29 13:54:27 +02003152 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003153 pcu_sock_exit(bts);
3154 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3155 if (rc < 0) {
3156 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3157 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3158 return CMD_WARNING;
3159 }
3160
3161 return CMD_SUCCESS;
3162}
3163
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003164#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3165
3166DEFUN(cfg_bts_excl_rf_lock,
3167 cfg_bts_excl_rf_lock_cmd,
3168 "rf-lock-exclude",
3169 EXCL_RFLOCK_STR)
3170{
3171 struct gsm_bts *bts = vty->index;
3172 bts->excl_from_rf_lock = 1;
3173 return CMD_SUCCESS;
3174}
3175
3176DEFUN(cfg_bts_no_excl_rf_lock,
3177 cfg_bts_no_excl_rf_lock_cmd,
3178 "no rf-lock-exclude",
3179 NO_STR EXCL_RFLOCK_STR)
3180{
3181 struct gsm_bts *bts = vty->index;
3182 bts->excl_from_rf_lock = 0;
3183 return CMD_SUCCESS;
3184}
3185
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003186#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3187
3188DEFUN(cfg_bts_force_comb_si,
3189 cfg_bts_force_comb_si_cmd,
3190 "force-combined-si",
3191 FORCE_COMB_SI_STR)
3192{
3193 struct gsm_bts *bts = vty->index;
3194 bts->force_combined_si = 1;
3195 return CMD_SUCCESS;
3196}
3197
3198DEFUN(cfg_bts_no_force_comb_si,
3199 cfg_bts_no_force_comb_si_cmd,
3200 "no force-combined-si",
3201 NO_STR FORCE_COMB_SI_STR)
3202{
3203 struct gsm_bts *bts = vty->index;
3204 bts->force_combined_si = 0;
3205 return CMD_SUCCESS;
3206}
3207
Andreas Eversberga83d5112013-12-07 18:32:28 +01003208static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3209{
3210 struct gsm_bts *bts = vty->index;
3211 struct bts_codec_conf *codec = &bts->codec;
3212 int i;
3213
3214 codec->hr = 0;
3215 codec->efr = 0;
3216 codec->amr = 0;
3217 for (i = 0; i < argc; i++) {
3218 if (!strcmp(argv[i], "hr"))
3219 codec->hr = 1;
3220 if (!strcmp(argv[i], "efr"))
3221 codec->efr = 1;
3222 if (!strcmp(argv[i], "amr"))
3223 codec->amr = 1;
3224 }
3225}
3226
3227#define CODEC_PAR_STR " (hr|efr|amr)"
3228#define CODEC_HELP_STR "Half Rate\n" \
3229 "Enhanced Full Rate\nAdaptive Multirate\n"
3230
3231DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3232 "codec-support fr",
3233 "Codec Support settings\nFullrate\n")
3234{
3235 _get_codec_from_arg(vty, 0, argv);
3236 return CMD_SUCCESS;
3237}
3238
3239DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3240 "codec-support fr" CODEC_PAR_STR,
3241 "Codec Support settings\nFullrate\n"
3242 CODEC_HELP_STR)
3243{
3244 _get_codec_from_arg(vty, 1, argv);
3245 return CMD_SUCCESS;
3246}
3247
3248DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3249 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3250 "Codec Support settings\nFullrate\n"
3251 CODEC_HELP_STR CODEC_HELP_STR)
3252{
3253 _get_codec_from_arg(vty, 2, argv);
3254 return CMD_SUCCESS;
3255}
3256
3257DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3258 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3259 "Codec Support settings\nFullrate\n"
3260 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3261{
3262 _get_codec_from_arg(vty, 3, argv);
3263 return CMD_SUCCESS;
3264}
3265
3266DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3267 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3268 "Codec Support settings\nFullrate\n"
3269 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3270{
3271 _get_codec_from_arg(vty, 4, argv);
3272 return CMD_SUCCESS;
3273}
3274
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003275DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3276 "depends-on-bts <0-255>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003277 "This BTS can only be started if another one is up\n"
3278 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003279{
3280 struct gsm_bts *bts = vty->index;
3281 struct gsm_bts *other_bts;
3282 int dep = atoi(argv[0]);
3283
3284
3285 if (!is_ipaccess_bts(bts)) {
3286 vty_out(vty, "This feature is only available for IP systems.%s",
3287 VTY_NEWLINE);
3288 return CMD_WARNING;
3289 }
3290
3291 other_bts = gsm_bts_num(bts->network, dep);
3292 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3293 vty_out(vty, "This feature is only available for IP systems.%s",
3294 VTY_NEWLINE);
3295 return CMD_WARNING;
3296 }
3297
3298 if (dep >= bts->nr) {
3299 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3300 VTY_NEWLINE);
3301 return CMD_WARNING;
3302 }
3303
3304 bts_depend_mark(bts, dep);
3305 return CMD_SUCCESS;
3306}
3307
3308DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3309 "depeneds-on-bts <0-255>",
3310 NO_STR "This BTS can only be started if another one is up\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003311 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003312{
3313 struct gsm_bts *bts = vty->index;
3314 int dep = atoi(argv[0]);
3315
3316 bts_depend_clear(bts, dep);
3317 return CMD_SUCCESS;
3318}
3319
Andreas Eversberg73266522014-01-19 11:47:44 +01003320#define AMR_TEXT "Adaptive Multi Rate settings\n"
3321#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3322#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3323 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3324#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3325#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3326
3327static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3328{
3329 struct gsm_bts *bts = vty->index;
3330 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3331 struct gsm48_multi_rate_conf *mr_conf =
3332 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3333 int i;
3334
3335 mr->gsm48_ie[1] = 0;
3336 for (i = 0; i < argc; i++)
3337 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3338 mr_conf->icmi = 0;
3339}
3340
3341static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3342{
3343 struct gsm_bts *bts = vty->index;
3344 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003345 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003346 int i;
3347
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003348 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3349 for (i = 0; i < argc - 1; i++)
3350 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003351}
3352
3353static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3354{
3355 struct gsm_bts *bts = vty->index;
3356 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003357 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003358 int i;
3359
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003360 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3361 for (i = 0; i < argc - 1; i++)
3362 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003363}
3364
3365static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3366{
3367 struct gsm_bts *bts = vty->index;
3368 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3369 struct gsm48_multi_rate_conf *mr_conf =
3370 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3371 int num = 0, i;
3372
3373 for (i = 0; i < ((full) ? 8 : 6); i++) {
3374 if ((mr->gsm48_ie[1] & (1 << i))) {
3375 num++;
3376 }
3377 }
3378
3379 if (argv[0][0] == 'a' || num == 0)
3380 mr_conf->icmi = 0;
3381 else {
3382 mr_conf->icmi = 1;
3383 if (num < atoi(argv[0]))
3384 mr_conf->smod = num - 1;
3385 else
3386 mr_conf->smod = atoi(argv[0]) - 1;
3387 }
3388}
3389
3390#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3391#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3392 "10,2k\n12,2k\n"
3393
3394#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3395#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3396
3397#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3398#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3399
3400DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3401 "amr tch-f modes" AMR_TCHF_PAR_STR,
3402 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3403 AMR_TCHF_HELP_STR)
3404{
3405 get_amr_from_arg(vty, 1, argv, 1);
3406 return CMD_SUCCESS;
3407}
3408
3409DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3410 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3411 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3412 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3413{
3414 get_amr_from_arg(vty, 2, argv, 1);
3415 return CMD_SUCCESS;
3416}
3417
3418DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3419 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3420 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3421 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3422{
3423 get_amr_from_arg(vty, 3, argv, 1);
3424 return CMD_SUCCESS;
3425}
3426
3427DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3428 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3429 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3430 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3431{
3432 get_amr_from_arg(vty, 4, argv, 1);
3433 return CMD_SUCCESS;
3434}
3435
3436DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3437 "amr tch-f start-mode (auto|1|2|3|4)",
3438 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3439{
3440 get_amr_start_from_arg(vty, argv, 1);
3441 return CMD_SUCCESS;
3442}
3443
3444DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3445 "amr tch-f threshold (ms|bts) <0-63>",
3446 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3447 AMR_TH_HELP_STR)
3448{
3449 get_amr_th_from_arg(vty, 2, argv, 1);
3450 return CMD_SUCCESS;
3451}
3452
3453DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3454 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3455 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3456 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3457{
3458 get_amr_th_from_arg(vty, 3, argv, 1);
3459 return CMD_SUCCESS;
3460}
3461
3462DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3463 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3464 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3465 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3466{
3467 get_amr_th_from_arg(vty, 4, argv, 1);
3468 return CMD_SUCCESS;
3469}
3470
3471DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3472 "amr tch-f hysteresis (ms|bts) <0-15>",
3473 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3474 AMR_HY_HELP_STR)
3475{
3476 get_amr_hy_from_arg(vty, 2, argv, 1);
3477 return CMD_SUCCESS;
3478}
3479
3480DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3481 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3482 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3483 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3484{
3485 get_amr_hy_from_arg(vty, 3, argv, 1);
3486 return CMD_SUCCESS;
3487}
3488
3489DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3490 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3491 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3492 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3493{
3494 get_amr_hy_from_arg(vty, 4, argv, 1);
3495 return CMD_SUCCESS;
3496}
3497
3498DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3499 "amr tch-h modes" AMR_TCHH_PAR_STR,
3500 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3501 AMR_TCHH_HELP_STR)
3502{
3503 get_amr_from_arg(vty, 1, argv, 0);
3504 return CMD_SUCCESS;
3505}
3506
3507DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3508 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3509 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3510 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3511{
3512 get_amr_from_arg(vty, 2, argv, 0);
3513 return CMD_SUCCESS;
3514}
3515
3516DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3517 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3518 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3519 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3520{
3521 get_amr_from_arg(vty, 3, argv, 0);
3522 return CMD_SUCCESS;
3523}
3524
3525DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3526 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3527 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3528 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3529{
3530 get_amr_from_arg(vty, 4, argv, 0);
3531 return CMD_SUCCESS;
3532}
3533
3534DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3535 "amr tch-h start-mode (auto|1|2|3|4)",
3536 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3537{
3538 get_amr_start_from_arg(vty, argv, 0);
3539 return CMD_SUCCESS;
3540}
3541
3542DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3543 "amr tch-h threshold (ms|bts) <0-63>",
3544 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3545 AMR_TH_HELP_STR)
3546{
3547 get_amr_th_from_arg(vty, 2, argv, 0);
3548 return CMD_SUCCESS;
3549}
3550
3551DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3552 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3553 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3554 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3555{
3556 get_amr_th_from_arg(vty, 3, argv, 0);
3557 return CMD_SUCCESS;
3558}
3559
3560DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3561 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3562 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3563 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3564{
3565 get_amr_th_from_arg(vty, 4, argv, 0);
3566 return CMD_SUCCESS;
3567}
3568
3569DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3570 "amr tch-h hysteresis (ms|bts) <0-15>",
3571 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3572 AMR_HY_HELP_STR)
3573{
3574 get_amr_hy_from_arg(vty, 2, argv, 0);
3575 return CMD_SUCCESS;
3576}
3577
3578DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3579 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3580 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3581 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3582{
3583 get_amr_hy_from_arg(vty, 3, argv, 0);
3584 return CMD_SUCCESS;
3585}
3586
3587DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3588 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3589 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3590 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3591{
3592 get_amr_hy_from_arg(vty, 4, argv, 0);
3593 return CMD_SUCCESS;
3594}
3595
Harald Welte8f0ed552010-05-11 21:53:49 +02003596#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003597
Harald Welte5258fc42009-03-28 19:07:53 +00003598/* per TRX configuration */
3599DEFUN(cfg_trx,
3600 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003601 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003602 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003603 "Select a TRX to configure")
3604{
3605 int trx_nr = atoi(argv[0]);
3606 struct gsm_bts *bts = vty->index;
3607 struct gsm_bts_trx *trx;
3608
Harald Weltee441d9c2009-06-21 16:17:15 +02003609 if (trx_nr > bts->num_trx) {
3610 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3611 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003612 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003613 } else if (trx_nr == bts->num_trx) {
3614 /* we need to allocate a new one */
3615 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003616 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003617 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003618
Harald Weltee441d9c2009-06-21 16:17:15 +02003619 if (!trx)
3620 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003621
3622 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003623 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003624 vty->node = TRX_NODE;
3625
3626 return CMD_SUCCESS;
3627}
3628
3629DEFUN(cfg_trx_arfcn,
3630 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003631 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003632 "Set the ARFCN for this TRX\n"
3633 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003634{
3635 int arfcn = atoi(argv[0]);
3636 struct gsm_bts_trx *trx = vty->index;
3637
3638 /* FIXME: check if this ARFCN is supported by this TRX */
3639
3640 trx->arfcn = arfcn;
3641
3642 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3643 /* FIXME: use OML layer to update the ARFCN */
3644 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3645
3646 return CMD_SUCCESS;
3647}
3648
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003649DEFUN(cfg_trx_nominal_power,
3650 cfg_trx_nominal_power_cmd,
3651 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003652 "Nominal TRX RF Power in dBm\n"
3653 "Nominal TRX RF Power in dBm\n"
3654 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003655{
3656 struct gsm_bts_trx *trx = vty->index;
3657
3658 trx->nominal_power = atoi(argv[0]);
3659
3660 return CMD_SUCCESS;
3661}
3662
Harald Weltefcd24452009-06-20 18:15:19 +02003663DEFUN(cfg_trx_max_power_red,
3664 cfg_trx_max_power_red_cmd,
3665 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003666 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003667 "Reduction of maximum BS RF Power in dB\n")
3668{
3669 int maxpwr_r = atoi(argv[0]);
3670 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003671 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003672
3673 /* FIXME: check if our BTS type supports more than 12 */
3674 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3675 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3676 maxpwr_r, VTY_NEWLINE);
3677 return CMD_WARNING;
3678 }
3679 if (maxpwr_r & 1) {
3680 vty_out(vty, "%% Power %d dB is not an even value%s",
3681 maxpwr_r, VTY_NEWLINE);
3682 return CMD_WARNING;
3683 }
3684
3685 trx->max_power_red = maxpwr_r;
3686
3687 /* FIXME: make sure we update this using OML */
3688
3689 return CMD_SUCCESS;
3690}
3691
Harald Welte42581822009-08-08 16:12:58 +02003692DEFUN(cfg_trx_rsl_e1,
3693 cfg_trx_rsl_e1_cmd,
3694 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003695 "RSL Parameters\n"
3696 "E1/T1 interface to be used for RSL\n"
3697 "E1/T1 interface to be used for RSL\n"
3698 "E1/T1 Line Number to be used for RSL\n"
3699 "E1/T1 Timeslot to be used for RSL\n"
3700 "E1/T1 Timeslot to be used for RSL\n"
3701 "E1/T1 Sub-slot to be used for RSL\n"
3702 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3703 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3704 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3705 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3706 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003707{
3708 struct gsm_bts_trx *trx = vty->index;
3709
3710 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3711
3712 return CMD_SUCCESS;
3713}
3714
3715DEFUN(cfg_trx_rsl_e1_tei,
3716 cfg_trx_rsl_e1_tei_cmd,
3717 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003718 "RSL Parameters\n"
3719 "Set the TEI to be used for RSL\n"
3720 "Set the TEI to be used for RSL\n"
3721 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003722{
3723 struct gsm_bts_trx *trx = vty->index;
3724
3725 trx->rsl_tei = atoi(argv[0]);
3726
3727 return CMD_SUCCESS;
3728}
3729
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003730DEFUN(cfg_trx_rf_locked,
3731 cfg_trx_rf_locked_cmd,
3732 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003733 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3734 "TRX is NOT RF locked (active)\n"
3735 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003736{
3737 int locked = atoi(argv[0]);
3738 struct gsm_bts_trx *trx = vty->index;
3739
Maxbe356ed2017-09-07 19:10:09 +02003740 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003741 return CMD_SUCCESS;
3742}
Harald Welte42581822009-08-08 16:12:58 +02003743
Harald Welte5258fc42009-03-28 19:07:53 +00003744/* per TS configuration */
3745DEFUN(cfg_ts,
3746 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003747 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003748 "Select a Timeslot to configure\n"
3749 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003750{
3751 int ts_nr = atoi(argv[0]);
3752 struct gsm_bts_trx *trx = vty->index;
3753 struct gsm_bts_trx_ts *ts;
3754
3755 if (ts_nr >= TRX_NR_TS) {
3756 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3757 TRX_NR_TS, VTY_NEWLINE);
3758 return CMD_WARNING;
3759 }
3760
3761 ts = &trx->ts[ts_nr];
3762
3763 vty->index = ts;
3764 vty->node = TS_NODE;
3765
3766 return CMD_SUCCESS;
3767}
3768
Harald Weltea6fd58e2009-08-07 00:25:23 +02003769DEFUN(cfg_ts_pchan,
3770 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003771 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003772 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003773{
3774 struct gsm_bts_trx_ts *ts = vty->index;
3775 int pchanc;
3776
3777 pchanc = gsm_pchan_parse(argv[0]);
3778 if (pchanc < 0)
3779 return CMD_WARNING;
3780
3781 ts->pchan = pchanc;
3782
3783 return CMD_SUCCESS;
3784}
3785
3786/* used for backwards compatibility with old config files that still
3787 * have uppercase pchan type names */
3788DEFUN_HIDDEN(cfg_ts_pchan_compat,
3789 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003790 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003791 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003792{
3793 struct gsm_bts_trx_ts *ts = vty->index;
3794 int pchanc;
3795
3796 pchanc = gsm_pchan_parse(argv[0]);
3797 if (pchanc < 0)
3798 return CMD_WARNING;
3799
3800 ts->pchan = pchanc;
3801
3802 return CMD_SUCCESS;
3803}
3804
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003805
3806
Harald Welte135a6482011-05-30 12:09:13 +02003807DEFUN(cfg_ts_tsc,
3808 cfg_ts_tsc_cmd,
3809 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003810 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003811{
3812 struct gsm_bts_trx_ts *ts = vty->index;
3813
Max71d082b2017-05-30 15:03:38 +02003814 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003815 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3816 "falling back to BCC%s", VTY_NEWLINE);
3817 ts->tsc = -1;
3818 return CMD_WARNING;
3819 }
3820
Harald Welte135a6482011-05-30 12:09:13 +02003821 ts->tsc = atoi(argv[0]);
3822
3823 return CMD_SUCCESS;
3824}
3825
Harald Weltea39b0f22010-06-14 22:26:10 +02003826#define HOPPING_STR "Configure frequency hopping\n"
3827
3828DEFUN(cfg_ts_hopping,
3829 cfg_ts_hopping_cmd,
3830 "hopping enabled (0|1)",
3831 HOPPING_STR "Enable or disable frequency hopping\n"
3832 "Disable frequency hopping\n" "Enable frequency hopping\n")
3833{
3834 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003835 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003836
Max71d082b2017-05-30 15:03:38 +02003837 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003838 vty_out(vty, "BTS model does not support hopping%s",
3839 VTY_NEWLINE);
3840 return CMD_WARNING;
3841 }
3842
3843 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003844
3845 return CMD_SUCCESS;
3846}
3847
Harald Welte6e0cd042009-09-12 13:05:33 +02003848DEFUN(cfg_ts_hsn,
3849 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003850 "hopping sequence-number <0-63>",
3851 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003852 "Which hopping sequence to use for this channel\n"
3853 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003854{
3855 struct gsm_bts_trx_ts *ts = vty->index;
3856
3857 ts->hopping.hsn = atoi(argv[0]);
3858
3859 return CMD_SUCCESS;
3860}
3861
3862DEFUN(cfg_ts_maio,
3863 cfg_ts_maio_cmd,
3864 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003865 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003866 "Which hopping MAIO to use for this channel\n"
3867 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003868{
3869 struct gsm_bts_trx_ts *ts = vty->index;
3870
3871 ts->hopping.maio = atoi(argv[0]);
3872
3873 return CMD_SUCCESS;
3874}
3875
3876DEFUN(cfg_ts_arfcn_add,
3877 cfg_ts_arfcn_add_cmd,
3878 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003879 HOPPING_STR "Configure hopping ARFCN list\n"
3880 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003881{
3882 struct gsm_bts_trx_ts *ts = vty->index;
3883 int arfcn = atoi(argv[0]);
3884
Harald Weltea39b0f22010-06-14 22:26:10 +02003885 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3886
Harald Welte6e0cd042009-09-12 13:05:33 +02003887 return CMD_SUCCESS;
3888}
3889
3890DEFUN(cfg_ts_arfcn_del,
3891 cfg_ts_arfcn_del_cmd,
3892 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003893 HOPPING_STR "Configure hopping ARFCN list\n"
3894 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003895{
3896 struct gsm_bts_trx_ts *ts = vty->index;
3897 int arfcn = atoi(argv[0]);
3898
Harald Weltea39b0f22010-06-14 22:26:10 +02003899 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3900
Harald Welte6e0cd042009-09-12 13:05:33 +02003901 return CMD_SUCCESS;
3902}
3903
Harald Weltea6fd58e2009-08-07 00:25:23 +02003904DEFUN(cfg_ts_e1_subslot,
3905 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003906 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003907 "E1/T1 channel connected to this on-air timeslot\n"
3908 "E1/T1 channel connected to this on-air timeslot\n"
3909 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003910 "E1/T1 timeslot connected to this on-air timeslot\n"
3911 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003912 "E1/T1 sub-slot connected to this on-air timeslot\n"
3913 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3914 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3915 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3916 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3917 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003918{
3919 struct gsm_bts_trx_ts *ts = vty->index;
3920
Harald Welte42581822009-08-08 16:12:58 +02003921 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003922
3923 return CMD_SUCCESS;
3924}
Harald Welte5258fc42009-03-28 19:07:53 +00003925
Harald Welte4f10c252010-05-16 21:47:13 +02003926void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3927{
Harald Weltecf9d4312017-12-13 23:17:16 +01003928 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003929 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003930 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003931 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003932}
3933
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003934DEFUN(drop_bts,
3935 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003936 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003937 "Debug/Simulation command to drop Abis/IP BTS\n"
3938 "Debug/Simulation command to drop Abis/IP BTS\n"
3939 "Debug/Simulation command to drop Abis/IP BTS\n"
3940 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003941{
3942 struct gsm_network *gsmnet;
3943 struct gsm_bts_trx *trx;
3944 struct gsm_bts *bts;
3945 unsigned int bts_nr;
3946
3947 gsmnet = gsmnet_from_vty(vty);
3948
3949 bts_nr = atoi(argv[0]);
3950 if (bts_nr >= gsmnet->num_bts) {
3951 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3952 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
3953 return CMD_WARNING;
3954 }
3955
3956 bts = gsm_bts_num(gsmnet, bts_nr);
3957 if (!bts) {
3958 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
3959 return CMD_WARNING;
3960 }
3961
3962 if (!is_ipaccess_bts(bts)) {
3963 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
3964 return CMD_WARNING;
3965 }
3966
3967
3968 /* close all connections */
3969 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003970 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003971 } else if (strcmp(argv[1], "rsl") == 0) {
3972 /* close all rsl connections */
3973 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01003974 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003975 }
3976 } else {
3977 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
3978 return CMD_WARNING;
3979 }
3980
3981 return CMD_SUCCESS;
3982}
3983
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003984DEFUN(restart_bts, restart_bts_cmd,
3985 "restart-bts <0-65535>",
3986 "Restart ip.access nanoBTS through OML\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003987 BTS_NR_STR)
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01003988{
3989 struct gsm_network *gsmnet;
3990 struct gsm_bts_trx *trx;
3991 struct gsm_bts *bts;
3992 unsigned int bts_nr;
3993
3994 gsmnet = gsmnet_from_vty(vty);
3995
3996 bts_nr = atoi(argv[0]);
3997 if (bts_nr >= gsmnet->num_bts) {
3998 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
3999 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4000 return CMD_WARNING;
4001 }
4002
4003 bts = gsm_bts_num(gsmnet, bts_nr);
4004 if (!bts) {
4005 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4006 return CMD_WARNING;
4007 }
4008
4009 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
4010 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
4011 VTY_NEWLINE);
4012 return CMD_WARNING;
4013 }
4014
4015 /* go from last TRX to c0 */
4016 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4017 abis_nm_ipaccess_restart(trx);
4018
4019 return CMD_SUCCESS;
4020}
4021
Harald Welte8e2e22f2017-07-10 20:25:10 +02004022DEFUN(bts_resend, bts_resend_cmd,
4023 "bts <0-255> resend-system-information",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004024 "BTS Specific Commands\n" BTS_NR_STR
Harald Welte8e2e22f2017-07-10 20:25:10 +02004025 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
4026{
4027 struct gsm_network *gsmnet;
4028 struct gsm_bts_trx *trx;
4029 struct gsm_bts *bts;
4030 unsigned int bts_nr;
4031
4032 gsmnet = gsmnet_from_vty(vty);
4033
4034 bts_nr = atoi(argv[0]);
4035 if (bts_nr >= gsmnet->num_bts) {
4036 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4037 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4038 return CMD_WARNING;
4039 }
4040
4041 bts = gsm_bts_num(gsmnet, bts_nr);
4042 if (!bts) {
4043 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4044 return CMD_WARNING;
4045 }
4046
4047 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4048 gsm_bts_trx_set_system_infos(trx);
4049
4050 return CMD_SUCCESS;
4051}
4052
4053
Harald Welte30f1f372014-12-28 15:00:45 +01004054DEFUN(smscb_cmd, smscb_cmd_cmd,
4055 "bts <0-255> smscb-command <1-4> HEXSTRING",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004056 "BTS related commands\n" BTS_NR_STR
Harald Welte30f1f372014-12-28 15:00:45 +01004057 "SMS Cell Broadcast\n" "Last Valid Block\n"
4058 "Hex Encoded SMSCB message (up to 88 octets)\n")
4059{
4060 struct gsm_bts *bts;
4061 int bts_nr = atoi(argv[0]);
4062 int last_block = atoi(argv[1]);
4063 struct rsl_ie_cb_cmd_type cb_cmd;
4064 uint8_t buf[88];
4065 int rc;
4066
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02004067 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01004068 if (!bts) {
4069 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4070 return CMD_WARNING;
4071 }
4072 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
4073 if (rc < 0 || rc > sizeof(buf)) {
4074 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
4075 return CMD_WARNING;
4076 }
4077
4078 cb_cmd.spare = 0;
4079 cb_cmd.def_bcast = 0;
4080 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
4081
4082 switch (last_block) {
4083 case 1:
4084 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
4085 break;
4086 case 2:
4087 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
4088 break;
4089 case 3:
4090 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
4091 break;
4092 case 4:
4093 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
4094 break;
4095 }
4096
4097 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
4098
4099 return CMD_SUCCESS;
4100}
4101
Harald Welte7fe00fb2017-05-27 14:09:50 +02004102/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02004103static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
4104 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02004105{
Harald Welte645eb622017-05-27 15:52:58 +02004106 int bts_nr = atoi(bts_str);
4107 int trx_nr = atoi(trx_str);
4108 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004109 struct gsm_bts *bts;
4110 struct gsm_bts_trx *trx;
4111 struct gsm_bts_trx_ts *ts;
4112
4113 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
4114 if (!bts) {
4115 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4116 return NULL;
4117 }
4118
4119 trx = gsm_bts_trx_num(bts, trx_nr);
4120 if (!trx) {
4121 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
4122 return NULL;
4123 }
4124
4125 ts = &trx->ts[ts_nr];
4126
4127 return ts;
4128}
Harald Welte30f1f372014-12-28 15:00:45 +01004129
Harald Welted0d2b0b2010-12-23 13:18:07 +01004130DEFUN(pdch_act, pdch_act_cmd,
4131 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004132 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4133 "TRX Timeslot\n" TS_NR_STR "Packet Data Channel\n"
Harald Welted0d2b0b2010-12-23 13:18:07 +01004134 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4135 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4136{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004137 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004138 int activate;
4139
Harald Welte645eb622017-05-27 15:52:58 +02004140 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004141 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004142 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004143
Harald Welte7fe00fb2017-05-27 14:09:50 +02004144 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004145 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4146 VTY_NEWLINE);
4147 return CMD_WARNING;
4148 }
4149
Harald Welted0d2b0b2010-12-23 13:18:07 +01004150 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4151 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004152 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004153 return CMD_WARNING;
4154 }
4155
4156 if (!strcmp(argv[3], "activate"))
4157 activate = 1;
4158 else
4159 activate = 0;
4160
4161 rsl_ipacc_pdch_activate(ts, activate);
4162
4163 return CMD_SUCCESS;
4164
4165}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004166
Harald Welte2abd5e12017-05-27 14:10:40 +02004167/* determine the logical channel type based on the physical channel type */
4168static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4169{
4170 switch (pchan) {
4171 case GSM_PCHAN_TCH_F:
4172 return GSM_LCHAN_TCH_F;
4173 case GSM_PCHAN_TCH_H:
4174 return GSM_LCHAN_TCH_H;
4175 case GSM_PCHAN_SDCCH8_SACCH8C:
4176 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4177 case GSM_PCHAN_CCCH_SDCCH4:
4178 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4179 return GSM_LCHAN_SDCCH;
4180 default:
4181 return -1;
4182 }
4183}
4184
4185/* configure the lchan for a single AMR mode (as specified) */
4186static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4187{
4188 struct amr_multirate_conf mr;
4189 struct gsm48_multi_rate_conf *mr_conf;
4190 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4191
4192 if (amr_mode > 7)
4193 return -1;
4194
4195 memset(&mr, 0, sizeof(mr));
4196 mr_conf->ver = 1;
4197 /* bit-mask of supported modes, only one bit is set. Reflects
4198 * Figure 10.5.2.47a where there are no thershold and only a
4199 * single mode */
4200 mr.gsm48_ie[1] = 1 << amr_mode;
4201
4202 mr.ms_mode[0].mode = amr_mode;
4203 mr.bts_mode[0].mode = amr_mode;
4204
4205 /* encode this configuration into the lchan for both uplink and
4206 * downlink direction */
4207 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4208 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4209
4210 return 0;
4211}
4212
4213/* Debug/Measurement command to activate a given logical channel
4214 * manually in a given mode/codec. This is useful for receiver
4215 * performance testing (FER/RBER/...) */
4216DEFUN(lchan_act, lchan_act_cmd,
4217 "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 +01004218 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4219 "TRX Timeslot\n" TS_NR_STR "Sub-Slot Number\n" LCHAN_NR_STR
Harald Welte2abd5e12017-05-27 14:10:40 +02004220 "Manual Channel Activation (e.g. for BER test)\n"
4221 "Manual Channel Deactivation (e.g. for BER test)\n"
4222 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4223{
4224 struct gsm_bts_trx_ts *ts;
4225 struct gsm_lchan *lchan;
4226 int ss_nr = atoi(argv[3]);
4227 const char *act_str = argv[4];
4228 const char *codec_str = argv[5];
4229 int activate;
4230
4231 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4232 if (!ts)
4233 return CMD_WARNING;
4234
4235 lchan = &ts->lchan[ss_nr];
4236
4237 if (!strcmp(act_str, "activate"))
4238 activate = 1;
4239 else
4240 activate = 0;
4241
4242 if (ss_nr >= ts_subslots(ts)) {
4243 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4244 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4245 return CMD_WARNING;
4246 }
4247
4248 if (activate) {
4249 int lchan_t;
4250 if (lchan->state != LCHAN_S_NONE) {
4251 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4252 return CMD_WARNING;
4253 }
4254 lchan_t = lchan_type_by_pchan(ts->pchan);
4255 if (lchan_t < 0)
4256 return CMD_WARNING;
4257 /* configure the lchan */
4258 lchan->type = lchan_t;
4259 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4260 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4261 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4262 else if (!strcmp(codec_str, "efr"))
4263 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4264 else if (!strcmp(codec_str, "amr")) {
4265 int amr_mode;
4266 if (argc < 7) {
4267 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4268 return CMD_WARNING;
4269 }
4270 amr_mode = atoi(argv[6]);
4271 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4272 lchan_set_single_amr_mode(lchan, amr_mode);
4273 }
4274 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4275 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4276 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004277 } else {
4278 rsl_direct_rf_release(lchan);
4279 }
4280
4281 return CMD_SUCCESS;
4282}
4283
Harald Welte3f86c522017-05-27 15:53:28 +02004284DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4285 "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 +01004286 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4287 "TRX Timeslot\n" TS_NR_STR "Sub-Slot\n" LCHAN_NR_STR
Harald Welte3f86c522017-05-27 15:53:28 +02004288 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4289{
4290 struct gsm_bts_trx_ts *ts;
4291 struct gsm_lchan *lchan;
4292 int ss_nr = atoi(argv[3]);
4293 int port = atoi(argv[5]);
4294 struct in_addr ia;
4295 inet_aton(argv[4], &ia);
4296
4297 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4298 if (!ts)
4299 return CMD_WARNING;
4300
4301 lchan = &ts->lchan[ss_nr];
4302
4303 if (ss_nr >= ts_subslots(ts)) {
4304 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4305 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4306 return CMD_WARNING;
4307 }
4308
4309 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4310 inet_ntoa(ia), port, VTY_NEWLINE);
4311 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4312 return CMD_SUCCESS;
4313}
Harald Welteb71147a2017-07-18 19:11:49 +02004314
4315DEFUN(ctrl_trap, ctrl_trap_cmd,
4316 "ctrl-interface generate-trap TRAP VALUE",
4317 "Commands related to the CTRL Interface\n"
4318 "Generate a TRAP for test purpose\n"
4319 "Identity/Name of the TRAP variable\n"
4320 "Value of the TRAP variable\n")
4321{
4322 struct gsm_network *net = gsmnet_from_vty(vty);
4323
4324 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4325 return CMD_SUCCESS;
4326}
4327
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004328#define NETWORK_STR "Configure the GSM network\n"
4329#define CODE_CMD_STR "Code commands\n"
4330#define NAME_CMD_STR "Name Commands\n"
4331#define NAME_STR "Name to use\n"
4332
4333DEFUN(cfg_net,
4334 cfg_net_cmd,
4335 "network", NETWORK_STR)
4336{
4337 vty->index = gsmnet_from_vty(vty);
4338 vty->node = GSMNET_NODE;
4339
4340 return CMD_SUCCESS;
4341}
4342
4343DEFUN(cfg_net_ncc,
4344 cfg_net_ncc_cmd,
4345 "network country code <1-999>",
4346 "Set the GSM network country code\n"
4347 "Country commands\n"
4348 CODE_CMD_STR
4349 "Network Country Code to use\n")
4350{
4351 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4352
4353 gsmnet->country_code = atoi(argv[0]);
4354
4355 return CMD_SUCCESS;
4356}
4357
4358DEFUN(cfg_net_mnc,
4359 cfg_net_mnc_cmd,
4360 "mobile network code <0-999>",
4361 "Set the GSM mobile network code\n"
4362 "Network Commands\n"
4363 CODE_CMD_STR
4364 "Mobile Network Code to use\n")
4365{
4366 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4367
4368 gsmnet->network_code = atoi(argv[0]);
4369
4370 return CMD_SUCCESS;
4371}
4372
4373DEFUN(cfg_net_encryption,
4374 cfg_net_encryption_cmd,
4375 "encryption a5 (0|1|2|3)",
4376 "Encryption options\n"
4377 "A5 encryption\n" "A5/0: No encryption\n"
4378 "A5/1: Encryption\n" "A5/2: Export-grade Encryption\n"
4379 "A5/3: 'New' Secure Encryption\n")
4380{
4381 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4382
4383 gsmnet->a5_encryption = atoi(argv[0]);
4384
4385 return CMD_SUCCESS;
4386}
4387
4388DEFUN(cfg_net_dyn_ts_allow_tch_f,
4389 cfg_net_dyn_ts_allow_tch_f_cmd,
4390 "dyn_ts_allow_tch_f (0|1)",
4391 "Allow or disallow allocating TCH/F on TCH_F_TCH_H_PDCH timeslots\n"
4392 "Disallow TCH/F on TCH_F_TCH_H_PDCH (default)\n"
4393 "Allow TCH/F on TCH_F_TCH_H_PDCH\n")
4394{
4395 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4396 gsmnet->dyn_ts_allow_tch_f = atoi(argv[0]) ? true : false;
4397 return CMD_SUCCESS;
4398}
4399
4400DEFUN(cfg_net_timezone,
4401 cfg_net_timezone_cmd,
4402 "timezone <-19-19> (0|15|30|45)",
4403 "Set the Timezone Offset of the network\n"
4404 "Timezone offset (hours)\n"
4405 "Timezone offset (00 minutes)\n"
4406 "Timezone offset (15 minutes)\n"
4407 "Timezone offset (30 minutes)\n"
4408 "Timezone offset (45 minutes)\n"
4409 )
4410{
4411 struct gsm_network *net = vty->index;
4412 int tzhr = atoi(argv[0]);
4413 int tzmn = atoi(argv[1]);
4414
4415 net->tz.hr = tzhr;
4416 net->tz.mn = tzmn;
4417 net->tz.dst = 0;
4418 net->tz.override = 1;
4419
4420 return CMD_SUCCESS;
4421}
4422
4423DEFUN(cfg_net_timezone_dst,
4424 cfg_net_timezone_dst_cmd,
4425 "timezone <-19-19> (0|15|30|45) <0-2>",
4426 "Set the Timezone Offset of the network\n"
4427 "Timezone offset (hours)\n"
4428 "Timezone offset (00 minutes)\n"
4429 "Timezone offset (15 minutes)\n"
4430 "Timezone offset (30 minutes)\n"
4431 "Timezone offset (45 minutes)\n"
4432 "DST offset (hours)\n"
4433 )
4434{
4435 struct gsm_network *net = vty->index;
4436 int tzhr = atoi(argv[0]);
4437 int tzmn = atoi(argv[1]);
4438 int tzdst = atoi(argv[2]);
4439
4440 net->tz.hr = tzhr;
4441 net->tz.mn = tzmn;
4442 net->tz.dst = tzdst;
4443 net->tz.override = 1;
4444
4445 return CMD_SUCCESS;
4446}
4447
4448DEFUN(cfg_net_no_timezone,
4449 cfg_net_no_timezone_cmd,
4450 "no timezone",
4451 NO_STR
4452 "Disable network timezone override, use system tz\n")
4453{
4454 struct gsm_network *net = vty->index;
4455
4456 net->tz.override = 0;
4457
4458 return CMD_SUCCESS;
4459}
4460
4461DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
4462 "periodic location update <6-1530>",
4463 "Periodic Location Updating Interval\n"
4464 "Periodic Location Updating Interval\n"
4465 "Periodic Location Updating Interval\n"
4466 "Periodic Location Updating Interval in Minutes\n")
4467{
4468 struct gsm_network *net = vty->index;
4469
4470 net->t3212 = atoi(argv[0]) / 6;
4471
4472 return CMD_SUCCESS;
4473}
4474
4475DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
4476 "no periodic location update",
4477 NO_STR
4478 "Periodic Location Updating Interval\n"
4479 "Periodic Location Updating Interval\n"
4480 "Periodic Location Updating Interval\n")
4481{
4482 struct gsm_network *net = vty->index;
4483
4484 net->t3212 = 0;
4485
4486 return CMD_SUCCESS;
4487}
4488
Harald Weltedcccb182010-05-16 20:52:23 +02004489extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004490
Maxdb0e3802017-01-12 19:35:11 +01004491int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004492{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004493 cfg_ts_pchan_cmd.string =
4494 vty_cmd_string_from_valstr(tall_bsc_ctx,
4495 gsm_pchant_names,
4496 "phys_chan_config (", "|", ")",
4497 VTY_DO_LOWER);
4498 cfg_ts_pchan_cmd.doc =
4499 vty_cmd_string_from_valstr(tall_bsc_ctx,
4500 gsm_pchant_descs,
4501 "Physical Channel Combination\n",
4502 "\n", "", 0);
4503
Harald Weltee555c2b2012-08-17 13:02:12 +02004504 cfg_bts_type_cmd.string =
4505 vty_cmd_string_from_valstr(tall_bsc_ctx,
4506 bts_type_names,
4507 "type (", "|", ")",
4508 VTY_DO_LOWER);
4509 cfg_bts_type_cmd.doc =
4510 vty_cmd_string_from_valstr(tall_bsc_ctx,
4511 bts_type_descs,
4512 "BTS Vendor/Type\n",
4513 "\n", "", 0);
4514
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004515 OSMO_ASSERT(vty_global_gsm_network == NULL);
4516 vty_global_gsm_network = network;
4517
4518 osmo_stats_vty_add_cmds();
4519
4520 install_element(CONFIG_NODE, &cfg_net_cmd);
4521 install_node(&net_node, config_write_net);
4522 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
4523 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
4524 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
4525 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
4526 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
4527 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
4528 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
4529 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
4530 install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);
Harald Weltee555c2b2012-08-17 13:02:12 +02004531
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004532 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004533 install_element_ve(&show_bts_cmd);
4534 install_element_ve(&show_trx_cmd);
4535 install_element_ve(&show_ts_cmd);
4536 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004537 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004538
Philipp Maier39f62bb2017-04-09 12:32:51 +02004539 install_element_ve(&show_subscr_conn_cmd);
4540 install_element_ve(&handover_subscr_conn_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004541 install_element_ve(&handover_any_cmd);
4542 install_element_ve(&assignment_subscr_conn_cmd);
4543 install_element_ve(&assignment_any_cmd);
Philipp Maier39f62bb2017-04-09 12:32:51 +02004544
Harald Welteb4d5b172010-05-12 16:10:35 +00004545 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004546 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004547
Maxdb0e3802017-01-12 19:35:11 +01004548 logging_vty_add_cmds(NULL);
Harald Welte2f4f4b82018-02-14 00:50:27 +01004549 osmo_talloc_vty_add_cmds();
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004550
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004551 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004552 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004553 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4554 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4555 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4556 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4557 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4558 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4559 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4560 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4561 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004562 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004563 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004564 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004565 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004566 /* See also handover commands added on net level from handover_vty.c */
Harald Welte5013b2a2009-08-07 13:29:14 +02004567
4568 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004569 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004570 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004571 install_element(BTS_NODE, &cfg_description_cmd);
4572 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004573 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004574 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004575 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4576 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4577 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4578 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004579 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4580 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004581 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004582 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004583 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004584 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004585 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004586 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004587 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004588 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4589 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004590 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004591 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4592 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004593 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4594 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4595 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004596 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4597 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004598 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004599 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004600 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004601 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004602 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4603 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004604 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4605 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4606 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4607 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4608 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4609 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004610 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004611 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004612 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304613 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004614 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004615 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004616 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004617 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4618 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004619 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004620 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004621 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004622 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004623 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4624 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4625 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004626 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004627 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4628 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004629 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004630 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004631 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4632 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004633 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004634 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4635 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004636 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4637 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004638 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4639 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004640 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4641 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004642 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4643 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4644 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4645 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4646 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004647 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4648 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004649 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4650 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4651 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4652 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4653 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4654 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4655 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4656 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4657 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4658 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4659 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4660 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4661 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4662 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4663 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4664 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4665 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4666 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4667 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4668 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4669 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4670 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004671 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004672 /* See also handover commands added on bts level from handover_vty.c */
Harald Welte68628e82009-03-10 12:17:57 +00004673
Harald Welte5258fc42009-03-28 19:07:53 +00004674 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004675 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004676 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004677 install_element(TRX_NODE, &cfg_description_cmd);
4678 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004679 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004680 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004681 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4682 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004683 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004684
Harald Welte5258fc42009-03-28 19:07:53 +00004685 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004686 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004687 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004688 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004689 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004690 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004691 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4692 install_element(TS_NODE, &cfg_ts_maio_cmd);
4693 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4694 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004695 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004696
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004697 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004698 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004699 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004700 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004701 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004702 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004703 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004704 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004705
Harald Welte81c9b9c2010-05-31 16:40:40 +02004706 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004707 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004708 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004709 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004710
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004711 ho_vty_init();
4712
Harald Weltedcccb182010-05-16 20:52:23 +02004713 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004714
Harald Welte68628e82009-03-10 12:17:57 +00004715 return 0;
4716}