#include #include "v5x_internal.h" #include "v5x_protocol.h" #include "v5le_vty.h" #include "v52_le_lcp_fsm.h" #include "v52_le_pp_fsm.h" #include "v5x_le_port_fsm.h" #include "v5x_le_pstn_fsm.h" #include "v5x_le_management.h" #include "layer1.h" #include "../config.h" extern struct v5x_instance *v5i; static struct v5x_interface *get_interface(struct vty *vty) { struct v5x_interface *v5if = NULL; if (!llist_empty(&v5i->interfaces)) v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list); if (!v5if) { vty_out(vty, "%%No interface created!%s", VTY_NEWLINE); return NULL; } return v5if; } /* * show */ DEFUN(show_interface, show_interface_cmd, "show interface", SHOW_STR "Show interface and states") { struct v5x_interface *v5if = get_interface(vty); struct v5x_link *v5l; if (!v5if) return CMD_WARNING; vty_out(vty, "Interface %s:%s", (v5if->dialect == V5X_DIALECT_V51) ? "V5.1" : "V5.2", VTY_NEWLINE); vty_out(vty, " ID: %d%s", v5if->id_local, VTY_NEWLINE); if (v5if->id_remote_valid && v5if->id_local != v5if->id_remote) vty_out(vty, " -> Mismatch! Remote ID: %d%s", v5if->id_remote, VTY_NEWLINE); vty_out(vty, " Variant: %d%s", v5if->variant_local, VTY_NEWLINE); if (v5if->variant_remote_valid && v5if->variant_local != v5if->variant_remote) vty_out(vty, " -> Mismatch! Remote variant: %d%s", v5if->variant_remote, VTY_NEWLINE); if (v5if->dialect == V5X_DIALECT_V52) { vty_out(vty, " Link IDs:"); llist_for_each_entry(v5l, &v5if->links, list) vty_out(vty, " %d", v5l->id); vty_out(vty, VTY_NEWLINE); if (v5if->primary_link) vty_out(vty, " Primary link ID: %d%s", v5if->primary_link->id, VTY_NEWLINE); if (v5if->secondary_link) vty_out(vty, " Secondary link ID: %d%s", v5if->secondary_link->id, VTY_NEWLINE); if (v5if->cc_link) vty_out(vty, " Current C-Channel link ID: %d%s", v5if->cc_link->id, VTY_NEWLINE); } if (v5if->control.li) vty_out(vty, " Control link: %s%s", (v5if->control.established) ? "establised" : "down" , VTY_NEWLINE); if (v5if->pstn.li) vty_out(vty, " PSTN link: %s%s", (v5if->pstn.established) ? "establised" : "down" , VTY_NEWLINE); if (v5if->lcp.li) vty_out(vty, " LCP link: %s%s", (v5if->lcp.established) ? "establised" : "down" , VTY_NEWLINE); if (v5if->bcc.li) vty_out(vty, " BCC link: %s%s", (v5if->bcc.established) ? "establised" : "down" , VTY_NEWLINE); if (v5if->protection.li[0]) vty_out(vty, " Protection link (primary): %s%s", (v5if->protection.established[0]) ? "establised" : "down" , VTY_NEWLINE); if (v5if->protection.li[1]) vty_out(vty, " Protection link (secondary): %s%s", (v5if->protection.established[1]) ? "establised" : "down" , VTY_NEWLINE); return CMD_SUCCESS; } DEFUN(show_link, show_link_cmd, "show link", SHOW_STR "Show links and states") { struct v5x_interface *v5if = get_interface(vty); struct v5x_link *v5l; struct v5x_user_port *v5up; int t; if (!v5if) return CMD_WARNING; if (llist_empty(&v5if->links)) { vty_out(vty, "%%No links created!%s", VTY_NEWLINE); return CMD_WARNING; } llist_for_each_entry(v5l, &v5if->links, list) { if (v5if->dialect == V5X_DIALECT_V51) vty_out(vty, "Link:%s", VTY_NEWLINE); else vty_out(vty, "Link ID %d:", v5l->id); if (v5if->dialect == V5X_DIALECT_V52) { vty_out(vty, " State=%s", v52_le_lcp_state_name(v5l->fi)); vty_out(vty, " L1=%s%s", v5x_l1_fsm_state_name(v5l->l1), VTY_NEWLINE); } for (t = 0; t < 32; t++) { if (v5l->c_channel[0].ts && v5l->c_channel[0].ts->nr == t) { vty_out(vty, " TS %2d: signaling channel 1%s", t, VTY_NEWLINE); continue; } if (v5l->c_channel[1].ts && v5l->c_channel[1].ts->nr == t) { vty_out(vty, " TS %2d: signaling channel 2%s", t, VTY_NEWLINE); continue; } if (v5l->c_channel[2].ts && v5l->c_channel[2].ts->nr == t) { vty_out(vty, " TS %2d: signaling channel 3%s", t, VTY_NEWLINE); continue; } if (v5l->ts[t].b_channel) { if ((v5up = v5l->ts[t].v5up)) vty_out(vty, " TS %2d: %s-%d %s%s", t, (v5up->type == V5X_USER_TYPE_PSTN) ? "PSTN" : "ISDN", v5up->nr, (v5l->ts[t].b_activated) ? "(active)": "", VTY_NEWLINE); } } } return CMD_SUCCESS; } static void print_port(struct vty *vty, struct v5x_user_port *v5up) { if (v5up->type == V5X_USER_TYPE_PSTN) { vty_out(vty, "PSTN port nr %d:", v5up->nr); vty_out(vty, " Port state=%s;", v5x_le_port_pstn_state_name(v5up->port_fi)); vty_out(vty, " PSTN state=%s%s", v5x_le_pstn_state_name(v5up->pstn.proto), VTY_NEWLINE); if (v5up->ts[0]) { if (v5up->interface->dialect == V5X_DIALECT_V51) vty_out(vty, " Channel: TS %d%s", v5up->ts[0]->nr, VTY_NEWLINE); else vty_out(vty, " Channel: link %d TS %d%s", v5up->ts[0]->link->id, v5up->ts[0]->nr, VTY_NEWLINE); } } else { vty_out(vty, "ISDN port nr %d:", v5up->nr); vty_out(vty, " Port state=%s%s", v5x_le_port_isdn_state_name(v5up->port_fi), VTY_NEWLINE); if (v5up->ts[0]) { if (v5up->interface->dialect == V5X_DIALECT_V51) vty_out(vty, " Channel B1: TS %d%s", v5up->ts[0]->nr, VTY_NEWLINE); else vty_out(vty, " Channel B1: link %d TS %d%s", v5up->ts[0]->link->id, v5up->ts[0]->nr, VTY_NEWLINE); } if (v5up->ts[1]) { if (v5up->interface->dialect == V5X_DIALECT_V51) vty_out(vty, " Channel B2: TS %d%s", v5up->ts[1]->nr, VTY_NEWLINE); else vty_out(vty, " Channel B2: link %d TS %d%s", v5up->ts[1]->link->id, v5up->ts[1]->nr, VTY_NEWLINE); } } } #define SHOW_PORT "Show given user port and states\n" DEFUN(show_port_pstn, show_port_pstn_cmd, "show port pstn <0-32767>", SHOW_STR SHOW_PORT "Show given PSTN user port and states\n" "L3 address") { struct v5x_interface *v5if = get_interface(vty); struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (!v5up) { vty_out(vty, "%%Given PSTN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } print_port(vty, v5up); return CMD_SUCCESS; } DEFUN(show_port_isdn, show_port_isdn_cmd, "show port isdn <0-8175>", SHOW_STR SHOW_PORT "Show given ISDN user port and states\n" "L3 address") { struct v5x_interface *v5if = get_interface(vty); struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (!v5up) { vty_out(vty, "%%Given ISDN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } print_port(vty, v5up); return CMD_SUCCESS; } DEFUN(show_port, show_port_cmd, "show port", SHOW_STR "Show all user ports and states") { struct v5x_interface *v5if = get_interface(vty); struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; if (llist_empty(&v5if->user_ports)) { vty_out(vty, "%%No user ports created!%s", VTY_NEWLINE); return CMD_WARNING; } llist_for_each_entry(v5up, &v5if->user_ports, list) print_port(vty, v5up); return CMD_SUCCESS; } /* * operate */ DEFUN(pstn_restart, pstn_restart_cmd, "pstn-restart", "Perform PSTN protocol restart") { struct v5x_interface *v5if = get_interface(vty); v5x_le_pstn_restart(v5if); return CMD_SUCCESS; } DEFUN(switchover, switchover_cmd, "switch-over <0-255>", "Perform switch-over to given link\n" "Link ID") { struct v5x_interface *v5if = get_interface(vty); struct v5x_link *v5l; if (v5if->dialect != V5X_DIALECT_V52) { vty_out(vty, "%%This command is only applicable to V5.2 interface.%s", VTY_NEWLINE); return CMD_WARNING; } v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Given link does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } if (v5l != v5if->primary_link && v5l != v5if->secondary_link) { vty_out(vty, "%%Given link is not primary, nor secondary.%s", VTY_NEWLINE); return CMD_WARNING; } v52_le_pp_mdu_snd(v5if, MDU_Protection_switch_over_com, atoi(argv[0]), v5l->c_channel[0].ts->nr, 0); return CMD_SUCCESS; } DEFUN(unblock_link, unblock_link_cmd, "unblock link <0-255>", "Perform unblocking\n" "Perform unblocking of link\n" "Link ID") { struct v5x_interface *v5if = get_interface(vty); struct v5x_link *v5l; if (v5if->dialect != V5X_DIALECT_V52) { vty_out(vty, "%%This command is only applicable to V5.2 interface.%s", VTY_NEWLINE); return CMD_WARNING; } v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Given link does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v52_le_lcp_mdu_snd(v5l, MDU_LUBR); return CMD_SUCCESS; } DEFUN(block_link, block_link_cmd, "block link <0-255>", "Perform blocking\n" "Perform blocking of link\n" "Link ID") { struct v5x_interface *v5if = get_interface(vty); struct v5x_link *v5l; if (v5if->dialect != V5X_DIALECT_V52) { vty_out(vty, "%%This command is only applicable to V5.2 interface.%s", VTY_NEWLINE); return CMD_WARNING; } v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Given link does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v52_le_lcp_mdu_snd(v5l, MDU_LBI); return CMD_SUCCESS; } /* * configure */ enum v5_vty_node { INTERFACE_NODE_V51 = _LAST_OSMOVTY_NODE + 1, INTERFACE_NODE_V52, LINK_NODE, PORT_NODE, }; static struct cmd_node interface_node_v51 = { .node = INTERFACE_NODE_V51, .prompt = "%s(config-v5.1-if)# ", .vtysh = 1, }; static struct cmd_node interface_node_v52 = { .node = INTERFACE_NODE_V52, .prompt = "%s(config-v5.2-if)# ", .vtysh = 1, }; static struct cmd_node link_node = { .node = LINK_NODE, .prompt = "%s(config-link)# ", .vtysh = 1, }; static struct cmd_node port_node = { .node = PORT_NODE, .prompt = "%s(config-port)# ", .vtysh = 1, }; static int v5le_vty_is_config_node(struct vty __attribute__((unused)) *vty, int node) { switch (node) { case CONFIG_NODE: return 0; default: return 1; } } static int v5le_vty_go_parent(struct vty *vty) { struct v5x_interface *v5if; struct v5x_link *v5l; struct v5x_user_port *v5up; switch (vty->node) { case PORT_NODE: v5up = vty->index; v5if = v5up->interface; vty->node = (v5if->dialect == V5X_DIALECT_V51) ? INTERFACE_NODE_V51 : INTERFACE_NODE_V52; vty->index = v5if; break; case LINK_NODE: v5l = vty->index; v5if = v5l->interface; vty->node = (v5if->dialect == V5X_DIALECT_V51) ? INTERFACE_NODE_V51 : INTERFACE_NODE_V52; vty->index = v5if; break; case INTERFACE_NODE_V51: case INTERFACE_NODE_V52: vty->node = CONFIG_NODE; vty->index = NULL; break; default: vty->node = ENABLE_NODE; vty->index = NULL; } return vty->node; } struct vty_app_info vty_info = { .name = "OsmoV5LE", .version = PACKAGE_VERSION, .go_parent_cb = v5le_vty_go_parent, .is_config_node = v5le_vty_is_config_node, }; DEFUN(cfg_interface, cfg_interface_cmd, "interface (v5.1|v5.2)", "Configure V5 interface\n" "Configure as V5.1 interface\n" "Configure as V5.2 interface") { struct v5x_interface *v5if = NULL; enum v5x_dialect dialect = V5X_DIALECT_V51; if (!llist_empty(&v5i->interfaces)) v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list); if (!strcasecmp(argv[0], "v5.2")) dialect = V5X_DIALECT_V52; if (!v5if) { v5if = v5x_interface_alloc(v5i, dialect); if (!v5if) { vty_out(vty, "%%Failed to create interface. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } } else if (dialect != v5if->dialect) { vty_out(vty, "%%Different interface type already created. To change, remove first.%s", VTY_NEWLINE); } vty->node = (v5if->dialect == V5X_DIALECT_V51) ? INTERFACE_NODE_V51 : INTERFACE_NODE_V52; vty->index = v5if; return CMD_SUCCESS; } DEFUN(cfg_no_interface, cfg_no_interface_cmd, "no interface", NO_STR "Remove V5 interface") { struct v5x_interface *v5if = NULL; if (!llist_empty(&v5i->interfaces)) v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list); if (v5if) { v5x_interface_free(v5if); } return CMD_SUCCESS; } DEFUN(cfg_interface_id, cfg_interface_id_cmd, "id <0-16777215>", "Set interface ID\n" "Interface ID") { struct v5x_interface *v5if = vty->index; v5if->id_local = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_interface_variant, cfg_interface_variant_cmd, "variant <0-127>", "Set interface provisioning variant\n" "Variant value") { struct v5x_interface *v5if = vty->index; v5if->variant_local = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_interface_cc_id, cfg_interface_cc_id_cmd, "cc-id <0-65535>", "Set protection CC-ID\n" "CC-ID value") { struct v5x_interface *v5if = vty->index; v5if->protection.cc_id = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_interface_capability, cfg_interface_capability_cmd, "information-transfer-capability <0-31>", "Enable information transfer capability with ISDN port allocation\n" "Information transfer capability") { struct v5x_interface *v5if = vty->index; v5if->use_capability = true; v5if->capability = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_interface_no_capability, cfg_interface_no_capability_cmd, "no information-transfer-capability", NO_STR "Disable information transfer capability with ISDN port allocation") { struct v5x_interface *v5if = vty->index; v5if->use_capability = false; return CMD_SUCCESS; } DEFUN(cfg_link_v51, cfg_link_cmd_v51, "link", "Modify link") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; v5l = llist_first_entry(&v5if->links, struct v5x_link, list); vty->node = LINK_NODE; vty->index = v5l; return CMD_SUCCESS; } DEFUN(cfg_link_v52, cfg_link_cmd_v52, "link <0-255>", "Add or modify link\n" "Link ID to create or modify") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { v5l = v5x_link_create(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Failed to create link. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } } vty->node = LINK_NODE; vty->index = v5l; return CMD_SUCCESS; } DEFUN(cfg_no_link_v52, cfg_no_link_cmd_v52, "no link <0-255>", NO_STR "Remove link from interface\n" "Link ID to remove") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; int rc; v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Given link with ID %d is not created.%s", atoi(argv[0]), VTY_NEWLINE); return CMD_WARNING; } rc = v5x_link_destroy(v5l); if (rc < 0) { vty_out(vty, "%%Given link with ID %d cannot be deleted, see debug output.%s", atoi(argv[0]), VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS; } DEFUN(cfg_e1_line, cfg_e1_line_cmd, "e1 line <0-255>", "E1 configuration\n" "E1 line configuration\n" "E1 line number to use for link") { struct v5x_link *v5l = vty->index, *search_v5l; struct e1inp_line *e1_line; unsigned int num = atoi(argv[0]); /* nothing has changed, same line number */ if (v5l->e1_line && v5l->e1_line->num == num) return CMD_SUCCESS; /* is there someone using this line number already? only can happen with multi-link (V5.2) */ llist_for_each_entry(search_v5l, &v5l->interface->links, list) { if (!search_v5l->e1_line) continue; if (search_v5l->e1_line->num == num) { vty_out(vty, "%%E1 line %d already used by link ID %d.%s", num, search_v5l->id, VTY_NEWLINE); return CMD_WARNING; } } /* remove line, if attached */ if (v5l->e1_line) e1_line_exit(v5l); /* add line, if created */ e1_line = e1_line_init(v5l, num); if (!e1_line) { vty_out(vty, "%%E1 line %d is not created. Please create it first.%s", num, VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS; } DEFUN(cfg_no_e1_line, cfg_no_e1_line_cmd, "no e1 line", NO_STR "E1 configuration\n" "Remove E1 line from link") { struct v5x_link *v5l = vty->index; /* remove line, if attached */ if (v5l->e1_line) e1_line_exit(v5l); return CMD_SUCCESS; } DEFUN(cfg_port_pstn_v51, cfg_port_pstn_cmd_v51, "port pstn <0-32767> <1-31>", "Create/modify V5 user port\n" "PSTN user port\n" "L3 address\n" "Time slot") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (v5up) { vty_out(vty, "%%Given PSTN user port already exists.%s", VTY_NEWLINE); return CMD_WARNING; } v5up = v5x_user_port_create(v5if, atoi(argv[0]), V5X_USER_TYPE_PSTN, atoi(argv[1]), 0); if (!v5up) { vty_out(vty, "%%Failed to create PSTN user port. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } vty->node = PORT_NODE; vty->index = v5up; return CMD_SUCCESS; } DEFUN(cfg_port_pstn, cfg_port_pstn_cmd, "port pstn <0-32767>", "Create/modify V5 user port\n" "PSTN user port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (!v5up) { if (v5if->dialect == V5X_DIALECT_V51) { vty_out(vty, "%%Given PSTN user port does not exist, give time slot.%s", VTY_NEWLINE); return CMD_WARNING; } v5up = v5x_user_port_create(v5if, atoi(argv[0]), V5X_USER_TYPE_PSTN, 0, 0); } if (!v5up) { vty_out(vty, "%%Failed to create PSTN user port. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } vty->node = PORT_NODE; vty->index = v5up; return CMD_SUCCESS; } DEFUN(cfg_no_port_pstn, cfg_no_port_pstn_cmd, "no port pstn <0-32767>", NO_STR "Delete V5 user port\n" "PSTN user port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (!v5up) { vty_out(vty, "%%Given PSTN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v5x_user_port_destroy(v5up); return CMD_SUCCESS; } DEFUN(cfg_port_isdn_v51, cfg_port_isdn_cmd_v51, "port isdn <0-8175> <1-31> <1-31>", "Create/modify V5 user port\n" "ISDN user port\n" "L3 address\n" "Time slot 1\n" "Time slot 2") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (v5up) { vty_out(vty, "%%Given ISDN user port already exists.%s", VTY_NEWLINE); return CMD_WARNING; } v5up = v5x_user_port_create(v5if, atoi(argv[0]), V5X_USER_TYPE_ISDN, atoi(argv[1]), atoi(argv[2])); if (!v5up) { vty_out(vty, "%%Failed to create ISDN user port. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } vty->node = PORT_NODE; vty->index = v5up; return CMD_SUCCESS; } DEFUN(cfg_port_isdn, cfg_port_isdn_cmd, "port isdn <0-8175>", "Create/modify V5 user port\n" "ISDN user port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (!v5up) { if (v5if->dialect == V5X_DIALECT_V51) { vty_out(vty, "%%Given ISDN user port does not exist, give time slots.%s", VTY_NEWLINE); return CMD_WARNING; } v5up = v5x_user_port_create(v5if, atoi(argv[0]), V5X_USER_TYPE_ISDN, 0, 0); } if (!v5up) { vty_out(vty, "%%Failed to create ISDN user port. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } vty->node = PORT_NODE; vty->index = v5up; return CMD_SUCCESS; } DEFUN(cfg_no_port_isdn, cfg_no_port_isdn_cmd, "no port isdn <0-8175>", NO_STR "Delete V5 user port\n" "ISDN user port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (!v5up) { vty_out(vty, "%%Given ISDN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v5x_user_port_destroy(v5up); return CMD_SUCCESS; } DEFUN(cfg_echo, cfg_echo_cmd, "line-echo-canceler", "Enable line echo canceler for all calls") { struct v5x_user_port *v5up = vty->index; v5up->echo_configured = 1; if (v5up->ts[0] && v5up->ts[0]->b_activated) v5x_echo_reset(&v5up->ep[0], v5up->echo_configured); if (v5up->ts[1] && v5up->ts[1]->b_activated) v5x_echo_reset(&v5up->ep[1], v5up->echo_configured); return CMD_SUCCESS; } DEFUN(cfg_no_echo, cfg_no_echo_cmd, "no line-echo-canceler", NO_STR "Disable line echo canceler for all calls") { struct v5x_user_port *v5up = vty->index; v5up->echo_configured = 0; if (v5up->ts[0] && v5up->ts[0]->b_activated) v5x_echo_reset(&v5up->ep[0], v5up->echo_configured); if (v5up->ts[1] && v5up->ts[1]->b_activated) v5x_echo_reset(&v5up->ep[1], v5up->echo_configured); return CMD_SUCCESS; } /* * write */ static void config_write_user_port(struct vty *vty, struct v5x_interface *v5if) { struct v5x_user_port *v5up; llist_for_each_entry(v5up, &v5if->user_ports, list) { switch (v5up->type) { case V5X_USER_TYPE_PSTN: if (v5if->dialect == V5X_DIALECT_V51) vty_out(vty, " port pstn %d %d%s", v5up->nr, v5up->ts[0]->nr, VTY_NEWLINE); else vty_out(vty, " port pstn %d%s", v5up->nr, VTY_NEWLINE); break; case V5X_USER_TYPE_ISDN: if (v5if->dialect == V5X_DIALECT_V51) vty_out(vty, " port isdn %d %d %d%s", v5up->nr, v5up->ts[0]->nr, v5up->ts[1]->nr, VTY_NEWLINE); else vty_out(vty, " port isdn %d%s", v5up->nr, VTY_NEWLINE); break; } if (v5up->echo_configured) vty_out(vty, " line-echo-canceler%s", VTY_NEWLINE); } } static int config_write_interface_v51(struct vty *vty) { struct v5x_interface *v5if = NULL; struct v5x_link *v5l; if (!llist_empty(&v5i->interfaces)) v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list); vty_out(vty, "!%s", VTY_NEWLINE); if (!v5if) vty_out(vty, "no interface%s", VTY_NEWLINE); if (v5if && v5if->dialect == V5X_DIALECT_V51) { v5l = llist_first_entry(&v5if->links, struct v5x_link, list); vty_out(vty, "interface v5.1%s", VTY_NEWLINE); vty_out(vty, " id %d%s", v5if->id_local, VTY_NEWLINE); vty_out(vty, " variant %d%s", v5if->variant_local, VTY_NEWLINE); vty_out(vty, " link%s", VTY_NEWLINE); if (!v5l->e1_line) vty_out(vty, " no e1 line%s", VTY_NEWLINE); else vty_out(vty, " e1 line %d%s", v5l->e1_line->num, VTY_NEWLINE); config_write_user_port(vty, v5if); } return CMD_SUCCESS; } static int config_write_interface_v52(struct vty *vty) { struct v5x_interface *v5if = NULL; struct v5x_link *v5l; if (!llist_empty(&v5i->interfaces)) v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list); vty_out(vty, "!%s", VTY_NEWLINE); if (v5if && v5if->dialect == V5X_DIALECT_V52) { vty_out(vty, "interface v5.2%s", VTY_NEWLINE); vty_out(vty, " id %d%s", v5if->id_local, VTY_NEWLINE); vty_out(vty, " variant %d%s", v5if->variant_local, VTY_NEWLINE); vty_out(vty, " cc-id %d%s", v5if->protection.cc_id, VTY_NEWLINE); if (v5if->use_capability) vty_out(vty, " information-transfer-capability %d%s", v5if->capability, VTY_NEWLINE); else vty_out(vty, " no information-transfer-capability%s", VTY_NEWLINE); llist_for_each_entry(v5l, &v5if->links, list) { vty_out(vty, " link %d%s", v5l->id, VTY_NEWLINE); if (v5l == v5if->primary_link) vty_out(vty, " # primary%s", VTY_NEWLINE); if (v5l == v5if->secondary_link) vty_out(vty, " # secondary%s", VTY_NEWLINE); if (!v5l->e1_line) vty_out(vty, " no e1 line%s", VTY_NEWLINE); else vty_out(vty, " e1 line %d%s", v5l->e1_line->num, VTY_NEWLINE); } config_write_user_port(vty, v5if); } return CMD_SUCCESS; } /* * init */ int v5le_vty_init(void) { install_element_ve(&show_interface_cmd); install_element_ve(&show_link_cmd); install_element_ve(&show_port_cmd); install_element_ve(&show_port_pstn_cmd); install_element_ve(&show_port_isdn_cmd); install_element(ENABLE_NODE, &pstn_restart_cmd); install_element(ENABLE_NODE, &switchover_cmd); install_element(ENABLE_NODE, &unblock_link_cmd); install_element(ENABLE_NODE, &block_link_cmd); install_element(CONFIG_NODE, &cfg_interface_cmd); install_element(CONFIG_NODE, &cfg_no_interface_cmd); install_node(&interface_node_v51, config_write_interface_v51); install_node(&interface_node_v52, config_write_interface_v52); install_element(INTERFACE_NODE_V51, &cfg_interface_id_cmd); install_element(INTERFACE_NODE_V51, &cfg_interface_variant_cmd); install_element(INTERFACE_NODE_V51, &cfg_link_cmd_v51); install_element(INTERFACE_NODE_V51, &cfg_port_pstn_cmd_v51); install_element(INTERFACE_NODE_V51, &cfg_port_pstn_cmd); install_element(INTERFACE_NODE_V51, &cfg_no_port_pstn_cmd); install_element(INTERFACE_NODE_V51, &cfg_port_isdn_cmd_v51); install_element(INTERFACE_NODE_V51, &cfg_port_isdn_cmd); install_element(INTERFACE_NODE_V51, &cfg_no_port_isdn_cmd); install_element(INTERFACE_NODE_V52, &cfg_interface_id_cmd); install_element(INTERFACE_NODE_V52, &cfg_interface_variant_cmd); install_element(INTERFACE_NODE_V52, &cfg_interface_cc_id_cmd); install_element(INTERFACE_NODE_V52, &cfg_interface_capability_cmd); install_element(INTERFACE_NODE_V52, &cfg_interface_no_capability_cmd); install_element(INTERFACE_NODE_V52, &cfg_link_cmd_v52); install_element(INTERFACE_NODE_V52, &cfg_no_link_cmd_v52); install_element(INTERFACE_NODE_V52, &cfg_port_pstn_cmd); install_element(INTERFACE_NODE_V52, &cfg_no_port_pstn_cmd); install_element(INTERFACE_NODE_V52, &cfg_port_isdn_cmd); install_element(INTERFACE_NODE_V52, &cfg_no_port_isdn_cmd); install_node(&link_node, NULL); install_element(LINK_NODE, &cfg_e1_line_cmd); install_element(LINK_NODE, &cfg_no_e1_line_cmd); install_node(&port_node, NULL); install_element(PORT_NODE, &cfg_echo_cmd); install_element(PORT_NODE, &cfg_no_echo_cmd); return 0; }