Error de "Todas las lineas estan ocupadas" DAHDI - Llamadas salientes

1,655 views
Skip to first unread message

DMRAsterisk

unread,
Mar 11, 2012, 12:34:59 PM3/11/12
to asterisk-es
Cuando intento hacer una llamada da el error en español "Todas las
lineas están ocupadas", despues el triple pitido caracteristico de
llamada no procesado. Que puede estar pasando?

Porque cuando uno llama desde otra linea a la central las llamadas
entrantes se derivan a los sip internos. El tema pasa cuando intento
hacer una llamada al exterior de la central.

Pasos los archivos que tengo configurados

Saludos

archivo chan_dahdi.conf

busydetect= yes
busycount=3
#include /etc/asterisk/dahdi-channels.conf

archivo dahdi_cahnnels.conf
; Autogenerated by /usr/sbin/dahdi_genconf on Sun Mar 11 12:56:32 2012
; If you edit this file and execute /usr/sbin/dahdi_genconf again,
; your manual changes will be LOST.
; Dahdi Channels Configurations (chan_dahdi.conf)
;
; This is not intended to be a complete chan_dahdi.conf. Rather, it is
intended
; to be #include-d by /etc/chan_dahdi.conf that will include the
global settings
;

; Span 1: WCFXO/0 "Generic Clone Board 1" (MASTER)
;;; line="1 WCFXO/0/0 FXSKS (In use) (SWEC: MG2)"
signalling=fxs_ks
callerid=asreceived
group=0
context=from-pstn
channel => 1
callerid=
group=
context=default



archivo system.conf
# Autogenerated by /usr/sbin/dahdi_genconf on Sun Mar 11 12:56:32 2012
# If you edit this file and execute /usr/sbin/dahdi_genconf again,
# your manual changes will be LOST.
# Dahdi Configuration File
#
# This file is parsed by the Dahdi Configurator, dahdi_cfg
#
# Span 1: WCFXO/0 "Generic Clone Board 1" (MASTER)
fxsks=1
echocanceller=mg2,1

# Global data

loadzone = es
defaultzone = es

oxido A

unread,
Mar 11, 2012, 1:27:10 PM3/11/12
to aster...@googlegroups.com

Mejor pega tu extensios.conf

