hmm you will soon find out that using DIALSTATUS is somewhat lacking
this is the code I use on our platform
[globals]
Trunk=gsm1,gsm2,gsm3,gsm4
NoFailoverCause=1,16,17,18,19,20,21,22,28,127
; 1 UNALLOCATED
; 16 NORMAL_CLEARING
; 17 USER_BUSY
; 18 NO_USER_RESPONSE
; 19 NO_ANSWER
; 20 SUBSCRIBER_ABSENT
; 21 CALL_REJECTED
; 22 NUMBER_CHANGED
; 28 INVALID_NUMBER_FORMAT
; 127 INTERWORKING
[Trunk] ;loadbalacing and failover
exten => _[+0-9*#s]!,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($[${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
[Dial_Handler]
exten => _[+0-9*#s]!,1,Set(PJSIP_HEADER(add,P-Early-Media)=supported) ; rfc5009
same => n,Set(PJSIP_HEADER(add,Max-Forwards)=${DEC(Max-Forwards)}) ; decrease the Max-Forwards from the incomming call to the outgong to prevent looping
same => n,ExecIf(${EXISTS(${Number_pres})}?Set(PJSIP_HEADER(add,Privacy)=id))
same => n,ExecIf(${EXISTS(${P-Asserted-Identity})}?Set(PJSIP_HEADER(add,P-Asserted-Identity)=<sip:${P-Asserted-Identity}@${Hostname}\;user=phone>))
same => n,ExecIf(${EXISTS(${Resource-Priority})}?Set(PJSIP_HEADER(add,Resource-Priority)=${Resource-Priority})) ; rfc4412
same => n,ExecIf(${EXISTS(${REDIRECTING(from-num)})}?Set(PJSIP_HEADER(add,Diversion)=<sip:${REDIRECTING(from-num)}@${Hostname}\;user=phone>\;reason=${REDIRECTING(reason)}\;counter=${REDIRECTING(count)}${Diversion-limit})) ; manaulay add Diversion to include counter and limit
same => n,ExecIf(${EXISTS(${REDIRECTING(from-num)})}?Set(REDIRECTING(from-num)=)) ; clear REDIRECTING(from-num) so we do not get 2 Diversion header
same => n,ExecIf(${EXISTS(${Session-ID})}?Set(PJSIP_HEADER(add,Session-ID)=${Session-ID})) ; rfc7329
same => n,Set(PJSIP_HEADER(add,X-Call-ID)=${Call-ID}) ; sngrep F4 extended dialog
same => n,Set(PJSIP_HEADER(add,X-CID)=${Call-ID}) ; homer correlation_id
same => n,While(${EXISTS(${SET(HI=${SHIFT(History-Info)})})})
same => n,Set(PJSIP_HEADER(add,History-Info)=${HI}) ; pass on the history to the outgoing call
same => n,EndWhile()
same => n,Set(CHANNEL(hangup_handler_push)=Hangup_Handler,${FILTER(+1234567890#*,${EXTEN})},1) ; enable that we show hangup reason in the log
same => n,Return()
[Hangup_Handler] ; only used to show hangup reason
exten => _[+0-9*#s]!,1,Set(HANGUPCAUSE_STRING=${HANGUPCAUSE_KEYS()})
same => n,While(${EXISTS(${SET(Channel=${POP(HANGUPCAUSE_STRING)})})})
same => n,Verbose(0, Channel:"${CHANNEL(name)}" ToChannel:${Channel} CauseCode:"${HANGUPCAUSE(${Channel},tech)}", Asterisk:"${HANGUPCAUSE(${Channel},ast)}")
same => n,EndWhile()
same => n,Return()