Simple SIP fallback with Asterisk

If you use a SIP provider for your phonecalls, it could happen that it won't be reachable. Say there where routing errors (happend also to youtube), DDoS, broken cables or just a simple configuration error. If this happens, you can't call out.

The solution is using to another SIP provider. Failback isn't difficult with asterisk, you can find some solutions with macro's. Somehow macro's would make my dialplan less clearly arranged. I don't like the macro seperation in smaller configurations. On bigger systems it would make sence. So I won't use it.

Fall back will become much more complicated if you have use Asterisk call through. If you do a call through like in the linked example, you will run into a problem when you jump back (#,5,Goto(s,1)). If you want this feature, you need for each call through section an own fall back configuration. If you don't use it, a macro will work fine.

Since priority jumping is deprecated and the use of the DIALSTATUS is recommend, we have a powerfull way to do a clean failure handling. If the provider tells us if the line is unavailable (f.e. because of a phone routing error) or asterisk identifys that our SIP provider isn't reachable DIALSTATUS will be set to CHANUNAVAIL.

The only problem with the new way of error handling is to get the dialed number to the fall-back, because EXTEN will be FOO-${DIALSTATUS}. Solution is to safe this number in a variable to use it in our fail-back.

;dial out with dus.net
exten => _0049.,1,NoOp(Call-out dusnet)
exten => _0049.,n,Dial(IAX2/dusnet/${EXTEN:3})
exten => _0049.,n,Goto(s-${DIALSTATUS},1)
exten => _X.,1,NoOp(Call-out dusnet)
exten => _X.,n,Dial(IAX2/dusnet/${EXTEN})
exten => _X.,n,SetVar(DIALEDNUMBER=${EXTEN})
exten => _X.,n,Goto(s-${DIALSTATUS},1)
;;
;; Fallback
;;
; usual errors
exten => s-BUSY,1,NoOp(s-BUSY, hangup)
exten => s-BUSY,n,Hangup
exten => s-CANCEL,1,NoOp(s-CANCEL, hangup)
exten => s-CANCEL,n,Hangup
exten => s-CONGESTION,1,NoOp(s-CONGESTION, send congestion)
exten => s-CONGESTION,n,Congestion ;not recognized number
exten => s-NOANSWER,1,NoOp(s-NOANSWER, hangup)
exten => s-NOANSWER,n,Hangup
exten => s-,1,NoOp(s-, every other return value, congestion)
exten => s-,n,Congestion
; CHANUNAVAIL: Channel unavailable. On SIP, peer may not be registered.
; F.e.: dus.net returned it when they had routing problems to US
exten => s-CHANUNAVAIL,1,NoOp(s-CHANUNAVAIL, fallback and dial again)
exten => s-CHANUNAVAIL,n,Dial(SIP/${DIALEDNUMBER}@sipgate,60,r)
exten => s-CHANUNAVAIL,n,NoOp(s-CHANUNAVAIL exited with ${DIALSTATUS}. Hang up now)
exten => s-CHANUNAVAIL,n,Hangup
Sure, you can reduce the SetVar-lines to have just one.

The only problem is which DIALSTATUS message you'll get. When dus.net had a routing problem to US, the return value was CHANUNAVAIL. When I tried the fail back the first time I haven't charged my sipgate account. It was clear, that sipgate won't let me call out... but the problem was the returned DIALSTATUS. BUSY isn't a really helpful dialstatus. voip-info.org says about the busy dialstatus: defines the busy value of DIALSTATUS as

BUSY: Busy signal. The dial command reached its number but the number is busy.

uhrig.eu.org/pbx/
$Id: index.html,v 1.3 2008-07-31 17:42:58 volker Exp $