--
Este email pertenece a la lista de Asterisk-ES (http://www.asterisk-es.org)

~~~ Normas de la lista Asterisk-ES: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
http://comunidad.asterisk-es.org/index.php?title=Lista:normas-asterisk-es
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Para anular la suscripción: asterisk-es...@googlegroups.com

Fernando Villares

unread,
Mar 11, 2012, 1:28:39 PM3/11/12
to aster...@googlegroups.com

ORTOGRAFIA CORRECTA, /etc/asterisk/extensions.conf.....

DMRAsterisk

unread,
Mar 11, 2012, 5:27:01 PM3/11/12
to asterisk-es
aqui te paso el archivo extensios.conf


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

; dialparties.agi (http://www.sprackett.com/asterisk/)
; Asterisk::AGI (http://asterisk.gnuinter.net/)
; gsm (http://www.ibiblio.org/pub/Linux/utils/compress/!
INDEX.short.html)
; loligo sounds (http://www.loligo.com/asterisk/sounds/)
; mpg123 (http://voip-info.org/wiki-Asterisk+config+musiconhold.conf)

;************************** -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

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

; MODIFICATION (PL)
;
; 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.
;
[from-did-direct]
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,...)
[macro-dial]
exten => s,1,GotoIf($["${MOHCLASS}" = ""]?dial)
exten => s,2,SetMusicOnHold(${MOHCLASS})
exten => s,3(dial),AGI(dialparties.agi)
exten => s,4,NoOp(Returned from dialparties with no extensions to call
and DIALSTATUS: ${DIALSTATUS})

exten => s,10,Dial(${ds}) ; dialparties
will set the priority to 10 if $ds is not null
exten => s,11,Set(DIALSTATUS=${IF($["${DIALSTATUS_CW}"!="" ]?$
{DIALSTATUS_CW}:${DIALSTATUS})})

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

exten => s,30,Set(HuntMember=HuntMember${HuntLoop})
exten => s,31,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["$
{RingGroupMethod}" = "hunt" ]]?32:35 ) ; Set CAll Trace for Hunt
member we are going to call
exten => s,32,Set(CT_EXTEN=${CUT(ARG3,,$[${HuntLoop} + 1])})
exten => s,33,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT})
exten => s,34,Goto(s,42)

exten => s,35,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["$
{RingGroupMethod}" = "memoryhunt" ]]?36:50 ) ;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,36,Set(CTLoop=0)
exten => s,37,GotoIf($[${CTLoop} > ${HuntLoop}]?42 ) ; if this is
from rg-group, don't strip prefix
exten => s,38,Set(CT_EXTEN=${CUT(ARG3,,$[${CTLoop} + 1])})
exten => s,39,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT})
exten => s,40,Set(CTLoop=$[1 + ${CTLoop}])
exten => s,41,Goto(s,37)

exten => s,42,Dial(${${HuntMember}}${ds} ) ; dialparties will set the
priority to 20 if $ds is not null and its a hunt group
exten => s,43,Set(HuntLoop=$[1 + ${HuntLoop}])
exten => s,44,GotoIf($[$[$["foo${RingGroupMethod}" !=
"foofirstavailable"] & $["foo${RingGroupMethod}" !=
"foofirstnotonphone"]] | $["foo${DialStatus}" = "fooBUSY"]]?46)
exten => s,45,Set(HuntMembers=0)
exten => s,46,Set(HuntMembers=$[${HuntMembers} - 1])
exten => s,47,Goto(s,22)
exten => s,50,DBdel(CALLTRACE/${CT_EXTEN})
exten => s,51,Goto(s,42)

; 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
; ARGS: $VMBOX, $EXT
[macro-exten-vm]
exten => s,1,Macro(user-callerid)

exten => s,n,Set(FROMCONTEXT=exten-vm)
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,Set(SV_DIALSTATUS=${DIALSTATUS})
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,Set(DIALSTATUS=${SV_DIALSTATUS})
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.
;
; VMX_REPEAT
; The number of times to repeat the users message if no option is
pressed.
; VMX_TIMEOUT
; The timeout to wait after playing message before repeating or
giving up.
; VMX_LOOPS
; The number of times it should replay the message and check for
an option when
; an invalid option is pressed.
;
; VMX_OPTS_DOVM
; 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.
; VMX_OPTS_TIMEOUT
; 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'.
; VMX_OPTS_LOOPS
; 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.
;
; VMX_CONTEXT
; Default context for user destinations if not supplied in the
user's settings
; VMX_PRI
; Default priority for user destinations if not supplied in the
user's settings
;
; VMX_TIMEDEST_CONTEXT
; Default context for timeout destination if not supplied in the
user's settings
; VMX_TIMEDEST_EXT
; Default extension for timeout destination if not supplied in the
user's settings
; VMX_TIMEDEST_PRI
; Default priority for timeout destination if not supplied in the
user's settings
;
; VMX_LOOPDEST_CONTEXT
; Default context for loops destination if not supplied in the
user's settings
; VMX_LOOPDEST_EXT
; Default extension for loops destination if not supplied in the
user's settings
; VMX_LOOPDEST_PRI
; 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
;------------------------------------------------------------------------
[macro-vm]
; ARG1 - extension
; ARG2 - DIRECTDIAL/BUSY
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}/${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,Set(VMX_TIMEDEST_CONTEXT=${DB_RESULT})
exten => vmx,n(timepri),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/$
{MODE}/timedest/pri)}" = "0"]?dotime)
exten => vmx,n,Set(VMX_TIMEDEST_PRI=${DB_RESULT})
exten => vmx,n(dotime),Goto(${VMX_TIMEDEST_CONTEXT},$
{VMX_TIMEDEST_EXT},${VMX_TIMEDEST_PRI})

; 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
exten => vmx,n(doloop),Goto(${VMX_LOOPDEST_CONTEXT},$
{VMX_LOOPDEST_EXT},${VMX_LOOPDEST_PRI})

; 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)

; 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},${VM_OPTS}$
{VMGAIN}) ; Voicemail Busy message
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,Goto(${VMX_OPDEST_CONTEXT},${VMX_OPDEST_EXT},$
{VMX_OPDEST_PRIORITY})
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/s@from-pstn)
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 => a,n,Goto(${VMX_ADEST_CONTEXT},${VMX_ADEST_EXT},$
{VMX_ADEST_PRI})

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,Hangup()

