aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc/abis_om2000_vty.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bsc/abis_om2000_vty.c')
-rw-r--r--src/osmo-bsc/abis_om2000_vty.c226
1 files changed, 188 insertions, 38 deletions
diff --git a/src/osmo-bsc/abis_om2000_vty.c b/src/osmo-bsc/abis_om2000_vty.c
index 26e8488cb..76048071a 100644
--- a/src/osmo-bsc/abis_om2000_vty.c
+++ b/src/osmo-bsc/abis_om2000_vty.c
@@ -41,6 +41,8 @@
#include <osmocom/vty/logging.h>
#include <osmocom/vty/telnet_interface.h>
+#define X(x) (1 << x)
+
static struct cmd_node om2k_node = {
OM2K_NODE,
"%s(om2k)# ",
@@ -61,11 +63,6 @@ struct oml_node_state {
struct con_group *cg;
};
-static int dummy_config_write(struct vty *v)
-{
- return CMD_SUCCESS;
-}
-
/* FIXME: auto-generate those strings from the value_string lists */
#define OM2K_OBJCLASS_VTY "(trxc|tg|ts|tf|is|con|dp|mctr|cf|tx|rx)"
#define OM2K_OBJCLASS_VTY_HELP "TRX Controller\n" \
@@ -79,6 +76,7 @@ static int dummy_config_write(struct vty *v)
"Central Function\n" \
"Transmitter\n" \
"Receiver\n"
+#define OM2K_VTY_HELP "Configure OM2K specific parameters\n"
DEFUN(om2k_class_inst, om2k_class_inst_cmd,
"bts <0-255> om2000 class " OM2K_OBJCLASS_VTY
@@ -343,10 +341,11 @@ static int con_group_del_path(struct con_group *cg, uint16_t ccp,
return -ENOENT;
}
-DEFUN(cfg_om2k_con_group, cfg_om2k_con_group_cmd,
- "con-connection-group <1-31>",
- "Configure a CON (Concentrator) Connection Group\n"
- "CON Connection Group Number\n")
+DEFUN_ATTR(cfg_om2k_con_group, cfg_om2k_con_group_cmd,
+ "con-connection-group <1-31>",
+ "Configure a CON (Concentrator) Connection Group\n"
+ "CON Connection Group Number\n",
+ CMD_ATTR_IMMEDIATE)
{
struct gsm_bts *bts = vty->index;
struct con_group *cg;
@@ -371,10 +370,11 @@ DEFUN(cfg_om2k_con_group, cfg_om2k_con_group_cmd,
return CMD_SUCCESS;
}
-DEFUN(del_om2k_con_group, del_om2k_con_group_cmd,
- "del-connection-group <1-31>",
- "Delete a CON (Concentrator) Connection Group\n"
- "CON Connection Group Number\n")
+DEFUN_ATTR(del_om2k_con_group, del_om2k_con_group_cmd,
+ "del-connection-group <1-31>",
+ "Delete a CON (Concentrator) Connection Group\n"
+ "CON Connection Group Number\n",
+ CMD_ATTR_IMMEDIATE)
{
struct gsm_bts *bts = vty->index;
int rc;
@@ -402,9 +402,10 @@ DEFUN(del_om2k_con_group, del_om2k_con_group_cmd,
"CON Connection Point\n" \
"Contiguity Index\n" \
-DEFUN(cfg_om2k_con_path_dec, cfg_om2k_con_path_dec_cmd,
- "con-path (add|del) <0-2047> <0-255> deconcentrated <0-63>",
- CON_PATH_HELP "De-concentrated in/outlet\n" "TEI Value\n")
+DEFUN_USRATTR(cfg_om2k_con_path_dec, cfg_om2k_con_path_dec_cmd,
+ X(BSC_VTY_ATTR_RESTART_ABIS_OML_LINK),
+ "con-path (add|del) <0-2047> <0-255> deconcentrated <0-63>",
+ CON_PATH_HELP "De-concentrated in/outlet\n" "TEI Value\n")
{
struct con_group *cg = vty->index;
uint16_t ccp = atoi(argv[1]);
@@ -424,9 +425,10 @@ DEFUN(cfg_om2k_con_path_dec, cfg_om2k_con_path_dec_cmd,
return CMD_SUCCESS;
}
-DEFUN(cfg_om2k_con_path_conc, cfg_om2k_con_path_conc_cmd,
- "con-path (add|del) <0-2047> <0-255> concentrated <1-16>",
- CON_PATH_HELP "Concentrated in/outlet\n" "Tag Number\n")
+DEFUN_USRATTR(cfg_om2k_con_path_conc, cfg_om2k_con_path_conc_cmd,
+ X(BSC_VTY_ATTR_RESTART_ABIS_OML_LINK),
+ "con-path (add|del) <0-2047> <0-255> concentrated <1-16>",
+ CON_PATH_HELP "Concentrated in/outlet\n" "Tag Number\n")
{
struct con_group *cg = vty->index;
uint16_t ccp = atoi(argv[1]);
@@ -446,11 +448,12 @@ DEFUN(cfg_om2k_con_path_conc, cfg_om2k_con_path_conc_cmd,
return CMD_SUCCESS;
}
-DEFUN(cfg_bts_alt_mode, cfg_bts_alt_mode_cmd,
- "abis-lower-transport (single-timeslot|super-channel)",
- "Configure thee Abis Lower Transport\n"
- "Single Timeslot (classic Abis)\n"
- "SuperChannel (Packet Abis)\n")
+DEFUN_USRATTR(cfg_bts_alt_mode, cfg_bts_alt_mode_cmd,
+ X(BSC_VTY_ATTR_RESTART_ABIS_OML_LINK),
+ "abis-lower-transport (single-timeslot|super-channel)",
+ "Configure thee Abis Lower Transport\n"
+ "Single Timeslot (classic Abis)\n"
+ "SuperChannel (Packet Abis)\n")
{
struct gsm_bts *bts = vty->index;
@@ -468,15 +471,37 @@ DEFUN(cfg_bts_alt_mode, cfg_bts_alt_mode_cmd,
return CMD_SUCCESS;
}
-DEFUN(cfg_bts_om2k_version_limit, cfg_bts_om2k_version_limit_cmd,
- "om2000 version-limit (oml|rsl) gen <0-99> rev <0-99>",
- "Configure OM2K specific parameters\n"
- "Configure optional maximum protocol version to negotiate\n"
- "Limit OML IWD version\n" "Limit RSL IWD version\n"
- "Generation limit\n"
- "Generation number to limit to (inclusive)\n"
- "Revision limit\n"
- "Revision number to limit to (inclusive)\n")
+DEFUN_USRATTR(cfg_bts_om2k_sync, cfg_bts_om2k_sync_cmd,
+ X(BSC_VTY_ATTR_RESTART_ABIS_OML_LINK),
+ "om2000 sync-source (internal|external)",
+ OM2K_VTY_HELP
+ "TF Synchronization Source\n"
+ "Use Internal (E1)\n"
+ "USe External (GPS)\n")
+{
+ struct gsm_bts *bts = vty->index;
+ if (bts->type != GSM_BTS_TYPE_RBS2000) {
+ vty_out(vty, "%% Command only works for RBS2000%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (!strcmp(argv[0], "internal"))
+ bts->rbs2000.sync_src = OM2K_SYNC_SRC_INTERNAL;
+ else if (!strcmp(argv[0], "external"))
+ bts->rbs2000.sync_src = OM2K_SYNC_SRC_EXTERNAL;
+ return CMD_SUCCESS;
+}
+
+DEFUN_USRATTR(cfg_bts_om2k_version_limit, cfg_bts_om2k_version_limit_cmd,
+ X(BSC_VTY_ATTR_RESTART_ABIS_OML_LINK),
+ "om2000 version-limit (oml|rsl) gen <0-99> rev <0-99>",
+ OM2K_VTY_HELP
+ "Configure optional maximum protocol version to negotiate\n"
+ "Limit OML IWD version\n" "Limit RSL IWD version\n"
+ "Generation limit\n"
+ "Generation number to limit to (inclusive)\n"
+ "Revision limit\n"
+ "Revision number to limit to (inclusive)\n")
{
struct gsm_bts *bts = vty->index;
int iwd;
@@ -502,11 +527,12 @@ DEFUN(cfg_bts_om2k_version_limit, cfg_bts_om2k_version_limit_cmd,
return CMD_SUCCESS;
}
-DEFUN(cfg_bts_is_conn_list, cfg_bts_is_conn_list_cmd,
- "is-connection-list (add|del) <0-2047> <0-2047> <0-255>",
- "Interface Switch Connection List\n"
- "Add to IS list\n" "Delete from IS list\n"
- "ICP1\n" "ICP2\n" "Contiguity Index\n")
+DEFUN_USRATTR(cfg_bts_is_conn_list, cfg_bts_is_conn_list_cmd,
+ X(BSC_VTY_ATTR_RESTART_ABIS_OML_LINK),
+ "is-connection-list (add|del) <0-2047> <0-2047> <0-255>",
+ "Interface Switch Connection List\n"
+ "Add to IS list\n" "Delete from IS list\n"
+ "ICP1\n" "ICP2\n" "Contiguity Index\n")
{
struct gsm_bts *bts = vty->index;
uint16_t icp1 = atoi(argv[1]);
@@ -543,6 +569,33 @@ DEFUN(cfg_bts_is_conn_list, cfg_bts_is_conn_list_cmd,
return CMD_SUCCESS;
}
+DEFUN_USRATTR(cfg_trx_om2k_rx_diversity,
+ cfg_trx_om2k_rx_diversity_cmd,
+ X(BSC_VTY_ATTR_RESTART_ABIS_RSL_LINK),
+ "om2000 rx-diversity-mode (a|ab|b)",
+ OM2K_VTY_HELP
+ "RX Diversity\n"
+ "Antenna TX/RX (A)\n"
+ "Both Antennas\n"
+ "Antenna RX (B)\n")
+
+{
+ struct gsm_bts_trx *trx = vty->index;
+
+ if (trx->bts->type != GSM_BTS_TYPE_RBS2000) {
+ vty_out(vty, "%% Command only works for RBS2000%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (!strcmp(argv[0], "a"))
+ trx->rbs2000.rx_diversity = OM2K_RX_DIVERSITY_A;
+ else if (!strcmp(argv[0], "ab"))
+ trx->rbs2000.rx_diversity = OM2K_RX_DIVERSITY_AB;
+ else if (!strcmp(argv[0], "b"))
+ trx->rbs2000.rx_diversity = OM2K_RX_DIVERSITY_B;
+ return CMD_SUCCESS;
+}
DEFUN(om2k_conf_req, om2k_conf_req_cmd,
"configuration-request",
@@ -622,6 +675,24 @@ static void dump_con_group(struct vty *vty, struct con_group *cg)
}
}
+static const struct value_string om2k_rx_diversity_names[4] = {
+ { OM2K_RX_DIVERSITY_A, "a" },
+ { OM2K_RX_DIVERSITY_AB, "ab" },
+ { OM2K_RX_DIVERSITY_B, "b" },
+ { 0, NULL }
+};
+
+static const char *rx_diversity2str(enum om2k_rx_diversity type)
+{
+ return get_value_string(om2k_rx_diversity_names, type);
+}
+
+void abis_om2k_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx)
+{
+ vty_out(vty, " om2000 rx-diversity-mode %s%s",
+ rx_diversity2str(trx->rbs2000.rx_diversity), VTY_NEWLINE);
+}
+
void abis_om2k_config_write_bts(struct vty *vty, struct gsm_bts *bts)
{
struct is_conn_group *igrp;
@@ -647,10 +718,86 @@ void abis_om2k_config_write_bts(struct vty *vty, struct gsm_bts *bts)
(bts->rbs2000.om2k_version[i].limit >> 8),
(bts->rbs2000.om2k_version[i].limit & 0xff),
VTY_NEWLINE);
+ vty_out(vty, " om2000 sync-source %s%s",
+ bts->rbs2000.sync_src != OM2K_SYNC_SRC_EXTERNAL
+ ? "internal" : "external",
+ VTY_NEWLINE);
+}
+
+static void vty_dump_om2k_mo(struct vty *vty, const struct om2k_mo *mo, const char *pfx)
+{
+ unsigned int pfx_len = strlen(pfx);
+ const char *mo_name = abis_om2k_mo_name(&mo->addr);
+ unsigned int pfx_mo_len = pfx_len + strlen(mo_name);
+ unsigned int pfx2_len;
+ char pfx2[23];
+ int i;
+
+ /* generate padding after MO class to align the state names in the same column */
+ if (pfx_mo_len > sizeof(pfx2)-1)
+ pfx2_len = 0;
+ else
+ pfx2_len = sizeof(pfx2)-1 - pfx_mo_len;
+ for (i = 0; i < pfx2_len; i++)
+ pfx2[i] = ' ';
+ pfx2[pfx2_len] = '\0';
+
+ vty_out(vty, "%s%s%s %s%s", pfx, mo_name, pfx2,
+ mo->fsm ? osmo_fsm_inst_state_name(mo->fsm) : "[NULL]",
+ VTY_NEWLINE);
+}
+
+DEFUN(show_om2k_mo, show_om2k_mo_cmd,
+ "show bts <0-255> om2k-mo",
+ SHOW_STR "Display information about a BTS\n"
+ "BTS number\n" "OM2000 Managed Object information\n")
+{
+ 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_trx *trx;
+
+ if (!bts) {
+ vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (bts->type != GSM_BTS_TYPE_RBS2000) {
+ vty_out(vty, "%% BTS is not using OM2000%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty_out(vty, "BTS %3u OM2K-FSM state %s%s", bts->nr,
+ osmo_fsm_inst_state_name(bts->rbs2000.bts_fi), VTY_NEWLINE);
+ vty_dump_om2k_mo(vty, &bts->rbs2000.cf.om2k_mo, " ");
+ vty_dump_om2k_mo(vty, &bts->rbs2000.con.om2k_mo, " ");
+ vty_dump_om2k_mo(vty, &bts->rbs2000.is.om2k_mo, " ");
+ vty_dump_om2k_mo(vty, &bts->rbs2000.dp.om2k_mo, " ");
+ vty_dump_om2k_mo(vty, &bts->rbs2000.tf.om2k_mo, " ");
+ vty_dump_om2k_mo(vty, &bts->rbs2000.mctr.om2k_mo, " ");
+
+
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ int tn;
+
+ vty_out(vty, " TRX %u OM2K-FSM state %s%s", trx->nr,
+ osmo_fsm_inst_state_name(trx->rbs2000.trx_fi), VTY_NEWLINE);
+ vty_dump_om2k_mo(vty, &trx->rbs2000.trxc.om2k_mo, " ");
+ vty_dump_om2k_mo(vty, &trx->rbs2000.rx.om2k_mo, " ");
+ vty_dump_om2k_mo(vty, &trx->rbs2000.tx.om2k_mo, " ");
+
+ for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {
+ struct gsm_bts_trx_ts *ts = &trx->ts[tn];
+ vty_dump_om2k_mo(vty, &ts->rbs2000.om2k_mo, " ");
+ }
+ }
+
+ return CMD_SUCCESS;
}
int abis_om2k_vty_init(void)
{
+ install_element_ve(&show_om2k_mo_cmd);
install_element(ENABLE_NODE, &om2k_class_inst_cmd);
install_element(ENABLE_NODE, &om2k_classnum_inst_cmd);
install_node(&om2k_node, dummy_config_write);
@@ -674,9 +821,12 @@ int abis_om2k_vty_init(void)
install_element(BTS_NODE, &cfg_bts_is_conn_list_cmd);
install_element(BTS_NODE, &cfg_bts_alt_mode_cmd);
+ install_element(BTS_NODE, &cfg_bts_om2k_sync_cmd);
install_element(BTS_NODE, &cfg_bts_om2k_version_limit_cmd);
install_element(BTS_NODE, &cfg_om2k_con_group_cmd);
install_element(BTS_NODE, &del_om2k_con_group_cmd);
+ install_element(TRX_NODE, &cfg_trx_om2k_rx_diversity_cmd);
+
return 0;
}