[general]
static=yes
writeprotect=no
autofallthrough=no
clearglobalvars=no
priorityjumping=no

[globals]
#include local/dialplan_local.conf


;Extensions for PJSIP

;This subvourine sets a header if the corresponding Variable is not empty
[setheader]
exten => s,1,NoOp()
 same => n, GotoIf($["${ARG2}" == ""]?no_header)
 same => n, Set(PJSIP_HEADER(add,${ARG1})=${ARG2})
 same => n, Return()
 same => n(no_header), NoOp()
 same => n, Return()

[handle-outgoing-codecs]
exten => s,1,NoOp()
 same => n, GoToIf($["${ACODEC}" != "alaw"]?not_alaw)
 same => n,Set(PJSIP_MEDIA_OFFER(audio)=!all,alaw,g726,g722,ulaw)
 same => n(not_alaw),NoOp()

 same => n, GoToIf($["${ACODEC}" != "clearmode"]?not_clearmode)
 same => n,Set(PJSIP_MEDIA_OFFER(audio)=!all,clearmode)
 same => n(not_clearmode),NoOp()

 same => n, GoToIf($["${ACODEC}" != "g726"]?not_g726)
 same => n,Set(PJSIP_MEDIA_OFFER(audio)=!all,g726,alaw,g722,ulaw)
 same => n(not_g726),NoOp()

 same => n, GoToIf($["${ACODEC}" != "g722"]?not_g722)
 same => n,Set(PJSIP_MEDIA_OFFER(audio)=!all,g722,alaw,g726,ulaw)
 same => n(not_g722),NoOp()

 same => n, GoToIf($["${ACODEC}" != "ulaw"]?not_ulaw)
 same => n,Set(PJSIP_MEDIA_OFFER(audio)=!all,ulaw,alaw,g726,g722)
 same => n(not_ulaw),NoOp()

 same => n,Set(PJSIP_SEND_SESSION_REFRESH()=invite)
 same => n,Return()

;Set the outgoing headers
;In case the variable is empty, the above subroutine will not set a header
[set-outgoing-headers]
exten => s,1, NoOp()
 same => n, GoSub(setheader,s,1(X-HFO-MediaType,${HFOMTYPE}))
 same => n, GoSub(setheader,s,1(X-HFO-EM-USER,${EMUSER}))
 same => n, GoSub(setheader,s,1(X-HFO-EM-CID,${EMCID}))
 same => n, GoSub(setheader,s,1(X-HFO-EM-ACZ,${EMACZ}))
 same => n, GoSub(setheader,s,1(X-HFO-EM-ONK,${EMONK}))
 same => n, GoSub(setheader,s,1(Privacy,${PRIVACY}))
 same => n, GoSub(setheader,s,1(P-Preferred-Identity,${PPI}))
 same => n, GoSub(setheader,s,1(History-Info,${HISTORY}))
 same => n, GoSub(setheader,s,1(X-HFO-TID,${HFOTP}))
 same => n, GoSub(setheader,s,1(X-HFO-LNPINFO,${LNPINFO}))
 same => n, GoSub(setheader,s,1(X-HFO-PRELNPINFO,${PRELNPINFO}))
 same => n, GoSub(setheader,s,1(X-HFO-ALEG,${CIDALEG}))
 same => n, GoSub(setheader,s,1(X-HFO-NPN-A,${NPNA}))
 same => n, GoSub(setheader,s,1(X-HFO-NPN-A-T,${NPNAT}))
 same => n, GoSub(setheader,s,1(X-HFO-UPN-A,${UPNA}))
 same => n, Set(PJSIP_HEADER(add,X-HFO-DIR-B)=B)
; same => n, GoSub(handle-outgoing-codecs,s,1)
 same => n, Return()

