/* Osmo BSC VTY Configuration */ /* (C) 2009-2011 by Holger Hans Peter Freyther * (C) 2009-2011 by On-Waves * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * 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 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 . * */ #include #include #include #include #define IPA_STR "IP.ACCESS specific\n" extern struct gsm_network *bsc_gsmnet; static struct osmo_msc_data *osmo_msc_data(struct vty *vty) { return bsc_gsmnet->msc_data; } static struct cmd_node msc_node = { MSC_NODE, "%s(msc)#", 1, }; DEFUN(cfg_net_msc, cfg_net_msc_cmd, "msc", "Configure MSC details") { vty->index = bsc_gsmnet; vty->node = MSC_NODE; return CMD_SUCCESS; } static int config_write_msc(struct vty *vty) { struct bsc_msc_dest *dest; struct osmo_msc_data *data = osmo_msc_data(vty); vty_out(vty, "msc%s", VTY_NEWLINE); if (data->bsc_token) vty_out(vty, " token %s%s", data->bsc_token, VTY_NEWLINE); if (data->core_ncc != -1) vty_out(vty, " core-mobile-network-code %d%s", data->core_ncc, VTY_NEWLINE); if (data->core_mcc != -1) vty_out(vty, " core-mobile-country-code %d%s", data->core_mcc, VTY_NEWLINE); vty_out(vty, " ip.access rtp-base %d%s", data->rtp_base, VTY_NEWLINE); vty_out(vty, " timeout-ping %d%s", data->ping_timeout, VTY_NEWLINE); vty_out(vty, " timeout-pong %d%s", data->pong_timeout, VTY_NEWLINE); if (data->mid_call_txt) vty_out(vty, " mid-call-text %s%s", data->mid_call_txt, VTY_NEWLINE); vty_out(vty, " mid-call-timeout %d%s", data->mid_call_timeout, VTY_NEWLINE); if (data->ussd_welcome_txt) vty_out(vty, " bsc-welcome-text %s%s", data->ussd_welcome_txt, VTY_NEWLINE); if (data->rf_ctrl_name) vty_out(vty, " bsc-rf-socket %s%s", data->rf_ctrl_name, VTY_NEWLINE); if (data->audio_length != 0) { int i; vty_out(vty, " codec-list "); for (i = 0; i < data->audio_length; ++i) { if (i != 0) vty_out(vty, ", "); if (data->audio_support[i]->hr) vty_out(vty, "hr%.1u", data->audio_support[i]->ver); else vty_out(vty, "fr%.1u", data->audio_support[i]->ver); } vty_out(vty, "%s", VTY_NEWLINE); } llist_for_each_entry(dest, &data->dests, list) vty_out(vty, " dest %s %d %d%s", dest->ip, dest->port, dest->dscp, VTY_NEWLINE); return CMD_SUCCESS; } DEFUN(cfg_net_bsc_token, cfg_net_bsc_token_cmd, "token TOKEN", "A token for the BSC to be sent to the MSC") { struct osmo_msc_data *data = osmo_msc_data(vty); bsc_replace_string(data, &data->bsc_token, argv[0]); return CMD_SUCCESS; } DEFUN(cfg_net_bsc_ncc, cfg_net_bsc_ncc_cmd, "core-mobile-network-code <1-999>", "Use this network code for the backbone\n" "NCC value\n") { struct osmo_msc_data *data = osmo_msc_data(vty); data->core_ncc = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_net_bsc_mcc, cfg_net_bsc_mcc_cmd, "core-mobile-country-code <1-999>", "Use this country code for the backbone\n" "MCC value\n") { struct osmo_msc_data *data = osmo_msc_data(vty); data->core_mcc = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_net_bsc_rtp_base, cfg_net_bsc_rtp_base_cmd, "ip.access rtp-base <1-65000>", IPA_STR "Set the rtp-base port for the RTP stream\n" "Port number\n") { struct osmo_msc_data *data = osmo_msc_data(vty); data->rtp_base = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_net_bsc_codec_list, cfg_net_bsc_codec_list_cmd, "codec-list .LIST", "Set the allowed audio codecs\n" "List of audio codecs\n") { struct osmo_msc_data *data = osmo_msc_data(vty); int saw_fr, saw_hr; int i; saw_fr = saw_hr = 0; /* free the old list... if it exists */ if (data->audio_support) { talloc_free(data->audio_support); data->audio_support = NULL; data->audio_length = 0; } /* create a new array */ data->audio_support = talloc_zero_array(data, struct gsm_audio_support *, argc); data->audio_length = argc; for (i = 0; i < argc; ++i) { /* check for hrX or frX */ if (strlen(argv[i]) != 3 || argv[i][1] != 'r' || (argv[i][0] != 'h' && argv[i][0] != 'f') || argv[i][2] < 0x30 || argv[i][2] > 0x39) goto error; data->audio_support[i] = talloc_zero(data->audio_support, struct gsm_audio_support); data->audio_support[i]->ver = atoi(argv[i] + 2); if (strncmp("hr", argv[i], 2) == 0) { data->audio_support[i]->hr = 1; saw_hr = 1; } else if (strncmp("fr", argv[i], 2) == 0) { data->audio_support[i]->hr = 0; saw_fr = 1; } if (saw_hr && saw_fr) { vty_out(vty, "Can not have full-rate and half-rate codec.%s", VTY_NEWLINE); return CMD_ERR_INCOMPLETE; } } return CMD_SUCCESS; error: vty_out(vty, "Codec name must be hrX or frX. Was '%s'%s", argv[i], VTY_NEWLINE); return CMD_ERR_INCOMPLETE; } DEFUN(cfg_net_msc_dest, cfg_net_msc_dest_cmd, "dest A.B.C.D <1-65000> <0-255>", "Add a destination to a MUX/MSC\n" "IP Address\n" "Port\n" "DSCP\n") { struct bsc_msc_dest *dest; struct osmo_msc_data *data = osmo_msc_data(vty); dest = talloc_zero(data, struct bsc_msc_dest); if (!dest) { vty_out(vty, "%%Failed to create structure.%s", VTY_NEWLINE); return CMD_WARNING; } dest->ip = talloc_strdup(data, argv[0]); if (!dest->ip) { vty_out(vty, "%%Failed to copy dest ip.%s", VTY_NEWLINE); talloc_free(dest); return CMD_WARNING; } dest->port = atoi(argv[1]); dest->dscp = atoi(argv[2]); llist_add_tail(&dest->list, &data->dests); return CMD_SUCCESS; } DEFUN(cfg_net_msc_no_dest, cfg_net_msc_no_dest_cmd, "no dest A.B.C.D <1-65000> <0-255>", NO_STR "Remove a destination to a MUX/MSC\n" "IP Address\n" "Port\n" "DSCP\n") { struct bsc_msc_dest *dest, *tmp; struct osmo_msc_data *data = osmo_msc_data(vty); int port = atoi(argv[1]); int dscp = atoi(argv[2]); llist_for_each_entry_safe(dest, tmp, &data->dests, list) { if (port != dest->port || dscp != dest->dscp || strcmp(dest->ip, argv[0]) != 0) continue; llist_del(&dest->list); talloc_free(dest); } return CMD_SUCCESS; } DEFUN(cfg_net_msc_ping_time, cfg_net_msc_ping_time_cmd, "timeout-ping NR", "Set the PING interval, negative for not sending PING") { struct osmo_msc_data *data = osmo_msc_data(vty); data->ping_timeout = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_net_msc_pong_time, cfg_net_msc_pong_time_cmd, "timeout-pong NR", "Set the time to wait for a PONG.") { struct osmo_msc_data *data = osmo_msc_data(vty); data->pong_timeout = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_net_msc_mid_call_text, cfg_net_msc_mid_call_text_cmd, "mid-call-text .TEXT", "Set the USSD notifcation to be send.\n" "Text to be sent\n") { struct osmo_msc_data *data = osmo_msc_data(vty); char *txt = argv_concat(argv, argc, 0); if (!txt) return CMD_WARNING; bsc_replace_string(data, &data->mid_call_txt, txt); talloc_free(txt); return CMD_SUCCESS; } DEFUN(cfg_net_msc_mid_call_timeout, cfg_net_msc_mid_call_timeout_cmd, "mid-call-timeout NR", "Switch from Grace to Off in NR seconds.\n" "Timeout in seconds\n") { struct osmo_msc_data *data = osmo_msc_data(vty); data->mid_call_timeout = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_net_msc_welcome_ussd, cfg_net_msc_welcome_ussd_cmd, "bsc-welcome-text .TEXT", "Set the USSD notification to be sent.\n" "Text to be sent\n") { struct osmo_msc_data *data = osmo_msc_data(vty); char *str = argv_concat(argv, argc, 0); if (!str) return CMD_WARNING; bsc_replace_string(data, &data->ussd_welcome_txt, str); talloc_free(str); return CMD_SUCCESS; } DEFUN(cfg_net_rf_socket, cfg_net_rf_socket_cmd, "bsc-rf-socket PATH", "Set the filename for the RF control interface.\n" "RF Control path\n") { struct osmo_msc_data *data = osmo_msc_data(vty); bsc_replace_string(data, &data->rf_ctrl_name, argv[0]); return CMD_SUCCESS; } int bsc_vty_init_extra(void) { install_element(CONFIG_NODE, &cfg_net_msc_cmd); install_node(&msc_node, config_write_msc); install_default(MSC_NODE); install_element(MSC_NODE, &cfg_net_bsc_token_cmd); install_element(MSC_NODE, &cfg_net_bsc_ncc_cmd); install_element(MSC_NODE, &cfg_net_bsc_mcc_cmd); install_element(MSC_NODE, &cfg_net_bsc_rtp_base_cmd); install_element(MSC_NODE, &cfg_net_bsc_codec_list_cmd); install_element(MSC_NODE, &cfg_net_msc_dest_cmd); install_element(MSC_NODE, &cfg_net_msc_no_dest_cmd); install_element(MSC_NODE, &cfg_net_msc_ping_time_cmd); install_element(MSC_NODE, &cfg_net_msc_pong_time_cmd); install_element(MSC_NODE, &cfg_net_msc_mid_call_text_cmd); install_element(MSC_NODE, &cfg_net_msc_mid_call_timeout_cmd); install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd); install_element(MSC_NODE, &cfg_net_rf_socket_cmd); return 0; }