[thirdparty-commits] rmudgett: mISDN/trunk r193 - /mISDN/trunk/drivers/isdn/hardware/mISDN/

SVN commits to the Digium third-party software repository thirdparty-commits at lists.digium.com
Fri Aug 10 15:42:59 CDT 2012


Author: rmudgett
Date: Fri Aug 10 15:42:55 2012
New Revision: 193

URL: http://svnview.digium.com/svn/thirdparty?view=rev&rev=193
Log:
Some mISDN fixes.

* Fixed T305 timer not started when another state's timeout transitions to
the U11 state.

* Made l3dss1_setup_req() always transition to state U1.  We don't care if
sending the SETUP message failed.  We need to be in state U1 to clean up
properly.

* Removes state change code from SendMsg().  If SendMsg() failed you don't
know if the state was changed.  It also should never have been in that
function in the first place.

* Fixed type mismatch in state comparison for valid HOLD states.

* Fixed call ref selection to try to avoid assigning a call ref that is
already in use.  Also removed sending the RELEASE COMPLETE when a SETUP
does not get any response because the call ref may already be in use by
another call.

* Fixed a l3m_debug() message erroneously truncating the call ref.

* Some indentation fixes.

The jira_abe_2869_misdn_fixes.patch started with the t305.patch file from
AST-914.

(issue ABE-2869)
Patches:
      jira_abe_2869_misdn_fixes.patch (license #5621) patch uploaded by rmudgett

Modified:
    mISDN/trunk/drivers/isdn/hardware/mISDN/l3_udss1.c
    mISDN/trunk/drivers/isdn/hardware/mISDN/layer3.c

Modified: mISDN/trunk/drivers/isdn/hardware/mISDN/l3_udss1.c
URL: http://svnview.digium.com/svn/thirdparty/mISDN/trunk/drivers/isdn/hardware/mISDN/l3_udss1.c?view=diff&rev=193&r1=192&r2=193
==============================================================================
--- mISDN/trunk/drivers/isdn/hardware/mISDN/l3_udss1.c (original)
+++ mISDN/trunk/drivers/isdn/hardware/mISDN/l3_udss1.c Fri Aug 10 15:42:55 2012
@@ -314,7 +314,8 @@
 	return(skb);
 }
 
-static int SendMsg(l3_process_t *pc, struct sk_buff *skb, int state) {
+static int SendMsg(l3_process_t *pc, struct sk_buff *skb)
+{
 	int		l;
 	int		ret;
 	struct sk_buff	*nskb;
@@ -331,8 +332,6 @@
 	if (l)
 		compose_msg(nskb, qi);
 	kfree_skb(skb);
-	if (state != -1)
-		newl3state(pc, state);
 	if ((ret=l3_msg(pc->l3, DL_DATA | REQUEST, 0, 0, nskb)))
 		kfree_skb(nskb);
 	return(ret);
@@ -749,10 +748,10 @@
 l3dss1_release_req(l3_process_t *pc, u_char pr, void *arg)
 {
 	StopAllL3Timer(pc);
+	newl3state(pc, 19);
 	if (arg) {
-		SendMsg(pc, arg, 19);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, 19);
 		l3dss1_message(pc, MT_RELEASE);
 	}
 	L3AddTimer(&pc->timer, T308, CC_T308_1);
@@ -763,12 +762,11 @@
 {
 	struct sk_buff	*skb = skb_clone(arg, GFP_ATOMIC);
 
-	if (!SendMsg(pc, arg, 1)) {
-		L3DelTimer(&pc->timer);
-		L3AddTimer(&pc->timer, T303, CC_T303);
-		pc->t303skb = skb;
-	} else
-		dev_kfree_skb(skb);
+	newl3state(pc, 1);
+	SendMsg(pc, arg);
+	L3DelTimer(&pc->timer);
+	L3AddTimer(&pc->timer, T303, CC_T303);
+	pc->t303skb = skb;
 }
 
 static void
@@ -779,6 +777,7 @@
 	u_char		*p;
 
 	StopAllL3Timer(pc);
+	newl3state(pc, 11);
 	if (arg) {
 		qi = (Q931_info_t *)skb->data;
 		if (!qi->cause.off) {
@@ -794,9 +793,8 @@
 			p += L3_EXTRA_SIZE + qi->cause.off;
 			pc->cause = (*(p+3) & 0x7f);
 		}
-		SendMsg(pc, arg, 11);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, 11);
 		l3dss1_message_cause(pc, MT_DISCONNECT, CAUSE_NORMALUNSPECIFIED);
 		pc->cause=CAUSE_NORMALUNSPECIFIED;
 	}
@@ -812,10 +810,10 @@
 		l3dss1_disconnect_req(pc, pr, NULL);
 		return;
 	}
