<div>Segue sip.conf e extension.conf..... Att, Deisy</div>
<div>
<p>; Note: If your SIP devices are behind a NAT and your Asterisk<br>; server isn't, try adding "nat=1" to each peer definition to<br>; solve translation problems.</p>
<p>[general]</p>
<p>bindport=5060 ; UDP Port to bind to (SIP standard port is 5060)<br>bindaddr=<a href="http://0.0.0.0">0.0.0.0</a> ; IP address to bind to (<a href="http://0.0.0.0">0.0.0.0</a> binds to all)<br>disallow=all<br>allow=g723,g729,gsm
<br>;allow=alaw<br>context = from-sip-external ; Send unknown SIP callers to this context<br>callerid = Unknown<br>tos=throughput</p>
<p><br>#include sip_nat.conf<br>#include sip_custom.conf<br>#include sip_additional.conf<br>#include additional_a2billing_sip.conf</p>
<p>--------------------------------------------------------------</p>
<p>; include extension contexts generated from AMP<br>#include extensions_additional.conf</p>
<p>; Customizations to this dialplan should be made in extensions_custom.conf<br>; See extensions_custom.conf.sample for an example<br>#include extensions_custom.conf</p>
<p>[from-trunk] ; just an alias since VoIP shouldn't be called PSTN<br>include => from-pstn</p>
<p>[from-pstn]<br>include => from-pstn-custom ; create this context in extensions_custom.conf to include customizations<br>include => ext-did<br>exten => fax,1,Goto(ext-fax,in_fax,1)</p>
<p><br>; ############################################################################<br>; Macros [macro]<br>; ############################################################################</p>
<p>; Rings one or more extensions. Handles things like call forwarding and DND<br>; We don't call dial directly for anything internal anymore.<br>; ARGS: $TIMER, $OPTIONS, $EXT1, $EXT2, $EXT3, ...<br>; Use a Macro call such as the following:
<br>; Macro(dial,$DIAL_TIMER,$DIAL_OPTIONS,$EXT1,$EXT2,$EXT3,...)<br>[macro-dial]<br>;exten => s,1,GotoIf($[ "${MACRO_CONTEXT}" = "macro-rg-group" ]?4:2) ; if this is from rg-group, don't strip prefix
<br>;exten => s,2,GotoIf($["${CALLERID(name):0:${LEN(${RGPREFIX})}}" != "${RGPREFIX}"]?4:3) ; check for ring-group prefix<br>;exten => s,3,Set(CALLERID(name)=${CALLERID(name):${LEN(${RGPREFIX})}}) ; strip off prefix
<br>exten => s,1,AGI,dialparties.agi<br>exten => s,2,NoOp(Returned from dialparties with no extensions to call)<br>exten => s,3,Set(DIALSTATUS=BUSY)<br>exten => s,10,Dial(${ds}) ; dialparties will set the priority to 10 if $ds is not null
<br>exten => s,20,NoOp(Returned from dialparties with hunt groups to dial )<br>exten => s,21,Set(HuntLoop=0)<br>exten => s,22,GotoIf($[${HuntMembers} >= 1]?30 ) ; if this is from rg-group, don't strip prefix
<br>exten => s,23,NoOp(Returning there are no members left in the hunt group to ring)</p>
<p>exten => s,30,Set(HuntMember=HuntMember${HuntLoop})<br>exten => s,31,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "hunt" ]]?32:35 ) ; Set CAll Trace for Hunt member we are going to call
<br> exten => s,32,Set(CT_EXTEN=${CUT(ARG3,,$[${HuntLoop} + 1])})<br> exten => s,33,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT})<br> exten => s,34,Goto(s,42)</p>
<p>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
<br> exten => s,36,Set(CTLoop=0)<br> exten => s,37,GotoIf($[${CTLoop} > ${HuntLoop}]?42 ) ; if this is from rg-group, don't strip prefix<br> exten => s,38,Set(CT_EXTEN=${CUT(ARG3,,$[${CTLoop} + 1])})
<br> exten => s,39,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT})<br> exten => s,40,Set(CTLoop=$[1 + ${CTLoop}])<br> exten => s,41,Goto(s,37)<br>exten => s,42,Dial(${${HuntMember}}${ds} ) ; dialparties will set the priority to 20 if $ds is not null and its a hunt group
<br>exten => s,43,Set(HuntLoop=$[1 + ${HuntLoop}])<br>exten => s,44,Set(HuntMembers=$[${HuntMembers} - 1])<br>exten => s,45,Goto(s,22)<br>exten => s,50,DBdel(CALLTRACE/${CT_EXTEN})<br>exten => s,51,Goto(s,42)
</p>
<p><br>;exten => s,1,GotoIf($[ "${MACRO_CONTEXT}" = "macro-rg-group" ]?4:2) ; if this is from rg-group, don't strip prefix<br>;exten => s,2,GotoIf($[${CALLERID(name):0:${LEN(${RGPREFIX})}} != ${RGPREFIX}]?4:3) ; check for ring-group prefix
<br>;exten => s,3,Set(CALLERID(name)=${CALLERID(name):${LEN(${RGPREFIX})}}) ; strip off prefix<br>;exten => s,4,AGI,dialparties.agi<br>;exten => s,5,NoOp(Returned from dialparties with no extensions to call)<br>;exten => s,6,Set(DIALSTATUS=BUSY)
<br>;exten => s,10,Dial(${ds}) ; dialparties will set the priority to 10 if $ds is not null</p>
<p>; Ring an extension, if the extension is busy or there is no answer send it<br>; to voicemail<br>; ARGS: $VMBOX, $EXT<br>[macro-exten-vm]<br>exten => s,1,Macro(user-callerid)<br>exten => s,2,Set(FROMCONTEXT=exten-vm)
<br>exten => s,3,Macro(record-enable,${ARG2},IN)<br>exten => s,4,Macro(dial,${RINGTIMER},${DIAL_OPTIONS},${ARG2})<br>exten => s,5,GotoIf($["${CHANNEL:0:5}" = "Local"]?s-${DIALSTATUS},1) ; if the channel is Local, then do not go to voicemail. This is primarily to avoid vm for call-forwarded extensions in ring groups
<br>exten => s,6,GotoIf($["${ARG1}" = "novm"]?s-${DIALSTATUS},1) ; no voicemail in use for this extension<br>exten => s,7,NoOp(Sending to Voicemail box ${ARG2})<br>exten => s,8,Macro(vm,${ARG1},${DIALSTATUS})
<br>exten => s-BUSY,1,NoOp(Extension is reporting BUSY and has no Voicemail)<br>exten => s-BUSY,2,Busy()<br>exten => s-BUSY,3,Wait(60)<br>exten => s-BUSY,4,NoOp()<br>exten => _s-.,1,Congestion()</p>
<p>[macro-vm]<br>exten => s,1,Macro(user-callerid)<br>exten => s,2,Goto(s-${ARG2},1)<br>exten => s-BUSY,1,Macro(get-vmcontext,${ARG1})<br>exten => s-BUSY,2,Voicemail(<a href="mailto:b${ARG1}@${VMCONTEXT">b${ARG1}@${VMCONTEXT
</a>}) ; Voicemail Busy message<br>exten => s-BUSY,3,Hangup()<br>exten => _s-.,1,Macro(get-vmcontext,${ARG1})<br>exten => _s-.,2,Voicemail(<a href="mailto:u${ARG1}@${VMCONTEXT">u${ARG1}@${VMCONTEXT</a>}) ; Voicemail Unavailable message
<br>exten => _s-.,3,Hangup()<br>exten => o,1,Background(one-moment-please) ; 0 during vm message will hangup<br>exten => o,2,GotoIf($["foo${FROM_DID}" = "foo"]?from-pstn,s,1:from-pstn,${FROM_DID},1)
<br>exten => a,1,Macro(get-vmcontext,${ARG1})<br>exten => a,2,VoiceMailMain(<a href="mailto:${ARG1}@${VMCONTEXT">${ARG1}@${VMCONTEXT</a>})<br>exten => a,3,Hangup</p>
<p>; get the voicemail context for the user in ARG1<br>[macro-get-vmcontext]<br>exten => s,1,Set(VMCONTEXT=${DB(AMPUSER/${ARG1}/voicemail)})<br>exten => s,2,GotoIf($["foo${VMCONTEXT}" = "foo"]?200:300)
<br>exten => s,200,Set(VMCONTEXT=default)<br>exten => s,300,NoOp()</p>
<p>; For some reason, if I don't run setCIDname, CALLERID(name) will be blank in my AGI<br>; ARGS: none<br>[macro-fixcid]<br>exten => s,1,Set(CALLERID(name)=${CALLERID(name)})</p>
<p>; Ring groups of phones<br>; ARGS: comma separated extension list<br>; 1 - Ring Group Strategy<br>; 2 - ringtimer<br>; 3 - prefix<br>; 4 - extension list<br>[macro-rg-group]<br>exten => s,1,Macro(user-callerid)<br>
exten => s,2,GotoIf($["${CALLERID(name):0:${LEN(${RGPREFIX})}}" != "${RGPREFIX}"]?4:3) ; check for old prefix<br>exten => s,3,Set(CALLERID(name)=${CALLERID(name):${LEN(${RGPREFIX})}}) ; strip off old prefix
<br>exten => s,4,Set(RGPREFIX=${ARG3}) ; set new prefix<br>exten => s,5,Set(CALLERID(name)=${RGPREFIX}${CALLERID(name)}) ; add prefix to callerid name<br>exten => s,6,Set(RecordMethod=Group) ; set new prefix<br>
exten => s,7,Macro(record-enable,${MACRO_EXTEN},${RecordMethod})<br>exten => s,8,Set(RingGroupMethod=${ARG1}) ;<br>exten => s,9,Macro(dial,${ARG2},${DIAL_OPTIONS},${ARG4})<br>exten => s,10,Set(RingGroupMethod='') ;
</p>
<p><br>;<br>; Outgoing channel(s) are busy ... inform the client<br>;<br>[macro-outisbusy]<br>exten => s,1,Playback(all-circuits-busy-now)<br>exten => s,2,Playback(pls-try-call-later)<br>exten => s,3,Macro(hangupcall)
</p>
<p>; What to do on hangup.<br>[macro-hangupcall]<br>exten => s,1,ResetCDR(w)<br>exten => s,2,NoCDR()<br>exten => s,3,Wait(5)<br>exten => s,4,Hangup</p>
<p>[macro-faxreceive]<br>exten => s,1,Set(FAXFILE=/var/spool/asterisk/fax/${UNIQUEID}.tif)<br>exten => s,2,Set(EMAILADDR=${FAX_RX_EMAIL})<br>exten => s,3,rxfax(${FAXFILE})<br>exten => s,103,Set(EMAILADDR=${FAX_RX_EMAIL})
<br>exten => s,104,Goto(3)</p>
<p>; dialout and strip the prefix<br>[macro-dialout]<br>exten => s,1,Macro(user-callerid)<br>exten => s,2,GotoIf($["${ECID${CALLERID(number)}}" = ""]?5) ;check for CID override for exten<br>exten => s,3,Set(CALLERID(all)=${ECID${CALLERID(number)}})
<br>exten => s,4,Goto(7)<br>exten => s,5,GotoIf($["${OUTCID_${ARG1}}" = ""]?7) ;check for CID override for trunk<br>exten => s,6,Set(CALLERID(all)=${OUTCID_${ARG1}})<br>exten => s,7,Set(length=${LEN(${DIAL_OUT_${ARG1}})})
<br>exten => s,8,Dial(${OUT_${ARG1}}/${ARG2:${length}})<br>exten => s,9,Congestion<br>exten => s,109,Macro(outisbusy)</p>
<p><br>; dialout using default OUT trunk - no prefix<br>[macro-dialout-default]<br>exten => s,1,Macro(user-callerid)<br>exten => s,2,Macro(record-enable,${CALLERID(number)},OUT)<br>exten => s,3,Macro(outbound-callerid,${ARG1})
<br>exten => s,4,Dial(${OUT}/${ARG1})<br>exten => s,5,Congestion<br>exten => s,105,Macro(outisbusy)</p>
<p>; dialout using a trunk, using pattern matching (don't strip any prefix)<br>; arg1 = trunk number, arg2 = number, arg3 = route password<br>[macro-dialout-trunk]<br>exten => s,1,GotoIf($["${ARG3}" = ""]?3:2) ; arg3 is pattern password
<br>exten => s,2,Authenticate(${ARG3})<br>exten => s,3,Macro(user-callerid)<br>exten => s,4,Macro(record-enable,${CALLERID(number)},OUT)<br>exten => s,5,Macro(outbound-callerid,${ARG1})<br>exten => s,6,Set(GROUP()=OUT_${ARG1})
<br>exten => s,7,GotoIf($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${ARG1}} ]?108)<br>; if we've used up the max channels, continue at (n+101)<br>exten => s,8,Set(DIAL_NUMBER=${ARG2})<br>exten => s,9,Set(DIAL_TRUNK=${ARG1})
<br>exten => s,10,AGI(fixlocalprefix) ; this sets DIAL_NUMBER to the proper dial string for this trunk<br>exten => s,11,Set(OUTNUM=${OUTPREFIX_${ARG1}}${DIAL_NUMBER}) ; OUTNUM is the final dial number<br>exten => s,12,Set(custom=${CUT(OUT_${ARG1},:,1)}) ; Custom trunks are prefixed with "AMP:"
<br>exten => s,13,GotoIf($["${custom}" = "AMP"]?16)<br>exten => s,14,Dial(${OUT_${ARG1}}/${OUTNUM}|120|W) ; Regular Trunk Dial, allow recording.<br>exten => s,15,Goto(s-${DIALSTATUS},1)</p>
<p>; This is a custom trunk. Substitute $OUTNUM$ with the actual number and rebuild the dialstring<br>; example trunks: "AMP:CAPI/XXXXXXXX:b$OUTNUM$,30,r", "AMP:OH323/$OUTNUM$@XX.XX.XX.XX:XXXX"<br>exten => s,16,Set(pre_num=${CUT(OUT_${ARG1},$,1)})
<br>exten => s,17,Set(the_num=${CUT(OUT_${ARG1},$,2)}) ; this is where we expect to find string OUTNUM<br>exten => s,18,Set(post_num=${CUT(OUT_${ARG1},$,3)})<br>exten => s,19,GotoIf($["${the_num}" = "OUTNUM"]?20:21) ; if we didn't find "OUTNUM", then skip to Dial
<br>exten => s,20,Set(the_num=${OUTNUM}) ; replace "OUTNUM" with the actual number to dial<br>exten => s,21,Dial(${pre_num:4}${the_num}${post_num})<br>exten => s,22,Goto(s-${DIALSTATUS},1)</p>
<p>exten => s,108,Noop(max channels used up)<br>exten => s-BUSY,1,NoOp(Trunk is reporting BUSY)<br>exten => s-BUSY,2,Busy()<br>exten => s-BUSY,3,Wait(60)<br>exten => s-BUSY,4,NoOp()</p>
<p>exten => _s-.,1,NoOp(Dial failed due to ${DIALSTATUS})</p>
<p>; Adds a dynamic agent/member to a Queue<br>; Prompts for call-back number - in not entered, uses CIDNum<br>[macro-agent-add]<br>exten => s,1,Wait(1)<br>exten => s,2,Macro(user-callerid)<br>exten => s,3,Read(CALLBACKNUM,agent-user) ; get callback number from user
<br>exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?5:7)) ; if user just pressed # or timed out, use cidnum<br>exten => s,5,Set(CALLBACKNUM=${CALLERID(number)})<br>exten => s,6,GotoIf($["${CALLBACKNUM}" = ""]?2)) ; if still no number, start over
<br>exten => s,7,GotoIf($["${ARG2}" = ""]?9:8)) ; arg2 is queue password<br>exten => s,8,Authenticate(${ARG2})<br>exten => s,9,AddQueueMember(<a href="mailto:${ARG1}|Local/${CALLBACKNUM}@from-internal/n">
${ARG1}|Local/${CALLBACKNUM}@from-internal/n</a>) ; using chan_local allows us to have agents over trunks<br>exten => s,10,UserEvent(Agentlogin|Agent: ${CALLBACKNUM})<br>exten => s,11,Wait(1)<br>exten => s,12,Playback(agent-loginok)
<br>exten => s,13,Hangup()</p>
<p>; Removes a dynamic agent/member from a Queue<br>; Prompts for call-back number - in not entered, uses CIDNum<br>[macro-agent-del]<br>exten => s,1,Wait(1)<br>exten => s,2,Macro(user-callerid)<br>exten => s,3,Read(CALLBACKNUM,agent-user) ; get callback number from user
<br>exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?5:7)) ; if user just pressed # or timed out, use cidnum<br>exten => s,5,Set(CALLBACKNUM=${CALLERID(number)})<br>exten => s,6,GotoIf($["${CALLBACKNUM}" = ""]?2)) ; if still no number, start over
<br>exten => s,7,RemoveQueueMember(<a href="mailto:${ARG1}|Local/${CALLBACKNUM}@from-internal/n">${ARG1}|Local/${CALLBACKNUM}@from-internal/n</a>)<br>exten => s,8,UserEvent(RefreshQueue)<br>exten => s,9,Wait(1)<br>
exten => s,10,Playback(agent-loggedoff)<br>exten => s,11,Hangup()</p>
<p>; arg1 = trunk number, arg2 = number<br>[macro-dialout-enum]<br>; This has been violently beaten upon by Rob Thomas, <a href="mailto:xrobau@gmail.com">xrobau@gmail.com</a><br>; to 1: Be compliant with all the depreciated bits in asterisk
1.2 and<br>; above, and 2: to give a good shot at attempting to be compliant with<br>; RFC3761 by honouring the order in which records are returned.<br>exten => s,1,Macro(user-callerid)<br>exten => s,n,Macro(record-enable,${CALLERID(number)},OUT)
<br>exten => s,n,Macro(outbound-callerid,${ARG1})<br>exten => s,n,Set(GROUP()=OUT_${ARG1})<br>exten => s,n,GotoIf($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${ARG1} ]?nochans)<br>exten => s,n,Set(DIAL_NUMBER=${ARG2})
<br>exten => s,n,Set(DIAL_TRUNK=${ARG1})<br>exten => s,n,AGI(fixlocalprefix) ; this sets DIAL_NUMBER to the proper dial string for this trunk<br>exten => s,n,GotoIf($["${DIAL_NUMBER:0:1}" = "+"]?hasplus) ; Skip next line if it already is prefixed by a plus
<br>exten => s,n,Set(DIAL_NUMBER=+${DIAL_NUMBER}) ; Add a plus to the start, becasue ENUMLOOKUP needs it.<br>; OK, this is now quite complex. To remain compliant, we have to iterate<br>; through, in order, the returned records. Since we want to make this
<br>; call over the network, we can ignore tel: lines. Even if it's first<br>; priority. <br>exten => s,n(hasplus),Set(ENUMCOUNT=${ENUMLOOKUP(${DIAL_NUMBER},ALL,c,<a href="http://e164.org">e164.org</a>)}) ; Should
<a href="http://e164.org">e164.org</a> be a var? I think so.<br>; Now the count may be zero, so if it is, just go to failed<br>exten => s,n,GotoIf($[ $[ ${ENUMCOUNT} = 0 ] | $[x${ENUMCOUNT} = x ] ]?failed)<br>; Now, let's start through them.
<br>exten => s,n,Set(ENUMPTR=1)<br>exten => s,n(startloop),Set(ENUM=${ENUMLOOKUP(${DIAL_NUMBER},ALL,${ENUMPTR},<a href="http://e164.org">e164.org</a>)})<br>; Sanity check the return, make sure there's something in there.
<br>exten => s,n,GotoIf($[${LEN(${ENUM})} = 0 ]?continue)<br>exten => s,n,GotoIf($["${ENUM:0:3}" = "sip" ]?sipuri)<br>exten => s,n,GotoIf($["${ENUM:0:3}" = "iax" ]?iaxuri)<br>
; It doesn't matter if you don't have h323 enabled, as when it tries to dial, it cares<br>; about dialstatus and retries if there are any enum results left.<br>exten => s,n,GotoIf($["${ENUM:0:3}" = "h32" ]?h323uri)
<br>; If we're here, it's not a protocol we know about. Let's increment the pointer<br>; and if it's more than ENUMCOUNT, we know we've run out of options. We also can<br>; come here if the enum string we've received is empty, or if the Dial command
<br>; returned CONGESTION or CHANUNAVAIL.<br>exten => s,n(continue),Set(ENUMPTR=$[${ENUMPTR}+1])<br>exten => s,n,GotoIf($[${ENUMPTR} > ${ENUMCOUNT}]?failed)<br>; OK. If we're here, we've still got some enum entries to go through. Back to
<br>; the start with you!<br>exten => s,n,Goto(startloop)<br>; If the prefix is 'sip:'...<br>exten => s,n(sipuri),Set(DIALSTR=SIP/${ENUM:4})<br>exten => s,n,Goto(dodial)<br>; If it's IAX2...<br>exten => s,n(iaxuri),Set(DIALSTR=IAX2/${ENUM:5})
<br>exten => s,n,Goto(dodial)<br>; Or even if it's H323.<br>exten => s,n(h323uri),Set(DIALSTR=H323/${ENUM:5})</p>
<p>exten => s,n(dodial),Dial(${DIALSTR})<br>exten => s,n,NoOp(Dial exited in macro-enum-dialout with ${DIALSTATUS})<br>; Now, if we're still here, that means the Dial failed for some reason. <br>; If it's CONGESTION or CHANUNAVAIL we probably want to try again on a
<br>; different channel. However, if it's the last one, we don't have any<br>; left, and I didn't keep any previous dialstatuses, so hopefully <br>; someone looking throught the logs would have seen the NoOp's
<br>exten => s,n,GotoIf($["${ENUMPTR}" = "${ENUMCOUNT}"]?noneleft)<br>exten => s,n,GotoIf($[ $[ "${DIALSTATUS}" = "CHANUNAVAIL" ] | $[ "${DIALSTATUS}" = "CONGESTION" ] ]?continue)
<br>; If we're here, then it's BUSY or NOANSWER or something and well, deal with it.<br>exten => s,n(noneleft),Goto(s-${DIALSTATUS},1)<br>; Here are the exit points for the macro.<br>exten => s,n(failed),NoOp(EnumLookup failed)
<br>exten => s,n,Goto(end)<br>exten => s,n(nochans),NoOp(max channels used up)<br>exten => s,n(end),NoOp(Exiting macro-dialout-enum)</p>
<p>exten => s-BUSY,1,NoOp(Trunk is reporting BUSY)<br>exten => s-BUSY,2,Busy()<br>exten => s-BUSY,3,Wait(60)<br>exten => s-BUSY,4,NoOp()</p>
<p>exten => _s-.,1,NoOp(Dial failed due to ${DIALSTATUS})</p>
<p>[macro-record-enable]<br>exten => s,1,GotoIf(${LEN(${BLINDTRANSFER})} > 0?2:4)<br>exten => s,2,ResetCDR(w)<br>exten => s,3,StopMonitor()<br>exten => s,4,AGI(recordingcheck,${TIMESTAMP},${UNIQUEID})<br>exten => s,5,Noop(No recording needed)
<br>exten => s,999,Monitor(wav49,${CALLFILENAME}, mb)</p>
<p>;exten => s,3,BackGround(for-quality-purposes)<br>;exten => s,4,BackGround(this-call-may-be)<br>;exten => s,5,BackGround(recorded)</p>
<p>; This macro is for dev purposes and just dumps channel/app variables. Useful when designing new contexts. <br>[macro-dumpvars]<br>exten => s,1,Noop(ACCOUNTCODE=${ACCOUNTCODE})<br>exten => s,2,Noop(ANSWEREDTIME=${ANSWEREDTIME})
<br>exten => s,3,Noop(BLINDTRANSFER=${BLINDTRANSFER})<br>exten => s,4,Noop(CALLERID=${CALLERID(all)})<br>exten => s,5,Noop(CALLERID(name)=${CALLERID(name)})<br>exten => s,6,Noop(CALLERID(number)=${CALLERID(number)})
<br>exten => s,7,Noop(CALLINGPRES=${CALLINGPRES})<br>exten => s,8,Noop(CHANNEL=${CHANNEL})<br>exten => s,9,Noop(CONTEXT=${CONTEXT})<br>exten => s,10,Noop(DATETIME=${DATETIME})<br>exten => s,11,Noop(DIALEDPEERNAME=${DIALEDPEERNAME})
<br>exten => s,12,Noop(DIALEDPEERNUMBER=${DIALEDPEERNUMBER})<br>exten => s,13,Noop(DIALEDTIME=${DIALEDTIME})<br>exten => s,14,Noop(DIALSTATUS=${DIALSTATUS})<br>exten => s,15,Noop(DNID=${DNID})<br>exten => s,16,Noop(EPOCH=${EPOCH})
<br>exten => s,17,Noop(EXTEN=${EXTEN})<br>exten => s,18,Noop(HANGUPCAUSE=${HANGUPCAUSE})<br>exten => s,19,Noop(INVALID_EXTEN=${INVALID_EXTEN})<br>exten => s,20,Noop(LANGUAGE=${LANGUAGE})<br>exten => s,21,Noop(MEETMESECS=${MEETMESECS})
<br>exten => s,22,Noop(PRIORITY=${PRIORITY})<br>exten => s,23,Noop(RDNIS=${RDNIS})<br>exten => s,24,Noop(SIPDOMAIN=${SIPDOMAIN})<br>exten => s,25,Noop(SIP_CODEC=${SIP_CODEC})<br>exten => s,26,Noop(SIPCALLID=${SIPCALLID})
<br>exten => s,27,Noop(SIPUSERAGENT=${SIPUSERAGENT})<br>exten => s,28,Noop(TIMESTAMP=${TIMESTAMP})<br>exten => s,29,Noop(TXTCIDNAME=${TXTCIDNAME})<br>exten => s,30,Noop(UNIQUEID=${UNIQUEID})<br>exten => s,31,Noop(TOUCH_MONITOR=${TOUCH_MONITOR})
<br>exten => s,32,Noop(MACRO_CONTEXT=${MACRO_CONTEXT})<br>exten => s,33,Noop(MACRO_EXTEN=${MACRO_EXTEN})<br>exten => s,34,Noop(MACRO_PRIORITY=${MACRO_PRIORITY})</p>
<p>[macro-user-logon]<br>; check device type<br>exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})<br>exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)<br>; get user's extension
<br>exten => s,3,Set(AMPUSER=${ARG1})<br>exten => s,4,GotoIf($["${AMPUSER}" = ""]?5:9)<br>exten => s,5,BackGround(please-enter-your)<br>exten => s,6,Playback(extension)<br>exten => s,7,Read(AMPUSER,then-press-pound)
<br>; get user's password and authenticate<br>exten => s,8,Wait(1)<br>exten => s,9,Set(AMPUSERPASS=${DB(AMPUSER/${AMPUSER}/password)})<br>exten => s,10,GotoIf($[${LEN(${AMPUSERPASS})} = 0]?s-NOPASSWORD,1)<br>
; do not continue if the user has already logged onto this device<br>exten => s,11,Set(DEVICEUSER=${DB(DEVICE/${CALLERID(number)}/user)})<br>exten => s,12,GotoIf($["${DEVICEUSER}" = "${AMPUSER}"]?s-ALREADYLOGGEDON,1)
<br>exten => s,13,Authenticate(${AMPUSERPASS})<br>; devices can only be mapped to one user - loggoff anyone else who is here<br>exten => s,14,Macro(user-logoff)<br>; map user to device<br>exten => s,15,Set(AMPUSERDEVICES=${DB(AMPUSER/${AMPUSER}/device)})
<br>exten => s,16,GotoIf($[${LEN(${AMPUSERDEVICES})} = 0]?18) <br>exten => s,17,Set(AMPUSERDEVICES=${AMPUSERDEVICES}&)<br>exten => s,18,Set(AMPUSERDEVICES=${AMPUSERDEVICES}${CALLERID(number)})<br>exten => s,19,Set(DB(AMPUSER/${AMPUSER}/device)=${AMPUSERDEVICES})
<br>; map device to user<br>exten => s,20,Set(DB(DEVICE/${CALLERID(number)}/user)=${AMPUSER})<br>; create symlink from dummy device mailbox to user's mailbox<br>exten => s,21,System(/bin/ln -s /var/spool/asterisk/voicemail/default/${AMPUSER}/ /var/spool/asterisk/voicemail/device/${CALLERID(number)})
</p>
<p>exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged into)<br>exten => s-FIXED,2,Playback(ha/phone)<br>exten => s-FIXED,3,SayDigits(${CALLERID(number)})<br>exten => s-FIXED,4,Playback(is-curntly-unavail)
<br>exten => s-FIXED,5,Playback(vm-goodbye)<br>exten => s-FIXED,6,Hangup ;TODO should play msg indicated device cannot be logged into </p>
<p>exten => s-ALREADYLOGGEDON,1,NoOp(This device has already been logged into by this user)<br>exten => s-ALREADYLOGGEDON,2,Playback(vm-goodbye)<br>exten => s-ALREADYLOGGEDON,3,Hangup ;TODO should play msg indicated device is already logged into
</p>
<p>exten => s-NOPASSWORD,1,NoOp(This extension does not exist or no password is set)<br>exten => s-NOPASSWORD,2,Playback(an-error-has-occured)<br>exten => s-NOPASSWORD,3,Playback(vm-goodbye)<br>exten => s-NOPASSWORD,4,Hangup ;TODO should play msg indicated device is already logged into
</p>
<p>[macro-user-logoff]<br>; check device type<br>exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})<br>exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)<br>; remove entry from user's DEVICE key
<br>; delete the symlink to user's voicemail box<br>exten => s,3,System(rm -f /var/spool/asterisk/voicemail/device/${CALLERID(number)})<br>exten => s,4,Set(DEVAMPUSER=${DB(DEVICE/${CALLERID(number)}/user)})<br>exten => s,5,Set(AMPUSERDEVICES=${DB(AMPUSER/${DEVAMPUSER}/device)})
<br>exten => s,6,AGI(list-item-remove.php,${AMPUSERDEVICES},${CALLERID(number)},AMPUSERDEVICES,&)<br>; reset user -> device mapping<br>; users can log onto multiple devices, need to just remove device from value
<br>exten => s,7,Set(DB(AMPUSER/${DEVAMPUSER}/device)=${AMPUSERDEVICES})<br>; reset device -> user mapping<br>exten => s,8,Set(DB(DEVICE/${CALLERID(number)}/user)=none)<br>exten => s,9,Playback(vm-goodbye)</p>
<p>exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged out of)<br>exten => s-FIXED,2,Playback(an-error-has-occured)<br>exten => s-FIXED,3,Playback(vm-goodbye)<br>exten => s-FIXED,4,Hangup ;TODO should play msg indicated device cannot be logged into
</p>
<p>;sets the callerid of the device to that of the logged in user<br>[macro-user-callerid]<br>exten => s,1,Set(AMPUSER=${DB(DEVICE/${CALLERID(number)}/user)})<br>exten => s,2,Set(EMERGENCYCID=${DB(DEVICE/${CALLERID(number)}/emergency_cid)})
<br>exten => s,3,Set(AMPUSERCIDNAME=${DB(AMPUSER/${AMPUSER}/cidname)})<br>exten => s,4,GotoIf($["${AMPUSERCIDNAME}" = ""]?6) <br>exten => s,5,Set(CALLERID(all)=\"${AMPUSERCIDNAME}\" <${AMPUSER}>)
<br>exten => s,6,NoOp(Using CallerID ${CALLERID(all)})</p>
<p>; overrides callerid out trunks<br>; arg1 is trunk<br>; macro-user-callerid should be called _before_ using this macro<br>[macro-outbound-callerid]<br>exten => s,1,Set(USEROUTCID=${DB(AMPUSER/${CALLERID(number)}/outboundcid)})
<br>exten => s,2,GotoIf($["${OUTCID_${ARG1}:1:2}" = ""]?4) ;check for CID override for trunk (global var)<br>exten => s,3,Set(CALLERID(all)=${OUTCID_${ARG1}})<br>exten => s,4,GotoIf($["${USEROUTCID:1:2}" = ""]?6) ; check CID override for extension
<br>exten => s,5,Set(CALLERID(all)=${USEROUTCID})<br>exten => s,6,GotoIf($["${EMERGENCYROUTE:1:2}" = ""]?8) ; check EMERGENCYROUTE override (set by route)<br>exten => s,7,Set(CALLERID(all)=${EMERGENCYCID}) ; emergency cid for device
<br>exten => s,8,NoOp(CallerID set to ${CALLERID(all)})</p>
<p> </p>
<p>; ############################################################################<br>; Applications [app]<br>; ############################################################################<br>; Moved to external file applications.conf
</p>
<p>#include applications.conf</p>
<p><br>;<br>; ############################################################################<br>; Inbound Contexts [from]<br>; ############################################################################</p>
<p>[from-sip-external]</p>
<p>;give external sip users congestion and hangup<br>exten => _.,1,Set(TIMEOUT(absolute)=15)<br>exten => _.,2,Congestion <br>exten => _.,3,Hangup</p>
<p>[from-internal]<br>;allow phones to use applications<br>include => app-userlogonoff<br>include => app-directory<br>include => app-dnd<br>include => app-callforward<br>include => app-callwaiting<br>include => app-messagecenter
<br>include => app-calltrace<br>include => parkedcalls<br>include => from-internal-custom<br>;allow phones to dial other extensions<br>include => ext-fax<br>include => ext-zapbarge<br>include => ext-record
<br>include => ext-test<br>;allow phones to access generated contexts<br>include => from-internal-additional<br>exten => s,1,Macro(hangupcall)<br>exten => h,1,Macro(hangupcall)</p>
<p>; ############################################################################<br>; Extension Contexts [ext]<br>; ############################################################################</p>
<p>[ext-zapbarge]<br>exten => 888,1,Macro(user-callerid)<br>exten => 888,2,Set(GROUP()=${CALLERID(number)})<br>exten => 888,3,Answer<br>exten => 888,4,Wait(1)<br>exten => 888,5,ZapBarge<br>exten => 888,6,Hangup
</p>
<p>[ext-fax]<br>exten => s,1,Answer<br>exten => s,2,Goto(in_fax,1)<br>exten => in_fax,1,GotoIf($["${FAX_RX}" = "system"]?2:analog_fax,1)<br>exten => in_fax,2,Macro(faxreceive)<br>exten => in_fax,3,system(tiff2ps -2eaz -w
8.5 -h 11 ${FAXFILE} | ps2pdf - ${FAXFILE}.pdf)<br>exten => in_fax,4,system(mime-construct --to ${EMAILADDR} --subject "Fax from ${CALLERID(number)} ${CALLERID(name)}" --attachment ${CALLERID(number)}.pdf --type application/pdf --file ${FAXFILE}.pdf)
<br>exten => in_fax,5,system(rm ${FAXFILE} ${FAXFILE}.pdf)<br>exten => in_fax,6,Hangup<br>exten => analog_fax,1,GotoIf($["${FAX_RX}" = "disabled"]?3:2) ;if fax is disabled, just hang up<br>exten => analog_fax,2,Set(DIAL=${DB(DEVICE/${FAX_RX}/dial)});
<br>exten => analog_fax,3,Dial(${DIAL},20,d)<br>exten => analog_fax,4,Hangup<br>;exten => out_fax,1,wait(7)<br>exten => out_fax,1,txfax(${TXFAX_NAME}|caller)<br>exten => out_fax,2,Hangup<br>exten => h,1,Hangup()
</p>
<p>[ext-record]<br>exten => *77,1,Macro(user-callerid)<br>exten => *77,2,Wait(2)<br>exten => *77,3,Record(${CALLERID(number)}-ivrrecording:wav) <br>exten => *77,4,Wait(2)<br>exten => *77,5,Hangup<br>exten => *99,1,Macro(user-callerid)
<br>exten => *99,2,Playback(${CALLERID(number)}-ivrrecording) <br>exten => *99,3,Wait(2) <br>exten => *99,4,Hangup </p>
<p>;this is where parked calls go if they time-out. Should probably re-ring<br>[default]<br>include => ext-local<br>exten => s,1,Playback(vm-goodbye)<br>exten => s,2,Macro(hangupcall)</p>
<p>[ext-test]<br>exten => 7777,1,Goto(from-pstn,s,1)<br>exten => 666,1,Goto(ext-fax,in_fax,1)<br>exten => h,1,Macro(hangupcall)</p>
<p>;echo test<br>;exten => *43,1,Answer<br>;exten => *43,2,Wait(2)<br>;exten => *43,3,Playback(demo-echotest)<br>;exten => *43,4,Echo<br>;exten => *43,5,Playback(demo-echodone)<br>;exten => *43,6,Hangup
<br></p></div>
<div><br> </div>