PDA

Bekijk Volledige Versie : asterisk & linksys prob



TomB
02/10/07, 15:55
Hallo,

Sinds enkele weken draait er een Asterisk/freepbx met een 7-tal linksys spa962 toestellen.

Wij hebben echter problemen dat ongeveer 10%-20% van de gesprekken niet tot stand gebracht kunnen worden (telefoon gaat over, maar geen audio hoorbaar langs beide kanten).
Tweede probleem is dat de asterisk soms eens vastloopt (kan echter gewoon een slecht stukje ram zijn, wat ik nu aan het testen ben).

Ben zelf absoluut geen expert en de installateur kan er zelf niet meer aan uit.

Zijn er bepaalde dingen die ik zelf kan nagaan?


Asterisk staat op een Dell server met een Digium 4port ISDN kaart.
De installateur heeft de standaard howto van Digium gevolgd en de ISDNstack van hun gedownload. Hij verdenkt dat de ISDNstack een probleem geeft, daar de server vast loopt en hij een rare isdnstack boodschap ziet.

Kan iemand me op weg helpen ... wat kan ik alvast nakijken.



misdn-init.conf
card=1,0x4
te_ptp=1,2
poll=128
dsp_poll=128
dsp_options=0
dtmfthreshold=100
debug=0

te_ptp staat in de howto echter ingesteld op 3,4
ook zeggen ze "nt_ptp=1,2" in de config te zetten, die bij ons echter geheel ontbreekt.

luser
02/10/07, 16:21
NT en TE is het type aansluiting (of er ISND lijnen of ISDN telefoons aanhangen). De nummertjes staan voor de poorten die je gebruikt op je quad BRI kaart.

Dus te_ptp is goed als je een isdn lijn op poort 1 en 2 hebt.



EDIT:
Draai je ergens NAT in je setup of zit alles op hetzelfde LAN?

(Ken wel niet echt iets van freepbx toestanden daar wij gewoon een plain asterisk doos bij de klant neerzetten. Geraak je bij deze dingen op de asterisk CLI?)

TomB
02/10/07, 17:18
NT en TE is het type aansluiting (of er ISND lijnen of ISDN telefoons aanhangen). De nummertjes staan voor de poorten die je gebruikt op je quad BRI kaart.

Dus te_ptp is goed als je een isdn lijn op poort 1 en 2 hebt.
ok, dat lijkt me dan inderdaad wel in orde. Er zijn 2 isdn lijnen op poort 1 en 2



EDIT:
Draai je ergens NAT in je setup of zit alles op hetzelfde LAN?

(Ken wel niet echt iets van freepbx toestanden daar wij gewoon een plain asterisk doos bij de klant neerzetten. Geraak je bij deze dingen op de asterisk CLI?)
Asterisk server en toestellen staan binnen hetzelfde LAN. CLI is bereikbaar ... zo heb ik al enkele dingen zelf aangepast (caller id etc...), maar de echte core config is mij grotendeels onbekend.

In de misdn-init.conf staan er ook enkele "options" in comment ... kan het daar iets mee te maken hebben?

luser
02/10/07, 17:35
Normaal heb je in de /etc/asterisk/misdn.conf een optie:
te_choose_channel, zet deze eens op yes.

Helpt wel eens bij vage problemen. Welke telco gebruik je?

TomB
02/10/07, 17:44
Normaal heb je in de /etc/asterisk/misdn.conf een optie:
te_choose_channel, zet deze eens op yes.

Helpt wel eens bij vage problemen. Welke telco gebruik je?

K, heb het aangepast in de config. Kan ik dit laden zonder reboot?

Momenteel gaat alles via Belgacom ... VoipBuster is ook ingesteld, maar wordt in praktijk niet gebruikt wegens de probs.

luser
02/10/07, 17:46
Doe op de cli (asterisk -r): misdn reload

EDIT:

Je krijgt de probs ook richting voipbuster? Dit gaat niet via mISDN dus zit je probleem ergens anders :)

