[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