SIP trunk adding locution or retrying after hangup()

Hello,

I have some lines configured to hang up without answering the call, when there are some conditions. The Answer() is not negotiable; I cannot do it because my client would be billed an international phone call, so the line needs to be disconnected before answering

[context]
exten = _X.,1,Noop()
<Code that checks if we can pick up the call>
same = n,Hangup()

Now, I have found that different SIP trunk providers react differently. I actually have three providers. One of them reacts properly to the Hangup() and just closes the connection, so the client who is calling gets disconnected. This is the expected behavior for me. The problem is that this provider is much more expensive than the others (otherwise, I’d use this one for all lines)

Another one disconnects the client but appends a locution saying that “the line is not available”, which is not ideal because it confuses the client. The client should just hear a “busy line” tone. However, at least it disconnects the user after the locution.

Finally, a third one, and this is where it gets weird, sends my server subsequent “100” just after I hang up, so in the same phone call, the client gets connected and disconnected about 3-4 times, (I have tried this myself, the context gets called 3-4 times) until the client’s provider times out (about 30 secs). This is again not ideal because then the client needs to wait for 30 seconds to get disconnected, while they should be disconnected immediately.

I have tried the following with no luck

  • Playing with Progress()
  • Adding different Hangup() causes (1, 16, 17, 21, 27, 38…)
  • Playing with prematuremedia and progressinband

I’ve read a lot of posts on the topic. Some say that in SIP, you can’t hangup() before answer(), so the behavior is unpredictable. Some say that this may be a proxy retrying the call.

Could I at least have some way to disconnect the caller or ignore subsequent “100” after I hangup()? Again, my goal is to Hangup() before Answer() and have the caller get disconnected immediately.

Here’s my sip.conf. It is identical for the different providers, changing only the IP addresses.

[provider]
type=friend
context=context
Host=<ip>
Canreinvite=no
nat=yes
fromdomain=<domain>
Disallow=all
Allow=alaw
Insecure=port,invite
deny=0.0.0.0/0.0.0.0
permit=<ip>/255.255.255.255
prematuremedia=no
progressinband=yes

Thanks a lot. I’ve been fighting for this for months now.

I share the pain of the described problem.
What usually would help is a Hangup(16) probably with a Busy() or Congestion() in front of it.
In some cases even this setting won’t help as the provider tries again and again. This could be fetched if You store the CALLERID of the calling client and immediately drop calls from the same client which arrives let’s say in an intervall of 10-30 seconds from the initial call.
This is only a workaround but up to now I’ve got no reliable solution when providers doesn’t implement all protocoll messages (as an BYE) correctly.

Thanks Olaf.

I’m exploring a workaround with your suggestions.

I’ve managed to record the caller id, however, how would you drop the calls from the same client in a short interval?

After checking the call time, what can I do? Sending them a Hangup() without Answer() doesn’t work, it’s actually the problem I have in the first place.

Edit: I’m now trying to use progressinband=no, but even then, Asterisk replies with a ‘183’ to the SIP trunk. May that contribute to the problem?

Thanks again,
Carlos

Hi Carlos,

I don’t think, that progressinband will change anything in this case.
I would try to just ignore the recurring call atempt (in a time slot from the first call). You could achieve this by capturing the CALLERID and storing it temporary into the AstDB (with a timestamp like ${EPOCH}). Now, when the same CALLERID calls again at ${EPOCH} <= + 30 (Seconds) just let the call get into a context where You simply setup a Wait(30) or something, thus the call won’t neither be answered nor handled in any other way. It’s not elegant, but it should work.

Remark:
From time to time You’ll need to clean up old entries in the AstDB when following this sttrategy.

Hi Olaf,

I implemented a solution which is similar to yours, I agree it’s not elegant to make the user wait for 30 seconds before disconnect, but at least I know it’s not a problem on my side. I’ll keep trying new SIP trunk providers to find one which works properly.

Thanks again for your help, it was much appreciated.

Cheers,
Carlos