diff --git a/src/main.c b/src/main.c index 478599b..f8acb37 100644 --- a/src/main.c +++ b/src/main.c @@ -108,6 +108,10 @@ static const struct e1inp_line_ops v5le_e1_line_ops = { static void hdlc_rx_cb(struct e1inp_ts *ts, struct msgb *msg) { #warning HACKING + if (llist_empty(&v5i->interfaces)) { + msgb_free(msg); + return; + } struct v5x_interface *v5if = (struct v5x_interface *)v5i->interfaces.next; LOGP(DLINP, LOGL_DEBUG, "L1->L2: %s\n", msgb_hexdump(msg)); @@ -122,6 +126,10 @@ static void hdlc_rx_cb(struct e1inp_ts *ts, struct msgb *msg) static void raw_rx_cb(struct e1inp_ts *ts, struct msgb *msg) { #warning HACKING + if (llist_empty(&v5i->interfaces)) { + msgb_free(msg); + return; + } struct v5x_interface *v5if = (struct v5x_interface *)v5i->interfaces.next; struct v5x_user_port *v5up = v5if->links[0].ts[ts->num].v5up; @@ -405,13 +413,6 @@ int main(int argc, char **argv) if (!v5i) return -ENOMEM; - // FIXME: move this to VTY code - /* create v5x interface */ - struct v5x_interface *v5if; - v5if = v5x_interface_alloc(v5i, V5X_DIALECT_V51, ph_data_req); - if (!v5if) - return -ENOMEM; - rc = vty_read_config_file(config_file, NULL); if (rc < 0) { fprintf(stderr, "Failed to read config file '%s'.\n", config_file); diff --git a/src/v5x_vty.c b/src/v5x_vty.c index e3a393b..119f807 100644 --- a/src/v5x_vty.c +++ b/src/v5x_vty.c @@ -8,12 +8,19 @@ extern struct v5x_instance *v5i; enum v5_vty_node { - INTERFACE_NODE = _LAST_OSMOVTY_NODE + 1, + INTERFACE_NODE_V51 = _LAST_OSMOVTY_NODE + 1, + INTERFACE_NODE_V52, }; -static struct cmd_node interface_node = { - INTERFACE_NODE, - "%s(config-if)# ", +static struct cmd_node interface_node_v51 = { + INTERFACE_NODE_V51, + "%s(config-v5.1-if)# ", + 1, +}; + +static struct cmd_node interface_node_v52 = { + INTERFACE_NODE_V52, + "%s(config-v5.2-if)# ", 1, }; @@ -49,16 +56,54 @@ struct vty_app_info vty_info = { .is_config_node = v5le_vty_is_config_node, }; -DEFUN(cfg_interface, cfg_interface_cmd, - "interface", "Configure the V5 interface") -{ - struct v5x_interface *v5if = (struct v5x_interface *)v5i->interfaces.next; +#warning hacking +int ph_data_req(struct msgb *msg, void *cbdata); - vty->node = INTERFACE_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 = (struct v5x_interface *)v5i->interfaces.next; + + if (!strcasecmp(argv[0], "v5.2")) + dialect = V5X_DIALECT_V52; + + if (!v5if) { + v5if = v5x_interface_alloc(v5i, dialect, ph_data_req); + if (!v5if) { + vty_out(vty, "%%Failed to create interface%s", VTY_NEWLINE); + return CMD_WARNING; + } + } else { + vty_out(vty, "%%Interface already created. If interface type has been changed, restart this " + "application.%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 = (struct v5x_interface *)v5i->interfaces.next; + + 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") @@ -79,7 +124,7 @@ DEFUN(cfg_interface_variant, cfg_interface_variant_cmd, return CMD_SUCCESS; } -DEFUN(cfg_port_pstn, cfg_port_pstn_cmd, +DEFUN(cfg_port_pstn_v51, cfg_port_pstn_cmd_v51, "port pstn <0-32767> <1-31>", "Create V5 user port\n" "PSTN user port\n" "L3 address\n" "Time slot") { @@ -99,6 +144,26 @@ DEFUN(cfg_port_pstn, cfg_port_pstn_cmd, return CMD_SUCCESS; } +DEFUN(cfg_port_pstn_v52, cfg_port_pstn_cmd_v52, + "port pstn <0-32767>", + "Create 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 already exists, remove first.%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.%s", VTY_NEWLINE); + return CMD_WARNING; + } + 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\n") @@ -115,7 +180,7 @@ DEFUN(cfg_no_port_pstn, cfg_no_port_pstn_cmd, return CMD_SUCCESS; } -DEFUN(cfg_port_isdn, cfg_port_isdn_cmd, +DEFUN(cfg_port_isdn_v51, cfg_port_isdn_cmd_v51, "port isdn <0-8175> <1-31> <1-31>", "Create V5 user port\n" "ISDN user port\n" "L3 address\n" "Time slot 1\n" "Time slot 2\n") { @@ -135,6 +200,26 @@ DEFUN(cfg_port_isdn, cfg_port_isdn_cmd, return CMD_SUCCESS; } +DEFUN(cfg_port_isdn_v52, cfg_port_isdn_cmd_v52, + "port isdn <0-8175>", + "Create V5 user port\n" "ISDN user port\n" "L3 address\n") +{ + 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, remove first.%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.%s", VTY_NEWLINE); + return CMD_WARNING; + } + 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\n") @@ -151,23 +236,58 @@ DEFUN(cfg_no_port_isdn, cfg_no_port_isdn_cmd, return CMD_SUCCESS; } -static int config_write_interface(struct vty *vty) +static int config_write_interface_v51(struct vty *vty) { - struct v5x_interface *v5if = (struct v5x_interface *)v5i->interfaces.next; + struct v5x_interface *v5if = NULL; struct v5x_user_port *v5up; + if (!llist_empty(&v5i->interfaces)) + v5if = (struct v5x_interface *)v5i->interfaces.next; + vty_out(vty, "!%s", VTY_NEWLINE); - vty_out(vty, "interface%s", VTY_NEWLINE); - vty_out(vty, " id %d%s", v5if->id, VTY_NEWLINE); - vty_out(vty, " variant %d%s", v5if->variant, VTY_NEWLINE); - llist_for_each_entry(v5up, &v5if->user_ports, list) { - switch (v5up->type) { - case V5X_USER_TYPE_PSTN: - vty_out(vty, " port pstn %d %d%s", v5up->nr, v5up->ts_nr[0], VTY_NEWLINE); - break; - case V5X_USER_TYPE_ISDN: - vty_out(vty, " port isdn %d %d %d%s", v5up->nr, v5up->ts_nr[0], v5up->ts_nr[1], VTY_NEWLINE); - break; + if (!v5if) + vty_out(vty, "no interface%s", VTY_NEWLINE); + if (v5if && v5if->dialect == V5X_DIALECT_V51) { + vty_out(vty, "interface v5.1%s", VTY_NEWLINE); + vty_out(vty, " id %d%s", v5if->id, VTY_NEWLINE); + vty_out(vty, " variant %d%s", v5if->variant, VTY_NEWLINE); + llist_for_each_entry(v5up, &v5if->user_ports, list) { + switch (v5up->type) { + case V5X_USER_TYPE_PSTN: + vty_out(vty, " port pstn %d %d%s", v5up->nr, v5up->ts_nr[0], VTY_NEWLINE); + break; + case V5X_USER_TYPE_ISDN: + vty_out(vty, " port isdn %d %d %d%s", v5up->nr, v5up->ts_nr[0], v5up->ts_nr[1], + VTY_NEWLINE); + break; + } + } + } + return CMD_SUCCESS; +} + +static int config_write_interface_v52(struct vty *vty) +{ + struct v5x_interface *v5if = NULL; + struct v5x_user_port *v5up; + + if (!llist_empty(&v5i->interfaces)) + v5if = (struct v5x_interface *)v5i->interfaces.next; + + 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, VTY_NEWLINE); + vty_out(vty, " variant %d%s", v5if->variant, VTY_NEWLINE); + llist_for_each_entry(v5up, &v5if->user_ports, list) { + switch (v5up->type) { + case V5X_USER_TYPE_PSTN: + vty_out(vty, " port pstn %d%s", v5up->nr, VTY_NEWLINE); + break; + case V5X_USER_TYPE_ISDN: + vty_out(vty, " port isdn %d%s", v5up->nr, VTY_NEWLINE); + break; + } } } return CMD_SUCCESS; @@ -176,13 +296,21 @@ static int config_write_interface(struct vty *vty) int v5x_vty_init(void) { install_element(CONFIG_NODE, &cfg_interface_cmd); - install_node(&interface_node, config_write_interface); - install_element(INTERFACE_NODE, &cfg_interface_id_cmd); - install_element(INTERFACE_NODE, &cfg_interface_variant_cmd); - install_element(INTERFACE_NODE, &cfg_port_pstn_cmd); - install_element(INTERFACE_NODE, &cfg_no_port_pstn_cmd); - install_element(INTERFACE_NODE, &cfg_port_isdn_cmd); - install_element(INTERFACE_NODE, &cfg_no_port_isdn_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_port_pstn_cmd_v51); + 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_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_port_pstn_cmd_v52); + install_element(INTERFACE_NODE_V52, &cfg_no_port_pstn_cmd); + install_element(INTERFACE_NODE_V52, &cfg_port_isdn_cmd_v52); + install_element(INTERFACE_NODE_V52, &cfg_no_port_isdn_cmd); return 0; }