Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 1 | /* |
Pau Espin Pedrol | e9ce77b | 2019-06-25 12:29:01 +0200 | [diff] [blame] | 2 | * Copyright (C) 2018-2019 sysmocom - s.f.m.c. GmbH |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 3 | * All Rights Reserved |
| 4 | * |
Pau Espin Pedrol | e9ce77b | 2019-06-25 12:29:01 +0200 | [diff] [blame] | 5 | * SPDX-License-Identifier: AGPL-3.0+ |
| 6 | * |
| 7 | * Author: Pau Espin Pedrol <pespin@sysmocom.de> |
| 8 | * |
| 9 | * This program is free software: you can redistribute it and/or modify |
| 10 | * it under the terms of the GNU Affero General Public License as published by |
| 11 | * the Free Software Foundation, either version 3 of the License, or |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 12 | * (at your option) any later version. |
| 13 | * |
| 14 | * This program is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
Pau Espin Pedrol | e9ce77b | 2019-06-25 12:29:01 +0200 | [diff] [blame] | 17 | * GNU Affero General Public License for more details. |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 18 | * |
Pau Espin Pedrol | e9ce77b | 2019-06-25 12:29:01 +0200 | [diff] [blame] | 19 | * You should have received a copy of the GNU Affero General Public License |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
Pau Espin Pedrol | e9ce77b | 2019-06-25 12:29:01 +0200 | [diff] [blame] | 21 | * See the COPYING file in the main directory for details. |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 22 | */ |
| 23 | |
| 24 | #include <string.h> |
| 25 | #include <stdint.h> |
| 26 | #include <inttypes.h> |
| 27 | #include <netinet/in.h> |
| 28 | #include <arpa/inet.h> |
| 29 | |
| 30 | #include <osmocom/core/talloc.h> |
| 31 | #include <osmocom/core/utils.h> |
| 32 | #include <osmocom/core/rate_ctr.h> |
| 33 | |
| 34 | #include <osmocom/vty/command.h> |
Pau Espin Pedrol | aebbfe0 | 2020-01-02 16:39:11 +0100 | [diff] [blame] | 35 | #include <osmocom/vty/logging.h> |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 36 | #include <osmocom/vty/vty.h> |
| 37 | #include <osmocom/vty/misc.h> |
| 38 | |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 39 | #include "trx_rate_ctr.h" |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 40 | #include "trx_vty.h" |
| 41 | #include "../config.h" |
| 42 | |
| 43 | static struct trx_ctx* g_trx_ctx; |
| 44 | |
Pau Espin Pedrol | a7bf6cd | 2020-01-14 17:52:15 +0100 | [diff] [blame] | 45 | const struct value_string clock_ref_names[] = { |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 46 | { REF_INTERNAL, "internal" }, |
| 47 | { REF_EXTERNAL, "external" }, |
Pau Espin Pedrol | aae403f | 2018-08-27 16:50:19 +0200 | [diff] [blame] | 48 | { REF_GPS, "gpsdo" }, |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 49 | { 0, NULL } |
| 50 | }; |
| 51 | |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 52 | const struct value_string filler_names[] = { |
| 53 | { FILLER_DUMMY, "Dummy bursts (C0 only)" }, |
| 54 | { FILLER_ZERO, "Empty bursts" }, |
| 55 | { FILLER_NORM_RAND, "GMSK Normal Bursts with random payload" }, |
| 56 | { FILLER_EDGE_RAND, "8-PSK Normal Bursts with random payload" }, |
| 57 | { FILLER_ACCESS_RAND, "Access Bursts with random payload" }, |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 58 | { 0, NULL } |
| 59 | }; |
| 60 | |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 61 | static const struct value_string filler_types[] = { |
| 62 | { FILLER_DUMMY, "dummy" }, |
| 63 | { FILLER_ZERO, "zero" }, |
| 64 | { FILLER_NORM_RAND, "random-nb-gmsk" }, |
| 65 | { FILLER_EDGE_RAND, "random-nb-8psk" }, |
| 66 | { FILLER_ACCESS_RAND, "random-ab" }, |
| 67 | { 0, NULL } |
| 68 | }; |
| 69 | |
Vadim Yanitskiy | c0e7ce9 | 2020-10-30 02:19:55 +0700 | [diff] [blame] | 70 | static const struct value_string filler_docs[] = { |
Vadim Yanitskiy | c0e7ce9 | 2020-10-30 02:19:55 +0700 | [diff] [blame] | 71 | { FILLER_DUMMY, "Send a Dummy Burst on C0 (TRX0) and empty burst on other channels" }, |
Vadim Yanitskiy | 1587307 | 2020-12-08 15:35:52 +0100 | [diff] [blame] | 72 | { FILLER_ZERO, "Send an empty burst (default)" }, |
Vadim Yanitskiy | c0e7ce9 | 2020-10-30 02:19:55 +0700 | [diff] [blame] | 73 | { FILLER_NORM_RAND, "Send a GMSK modulated Normal Burst with random bits (spectrum mask testing)" }, |
| 74 | { FILLER_EDGE_RAND, "Send an 8-PSK modulated Normal Burst with random bits (spectrum mask testing)" }, |
| 75 | { FILLER_ACCESS_RAND, "Send an Access Burst with random bits (Rx/Tx alignment testing)" }, |
| 76 | { 0, NULL } |
| 77 | }; |
| 78 | |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 79 | |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 80 | struct trx_ctx *trx_from_vty(struct vty *v) |
| 81 | { |
| 82 | /* It can't hurt to force callers to continue to pass the vty instance |
| 83 | * to this function, in case we'd like to retrieve the global |
| 84 | * trx instance from the vty at some point in the future. But |
| 85 | * until then, just return the global pointer, which should have been |
| 86 | * initialized by trx_vty_init(). |
| 87 | */ |
| 88 | OSMO_ASSERT(g_trx_ctx); |
| 89 | return g_trx_ctx; |
| 90 | } |
| 91 | |
| 92 | enum trx_vty_node { |
| 93 | TRX_NODE = _LAST_OSMOVTY_NODE + 1, |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 94 | CHAN_NODE, |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 95 | }; |
| 96 | |
| 97 | static struct cmd_node trx_node = { |
| 98 | TRX_NODE, |
| 99 | "%s(config-trx)# ", |
| 100 | 1, |
| 101 | }; |
| 102 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 103 | static struct cmd_node chan_node = { |
| 104 | CHAN_NODE, |
| 105 | "%s(config-trx-chan)# ", |
| 106 | 1, |
| 107 | }; |
| 108 | |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 109 | DEFUN(cfg_trx, cfg_trx_cmd, |
| 110 | "trx", |
| 111 | "Configure the TRX\n") |
| 112 | { |
| 113 | struct trx_ctx *trx = trx_from_vty(vty); |
| 114 | |
| 115 | if (!trx) |
| 116 | return CMD_WARNING; |
| 117 | |
| 118 | vty->node = TRX_NODE; |
| 119 | |
| 120 | return CMD_SUCCESS; |
| 121 | } |
| 122 | |
| 123 | DEFUN(cfg_bind_ip, cfg_bind_ip_cmd, |
Vadim Yanitskiy | c620ced | 2020-10-30 01:47:35 +0700 | [diff] [blame] | 124 | "bind-ip " VTY_IPV4_CMD, |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 125 | "Set the IP address for the local bind\n" |
| 126 | "IPv4 Address\n") |
| 127 | { |
| 128 | struct trx_ctx *trx = trx_from_vty(vty); |
| 129 | |
| 130 | osmo_talloc_replace_string(trx, &trx->cfg.bind_addr, argv[0]); |
| 131 | |
| 132 | return CMD_SUCCESS; |
| 133 | } |
| 134 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 135 | DEFUN(cfg_remote_ip, cfg_remote_ip_cmd, |
Vadim Yanitskiy | c620ced | 2020-10-30 01:47:35 +0700 | [diff] [blame] | 136 | "remote-ip " VTY_IPV4_CMD, |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 137 | "Set the IP address for the remote BTS\n" |
| 138 | "IPv4 Address\n") |
| 139 | { |
| 140 | struct trx_ctx *trx = trx_from_vty(vty); |
| 141 | |
| 142 | osmo_talloc_replace_string(trx, &trx->cfg.remote_addr, argv[0]); |
| 143 | |
| 144 | return CMD_SUCCESS; |
| 145 | } |
| 146 | |
| 147 | DEFUN(cfg_base_port, cfg_base_port_cmd, |
| 148 | "base-port <1-65535>", |
| 149 | "Set the TRX Base Port\n" |
| 150 | "TRX Base Port\n") |
| 151 | { |
| 152 | struct trx_ctx *trx = trx_from_vty(vty); |
| 153 | |
| 154 | trx->cfg.base_port = atoi(argv[0]); |
| 155 | |
| 156 | return CMD_SUCCESS; |
| 157 | } |
| 158 | |
| 159 | DEFUN(cfg_dev_args, cfg_dev_args_cmd, |
| 160 | "dev-args DESC", |
| 161 | "Set the device-specific arguments to pass to the device\n" |
| 162 | "Device-specific arguments\n") |
| 163 | { |
| 164 | struct trx_ctx *trx = trx_from_vty(vty); |
| 165 | |
| 166 | osmo_talloc_replace_string(trx, &trx->cfg.dev_args, argv[0]); |
| 167 | |
| 168 | return CMD_SUCCESS; |
| 169 | } |
| 170 | |
| 171 | DEFUN(cfg_tx_sps, cfg_tx_sps_cmd, |
| 172 | "tx-sps (1|4)", |
| 173 | "Set the Tx Samples-per-Symbol\n" |
Vadim Yanitskiy | ef79fd9 | 2020-10-30 01:44:29 +0700 | [diff] [blame] | 174 | "Tx Samples-per-Symbol\n" |
| 175 | "1 Sample-per-Symbol\n" |
| 176 | "4 Samples-per-Symbol\n") |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 177 | { |
| 178 | struct trx_ctx *trx = trx_from_vty(vty); |
| 179 | |
| 180 | trx->cfg.tx_sps = atoi(argv[0]); |
| 181 | |
| 182 | return CMD_SUCCESS; |
| 183 | } |
| 184 | |
| 185 | DEFUN(cfg_rx_sps, cfg_rx_sps_cmd, |
| 186 | "rx-sps (1|4)", |
| 187 | "Set the Rx Samples-per-Symbol\n" |
Vadim Yanitskiy | ef79fd9 | 2020-10-30 01:44:29 +0700 | [diff] [blame] | 188 | "Rx Samples-per-Symbol\n" |
| 189 | "1 Sample-per-Symbol\n" |
| 190 | "4 Samples-per-Symbol\n") |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 191 | { |
| 192 | struct trx_ctx *trx = trx_from_vty(vty); |
| 193 | |
| 194 | trx->cfg.rx_sps = atoi(argv[0]); |
| 195 | |
| 196 | return CMD_SUCCESS; |
| 197 | } |
| 198 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 199 | DEFUN(cfg_clock_ref, cfg_clock_ref_cmd, |
| 200 | "clock-ref (internal|external|gpsdo)", |
| 201 | "Set the Reference Clock\n" |
Martin Hauke | 066fd04 | 2019-10-13 19:08:00 +0200 | [diff] [blame] | 202 | "Enable internal reference (default)\n" |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 203 | "Enable external 10 MHz reference\n" |
| 204 | "Enable GPSDO reference\n") |
| 205 | { |
| 206 | struct trx_ctx *trx = trx_from_vty(vty); |
| 207 | |
| 208 | trx->cfg.clock_ref = get_string_value(clock_ref_names, argv[0]); |
| 209 | |
| 210 | return CMD_SUCCESS; |
| 211 | } |
| 212 | |
| 213 | DEFUN(cfg_multi_arfcn, cfg_multi_arfcn_cmd, |
| 214 | "multi-arfcn (disable|enable)", |
Vadim Yanitskiy | 5d6504c | 2020-10-30 01:50:05 +0700 | [diff] [blame] | 215 | "Multi-ARFCN transceiver mode (default=disable)\n" |
| 216 | "Enable multi-ARFCN mode\n" "Disable multi-ARFCN mode\n") |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 217 | { |
| 218 | struct trx_ctx *trx = trx_from_vty(vty); |
| 219 | |
| 220 | if (strcmp("disable", argv[0]) == 0) { |
| 221 | trx->cfg.multi_arfcn = false; |
Tom Tsou | d280045 | 2019-04-01 07:55:48 +0700 | [diff] [blame] | 222 | return CMD_SUCCESS; |
| 223 | } |
| 224 | |
| 225 | if (trx->cfg.num_chans > TRX_MCHAN_MAX) { |
| 226 | vty_out(vty, "Up to %i channels are supported for multi-TRX mode%s", |
| 227 | TRX_MCHAN_MAX, VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 228 | return CMD_WARNING; |
| 229 | } |
| 230 | |
Tom Tsou | d280045 | 2019-04-01 07:55:48 +0700 | [diff] [blame] | 231 | trx->cfg.multi_arfcn = true; |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 232 | return CMD_SUCCESS; |
| 233 | } |
| 234 | |
| 235 | DEFUN(cfg_offset, cfg_offset_cmd, |
| 236 | "offset FLOAT", |
| 237 | "Set the baseband frequency offset (default=0, auto)\n" |
| 238 | "Baseband Frequency Offset\n") |
| 239 | { |
| 240 | struct trx_ctx *trx = trx_from_vty(vty); |
| 241 | |
| 242 | trx->cfg.offset = atof(argv[0]); |
| 243 | |
| 244 | return CMD_SUCCESS; |
| 245 | } |
| 246 | |
Vadim Yanitskiy | 3b8f7c4 | 2018-08-23 13:41:06 +0700 | [diff] [blame] | 247 | DEFUN_ATTR(cfg_freq_offset, cfg_freq_offset_cmd, |
| 248 | "freq-offset FLOAT", |
| 249 | "Apply an artificial offset to Rx/Tx carrier frequency\n" |
| 250 | "Frequency offset in kHz (e.g. -145300)\n", |
| 251 | CMD_ATTR_HIDDEN) |
| 252 | { |
| 253 | struct trx_ctx *trx = trx_from_vty(vty); |
| 254 | |
| 255 | trx->cfg.freq_offset_khz = atof(argv[0]); |
| 256 | |
| 257 | return CMD_SUCCESS; |
| 258 | } |
| 259 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 260 | DEFUN(cfg_rssi_offset, cfg_rssi_offset_cmd, |
Pau Espin Pedrol | e91544d | 2020-10-13 17:03:37 +0200 | [diff] [blame] | 261 | "rssi-offset FLOAT [relative]", |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 262 | "Set the RSSI to dBm offset in dB (default=0)\n" |
Pau Espin Pedrol | e91544d | 2020-10-13 17:03:37 +0200 | [diff] [blame] | 263 | "RSSI to dBm offset in dB\n" |
| 264 | "Add to the default rssi-offset value instead of completely replacing it\n") |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 265 | { |
| 266 | struct trx_ctx *trx = trx_from_vty(vty); |
| 267 | |
| 268 | trx->cfg.rssi_offset = atof(argv[0]); |
Pau Espin Pedrol | e91544d | 2020-10-13 17:03:37 +0200 | [diff] [blame] | 269 | trx->cfg.force_rssi_offset = (argc == 1); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 270 | |
| 271 | return CMD_SUCCESS; |
| 272 | } |
| 273 | |
Eric | c27fe60 | 2021-05-05 17:33:18 +0200 | [diff] [blame] | 274 | |
| 275 | DEFUN_ATTR(cfg_ul_fn_offset, cfg_ul_fn_offset_cmd, |
| 276 | "ul-fn-offset <-10-10>", |
| 277 | "Adjusts the uplink frame FN by the specified amount\n" |
| 278 | "Frame Number offset\n", |
| 279 | CMD_ATTR_HIDDEN) |
| 280 | { |
| 281 | struct trx_ctx *trx = trx_from_vty(vty); |
| 282 | |
| 283 | trx->cfg.ul_fn_offset = atoi(argv[0]); |
| 284 | |
| 285 | return CMD_SUCCESS; |
| 286 | } |
| 287 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 288 | DEFUN(cfg_swap_channels, cfg_swap_channels_cmd, |
| 289 | "swap-channels (disable|enable)", |
Vadim Yanitskiy | 948b4e4 | 2020-10-30 01:27:21 +0700 | [diff] [blame] | 290 | "Swap primary and secondary channels of the PHY (if any)\n" |
| 291 | "Do not swap primary and secondary channels (default)\n" |
| 292 | "Swap primary and secondary channels\n") |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 293 | { |
| 294 | struct trx_ctx *trx = trx_from_vty(vty); |
| 295 | |
| 296 | if (strcmp("disable", argv[0]) == 0) { |
| 297 | trx->cfg.swap_channels = false; |
| 298 | } else if (strcmp("enable", argv[0]) == 0) { |
| 299 | trx->cfg.swap_channels = true; |
| 300 | } else { |
| 301 | return CMD_WARNING; |
| 302 | } |
| 303 | |
| 304 | return CMD_SUCCESS; |
| 305 | } |
| 306 | |
| 307 | DEFUN(cfg_egprs, cfg_egprs_cmd, |
| 308 | "egprs (disable|enable)", |
Vadim Yanitskiy | e0bdb6b | 2020-10-30 01:35:19 +0700 | [diff] [blame] | 309 | "EGPRS (8-PSK demodulation) support (default=disable)\n" |
| 310 | "Disable EGPRS (8-PSK demodulation) support\n" |
| 311 | "Enable EGPRS (8-PSK demodulation) support\n") |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 312 | { |
| 313 | struct trx_ctx *trx = trx_from_vty(vty); |
| 314 | |
| 315 | if (strcmp("disable", argv[0]) == 0) { |
| 316 | trx->cfg.egprs = false; |
| 317 | } else if (strcmp("enable", argv[0]) == 0) { |
| 318 | trx->cfg.egprs = true; |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 319 | } else { |
| 320 | return CMD_WARNING; |
| 321 | } |
| 322 | |
| 323 | return CMD_SUCCESS; |
| 324 | } |
| 325 | |
Vadim Yanitskiy | a8b3565 | 2018-10-22 02:52:18 +0200 | [diff] [blame] | 326 | DEFUN(cfg_ext_rach, cfg_ext_rach_cmd, |
| 327 | "ext-rach (disable|enable)", |
Vadim Yanitskiy | faacb19 | 2020-10-30 01:35:49 +0700 | [diff] [blame] | 328 | "11-bit Access Burst correlation support (default=disable)\n" |
| 329 | "Disable 11-bit Access Burst (TS1 & TS2) correlation\n" |
| 330 | "Enable 11-bit Access Burst (TS1 & TS2) correlation\n") |
Vadim Yanitskiy | a8b3565 | 2018-10-22 02:52:18 +0200 | [diff] [blame] | 331 | { |
| 332 | struct trx_ctx *trx = trx_from_vty(vty); |
| 333 | |
| 334 | if (strcmp("disable", argv[0]) == 0) |
| 335 | trx->cfg.ext_rach = false; |
| 336 | |
| 337 | if (strcmp("enable", argv[0]) == 0) |
| 338 | trx->cfg.ext_rach = true; |
| 339 | |
| 340 | return CMD_SUCCESS; |
| 341 | } |
| 342 | |
Pau Espin Pedrol | 553a250 | 2020-07-29 18:05:25 +0200 | [diff] [blame] | 343 | DEFUN_DEPRECATED(cfg_rt_prio, cfg_rt_prio_cmd, |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 344 | "rt-prio <1-32>", |
| 345 | "Set the SCHED_RR real-time priority\n" |
| 346 | "Real time priority\n") |
| 347 | { |
| 348 | struct trx_ctx *trx = trx_from_vty(vty); |
| 349 | |
| 350 | trx->cfg.sched_rr = atoi(argv[0]); |
Pau Espin Pedrol | 553a250 | 2020-07-29 18:05:25 +0200 | [diff] [blame] | 351 | vty_out (vty, "%% 'rt-prio %u' is deprecated, use 'policy rr %u' under 'sched' node instead%s", |
| 352 | trx->cfg.sched_rr, trx->cfg.sched_rr, VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 353 | |
| 354 | return CMD_SUCCESS; |
| 355 | } |
| 356 | |
Eric Wild | ac0487e | 2019-06-17 13:02:44 +0200 | [diff] [blame] | 357 | DEFUN(cfg_stack_size, cfg_stack_size_cmd, |
| 358 | "stack-size <0-2147483647>", |
| 359 | "Set the stack size per thread in BYTE, 0 = OS default\n" |
| 360 | "Stack size per thread in BYTE\n") |
| 361 | { |
| 362 | struct trx_ctx *trx = trx_from_vty(vty); |
| 363 | |
| 364 | trx->cfg.stack_size = atoi(argv[0]); |
| 365 | |
| 366 | return CMD_SUCCESS; |
| 367 | } |
| 368 | |
Vadim Yanitskiy | c0e7ce9 | 2020-10-30 02:19:55 +0700 | [diff] [blame] | 369 | #define CFG_FILLER_DOC_STR \ |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 370 | "Filler burst settings\n" |
Vadim Yanitskiy | c0e7ce9 | 2020-10-30 02:19:55 +0700 | [diff] [blame] | 371 | |
| 372 | DEFUN(cfg_filler, cfg_filler_type_cmd, |
| 373 | "AUTO-GENERATED", "AUTO-GENERATED") |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 374 | { |
| 375 | struct trx_ctx *trx = trx_from_vty(vty); |
| 376 | // trx->cfg.filler is unsigned, so we need an interim int var to detect errors |
| 377 | int type = get_string_value(filler_types, argv[0]); |
| 378 | |
| 379 | if (type < 0) { |
| 380 | trx->cfg.filler = FILLER_ZERO; |
| 381 | return CMD_WARNING; |
| 382 | } |
| 383 | trx->cfg.filler = type; |
| 384 | |
| 385 | return CMD_SUCCESS; |
| 386 | } |
| 387 | |
| 388 | DEFUN(cfg_test_rtsc, cfg_filler_tsc_cmd, |
| 389 | "filler tsc <0-7>", |
Vadim Yanitskiy | c0e7ce9 | 2020-10-30 02:19:55 +0700 | [diff] [blame] | 390 | CFG_FILLER_DOC_STR |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 391 | "Set the TSC for GMSK/8-PSK Normal Burst random fillers. Used only with 'random-nb-gmsk' and" |
| 392 | " 'random-nb-8psk' filler types. (default=0)\n" |
| 393 | "TSC\n") |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 394 | { |
| 395 | struct trx_ctx *trx = trx_from_vty(vty); |
| 396 | |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 397 | trx->cfg.rtsc = atoi(argv[0]); |
| 398 | |
| 399 | return CMD_SUCCESS; |
| 400 | } |
| 401 | |
| 402 | DEFUN(cfg_test_rach_delay, cfg_filler_rach_delay_cmd, |
| 403 | "filler access-burst-delay <0-68>", |
Vadim Yanitskiy | c0e7ce9 | 2020-10-30 02:19:55 +0700 | [diff] [blame] | 404 | CFG_FILLER_DOC_STR |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 405 | "Set the delay for Access Burst random fillers. Used only with 'random-ab' filler type. (default=0)\n" |
| 406 | "RACH delay in symbols\n") |
| 407 | { |
| 408 | struct trx_ctx *trx = trx_from_vty(vty); |
| 409 | |
| 410 | trx->cfg.rach_delay = atoi(argv[0]); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 411 | |
| 412 | return CMD_SUCCESS; |
| 413 | } |
| 414 | |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 415 | static int vty_ctr_name_2_id(const char* str) { |
| 416 | size_t i; |
| 417 | for (i = 0; trx_chan_ctr_names[i].str; i++) { |
| 418 | if (strstr(trx_chan_ctr_names[i].str, str)) { |
| 419 | return i; |
| 420 | } |
| 421 | } |
| 422 | return -1; |
| 423 | } |
| 424 | |
| 425 | static int vty_intv_name_2_id(const char* str) { |
| 426 | size_t i; |
| 427 | for (i = 0; rate_ctr_intv[i].str; i++) { |
| 428 | if (strcmp(rate_ctr_intv[i].str, str) == 0) { |
| 429 | return i; |
| 430 | } |
| 431 | } |
| 432 | return -1; |
| 433 | } |
| 434 | |
Pau Espin Pedrol | 1d0c6fe | 2020-07-09 18:09:10 +0200 | [diff] [blame] | 435 | #define THRESHOLD_ARGS "(rx_overruns|tx_underruns|rx_drop_events|rx_drop_samples|tx_drop_events|tx_drop_samples|tx_stale_bursts|tx_unavailable_bursts|tx_trxd_fn_repeated|tx_trxd_fn_outoforder|tx_trxd_fn_skipped)" |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 436 | #define THRESHOLD_STR_VAL(s) "Set threshold value for rate_ctr device:" OSMO_STRINGIFY_VAL(s) "\n" |
| 437 | #define THRESHOLD_STRS \ |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 438 | THRESHOLD_STR_VAL(rx_overruns) \ |
| 439 | THRESHOLD_STR_VAL(tx_underruns) \ |
| 440 | THRESHOLD_STR_VAL(rx_drop_events) \ |
Pau Espin Pedrol | 68a7809 | 2019-07-29 20:11:25 +0200 | [diff] [blame] | 441 | THRESHOLD_STR_VAL(rx_drop_samples) \ |
| 442 | THRESHOLD_STR_VAL(tx_drop_events) \ |
Pau Espin Pedrol | 92ba59d | 2020-06-29 14:34:59 +0200 | [diff] [blame] | 443 | THRESHOLD_STR_VAL(tx_drop_samples) \ |
Pau Espin Pedrol | c0d6fd2 | 2020-07-09 16:51:47 +0200 | [diff] [blame] | 444 | THRESHOLD_STR_VAL(tx_stale_bursts) \ |
Pau Espin Pedrol | 1d0c6fe | 2020-07-09 18:09:10 +0200 | [diff] [blame] | 445 | THRESHOLD_STR_VAL(tx_unavailable_bursts) \ |
Pau Espin Pedrol | c0d6fd2 | 2020-07-09 16:51:47 +0200 | [diff] [blame] | 446 | THRESHOLD_STR_VAL(tx_trxd_fn_repeated) \ |
| 447 | THRESHOLD_STR_VAL(tx_trxd_fn_outoforder) \ |
| 448 | THRESHOLD_STR_VAL(tx_trxd_fn_skipped) \ |
| 449 | "" |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 450 | #define INTV_ARGS "(per-second|per-minute|per-hour|per-day)" |
| 451 | #define INTV_STR_VAL(s) "Threshold value sampled " OSMO_STRINGIFY_VAL(s) "\n" |
| 452 | #define INTV_STRS \ |
| 453 | INTV_STR_VAL(per-second) \ |
| 454 | INTV_STR_VAL(per-minute) \ |
| 455 | INTV_STR_VAL(per-hour) \ |
| 456 | INTV_STR_VAL(per-day) |
| 457 | |
Philipp Maier | 30863e8 | 2020-09-29 22:03:51 +0200 | [diff] [blame] | 458 | DEFUN_ATTR(cfg_ctr_error_threshold, cfg_ctr_error_threshold_cmd, |
| 459 | "ctr-error-threshold " THRESHOLD_ARGS " <0-65535> " INTV_ARGS, |
| 460 | "Threshold rate for error counter\n" |
| 461 | THRESHOLD_STRS |
| 462 | "Value to set for threshold\n" |
| 463 | INTV_STRS, |
| 464 | CMD_ATTR_IMMEDIATE) |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 465 | { |
| 466 | int rc; |
| 467 | struct ctr_threshold ctr; |
| 468 | |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 469 | rc = vty_ctr_name_2_id(argv[0]); |
| 470 | if (rc < 0) { |
| 471 | vty_out(vty, "No valid ctr_name found for ctr-error-threshold %s%s", |
| 472 | argv[0], VTY_NEWLINE); |
| 473 | return CMD_WARNING; |
| 474 | } |
| 475 | ctr.ctr_id = (enum TrxCtr)rc; |
| 476 | ctr.val = atoi(argv[1]); |
| 477 | rc = vty_intv_name_2_id(argv[2]); |
| 478 | if (rc < 0) { |
| 479 | vty_out(vty, "No valid time frame found for ctr-error-threshold %s %d %s%s", |
| 480 | argv[0], ctr.val, argv[2], VTY_NEWLINE); |
| 481 | return CMD_WARNING; |
| 482 | } |
| 483 | ctr.intv = (enum rate_ctr_intv) rc; |
| 484 | trx_rate_ctr_threshold_add(&ctr); |
| 485 | |
| 486 | return CMD_SUCCESS; |
| 487 | } |
| 488 | |
Philipp Maier | 30863e8 | 2020-09-29 22:03:51 +0200 | [diff] [blame] | 489 | DEFUN_ATTR(cfg_no_ctr_error_threshold, cfg_no_ctr_error_threshold_cmd, |
| 490 | "no ctr-error-threshold " THRESHOLD_ARGS " <0-65535> " INTV_ARGS, |
| 491 | NO_STR "Threshold rate for error counter\n" |
| 492 | THRESHOLD_STRS |
| 493 | "Value to set for threshold\n" |
| 494 | INTV_STRS, |
| 495 | CMD_ATTR_IMMEDIATE) |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 496 | { |
| 497 | int rc; |
| 498 | struct ctr_threshold ctr; |
| 499 | |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 500 | rc = vty_ctr_name_2_id(argv[0]); |
| 501 | if (rc < 0) { |
| 502 | vty_out(vty, "No valid ctr_name found for ctr-error-threshold %s%s", |
| 503 | argv[0], VTY_NEWLINE); |
| 504 | return CMD_WARNING; |
| 505 | } |
| 506 | ctr.ctr_id = (enum TrxCtr)rc; |
| 507 | ctr.val = atoi(argv[1]); |
| 508 | rc = vty_intv_name_2_id(argv[2]); |
| 509 | if (rc < 0) { |
| 510 | vty_out(vty, "No valid time frame found for ctr-error-threshold %s %d %s%s", |
| 511 | argv[0], ctr.val, argv[2], VTY_NEWLINE); |
| 512 | return CMD_WARNING; |
| 513 | } |
| 514 | ctr.intv = (enum rate_ctr_intv) rc; |
| 515 | if (trx_rate_ctr_threshold_del(&ctr) < 0) { |
| 516 | vty_out(vty, "no ctr-error-threshold: Entry to delete not found%s", VTY_NEWLINE); |
| 517 | return CMD_WARNING; |
| 518 | } |
| 519 | |
| 520 | return CMD_SUCCESS; |
| 521 | } |
| 522 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 523 | DEFUN(cfg_chan, cfg_chan_cmd, |
| 524 | "chan <0-100>", |
| 525 | "Select a channel to configure\n" |
| 526 | "Channel index\n") |
| 527 | { |
| 528 | struct trx_ctx *trx = trx_from_vty(vty); |
| 529 | int idx = atoi(argv[0]); |
| 530 | |
| 531 | if (idx >= TRX_CHAN_MAX) { |
| 532 | vty_out(vty, "Chan list full.%s", VTY_NEWLINE); |
| 533 | return CMD_WARNING; |
Tom Tsou | d280045 | 2019-04-01 07:55:48 +0700 | [diff] [blame] | 534 | } else if (trx->cfg.multi_arfcn && trx->cfg.num_chans >= TRX_MCHAN_MAX) { |
| 535 | vty_out(vty, "Up to %i channels are supported for multi-TRX mode%s", |
| 536 | TRX_MCHAN_MAX, VTY_NEWLINE); |
| 537 | return CMD_WARNING; |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 538 | } |
Tom Tsou | d280045 | 2019-04-01 07:55:48 +0700 | [diff] [blame] | 539 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 540 | if (trx->cfg.num_chans < idx) { /* Unexisting or creating non-consecutive */ |
| 541 | vty_out(vty, "Non-existent or non-consecutive chan %d.%s", |
| 542 | idx, VTY_NEWLINE); |
| 543 | return CMD_WARNING; |
| 544 | } else if (trx->cfg.num_chans == idx) { /* creating it */ |
| 545 | trx->cfg.num_chans++; |
| 546 | trx->cfg.chans[idx].trx = trx; |
| 547 | trx->cfg.chans[idx].idx = idx; |
| 548 | } |
| 549 | |
| 550 | vty->node = CHAN_NODE; |
| 551 | vty->index = &trx->cfg.chans[idx]; |
| 552 | |
| 553 | return CMD_SUCCESS; |
| 554 | } |
| 555 | |
| 556 | DEFUN(cfg_chan_rx_path, cfg_chan_rx_path_cmd, |
| 557 | "rx-path NAME", |
| 558 | "Set the Rx Path\n" |
| 559 | "Rx Path name\n") |
| 560 | { |
| 561 | struct trx_chan *chan = vty->index; |
| 562 | |
Vadim Yanitskiy | 4d43684 | 2020-09-11 18:31:08 +0700 | [diff] [blame] | 563 | if (chan->trx->cfg.multi_arfcn && chan->idx > 0) { |
| 564 | vty_out(vty, "%% Setting 'rx-path' for chan %u in multi-ARFCN mode " |
| 565 | "does not make sense, because only chan 0 is used%s", |
| 566 | chan->idx, VTY_NEWLINE); |
| 567 | } |
| 568 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 569 | osmo_talloc_replace_string(chan->trx, &chan->rx_path, argv[0]); |
| 570 | |
| 571 | return CMD_SUCCESS; |
| 572 | } |
| 573 | |
| 574 | DEFUN(cfg_chan_tx_path, cfg_chan_tx_path_cmd, |
| 575 | "tx-path NAME", |
| 576 | "Set the Tx Path\n" |
| 577 | "Tx Path name\n") |
| 578 | { |
| 579 | struct trx_chan *chan = vty->index; |
| 580 | |
Vadim Yanitskiy | 4d43684 | 2020-09-11 18:31:08 +0700 | [diff] [blame] | 581 | if (chan->trx->cfg.multi_arfcn && chan->idx > 0) { |
| 582 | vty_out(vty, "%% Setting 'tx-path' for chan %u in multi-ARFCN mode " |
| 583 | "does not make sense, because only chan 0 is used%s", |
| 584 | chan->idx, VTY_NEWLINE); |
| 585 | } |
| 586 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 587 | osmo_talloc_replace_string(chan->trx, &chan->tx_path, argv[0]); |
| 588 | |
| 589 | return CMD_SUCCESS; |
| 590 | } |
| 591 | |
| 592 | static int dummy_config_write(struct vty *v) |
| 593 | { |
| 594 | return CMD_SUCCESS; |
| 595 | } |
| 596 | |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 597 | static int config_write_trx(struct vty *vty) |
| 598 | { |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 599 | struct trx_chan *chan; |
| 600 | int i; |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 601 | struct trx_ctx *trx = trx_from_vty(vty); |
| 602 | |
| 603 | vty_out(vty, "trx%s", VTY_NEWLINE); |
| 604 | if (trx->cfg.bind_addr) |
| 605 | vty_out(vty, " bind-ip %s%s", trx->cfg.bind_addr, VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 606 | if (trx->cfg.remote_addr) |
| 607 | vty_out(vty, " remote-ip %s%s", trx->cfg.remote_addr, VTY_NEWLINE); |
| 608 | if (trx->cfg.base_port != DEFAULT_TRX_PORT) |
| 609 | vty_out(vty, " base-port %u%s", trx->cfg.base_port, VTY_NEWLINE); |
Eric | 19e134a | 2023-05-10 23:50:38 +0200 | [diff] [blame^] | 610 | if (strlen(trx->cfg.dev_args)) |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 611 | vty_out(vty, " dev-args %s%s", trx->cfg.dev_args, VTY_NEWLINE); |
| 612 | if (trx->cfg.tx_sps != DEFAULT_TX_SPS) |
| 613 | vty_out(vty, " tx-sps %u%s", trx->cfg.tx_sps, VTY_NEWLINE); |
| 614 | if (trx->cfg.rx_sps != DEFAULT_RX_SPS) |
| 615 | vty_out(vty, " rx-sps %u%s", trx->cfg.rx_sps, VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 616 | if (trx->cfg.clock_ref != REF_INTERNAL) |
| 617 | vty_out(vty, " clock-ref %s%s", get_value_string(clock_ref_names, trx->cfg.clock_ref), VTY_NEWLINE); |
| 618 | vty_out(vty, " multi-arfcn %s%s", trx->cfg.multi_arfcn ? "enable" : "disable", VTY_NEWLINE); |
| 619 | if (trx->cfg.offset != 0) |
| 620 | vty_out(vty, " offset %f%s", trx->cfg.offset, VTY_NEWLINE); |
Vadim Yanitskiy | 3b8f7c4 | 2018-08-23 13:41:06 +0700 | [diff] [blame] | 621 | if (trx->cfg.freq_offset_khz != 0) |
| 622 | vty_out(vty, " freq-offset %f%s", trx->cfg.freq_offset_khz, VTY_NEWLINE); |
Pau Espin Pedrol | e91544d | 2020-10-13 17:03:37 +0200 | [diff] [blame] | 623 | if (!(trx->cfg.rssi_offset == 0 && !trx->cfg.force_rssi_offset)) |
| 624 | vty_out(vty, " rssi-offset %f%s%s", trx->cfg.rssi_offset, |
| 625 | trx->cfg.force_rssi_offset ? " relative": "", VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 626 | vty_out(vty, " swap-channels %s%s", trx->cfg.swap_channels ? "enable" : "disable", VTY_NEWLINE); |
| 627 | vty_out(vty, " egprs %s%s", trx->cfg.egprs ? "enable" : "disable", VTY_NEWLINE); |
Vadim Yanitskiy | a8b3565 | 2018-10-22 02:52:18 +0200 | [diff] [blame] | 628 | vty_out(vty, " ext-rach %s%s", trx->cfg.ext_rach ? "enable" : "disable", VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 629 | if (trx->cfg.sched_rr != 0) |
| 630 | vty_out(vty, " rt-prio %u%s", trx->cfg.sched_rr, VTY_NEWLINE); |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 631 | if (trx->cfg.filler != FILLER_ZERO) |
| 632 | vty_out(vty, " filler type %s%s", get_value_string(filler_types, trx->cfg.filler), VTY_NEWLINE); |
| 633 | if (trx->cfg.rtsc > 0) |
| 634 | vty_out(vty, " filler tsc %u%s", trx->cfg.rtsc, VTY_NEWLINE); |
| 635 | if (trx->cfg.rach_delay > 0) |
| 636 | vty_out(vty, " filler access-burst-delay %u%s", trx->cfg.rach_delay, VTY_NEWLINE); |
Eric Wild | ac0487e | 2019-06-17 13:02:44 +0200 | [diff] [blame] | 637 | if (trx->cfg.stack_size != 0) |
| 638 | vty_out(vty, " stack-size %u%s", trx->cfg.stack_size, VTY_NEWLINE); |
Eric | c27fe60 | 2021-05-05 17:33:18 +0200 | [diff] [blame] | 639 | if (trx->cfg.ul_fn_offset != 0) |
Eric | 0c34c64 | 2021-06-16 15:20:51 +0200 | [diff] [blame] | 640 | vty_out(vty, " ul-fn-offset %d%s", trx->cfg.ul_fn_offset, VTY_NEWLINE); |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 641 | trx_rate_ctr_threshold_write_config(vty, " "); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 642 | |
| 643 | for (i = 0; i < trx->cfg.num_chans; i++) { |
| 644 | chan = &trx->cfg.chans[i]; |
| 645 | vty_out(vty, " chan %u%s", chan->idx, VTY_NEWLINE); |
| 646 | if (chan->rx_path) |
Harald Welte | 03b3c30 | 2018-07-31 15:48:18 +0200 | [diff] [blame] | 647 | vty_out(vty, " rx-path %s%s", chan->rx_path, VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 648 | if (chan->tx_path) |
Harald Welte | 03b3c30 | 2018-07-31 15:48:18 +0200 | [diff] [blame] | 649 | vty_out(vty, " tx-path %s%s", chan->tx_path, VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 650 | } |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 651 | |
| 652 | return CMD_SUCCESS; |
| 653 | } |
| 654 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 655 | static void trx_dump_vty(struct vty *vty, struct trx_ctx *trx) |
| 656 | { |
| 657 | struct trx_chan *chan; |
| 658 | int i; |
| 659 | vty_out(vty, "TRX Config:%s", VTY_NEWLINE); |
| 660 | vty_out(vty, " Local IP: %s%s", trx->cfg.bind_addr, VTY_NEWLINE); |
| 661 | vty_out(vty, " Remote IP: %s%s", trx->cfg.remote_addr, VTY_NEWLINE); |
| 662 | vty_out(vty, " TRX Base Port: %u%s", trx->cfg.base_port, VTY_NEWLINE); |
| 663 | vty_out(vty, " Device args: %s%s", trx->cfg.dev_args, VTY_NEWLINE); |
| 664 | vty_out(vty, " Tx Samples-per-Symbol: %u%s", trx->cfg.tx_sps, VTY_NEWLINE); |
| 665 | vty_out(vty, " Rx Samples-per-Symbol: %u%s", trx->cfg.rx_sps, VTY_NEWLINE); |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 666 | vty_out(vty, " Filler Burst Type: %s%s", get_value_string(filler_names, trx->cfg.filler), VTY_NEWLINE); |
| 667 | vty_out(vty, " Filler Burst TSC: %u%s", trx->cfg.rtsc, VTY_NEWLINE); |
| 668 | vty_out(vty, " Filler Burst RACH Delay: %u%s", trx->cfg.rach_delay, VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 669 | vty_out(vty, " Clock Reference: %s%s", get_value_string(clock_ref_names, trx->cfg.clock_ref), VTY_NEWLINE); |
| 670 | vty_out(vty, " Multi-Carrier: %s%s", trx->cfg.multi_arfcn ? "Enabled" : "Disabled", VTY_NEWLINE); |
| 671 | vty_out(vty, " Tuning offset: %f%s", trx->cfg.offset, VTY_NEWLINE); |
| 672 | vty_out(vty, " RSSI to dBm offset: %f%s", trx->cfg.rssi_offset, VTY_NEWLINE); |
| 673 | vty_out(vty, " Swap channels: %s%s", trx->cfg.swap_channels ? "Enabled" : "Disabled", VTY_NEWLINE); |
| 674 | vty_out(vty, " EDGE support: %s%s", trx->cfg.egprs ? "Enabled" : "Disabled", VTY_NEWLINE); |
Vadim Yanitskiy | a8b3565 | 2018-10-22 02:52:18 +0200 | [diff] [blame] | 675 | vty_out(vty, " Extended RACH support: %s%s", trx->cfg.ext_rach ? "Enabled" : "Disabled", VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 676 | vty_out(vty, " Real Time Priority: %u (%s)%s", trx->cfg.sched_rr, |
| 677 | trx->cfg.sched_rr ? "Enabled" : "Disabled", VTY_NEWLINE); |
Eric Wild | ac0487e | 2019-06-17 13:02:44 +0200 | [diff] [blame] | 678 | vty_out(vty, " Stack size per Thread in BYTE (0 = OS default): %u%s", trx->cfg.stack_size, VTY_NEWLINE); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 679 | vty_out(vty, " Channels: %u%s", trx->cfg.num_chans, VTY_NEWLINE); |
| 680 | for (i = 0; i < trx->cfg.num_chans; i++) { |
| 681 | chan = &trx->cfg.chans[i]; |
| 682 | vty_out(vty, " Channel %u:%s", chan->idx, VTY_NEWLINE); |
| 683 | if (chan->rx_path) |
| 684 | vty_out(vty, " Rx Path: %s%s", chan->rx_path, VTY_NEWLINE); |
| 685 | if (chan->tx_path) |
| 686 | vty_out(vty, " Tx Path: %s%s", chan->tx_path, VTY_NEWLINE); |
| 687 | } |
| 688 | } |
| 689 | |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 690 | DEFUN(show_trx, show_trx_cmd, |
| 691 | "show trx", |
| 692 | SHOW_STR "Display information on the TRX\n") |
| 693 | { |
| 694 | struct trx_ctx *trx = trx_from_vty(vty); |
| 695 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 696 | trx_dump_vty(vty, trx); |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 697 | |
| 698 | return CMD_SUCCESS; |
| 699 | } |
| 700 | |
| 701 | static int trx_vty_is_config_node(struct vty *vty, int node) |
| 702 | { |
| 703 | switch (node) { |
| 704 | case TRX_NODE: |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 705 | case CHAN_NODE: |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 706 | return 1; |
| 707 | default: |
| 708 | return 0; |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | static int trx_vty_go_parent(struct vty *vty) |
| 713 | { |
| 714 | switch (vty->node) { |
| 715 | case TRX_NODE: |
| 716 | vty->node = CONFIG_NODE; |
| 717 | vty->index = NULL; |
| 718 | vty->index_sub = NULL; |
| 719 | break; |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 720 | case CHAN_NODE: |
| 721 | vty->node = TRX_NODE; |
| 722 | vty->index = NULL; |
| 723 | vty->index_sub = NULL; |
| 724 | break; |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 725 | default: |
Vadim Yanitskiy | 01eea0a | 2018-05-09 15:19:48 +0700 | [diff] [blame] | 726 | vty->node = CONFIG_NODE; |
| 727 | vty->index = NULL; |
| 728 | vty->index_sub = NULL; |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 729 | } |
| 730 | |
| 731 | return vty->node; |
| 732 | } |
| 733 | |
| 734 | static const char trx_copyright[] = |
| 735 | "Copyright (C) 2007-2014 Free Software Foundation, Inc.\r\n" |
| 736 | "Copyright (C) 2013 Thomas Tsou <tom@tsou.cc>\r\n" |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 737 | "Copyright (C) 2013-2019 Fairwaves, Inc.\r\n" |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 738 | "Copyright (C) 2015 Ettus Research LLC\r\n" |
| 739 | "Copyright (C) 2017-2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>\r\n" |
| 740 | "License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n" |
| 741 | "This is free software: you are free to change and redistribute it.\r\n" |
| 742 | "There is NO WARRANTY, to the extent permitted by law.\r\n"; |
| 743 | |
| 744 | struct vty_app_info g_vty_info = { |
| 745 | .name = "OsmoTRX", |
| 746 | .version = PACKAGE_VERSION, |
| 747 | .copyright = trx_copyright, |
| 748 | .go_parent_cb = trx_vty_go_parent, |
| 749 | .is_config_node = trx_vty_is_config_node, |
| 750 | }; |
| 751 | |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 752 | struct trx_ctx *vty_trx_ctx_alloc(void *talloc_ctx) |
| 753 | { |
| 754 | struct trx_ctx * trx = talloc_zero(talloc_ctx, struct trx_ctx); |
| 755 | |
| 756 | trx->cfg.bind_addr = talloc_strdup(trx, DEFAULT_TRX_IP); |
| 757 | trx->cfg.remote_addr = talloc_strdup(trx, DEFAULT_TRX_IP); |
| 758 | trx->cfg.base_port = DEFAULT_TRX_PORT; |
| 759 | trx->cfg.tx_sps = DEFAULT_TX_SPS; |
| 760 | trx->cfg.rx_sps = DEFAULT_RX_SPS; |
| 761 | trx->cfg.filler = FILLER_ZERO; |
Pau Espin Pedrol | e91544d | 2020-10-13 17:03:37 +0200 | [diff] [blame] | 762 | trx->cfg.rssi_offset = 0.0f; |
Eric | 19e134a | 2023-05-10 23:50:38 +0200 | [diff] [blame^] | 763 | trx->cfg.dev_args = ""; |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 764 | |
| 765 | return trx; |
| 766 | } |
| 767 | |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 768 | int trx_vty_init(struct trx_ctx* trx) |
| 769 | { |
Vadim Yanitskiy | c0e7ce9 | 2020-10-30 02:19:55 +0700 | [diff] [blame] | 770 | cfg_filler_type_cmd.string = vty_cmd_string_from_valstr(trx, filler_types, |
| 771 | "filler type (", "|", ")", 0); |
| 772 | cfg_filler_type_cmd.doc = vty_cmd_string_from_valstr(trx, filler_docs, |
| 773 | CFG_FILLER_DOC_STR "What to do when there is nothing to send " |
| 774 | "(filler type, default=zero)\n", "\n", "", 0); |
| 775 | |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 776 | g_trx_ctx = trx; |
| 777 | install_element_ve(&show_trx_cmd); |
| 778 | |
| 779 | install_element(CONFIG_NODE, &cfg_trx_cmd); |
| 780 | |
| 781 | install_node(&trx_node, config_write_trx); |
| 782 | install_element(TRX_NODE, &cfg_bind_ip_cmd); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 783 | install_element(TRX_NODE, &cfg_remote_ip_cmd); |
| 784 | install_element(TRX_NODE, &cfg_base_port_cmd); |
| 785 | install_element(TRX_NODE, &cfg_dev_args_cmd); |
| 786 | install_element(TRX_NODE, &cfg_tx_sps_cmd); |
| 787 | install_element(TRX_NODE, &cfg_rx_sps_cmd); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 788 | install_element(TRX_NODE, &cfg_clock_ref_cmd); |
| 789 | install_element(TRX_NODE, &cfg_multi_arfcn_cmd); |
| 790 | install_element(TRX_NODE, &cfg_offset_cmd); |
Vadim Yanitskiy | 3b8f7c4 | 2018-08-23 13:41:06 +0700 | [diff] [blame] | 791 | install_element(TRX_NODE, &cfg_freq_offset_cmd); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 792 | install_element(TRX_NODE, &cfg_rssi_offset_cmd); |
| 793 | install_element(TRX_NODE, &cfg_swap_channels_cmd); |
| 794 | install_element(TRX_NODE, &cfg_egprs_cmd); |
Vadim Yanitskiy | a8b3565 | 2018-10-22 02:52:18 +0200 | [diff] [blame] | 795 | install_element(TRX_NODE, &cfg_ext_rach_cmd); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 796 | install_element(TRX_NODE, &cfg_rt_prio_cmd); |
Alexander Chemeris | 9a87d90 | 2019-10-15 00:33:07 +0300 | [diff] [blame] | 797 | install_element(TRX_NODE, &cfg_filler_type_cmd); |
| 798 | install_element(TRX_NODE, &cfg_filler_tsc_cmd); |
| 799 | install_element(TRX_NODE, &cfg_filler_rach_delay_cmd); |
Pau Espin Pedrol | 6a305fe | 2019-05-24 19:58:20 +0200 | [diff] [blame] | 800 | install_element(TRX_NODE, &cfg_ctr_error_threshold_cmd); |
| 801 | install_element(TRX_NODE, &cfg_no_ctr_error_threshold_cmd); |
Eric Wild | ac0487e | 2019-06-17 13:02:44 +0200 | [diff] [blame] | 802 | install_element(TRX_NODE, &cfg_stack_size_cmd); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 803 | |
| 804 | install_element(TRX_NODE, &cfg_chan_cmd); |
Eric | c27fe60 | 2021-05-05 17:33:18 +0200 | [diff] [blame] | 805 | install_element(TRX_NODE, &cfg_ul_fn_offset_cmd); |
Pau Espin Pedrol | a3ab8c2 | 2018-02-21 15:41:03 +0100 | [diff] [blame] | 806 | install_node(&chan_node, dummy_config_write); |
| 807 | install_element(CHAN_NODE, &cfg_chan_rx_path_cmd); |
| 808 | install_element(CHAN_NODE, &cfg_chan_tx_path_cmd); |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 809 | |
Pau Espin Pedrol | aebbfe0 | 2020-01-02 16:39:11 +0100 | [diff] [blame] | 810 | logging_vty_add_deprecated_subsys(g_trx_ctx, "lms"); |
| 811 | |
Pau Espin Pedrol | 5ea1817 | 2018-02-20 16:48:15 +0100 | [diff] [blame] | 812 | return 0; |
| 813 | } |