+	newl3state(pc, 8);
 	if (arg) {
-		SendMsg(pc, arg, 8);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, 8);
 		l3dss1_message(pc, MT_CONNECT);
 	}
 	L3DelTimer(&pc->timer);
@@ -826,10 +824,10 @@
 l3dss1_release_cmpl_req(l3_process_t *pc, u_char pr, void *arg)
 {
 	StopAllL3Timer(pc);
+	newl3state(pc, 0);
 	if (arg) {
-		SendMsg(pc, arg, 0);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, 0);
 		l3dss1_message(pc, MT_RELEASE_COMPLETE);
 	}
 	mISDN_l3up(pc, CC_RELEASE_COMPLETE | CONFIRM, NULL);
@@ -839,10 +837,10 @@
 static void
 l3dss1_alert_req(l3_process_t *pc, u_char pr, void *arg)
 {
+	newl3state(pc, 7);
 	if (arg) {
-		SendMsg(pc, arg, 7);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, 7);
 		l3dss1_message(pc, MT_ALERTING);
 	}
 	L3DelTimer(&pc->timer);
@@ -851,10 +849,10 @@
 static void
 l3dss1_proceed_req(l3_process_t *pc, u_char pr, void *arg)
 {
+	newl3state(pc, 9);
 	if (arg) {
-		SendMsg(pc, arg, 9);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, 9);
 		l3dss1_message(pc, MT_CALL_PROCEEDING);
 	}
 	L3DelTimer(&pc->timer);
@@ -863,10 +861,10 @@
 static void
 l3dss1_setup_ack_req(l3_process_t *pc, u_char pr, void *arg)
 {
+	newl3state(pc, 25);
 	if (arg) {
-		SendMsg(pc, arg, 25);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, 25);
 		l3dss1_message(pc, MT_SETUP_ACKNOWLEDGE);
 	}
 	L3DelTimer(&pc->timer);
@@ -876,10 +874,10 @@
 static void
 l3dss1_suspend_req(l3_process_t *pc, u_char pr, void *arg)
 {
+	newl3state(pc, 15);
 	if (arg) {
-		SendMsg(pc, arg, 15);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, 15);
 		l3dss1_message(pc, MT_SUSPEND);
 	}
 	L3AddTimer(&pc->timer, T319, CC_T319);
@@ -888,10 +886,10 @@
 static void
 l3dss1_resume_req(l3_process_t *pc, u_char pr, void *arg)
 {
+	newl3state(pc, 17);
 	if (arg) {
-		SendMsg(pc, arg, 17);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, 17);
 		l3dss1_message(pc, MT_RESUME);
 	}
 	L3AddTimer(&pc->timer, T318, CC_T318);
@@ -914,7 +912,7 @@
 	}
 
 	if (arg) {
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	}
 }
 
@@ -922,7 +920,7 @@
 l3dss1_notify_req(l3_process_t *pc, u_char pr, void *arg)
 {
 	if (arg) {
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	}
 }
 
@@ -930,7 +928,7 @@
 l3dss1_progress_req(l3_process_t *pc, u_char pr, void *arg)
 {
 	if (arg) {
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	}
 }
 
@@ -938,7 +936,7 @@
 l3dss1_facility_req(l3_process_t *pc, u_char pr, void *arg)
 {
 	if (arg) {
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	}
 }
 
@@ -946,7 +944,8 @@
 l3dss1_register_req(l3_process_t *pc, u_char pr, void *arg)
 {
 	if (arg) {
-		SendMsg(pc, arg, 31);/* call state: Call Independent Service (U31/N31) */
+		newl3state(pc, 31);/* call state: Call Independent Service (U31/N31) */
+		SendMsg(pc, arg);
 	}
 }
 
@@ -955,7 +954,7 @@
 {
 	pc->callref=0;
 	if (arg) {
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	}
 	pc->callref=-1;
 }
@@ -1117,7 +1116,7 @@
 		newl3state(pc, 19);
 	else
 		newl3state(pc, 12);
