forked from retronetworking/osmo-v5
Improve management process, to handle startup/blocking/unblocking correctly
This is a big one: Startup process was hacked. Several state machines do the startup process now: - system startup - PSTN startup - PSTN restart - 5 state machines to do multiple port unblocking/blocking
This commit is contained in:
parent
dd23410c52
commit
f489ce381c
24
src/lapv5.c
24
src/lapv5.c
|
@ -189,6 +189,12 @@ int lapv5_ph_data_ind(struct lapv5_instance *li, struct msgb *msg, int *error)
|
|||
/* write to PCAP file, if enabled. */
|
||||
osmo_pcap_lapd_write(li->pcap_fd, OSMO_LAPD_PCAP_INPUT, msg);
|
||||
|
||||
if (!li->enabled) {
|
||||
LOGLI(li, LOGL_DEBUG, "LAPV5 frame ignored, because DL is disabled.\n");
|
||||
msgb_free(msg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msgb_pull(msg, msg->l2h - msg->data);
|
||||
|
||||
LOGLI(li, LOGL_DEBUG, "RX: %s\n", osmo_hexdump(msg->data, msg->len));
|
||||
|
@ -279,12 +285,11 @@ int lapv5_dl_est_req(struct lapv5_instance *li, uint16_t dladdr)
|
|||
struct msgb *msg;
|
||||
|
||||
sap = lapv5_sap_find(li, dladdr);
|
||||
if (sap)
|
||||
return -EEXIST;
|
||||
|
||||
if (!sap) {
|
||||
sap = lapv5_sap_alloc(li, dladdr);
|
||||
if (!sap)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
LOGSAP(sap, LOGL_DEBUG, "LAPV5 DL-ESTABLISH request DLADDR=%u\n", dladdr);
|
||||
|
||||
|
@ -579,3 +584,16 @@ int lapv5ef_tx(struct v5x_user_port *v5up, struct msgb *msg)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set enabled state, also free all SAP, so it will disable/enable with a cleanly */
|
||||
void lapv5_set_enabled(struct lapv5_instance *li, bool enabled)
|
||||
{
|
||||
struct lapv5_sap *sap;
|
||||
|
||||
li->enabled = enabled;
|
||||
|
||||
/* reset DL instances */
|
||||
llist_for_each_entry(sap, &li->sap_list, list) {
|
||||
lapd_dl_reset(&sap->dl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ struct lapv5_instance {
|
|||
struct llist_head sap_list; /* list of SAP/datalinks in this instance */
|
||||
int pcap_fd; /* PCAP file descriptor */
|
||||
char *name; /* human-readable name */
|
||||
|
||||
bool enabled; /* only receive messages when enabled */
|
||||
};
|
||||
|
||||
extern const struct lapd_profile lapd_profile_lapv5dl;
|
||||
|
@ -37,3 +39,5 @@ void lapv5_instance_free(struct lapv5_instance *li);
|
|||
|
||||
int lapv5ef_rx(struct v5x_link *link, struct msgb *msg);
|
||||
int lapv5ef_tx(struct v5x_user_port *v5up, struct msgb *msg);
|
||||
|
||||
void lapv5_set_enabled(struct lapv5_instance *li, bool enabled);
|
||||
|
|
30
src/main.c
30
src/main.c
|
@ -265,30 +265,11 @@ int main(int argc, char **argv)
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* start telnet after reading config for vty_get_bind_addr() */
|
||||
rc = telnet_init_dynif(tall_v5le_ctx, NULL,
|
||||
vty_get_bind_addr(), OSMO_VTY_PORT_MGW);
|
||||
/* start telnet after reading config */
|
||||
rc = telnet_init_default(tall_v5le_ctx, NULL, OSMO_VTY_PORT_MGW);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* start DL */
|
||||
if (!llist_empty(&v5i->interfaces)) {
|
||||
struct v5x_interface *v5if;
|
||||
v5if = (struct v5x_interface *)v5i->interfaces.next;
|
||||
if (v5if->control.li)
|
||||
lapv5_dl_est_req(v5if->control.li, V5X_DLADDR_CTRL);
|
||||
if (v5if->pstn.li)
|
||||
lapv5_dl_est_req(v5if->pstn.li, V5X_DLADDR_PSTN);
|
||||
if (v5if->lcp.li)
|
||||
lapv5_dl_est_req(v5if->lcp.li, V52_DLADDR_LCP);
|
||||
if (v5if->bcc.li)
|
||||
lapv5_dl_est_req(v5if->bcc.li, V52_DLADDR_BCC);
|
||||
if (v5if->protection.li[0])
|
||||
lapv5_dl_est_req(v5if->protection.li[0], V52_DLADDR_PROTECTION);
|
||||
if (v5if->protection.li[1])
|
||||
lapv5_dl_est_req(v5if->protection.li[1], V52_DLADDR_PROTECTION);
|
||||
}
|
||||
|
||||
/* initialisation */
|
||||
srand(time(NULL));
|
||||
|
||||
|
@ -306,6 +287,13 @@ int main(int argc, char **argv)
|
|||
signal(SIGTERM, sighandler);
|
||||
signal(SIGPIPE, sighandler);
|
||||
|
||||
/* start management state machine */
|
||||
if (!llist_empty(&v5i->interfaces)) {
|
||||
struct v5x_interface *v5if;
|
||||
v5if = (struct v5x_interface *)v5i->interfaces.next;
|
||||
v5x_le_mgmt_start_delay(v5if, SOCKET_RETRY_TIMER + 1);
|
||||
}
|
||||
|
||||
/* main loop */
|
||||
while (!quit) {
|
||||
osmo_select_main(0);
|
||||
|
|
401
src/v5le_vty.c
401
src/v5le_vty.c
|
@ -10,6 +10,7 @@
|
|||
#include "v5x_le_pstn_fsm.h"
|
||||
#include "v5x_le_management.h"
|
||||
#include "layer1.h"
|
||||
#include "lapv5.h"
|
||||
#include "../config.h"
|
||||
|
||||
extern struct v5x_instance *v5i;
|
||||
|
@ -32,23 +33,76 @@ static struct v5x_interface *get_interface(struct vty *vty)
|
|||
* show
|
||||
*/
|
||||
|
||||
static const char *link_status(bool established, struct lapv5_instance *li)
|
||||
{
|
||||
if (!li->enabled)
|
||||
return "disabled";
|
||||
if (!established)
|
||||
return "down";
|
||||
return "up";
|
||||
}
|
||||
|
||||
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;
|
||||
struct v5x_user_port *v5up;
|
||||
int calls;
|
||||
|
||||
if (!v5if)
|
||||
if (!v5if) {
|
||||
vty_out(vty, "No interface exists.%s", VTY_NEWLINE);
|
||||
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);
|
||||
vty_out(vty, " Trigger system restart: %s%s", (v5if->mgmt->auto_restart) ? "automatic" : "manual", VTY_NEWLINE);
|
||||
vty_out(vty, " Trigger data links: %s%s", (v5if->mgmt->do_est) ? "yes" : "no", VTY_NEWLINE);
|
||||
vty_out(vty, " Trigger user port alignment: %s%s", (v5if->mgmt->do_align) ? "yes" : "no", VTY_NEWLINE);
|
||||
if (v5if->dialect == V5X_DIALECT_V52)
|
||||
vty_out(vty, " Accelerated alignment: %s%s", (v5if->mgmt->acc_align) ? "yes" : "no", VTY_NEWLINE);
|
||||
if (v5if->control.li)
|
||||
vty_out(vty, " Control data link: %s%s", link_status(v5if->control.established, v5if->control.li),
|
||||
VTY_NEWLINE);
|
||||
if (v5if->pstn.li)
|
||||
vty_out(vty, " PSTN data link: %s%s", link_status(v5if->pstn.established, v5if->pstn.li), VTY_NEWLINE);
|
||||
if (v5if->lcp.li)
|
||||
vty_out(vty, " LCP data link: %s%s", link_status(v5if->lcp.established, v5if->lcp.li), VTY_NEWLINE);
|
||||
if (v5if->bcc.li)
|
||||
vty_out(vty, " BCC data link: %s%s", link_status(v5if->bcc.established, v5if->bcc.li), VTY_NEWLINE);
|
||||
if (v5if->protection.li[0])
|
||||
vty_out(vty, " Protection data link (primary): %s%s",
|
||||
link_status(v5if->protection.established[0], v5if->protection.li[0]), VTY_NEWLINE);
|
||||
if (v5if->protection.li[1])
|
||||
vty_out(vty, " Protection data link (secondary): %s%s",
|
||||
link_status(v5if->protection.established[1], v5if->protection.li[1]), VTY_NEWLINE);
|
||||
vty_out(vty, " System startup state: %s%s", v5x_le_system_fsm_state_name(v5if->mgmt->system_fi), VTY_NEWLINE);
|
||||
vty_out(vty, " PSTN data link startup state: %s%s", v5x_le_pstn_dl_fsm_state_name(v5if->mgmt->pstn_dl_fi),
|
||||
VTY_NEWLINE);
|
||||
vty_out(vty, " PSTN restart state: %s%s", v5x_le_pstn_rs_fsm_state_name(v5if->mgmt->pstn_rs_fi), VTY_NEWLINE);
|
||||
if (v5if->dialect == V5X_DIALECT_V52) {
|
||||
vty_out(vty, " Unblock all PSTN/ISDN state: %s%s",
|
||||
v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[UNBLK_ALL_PSTN_ISDN]), VTY_NEWLINE);
|
||||
vty_out(vty, " Unblock all PSTN state: %s%s",
|
||||
v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[UNBLK_ALL_PSTN]), VTY_NEWLINE);
|
||||
vty_out(vty, " Unblock all ISDN state: %s%s",
|
||||
v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[UNBLK_ALL_ISDN]), VTY_NEWLINE);
|
||||
vty_out(vty, " Block all PSTN state: %s%s",
|
||||
v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[BLK_ALL_PSTN]), VTY_NEWLINE);
|
||||
vty_out(vty, " Block all ISDN state: %s%s",
|
||||
v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[BLK_ALL_ISDN]), VTY_NEWLINE);
|
||||
}
|
||||
if (!v5if->id_remote_valid)
|
||||
vty_out(vty, " ID: local: %d remote: unknown%s", v5if->id_local, VTY_NEWLINE);
|
||||
else
|
||||
vty_out(vty, " ID: local: %d remote: %d%s%s", v5if->id_local, v5if->id_remote,
|
||||
(v5if->id_local != v5if->id_remote) ? " (mismatching)" : "", VTY_NEWLINE);
|
||||
if (!v5if->variant_remote_valid)
|
||||
vty_out(vty, " Variant: local: %d remote: unknown%s", v5if->variant_local, VTY_NEWLINE);
|
||||
else
|
||||
vty_out(vty, " Variant: local: %d remote: %d%s%s", v5if->variant_local, v5if->variant_remote,
|
||||
(v5if->variant_local != v5if->variant_remote) ? " (mismatching)" : "", VTY_NEWLINE);
|
||||
if (v5if->dialect == V5X_DIALECT_V52) {
|
||||
vty_out(vty, " Link IDs:");
|
||||
llist_for_each_entry(v5l, &v5if->links, list)
|
||||
|
@ -59,22 +113,17 @@ DEFUN(show_interface, show_interface_cmd,
|
|||
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);
|
||||
vty_out(vty, " Current C-Channel data 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);
|
||||
calls = 0;
|
||||
llist_for_each_entry(v5up, &v5if->user_ports, list) {
|
||||
if (v5up->ts[0] && v5up->ts[0]->b_activated)
|
||||
calls++;
|
||||
if (v5up->ts[1] && v5up->ts[1]->b_activated)
|
||||
calls++;
|
||||
}
|
||||
vty_out(vty, " Active calls (B-channels): %d%s", calls, VTY_NEWLINE);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -107,43 +156,39 @@ DEFUN(show_link, show_link_cmd,
|
|||
if (!v5l->ts[t].b_channel)
|
||||
continue;
|
||||
if ((v5up = v5l->ts[t].v5up))
|
||||
vty_out(vty, " TS %2d: %s-%d %s", t,
|
||||
(v5up->type == V5X_USER_TYPE_PSTN) ? "PSTN" : "ISDN", v5up->nr, VTY_NEWLINE);
|
||||
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_channel(struct vty *vty, enum v5x_dialect dialect, const char *bchan, struct v5x_timeslot *ts)
|
||||
{
|
||||
if (dialect == V5X_DIALECT_V51)
|
||||
vty_out(vty, " Channel%s: TS %d %s%s", bchan, ts->nr,
|
||||
(ts->b_activated) ? "(active)": "", VTY_NEWLINE);
|
||||
else
|
||||
vty_out(vty, " Channel%s: link %d TS %d %s%s", bchan, ts->link->id, ts->nr,
|
||||
(ts->b_activated) ? "(active)": "", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (v5up->ts[0])
|
||||
print_port_channel(vty, v5up->interface->dialect, "", v5up->ts[0]);
|
||||
} 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);
|
||||
}
|
||||
if (v5up->ts[0])
|
||||
print_port_channel(vty, v5up->interface->dialect, " B1", v5up->ts[0]);
|
||||
if (v5up->ts[1])
|
||||
print_port_channel(vty, v5up->interface->dialect, " B2", v5up->ts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,13 +261,64 @@ DEFUN(show_port, show_port_cmd,
|
|||
* operate
|
||||
*/
|
||||
|
||||
DEFUN(system_restart, system_restart_cmd,
|
||||
"system-restart",
|
||||
"Perform system startup/restart")
|
||||
{
|
||||
struct v5x_interface *v5if = get_interface(vty);
|
||||
int rc;
|
||||
|
||||
if (!v5if)
|
||||
return CMD_WARNING;
|
||||
|
||||
rc = v5x_le_mgmt_start(v5if);
|
||||
if (rc < 0) {
|
||||
vty_out(vty, "%%System is not in right state.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(pstn_restart, pstn_restart_cmd,
|
||||
"pstn-restart",
|
||||
"Perform PSTN protocol restart")
|
||||
{
|
||||
struct v5x_interface *v5if = get_interface(vty);
|
||||
int rc;
|
||||
|
||||
if (!v5if)
|
||||
return CMD_WARNING;
|
||||
|
||||
rc = v5x_le_pstn_restart(v5if);
|
||||
if (rc < 0) {
|
||||
vty_out(vty, "%%System is not in right state.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(align_ports, align_ports_cmd,
|
||||
"align-ports [accelerated]",
|
||||
"Perform alignment of all ports (sync (un)blocked state)")
|
||||
{
|
||||
struct v5x_interface *v5if = get_interface(vty);
|
||||
int accelerated = 0;
|
||||
int rc;
|
||||
|
||||
if (!v5if)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (argc >= 1)
|
||||
accelerated = 1;
|
||||
|
||||
rc = v5x_le_align_ports(v5if, accelerated);
|
||||
if (rc < 0) {
|
||||
vty_out(vty, "%%System is not in right state.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
v5x_le_pstn_restart(v5if);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -233,6 +329,9 @@ DEFUN(switchover, switchover_cmd,
|
|||
struct v5x_interface *v5if = get_interface(vty);
|
||||
struct v5x_link *v5l;
|
||||
|
||||
if (!v5if)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (v5if->dialect != V5X_DIALECT_V52) {
|
||||
vty_out(vty, "%%This command is only applicable to V5.2 interface.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
|
@ -252,13 +351,19 @@ DEFUN(switchover, switchover_cmd,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#define PERF_UBLK "Perform unblocking\n"
|
||||
#define PERF_BLK "Perform blocking\n"
|
||||
|
||||
DEFUN(unblock_link, unblock_link_cmd,
|
||||
"unblock link <0-255>",
|
||||
"Perform unblocking\n" "Perform unblocking of link\n" "Link ID")
|
||||
PERF_UBLK "Perform unblocking of link\n" "Link ID")
|
||||
{
|
||||
struct v5x_interface *v5if = get_interface(vty);
|
||||
struct v5x_link *v5l;
|
||||
|
||||
if (!v5if)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (v5if->dialect != V5X_DIALECT_V52) {
|
||||
vty_out(vty, "%%This command is only applicable to V5.2 interface.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
|
@ -276,11 +381,14 @@ DEFUN(unblock_link, unblock_link_cmd,
|
|||
|
||||
DEFUN(block_link, block_link_cmd,
|
||||
"block link <0-255>",
|
||||
"Perform blocking\n" "Perform blocking of link\n" "Link ID")
|
||||
PERF_BLK "Perform blocking of link\n" "Link ID")
|
||||
{
|
||||
struct v5x_interface *v5if = get_interface(vty);
|
||||
struct v5x_link *v5l;
|
||||
|
||||
if (!v5if)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (v5if->dialect != V5X_DIALECT_V52) {
|
||||
vty_out(vty, "%%This command is only applicable to V5.2 interface.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
|
@ -296,6 +404,86 @@ DEFUN(block_link, block_link_cmd,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(unblock_pstn_port, unblock_pstn_port_cmd,
|
||||
"unblock pstn <0-32767>",
|
||||
PERF_UBLK "Perform unblocking of PSTN port\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;
|
||||
}
|
||||
|
||||
v5x_le_mgmt_port_unblock(v5up);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(block_pstn_port, block_pstn_port_cmd,
|
||||
"block pstn <0-32767>",
|
||||
PERF_BLK "Perform blocking of PSTN port\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;
|
||||
}
|
||||
|
||||
v5x_le_mgmt_port_block(v5up);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(unblock_isdn_port, unblock_isdn_port_cmd,
|
||||
"unblock isdn <0-8175>",
|
||||
PERF_UBLK "Perform unblocking of ISDN port\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;
|
||||
}
|
||||
|
||||
v5x_le_mgmt_port_unblock(v5up);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(block_isdn_port, block_isdn_port_cmd,
|
||||
"block isdn <0-8175>",
|
||||
PERF_BLK "Perform blocking of ISDN port\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;
|
||||
}
|
||||
|
||||
v5x_le_mgmt_port_block(v5up);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* configure
|
||||
*/
|
||||
|
@ -381,7 +569,7 @@ struct vty_app_info vty_info = {
|
|||
};
|
||||
|
||||
DEFUN(cfg_interface, cfg_interface_cmd,
|
||||
"interface (v5.1|v5.2)",
|
||||
"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;
|
||||
|
@ -390,8 +578,16 @@ DEFUN(cfg_interface, cfg_interface_cmd,
|
|||
if (!llist_empty(&v5i->interfaces))
|
||||
v5if = llist_first_entry(&v5i->interfaces, struct v5x_interface, list);
|
||||
|
||||
if (argc < 1) {
|
||||
if (!v5if) {
|
||||
vty_out(vty, "%%No interface created, Add v5.1 or v5.2 after this command.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
dialect = v5if->dialect;
|
||||
} else {
|
||||
if (!strcasecmp(argv[0], "v5.2"))
|
||||
dialect = V5X_DIALECT_V52;
|
||||
}
|
||||
|
||||
if (!v5if) {
|
||||
v5if = v5x_interface_alloc(v5i, dialect);
|
||||
|
@ -424,6 +620,86 @@ DEFUN(cfg_no_interface, cfg_no_interface_cmd,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_auto_restart, cfg_auto_restart_cmd,
|
||||
"auto-restart",
|
||||
"Automatically restart interface in case of failure")
|
||||
{
|
||||
struct v5x_interface *v5if = vty->index;
|
||||
|
||||
v5if->mgmt->auto_restart = true;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_no_auto_restart, cfg_no_auto_restart_cmd,
|
||||
"no auto-restart",
|
||||
NO_STR "Automatically restart interface in case of failure")
|
||||
{
|
||||
struct v5x_interface *v5if = vty->index;
|
||||
|
||||
v5if->mgmt->auto_restart = false;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_establish, cfg_establish_cmd,
|
||||
"establish",
|
||||
"Actively establish and re-establish data link layer")
|
||||
{
|
||||
struct v5x_interface *v5if = vty->index;
|
||||
|
||||
v5if->mgmt->do_est = true;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_no_establish, cfg_no_establish_cmd,
|
||||
"no establish",
|
||||
NO_STR "Let the remote side establish and re-establish data link layer")
|
||||
{
|
||||
struct v5x_interface *v5if = vty->index;
|
||||
|
||||
v5if->mgmt->do_est = false;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_alignment, cfg_alignment_cmd,
|
||||
"alignment",
|
||||
"Actively trigger alignment of user ports on startup")
|
||||
{
|
||||
struct v5x_interface *v5if = vty->index;
|
||||
|
||||
v5if->mgmt->do_align = true;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_no_alignment, cfg_no_alignment_cmd,
|
||||
"no alignment",
|
||||
NO_STR "Let the remote side do the alignment of user ports on startup")
|
||||
{
|
||||
struct v5x_interface *v5if = vty->index;
|
||||
|
||||
v5if->mgmt->do_align = false;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_accelerated, cfg_accelerated_cmd,
|
||||
"accelerated-alignment",
|
||||
"Use accelerated alignment to block/unblock user ports")
|
||||
{
|
||||
struct v5x_interface *v5if = vty->index;
|
||||
|
||||
v5if->mgmt->acc_align = true;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_no_accelerated, cfg_no_accelerated_cmd,
|
||||
"no accelerated-alignment",
|
||||
NO_STR "Use individual alignment to block/unblock user ports")
|
||||
{
|
||||
struct v5x_interface *v5if = vty->index;
|
||||
|
||||
v5if->mgmt->acc_align = false;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_interface_id, cfg_interface_id_cmd,
|
||||
"id <0-16777215>",
|
||||
"Set interface ID\n" "Interface ID")
|
||||
|
@ -781,6 +1057,9 @@ static int config_write_interface_v51(struct vty *vty)
|
|||
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, " %sauto-restart%s", (v5if->mgmt->auto_restart) ? "" : "no ", VTY_NEWLINE);
|
||||
vty_out(vty, " %sestablish%s", (v5if->mgmt->do_est) ? "" : "no ", VTY_NEWLINE);
|
||||
vty_out(vty, " %salignment%s", (v5if->mgmt->do_align) ? "" : "no ", 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);
|
||||
|
@ -804,6 +1083,10 @@ static int config_write_interface_v52(struct vty *vty)
|
|||
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, " %sauto-restart%s", (v5if->mgmt->auto_restart) ? "" : "no ", VTY_NEWLINE);
|
||||
vty_out(vty, " %sestablish%s", (v5if->mgmt->do_est) ? "" : "no ", VTY_NEWLINE);
|
||||
vty_out(vty, " %salignment%s", (v5if->mgmt->do_align) ? "" : "no ", VTY_NEWLINE);
|
||||
vty_out(vty, " %saccelerated-alignment%s", (v5if->mgmt->acc_align) ? "" : "no ", 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);
|
||||
|
@ -838,14 +1121,26 @@ int v5le_vty_init(void)
|
|||
install_element_ve(&show_port_cmd);
|
||||
install_element_ve(&show_port_pstn_cmd);
|
||||
install_element_ve(&show_port_isdn_cmd);
|
||||
install_element(ENABLE_NODE, &system_restart_cmd);
|
||||
install_element(ENABLE_NODE, &pstn_restart_cmd);
|
||||
install_element(ENABLE_NODE, &align_ports_cmd);
|
||||
install_element(ENABLE_NODE, &switchover_cmd);
|
||||
install_element(ENABLE_NODE, &unblock_link_cmd);
|
||||
install_element(ENABLE_NODE, &block_link_cmd);
|
||||
install_element(ENABLE_NODE, &unblock_pstn_port_cmd);
|
||||
install_element(ENABLE_NODE, &block_pstn_port_cmd);
|
||||
install_element(ENABLE_NODE, &unblock_isdn_port_cmd);
|
||||
install_element(ENABLE_NODE, &block_isdn_port_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_auto_restart_cmd);
|
||||
install_element(INTERFACE_NODE_V51, &cfg_no_auto_restart_cmd);
|
||||
install_element(INTERFACE_NODE_V51, &cfg_establish_cmd);
|
||||
install_element(INTERFACE_NODE_V51, &cfg_no_establish_cmd);
|
||||
install_element(INTERFACE_NODE_V51, &cfg_alignment_cmd);
|
||||
install_element(INTERFACE_NODE_V51, &cfg_no_alignment_cmd);
|
||||
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);
|
||||
|
@ -855,6 +1150,14 @@ int v5le_vty_init(void)
|
|||
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_auto_restart_cmd);
|
||||
install_element(INTERFACE_NODE_V52, &cfg_no_auto_restart_cmd);
|
||||
install_element(INTERFACE_NODE_V52, &cfg_establish_cmd);
|
||||
install_element(INTERFACE_NODE_V52, &cfg_no_establish_cmd);
|
||||
install_element(INTERFACE_NODE_V52, &cfg_alignment_cmd);
|
||||
install_element(INTERFACE_NODE_V52, &cfg_no_alignment_cmd);
|
||||
install_element(INTERFACE_NODE_V52, &cfg_accelerated_cmd);
|
||||
install_element(INTERFACE_NODE_V52, &cfg_no_accelerated_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);
|
||||
|
|
|
@ -243,6 +243,10 @@ struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dia
|
|||
goto error;
|
||||
}
|
||||
|
||||
v5if->mgmt = v5x_le_mgmt_create(v5if);
|
||||
if (!v5if->mgmt)
|
||||
goto error;
|
||||
|
||||
v5if->control.ctrl = v5x_le_ctrl_create(V5X_CTRL_TYPE_COMMON, v5if, v5if, 0);
|
||||
if (!v5if->control.ctrl)
|
||||
goto error;
|
||||
|
@ -297,6 +301,9 @@ void v5x_interface_free(struct v5x_interface *v5if) {
|
|||
OSMO_ASSERT(rc == 0);
|
||||
}
|
||||
|
||||
if (v5if->mgmt)
|
||||
v5x_le_mgmt_destroy(v5if->mgmt);
|
||||
|
||||
if (v5if->control.ctrl)
|
||||
v5x_le_ctrl_destroy(v5if->control.ctrl);
|
||||
if (v5if->control.li)
|
||||
|
|
|
@ -132,6 +132,13 @@ enum v5x_mgmt_prim {
|
|||
MDU_Protection_reset_SN_ack,
|
||||
MDU_Protection_reset_SN_error_ind,
|
||||
MDU_Protection_protocol_error_ind,
|
||||
/* Figure 11/G.964 */
|
||||
MDL_ESTABLISH_req,
|
||||
MDL_ESTABLISH_cnf,
|
||||
MDL_ESTABLISH_ind,
|
||||
MDL_RELEASE_ind,
|
||||
MDL_ERROR_ind,
|
||||
MDL_LAYER_1_FAILURE_ind,
|
||||
};
|
||||
|
||||
struct osmo_fsm_inst;
|
||||
|
@ -202,6 +209,8 @@ struct v5x_interface {
|
|||
bool use_capability; /* use bearer transfer capability */
|
||||
uint8_t capability; /* bearer transfer capability */
|
||||
|
||||
struct v5x_mgmt_proto *mgmt; /* management prococol states */
|
||||
|
||||
struct {
|
||||
struct v5x_ctrl_proto *ctrl; /* common control protocol instance */
|
||||
struct lapv5_instance *li; /* Control data link */
|
||||
|
@ -259,6 +268,36 @@ struct v5x_pstn_proto {
|
|||
struct osmo_timer_list timer_Tt; /* extra timer for transmit sequence ack */
|
||||
};
|
||||
|
||||
/* indexes of blocking/unblocking instances */
|
||||
#define UNBLK_ALL_PSTN_ISDN 0
|
||||
#define UNBLK_ALL_PSTN 1
|
||||
#define UNBLK_ALL_ISDN 2
|
||||
#define BLK_ALL_PSTN 3
|
||||
#define BLK_ALL_ISDN 4
|
||||
|
||||
struct v5x_mgmt_proto {
|
||||
struct v5x_interface *interface; /* back-pointer to instance we're part of */
|
||||
bool auto_restart; /* restart automatically after TC8/TC9 timeout */
|
||||
bool pstn_rs_pending; /* pending restart flag */
|
||||
bool do_est; /* actively establish datalinks */
|
||||
bool do_align; /* actively perform alignment */
|
||||
bool acc_align; /* use accellerated alignment */
|
||||
struct osmo_fsm_inst *system_fi; /* system startup FSM */
|
||||
struct osmo_fsm_inst *pstn_dl_fi; /* PSTN DL startup FSM */
|
||||
struct osmo_fsm_inst *pstn_rs_fi; /* PSTN restart FSM */
|
||||
struct osmo_fsm_inst *unblk_all_fi[5]; /* unblock/block all FSM (5 instances) */
|
||||
struct osmo_timer_list timer_system; /* delayed start, so sockets can connect first */
|
||||
struct osmo_timer_list timer_tr1; /* see Table C.1/G.965 */
|
||||
struct osmo_timer_list timer_tr2;
|
||||
struct osmo_timer_list timer_tc1;
|
||||
struct osmo_timer_list timer_tc2;
|
||||
struct osmo_timer_list timer_tc3;
|
||||
struct osmo_timer_list timer_tc7;
|
||||
struct osmo_timer_list timer_tc8;
|
||||
struct osmo_timer_list timer_tc9;
|
||||
struct osmo_timer_list timer_tv1;
|
||||
};
|
||||
|
||||
#define EC_BUFFER 1024
|
||||
#define EC_TAPS 256
|
||||
|
||||
|
@ -290,7 +329,6 @@ struct v5x_user_port {
|
|||
struct v5x_pstn_proto *proto;
|
||||
} pstn;
|
||||
ph_socket_t ph_socket; /* unix socket to connect port to */
|
||||
bool blocking_enabled; /* we may only send blocking updates, if true */
|
||||
bool le_unblocked; /* if port is not blocked by LE */
|
||||
bool an_unblocked; /* if port is not blocked by AN */
|
||||
int echo_configured; /* line echo canceler is configured */
|
||||
|
|
|
@ -698,5 +698,12 @@ void v5x_le_ctrl_start(struct v5x_ctrl_proto *ctrl)
|
|||
}
|
||||
void v5x_le_ctrl_stop(struct v5x_ctrl_proto *ctrl)
|
||||
{
|
||||
if (ctrl->fi->state == V5X_CTRL_ST_OUT_OF_SERVICE)
|
||||
return;
|
||||
osmo_fsm_inst_dispatch(ctrl->fi, V5X_CTRL_EV_MDU_STOP_TRAFFIC, NULL);
|
||||
}
|
||||
|
||||
bool v5x_le_ctrl_is_in_service(struct v5x_ctrl_proto *ctrl)
|
||||
{
|
||||
return (ctrl->fi->state >= V5X_CTRL_ST_IN_SERVICE);
|
||||
}
|
||||
|
|
|
@ -10,3 +10,4 @@ int v5x_le_ctrl_port_snd(struct v5x_user_port *v5up, enum v5x_ctrl_func_el cfe);
|
|||
int v52_le_ctrl_link_snd(struct v5x_link *v5l, enum v52_link_ctrl_func lcf);
|
||||
void v5x_le_ctrl_start(struct v5x_ctrl_proto *ctrl);
|
||||
void v5x_le_ctrl_stop(struct v5x_ctrl_proto *ctrl);
|
||||
bool v5x_le_ctrl_is_in_service(struct v5x_ctrl_proto *ctrl);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,21 @@
|
|||
|
||||
const char *v5x_le_system_fsm_state_name(struct osmo_fsm_inst *fi);
|
||||
const char *v5x_le_pstn_dl_fsm_state_name(struct osmo_fsm_inst *fi);
|
||||
const char *v5x_le_pstn_rs_fsm_state_name(struct osmo_fsm_inst *fi);
|
||||
const char *v5x_le_unblk_all_fsm_state_name(struct osmo_fsm_inst *fi);
|
||||
void v5x_le_mgmt_init(void);
|
||||
|
||||
struct v5x_mgmt_proto *v5x_le_mgmt_create(struct v5x_interface *v5if);
|
||||
void v5x_le_mgmt_destroy(struct v5x_mgmt_proto *mgmt);
|
||||
void v5x_le_mgmt_start_delay(struct v5x_interface *v5if, int delay);
|
||||
int v5x_le_mgmt_start(struct v5x_interface *v5if);
|
||||
int v5x_le_pstn_restart(struct v5x_interface *v5if);
|
||||
int v5x_le_align_ports(struct v5x_interface *v5if, int accelerated);
|
||||
void v5x_le_mdl_rcv(struct v5x_interface *v5if, struct v5x_link *v5l, enum v5x_mgmt_prim prim, uint16_t dladdr);
|
||||
void v5x_le_common_ctrl_rcv(struct v5x_interface *v5if, uint8_t cfi, uint8_t variant, uint8_t rej_cause,
|
||||
uint32_t interface_id);
|
||||
void v5x_le_provisioning_start(struct v5x_interface *v5if);
|
||||
void v5x_le_pstn_restart(struct v5x_interface *v5if);
|
||||
void v5x_le_mgmt_port_unblock(struct v5x_user_port *v5up);
|
||||
void v5x_le_mgmt_port_block(struct v5x_user_port *v5up);
|
||||
void v5x_le_nat_ph_rcv(struct v5x_user_port *v5up, uint8_t prim, uint8_t *data, int length);
|
||||
void v5x_le_port_mph_rcv(struct v5x_user_port *v5up, enum v5x_mph_prim prim, uint8_t perf_grading);
|
||||
void v5x_le_nat_fe_rcv(struct v5x_user_port *v5up, struct msgb *msg);
|
||||
|
|
|
@ -763,7 +763,7 @@ void v5x_le_port_init(void)
|
|||
LOGP(DV5PORT, LOGL_NOTICE, "Using V5x port control protocol\n");
|
||||
}
|
||||
|
||||
bool v52_le_port_pstn_is_operational(struct osmo_fsm_inst *fi)
|
||||
bool v5x_le_port_pstn_is_operational(struct osmo_fsm_inst *fi)
|
||||
{
|
||||
return (fi->state >= V5X_LE_UP_P_S_LE20_OPERATIONAL);
|
||||
}
|
||||
|
|
|
@ -403,51 +403,13 @@ int v5x_dl_rcv(struct osmo_dlsap_prim *odp, uint16_t dladdr, void *rx_cbdata)
|
|||
LOGP(DV5, LOGL_DEBUG, "DL-EST indication received (ldaddr=%d)\n", dladdr);
|
||||
switch (dladdr) {
|
||||
case V5X_DLADDR_CTRL:
|
||||
if (v5if->control.established)
|
||||
break;
|
||||
v5if->control.established = true;
|
||||
/* start ctrl protocols */
|
||||
v5x_le_ctrl_start(v5if->control.ctrl);
|
||||
llist_for_each_entry(v5up, &v5if->user_ports, list)
|
||||
v5x_le_ctrl_start(v5up->ctrl);
|
||||
/* start provisioning */
|
||||
v5x_le_provisioning_start(v5if);
|
||||
v5l = NULL;
|
||||
break;
|
||||
case V5X_DLADDR_PSTN:
|
||||
if (v5if->pstn.established)
|
||||
break;
|
||||
v5if->pstn.established = true;
|
||||
v5l = NULL;
|
||||
break;
|
||||
case V52_DLADDR_LCP:
|
||||
if (v5if->lcp.established)
|
||||
break;
|
||||
v5if->lcp.established = true;
|
||||
/* start ctrl protocols */
|
||||
llist_for_each_entry(v5l, &v5if->links, list)
|
||||
v5x_le_ctrl_start(v5l->ctrl);
|
||||
v5l = NULL;
|
||||
break;
|
||||
case V52_DLADDR_BCC:
|
||||
if (v5if->bcc.established)
|
||||
break;
|
||||
v5if->bcc.established = true;
|
||||
v5l = NULL;
|
||||
v5x_le_mdl_rcv(v5if, NULL, MDL_ESTABLISH_ind, dladdr);
|
||||
break;
|
||||
case V52_DLADDR_PROTECTION:
|
||||
v5if = v5l->interface;
|
||||
if (v5l == v5if->primary_link) {
|
||||
if (v5if->protection.established[0])
|
||||
break;
|
||||
v5if->protection.established[0] = true;
|
||||
}
|
||||
if (v5l == v5if->secondary_link) {
|
||||
if (v5if->protection.established[1])
|
||||
break;
|
||||
v5if->protection.established[1] = true;
|
||||
}
|
||||
v5if = NULL;
|
||||
v5x_le_mdl_rcv(v5l->interface, v5l, MDL_ESTABLISH_ind, dladdr);
|
||||
break;
|
||||
}
|
||||
goto out;
|
||||
|
@ -455,35 +417,13 @@ int v5x_dl_rcv(struct osmo_dlsap_prim *odp, uint16_t dladdr, void *rx_cbdata)
|
|||
LOGP(DV5, LOGL_DEBUG, "DL-REL indication received (ldaddr=%d)\n", dladdr);
|
||||
switch (dladdr) {
|
||||
case V5X_DLADDR_CTRL:
|
||||
v5if->control.established = false;
|
||||
/* stop ctrl protocols */
|
||||
v5x_le_ctrl_stop(v5if->control.ctrl);
|
||||
llist_for_each_entry(v5up, &v5if->user_ports, list)
|
||||
v5x_le_ctrl_stop(v5up->ctrl);
|
||||
v5l = NULL;
|
||||
break;
|
||||
case V5X_DLADDR_PSTN:
|
||||
v5if->pstn.established = false;
|
||||
v5l = NULL;
|
||||
break;
|
||||
case V52_DLADDR_LCP:
|
||||
v5if->lcp.established = false;
|
||||
/* stop ctrl protocols */
|
||||
llist_for_each_entry(v5l, &v5if->links, list)
|
||||
v5x_le_ctrl_stop(v5l->ctrl);
|
||||
v5l = NULL;
|
||||
break;
|
||||
case V52_DLADDR_BCC:
|
||||
v5if->bcc.established = false;
|
||||
v5l = NULL;
|
||||
v5x_le_mdl_rcv(v5if, NULL, MDL_RELEASE_ind, dladdr);
|
||||
break;
|
||||
case V52_DLADDR_PROTECTION:
|
||||
v5if = v5l->interface;
|
||||
if (v5l == v5if->primary_link)
|
||||
v5if->protection.established[0] = false;
|
||||
if (v5l == v5if->secondary_link)
|
||||
v5if->protection.established[1] = false;
|
||||
v5if = NULL;
|
||||
v5x_le_mdl_rcv(v5l->interface, v5l, MDL_RELEASE_ind, dladdr);
|
||||
break;
|
||||
}
|
||||
goto out;
|
||||
|
|
Loading…
Reference in New Issue