SIP trixbox 2.6 keine eingehende anrufe


Neuer User
Mitglied seit
3 Okt 2008
Punkte für Reaktionen

niemand da der mir noch einen tip geben könnte??????


Neuer User
Mitglied seit
3 Okt 2008
Punkte für Reaktionen

niemand mehr da der mir doch noch eventuell helfen könnte???

bin am verzweifeln.....


Neuer User
Mitglied seit
13 Aug 2008
Punkte für Reaktionen
ich habe eine ringgroup eingerichtet (alles ohne inbound Route) ... nun brauch ich aber für das Day/Night auch eine :(

egal welche DID ich eintrage, über inbound route kommt nichts an... wäre auch für ein Tipp dankbar...


Neuer User
Mitglied seit
3 Okt 2008
Punkte für Reaktionen
du brauchst auf jeden fall eine inbound route... die kannst du danach zum ring leiten!


Neuer User
Mitglied seit
13 Aug 2008
Punkte für Reaktionen
da die trixbox als unteranlage fungiert, geht es irgendwie auch ohne inbound route (es sei denn ich habe in meinem jugendlichen Wahnsinn in der config etwas manuell eingefügt)

aber egal ich brauh auf jeden fall eine inbound für das Day/Night feature...

Als Trunk ist folgendes eingerichtet "mISDN/1/$OUTNUM$", die auch für die outbound route genutzt wird

in der extensions habe ich folgendes eingefügt (ganz unten ab DEFAULT)... habe aber erst später gesehen das das in der Trixbox anderst konfiguriert wird als in asterisk mit den configs... habs aber sicherheitshalber mal drin gelassen

vll sieht ja jemand einen fehler :)

; do not edit this file, this is an auto-generated file by freepbx
; all modifications must be done from the web gui

; FreePBX
; Copyright (C) 2004 Coalescent Systems Inc (Canada)
; Copyright (C) 2006 Why Pay More 4 Less Pty Ltd (Australia)
; Copyright (C) 2007 Astrogen LLC (USA)
; Released under the GNU GPL Licence version 2.

; dialparties.agi (
; Asterisk::AGI (
; gsm (!INDEX.short.html)
; loligo sounds (
; mpg123 (

;**************************  -WARNING-  ****************************************
;                                                                              *
; This include file is to be used with extreme caution. In almost all cases    *
; any custom dialplan SHOULD be put in extensions_custom.conf which will       *
; not hurt freepbx generated dialplan. In some very rare and custom situation  *
; users have a need to override what freepbx generates. Anything in this file  *
; will do such.                                                                *
;                                                                              *
#include extensions_override_freepbx.conf
;                                                                              *
;**************************  -WARNING-  ****************************************

; include extension contexts generated from AMP
#include extensions_additional.conf

; Customizations to this dialplan should be made in extensions_custom.conf
; See extensions_custom.conf.sample for an example
#include extensions_custom.conf

[from-trunk]							; just an alias since VoIP shouldn't be called PSTN
include => from-pstn

include => from-pstn-custom                     ; create this context in extensions_custom.conf to include customizations
include => ext-did
include => from-did-direct		; MODIFICATOIN (PL) for findmefollow if enabled, should be bofore ext-local
include => ext-did-catchall		; THIS MUST COME AFTER ext-did
exten => fax,1,Goto(ext-fax,in_fax,1)

; Required to assure that direct dids go to personal ring group before local extension.
; This could be auto-generated however I it is prefered to be put here and hard coded
; so that it can be modified if ext-local should take precedence in certain situations.
; will have to decide what to do later.
include => ext-findmefollow
include => ext-local

; ############################################################################
; Macros [macro]
; ############################################################################

; Rings one or more extensions.  Handles things like call forwarding and DND
; We don't call dial directly for anything internal anymore.
; ARGS: $TIMER, $OPTIONS, $EXT1, $EXT2, $EXT3, ...
; Use a Macro call such as the following: 
;  Macro(dial,$DIAL_TIMER,$DIAL_OPTIONS,$EXT1,$EXT2,$EXT3,...)
exten => s,1,GotoIf($["${MOHCLASS}" = ""]?dial)
exten => s,n,SetMusicOnHold(${MOHCLASS})
exten => s,n(dial),AGI(dialparties.agi)
exten => s,n,NoOp(Returned from dialparties with no extensions to call and DIALSTATUS: ${DIALSTATUS})

exten => s,n+2(normdial),Dial(${ds})                               ; dialparties will set the priority to 10 if $ds is not null

exten => s,20(huntdial),NoOp(Returned from dialparties with hunt groups to dial )
exten => s,n,Set(HuntLoop=0)
exten => s,n(a22),GotoIf($[${HuntMembers} >= 1]?a30)  ; if this is from rg-group, don't strip prefix
exten => s,n,NoOp(Returning there are no members left in the hunt group to ring)

; dialparties.agi has setup the dialstring for each hunt member in a variable labeled HuntMember0, HuntMember1 etc for each iteration
; and The total number in HuntMembers. So for each iteration, we will update the CALLTRACE Data.
exten => s,n+2(a30),Set(HuntMember=HuntMember${HuntLoop})
exten => s,n,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "hunt" ]]?a32:a35)
exten => s,n(a32),Set(CT_EXTEN=${CUT(FILTERED_DIAL,,$[${HuntLoop} + 1])})
exten => s,n,Goto(s,a42)

;Set Call Trace for each hunt member we are going to call "Memory groups have multiple members to set CALL TRACE For hence the loop
exten => s,n(a35),GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "memoryhunt" ]]?a36:a50)  
exten => s,n(a36),Set(CTLoop=0)
exten => s,n(a37),GotoIf($[${CTLoop} > ${HuntLoop}]?a42)  ; if this is from rg-group, don't strip prefix
exten => s,n,Set(CT_EXTEN=${CUT(FILTERED_DIAL,,$[${CTLoop} + 1])})
exten => s,n,Set(CTLoop=$[1 + ${CTLoop}])
exten => s,n,Goto(s,a37)
exten => s,n(a42),Dial(${${HuntMember}}${ds})
exten => s,n,Set(HuntLoop=$[1 + ${HuntLoop}])
exten => s,n,GotoIf($[$[$["foo${RingGroupMethod}" != "foofirstavailable"] & $["foo${RingGroupMethod}" != "foofirstnotonphone"]] | $["foo${DialStatus}" = "fooBUSY"]]?a46)
exten => s,n,Set(HuntMembers=0)
exten => s,n(a46),Set(HuntMembers=$[${HuntMembers} - 1])
exten => s,n,Goto(s,a22)

exten => s,n(a50),DBdel(CALLTRACE/${CT_EXTEN})
exten => s,n,Goto(s,a42)

; make sure hungup calls go here so that proper cleanup occurs from call confirmed calls and the like
exten => h,1,Macro(hangupcall)

; Ring an extension, if the extension is busy or there is no answer send it
; to voicemail
exten => s,1,Macro(user-callerid)

exten => s,n,Set(RingGroupMethod=none)
exten => s,n,Set(VMBOX=${ARG1})
exten => s,n,Set(EXTTOCALL=${ARG2})
exten => s,n,Set(CFUEXT=${DB(CFU/${EXTTOCALL})})
exten => s,n,Set(CFBEXT=${DB(CFB/${EXTTOCALL})})
exten => s,n,Set(RT=${IF($[$["${VMBOX}"!="novm"] | $["foo${CFUEXT}"!="foo"]]?${RINGTIMER}:"")})
exten => s,n,Macro(record-enable,${EXTTOCALL},IN)

exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS},${EXTTOCALL})
exten => s,n,GosubIf($[$["${SV_DIALSTATUS}"="NOANSWER"] & $["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer
exten => s,n,GosubIf($[$["${SV_DIALSTATUS}"="BUSY"] & $["foo${CFBEXT}"!="foo"]]?docfb,1) ; check for CFB in use on busy
exten => s,n,NoOp(Voicemail is '${VMBOX}')
exten => s,n,GotoIf($["${VMBOX}" = "novm"]?s-${DIALSTATUS},1) ; no voicemail in use for this extension
exten => s,n,NoOp(Sending to Voicemail box ${EXTTOCALL})
exten => s,n,Macro(vm,${VMBOX},${DIALSTATUS})

; Try the Call Forward on No Answer / Unavailable number
exten => docfu,1,Set(RTCFU=${IF($["${VMBOX}"!="novm"]?${RINGTIMER}:"")})
exten => docfu,n,Dial(Local/${CFUEXT}@from-internal/n,${RTCFU},${DIAL_OPTIONS})
exten => docfu,n,Return

; Try the Call Forward on Busy number
exten => docfb,1,Set(RTCFB=${IF($["${VMBOX}"!="novm"]?${RINGTIMER}:"")})
exten => docfb,n,Dial(Local/${CFBEXT}@from-internal/n,${RTCFB},${DIAL_OPTIONS})
exten => docfb,n,Return

; Extensions with no Voicemail box reporting BUSY come here
exten => s-BUSY,1,NoOp(Extension is reporting BUSY and not passing to Voicemail)
exten => s-BUSY,n,Playtones(busy)
exten => s-BUSY,n,Busy(20)

; Anything but BUSY comes here
exten => _s-.,1,Playtones(congestion)
exten => _s-.,n,Congestion(10)

; [macro-vm]
; CONTEXT:      macro-vm
; PURPOSE:      call voicemail system and extend with personal ivr
; Under normal use, this macro will call the voicemail system with the extension and
; desired greeting mode of busy, unavailable or as specified with direct voicemail
; calls (usually unavailable) when entered from destinations.
; The voicemail system's two greetings have been 'hijacked' as follows to extend the
; system by giving the option of a private 'ivr' for each voicemail user. The following
; applies to both the busy and unavailable modes of voicemail and can be applied to one
; or both, and differently.
; Global Defaults:
; The following are default values, used in both busy and unavail modes if no specific
; values are specified.
;					The number of times to repeat the users message if no option is pressed.
;					The timeout to wait after playing message before repeating or giving up.
;					The number of times it should replay the message and check for an option when
;					an invalid option is pressed.
;					Default voicemail option to use if vm is chosen as an option. No options will
;					cause Allison's generic message, 's' will go straight to beep.
;					Default voicemail option to use if it times out with no options. No options will
;					cause Allison's generic message, 's' will go straight to beep.
;					IF THE USER PRESSES # - it will look like a timeout as well since no option will
;					be presented. If the user wishes to enable a mode where a caller can press #
;					during their message and it goes straight to voicemail with only a 'beep' then
;					this should be set to 's'.
;					Default voicemail option to use if to many wrong options occur. No options will
;					cause Allison's generic message, 's' will go straight to beep.
;					Default context for user destinations if not supplied in the user's settings
;					Default priority for user destinations if not supplied in the user's settings
;					Default context for timeout destination if not supplied in the user's settings
;					Default extension for timeout destination if not supplied in the user's settings
;					Default priority for timeout destination if not supplied in the user's settings
;					Default context for loops  destination if not supplied in the user's settings
;					Default extension for loops  destination if not supplied in the user's settings
;					Default priority for loops  destination if not supplied in the user's settings
; The AMPUSER database variable has been extended with a 'vmx' tree (vm-extension). A
; duplicate set is included for both unavail and busy. You could choose for to have an
; ivr when unavail is taken, but not with busy - or a different once with busy.
; The full list is below, each specific entry is futher described:
; state:		Whether teh current mode is enabled or disabled. Anything but 'enabled' is
;						treated as disabled.
; repeat:		This is the number of times that the users message should be played after the
;						timeout if the user has not entered anything. It is just a variable to the
;						Read() function which will do the repeating.
; timeout:	This is how long to wait after the message has been read for a response from
;						the user. A caller can enter a digit any time during the playback.
; loops:		This is the number of loops that the system will allow a caller to retry if
;						they enter a bad menu choice, before going to the loop failover destination
; vmxopts:	This is the vm options to send to the voicemail command used when a specific
;						voicemail destination is chosen (inidcated by 'dovm' in the ext field). This is
;						typically either set to 's' or left blank. When set to 's' there will be no
;						message played when entering the voicemail, just a beep. When blank, you will
;						have Allison's generic message played. It is not typical to play the greetings
;						since they have been 'hijacked' for these IVR's and from a caller's perspecitive
;						this system appears interconnected with the voicemail so instructions can be
;						left there.
; timedest: The three variables: ext, context and pri are the goto destination if the caller
;						enters no options and it timesout. None have to be set and a system default
;						will be used. If just ext is set, then defaults will be used for context and
;						pri, etc.
; loopdest:	This is identical to timedest but used if the caller exceeds the maximum invalid
;						menu choices.
; [0-9*]:		The user can specify up to 11 ivr options, all as single digits from 0-9 or *. The
;						# key can not be used since it is used as a terminator key for the Read command
;						and will never be returned. A minimum of the ext must be specified for each valid
;						option and as above, the context and priority can also be specified if the default
;						is not to be used.
;						Option '0' takes on a special meaning. Since a user is able to break out of the
;						voicemail command once entering it with a 0, if specified, the 0 destination will
;						be used.
;						Option '*' can also be used to breakout. It is undecided at this point whether
;						providing that option will be used as well. (probably should).
; /AMPUSER/<ext>/vmx/[busy|unavail]/state:								enabled|disabled
; /AMPUSER/<ext>/vmx/[busy|unavail]/repeat:								n (times to repeat message)
; /AMPUSER/<ext>/vmx/[busy|unavail]/timeout:							n (timeout to wait for digit)
; /AMPUSER/<ext>/vmx/[busy|unavail]/loops:								n (loop returies for invalid entries)
; /AMPUSER/<ext>/vmx/[busy|unavail]/vmxopts/dovm:					vmoptions (if ext is dovm)
; /AMPUSER/<ext>/vmx/[busy|unavail]/vmxopts/timeout:			vmoptions (if timeout)
; /AMPUSER/<ext>/vmx/[busy|unavail]/vmxopts/loops:				vmoptions (if loops)
; /AMPUSER/<ext>/vmx/[busy|unavail]/timedest/ext:					extension (if timeout)
; /AMPUSER/<ext>/vmx/[busy|unavail]/timedest/context:			context (if timeout)
; /AMPUSER/<ext>/vmx/[busy|unavail]/timedest/pri:					priority (if timeout)
; /AMPUSER/<ext>/vmx/[busy|unavail]/loopdest/ext:					extension (if too many failures)
; /AMPUSER/<ext>/vmx/[busy|unavail]/loopdest/context:			context (if too many failures)
; /AMPUSER/<ext>/vmx/[busy|unavail]/loopdest/pri:					priority (if too many failures)
; /AMPUSER/<ext>/vmx/[busy|unavail]/[0-9*]/ext:						extension (dovm for vm access)
; /AMPUSER/<ext>/vmx/[busy|unavail]/[0-9*]/context:				context 
; /AMPUSER/<ext>/vmx/[busy|unavail]/[0-9*]/pri:						priority 
; ARG1 - extension
; ARG3 - RETURN makes macro return, otherwise hangup
exten => s,1,Macro(user-callerid,SKIPTTL)
exten => s,n,Set(VMGAIN=${IF($["foo${VM_GAIN}"!="foo"]?"g(${VM_GAIN})":"")})
; If BLKVM_OVERRIDE is set, then someone told us to block calls from going to
; voicemail. This variable is reset by the answering channel so subsequent
; transfers will properly function.
exten => s,n,GotoIf($["foo${DB(${BLKVM_OVERRIDE})}" != "fooTRUE"]?vmx,1)
; we didn't branch so block this from voicemail
exten => s,n,Noop(CAME FROM: ${NODEST} - Blocking VM cause of key: ${DB(BLKVM_OVERRIDE)})

; If vmx not enabled for the current mode,then jump to normal voicemail behavior
; also - if not message (no-msg) is requested, straight to voicemail
exten => vmx,1,GotoIf($["${ARG2}"="NOMESSAGE"]?s-${ARG2},1)
exten => vmx,n,Set(MODE=${IF($["${ARG2}"="BUSY"]?busy:unavail)})
exten => vmx,n,GotoIf($["${ARG2}" != "DIRECTDIAL"]?notdirect)
exten => vmx,n,Set(MODE=${IF($["${REGEX("[b]" ${VM_DDTYPE})}" = "1"]?busy:${MODE})})
exten => vmx,n(notdirect),Noop(Checking if ext ${ARG1} is enabled: ${DB(AMPUSER/${ARG1}/vmx/${MODE}/state)})
exten => vmx,n,GotoIf($["${DB(AMPUSER/${ARG1}/vmx/${MODE}/state)}" != "enabled"]?s-${ARG2},1)

; If the required voicemail file does not exist, then abort and go to normal voicemail behavior
; TODO: there have been errors using System() with jump to 101 where asterisk works fine at the begining and
;       then starts to jump to 101 even on success. This new mode is being tried with the SYSTEM Status which
;       returns SUCCESS when the command returned succcessfully with a 0 app return code.
exten => vmx,n,Macro(get-vmcontext,${ARG1})
;exten => vmx,n,TrySystem(/bin/ls ${ASTSPOOLDIR}/voicemail/${VMCONTEXT}/${ARG1}/${MODE}.[wW][aA][vV])
exten => vmx,n,AGI(checksound.agi,${ASTSPOOLDIR}/voicemail/${VMCONTEXT}/${ARG1}/temp)
exten => vmx,n,GotoIf($["${SYSTEMSTATUS}" = "SUCCESS"]?tmpgreet)
exten => vmx,n,AGI(checksound.agi,${ASTSPOOLDIR}/voicemail/${VMCONTEXT}/${ARG1}/${MODE})
exten => vmx,n,GotoIf($["${SYSTEMSTATUS}" != "SUCCESS"]?nofile)

; Get the repeat, timeout and loop times to use if they are overriden form the global settings
exten => vmx,n,Set(LOOPCOUNT=0)
exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/repeat)}" = "0"]?vmxtime)
exten => vmx,n,Set(VMX_REPEAT=${DB_RESULT})
exten => vmx,n(vmxtime),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timeout)}" = "0"]?vmxloops)
exten => vmx,n,Set(VMX_TIMEOUT=${DB_RESULT})
exten => vmx,n(vmxloops),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/loops)}" = "0"]?vmxanswer)
exten => vmx,n,Set(VMX_LOOPS=${DB_RESULT})
exten => vmx,n(vmxanswer),Answer()