-       	if (11 != ret) {
+	if (11 != ret) {
 		if (mISDN_l3up(pc, CC_DISCONNECT | INDICATION, skb))
 			dev_kfree_skb(skb);
 	} else if (!cause) {
@@ -1838,7 +1837,7 @@
 l3dss1_hold_req(l3_process_t *pc, u_char pr, void *arg)
 {
 	if (!test_bit(FLG_PTP, &pc->l3->Flag)) {
-		if ((pc->state & VALID_HOLD_STATES_PTMP) == 0) { /* not a valid HOLD state for PtMP */
+		if ((SBIT(pc->state) & VALID_HOLD_STATES_PTMP) == 0) { /* not a valid HOLD state for PtMP */
 			return;
 		}
 	}
@@ -1851,7 +1850,7 @@
 			return;
 	}
 	if (arg)
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	else
 		l3dss1_message(pc, MT_HOLD);
 	pc->aux_state = AUX_HOLD_REQ;
@@ -1869,7 +1868,7 @@
 			return;
 	}
 	if (arg)
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	else
 		l3dss1_message(pc, MT_HOLD_ACKNOWLEDGE);
 	pc->aux_state = AUX_CALL_HELD;
@@ -1886,7 +1885,7 @@
 			return;
 	}
 	if (arg)
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	else
 		l3dss1_message_cause(pc, MT_HOLD_REJECT, CAUSE_RESOURCES_UNAVAIL); // FIXME
 	pc->aux_state = AUX_IDLE;
@@ -1905,13 +1904,13 @@
 		return;
 	}
 	if (test_bit(FLG_PTP, &pc->l3->Flag)) {
-		if ((pc->state & VALID_HOLD_STATES_PTP) == 0) { /* not a valid HOLD state for PtP */
+		if ((SBIT(pc->state) & VALID_HOLD_STATES_PTP) == 0) { /* not a valid HOLD state for PtP */
 			l3dss1_message_cause(pc, MT_HOLD_REJECT, CAUSE_NOTCOMPAT_STATE);
 			dev_kfree_skb(skb);
 			return;
 		}
 	} else {
-		if ((pc->state & VALID_HOLD_STATES_PTMP) == 0) { /* not a valid HOLD state for PtMP */
+		if ((SBIT(pc->state) & VALID_HOLD_STATES_PTMP) == 0) { /* not a valid HOLD state for PtMP */
 			l3dss1_message_cause(pc, MT_HOLD_REJECT, CAUSE_NOTCOMPAT_STATE);
 			dev_kfree_skb(skb);
 			return;
@@ -2014,7 +2013,7 @@
 l3dss1_retrieve_req(l3_process_t *pc, u_char pr, void *arg)
 {
 	if (!test_bit(FLG_PTP, &pc->l3->Flag)) {
-		if ((pc->state & (VALID_HOLD_STATES_PTMP | SBIT(12))) == 0) { /* not a valid RETRIEVE state for PtMP */
+		if ((SBIT(pc->state) & (VALID_HOLD_STATES_PTMP | SBIT(12))) == 0) { /* not a valid RETRIEVE state for PtMP */
 			return;
 		}
 	}
@@ -2027,9 +2026,8 @@
 			return;
 	}
 	if (arg) {
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	} else {
-		newl3state(pc, -1);
 		l3dss1_message(pc, MT_RETRIEVE);
 	}
 	pc->aux_state = AUX_RETRIEVE_REQ;
@@ -2047,7 +2045,7 @@
 			return;
 	}
 	if (arg)
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	else
 		l3dss1_message(pc, MT_RETRIEVE_ACKNOWLEDGE);
 	pc->aux_state = AUX_IDLE;
@@ -2064,7 +2062,7 @@
 			return;
 	}
 	if (arg)
-		SendMsg(pc, arg, -1);
+		SendMsg(pc, arg);
 	else
 		l3dss1_message_cause(pc, MT_RETRIEVE_REJECT, CAUSE_RESOURCES_UNAVAIL); // FIXME
 	pc->aux_state = AUX_CALL_HELD;
@@ -2078,13 +2076,13 @@
 	int		ret;
 
 	if (test_bit(FLG_PTP, &pc->l3->Flag)) {
-		if ((pc->state & (VALID_HOLD_STATES_PTP | SBIT(12))) == 0) { /* not a valid RETRIEVE state for PtP */
+		if ((SBIT(pc->state) & (VALID_HOLD_STATES_PTP | SBIT(12))) == 0) { /* not a valid RETRIEVE state for PtP */
 			l3dss1_message_cause(pc, MT_RETRIEVE_REJECT, CAUSE_NOTCOMPAT_STATE);
 			dev_kfree_skb(skb);
 			return;
 		}
 	} else {
-		if ((pc->state & (VALID_HOLD_STATES_PTMP | SBIT(12))) == 0) { /* not a valid RETRIEVE state for PtMP */
+		if ((SBIT(pc->state) & (VALID_HOLD_STATES_PTMP | SBIT(12))) == 0) { /* not a valid RETRIEVE state for PtMP */
 			l3dss1_message_cause(pc, MT_RETRIEVE_REJECT, CAUSE_NOTCOMPAT_STATE);
 			dev_kfree_skb(skb);
 			return;
@@ -2226,8 +2224,11 @@
 l3dss1_t302(l3_process_t *pc, u_char pr, void *arg)
 {
 	L3DelTimer(&pc->timer);
+	/* BUG? Q.931 p. 207 in state 25 says indicate timeout and let CC decide what happens next */
+	/*      ETS300102: IS CALL INFO DEFINITELY INCOMPLETE? DISCONNECT and state 11, no indication to CC */
 	newl3state(pc, 11);
 	l3dss1_message_cause(pc, MT_DISCONNECT, CAUSE_INVALID_NUMBER);
+	L3AddTimer(&pc->timer, T305, CC_T305);
 	mISDN_l3up(pc, CC_TIMEOUT | INDICATION, NULL);
 }
 
@@ -2246,7 +2247,7 @@
 				pc->t303skb = NULL;
 			}
 			if (skb)
-				SendMsg(pc, skb, -1);
+				SendMsg(pc, skb);
 		}
 		L3AddTimer(&pc->timer, T303, CC_T303);
 		return;
@@ -2254,7 +2255,16 @@
 	if (pc->t303skb)
 		kfree_skb(pc->t303skb);
 	pc->t303skb = NULL;
+#if 0
+	/*
+	 * This REL CMPL is not in Q.931/ETS300102.
+	 *
+	 * We should not send this RELEASE COMPLETE message in case we
+	 * are using a call ref of another call.  We could be tearing
+	 * down some other call unexpectedly.
+	 */
 	l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, CAUSE_TIMER_EXPIRED);
+#endif
 	mISDN_l3up(pc, CC_TIMEOUT | INDICATION, NULL);
 	release_l3_process(pc);
 }
@@ -2265,6 +2275,7 @@
 	L3DelTimer(&pc->timer);
 	newl3state(pc, 11);
 	l3dss1_message_cause(pc, MT_DISCONNECT, CAUSE_TIMER_EXPIRED);
+	L3AddTimer(&pc->timer, T305, CC_T305);
 	mISDN_l3up(pc, CC_TIMEOUT | INDICATION, NULL);
 }
 
@@ -2295,6 +2306,7 @@
 	L3DelTimer(&pc->timer);
 	newl3state(pc, 11);
 	l3dss1_message_cause(pc, MT_DISCONNECT, CAUSE_TIMER_EXPIRED);
+	L3AddTimer(&pc->timer, T305, CC_T305);
 	mISDN_l3up(pc, CC_TIMEOUT | INDICATION, NULL);
 }
 
@@ -2304,6 +2316,7 @@
 	L3DelTimer(&pc->timer);
 	newl3state(pc, 11);
 	l3dss1_message_cause(pc, MT_DISCONNECT, CAUSE_TIMER_EXPIRED);
+	L3AddTimer(&pc->timer, T305, CC_T305);
 	mISDN_l3up(pc, CC_TIMEOUT | INDICATION, NULL);
 }
 
