[svn-commits] rmudgett: branch 1.4 r2111 - in /branches/1.4: pri_internal.h q921.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Nov 10 18:30:37 CST 2010


Author: rmudgett
Date: Wed Nov 10 18:30:33 2010
New Revision: 2111

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=2111
Log:
SABME flood on backup D-channel in NFAS configuration.

Made delay restarting the PTP layer 2 link by the T200 time instead of
immediately.  Q.921 does not specify any particular time to restart the
layer 2 link.  Q.921 leaves it up to the upper layers to decide when or if
another attempt to bring layer 2 up is made.  Earlier versions of libpri
used the T200 time to restart the link.

This is a reimplementaion of -r1878.

(closes issue #18255)
Reported by: bklang

JIRA SWP-2508

Modified:
    branches/1.4/pri_internal.h
    branches/1.4/q921.c

Modified: branches/1.4/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_internal.h?view=diff&rev=2111&r1=2110&r2=2111
==============================================================================
--- branches/1.4/pri_internal.h (original)
+++ branches/1.4/pri_internal.h Wed Nov 10 18:30:33 2010
@@ -119,6 +119,8 @@
 	int t201_timer;
 	/*! Number of times T201 has expired. */
 	int t201_expirycnt;
+	/*! PTP layer 2 restart delay timer */
+	int restart_timer;
 	
 	int cref;			/* Next call reference value */
 

Modified: branches/1.4/q921.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/q921.c?view=diff&rev=2111&r1=2110&r2=2111
==============================================================================
--- branches/1.4/q921.c (original)
+++ branches/1.4/q921.c Wed Nov 10 18:30:33 2010
@@ -58,7 +58,6 @@
 static void q921_mdl_error(struct q921_link *link, char error);
 static void q921_mdl_remove(struct q921_link *link);
 static void q921_mdl_destroy(struct q921_link *link);
-static void q921_restart_ptp_link_if_needed(struct q921_link *link);
 
 /*!
  * \internal
@@ -549,6 +548,72 @@
 	}
 }
 
+static void restart_timer_expire(void *vctrl)
+{
+	struct pri *ctrl = vctrl;
+	struct q921_link *link;
+
+	if (ctrl->debug & PRI_DEBUG_Q921_STATE) {
+		pri_message(ctrl, "Kick starting layer 2\n");
+	}
+
+	ctrl->restart_timer = 0;
+	link = &ctrl->link;
+
+	switch (link->state) {
+	case Q921_TEI_ASSIGNED:
+		/* Try to bring layer 2 up. */
+		q921_discard_iqueue(link);
+		q921_establish_data_link(link);
+		link->l3_initiated = 1;
+		q921_setstate(link, Q921_AWAITING_ESTABLISHMENT);
+		break;
+	default:
+		/* Looks like someone forgot to stop the restart timer. */
+		pri_error(ctrl, "Layer 2 restart delay timer expired in state %d(%s)\n",
+			link->state, q921_state2str(link->state));
+		break;
+	}
+}
+
+static void restart_timer_stop(struct pri *ctrl)
+{
+	pri_schedule_del(ctrl, ctrl->restart_timer);
+	ctrl->restart_timer = 0;
+}
+
+static void restart_timer_start(struct pri *ctrl)
+{
+	if (ctrl->debug & PRI_DEBUG_Q921_DUMP) {
+		pri_message(ctrl, "-- Starting layer 2 restart delay timer\n");
+	}
+	pri_schedule_del(ctrl, ctrl->restart_timer);
+	ctrl->restart_timer =
+		pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T200], restart_timer_expire, ctrl);
+}
+
+static pri_event *q921_ptp_delay_restart(struct pri *ctrl)
+{
+	pri_event *ev;
+
+	if (PTP_MODE(ctrl)) {
+		/*
+		 * This is where we act a bit like L3 instead of L2, since we've
+		 * got an L3 that depends on us keeping L2 automatically alive
+		 * and happy for PTP links.
+		 */
+		restart_timer_start(ctrl);
+
+		/* Notify the upper layer that layer 2 is down. */
+		ctrl->schedev = 1;
+		ctrl->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
+		ev = &ctrl->ev;
+	} else {
+		ev = NULL;
+	}
+	return ev;
+}
+
 /* This is the equivalent of the I-Frame queued up path in Figure B.7 in MULTI_FRAME_ESTABLISHED */
 static int q921_send_queued_iframes(struct q921_link *link)
 {
@@ -765,6 +830,7 @@
 			q921_setstate(link, Q921_TEI_ASSIGNED);
 			/* DL-RELEASE indication */
 			q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_IND);
+			q921_ptp_delay_restart(ctrl);
 		}
 		break;
 	case Q921_AWAITING_RELEASE:
@@ -777,6 +843,7 @@
 			/* DL-RELEASE confirm */
 			q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_CONFIRM);
 			q921_setstate(link, Q921_TEI_ASSIGNED);
+			q921_ptp_delay_restart(ctrl);
 		}
 		break;
 	default:
