[Asterisk-Users] Re: fine-tuning asterisk questions

M.Hockings veeshooter at hockings.net
Tue Jun 6 11:15:52 MST 2006


William Piper wrote:
> For Problem #2:
> I'm not sure what you are asking. Perhaps post your dialplan for this 
> problem & we will take a look.
>  
> bp
>  
> On 6/4/06, *M.Hockings* <veeshooter at hockings.net 
> <mailto:veeshooter at hockings.net>> wrote:
> 
>     Problem 2) Incoming sip calls from my voip provider get rejected unless
>     I allow anyone to connect with sip. I have an incoming route set up with
>     the right DID that matches the DID that asterisk picks out but it still
>     rejects the call.  Any suggestions about how to get this to work without
>     allowing any sip connection?
> 
> 
>     Mike

Hi William, at the bottom of this is my extensions.conf which seems to 
be the largest part of the equation for problem #2.  I have not applied 
any changes to try and resolve my problem #1 yet.

I think the question here is the operation of the following statement in 
the [from-sip-external] section:

exten => s,1,GotoIf($["${ALLOW_SIP_ANON}"="yes"]?from-trunk,${DID},1)

If I interpret it correctly it should go to from-trunk,1 if the freePBX 
"allow anonymous sip connections" is true and go to 
incoming-sip-did-value,1 if it is false ?  That is should I be looking 
for something like this in the config files to understand how this would 
be handled?

exten=>4169671111,1,....

As an aside, is there some beginners guide to understanding dial plans? 
  My original dial plan (based on things read on voip-info.org) was very 
simple and worked as far as it was configured.  I have recently gone to 
freePBX to try and make the dial plan changes easier and faster however 
it adds a lot of gorp like this that I don't understand.

Thanks for any guidance on this,

Mike


; Asterisk Management Portal (AMP)
; Copyright (C) 2004 Coalescent Systems Inc

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


; 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-findmefollow		; MODIFICATOIN (PL) for findmefollow if 
enabled, should be bofore ext-local
include => ext-did-direct		; MODIFICATOIN (PL) put before ext-did to 
take precedence
include => ext-did
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,AGI,dialparties.agi
exten => s,2,NoOp(Returned from dialparties with no extensions to call)
exten => s,3,NoOp(DIALSTATUS is '${DIALSTATUS}')

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

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,Set(HuntMembers=$[${HuntMembers} - 1])
exten => s,45,Goto(s,22)
exten => s,50,DBdel(CALLTRACE/${CT_EXTEN})
exten => s,51,Goto(s,42)

; 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(RT=${IF($[$["${VMBOX}"!="novm"] | 
$["foo${CFUEXT}"!="foo"]]?${RINGTIMER}:"")})
exten => s,n,Macro(record-enable,${EXTTOCALL},IN)
exten => s,n,GotoIf($["${CHANNEL:0:5}" = "Local"]?dolocaldial,1) ; if 
the channel is Local
exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS},${EXTTOCALL})
exten => s,n,GosubIf($[$["${DIALSTATUS}"="NOANSWER"] & 
$["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer
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})

; Local channel should try to ring the phone only then come back out
; i.e. it's wrong for it to Answer the call in any way (including Congestion
; and stop the initiating dialplan from being returned to)
exten => dolocaldial,1,Macro(dial,,${DIAL_OPTIONS},${EXTTOCALL})
exten => dolocaldial,n,NoOp(Returned to dolocaldial with DIALSTATUS 
'${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

; 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,Busy()
exten => s-BUSY,n,Wait(60)
exten => s-BUSY,n,Congestion()

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

[macro-vm]
exten => s,1,Macro(user-callerid)
exten => s,n,Set(VMGAIN=${IF($["foo${VM_GAIN}"!="foo"]?"g(${VM_GAIN})":"")})
exten => s,n,Goto(s-${ARG2},1)

exten => s-BUSY,1,NoOp(BUSY voicemail)
exten => s-BUSY,n,Macro(get-vmcontext,${ARG1})
exten => s-BUSY,n,Voicemail(${ARG1}@${VMCONTEXT}|b${VMGAIN})   ; 
Voicemail Busy message
exten => s-BUSY,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_DDTYPE}${VMGAIN})
exten => s-DIRECTDIAL,n,Goto(exit-${VMSTATUS},1)

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

exten => o,1,Background(one-moment-please)      ; 0 during vm message 
will hangup
exten => o,n,GotoIf($["foo${FROM_DID}" = 
"foo"]?from-pstn,s,1:from-pstn,${FROM_DID},1)

exten => a,1,Macro(get-vmcontext,${ARG1})
exten => a,n,VoiceMailMain(${ARG1}@${VMCONTEXT})
exten => a,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()