exten => exit-SUCCESS,1,Playback(goodbye)
exten => exit-SUCCESS,n,Hangup()

exten => exit-USEREXIT,1,Playback(goodbye)
exten => exit-USEREXIT,n,Hangup()

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
; ARGS: $EXTENSION, $RINGTIME
;------------------------------------------------------------------------
[macro-simple-dial]
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})

exten => s,n,Set(PR_DIALSTATUS=${DIALSTATUS})

; 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
exten => s,n,Set(DIALSTATUS=${PR_DIALSTATUS})

; 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
[macro-get-vmcontext]
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
[macro-fixcid]
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
[macro-rg-group]
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.
;
[macro-outisbusy]
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.
[macro-hangupcall]
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

[macro-faxreceive]
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
[macro-dialout]
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
[macro-dialout-default]
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)

[macro-dialout-trunk-predial-hook]
; this macro intentially left blank so it may be safely overwritten
for any custom
; requirements that an installatin may have.
;
; MACRO RETURN CODE: ${PREDIAL_HOOK_RET}
; if set to "BYPASS" then this trunk will be
skipped
;


; dialout using a trunk, using pattern matching (don't strip any
prefix)
; arg1 = trunk number, arg2 = number, arg3 = route password
;
; MODIFIED (PL)
;
; Modified both Dial() commands to include the new TRUNK_OPTIONS from
the general
; screen of AMP
;
[macro-dialout-trunk]
exten => s,1,Set(DIAL_TRUNK=${ARG1})
exten => s,n,Set(DIAL_NUMBER=${ARG2})
exten => s,n,Set(ROUTE_PASSWD=${ARG3})

exten => s,n,GotoIf($["${ROUTE_PASSWD}" = ""]?noauth) ; arg3 is
pattern password
exten => s,n(auth),Authenticate(${ROUTE_PASSWD})
exten => s,n(noauth),GotoIf($["x${OUTDISABLE_${ARG1}}" = "xon"]?
disabletrunk,1)

; If NODEST is set, clear it. No point in remembering since dialout-
trunk will just end in the
; bit bucket. But if answered by an outside line with transfer
capability, we want NODEST to be
; clear so a subsequent transfer to an internal extension works and
goes to voicmail or other
; destinations.
;
exten => s,n,Set(_NODEST=)

exten => s,n,Set(DIAL_TRUNK_OPTIONS=${DIAL_OPTIONS}) // will be reset
to TRUNK_OPTIONS if not intra-company
exten => s,n,Set(GROUP()=OUT_${DIAL_TRUNK})
exten => s,n,Macro(user-callerid,SKIPTTL)
exten => s,n,Macro(record-enable,${CALLERID(number)},OUT)
exten => s,n,GotoIf($["${INTRACOMPANYROUTE}" = "YES"]?skipoutcid) ;Set
to YES if treated like internal
exten => s,n,Set(DIAL_TRUNK_OPTIONS=${TRUNK_OPTIONS})
exten => s,n,Macro(outbound-callerid,${DIAL_TRUNK})
exten => s,n(skipoutcid),GotoIf($["${OUTMAXCHANS_${DIAL_TRUNK}}foo" =
"foo"]?nomax)
exten => s,n(checkmax),GotoIf($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_$
{DIAL_TRUNK}} ]?chanfull)
exten => s,n(nomax),AGI(fixlocalprefix) ; this sets DIAL_NUMBER to the
proper dial string for this trunk
exten => s,n,Set(OUTNUM=${OUTPREFIX_${DIAL_TRUNK}}${DIAL_NUMBER}) ;
OUTNUM is the final dial number
exten => s,n,Set(custom=${CUT(OUT_${DIAL_TRUNK},:,1)}) ; Custom trunks
are prefixed with "AMP:"