@@ -876,6 +943,7 @@
 	switch (link->state) {
 	case Q921_TEI_ASSIGNED:
 		/* If we aren't in a state compatiable with DL-DATA requests, start getting us there here */
+		restart_timer_stop(ctrl);
 		q921_establish_data_link(link);
 		link->l3_initiated = 1;
 		q921_setstate(link, Q921_AWAITING_ESTABLISHMENT);
@@ -1598,6 +1666,7 @@
 		}
 		break;
 	case Q921_TEI_ASSIGNED:
+		restart_timer_stop(ctrl);
 		q921_send_ua(link, h->u.p_f);
 		q921_clear_exception_conditions(link);
 		link->v_s = link->v_a = link->v_r = 0;
@@ -1658,7 +1727,7 @@
 		if (link->state == Q921_MULTI_FRAME_ESTABLISHED)
 			stop_t203(link);
 		q921_setstate(link, Q921_TEI_ASSIGNED);
-		q921_restart_ptp_link_if_needed(link);
+		res = q921_ptp_delay_restart(ctrl);
 		break;
 	default:
 		pri_error(ctrl, "Don't know what to do with DISC in state %d(%s)\n",
@@ -1691,6 +1760,7 @@
 
 	switch (link->state) {
 	case Q921_TEI_ASSIGNED:
+		restart_timer_stop(ctrl);
 		/* XXX: deviation! Since we don't have a UI queue, we just discard our I-queue */
 		q921_discard_iqueue(link);
 		q921_setstate(link, Q921_TEI_UNASSIGNED);
@@ -1835,29 +1905,14 @@
 
 	ctrl = link->ctrl;
 
-	/* This is where we act a bit like L3 instead of L2, since we've got an L3 that depends on us
-	 * keeping L2 automatically alive and happy for point to point links */
 	switch (error) {
-	case 'Z':
-		/* This is a special MDL error that actually isn't a spec error, but just so we
-		 * have an asynchronous context from the state machine to kick a PTP link back
-		 * up after being requested to drop politely (using DISC or DM) */
-	case 'G':
-		/* We pick it back up and put it back together for this case */
-		q921_discard_iqueue(link);
-		q921_establish_data_link(link);
-		q921_setstate(link, Q921_AWAITING_ESTABLISHMENT);
-		link->l3_initiated = 1;
-
-		ctrl->schedev = 1;
-		ctrl->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
-		break;
 	case 'A':
 	case 'B':
 	case 'C':
 	case 'D':
 	case 'E':
 	case 'F':
+	case 'G':
 	case 'H':
 	case 'I':
 	case 'J':
@@ -1866,16 +1921,6 @@
 	default:
 		pri_error(ctrl, "PTP MDL can't handle error of type %c\n", error);
 		break;
-	}
-}
-
-static void q921_restart_ptp_link_if_needed(struct q921_link *link)
-{
-	struct pri *ctrl;
-
-	ctrl = link->ctrl;
-	if (PTP_MODE(ctrl)) {
-		q921_mdl_error(&ctrl->link, 'Z');
 	}
 }
 
@@ -1995,14 +2040,6 @@
 		pri_error(ctrl, "TEI=%d MDL-ERROR (K): FRMR in state %d(%s)\n",
 			link->tei, link->state, q921_state2str(link->state));
 		break;
-	case 'Z':
-		if (is_debug_q921_state) {
-			/* Fake MDL-ERROR to kick start PTP L2 link back up. */
-			pri_message(ctrl,
-				"TEI=%d MDL-ERROR (Z): Kick starting L2 link in state %d(%s)\n",
-				link->tei, link->state, q921_state2str(link->state));
-		}
-		break;
 	default:
 		pri_message(ctrl, "TEI=%d MDL-ERROR (%c): in state %d(%s)\n",
 			link->tei, error, link->state, q921_state2str(link->state));
@@ -2089,6 +2126,7 @@
 			q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_CONFIRM);
 			stop_t200(link);
 			q921_setstate(link, Q921_TEI_ASSIGNED);
+			res = q921_ptp_delay_restart(ctrl);
 		}
 		break;
 	default:
@@ -2520,6 +2558,7 @@
 		if (h->u.p_f)
 			break;
 		/* else */
+		restart_timer_stop(ctrl);
 		q921_establish_data_link(link);
 		link->l3_initiated = 1;
 		q921_setstate(link, Q921_AWAITING_ESTABLISHMENT);
@@ -2533,7 +2572,7 @@
 		q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_IND);
 		stop_t200(link);
 		q921_setstate(link, Q921_TEI_ASSIGNED);
-		q921_restart_ptp_link_if_needed(link);
+		res = q921_ptp_delay_restart(ctrl);
 		break;
 	case Q921_AWAITING_RELEASE:
 		if (!h->u.p_f)
@@ -2542,6 +2581,7 @@
 		q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_CONFIRM);
 		stop_t200(link);
 		q921_setstate(link, Q921_TEI_ASSIGNED);
+		res = q921_ptp_delay_restart(ctrl);
 		break;
 	case Q921_MULTI_FRAME_ESTABLISHED:
 		if (h->u.p_f) {




More information about the svn-commits mailing list