;This subroutine sets headers to variables
;Variables starting with _are inherited to the outgoing channel.
;This is needed because we can only set the outgoing variables in a separate context
[headtovar]
exten => s,1,NoOP()
 same => n, Set(_HFOMTYPE=${PJSIP_HEADER(read,X-HFO-MediaType)})
 same => n, Set(_HFOTP=${PJSIP_HEADER(read,X-HFO-TID)})
 same => n, Set(_PPI=${PJSIP_HEADER(read,P-Preferred-Identity)})
 same => n, Set(_PRIVACY=${PJSIP_HEADER(read,Privacy)})
 same => n, Set(_HFOAWL=${PJSIP_HEADER(read,X-HFO-AWL)})
 same => n, Set(_HFOSRCNET=${PJSIP_HEADER(read,X-HFO-SRCNET)})
 same => n, Set(_HFOINPEER=${PJSIP_HEADER(read,X-HFO-INPEER)})
 same => n, Set(_HFODIR=${PJSIP_HEADER(read,X-HFO-DIR)})
 same => n, Set(_HISTORY=${PJSIP_HEADER(read,History-Info)})
 same => n, Set(_LNPINFO=${PJSIP_HEADER(read,X-HFO-LNPINFO)})
 same => n, Set(_PRELNPINFO=${PJSIP_HEADER(read,X-HFO-PRELNPINFO)})
 same => n, Set(_CIDALEG=${PJSIP_HEADER(read,Call-ID)})
 same => n, Set(_EMUSER=${PJSIP_HEADER(read,X-HFO-EM-USER)})
 same => n, Set(_EMCID=${PJSIP_HEADER(read,X-HFO-EM-CID)})
 same => n, Set(_EMACZ=${PJSIP_HEADER(read,X-HFO-EM-ACZ)})
 same => n, Set(_EMONK=${PJSIP_HEADER(read,X-HFO-EM-ONK)})
 same => n, Set(_NPNA=${PJSIP_HEADER(read,X-HFO-NPN-A)})
 same => n, Set(_NPNAT=${PJSIP_HEADER(read,X-HFO-NPN-A-T)})
 same => n, Set(_UPNA=${PJSIP_HEADER(read,X-HFO-UPN-A)})
 same => n, Return()

[from_sgw]
exten => s,1,Goto(_X.,1)
;New calls arive here
exten => _X.,1,NoOp()
;count calls
 same => n, Set(GROUP()=call_count)
 same => n, GotoIf($[${GROUP_COUNT(call_count)} > ${MAX_CALLS} ]?to_many_calls) 
;copy headers to variables
 same => n, Gosub(headtovar,s,1)
;Store Codec on A-Side
 same => n, Set(_ACODEC=${CHANNEL(audioreadformat)});
;determine length limit for call
 same => n,Set(LEN_LIMIT=14400) 
 same => n,GotoIf($["${PJSIP_HEADER(read,X-HFO-LEN-LIMIT)}" == ""]?no_len_limit)
 same => n,Set(LEN_LIMIT=${PJSIP_HEADER(read,X-HFO-LEN-LIMIT)})
 same => n(no_len_limit), NoOp()

;enable Fax gateway (t38 <-> G.711 conversion)
 same => n, Set(FAXOPT(gateway)=yes)
;dial out, this calls 
 same => n, Dial(PJSIP/sgw/sip:${EXTEN}@${CHANNEL(pjsip,remote_addr)},,b(set-outgoing-headers^s^1)S(${LEN_LIMIT}))
 same => n, Goto(s-${DIALSTATUS},1)
;If there are to many calls, drop it with 580
 same => n(to_many_calls), Hangup(580)

;These extensions handle hangup causes
exten => s-ANSWER,1,Hangup
exten => s-CONGESTION,1,Hangup
exten => s-CANCEL,1,Hangup
exten => s-INCOMPLETE,1,Hangup
exten => s-INVALID,1,Hangup
exten => s-NOANSWER,1,Hangup
exten => s-BUSY,1,Busy
exten => s-CHANUNAVAIL,1,Hangup
exten => T,1,Wait(1)
 same => n,Hangup
;On hangup write the CDR
exten => h,1,noop("CDR details for ${CALLERID(num)}")
 same => n,set(CDR(hangupcause)=${HANGUPCAUSE})
 same => n,set(CDR(uri)=${CHANNEL(pjsip,local_uri)})
 same => n,set(CDR(useragent)=${PJSIP_HEADER(read,User-Agent)})
 same => n,set(CDR(codec1)=${CHANNEL(audioreadformat)})
 same => n,set(CDR(codec2)=${CHANNEL(audiowriteformat)})
 same => n,set(CDR(llp)=${CHANNEL(rtcp,local_maxrxploss)})
 same => n,set(CDR(rlp)=${CHANNEL(rtcp,remote_maxrxploss)})
 same => n,set(CDR(ljitt)=${CHANNEL(rtcp,local_maxjitter)})
 same => n,set(CDR(rjitt)=${CHANNEL(rtcp,remote_maxjitter)})
 same => n,set(CDR(upna)=${UPNA})
 same => n,set(CDR(npna)=${NPNA})
 same => n,set(CDR(userfield)=${HFOTP})