TomB
02/10/07, 17:57
-- Called g:first_extern/0486738852/:s:e128
-- mISDN/1-u17 is proceeding passing it to SIP/23-08adf0b0
-- mISDN/1-u17 is ringing
-- SIP/30-08ad9b70 answered mISDN/1-1
-- mISDN/1-u17 answered SIP/23-08adf0b0
== Spawn extension (macro-dialout-trunk, s, 30) exited non-zero on 'SIP/23-08adf0b0' in macro 'dialout-trunk'
== Spawn extension (macro-dialout-trunk, s, 30) exited non-zero on 'SIP/23-08adf0b0'
-- Executing Macro("SIP/23-08adf0b0", "hangupcall") in new stack
-- Executing ResetCDR("SIP/23-08adf0b0", "w") in new stack
-- Executing NoCDR("SIP/23-08adf0b0", "") in new stack
-- Executing GotoIf("SIP/23-08adf0b0", "1?skiprg") in new stack
-- Goto (macro-hangupcall,s,6)
-- Executing GotoIf("SIP/23-08adf0b0", "1?skipblkvm") in new stack
-- Goto (macro-hangupcall,s,9)
-- Executing GotoIf("SIP/23-08adf0b0", "1?theend") in new stack
-- Goto (macro-hangupcall,s,11)
-- Executing Hangup("SIP/23-08adf0b0", "") in new stack
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/23-08adf0b0' in macro 'hangupcall'
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/23-08adf0b0'


dan kan ik bellen, maar van zodra de persoon opneemt valt de lijn weg.

luser
02/10/07, 18:07
Loopt iets fout in de macro denkik. Maak best even een dialout extensie die direkt de misdn aanroept.

Iets in formaat van:
[sip-to-isdn-out]
exten => _0.,1,Dial(mISDN/g:first_extern/${EXTEN:1})
exten => _0.,2,Hangup()

Dan de context bij je uitgaande sip context includen.
Vanaf dan kan je buitenbellen met prefix 0.

TomB
03/10/07, 09:50
wat vraag jij om een config eens na te kijken?

Mark Vletter
03/10/07, 10:21
Dit
Wij hebben echter problemen dat ongeveer 10%-20% van de gesprekken niet tot stand gebracht kunnen worden (telefoon gaat over, maar geen audio hoorbaar langs beide kanten). wordt in 90% van de gevallen veroorzaakt door NAT. Een Firewall op de linux doos die niet goed ingesteld staat (bv IP tables die de de poorten waarover de spraak plaatst vindt niet goed door laten), of een modem (Thomson/Alcatel) waarbij NAT stiekem toch niet werkt zoals het zou moeten.

Kijk voor de zekerheid je IP tables even na (aan een modem zal het niet liggen omdat de gesprekken via de ISDN kaart binnen komen).

Geldt dit trouwens voor uitgaande en inkomende gesprekken?

TomB
03/10/07, 10:25
Dit wordt in 90% van de gevallen veroorzaakt door NAT. Een Firewall op de linux doos die niet goed ingesteld staat (IP tables laten de poorten waarover de spraak plaatst vindt niet goed door), of een modem (Thomson/Alcatel) waarbij NAT stiekem toch niet werkt zoals het zou moeten.

Kijk voor de zekerheid je IP tables even na (aan een modem zal het niet liggen omdat de gesprekken via de ISDN kaart binnen komen).

Geldt dit trouwens voor uitgaande en inkomende gesprekken?

voor zover ik weet voor inkomende gesprekken ... maar daarvoor moet ik men collega's eens raadplegen.

Mark Vletter
03/10/07, 10:46
Dan is de kans dat het een nat probleem is nog groter... Kijk eens in je IP tables wat er gebeurd met de poorten 10000 t/m 10500.

luser
03/10/07, 11:09
voor zover ik weet voor inkomende gesprekken ... maar daarvoor moet ik men collega's eens raadplegen.

In één van je posts vertel je dat voipbuster momenteel niet gebruikt wordt, dus je hebt dit probleem ook voor gesprekken die toekomen via je ISDN lijnen?

TomB
03/10/07, 11:12
In één van je posts vertel je dat voipbuster momenteel niet gebruikt wordt, dus je hebt dit probleem ook voor gesprekken die toekomen via je ISDN lijnen?

