diff options
Diffstat (limited to 'src/common/vty.c')
-rw-r--r-- | src/common/vty.c | 621 |
1 files changed, 506 insertions, 115 deletions
diff --git a/src/common/vty.c b/src/common/vty.c index a7d1e845..c0008a85 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -22,6 +22,7 @@ #include "btsconfig.h" #include <inttypes.h> +#include <limits.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -37,17 +38,20 @@ #include <osmocom/vty/logging.h> #include <osmocom/vty/misc.h> #include <osmocom/vty/ports.h> +#include <osmocom/vty/tdef_vty.h> #include <osmocom/core/gsmtap.h> #include <osmocom/core/utils.h> #include <osmocom/core/sockaddr_str.h> #include <osmocom/trau/osmo_ortp.h> - +#include <osmocom/core/fsm.h> +#include <osmocom/codec/codec.h> #include <osmo-bts/logging.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/phy_link.h> #include <osmo-bts/abis.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/rsl.h> #include <osmo-bts/oml.h> #include <osmo-bts/signal.h> @@ -56,6 +60,7 @@ #include <osmo-bts/measurement.h> #include <osmo-bts/vty.h> #include <osmo-bts/l1sap.h> +#include <osmo-bts/osmux.h> #define VTY_STR "Configure the VTY\n" @@ -66,6 +71,9 @@ #define BTS_TRX_STR BTS_NR_STR TRX_NR_STR #define BTS_TRX_TS_STR BTS_TRX_STR TS_NR_STR #define BTS_TRX_TS_LCHAN_STR BTS_TRX_TS_STR LCHAN_NR_STR +/* INT32_MAX, because osmo_wqueue_init takes int as an argument + * and INT_MAX can't be stringified as a decimal */ +#define BTS_CFG_PCU_SOCK_WQUEUE_LEN_MAX_MAX 2147483647 #define X(x) (1 << x) @@ -132,21 +140,9 @@ int bts_vty_go_parent(struct vty *vty) return vty->node; } -int bts_vty_is_config_node(struct vty *vty, int node) -{ - switch (node) { - case TRX_NODE: - case BTS_NODE: - case PHY_NODE: - case PHY_INST_NODE: - return 1; - default: - return 0; - } -} - static const char osmobts_copyright[] = - "Copyright (C) 2010, 2011 by Harald Welte, Andreas Eversberg and On-Waves\r\n" + "Copyright (C) 2010-2011 by Harald Welte, Andreas Eversberg and On-Waves\r\n" + "Copyright (C) 2011-2022 by sysmocom - s.f.m.c. GmbH\r\n" "License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n" "This is free software: you are free to change and redistribute it.\r\n" "There is NO WARRANTY, to the extent permitted by law.\r\n"; @@ -156,7 +152,6 @@ struct vty_app_info bts_vty_info = { .version = PACKAGE_VERSION, .copyright = osmobts_copyright, .go_parent_cb = bts_vty_go_parent, - .is_config_node = bts_vty_is_config_node, .usr_attr_desc = { [BTS_VTY_ATTR_NEW_LCHAN] = \ "This command applies for newly created lchans", @@ -169,13 +164,6 @@ struct vty_app_info bts_vty_info = { }, }; -extern struct gsm_network bts_gsmnet; - -struct gsm_network *gsmnet_from_vty(struct vty *v) -{ - return &bts_gsmnet; -} - static struct cmd_node bts_node = { BTS_NODE, "%s(bts)# ", @@ -188,6 +176,12 @@ static struct cmd_node trx_node = { 1, }; +static struct cmd_node osmux_node = { + OSMUX_NODE, + "%s(osmux)# ", + 1, +}; + gDEFUN(cfg_bts_auto_band, cfg_bts_auto_band_cmd, "auto-band", "Automatically select band for ARFCN based on configured band\n") @@ -208,6 +202,90 @@ gDEFUN(cfg_bts_no_auto_band, cfg_bts_no_auto_band_cmd, return CMD_SUCCESS; } +DEFUN_ATTR(cfg_bts_osmux, cfg_bts_osmux_cmd, + "osmux", + "Configure Osmux\n", + CMD_ATTR_IMMEDIATE) +{ + vty->node = OSMUX_NODE; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_bts_osmux_use, cfg_bts_osmux_use_cmd, + "use (off|on|only)", + "Configure Osmux usage\n" + "Never use Osmux\n" + "Use Osmux if requested by BSC (default)\n" + "Always use Osmux, reject non-Osmux BSC requests\n", + CMD_ATTR_IMMEDIATE) +{ + struct gsm_bts *bts = vty->index; + if (strcmp(argv[0], "off") == 0) + bts->osmux.use = OSMUX_USAGE_OFF; + else if (strcmp(argv[0], "on") == 0) + bts->osmux.use = OSMUX_USAGE_ON; + else if (strcmp(argv[0], "only") == 0) + bts->osmux.use = OSMUX_USAGE_ONLY; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_ip, + cfg_bts_osmux_ip_cmd, + "local-ip " VTY_IPV46_CMD, + IP_STR + "IPv4 Address to bind to\n" + "IPv6 Address to bind to\n") +{ + struct gsm_bts *bts = vty->index; + osmo_talloc_replace_string(bts, &bts->osmux.local_addr, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_port, + cfg_bts_osmux_port_cmd, + "local-port <1-65535>", + "Osmux port\n" "UDP port\n") +{ + struct gsm_bts *bts = vty->index; + bts->osmux.local_port = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_batch_factor, + cfg_bts_osmux_batch_factor_cmd, + "batch-factor <1-8>", + "Batching factor\n" "Number of messages in the batch\n") +{ + struct gsm_bts *bts = vty->index; + bts->osmux.batch_factor = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_batch_size, + cfg_bts_osmux_batch_size_cmd, + "batch-size <1-65535>", + "Batch size\n" "Batch size in bytes\n") +{ + struct gsm_bts *bts = vty->index; + bts->osmux.batch_size = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_dummy_padding, + cfg_bts_osmux_dummy_padding_cmd, + "dummy-padding (on|off)", + "Dummy padding\n" + "Enable dummy padding\n" + "Disable dummy padding (default)\n") +{ + struct gsm_bts *bts = vty->index; + if (strcmp(argv[0], "on") == 0) + bts->osmux.dummy_padding = true; + else if (strcmp(argv[0], "off") == 0) + bts->osmux.dummy_padding = false; + return CMD_SUCCESS; +} + DEFUN_ATTR(cfg_bts_trx, cfg_bts_trx_cmd, "trx <0-254>", "Select a TRX to configure\n" "TRX number\n", @@ -277,11 +355,35 @@ static void config_write_dpc_params(struct vty *vty, const char *prefix, } } +static void config_write_osmux(struct vty *vty, const char *prefix, const struct gsm_bts *bts) +{ + vty_out(vty, "%sosmux%s", prefix, VTY_NEWLINE); + vty_out(vty, "%s use ", prefix); + switch (bts->osmux.use) { + case OSMUX_USAGE_ON: + vty_out(vty, "on%s", VTY_NEWLINE); + break; + case OSMUX_USAGE_ONLY: + vty_out(vty, "only%s", VTY_NEWLINE); + break; + case OSMUX_USAGE_OFF: + default: + vty_out(vty, "off%s", VTY_NEWLINE); + break; + } + vty_out(vty, "%s local-ip %s%s", prefix, bts->osmux.local_addr, VTY_NEWLINE); + vty_out(vty, "%s local-port %u%s", prefix, bts->osmux.local_port, VTY_NEWLINE); + vty_out(vty, "%s batch-factor %d%s", prefix, bts->osmux.batch_factor, VTY_NEWLINE); + vty_out(vty, "%s batch-size %u%s", prefix, bts->osmux.batch_size, VTY_NEWLINE); + vty_out(vty, "%s dummy-padding %s%s", prefix, bts->osmux.dummy_padding ? "on" : "off", VTY_NEWLINE); +} + static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) { const struct gsm_bts_trx *trx; const char *sapi_buf; int i; + struct bsc_oml_host *bsc_oml_host; vty_out(vty, "bts %u%s", bts->nr, VTY_NEWLINE); if (bts->description) @@ -291,7 +393,8 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " auto-band%s", VTY_NEWLINE); vty_out(vty, " ipa unit-id %u %u%s", bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE); - vty_out(vty, " oml remote-ip %s%s", bts->bsc_oml_host, VTY_NEWLINE); + llist_for_each_entry(bsc_oml_host, &bts->bsc_oml_hosts, list) + vty_out(vty, " oml remote-ip %s%s", bsc_oml_host->addr, VTY_NEWLINE); vty_out(vty, " rtp jitter-buffer %u", bts->rtp_jitter_buf_ms); if (bts->rtp_jitter_adaptive) vty_out(vty, " adaptive"); @@ -299,9 +402,15 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " rtp port-range %u %u%s", bts->rtp_port_range_start, bts->rtp_port_range_end, VTY_NEWLINE); if (bts->rtp_ip_dscp != -1) - vty_out(vty, " rtp ip-dscp %i%s", bts->rtp_ip_dscp, VTY_NEWLINE); + vty_out(vty, " rtp ip-dscp %d%s", bts->rtp_ip_dscp, VTY_NEWLINE); if (bts->rtp_priority != -1) - vty_out(vty, " rtp socket-priority %i%s", bts->rtp_priority, VTY_NEWLINE); + vty_out(vty, " rtp socket-priority %d%s", bts->rtp_priority, VTY_NEWLINE); + if (bts->rtp_nogaps_mode) + vty_out(vty, " rtp continuous-streaming%s", VTY_NEWLINE); + vty_out(vty, " %srtp internal-uplink-ecu%s", + bts->use_ul_ecu ? "" : "no ", VTY_NEWLINE); + vty_out(vty, " rtp hr-format %s%s", + bts->emit_hr_rfc5993 ? "rfc5993" : "ts101318", VTY_NEWLINE); vty_out(vty, " paging queue-size %u%s", paging_get_queue_max(bts->paging_state), VTY_NEWLINE); vty_out(vty, " paging lifetime %u%s", paging_get_lifetime(bts->paging_state), @@ -321,6 +430,10 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " gsmtap-remote-host %s%s", bts->gsmtap.remote_host, VTY_NEWLINE); + if (bts->gsmtap.local_host != NULL) + vty_out(vty, " gsmtap-local-host %s%s", + bts->gsmtap.local_host, + VTY_NEWLINE); for (i = 0; i < sizeof(uint32_t) * 8; i++) { if (bts->gsmtap.sapi_mask & ((uint32_t) 1 << i)) { sapi_buf = get_value_string_or_null(gsmtap_sapi_names, i); @@ -334,6 +447,12 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) sapi_buf = osmo_str_tolower(get_value_string(gsmtap_sapi_names, GSMTAP_CHANNEL_ACCH)); vty_out(vty, " gsmtap-sapi %s%s", sapi_buf, VTY_NEWLINE); } + if (bts->gsmtap.rlp) { + if (bts->gsmtap.rlp_skip_null) + vty_out(vty, " gsmtap-rlp skip-null%s", VTY_NEWLINE); + else + vty_out(vty, " gsmtap-rlp%s", VTY_NEWLINE); + } vty_out(vty, " min-qual-rach %d%s", bts->min_qual_rach, VTY_NEWLINE); vty_out(vty, " min-qual-norm %d%s", bts->min_qual_norm, @@ -342,12 +461,16 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) VTY_NEWLINE); if (strcmp(bts->pcu.sock_path, PCU_SOCK_DEFAULT)) vty_out(vty, " pcu-socket %s%s", bts->pcu.sock_path, VTY_NEWLINE); + if (bts->pcu.sock_wqueue_len_max != BTS_CFG_PCU_SOCK_WQUEUE_LEN_MAX_MAX) + vty_out(vty, " pcu-socket-wqueue-length %u%s", bts->pcu.sock_wqueue_len_max, VTY_NEWLINE); if (bts->supp_meas_toa256) vty_out(vty, " supp-meas-info toa256%s", VTY_NEWLINE); vty_out(vty, " smscb queue-max-length %d%s", bts->smscb_queue_max_len, VTY_NEWLINE); vty_out(vty, " smscb queue-target-length %d%s", bts->smscb_queue_tgt_len, VTY_NEWLINE); vty_out(vty, " smscb queue-hysteresis %d%s", bts->smscb_queue_hyst, VTY_NEWLINE); + config_write_osmux(vty, " ", bts); + bts_model_config_write_bts(vty, bts); llist_for_each_entry(trx, &bts->trx_list, list) { @@ -355,7 +478,7 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) const struct phy_instance *pinst = trx_phy_instance(trx); vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE); - if (trx->power_params.user_gain_mdB) + if (tpp->user_gain_mdB) vty_out(vty, " user-gain %u mdB%s", tpp->user_gain_mdB, VTY_NEWLINE); vty_out(vty, " power-ramp max-initial %d mdBm%s", @@ -367,6 +490,8 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " ms-power-control %s%s", trx->ms_pwr_ctl_soft ? "osmo" : "dsp", VTY_NEWLINE); + vty_out(vty, " ta-control interval %u%s", + trx->ta_ctrl_interval, VTY_NEWLINE); vty_out(vty, " phy %u instance %u%s", pinst->phy_link->num, pinst->num, VTY_NEWLINE); @@ -376,12 +501,12 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) static int config_write_bts(struct vty *vty) { - struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts; - llist_for_each_entry(bts, &net->bts_list, list) + llist_for_each_entry(bts, &g_bts_sm->bts_list, list) config_write_bts_single(vty, bts); + osmo_tdef_vty_groups_write(vty, ""); return CMD_SUCCESS; } @@ -437,16 +562,15 @@ DEFUN_ATTR(cfg_bts, "BTS Number\n", CMD_ATTR_IMMEDIATE) { - struct gsm_network *gsmnet = gsmnet_from_vty(vty); int bts_nr = atoi(argv[0]); struct gsm_bts *bts; - if (bts_nr >= gsmnet->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% Unknown BTS number %u (num %u)%s", - bts_nr, gsmnet->num_bts, VTY_NEWLINE); + bts_nr, g_bts_sm->num_bts, VTY_NEWLINE); return CMD_WARNING; } else - bts = gsm_bts_num(gsmnet, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); vty->index = bts; vty->index_sub = &bts->description; @@ -507,11 +631,51 @@ DEFUN(cfg_bts_oml_ip, "OML Parameters\n" "OML IP Address\n" "OML IP Address\n") { struct gsm_bts *bts = vty->index; + struct bsc_oml_host *bsc_oml_host; + + /* stop when the address is already in the list */ + llist_for_each_entry(bsc_oml_host, &bts->bsc_oml_hosts, list) { + if (strcmp(argv[0], bsc_oml_host->addr) == 0) { + vty_out(vty, "%% duplicate BSC (A-Bis/OML) ip address configured ('%s')%s", + argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + } + + bsc_oml_host = talloc_zero(bts, struct bsc_oml_host); + OSMO_ASSERT(bsc_oml_host); + bsc_oml_host->addr = talloc_strdup(bsc_oml_host, argv[0]); + OSMO_ASSERT(bsc_oml_host->addr); + llist_add_tail(&bsc_oml_host->list, &bts->bsc_oml_hosts); + + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_oml_ip, + cfg_bts_no_oml_ip_cmd, + "no oml remote-ip A.B.C.D", + NO_STR "OML Parameters\n" "OML IP Address\n" "OML IP Address\n") +{ + struct gsm_bts *bts = vty->index; + struct bsc_oml_host *bsc_oml_host; + struct bsc_oml_host *bsc_oml_host_del = NULL; - if (bts->bsc_oml_host) - talloc_free(bts->bsc_oml_host); + llist_for_each_entry(bsc_oml_host, &bts->bsc_oml_hosts, list) { + if (strcmp(argv[0], bsc_oml_host->addr) == 0) + bsc_oml_host_del = bsc_oml_host; + } - bts->bsc_oml_host = talloc_strdup(bts, argv[0]); + if (bsc_oml_host_del) { + if (bts->abis_link_fi) { + osmo_fsm_inst_dispatch(bts->abis_link_fi, ABIS_LINK_EV_VTY_RM_ADDR, bsc_oml_host_del); + llist_del(&bsc_oml_host_del->list); + talloc_free(bsc_oml_host_del); + } + } else { + vty_out(vty, "%% no such BSC (A-Bis/OML) ip address configured ('%s')%s", + argv[0], VTY_NEWLINE); + return CMD_WARNING; + } return CMD_SUCCESS; } @@ -612,6 +776,62 @@ DEFUN_USRATTR(cfg_bts_rtp_priority, return CMD_SUCCESS; } +DEFUN(cfg_bts_rtp_cont_stream, + cfg_bts_rtp_cont_stream_cmd, + "rtp continuous-streaming", + RTP_STR "Always emit an RTP packet every 20 ms\n") +{ + struct gsm_bts *bts = vty->index; + + bts->rtp_nogaps_mode = true; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_rtp_cont_stream, + cfg_bts_no_rtp_cont_stream_cmd, + "no rtp continuous-streaming", + NO_STR RTP_STR "Always emit an RTP packet every 20 ms\n") +{ + struct gsm_bts *bts = vty->index; + + bts->rtp_nogaps_mode = false; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_rtp_int_ul_ecu, + cfg_bts_rtp_int_ul_ecu_cmd, + "rtp internal-uplink-ecu", + RTP_STR "Apply a BTS-internal ECU to the uplink traffic frame stream\n") +{ + struct gsm_bts *bts = vty->index; + + bts->use_ul_ecu = true; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_rtp_int_ul_ecu, + cfg_bts_no_rtp_int_ul_ecu_cmd, + "no rtp internal-uplink-ecu", + NO_STR RTP_STR "Apply a BTS-internal ECU to the uplink traffic frame stream\n") +{ + struct gsm_bts *bts = vty->index; + + bts->use_ul_ecu = false; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_bts_rtp_hr_format, + cfg_bts_rtp_hr_format_cmd, + "rtp hr-format (rfc5993|ts101318)", + RTP_STR "HRv1 codec output format\n" "RFC 5993\n" "TS 101 318\n", + CMD_ATTR_IMMEDIATE) +{ + struct gsm_bts *bts = vty->index; + + bts->emit_hr_rfc5993 = !strcmp(argv[0], "rfc5993"); + return CMD_SUCCESS; +} + #define PAG_STR "Paging related parameters\n" DEFUN_ATTR(cfg_bts_paging_queue_size, @@ -800,7 +1020,7 @@ DEFUN_ATTR(cfg_bts_max_ber_rach, cfg_bts_max_ber_rach_cmd, return CMD_SUCCESS; } -DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd, +DEFUN(cfg_bts_pcu_sock_path, cfg_bts_pcu_sock_path_cmd, "pcu-socket PATH", "Configure the PCU socket file/path name\n" "UNIX socket path\n") @@ -813,6 +1033,16 @@ DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd, return CMD_SUCCESS; } +DEFUN(cfg_bts_pcu_sock_ql, cfg_bts_pcu_sock_ql_cmd, + "pcu-socket-wqueue-length <1-" OSMO_STRINGIFY_VAL(BTS_CFG_PCU_SOCK_WQUEUE_LEN_MAX_MAX) ">", + "Configure the PCU socket queue length\n" + "Queue length\n") +{ + struct gsm_bts *bts = vty->index; + bts->pcu.sock_wqueue_len_max = atoi(argv[0]); + return CMD_SUCCESS; +} + DEFUN_ATTR(cfg_bts_supp_meas_toa256, cfg_bts_supp_meas_toa256_cmd, "supp-meas-info toa256", "Configure the RSL Supplementary Measurement Info\n" @@ -965,6 +1195,19 @@ DEFUN(cfg_trx_ms_power_control, cfg_trx_ms_power_control_cmd, return CMD_SUCCESS; } +DEFUN(cfg_ta_ctrl_interval, cfg_ta_ctrl_interval_cmd, + "ta-control interval <0-31>", + "Timing Advance Control Parameters\n" + "Set TA control loop interval\n" + "As in P_CON_INTERVAL, in units of 2 SACCH periods (0.96 seconds) (default=0, every SACCH block)\n") +{ + struct gsm_bts_trx *trx = vty->index; + + trx->ta_ctrl_interval = atoi(argv[0]); + + return CMD_SUCCESS; +} + DEFUN(cfg_trx_phy, cfg_trx_phy_cmd, "phy <0-255> instance <0-255>", "Configure PHY Link+Instance for this TRX\n" @@ -1030,10 +1273,10 @@ static void bts_dump_vty_features(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " BTS model specific (internal) flags:%s", VTY_NEWLINE); - for (i = 0, no_features = true; i < sizeof(bts->flags) * 8; i++) { - if (bts_internal_flag_get(bts, (1 << i))) { + for (i = 0, no_features = true; i < _BTS_INTERNAL_FLAG_NUM; i++) { + if (bts_internal_flag_get(bts, i)) { vty_out(vty, " %03u ", i); - vty_out(vty, "%-40s%s", get_value_string(bts_impl_flag_desc, (1 << i)), VTY_NEWLINE); + vty_out(vty, "%-40s%s", get_value_string(bts_impl_flag_desc, i), VTY_NEWLINE); no_features = false; } } @@ -1072,7 +1315,7 @@ static void bts_dump_vty(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " NM State: "); net_dump_nmstate(vty, &bts->mo.nm_state); vty_out(vty, " Site Mgr NM State: "); - net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state); + net_dump_nmstate(vty, &g_bts_sm->mo.nm_state); if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH)) vty_out(vty, " PCU version %s connected%s", bts->pcu_version, VTY_NEWLINE); @@ -1131,23 +1374,22 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]", SHOW_STR "Display information about a BTS\n" BTS_NR_STR) { - const struct gsm_network *net = gsmnet_from_vty(vty); int bts_nr; if (argc != 0) { /* use the BTS number that the user has specified */ bts_nr = atoi(argv[0]); - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts_dump_vty(vty, gsm_bts_num(net, bts_nr)); + bts_dump_vty(vty, gsm_bts_num(g_bts_sm, bts_nr)); return CMD_SUCCESS; } /* print all BTS's */ - for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) - bts_dump_vty(vty, gsm_bts_num(net, bts_nr)); + for (bts_nr = 0; bts_nr < g_bts_sm->num_bts; bts_nr++) + bts_dump_vty(vty, gsm_bts_num(g_bts_sm, bts_nr)); return CMD_SUCCESS; } @@ -1155,21 +1397,22 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]", static void gprs_dump_vty(struct vty *vty, const struct gsm_bts *bts) { unsigned int i; + const struct gsm_gprs_nse *nse = &bts->site_mgr->gprs.nse; /* GPRS parameters received from the BSC */ vty_out(vty, "BTS %u, RAC %u, NSEI %u, BVCI %u%s", bts->nr, bts->gprs.rac, - bts->gprs.nse.nsei, + nse->nsei, bts->gprs.cell.bvci, VTY_NEWLINE); vty_out(vty, " Cell NM state: "); net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state); vty_out(vty, " NSE NM state: "); - net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state); + net_dump_nmstate(vty, &nse->mo.nm_state); - for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) { - const struct gsm_bts_gprs_nsvc *nsvc = &bts->gprs.nsvc[i]; + for (i = 0; i < ARRAY_SIZE(nse->nsvc); i++) { + const struct gsm_gprs_nsvc *nsvc = &nse->nsvc[i]; vty_out(vty, " NSVC%u (NSVCI %u) NM state: ", i, nsvc->nsvci); net_dump_nmstate(vty, &nsvc->mo.nm_state); @@ -1204,10 +1447,9 @@ DEFUN(show_bts_gprs, show_bts_gprs_cmd, SHOW_STR "Display information about a BTS\n" BTS_NR_STR "GPRS/EGPRS configuration\n") { - const struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts; - bts = gsm_bts_num(net, atoi(argv[0])); + bts = gsm_bts_num(g_bts_sm, atoi(argv[0])); if (bts == NULL) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); @@ -1223,16 +1465,15 @@ DEFUN(test_send_failure_event_report, test_send_failure_event_report_cmd, "test "Various testing commands\n" "Send a test OML failure event report to the BSC\n" BTS_NR_STR) { - const struct gsm_network *net = gsmnet_from_vty(vty); int bts_nr = atoi(argv[0]); const struct gsm_bts *bts; - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); oml_tx_failure_event_rep(&bts->mo, NM_SEVER_MINOR, OSMO_EVT_WARN_SW_WARN, "test message sent from VTY"); return CMD_SUCCESS; @@ -1244,9 +1485,8 @@ DEFUN_HIDDEN(radio_link_timeout, radio_link_timeout_cmd, "bts <0-0> radio-link-t "Use infinite timeout (DANGEROUS: only use during testing!)\n" "Number of lost SACCH blocks\n") { - const struct gsm_network *net = gsmnet_from_vty(vty); int bts_nr = atoi(argv[0]); - struct gsm_bts *bts = gsm_bts_num(net, bts_nr); + struct gsm_bts *bts = gsm_bts_num(g_bts_sm, bts_nr); if (!bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); @@ -1270,17 +1510,16 @@ DEFUN_HIDDEN(radio_link_timeout, radio_link_timeout_cmd, "bts <0-0> radio-link-t DEFUN(bts_c0_power_red, bts_c0_power_red_cmd, - "bts <0-255> c0-power-red <0-6>", + "bts <0-0> c0-power-red <0-6>", "BTS Specific Commands\n" BTS_NR_STR "BCCH carrier power reduction operation\n" "Power reduction value (in dB, even numbers only)\n") { - struct gsm_network *net = gsmnet_from_vty(vty); const int bts_nr = atoi(argv[0]); const int red = atoi(argv[1]); struct gsm_bts *bts; - bts = gsm_bts_num(net, atoi(argv[0])); + bts = gsm_bts_num(g_bts_sm, atoi(argv[0])); if (bts == NULL) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; @@ -1347,7 +1586,7 @@ static void dump_dpc_meas_params(struct vty *vty, const unsigned int indent, } static void dump_dpc_params(struct vty *vty, const unsigned int indent, - const struct gsm_power_ctrl_params *cp) + const struct gsm_power_ctrl_params *cp, bool uplink) { cfg_out(vty, "Power control interval: %u ms (every %u SACCH block(s))%s", cp->ctrl_interval ? cp->ctrl_interval * 2 * 480 : 480, @@ -1364,6 +1603,26 @@ static void dump_dpc_params(struct vty *vty, const unsigned int indent, cfg_out(vty, "RxQual measurement processing:%s", VTY_NEWLINE); dump_dpc_meas_params(vty, indent + 2, &cp->rxqual_meas, "RXQUAL", 3); + + if (uplink) { + cfg_out(vty, "C/I measurement processing (FR/EFR):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_fr_meas, "CI_FR", 0); + + cfg_out(vty, "C/I measurement processing (HR):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_hr_meas, "CI_HR", 0); + + cfg_out(vty, "C/I measurement processing (AMR-FR):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_amr_fr_meas, "CI_AMR_FR", 0); + + cfg_out(vty, "C/I measurement processing (AMR-HR):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_amr_hr_meas, "CI_AMR_HR", 0); + + cfg_out(vty, "C/I measurement processing (SDCCH):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_sdcch_meas, "CI_SDCCH", 0); + + cfg_out(vty, "C/I measurement processing (GPRS):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_gprs_meas, "CI_GPRS", 0); + } } static void trx_dump_vty(struct vty *vty, const struct gsm_bts_trx *trx) @@ -1381,20 +1640,20 @@ static void trx_dump_vty(struct vty *vty, const struct gsm_bts_trx *trx) trx->bs_dpc_params == &trx->bts->bs_dpc_params ? "fall-back" : "from BSC", VTY_NEWLINE); - dump_dpc_params(vty, 4, trx->bs_dpc_params); + dump_dpc_params(vty, 4, trx->bs_dpc_params, false); vty_out(vty, " MS Power control parameters (%s):%s", trx->ms_dpc_params == &trx->bts->ms_dpc_params ? "fall-back" : "from BSC", VTY_NEWLINE); - dump_dpc_params(vty, 4, trx->ms_dpc_params); + dump_dpc_params(vty, 4, trx->ms_dpc_params, true); vty_out(vty, " NM State: "); net_dump_nmstate(vty, &trx->mo.nm_state); - vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE); + vty_out(vty, " RSL State: %s%s", trx->bb_transc.rsl.link ? "connected" : "disconnected", VTY_NEWLINE); vty_out(vty, " Baseband Transceiver NM State: "); net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state); - vty_out(vty, " IPA stream ID: 0x%02x%s", trx->rsl_tei, VTY_NEWLINE); + vty_out(vty, " IPA stream ID: 0x%02x%s", trx->bb_transc.rsl.tei, VTY_NEWLINE); } static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts) @@ -1410,19 +1669,18 @@ DEFUN(show_trx, SHOW_STR "Display information about a TRX\n" BTS_TRX_STR) { - const struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts = NULL; int bts_nr, trx_nr; if (argc >= 1) { /* use the BTS number that the user has specified */ bts_nr = atoi(argv[0]); - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); } if (argc >= 2) { trx_nr = atoi(argv[1]); @@ -1440,8 +1698,8 @@ DEFUN(show_trx, return CMD_SUCCESS; } - for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) - print_all_trx(vty, gsm_bts_num(net, bts_nr)); + for (bts_nr = 0; bts_nr < g_bts_sm->num_bts; bts_nr++) + print_all_trx(vty, gsm_bts_num(g_bts_sm, bts_nr)); return CMD_SUCCESS; } @@ -1466,7 +1724,6 @@ DEFUN(show_ts, SHOW_STR "Display information about a TS\n" BTS_TRX_TS_STR) { - const struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts = NULL; const struct gsm_bts_trx *trx = NULL; const struct gsm_bts_trx_ts *ts = NULL; @@ -1475,12 +1732,12 @@ DEFUN(show_ts, if (argc >= 1) { /* use the BTS number that the user has specified */ bts_nr = atoi(argv[0]); - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); } if (argc >= 2) { trx_nr = atoi(argv[1]); @@ -1521,8 +1778,8 @@ DEFUN(show_ts, } } else { /* Iterate over all BTS, TRX in each BTS, TS in each TRX */ - for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) { - bts = gsm_bts_num(net, bts_nr); + for (bts_nr = 0; bts_nr < g_bts_sm->num_bts; bts_nr++) { + bts = gsm_bts_num(g_bts_sm, bts_nr); for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) { trx = gsm_bts_trx_num(bts, trx_nr); for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) { @@ -1594,7 +1851,7 @@ static void lchan_bs_power_ctrl_state_dump(struct vty *vty, unsigned int indent, return; cfg_out(vty, "Power Control parameters:%s", VTY_NEWLINE); - dump_dpc_params(vty, indent + 2, st->dpc_params); + dump_dpc_params(vty, indent + 2, st->dpc_params, false); } static void lchan_ms_power_ctrl_state_dump(struct vty *vty, unsigned int indent, @@ -1610,17 +1867,17 @@ static void lchan_ms_power_ctrl_state_dump(struct vty *vty, unsigned int indent, int current_dbm = ms_pwr_dbm(trx->bts->band, st->current); int max_dbm = ms_pwr_dbm(trx->bts->band, st->max); - cfg_out(vty, "Current power level: %u, -%d dBm", + cfg_out(vty, "Current power level: %u, %d dBm", st->current, current_dbm); if (st->dpc_params != NULL) - vty_out(vty, " (max %u, -%d dBm)", st->max, max_dbm); + vty_out(vty, " (max %u, %d dBm)", st->max, max_dbm); vty_out(vty, "%s", VTY_NEWLINE); if (st->dpc_params == NULL) return; cfg_out(vty, "Power Control parameters:%s", VTY_NEWLINE); - dump_dpc_params(vty, indent + 2, st->dpc_params); + dump_dpc_params(vty, indent + 2, st->dpc_params, true); } static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, @@ -1628,23 +1885,23 @@ static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, { cfg_out(vty, "ACCH repetition:%s", VTY_NEWLINE); indent += 2; - if (lchan->repeated_acch_capability.rxqual) + if (lchan->rep_acch_cap.rxqual) cfg_out(vty, "Enable RXQUAL threshold: %u%s", - lchan->repeated_acch_capability.rxqual, VTY_NEWLINE); + lchan->rep_acch_cap.rxqual, VTY_NEWLINE); else cfg_out(vty, "Enable RXQUAL threshold: (none, alway on)%s", VTY_NEWLINE); cfg_out(vty, "DL-FACCH:%s", VTY_NEWLINE); indent += 2; - if (lchan->repeated_acch_capability.dl_facch_all) + if (lchan->rep_acch_cap.dl_facch_all) cfg_out(vty, "retramsit all LAPDM block types%s", VTY_NEWLINE); - else if (lchan->repeated_acch_capability.dl_facch_cmd) + else if (lchan->rep_acch_cap.dl_facch_cmd) cfg_out(vty, "retramsit only LAPDM command blocks%s", VTY_NEWLINE); else cfg_out(vty, "no retransmission (disabled)%s", VTY_NEWLINE); - if (lchan->repeated_dl_facch_active) + if (lchan->rep_acch.dl_facch_active) cfg_out(vty, "retransmission currently active%s", VTY_NEWLINE); else cfg_out(vty, "retransmission currently inactive%s", @@ -1653,12 +1910,12 @@ static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, cfg_out(vty, "DL-SACCH:%s", VTY_NEWLINE); indent += 2; - if (lchan->repeated_acch_capability.ul_sacch) + if (lchan->rep_acch_cap.ul_sacch) cfg_out(vty, "retramsit all SACCH blocks for SAPI=0%s", VTY_NEWLINE); else cfg_out(vty, "no retransmission (disabled)%s", VTY_NEWLINE); - if (lchan->repeated_dl_sacch_active) + if (lchan->rep_acch.dl_sacch_active) cfg_out(vty, "retransmission currently active%s", VTY_NEWLINE); else cfg_out(vty, "retransmission currently inactive%s", @@ -1667,12 +1924,12 @@ static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, cfg_out(vty, "UL-SACCH:%s", VTY_NEWLINE); indent += 2; - if (lchan->repeated_acch_capability.dl_sacch) + if (lchan->rep_acch_cap.dl_sacch) cfg_out(vty, "retramsit all SACCH blocks for SAPI=0%s", VTY_NEWLINE); else cfg_out(vty, "no retransmission (disabled)%s", VTY_NEWLINE); - if (lchan->repeated_ul_sacch_active) + if (lchan->rep_acch.ul_sacch_active) cfg_out(vty, "retransmission currently active%s", VTY_NEWLINE); else cfg_out(vty, "retransmission currently inactive%s", @@ -1680,6 +1937,34 @@ static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, indent -= 2; } +static void lchan_acch_top_state_dump(struct vty *vty, unsigned int indent, + const struct gsm_lchan *lchan) +{ + if (lchan->top_acch_cap.overpower_db == 0) + return; + + cfg_out(vty, "Temporary ACCH overpower:%s", VTY_NEWLINE); + indent += 2; + + cfg_out(vty, "Overpower value: %u dB%s", + lchan->top_acch_cap.overpower_db, VTY_NEWLINE); + + cfg_out(vty, "SACCH overpower: %sabled%s", + lchan->top_acch_cap.sacch_enable ? "en" : "dis", + VTY_NEWLINE); + cfg_out(vty, "FACCH overpower: %sabled%s", + lchan->top_acch_cap.facch_enable ? "en" : "dis", + VTY_NEWLINE); + + if (lchan->top_acch_cap.rxqual == 0) { + cfg_out(vty, "RxQual threshold: disabled " + "(overpower is always on)%s", VTY_NEWLINE); + } else { + cfg_out(vty, "RxQual threshold: %u%s", + lchan->top_acch_cap.rxqual, VTY_NEWLINE); + } +} + static void lchan_dump_full_vty(struct vty *vty, const struct gsm_lchan *lchan) { struct in_addr ia; @@ -1712,20 +1997,39 @@ static void lchan_dump_full_vty(struct vty *vty, const struct gsm_lchan *lchan) vty_out(vty, " Channel Mode / Codec: %s%s", gsm48_chan_mode_name(lchan->tch_mode), VTY_NEWLINE); + if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) { + const struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; + const struct gsm48_multi_rate_conf *mr_conf = + (const struct gsm48_multi_rate_conf *) amr_mrc->gsm48_ie; + vty_out(vty, " AMR Multi-Rate Configuration: ICMI=%u, Start Mode=%u gsm48=%02x%02x%s", + mr_conf->icmi, mr_conf->smod, amr_mrc->gsm48_ie[0], amr_mrc->gsm48_ie[1], VTY_NEWLINE); + for (uint8_t i = 0; i < amr_mrc->num_modes; i++) { + const struct amr_mode *amode = &amr_mrc->mode[i]; + vty_out(vty, " AMR Mode %u (%s), threshold=%u, hysteresis=%u%s", + amode->mode, osmo_amr_type_name(amode->mode), + amode->threshold, amode->hysteresis, VTY_NEWLINE); + } + } if (lchan->abis_ip.bound_ip) { ia.s_addr = htonl(lchan->abis_ip.bound_ip); - vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s", + vty_out(vty, " Bound IP: %s Port %u CONN_ID=%u", inet_ntoa(ia), lchan->abis_ip.bound_port, - lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id, - VTY_NEWLINE); + lchan->abis_ip.conn_id); + if (lchan->abis_ip.osmux.use) + vty_out(vty, " Osmux_CID=%u%s", lchan->abis_ip.osmux.local_cid, VTY_NEWLINE); + else + vty_out(vty, " RTP_TYPE2=%u%s", lchan->abis_ip.rtp_payload2, VTY_NEWLINE); } if (lchan->abis_ip.connect_ip) { ia.s_addr = htonl(lchan->abis_ip.connect_ip); - vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02u%s", + vty_out(vty, " Conn. IP: %s Port %u SPEECH_MODE=0x%02x", inet_ntoa(ia), lchan->abis_ip.connect_port, - lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode, - VTY_NEWLINE); + lchan->abis_ip.speech_mode); + if (lchan->abis_ip.osmux.use) + vty_out(vty, " Osmux_CID=%u%s", lchan->abis_ip.osmux.remote_cid, VTY_NEWLINE); + else + vty_out(vty, " RTP_TYPE=%u%s", lchan->abis_ip.rtp_payload, VTY_NEWLINE); } #define LAPDM_ESTABLISHED(link, sapi_idx) \ (link).datalink[sapi_idx].dl.state == LAPD_STATE_MF_EST @@ -1751,10 +2055,21 @@ static void lchan_dump_full_vty(struct vty *vty, const struct gsm_lchan *lchan) vty_out(vty, " RTP/PDCH Loopback Enabled%s", VTY_NEWLINE); vty_out(vty, " Radio Link Failure Counter 'S': %d%s", lchan->s, VTY_NEWLINE); + /* Interference levels */ + if (lchan->meas.interf_meas_avg_dbm != 0) { + vty_out(vty, " Interference: %d dBm (band %d)%s", + lchan->meas.interf_meas_avg_dbm, + lchan->meas.interf_band, + VTY_NEWLINE); + } + /* BS/MS Power Control state and parameters */ lchan_bs_power_ctrl_state_dump(vty, 2, lchan); lchan_ms_power_ctrl_state_dump(vty, 2, lchan); + + /* ACCH repetition / overpower state */ lchan_acch_rep_state_dump(vty, 2, lchan); + lchan_acch_top_state_dump(vty, 2, lchan); } static void lchan_dump_short_vty(struct vty *vty, const struct gsm_lchan *lchan) @@ -1827,7 +2142,6 @@ static int dump_lchan_bts(const struct gsm_bts *bts, struct vty *vty, static int lchan_summary(struct vty *vty, int argc, const char **argv, void (*dump_cb)(struct vty *, const struct gsm_lchan *)) { - const struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts = NULL; /* initialize to avoid uninitialized false warnings on some gcc versions (11.1.0) */ const struct gsm_bts_trx *trx = NULL; /* initialize to avoid uninitialized false warnings on some gcc versions (11.1.0) */ const struct gsm_bts_trx_ts *ts = NULL; /* initialize to avoid uninitialized false warnings on some gcc versions (11.1.0) */ @@ -1837,12 +2151,12 @@ static int lchan_summary(struct vty *vty, int argc, const char **argv, if (argc >= 1) { /* use the BTS number that the user has specified */ bts_nr = atoi(argv[0]); - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); if (argc == 1) return dump_lchan_bts(bts, vty, dump_cb); @@ -1883,8 +2197,8 @@ static int lchan_summary(struct vty *vty, int argc, const char **argv, return CMD_SUCCESS; } - for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) { - bts = gsm_bts_num(net, bts_nr); + for (bts_nr = 0; bts_nr < g_bts_sm->num_bts; bts_nr++) { + bts = gsm_bts_num(g_bts_sm, bts_nr); dump_lchan_bts(bts, vty, dump_cb); } @@ -1910,8 +2224,7 @@ DEFUN(show_lchan_summary, return lchan_summary(vty, argc, argv, lchan_dump_short_vty); } -static struct gsm_lchan *resolve_lchan(const struct gsm_network *net, - const char **argv, int idx) +static struct gsm_lchan *resolve_lchan(const char **argv, int idx) { int bts_nr = atoi(argv[idx+0]); int trx_nr = atoi(argv[idx+1]); @@ -1922,7 +2235,7 @@ static struct gsm_lchan *resolve_lchan(const struct gsm_network *net, struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); if (!bts) return NULL; @@ -1975,6 +2288,22 @@ DEFUN(cfg_bts_gsmtap_remote_host, return CMD_SUCCESS; } +DEFUN(cfg_bts_gsmtap_local_host, + cfg_bts_gsmtap_local_host_cmd, + "gsmtap-local-host HOSTNAME", + "Enable local bind for GSMTAP Um logging (see also 'gsmtap-sapi')\n" + "Local IP address or hostname\n") +{ + struct gsm_bts *bts = vty->index; + + osmo_talloc_replace_string(bts, &bts->gsmtap.local_host, argv[0]); + + if (vty->type != VTY_FILE) + vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE); + + return CMD_SUCCESS; +} + DEFUN(cfg_bts_no_gsmtap_remote_host, cfg_bts_no_gsmtap_remote_host_cmd, "no gsmtap-remote-host", @@ -1992,6 +2321,24 @@ DEFUN(cfg_bts_no_gsmtap_remote_host, return CMD_SUCCESS; } +DEFUN(cfg_bts_no_gsmtap_local_host, + cfg_bts_no_gsmtap_local_host_cmd, + "no gsmtap-local-host", + NO_STR "Disable local bind for GSMTAP Um logging\n") +{ + struct gsm_bts *bts = vty->index; + + if (bts->gsmtap.local_host != NULL) + talloc_free(bts->gsmtap.local_host); + + bts->gsmtap.local_host = NULL; + + if (vty->type != VTY_FILE) + vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE); + + return CMD_SUCCESS; +} + DEFUN(cfg_bts_gsmtap_sapi_all, cfg_bts_gsmtap_sapi_all_cmd, "gsmtap-sapi (enable-all|disable-all)", "Enable/disable sending of UL/DL messages over GSMTAP\n" @@ -2028,7 +2375,7 @@ DEFUN(cfg_bts_gsmtap_sapi, cfg_bts_gsmtap_sapi_cmd, return CMD_SUCCESS; } -DEFUN(cfg_trx_no_gsmtap_sapi, cfg_bts_no_gsmtap_sapi_cmd, +DEFUN(cfg_bts_no_gsmtap_sapi, cfg_bts_no_gsmtap_sapi_cmd, "HIDDEN", "HIDDEN") { struct gsm_bts *bts = vty->index; @@ -2045,6 +2392,29 @@ DEFUN(cfg_trx_no_gsmtap_sapi, cfg_bts_no_gsmtap_sapi_cmd, return CMD_SUCCESS; } +DEFUN(cfg_bts_gsmtap_rlp, cfg_bts_gsmtap_rlp_cmd, + "gsmtap-rlp [skip-null]", + "Enable generation of GSMTAP frames for RLP (non-transparent CSD)\n" + "Skip the generation of GSMTAP for RLP NULL frames\n") +{ + struct gsm_bts *bts = vty->index; + bts->gsmtap.rlp = true; + if (argc >= 1 && !strcmp(argv[0], "skip-null")) + bts->gsmtap.rlp_skip_null = true; + else + bts->gsmtap.rlp_skip_null = false; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_gsmtap_rlp, cfg_bts_no_gsmtap_rlp_cmd, + "no gsmtap-rlp", + NO_STR "Disable generation of GSMTAP frames for RLP (non-transparent CSD)\n") +{ + struct gsm_bts *bts = vty->index; + bts->gsmtap.rlp = false; + return CMD_SUCCESS; +} + static struct cmd_node phy_node = { PHY_NODE, "%s(phy)# ", @@ -2153,11 +2523,10 @@ DEFUN(bts_t_t_l_jitter_buf, BTS_T_T_L_STR "RTP settings\n" "Jitter buffer\n" "Size of jitter buffer in (ms)\n") { - struct gsm_network *net = gsmnet_from_vty(vty); struct gsm_lchan *lchan; int jitbuf_ms = atoi(argv[4]), rc; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2186,10 +2555,9 @@ DEFUN_ATTR(bts_t_t_l_loopback, BTS_T_T_L_STR "Set loopback\n", CMD_ATTR_HIDDEN) { - struct gsm_network *net = gsmnet_from_vty(vty); struct gsm_lchan *lchan; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2205,10 +2573,9 @@ DEFUN_ATTR(no_bts_t_t_l_loopback, NO_STR BTS_T_T_L_STR "Set loopback\n", CMD_ATTR_HIDDEN) { - struct gsm_network *net = gsmnet_from_vty(vty); struct gsm_lchan *lchan; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2231,13 +2598,12 @@ DEFUN_ATTR(bts_t_t_l_power_ctrl_mode, "Enable the power control loop\n", CMD_ATTR_HIDDEN) { - struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_power_ctrl_params *params; struct lchan_power_ctrl_state *state; const char **args = argv + 4; struct gsm_lchan *lchan; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2268,12 +2634,11 @@ DEFUN_ATTR(bts_t_t_l_power_ctrl_current_max, "BS power reduction (in dB) or MS power level\n", CMD_ATTR_HIDDEN) { - struct gsm_network *net = gsmnet_from_vty(vty); struct lchan_power_ctrl_state *state; const char **args = argv + 4; struct gsm_lchan *lchan; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2376,13 +2741,22 @@ int bts_vty_init(void *ctx) install_node(&bts_node, config_write_bts); install_element(CONFIG_NODE, &cfg_bts_cmd); install_element(CONFIG_NODE, &cfg_vty_telnet_port_cmd); + + osmo_tdef_vty_groups_init(CONFIG_NODE, bts_tdef_groups); + install_element(BTS_NODE, &cfg_bts_unit_id_cmd); install_element(BTS_NODE, &cfg_bts_oml_ip_cmd); + install_element(BTS_NODE, &cfg_bts_no_oml_ip_cmd); install_element(BTS_NODE, &cfg_bts_rtp_bind_ip_cmd); install_element(BTS_NODE, &cfg_bts_rtp_jitbuf_cmd); install_element(BTS_NODE, &cfg_bts_rtp_port_range_cmd); install_element(BTS_NODE, &cfg_bts_rtp_ip_dscp_cmd); install_element(BTS_NODE, &cfg_bts_rtp_priority_cmd); + install_element(BTS_NODE, &cfg_bts_rtp_cont_stream_cmd); + install_element(BTS_NODE, &cfg_bts_no_rtp_cont_stream_cmd); + install_element(BTS_NODE, &cfg_bts_rtp_int_ul_ecu_cmd); + install_element(BTS_NODE, &cfg_bts_no_rtp_int_ul_ecu_cmd); + install_element(BTS_NODE, &cfg_bts_rtp_hr_format_cmd); install_element(BTS_NODE, &cfg_bts_band_cmd); install_element(BTS_NODE, &cfg_description_cmd); install_element(BTS_NODE, &cfg_no_description_cmd); @@ -2397,7 +2771,8 @@ int bts_vty_init(void *ctx) install_element(BTS_NODE, &cfg_bts_min_qual_rach_cmd); install_element(BTS_NODE, &cfg_bts_min_qual_norm_cmd); install_element(BTS_NODE, &cfg_bts_max_ber_rach_cmd); - install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd); + install_element(BTS_NODE, &cfg_bts_pcu_sock_path_cmd); + install_element(BTS_NODE, &cfg_bts_pcu_sock_ql_cmd); install_element(BTS_NODE, &cfg_bts_supp_meas_toa256_cmd); install_element(BTS_NODE, &cfg_bts_no_supp_meas_toa256_cmd); install_element(BTS_NODE, &cfg_bts_smscb_max_qlen_cmd); @@ -2406,9 +2781,24 @@ int bts_vty_init(void *ctx) install_element(BTS_NODE, &cfg_bts_gsmtap_remote_host_cmd); install_element(BTS_NODE, &cfg_bts_no_gsmtap_remote_host_cmd); + install_element(BTS_NODE, &cfg_bts_gsmtap_local_host_cmd); + install_element(BTS_NODE, &cfg_bts_no_gsmtap_local_host_cmd); install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_all_cmd); install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_cmd); install_element(BTS_NODE, &cfg_bts_no_gsmtap_sapi_cmd); + install_element(BTS_NODE, &cfg_bts_gsmtap_rlp_cmd); + install_element(BTS_NODE, &cfg_bts_no_gsmtap_rlp_cmd); + + /* Osmux Node */ + install_element(BTS_NODE, &cfg_bts_osmux_cmd); + install_node(&osmux_node, config_write_dummy); + + install_element(OSMUX_NODE, &cfg_bts_osmux_use_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_ip_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_port_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_batch_factor_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_batch_size_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_dummy_padding_cmd); /* add and link to TRX config node */ install_element(BTS_NODE, &cfg_bts_trx_cmd); @@ -2419,6 +2809,7 @@ int bts_vty_init(void *ctx) install_element(TRX_NODE, &cfg_trx_pr_step_size_cmd); install_element(TRX_NODE, &cfg_trx_pr_step_interval_cmd); install_element(TRX_NODE, &cfg_trx_ms_power_control_cmd); + install_element(TRX_NODE, &cfg_ta_ctrl_interval_cmd); install_element(TRX_NODE, &cfg_trx_phy_cmd); install_element(ENABLE_NODE, &bts_t_t_l_jitter_buf_cmd); |