diff --git a/src/libmsc/vty_interface_layer3.c b/src/libmsc/vty_interface_layer3.c index 1761ebc6c..864597d6c 100644 --- a/src/libmsc/vty_interface_layer3.c +++ b/src/libmsc/vty_interface_layer3.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -473,6 +474,97 @@ DEFUN(subscriber_ussd_notify, return CMD_SUCCESS; } +static int loop_by_char(uint8_t ch) +{ + switch (ch) { + case 'a': + return GSM414_LOOP_A; + case 'b': + return GSM414_LOOP_B; + case 'c': + return GSM414_LOOP_C; + case 'd': + return GSM414_LOOP_D; + case 'e': + return GSM414_LOOP_E; + case 'f': + return GSM414_LOOP_F; + case 'i': + return GSM414_LOOP_I; + } + return -1; +} + +DEFUN(subscriber_mstest_close, + subscriber_mstest_close_cmd, + "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)", + SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n" + "Close a TCH Loop inside the MS\n" + "Loop Type A\n" + "Loop Type B\n" + "Loop Type C\n" + "Loop Type D\n" + "Loop Type E\n" + "Loop Type F\n" + "Loop Type I\n") +{ + struct gsm_subscriber_connection *conn; + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); + const char *loop_str; + int loop_mode; + + if (!vsub) { + vty_out(vty, "%% No subscriber found for %s %s%s", + argv[0], argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + + loop_str = argv[2]; + loop_mode = loop_by_char(loop_str[0]); + + conn = connection_for_subscr(vsub); + if (!conn) { + vty_out(vty, "%% An active connection is required for %s %s%s", + argv[0], argv[1], VTY_NEWLINE); + vlr_subscr_put(vsub); + return CMD_WARNING; + } + + gsm0414_tx_close_tch_loop_cmd(conn, loop_mode); + + return CMD_SUCCESS; +} + +DEFUN(subscriber_mstest_open, + subscriber_mstest_open_cmd, + "subscriber " SUBSCR_TYPES " ID ms-test open-loop", + SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n" + "Open a TCH Loop inside the MS\n") +{ + struct gsm_subscriber_connection *conn; + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); + + if (!vsub) { + vty_out(vty, "%% No subscriber found for %s %s%s", + argv[0], argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + + conn = connection_for_subscr(vsub); + if (!conn) { + vty_out(vty, "%% An active connection is required for %s %s%s", + argv[0], argv[1], VTY_NEWLINE); + vlr_subscr_put(vsub); + return CMD_WARNING; + } + + gsm0414_tx_open_loop_cmd(conn); + + return CMD_SUCCESS; +} + DEFUN(ena_subscr_expire, ena_subscr_expire_cmd, "subscriber " SUBSCR_TYPES " ID expire", @@ -851,6 +943,8 @@ int bsc_vty_init_extra(void) install_element_ve(&subscriber_silent_call_start_cmd); install_element_ve(&subscriber_silent_call_stop_cmd); install_element_ve(&subscriber_ussd_notify_cmd); + install_element_ve(&subscriber_mstest_close_cmd); + install_element_ve(&subscriber_mstest_open_cmd); install_element_ve(&subscriber_update_cmd); install_element_ve(&show_stats_cmd); install_element_ve(&show_smsqueue_cmd);