VoipBuster gebruiken we momenteel niet, maar gewoon omdat we ons eerst willen concentreren op de problemen via ISDN.
Die werkt wel, maar nog niet genoeg getest om te zien of we via dat kanaal dezelfde probs hebben.


edit: heb net mijn collega's effe gesproken, en zij hebben het probleem ook al ondervonden als zij zelf iemand bellen (uitgaand dus).

luser
03/10/07, 11:30
Kunnen ze zonder problemen naar elkaar toe bellen?

TomB
03/10/07, 11:34
[root@Voipboxplus ~]# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination


Kunnen ze zonder problemen naar elkaar toe bellen?

Collega verteld me dat het probleem intern ook al eens voorgekomen is, maar zoals reeds gezegd waren er op dat moment wat server probs en hebben ze de server moeten rebooten.
Buiten dat eene incident lijkt het intern dus quasi perfect te lopen (95% zeker).


Loopt iets fout in de macro denkik. Maak best even een dialout extensie die direkt de misdn aanroept.

Iets in formaat van:
[sip-to-isdn-out]
exten => _0.,1,Dial(mISDN/g:first_extern/${EXTEN:1})
exten => _0.,2,Hangup()

Dan de context bij je uitgaande sip context includen.
Vanaf dan kan je buitenbellen met prefix 0.

Het is een live omgeving. Als ik dit bijvoeg ... neem ik aan dat er niet meer getelefoneerd kan worden en dus best na de uren wordt uitgevoerd?
of ben ik mis?

Mark Vletter
03/10/07, 14:22
Kunnen ze zonder problemen naar elkaar toe bellen?

Als dat niet goed gaat ligt het aan het VoIP stuk. Gaat het wel goed dan is je ISDN kaart niet gelukkig.

TomB
03/10/07, 14:43
Als dat niet goed gaat ligt het aan het VoIP stuk. Gaat het wel goed dan is je ISDN kaart niet gelukkig.

Wel, voor 95% zijn wij zeker dat intern bellen geen problemen geeft.
Is wel zo dat onze leverancier nooit Digium kaarten had geinstalleerd voor ik daar achter vroeg. Maar adhv mijn eerste post lijkt die misdn-init.conf wel correct te zijn.

Wat kan er dan nog misgaan: dan toch ISDN-stack?

luser
03/10/07, 15:17
Het is een live omgeving. Als ik dit bijvoeg ... neem ik aan dat er niet meer getelefoneerd kan worden en dus best na de uren wordt uitgevoerd?
of ben ik mis?

Hangt er vanaf, neem een prefix die nog niet in gebruik is en dan kan je kiezen hoe je buitenbelt.

TomB
03/10/07, 15:59
extensions.conf


#include extensions_override_freepbx.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
include => ext-did-catchall ; THIS MUST COME AFTER ext-did
include => from-did-direct ; MODIFICATOIN (PL) for findmefollow if enabled, should be bofore ext-local
exten => fax,1,Goto(ext-fax,in_fax,1)

[from-did-direct]
include => ext-findmefollow
include => ext-local
; ################################################## ##########################
; Macros [macro]
; ################################################## ##########################

; Use a Macro call such as the following:
; Macro(dial,$DIAL_TIMER,$DIAL_OPTIONS,$EXT1,$EXT2,$ EXT3,...)
[macro-dial]
exten => s,1,GotoIf($["${MOHCLASS}" = ""]?dial)
exten => s,2,SetMusicOnHold(${MOHCLASS})
exten => s,3(dial),AGI(dialparties.agi)
exten => s,4,NoOp(Returned from dialparties with no extensions to call and DIALSTATUS: ${DIALSTATUS})

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

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

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

exten => s,35,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "memoryhunt" ]]?36:50 ) ;Set Call Trace for each hunt member we are going to call "Memory groups have multiple members to set CALL TRACE For hence the loop
exten => s,36,Set(CTLoop=0)
exten => s,37,GotoIf($[${CTLoop} > ${HuntLoop}]?42 ) ; if this is from rg-group, don't strip prefix
exten => s,38,Set(CT_EXTEN=${CUT(ARG3,,$[${CTLoop} + 1])})
exten => s,39,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT})
exten => s,40,Set(CTLoop=$[1 + ${CTLoop}])
exten => s,41,Goto(s,37)

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

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

