GotoIf statement for failover


I’m running Asterisk between IP clients and FXO gateway. For redundancy I’m running two FXO gateways side-by side, but at any time FXO lines are only terminated on one gateway. I’m facing a problem where Asterisk is sending SIP invites to both gateways simultaneously, and for some reason the call is always picked up by the gateway with no active FXO interfaces, causing the calls to fail.

I can always just power off one of the gateways to fix this problem. But I was wondering if there is a way of using the GotoIf statement to send the invite first to the main gateway, and if there is no reply, only then send it to the secondary gateway.

Here’s my current Asterisk context for the FXO gateways:

exten => _9XX!,1,NoOP(Call to FXO Ports)
exten => _9XX!,n,Set(Dial_String=${EXTEN:0:3})
exten => _9XX!,n,Set(DTMF_String=${EXTEN:4})
exten => _9XX!,n,Set(DTMF_String=${REPLACE(DTMF_String,,,w)})
exten => _9XX!,n,Dial(SIP/${Dial_String}@GW_1&SIP/${Dial_String}@GW_2,90,M(logConnected^${CDR(src)}^${CDR(${Dial_String})})&D(${DTMF_String}))
exten => _9XX!,n,Hangup()

Use two consecutive Dials, not a parallel Dial. It is best to check the hangup cause, but, in this case, even that may not matter.

You must realize a basic troubleshooting:

1 - Check if both FXO gateways are using same firmware2 - some line could cause your problem. Check each line during necessary time to detect your problem.
3 - change lines between gateways and watch if problem persists

here is how we do it
it is random first so you just need simplify it to do linear


[Trunk] ;loadbalacing and failover
exten => _[0-9s#*+]!,1,Set(Num=${FIELDQTY(Trunk,\,)})
same => n,Set(CHANNEL(hangup_handler_push)=Hangup_Handler,${FILTER(+1234567890#*,${EXTEN})},1)          ; enable that we show hangup reason in the log
same => n,ExecIf($[0${Max-Forwards} <= 0]?Congestion(5))                                                ; Too many hops / Loop Detected
same => n,ExecIf($[${EXISTS(${PJSIP_HEADER(read,Privacy)})} & "${PJSIP_HEADER(read,Privacy)}" != "none"]?Set(_Number_pres="prohib"))    ; Privacy: id;user;header
same => n,Set(Count=0)
same => n,Set(Current=${RAND(1,${Num})})                                                                ; select a random place to start (load balacing)
same => n,While($[${INC(Count)} <= ${Num}])
same => n,Set(Current=$[${MATH(${Current}%${Num},i)}+1])                                                ; fancy modulus stuff to loop the list of hosts
same => n,ExecIf($["${DEVICE_STATE(PJSIP/${CUT(Trunk,\,,${Current})})}"="UNAVAILABLE"]?ContinueWhile()) ; check where the device in responding to option
same => n,ExecIf($["${DEVICE_STATE(PJSIP/${CUT(Trunk,\,,${Current})})}"="INVALID"]?ContinueWhile())     ; check that the device exists
same => n,Dial(PJSIP/${EXTEN}@${CUT(Trunk,\,,${Current})},${DialTimeout},iS(${MaxCallTime})b(Dial_Handler^${EXTEN}^1))
same => n,ExecIf($["${NoFailoverCause}"!="${LISTFILTER(NoFailoverCause,",",${HANGUPCAUSE})}"]?ExitWhile())      ; check if we should failover or not
same => n,EndWhile()
same => n,ExecIf($["${HANGUPCAUSE}"!="0"]?Hangup(${HANGUPCAUSE}):Hangup(38))                            ; 38    NETWORK_OUT_OF_ORDER
1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.