; 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)
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
;
[macro-outisbusy]
exten => s,1,Playback(all-circuits-busy-now)
exten => s,2,Playback(pls-try-call-later)
exten => s,3,Macro(hangupcall)

; What to do on hangup.
[macro-hangupcall]
exten => s,1,ResetCDR(w)
exten => s,2,NoCDR()
exten => s,3,Wait(5)
exten => s,4,Hangup

[macro-faxreceive]
exten => s,1,Set(FAXFILE=/var/spool/asterisk/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)
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,Congestion
exten => s,109,Macro(outisbusy)


; dialout using default OUT trunk - no prefix
[macro-dialout-default]
exten => s,1,Macro(user-callerid)
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,Congestion
exten => s,105,Macro(outisbusy)

; 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),Set(GROUP()=OUT_${DIAL_TRUNK})
exten => s,n,Macro(user-callerid)
exten => s,n,Macro(record-enable,${CALLERID(number)},OUT)
exten => s,n,Macro(outbound-callerid,${DIAL_TRUNK})
exten => s,n,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:"
exten => s,n,GotoIf($["${custom}" = "AMP"]?customtrunk)
exten => s,n,Dial(${OUT_${DIAL_TRUNK}}/${OUTNUM},120,${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},120,${TRUNK_OPTIONS})
exten => s,n,Goto(s-${DIALSTATUS},1)

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

exten => s-BUSY,1,NoOp(Trunk is reporting BUSY)
exten => s-BUSY,2,Busy()
exten => s-BUSY,3,Wait(60)
exten => s-BUSY,4,NoOp()

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

; 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)
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)
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]
; This has been violently beaten upon by Rob Thomas, xrobau at gmail.com
; to 1: Be compliant with all the depreciated bits in asterisk 1.2 and
; above, and 2: to give a good shot at attempting to be compliant with
; RFC3761 by honouring the order in which records are returned.
exten => s,1,GotoIf($["${ARG3}" = ""]PASSWD?NOPASSWD); arg3 is pattern 
password
exten => s,n(PASSWD),Authenticate(${ARG3})
exten => s,n(NOPASSWD),Macro(user-callerid)
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($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${ARG1}} ]?nochans)
exten => s,n,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
exten => s,n,Set(E164NETWORKS=e164.arpa-e164.info-e164.org) ; enum 
networks to check
exten => s,n,GotoIf($["${DIAL_NUMBER:0:1}" = "+"]?begin) ; Skip next 
line if it already is prefixed by a plus
exten => s,n,Set(DIAL_NUMBER=+${DIAL_NUMBER}) ; Add a plus to the start, 
becasue ENUMLOOKUP needs it.

; start of main network loop
exten => s,n(begin),NoOp(E164NETWORKS is ${E164NETWORKS})
exten => s,n,GotoIf($["${E164NETWORKS:1:2}"=""]?failedtotally)
exten => s,n,Set(ENUMNET=${CUT(E164NETWORKS,-,1)})
exten => s,n,Set(E164NETWORKS=${CUT(E164NETWORKS,-,2-)})

exten => s,n,NoOp(E164NETWORKS is now ${E164NETWORKS})
exten => s,n,NoOp(ENUMNET is ${ENUMNET})

exten => s,n,Set(ENUMCOUNT=${ENUMLOOKUP(${DIAL_NUMBER},all,c,${ENUMNET})})
exten => s,n,Set(ENUMPTR=0)
exten => s,n,Set(LOOKUPBUG=0)

; start of main lookup loop
exten => 
s,n(startloop),GotoIf($["${ENUMPTR}"<"${ENUMCOUNT}"]?continue:failed)

; Now, let's start through them.
exten => s,n(continue),Set(ENUMPTR=$[${ENUMPTR}+1])
exten => s,n,NoOp(Doing 
ENUMLOOKUP(${DIAL_NUMBER},all,${ENUMPTR},${ENUMNET}))
exten => 
s,n,Set(ENUM=${ENUMLOOKUP(${DIAL_NUMBER},all,${ENUMPTR},${ENUMNET})})

; Deal with reponse
exten => s,n,GotoIf($["${ENUM:0:3}" = "sip" ]?sipuri)
exten => s,n,GotoIf($["${ENUM:0:3}" = "iax" ]?iaxuri)
; It doesn't matter if you don't have h323 enabled, as when it tries to 
dial, it cares
; about dialstatus and retries if there are any enum results left.
exten => s,n,GotoIf($["${ENUM:0:3}" = "h32" ]?h323uri)

; e164.org can return 'ADDRESS' lines. Because of *'s poor handling of Enum
; lookups, we want to DECREMENT the enum pointer. Yes. That means we try 
more
; times than there actually exists entries.
exten => s,n,GotoIf($["${ENUM:0:3}" = "ADD" ]?enumbug)