; Ring an extension, if the extension is busy or there is no answer send it
; to voicemail
; ARGS: $VMBOX, $EXT
[macro-exten-vm]
exten => s,1,Macro(user-callerid)

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

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

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

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

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

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

;------------------------------------------------------------------------
; [macro-vm]
;------------------------------------------------------------------------
[macro-vm]
; ARG1 - extension
; ARG2 - DIRECTDIAL/BUSY
exten => s,1,Macro(user-callerid,SKIPTTL)
exten => s,n,Set(VMGAIN=${IF($["foo${VM_GAIN}"!="foo"]?"g(${VM_GAIN})":"")})
;
; If BLKVM_OVERRIDE is set, then someone told us to block calls from going to
; voicemail. This variable is reset by the answering channel so subsequent
; transfers will properly function.
;
exten => s,n,GotoIf($["foo${DB(${BLKVM_OVERRIDE})}" != "fooTRUE"]?vmx,1)
;
; we didn't branch so block this from voicemail
;
exten => s,n,Noop(CAME FROM: ${NODEST} - Blocking VM cause of key: ${DB(BLKVM_OVERRIDE)})


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

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

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

exten => vmx,n(loopstart),Read(ACTION,${ASTSPOOLDIR}/voicemail/${VMCONTEXT}/${ARG1}/${MODE},1,skip,${VMX_REPEAT},${VMX_TIMEOUT})
exten => vmx,n,GotoIf($["${EXISTS(${ACTION})}" = "1"]?checkopt)

exten => vmx,n(noopt),Noop(Timeout: going to timeout dest)
exten => vmx,n,Set(VMX_OPTS=${VMX_OPTS_TIMEOUT})
exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/vmxopts/timeout)}" = "0"]?chktime)
exten => vmx,n,Set(VMX_OPTS=${DB_RESULT})
exten => vmx,n(chktime),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timedest/ext)}" = "0"]?dotime)
exten => vmx,n,Set(VMX_TIMEDEST_EXT=${DB_RESULT})
exten => vmx,n,GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timedest/context)}" = "0"]?timepri)
exten => vmx,n,Set(VMX_TIMEDEST_CONTEXT=${DB_RESULT})
exten => vmx,n(timepri),GotoIf($["${DB_EXISTS(AMPUSER/${ARG1}/vmx/${MODE}/timedest/pri)}" = "0"]?dotime)
exten => vmx,n,Set(VMX_TIMEDEST_PRI=${DB_RESULT})
exten => vmx,n(dotime),Goto(${VMX_TIMEDEST_CONTEXT},${VMX_T IMEDEST_EXT},${VMX_TIMEDEST_PRI})

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

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

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

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

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

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

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

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

exten => s-DIRECTDIAL,1,NoOp(DIRECTDIAL voicemail)
exten => s-DIRECTDIAL,n,Macro(get-vmcontext,${ARG1})
exten => s-DIRECTDIAL,n,Voicemail(${ARG1}@${VMCONTEXT},${VM_O PTS}${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${VM GAIN}) ; Voicemail Unavailable message
exten => _s-.,n,Goto(exit-${VMSTATUS},1)

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

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

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

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

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

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

exten => exit-FAILED,1,Playback(im-sorry&an-error-has-occured)
exten => exit-FAILED,n,Hangup()

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

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

exten => t,1,Hangup()
;------------------------------------------------------------------------

;------------------------------------------------------------------------
; [macro-simple-dial]
;------------------------------------------------------------------------
; 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

exten => s,n,Set(EXTTOCALL=${ARG1})
exten => s,n,Set(RT=${ARG2})
exten => s,n,Set(CFUEXT=${DB(CFU/${EXTTOCALL})})
exten => s,n,Set(CFBEXT=${DB(CFB/${EXTTOCALL})})
exten => s,n,Macro(record-enable,${EXTTOCALL},IN)

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

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

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

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

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

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

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

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

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

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


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

; What to do on hangup.
[macro-hangupcall]
exten => s,1,ResetCDR(w)
exten => s,n,NoCDR()

; Cleanup any remaining RG flag
;
exten => s,n,GotoIf($[ "x${USE_CONFIRMATION}" = "x" | "x${RINGGROUP_INDEX}" = "x" | "${CHANNEL}" != "${UNIQCHAN}"]?skiprg)
exten => s,n,Noop(Cleaning Up Confirmation Flag: RG/${RINGGROUP_INDEX}/${CHANNEL})
exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL})

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

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