; Back to normal processing, whether intracompany or not.
; But add the macro-setmusic if we don't want music on this outbound
call
;
exten => s,n,GotoIf($[$["${MOHCLASS}" = "default"] | $["foo$
{MOHCLASS}" = "foo"]]?gocall) ; Set to YES if we should pump silence
exten => s,n,Set(DIAL_TRUNK_OPTIONS=M(setmusic^${MOHCLASS})$
{DIAL_TRUNK_OPTIONS}) ; set MoH or off

; This macro call will always be blank and is provided as a hook for
customization required prior to making a call
; such as adding SIP header information or other requirements. All the
channel variables from above are present
;
exten => s,n,Macro(dialout-trunk-predial-hook)
exten => s,n,GotoIf($["${PREDIAL_HOOK_RET}" = "BYPASS"]?bypass,1)

exten => s,n(gocall),GotoIf($["${custom}" = "AMP"]?customtrunk)
exten => s,n,Dial(${OUT_${DIAL_TRUNK}}/${OUTNUM},300,$
{DIAL_TRUNK_OPTIONS}) ; Regular Trunk Dial
exten => s,n,Goto(s-${DIALSTATUS},1)
exten => s,n(customtrunk),Set(pre_num=${CUT(OUT_${DIAL_TRUNK},$,1)})
exten => s,n,Set(the_num=${CUT(OUT_${DIAL_TRUNK},$,2)}) ; this is
where we expect to find string OUTNUM
exten => s,n,Set(post_num=${CUT(OUT_${DIAL_TRUNK},$,3)})
exten => s,n,GotoIf($["${the_num}" = "OUTNUM"]?outnum:skipoutnum) ; if
we didn't find "OUTNUM", then skip to Dial
exten => s,n(outnum),Set(the_num=${OUTNUM}) ; replace "OUTNUM" with
the actual number to dial
exten => s,n(skipoutnum),Dial(${pre_num:4}${the_num}${post_num},300,$
{DIAL_TRUNK_OPTIONS})
exten => s,n,Goto(s-${DIALSTATUS},1)

exten => s,n(chanfull),Noop(max channels used up)

exten => s-BUSY,1,NoOp(Dial failed due to trunk reporting BUSY -
giving up)
exten => s-BUSY,2,Busy(20)

exten => s-NOANSWER,1,NoOp(Dial failed due to trunk reporting NOANSWER
- giving up)
exten => s-NOANSWER,2,Playtones(congestion)
exten => s-NOANSWER,3,Congestion(20)

exten => s-CANCEL,1,NoOp(Dial failed due to trunk reporting CANCEL -
giving up)
exten => s-CANCEL,2,Playtones(congestion)
exten => s-CANCEL,3,Congestion(20)

exten => _s-.,1,GotoIf($["x${OUTFAIL_${ARG1}}" = "x"]?noreport)
exten => _s-.,n,AGI(${OUTFAIL_${ARG1}})
exten => _s-.,n(noreport),Noop(TRUNK Dial failed due to ${DIALSTATUS}
- failing through to other trunks)

exten => disabletrunk,1,Noop(TRUNK: ${OUT_${DIAL_TRUNK}} DISABLED -
falling through to next trunk)
exten => bypass,1,Noop(TRUNK: ${OUT_${DIAL_TRUNK}} BYPASSING because
dialout-trunk-predial-hook)

exten => h,1,Macro(hangupcall)

; Adds a dynamic agent/member to a Queue
; Prompts for call-back number - in not entered, uses CIDNum
[macro-agent-add]
exten => s,1,Wait(1)
exten => s,2,Macro(user-callerid,SKIPTTL)
exten => s,3,Read(CALLBACKNUM,agent-user) ; get callback number from
user
exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?5:7) ; if user just
pressed # or timed out, use cidnum
exten => s,5,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,6,GotoIf($["${CALLBACKNUM}" = ""]?2) ; if still no number,
start over
exten => s,7,GotoIf($["${ARG2}" = ""]?9:8) ; arg2 is queue password
exten => s,8,Authenticate(${ARG2})
exten => s,9,AddQueueMember(${ARG1},Local/${CALLBACKNUM}@from-internal/
n) ; using chan_local allows us to have agents over trunks
exten => s,10,UserEvent(Agentlogin,Agent: ${CALLBACKNUM})
exten => s,11,Wait(1)
exten => s,12,Playback(agent-loginok)
exten => s,13,Hangup()

; Removes a dynamic agent/member from a Queue
; Prompts for call-back number - in not entered, uses CIDNum
[macro-agent-del]
exten => s,1,Wait(1)
exten => s,2,Macro(user-callerid,SKIPTTL)
exten => s,3,Read(CALLBACKNUM,agent-user) ; get callback number from
user
exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?5:7) ; if user just
pressed # or timed out, use cidnum
exten => s,5,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,6,GotoIf($["${CALLBACKNUM}" = ""]?2) ; if still no number,
start over
exten => s,7,RemoveQueueMember(${ARG1},Local/${CALLBACKNUM}@from-
internal/n)
exten => s,8,UserEvent(RefreshQueue)
exten => s,9,Wait(1)
exten => s,10,Playback(agent-loggedoff)
exten => s,11,Hangup()

; arg1 = trunk number, arg2 = number
[macro-dialout-enum]
; Re-written to use enumlookup.agi
exten => s,1,GotoIf($["${ARG3}" != ""]?PASSWD:NOPASSWD); arg3 is
pattern password
exten => s,n(PASSWD),Authenticate(${ARG3})
exten => s,n(NOPASSWD),Macro(user-callerid,SKIPTTL)
exten => s,n,Macro(record-enable,${CALLERID(number)},OUT)
exten => s,n,Macro(outbound-callerid,${ARG1})
exten => s,n,Set(GROUP()=OUT_${ARG1})
exten => s,n,GotoIf($["${OUTMAXCHANS_${ARG1}}foo" = "foo"]?nomax)
exten => s,n,GotoIf($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${ARG1}} ]?
nochans)
exten => s,n(nomax),Set(DIAL_NUMBER=${ARG2})
exten => s,n,Set(DIAL_TRUNK=${ARG1})
exten => s,n,AGI(fixlocalprefix) ; this sets DIAL_NUMBER to the
proper dial string for this trunk
; Replacement for asterisk's ENUMLOOKUP function
exten => s,n,AGI(enumlookup.agi)
; Now we have the variable DIALARR set to a list of URI's that can be
called, in order of priority
; Loop through them trying them in order.
exten => s,n(dialloop),GotoIf($["foo${DIALARR}"="foo"]?end)
exten => s,n,Set(TRYDIAL=${CUT(DIALARR,%,1)})
exten => s,n,Set(DIALARR=${CUT(DIALARR,%,2-)})
exten => s,n,Dial(${TRYDIAL})
exten => s,n,NoOp(Dial exited in macro-enum-dialout with $
{DIALSTATUS})

