[Asterisk-Users] Local Channel Call Looping
Darren Sessions
dsessions at ionosphere.net
Thu Jan 26 10:13:12 MST 2006
*** If anyone has a better way of doing this, please post to the list. I
hadn't seen anything on this list or in channel.c/chan_local.c - which
prompted this email ***
I'm not sure how many VoIP providers out there are using Asterisk as a
service platform like we do, but I thought I'd share an experience with
call looping that was racking my brain with the list.
One of the features we offer our customers, is of course, call
forwarding. We take a call in and spit it back out to whatever the call
forward number is set by the customer.
With our particular proxy setup, if a call originates from * to the
proxy it will never loop back to *; this prevents SIP call loops.
In *, for an on-net call forward number, we would use the dial command
to call (if it was registered) the customer's device with SIP via the
proxy, and also dial a local channel to process any of the 'forward to'
customer's features; again, this is for an on-net call.
The problem was that if when we dial the local channel and that customer
had forwarded calls to the first number or calls were setup to forward
from cust1 to cust2 to cust3 to cust1, we were getting an infinite local
channel loop. As you can imagine, the load on * was off the charts.
The solution to the problem finally ended up being to set inherited
channel variables.
First, we'd read/parse the channel variable to determine if the call was
coming in anything other than a local channel. If it was, a variable
with that called number label was immediately set to a value of 1 - i.e.
the first in the chain.
Next, an addition variable with the 'call forward to' number was also
given a value of 1, and then the call was processed. When the new local
channel for the 'forward to' number was spawned, and assuming that call
forwarding was set on that number, the process would repeat with this
inherited variable label scheme.
The catch is that in each iteration at the same time the call forward to
number is being labeled, the system would check that variable for a
value before it tried to assign one. If the variable had a value, it was
safe to assume that it had already been processed in the call chain
somewhere and therefore the system would be looping the call if it
continued.
Here are some sanitized Perl based AGI excerpts that accomplish this:
sub callfwd_loop_check
{
my %v;
($v{callednum},$v{cfnum}) = @_;
$v{num} = $AGI->get_variable($v{cfnum});
if ($v{num})
{
debug(" Call Loop Anaylsis for ".$v{callednum}." =
LOOPING");
return(1);
}
else
{
debug(" Call Loop Anaylsis for ".$v{callednum}." = NO
LOOP");
$AGI->exec('Set',"__".$v{cfnum}."=".$v{callednum})
}
return;
}
$AGI->exec('Set',"__".$callednumber."=1") if ($calltype !~/^Local/);
if (callfwd_loop_check($callednumber,$callfwdtonum))
{
return;
}
$AGI->exec('Dial',"Local/+".$callfwdtonum."\@localcontext\&SIP/+".$callfwdtonum."\@sipproxy|180");
I hope this all makes sense! :)
Thanks,
- Darren
More information about the asterisk-users
mailing list