blob: 3ce310ad3c5ed746405a57b5c8c2821369f2a76c [file] [log] [blame]
Harald Welte68628e82009-03-10 12:17:57 +00001/* OpenBSC interface to quagga VTY */
Harald Welte51e4bf32017-12-23 17:30:18 +01002/* (C) 2009-2017 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;
Harald Welte51e4bf32017-12-23 17:30:18 +0100195 int i;
Harald Welteb908cb72009-12-22 13:09:29 +0100196
Harald Welteef235b52009-03-10 12:34:02 +0000197 vty_out(vty, "BSC is on Country Code %u, Network Code %u "
198 "and has %u BTS%s", net->country_code, net->network_code,
199 net->num_bts, VTY_NEWLINE);
Maxddee01f2016-05-24 14:23:27 +0200200 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte51e4bf32017-12-23 17:30:18 +0100201 vty_out(vty, " Encryption:");
202 for (i = 0; i < 8; i++) {
203 if (net->a5_encryption_mask & (1 << i))
204 vty_out(vty, " A5/%u", i);
205 }
206 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +0100207 vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
208 VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800209 vty_out(vty, " Use TCH for Paging any: %d%s", net->pag_any_tch,
210 VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100211
212 {
213 struct gsm_bts *bts;
214 unsigned int ho_active_count = 0;
215 unsigned int ho_inactive_count = 0;
216
217 llist_for_each_entry(bts, &net->bts_list, list) {
218 if (ho_get_ho_active(bts->ho))
219 ho_active_count ++;
220 else
221 ho_inactive_count ++;
222 }
223
224 if (ho_active_count && ho_inactive_count)
225 vty_out(vty, " Handover: On at %u BTS, Off at %u BTS%s",
226 ho_active_count, ho_inactive_count, VTY_NEWLINE);
227 else
228 vty_out(vty, " Handover: %s%s", ho_active_count ? "On" : "Off",
229 VTY_NEWLINE);
230 }
231
Harald Welteb908cb72009-12-22 13:09:29 +0100232 network_chan_load(&pl, net);
233 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
234 dump_pchan_load_vty(vty, " ", &pl);
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100235
236 /* show rf */
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100237 if (net->bsc_data)
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100238 vty_out(vty, " Last RF Command: %s%s",
Holger Hans Peter Freyther8ec49522011-08-15 15:53:00 +0200239 net->bsc_data->rf_ctrl->last_state_command,
Holger Hans Peter Freyther37ac4202011-02-24 14:19:14 +0100240 VTY_NEWLINE);
Holger Hans Peter Freythera9fae1a2014-02-08 12:12:03 +0100241 if (net->bsc_data)
Jacob Erlbeck779a7282013-09-11 10:46:57 +0200242 vty_out(vty, " Last RF Lock Command: %s%s",
243 net->bsc_data->rf_ctrl->last_rf_lock_ctrl_command,
244 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000245}
246
Neels Hofmeyrea11bf82016-05-12 01:53:23 +0200247DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
Harald Welte68628e82009-03-10 12:17:57 +0000248 SHOW_STR "Display information about a GSM NETWORK\n")
249{
Harald Weltedcccb182010-05-16 20:52:23 +0200250 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000251 net_dump_vty(vty, net);
252
253 return CMD_SUCCESS;
254}
255
256static void e1isl_dump_vty(struct vty *vty, struct e1inp_sign_link *e1l)
257{
Harald Welteedb37782009-05-01 14:59:07 +0000258 struct e1inp_line *line;
259
260 if (!e1l) {
261 vty_out(vty, " None%s", VTY_NEWLINE);
262 return;
263 }
264
265 line = e1l->ts->line;
266
267 vty_out(vty, " E1 Line %u, Type %s: Timeslot %u, Mode %s%s",
268 line->num, line->driver->name, e1l->ts->num,
Harald Welte1bc77352009-03-10 19:47:51 +0000269 e1inp_signtype_name(e1l->type), VTY_NEWLINE);
Harald Welteedb37782009-05-01 14:59:07 +0000270 vty_out(vty, " E1 TEI %u, SAPI %u%s",
Harald Welte68628e82009-03-10 12:17:57 +0000271 e1l->tei, e1l->sapi, VTY_NEWLINE);
272}
273
Neels Hofmeyrc1db52f2018-01-19 00:59:33 +0100274static void vty_out_neigh_list(struct vty *vty, struct bitvec *bv)
275{
276 int count = 0;
277 int i;
278 for (i = 0; i < 1024; i++) {
279 if (!bitvec_get_bit_pos(bv, i))
280 continue;
281 vty_out(vty, " %u", i);
282 count ++;
283 }
284 if (!count)
285 vty_out(vty, " (none)");
286 else
287 vty_out(vty, " (%d)", count);
288}
289
Harald Welte68628e82009-03-10 12:17:57 +0000290static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
291{
Harald Welteb908cb72009-12-22 13:09:29 +0100292 struct pchan_load pl;
Maxd1f70ed2017-09-21 16:15:32 +0200293 unsigned long long sec;
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100294 struct gsm_bts_trx *trx;
295 int ts_hopping_total;
296 int ts_non_hopping_total;
Harald Welteb908cb72009-12-22 13:09:29 +0100297
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200298 vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
Harald Welte557c84e2015-11-20 10:50:24 +0100299 "BSIC %u (NCC=%u, BCC=%u) and %u TRX%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200300 bts->nr, btstype2str(bts->type), gsm_band_name(bts->band),
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +0200301 bts->cell_identity,
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100302 bts->location_area_code, bts->bsic,
Harald Welte557c84e2015-11-20 10:50:24 +0100303 bts->bsic >> 3, bts->bsic & 7,
Harald Weltefcd24452009-06-20 18:15:19 +0200304 bts->num_trx, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100305 vty_out(vty, " Description: %s%s",
Harald Welte197dea92010-05-14 17:59:53 +0200306 bts->description ? bts->description : "(null)", VTY_NEWLINE);
Neels Hofmeyr097a6e72018-01-19 00:59:33 +0100307
308 vty_out(vty, " ARFCNs:");
309 ts_hopping_total = 0;
310 ts_non_hopping_total = 0;
311 llist_for_each_entry(trx, &bts->trx_list, list) {
312 int ts_nr;
313 int ts_hopping = 0;
314 int ts_non_hopping = 0;
315 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
316 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
317 if (ts->hopping.enabled)
318 ts_hopping++;
319 else
320 ts_non_hopping++;
321 }
322
323 if (ts_non_hopping)
324 vty_out(vty, " %u", trx->arfcn);
325 ts_hopping_total += ts_hopping;
326 ts_non_hopping_total += ts_non_hopping;
327 }
328 if (ts_hopping_total) {
329 if (ts_non_hopping_total)
330 vty_out(vty, " / Hopping on %d of %d timeslots",
331 ts_hopping_total, ts_hopping_total + ts_non_hopping_total);
332 else
333 vty_out(vty, " Hopping on all %d timeslots", ts_hopping_total);
334 }
335 vty_out(vty, "%s", VTY_NEWLINE);
336
Maxf9685c12017-03-23 12:01:07 +0100337 if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100338 vty_out(vty, " PCU version %s connected%s", bts->pcu_version,
Maxf9685c12017-03-23 12:01:07 +0100339 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100340 vty_out(vty, " MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE);
341 vty_out(vty, " Minimum Rx Level for Access: %i dBm%s",
Harald Welte1d8dbc42009-12-12 15:38:16 +0100342 rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min),
343 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100344 vty_out(vty, " Cell Reselection Hysteresis: %u dBm%s",
Harald Welte73225282009-12-12 18:17:25 +0100345 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100346 vty_out(vty, " RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100347 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100348 vty_out(vty, " RACH Max transmissions: %u%s",
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100349 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
350 VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100351 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200352 vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200353 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100354 vty_out(vty, " Uplink DTX: %s%s",
Maxc08ee712016-05-11 12:45:13 +0200355 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ?
356 "enabled" : "forced", VTY_NEWLINE);
357 else
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100358 vty_out(vty, " Uplink DTX: not enabled%s", VTY_NEWLINE);
359 vty_out(vty, " Downlink DTX: %senabled%s", bts->dtxd ? "" : "not ",
Maxc08ee712016-05-11 12:45:13 +0200360 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100361 vty_out(vty, " Channel Description Attachment: %s%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200362 (bts->si_common.chan_desc.att) ? "yes" : "no", VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100363 vty_out(vty, " Channel Description BS-PA-MFRMS: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200364 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100365 vty_out(vty, " Channel Description BS-AG_BLKS-RES: %u%s",
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200366 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100367 vty_out(vty, " System Information present: 0x%08x, static: 0x%08x%s",
Harald Welte9fbff4a2010-07-30 11:50:09 +0200368 bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100369 vty_out(vty, " Early Classmark Sending: 2G %s, 3G %s%s%s",
Harald Welte42def722017-01-13 00:10:32 +0100370 bts->early_classmark_allowed ? "allowed" : "forbidden",
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100371 bts->early_classmark_allowed_3g ? "allowed" : "forbidden",
372 bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ?
373 " (forbidden by 2G bit)" : "",
Harald Welte42def722017-01-13 00:10:32 +0100374 VTY_NEWLINE);
Harald Welte8254cf72017-05-29 13:42:19 +0200375 if (bts->pcu_sock_path)
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100376 vty_out(vty, " PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Harald Welte4cc34222009-05-01 15:12:31 +0000377 if (is_ipaccess_bts(bts))
Harald Welte8175e952009-10-20 00:22:00 +0200378 vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
Harald Welte4cc34222009-05-01 15:12:31 +0000379 bts->ip_access.site_id, bts->ip_access.bts_id,
Harald Welte8175e952009-10-20 00:22:00 +0200380 bts->oml_tei, VTY_NEWLINE);
Sylvain Munautc9519462011-10-17 14:04:55 +0200381 else if (bts->type == GSM_BTS_TYPE_NOKIA_SITE)
382 vty_out(vty, " Skip Reset: %d%s",
383 bts->nokia.skip_reset, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000384 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200385 net_dump_nmstate(vty, &bts->mo.nm_state);
Harald Welte68628e82009-03-10 12:17:57 +0000386 vty_out(vty, " Site Mgr NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200387 net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
Holger Hans Peter Freyther846d8dc2013-05-29 16:22:09 +0200388 vty_out(vty, " GPRS NSE: ");
389 net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state);
390 vty_out(vty, " GPRS CELL: ");
391 net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state);
392 vty_out(vty, " GPRS NSVC0: ");
393 net_dump_nmstate(vty, &bts->gprs.nsvc[0].mo.nm_state);
394 vty_out(vty, " GPRS NSVC1: ");
395 net_dump_nmstate(vty, &bts->gprs.nsvc[1].mo.nm_state);
Holger Hans Peter Freyther66e14cd2011-04-26 15:52:34 +0200396 vty_out(vty, " Paging: %u pending requests, %u free slots%s",
397 paging_pending_requests_nr(bts),
Harald Welte68628e82009-03-10 12:17:57 +0000398 bts->paging.available_slots, VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100399 if (is_ipaccess_bts(bts)) {
Max3d049d22017-10-09 17:12:53 +0200400 vty_out(vty, " OML Link state: %s", get_model_oml_status(bts));
Max25cc4072017-10-10 14:50:35 +0200401 sec = bts_uptime(bts);
402 if (sec)
Maxff3fad12018-01-07 16:50:42 +0100403 vty_out(vty, " %llu days %llu hours %llu min. %llu sec.",
404 OSMO_SEC2DAY(sec), OSMO_SEC2HRS(sec), OSMO_SEC2MIN(sec), sec % 60);
405 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100406 } else {
Harald Welte8175e952009-10-20 00:22:00 +0200407 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
408 e1isl_dump_vty(vty, bts->oml_link);
409 }
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100410
Neels Hofmeyrc1db52f2018-01-19 00:59:33 +0100411 vty_out(vty, " Neighbor Cells: ");
412 switch (bts->neigh_list_manual_mode) {
413 default:
414 case NL_MODE_AUTOMATIC:
415 vty_out(vty, "Automatic");
416 /* generate_bcch_chan_list() should populate si_common.neigh_list */
417 break;
418 case NL_MODE_MANUAL:
419 vty_out(vty, "Manual");
420 break;
421 case NL_MODE_MANUAL_SI5SEP:
422 vty_out(vty, "Manual/separate SI5");
423 break;
424 }
425 vty_out(vty, ", ARFCNs:");
426 vty_out_neigh_list(vty, &bts->si_common.neigh_list);
427 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
428 vty_out(vty, " SI5:");
429 vty_out_neigh_list(vty, &bts->si_common.si5_neigh_list);
430 }
431 vty_out(vty, "%s", VTY_NEWLINE);
432
Holger Hans Peter Freytherd283db42010-11-25 16:28:45 +0100433 /* FIXME: chan_desc */
Harald Welteb908cb72009-12-22 13:09:29 +0100434 memset(&pl, 0, sizeof(pl));
Neels Hofmeyr2afffd52016-09-25 17:01:20 +0200435 bts_chan_load(&pl, bts);
Harald Welteb908cb72009-12-22 13:09:29 +0100436 vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE);
437 dump_pchan_load_vty(vty, " ", &pl);
Harald Welted82101e2017-12-09 23:07:38 +0100438
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100439 vty_out(vty, " Channel Requests : %"PRIu64" total, %"PRIu64" no channel%s",
Harald Welted82101e2017-12-09 23:07:38 +0100440 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL].current,
441 bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL].current,
442 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100443 vty_out(vty, " Channel Failures : %"PRIu64" rf_failures, %"PRIu64" rll failures%s",
Harald Welted82101e2017-12-09 23:07:38 +0100444 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RF_FAIL].current,
445 bts->bts_ctrs->ctr[BTS_CTR_CHAN_RLL_ERR].current,
446 VTY_NEWLINE);
Neels Hofmeyr97d110e2018-01-19 00:59:33 +0100447 vty_out(vty, " BTS failures : %"PRIu64" OML, %"PRIu64" RSL%s",
Harald Welted82101e2017-12-09 23:07:38 +0100448 bts->bts_ctrs->ctr[BTS_CTR_BTS_OML_FAIL].current,
449 bts->bts_ctrs->ctr[BTS_CTR_BTS_RSL_FAIL].current,
450 VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000451}
452
Sylvain Munaut39c31de2012-12-28 12:15:11 +0100453DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
Harald Welte68628e82009-03-10 12:17:57 +0000454 SHOW_STR "Display information about a BTS\n"
455 "BTS number")
456{
Harald Weltedcccb182010-05-16 20:52:23 +0200457 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +0000458 int bts_nr;
459
460 if (argc != 0) {
461 /* use the BTS number that the user has specified */
462 bts_nr = atoi(argv[0]);
Harald Welte712ddbc2010-12-24 12:24:03 +0100463 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +0000464 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +0000465 VTY_NEWLINE);
466 return CMD_WARNING;
467 }
Harald Weltee441d9c2009-06-21 16:17:15 +0200468 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000469 return CMD_SUCCESS;
470 }
471 /* print all BTS's */
472 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
Harald Weltee441d9c2009-06-21 16:17:15 +0200473 bts_dump_vty(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +0000474
475 return CMD_SUCCESS;
476}
477
Harald Welte42581822009-08-08 16:12:58 +0200478/* utility functions */
479static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
480 const char *ts, const char *ss)
481{
482 e1_link->e1_nr = atoi(line);
483 e1_link->e1_ts = atoi(ts);
484 if (!strcmp(ss, "full"))
485 e1_link->e1_ts_ss = 255;
486 else
487 e1_link->e1_ts_ss = atoi(ss);
488}
489
490static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
491 const char *prefix)
492{
493 if (!e1_link->e1_ts)
494 return;
495
496 if (e1_link->e1_ts_ss == 255)
497 vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
498 prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
499 else
500 vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
501 prefix, e1_link->e1_nr, e1_link->e1_ts,
502 e1_link->e1_ts_ss, VTY_NEWLINE);
503}
504
505
Harald Welte67ce0732009-08-06 19:06:46 +0200506static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
507{
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100508 vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
Harald Weltea2bbc5e2015-11-20 10:43:31 +0100509 if (ts->tsc != -1)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100510 vty_out(vty, " training_sequence_code %u%s", ts->tsc, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200511 if (ts->pchan != GSM_PCHAN_NONE)
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100512 vty_out(vty, " phys_chan_config %s%s",
Harald Welte42581822009-08-08 16:12:58 +0200513 gsm_pchan_name(ts->pchan), VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100514 vty_out(vty, " hopping enabled %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200515 ts->hopping.enabled, VTY_NEWLINE);
516 if (ts->hopping.enabled) {
517 unsigned int i;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100518 vty_out(vty, " hopping sequence-number %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200519 ts->hopping.hsn, VTY_NEWLINE);
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100520 vty_out(vty, " hopping maio %u%s",
Harald Welte6e0cd042009-09-12 13:05:33 +0200521 ts->hopping.maio, VTY_NEWLINE);
Harald Weltea39b0f22010-06-14 22:26:10 +0200522 for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) {
523 if (!bitvec_get_bit_pos(&ts->hopping.arfcns, i))
524 continue;
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100525 vty_out(vty, " hopping arfcn add %u%s",
Harald Weltea39b0f22010-06-14 22:26:10 +0200526 i, VTY_NEWLINE);
527 }
Harald Welte127af342010-12-24 12:07:07 +0100528 }
Neels Hofmeyr9c4f1d62016-01-27 14:20:29 +0100529 config_write_e1_link(vty, &ts->e1_link, " ");
Harald Welteface7ed2011-02-14 16:15:21 +0100530
531 if (ts->trx->bts->model->config_write_ts)
532 ts->trx->bts->model->config_write_ts(vty, ts);
Harald Welte67ce0732009-08-06 19:06:46 +0200533}
534
535static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
536{
537 int i;
538
Harald Welte5013b2a2009-08-07 13:29:14 +0200539 vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200540 if (trx->description)
541 vty_out(vty, " description %s%s", trx->description,
542 VTY_NEWLINE);
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200543 vty_out(vty, " rf_locked %u%s",
Harald Welted64c0bc2011-05-30 12:07:53 +0200544 trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
Holger Hans Peter Freyther2ba40af2010-04-17 06:42:07 +0200545 VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200546 vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
Harald Welte (local)7b37d972009-12-27 20:56:38 +0100547 vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200548 vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200549 config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
550 vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
Harald Welte67ce0732009-08-06 19:06:46 +0200551
Harald Welteface7ed2011-02-14 16:15:21 +0100552 if (trx->bts->model->config_write_trx)
553 trx->bts->model->config_write_trx(vty, trx);
554
Harald Welte67ce0732009-08-06 19:06:46 +0200555 for (i = 0; i < TRX_NR_TS; i++)
556 config_write_ts_single(vty, &trx->ts[i]);
557}
558
Harald Welte615e9562010-05-11 23:50:21 +0200559static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
560{
561 unsigned int i;
562 vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
563 VTY_NEWLINE);
564 if (bts->gprs.mode == BTS_GPRS_NONE)
565 return;
566
bhargava350533c2016-07-21 11:14:34 +0530567 vty_out(vty, " gprs 11bit_rach_support_for_egprs %u%s",
568 bts->gprs.supports_egprs_11bit_rach, VTY_NEWLINE);
569
Harald Welte615e9562010-05-11 23:50:21 +0200570 vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
571 VTY_NEWLINE);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +0100572 vty_out(vty, " gprs network-control-order nc%u%s",
573 bts->gprs.net_ctrl_ord, VTY_NEWLINE);
Max292ec582016-07-28 11:55:37 +0200574 if (!bts->gprs.ctrl_ack_type_use_block)
575 vty_out(vty, " gprs control-ack-type-rach%s", VTY_NEWLINE);
Harald Welte615e9562010-05-11 23:50:21 +0200576 vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
577 VTY_NEWLINE);
578 for (i = 0; i < ARRAY_SIZE(bts->gprs.cell.timer); i++)
579 vty_out(vty, " gprs cell timer %s %u%s",
580 get_value_string(gprs_bssgp_cfg_strs, i),
581 bts->gprs.cell.timer[i], VTY_NEWLINE);
582 vty_out(vty, " gprs nsei %u%s", bts->gprs.nse.nsei,
583 VTY_NEWLINE);
584 for (i = 0; i < ARRAY_SIZE(bts->gprs.nse.timer); i++)
585 vty_out(vty, " gprs ns timer %s %u%s",
586 get_value_string(gprs_ns_timer_strs, i),
587 bts->gprs.nse.timer[i], VTY_NEWLINE);
588 for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
589 struct gsm_bts_gprs_nsvc *nsvc =
590 &bts->gprs.nsvc[i];
591 struct in_addr ia;
592
593 ia.s_addr = htonl(nsvc->remote_ip);
594 vty_out(vty, " gprs nsvc %u nsvci %u%s", i,
595 nsvc->nsvci, VTY_NEWLINE);
596 vty_out(vty, " gprs nsvc %u local udp port %u%s", i,
597 nsvc->local_port, VTY_NEWLINE);
598 vty_out(vty, " gprs nsvc %u remote udp port %u%s", i,
599 nsvc->remote_port, VTY_NEWLINE);
600 vty_out(vty, " gprs nsvc %u remote ip %s%s", i,
601 inet_ntoa(ia), VTY_NEWLINE);
602 }
603}
604
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200605/* Write the model data if there is one */
606static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts)
Harald Welte67ce0732009-08-06 19:06:46 +0200607{
608 struct gsm_bts_trx *trx;
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200609
610 if (!bts->model)
611 return;
612
613 if (bts->model->config_write_bts)
614 bts->model->config_write_bts(vty, bts);
615
616 llist_for_each_entry(trx, &bts->trx_list, list)
617 config_write_trx_single(vty, trx);
618}
619
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200620static void write_amr_modes(struct vty *vty, const char *prefix,
621 const char *name, struct amr_mode *modes, int num)
622{
623 int i;
624
625 vty_out(vty, " %s threshold %s", prefix, name);
626 for (i = 0; i < num - 1; i++)
627 vty_out(vty, " %d", modes[i].threshold);
628 vty_out(vty, "%s", VTY_NEWLINE);
629 vty_out(vty, " %s hysteresis %s", prefix, name);
630 for (i = 0; i < num - 1; i++)
631 vty_out(vty, " %d", modes[i].hysteresis);
632 vty_out(vty, "%s", VTY_NEWLINE);
633}
634
Andreas Eversberg73266522014-01-19 11:47:44 +0100635static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
636 struct amr_multirate_conf *mr, int full)
637{
638 struct gsm48_multi_rate_conf *mr_conf;
639 const char *prefix = (full) ? "amr tch-f" : "amr tch-h";
640 int i, num;
641
642 if (!(mr->gsm48_ie[1]))
643 return;
644
645 mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
646
647 num = 0;
648 vty_out(vty, " %s modes", prefix);
649 for (i = 0; i < ((full) ? 8 : 6); i++) {
650 if ((mr->gsm48_ie[1] & (1 << i))) {
651 vty_out(vty, " %d", i);
652 num++;
653 }
654 }
655 vty_out(vty, "%s", VTY_NEWLINE);
656 if (num > 4)
657 num = 4;
658 if (num > 1) {
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +0200659 write_amr_modes(vty, prefix, "ms", mr->ms_mode, num);
660 write_amr_modes(vty, prefix, "bts", mr->bts_mode, num);
Andreas Eversberg73266522014-01-19 11:47:44 +0100661 }
662 vty_out(vty, " %s start-mode ", prefix);
663 if (mr_conf->icmi) {
664 num = 0;
665 for (i = 0; i < ((full) ? 8 : 6) && num < 4; i++) {
666 if ((mr->gsm48_ie[1] & (1 << i)))
667 num++;
668 if (mr_conf->smod == num - 1) {
669 vty_out(vty, "%d%s", num, VTY_NEWLINE);
670 break;
671 }
672 }
673 } else
674 vty_out(vty, "auto%s", VTY_NEWLINE);
675}
676
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200677static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
678{
Harald Welte9fbff4a2010-07-30 11:50:09 +0200679 int i;
Max2c16bee2017-02-15 13:51:37 +0100680 uint8_t tmp;
Harald Welte67ce0732009-08-06 19:06:46 +0200681
Harald Welte5013b2a2009-08-07 13:29:14 +0200682 vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
683 vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200684 if (bts->description)
685 vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200686 vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
Holger Hans Peter Freytherf926ed62009-11-19 16:38:49 +0100687 vty_out(vty, " cell_identity %u%s", bts->cell_identity, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200688 vty_out(vty, " location_area_code %u%s", bts->location_area_code,
Harald Welte67ce0732009-08-06 19:06:46 +0200689 VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +0200690 if (bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
691 vty_out(vty, " dtx uplink%s%s",
692 (bts->dtxu != GSM48_DTX_SHALL_BE_USED) ? "" : " force",
693 VTY_NEWLINE);
694 if (bts->dtxd)
695 vty_out(vty, " dtx downlink%s", VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200696 vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
Harald Welte (local)0e451d02009-08-13 10:14:26 +0200697 vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +0100698 vty_out(vty, " cell reselection hysteresis %u%s",
699 bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
700 vty_out(vty, " rxlev access min %u%s",
701 bts->si_common.cell_sel_par.rxlev_acc_min, VTY_NEWLINE);
Sylvain Munaute0b06b02010-11-28 18:17:28 +0100702
703 if (bts->si_common.cell_ro_sel_par.present) {
704 struct gsm48_si_selection_params *sp;
705 sp = &bts->si_common.cell_ro_sel_par;
706
707 if (sp->cbq)
708 vty_out(vty, " cell bar qualify %u%s",
709 sp->cbq, VTY_NEWLINE);
710
711 if (sp->cell_resel_off)
712 vty_out(vty, " cell reselection offset %u%s",
713 sp->cell_resel_off*2, VTY_NEWLINE);
714
715 if (sp->temp_offs == 7)
716 vty_out(vty, " temporary offset infinite%s",
717 VTY_NEWLINE);
718 else if (sp->temp_offs)
719 vty_out(vty, " temporary offset %u%s",
720 sp->temp_offs*10, VTY_NEWLINE);
721
722 if (sp->penalty_time == 31)
723 vty_out(vty, " penalty time reserved%s",
724 VTY_NEWLINE);
725 else if (sp->penalty_time)
726 vty_out(vty, " penalty time %u%s",
727 (sp->penalty_time*20)+20, VTY_NEWLINE);
728 }
729
Harald Welte2f8b9d22017-06-18 11:12:13 +0300730 if (gsm_bts_get_radio_link_timeout(bts) < 0)
731 vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE);
732 else
733 vty_out(vty, " radio-link-timeout %d%s",
734 gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +0100735
Harald Welte7a8fa412009-08-10 13:48:16 +0200736 vty_out(vty, " channel allocator %s%s",
737 bts->chan_alloc_reverse ? "descending" : "ascending",
738 VTY_NEWLINE);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +0100739 vty_out(vty, " rach tx integer %u%s",
740 bts->si_common.rach_control.tx_integer, VTY_NEWLINE);
741 vty_out(vty, " rach max transmission %u%s",
742 rach_max_trans_raw2val(bts->si_common.rach_control.max_trans),
743 VTY_NEWLINE);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800744
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +0200745 vty_out(vty, " channel-descrption attach %u%s",
746 bts->si_common.chan_desc.att, VTY_NEWLINE);
747 vty_out(vty, " channel-descrption bs-pa-mfrms %u%s",
748 bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE);
749 vty_out(vty, " channel-descrption bs-ag-blks-res %u%s",
750 bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE);
751
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800752 if (bts->rach_b_thresh != -1)
753 vty_out(vty, " rach nm busy threshold %u%s",
754 bts->rach_b_thresh, VTY_NEWLINE);
755 if (bts->rach_ldavg_slots != -1)
756 vty_out(vty, " rach nm load average %u%s",
757 bts->rach_ldavg_slots, VTY_NEWLINE);
Harald Welte71355012009-12-21 23:08:18 +0100758 if (bts->si_common.rach_control.cell_bar)
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200759 vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +0800760 if ((bts->si_common.rach_control.t2 & 0x4) == 0)
761 vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
Ivan Kluchnikov67920592013-09-16 13:13:04 +0400762 if ((bts->si_common.rach_control.t3) != 0)
763 for (i = 0; i < 8; i++)
764 if (bts->si_common.rach_control.t3 & (0x1 << i))
765 vty_out(vty, " rach access-control-class %d barred%s", i, VTY_NEWLINE);
766 if ((bts->si_common.rach_control.t2 & 0xfb) != 0)
767 for (i = 0; i < 8; i++)
768 if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
769 vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
Harald Welte9fbff4a2010-07-30 11:50:09 +0200770 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
771 if (bts->si_mode_static & (1 << i)) {
772 vty_out(vty, " system-information %s mode static%s",
773 get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
774 vty_out(vty, " system-information %s static %s%s",
775 get_value_string(osmo_sitype_strs, i),
Max6f0e50c2017-04-12 15:30:54 +0200776 osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN),
Harald Welte9fbff4a2010-07-30 11:50:09 +0200777 VTY_NEWLINE);
778 }
779 }
Harald Welte42def722017-01-13 00:10:32 +0100780 vty_out(vty, " early-classmark-sending %s%s",
781 bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100782 vty_out(vty, " early-classmark-sending-3g %s%s",
783 bts->early_classmark_allowed_3g ? "allowed" : "forbidden", VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100784 switch (bts->type) {
785 case GSM_BTS_TYPE_NANOBTS:
Maxf9685c12017-03-23 12:01:07 +0100786 case GSM_BTS_TYPE_OSMOBTS:
Harald Welte5013b2a2009-08-07 13:29:14 +0200787 vty_out(vty, " ip.access unit_id %u %u%s",
Harald Weltea6fd58e2009-08-07 00:25:23 +0200788 bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
Harald Welte8b291802013-03-12 13:57:05 +0100789 if (bts->ip_access.rsl_ip) {
790 struct in_addr ia;
791 ia.s_addr = htonl(bts->ip_access.rsl_ip);
792 vty_out(vty, " ip.access rsl-ip %s%s", inet_ntoa(ia),
793 VTY_NEWLINE);
794 }
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +0200795 vty_out(vty, " oml ip.access stream_id %u line %u%s",
796 bts->oml_tei, bts->oml_e1_link.e1_nr, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100797 break;
Sylvain Munautc9519462011-10-17 14:04:55 +0200798 case GSM_BTS_TYPE_NOKIA_SITE:
799 vty_out(vty, " nokia_site skip-reset %d%s", bts->nokia.skip_reset, VTY_NEWLINE);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +0100800 vty_out(vty, " nokia_site no-local-rel-conf %d%s",
801 bts->nokia.no_loc_rel_cnf, VTY_NEWLINE);
Sipos Csaba56e17662015-02-07 13:27:36 +0100802 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 +0100803 /* fall through: Nokia requires "oml e1" parameters also */
Harald Weltefd355a32011-03-04 13:41:31 +0100804 default:
Harald Welte42581822009-08-08 16:12:58 +0200805 config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
806 vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
Harald Weltefd355a32011-03-04 13:41:31 +0100807 break;
Harald Welte42581822009-08-08 16:12:58 +0200808 }
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +0800809
810 /* if we have a limit, write it */
811 if (bts->paging.free_chans_need >= 0)
812 vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
813
Harald Welte32c09622011-01-11 23:44:56 +0100814 vty_out(vty, " neighbor-list mode %s%s",
Harald Welte64c07d22011-02-15 11:43:27 +0100815 get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
816 if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
Harald Welte32c09622011-01-11 23:44:56 +0100817 for (i = 0; i < 1024; i++) {
818 if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
819 vty_out(vty, " neighbor-list add arfcn %u%s",
820 i, VTY_NEWLINE);
821 }
822 }
Harald Welte64c07d22011-02-15 11:43:27 +0100823 if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
824 for (i = 0; i < 1024; i++) {
825 if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
826 vty_out(vty, " si5 neighbor-list add arfcn %u%s",
827 i, VTY_NEWLINE);
828 }
829 }
Harald Welte32c09622011-01-11 23:44:56 +0100830
Max59a1bf32016-04-15 16:04:46 +0200831 for (i = 0; i < MAX_EARFCN_LIST; i++) {
Max2c16bee2017-02-15 13:51:37 +0100832 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
833 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
834 vty_out(vty, " si2quater neighbor-list add earfcn %u "
835 "thresh-hi %u", e->arfcn[i], e->thresh_hi);
836
837 vty_out(vty, " thresh-lo %u",
838 e->thresh_lo_valid ? e->thresh_lo : 32);
839
840 vty_out(vty, " prio %u",
841 e->prio_valid ? e->prio : 8);
842
843 vty_out(vty, " qrxlv %u",
844 e->qrxlm_valid ? e->qrxlm : 32);
845
846 tmp = e->meas_bw[i];
847 vty_out(vty, " meas %u",
848 (tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
Max59a1bf32016-04-15 16:04:46 +0200849
850 vty_out(vty, "%s", VTY_NEWLINE);
851 }
852 }
853
Max26679e02016-04-20 15:57:13 +0200854 for (i = 0; i < bts->si_common.uarfcn_length; i++) {
855 vty_out(vty, " si2quater neighbor-list add uarfcn %u %u %u%s",
856 bts->si_common.data.uarfcn_list[i],
857 bts->si_common.data.scramble_list[i] & ~(1 << 9),
858 (bts->si_common.data.scramble_list[i] >> 9) & 1,
859 VTY_NEWLINE);
860 }
861
Andreas Eversberga83d5112013-12-07 18:32:28 +0100862 vty_out(vty, " codec-support fr");
863 if (bts->codec.hr)
864 vty_out(vty, " hr");
865 if (bts->codec.efr)
866 vty_out(vty, " efr");
867 if (bts->codec.amr)
868 vty_out(vty, " amr");
869 vty_out(vty, "%s", VTY_NEWLINE);
870
Andreas Eversberg73266522014-01-19 11:47:44 +0100871 config_write_bts_amr(vty, bts, &bts->mr_full, 1);
872 config_write_bts_amr(vty, bts, &bts->mr_half, 0);
873
Harald Welte615e9562010-05-11 23:50:21 +0200874 config_write_bts_gprs(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200875
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +0200876 if (bts->excl_from_rf_lock)
877 vty_out(vty, " rf-lock-exclude%s", VTY_NEWLINE);
878
Jacob Erlbeck65d114f2014-01-16 11:02:14 +0100879 vty_out(vty, " %sforce-combined-si%s",
880 bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
881
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100882 for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
883 int j;
884
885 if (bts->depends_on[i] == 0)
886 continue;
887
888 for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
889 int bts_nr;
890
891 if ((bts->depends_on[i] & (1<<j)) == 0)
892 continue;
893
894 bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
895 vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
896 }
897 }
Harald Welte8254cf72017-05-29 13:42:19 +0200898 if (bts->pcu_sock_path)
899 vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +0100900
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100901 ho_vty_write_bts(vty, bts);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100902
Holger Hans Peter Freythercd40fb42013-09-15 17:23:34 +0200903 config_write_bts_model(vty, bts);
Harald Welte67ce0732009-08-06 19:06:46 +0200904}
905
906static int config_write_bts(struct vty *v)
907{
Harald Weltedcccb182010-05-16 20:52:23 +0200908 struct gsm_network *gsmnet = gsmnet_from_vty(v);
Harald Welte67ce0732009-08-06 19:06:46 +0200909 struct gsm_bts *bts;
910
911 llist_for_each_entry(bts, &gsmnet->bts_list, list)
912 config_write_bts_single(v, bts);
913
914 return CMD_SUCCESS;
915}
916
Harald Weltea0d324b2017-07-20 01:47:39 +0200917/* small helper macro for conditional dumping of timer */
918#define VTY_OUT_TIMER(number) \
919 if (gsmnet->T##number != GSM_T##number##_DEFAULT) \
920 vty_out(vty, " timer t"#number" %u%s", gsmnet->T##number, VTY_NEWLINE)
921
Harald Welte5013b2a2009-08-07 13:29:14 +0200922static int config_write_net(struct vty *vty)
923{
Harald Weltedcccb182010-05-16 20:52:23 +0200924 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte51e4bf32017-12-23 17:30:18 +0100925 int i;
Harald Weltedcccb182010-05-16 20:52:23 +0200926
Harald Welte5013b2a2009-08-07 13:29:14 +0200927 vty_out(vty, "network%s", VTY_NEWLINE);
Harald Welte42581822009-08-08 16:12:58 +0200928 vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200929 vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
Harald Welte51e4bf32017-12-23 17:30:18 +0100930 vty_out(vty, " encryption a5");
931 for (i = 0; i < 8; i++) {
932 if (gsmnet->a5_encryption_mask & (1 << i))
933 vty_out(vty, " %u", i);
934 }
935 vty_out(vty, "%s", VTY_NEWLINE);
Holger Hans Peter Freytherd54c3372009-11-19 16:37:48 +0100936 vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +0800937 vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100938
Neels Hofmeyrdfd36da2018-02-12 16:48:45 +0100939 ho_vty_write_net(vty, gsmnet);
Neels Hofmeyre25018b2017-11-27 21:29:33 +0100940
Harald Weltea0d324b2017-07-20 01:47:39 +0200941 VTY_OUT_TIMER(3101);
942 VTY_OUT_TIMER(3103);
943 VTY_OUT_TIMER(3105);
944 VTY_OUT_TIMER(3107);
945 VTY_OUT_TIMER(3109);
946 VTY_OUT_TIMER(3111);
947 VTY_OUT_TIMER(3113);
948 VTY_OUT_TIMER(3115);
949 VTY_OUT_TIMER(3117);
950 VTY_OUT_TIMER(3119);
951 VTY_OUT_TIMER(3122);
952 VTY_OUT_TIMER(3141);
Vadim Yanitskiy7f3724e2017-03-31 23:27:44 +0700953 vty_out(vty, " dyn_ts_allow_tch_f %d%s",
954 gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr73983952016-05-10 13:29:33 +0200955 if (gsmnet->tz.override != 0) {
956 if (gsmnet->tz.dst)
957 vty_out(vty, " timezone %d %d %d%s",
958 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
959 VTY_NEWLINE);
960 else
961 vty_out(vty, " timezone %d %d%s",
962 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
963 }
Neels Hofmeyrce4d88b2017-05-08 15:12:20 +0200964 if (gsmnet->t3212 == 0)
965 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
966 else
967 vty_out(vty, " periodic location update %u%s",
968 gsmnet->t3212 * 6, VTY_NEWLINE);
Harald Welte5013b2a2009-08-07 13:29:14 +0200969
970 return CMD_SUCCESS;
971}
Harald Welte67ce0732009-08-06 19:06:46 +0200972
Harald Welte68628e82009-03-10 12:17:57 +0000973static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
974{
975 vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
976 trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
Harald Welte197dea92010-05-14 17:59:53 +0200977 vty_out(vty, "Description: %s%s",
978 trx->description ? trx->description : "(null)", VTY_NEWLINE);
Harald Weltefcd24452009-06-20 18:15:19 +0200979 vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
Harald Welte42581822009-08-08 16:12:58 +0200980 "resulting BS power: %d dBm%s",
Harald Weltefcd24452009-06-20 18:15:19 +0200981 trx->nominal_power, trx->max_power_red,
Harald Welte42581822009-08-08 16:12:58 +0200982 trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000983 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200984 net_dump_nmstate(vty, &trx->mo.nm_state);
Max94059b02018-01-07 16:47:49 +0100985 vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +0000986 vty_out(vty, " Baseband Transceiver NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +0200987 net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
Harald Welte8175e952009-10-20 00:22:00 +0200988 if (is_ipaccess_bts(trx->bts)) {
989 vty_out(vty, " ip.access stream ID: 0x%02x%s",
990 trx->rsl_tei, VTY_NEWLINE);
991 } else {
992 vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
993 e1isl_dump_vty(vty, trx->rsl_link);
994 }
Harald Welte68628e82009-03-10 12:17:57 +0000995}
996
Max6e4f1842018-01-07 16:45:42 +0100997static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
998{
999 uint8_t trx_nr;
1000 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++)
1001 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
1002}
1003
Harald Welte68628e82009-03-10 12:17:57 +00001004DEFUN(show_trx,
1005 show_trx_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001006 "show trx [<0-255>] [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001007 SHOW_STR "Display information about a TRX\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001008 BTS_TRX_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001009{
Harald Weltedcccb182010-05-16 20:52:23 +02001010 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001011 struct gsm_bts *bts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001012 int bts_nr, trx_nr;
1013
1014 if (argc >= 1) {
1015 /* use the BTS number that the user has specified */
1016 bts_nr = atoi(argv[0]);
1017 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001018 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001019 VTY_NEWLINE);
1020 return CMD_WARNING;
1021 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001022 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001023 }
1024 if (argc >= 2) {
1025 trx_nr = atoi(argv[1]);
1026 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001027 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001028 VTY_NEWLINE);
1029 return CMD_WARNING;
1030 }
Max6e4f1842018-01-07 16:45:42 +01001031 trx_dump_vty(vty, gsm_bts_trx_num(bts, trx_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001032 return CMD_SUCCESS;
1033 }
1034 if (bts) {
1035 /* print all TRX in this BTS */
Max6e4f1842018-01-07 16:45:42 +01001036 print_all_trx(vty, bts);
Harald Welte68628e82009-03-10 12:17:57 +00001037 return CMD_SUCCESS;
1038 }
1039
Max6e4f1842018-01-07 16:45:42 +01001040 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++)
1041 print_all_trx(vty, gsm_bts_num(net, bts_nr));
Harald Welte68628e82009-03-10 12:17:57 +00001042
1043 return CMD_SUCCESS;
1044}
1045
Harald Welte67ce0732009-08-06 19:06:46 +02001046
Harald Welte68628e82009-03-10 12:17:57 +00001047static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
1048{
Harald Welte135a6482011-05-30 12:09:13 +02001049 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, phys cfg %s, TSC %u",
Harald Welte026b4ca2010-12-24 12:12:10 +01001050 ts->trx->bts->nr, ts->trx->nr, ts->nr,
Harald Welte1fe24122014-01-19 17:18:21 +01001051 gsm_pchan_name(ts->pchan), gsm_ts_tsc(ts));
Harald Weltecd103a92010-12-24 12:14:52 +01001052 if (ts->pchan == GSM_PCHAN_TCH_F_PDCH)
Harald Welteb29cea12010-12-24 12:26:13 +01001053 vty_out(vty, " (%s mode)",
Neels Hofmeyr2ebacce2016-06-14 14:08:35 +02001054 ts->flags & TS_F_PDCH_ACTIVE ? "PDCH" : "TCH/F");
Harald Weltecd103a92010-12-24 12:14:52 +01001055 vty_out(vty, "%s", VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001056 vty_out(vty, " NM State: ");
Harald Welted64c0bc2011-05-30 12:07:53 +02001057 net_dump_nmstate(vty, &ts->mo.nm_state);
Harald Welte2c828992009-12-02 01:56:49 +05301058 if (!is_ipaccess_bts(ts->trx->bts))
Harald Welteef235b52009-03-10 12:34:02 +00001059 vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
1060 ts->e1_link.e1_nr, ts->e1_link.e1_ts,
1061 ts->e1_link.e1_ts_ss, VTY_NEWLINE);
Harald Welte68628e82009-03-10 12:17:57 +00001062}
1063
1064DEFUN(show_ts,
1065 show_ts_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001066 "show timeslot [<0-255>] [<0-255>] [<0-7>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001067 SHOW_STR "Display information about a TS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001068 BTS_TRX_TS_STR)
Harald Welte68628e82009-03-10 12:17:57 +00001069{
Harald Weltedcccb182010-05-16 20:52:23 +02001070 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte274d0152010-12-24 12:05:03 +01001071 struct gsm_bts *bts = NULL;
1072 struct gsm_bts_trx *trx = NULL;
1073 struct gsm_bts_trx_ts *ts = NULL;
Harald Welte68628e82009-03-10 12:17:57 +00001074 int bts_nr, trx_nr, ts_nr;
1075
1076 if (argc >= 1) {
1077 /* use the BTS number that the user has specified */
1078 bts_nr = atoi(argv[0]);
1079 if (bts_nr >= net->num_bts) {
Harald Welte1bc77352009-03-10 19:47:51 +00001080 vty_out(vty, "%% can't find BTS '%s'%s", argv[0],
Harald Welte68628e82009-03-10 12:17:57 +00001081 VTY_NEWLINE);
1082 return CMD_WARNING;
1083 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001084 bts = gsm_bts_num(net, bts_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001085 }
1086 if (argc >= 2) {
1087 trx_nr = atoi(argv[1]);
1088 if (trx_nr >= bts->num_trx) {
Harald Welte1bc77352009-03-10 19:47:51 +00001089 vty_out(vty, "%% can't find TRX '%s'%s", argv[1],
Harald Welte68628e82009-03-10 12:17:57 +00001090 VTY_NEWLINE);
1091 return CMD_WARNING;
1092 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001093 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001094 }
1095 if (argc >= 3) {
1096 ts_nr = atoi(argv[2]);
1097 if (ts_nr >= TRX_NR_TS) {
Harald Welte1bc77352009-03-10 19:47:51 +00001098 vty_out(vty, "%% can't find TS '%s'%s", argv[2],
Harald Welte68628e82009-03-10 12:17:57 +00001099 VTY_NEWLINE);
1100 return CMD_WARNING;
1101 }
Harald Welte274d0152010-12-24 12:05:03 +01001102 /* Fully Specified: print and exit */
Harald Welte68628e82009-03-10 12:17:57 +00001103 ts = &trx->ts[ts_nr];
1104 ts_dump_vty(vty, ts);
1105 return CMD_SUCCESS;
1106 }
Harald Welte274d0152010-12-24 12:05:03 +01001107
1108 if (bts && trx) {
1109 /* Iterate over all TS in this TRX */
1110 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1111 ts = &trx->ts[ts_nr];
1112 ts_dump_vty(vty, ts);
1113 }
1114 } else if (bts) {
1115 /* Iterate over all TRX in this BTS, TS in each TRX */
Harald Welte68628e82009-03-10 12:17:57 +00001116 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001117 trx = gsm_bts_trx_num(bts, trx_nr);
Harald Welte68628e82009-03-10 12:17:57 +00001118 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1119 ts = &trx->ts[ts_nr];
1120 ts_dump_vty(vty, ts);
1121 }
1122 }
Harald Welte274d0152010-12-24 12:05:03 +01001123 } else {
1124 /* Iterate over all BTS, TRX in each BTS, TS in each TRX */
1125 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
1126 bts = gsm_bts_num(net, bts_nr);
1127 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1128 trx = gsm_bts_trx_num(bts, trx_nr);
1129 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1130 ts = &trx->ts[ts_nr];
1131 ts_dump_vty(vty, ts);
1132 }
1133 }
1134 }
Harald Welte68628e82009-03-10 12:17:57 +00001135 }
1136
1137 return CMD_SUCCESS;
1138}
1139
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001140static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
1141{
1142 if (strlen(bsub->imsi))
1143 vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
1144 if (bsub->tmsi != GSM_RESERVED_TMSI)
1145 vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
1146 VTY_NEWLINE);
1147 vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
1148}
1149
Harald Welte8387a492009-12-22 21:43:14 +01001150static void meas_rep_dump_uni_vty(struct vty *vty,
1151 struct gsm_meas_rep_unidir *mru,
1152 const char *prefix,
1153 const char *dir)
1154{
1155 vty_out(vty, "%s RXL-FULL-%s: %4d dBm, RXL-SUB-%s: %4d dBm ",
1156 prefix, dir, rxlev2dbm(mru->full.rx_lev),
1157 dir, rxlev2dbm(mru->sub.rx_lev));
1158 vty_out(vty, "RXQ-FULL-%s: %d, RXQ-SUB-%s: %d%s",
1159 dir, mru->full.rx_qual, dir, mru->sub.rx_qual,
1160 VTY_NEWLINE);
1161}
1162
1163static void meas_rep_dump_vty(struct vty *vty, struct gsm_meas_rep *mr,
1164 const char *prefix)
1165{
1166 vty_out(vty, "%sMeasurement Report:%s", prefix, VTY_NEWLINE);
1167 vty_out(vty, "%s Flags: %s%s%s%s%s", prefix,
1168 mr->flags & MEAS_REP_F_UL_DTX ? "DTXu " : "",
1169 mr->flags & MEAS_REP_F_DL_DTX ? "DTXd " : "",
1170 mr->flags & MEAS_REP_F_FPC ? "FPC " : "",
1171 mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ",
1172 VTY_NEWLINE);
1173 if (mr->flags & MEAS_REP_F_MS_TO)
Max11e4e412017-04-20 13:07:58 +02001174 vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE);
Harald Welte8387a492009-12-22 21:43:14 +01001175 if (mr->flags & MEAS_REP_F_MS_L1)
1176 vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s",
1177 prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE);
1178 if (mr->flags & MEAS_REP_F_DL_VALID)
1179 meas_rep_dump_uni_vty(vty, &mr->dl, prefix, "dl");
1180 meas_rep_dump_uni_vty(vty, &mr->ul, prefix, "ul");
1181}
1182
Harald Welte0a8cf322015-12-05 17:22:49 +01001183/* FIXME: move this to libosmogsm */
1184static const struct value_string gsm48_cmode_names[] = {
1185 { GSM48_CMODE_SIGN, "signalling" },
1186 { GSM48_CMODE_SPEECH_V1, "FR or HR" },
1187 { GSM48_CMODE_SPEECH_EFR, "EFR" },
1188 { GSM48_CMODE_SPEECH_AMR, "AMR" },
1189 { GSM48_CMODE_DATA_14k5, "CSD(14k5)" },
1190 { GSM48_CMODE_DATA_12k0, "CSD(12k0)" },
1191 { GSM48_CMODE_DATA_6k0, "CSD(6k0)" },
1192 { GSM48_CMODE_DATA_3k6, "CSD(3k6)" },
1193 { 0, NULL }
1194};
1195
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001196/* call vty_out() to print a string like " as TCH/H" for dynamic timeslots.
1197 * Don't do anything if the ts is not dynamic. */
1198static void vty_out_dyn_ts_status(struct vty *vty, struct gsm_bts_trx_ts *ts)
1199{
1200 switch (ts->pchan) {
1201 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1202 if (ts->dyn.pchan_is == ts->dyn.pchan_want)
1203 vty_out(vty, " as %s",
1204 gsm_pchan_name(ts->dyn.pchan_is));
1205 else
1206 vty_out(vty, " switching %s -> %s",
1207 gsm_pchan_name(ts->dyn.pchan_is),
1208 gsm_pchan_name(ts->dyn.pchan_want));
1209 break;
1210 case GSM_PCHAN_TCH_F_PDCH:
1211 if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
1212 vty_out(vty, " as %s",
1213 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1214 : "TCH/F");
1215 else
1216 vty_out(vty, " switching %s -> %s",
1217 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
1218 : "TCH/F",
1219 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
1220 : "TCH/F");
1221 break;
1222 default:
1223 /* no dyn ts */
1224 break;
1225 }
1226}
1227
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001228static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
Harald Welte68628e82009-03-10 12:17:57 +00001229{
Harald Welte8387a492009-12-22 21:43:14 +01001230 int idx;
1231
Harald Welte85bded82010-12-24 12:22:34 +01001232 vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
1233 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
1234 lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001235 /* show dyn TS details, if applicable */
1236 switch (lchan->ts->pchan) {
1237 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
1238 vty_out(vty, " Osmocom Dyn TS:");
1239 vty_out_dyn_ts_status(vty, lchan->ts);
1240 vty_out(vty, VTY_NEWLINE);
1241 break;
1242 case GSM_PCHAN_TCH_F_PDCH:
1243 vty_out(vty, " IPACC Dyn PDCH TS:");
1244 vty_out_dyn_ts_status(vty, lchan->ts);
1245 vty_out(vty, VTY_NEWLINE);
1246 break;
1247 default:
1248 /* no dyn ts */
1249 break;
1250 }
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001251 vty_out(vty, " Connection: %u, State: %s%s%s%s",
Holger Hans Peter Freyther40494552010-06-28 17:09:29 +08001252 lchan->conn ? 1: 0,
Holger Hans Peter Freyther454140e2014-12-28 12:08:28 +01001253 gsm_lchans_name(lchan->state),
1254 lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
1255 lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
1256 VTY_NEWLINE);
Harald Welte73225282009-12-12 18:17:25 +01001257 vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
1258 lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
1259 - lchan->bs_power*2,
1260 ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
1261 VTY_NEWLINE);
Harald Welte0a8cf322015-12-05 17:22:49 +01001262 vty_out(vty, " Channel Mode / Codec: %s%s",
1263 get_value_string(gsm48_cmode_names, lchan->tch_mode),
1264 VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001265 if (lchan->conn && lchan->conn->bsub) {
Harald Welte68628e82009-03-10 12:17:57 +00001266 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
Neels Hofmeyr7b656882017-07-09 22:09:18 +02001267 bsc_subscr_dump_vty(vty, lchan->conn->bsub);
Harald Welte68628e82009-03-10 12:17:57 +00001268 } else
1269 vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
Harald Welte2c828992009-12-02 01:56:49 +05301270 if (is_ipaccess_bts(lchan->ts->trx->bts)) {
1271 struct in_addr ia;
Harald Welte5f45a4a2018-02-05 21:33:34 +01001272 if (lchan->abis_ip.bound_ip) {
1273 ia.s_addr = htonl(lchan->abis_ip.bound_ip);
1274 vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
1275 inet_ntoa(ia), lchan->abis_ip.bound_port,
1276 lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
1277 VTY_NEWLINE);
1278 }
1279 if (lchan->abis_ip.connect_ip) {
1280 ia.s_addr = htonl(lchan->abis_ip.connect_ip);
1281 vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02x%s",
1282 inet_ntoa(ia), lchan->abis_ip.connect_port,
1283 lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode,
1284 VTY_NEWLINE);
1285 }
1286
Harald Welte2c828992009-12-02 01:56:49 +05301287 }
Harald Welte8387a492009-12-22 21:43:14 +01001288
1289 /* we want to report the last measurement report */
1290 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1291 lchan->meas_rep_idx, 1);
1292 meas_rep_dump_vty(vty, &lchan->meas_rep[idx], " ");
Harald Welte68628e82009-03-10 12:17:57 +00001293}
1294
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001295static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
1296{
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001297 struct gsm_meas_rep *mr;
1298 int idx;
1299
1300 /* we want to report the last measurement report */
1301 idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
1302 lchan->meas_rep_idx, 1);
1303 mr = &lchan->meas_rep[idx];
1304
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001305 vty_out(vty, "BTS %u, TRX %u, Timeslot %u %s",
Harald Welte85bded82010-12-24 12:22:34 +01001306 lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
Neels Hofmeyrb7480122016-11-02 14:28:15 +01001307 gsm_pchan_name(lchan->ts->pchan));
1308 vty_out_dyn_ts_status(vty, lchan->ts);
1309 vty_out(vty, ", Lchan %u, Type %s, State %s - "
1310 "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
Neels Hofmeyrefedf802016-06-14 01:31:38 +02001311 lchan->nr,
1312 gsm_lchant_name(lchan->type), gsm_lchans_name(lchan->state),
1313 mr->ms_l1.pwr,
Holger Hans Peter Freythercf5cc5b2010-05-14 01:57:02 +08001314 rxlev2dbm(mr->dl.full.rx_lev),
1315 rxlev2dbm(mr->ul.full.rx_lev),
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001316 VTY_NEWLINE);
1317}
1318
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001319
1320static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
1321 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1322{
1323 int lchan_nr;
1324 for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; lchan_nr++) {
1325 struct gsm_lchan *lchan = &ts->lchan[lchan_nr];
1326 if ((lchan->type == GSM_LCHAN_NONE) && (lchan->state == LCHAN_S_NONE))
1327 continue;
1328 dump_cb(vty, lchan);
1329 }
1330
1331 return CMD_SUCCESS;
1332}
1333
1334static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,
1335 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1336{
1337 int ts_nr;
1338
1339 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
1340 struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
1341 dump_lchan_trx_ts(ts, vty, dump_cb);
1342 }
1343
1344 return CMD_SUCCESS;
1345}
1346
1347static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,
1348 void (*dump_cb)(struct vty *, struct gsm_lchan *))
1349{
1350 int trx_nr;
1351
1352 for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {
1353 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);
1354 dump_lchan_trx(trx, vty, dump_cb);
1355 }
1356
1357 return CMD_SUCCESS;
1358}
1359
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001360static int lchan_summary(struct vty *vty, int argc, const char **argv,
1361 void (*dump_cb)(struct vty *, struct gsm_lchan *))
Harald Welte68628e82009-03-10 12:17:57 +00001362{
Harald Weltedcccb182010-05-16 20:52:23 +02001363 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Welte68628e82009-03-10 12:17:57 +00001364 struct gsm_bts *bts;
1365 struct gsm_bts_trx *trx;
1366 struct gsm_bts_trx_ts *ts;
1367 struct gsm_lchan *lchan;
1368 int bts_nr, trx_nr, ts_nr, lchan_nr;
1369
1370 if (argc >= 1) {
1371 /* use the BTS number that the user has specified */
1372 bts_nr = atoi(argv[0]);
1373 if (bts_nr >= net->num_bts) {
1374 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1375 VTY_NEWLINE);
1376 return CMD_WARNING;
1377 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001378 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001379
1380 if (argc == 1)
1381 return dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001382 }
1383 if (argc >= 2) {
1384 trx_nr = atoi(argv[1]);
1385 if (trx_nr >= bts->num_trx) {
1386 vty_out(vty, "%% can't find TRX %s%s", argv[1],
1387 VTY_NEWLINE);
1388 return CMD_WARNING;
1389 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001390 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001391
1392 if (argc == 2)
1393 return dump_lchan_trx(trx, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001394 }
1395 if (argc >= 3) {
1396 ts_nr = atoi(argv[2]);
1397 if (ts_nr >= TRX_NR_TS) {
1398 vty_out(vty, "%% can't find TS %s%s", argv[2],
1399 VTY_NEWLINE);
1400 return CMD_WARNING;
1401 }
1402 ts = &trx->ts[ts_nr];
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001403
1404 if (argc == 3)
1405 return dump_lchan_trx_ts(ts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001406 }
1407 if (argc >= 4) {
1408 lchan_nr = atoi(argv[3]);
1409 if (lchan_nr >= TS_MAX_LCHAN) {
1410 vty_out(vty, "%% can't find LCHAN %s%s", argv[3],
1411 VTY_NEWLINE);
1412 return CMD_WARNING;
1413 }
1414 lchan = &ts->lchan[lchan_nr];
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001415 dump_cb(vty, lchan);
Harald Welte68628e82009-03-10 12:17:57 +00001416 return CMD_SUCCESS;
1417 }
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001418
1419
Harald Welte68628e82009-03-10 12:17:57 +00001420 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001421 bts = gsm_bts_num(net, bts_nr);
Holger Hans Peter Freyther7173f632011-12-27 16:34:12 +01001422 dump_lchan_bts(bts, vty, dump_cb);
Harald Welte68628e82009-03-10 12:17:57 +00001423 }
1424
1425 return CMD_SUCCESS;
1426}
1427
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001428
1429DEFUN(show_lchan,
1430 show_lchan_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001431 "show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001432 SHOW_STR "Display information about a logical channel\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001433 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther029235e2010-05-14 02:03:16 +08001434{
1435 return lchan_summary(vty, argc, argv, lchan_dump_full_vty);
1436}
1437
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001438DEFUN(show_lchan_summary,
1439 show_lchan_summary_cmd,
Neels Hofmeyre5b5a892018-01-19 15:41:24 +01001440 "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001441 SHOW_STR "Display information about a logical channel\n"
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001442 "Short summary\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001443 BTS_TRX_TS_LCHAN_STR)
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08001444{
1445 return lchan_summary(vty, argc, argv, lchan_dump_short_vty);
1446}
1447
Philipp Maier39f62bb2017-04-09 12:32:51 +02001448DEFUN(show_subscr_conn,
1449 show_subscr_conn_cmd,
1450 "show conns",
1451 SHOW_STR "Display currently active subscriber connections\n")
1452{
1453 struct gsm_subscriber_connection *conn;
1454 struct gsm_network *net = gsmnet_from_vty(vty);
1455 bool no_conns = true;
1456 unsigned int count = 0;
1457
1458 vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
1459
1460 llist_for_each_entry(conn, &net->subscr_conns, entry) {
1461 vty_out(vty, "conn nr #%u:%s", count, VTY_NEWLINE);
1462 lchan_dump_full_vty(vty, conn->lchan);
1463 no_conns = false;
1464 count++;
1465 }
1466
1467 if (no_conns)
1468 vty_out(vty, "None%s", VTY_NEWLINE);
1469
1470 return CMD_SUCCESS;
1471}
1472
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001473static int trigger_ho_or_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_bts *to_bts)
1474{
1475 int rc;
1476
1477 if (!to_bts || from_lchan->ts->trx->bts == to_bts) {
1478 LOGP(DHO, LOGL_NOTICE, "%s Manually triggering Assignment from VTY\n",
1479 gsm_lchan_name(from_lchan));
1480 to_bts = from_lchan->ts->trx->bts;
1481 } else
1482 LOGP(DHO, LOGL_NOTICE, "%s (ARFCN %u) --> BTS %u Manually triggering Handover from VTY\n",
1483 gsm_lchan_name(from_lchan), from_lchan->ts->trx->arfcn, to_bts->nr);
Neels Hofmeyr6dff51d2018-02-12 16:56:41 +01001484 rc = bsc_handover_start(from_lchan, to_bts, from_lchan->type);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001485 if (rc) {
1486 vty_out(vty, "bsc_handover_start() returned %d=%s%s", rc,
1487 strerror(-rc), VTY_NEWLINE);
1488 return CMD_WARNING;
1489 }
1490 return CMD_SUCCESS;
1491}
1492
1493static int ho_or_as(struct vty *vty, const char *argv[], int argc)
Philipp Maier39f62bb2017-04-09 12:32:51 +02001494{
1495 struct gsm_network *net = gsmnet_from_vty(vty);
1496 struct gsm_subscriber_connection *conn;
1497 struct gsm_bts *bts;
1498 struct gsm_bts *new_bts = NULL;
1499 unsigned int bts_nr = atoi(argv[0]);
1500 unsigned int trx_nr = atoi(argv[1]);
1501 unsigned int ts_nr = atoi(argv[2]);
1502 unsigned int ss_nr = atoi(argv[3]);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001503 unsigned int bts_nr_new;
1504 const char *action;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001505
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001506 if (argc > 4) {
1507 bts_nr_new = atoi(argv[4]);
1508
1509 /* Lookup the BTS where we want to handover to */
1510 llist_for_each_entry(bts, &net->bts_list, list) {
1511 if (bts->nr == bts_nr_new) {
1512 new_bts = bts;
1513 break;
1514 }
1515 }
1516
1517 if (!new_bts) {
1518 vty_out(vty, "Unable to trigger handover, specified bts #%u does not exist %s",
1519 bts_nr_new, VTY_NEWLINE);
1520 return CMD_WARNING;
Philipp Maier39f62bb2017-04-09 12:32:51 +02001521 }
1522 }
1523
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001524 action = new_bts ? "handover" : "assignment";
Philipp Maier39f62bb2017-04-09 12:32:51 +02001525
1526 /* Find the connection/lchan that we want to handover */
1527 llist_for_each_entry(conn, &net->subscr_conns, entry) {
Harald Welte148ee362017-12-18 18:44:25 +01001528 if (conn_get_bts(conn)->nr == bts_nr &&
Philipp Maier39f62bb2017-04-09 12:32:51 +02001529 conn->lchan->ts->trx->nr == trx_nr &&
1530 conn->lchan->ts->nr == ts_nr && conn->lchan->nr == ss_nr) {
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001531 vty_out(vty, "starting %s for lchan %s...%s", action, conn->lchan->name, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001532 lchan_dump_full_vty(vty, conn->lchan);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001533 return trigger_ho_or_as(vty, conn->lchan, new_bts);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001534 }
1535 }
1536
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001537 vty_out(vty, "Unable to trigger %s, specified connection (bts=%u,trx=%u,ts=%u,ss=%u) does not exist%s",
1538 action, bts_nr, trx_nr, ts_nr, ss_nr, VTY_NEWLINE);
Philipp Maier39f62bb2017-04-09 12:32:51 +02001539
1540 return CMD_WARNING;
1541}
1542
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01001543#define MANUAL_HANDOVER_STR "Manually trigger handover (for debugging)\n"
1544#define MANUAL_ASSIGNMENT_STR "Manually trigger assignment (for debugging)\n"
1545
1546DEFUN(handover_subscr_conn,
1547 handover_subscr_conn_cmd,
1548 "handover <0-255> <0-255> <0-7> <0-7> <0-255>",
1549 MANUAL_HANDOVER_STR
1550 "Current " BTS_TRX_TS_LCHAN_STR
1551 "New " BTS_NR_STR)
1552{
1553 return ho_or_as(vty, argv, argc);
1554}
1555
1556DEFUN(assignment_subscr_conn,
1557 assignment_subscr_conn_cmd,
1558 "assignment <0-255> <0-255> <0-7> <0-7>",
1559 MANUAL_ASSIGNMENT_STR
1560 "Current " BTS_TRX_TS_LCHAN_STR)
1561{
1562 return ho_or_as(vty, argv, argc);
1563}
1564
1565static struct gsm_lchan *find_used_voice_lchan(struct vty *vty)
1566{
1567 struct gsm_bts *bts;
1568 struct gsm_network *network = gsmnet_from_vty(vty);
1569
1570 llist_for_each_entry(bts, &network->bts_list, list) {
1571 struct gsm_bts_trx *trx;
1572
1573 llist_for_each_entry(trx, &bts->trx_list, list) {
1574 int i;
1575 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1576 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1577 int j;
1578 int subslots;
1579
1580 /* skip administratively deactivated timeslots */
1581 if (!nm_is_running(&ts->mo.nm_state))
1582 continue;
1583
1584 subslots = ts_subslots(ts);
1585 for (j = 0; j < subslots; j++) {
1586 struct gsm_lchan *lchan = &ts->lchan[j];
1587
1588 if (lchan->state == LCHAN_S_ACTIVE
1589 && (lchan->type == GSM_LCHAN_TCH_F
1590 || lchan->type == GSM_LCHAN_TCH_H)) {
1591
1592 vty_out(vty, "Found voice call: %s%s",
1593 gsm_lchan_name(lchan), VTY_NEWLINE);
1594 lchan_dump_full_vty(vty, lchan);
1595 return lchan;
1596 }
1597 }
1598 }
1599 }
1600 }
1601
1602 vty_out(vty, "Cannot find any ongoing voice calls%s", VTY_NEWLINE);
1603 return NULL;
1604}
1605
1606static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gsm_bts *not_this_bts,
1607 enum gsm_phys_chan_config free_type)
1608{
1609 struct gsm_bts *bts;
1610 struct gsm_network *network = gsmnet_from_vty(vty);
1611
1612 llist_for_each_entry(bts, &network->bts_list, list) {
1613 struct gsm_bts_trx *trx;
1614
1615 if (bts == not_this_bts)
1616 continue;
1617
1618 llist_for_each_entry(trx, &bts->trx_list, list) {
1619 int i;
1620 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
1621 struct gsm_bts_trx_ts *ts = &trx->ts[i];
1622 int j;
1623 int subslots;
1624
1625 /* skip administratively deactivated timeslots */
1626 if (!nm_is_running(&ts->mo.nm_state))
1627 continue;
1628
1629 if (ts->pchan != free_type)
1630 continue;
1631
1632 subslots = ts_subslots(ts);
1633 for (j = 0; j < subslots; j++) {
1634 struct gsm_lchan *lchan = &ts->lchan[j];
1635
1636 if (lchan->state == LCHAN_S_NONE) {
1637 vty_out(vty, "Found unused %s slot: %s%s",
1638 gsm_pchan_name(free_type),
1639 gsm_lchan_name(lchan),
1640 VTY_NEWLINE);
1641 lchan_dump_full_vty(vty, lchan);
1642 return bts;
1643 }
1644 }
1645 }
1646 }
1647 }
1648 vty_out(vty, "Cannot find any BTS (other than BTS %u) with free %s lchan%s",
1649 not_this_bts? not_this_bts->nr : 255, gsm_lchant_name(free_type), VTY_NEWLINE);
1650 return NULL;
1651}
1652
1653DEFUN(handover_any, handover_any_cmd,
1654 "handover any",
1655 MANUAL_HANDOVER_STR
1656 "Pick any actively used TCH/F or TCH/H lchan and handover to any other BTS."
1657 " This is likely to fail if not all BTS are guaranteed to be reachable by the MS.\n")
1658{
1659 struct gsm_lchan *from_lchan;
1660 struct gsm_bts *to_bts;
1661
1662 from_lchan = find_used_voice_lchan(vty);
1663 if (!from_lchan)
1664 return CMD_WARNING;
1665
1666 to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts,
1667 ts_pchan(from_lchan->ts));
1668 if (!to_bts)
1669 return CMD_WARNING;
1670
1671 return trigger_ho_or_as(vty, from_lchan, to_bts);
1672}
1673
1674DEFUN(assignment_any, assignment_any_cmd,
1675 "assignment any",
1676 MANUAL_ASSIGNMENT_STR
1677 "Pick any actively used TCH/F or TCH/H lchan and re-assign within the same BTS."
1678 " This will fail if no lchans of the same type are available besides the used one.\n")
1679{
1680 struct gsm_lchan *from_lchan;
1681
1682 from_lchan = find_used_voice_lchan(vty);
1683 if (!from_lchan)
1684 return CMD_WARNING;
1685
1686 return trigger_ho_or_as(vty, from_lchan, NULL);
1687}
1688
Harald Weltebe4b7302009-05-23 16:59:33 +00001689static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
Harald Weltef5025b62009-03-28 16:55:11 +00001690{
1691 vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
Neels Hofmeyr6d804b12017-02-18 22:20:46 +01001692 bsc_subscr_dump_vty(vty, pag->bsub);
Harald Weltef5025b62009-03-28 16:55:11 +00001693}
1694
Harald Weltebe4b7302009-05-23 16:59:33 +00001695static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
Harald Weltef5025b62009-03-28 16:55:11 +00001696{
1697 struct gsm_paging_request *pag;
1698
Holger Hans Peter Freyther9b5192b2013-03-03 11:03:17 +01001699 if (!bts->paging.bts)
1700 return;
1701
Harald Weltef5025b62009-03-28 16:55:11 +00001702 llist_for_each_entry(pag, &bts->paging.pending_requests, entry)
1703 paging_dump_vty(vty, pag);
1704}
1705
1706DEFUN(show_paging,
1707 show_paging_cmd,
Sylvain Munaut39c31de2012-12-28 12:15:11 +01001708 "show paging [<0-255>]",
Harald Welte8f0ed552010-05-11 21:53:49 +02001709 SHOW_STR "Display information about paging reuqests of a BTS\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001710 BTS_NR_STR)
Harald Weltef5025b62009-03-28 16:55:11 +00001711{
Harald Weltedcccb182010-05-16 20:52:23 +02001712 struct gsm_network *net = gsmnet_from_vty(vty);
Harald Weltef5025b62009-03-28 16:55:11 +00001713 struct gsm_bts *bts;
1714 int bts_nr;
1715
1716 if (argc >= 1) {
1717 /* use the BTS number that the user has specified */
1718 bts_nr = atoi(argv[0]);
1719 if (bts_nr >= net->num_bts) {
1720 vty_out(vty, "%% can't find BTS %s%s", argv[0],
1721 VTY_NEWLINE);
1722 return CMD_WARNING;
1723 }
Harald Weltee441d9c2009-06-21 16:17:15 +02001724 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001725 bts_paging_dump_vty(vty, bts);
Pau Espin Pedrolc5a84162017-11-28 15:04:26 +01001726
Harald Weltef5025b62009-03-28 16:55:11 +00001727 return CMD_SUCCESS;
1728 }
1729 for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
Harald Weltee441d9c2009-06-21 16:17:15 +02001730 bts = gsm_bts_num(net, bts_nr);
Harald Weltef5025b62009-03-28 16:55:11 +00001731 bts_paging_dump_vty(vty, bts);
1732 }
1733
1734 return CMD_SUCCESS;
1735}
1736
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001737DEFUN(show_paging_group,
1738 show_paging_group_cmd,
1739 "show paging-group <0-255> IMSI",
1740 SHOW_STR "Display the paging group\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001741 BTS_NR_STR "IMSI\n")
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01001742{
1743 struct gsm_network *net = gsmnet_from_vty(vty);
1744 struct gsm_bts *bts;
1745 unsigned int page_group;
1746 int bts_nr = atoi(argv[0]);
1747
1748 if (bts_nr >= net->num_bts) {
1749 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1750 return CMD_WARNING;
1751 }
1752
1753 bts = gsm_bts_num(net, bts_nr);
1754 if (!bts) {
1755 vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE);
1756 return CMD_WARNING;
1757 }
1758
1759 page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
1760 str_to_imsi(argv[1]));
1761 vty_out(vty, "%%Paging group for IMSI %" PRIu64 " on BTS #%d is %u%s",
1762 str_to_imsi(argv[1]), bts->nr,
1763 page_group, VTY_NEWLINE);
1764 return CMD_SUCCESS;
1765}
1766
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001767DEFUN(cfg_net_neci,
1768 cfg_net_neci_cmd,
1769 "neci (0|1)",
Harald Welte28326062010-05-14 20:05:17 +02001770 "New Establish Cause Indication\n"
1771 "Don't set the NECI bit\n" "Set the NECI bit\n")
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001772{
Harald Weltedcccb182010-05-16 20:52:23 +02001773 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
1774
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001775 gsmnet->neci = atoi(argv[0]);
Holger Hans Peter Freyther78891072010-09-06 09:36:02 +08001776 gsm_net_update_ctype(gsmnet);
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01001777 return CMD_SUCCESS;
1778}
1779
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001780DEFUN(cfg_net_pag_any_tch,
1781 cfg_net_pag_any_tch_cmd,
1782 "paging any use tch (0|1)",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001783 "Assign a TCH when receiving a Paging Any request\n"
1784 "Any Channel\n" "Use\n" "TCH\n"
1785 "Do not use TCH for Paging Request Any\n"
1786 "Do use TCH for Paging Request Any\n")
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001787{
Holger Hans Peter Freytherb0e88b82010-09-06 10:09:19 +08001788 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08001789 gsmnet->pag_any_tch = atoi(argv[0]);
1790 gsm_net_update_ctype(gsmnet);
1791 return CMD_SUCCESS;
1792}
1793
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001794#define DEFAULT_TIMER(number) GSM_T##number##_DEFAULT
1795/* Add another expansion so that DEFAULT_TIMER() becomes its value */
1796#define EXPAND_AND_STRINGIFY(x) OSMO_STRINGIFY(x)
1797
Holger Hans Peter Freytherc8021062009-12-22 08:27:21 +01001798#define DECLARE_TIMER(number, doc) \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001799 DEFUN(cfg_net_T##number, \
1800 cfg_net_T##number##_cmd, \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001801 "timer t" #number " (default|<1-65535>)", \
Harald Welte8f0ed552010-05-11 21:53:49 +02001802 "Configure GSM Timers\n" \
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001803 doc " (default: " EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001804 "Set to default timer value" \
1805 " (" EXPAND_AND_STRINGIFY(DEFAULT_TIMER(number)) " seconds)\n" \
1806 "Timer Value in seconds\n") \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001807{ \
Harald Weltedcccb182010-05-16 20:52:23 +02001808 struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
Neels Hofmeyrf704a6e2017-07-24 13:06:45 +02001809 int value; \
1810 if (strcmp(argv[0], "default") == 0) \
1811 value = DEFAULT_TIMER(number); \
1812 else \
1813 value = atoi(argv[0]); \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001814 \
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001815 gsmnet->T##number = value; \
1816 return CMD_SUCCESS; \
1817}
1818
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001819DECLARE_TIMER(3101, "Set the timeout value for IMMEDIATE ASSIGNMENT")
1820DECLARE_TIMER(3103, "Set the timeout value for HANDOVER")
1821DECLARE_TIMER(3105, "Set the timer for repetition of PHYSICAL INFORMATION")
1822DECLARE_TIMER(3107, "Currently not used")
1823DECLARE_TIMER(3109, "Set the RSL SACCH deactivation timeout")
1824DECLARE_TIMER(3111, "Set the RSL timeout to wait before releasing the RF Channel")
1825DECLARE_TIMER(3113, "Set the time to try paging a subscriber")
1826DECLARE_TIMER(3115, "Currently not used")
1827DECLARE_TIMER(3117, "Currently not used")
1828DECLARE_TIMER(3119, "Currently not used")
Stefan Sperling6cee8932018-01-30 18:14:22 +01001829DECLARE_TIMER(3122, "Default waiting time (seconds) after IMM ASS REJECT")
Neels Hofmeyr18f4af82017-07-24 13:36:42 +02001830DECLARE_TIMER(3141, "Currently not used")
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001831
Maxc08ee712016-05-11 12:45:13 +02001832DEFUN_DEPRECATED(cfg_net_dtx,
1833 cfg_net_dtx_cmd,
1834 "dtx-used (0|1)",
1835 ".HIDDEN\n""Obsolete\n""Obsolete\n")
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001836{
Maxc08ee712016-05-11 12:45:13 +02001837 vty_out(vty, "%% 'dtx-used' is now deprecated: use dtx * "
1838 "configuration options of BTS instead%s", VTY_NEWLINE);
1839 return CMD_SUCCESS;
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001840}
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01001841
Harald Welte5258fc42009-03-28 19:07:53 +00001842/* per-BTS configuration */
1843DEFUN(cfg_bts,
1844 cfg_bts_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02001845 "bts <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02001846 "Select a BTS to configure\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01001847 BTS_NR_STR)
Harald Welte5258fc42009-03-28 19:07:53 +00001848{
Harald Weltedcccb182010-05-16 20:52:23 +02001849 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte5258fc42009-03-28 19:07:53 +00001850 int bts_nr = atoi(argv[0]);
1851 struct gsm_bts *bts;
1852
Harald Weltee441d9c2009-06-21 16:17:15 +02001853 if (bts_nr > gsmnet->num_bts) {
1854 vty_out(vty, "%% The next unused BTS number is %u%s",
1855 gsmnet->num_bts, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00001856 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02001857 } else if (bts_nr == gsmnet->num_bts) {
1858 /* allocate a new one */
Harald Welte3300c012011-06-05 13:31:33 +02001859 bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_UNKNOWN,
Harald Weltea2bbc5e2015-11-20 10:43:31 +01001860 HARDCODED_BSIC);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02001861 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02001862 bts = gsm_bts_num(gsmnet, bts_nr);
1863
Daniel Willmannf15c2762010-01-11 13:43:07 +01001864 if (!bts) {
1865 vty_out(vty, "%% Unable to allocate BTS %u%s",
1866 gsmnet->num_bts, VTY_NEWLINE);
Harald Weltee441d9c2009-06-21 16:17:15 +02001867 return CMD_WARNING;
Daniel Willmannf15c2762010-01-11 13:43:07 +01001868 }
Harald Welte5258fc42009-03-28 19:07:53 +00001869
1870 vty->index = bts;
Harald Welte197dea92010-05-14 17:59:53 +02001871 vty->index_sub = &bts->description;
Harald Welte5258fc42009-03-28 19:07:53 +00001872 vty->node = BTS_NODE;
1873
1874 return CMD_SUCCESS;
1875}
1876
1877DEFUN(cfg_bts_type,
1878 cfg_bts_type_cmd,
Harald Weltee555c2b2012-08-17 13:02:12 +02001879 "type TYPE", /* dynamically created */
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001880 "Set the BTS type\n" "Type\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001881{
1882 struct gsm_bts *bts = vty->index;
Harald Welte39315c42010-01-10 18:01:52 +01001883 int rc;
Harald Welte5258fc42009-03-28 19:07:53 +00001884
Max7507aef2017-04-10 13:59:14 +02001885 rc = gsm_set_bts_type(bts, str2btstype(argv[0]));
Harald Welte39315c42010-01-10 18:01:52 +01001886 if (rc < 0)
1887 return CMD_WARNING;
Harald Welte8175e952009-10-20 00:22:00 +02001888
Harald Welte5258fc42009-03-28 19:07:53 +00001889 return CMD_SUCCESS;
1890}
1891
Harald Weltefcd24452009-06-20 18:15:19 +02001892DEFUN(cfg_bts_band,
1893 cfg_bts_band_cmd,
1894 "band BAND",
Holger Hans Peter Freyther08542562011-10-03 23:42:06 +02001895 "Set the frequency band of this BTS\n" "Frequency band\n")
Harald Weltefcd24452009-06-20 18:15:19 +02001896{
1897 struct gsm_bts *bts = vty->index;
Harald Welte42581822009-08-08 16:12:58 +02001898 int band = gsm_band_parse(argv[0]);
Harald Weltefcd24452009-06-20 18:15:19 +02001899
1900 if (band < 0) {
1901 vty_out(vty, "%% BAND %d is not a valid GSM band%s",
1902 band, VTY_NEWLINE);
1903 return CMD_WARNING;
1904 }
1905
1906 bts->band = band;
1907
1908 return CMD_SUCCESS;
1909}
1910
Maxc08ee712016-05-11 12:45:13 +02001911DEFUN(cfg_bts_dtxu, cfg_bts_dtxu_cmd, "dtx uplink [force]",
1912 "Configure discontinuous transmission\n"
1913 "Enable Uplink DTX for this BTS\n"
1914 "MS 'shall' use DTXu instead of 'may' use (might not be supported by "
1915 "older phones).\n")
1916{
1917 struct gsm_bts *bts = vty->index;
1918
1919 bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED;
Max60795282016-06-06 11:30:57 +02001920 if (!is_ipaccess_bts(bts))
1921 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1922 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001923 return CMD_SUCCESS;
1924}
1925
1926DEFUN(cfg_bts_no_dtxu, cfg_bts_no_dtxu_cmd, "no dtx uplink",
1927 NO_STR
1928 "Configure discontinuous transmission\n"
1929 "Disable Uplink DTX for this BTS\n")
1930{
1931 struct gsm_bts *bts = vty->index;
1932
1933 bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
1934
1935 return CMD_SUCCESS;
1936}
1937
1938DEFUN(cfg_bts_dtxd, cfg_bts_dtxd_cmd, "dtx downlink",
1939 "Configure discontinuous transmission\n"
1940 "Enable Downlink DTX for this BTS\n")
1941{
1942 struct gsm_bts *bts = vty->index;
1943
1944 bts->dtxd = true;
Max60795282016-06-06 11:30:57 +02001945 if (!is_ipaccess_bts(bts))
1946 vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration "
1947 "neither supported nor tested!%s", VTY_NEWLINE);
Maxc08ee712016-05-11 12:45:13 +02001948 return CMD_SUCCESS;
1949}
1950
1951DEFUN(cfg_bts_no_dtxd, cfg_bts_no_dtxd_cmd, "no dtx downlink",
1952 NO_STR
1953 "Configure discontinuous transmission\n"
1954 "Disable Downlink DTX for this BTS\n")
1955{
1956 struct gsm_bts *bts = vty->index;
1957
1958 bts->dtxd = false;
1959
1960 return CMD_SUCCESS;
1961}
1962
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001963DEFUN(cfg_bts_ci,
1964 cfg_bts_ci_cmd,
1965 "cell_identity <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001966 "Set the Cell identity of this BTS\n" "Cell Identity\n")
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02001967{
1968 struct gsm_bts *bts = vty->index;
1969 int ci = atoi(argv[0]);
1970
1971 if (ci < 0 || ci > 0xffff) {
1972 vty_out(vty, "%% CI %d is not in the valid range (0-65535)%s",
1973 ci, VTY_NEWLINE);
1974 return CMD_WARNING;
1975 }
1976 bts->cell_identity = ci;
1977
1978 return CMD_SUCCESS;
1979}
1980
Harald Welte5258fc42009-03-28 19:07:53 +00001981DEFUN(cfg_bts_lac,
1982 cfg_bts_lac_cmd,
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001983 "location_area_code <0-65535>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02001984 "Set the Location Area Code (LAC) of this BTS\n" "LAC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00001985{
1986 struct gsm_bts *bts = vty->index;
1987 int lac = atoi(argv[0]);
1988
Holger Hans Peter Freyther0b7f4b32009-09-29 14:02:33 +02001989 if (lac < 0 || lac > 0xffff) {
1990 vty_out(vty, "%% LAC %d is not in the valid range (0-65535)%s",
Harald Welte5258fc42009-03-28 19:07:53 +00001991 lac, VTY_NEWLINE);
1992 return CMD_WARNING;
1993 }
Holger Hans Peter Freythere48b9562009-10-01 04:07:15 +02001994
1995 if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
1996 vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
1997 lac, VTY_NEWLINE);
1998 return CMD_WARNING;
1999 }
2000
Harald Welte5258fc42009-03-28 19:07:53 +00002001 bts->location_area_code = lac;
2002
2003 return CMD_SUCCESS;
2004}
2005
Harald Weltea43f7892009-12-01 18:04:30 +05302006
Harald Weltea2bbc5e2015-11-20 10:43:31 +01002007/* compatibility wrapper for old config files */
2008DEFUN_HIDDEN(cfg_bts_tsc,
Harald Welte5258fc42009-03-28 19:07:53 +00002009 cfg_bts_tsc_cmd,
Harald Weltec513ded2012-05-31 10:57:08 +02002010 "training_sequence_code <0-7>",
Holger Hans Peter Freyther64c17fa2012-07-21 00:27:10 +02002011 "Set the Training Sequence Code (TSC) of this BTS\n" "TSC\n")
Harald Welte5258fc42009-03-28 19:07:53 +00002012{
Harald Welte5258fc42009-03-28 19:07:53 +00002013 return CMD_SUCCESS;
2014}
2015
Harald Welte78f2f502009-05-23 16:56:52 +00002016DEFUN(cfg_bts_bsic,
2017 cfg_bts_bsic_cmd,
2018 "base_station_id_code <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002019 "Set the Base Station Identity Code (BSIC) of this BTS\n"
2020 "BSIC of this BTS\n")
Harald Welte78f2f502009-05-23 16:56:52 +00002021{
2022 struct gsm_bts *bts = vty->index;
2023 int bsic = atoi(argv[0]);
2024
2025 if (bsic < 0 || bsic > 0x3f) {
Harald Welte42581822009-08-08 16:12:58 +02002026 vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
Harald Welte78f2f502009-05-23 16:56:52 +00002027 bsic, VTY_NEWLINE);
2028 return CMD_WARNING;
2029 }
2030 bts->bsic = bsic;
2031
2032 return CMD_SUCCESS;
2033}
2034
Harald Welte4cc34222009-05-01 15:12:31 +00002035DEFUN(cfg_bts_unit_id,
2036 cfg_bts_unit_id_cmd,
Harald Welte07dc73d2009-08-07 13:27:09 +02002037 "ip.access unit_id <0-65534> <0-255>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002038 "Abis/IP specific options\n"
2039 "Set the IPA BTS Unit ID\n"
2040 "Unit ID (Site)\n"
2041 "Unit ID (BTS)\n")
Harald Welte4cc34222009-05-01 15:12:31 +00002042{
2043 struct gsm_bts *bts = vty->index;
2044 int site_id = atoi(argv[0]);
2045 int bts_id = atoi(argv[1]);
2046
Harald Welte07dc73d2009-08-07 13:27:09 +02002047 if (!is_ipaccess_bts(bts)) {
2048 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2049 return CMD_WARNING;
2050 }
2051
Harald Welte4cc34222009-05-01 15:12:31 +00002052 bts->ip_access.site_id = site_id;
2053 bts->ip_access.bts_id = bts_id;
2054
2055 return CMD_SUCCESS;
2056}
2057
Harald Welte8b291802013-03-12 13:57:05 +01002058DEFUN(cfg_bts_rsl_ip,
2059 cfg_bts_rsl_ip_cmd,
2060 "ip.access rsl-ip A.B.C.D",
2061 "Abis/IP specific options\n"
2062 "Set the IPA RSL IP Address of the BSC\n"
2063 "Destination IP address for RSL connection\n")
2064{
2065 struct gsm_bts *bts = vty->index;
2066 struct in_addr ia;
2067
2068 if (!is_ipaccess_bts(bts)) {
2069 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2070 return CMD_WARNING;
2071 }
2072
2073 inet_aton(argv[0], &ia);
2074 bts->ip_access.rsl_ip = ntohl(ia.s_addr);
2075
2076 return CMD_SUCCESS;
2077}
2078
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002079#define NOKIA_STR "Nokia *Site related commands\n"
Harald Welte8b291802013-03-12 13:57:05 +01002080
Sylvain Munautc9519462011-10-17 14:04:55 +02002081DEFUN(cfg_bts_nokia_site_skip_reset,
2082 cfg_bts_nokia_site_skip_reset_cmd,
2083 "nokia_site skip-reset (0|1)",
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002084 NOKIA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002085 "Skip the reset step during bootstrap process of this BTS\n"
2086 "Do NOT skip the reset\n" "Skip the reset\n")
Sylvain Munautc9519462011-10-17 14:04:55 +02002087{
2088 struct gsm_bts *bts = vty->index;
2089
2090 if (bts->type != GSM_BTS_TYPE_NOKIA_SITE) {
2091 vty_out(vty, "%% BTS is not of Nokia *Site type%s", VTY_NEWLINE);
2092 return CMD_WARNING;
2093 }
2094
2095 bts->nokia.skip_reset = atoi(argv[0]);
2096
2097 return CMD_SUCCESS;
2098}
2099
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01002100DEFUN(cfg_bts_nokia_site_no_loc_rel_cnf,
2101 cfg_bts_nokia_site_no_loc_rel_cnf_cmd,
2102 "nokia_site no-local-rel-conf (0|1)",
2103 NOKIA_STR
2104 "Do not wait for RELease CONFirm message when releasing channel locally\n"
2105 "Wait for RELease CONFirm\n" "Do not wait for RELease CONFirm\n")
2106{
2107 struct gsm_bts *bts = vty->index;
2108
2109 if (!is_nokia_bts(bts)) {
2110 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2111 VTY_NEWLINE);
2112 return CMD_WARNING;
2113 }
2114
2115 bts->nokia.no_loc_rel_cnf = atoi(argv[0]);
2116
2117 return CMD_SUCCESS;
2118}
2119
Sipos Csaba56e17662015-02-07 13:27:36 +01002120DEFUN(cfg_bts_nokia_site_bts_reset_timer_cnf,
2121 cfg_bts_nokia_site_bts_reset_timer_cnf_cmd,
2122 "nokia_site bts-reset-timer <15-100>",
2123 NOKIA_STR
2124 "The amount of time (in sec.) between BTS_RESET is sent,\n"
2125 "and the BTS is being bootstrapped.\n")
2126{
2127 struct gsm_bts *bts = vty->index;
2128
2129 if (!is_nokia_bts(bts)) {
2130 vty_out(vty, "%% BTS is not of Nokia *Site type%s",
2131 VTY_NEWLINE);
2132 return CMD_WARNING;
2133 }
2134
2135 bts->nokia.bts_reset_timer_cnf = atoi(argv[0]);
2136
2137 return CMD_SUCCESS;
2138}
Harald Welte8f0ed552010-05-11 21:53:49 +02002139#define OML_STR "Organization & Maintenance Link\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002140#define IPA_STR "A-bis/IP Specific Options\n"
Harald Welte8f0ed552010-05-11 21:53:49 +02002141
Harald Welte8175e952009-10-20 00:22:00 +02002142DEFUN(cfg_bts_stream_id,
2143 cfg_bts_stream_id_cmd,
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002144 "oml ip.access stream_id <0-255> line E1_LINE",
Harald Welte8f0ed552010-05-11 21:53:49 +02002145 OML_STR IPA_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002146 "Set the ip.access Stream ID of the OML link of this BTS\n"
2147 "Stream Identifier\n" "Virtual E1 Line Number\n" "Virtual E1 Line Number\n")
Harald Welte8175e952009-10-20 00:22:00 +02002148{
2149 struct gsm_bts *bts = vty->index;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002150 int stream_id = atoi(argv[0]), linenr = atoi(argv[1]);
Harald Welte8175e952009-10-20 00:22:00 +02002151
2152 if (!is_ipaccess_bts(bts)) {
2153 vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
2154 return CMD_WARNING;
2155 }
2156
2157 bts->oml_tei = stream_id;
Pablo Neira Ayusoed5cacb2011-08-17 22:44:07 +02002158 /* This is used by e1inp_bind_ops callback for each BTS model. */
2159 bts->oml_e1_link.e1_nr = linenr;
2160
2161 return CMD_SUCCESS;
2162}
2163
Harald Welted13e0cd2012-08-17 09:52:03 +02002164#define OML_E1_STR OML_STR "OML E1/T1 Configuration\n"
Harald Welte8175e952009-10-20 00:22:00 +02002165
Harald Welte42581822009-08-08 16:12:58 +02002166DEFUN(cfg_bts_oml_e1,
2167 cfg_bts_oml_e1_cmd,
2168 "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Welted13e0cd2012-08-17 09:52:03 +02002169 OML_E1_STR
2170 "E1/T1 line number to be used for OML\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002171 "E1/T1 line number to be used for OML\n"
2172 "E1/T1 timeslot to be used for OML\n"
2173 "E1/T1 timeslot to be used for OML\n"
2174 "E1/T1 sub-slot to be used for OML\n"
2175 "Use E1/T1 sub-slot 0\n"
2176 "Use E1/T1 sub-slot 1\n"
2177 "Use E1/T1 sub-slot 2\n"
2178 "Use E1/T1 sub-slot 3\n"
2179 "Use full E1 slot 3\n"
2180 )
Harald Welte42581822009-08-08 16:12:58 +02002181{
2182 struct gsm_bts *bts = vty->index;
2183
2184 parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
2185
2186 return CMD_SUCCESS;
2187}
2188
2189
2190DEFUN(cfg_bts_oml_e1_tei,
2191 cfg_bts_oml_e1_tei_cmd,
2192 "oml e1 tei <0-63>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002193 OML_E1_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002194 "Set the TEI to be used for OML\n"
2195 "TEI Number\n")
Harald Welte42581822009-08-08 16:12:58 +02002196{
2197 struct gsm_bts *bts = vty->index;
2198
2199 bts->oml_tei = atoi(argv[0]);
2200
2201 return CMD_SUCCESS;
2202}
2203
Harald Welte7a8fa412009-08-10 13:48:16 +02002204DEFUN(cfg_bts_challoc, cfg_bts_challoc_cmd,
2205 "channel allocator (ascending|descending)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002206 "Channnel Allocator\n" "Channel Allocator\n"
2207 "Allocate Timeslots and Transceivers in ascending order\n"
2208 "Allocate Timeslots and Transceivers in descending order\n")
Harald Welte7a8fa412009-08-10 13:48:16 +02002209{
2210 struct gsm_bts *bts = vty->index;
2211
2212 if (!strcmp(argv[0], "ascending"))
2213 bts->chan_alloc_reverse = 0;
2214 else
2215 bts->chan_alloc_reverse = 1;
2216
2217 return CMD_SUCCESS;
2218}
2219
Harald Welte8f0ed552010-05-11 21:53:49 +02002220#define RACH_STR "Random Access Control Channel\n"
2221
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002222DEFUN(cfg_bts_rach_tx_integer,
2223 cfg_bts_rach_tx_integer_cmd,
2224 "rach tx integer <0-15>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002225 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002226 "Set the raw tx integer value in RACH Control parameters IE\n"
2227 "Set the raw tx integer value in RACH Control parameters IE\n"
2228 "Raw tx integer value in RACH Control parameters IE\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002229{
2230 struct gsm_bts *bts = vty->index;
2231 bts->si_common.rach_control.tx_integer = atoi(argv[0]) & 0xf;
2232 return CMD_SUCCESS;
2233}
2234
2235DEFUN(cfg_bts_rach_max_trans,
2236 cfg_bts_rach_max_trans_cmd,
2237 "rach max transmission (1|2|4|7)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002238 RACH_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002239 "Set the maximum number of RACH burst transmissions\n"
2240 "Set the maximum number of RACH burst transmissions\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002241 "Maximum number of 1 RACH burst transmissions\n"
2242 "Maximum number of 2 RACH burst transmissions\n"
2243 "Maximum number of 4 RACH burst transmissions\n"
2244 "Maximum number of 7 RACH burst transmissions\n")
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01002245{
2246 struct gsm_bts *bts = vty->index;
2247 bts->si_common.rach_control.max_trans = rach_max_trans_val2raw(atoi(argv[0]));
2248 return CMD_SUCCESS;
2249}
2250
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02002251#define CD_STR "Channel Description\n"
2252
2253DEFUN(cfg_bts_chan_desc_att,
2254 cfg_bts_chan_desc_att_cmd,
2255 "channel-descrption attach (0|1)",
2256 CD_STR
2257 "Set if attachment is required\n"
2258 "Attachment is NOT required\n"
2259 "Attachment is required (standard)\n")
2260{
2261 struct gsm_bts *bts = vty->index;
2262 bts->si_common.chan_desc.att = atoi(argv[0]);
2263 return CMD_SUCCESS;
2264}
2265
2266DEFUN(cfg_bts_chan_desc_bs_pa_mfrms,
2267 cfg_bts_chan_desc_bs_pa_mfrms_cmd,
2268 "channel-descrption bs-pa-mfrms <2-9>",
2269 CD_STR
2270 "Set number of multiframe periods for paging groups\n"
2271 "Number of multiframe periods for paging groups\n")
2272{
2273 struct gsm_bts *bts = vty->index;
2274 int bs_pa_mfrms = atoi(argv[0]);
2275
2276 bts->si_common.chan_desc.bs_pa_mfrms = bs_pa_mfrms - 2;
2277 return CMD_SUCCESS;
2278}
2279
2280DEFUN(cfg_bts_chan_desc_bs_ag_blks_res,
2281 cfg_bts_chan_desc_bs_ag_blks_res_cmd,
2282 "channel-descrption bs-ag-blks-res <0-7>",
2283 CD_STR
2284 "Set number of blocks reserved for access grant\n"
2285 "Number of blocks reserved for access grant\n")
2286{
2287 struct gsm_bts *bts = vty->index;
2288 int bs_ag_blks_res = atoi(argv[0]);
2289
2290 bts->si_common.chan_desc.bs_ag_blks_res = bs_ag_blks_res;
2291 return CMD_SUCCESS;
2292}
2293
Harald Welte8f0ed552010-05-11 21:53:49 +02002294#define NM_STR "Network Management\n"
2295
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002296DEFUN(cfg_bts_rach_nm_b_thresh,
2297 cfg_bts_rach_nm_b_thresh_cmd,
2298 "rach nm busy threshold <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002299 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002300 "Set the NM Busy Threshold\n"
2301 "Set the NM Busy Threshold\n"
2302 "NM Busy Threshold in dB")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002303{
2304 struct gsm_bts *bts = vty->index;
2305 bts->rach_b_thresh = atoi(argv[0]);
2306 return CMD_SUCCESS;
2307}
2308
2309DEFUN(cfg_bts_rach_nm_ldavg,
2310 cfg_bts_rach_nm_ldavg_cmd,
2311 "rach nm load average <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002312 RACH_STR NM_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02002313 "Set the NM Loadaverage Slots value\n"
2314 "Set the NM Loadaverage Slots value\n"
2315 "NM Loadaverage Slots value\n")
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08002316{
2317 struct gsm_bts *bts = vty->index;
2318 bts->rach_ldavg_slots = atoi(argv[0]);
2319 return CMD_SUCCESS;
2320}
2321
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002322DEFUN(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd,
2323 "cell barred (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002324 "Should this cell be barred from access?\n"
2325 "Should this cell be barred from access?\n"
2326 "Cell should NOT be barred\n"
2327 "Cell should be barred\n")
2328
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002329{
2330 struct gsm_bts *bts = vty->index;
2331
Harald Welte71355012009-12-21 23:08:18 +01002332 bts->si_common.rach_control.cell_bar = atoi(argv[0]);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02002333
2334 return CMD_SUCCESS;
2335}
2336
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002337DEFUN(cfg_bts_rach_ec_allowed, cfg_bts_rach_ec_allowed_cmd,
2338 "rach emergency call allowed (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002339 RACH_STR
2340 "Should this cell allow emergency calls?\n"
2341 "Should this cell allow emergency calls?\n"
2342 "Should this cell allow emergency calls?\n"
2343 "Do NOT allow emergency calls\n"
2344 "Allow emergency calls\n")
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08002345{
2346 struct gsm_bts *bts = vty->index;
2347
2348 if (atoi(argv[0]) == 0)
2349 bts->si_common.rach_control.t2 |= 0x4;
2350 else
2351 bts->si_common.rach_control.t2 &= ~0x4;
2352
2353 return CMD_SUCCESS;
2354}
2355
Ivan Kluchnikov67920592013-09-16 13:13:04 +04002356DEFUN(cfg_bts_rach_ac_class, cfg_bts_rach_ac_class_cmd,
2357 "rach access-control-class (0|1|2|3|4|5|6|7|8|9|11|12|13|14|15) (barred|allowed)",
2358 RACH_STR
2359 "Set access control class\n"
2360 "Access control class 0\n"
2361 "Access control class 1\n"
2362 "Access control class 2\n"
2363 "Access control class 3\n"
2364 "Access control class 4\n"
2365 "Access control class 5\n"
2366 "Access control class 6\n"
2367 "Access control class 7\n"
2368 "Access control class 8\n"
2369 "Access control class 9\n"
2370 "Access control class 11 for PLMN use\n"
2371 "Access control class 12 for security services\n"
2372 "Access control class 13 for public utilities (e.g. water/gas suppliers)\n"
2373 "Access control class 14 for emergency services\n"
2374 "Access control class 15 for PLMN staff\n"
2375 "barred to use access control class\n"
2376 "allowed to use access control class\n")
2377{
2378 struct gsm_bts *bts = vty->index;
2379
2380 uint8_t control_class;
2381 uint8_t allowed = 0;
2382
2383 if (strcmp(argv[1], "allowed") == 0)
2384 allowed = 1;
2385
2386 control_class = atoi(argv[0]);
2387 if (control_class < 8)
2388 if (allowed)
2389 bts->si_common.rach_control.t3 &= ~(0x1 << control_class);
2390 else
2391 bts->si_common.rach_control.t3 |= (0x1 << control_class);
2392 else
2393 if (allowed)
2394 bts->si_common.rach_control.t2 &= ~(0x1 << (control_class - 8));
2395 else
2396 bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
2397
2398 return CMD_SUCCESS;
2399}
2400
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002401DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
2402 "ms max power <0-40>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002403 "MS Options\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02002404 "Maximum transmit power of the MS\n"
2405 "Maximum transmit power of the MS\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002406 "Maximum transmit power of the MS in dBm")
Harald Welte (local)0e451d02009-08-13 10:14:26 +02002407{
2408 struct gsm_bts *bts = vty->index;
2409
2410 bts->ms_max_power = atoi(argv[0]);
2411
2412 return CMD_SUCCESS;
2413}
2414
Harald Weltecfaabbb2012-08-16 23:23:50 +02002415#define CELL_STR "Cell Parameters\n"
2416
Harald Welte73225282009-12-12 18:17:25 +01002417DEFUN(cfg_bts_cell_resel_hyst, cfg_bts_cell_resel_hyst_cmd,
2418 "cell reselection hysteresis <0-14>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002419 CELL_STR "Cell re-selection parameters\n"
2420 "Cell Re-Selection Hysteresis in dB\n"
Harald Welte73225282009-12-12 18:17:25 +01002421 "Cell Re-Selection Hysteresis in dB")
2422{
2423 struct gsm_bts *bts = vty->index;
2424
2425 bts->si_common.cell_sel_par.cell_resel_hyst = atoi(argv[0])/2;
2426
2427 return CMD_SUCCESS;
2428}
2429
2430DEFUN(cfg_bts_rxlev_acc_min, cfg_bts_rxlev_acc_min_cmd,
2431 "rxlev access min <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002432 "Minimum RxLev needed for cell access\n"
2433 "Minimum RxLev needed for cell access\n"
2434 "Minimum RxLev needed for cell access\n"
Harald Welte73225282009-12-12 18:17:25 +01002435 "Minimum RxLev needed for cell access (better than -110dBm)")
2436{
2437 struct gsm_bts *bts = vty->index;
2438
2439 bts->si_common.cell_sel_par.rxlev_acc_min = atoi(argv[0]);
2440
2441 return CMD_SUCCESS;
2442}
2443
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002444DEFUN(cfg_bts_cell_bar_qualify, cfg_bts_cell_bar_qualify_cmd,
2445 "cell bar qualify (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002446 CELL_STR "Cell Bar Qualify\n" "Cell Bar Qualify\n"
2447 "Set CBQ to 0\n" "Set CBQ to 1\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002448{
2449 struct gsm_bts *bts = vty->index;
2450
2451 bts->si_common.cell_ro_sel_par.present = 1;
2452 bts->si_common.cell_ro_sel_par.cbq = atoi(argv[0]);
2453
2454 return CMD_SUCCESS;
2455}
2456
2457DEFUN(cfg_bts_cell_resel_ofs, cfg_bts_cell_resel_ofs_cmd,
2458 "cell reselection offset <0-126>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002459 CELL_STR "Cell Re-Selection Parameters\n"
2460 "Cell Re-Selection Offset (CRO) in dB\n"
2461 "Cell Re-Selection Offset (CRO) in dB\n"
2462 )
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002463{
2464 struct gsm_bts *bts = vty->index;
2465
2466 bts->si_common.cell_ro_sel_par.present = 1;
2467 bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(argv[0])/2;
2468
2469 return CMD_SUCCESS;
2470}
2471
2472DEFUN(cfg_bts_temp_ofs, cfg_bts_temp_ofs_cmd,
2473 "temporary offset <0-60>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002474 "Cell selection temporary negative offset\n"
2475 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002476 "Cell selection temporary negative offset in dB")
2477{
2478 struct gsm_bts *bts = vty->index;
2479
2480 bts->si_common.cell_ro_sel_par.present = 1;
2481 bts->si_common.cell_ro_sel_par.temp_offs = atoi(argv[0])/10;
2482
2483 return CMD_SUCCESS;
2484}
2485
2486DEFUN(cfg_bts_temp_ofs_inf, cfg_bts_temp_ofs_inf_cmd,
2487 "temporary offset infinite",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002488 "Cell selection temporary negative offset\n"
2489 "Cell selection temporary negative offset\n"
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002490 "Sets cell selection temporary negative offset to infinity")
2491{
2492 struct gsm_bts *bts = vty->index;
2493
2494 bts->si_common.cell_ro_sel_par.present = 1;
2495 bts->si_common.cell_ro_sel_par.temp_offs = 7;
2496
2497 return CMD_SUCCESS;
2498}
2499
2500DEFUN(cfg_bts_penalty_time, cfg_bts_penalty_time_cmd,
2501 "penalty time <20-620>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002502 "Cell selection penalty time\n"
2503 "Cell selection penalty time\n"
2504 "Cell selection penalty time in seconds (by 20s increments)\n")
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002505{
2506 struct gsm_bts *bts = vty->index;
2507
2508 bts->si_common.cell_ro_sel_par.present = 1;
2509 bts->si_common.cell_ro_sel_par.penalty_time = (atoi(argv[0])-20)/20;
2510
2511 return CMD_SUCCESS;
2512}
2513
2514DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
2515 "penalty time reserved",
Harald Weltecfaabbb2012-08-16 23:23:50 +02002516 "Cell selection penalty time\n"
2517 "Cell selection penalty time\n"
2518 "Set cell selection penalty time to reserved value 31, "
Sylvain Munaute0b06b02010-11-28 18:17:28 +01002519 "(indicate that CELL_RESELECT_OFFSET is subtracted from C2 "
2520 "and TEMPORARY_OFFSET is ignored)")
2521{
2522 struct gsm_bts *bts = vty->index;
2523
2524 bts->si_common.cell_ro_sel_par.present = 1;
2525 bts->si_common.cell_ro_sel_par.penalty_time = 31;
2526
2527 return CMD_SUCCESS;
2528}
2529
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002530DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
2531 "radio-link-timeout <4-64>",
2532 "Radio link timeout criterion (BTS side)\n"
2533 "Radio link timeout value (lost SACCH block)\n")
2534{
2535 struct gsm_bts *bts = vty->index;
2536
Harald Welte2f8b9d22017-06-18 11:12:13 +03002537 gsm_bts_set_radio_link_timeout(bts, atoi(argv[0]));
2538
2539 return CMD_SUCCESS;
2540}
2541
2542DEFUN(cfg_bts_radio_link_timeout_inf, cfg_bts_radio_link_timeout_inf_cmd,
2543 "radio-link-timeout infinite",
2544 "Radio link timeout criterion (BTS side)\n"
2545 "Infinite Radio link timeout value (use only for BTS RF testing)\n")
2546{
2547 struct gsm_bts *bts = vty->index;
2548
2549 if (bts->type != GSM_BTS_TYPE_OSMOBTS) {
2550 vty_out(vty, "%% infinite radio link timeout not supported by this BTS%s", VTY_NEWLINE);
2551 return CMD_WARNING;
2552 }
2553
2554 vty_out(vty, "%% INFINITE RADIO LINK TIMEOUT, USE ONLY FOR BTS RF TESTING%s", VTY_NEWLINE);
2555 gsm_bts_set_radio_link_timeout(bts, -1);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01002556
Holger Hans Peter Freytherc63f6f12013-07-27 21:07:57 +02002557 return CMD_SUCCESS;
2558}
2559
Harald Welte8f0ed552010-05-11 21:53:49 +02002560#define GPRS_TEXT "GPRS Packet Network\n"
2561
Harald Welteaf387632010-03-14 23:30:30 +08002562DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
Harald Welte57ba7e32010-04-18 14:00:26 +02002563 "gprs cell bvci <2-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002564 GPRS_TEXT
2565 "GPRS Cell Settings\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02002566 "GPRS BSSGP VC Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002567 "GPRS BSSGP VC Identifier")
2568{
Pau Espin Pedrol8c209c92017-11-28 15:05:08 +01002569 /* ETSI TS 101 343: values 0 and 1 are reserved for signalling and PTM */
Harald Welte97a282b2010-03-14 15:37:43 +08002570 struct gsm_bts *bts = vty->index;
2571
Harald Welte4511d892010-04-18 15:51:20 +02002572 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002573 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2574 return CMD_WARNING;
2575 }
2576
Harald Welte97a282b2010-03-14 15:37:43 +08002577 bts->gprs.cell.bvci = atoi(argv[0]);
2578
2579 return CMD_SUCCESS;
2580}
2581
Harald Weltea5731cf2010-03-22 11:48:36 +08002582DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd,
2583 "gprs nsei <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002584 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002585 "GPRS NS Entity Identifier\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002586 "GPRS NS Entity Identifier")
2587{
2588 struct gsm_bts *bts = vty->index;
2589
Harald Welte4511d892010-04-18 15:51:20 +02002590 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Weltea5731cf2010-03-22 11:48:36 +08002591 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2592 return CMD_WARNING;
2593 }
2594
2595 bts->gprs.nse.nsei = atoi(argv[0]);
2596
2597 return CMD_SUCCESS;
2598}
2599
Harald Welte8f0ed552010-05-11 21:53:49 +02002600#define NSVC_TEXT "Network Service Virtual Connection (NS-VC)\n" \
2601 "NSVC Logical Number\n"
Harald Weltea5731cf2010-03-22 11:48:36 +08002602
Harald Welte97a282b2010-03-14 15:37:43 +08002603DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd,
2604 "gprs nsvc <0-1> nsvci <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002605 GPRS_TEXT NSVC_TEXT
2606 "NS Virtual Connection Identifier\n"
Harald Welte97a282b2010-03-14 15:37:43 +08002607 "GPRS NS VC Identifier")
2608{
2609 struct gsm_bts *bts = vty->index;
2610 int idx = atoi(argv[0]);
2611
Harald Welte4511d892010-04-18 15:51:20 +02002612 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002613 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2614 return CMD_WARNING;
2615 }
2616
Harald Welte97a282b2010-03-14 15:37:43 +08002617 bts->gprs.nsvc[idx].nsvci = atoi(argv[1]);
2618
2619 return CMD_SUCCESS;
2620}
2621
Harald Welteaf387632010-03-14 23:30:30 +08002622DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd,
2623 "gprs nsvc <0-1> local udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002624 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002625 "GPRS NS Local UDP Port\n"
2626 "GPRS NS Local UDP Port\n"
2627 "GPRS NS Local UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002628 "GPRS NS Local UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002629{
2630 struct gsm_bts *bts = vty->index;
2631 int idx = atoi(argv[0]);
2632
Harald Welte4511d892010-04-18 15:51:20 +02002633 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002634 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2635 return CMD_WARNING;
2636 }
2637
Harald Welteaf387632010-03-14 23:30:30 +08002638 bts->gprs.nsvc[idx].local_port = atoi(argv[1]);
2639
2640 return CMD_SUCCESS;
2641}
2642
2643DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd,
2644 "gprs nsvc <0-1> remote udp port <0-65535>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002645 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002646 "GPRS NS Remote UDP Port\n"
2647 "GPRS NS Remote UDP Port\n"
Harald Welte13fe2192012-08-17 09:57:25 +02002648 "GPRS NS Remote UDP Port\n"
2649 "GPRS NS Remote UDP Port Number\n")
Harald Welteaf387632010-03-14 23:30:30 +08002650{
2651 struct gsm_bts *bts = vty->index;
2652 int idx = atoi(argv[0]);
2653
Harald Welte4511d892010-04-18 15:51:20 +02002654 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002655 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2656 return CMD_WARNING;
2657 }
2658
Harald Welteaf387632010-03-14 23:30:30 +08002659 bts->gprs.nsvc[idx].remote_port = atoi(argv[1]);
2660
2661 return CMD_SUCCESS;
2662}
2663
2664DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd,
2665 "gprs nsvc <0-1> remote ip A.B.C.D",
Harald Welte8f0ed552010-05-11 21:53:49 +02002666 GPRS_TEXT NSVC_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002667 "GPRS NS Remote IP Address\n"
2668 "GPRS NS Remote IP Address\n"
2669 "GPRS NS Remote IP Address\n")
Harald Welteaf387632010-03-14 23:30:30 +08002670{
2671 struct gsm_bts *bts = vty->index;
2672 int idx = atoi(argv[0]);
2673 struct in_addr ia;
2674
Harald Welte4511d892010-04-18 15:51:20 +02002675 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002676 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2677 return CMD_WARNING;
2678 }
2679
Harald Welteaf387632010-03-14 23:30:30 +08002680 inet_aton(argv[1], &ia);
2681 bts->gprs.nsvc[idx].remote_ip = ntohl(ia.s_addr);
2682
2683 return CMD_SUCCESS;
2684}
2685
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002686DEFUN(cfg_bts_pag_free, cfg_bts_pag_free_cmd,
Harald Weltecfaabbb2012-08-16 23:23:50 +02002687 "paging free <-1-1024>",
2688 "Paging options\n"
2689 "Only page when having a certain amount of free slots\n"
2690 "amount of required free paging slots. -1 to disable\n")
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08002691{
2692 struct gsm_bts *bts = vty->index;
2693
2694 bts->paging.free_chans_need = atoi(argv[0]);
2695 return CMD_SUCCESS;
2696}
2697
Harald Welte615e9562010-05-11 23:50:21 +02002698DEFUN(cfg_bts_gprs_ns_timer, cfg_bts_gprs_ns_timer_cmd,
2699 "gprs ns timer " NS_TIMERS " <0-255>",
2700 GPRS_TEXT "Network Service\n"
2701 "Network Service Timer\n"
2702 NS_TIMERS_HELP "Timer Value\n")
2703{
2704 struct gsm_bts *bts = vty->index;
2705 int idx = get_string_value(gprs_ns_timer_strs, argv[0]);
2706 int val = atoi(argv[1]);
2707
2708 if (bts->gprs.mode == BTS_GPRS_NONE) {
2709 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2710 return CMD_WARNING;
2711 }
2712
2713 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.nse.timer))
2714 return CMD_WARNING;
2715
2716 bts->gprs.nse.timer[idx] = val;
2717
2718 return CMD_SUCCESS;
2719}
2720
2721#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 +02002722#define BSSGP_TIMERS_HELP \
2723 "Tbvc-block timeout\n" \
2724 "Tbvc-block retries\n" \
2725 "Tbvc-unblock retries\n" \
2726 "Tbvcc-reset timeout\n" \
2727 "Tbvc-reset retries\n" \
2728 "Tbvc-suspend timeout\n" \
2729 "Tbvc-suspend retries\n" \
2730 "Tbvc-resume timeout\n" \
2731 "Tbvc-resume retries\n" \
2732 "Tbvc-capa-update timeout\n" \
2733 "Tbvc-capa-update retries\n"
Harald Welte615e9562010-05-11 23:50:21 +02002734
2735DEFUN(cfg_bts_gprs_cell_timer, cfg_bts_gprs_cell_timer_cmd,
2736 "gprs cell timer " BSSGP_TIMERS " <0-255>",
2737 GPRS_TEXT "Cell / BSSGP\n"
2738 "Cell/BSSGP Timer\n"
2739 BSSGP_TIMERS_HELP "Timer Value\n")
2740{
2741 struct gsm_bts *bts = vty->index;
2742 int idx = get_string_value(gprs_bssgp_cfg_strs, argv[0]);
2743 int val = atoi(argv[1]);
2744
2745 if (bts->gprs.mode == BTS_GPRS_NONE) {
2746 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2747 return CMD_WARNING;
2748 }
2749
2750 if (idx < 0 || idx >= ARRAY_SIZE(bts->gprs.cell.timer))
2751 return CMD_WARNING;
2752
2753 bts->gprs.cell.timer[idx] = val;
2754
2755 return CMD_SUCCESS;
2756}
2757
Harald Welte97a282b2010-03-14 15:37:43 +08002758DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd,
2759 "gprs routing area <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02002760 GPRS_TEXT
Harald Weltecfaabbb2012-08-16 23:23:50 +02002761 "GPRS Routing Area Code\n"
2762 "GPRS Routing Area Code\n"
2763 "GPRS Routing Area Code\n")
Harald Welte97a282b2010-03-14 15:37:43 +08002764{
2765 struct gsm_bts *bts = vty->index;
2766
Harald Welte4511d892010-04-18 15:51:20 +02002767 if (bts->gprs.mode == BTS_GPRS_NONE) {
Harald Welte94036702010-03-14 23:56:56 +08002768 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2769 return CMD_WARNING;
2770 }
2771
Harald Welte97a282b2010-03-14 15:37:43 +08002772 bts->gprs.rac = atoi(argv[0]);
2773
2774 return CMD_SUCCESS;
2775}
2776
Max292ec582016-07-28 11:55:37 +02002777DEFUN(cfg_bts_gprs_ctrl_ack, cfg_bts_gprs_ctrl_ack_cmd,
2778 "gprs control-ack-type-rach", GPRS_TEXT
2779 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2780 "four access bursts format instead of default RLC/MAC control block\n")
2781{
2782 struct gsm_bts *bts = vty->index;
2783
2784 if (bts->gprs.mode == BTS_GPRS_NONE) {
2785 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2786 return CMD_WARNING;
2787 }
2788
2789 bts->gprs.ctrl_ack_type_use_block = false;
2790
2791 return CMD_SUCCESS;
2792}
2793
2794DEFUN(cfg_no_bts_gprs_ctrl_ack, cfg_no_bts_gprs_ctrl_ack_cmd,
2795 "no gprs control-ack-type-rach", NO_STR GPRS_TEXT
2796 "Set GPRS Control Ack Type for PACKET CONTROL ACKNOWLEDGMENT message to "
2797 "four access bursts format instead of default RLC/MAC control block\n")
2798{
2799 struct gsm_bts *bts = vty->index;
2800
2801 if (bts->gprs.mode == BTS_GPRS_NONE) {
2802 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2803 return CMD_WARNING;
2804 }
2805
2806 bts->gprs.ctrl_ack_type_use_block = true;
2807
2808 return CMD_SUCCESS;
2809}
2810
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01002811DEFUN(cfg_bts_gprs_net_ctrl_ord, cfg_bts_gprs_net_ctrl_ord_cmd,
2812 "gprs network-control-order (nc0|nc1|nc2)",
2813 GPRS_TEXT
2814 "GPRS Network Control Order\n"
2815 "MS controlled cell re-selection, no measurement reporting\n"
2816 "MS controlled cell re-selection, MS sends measurement reports\n"
2817 "Network controlled cell re-selection, MS sends measurement reports\n")
2818{
2819 struct gsm_bts *bts = vty->index;
2820
2821 if (bts->gprs.mode == BTS_GPRS_NONE) {
2822 vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
2823 return CMD_WARNING;
2824 }
2825
2826 bts->gprs.net_ctrl_ord = atoi(argv[0] + 2);
2827
2828 return CMD_SUCCESS;
2829}
2830
Harald Welte4511d892010-04-18 15:51:20 +02002831DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
2832 "gprs mode (none|gprs|egprs)",
Harald Welte8f0ed552010-05-11 21:53:49 +02002833 GPRS_TEXT
2834 "GPRS Mode for this BTS\n"
2835 "GPRS Disabled on this BTS\n"
2836 "GPRS Enabled on this BTS\n"
2837 "EGPRS (EDGE) Enabled on this BTS\n")
Harald Welteaf387632010-03-14 23:30:30 +08002838{
2839 struct gsm_bts *bts = vty->index;
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002840 enum bts_gprs_mode mode = bts_gprs_mode_parse(argv[0], NULL);
Harald Welteaf387632010-03-14 23:30:30 +08002841
Holger Hans Peter Freyther4e13a8f2015-01-31 22:16:00 +01002842 if (!bts_gprs_mode_is_compat(bts, mode)) {
Harald Weltef3d8e922010-06-14 22:44:42 +02002843 vty_out(vty, "This BTS type does not support %s%s", argv[0],
2844 VTY_NEWLINE);
2845 return CMD_WARNING;
2846 }
2847
2848 bts->gprs.mode = mode;
Harald Welteaf387632010-03-14 23:30:30 +08002849
2850 return CMD_SUCCESS;
2851}
2852
bhargava350533c2016-07-21 11:14:34 +05302853DEFUN(cfg_bts_gprs_11bit_rach_support_for_egprs,
2854 cfg_bts_gprs_11bit_rach_support_for_egprs_cmd,
2855 "gprs 11bit_rach_support_for_egprs (0|1)",
2856 GPRS_TEXT "11 bit RACH options\n"
2857 "Disable 11 bit RACH for EGPRS\n"
2858 "Enable 11 bit RACH for EGPRS")
2859{
2860 struct gsm_bts *bts = vty->index;
2861
2862 bts->gprs.supports_egprs_11bit_rach = atoi(argv[0]);
2863
2864 if (bts->gprs.supports_egprs_11bit_rach > 1) {
2865 vty_out(vty, "Error in RACH type%s", VTY_NEWLINE);
2866 return CMD_WARNING;
2867 }
2868
2869 if ((bts->gprs.mode == BTS_GPRS_NONE) &&
2870 (bts->gprs.supports_egprs_11bit_rach == 1)) {
2871 vty_out(vty, "Error:gprs mode is none and 11bit rach is"
2872 " enabled%s", VTY_NEWLINE);
2873 return CMD_WARNING;
2874 }
2875
2876 return CMD_SUCCESS;
2877}
2878
Harald Welte9fbff4a2010-07-30 11:50:09 +02002879#define SI_TEXT "System Information Messages\n"
2880#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)"
2881#define SI_TYPE_HELP "System Information Type 1\n" \
2882 "System Information Type 2\n" \
2883 "System Information Type 3\n" \
2884 "System Information Type 4\n" \
2885 "System Information Type 5\n" \
2886 "System Information Type 6\n" \
2887 "System Information Type 7\n" \
2888 "System Information Type 8\n" \
2889 "System Information Type 9\n" \
2890 "System Information Type 10\n" \
2891 "System Information Type 13\n" \
2892 "System Information Type 16\n" \
2893 "System Information Type 17\n" \
2894 "System Information Type 18\n" \
2895 "System Information Type 19\n" \
2896 "System Information Type 20\n" \
2897 "System Information Type 2bis\n" \
2898 "System Information Type 2ter\n" \
2899 "System Information Type 2quater\n" \
2900 "System Information Type 5bis\n" \
2901 "System Information Type 5ter\n"
2902
2903DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
2904 "system-information " SI_TYPE_TEXT " mode (static|computed)",
2905 SI_TEXT SI_TYPE_HELP
2906 "System Information Mode\n"
2907 "Static user-specified\n"
2908 "Dynamic, BSC-computed\n")
2909{
2910 struct gsm_bts *bts = vty->index;
2911 int type;
2912
2913 type = get_string_value(osmo_sitype_strs, argv[0]);
2914 if (type < 0) {
2915 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2916 return CMD_WARNING;
2917 }
2918
2919 if (!strcmp(argv[1], "static"))
2920 bts->si_mode_static |= (1 << type);
2921 else
2922 bts->si_mode_static &= ~(1 << type);
2923
2924 return CMD_SUCCESS;
2925}
2926
2927DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
2928 "system-information " SI_TYPE_TEXT " static HEXSTRING",
2929 SI_TEXT SI_TYPE_HELP
2930 "Static System Information filling\n"
2931 "Static user-specified SI content in HEX notation\n")
2932{
2933 struct gsm_bts *bts = vty->index;
2934 int rc, type;
2935
2936 type = get_string_value(osmo_sitype_strs, argv[0]);
2937 if (type < 0) {
2938 vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
2939 return CMD_WARNING;
2940 }
2941
2942 if (!(bts->si_mode_static & (1 << type))) {
2943 vty_out(vty, "SI Type %s is not configured in static mode%s",
2944 get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
2945 return CMD_WARNING;
2946 }
2947
Harald Welte290aaed2010-07-30 11:53:18 +02002948 /* Fill buffer with padding pattern */
Max6f0e50c2017-04-12 15:30:54 +02002949 memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN);
Harald Welte290aaed2010-07-30 11:53:18 +02002950
2951 /* Parse the user-specified SI in hex format, [partially] overwriting padding */
Max6f0e50c2017-04-12 15:30:54 +02002952 rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN);
2953 if (rc < 0 || rc > GSM_MACBLOCK_LEN) {
Harald Welte9fbff4a2010-07-30 11:50:09 +02002954 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
2955 return CMD_WARNING;
2956 }
2957
2958 /* Mark this SI as present */
2959 bts->si_valid |= (1 << type);
2960
2961 return CMD_SUCCESS;
2962}
2963
Harald Welte42def722017-01-13 00:10:32 +01002964DEFUN(cfg_bts_early_cm, cfg_bts_early_cm_cmd,
2965 "early-classmark-sending (allowed|forbidden)",
2966 "Early Classmark Sending\n"
2967 "Early Classmark Sending is allowed\n"
2968 "Early Classmark Sending is forbidden\n")
2969{
2970 struct gsm_bts *bts = vty->index;
Harald Welte42def722017-01-13 00:10:32 +01002971
2972 if (!strcmp(argv[0], "allowed"))
2973 bts->early_classmark_allowed = true;
2974 else
2975 bts->early_classmark_allowed = false;
2976
2977 return CMD_SUCCESS;
2978}
2979
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01002980DEFUN(cfg_bts_early_cm_3g, cfg_bts_early_cm_3g_cmd,
2981 "early-classmark-sending-3g (allowed|forbidden)",
2982 "3G Early Classmark Sending\n"
2983 "3G Early Classmark Sending is allowed\n"
2984 "3G Early Classmark Sending is forbidden\n")
2985{
2986 struct gsm_bts *bts = vty->index;
2987
2988 if (!strcmp(argv[0], "allowed"))
2989 bts->early_classmark_allowed_3g = true;
2990 else
2991 bts->early_classmark_allowed_3g = false;
2992
2993 return CMD_SUCCESS;
2994}
2995
Harald Welte32c09622011-01-11 23:44:56 +01002996DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
Harald Welte64c07d22011-02-15 11:43:27 +01002997 "neighbor-list mode (automatic|manual|manual-si5)",
Harald Welte32c09622011-01-11 23:44:56 +01002998 "Neighbor List\n" "Mode of Neighbor List generation\n"
Harald Welte64c07d22011-02-15 11:43:27 +01002999 "Automatically from all BTS in this OpenBSC\n" "Manual\n"
3000 "Manual with different lists for SI2 and SI5\n")
Harald Welte32c09622011-01-11 23:44:56 +01003001{
3002 struct gsm_bts *bts = vty->index;
Harald Welte64c07d22011-02-15 11:43:27 +01003003 int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
Harald Welte32c09622011-01-11 23:44:56 +01003004
Harald Welte64c07d22011-02-15 11:43:27 +01003005 switch (mode) {
3006 case NL_MODE_MANUAL_SI5SEP:
3007 case NL_MODE_MANUAL:
Harald Welte32c09622011-01-11 23:44:56 +01003008 /* make sure we clear the current list when switching to
3009 * manual mode */
3010 if (bts->neigh_list_manual_mode == 0)
3011 memset(&bts->si_common.data.neigh_list, 0,
3012 sizeof(bts->si_common.data.neigh_list));
Harald Welte64c07d22011-02-15 11:43:27 +01003013 break;
3014 default:
3015 break;
3016 }
3017
3018 bts->neigh_list_manual_mode = mode;
Harald Welte32c09622011-01-11 23:44:56 +01003019
3020 return CMD_SUCCESS;
3021}
3022
3023DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003024 "neighbor-list (add|del) arfcn <0-1023>",
Harald Welte32c09622011-01-11 23:44:56 +01003025 "Neighbor List\n" "Add to manual neighbor list\n"
3026 "Delete from manual neighbor list\n" "ARFCN of neighbor\n"
3027 "ARFCN of neighbor\n")
3028{
3029 struct gsm_bts *bts = vty->index;
3030 struct bitvec *bv = &bts->si_common.neigh_list;
3031 uint16_t arfcn = atoi(argv[1]);
3032
3033 if (!bts->neigh_list_manual_mode) {
3034 vty_out(vty, "%% Cannot configure neighbor list in "
3035 "automatic mode%s", VTY_NEWLINE);
3036 return CMD_WARNING;
3037 }
3038
3039 if (!strcmp(argv[0], "add"))
3040 bitvec_set_bit_pos(bv, arfcn, 1);
3041 else
3042 bitvec_set_bit_pos(bv, arfcn, 0);
3043
3044 return CMD_SUCCESS;
3045}
3046
Max70fdd242017-06-15 15:10:53 +02003047/* help text should be kept in sync with EARFCN_*_INVALID defines */
Max59a1bf32016-04-15 16:04:46 +02003048DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
Max2c16bee2017-02-15 13:51:37 +01003049 "si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
3050 "thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
3051 "SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
3052 "Add to manual SI2quater neighbor list\n"
3053 "EARFCN of neighbor\n" "EARFCN of neighbor\n"
3054 "threshold high bits\n" "threshold high bits\n"
3055 "threshold low bits\n" "threshold low bits (32 means NA)\n"
3056 "priority\n" "priority (8 means NA)\n"
3057 "QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
3058 "measurement bandwidth\n" "measurement bandwidth (8 means NA)\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;
3062 uint16_t arfcn = atoi(argv[0]);
Max2c16bee2017-02-15 13:51:37 +01003063 uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
3064 prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
Max70fdd242017-06-15 15:10:53 +02003065 int r = bts_earfcn_add(bts, arfcn, thresh_hi, thresh_lo, prio, qrx, meas);
Max59a1bf32016-04-15 16:04:46 +02003066
Max70fdd242017-06-15 15:10:53 +02003067 switch (r) {
3068 case 1:
3069 vty_out(vty, "Warning: multiple threshold-high are not supported, overriding with %u%s",
3070 thresh_hi, VTY_NEWLINE);
3071 break;
3072 case EARFCN_THRESH_LOW_INVALID:
3073 vty_out(vty, "Warning: multiple threshold-low are not supported, overriding with %u%s",
3074 thresh_lo, VTY_NEWLINE);
3075 break;
3076 case EARFCN_QRXLV_INVALID + 1:
3077 vty_out(vty, "Warning: multiple QRXLEVMIN are not supported, overriding with %u%s",
3078 qrx, VTY_NEWLINE);
3079 break;
3080 case EARFCN_PRIO_INVALID:
3081 vty_out(vty, "Warning: multiple priorities are not supported, overriding with %u%s",
3082 prio, VTY_NEWLINE);
3083 break;
3084 default:
3085 if (r < 0) {
3086 vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r), VTY_NEWLINE);
3087 return CMD_WARNING;
3088 }
Max59a1bf32016-04-15 16:04:46 +02003089 }
3090
Max70fdd242017-06-15 15:10:53 +02003091 if (si2q_num(bts) <= SI2Q_MAX_NUM)
Max2c16bee2017-02-15 13:51:37 +01003092 return CMD_SUCCESS;
3093
Maxf39d03a2017-05-12 17:00:30 +02003094 vty_out(vty, "Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s",
Max70fdd242017-06-15 15:10:53 +02003095 bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE);
Maxaafff962016-04-20 15:57:14 +02003096 osmo_earfcn_del(e, arfcn);
Max2c16bee2017-02-15 13:51:37 +01003097
Maxaafff962016-04-20 15:57:14 +02003098 return CMD_WARNING;
Max59a1bf32016-04-15 16:04:46 +02003099}
3100
3101DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd,
Max35697b92016-04-29 12:51:31 +02003102 "si2quater neighbor-list del earfcn <0-65535>",
Max59a1bf32016-04-15 16:04:46 +02003103 "SI2quater Neighbor List\n"
3104 "SI2quater Neighbor List\n"
3105 "Delete from SI2quater manual neighbor list\n"
Max36212f22016-04-20 12:06:05 +02003106 "EARFCN of neighbor\n"
3107 "EARFCN\n")
Max59a1bf32016-04-15 16:04:46 +02003108{
3109 struct gsm_bts *bts = vty->index;
3110 struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
Max0c1bc262016-04-20 12:06:06 +02003111 uint16_t arfcn = atoi(argv[0]);
Max59a1bf32016-04-15 16:04:46 +02003112 int r = osmo_earfcn_del(e, arfcn);
3113 if (r < 0) {
3114 vty_out(vty, "Unable to delete arfcn %u: %s%s", arfcn,
Max0c1bc262016-04-20 12:06:06 +02003115 strerror(-r), VTY_NEWLINE);
Max59a1bf32016-04-15 16:04:46 +02003116 return CMD_WARNING;
3117 }
3118
3119 return CMD_SUCCESS;
3120}
3121
Max26679e02016-04-20 15:57:13 +02003122DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd,
Max35697b92016-04-29 12:51:31 +02003123 "si2quater neighbor-list add uarfcn <0-16383> <0-511> <0-1>",
Max26679e02016-04-20 15:57:13 +02003124 "SI2quater Neighbor List\n"
3125 "SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
3126 "UARFCN of neighbor\n" "UARFCN of neighbor\n" "scrambling code\n"
3127 "diversity bit\n")
3128{
3129 struct gsm_bts *bts = vty->index;
3130 uint16_t arfcn = atoi(argv[0]), scramble = atoi(argv[1]);
3131
3132 switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv[2]))) {
3133 case -ENOMEM:
Max70fdd242017-06-15 15:10:53 +02003134 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 +01003135 return CMD_WARNING;
Maxaafff962016-04-20 15:57:14 +02003136 case -ENOSPC:
Max70fdd242017-06-15 15:10:53 +02003137 vty_out(vty, "Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s",
3138 arfcn, scramble, VTY_NEWLINE);
Harald Weltea191dcd2016-11-26 15:06:37 +01003139 return CMD_WARNING;
Max26679e02016-04-20 15:57:13 +02003140 case -EADDRINUSE:
Max70fdd242017-06-15 15:10:53 +02003141 vty_out(vty, "Unable to add UARFCN: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE);
Max26679e02016-04-20 15:57:13 +02003142 return CMD_WARNING;
3143 }
3144
3145 return CMD_SUCCESS;
3146}
3147
3148DEFUN(cfg_bts_si2quater_uarfcn_del, cfg_bts_si2quater_uarfcn_del_cmd,
Max35697b92016-04-29 12:51:31 +02003149 "si2quater neighbor-list del uarfcn <0-16383> <0-511>",
Max26679e02016-04-20 15:57:13 +02003150 "SI2quater Neighbor List\n"
3151 "SI2quater Neighbor List\n"
3152 "Delete from SI2quater manual neighbor list\n"
3153 "UARFCN of neighbor\n"
3154 "UARFCN\n"
3155 "scrambling code\n")
3156{
3157 struct gsm_bts *bts = vty->index;
3158
3159 if (bts_uarfcn_del(bts, atoi(argv[0]), atoi(argv[1])) < 0) {
3160 vty_out(vty, "Unable to delete uarfcn: pair not found%s",
3161 VTY_NEWLINE);
3162 return CMD_WARNING;
3163 }
3164
3165 return CMD_SUCCESS;
3166}
3167
Harald Welte64c07d22011-02-15 11:43:27 +01003168DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003169 "si5 neighbor-list (add|del) arfcn <0-1023>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003170 "SI5 Neighbor List\n"
Harald Welte64c07d22011-02-15 11:43:27 +01003171 "SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
3172 "Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
3173 "ARFCN of neighbor\n")
3174{
3175 struct gsm_bts *bts = vty->index;
3176 struct bitvec *bv = &bts->si_common.si5_neigh_list;
3177 uint16_t arfcn = atoi(argv[1]);
3178
3179 if (!bts->neigh_list_manual_mode) {
3180 vty_out(vty, "%% Cannot configure neighbor list in "
3181 "automatic mode%s", VTY_NEWLINE);
3182 return CMD_WARNING;
3183 }
3184
3185 if (!strcmp(argv[0], "add"))
3186 bitvec_set_bit_pos(bv, arfcn, 1);
3187 else
3188 bitvec_set_bit_pos(bv, arfcn, 0);
3189
3190 return CMD_SUCCESS;
3191}
Harald Welte9fbff4a2010-07-30 11:50:09 +02003192
Harald Welte8254cf72017-05-29 13:42:19 +02003193DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
3194 "pcu-socket PATH",
3195 "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n"
3196 "Path in the file system for the unix-domain PCU socket\n")
3197{
3198 struct gsm_bts *bts = vty->index;
3199 int rc;
3200
Harald Welte4a824ca2017-05-29 13:54:27 +02003201 osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv[0]);
Harald Welte8254cf72017-05-29 13:42:19 +02003202 pcu_sock_exit(bts);
3203 rc = pcu_sock_init(bts->pcu_sock_path, bts);
3204 if (rc < 0) {
3205 vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s",
3206 bts->pcu_sock_path, bts->nr, VTY_NEWLINE);
3207 return CMD_WARNING;
3208 }
3209
3210 return CMD_SUCCESS;
3211}
3212
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02003213#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
3214
3215DEFUN(cfg_bts_excl_rf_lock,
3216 cfg_bts_excl_rf_lock_cmd,
3217 "rf-lock-exclude",
3218 EXCL_RFLOCK_STR)
3219{
3220 struct gsm_bts *bts = vty->index;
3221 bts->excl_from_rf_lock = 1;
3222 return CMD_SUCCESS;
3223}
3224
3225DEFUN(cfg_bts_no_excl_rf_lock,
3226 cfg_bts_no_excl_rf_lock_cmd,
3227 "no rf-lock-exclude",
3228 NO_STR EXCL_RFLOCK_STR)
3229{
3230 struct gsm_bts *bts = vty->index;
3231 bts->excl_from_rf_lock = 0;
3232 return CMD_SUCCESS;
3233}
3234
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01003235#define FORCE_COMB_SI_STR "Force the generation of a single SI (no ter/bis)\n"
3236
3237DEFUN(cfg_bts_force_comb_si,
3238 cfg_bts_force_comb_si_cmd,
3239 "force-combined-si",
3240 FORCE_COMB_SI_STR)
3241{
3242 struct gsm_bts *bts = vty->index;
3243 bts->force_combined_si = 1;
3244 return CMD_SUCCESS;
3245}
3246
3247DEFUN(cfg_bts_no_force_comb_si,
3248 cfg_bts_no_force_comb_si_cmd,
3249 "no force-combined-si",
3250 NO_STR FORCE_COMB_SI_STR)
3251{
3252 struct gsm_bts *bts = vty->index;
3253 bts->force_combined_si = 0;
3254 return CMD_SUCCESS;
3255}
3256
Andreas Eversberga83d5112013-12-07 18:32:28 +01003257static void _get_codec_from_arg(struct vty *vty, int argc, const char *argv[])
3258{
3259 struct gsm_bts *bts = vty->index;
3260 struct bts_codec_conf *codec = &bts->codec;
3261 int i;
3262
3263 codec->hr = 0;
3264 codec->efr = 0;
3265 codec->amr = 0;
3266 for (i = 0; i < argc; i++) {
3267 if (!strcmp(argv[i], "hr"))
3268 codec->hr = 1;
3269 if (!strcmp(argv[i], "efr"))
3270 codec->efr = 1;
3271 if (!strcmp(argv[i], "amr"))
3272 codec->amr = 1;
3273 }
3274}
3275
3276#define CODEC_PAR_STR " (hr|efr|amr)"
3277#define CODEC_HELP_STR "Half Rate\n" \
3278 "Enhanced Full Rate\nAdaptive Multirate\n"
3279
3280DEFUN(cfg_bts_codec0, cfg_bts_codec0_cmd,
3281 "codec-support fr",
3282 "Codec Support settings\nFullrate\n")
3283{
3284 _get_codec_from_arg(vty, 0, argv);
3285 return CMD_SUCCESS;
3286}
3287
3288DEFUN(cfg_bts_codec1, cfg_bts_codec1_cmd,
3289 "codec-support fr" CODEC_PAR_STR,
3290 "Codec Support settings\nFullrate\n"
3291 CODEC_HELP_STR)
3292{
3293 _get_codec_from_arg(vty, 1, argv);
3294 return CMD_SUCCESS;
3295}
3296
3297DEFUN(cfg_bts_codec2, cfg_bts_codec2_cmd,
3298 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR,
3299 "Codec Support settings\nFullrate\n"
3300 CODEC_HELP_STR CODEC_HELP_STR)
3301{
3302 _get_codec_from_arg(vty, 2, argv);
3303 return CMD_SUCCESS;
3304}
3305
3306DEFUN(cfg_bts_codec3, cfg_bts_codec3_cmd,
3307 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3308 "Codec Support settings\nFullrate\n"
3309 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3310{
3311 _get_codec_from_arg(vty, 3, argv);
3312 return CMD_SUCCESS;
3313}
3314
3315DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
3316 "codec-support fr" CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR CODEC_PAR_STR,
3317 "Codec Support settings\nFullrate\n"
3318 CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR CODEC_HELP_STR)
3319{
3320 _get_codec_from_arg(vty, 4, argv);
3321 return CMD_SUCCESS;
3322}
3323
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003324DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
3325 "depends-on-bts <0-255>",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003326 "This BTS can only be started if another one is up\n"
3327 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003328{
3329 struct gsm_bts *bts = vty->index;
3330 struct gsm_bts *other_bts;
3331 int dep = atoi(argv[0]);
3332
3333
3334 if (!is_ipaccess_bts(bts)) {
3335 vty_out(vty, "This feature is only available for IP systems.%s",
3336 VTY_NEWLINE);
3337 return CMD_WARNING;
3338 }
3339
3340 other_bts = gsm_bts_num(bts->network, dep);
3341 if (!other_bts || !is_ipaccess_bts(other_bts)) {
3342 vty_out(vty, "This feature is only available for IP systems.%s",
3343 VTY_NEWLINE);
3344 return CMD_WARNING;
3345 }
3346
3347 if (dep >= bts->nr) {
3348 vty_out(vty, "%%Need to depend on an already declared unit.%s",
3349 VTY_NEWLINE);
3350 return CMD_WARNING;
3351 }
3352
3353 bts_depend_mark(bts, dep);
3354 return CMD_SUCCESS;
3355}
3356
3357DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
3358 "depeneds-on-bts <0-255>",
3359 NO_STR "This BTS can only be started if another one is up\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01003360 BTS_NR_STR)
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01003361{
3362 struct gsm_bts *bts = vty->index;
3363 int dep = atoi(argv[0]);
3364
3365 bts_depend_clear(bts, dep);
3366 return CMD_SUCCESS;
3367}
3368
Andreas Eversberg73266522014-01-19 11:47:44 +01003369#define AMR_TEXT "Adaptive Multi Rate settings\n"
3370#define AMR_MODE_TEXT "Codec modes to use with AMR codec\n"
3371#define AMR_START_TEXT "Initial codec to use with AMR\n" \
3372 "Automatically\nFirst codec\nSecond codec\nThird codec\nFourth codec\n"
3373#define AMR_TH_TEXT "AMR threshold between codecs\nMS side\nBTS side\n"
3374#define AMR_HY_TEXT "AMR hysteresis between codecs\nMS side\nBTS side\n"
3375
3376static void get_amr_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3377{
3378 struct gsm_bts *bts = vty->index;
3379 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3380 struct gsm48_multi_rate_conf *mr_conf =
3381 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3382 int i;
3383
3384 mr->gsm48_ie[1] = 0;
3385 for (i = 0; i < argc; i++)
3386 mr->gsm48_ie[1] |= 1 << atoi(argv[i]);
3387 mr_conf->icmi = 0;
3388}
3389
3390static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3391{
3392 struct gsm_bts *bts = vty->index;
3393 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003394 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003395 int i;
3396
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003397 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3398 for (i = 0; i < argc - 1; i++)
3399 modes[i].threshold = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003400}
3401
3402static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full)
3403{
3404 struct gsm_bts *bts = vty->index;
3405 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003406 struct amr_mode *modes;
Andreas Eversberg73266522014-01-19 11:47:44 +01003407 int i;
3408
Holger Hans Peter Freythera174a472015-09-24 11:39:38 +02003409 modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode;
3410 for (i = 0; i < argc - 1; i++)
3411 modes[i].hysteresis = atoi(argv[i + 1]);
Andreas Eversberg73266522014-01-19 11:47:44 +01003412}
3413
3414static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full)
3415{
3416 struct gsm_bts *bts = vty->index;
3417 struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half;
3418 struct gsm48_multi_rate_conf *mr_conf =
3419 (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
3420 int num = 0, i;
3421
3422 for (i = 0; i < ((full) ? 8 : 6); i++) {
3423 if ((mr->gsm48_ie[1] & (1 << i))) {
3424 num++;
3425 }
3426 }
3427
3428 if (argv[0][0] == 'a' || num == 0)
3429 mr_conf->icmi = 0;
3430 else {
3431 mr_conf->icmi = 1;
3432 if (num < atoi(argv[0]))
3433 mr_conf->smod = num - 1;
3434 else
3435 mr_conf->smod = atoi(argv[0]) - 1;
3436 }
3437}
3438
3439#define AMR_TCHF_PAR_STR " (0|1|2|3|4|5|6|7)"
3440#define AMR_TCHF_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n" \
3441 "10,2k\n12,2k\n"
3442
3443#define AMR_TCHH_PAR_STR " (0|1|2|3|4|5)"
3444#define AMR_TCHH_HELP_STR "4,75k\n5,15k\n5,90k\n6,70k\n7,40k\n7,95k\n"
3445
3446#define AMR_TH_HELP_STR "Threshold between codec 1 and 2\n"
3447#define AMR_HY_HELP_STR "Hysteresis between codec 1 and 2\n"
3448
3449DEFUN(cfg_bts_amr_fr_modes1, cfg_bts_amr_fr_modes1_cmd,
3450 "amr tch-f modes" AMR_TCHF_PAR_STR,
3451 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3452 AMR_TCHF_HELP_STR)
3453{
3454 get_amr_from_arg(vty, 1, argv, 1);
3455 return CMD_SUCCESS;
3456}
3457
3458DEFUN(cfg_bts_amr_fr_modes2, cfg_bts_amr_fr_modes2_cmd,
3459 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3460 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3461 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3462{
3463 get_amr_from_arg(vty, 2, argv, 1);
3464 return CMD_SUCCESS;
3465}
3466
3467DEFUN(cfg_bts_amr_fr_modes3, cfg_bts_amr_fr_modes3_cmd,
3468 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3469 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3470 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3471{
3472 get_amr_from_arg(vty, 3, argv, 1);
3473 return CMD_SUCCESS;
3474}
3475
3476DEFUN(cfg_bts_amr_fr_modes4, cfg_bts_amr_fr_modes4_cmd,
3477 "amr tch-f modes" AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR AMR_TCHF_PAR_STR,
3478 AMR_TEXT "Full Rate\n" AMR_MODE_TEXT
3479 AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR AMR_TCHF_HELP_STR)
3480{
3481 get_amr_from_arg(vty, 4, argv, 1);
3482 return CMD_SUCCESS;
3483}
3484
3485DEFUN(cfg_bts_amr_fr_start_mode, cfg_bts_amr_fr_start_mode_cmd,
3486 "amr tch-f start-mode (auto|1|2|3|4)",
3487 AMR_TEXT "Full Rate\n" AMR_START_TEXT)
3488{
3489 get_amr_start_from_arg(vty, argv, 1);
3490 return CMD_SUCCESS;
3491}
3492
3493DEFUN(cfg_bts_amr_fr_thres1, cfg_bts_amr_fr_thres1_cmd,
3494 "amr tch-f threshold (ms|bts) <0-63>",
3495 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3496 AMR_TH_HELP_STR)
3497{
3498 get_amr_th_from_arg(vty, 2, argv, 1);
3499 return CMD_SUCCESS;
3500}
3501
3502DEFUN(cfg_bts_amr_fr_thres2, cfg_bts_amr_fr_thres2_cmd,
3503 "amr tch-f threshold (ms|bts) <0-63> <0-63>",
3504 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3505 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3506{
3507 get_amr_th_from_arg(vty, 3, argv, 1);
3508 return CMD_SUCCESS;
3509}
3510
3511DEFUN(cfg_bts_amr_fr_thres3, cfg_bts_amr_fr_thres3_cmd,
3512 "amr tch-f threshold (ms|bts) <0-63> <0-63> <0-63>",
3513 AMR_TEXT "Full Rate\n" AMR_TH_TEXT
3514 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3515{
3516 get_amr_th_from_arg(vty, 4, argv, 1);
3517 return CMD_SUCCESS;
3518}
3519
3520DEFUN(cfg_bts_amr_fr_hyst1, cfg_bts_amr_fr_hyst1_cmd,
3521 "amr tch-f hysteresis (ms|bts) <0-15>",
3522 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3523 AMR_HY_HELP_STR)
3524{
3525 get_amr_hy_from_arg(vty, 2, argv, 1);
3526 return CMD_SUCCESS;
3527}
3528
3529DEFUN(cfg_bts_amr_fr_hyst2, cfg_bts_amr_fr_hyst2_cmd,
3530 "amr tch-f hysteresis (ms|bts) <0-15> <0-15>",
3531 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3532 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3533{
3534 get_amr_hy_from_arg(vty, 3, argv, 1);
3535 return CMD_SUCCESS;
3536}
3537
3538DEFUN(cfg_bts_amr_fr_hyst3, cfg_bts_amr_fr_hyst3_cmd,
3539 "amr tch-f hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3540 AMR_TEXT "Full Rate\n" AMR_HY_TEXT
3541 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3542{
3543 get_amr_hy_from_arg(vty, 4, argv, 1);
3544 return CMD_SUCCESS;
3545}
3546
3547DEFUN(cfg_bts_amr_hr_modes1, cfg_bts_amr_hr_modes1_cmd,
3548 "amr tch-h modes" AMR_TCHH_PAR_STR,
3549 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3550 AMR_TCHH_HELP_STR)
3551{
3552 get_amr_from_arg(vty, 1, argv, 0);
3553 return CMD_SUCCESS;
3554}
3555
3556DEFUN(cfg_bts_amr_hr_modes2, cfg_bts_amr_hr_modes2_cmd,
3557 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3558 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3559 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3560{
3561 get_amr_from_arg(vty, 2, argv, 0);
3562 return CMD_SUCCESS;
3563}
3564
3565DEFUN(cfg_bts_amr_hr_modes3, cfg_bts_amr_hr_modes3_cmd,
3566 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3567 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3568 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3569{
3570 get_amr_from_arg(vty, 3, argv, 0);
3571 return CMD_SUCCESS;
3572}
3573
3574DEFUN(cfg_bts_amr_hr_modes4, cfg_bts_amr_hr_modes4_cmd,
3575 "amr tch-h modes" AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR AMR_TCHH_PAR_STR,
3576 AMR_TEXT "Half Rate\n" AMR_MODE_TEXT
3577 AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR AMR_TCHH_HELP_STR)
3578{
3579 get_amr_from_arg(vty, 4, argv, 0);
3580 return CMD_SUCCESS;
3581}
3582
3583DEFUN(cfg_bts_amr_hr_start_mode, cfg_bts_amr_hr_start_mode_cmd,
3584 "amr tch-h start-mode (auto|1|2|3|4)",
3585 AMR_TEXT "Half Rate\n" AMR_START_TEXT)
3586{
3587 get_amr_start_from_arg(vty, argv, 0);
3588 return CMD_SUCCESS;
3589}
3590
3591DEFUN(cfg_bts_amr_hr_thres1, cfg_bts_amr_hr_thres1_cmd,
3592 "amr tch-h threshold (ms|bts) <0-63>",
3593 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3594 AMR_TH_HELP_STR)
3595{
3596 get_amr_th_from_arg(vty, 2, argv, 0);
3597 return CMD_SUCCESS;
3598}
3599
3600DEFUN(cfg_bts_amr_hr_thres2, cfg_bts_amr_hr_thres2_cmd,
3601 "amr tch-h threshold (ms|bts) <0-63> <0-63>",
3602 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3603 AMR_TH_HELP_STR AMR_TH_HELP_STR)
3604{
3605 get_amr_th_from_arg(vty, 3, argv, 0);
3606 return CMD_SUCCESS;
3607}
3608
3609DEFUN(cfg_bts_amr_hr_thres3, cfg_bts_amr_hr_thres3_cmd,
3610 "amr tch-h threshold (ms|bts) <0-63> <0-63> <0-63>",
3611 AMR_TEXT "Half Rate\n" AMR_TH_TEXT
3612 AMR_TH_HELP_STR AMR_TH_HELP_STR AMR_TH_HELP_STR)
3613{
3614 get_amr_th_from_arg(vty, 4, argv, 0);
3615 return CMD_SUCCESS;
3616}
3617
3618DEFUN(cfg_bts_amr_hr_hyst1, cfg_bts_amr_hr_hyst1_cmd,
3619 "amr tch-h hysteresis (ms|bts) <0-15>",
3620 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3621 AMR_HY_HELP_STR)
3622{
3623 get_amr_hy_from_arg(vty, 2, argv, 0);
3624 return CMD_SUCCESS;
3625}
3626
3627DEFUN(cfg_bts_amr_hr_hyst2, cfg_bts_amr_hr_hyst2_cmd,
3628 "amr tch-h hysteresis (ms|bts) <0-15> <0-15>",
3629 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3630 AMR_HY_HELP_STR AMR_HY_HELP_STR)
3631{
3632 get_amr_hy_from_arg(vty, 3, argv, 0);
3633 return CMD_SUCCESS;
3634}
3635
3636DEFUN(cfg_bts_amr_hr_hyst3, cfg_bts_amr_hr_hyst3_cmd,
3637 "amr tch-h hysteresis (ms|bts) <0-15> <0-15> <0-15>",
3638 AMR_TEXT "Half Rate\n" AMR_HY_TEXT
3639 AMR_HY_HELP_STR AMR_HY_HELP_STR AMR_HY_HELP_STR)
3640{
3641 get_amr_hy_from_arg(vty, 4, argv, 0);
3642 return CMD_SUCCESS;
3643}
3644
Harald Welte8f0ed552010-05-11 21:53:49 +02003645#define TRX_TEXT "Radio Transceiver\n"
Harald Welte7a8fa412009-08-10 13:48:16 +02003646
Harald Welte5258fc42009-03-28 19:07:53 +00003647/* per TRX configuration */
3648DEFUN(cfg_trx,
3649 cfg_trx_cmd,
Harald Welte57e07242012-08-17 12:50:14 +02003650 "trx <0-255>",
Harald Welte8f0ed552010-05-11 21:53:49 +02003651 TRX_TEXT
Harald Welte5258fc42009-03-28 19:07:53 +00003652 "Select a TRX to configure")
3653{
3654 int trx_nr = atoi(argv[0]);
3655 struct gsm_bts *bts = vty->index;
3656 struct gsm_bts_trx *trx;
3657
Harald Weltee441d9c2009-06-21 16:17:15 +02003658 if (trx_nr > bts->num_trx) {
3659 vty_out(vty, "%% The next unused TRX number in this BTS is %u%s",
3660 bts->num_trx, VTY_NEWLINE);
Harald Welte5258fc42009-03-28 19:07:53 +00003661 return CMD_WARNING;
Harald Weltee441d9c2009-06-21 16:17:15 +02003662 } else if (trx_nr == bts->num_trx) {
3663 /* we need to allocate a new one */
3664 trx = gsm_bts_trx_alloc(bts);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003665 } else
Harald Weltee441d9c2009-06-21 16:17:15 +02003666 trx = gsm_bts_trx_num(bts, trx_nr);
Holger Hans Peter Freytheracf8a0c2010-03-29 08:47:44 +02003667
Harald Weltee441d9c2009-06-21 16:17:15 +02003668 if (!trx)
3669 return CMD_WARNING;
Harald Welte5258fc42009-03-28 19:07:53 +00003670
3671 vty->index = trx;
Harald Welte197dea92010-05-14 17:59:53 +02003672 vty->index_sub = &trx->description;
Harald Welte5258fc42009-03-28 19:07:53 +00003673 vty->node = TRX_NODE;
3674
3675 return CMD_SUCCESS;
3676}
3677
3678DEFUN(cfg_trx_arfcn,
3679 cfg_trx_arfcn_cmd,
Harald Welte1fe73a12012-01-29 13:24:12 +01003680 "arfcn <0-1023>",
Harald Welte13fe2192012-08-17 09:57:25 +02003681 "Set the ARFCN for this TRX\n"
3682 "Absolute Radio Frequency Channel Number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003683{
3684 int arfcn = atoi(argv[0]);
3685 struct gsm_bts_trx *trx = vty->index;
3686
3687 /* FIXME: check if this ARFCN is supported by this TRX */
3688
3689 trx->arfcn = arfcn;
3690
3691 /* FIXME: patch ARFCN into SYSTEM INFORMATION */
3692 /* FIXME: use OML layer to update the ARFCN */
3693 /* FIXME: use RSL layer to update SYSTEM INFORMATION */
3694
3695 return CMD_SUCCESS;
3696}
3697
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003698DEFUN(cfg_trx_nominal_power,
3699 cfg_trx_nominal_power_cmd,
3700 "nominal power <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003701 "Nominal TRX RF Power in dBm\n"
3702 "Nominal TRX RF Power in dBm\n"
3703 "Nominal TRX RF Power in dBm\n")
Harald Welte (local)7b37d972009-12-27 20:56:38 +01003704{
3705 struct gsm_bts_trx *trx = vty->index;
3706
3707 trx->nominal_power = atoi(argv[0]);
3708
3709 return CMD_SUCCESS;
3710}
3711
Harald Weltefcd24452009-06-20 18:15:19 +02003712DEFUN(cfg_trx_max_power_red,
3713 cfg_trx_max_power_red_cmd,
3714 "max_power_red <0-100>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003715 "Reduction of maximum BS RF Power (relative to nominal power)\n"
Harald Weltefcd24452009-06-20 18:15:19 +02003716 "Reduction of maximum BS RF Power in dB\n")
3717{
3718 int maxpwr_r = atoi(argv[0]);
3719 struct gsm_bts_trx *trx = vty->index;
Harald Welte61a83b22009-11-18 09:20:22 +01003720 int upper_limit = 24; /* default 12.21 max power red. */
Harald Weltefcd24452009-06-20 18:15:19 +02003721
3722 /* FIXME: check if our BTS type supports more than 12 */
3723 if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
3724 vty_out(vty, "%% Power %d dB is not in the valid range%s",
3725 maxpwr_r, VTY_NEWLINE);
3726 return CMD_WARNING;
3727 }
3728 if (maxpwr_r & 1) {
3729 vty_out(vty, "%% Power %d dB is not an even value%s",
3730 maxpwr_r, VTY_NEWLINE);
3731 return CMD_WARNING;
3732 }
3733
3734 trx->max_power_red = maxpwr_r;
3735
3736 /* FIXME: make sure we update this using OML */
3737
3738 return CMD_SUCCESS;
3739}
3740
Harald Welte42581822009-08-08 16:12:58 +02003741DEFUN(cfg_trx_rsl_e1,
3742 cfg_trx_rsl_e1_cmd,
3743 "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003744 "RSL Parameters\n"
3745 "E1/T1 interface to be used for RSL\n"
3746 "E1/T1 interface to be used for RSL\n"
3747 "E1/T1 Line Number to be used for RSL\n"
3748 "E1/T1 Timeslot to be used for RSL\n"
3749 "E1/T1 Timeslot to be used for RSL\n"
3750 "E1/T1 Sub-slot to be used for RSL\n"
3751 "E1/T1 Sub-slot 0 is to be used for RSL\n"
3752 "E1/T1 Sub-slot 1 is to be used for RSL\n"
3753 "E1/T1 Sub-slot 2 is to be used for RSL\n"
3754 "E1/T1 Sub-slot 3 is to be used for RSL\n"
3755 "E1/T1 full timeslot is to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003756{
3757 struct gsm_bts_trx *trx = vty->index;
3758
3759 parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
3760
3761 return CMD_SUCCESS;
3762}
3763
3764DEFUN(cfg_trx_rsl_e1_tei,
3765 cfg_trx_rsl_e1_tei_cmd,
3766 "rsl e1 tei <0-63>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003767 "RSL Parameters\n"
3768 "Set the TEI to be used for RSL\n"
3769 "Set the TEI to be used for RSL\n"
3770 "TEI to be used for RSL\n")
Harald Welte42581822009-08-08 16:12:58 +02003771{
3772 struct gsm_bts_trx *trx = vty->index;
3773
3774 trx->rsl_tei = atoi(argv[0]);
3775
3776 return CMD_SUCCESS;
3777}
3778
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003779DEFUN(cfg_trx_rf_locked,
3780 cfg_trx_rf_locked_cmd,
3781 "rf_locked (0|1)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003782 "Set or unset the RF Locking (Turn off RF of the TRX)\n"
3783 "TRX is NOT RF locked (active)\n"
3784 "TRX is RF locked (turned off)\n")
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003785{
3786 int locked = atoi(argv[0]);
3787 struct gsm_bts_trx *trx = vty->index;
3788
Maxbe356ed2017-09-07 19:10:09 +02003789 gsm_trx_lock_rf(trx, locked, "vty");
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01003790 return CMD_SUCCESS;
3791}
Harald Welte42581822009-08-08 16:12:58 +02003792
Harald Welte5258fc42009-03-28 19:07:53 +00003793/* per TS configuration */
3794DEFUN(cfg_ts,
3795 cfg_ts_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003796 "timeslot <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003797 "Select a Timeslot to configure\n"
3798 "Timeslot number\n")
Harald Welte5258fc42009-03-28 19:07:53 +00003799{
3800 int ts_nr = atoi(argv[0]);
3801 struct gsm_bts_trx *trx = vty->index;
3802 struct gsm_bts_trx_ts *ts;
3803
3804 if (ts_nr >= TRX_NR_TS) {
3805 vty_out(vty, "%% A GSM TRX only has %u Timeslots per TRX%s",
3806 TRX_NR_TS, VTY_NEWLINE);
3807 return CMD_WARNING;
3808 }
3809
3810 ts = &trx->ts[ts_nr];
3811
3812 vty->index = ts;
3813 vty->node = TS_NODE;
3814
3815 return CMD_SUCCESS;
3816}
3817
Harald Weltea6fd58e2009-08-07 00:25:23 +02003818DEFUN(cfg_ts_pchan,
3819 cfg_ts_pchan_cmd,
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003820 "phys_chan_config PCHAN", /* dynamically generated! */
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003821 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003822{
3823 struct gsm_bts_trx_ts *ts = vty->index;
3824 int pchanc;
3825
3826 pchanc = gsm_pchan_parse(argv[0]);
3827 if (pchanc < 0)
3828 return CMD_WARNING;
3829
3830 ts->pchan = pchanc;
3831
3832 return CMD_SUCCESS;
3833}
3834
3835/* used for backwards compatibility with old config files that still
3836 * have uppercase pchan type names */
3837DEFUN_HIDDEN(cfg_ts_pchan_compat,
3838 cfg_ts_pchan_compat_cmd,
Harald Weltea6fd58e2009-08-07 00:25:23 +02003839 "phys_chan_config PCHAN",
Holger Hans Peter Freyther63b0e442013-03-03 09:32:08 +01003840 "Physical Channel configuration (TCH/SDCCH/...)\n" "Physical Channel\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003841{
3842 struct gsm_bts_trx_ts *ts = vty->index;
3843 int pchanc;
3844
3845 pchanc = gsm_pchan_parse(argv[0]);
3846 if (pchanc < 0)
3847 return CMD_WARNING;
3848
3849 ts->pchan = pchanc;
3850
3851 return CMD_SUCCESS;
3852}
3853
Harald Welte4ab9d7c2012-08-17 12:42:06 +02003854
3855
Harald Welte135a6482011-05-30 12:09:13 +02003856DEFUN(cfg_ts_tsc,
3857 cfg_ts_tsc_cmd,
3858 "training_sequence_code <0-7>",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003859 "Training Sequence Code of the Timeslot\n" "TSC\n")
Harald Welte135a6482011-05-30 12:09:13 +02003860{
3861 struct gsm_bts_trx_ts *ts = vty->index;
3862
Max71d082b2017-05-30 15:03:38 +02003863 if (!gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_MULTI_TSC)) {
Harald Welte903aaea2014-01-19 17:10:50 +01003864 vty_out(vty, "%% This BTS does not support a TSC != BCC, "
3865 "falling back to BCC%s", VTY_NEWLINE);
3866 ts->tsc = -1;
3867 return CMD_WARNING;
3868 }
3869
Harald Welte135a6482011-05-30 12:09:13 +02003870 ts->tsc = atoi(argv[0]);
3871
3872 return CMD_SUCCESS;
3873}
3874
Harald Weltea39b0f22010-06-14 22:26:10 +02003875#define HOPPING_STR "Configure frequency hopping\n"
3876
3877DEFUN(cfg_ts_hopping,
3878 cfg_ts_hopping_cmd,
3879 "hopping enabled (0|1)",
3880 HOPPING_STR "Enable or disable frequency hopping\n"
3881 "Disable frequency hopping\n" "Enable frequency hopping\n")
3882{
3883 struct gsm_bts_trx_ts *ts = vty->index;
Harald Weltec2fb3d02010-06-14 22:47:37 +02003884 int enabled = atoi(argv[0]);
Harald Weltea39b0f22010-06-14 22:26:10 +02003885
Max71d082b2017-05-30 15:03:38 +02003886 if (enabled && !gsm_btsmodel_has_feature(ts->trx->bts->model, BTS_FEAT_HOPPING)) {
Harald Weltec2fb3d02010-06-14 22:47:37 +02003887 vty_out(vty, "BTS model does not support hopping%s",
3888 VTY_NEWLINE);
3889 return CMD_WARNING;
3890 }
3891
3892 ts->hopping.enabled = enabled;
Harald Weltea39b0f22010-06-14 22:26:10 +02003893
3894 return CMD_SUCCESS;
3895}
3896
Harald Welte6e0cd042009-09-12 13:05:33 +02003897DEFUN(cfg_ts_hsn,
3898 cfg_ts_hsn_cmd,
Harald Weltea39b0f22010-06-14 22:26:10 +02003899 "hopping sequence-number <0-63>",
3900 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003901 "Which hopping sequence to use for this channel\n"
3902 "Hopping Sequence Number (HSN)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003903{
3904 struct gsm_bts_trx_ts *ts = vty->index;
3905
3906 ts->hopping.hsn = atoi(argv[0]);
3907
3908 return CMD_SUCCESS;
3909}
3910
3911DEFUN(cfg_ts_maio,
3912 cfg_ts_maio_cmd,
3913 "hopping maio <0-63>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003914 HOPPING_STR
Harald Weltecfaabbb2012-08-16 23:23:50 +02003915 "Which hopping MAIO to use for this channel\n"
3916 "Mobile Allocation Index Offset (MAIO)\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003917{
3918 struct gsm_bts_trx_ts *ts = vty->index;
3919
3920 ts->hopping.maio = atoi(argv[0]);
3921
3922 return CMD_SUCCESS;
3923}
3924
3925DEFUN(cfg_ts_arfcn_add,
3926 cfg_ts_arfcn_add_cmd,
3927 "hopping arfcn add <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003928 HOPPING_STR "Configure hopping ARFCN list\n"
3929 "Add an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003930{
3931 struct gsm_bts_trx_ts *ts = vty->index;
3932 int arfcn = atoi(argv[0]);
3933
Harald Weltea39b0f22010-06-14 22:26:10 +02003934 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 1);
3935
Harald Welte6e0cd042009-09-12 13:05:33 +02003936 return CMD_SUCCESS;
3937}
3938
3939DEFUN(cfg_ts_arfcn_del,
3940 cfg_ts_arfcn_del_cmd,
3941 "hopping arfcn del <0-1023>",
Harald Weltea39b0f22010-06-14 22:26:10 +02003942 HOPPING_STR "Configure hopping ARFCN list\n"
3943 "Delete an entry to the hopping ARFCN list\n" "ARFCN\n")
Harald Welte6e0cd042009-09-12 13:05:33 +02003944{
3945 struct gsm_bts_trx_ts *ts = vty->index;
3946 int arfcn = atoi(argv[0]);
3947
Harald Weltea39b0f22010-06-14 22:26:10 +02003948 bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, 0);
3949
Harald Welte6e0cd042009-09-12 13:05:33 +02003950 return CMD_SUCCESS;
3951}
3952
Harald Weltea6fd58e2009-08-07 00:25:23 +02003953DEFUN(cfg_ts_e1_subslot,
3954 cfg_ts_e1_subslot_cmd,
Harald Welte42581822009-08-08 16:12:58 +02003955 "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003956 "E1/T1 channel connected to this on-air timeslot\n"
3957 "E1/T1 channel connected to this on-air timeslot\n"
3958 "E1/T1 line connected to this on-air timeslot\n"
Harald Welted13e0cd2012-08-17 09:52:03 +02003959 "E1/T1 timeslot connected to this on-air timeslot\n"
3960 "E1/T1 timeslot connected to this on-air timeslot\n"
Harald Weltecfaabbb2012-08-16 23:23:50 +02003961 "E1/T1 sub-slot connected to this on-air timeslot\n"
3962 "E1/T1 sub-slot 0 connected to this on-air timeslot\n"
3963 "E1/T1 sub-slot 1 connected to this on-air timeslot\n"
3964 "E1/T1 sub-slot 2 connected to this on-air timeslot\n"
3965 "E1/T1 sub-slot 3 connected to this on-air timeslot\n"
3966 "Full E1/T1 timeslot connected to this on-air timeslot\n")
Harald Weltea6fd58e2009-08-07 00:25:23 +02003967{
3968 struct gsm_bts_trx_ts *ts = vty->index;
3969
Harald Welte42581822009-08-08 16:12:58 +02003970 parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
Harald Weltea6fd58e2009-08-07 00:25:23 +02003971
3972 return CMD_SUCCESS;
3973}
Harald Welte5258fc42009-03-28 19:07:53 +00003974
Harald Welte4f10c252010-05-16 21:47:13 +02003975void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
3976{
Harald Weltecf9d4312017-12-13 23:17:16 +01003977 vty_out(vty, "Paging : %"PRIu64" attempted, %"PRIu64" responded%s",
Alexander Couzensb847a212016-08-02 11:34:11 +02003978 net->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED].current,
Harald Weltecf9d4312017-12-13 23:17:16 +01003979 net->bsc_ctrs->ctr[BSC_CTR_PAGING_RESPONDED].current,
Alexander Couzens20423ea2016-07-12 15:42:02 +02003980 VTY_NEWLINE);
Harald Welte4f10c252010-05-16 21:47:13 +02003981}
3982
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003983DEFUN(drop_bts,
3984 drop_bts_cmd,
Holger Hans Peter Freyther0586b0f2010-04-11 12:46:45 +02003985 "drop bts connection <0-65535> (oml|rsl)",
Harald Weltecfaabbb2012-08-16 23:23:50 +02003986 "Debug/Simulation command to drop Abis/IP BTS\n"
3987 "Debug/Simulation command to drop Abis/IP BTS\n"
3988 "Debug/Simulation command to drop Abis/IP BTS\n"
3989 "BTS NR\n" "Drop OML Connection\n" "Drop RSL Connection\n")
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02003990{
3991 struct gsm_network *gsmnet;
3992 struct gsm_bts_trx *trx;
3993 struct gsm_bts *bts;
3994 unsigned int bts_nr;
3995
3996 gsmnet = gsmnet_from_vty(vty);
3997
3998 bts_nr = atoi(argv[0]);
3999 if (bts_nr >= gsmnet->num_bts) {
4000 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4001 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4002 return CMD_WARNING;
4003 }
4004
4005 bts = gsm_bts_num(gsmnet, bts_nr);
4006 if (!bts) {
4007 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4008 return CMD_WARNING;
4009 }
4010
4011 if (!is_ipaccess_bts(bts)) {
4012 vty_out(vty, "This command only works for ipaccess.%s", VTY_NEWLINE);
4013 return CMD_WARNING;
4014 }
4015
4016
4017 /* close all connections */
4018 if (strcmp(argv[1], "oml") == 0) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004019 ipaccess_drop_oml(bts);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004020 } else if (strcmp(argv[1], "rsl") == 0) {
4021 /* close all rsl connections */
4022 llist_for_each_entry(trx, &bts->trx_list, list) {
Holger Hans Peter Freytherdab8e272010-11-15 20:29:46 +01004023 ipaccess_drop_rsl(trx);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004024 }
4025 } else {
4026 vty_out(vty, "Argument must be 'oml# or 'rsl'.%s", VTY_NEWLINE);
4027 return CMD_WARNING;
4028 }
4029
4030 return CMD_SUCCESS;
4031}
4032
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004033DEFUN(restart_bts, restart_bts_cmd,
4034 "restart-bts <0-65535>",
4035 "Restart ip.access nanoBTS through OML\n"
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004036 BTS_NR_STR)
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004037{
4038 struct gsm_network *gsmnet;
4039 struct gsm_bts_trx *trx;
4040 struct gsm_bts *bts;
4041 unsigned int bts_nr;
4042
4043 gsmnet = gsmnet_from_vty(vty);
4044
4045 bts_nr = atoi(argv[0]);
4046 if (bts_nr >= gsmnet->num_bts) {
4047 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4048 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4049 return CMD_WARNING;
4050 }
4051
4052 bts = gsm_bts_num(gsmnet, bts_nr);
4053 if (!bts) {
4054 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4055 return CMD_WARNING;
4056 }
4057
4058 if (!is_ipaccess_bts(bts) || is_sysmobts_v2(bts)) {
4059 vty_out(vty, "This command only works for ipaccess nanoBTS.%s",
4060 VTY_NEWLINE);
4061 return CMD_WARNING;
4062 }
4063
4064 /* go from last TRX to c0 */
4065 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4066 abis_nm_ipaccess_restart(trx);
4067
4068 return CMD_SUCCESS;
4069}
4070
Harald Welte8e2e22f2017-07-10 20:25:10 +02004071DEFUN(bts_resend, bts_resend_cmd,
4072 "bts <0-255> resend-system-information",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004073 "BTS Specific Commands\n" BTS_NR_STR
Harald Welte8e2e22f2017-07-10 20:25:10 +02004074 "Re-generate + re-send BCCH SYSTEM INFORMATION\n")
4075{
4076 struct gsm_network *gsmnet;
4077 struct gsm_bts_trx *trx;
4078 struct gsm_bts *bts;
4079 unsigned int bts_nr;
4080
4081 gsmnet = gsmnet_from_vty(vty);
4082
4083 bts_nr = atoi(argv[0]);
4084 if (bts_nr >= gsmnet->num_bts) {
4085 vty_out(vty, "BTS number must be between 0 and %d. It was %d.%s",
4086 gsmnet->num_bts, bts_nr, VTY_NEWLINE);
4087 return CMD_WARNING;
4088 }
4089
4090 bts = gsm_bts_num(gsmnet, bts_nr);
4091 if (!bts) {
4092 vty_out(vty, "BTS Nr. %d could not be found.%s", bts_nr, VTY_NEWLINE);
4093 return CMD_WARNING;
4094 }
4095
4096 llist_for_each_entry_reverse(trx, &bts->trx_list, list)
4097 gsm_bts_trx_set_system_infos(trx);
4098
4099 return CMD_SUCCESS;
4100}
4101
4102
Harald Welte30f1f372014-12-28 15:00:45 +01004103DEFUN(smscb_cmd, smscb_cmd_cmd,
4104 "bts <0-255> smscb-command <1-4> HEXSTRING",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004105 "BTS related commands\n" BTS_NR_STR
Harald Welte30f1f372014-12-28 15:00:45 +01004106 "SMS Cell Broadcast\n" "Last Valid Block\n"
4107 "Hex Encoded SMSCB message (up to 88 octets)\n")
4108{
4109 struct gsm_bts *bts;
4110 int bts_nr = atoi(argv[0]);
4111 int last_block = atoi(argv[1]);
4112 struct rsl_ie_cb_cmd_type cb_cmd;
4113 uint8_t buf[88];
4114 int rc;
4115
Neels Hofmeyrb90eabf2016-05-11 18:48:39 +02004116 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
Harald Welte30f1f372014-12-28 15:00:45 +01004117 if (!bts) {
4118 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4119 return CMD_WARNING;
4120 }
4121 rc = osmo_hexparse(argv[2], buf, sizeof(buf));
4122 if (rc < 0 || rc > sizeof(buf)) {
4123 vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
4124 return CMD_WARNING;
4125 }
4126
4127 cb_cmd.spare = 0;
4128 cb_cmd.def_bcast = 0;
4129 cb_cmd.command = RSL_CB_CMD_TYPE_NORMAL;
4130
4131 switch (last_block) {
4132 case 1:
4133 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_1;
4134 break;
4135 case 2:
4136 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_2;
4137 break;
4138 case 3:
4139 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_3;
4140 break;
4141 case 4:
4142 cb_cmd.last_block = RSL_CB_CMD_LASTBLOCK_4;
4143 break;
4144 }
4145
4146 rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, cb_cmd, buf, rc);
4147
4148 return CMD_SUCCESS;
4149}
4150
Harald Welte7fe00fb2017-05-27 14:09:50 +02004151/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
Harald Welte645eb622017-05-27 15:52:58 +02004152static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
4153 const char *ts_str)
Harald Welte7fe00fb2017-05-27 14:09:50 +02004154{
Harald Welte645eb622017-05-27 15:52:58 +02004155 int bts_nr = atoi(bts_str);
4156 int trx_nr = atoi(trx_str);
4157 int ts_nr = atoi(ts_str);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004158 struct gsm_bts *bts;
4159 struct gsm_bts_trx *trx;
4160 struct gsm_bts_trx_ts *ts;
4161
4162 bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
4163 if (!bts) {
4164 vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
4165 return NULL;
4166 }
4167
4168 trx = gsm_bts_trx_num(bts, trx_nr);
4169 if (!trx) {
4170 vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
4171 return NULL;
4172 }
4173
4174 ts = &trx->ts[ts_nr];
4175
4176 return ts;
4177}
Harald Welte30f1f372014-12-28 15:00:45 +01004178
Harald Welted0d2b0b2010-12-23 13:18:07 +01004179DEFUN(pdch_act, pdch_act_cmd,
4180 "bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
Neels Hofmeyr70c5fd22018-01-19 15:55:14 +01004181 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4182 "TRX Timeslot\n" TS_NR_STR "Packet Data Channel\n"
Harald Welted0d2b0b2010-12-23 13:18:07 +01004183 "Activate Dynamic PDCH/TCH (-> PDCH mode)\n"
4184 "Deactivate Dynamic PDCH/TCH (-> TCH mode)\n")
4185{
Harald Welted0d2b0b2010-12-23 13:18:07 +01004186 struct gsm_bts_trx_ts *ts;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004187 int activate;
4188
Harald Welte645eb622017-05-27 15:52:58 +02004189 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
Harald Welte7fe00fb2017-05-27 14:09:50 +02004190 if (!ts)
Harald Welted0d2b0b2010-12-23 13:18:07 +01004191 return CMD_WARNING;
Harald Welted0d2b0b2010-12-23 13:18:07 +01004192
Harald Welte7fe00fb2017-05-27 14:09:50 +02004193 if (!is_ipaccess_bts(ts->trx->bts)) {
Harald Welted0d2b0b2010-12-23 13:18:07 +01004194 vty_out(vty, "%% This command only works for ipaccess BTS%s",
4195 VTY_NEWLINE);
4196 return CMD_WARNING;
4197 }
4198
Harald Welted0d2b0b2010-12-23 13:18:07 +01004199 if (ts->pchan != GSM_PCHAN_TCH_F_PDCH) {
4200 vty_out(vty, "%% Timeslot %u is not in dynamic TCH_F/PDCH "
Harald Welte645eb622017-05-27 15:52:58 +02004201 "mode%s", ts->nr, VTY_NEWLINE);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004202 return CMD_WARNING;
4203 }
4204
4205 if (!strcmp(argv[3], "activate"))
4206 activate = 1;
4207 else
4208 activate = 0;
4209
4210 rsl_ipacc_pdch_activate(ts, activate);
4211
4212 return CMD_SUCCESS;
4213
4214}
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004215
Harald Welte2abd5e12017-05-27 14:10:40 +02004216/* determine the logical channel type based on the physical channel type */
4217static int lchan_type_by_pchan(enum gsm_phys_chan_config pchan)
4218{
4219 switch (pchan) {
4220 case GSM_PCHAN_TCH_F:
4221 return GSM_LCHAN_TCH_F;
4222 case GSM_PCHAN_TCH_H:
4223 return GSM_LCHAN_TCH_H;
4224 case GSM_PCHAN_SDCCH8_SACCH8C:
4225 case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
4226 case GSM_PCHAN_CCCH_SDCCH4:
4227 case GSM_PCHAN_CCCH_SDCCH4_CBCH:
4228 return GSM_LCHAN_SDCCH;
4229 default:
4230 return -1;
4231 }
4232}
4233
4234/* configure the lchan for a single AMR mode (as specified) */
4235static int lchan_set_single_amr_mode(struct gsm_lchan *lchan, uint8_t amr_mode)
4236{
4237 struct amr_multirate_conf mr;
4238 struct gsm48_multi_rate_conf *mr_conf;
4239 mr_conf = (struct gsm48_multi_rate_conf *) &mr.gsm48_ie;
4240
4241 if (amr_mode > 7)
4242 return -1;
4243
4244 memset(&mr, 0, sizeof(mr));
4245 mr_conf->ver = 1;
4246 /* bit-mask of supported modes, only one bit is set. Reflects
4247 * Figure 10.5.2.47a where there are no thershold and only a
4248 * single mode */
4249 mr.gsm48_ie[1] = 1 << amr_mode;
4250
4251 mr.ms_mode[0].mode = amr_mode;
4252 mr.bts_mode[0].mode = amr_mode;
4253
4254 /* encode this configuration into the lchan for both uplink and
4255 * downlink direction */
4256 gsm48_multirate_config(lchan->mr_ms_lv, &mr, mr.ms_mode);
4257 gsm48_multirate_config(lchan->mr_bts_lv, &mr, mr.bts_mode);
4258
4259 return 0;
4260}
4261
4262/* Debug/Measurement command to activate a given logical channel
4263 * manually in a given mode/codec. This is useful for receiver
4264 * performance testing (FER/RBER/...) */
4265DEFUN(lchan_act, lchan_act_cmd,
4266 "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 +01004267 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4268 "TRX Timeslot\n" TS_NR_STR "Sub-Slot Number\n" LCHAN_NR_STR
Harald Welte2abd5e12017-05-27 14:10:40 +02004269 "Manual Channel Activation (e.g. for BER test)\n"
4270 "Manual Channel Deactivation (e.g. for BER test)\n"
4271 "Half-Rate v1\n" "Full-Rate\n" "Enhanced Full Rate\n" "Adaptive Multi-Rate\n" "AMR Mode\n")
4272{
4273 struct gsm_bts_trx_ts *ts;
4274 struct gsm_lchan *lchan;
4275 int ss_nr = atoi(argv[3]);
4276 const char *act_str = argv[4];
4277 const char *codec_str = argv[5];
4278 int activate;
4279
4280 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4281 if (!ts)
4282 return CMD_WARNING;
4283
4284 lchan = &ts->lchan[ss_nr];
4285
4286 if (!strcmp(act_str, "activate"))
4287 activate = 1;
4288 else
4289 activate = 0;
4290
4291 if (ss_nr >= ts_subslots(ts)) {
4292 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4293 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4294 return CMD_WARNING;
4295 }
4296
4297 if (activate) {
4298 int lchan_t;
4299 if (lchan->state != LCHAN_S_NONE) {
4300 vty_out(vty, "%% Cannot activate: Channel busy!%s", VTY_NEWLINE);
4301 return CMD_WARNING;
4302 }
4303 lchan_t = lchan_type_by_pchan(ts->pchan);
4304 if (lchan_t < 0)
4305 return CMD_WARNING;
4306 /* configure the lchan */
4307 lchan->type = lchan_t;
4308 lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
4309 if (!strcmp(codec_str, "hr") || !strcmp(codec_str, "fr"))
4310 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
4311 else if (!strcmp(codec_str, "efr"))
4312 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
4313 else if (!strcmp(codec_str, "amr")) {
4314 int amr_mode;
4315 if (argc < 7) {
4316 vty_out(vty, "%% AMR requires specification of AMR mode%s", VTY_NEWLINE);
4317 return CMD_WARNING;
4318 }
4319 amr_mode = atoi(argv[6]);
4320 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
4321 lchan_set_single_amr_mode(lchan, amr_mode);
4322 }
4323 vty_out(vty, "%% activating lchan %s%s", gsm_lchan_name(lchan), VTY_NEWLINE);
4324 rsl_chan_activate_lchan(lchan, RSL_ACT_TYPE_INITIAL, 0);
4325 rsl_ipacc_crcx(lchan);
Harald Welte2abd5e12017-05-27 14:10:40 +02004326 } else {
4327 rsl_direct_rf_release(lchan);
4328 }
4329
4330 return CMD_SUCCESS;
4331}
4332
Harald Welte3f86c522017-05-27 15:53:28 +02004333DEFUN(lchan_mdcx, lchan_mdcx_cmd,
4334 "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 +01004335 "BTS related commands\n" BTS_NR_STR "Transceiver\n" TRX_NR_STR
4336 "TRX Timeslot\n" TS_NR_STR "Sub-Slot\n" LCHAN_NR_STR
Harald Welte3f86c522017-05-27 15:53:28 +02004337 "Modify RTP Connection\n" "MGW IP Address\n" "MGW UDP Port\n")
4338{
4339 struct gsm_bts_trx_ts *ts;
4340 struct gsm_lchan *lchan;
4341 int ss_nr = atoi(argv[3]);
4342 int port = atoi(argv[5]);
4343 struct in_addr ia;
4344 inet_aton(argv[4], &ia);
4345
4346 ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
4347 if (!ts)
4348 return CMD_WARNING;
4349
4350 lchan = &ts->lchan[ss_nr];
4351
4352 if (ss_nr >= ts_subslots(ts)) {
4353 vty_out(vty, "%% subslot %d >= permitted %d for physical channel %s%s",
4354 ss_nr, ts_subslots(ts), gsm_pchan_name(ts->pchan), VTY_NEWLINE);
4355 return CMD_WARNING;
4356 }
4357
4358 vty_out(vty, "%% connecting RTP of %s to %s:%u%s", gsm_lchan_name(lchan),
4359 inet_ntoa(ia), port, VTY_NEWLINE);
4360 rsl_ipacc_mdcx(lchan, ntohl(ia.s_addr), port, 0);
4361 return CMD_SUCCESS;
4362}
Harald Welteb71147a2017-07-18 19:11:49 +02004363
4364DEFUN(ctrl_trap, ctrl_trap_cmd,
4365 "ctrl-interface generate-trap TRAP VALUE",
4366 "Commands related to the CTRL Interface\n"
4367 "Generate a TRAP for test purpose\n"
4368 "Identity/Name of the TRAP variable\n"
4369 "Value of the TRAP variable\n")
4370{
4371 struct gsm_network *net = gsmnet_from_vty(vty);
4372
4373 ctrl_cmd_send_trap(net->ctrl, argv[0], (char *) argv[1]);
4374 return CMD_SUCCESS;
4375}
4376
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004377#define NETWORK_STR "Configure the GSM network\n"
4378#define CODE_CMD_STR "Code commands\n"
4379#define NAME_CMD_STR "Name Commands\n"
4380#define NAME_STR "Name to use\n"
4381
4382DEFUN(cfg_net,
4383 cfg_net_cmd,
4384 "network", NETWORK_STR)
4385{
4386 vty->index = gsmnet_from_vty(vty);
4387 vty->node = GSMNET_NODE;
4388
4389 return CMD_SUCCESS;
4390}
4391
4392DEFUN(cfg_net_ncc,
4393 cfg_net_ncc_cmd,
4394 "network country code <1-999>",
4395 "Set the GSM network country code\n"
4396 "Country commands\n"
4397 CODE_CMD_STR
4398 "Network Country Code to use\n")
4399{
4400 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4401
4402 gsmnet->country_code = atoi(argv[0]);
4403
4404 return CMD_SUCCESS;
4405}
4406
4407DEFUN(cfg_net_mnc,
4408 cfg_net_mnc_cmd,
4409 "mobile network code <0-999>",
4410 "Set the GSM mobile network code\n"
4411 "Network Commands\n"
4412 CODE_CMD_STR
4413 "Mobile Network Code to use\n")
4414{
4415 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4416
4417 gsmnet->network_code = atoi(argv[0]);
4418
4419 return CMD_SUCCESS;
4420}
4421
4422DEFUN(cfg_net_encryption,
4423 cfg_net_encryption_cmd,
Harald Welte51e4bf32017-12-23 17:30:18 +01004424 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
4425 "Encryption options\n"
4426 "GSM A5 Air Interface Encryption\n"
4427 "A5/n Algorithm Number\n"
4428 "A5/n Algorithm Number\n"
4429 "A5/n Algorithm Number\n"
4430 "A5/n Algorithm Number\n")
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004431{
4432 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
Harald Welte51e4bf32017-12-23 17:30:18 +01004433 unsigned int i;
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004434
Harald Welte51e4bf32017-12-23 17:30:18 +01004435 gsmnet->a5_encryption_mask = 0;
4436 for (i = 0; i < argc; i++)
4437 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004438
4439 return CMD_SUCCESS;
4440}
4441
4442DEFUN(cfg_net_dyn_ts_allow_tch_f,
4443 cfg_net_dyn_ts_allow_tch_f_cmd,
4444 "dyn_ts_allow_tch_f (0|1)",
4445 "Allow or disallow allocating TCH/F on TCH_F_TCH_H_PDCH timeslots\n"
4446 "Disallow TCH/F on TCH_F_TCH_H_PDCH (default)\n"
4447 "Allow TCH/F on TCH_F_TCH_H_PDCH\n")
4448{
4449 struct gsm_network *gsmnet = gsmnet_from_vty(vty);
4450 gsmnet->dyn_ts_allow_tch_f = atoi(argv[0]) ? true : false;
4451 return CMD_SUCCESS;
4452}
4453
4454DEFUN(cfg_net_timezone,
4455 cfg_net_timezone_cmd,
4456 "timezone <-19-19> (0|15|30|45)",
4457 "Set the Timezone Offset of the network\n"
4458 "Timezone offset (hours)\n"
4459 "Timezone offset (00 minutes)\n"
4460 "Timezone offset (15 minutes)\n"
4461 "Timezone offset (30 minutes)\n"
4462 "Timezone offset (45 minutes)\n"
4463 )
4464{
4465 struct gsm_network *net = vty->index;
4466 int tzhr = atoi(argv[0]);
4467 int tzmn = atoi(argv[1]);
4468
4469 net->tz.hr = tzhr;
4470 net->tz.mn = tzmn;
4471 net->tz.dst = 0;
4472 net->tz.override = 1;
4473
4474 return CMD_SUCCESS;
4475}
4476
4477DEFUN(cfg_net_timezone_dst,
4478 cfg_net_timezone_dst_cmd,
4479 "timezone <-19-19> (0|15|30|45) <0-2>",
4480 "Set the Timezone Offset of the network\n"
4481 "Timezone offset (hours)\n"
4482 "Timezone offset (00 minutes)\n"
4483 "Timezone offset (15 minutes)\n"
4484 "Timezone offset (30 minutes)\n"
4485 "Timezone offset (45 minutes)\n"
4486 "DST offset (hours)\n"
4487 )
4488{
4489 struct gsm_network *net = vty->index;
4490 int tzhr = atoi(argv[0]);
4491 int tzmn = atoi(argv[1]);
4492 int tzdst = atoi(argv[2]);
4493
4494 net->tz.hr = tzhr;
4495 net->tz.mn = tzmn;
4496 net->tz.dst = tzdst;
4497 net->tz.override = 1;
4498
4499 return CMD_SUCCESS;
4500}
4501
4502DEFUN(cfg_net_no_timezone,
4503 cfg_net_no_timezone_cmd,
4504 "no timezone",
4505 NO_STR
4506 "Disable network timezone override, use system tz\n")
4507{
4508 struct gsm_network *net = vty->index;
4509
4510 net->tz.override = 0;
4511
4512 return CMD_SUCCESS;
4513}
4514
4515DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
4516 "periodic location update <6-1530>",
4517 "Periodic Location Updating Interval\n"
4518 "Periodic Location Updating Interval\n"
4519 "Periodic Location Updating Interval\n"
4520 "Periodic Location Updating Interval in Minutes\n")
4521{
4522 struct gsm_network *net = vty->index;
4523
4524 net->t3212 = atoi(argv[0]) / 6;
4525
4526 return CMD_SUCCESS;
4527}
4528
4529DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
4530 "no periodic location update",
4531 NO_STR
4532 "Periodic Location Updating Interval\n"
4533 "Periodic Location Updating Interval\n"
4534 "Periodic Location Updating Interval\n")
4535{
4536 struct gsm_network *net = vty->index;
4537
4538 net->t3212 = 0;
4539
4540 return CMD_SUCCESS;
4541}
4542
Harald Weltedcccb182010-05-16 20:52:23 +02004543extern int bsc_vty_init_extra(void);
Holger Hans Peter Freythere1ffc082010-04-10 00:08:28 +02004544
Maxdb0e3802017-01-12 19:35:11 +01004545int bsc_vty_init(struct gsm_network *network)
Harald Welte68628e82009-03-10 12:17:57 +00004546{
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004547 cfg_ts_pchan_cmd.string =
4548 vty_cmd_string_from_valstr(tall_bsc_ctx,
4549 gsm_pchant_names,
4550 "phys_chan_config (", "|", ")",
4551 VTY_DO_LOWER);
4552 cfg_ts_pchan_cmd.doc =
4553 vty_cmd_string_from_valstr(tall_bsc_ctx,
4554 gsm_pchant_descs,
4555 "Physical Channel Combination\n",
4556 "\n", "", 0);
4557
Harald Weltee555c2b2012-08-17 13:02:12 +02004558 cfg_bts_type_cmd.string =
4559 vty_cmd_string_from_valstr(tall_bsc_ctx,
4560 bts_type_names,
4561 "type (", "|", ")",
4562 VTY_DO_LOWER);
4563 cfg_bts_type_cmd.doc =
4564 vty_cmd_string_from_valstr(tall_bsc_ctx,
4565 bts_type_descs,
4566 "BTS Vendor/Type\n",
4567 "\n", "", 0);
4568
Neels Hofmeyr6dd5a9b2018-02-14 00:06:19 +01004569 OSMO_ASSERT(vty_global_gsm_network == NULL);
4570 vty_global_gsm_network = network;
4571
4572 osmo_stats_vty_add_cmds();
4573
4574 install_element(CONFIG_NODE, &cfg_net_cmd);
4575 install_node(&net_node, config_write_net);
4576 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
4577 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
4578 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
4579 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
4580 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
4581 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
4582 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
4583 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
4584 install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);
Harald Weltee555c2b2012-08-17 13:02:12 +02004585
Neels Hofmeyrea11bf82016-05-12 01:53:23 +02004586 install_element_ve(&bsc_show_net_cmd);
Harald Welteb4d5b172010-05-12 16:10:35 +00004587 install_element_ve(&show_bts_cmd);
4588 install_element_ve(&show_trx_cmd);
4589 install_element_ve(&show_ts_cmd);
4590 install_element_ve(&show_lchan_cmd);
Holger Hans Peter Freyther3d6a5d62010-05-14 02:08:49 +08004591 install_element_ve(&show_lchan_summary_cmd);
Harald Welte1bc77352009-03-10 19:47:51 +00004592
Philipp Maier39f62bb2017-04-09 12:32:51 +02004593 install_element_ve(&show_subscr_conn_cmd);
4594 install_element_ve(&handover_subscr_conn_cmd);
Neels Hofmeyrb99e0252017-12-05 02:10:15 +01004595 install_element_ve(&handover_any_cmd);
4596 install_element_ve(&assignment_subscr_conn_cmd);
4597 install_element_ve(&assignment_any_cmd);
Philipp Maier39f62bb2017-04-09 12:32:51 +02004598
Harald Welteb4d5b172010-05-12 16:10:35 +00004599 install_element_ve(&show_paging_cmd);
Holger Hans Peter Freytherec37bb22013-02-05 09:39:09 +01004600 install_element_ve(&show_paging_group_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004601
Maxdb0e3802017-01-12 19:35:11 +01004602 logging_vty_add_cmds(NULL);
Harald Welte2f4f4b82018-02-14 00:50:27 +01004603 osmo_talloc_vty_add_cmds();
Holger Hans Peter Freytherb61e3b22009-12-22 22:32:51 +01004604
Holger Hans Peter Freytherf7d752f2009-11-16 17:12:38 +01004605 install_element(GSMNET_NODE, &cfg_net_neci_cmd);
Holger Hans Peter Freytherc4d88ad2009-11-21 21:18:38 +01004606 install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004607 install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
4608 install_element(GSMNET_NODE, &cfg_net_T3105_cmd);
4609 install_element(GSMNET_NODE, &cfg_net_T3107_cmd);
4610 install_element(GSMNET_NODE, &cfg_net_T3109_cmd);
4611 install_element(GSMNET_NODE, &cfg_net_T3111_cmd);
4612 install_element(GSMNET_NODE, &cfg_net_T3113_cmd);
4613 install_element(GSMNET_NODE, &cfg_net_T3115_cmd);
4614 install_element(GSMNET_NODE, &cfg_net_T3117_cmd);
4615 install_element(GSMNET_NODE, &cfg_net_T3119_cmd);
Harald Weltec9f499f2010-12-23 22:53:50 +01004616 install_element(GSMNET_NODE, &cfg_net_T3122_cmd);
Holger Hans Peter Freyther23975e72009-11-21 21:42:26 +01004617 install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08004618 install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
Holger Hans Peter Freyther76fc4a32010-09-06 09:41:50 +08004619 install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004620 /* See also handover commands added on net level from handover_vty.c */
Harald Welte5013b2a2009-08-07 13:29:14 +02004621
4622 install_element(GSMNET_NODE, &cfg_bts_cmd);
Harald Welte67ce0732009-08-06 19:06:46 +02004623 install_node(&bts_node, config_write_bts);
Harald Welte5258fc42009-03-28 19:07:53 +00004624 install_element(BTS_NODE, &cfg_bts_type_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004625 install_element(BTS_NODE, &cfg_description_cmd);
4626 install_element(BTS_NODE, &cfg_no_description_cmd);
Harald Weltefcd24452009-06-20 18:15:19 +02004627 install_element(BTS_NODE, &cfg_bts_band_cmd);
Holger Hans Peter Freytherc4a49e32009-08-21 14:44:12 +02004628 install_element(BTS_NODE, &cfg_bts_ci_cmd);
Maxc08ee712016-05-11 12:45:13 +02004629 install_element(BTS_NODE, &cfg_bts_dtxu_cmd);
4630 install_element(BTS_NODE, &cfg_bts_dtxd_cmd);
4631 install_element(BTS_NODE, &cfg_bts_no_dtxu_cmd);
4632 install_element(BTS_NODE, &cfg_bts_no_dtxd_cmd);
Harald Welte5258fc42009-03-28 19:07:53 +00004633 install_element(BTS_NODE, &cfg_bts_lac_cmd);
4634 install_element(BTS_NODE, &cfg_bts_tsc_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004635 install_element(BTS_NODE, &cfg_bts_bsic_cmd);
Harald Welte4cc34222009-05-01 15:12:31 +00004636 install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
Harald Welte8b291802013-03-12 13:57:05 +01004637 install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
Sylvain Munautc9519462011-10-17 14:04:55 +02004638 install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
Andreas Eversberg7d8fa342013-12-05 13:25:06 +01004639 install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
Sipos Csaba56e17662015-02-07 13:27:36 +01004640 install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
Harald Welte8175e952009-10-20 00:22:00 +02004641 install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004642 install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
4643 install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
Harald Welte7a8fa412009-08-10 13:48:16 +02004644 install_element(BTS_NODE, &cfg_bts_challoc_cmd);
Sylvain Munaut4010f1e2009-12-22 13:43:26 +01004645 install_element(BTS_NODE, &cfg_bts_rach_tx_integer_cmd);
4646 install_element(BTS_NODE, &cfg_bts_rach_max_trans_cmd);
Andreas Eversberg2ee7ecd2012-10-13 07:27:47 +02004647 install_element(BTS_NODE, &cfg_bts_chan_desc_att_cmd);
4648 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_pa_mfrms_cmd);
4649 install_element(BTS_NODE, &cfg_bts_chan_desc_bs_ag_blks_res_cmd);
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +08004650 install_element(BTS_NODE, &cfg_bts_rach_nm_b_thresh_cmd);
4651 install_element(BTS_NODE, &cfg_bts_rach_nm_ldavg_cmd);
Harald Welte (local)5dececf2009-08-12 13:28:23 +02004652 install_element(BTS_NODE, &cfg_bts_cell_barred_cmd);
Holger Hans Peter Freyther3a0a4632010-05-14 00:39:19 +08004653 install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
Ivan Kluchnikov67920592013-09-16 13:13:04 +04004654 install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
Harald Welte (local)0e451d02009-08-13 10:14:26 +02004655 install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
Harald Welte73225282009-12-12 18:17:25 +01004656 install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
4657 install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
Sylvain Munaute0b06b02010-11-28 18:17:28 +01004658 install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
4659 install_element(BTS_NODE, &cfg_bts_cell_resel_ofs_cmd);
4660 install_element(BTS_NODE, &cfg_bts_temp_ofs_cmd);
4661 install_element(BTS_NODE, &cfg_bts_temp_ofs_inf_cmd);
4662 install_element(BTS_NODE, &cfg_bts_penalty_time_cmd);
4663 install_element(BTS_NODE, &cfg_bts_penalty_time_rsvd_cmd);
Andreas Eversberg4d4944a2013-03-10 11:49:35 +01004664 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_cmd);
Harald Welte2f8b9d22017-06-18 11:12:13 +03004665 install_element(BTS_NODE, &cfg_bts_radio_link_timeout_inf_cmd);
Harald Welte4511d892010-04-18 15:51:20 +02004666 install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
bhargava350533c2016-07-21 11:14:34 +05304667 install_element(BTS_NODE, &cfg_bts_gprs_11bit_rach_support_for_egprs_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004668 install_element(BTS_NODE, &cfg_bts_gprs_ns_timer_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004669 install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
Andreas Eversberg0c8f9ca2013-03-16 16:31:26 +01004670 install_element(BTS_NODE, &cfg_bts_gprs_net_ctrl_ord_cmd);
Max292ec582016-07-28 11:55:37 +02004671 install_element(BTS_NODE, &cfg_bts_gprs_ctrl_ack_cmd);
4672 install_element(BTS_NODE, &cfg_no_bts_gprs_ctrl_ack_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004673 install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
Harald Welte615e9562010-05-11 23:50:21 +02004674 install_element(BTS_NODE, &cfg_bts_gprs_cell_timer_cmd);
Harald Weltea5731cf2010-03-22 11:48:36 +08004675 install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
Harald Welte97a282b2010-03-14 15:37:43 +08004676 install_element(BTS_NODE, &cfg_bts_gprs_nsvci_cmd);
Harald Welteaf387632010-03-14 23:30:30 +08004677 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
4678 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
4679 install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
Holger Hans Peter Freythere66bf1f2010-09-06 10:11:25 +08004680 install_element(BTS_NODE, &cfg_bts_pag_free_cmd);
Harald Welte9fbff4a2010-07-30 11:50:09 +02004681 install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
4682 install_element(BTS_NODE, &cfg_bts_si_static_cmd);
Harald Welte42def722017-01-13 00:10:32 +01004683 install_element(BTS_NODE, &cfg_bts_early_cm_cmd);
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +01004684 install_element(BTS_NODE, &cfg_bts_early_cm_3g_cmd);
Harald Welte32c09622011-01-11 23:44:56 +01004685 install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
4686 install_element(BTS_NODE, &cfg_bts_neigh_cmd);
Harald Welte64c07d22011-02-15 11:43:27 +01004687 install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
Max59a1bf32016-04-15 16:04:46 +02004688 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_add_cmd);
4689 install_element(BTS_NODE, &cfg_bts_si2quater_neigh_del_cmd);
Max26679e02016-04-20 15:57:13 +02004690 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_add_cmd);
4691 install_element(BTS_NODE, &cfg_bts_si2quater_uarfcn_del_cmd);
Holger Hans Peter Freythere30d40d2012-07-20 10:27:31 +02004692 install_element(BTS_NODE, &cfg_bts_excl_rf_lock_cmd);
4693 install_element(BTS_NODE, &cfg_bts_no_excl_rf_lock_cmd);
Jacob Erlbeck65d114f2014-01-16 11:02:14 +01004694 install_element(BTS_NODE, &cfg_bts_force_comb_si_cmd);
4695 install_element(BTS_NODE, &cfg_bts_no_force_comb_si_cmd);
Andreas Eversberga83d5112013-12-07 18:32:28 +01004696 install_element(BTS_NODE, &cfg_bts_codec0_cmd);
4697 install_element(BTS_NODE, &cfg_bts_codec1_cmd);
4698 install_element(BTS_NODE, &cfg_bts_codec2_cmd);
4699 install_element(BTS_NODE, &cfg_bts_codec3_cmd);
4700 install_element(BTS_NODE, &cfg_bts_codec4_cmd);
Holger Hans Peter Freytherc22930e2014-12-17 14:46:17 +01004701 install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
4702 install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
Andreas Eversberg73266522014-01-19 11:47:44 +01004703 install_element(BTS_NODE, &cfg_bts_amr_fr_modes1_cmd);
4704 install_element(BTS_NODE, &cfg_bts_amr_fr_modes2_cmd);
4705 install_element(BTS_NODE, &cfg_bts_amr_fr_modes3_cmd);
4706 install_element(BTS_NODE, &cfg_bts_amr_fr_modes4_cmd);
4707 install_element(BTS_NODE, &cfg_bts_amr_fr_thres1_cmd);
4708 install_element(BTS_NODE, &cfg_bts_amr_fr_thres2_cmd);
4709 install_element(BTS_NODE, &cfg_bts_amr_fr_thres3_cmd);
4710 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst1_cmd);
4711 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst2_cmd);
4712 install_element(BTS_NODE, &cfg_bts_amr_fr_hyst3_cmd);
4713 install_element(BTS_NODE, &cfg_bts_amr_fr_start_mode_cmd);
4714 install_element(BTS_NODE, &cfg_bts_amr_hr_modes1_cmd);
4715 install_element(BTS_NODE, &cfg_bts_amr_hr_modes2_cmd);
4716 install_element(BTS_NODE, &cfg_bts_amr_hr_modes3_cmd);
4717 install_element(BTS_NODE, &cfg_bts_amr_hr_modes4_cmd);
4718 install_element(BTS_NODE, &cfg_bts_amr_hr_thres1_cmd);
4719 install_element(BTS_NODE, &cfg_bts_amr_hr_thres2_cmd);
4720 install_element(BTS_NODE, &cfg_bts_amr_hr_thres3_cmd);
4721 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst1_cmd);
4722 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst2_cmd);
4723 install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
4724 install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
Harald Welte8254cf72017-05-29 13:42:19 +02004725 install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004726 /* See also handover commands added on bts level from handover_vty.c */
Harald Welte68628e82009-03-10 12:17:57 +00004727
Harald Welte5258fc42009-03-28 19:07:53 +00004728 install_element(BTS_NODE, &cfg_trx_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004729 install_node(&trx_node, dummy_config_write);
Harald Welte5258fc42009-03-28 19:07:53 +00004730 install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
Harald Welte197dea92010-05-14 17:59:53 +02004731 install_element(TRX_NODE, &cfg_description_cmd);
4732 install_element(TRX_NODE, &cfg_no_description_cmd);
Harald Welte (local)7b37d972009-12-27 20:56:38 +01004733 install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
Harald Welte879dc972009-06-20 22:36:12 +02004734 install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
Harald Welte42581822009-08-08 16:12:58 +02004735 install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
4736 install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +01004737 install_element(TRX_NODE, &cfg_trx_rf_locked_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004738
Harald Welte5258fc42009-03-28 19:07:53 +00004739 install_element(TRX_NODE, &cfg_ts_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004740 install_node(&ts_node, dummy_config_write);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004741 install_element(TS_NODE, &cfg_ts_pchan_cmd);
Harald Welte4ab9d7c2012-08-17 12:42:06 +02004742 install_element(TS_NODE, &cfg_ts_pchan_compat_cmd);
Harald Welte135a6482011-05-30 12:09:13 +02004743 install_element(TS_NODE, &cfg_ts_tsc_cmd);
Harald Weltea39b0f22010-06-14 22:26:10 +02004744 install_element(TS_NODE, &cfg_ts_hopping_cmd);
Harald Welte6e0cd042009-09-12 13:05:33 +02004745 install_element(TS_NODE, &cfg_ts_hsn_cmd);
4746 install_element(TS_NODE, &cfg_ts_maio_cmd);
4747 install_element(TS_NODE, &cfg_ts_arfcn_add_cmd);
4748 install_element(TS_NODE, &cfg_ts_arfcn_del_cmd);
Harald Weltea6fd58e2009-08-07 00:25:23 +02004749 install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
Harald Welte68628e82009-03-10 12:17:57 +00004750
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004751 install_element(ENABLE_NODE, &drop_bts_cmd);
Holger Hans Peter Freyther740e65f2016-03-16 13:45:23 +01004752 install_element(ENABLE_NODE, &restart_bts_cmd);
Harald Welte8e2e22f2017-07-10 20:25:10 +02004753 install_element(ENABLE_NODE, &bts_resend_cmd);
Harald Welted0d2b0b2010-12-23 13:18:07 +01004754 install_element(ENABLE_NODE, &pdch_act_cmd);
Harald Welte2abd5e12017-05-27 14:10:40 +02004755 install_element(ENABLE_NODE, &lchan_act_cmd);
Harald Welte3f86c522017-05-27 15:53:28 +02004756 install_element(ENABLE_NODE, &lchan_mdcx_cmd);
Harald Welte30f1f372014-12-28 15:00:45 +01004757 install_element(ENABLE_NODE, &smscb_cmd_cmd);
Harald Welteb71147a2017-07-18 19:11:49 +02004758 install_element(ENABLE_NODE, &ctrl_trap_cmd);
Holger Hans Peter Freyther2484ceb2010-10-26 09:40:13 +02004759
Harald Welte81c9b9c2010-05-31 16:40:40 +02004760 abis_nm_vty_init();
Harald Weltee1d5eca2011-02-12 14:42:59 +01004761 abis_om2k_vty_init();
Harald Welte3016d9f2011-02-05 13:54:41 +01004762 e1inp_vty_init();
Harald Welte42def722017-01-13 00:10:32 +01004763 osmo_fsm_vty_add_cmds();
Harald Welte81c9b9c2010-05-31 16:40:40 +02004764
Neels Hofmeyre25018b2017-11-27 21:29:33 +01004765 ho_vty_init();
4766
Harald Weltedcccb182010-05-16 20:52:23 +02004767 bsc_vty_init_extra();
Harald Welte40f82892009-05-23 17:31:39 +00004768
Harald Welte68628e82009-03-10 12:17:57 +00004769 return 0;
4770}