; Now, if we're still here, that means the Dial failed for some
reason.
; If it's CONGESTION or CHANUNAVAIL we want to try again on a
different
; different channel. If there's no more left, the dialloop tag will
exit.
exten => s,n,GotoIf($[ $[ "${DIALSTATUS}" = "CHANUNAVAIL" ] | $[ "$
{DIALSTATUS}" = "CONGESTION" ] ]?dialloop)

; If we're here, then it's BUSY or NOANSWER or something and well,
deal with it.
exten => s,n(dialfailed),Goto(s-${DIALSTATUS},1)

; Here are the exit points for the macro.

exten => s,n(nochans),NoOp(max channels used up)

exten => s,n(end),NoOp(Exiting macro-dialout-enum)

exten => s-BUSY,1,NoOp(Trunk is reporting BUSY)
exten => s-BUSY,2,Busy(20)

exten => _s-.,1,NoOp(Dial failed due to ${DIALSTATUS})

[macro-record-enable]
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.
[macro-dumpvars]
exten => s,1,Noop(ACCOUNTCODE=${ACCOUNTCODE})
exten => s,2,Noop(ANSWEREDTIME=${ANSWEREDTIME})
exten => s,3,Noop(BLINDTRANSFER=${BLINDTRANSFER})
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,7,Noop(CALLINGPRES=${CALLINGPRES})
exten => s,8,Noop(CHANNEL=${CHANNEL})
exten => s,9,Noop(CONTEXT=${CONTEXT})
exten => s,10,Noop(DATETIME=${DATETIME})
exten => s,11,Noop(DIALEDPEERNAME=${DIALEDPEERNAME})
exten => s,12,Noop(DIALEDPEERNUMBER=${DIALEDPEERNUMBER})
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,27,Noop(SIPUSERAGENT=${SIPUSERAGENT})
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})
exten => s,34,Noop(MACRO_PRIORITY=${MACRO_PRIORITY})

[macro-user-logon]
; check device type
exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})
exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)
; get user's extension
exten => s,3,Set(AMPUSER=${ARG1})
exten => s,4,GotoIf($["${AMPUSER}" = ""]?5:9)
exten => s,5,Playback(please-enter-your)
exten => s,6,Playback(extension)
exten => s,7,Read(AMPUSER,then-press-pound)
; get user's password and authenticate
exten => s,8,Wait(1)
exten => s,9,Set(AMPUSERPASS=${DB(AMPUSER/${AMPUSER}/password)})
exten => s,10,GotoIf($[${LEN(${AMPUSERPASS})} = 0]?s-NOPASSWORD,1)
; do not continue if the user has already logged onto this device
exten => s,11,Set(DEVICEUSER=${DB(DEVICE/${CALLERID(number)}/user)})
exten => s,12,GotoIf($["${DEVICEUSER}" = "${AMPUSER}"]?s-
ALREADYLOGGEDON,1)
exten => s,13,Authenticate(${AMPUSERPASS})
; devices can only be mapped to one user - loggoff anyone else who is
here
exten => s,14,Macro(user-logoff)
; map user to device
exten => s,15,Set(AMPUSERDEVICES=${DB(AMPUSER/${AMPUSER}/device)})
exten => s,16,GotoIf($[${LEN(${AMPUSERDEVICES})} = 0]?18)
exten => s,17,Set(AMPUSERDEVICES=${AMPUSERDEVICES}&)
exten => s,18,Set(AMPUSERDEVICES=${AMPUSERDEVICES}${CALLERID(number)})
exten => s,19,Set(DB(AMPUSER/${AMPUSER}/device)=${AMPUSERDEVICES})
; map device to user
exten => s,20,Set(DB(DEVICE/${CALLERID(number)}/user)=${AMPUSER})
; create symlink from dummy device mailbox to user's mailbox
exten => s,21,System(/bin/ln -s ${ASTSPOOLDIR}/voicemail/default/$
{AMPUSER}/ ${ASTSPOOLDIR}/voicemail/device/${CALLERID(number)})

exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged into)
exten => s-FIXED,2,Playback(ha/phone)
exten => s-FIXED,3,SayDigits(${CALLERID(number)})
exten => s-FIXED,4,Playback(is-curntly-unavail)
exten => s-FIXED,5,Playback(vm-goodbye)
exten => s-FIXED,6,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,2,Playback(vm-goodbye)
exten => s-ALREADYLOGGEDON,3,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,2,Playback(an-error-has-occured)
exten => s-NOPASSWORD,3,Playback(vm-goodbye)
exten => s-NOPASSWORD,4,Hangup ;TODO should play msg indicated device
is already logged into

[macro-user-logoff]
; check device type
exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})
exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)
; remove entry from user's DEVICE key
; delete the symlink to user's voicemail box
exten => s,3,System(rm -f ${ASTSPOOLDIR}/voicemail/device/$
{CALLERID(number)})
exten => s,4,Set(DEVAMPUSER=${DB(DEVICE/${CALLERID(number)}/user)})
exten => s,5,Set(AMPUSERDEVICES=${DB(AMPUSER/${DEVAMPUSER}/device)})
exten => s,6,AGI(list-item-remove.php,${AMPUSERDEVICES},$
{CALLERID(number)},AMPUSERDEVICES,&)
; reset user -> device mapping
; users can log onto multiple devices, need to just remove device from
value
exten => s,7,Set(DB(AMPUSER/${DEVAMPUSER}/device)=${AMPUSERDEVICES})
; reset device -> user mapping
exten => s,8,Set(DB(DEVICE/${CALLERID(number)}/user)=none)
exten => s,9,Playback(vm-goodbye)

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

[macro-systemrecording]
exten => s,1,Goto(${ARG1},1)

exten => dorecord,1,Record(/tmp/${AMPUSER}-ivrrecording:wav)
exten => dorecord,n,Wait(1)
exten => dorecord,n,Goto(confmenu,1)

exten => docheck,1,Playback(/tmp/${AMPUSER}-ivrrecording)
exten => docheck,n,Wait(1)
exten => docheck,n,Goto(confmenu,1)

exten => confmenu,1,Background(to-listen-to-it&press-1&to-rerecord-
it&press-star,m,${LANGUAGE},macro-systemrecording)
exten => confmenu,n,Read(RECRESULT,,1,,,4)
exten => confmenu,n,GotoIf($["x${RECRESULT}"="x*"]?dorecord,1)
exten => confmenu,n,GotoIf($["x${RECRESULT}"="x1"]?docheck,1)
exten => confmenu,n,Goto(1)