exten => s,n(theend),Hangup

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

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


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

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

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

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

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

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

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

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

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

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

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

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

exten => disabletrunk,1,Noop(TRUNK: ${OUT_${DIAL_TRUNK}} DISABLED - falling through to next trunk)

exten => h,1,Macro(hangupcall)

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

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

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

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

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

; Here are the exit points for the macro.

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

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

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

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

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

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

; This macro is for dev purposes and just dumps channel/app variables. Useful when designing new contexts.
[macro-dumpvars]
exten => s,1,Noop(ACCOUNTCODE=${ACCOUNTCODE})
exten => s,2,Noop(ANSWEREDTIME=${ANSWEREDTIME})
exten => s,3,Noop(BLINDTRANSFER=${BLINDTRANSFER})
exten => s,4,Noop(CALLERID=${CALLERID(all)})
exten => s,5,Noop(CALLERID(name)=${CALLERID(name)})
exten => s,6,Noop(CALLERID(number)=${CALLERID(number)})
exten => s,7,Noop(CALLINGPRES=${CALLINGPRES})
exten => s,8,Noop(CHANNEL=${CHANNEL})
exten => s,9,Noop(CONTEXT=${CONTEXT})
exten => s,10,Noop(DATETIME=${DATETIME})
exten => s,11,Noop(DIALEDPEERNAME=${DIALEDPEERNAME})
exten => s,12,Noop(DIALEDPEERNUMBER=${DIALEDPEERNUMBER})
exten => s,13,Noop(DIALEDTIME=${DIALEDTIME})
exten => s,14,Noop(DIALSTATUS=${DIALSTATUS})
exten => s,15,Noop(DNID=${DNID})
exten => s,16,Noop(EPOCH=${EPOCH})
exten => s,17,Noop(EXTEN=${EXTEN})
exten => s,18,Noop(HANGUPCAUSE=${HANGUPCAUSE})
exten => s,19,Noop(INVALID_EXTEN=${INVALID_EXTEN})
exten => s,20,Noop(LANGUAGE=${LANGUAGE})
exten => s,21,Noop(MEETMESECS=${MEETMESECS})
exten => s,22,Noop(PRIORITY=${PRIORITY})
exten => s,23,Noop(RDNIS=${RDNIS})
exten => s,24,Noop(SIPDOMAIN=${SIPDOMAIN})
exten => s,25,Noop(SIP_CODEC=${SIP_CODEC})
exten => s,26,Noop(SIPCALLID=${SIPCALLID})
exten => s,27,Noop(SIPUSERAGENT=${SIPUSERAGENT})
exten => s,29,Noop(TXTCIDNAME=${TXTCIDNAME})
exten => s,30,Noop(UNIQUEID=${UNIQUEID})
exten => s,31,Noop(TOUCH_MONITOR=${TOUCH_MONITOR})
exten => s,32,Noop(MACRO_CONTEXT=${MACRO_CONTEXT})
exten => s,33,Noop(MACRO_EXTEN=${MACRO_EXTEN})
exten => s,34,Noop(MACRO_PRIORITY=${MACRO_PRIORITY})
[macro-user-logon]
; check device type
exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})
exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)
; get user's extension
exten => s,3,Set(AMPUSER=${ARG1})
exten => s,4,GotoIf($["${AMPUSER}" = ""]?5:9)
exten => s,5,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}${CALLERI D(number)})
exten => s,19,Set(DB(AMPUSER/${AMPUSER}/device)=${AMPUSERDEVICES})
; map device to user
exten => s,20,Set(DB(DEVICE/${CALLERID(number)}/user)=${AMPUSER})
; create symlink from dummy device mailbox to user's mailbox
exten => s,21,System(/bin/ln -s ${ASTSPOOLDIR}/voicemail/default/${AMPUSER}/ ${ASTSPOOLDIR}/voicemail/device/${CALLERID(number)})

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

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

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

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

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

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

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

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

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

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

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

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

