[svn-commits] rmudgett: mISDNuser/trunk r112 - /mISDNuser/trunk/i4lnet/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed May 13 09:59:43 CDT 2009


Author: rmudgett
Date: Wed May 13 09:59:39 2009
New Revision: 112

URL: http://svn.asterisk.org/svn-view/thirdparty?view=rev&rev=112
Log:
Add TEI recovery as described in Q.921 section 5.3 when all TEI's are exhausted.

When all possible automatic TEI values are assigned once, a subsequent
TEI request by a TE never succeeds and not even a reply "ID denied" is
sent.  Telephony is no longer possible on this ISDN NT port.

The problem is that the TEI manager does not implement TEI recovery.

This patch adds a simple but slightly inefficient way to recover unused TEI's.
First, we reply with ID denied message.
Second, all L2 entities with an assigned TEI will start a TEI check sequence
of their own.  They all send an identity check request with their specific
TEI value.  This way when all TEIs are exhausted there will be 63 id check
messages sent on the S0 bus.
All TEI's which do not get a response will have their TEI removed and the
corresponding L2 entity will be destroyed.  (Otherwise the L2 entity would
eat up memory, because new TEI requests will always create new L2 entities.)

Patches:
    tei-check1.patch file uploaded by customer (with minor cosmetic changes).

JIRA ABE-1865

Modified:
    mISDNuser/trunk/i4lnet/net_l2.c
    mISDNuser/trunk/i4lnet/net_l2.h
    mISDNuser/trunk/i4lnet/tei.c

Modified: mISDNuser/trunk/i4lnet/net_l2.c
URL: http://svn.asterisk.org/svn-view/thirdparty/mISDNuser/trunk/i4lnet/net_l2.c?view=diff&rev=112&r1=111&r2=112
==============================================================================
--- mISDNuser/trunk/i4lnet/net_l2.c (original)
+++ mISDNuser/trunk/i4lnet/net_l2.c Wed May 13 09:59:39 2009
@@ -1975,7 +1975,7 @@
 	va_end(args);
 }
 
-static void
+void
 release_l2(layer2_t *l2)
 {
 	dprint(DBGM_L2, l2->nst->cardnr, "%s: sapi(%d) tei(%d) state(%d)\n", __FUNCTION__,

Modified: mISDNuser/trunk/i4lnet/net_l2.h
URL: http://svn.asterisk.org/svn-view/thirdparty/mISDNuser/trunk/i4lnet/net_l2.h?view=diff&rev=112&r1=111&r2=112
==============================================================================
--- mISDNuser/trunk/i4lnet/net_l2.h (original)
+++ mISDNuser/trunk/i4lnet/net_l2.h Wed May 13 09:59:39 2009
@@ -61,6 +61,7 @@
 
 /* from mISDN_l2.c */
 extern int	tei0_active(layer2_t *l2);
+extern void	release_l2(layer2_t *l2);
 extern layer2_t	*new_dl2(net_stack_t *nst, int tei);
 extern int	tei_l2(layer2_t *l2, msg_t *msg);
 extern int	Isdnl2Init(net_stack_t *nst);

Modified: mISDNuser/trunk/i4lnet/tei.c
URL: http://svn.asterisk.org/svn-view/thirdparty/mISDNuser/trunk/i4lnet/tei.c?view=diff&rev=112&r1=111&r2=112
==============================================================================
--- mISDNuser/trunk/i4lnet/tei.c (original)
+++ mISDNuser/trunk/i4lnet/tei.c Wed May 13 09:59:39 2009
@@ -88,6 +88,19 @@
 	return(l2);
 }
 
+static void
+check_all_tei(net_stack_t *nst)
+{
+	layer2_t *l2;
+
+	l2 = nst->layer2;
+	while (l2) {
+		if (l2->tei >= 64 && l2->tei < 127)
+			FsmEvent(&l2->tm->tei_m, EV_VERIFY, &l2->tei);
+		l2 = l2->next;
+	}
+}
+
 unsigned int
 random_ri(void)
 {
@@ -216,6 +229,9 @@
 			tm->l2->tei);
 	put_tei_msg(tm, ID_REMOVE, 0, tm->val);
 	FsmChangeState(fi, ST_TEI_NOP);
+	if (tm->l2->tei >= 64 && tm->l2->tei < 127)
+		/* maybe an EV_MDL_REMOVE must be sent to l2 before releasing it */
+		release_l2(tm->l2);
 }
 
 static void
@@ -235,7 +251,8 @@
 		if (tm->ri == -1) {
 			tm->tei_m.printdebug(fi, "tei %d check no response",
 				tm->l2->tei);
-			// remove tei
+			/* remove tei and release l2 to recover this TEI */
+			FsmEvent(&tm->tei_m, EV_REMOVE, &tm->l2->tei);
 		} else
 			tm->tei_m.printdebug(fi, "tei %d check ok",
 				tm->l2->tei);
@@ -297,6 +314,7 @@
 release_tei(teimgr_t *tm)
 {
 	FsmDelTimer(&tm->t201, 1);
+	FsmRemoveTimer(&tm->t201);
 	free(tm);
 }
 
@@ -363,10 +381,9 @@
 		wprint("tei handler wrong entity id %x\n", *dp);
 		return(-EINVAL);
 	} else {
-		mt = *(dp+2);
 		ri = ((unsigned int) *dp++ << 8);
 		ri += *dp++;
-		dp++;
+		mt = *dp++;
 		ai = (unsigned int) *dp++;
 		ai >>= 1;
 		dprint(DBGM_TEI, -1, "tei handler mt %x ri(%x) ai(%d)\n",
@@ -380,7 +397,19 @@
 			l2 = new_tei_req(nst);
 			if (!l2) {
 				wprint("%s: no free tei\n", __FUNCTION__);
-				return(-EBUSY);
+				l2 = find_tei(nst, 127);
+				if (!l2) {
+					wprint("%s: no 127 manager\n", __FUNCTION__);
+					return(-EBUSY);
+				}
+				put_tei_msg(l2->tm, ID_DENIED, ri, 127);
+				/*
+				 * Start a TEI check for all l2's that have one.  This will
+				 * eventually remove a TEI and the next request will succeed.
+				 */
+				check_all_tei(nst);
+				free_msg(msg);
+				return(0);
 			}
 			l2->tm->ri = ri;
 			put_tei_msg(l2->tm, ID_ASSIGNED, ri, l2->tei);




More information about the svn-commits mailing list