@@ -2611,7 +2624,7 @@
 	proc->callref = skb->data[2]; /* cr flag */
 	for (i = 0; i < GLOBALM_LEN; i++)
 		if ((mt == globalmes_list[i].primitive) &&
-		    ((1UL << proc->state) & globalmes_list[i].state))
+		    (SBIT(proc->state) & globalmes_list[i].state))
 			break;
 	if (i == GLOBALM_LEN) {
 		if (l3->debug & L3_DEB_STATE) {
@@ -2792,7 +2805,7 @@
 	}
 	for (i = 0; i < DATASLLEN; i++)
 		if ((qi->type == datastatelist[i].primitive) &&
-		    ((1UL << proc->state) & datastatelist[i].state))
+		    (SBIT(proc->state) & datastatelist[i].state))
 			break;
 	if (i == DATASLLEN) {
 		if (l3->debug & L3_DEB_STATE) {
@@ -2834,8 +2847,18 @@
 				__FUNCTION__, hh->dinfo);
 			ret = -EBUSY;
 		} else {
-			cr = newcallref(l3);
-			cr |= 0x8000;
+			int first_cr;
+
+			first_cr = cr = newcallref(l3) | 0x8000;
+			while (getl3proc(l3, cr)) {
+				/* Selected call ref was in use.  Try next call ref. */
+				cr = newcallref(l3) | 0x8000;
+				if (cr == first_cr) {
+					/* All call ref values are in use!  Use it anyway. */
+					break;
+				}
+			}
+
 			ret = -ENOMEM;
 			if ((proc = new_l3_process(l3, cr, N303, hh->dinfo))) {
 				ret = 0;
@@ -2869,18 +2892,18 @@
 		if(debug)
 			printk(KERN_ERR "mISDN dss1 fromup without proc pr=%04x dinfo(%x)\n",
 				hh->prim, hh->dinfo);
-				return(-EINVAL);
+		return(-EINVAL);
 	}
 	for (i = 0; i < DOWNSLLEN; i++)
 		if ((hh->prim == downstatelist[i].primitive) &&
-		    ((1UL << proc->state) & downstatelist[i].state))
+		    (SBIT(proc->state) & downstatelist[i].state))
 			break;
 	if (i == DOWNSLLEN) {
 		if (l3->debug & L3_DEB_STATE) {
 			l3_debug(l3, "dss1down state %d prim %#x unhandled",
 				proc->state, hh->prim);
 		}
-			dev_kfree_skb(skb);
+		dev_kfree_skb(skb);
 	} else {
 		if (l3->debug & L3_DEB_STATE) {
 			l3_debug(l3, "dss1down state %d prim %#x para len %d",
@@ -2907,19 +2930,19 @@
 	}
 	for (i = 0; i < MANSLLEN; i++)
 		if ((pr == manstatelist[i].primitive) &&
-			((1UL << proc->state) & manstatelist[i].state))
-			break;
-		if (i == MANSLLEN) {
-			if (proc->l3->debug & L3_DEB_STATE) {
-				l3_debug(proc->l3, "cr %d dss1man state %d prim %#x unhandled",
-					proc->callref & 0x7fff, proc->state, pr);
-			}
-		} else {
-			if (proc->l3->debug & L3_DEB_STATE) {
-				l3_debug(proc->l3, "cr %d dss1man state %d prim %#x",
-					proc->callref & 0x7fff, proc->state, pr);
-			}
-			manstatelist[i].rout(proc, pr, arg);
+			(SBIT(proc->state) & manstatelist[i].state))
+			break;
+	if (i == MANSLLEN) {
+		if (proc->l3->debug & L3_DEB_STATE) {
+			l3_debug(proc->l3, "cr %d dss1man state %d prim %#x unhandled",
+				proc->callref & 0x7fff, proc->state, pr);
+		}
+	} else {
+		if (proc->l3->debug & L3_DEB_STATE) {
+			l3_debug(proc->l3, "cr %d dss1man state %d prim %#x",
+				proc->callref & 0x7fff, proc->state, pr);
+		}
+		manstatelist[i].rout(proc, pr, arg);
 	}
 	return(0);
 }

Modified: mISDN/trunk/drivers/isdn/hardware/mISDN/layer3.c
URL: http://svnview.digium.com/svn/thirdparty/mISDN/trunk/drivers/isdn/hardware/mISDN/layer3.c?view=diff&rev=193&r1=192&r2=193
==============================================================================
--- mISDN/trunk/drivers/isdn/hardware/mISDN/layer3.c (original)
+++ mISDN/trunk/drivers/isdn/hardware/mISDN/layer3.c Fri Aug 10 15:42:55 2012
@@ -178,7 +178,7 @@
 {
 	if (pc->l3->debug & L3_DEB_STATE)
 		l3m_debug(&pc->l3->l3m, "newstate cr %d %d --> %d", 
-			 pc->callref & 0x7F,
+			 pc->callref & 0x7FFF,
 			 pc->state, state);
 	pc->state = state;
 }




More information about the thirdparty-commits mailing list