exten => h,1,Hangup


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

;sets the callerid of the device to that of the logged in user
;
[macro-user-callerid]
exten => s,1,Noop(user-callerid: ${CALLERID(name)} ${CALLERID(number)})

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

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

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

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

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

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

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

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

luser
03/10/07, 16:14
Klopt.

Kijk even in je sip.conf in wat voor context je telefoons staan. Zoek die context op in de extensions.conf en voeg daarin dan toe:
include =>sip-to-isdn-out

dialplan reload op de cli en klaar.

TomB
03/10/07, 16:18
Klopt.

Kijk even in je sip.conf in wat voor context je telefoons staan. Zoek die context op in de extensions.conf en voeg daarin dan toe:
include =>sip-to-isdn-out

dialplan reload op de cli en klaar.



; Note: If your SIP devices are behind a NAT and your Asterisk
; server isn't, try adding "nat=1" to each peer definition to
; solve translation problems.

[general]
#include sip_general_additional.conf

bindport = 5060 ; Port to bind to (SIP is 5060)
bindaddr = 0.0.0.0 ; Address to bind to (all addresses on machine)
disallow=all
allow=ulaw
allow=alaw
; If you need to answer unauthenticated calls, you should change this
; next line to 'from-trunk', rather than 'from-sip-external'.
; You'll know this is happening if when you call in you get a message
; saying "The number you have dialed is not in service. Please check the
; number and try again."
context = from-sip-external ; Send unknown SIP callers to this context
callerid = Unknown
tos=0x68

; Reported as required for Asterisk 1.4
notifyringing=yes
notifyhold=yes
limitonpeers=yes

; enable and force the sip jitterbuffer. If these settings are desired
; they should be set in the sip_general_custom.conf file as this file
; will get overwritten during reloads and upgrades.
;
; jbenable=yes
; jbforce=yes

; #, in this configuration file, is NOT A COMMENT. This is exactly
; how it should be.
#include sip_general_custom.conf
#include sip_nat.conf
#include sip_registrations_custom.conf
#include sip_registrations.conf
#include sip_custom.conf
#include sip_additional.conf

ok,
heb dus voor de makkelijkheid volgende bovenaan in extension.conf bijgezet


[sip-to-isdn-out]
exten => _7.,1,Dial(mISDN/g:first_extern/${EXTEN:1})
exten => _7.,2,Hangup()


en bij de context sip-to-external na alle exten's die er al stonden, volgende bijgezet


include =>sip-to-isdn-out


edit: "dialplan reload" kent hij niet in cli (of erbuiten)
heb "extensions reload" gedaan .... is het dat niet ?

Indien ik dan probeer naar buiten te bellen krijg ik melding dat extension niet correct is.


== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/23-08b290d8' in macro 'hangupcall'
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/23-08b290d8'
-- Executing Wait("SIP/23-08b290d8", "1") in new stack
-- Executing Playback("SIP/23-08b290d8", "silence/1&cannot-complete-as-dialed&check-number-dial-again|noanswer") in new stack
-- Playing 'silence/1' (language 'en')
-- Playing 'cannot-complete-as-dialed' (language 'en')
-- Playing 'check-number-dial-again' (language 'en')
-- Executing Wait("SIP/23-08b290d8", "1") in new stack
-- Executing Congestion("SIP/23-08b290d8", "20") in new stack
== Spawn extension (from-internal, 70478781981, 4) exited non-zero on 'SIP/23-08b290d8'
-- Executing Macro("SIP/23-08b290d8", "hangupcall") in new stack
-- Executing ResetCDR("SIP/23-08b290d8", "w") in new stack
-- Executing NoCDR("SIP/23-08b290d8", "") in new stack
-- Executing GotoIf("SIP/23-08b290d8", "1?skiprg") in new stack
-- Goto (macro-hangupcall,s,6)
-- Executing GotoIf("SIP/23-08b290d8", "1?skipblkvm") in new stack
-- Goto (macro-hangupcall,s,9)
-- Executing GotoIf("SIP/23-08b290d8", "1?theend") in new stack
-- Goto (macro-hangupcall,s,11)
-- Executing Hangup("SIP/23-08b290d8", "") in new stack
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/23-08b290d8' in macro 'hangupcall'
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/23-08b290d8'
Voipboxplus*CLI>



