[asterisk-dev] Re: chan_zap: problem in PRI_EVENT_HANGUP_REQ

Tony Mountifield tony at softins.clara.co.uk
Wed Apr 25 03:10:14 MST 2007


Well, following up my own post (since no-one else has :-))...

In article <f0l44t$vre$1 at softins.clara.co.uk>, I wrote:
> I'm just debugging a customer problem in the UK with EuroISDN channels.
> 
> The problem manifests itself like this:
> a) Caller is probably on a mobile, and is talking to a Meetme conference.
> b) Caller's mobile loses signal and drops the call.
> c) Asterisk logs "Channel 0/n, span x got hangup request", but doesn't
>    hangup the call.
> d) After about a second, the exchange sends a tri-tone followed by "Sorry,
>    there is a fault - please try again" for about 40 seconds.
> e) Asterisk logs "Channel 0/n, span x got hangup" and then process the hangup
>    in the dial plan.
> 
> The fault message is of course very disruptive to the conference in progress.

Having run with PRI debugging enabled until the same problem happened
again, I discovered that the disconnect cause code being sent by the network
to the established call was 41 (PRI_CAUSE_NORMAL_TEMPORARY_FAILURE).
In the code below, this will not cause the line to be hung up.

> Looking at a part of the code that handles PRI_EVENT_HANGUP_REQ (I'm using 1.2,
> but it looks to be the same in trunk), I see this:
> 
>   pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
>   switch(e->hangup.cause) {
>     case PRI_CAUSE_USER_BUSY:
>       pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
>       break;
>     case PRI_CAUSE_CALL_REJECTED:
>     case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
>     case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
>     case PRI_CAUSE_SWITCH_CONGESTION:
>     case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
>     case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
>       pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
>       break;
>     default:
>       pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
>   }
>   if (option_verbose > 2) 
>     ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup request\n",
> PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);

I've now changed the above code to the following, so that an established
call will always be hung up and a non-established call will always get
either needbusy or needcongestion set:

  pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;

  if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
    pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
  else if (pri->pvts[chanpos]->owner->hangupcause == PRI_CAUSE_USER_BUSY)
    pri->pvts[chanpos]->subs[SUB_REAL].needbusy = 1;
  else
    pri->pvts[chanpos]->subs[SUB_REAL].needcongestion = 1;

  if (option_verbose > 2) 
    ast_verbose(VERBOSE_PREFIX_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);

And similarly further up in PRI_EVEN_HANGUP.

Bug report and patches submitted at http://bugs.digium.com/view.php?id=9588

Cheers
Tony
-- 
Tony Mountifield
Work: tony at softins.co.uk - http://www.softins.co.uk
Play: tony at mountifield.org - http://tony.mountifield.org


More information about the asterisk-dev mailing list