diff options
Diffstat (limited to 'src/osmo-bsc/abis_om2000_vty.c')
-rw-r--r-- | src/osmo-bsc/abis_om2000_vty.c | 226 |
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; } |