als ik trouwens die sip-to-isdn in een aparte extensions_custom.conf bijvoeg (zodat die als laatste geladen worden), dan krijg ik volgende bij reload.


== Spawn extension (macro-dial, s, 10) exited non-zero on 'mISDN/1-1' in macro 'dial'
== Spawn extension (macro-dial, s, 10) exited non-zero on 'mISDN/1-1' in macro 'exten-vm'
== Spawn extension (macro-dial, s, 10) exited non-zero on 'mISDN/1-1'
-- Executing Macro("mISDN/1-1", "hangupcall") in new stack
-- Executing ResetCDR("mISDN/1-1", "w") in new stack
-- Executing NoCDR("mISDN/1-1", "") in new stack
-- Executing GotoIf("mISDN/1-1", "1?skiprg") in new stack
-- Goto (macro-hangupcall,s,6)
-- Executing GotoIf("mISDN/1-1", "1?skipblkvm") in new stack
-- Goto (macro-hangupcall,s,9)
-- Executing GotoIf("mISDN/1-1", "1?theend") in new stack
-- Goto (macro-hangupcall,s,11)
-- Executing Hangup("mISDN/1-1", "") in new stack
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'mISDN/1-1' in macro 'hangupcall'
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'mISDN/1-1'

luser
03/10/07, 17:00
Dialplan/extensions cmd hangt af welke asterisk versie je gebruikt.

Aan de 1ste debug te zien loopt hij nog steeds over een macro.
Als je even kijkt in:
sip_registrations.conf

ZIe je daar een van je phones?

TomB
03/10/07, 17:04
nope, geen enkele

staat enkel:



register=login: pass@sip1.voipbuster.com

luser
03/10/07, 17:05
Ga dan even al die files door die included worden in de sip.conf.
Ergens moet een phone staan met context= :)

TomB
03/10/07, 17:13
heb dit gevonden in sip_additional.conf


[23]
type=friend
secret=Pass_23
record_out=Never
record_in=Never
qualify=yes
port=5060
pickupgroup=
nat=yes
mailbox=23@device
host=dynamic
dtmfmode=rfc2833
disallow=
dial=SIP/23
context=from-internal
canreinvite=no
callgroup=
callerid=device <23>
allow=
accountcode=

luser
03/10/07, 17:15
Zoek nu from-internal op in de extensions.conf op en zet daar de prefix 7 toestanden.

Dan reloaden en testen.

TomB
03/10/07, 17:28
ok, dit werkt nu



-- Added extension '1' priority 1 to app-calltrace-perform
-- Executing Dial("SIP/23-08b64a40", "mISDN/g:first_extern/0478781981") in new stack
-- Called g:first_extern/0478781981
-- mISDN/1-u52 is proceeding passing it to SIP/23-08b64a40
-- mISDN/1-u52 is ringing
-- mISDN/1-u52 answered SIP/23-08b64a40
== Spawn extension (from-internal, 70478781981, 1) exited non-zero on 'SIP/23-08b64a40'
-- Executing Macro("SIP/23-08b64a40", "hangupcall") in new stack
-- Executing ResetCDR("SIP/23-08b64a40", "w") in new stack
-- Executing NoCDR("SIP/23-08b64a40", "") in new stack
-- Executing GotoIf("SIP/23-08b64a40", "1?skiprg") in new stack
-- Goto (macro-hangupcall,s,6)
-- Executing GotoIf("SIP/23-08b64a40", "1?skipblkvm") in new stack
-- Goto (macro-hangupcall,s,9)
-- Executing GotoIf("SIP/23-08b64a40", "1?theend") in new stack
-- Goto (macro-hangupcall,s,11)
-- Executing Hangup("SIP/23-08b64a40", "") in new stack
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/23-08b64a40' in macro 'hangupcall'
== Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/23-08b64a40'



Maar dit test de uitgaande gesprekken vooral. Enige test mogelijk voor inkomende gesprekken?

of mis ik iets ?