Merged revisions 224260 via svnmerge from
authorRichard Mudgett <rmudgett@digium.com>
Fri, 16 Oct 2009 20:40:57 +0000 (20:40 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 16 Oct 2009 20:40:57 +0000 (20:40 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r224260 | rmudgett | 2009-10-16 15:25:23 -0500 (Fri, 16 Oct 2009) | 18 lines

  Never released PRI channels when using Busy() or Congestion() dialplan apps.

  When the Busy() or Congestion() application is used towards ISDN (an ISDN
  progress is sent), the responding ISDN Disconnect or Release may contain
  the ISDN cause user busy or one of the congestion causes.  In chan_dahdi.c
  these causes will only set the needbusy or needcongestion flags and not
  activate the softhangup procedure.  Unfortunately only the latter can
  interrupt the endless wait loop of Busy()/Congestion().

  Result: PRI channels staying in state busy for the rest of asterisk life
  or until the other end times out and forces the call to clear.

  (issue #14292)
  Reported by: tomaso
  Patches:
        disc_rel_userbusy.patch uploaded by tomaso (license 564)
        (This patch is unrelated to the issue.)
........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@224261 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/sig_pri.c

index 4764112..8f05e92 100644 (file)
@@ -2096,9 +2096,12 @@ static void *pri_dchannel(void *vpri)
                                                        if (pri->pvts[chanpos]->owner) {
                                                                /* Queue a BUSY instead of a hangup if our cause is appropriate */
                                                                pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
                                                        if (pri->pvts[chanpos]->owner) {
                                                                /* Queue a BUSY instead of a hangup if our cause is appropriate */
                                                                pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
-                                                               if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
+                                                               switch (pri->pvts[chanpos]->owner->_state) {
+                                                               case AST_STATE_BUSY:
+                                                               case AST_STATE_UP:
                                                                        ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
                                                                        ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
-                                                               else {
+                                                                       break;
+                                                               default:
                                                                        switch (e->hangup.cause) {
                                                                        case PRI_CAUSE_USER_BUSY:
                                                                                pri_queue_control(pri->pvts[chanpos], AST_CONTROL_BUSY, pri);
                                                                        switch (e->hangup.cause) {
                                                                        case PRI_CAUSE_USER_BUSY:
                                                                                pri_queue_control(pri->pvts[chanpos], AST_CONTROL_BUSY, pri);
@@ -2115,6 +2118,7 @@ static void *pri_dchannel(void *vpri)
                                                                                ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
                                                                                break;
                                                                        }
                                                                                ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
                                                                                break;
                                                                        }
+                                                                       break;
                                                                }
                                                        }
                                                        ast_verb(3, "Channel %d/%d, span %d got hangup, cause %d\n",
                                                                }
                                                        }
                                                        ast_verb(3, "Channel %d/%d, span %d got hangup, cause %d\n",
@@ -2167,9 +2171,12 @@ static void *pri_dchannel(void *vpri)
                                                        e->hangup.subcmds);
                                                if (pri->pvts[chanpos]->owner) {
                                                        pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
                                                        e->hangup.subcmds);
                                                if (pri->pvts[chanpos]->owner) {
                                                        pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
-                                                       if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
+                                                       switch (pri->pvts[chanpos]->owner->_state) {
+                                                       case AST_STATE_BUSY:
+                                                       case AST_STATE_UP:
                                                                ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
                                                                ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
-                                                       else {
+                                                               break;
+                                                       default:
                                                                switch (e->hangup.cause) {
                                                                case PRI_CAUSE_USER_BUSY:
                                                                        pri_queue_control(pri->pvts[chanpos], AST_CONTROL_BUSY, pri);
                                                                switch (e->hangup.cause) {
                                                                case PRI_CAUSE_USER_BUSY:
                                                                        pri_queue_control(pri->pvts[chanpos], AST_CONTROL_BUSY, pri);
@@ -2186,6 +2193,7 @@ static void *pri_dchannel(void *vpri)
                                                                        ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
                                                                        break;
                                                                }
                                                                        ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
                                                                        break;
                                                                }
+                                                               break;
                                                        }
                                                        ast_verb(3, "Channel %d/%d, span %d got hangup request, cause %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause);
                                                        if (e->hangup.aoc_units > -1)
                                                        }
                                                        ast_verb(3, "Channel %d/%d, span %d got hangup request, cause %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause);
                                                        if (e->hangup.aoc_units > -1)