/* osmo-isdntap VTY interface */ /* (C) 2022 by Harald Welte * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #define _GNU_SOURCE /* struct ucred */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "isdntap.h" static struct isdntap_instance *vty_itd; static struct cmd_node isdntap_node = { (enum node_type) ISDNTAP_NODE, "%s(config-isdntap)# ", 1, }; static struct cmd_node line_node = { (enum node_type) LINE_NODE, "%s(config-isdntap-line)# ", 1, }; static void vty_dump_line(struct vty *vty, const struct isdntap_line *line) { vty_out(vty, "Line %s%s", line->name, VTY_NEWLINE); if (1) { vty_out(vty, " Driver: DAHDI, span_name=%s, span_type=%s, span_no=%d, " "basechan=%d, channels=%d%s", line->drvdata.dahdi.name, line->drvdata.dahdi.spantype, line->drvdata.dahdi.spanno, line->drvdata.dahdi.basechan, line->drvdata.dahdi.channels, VTY_NEWLINE); } //vty_out_rate_ctr_group(vty, " ", line->ctrs); } DEFUN(show_line, show_line_cmd, "show line", SHOW_STR "Display information about an E1 Line\n") { struct isdntap_line *line; llist_for_each_entry(line, &vty_itd->lines, list) { vty_dump_line(vty, line); } return CMD_SUCCESS; } DEFUN(cfg_isdntap, cfg_isdntap_cmd, "isdntap", "isdntap Daemon specific configuration\n") { vty->node = ISDNTAP_NODE; return CMD_SUCCESS; } DEFUN(cfg_itd_gsmtap_remote_host, cfg_itd_gsmtap_remote_host_cmd, "gsmtap remote-host " VTY_IPV46_CMD, "GSMTAP configuration\n" "Remote host to which signaling shall be sent in GSMTAP format\n" IP_STR IPV6_STR) { osmo_talloc_replace_string(vty_itd, &vty_itd->cfg.gsmtap.remote_host, argv[0]); if (vty_itd->gti) gsmtap_source_free(vty_itd->gti); vty_itd->gti = gsmtap_source_init(vty_itd->cfg.gsmtap.remote_host, GSMTAP_UDP_PORT, 0); return CMD_SUCCESS; } DEFUN(cfg_itd_output_path, cfg_itd_output_path_cmd, "output-path PATH", "Path of output directory for B-Channel recordings\n" "Path of output directory for B-Channel recordings\n") { osmo_talloc_replace_string(vty_itd, &vty_itd->cfg.output_path, argv[0]); return CMD_SUCCESS; } DEFUN(cfg_itd_line_dahdi, cfg_itd_line_dahdi_cmd, "line NAME dahdi SPAN_NAME", "Configure an ISDNtap E1 line\n" "E1 Line (Span) Name\n" "Use the DAHDI Driver\n" "DAHDI span name of the line\n") { const char *name = argv[0]; const char *span_name = argv[1]; struct isdntap_line *line; int rc; if (!osmo_identifier_valid(name)) { vty_out(vty, "%% Sorry, '%s' is not a valid identifier%s", name, VTY_NEWLINE); return CMD_WARNING; } line = isdntap_line_find(vty_itd, name); if (line) { if (strcmp(line->drvdata.dahdi.name, span_name)) { /* span name has changed */ /* close old line / span name */ line->driver->line_close(line); osmo_talloc_replace_string(line, &line->drvdata.dahdi.name, span_name); /* open new span name */ rc = line->driver->line_open(line); if (rc < 0) { vty_out(vty, "%% Could not open line%s", VTY_NEWLINE); isdntap_line_free(line); /* should we try to re-open the old one? better fail fast... */ exit(23); } } } else { line = isdntap_line_new(vty_itd, name); if (!line) { vty_out(vty, "%% Could not create line%s", VTY_NEWLINE); return CMD_WARNING; } line->driver = &dahdi_driver; line->drvdata.dahdi.name = talloc_strdup(line, span_name); rc = line->driver->line_open(line); if (rc < 0) { vty_out(vty, "%% Could not open line%s", VTY_NEWLINE); isdntap_line_free(line); return CMD_WARNING; } } vty->index = line; vty->node = LINE_NODE; return CMD_SUCCESS; } DEFUN(cfg_line_role, cfg_line_role_cmd, "local-role (network|user)", "Local role of the ISDN line\n" "Local end implements NETWORK role\n" "Local end implements USER role\n") { struct isdntap_line *line = vty->index; if (!strcmp(argv[0], "network")) line->local_side_is_network = true; else line->local_side_is_network = false; return CMD_SUCCESS; } #if 0 DEFUN(cfg_e1d_if_usb_serial, cfg_e1d_if_usb_serial_cmd, "usb-serial SERNO", "Configure the USB serial number of an E1 interface device\n" "iSerial string\n") { struct e1_intf *intf = vty->index; if (intf->drv != E1_DRIVER_USB) return CMD_WARNING; osmo_talloc_replace_string(intf, &intf->usb.serial_str, argv[0]); return CMD_SUCCESS; } DEFUN(cfg_e1d_if_line_mode, cfg_e1d_if_line_mode_cmd, "mode (channelized|superchannel|e1oip)", "Configure the mode of the E1 line\n" "Channelized (64kBps timeslot) mode\n" "Superchannel (1xHDLC over 31x64kBps) mode\n") { struct e1_line *line = vty->index; enum e1_line_mode new_mode = get_string_value(e1_line_mode_names, argv[0]); if (line->mode != new_mode) { /* FIXME: clean up any old state */ line->mode = new_mode; } return CMD_SUCCESS; } #endif static int config_write_line(struct vty *vty, struct isdntap_line *line) { vty_out(vty, " line %s dahdi %s%s", line->name, line->drvdata.dahdi.name, VTY_NEWLINE); //vty_out(vty, " mode %s%s", get_value_string(e1_line_mode_names, line->mode), VTY_NEWLINE); vty_out(vty, " local-role %s%s", line->local_side_is_network ? "network" : "user", VTY_NEWLINE); return 0; } static int config_write_isdntap(struct vty *vty) { struct isdntap_line *line; vty_out(vty, "isdntap%s", VTY_NEWLINE); vty_out(vty, " output-path %s%s", vty_itd->cfg.output_path, VTY_NEWLINE); if (vty_itd->cfg.gsmtap.remote_host) vty_out(vty, " gsmtap remote-host %s%s", vty_itd->cfg.gsmtap.remote_host, VTY_NEWLINE); /* find all vpair interfaces */ llist_for_each_entry(line, &vty_itd->lines, list) { config_write_line(vty, line); } return 0; } void isdntap_vty_init(struct isdntap_instance *itd) { vty_itd = itd; install_element_ve(&show_line_cmd); install_node(&isdntap_node, config_write_isdntap); install_element(CONFIG_NODE, &cfg_isdntap_cmd); install_node(&line_node, NULL); install_element(ISDNTAP_NODE, &cfg_itd_output_path_cmd); install_element(ISDNTAP_NODE, &cfg_itd_gsmtap_remote_host_cmd); install_element(ISDNTAP_NODE, &cfg_itd_line_dahdi_cmd); install_element(LINE_NODE, &cfg_line_role_cmd); }