; OK. If we're here, we've still got some enum entries to go through. 
Back to
; the start with you!
exten => s,n,Goto(startloop)

; We're here because of the poor implementation of ENUMLOOKUP in 
Asterisk. It
; is quite possible to do three ENUMLOOKUPS and get the same entry each 
time.
; The only workaround I can think of is when we hit an invalid entry, do a
; DECREMENT of the pointer, and keep trying.
exten => s,n(enumbug),Set(ENUMPTR=$[${ENUMPTR}-1])
exten => s,n,NoOp(If this is looping with the same ENUM value, The 
ENUMLOOKUP function is fixed!)
exten => s,n,Set(LOOKUPBUG=$[${LOOKUPBUG}+1])
; If we've done this more than, ooh, 5 times, then give up on this 
network. Sorry.
exten => s,n,GotoIf($["${LOOKUPBUG}" > 5 ]?failed)
exten => s,n,Goto(continue)

; If the prefix is 'sip:'...
exten => s,n(sipuri),Set(DIALSTR=SIP/${ENUM:4})
exten => s,n,Goto(dodial)

; If it's IAX2...
exten => s,n(iaxuri),Set(DIALSTR=IAX2/${ENUM:5})
exten => s,n,Goto(dodial)

; Or even if it's H323.
exten => s,n(h323uri),Set(DIALSTR=H323/${ENUM:5})

exten => s,n(dodial),Dial(${DIALSTR})
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 probably want to try again on a
; different channel. However, if it's the last one, we don't have any
; left, and I didn't keep any previous dialstatuses, so hopefully
; someone looking throught the logs would have seen the NoOp's
exten => s,n,GotoIf($["${ENUMPTR}"<"${ENUMCOUNT}"]?maybemore:dialfailed)
exten => s,n(maybemore),GotoIf($[ $[ "${DIALSTATUS}" = "CHANUNAVAIL" ] | 
$[ "${DIALSTATUS}" = "CONGESTION" ] ]?continue)

; 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(failed),NoOp(EnumLookup failed on network ${ENUMNET})
exten => s,n,Goto(begin)

exten => s,n(failedtotally),NoOp(EnumLookup failed -- no more networks 
to try)
exten => s,n,Goto(end)

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()
exten => s-BUSY,3,Wait(60)
exten => s-BUSY,4,NoOp()

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,${TIMESTAMP},${UNIQUEID})
exten => s,5,Noop(No recording needed)
exten => s,999,Monitor(wav49,${CALLFILENAME}, mb)

;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,28,Noop(TIMESTAMP=${TIMESTAMP})
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,BackGround(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 
/var/spool/asterisk/voicemail/default/${AMPUSER}/ 
/var/spool/asterisk/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 
/var/spool/asterisk/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/${CALLERID(number)}-ivrrecording:wav)
exten => dorecord,n,Wait(1)
exten => dorecord,n,Goto(confmenu,1)

exten => docheck,1,Playback(/tmp/${CALLERID(number)}-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||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
[macro-user-callerid]
exten => s,1,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)
exten => s,n,Set(CALLERID(all)=${AMPUSERCIDNAME} <${AMPUSER}>)
exten => s,n(report),NoOp(Using CallerID ${CALLERID(all)})

; overrides callerid out trunks
; arg1 is trunk
; macro-user-callerid should be called _before_ using this macro
[macro-outbound-callerid]
exten => s,1,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start)
exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)})
exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM})
exten => s,n,Set(USEROUTCID=${DB(AMPUSER/${REALCALLERIDNUM}/outboundcid)})
exten => 
s,n,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(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,SetCallerPres(allowed_passed_screen); stop gap until 
app_privacy.c clears unavailble bit
exten => s,PRIVMGR+101,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,Congestion()
exten => s,n,Hangup


;
; 
############################################################################
; 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,Congestion
exten => s,n,Hangup
exten => h,1,NoOp(Hangup)
exten => i,1,NoOp(Invalid)
exten => t,1,NoOp(Timeout)

[from-internal]
; 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 => from-internal-additional
exten => s,1,Macro(hangupcall)
exten => h,1,Macro(hangupcall)

[from-zaptel]
exten => _X.,1,Set(DID=${EXTEN})
exten => _X.,n,Goto(s,1)
exten => s,1,NoOp(Entering from-zaptel with DID == ${DID})
; 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(ext-did,${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(ext-did,${DID},1)


; 
############################################################################
; 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,system(/var/lib/asterisk/bin/fax-process.pl --to 
${EMAILADDR} --from ${FAX_RX_FROM} --subject "Fax from 
${CALLERID(number)} ${CALLERID(name)}" --attachment 
${CALLERID(number)}.pdf --type application/pdf --file ${FAXFILE});
exten => in_fax,5,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,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)




More information about the asterisk-users mailing list