; Now play the users voicemail recording as the basis for their ivr, the Read command will repeat as needed and if it timesout
; then we go to the timeout. Otherwise handle invalid options by looping until the limit until a valid option is played.
exten => vmx,n(loopstart),Read(ACTION,${ASTSPOOLDIR}/voicemail/${VMCONTEXT}/${ARG1}/${MODE},1,skip,${VMX_REPEAT},${VMX_TIMEOUT})
exten => vmx,n,GotoIf($["${EXISTS(${ACTION})}" = "1"]?checkopt)

; If we are here we timed out, go to the required destination
exten => vmx,n(noopt),Noop(Timeout: going to timeout dest)
exten => vmx,n,Set(VMX_OPTS=${VMX_OPTS_TIMEOUT})
exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/vmxopts/timeout)}" = "0"]?chktime)
exten => vmx,n,Set(VMX_OPTS=${DB_RESULT})
exten => vmx,n(chktime),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timedest/ext)}" = "0"]?dotime)
exten => vmx,n,Set(VMX_TIMEDEST_EXT=${DB_RESULT})
exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timedest/context)}" = "0"]?timepri)
exten => vmx,n(timepri),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timedest/pri)}" = "0"]?dotime)
exten => vmx,n,Set(VMX_TIMEDEST_PRI=${DB_RESULT})

; We got an option, check if the option is defined, or one of the system defaults
exten => vmx,n(checkopt),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/${ACTION}/ext)}" = "1"]?doopt)
exten => vmx,n,GotoIf($["${ACTION}" = "0"]?o,1)
exten => vmx,n,GotoIf($["${ACTION}" = "*"]?adef,1)

; Got invalid option loop until the max
exten => vmx,n,Set(LOOPCOUNT=$[${LOOPCOUNT} + 1])
exten => vmx,n,GotoIf($[${LOOPCOUNT} > ${VMX_LOOPS}]?toomany)
exten => vmx,n,Playback(pm-invalid-option&please-try-again)
exten => vmx,n,Goto(loopstart)

; tomany: to many invalid options, go to the specified destination
exten => vmx,n(toomany),Noop(Too Many invalid entries, got to invalid dest)
exten => vmx,n,Set(VMX_OPTS=${VMX_OPTS_LOOPS})
exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/vmxopts/loops)}" = "0"]?chkloop)
exten => vmx,n,Set(VMX_OPTS=${DB_RESULT})
exten => vmx,n(chkloop),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/loopdest/ext)}" = "0"]?doloop)
exten => vmx,n,Set(VMX_LOOPDEST_EXT=${DB_RESULT})
exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/loopdest/context)}" = "0"]?looppri)
exten => vmx,n,Set(VMX_LOOPDEST_CONTEXT=${DB_RESULT}) ;TODO make configurable per above
exten => vmx,n(looppri),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/loopdest/pri)}" = "0"]?doloop)
exten => vmx,n,Set(VMX_LOOPDEST_PRI=${DB_RESULT}) ;TODO make configurable per above

; doopt: execute the valid option that was chosen
exten => vmx,n(doopt),Noop(Got a valid option: ${DB_RESULT})
exten => vmx,n,Set(VMX_EXT=${DB_RESULT})
; Special case, if this option was to go to voicemail, set options and go
exten => vmx,n,GotoIf($["${VMX_EXT}" != "dovm"]?getdest)
exten => vmx,n(vmxopts),Set(VMX_OPTS=${VMX_OPTS_DOVM})
exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/vmxopts/dovm)}" = "0"]?vmxdovm)
exten => vmx,n(vmxopts),Set(VMX_OPTS=${DB_RESULT})
exten => vmx,n(vmxdovm),goto(dovm,1)
; General case, setup the goto destination and go there (no error checking, its up to the GUI's to assure
; reasonable values
exten => vmx,n(getdest),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/${ACTION}/context)}" = "0"]?vmxpri)
exten => vmx,n,Set(VMX_CONTEXT=${DB_RESULT})
exten => vmx,n(vmxpri),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/${ACTION}/pri)}" = "0"]?vmxgoto)
exten => vmx,n,Set(VMX_PRI=${DB_RESULT})
exten => vmx,n(vmxgoto),Goto(${VMX_CONTEXT},${VMX_EXT},${VMX_PRI})

; If the required voicemail file is not present, then revert to normal voicemail
; behavior treating as if it was not set
exten => vmx,n(nofile),Noop(File for mode: ${MODE} does not exist, SYSTEMSTATUS: ${SYSTEMSTATUS}, going to normal voicemail)
exten => vmx,n,Goto(s-${ARG2},1)
exten => vmx,n(tmpgreet),Noop(Temporary Greeting Detected, going to normal voicemail)
exten => vmx,n,Goto(s-${ARG2},1)

; Drop into voicemail either as a direct destination (in which case VMX_OPTS might be set to something) or
; if the user timed out or broke out of the loop then VMX_OPTS is always cleared such that an Allison
; message is played and the caller know's what is going on.
exten => dovm,1,Noop(VMX Timeout - go to voicemail)
exten => dovm,n,Voicemail(${ARG1}@${VMCONTEXT},${VMX_OPTS}${VMGAIN}) ; no flags, so allison plays please leave ...
exten => dovm,n,Goto(exit-${VMSTATUS},1)

exten => s-BUSY,1,NoOp(BUSY voicemail)
exten => s-BUSY,n,Macro(get-vmcontext,${ARG1})
exten => s-BUSY,n,Voicemail(${ARG1}@${VMCONTEXT},${VM_OPTS}b${VMGAIN})   ; Voicemail Busy message
exten => s-BUSY,n,Goto(exit-${VMSTATUS},1)

exten => s-NOMESSAGE,1,NoOp(NOMESSAGE (beeb only) voicemail)
exten => s-NOMESSAGE,n,Macro(get-vmcontext,${ARG1})
exten => s-NOMESSAGE,n,Voicemail(${ARG1}@${VMCONTEXT},s${VM_OPTS}${VMGAIN})
exten => s-NOMESSAGE,n,Goto(exit-${VMSTATUS},1)

exten => s-DIRECTDIAL,1,NoOp(DIRECTDIAL voicemail)
exten => s-DIRECTDIAL,n,Macro(get-vmcontext,${ARG1})
exten => s-DIRECTDIAL,n,Voicemail(${ARG1}@${VMCONTEXT},${VM_OPTS}${VM_DDTYPE}${VMGAIN})
exten => s-DIRECTDIAL,n,Goto(exit-${VMSTATUS},1)

exten => _s-.,1,Macro(get-vmcontext,${ARG1})
exten => _s-.,n,Voicemail(${ARG1}@${VMCONTEXT},${VM_OPTS}u${VMGAIN})     ; Voicemail Unavailable message
exten => _s-.,n,Goto(exit-${VMSTATUS},1)

; If the user has a 0 option defined, use that for operator zero-out from within voicemail
; as well to keep it consistant with the menu structure
exten => o,1,Background(one-moment-please)      ; 0 during vm message will hangup
exten => o,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/0/ext)}" = "0"]?doopdef)

exten => o,n,Set(VMX_OPDEST_EXT=${DB_RESULT})
exten => o,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/0/context)}" = "1"]?opcontext)
exten => o,n,Set(DB_RESULT=${VMX_CONTEXT})
exten => o,n(opcontext),Set(VMX_OPDEST_CONTEXT=${DB_RESULT})
exten => o,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/0/pri)}" = "1"]?oppri)
exten => o,n,Set(DB_RESULT=${VMX_PRI})
exten => o,n(oppri),Set(VMX_OPDEST_PRI=${DB_RESULT})

exten => o,n(doopdef),GotoIf($["x${OPERATOR_XTN}"="x"]?nooper:from-internal,${OPERATOR_XTN},1)
exten => o,n(nooper),GotoIf($["x${FROM_DID}"="x"]?nodid)
exten => o,n,Dial(Local/${FROM_DID)@from-pstn)
exten => o,n,Macro(hangup)
exten => o,n(nodid),Dial(Local/[email protected])
exten => o,n,Macro(hangup)

; If the user has a * option defined, use that for the * out from within voicemail
; as well to keep it consistant with the menu structure
exten => a,1,Macro(get-vmcontext,${ARG1})
exten => a,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/*/ext)}" = "0"]?adef,1)

exten => a,n,Set(VMX_ADEST_EXT=${DB_RESULT})
exten => a,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/*/context)}" = "1"]?acontext)
exten => a,n,Set(DB_RESULT=${VMX_CONTEXT})
exten => a,n(acontext),Set(VMX_ADEST_CONTEXT=${DB_RESULT})
exten => a,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/*/pri)}" = "1"]?apri)
exten => a,n,Set(DB_RESULT=${VMX_PRI})
exten => a,n(apri),Set(VMX_ADEST_PRI=${DB_RESULT})

exten => adef,1,VoiceMailMain(${ARG1}@${VMCONTEXT})
exten => adef,n,Hangup

exten => exit-FAILED,1,Playback(im-sorry&an-error-has-occured)
exten => exit-FAILED,n,GotoIf($["${ARG3}" = "RETURN"]?exit-RETURN,1)
exten => exit-FAILED,n,Hangup()

exten => exit-SUCCESS,1,GotoIf($["${ARG3}" = "RETURN"]?exit-RETURN,1)
exten => exit-SUCCESS,n,Playback(goodbye)
exten => exit-SUCCESS,n,Hangup()

exten => exit-USEREXIT,1,GotoIf($["${ARG3}" = "RETURN"]?exit-RETURN,1)
exten => exit-USEREXIT,n,Playback(goodbye)
exten => exit-USEREXIT,n,Hangup()

exten => exit-RETURN,1,Noop(Returning From Voicemail because macro)

exten => t,1,Hangup()

; [macro-simple-dial]
; This macro was derived from macro-exten-vm, which is what is normally used to
; ring an extension. It has been simplified and designed to never go to voicemail
; and always return regardless of the DIALSTATUS for any incomplete call.
; It's current primary purpose is to allow findmefollow ring an extension prior
; to trying the follow-me ringgroup that is provided.
; Ring an extension, if the extension is busy or there is no answer, return
exten => s,1,Macro(user-callerid,SKIPTTL) ; already called from follow-me

; FROMCONTEXT was in the original macro-exten-vm where this macro was derived from. A
; search through all the modules does not come up with any place using this
; variable, but it is left here as a reminder in case there is functionality
; that eventually behaves in a certain way as a result of this variable being set
; and this macro has to masquerade as exten-vm.
exten => s,n,Set(EXTTOCALL=${ARG1})
exten => s,n,Set(RT=${ARG2})
exten => s,n,Set(CFUEXT=${DB(CFU/${EXTTOCALL})})
exten => s,n,Set(CFBEXT=${DB(CFB/${EXTTOCALL})})
exten => s,n,Macro(record-enable,${EXTTOCALL},IN)

exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS},${EXTTOCALL})


; if we return, thus no answer, and they have a CFU setting, then  we try that next
exten => s,n,GosubIf($[$["${PR_DIALSTATUS}"="NOANSWER"] & $["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer
exten => s,n,GosubIf($[$["${PR_DIALSTATUS}"="BUSY"] & $["foo${CFBEXT}"!="foo"]]?docfb,1) ; check for CFB in use on busy

; Nothing yet, then go to the end (which will just return, but in case we decide to do something with certain
; return situations, this is left in.
exten => s,n,Goto(s-${DIALSTATUS},1)

; Try the Call Forward on No Answer / Unavailable number.
; We want to try CFU if set, but we want the same ring timer as was set to our call (or do we want the
; system ringtimer? - probably not). Then if no answer there (assuming it doesn't drop into their vm or
; something we return, which will have the net effect of returning to the followme setup.)
; want to avoid going to other follow-me settings here. So check if the CFUEXT is a user and if it is
; then direct it straight to ext-local (to avoid getting intercepted by findmefollow) otherwise send it
; to from-internal since it may be an outside line.
exten => docfu,1,GotoIf( $[ "foo${DB(AMPUSER/${CFUEXT}/device)}" = "foo" ]?chlocal)
exten => docfu,n,Dial(Local/${CFUEXT}@ext-local,${RT},${DIAL_OPTIONS})
exten => docfu,n,Return
exten => docfu,n(chlocal),Dial(Local/${CFUEXT}@from-internal/n,${RT},${DIAL_OPTIONS})
exten => docfu,n,Return

; Try the Call Forward on Busy number
exten => docfb,1,GotoIf( $[ "foo${DB(AMPUSER/${CFBEXT}/device)}" = "foo" ]?chlocal)
exten => docfb,n,Dial(Local/${CFBEXT}@ext-local,${RT},${DIAL_OPTIONS})
exten => docfb,n,Return
exten => docfb,n(chlocal),Dial(Local/${CFBEXT}@from-internal/n,${RT},${DIAL_OPTIONS})
exten => docfb,n,Return

; In all cases of no connection, come here and simply return, since the calling dialplan will
; decide what to do next
exten => _s-.,1,NoOp(Extension is reporting ${EXTEN})

; get the voicemail context for the user in ARG1
exten => s,1,Set(VMCONTEXT=${DB(AMPUSER/${ARG1}/voicemail)})
exten => s,2,GotoIf($["foo${VMCONTEXT}" = "foo"]?200:300)
exten => s,200,Set(VMCONTEXT=default)
exten => s,300,NoOp()

; For some reason, if I don't run setCIDname, CALLERID(name) will be blank in my AGI
; ARGS: none
exten => s,1,Set(CALLERID(name)=${CALLERID(name)})

; Ring groups of phones
; ARGS: comma separated extension list
; 1 - Ring Group Strategy
; 2 - ringtimer
; 3 - prefix
; 4 - extension list
exten => s,1,Macro(user-callerid,SKIPTTL) ; already called from ringgroup
exten => s,2,GotoIf($["${CALLERID(name):0:${LEN(${RGPREFIX})}}" != "${RGPREFIX}"]?4:3)  ; check for old prefix
exten => s,3,Set(CALLERID(name)=${CALLERID(name):${LEN(${RGPREFIX})}}) ; strip off old prefix
exten => s,4,Set(RGPREFIX=${ARG3})  ; set new prefix
exten => s,5,Set(CALLERID(name)=${RGPREFIX}${CALLERID(name)})  ; add prefix to callerid name
exten => s,6,Set(RecordMethod=Group)  ; set new prefix
exten => s,7,Macro(record-enable,${MACRO_EXTEN},${RecordMethod})
exten => s,8,Set(RingGroupMethod=${ARG1})     ;
exten => s,9,Macro(dial,${ARG2},${DIAL_OPTIONS},${ARG4})
exten => s,10,Set(RingGroupMethod='')     ;

; Outgoing channel(s) are busy ... inform the client
; but use noanswer features like ringgroups don't break by being answered
; just to play the message.
exten => s,1,Playback(all-circuits-busy-now,noanswer)
exten => s,n,Playback(pls-try-call-later,noanswer)
exten => s,n,Macro(hangupcall)

; What to do on hangup.                                         
exten => s,1,ResetCDR(w)
exten => s,n,NoCDR()
; Cleanup any remaining RG flag
exten => s,n,GotoIf($[ "x${USE_CONFIRMATION}" = "x" | "x${RINGGROUP_INDEX}" = "x" | "${CHANNEL}" != "${UNIQCHAN}"]?skiprg)
exten => s,n,Noop(Cleaning Up Confirmation Flag: RG/${RINGGROUP_INDEX}/${CHANNEL})
exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL})

; Cleanup any remaining BLKVM flag
exten => s,n(skiprg),GotoIf($[ "x${BLKVM_BASE}" = "x" | "BLKVM/${BLKVM_BASE}/${CHANNEL}" != "${BLKVM_OVERRIDE}" ]?skipblkvm)
exten => s,n,Noop(Cleaning Up Block VM Flag: ${BLKVM_OVERRIDE})
exten => s,n,DBDel(${BLKVM_OVERRIDE})

; Cleanup any remaining FollowMe DND flags
exten => s,n(skipblkvm),GotoIf($[ "x${FMGRP}" = "x" | "x${FMUNIQUE}" = "x" | "${CHANNEL}" != "${FMUNIQUE}" ]?theend)
exten => s,n,DBDel(FM/DND/${FMGRP}/${CHANNEL})

exten => s,n(theend),Hangup

exten => s,1,Set(FAXFILE=${ASTSPOOLDIR}/fax/${UNIQUEID}.tif)
exten => s,2,Set(EMAILADDR=${FAX_RX_EMAIL})
exten => s,3,rxfax(${FAXFILE})
exten => s,103,Set(EMAILADDR=${FAX_RX_EMAIL})
exten => s,104,Goto(3)

; dialout and strip the prefix
exten => s,1,Macro(user-callerid,SKIPTTL)
exten => s,2,GotoIf($["${ECID${CALLERID(number)}}" = ""]?5) 	;check for CID override for exten
exten => s,3,Set(CALLERID(all)=${ECID${CALLERID(number)}})
exten => s,4,Goto(7)
exten => s,5,GotoIf($["${OUTCID_${ARG1}}" = ""]?7) 		;check for CID override for trunk
exten => s,6,Set(CALLERID(all)=${OUTCID_${ARG1}})
exten => s,7,Set(length=${LEN(${DIAL_OUT_${ARG1}})})
exten => s,8,Dial(${OUT_${ARG1}}/${ARG2:${length}})
exten => s,9,Playtones(congestion)
exten => s,10,Congestion(5)
exten => s,109,Macro(outisbusy)

; dialout using default OUT trunk - no prefix
exten => s,1,Macro(user-callerid,SKIPTTL)
exten => s,2,Macro(record-enable,${CALLERID(number)},OUT)
exten => s,3,Macro(outbound-callerid,${ARG1})
exten => s,4,Dial(${OUT}/${ARG1})
exten => s,5,Playtones(congestion)
exten => s,6,Congestion(5)
exten => s,105,Macro(outisbusy)

; this macro intentially left blank so it may be safely overwritten for any custom
; requirements that an installatin may have.
;                    if set to "BYPASS" then this trunk will be skipped

exten => s,1,GotoIf($[${LEN(${BLINDTRANSFER})} > 0]?2:4)
exten => s,2,ResetCDR(w)
exten => s,3,StopMonitor()
exten => s,4,AGI(recordingcheck,${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},${UNIQUEID})
exten => s,5,Noop(No recording needed) 
exten => s,999,MixMonitor(${CALLFILENAME}.wav)

;exten => s,3,BackGround(for-quality-purposes)
;exten => s,4,BackGround(this-call-may-be)
;exten => s,5,BackGround(recorded)

; This macro is for dev purposes and just dumps channel/app variables.  Useful when designing new contexts. 
exten => s,4,Noop(CALLERID=${CALLERID(all)})
exten => s,5,Noop(CALLERID(name)=${CALLERID(name)})
exten => s,6,Noop(CALLERID(number)=${CALLERID(number)})
exten => s,8,Noop(CHANNEL=${CHANNEL})
exten => s,9,Noop(CONTEXT=${CONTEXT})
exten => s,10,Noop(DATETIME=${DATETIME})
exten => s,13,Noop(DIALEDTIME=${DIALEDTIME})
exten => s,14,Noop(DIALSTATUS=${DIALSTATUS})
exten => s,15,Noop(DNID=${DNID})
exten => s,16,Noop(EPOCH=${EPOCH})
exten => s,17,Noop(EXTEN=${EXTEN})
exten => s,18,Noop(HANGUPCAUSE=${HANGUPCAUSE})
exten => s,19,Noop(INVALID_EXTEN=${INVALID_EXTEN})
exten => s,20,Noop(LANGUAGE=${LANGUAGE})
exten => s,21,Noop(MEETMESECS=${MEETMESECS})
exten => s,22,Noop(PRIORITY=${PRIORITY})
exten => s,23,Noop(RDNIS=${RDNIS})
exten => s,24,Noop(SIPDOMAIN=${SIPDOMAIN})
exten => s,25,Noop(SIP_CODEC=${SIP_CODEC})
exten => s,26,Noop(SIPCALLID=${SIPCALLID})
exten => s,29,Noop(TXTCIDNAME=${TXTCIDNAME})
exten => s,30,Noop(UNIQUEID=${UNIQUEID})
exten => s,31,Noop(TOUCH_MONITOR=${TOUCH_MONITOR})
exten => s,32,Noop(MACRO_CONTEXT=${MACRO_CONTEXT})
exten => s,33,Noop(MACRO_EXTEN=${MACRO_EXTEN})

; check device type
exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})
exten => s,n,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)
; get user's extension
exten => s,n,Set(AMPUSER=${ARG1})
exten => s,n,GotoIf($["${AMPUSER}" != ""]?gotpass)
exten => s,n,Playback(please-enter-your&extension)
exten => s,n,Read(AMPUSER,then-press-pound)
; get user's password and authenticate
exten => s,n(gotpass),Set(AMPUSERPASS=${DB(AMPUSER/${AMPUSER}/password)})
exten => s,n,GotoIf($[${LEN(${AMPUSERPASS})} = 0]?s-NOPASSWORD,1)
; do not continue if the user has already logged onto this device
exten => s,n,Set(DEVICEUSER=${DB(DEVICE/${CALLERID(number)}/user)})
exten => s,n,GotoIf($["${DEVICEUSER}" = "${AMPUSER}"]?s-ALREADYLOGGEDON,1)
exten => s,n,Authenticate(${AMPUSERPASS})
exten => s,n,DeadAGI(user_login_out.agi,login,${CALLERID(number)},${AMPUSER})
exten => s,n,Playback(vm-goodbye)

exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged into)
exten => s-FIXED,n,Playback(ha/phone)
exten => s-FIXED,n,SayDigits(${CALLERID(number)})
exten => s-FIXED,n,Playback(is-curntly-unavail&vm-goodbye)
exten => s-FIXED,n,Hangup ;TODO should play msg indicated device cannot be logged into 

exten => s-ALREADYLOGGEDON,1,NoOp(This device has already been logged into by this user)
exten => s-ALREADYLOGGEDON,n,Playback(vm-goodbye)
exten => s-ALREADYLOGGEDON,n,Hangup ;TODO should play msg indicated device is already logged into 

exten => s-NOPASSWORD,1,NoOp(This extension does not exist or no password is set)
exten => s-NOPASSWORD,n,Playback(an-error-has-occured&vm-goodbye)
exten => s-NOPASSWORD,n,Hangup ;TODO should play msg indicated device is already logged into 

; check device type
exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})
exten => s,n,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)
exten => s,n,DeadAGI(user_login_out.agi,logout,${CALLERID(number)})
exten => s,n(done),Playback(vm-goodbye)

exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged out of)
exten => s-FIXED,n,Playback(an-error-has-occured&vm-goodbye)
exten => s-FIXED,n,Hangup ;TODO should play msg indicated device cannot be logged into 

; Privacy Manager Macro makes sure that any calls that don't pass the privacy manager are presented
; with congestion since there have been observed cases of the call continuing if not stopped with a 
; congestion, and this provides a slightly more friendly 'sorry' message in case the user is
; legitamately trying to be cooperative. 
; Note: the following options are configurable in privacy.conf:
;	maxretries = 3 ; default value, number of retries before failing
;	minlength = 10 ; default value, number of digits to be accepted as valid CID
exten => s,1,Set(KEEPCID=${CALLERID(num)})
exten => s,n,GotoIf($["foo${CALLERID(num):0:1}"="foo+"]?CIDTEST2:CIDTEST1)
exten => s,n(CIDTEST1),Set(TESTCID=${MATH(1+${CALLERID(num)})})
exten => s,n,Goto(TESTRESULT)
exten => s,n(CIDTEST2),Set(TESTCID=${MATH(1+${CALLERID(num):1})})
exten => s,n(TESTRESULT),GotoIf($["foo${TESTCID}"="foo"]?CLEARCID:PRIVMGR)
exten => s,n(CLEARCID),Set(CALLERID(num)=)
exten => s,n(PRIVMGR),PrivacyManager()
exten => s,n,GotoIf($["${PRIVACYMGRSTATUS}"="FAILED"]?fail)
exten => s,n,SetCallerPres(allowed_passed_screen); stop gap until app_privacy.c clears unavailble bit
exten => s,n,Playback(sorry-youre-having-problems)
exten => s,n,Playback(goodbye)
exten => s,n,Playtones(congestion)
exten => s,n,Congestion(5)

; Text-To-Speech related macros
; These all follow common actions.  First try to playback a file "tts/custom-md5" 
; where "md5" is the md5() of whatever is going to be played. If that doesn't exist,
; try to playback using macro-tts-sayXXXXX (where XXXXX is text/digits/etc, same as
; the macro below). If that macro exits with MACRO_OFFSET=100, then it's done, 
; therwise, fallback to the default asterisk method. 
; say text is purely for text-to-speech, there is no fallback
exten => s,1,Noop(Trying custom SayText playback for "${ARG1}")
exten => s,n,Playback(tts/custom-${MD5(${ARG1})})
exten => s,n,GotoIf($["${PLAYBACKSTATUS}"="SUCCESS"]?done)
; call tts-saytext. This should set MACRO_OFFSET=101 if it was successful
exten => s,n(tts),Macro(tts-saytext,${ARG1},${ARG2},${ARG3})
exten => s,n,Noop(No text-to-speech handler for SayText, cannot say "${ARG1}")
exten => s,n,Goto(done)
exten => s,tts+101,Noop(tts handled saytext)

; say name is for saying names typically, but fallsback to using SayAlpha
; (saying the word letter-by-letter)
exten => s,1,Noop(Trying custom SayName playback for "${ARG1}")
exten => s,n,Playback(tts/custom-${MD5(${ARG1})})
exten => s,n,GotoIf($["${PLAYBACKSTATUS}"="SUCCESS"]?done)
; call tts-sayalpha. This should set MACRO_OFFSET=101 if it was successful
exten => s,n(tts),Macro(tts-sayalpha,${ARG1},${ARG2},${ARG3})
exten => s,n,SayAlpha(${ARG1})
exten => s,n,Goto(done)
exten => s,tts+101,Noop(tts handled sayname)

; Say number is for saying numbers (eg "one thousand forty six") 
exten => s,1,Noop(Trying custom SayNumber playback for "${ARG1}")
exten => s,n,Playback(tts/custom-${MD5(${ARG1})})
exten => s,n,GotoIf($["${PLAYBACKSTATUS}"="SUCCESS"]?done)
; call tts-saynumber. This should set MACRO_OFFSET=101 if it was successful
exten => s,n(tts),Macro(tts-saynumber,${ARG1},${ARG2},${ARG3})
exten => s,n,SayNumber(${ARG1})
exten => s,n,Goto(done)
exten => s,tts+101,Noop(tts handled saynumber)

; Say digits is for saying digits one-by-one (eg, "one zero four six")
exten => s,1,Noop(Trying custom SayDigits playback for "${ARG1}")
exten => s,n,Playback(tts/custom-${MD5(${ARG1})})
exten => s,n,GotoIf($["${PLAYBACKSTATUS}"="SUCCESS"]?done)
; call tts-saydigits. This should set MACRO_OFFSET=101 if it was successful
exten => s,n(tts),Macro(tts-saydigits,${ARG1},${ARG2},${ARG3})
exten => s,n,SayDigits(${ARG1})
exten => s,n,Goto(done)

; ############################################################################
; Inbound Contexts [from]
; ############################################################################

;give external sip users congestion and hangup
; Yes. This is _really_ meant to be _. - I know asterisk whinges about it, but 
; I do know what I'm doing. This is correct.
exten => _.,1,NoOp(Received incoming SIP connection from unknown peer to ${EXTEN})
exten => _.,n,Set(DID=${IF($["${EXTEN:1:2}"=""]?s:${EXTEN})})
exten => _.,n,Goto(s,1)
exten => s,1,GotoIf($["${ALLOW_SIP_ANON}"="yes"]?from-trunk,${DID},1)
exten => s,n,Set(TIMEOUT(absolute)=15)
exten => s,n,Answer
exten => s,n,Wait(2)
exten => s,n,Playback(ss-noservice)
exten => s,n,Playtones(congestion)
exten => s,n,Congestion(5)
exten => h,1,NoOp(Hangup)
exten => i,1,NoOp(Invalid)
exten => t,1,NoOp(Timeout)

; applications are now mostly all found in from-internal-additional in _custom.conf
include => parkedcalls
include => from-internal-custom
;allow phones to dial other extensions
include => ext-fax
;allow phones to access generated contexts
; Currently the include for findmefollow is being auto-generated before ext-local which is the desired behavior.
; However, I haven't been able to do anything that I know of to force this. We need to determine if it should
; be hardcoded into here to make sure it doesn't change with some configuration. For now I will leave it out
; until we can discuss this.
include => ext-local-confirm
include => findmefollow-ringallv2
include => from-internal-additional
; This causes grief with '#' transfers, commenting out for the moment.
; include => bad-number
exten => s,1,Macro(hangupcall)
exten => h,1,Macro(hangupcall)

include => from-internal-xfer
include => bad-number

exten => _X.,1,Set(DID=${EXTEN})
exten => _X.,n,Goto(s,1)
exten => s,1,NoOp(Entering from-zaptel with DID == ${DID})
; Some trunks _require_ a RINGING be sent before an Answer. 
exten => s,n,Ringing()
; If ($did == "") { $did = "s"; }
exten => s,n,Set(DID=${IF($["${DID}"= ""]?s:${DID})})
exten => s,n,NoOp(DID is now ${DID})
exten => s,n,GotoIf($["${CHANNEL:0:3}"="Zap"]?zapok:notzap)
exten => s,n(notzap),Goto(from-pstn,${DID},1)
; If there's no ext-did,s,1, that means there's not a no did/no cid route. Hangup.
exten => s,n,Macro(hangup)
exten => s,n(zapok),NoOp(Is a Zaptel Channel)
exten => s,n,Set(CHAN=${CHANNEL:4})
exten => s,n,Set(CHAN=${CUT(CHAN,-,1)})
exten => s,n,Macro(from-zaptel-${CHAN},${DID},1)
; If nothing there, then treat it as a DID
exten => s,n,NoOp(Returned from Macro from-zaptel-${CHAN})
exten => s,n,Goto(from-pstn,${DID},1)
exten => fax,1,Goto(ext-fax,in_fax,1)

; [macro-setmusic]
; CONTEXT:      macro-setmusic
; PURPOSE:      to turn off moh on routes where it is not desired
exten => s,1,NoOp(Setting Outbound Route MoH To: ${ARG1})
exten => s,2,SetMusicOnHold(${ARG1})

; ##########################################
; ## Ring Groups with Confirmation macros ##
; ##########################################
; Used by followme and ringgroups

; [macro-dial-confirm]
; This has now been incorporated into dialparties. It still only works with ringall
; and ringall-prim strategies. Have not investigated why it doesn't work with
; hunt and memory hunt.
; This was written to make it easy to use macro-dial-confirm instead of macro-dial in generated dialplans.
; This takes the same paramaters, with an additional paramater of the ring group Number
; ARG1 is the timeout
; ARG3 is a list of xtns to call - 203-222-240-123123123#-211
; ARG4 is the ring group number

; This sets a unique value to indicate that the channel is ringing. This is used for warning slow
; users that the call has already been picked up.
exten => s,1,Set(DB(RG/${ARG4}/${CHANNEL})=RINGING)

; We need to keep that channel variable, because it'll change when we do this dial, so set it to
; fallthrough to every sibling.
exten => s,n,Set(__UNIQCHAN=${CHANNEL})

; The calling ringgroup should have set RingGroupMethod appropriately. We need to set two
; additional parameters:
; Thse are passed to inform dialparties to place external calls through the [grps] context
exten => s,n,Set(RINGGROUP_INDEX=${ARG4})
exten => s,n,Set(ARG4=) ; otherwise it gets passed to dialparties.agi which processes it (prob bug) 

exten => s,n,Macro(dial,${ARG1},${ARG2},${ARG3})

; delete the variable, if we are here, we are done trying to dial and it may have been left around
exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL})
exten => s,n,Set(USE_CONFIRMATION=)
exten => s,n,Set(RINGGROUP_INDEX=)

; [macro-auto-confirm]
; This macro is called from ext-local-confirm to auto-confirm a call so that other extensions
; are aware that the call has been answered.
exten => s,1,Set(__MACRO_RESULT=)
exten => s,n,Set(__CWIGNORE=)
exten => s,n,DBDel(${BLKVM_OVERRIDE})
exten => s,n,DBDel(RG/${ARG1}/${UNIQCHAN})

; [macro-auto-blkvm]
; This macro is called for any extension dialed form a queue, ringgroup
; or followme, so that the answering extension can clear the voicemail block
; override allow subsequent transfers to properly operate.
exten => s,1,Set(__MACRO_RESULT=)
exten => s,n,Set(__CWIGNORE=)
exten => s,n,DBDel(${BLKVM_OVERRIDE})

; [ext-local-confirm]
; If call confirm is being used in a ringgroup, then calls that do not require confirmation are sent
; to this extension instead of straight to the device.
; The sole purpose of sending them here is to make sure we run Macro(auto-confirm) if this
; extension answers the line. This takes care of clearing the database key that is used to inform
; other potential late comers that the extension has been answered by someone else.
; ALERT_INFO is deprecated in Asterisk 1.4 but still used throughout the FreePBX dialplan and
; usually set by dialparties.agi. This allows ineritance. Since no dialparties.agi here, set the
; header if it is set.
exten => _LC-.,1,Noop(IN ext-local-confirm with - RT: ${RT}, RG_IDX: ${RG_IDX})
exten => _LC-.,n,GotoIf($["x${ALERT_INFO}"="x"]?godial)
exten => _LC-.,n,SIPAddHeader(Alert-Info: ${ALERT_INFO})
exten => _LC-.,n(godial),dial(${DB(DEVICE/${EXTEN:3}/dial)},${RT},M(auto-confirm^${RG_IDX})${DIAL_OPTIONS})

; [macro-confirm]
; CONTEXT:      macro-confirm                                                                                                              
; PURPOSE:      added default message if none supplied
; Follom-Me and Ringgroups provide an option to supply a message to be
; played as part of the confirmation. These changes have added a default
; message if none is supplied.
exten => s,1,Set(LOOPCOUNT=0)

; We set ABORT rather than CONTINUE, as we want the server to forget about this channel 
; if it's declined, hung up, or timed out. We don't want it to continue on to the next
; step in the dialplan, which could be anything!
exten => s,n,Set(__MACRO_RESULT=ABORT)

; ARG1 is the announcement to play to tell the user that they've got a call they need
; to confirm. Something along the lines of 'You have an incoming call. Press 1 to accept, 9 to reject'
exten => s,n,Set(MSG1=${IF($["foo${ARG1}" != "foo"]?${ARG1}:"incoming-call-1-accept-2-decline")})
exten => s,n(start),Read(INPUT,${MSG1},1,,1,5)

; So. We've now read something, or nothing. We should check to make sure that the call hasn't
; already been answered by someone else. If it has, send this call to toolate
exten => s,n,GotoIf(${DB_EXISTS(RG/${ARG3}/${UNIQCHAN})}?check:toolate)

; We passed that test, so it means the call hasn't been answered. Has this user pushed 1? If so,
; then go to OK.
exten => s,n(check),GotoIf($["${INPUT}"="1"]?ok)

; If they've pushed 9, then they definately don't want the call. Just pretend there was no response
; and go to noanswer (or 2 since that will be default for asterisk)
exten => s,n,GotoIf($["${INPUT}"="9"]?noanswer)
exten => s,n,GotoIf($["${INPUT}"="2"]?noanswer)
exten => s,n,GotoIf($["${INPUT}"="3"]?playcid)

; Increment LOOPCOUNT, and check to make sure we haven't played it 5 times by now. We assume that
; the person is able to push '1' in a reasonably short time.
exten => s,n,Set(LOOPCOUNT=$[ ${LOOPCOUNT} + 1 ])
exten => s,n,GotoIf($[ ${LOOPCOUNT} < 5 ]?start)

; If we're here, that means we've played it MORE than 5 times. Set __MACRO_RESULT=ABORT, well, just 
; coz, and goto fin, which is the last line, meaning it returns to the previous Dial, and pretends as
; if nothing has happened.
exten => s,n(noanswer),Set(__MACRO_RESULT=ABORT)
exten => s,n,Goto(fin)

; Test play callerid
exten => s,n(playcid),Noop(Playing CID: ${CALLCONFIRMCID})
exten => s,n,SayDigits(${CALLCONFIRMCID})
exten => s,n,Goto(start)

; If we're here, it's because the call was already accepted by someone else.
exten => s,n(toolate),Set(MSG2=${IF($["foo${ARG2}" != "foo"]?${ARG2}:"incoming-call-no-longer-avail")})
exten => s,n,Playback(${MSG2})
exten => s,n,Goto(noanswer)

; If we made it here, it's because the call _WAS_ accepted, AND it's still ringing. We delete the
; database entry (so that the DB_EXISTS line above will trigger a 'toolate' jump), and set the 
; MACRO_RESULT variable to NOTHING. This is the magic string that joins both legs of the call together
exten => s,n(ok),DBDel(RG/${ARG3}/${UNIQCHAN})
exten => s,n,DBDel(${BLKVM_OVERRIDE})
exten => s,n,Set(__MACRO_RESULT=)

; The end.
exten => s,n(fin),NoOp(Finished)
exten => h,1,Noop(Hangup Extension in macro-confirm)
exten => h,n,Macro(hangupcall)


; [findmefollow-ringallv2]
; This context, to be included in from-internal, implements the PreRing part of findmefollow
; as well as the GroupRing part. It also communicates between the two so that if DND is set
; on the primary extension, and mastermode is enabled, then the other extensions will not ring
exten => _FMPR-.,1,Noop(In FMPR ${FMGRP} with ${EXTEN:5})
exten => _FMPR-.,n,Set(RingGroupMethod=)
exten => _FMPR-.,n,Set(USE_CONFIRMATION=)
exten => _FMPR-.,n,Set(RINGGROUP_INDEX=)
exten => _FMPR-.,n,Macro(simple-dial,${EXTEN:5},${FMREALPRERING})
exten => _FMPR-.,n,GotoIf($["${DIALSTATUS}" != "BUSY"]?nodnd)
exten => _FMPR-.,n,Set(DB(FM/DND/${FMGRP}/${FMUNIQUE})=DND)
exten => _FMPR-.,n(nodnd),Noop(Ending FMPR ${FMGRP} with ${EXTEN:5} and dialstatus ${DIALSTATUS})
exten => _FMPR-.,n,Hangup()

exten => _FMGL-.,1,Noop(In FMGL ${FMGRP} with ${EXTEN:5})
exten => _FMGL-.,n,GotoIf($["${DB(FM/DND/${FMGRP}/${FMUNIQUE})}" = "DND"]?dodnd)
exten => _FMGL-.,n,Wait(1)
exten => _FMGL-.,n,GotoIf($["${DB(FM/DND/${FMGRP}/${FMUNIQUE})}" = "DND"]?dodnd)
exten => _FMGL-.,n,Wait(1)
exten => _FMGL-.,n,GotoIf($["${DB(FM/DND/${FMGRP}/${FMUNIQUE})}" = "DND"]?dodnd)
exten => _FMGL-.,n,Wait(${FMPRERING})
exten => _FMGL-.,n,GotoIf($["${DB(FM/DND/${FMGRP}/${FMUNIQUE})}" = "DND"]?dodnd)
exten => _FMGL-.,n,DBDel(FM/DND/${FMGRP}/${FMUNIQUE})
exten => _FMGL-.,n(dodial),Macro(dial,${FMGRPTIME},${DIAL_OPTIONS},${EXTEN:5})
exten => _FMGL-.,n,Noop(Ending FMGL ${FMGRP} with ${EXTEN:5} and dialstatus ${DIALSTATUS})
exten => _FMGL-.,n,Hangup()
exten => _FMGL-.,n+10(dodnd),DBDel(FM/DND/${FMGRP}/${FMUNIQUE})
exten => _FMGL-.,n,GotoIf($["${FMPRIME}" = "FALSE"]?dodial)
exten => _FMGL-.,n,Noop(Got DND in FMGL ${FMGRP} with ${EXTEN:5} in ${RingGroupMethod} mode, aborting)
exten => _FMGL-.,n,Hangup()


; ############################################################################
; Extension Contexts [ext]
; ############################################################################

exten => s,1,Answer
exten => s,2,Goto(in_fax,1)
exten => in_fax,1,StopPlayTones  
exten => in_fax,2,GotoIf($["${FAX_RX}" = "system"]?3:analog_fax,1)
exten => in_fax,3,Macro(faxreceive)
exten => in_fax,4,Hangup
exten => analog_fax,1,GotoIf($["${FAX_RX}" = "disabled"]?4:2)  ;if fax is disabled, just hang up
exten => analog_fax,2,Set(DIAL=${DB(DEVICE/${FAX_RX}/dial)});
exten => analog_fax,3,Dial(${DIAL},20,d)
exten => analog_fax,4,Hangup
;exten => out_fax,1,wait(7)
exten => out_fax,1,txfax(${TXFAX_NAME},caller)
exten => out_fax,2,Hangup
exten => h,1,system(/var/lib/asterisk/bin/ --to ${EMAILADDR} --from ${FAX_RX_FROM} --subject "Fax from ${URIENCODE(${CALLERID(number)})} ${URIENCODE(${CALLERID(name)})}" --attachment fax_${URIENCODE(${CALLERID(number)})}.pdf --type application/pdf --file ${FAXFILE});
exten => h,2,Hangup()

;this is where parked calls go if they time-out.  Should probably re-ring
include => Nur_intern
include => ISDN_raus

;hier kommen die Gespr�che von ISDN an
exten => _XX,1,goto(Nur_intern,${EXTEN},1)
exten => _X.,1,TrySystem(echo "Fehler: Ruf von ISDN (CID:${CALLERID(number)}) zu Rufnummer ${EXTEN}" >> /var/log/asterisk/error.log) 

exten => _2[023],1,Dial(SIP/${EXTEN},120)
exten => _XX,1,Dial(mISDN/g:INTERN/${EXTEN},120)
exten => _XX,2,Busy()

exten => _X.,1,Dial(mISDN/g:INTERN/${EXTEN},120)

; chan_misdn sample config

; general section:
; for debugging and general setup, things that are not bound to port groups

; Sets the Path to the misdn-init.conf (for nt_ptp mode checking)

; set debugging flag: 
;   0 - No Debug
;   1 - mISDN Messages and * - Messages, and * - State changes
;   2 - Messages + Message specific Informations (e.g. bearer capability)
;   3 - very Verbose, the above + lots of Driver specific infos
;   4 - even more Verbose than 3
; default value: 0

; set debugging file and flags for mISDNuser (NT-Stack) 
; flags can be or'ed with the following values:
; DBGM_NET        0x00000001
; DBGM_MSG        0x00000002
; DBGM_FSM        0x00000004
; DBGM_TEI        0x00000010
; DBGM_L2         0x00000020
; DBGM_L3         0x00000040
; DBGM_L3DATA     0x00000080
; DBGM_BC         0x00000100
; DBGM_TONE       0x00000200
; DBGM_BCDATA     0x00000400
; DBGM_MAN        0x00001000
; DBGM_APPL       0x00002000
; DBGM_ISDN       0x00004000
; DBGM_SOCK       0x00010000
; DBGM_CONN       0x00020000
; DBGM_CDATA      0x00040000
; DBGM_DDATA      0x00080000
; DBGM_SOUND      0x00100000
; DBGM_SDATA      0x00200000
; DBGM_TOPLEVEL   0x40000000
; DBGM_ALL        0xffffffff


; some pbx systems do cut the L1 for some milliseconds, to avoid 
; dropping running calls, we can set this flag to yes and tell
; mISDNuser not to drop the calls on L2_RELEASE

; the big trace
; default value: [not set]

; set to yes if you want mISDN_dsp to bridge the calls in HW
; default value: yes

; watches the L1s of every port. If one l1 is down it tries to 
; get it up. The timeout is given in seconds. with 0 as value it
; does not watch the l1 at all
; default value: 0
; this option is only read at loading time of chan_misdn, 
; which means you need to unload and load chan_misdn to change the 
; value, an asterisk restart should do the trick

; stops dialtone after getting first digit on nt Port
; default value: yes

; whether to append overlapdialed Digits to Extension or not 
; default value: yes


; Whether to look for dynamic crypting attempt
; default value: no

; crypt_prefix, what is used for crypting Protocol
; default value: [not set]

; Keys for cryption, you reference them in the dialplan
; later also in dynamic encr.
; default value: [not set]

; users sections:
; name your sections as you which but not "general" ! 
; the sections are Groups, you can dial out in extensions.conf
; with Dial(mISDN/g:extern/101) where extern is a section name, 
; chan_misdn tries every port in this section to find a 
; new free channel

; The default section is not a group section, it just contains config elements
; which are inherited by group sections.


; define your default context here
; default value: default

; language
; default value: en

; sets the musiconhold class

; Either if we should produce DTMF Tones ourselves

; If we should generate Ringing for chan_sip and others

; here you can define which bearers should be allowed

; Prefixes for national and international, those are put before the 
; oad if an according dialplan is set by the other end. 
; default values: nationalprefix      : 0
;                 internationalprefix : 00

; set rx/tx gains between -8 and 8 to change the RX/TX Gain
; default values: rxgain: 0
;                 txgain: 0

; some telcos especially in NL seem to need this set to yes, also in 
; switzerland this seems to be important
; default value: no

; This option defines, if chan_misdn should check the L1 on  a PMP 
; before making a group call on it. The L1 may go down for PMP Ports
; so we might need this.
; But be aware! a broken or plugged off cable might be used for a group call
; as well, since chan_misdn has no chance to distinguish if the L1 is down
; because of a lost Link or because the Provider shut it down...
; default: no

; in PMP this option defines which cause should be sent out to 
; the 3. caller. chan_misdn does not support callwaiting on TE
; PMP side. This allows to modify the RELEASE_COMPLETE cause 
; at least.

; Send Setup_Acknowledge on incoming calls anyway (instead of PROCEEDING), 
; this requests additional Infos, so we can waitfordigits 
; without much issues. This works only for PTP Ports
; default value: no

; set this to yes if you want to disconnect calls when a timeout occurs
; for example during the overlapdial phase

; set the method to use for channel selection:
;   standard    - always choose the first free channel with the lowest number
;   round_robin - use the round robin algorithm to select a channel. use this
;                 if you want to balance your load.
; default value: standard

; specify if chan_misdn should collect digits before going into the 
; dialplan, you can choose yes=4 Seconds, no, or specify the amount
; of seconds you need;

; dialplan means Type Of Number in ISDN Terms (for outgoing calls)
; there are different types of the dialplan:
; dialplan -> outgoing Number
; localdialplan -> callerid
; cpndialplan -> connected party number
; dialplan options: 
; 0 - unknown
; 1 - International
; 2 - National
; 4 - Subscriber
; This setting is used for outgoing calls
; default value: 0

; turn this to no if you don't mind correct handling of Progress Indicators  

; turn this on if you like to send Tone Indications to a Incoming
; isdn channel on a TE Port. Rarely used, only if the Telco allows
; you to send indications by yourself, normally the Telco sends the 
; indications to the remote party.
; default: no

; uncomment the following to get into s extension at extension conf
; there you can use DigitTimeout if you can't or don't want to use
; isdn overlap dial. 
; note: This will jump into the s exten for every exten!
; default value: no

; set this to yes if you want to generate your own dialtone 
; with always_immediate=yes, else chan_misdn generates the dialtone
; default value: no

; uncomment the following if you want callers which called exactly the 
; base number (so no extension is set) jump to the s extension.
; if the user dials something more it jumps to the correct extension 
; instead
; default value: no

; uncomment the following to have hold and retrieve support
; default value: no

; Pickup and Callgroup
; default values: not set = 0
; range: 0-63

; these are the exact isdn screening and presentation indicators
; if -1 is given for both values the presentation indicators are used
; from asterisks SetCallerPres application.
; s=0, p=0 -> callerid presented not screened
; s=1, p=1 -> callerid presented but screened (the remote end does not see it!)
; default values s=-1, p=-1

; this enables echocancellation, with the given number of taps
; be aware, move this setting only to outgoing portgroups!
; A value of zero turns echocancellation off.
; possible values are: 0,32,64,128,256,yes(=128),no(=0)
; default value: no

; Set this to no to disable echotraining. You can enter a number > 10
; the value is a multiple of 0.125 ms. 
; default value: no 
; yes = 2000
; no = 0

; chan_misdns jitterbuffer, default 4000

; change this threshold to enable dejitter functionality

; change this to yes, if you want to bridge a mISDN data channel to 
; another channel type or to an application.

; defines the maximum amount of incoming calls per port for
; this group. Calls which exceed the maximum will be marked with 
; the channel variable MAX_OVERFLOW. It will contain the amount of 
; overflowed calls

; defines the maximum amount of outgoing calls per port for this group
; exceeding calls will be rejected

; define your ports, e.g. 1,2 (depends on mISDN-driver loading order) 
; context where to go to when incoming Call on one of the above ports



Neuer User
Mitglied seit
9 Feb 2008
Punkte für Reaktionen
Trixbox Inbound Route

Krieg keine Inbound Route zustande. Ok, wenn ich sie selbst eingebe in extensions_custom dann funktioniert. Nun möchte ich die Route aber über das Web-Interface eingeben und das ist ja wirklich keine Hexerei (oder doch).
Habe der Route einen Namen gegeben und sie auf eine bestehende Extension geleitet. Mit DID hab ichs auch versucht...dito.
Wenn ich den Anruf über einen SIP Account annehmen will geschieht in der Asterisk CLI gar nix. Wenn ich den Anruf über ISDN annehmen will, kommt einzig die Meldung "P[ 1] channel with stid:0 for one second still in use!"
Ok, kann sein, dass die verschiedenen Eingänge, unterschiedliche Probleme haben, aber...hat jemand ne Idee?

Besten Dank


Neuer User
Mitglied seit
7 Mrz 2009
Punkte für Reaktionen
Kannst du dein Providerkonto(Trunk) auf Type = peer einstellen (nur bei SIP Tranks)?
dann müste bei eingehenden Anrufen keine Authorisierung Abgefragt werden.

ich vermute das hier der Anruf vom Provider auf deine Anlage kommt.
[Oct 10 09:41:45] WARNING[2439] chan_sip.c: username mismatch, have <044xxxxxxx city>, digest has <044xxxxxxx>
[Oct 10 09:41:45] NOTICE[2439] chan_sip.c: Failed to authenticate user "044xxxxxxx" <sip:[email protected]>;tag=xxxxxxxxx

Hier will die anlage eine authorisierung, das machen aber viele Provider einfach nicht...
Daraufhin schickt die Anlage ein SIP 400 .... und die Gegenstelle bekommt ein besetzt.

Mach mal bitte auf console :

asterisk -r
sip show peers
Sip show peer <provider trunk>
set verbose 4
nun anruf tätigen..

und poste die ergebnisse

Dann bitte noch folgenden trace
asterisk -r
sip set debug (?on?)

und auch posten
Mit freundlichen Grüßen
Zuletzt bearbeitet:


Neuer User
Mitglied seit
4 Feb 2008
Punkte für Reaktionen
Eine Lösungsmöglichkeit

Ich erlaube mir, auch nach etwas längerer Zeit in diesen Thread eine Antwort zu schreiben - nachdem ich selbst zirka 3 Stunden mit der Suche nach einer Lösung verbracht habe :(, möchte ich Euch meine Config-Erfahrung nicht vorenthalten: Sitzt Deine TrixBox hinter einem NAT-Router, so muss zwingend die Option:


gesetzt sein! (TrixBox: PBX Settings / Trunks / [DeinSIPTrunk] unter "PEER Details" oder "USER Details")
Ansonsten genau die Probleme auftauchen, wie hier beschrieben: Raustelefonieren geht perfekt, Anrufende erhalten nur ein Besetztzeichen.
Wer eine ISDN-Karte im Einsatz hat, kennt dieses Problem selbstredend nicht - da die Angebote der SIP-Provider aber immer besser werden, ist ein Umstieg durchaus bedenkenswert.

Viel Glück!

Linux / Win / Cloud

Statistik des Forums

Neuestes Mitglied