exten => 1,1,Goto(docheck,1)
exten => *,1,Goto(dorecord,1)

exten => t,1,Playback(goodbye)
exten => t,n,Hangup

exten => i,1,Playback(pm-invalid-option)
exten => i,n,Goto(confmenu,1)

exten => h,1,Hangup


;
;
############################################################################
; CallerID Handling
;
############################################################################

;sets the callerid of the device to that of the logged in user
;
; ${AMPUSER} is set upon return to the real user despite any aliasing
that may
; have been set as a result of the AMPUSER/<nnn>/cidnum field. This is
used by
; features like DND, CF, etc. to set the proper structure on aliased
instructions
;
[macro-user-callerid]
exten => s,1,Noop(user-callerid: ${CALLERID(name)} $
{CALLERID(number)})

; make sure AMPUSER is set if it doesn't get set below
;
exten => s,n,Set(AMPUSER=${IF($["foo${AMPUSER}" = "foo"]?$
{CALLERID(number)}:${AMPUSER})})
exten => s,n,GotoIf($["${CHANNEL:0:5}" = "Local"]?report)
exten => s,n,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start)
exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)})
exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM})
exten => s,n,Set(AMPUSER=${DB(DEVICE/${REALCALLERIDNUM}/user)})
exten => s,n,Set(AMPUSERCIDNAME=${DB(AMPUSER/${AMPUSER}/cidname)})
exten => s,n,GotoIf($["x${AMPUSERCIDNAME:1:2}" = "x"]?report)

; user may masquerade as a different user internally, so set the
internal cid as indicated
; but keep the REALCALLERID which is used to determine their true
identify and lookup info
; during outbound calls.
;
exten => s,n,Set(AMPUSERCID=${IF($["${DB_EXISTS(AMPUSER/${AMPUSER}/
cidnum)}" = "1"]?${DB_RESULT}:${AMPUSER})})
exten => s,n,Set(CALLERID(all)="${AMPUSERCIDNAME}" <${AMPUSERCID}>)
exten => s,n,Set(REALCALLERIDNUM=${DB(DEVICE/${REALCALLERIDNUM}/
user)})
exten => s,n(report),Noop(TTL: ${TTL} ARG1: ${ARG1})
exten => s,n,GotoIf($[ "${ARG1}" = "SKIPTTL" ]?continue)
exten => s,n(report2),Set(__TTL=${IF($["foo${TTL}" = "foo"]?64:$[ $
{TTL} - 1 ])})
exten => s,n,GotoIf($[ ${TTL} > 0 ]?continue)
exten => s,n,Wait(${RINGTIMER}) ; wait for a while, to give it a
chance to be picked up by voicemail
exten => s,n,Answer()
exten => s,n,Wait(2)
exten => s,n,Playback(im-sorry&an-error-has-occured&with&call-
forwarding)
exten => s,n,Macro(hangupcall)
exten => s,n,Congestion()
exten => s,n(continue),NoOp(Using CallerID ${CALLERID(all)})
exten => h,1,Macro(hangupcall)

; overrides callerid out trunks
; arg1 is trunk
; macro-user-callerid should be called _before_ using this macro
[macro-outbound-callerid]
; Keep the original CallerID number, for failover to the next trunk.
exten => s,1,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start)
exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)})
exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM})

; If this came through a ringgroup or CF, then we want to retain
original CID unless
; OUTKEEPCID_${trunknum} is set.
;
exten => s,n,GotoIf($["${KEEPCID}" != "TRUE"]?normcid) ;Set to TRUE if
coming from ringgroups, CF, etc.
exten => s,n,GotoIf($["x${OUTKEEPCID_${ARG1}}" = "xon"]?normcid)
exten => s,n,GotoIf($["foo${REALCALLERIDNUM}" = "foo"]?normcid) ;if
not set to anything, go through normal processing
exten => s,n,Set(USEROUTCID=${REALCALLERIDNUM})

; We now have to make sure the CID is valid. If we find an AMPUSER
with the same CID, we assume it is an internal
; call (would be quite a conincidence if not) and go through the
normal processing to get that CID. If a device
; is set for this CID, then it must be internal
;
exten => s,n,GotoIf($["foo${DB(AMPUSER/${REALCALLERIDNUM}/device)}" =
"foo"]?bypass:normcid)

