[prev in list] [next in list] [prev in thread] [next in thread] 

List:       asterisk-dev
Subject:    Re: [asterisk-dev] DAHDI/MFCR2: handling remote clearing for outgoing calls ?
From:       Richard Mudgett <rmudgett () digium ! com>
Date:       2013-10-11 15:50:52
Message-ID: CALD46g0WK8XKV1VSMi7hAckB8X1Qvp35Jkrp=AgND8rhWeUs8w () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


On Fri, Oct 11, 2013 at 12:00 AM, Pavel Troller <patrol@sinus.cz> wrote:

> Hi!
>   I'm preparing an Asterisk installation serving as a gateway to the legacy
> CAS/MFCR2 exchange. All seems to work well, except that almost any clear
> cause
> occuring during outgoing connection setup to the remote exchange is
> presented
> as Congestion (Clear Cause 34) to the originator.
>   I was searching through the code of chan_dahdi.c and found this part, in
> the
> dahdi_r2_on_call_disconnect() function:
> ...
>         } else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {
>                 /* being the forward side we must report what happened to
> the call to whoever requested it */
>                 switch (cause) {
>                 case OR2_CAUSE_BUSY_NUMBER:
>                         p->subs[SUB_REAL].needbusy = 1;
>                         break;
>                 case OR2_CAUSE_NETWORK_CONGESTION:
>                 case OR2_CAUSE_OUT_OF_ORDER:
>                 case OR2_CAUSE_UNALLOCATED_NUMBER:
>                 case OR2_CAUSE_NO_ANSWER:
>                 case OR2_CAUSE_UNSPECIFIED:
>                 case OR2_CAUSE_NORMAL_CLEARING:
>                         p->subs[SUB_REAL].needcongestion = 1;
>                         break;
>                 default:
>                         ast_channel_softhangup_internal_flag_add(p->owner,
> AST_SOFTHANGUP_DEV);
>                 }
>                 ast_mutex_unlock(&p->lock);
>         } else {
>                 ast_mutex_unlock(&p->lock);
>                 /* being the backward side and not UP yet, we only need to
> request hangup */
>                 /* TODO: what about doing this same thing when were
> AST_STATE_UP? */
>                 ast_queue_hangup_with_cause(p->owner,
> dahdi_r2_cause_to_ast_cause(cause));
>         }
> ...
>   Setting needcongestion causes that dahdi_read() sends the
> AST_CONTROL_CONGESTION frame towards the originator, causing it to initiate
> hangup with obvious Congestion clear cause (34).
>   But what I don't understand, is, WHY we are sending the congestion frame
> instead of simply initiating the hangup by ourself with a proper cause ?
>   Because I didn't find a trick how to propagate a proper cause code to the
> originator, I've changed the code to the following:
>
>         } else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {
>                 /* being the forward side we must report what happened to
> the call to whoever requested it */
>                 switch (cause) {
>                 case OR2_CAUSE_BUSY_NUMBER:
>                         p->subs[SUB_REAL].needbusy = 1;
>                         break;
>                 case OR2_CAUSE_NETWORK_CONGESTION:
>                 case OR2_CAUSE_OUT_OF_ORDER:
>                 case OR2_CAUSE_UNSPECIFIED:
>                         p->subs[SUB_REAL].needcongestion = 1;
>                         break;
>                 case OR2_CAUSE_UNALLOCATED_NUMBER:
>                 case OR2_CAUSE_NO_ANSWER:
>                 case OR2_CAUSE_NORMAL_CLEARING:
>                         ast_mutex_unlock(&p->lock);
>                         ast_queue_hangup_with_cause(p->owner,
> dahdi_r2_cause_to_ast_cause(cause));
>                         return;
>                         break;
>                 default:
>                         ast_channel_softhangup_internal_flag_add(p->owner,
> AST_SOFTHANGUP_DEV);
>                 }
>                 ast_mutex_unlock(&p->lock);
>         } else {
>
>   In this case, it is chan_dahdi, who initiates the hangup, and it can set
> the
> clear cause using the standard set of cause values (for selected clear
> cases).
> From the user's point of view, I can't find anything wrong with this
> solution.
> Now the connection attempt is cleared as before, but with the proper cause
> code
> (tested on UNALLOCATED).
>
>   By the way, there is probably a bug in the mapping function,
> dahdi_r2_cause_to_ast_cause().
> OR2_CAUSE_UNALLOCATED_NUMBER is mapped to AST_CAUSE_UNREGISTERED, while it
> must be mapped to
> AST_CAUSE_UNALLOCATED.
>
>
>   I would like to hear, why the hangup handling was written in such a
> strange
> way, and whether we need a different handling for forward and backward
> connections at all - for me it seems superfluous.


In a word: legacy.  The chan_dahdi channel driver was originally written
for analog lines in
early versions of Asterisk.  Later MFC/R2, PRI, and SS7 were forced into
the driver so they
for the most part do things the way the old analog code did it.

Richard

[Attachment #5 (text/html)]

<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, \
Oct 11, 2013 at 12:00 AM, Pavel Troller <span dir="ltr">&lt;<a \
href="mailto:patrol@sinus.cz" target="_blank">patrol@sinus.cz</a>&gt;</span> \
wrote:<br> <blockquote class="gmail_quote" style="margin:0pt 0pt 0pt \
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi!<br>  I&#39;m \
preparing an Asterisk installation serving as a gateway to the legacy<br> CAS/MFCR2 \
exchange. All seems to work well, except that almost any clear cause<br> occuring \
during outgoing connection setup to the remote exchange is presented<br> as \
Congestion (Clear Cause 34) to the originator.<br>  I was searching through the code \
of chan_dahdi.c and found this part, in the<br> dahdi_r2_on_call_disconnect() \
                function:<br>
...<br>
        } else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {<br>
                /* being the forward side we must report what happened to the call to \
whoever requested it */<br>  switch (cause) {<br>
                case OR2_CAUSE_BUSY_NUMBER:<br>
                        p-&gt;subs[SUB_REAL].needbusy = 1;<br>
                        break;<br>
                case OR2_CAUSE_NETWORK_CONGESTION:<br>
                case OR2_CAUSE_OUT_OF_ORDER:<br>
                case OR2_CAUSE_UNALLOCATED_NUMBER:<br>
                case OR2_CAUSE_NO_ANSWER:<br>
                case OR2_CAUSE_UNSPECIFIED:<br>
                case OR2_CAUSE_NORMAL_CLEARING:<br>
                        p-&gt;subs[SUB_REAL].needcongestion = 1;<br>
                        break;<br>
                default:<br>
                        ast_channel_softhangup_internal_flag_add(p-&gt;owner, \
AST_SOFTHANGUP_DEV);<br>  }<br>
                ast_mutex_unlock(&amp;p-&gt;lock);<br>
        } else {<br>
                ast_mutex_unlock(&amp;p-&gt;lock);<br>
                /* being the backward side and not UP yet, we only need to request \
                hangup */<br>
                /* TODO: what about doing this same thing when were AST_STATE_UP? \
                */<br>
                ast_queue_hangup_with_cause(p-&gt;owner, \
dahdi_r2_cause_to_ast_cause(cause));<br>  }<br>
...<br>
  Setting needcongestion causes that dahdi_read() sends the<br>
AST_CONTROL_CONGESTION frame towards the originator, causing it to initiate<br>
hangup with obvious Congestion clear cause (34).<br>
  But what I don&#39;t understand, is, WHY we are sending the congestion frame<br>
instead of simply initiating the hangup by ourself with a proper cause ?<br>
  Because I didn&#39;t find a trick how to propagate a proper cause code to the<br>
originator, I&#39;ve changed the code to the following:<br>
<br>
        } else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {<br>
                /* being the forward side we must report what happened to the call to \
whoever requested it */<br>  switch (cause) {<br>
                case OR2_CAUSE_BUSY_NUMBER:<br>
                        p-&gt;subs[SUB_REAL].needbusy = 1;<br>
                        break;<br>
                case OR2_CAUSE_NETWORK_CONGESTION:<br>
                case OR2_CAUSE_OUT_OF_ORDER:<br>
                case OR2_CAUSE_UNSPECIFIED:<br>
                        p-&gt;subs[SUB_REAL].needcongestion = 1;<br>
                        break;<br>
                case OR2_CAUSE_UNALLOCATED_NUMBER:<br>
                case OR2_CAUSE_NO_ANSWER:<br>
                case OR2_CAUSE_NORMAL_CLEARING:<br>
                        ast_mutex_unlock(&amp;p-&gt;lock);<br>
                        ast_queue_hangup_with_cause(p-&gt;owner, \
dahdi_r2_cause_to_ast_cause(cause));<br>  return;<br>
                        break;<br>
                default:<br>
                        ast_channel_softhangup_internal_flag_add(p-&gt;owner, \
AST_SOFTHANGUP_DEV);<br>  }<br>
                ast_mutex_unlock(&amp;p-&gt;lock);<br>
        } else {<br>
<br>
  In this case, it is chan_dahdi, who initiates the hangup, and it can set the<br>
clear cause using the standard set of cause values (for selected clear cases).<br>
From the user&#39;s point of view, I can&#39;t find anything wrong with this \
solution.<br> Now the connection attempt is cleared as before, but with the proper \
cause code<br> (tested on UNALLOCATED).<br>
<br>
  By the way, there is probably a bug in the mapping function, \
dahdi_r2_cause_to_ast_cause().<br> OR2_CAUSE_UNALLOCATED_NUMBER is mapped to \
AST_CAUSE_UNREGISTERED, while it must be mapped to<br> AST_CAUSE_UNALLOCATED.<br>
<br>
<br>
  I would like to hear, why the hangup handling was written in such a strange<br>
way, and whether we need a different handling for forward and backward<br>
connections at all - for me it seems superfluous.</blockquote><div><br></div><div>In \
a word: legacy.  The chan_dahdi channel driver was originally written for analog \
lines in<br>early versions of Asterisk.  Later MFC/R2, PRI, and SS7 were forced into \
the driver so they<br> </div><div>for the most part do things the way the old analog \
code did it.<br><br>Richard<br></div></div></div></div>



-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic