Rauswählen geht nicht mehr....

gooze

Neuer User
Mitglied seit
14 Nov 2006
Beiträge
46
Punkte für Reaktionen
0
Punkte
0
Hallo zusammen,

folgendes Problem.

Mein Asterisk steht hinter unsere Tk. Wenn ich jetzt via S0 eine der Nebenstellen an der TK anrufen will klappt das auch wunderbar. Wenn ich aber nun komplett rauswählen will klappt es nicht mehr. Was mich jetzt vorallem am meisten wundert ist die Tatsache, das wenn ich meine handynummer wählen .. sprich 000177xxxxxxxxx (erste Null für * um auf zap zu gehen, zweite null für amtsleitung auf der TK), klingelt bei uns im Haus die Nebenstelle 177. * Schneidet scheinbar die zwei führenden Nullen weg, ebenso wie alles hinter der 177. Schlimmer wiegt wahrscheinlich des wegschneiden der führenden Nullen so das die Tk die 177 direkt als internes gespräch verarbeitet. Komischerweise hatte es bis vor kurzem auch funktioniert.
Evtl. hab ich auch bei den Outboundroutes was falsch gemacht..

hab testweise die 5|. (hier wähle ich dann 500177xxxxx)
und noch eine 0|.

vielleicht kann mir wer von euch helfen..

gruß
Sven
 
Zeile 17 in Deiner extensions.conf ist falsch


rate ich mal

alternativ mach die Änderungen rückgängig die Du gemacht hast seitdem es ging :)
 
;)

okok... welche .conf hätten wir denn gerne??

das mit den änderungen ist so ein problem, ich hab nämlich an den "rauswähleinstellungen" nix verändert... warum auch, ging ja alles... :cool:


Das hab ich mal von der CLI kopiert....

Code:
 -- Executing Macro("SIP/1005-b6a3ea08", "dialout-trunk|1|00177XXXXXX||") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "DIAL_TRUNK=1") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "_NODEST=") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "DIAL_NUMBER=00177XXXXXXX") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "ROUTE_PASSWD=") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "DIAL_TRUNK_OPTIONS=tr") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?noauth") in new stack
    -- Goto (macro-dialout-trunk,s,8)
    -- Executing Set("SIP/1005-b6a3ea08", "GROUP()=OUT_1") in new stack
    -- Executing Macro("SIP/1005-b6a3ea08", "user-callerid|SKIPTTL") in new stack
    -- Executing NoOp("SIP/1005-b6a3ea08", "user-callerid: device 1005") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "0?report") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "0?start") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "REALCALLERIDNUM=1005") in new stack
    -- Executing NoOp("SIP/1005-b6a3ea08", "REALCALLERIDNUM is 1005") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "AMPUSER=1005") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "AMPUSERCIDNAME=Boettcher") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "0?report") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "CALLERID(all)=Boettcher <1005>") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "REALCALLERIDNUM=1005") in new stack
    -- Executing NoOp("SIP/1005-b6a3ea08", "TTL:  ARG1: SKIPTTL") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?continue") in new stack
    -- Goto (macro-user-callerid,s,21)
    -- Executing NoOp("SIP/1005-b6a3ea08", "Using CallerID "Boettcher" <1005>") in new stack
    -- Executing Macro("SIP/1005-b6a3ea08", "record-enable|1005|OUT") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "0 > 0?2:4") in new stack
    -- Goto (macro-record-enable,s,4)
    -- Executing DeadAGI("SIP/1005-b6a3ea08", "recordingcheck|20070606-172208|asterisk-19368-1181143328.2593") in new stack
    -- Launched AGI Script /var/lib/asterisk/agi-bin/recordingcheck
  recordingcheck|20070606-172208|asterisk-19368-1181143328.2593: Outbound recording not enabled
    -- AGI Script recordingcheck completed, returning 0
    -- Executing NoOp("SIP/1005-b6a3ea08", "No recording needed") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "0?skipoutcid") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "DIAL_TRUNK_OPTIONS=") in new stack
    -- Executing Macro("SIP/1005-b6a3ea08", "outbound-callerid|1") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?start") in new stack
    -- Goto (macro-outbound-callerid,s,3)
    -- Executing NoOp("SIP/1005-b6a3ea08", "REALCALLERIDNUM is 1005") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?normcid") in new stack
    -- Goto (macro-outbound-callerid,s,9)
    -- Executing Set("SIP/1005-b6a3ea08", "USEROUTCID=") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "EMERGENCYCID=") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "TRUNKOUTCID=") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?trunkcid") in new stack
    -- Goto (macro-outbound-callerid,s,16)
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?usercid") in new stack
    -- Goto (macro-outbound-callerid,s,18)
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?report") in new stack
    -- Goto (macro-outbound-callerid,s,22)
    -- Executing NoOp("SIP/1005-b6a3ea08", "CallerID set to "Boettcher" <1005>") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?nomax") in new stack
    -- Goto (macro-dialout-trunk,s,16)
    -- Executing DeadAGI("SIP/1005-b6a3ea08", "fixlocalprefix") in new stack
    -- Launched AGI Script /var/lib/asterisk/agi-bin/fixlocalprefix
    -- AGI Script fixlocalprefix completed, returning 0
    -- Executing Set("SIP/1005-b6a3ea08", "OUTNUM=00177XXXXXXX") in new stack
    -- Executing Set("SIP/1005-b6a3ea08", "custom=ZAP/g0") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "0?customtrunk") in new stack
    -- Executing Dial("SIP/1005-b6a3ea08", "ZAP/g0/00177XXXXXXXX|300|") in new stack
    -- Requested transfer capability: 0x00 - SPEECH
    -- Called g0/00177XXXXXXX
    -- Zap/1-1 is proceeding passing it to SIP/1005-b6a3ea08
    -- Zap/1-1 is making progress passing it to SIP/1005-b6a3ea08
    -- Zap/1-1 is ringing
    -- Hungup 'Zap/1-1'
  == Spawn extension (macro-dialout-trunk, s, 20) exited non-zero on 'SIP/1005-b6a3ea08' in macro 'dialout-trunk'
  == Spawn extension (macro-dialout-trunk, s, 20) exited non-zero on 'SIP/1005-b6a3ea08'
    -- Executing Macro("SIP/1005-b6a3ea08", "hangupcall") in new stack
    -- Executing ResetCDR("SIP/1005-b6a3ea08", "w") in new stack
    -- Executing NoCDR("SIP/1005-b6a3ea08", "") in new stack
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?skiprg") in new stack
    -- Goto (macro-hangupcall,s,6)
    -- Executing GotoIf("SIP/1005-b6a3ea08", "1?theend") in new stack
    -- Goto (macro-hangupcall,s,9)
    -- Executing Wait("SIP/1005-b6a3ea08", "5") in new stack
  == Spawn extension (macro-hangupcall, s, 9) exited non-zero on 'SIP/1005-b6a3ea08' in macro 'hangupcall'
  == Spawn extension (macro-hangupcall, s, 9) exited non-zero on 'SIP/1005-b6a3ea08'
    -- Channel 0/1, span 1 received AOC-E charging 0 units


wenn ich die Nebenstelle 177 anrufe ist der CLI Abschnitt der gleiche, bis auf die Tatsache das überall da wo die 00177XXXXXX halt nur die 177 steht.
 
gooze schrieb:
okok... welche .conf hätten wir denn gerne??

Das steht doch eindeutig in dem Posting zuvor :rolleyes:

in Deiner extensions.conf ist falsch

Und außerdem gehört das nicht nach "Asterisk Allgemein" sondern allerhöchstens nach "Asterisk Rufnummernplan". Aber da es sich nach der CLI Ausgabe im Trixbox handelt, verschubse ich das ganze Thema jetzt einfach mal dorthin :D
 
Sorry....
Freitag... ziemlich heiß.... und keine lust mehr.. ;)

sodele... hier dann mal die extensions.conf....

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


; 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-direct		; MODIFICATOIN (PL) put before ext-did to take precedence
include => 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,DeadAGI(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)

; 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(RT=${IF($[$["${VMBOX}"!="novm"] | $["foo${CFUEXT}"!="foo"]]?${RINGTIMER}:"")})
exten => s,n,Macro(record-enable,${EXTTOCALL},IN)

exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS},${EXTTOCALL})
exten => s,n,GosubIf($[$["${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})

; 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,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]
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"]?s-${ARG2},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)})

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

exten => o,1,Background(one-moment-please)      ; 0 during vm message will hangup
exten => o,n,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)

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

;------------------------------------------------------------------------
; [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,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($[$["${DIALSTATUS}"="NOANSWER"] & $["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer

; 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

; 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($[ "foo${USE_CONFIRMATION}" = "foo" | "foo${RINGGROUP_INDEX}" = "foo" | "${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($[ "foo${BLKVM_BASE}" = "foo" | "BLKVM/${BLKVM_BASE}/${CHANNEL}" != "${BLKVM_OVERRIDE}" ]?theend)
exten => s,n,Noop(Cleaning Up Block VM Flag: ${BLKVM_OVERRIDE})
exten => s,n,DBDel(${BLKVM_OVERRIDE})

exten => s,n(theend),Wait(5)
exten => s,n,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,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)

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

; 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_NUMBER=${ARG2})
exten => s,n,Set(ROUTE_PASSWD=${ARG3})
exten => s,n,Set(DIAL_TRUNK_OPTIONS=${DIAL_OPTIONS}) // will be reset to TRUNK_OPTIONS if not intra-company
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,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),DeadAGI(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},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,NoOp(Dial failed due to ${DIALSTATUS} - failing through to other trunks)

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)
;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(${ARG3})
exten => s,2,AddQueueMember(${ARG1}|Local/${CALLERID(number)}@from-internal/n)	; using chan_local allows us to have agents over trunks
exten => s,3,UserEvent(Agentlogin|Agent: ${CALLERID(number)})
exten => s,4,Wait(1)
exten => s,5,Playback(agent-loginok)
exten => s,6,Hangup()






;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)
;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,2,RemoveQueueMember(${ARG1}|Local/${CALLERID(number)}@from-internal/n)
;exten => s,4,UserEvent(RefreshQueue)
exten => s,3,Wait(1)
exten => s,4,Playback(agent-loggedoff)
exten => s,5,Hangup()



;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]
; This has been violently beaten upon by Rob Thomas, [email protected]
; 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,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($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${ARG1}} ]?nochans)
exten => s,n,Set(DIAL_NUMBER=${ARG2})
exten => s,n,Set(DIAL_TRUNK=${ARG1})
exten => s,n,DeadAGI(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(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()
; I haven't figured out how, but occasionally a hung up
; call can end up here. If you don't use DeadAGI (which does
; work fine as a normal AGI), asterisk deadlocks a thread,
; and ends up grumpy.
exten => s,4,DeadAGI(recordingcheck,${TIMESTAMP},${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,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,DeadAGI(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,Noop(user-callerid: ${CALLERID(name)} ${CALLERID(number)})
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) 
exten => s,n,Set(CALLERID(all)=${AMPUSERCIDNAME} <${AMPUSER}>)
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,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,Playtones(congestion)
exten => s,n,Congestion(5)


;
; ############################################################################
; 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,Ringing
exten => s,n,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]
; 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
include => ext-local-confirm
; This causes grief with '#' transfers, commenting out for the moment.
; include => bad-number
exten => s,1,Macro(hangupcall)
exten => h,1,Macro(hangupcall)

;------------------------------------------------------------------------
; [bad-number]
;------------------------------------------------------------------------
; This is where all calls go that don't have any other destination provided
;
;------------------------------------------------------------------------
[bad-number]
exten => _X.,1,Wait(1)
exten => _X.,n,Playback(silence/1&cannot-complete-as-dialed&check-number-dial-again,noanswer)
exten => _X.,n,Wait(1)
exten => _X.,n,Congestion(20)
exten => _X.,n,Hangup()

exten => _*.,1,Wait(1)
exten => _*.,n,Playback(silence/1&feature-not-avail-line&silence/1&cannot-complete-as-dialed&check-number-dial-again,noanswer)
exten => _*.,n,Wait(1)
exten => _*.,n,Congestion(20)
exten => _*.,n,Hangup()
;------------------------------------------------------------------------

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

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

exten => s,n,Set(USE_CONFIRMATION=)
exten => s,n,Set(RINGGROUP_INDEX=)

; 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/${ARG4}/${CHANNEL})
;------------------------------------------------------------------------

;------------------------------------------------------------------------
; [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.
;
;------------------------------------------------------------------------
[ext-local-confirm]
exten => _LC-.,1,Noop(IN ext-local-confirm with - RT: ${RT}, RG_IDX: ${RG_IDX})
exten => _LC-.,n,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)

;------------------------------------------------------------------------

; ############################################################################
; 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)
 
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.