exten => s,n(normcid),Set(USEROUTCID=${DB(AMPUSER/${REALCALLERIDNUM}/
outboundcid)})
exten => s,n(bypass),Set(EMERGENCYCID=${DB(DEVICE/${REALCALLERIDNUM}/
emergency_cid)})
exten => s,n,Set(TRUNKOUTCID=${OUTCID_${ARG1}})
exten => s,n,GotoIf($["${EMERGENCYROUTE:1:2}" = ""]?trunkcid) ; check
EMERGENCY ROUTE
exten => s,n,GotoIf($["${EMERGENCYCID:1:2}" = ""]?trunkcid) ; empty
EMERGENCY CID, so default back to trunk
exten => s,n,Set(CALLERID(all)=${EMERGENCYCID}) ; emergency cid for
device
exten => s,n,Goto(report)
exten => s,n(trunkcid),GotoIf($["${TRUNKOUTCID:1:2}" = ""]?
usercid) ;check for CID override for trunk (global var)
exten => s,n,Set(CALLERID(all)=${TRUNKOUTCID})
exten => s,n(usercid),GotoIf($["${USEROUTCID:1:2}" = ""]?report) ;
check CID override for extension
exten => s,n,Set(CALLERID(all)=${USEROUTCID})
exten => s,n,GotoIf($["x${CALLERID(name)}"!="xhidden"]?
report:hidecid) ; check CID blocking for extension
exten => s,n(hidecid),SetCallerPres(prohib_passed_screen) ; Only works
with ISDN (T1/E1/BRI)
exten => s,n(report),NoOp(CallerID set to ${CALLERID(all)})

; 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
;
[macro-privacy-mgr]
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,PRIVMGR+101(fail),Noop(STATUS: ${PRIVACYMGRSTATUS} CID: $
{CALLERID(num)} ${CALLERID(name)} CALLPRES: ${CALLLINGPRES})
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
[macro-saytext]
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)
[macro-sayname]
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")
[macro-saynumber]
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")
[macro-saydigits]
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]
;
############################################################################

[from-sip-external]
;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)

[from-internal-xfer]
; 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
;
; MODIFIED (PL)
;
; 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)

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

[from-zaptel]
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
;
;------------------------------------------------------------------------
[macro-setmusic]
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.
;
;------------------------------------------------------------------------
[macro-dial-confirm]
; 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
; ARG2 is the DIAL_OPTIONS
; 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:
;
; USE_CONFIRMATION, RINGGROUP_INDEX
;
; Thse are passed to inform dialparties to place external calls
through the [grps] context
;
exten => s,n,Set(USE_CONFIRMATION=TRUE)
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.
;
;------------------------------------------------------------------------
[macro-auto-confirm]
exten => s,1,Set(__MACRO_RESULT=)
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.
;
;------------------------------------------------------------------------
[macro-auto-blkvm]
exten => s,1,Set(__MACRO_RESULT=)
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.
;
;------------------------------------------------------------------------
[ext-local-confirm]
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.
;
;------------------------------------------------------------------------
[macro-confirm]
exten => s,1,Set(LOOPCOUNT=0)
exten => s,n,Noop(CALLCONFIRMCID: ${CALLCONFIRMCID})

; 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
;
;------------------------------------------------------------------------
[findmefollow-ringallv2]
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]
;
############################################################################

[ext-fax]
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/fax-process.pl --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
[default]
include => ext-local
exten => s,1,Playback(vm-goodbye)
exten => s,2,Macro(hangupcall)


On Mar 11, 2:27 pm, oxido A <ox1d...@gmail.com> wrote:
> Mejor pega tu extensios.conf
> >http://comunidad.asterisk-es.org/index.php?title=Lista:normas-asteris...

ricardo vargas

unread,
Mar 11, 2012, 11:07:08 PM3/11/12
to asterisk-es
Tienes que cerciorarte si Asterisk esta cargando dahdi, abres con
"asterisk -vvvr" en el "CLI>" escribes 'dahdi show channels' si ves
que no se ejecuta seguramente te toca volver a compilar dahdi.
> ; VMX_LOOPDEST_PRI ...
>
> leer más »
Reply all
Reply to author
Forward
0 new messages