Ticket #1849: extensions.conf.php

File extensions.conf.php, 56.8 kB (added by bsdtech, 5 years ago)
Line 
1 <?php
2 function get_config($engine) {
3   global $ext; 
4    
5 //* FreePBX
6 //* Copyright (C) 2004 Coalescent Systems Inc (Canada)
7 //* Copyright (C) 2006 Why Pay More 4 Less Pty Ltd (Australia)
8 //* Released under the GNU GPL Licence version 2.
9
10 //* dialparties.agi (http://www.sprackett.com/asterisk/)
11 //* Asterisk::AGI (http://asterisk.gnuinter.net/)
12 //* gsm (http://www.ibiblio.org/pub/Linux/utils/compress/!INDEX.short.html)
13 //* loligo sounds (http://www.loligo.com/asterisk/sounds/)
14 //* mpg123 (http://voip-info.org/wiki-Asterisk+config+musiconhold.conf)*/
15
16 //* include extension contexts generated from AMP
17 $ext->addInclude('#include extensions_additional.conf');
18
19 //* Customizations to this dialplan should be made in extensions_custom.conf
20 //* See extensions_custom.conf.sample for an example
21 //* #include extensions_custom.conf
22
23 $id  =  'from-trunk';   // just an alias since VoIP shouldn't be called PSTN
24 $ext->addInclude('include from-pstn'));
25
26 $id  =  'from-pstn';
27 $ext->addInclude('include from-pstn-custom');    // create this context in extensions_custom.conf to include customizations
28 $ext->addInclude('include ext-did-direct');   // MODIFICATOIN (PL) put before ext-did to take precedence
29 $ext->addInclude('include ext-did');
30 $ext->addInclude('include from-did-direct');    // MODIFICATOIN (PL) for findmefollow if enabled, should be bofore ext-local
31 $ext->add(fax,1,'',new ext_Goto('ext-fax','in_fax','1'));
32
33 // MODIFICATION (PL)
34 //
35 // Required to assure that direct dids go to personal ring group before local extension.
36 // This could be auto-generated however I it is prefered to be put here and hard coded
37 // so that it can be modified if ext-local should take precedence in certain situations.
38 // will have to decide what to do later.
39 //
40 $id  =  'from-did-direct';
41   $ext->addInclude('include ext-findmefollow');
42    $ext->addInclude('include ext-local');
43
44
45
46 // ############################################################################
47 // Macros [macro]
48 // ############################################################################
49
50 // Rings one or more extensions.  Handles things like call forwarding and DND
51 // We don't call dial directly for anything internal anymore.
52 // ARGS: $TIMER, $OPTIONS, $EXT1, $EXT2, $EXT3, ...
53 // Use a Macro call such as the following:
54 //  Macro(dial,$DIAL_TIMER,$DIAL_OPTIONS,$EXT1,$EXT2,$EXT3,...)
55 $id  =  'macro-dial';
56 $ext->add(s,1,'',new ext_DeadAGI('dialparties.agi'));
57 $ext->add(s,2,'',new ext_NoOp('Returned from dialparties with no extensions to call'));
58 $ext->add(s,3,'',new ext_NoOp('DIALSTATUS' is '${DIALSTATUS}'));
59
60 $ext->add(s,10,'',new ext_Dial('${ds}'));  // ; dialparties will set the priority to 10 if $ds is not null
61
62 $ext->add(s,20,'',new ext_NoOp('Returned from dialparties with hunt groups to dial '));
63 $ext->add(s,21,'',new ext_Set('HuntLoop '=' 0'));
64 $ext->add(s,22,'',new ext_GotoIf('$[${HuntMembers} > '='  1]?30 '));  ; //if this is from rg-group, don't strip prefix
65 $ext->add(s,23,'',new ext_NoOp('Returning there are no members left in the hunt group to ring'));
66
67 $ext->add(s,30,'',new ext_Set('HuntMember '=' HuntMember${HuntLoop}'));
68 $ext->add(s,31,'',new ext_GotoIf('$[$['${CALLTRACE_HUNT}' ! '='  '' ] & $['${RingGroupMethod}'  '='  'hunt' ]]?32:35 ')); // ; Set CAll Trace for Hunt member we are going to call
69 $ext->add(s,32,'',new ext_Set('CT_EXTEN '=' ${CUT(ARG3,,$[${HuntLoop} + 1])}'));
70 $ext->add(s,33,'',new ext_Set('DB(CALLTRACE/${CT_EXTEN}) '=' ${CALLTRACE_HUNT}'));
71 $ext->add(s,34,'',new ext_Goto('s,42'));
72
73 $ext->add(s,35,'',new ext_ext-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
74 $ext->add(s,36,'',new ext_Set('CTLoop '=' 0'));
75 $ext->add(s,37,'',new ext_GotoIf('$[${CTLoop} > ${HuntLoop}]?42 ')); // ; if this is from rg-group, don't strip prefix
76 $ext->add(s,38,'',new ext_Set('CT_EXTEN '=' ${CUT(ARG3,,$[${CTLoop} + 1])}'));
77 $ext->add(s,39,'',new ext_Set('DB(CALLTRACE/${CT_EXTEN}) '=' ${CALLTRACE_HUNT}'));
78 $ext->add(s,40,'',new ext_Set('CTLoop '=' $[1 + ${CTLoop}]'));
79 $ext->add(s,41,'',new ext_Goto('s,37'));
80        
81 $ext->add(s,42,'',new ext_Dial('${${HuntMember}}${ds} ')); // dialparties will set the priority to 20 if $ds is not null and its a hunt group
82 $ext->add(s,43,'',new ext_Set('HuntLoop '=' $[1 + ${HuntLoop}]'));
83 $ext->add(s,44,'',new ext_Set('HuntMembers '=' $[${HuntMembers} - 1]'));
84 $ext->add(s,45,'',new ext_Goto('s,22'));
85 $ext->add(s,50,'',new ext_DBDel('CALLTRACE/${CT_EXTEN}'));
86 $ext->add(s,51,'',new ext_Goto('s,42'));
87
88 // make sure hungup calls go here so that proper cleanup occurs from call confirmed calls and the like
89 //
90 $ext->add(h,1,'',ext_Macro('hangupcall'));
91
92 // Ring an extension, if the extension is busy or there is no answer send it
93 // to voicemail
94 // ARGS: $VMBOX, $EXT
95 $id  =  'macro-exten-vm';
96 $ext->add(s,1,'',new ext_Macro('user-callerid'));
97
98 $ext->add(s,n,'',new ext_Set('FROMCONTEXT '=' exten-vm'));
99 $ext->add(s,n,'',new ext_Set('VMBOX '=' ${ARG1}'));
100 $ext->add(s,n,'',new ext_Set('EXTTOCALL '=' ${ARG2}'));
101 $ext->add(s,n,'',new ext_Set('CFUEXT '=' ${DB(CFU/${EXTTOCALL})}'));
102 $ext->add(s,n,'',new ext_Set('CFBEXT '=' ${DB(CFB/${EXTTOCALL})}'));
103 $ext->add(s,n,'',new ext_Set('RT '=' ${IF($[$['${VMBOX}' ! '='  'novm'] | $['foo${CFUEXT}' ! '='  'foo']]?${RINGTIMER}:'')}'));
104 $ext->add(s,n,'',new ext_Macro('record-enable,${EXTTOCALL},IN'));
105
106 $ext->add(s,n,'',new ext_Macro('dial,${RT},${DIAL_OPTIONS},${EXTTOCALL}'));
107 $ext->add(s,n,'',new ext_GosubIf('$[$['${DIALSTATUS}' '=' 'NOANSWER'] & $['foo${CFUEXT}'! '=' 'foo']]?docfu,1')); //; check for CFU in use on no answer
108 $ext->add(s,n,'',new ext_GosubIf('$[$['${DIALSTATUS}' '=' 'BUSY'] & $['foo${CFBEXT}'! '=' 'foo']]?docfb,1')); //; check for CFB in use on busy
109 $ext->add(s,n,'',new ext_NoOp('Voicemail' is '${VMBOX}'));
110 $ext->add(s,n,'',new ext_GotoIf('$['${VMBOX}'  '='  'novm']?s-${DIALSTATUS},1')); //; no voicemail in use for this extension
111 $ext->add(s,n,'',new ext_NoOp('Sending to Voicemail box ${EXTTOCALL}'));
112 $ext->add(s,n,'',new ext_Macro('vm,${VMBOX},${DIALSTATUS}'));
113
114 // Try the Call Forward on No Answer / Unavailable number
115 $ext->add(docfu,1,'',new ext_Set('RTCFU '=' ${IF($['${VMBOX}' ! '='  'novm']?${RINGTIMER}:'')}'));
116 $ext->add(docfu,n,'',new ext_Dial('Local/${CFUEXT}@from-internal/n,${RTCFU},${DIAL_OPTIONS}'));
117 $ext->add(docfu,n,'',new ext_macro('return');
118
119 // Try the Call Forward on Busy number
120 $ext->add(docfb,1,'',new ext_Set('RTCFB '=' ${IF($['${VMBOX}' ! '='  'novm']?${RINGTIMER}:'')}'));
121 $ext->add(docfb,n,'',new ext_Dial('Local/${CFBEXT}@from-internal/n,${RTCFB},${DIAL_OPTIONS}'));
122 $ext->add(docfb,n,'',new ext_macro('return');
123
124 ; Extensions with no Voicemail box reporting BUSY come here
125 $ext->add(s-BUSY,1,'',new ext_NoOp('Extension is reporting BUSY and not passing to Voicemail'));
126 $ext->add(s-BUSY,n,'',new ext_Playtones('busy'));
127 $ext->add(s-BUSY,n,'',new ext_Busy('20'));
128
129 ; Anything but BUSY comes here
130 $ext->add(_s-.,1,'',new ext_Playtones('congestion'));
131 $ext->add(_s-.,n,'',new ext_Congestion,('10'));
132
133 $id  =  'macro-vm';
134 $ext->add(s,1,'',new ext_Macro('user-callerid,SKIPTTL'));
135 $ext->add(s,n,'',new ext_Set('VMGAIN' '=' '${IF($['foo${VM_GAIN}' ! '='  'foo' ]? 'g(${VM_GAIN})' : '')}'));
136 //
137 // If BLKVM_OVERRIDE is set, then someone told us to block calls from going to
138 // voicemail. This variable is reset by the answering channel so subsequent
139 // transfers will properly function.
140 //
141 $ext->add(s,n,'',new ext_GotoIf('$['foo${DB(${BLKVM_OVERRIDE})}' ! '='  'fooTRUE']?s-${ARG2},1'));
142 //
143 // we didn't branch so block this from voicemail
144 //
145 $ext->add(s,n,'',new ext_NoOp('CAME FROM: ${NODEST} - Blocking VM cause of key: ${DB(BLKVM_OVERRIDE)}'));
146
147 $ext->add(s-BUSY,1,'',new ext_NoOp('BUSY voicemail'));
148 $ext->add(s-BUSY,n,'',new ext_Macro('get-vmcontext,${ARG1}'));
149 $ext->add(s-BUSY,n,'',new ext_vm('${ARG1}@${VMCONTEXT}|${VM_OPTS}b${VMGAIN}'));  //; Voicemail Busy message
150 $ext->add(s-BUSY,n,'',new ext_Goto('exit-${VMSTATUS},1'));
151
152 $ext->add(s-DIRECTDIAL,1,'',new ext_NoOp('DIRECTDIAL voicemail'));
153 $ext->add(s-DIRECTDIAL,n,'',new ext_Macro('get-vmcontext,${ARG1}'));
154 $ext->add(s-DIRECTDIAL,n,'',new ext_vm('${ARG1}@${VMCONTEXT}|${VM_OPTS}${VM_DDTYPE}${VMGAIN}'));
155 $ext->add(s-DIRECTDIAL,n,'',new ext_Goto('exit-${VMSTATUS},1'));
156
157 $ext->add(_s-.,1,'',new ext_Macro('get-vmcontext,${ARG1}'));
158 $ext->add(_s-.,n,'',new ext_vm('${ARG1}@${VMCONTEXT}|${VM_OPTS}u${VMGAIN}'));    // ; Voicemail Unavailable message
159 $ext->add(_s-.,n,'',new ext_Goto('exit-${VMSTATUS},1'));
160
161 $ext->add(o,1,'',new ext_Background('one-moment-please'));      ; 0 during vm message will hangup
162 $ext->add(o,n,'',new ext_GotoIf('$['x${OPERATOR_XTN}'  '='  'x']?nooper:from-internal,${OPERATOR_XTN},1'));
163 $ext->add(o,n,'nooper',new ext_GotoIf('$['x${FROM_DID}' '=' 'x']?nodid'));
164 $ext->add(o,n,'',new ext_Dial('Local/${FROM_DID}@from-pstn'));
165 $ext->add(o,n,'',new ext_Macro('hangup'));
166 $ext->add(o,n,'nodid',new ext_Dial('Local/s@from-pstn'));
167 $ext->add(o,n,'',new ext_Macro('hangup'));
168
169 $ext->add(a,1,'',new ext_Macro('get-vmcontext,${ARG1}'));
170 $ext->add(a,n,'',new ext_vmMain,('${ARG1}@${VMCONTEXT}'));
171 $ext->add(a,n,'',new ext_Macro('hangup'));
172
173 $ext->add(exit-FAILED,1,'',new ext_Playback('im-sorry&an-error-has-occured'));
174 $ext->add(exit-FAILED,n,'',new ext_Macro('hangup'));
175
176 $ext->add(exit-SUCCESS,1,'',new ext_Playback('goodbye'));
177 $ext->add(exit-SUCCESS,n,'',new ext_Macro('hangup'));
178
179 $ext->add(exit-USEREXIT,1,'',new ext_Playback('goodbye'));
180 $ext->add(exit-USEREXIT,n,'',new ext_Macro('hangup'));
181
182 $ext->add(t,1,'',new ext_Macro('hangup'));
183
184 //------------------------------------------------------------------------
185 // $id  =  'macro-simple-dial]
186 //------------------------------------------------------------------------
187 // This macro was derived from macro-exten-vm, which is what is normally used to
188 // ring an extension. It has been simplified and designed to never go to voicemail
189 // and always return regardless of the DIALSTATUS for any incomplete call.
190 //
191 // It's current primary purpose is to allow findmefollow ring an extension prior
192 // to trying the follow-me ringgroup that is provided.
193 //
194 // Ring an extension, if the extension is busy or there is no answer, return
195 // ARGS: $EXTENSION, $RINGTIME
196 //------------------------------------------------------------------------
197 $id  =  'macro-simple-dial';
198 $ext->add(s,1,'',new ext_Macro('user-callerid,SKIPTTL')); // ; already called from follow-me
199
200 // FROMCONTEXT was in the original macro-exten-vm where this macro was derived from. A
201 // search through all the modules does not come up with any place using this
202 // variable, but it is left here as a reminder in case there is functionality
203 // that eventually behaves in a certain way as a result of this variable being set
204 // and this macro has to masquerade as exten-vm.
205 //
206 $ext->add(s,n,'',new ext_Set('EXTTOCALL '=' ${ARG1}'));
207 $ext->add(s,n,'',new ext_Set('RT '=' ${ARG2}'));
208 $ext->add(s,n,'',new ext_Set('CFUEXT '=' ${DB(CFU/${EXTTOCALL})}'));
209 $ext->add(s,n,'',new ext_Set('CFBEXT '=' ${DB(CFB/${EXTTOCALL})}'));
210 $ext->add(s,n,'',new ext_Macro('record-enable,${EXTTOCALL},IN'));
211
212 $ext->add(s,n,'',new ext_Macro('dial,${RT},${DIAL_OPTIONS},${EXTTOCALL}'));
213
214 $ext->add(s,n,'',new ext_Set('PR_DIALSTATUS '=' ${DIALSTATUS}'));
215
216 // if we return, thus no answer, and they have a CFU setting, then  we try that next
217 //
218 $ext->add(s,n,'',new ext_GosubIf('$[$['${DIALSTATUS}' '=' 'NOANSWER'] & $['foo${CFUEXT}'! '=' 'foo']]?docfu,1')); // check for CFU in use on no answer
219 $ext->add(s,n,'',new ext_GosubIf('$[$['${DIALSTATUS}' '=' 'BUSY'] & $['foo${CFBEXT}'! '=' 'foo']]?docfb,1')); // check for CFB in use on busy
220
221 // Nothing yet, then go to the end (which will just return, but in case we decide to do something with certain
222 // return situations, this is left in.
223 //
224 $ext->add(s,n,'',new ext_Goto('s-${DIALSTATUS},1'));
225
226 // Try the Call Forward on No Answer / Unavailable number.
227 // 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
228 // system ringtimer? - probably not). Then if no answer there (assuming it doesn't drop into their vm or
229 // something we return, which will have the net effect of returning to the followme setup.)
230 //
231 // want to avoid going to other follow-me settings here. So check if the CFUEXT is a user and if it is
232 // then direct it straight to ext-local (to avoid getting intercepted by findmefollow) otherwise send it
233 // to from-internal since it may be an outside line.
234 //
235 $ext->add(docfu,1,'',new ext_GotoIf(' $[ 'foo${DB(AMPUSER/${CFUEXT}/device)}'  '='  'foo' ]?chlocal'));
236 $ext->add(docfu,n,'',new ext_Dial('Local/${CFUEXT}@ext-local,${RT},${DIAL_OPTIONS}'));
237 $ext->add(docfu,n,'',new ext_macro('return');
238 $ext->add(docfu,n,'chlocal',new ext_Dial('Local/${CFUEXT}@from-internal/n,${RT},${DIAL_OPTIONS}'));
239 $ext->add(docfu,n,'',new ext_macro('return');
240
241 // Try the Call Forward on Busy number
242 $ext->add(docfb,1,'',new ext_GotoIf(' $[ 'foo${DB(AMPUSER/${CFBEXT}/device)}'  '='  'foo' ]?chlocal'));
243 $ext->add(docfb,n,'',new ext_Dial('Local/${CFBEXT}@ext-local,${RT},${DIAL_OPTIONS}'));
244 $ext->add(docfb,n,'',new ext_macro('return'));
245 $ext->add(docfb,n,'chlocal',new ext_Dial('Local/${CFBEXT}@from-internal/n,${RT},${DIAL_OPTIONS}'));
246 $ext->add(docfb,n,'',new ext_macro('return'));
247
248 // In all cases of no connection, come here and simply return, since the calling dialplan will
249 // decide what to do next
250 $ext->add(_s-.,1,'',ext_NoOp('Extension is reporting ${EXTEN}'));
251 //------------------------------------------------------------------------
252 // get the voicemail context for the user in ARG1
253 $id  =  'macro-get-vmcontext';
254 $ext->add(s,1,'',ext_Set('VMCONTEXT '=' ${DB(AMPUSER/${ARG1}/voicemail)}'));
255 $ext->add(s,2,'',ext_GotoIf('$['foo${VMCONTEXT}'  '='  'foo']?200:300'));
256 $ext->add(s,200,'',ext_Set('VMCONTEXT '=' default'));
257 $ext->add(s,300,'',ext_NoOp('));
258
259 // For some reason, if I don't run setCIDname, CALLERID(name) will be blank in my AGI
260 // ARGS: none
261 $id  =  'macro-fixcid'
262 $ext->add(s,1,'',ext_Set('CALLERID(name) '=' ${CALLERID(name)}'));
263
264
265
266 // Ring groups of phones
267 // ARGS: comma separated extension list
268 // 1 - Ring Group Strategy
269 // 2 - ringtimer
270 // 3 - prefix
271 // 4 - extension list
272 $id  =  'macro-rg-group'
273 $ext->add(s,1,'',ext_Macro('user-callerid,SKIPTTL')); // already called from ringgroup
274 $ext->add(s,2,'',ext_GotoIf('$['${CALLERID(name):0:${LEn,'${RGPREFIX})}}' '!='  '${RGPREFIX}']?4:3'));  // check for old prefix
275 $ext->add(s,3,'',ext_Set('CALLERID(name)' '=' '${CALLERID(name)' ':' '${LEn','${RGPREFIX})}}')); // strip off old prefix
276 $ext->add(s,4,'',ext_Set('RGPREFIX' '=' '${ARG3}'));  // set new prefix
277 $ext->add(s,5,'',ext_Set('CALLERID(name)' '=' '${RGPREFIX}${CALLERID(name)}'));  // add prefix to callerid name
278 $ext->add(s,6,'',ext_Set('RecordMethod' '=' 'Group'));  // set new prefix
279 $ext->add(s,7,'',ext_Macro('record-enable,${MACRO_EXTEN},${RecordMethod}'));
280 $ext->add(s,8,'',ext_Set('RingGroupMethod' '=' '${ARG1}'));     
281 $ext->add(s,9,'',ext_Macro('dial,${ARG2},${DIAL_OPTIONS},${ARG4}'));
282 $ext->add(s,10,'',ext_Set('RingGroupMethod '=' ''));     
283
284 //
285 // Outgoing channel(s) are busy ... inform the client
286 // but use noanswer features like ringgroups don't break by being answered
287 // just to play the message.
288 //
289 $id  =  'macro-outisbusy';
290 $ext->add(s,1,'',ext_Playback('all-circuits-busy-now,noanswer'));
291 $ext->add(s,n,'',ext_Playback('pls-try-call-later,noanswer'));
292 $ext->add(s,n,'',ext_Macro('hangupcall'));
293
294 // What to do on hangup.                                         
295 $id  =  'macro-hangupcall';
296 $ext->add(s,1,'',ResetCDR('w'));
297 $ext->add(s,n,'',NoCDR(''));
298  
299 // Cleanup any remaining RG flag
300 //
301 $ext->add(s,n,'',ext_GotoIf('$[ 'foo${USE_CONFIRMATION}'  '='  'foo' | 'foo${RINGGROUP_INDEX}'  '='  'foo' | '${CHANNEL}' ! '='  '${UNIQCHAN}']?skiprg'));
302 $ext->add(s,n,'',ext_NoOp('Cleaning Up Confirmation Flag: RG/${RINGGROUP_INDEX}/${CHANNEL}'));
303 $ext->add(s,n,''.ext_DBDel('RG/${RINGGROUP_INDEX}/${CHANNEL}'));
304
305 // Cleanup any remaining BLKVM flag
306 //
307 $ext->add(s,n,'skiprg',ext_GotoIf('$[ 'foo${BLKVM_BASE}'  '='  'foo' | 'BLKVM/${BLKVM_BASE}/${CHANNEL}' ! '='  '${BLKVM_OVERRIDE}' ]?theend'));
308 $ext->add(s,n,'',ext_NoOp('Cleaning Up Block VM Flag:' '${BLKVM_OVERRIDE}'));
309 $ext->add(s,n,'',ext_DBDel('${BLKVM_OVERRIDE}'));
310
311 $ext->add(s,n,'theend',,ext_Wait('5'));
312 $ext->add(s,n,'',ext_Macro('hangup'));
313
314 $id  =  'macro-faxreceive';
315 $ext->add(s,1,'',ext_Set('FAXFILE '=' /var/spool/asterisk/fax/${UNIQUEID}.tif'));
316 $ext->add(s,2,'',ext_Set('EMAILADDR '=' ${FAX_RX_EMAIL}'));
317 $ext->add(s,3,'',ext_rxfax('${FAXFILE}'));
318 $ext->add(s,103,'',ext_Set('EMAILADDR '=' ${FAX_RX_EMAIL}'));
319 $ext->add(s,104,'',ext_Goto('3'));
320
321 // dialout and strip the prefix
322 $id  =  'macro-dialout';
323 $ext->add(s,1,'',ext_Macro('user-callerid,SKIPTTL'));
324 $ext->add(s,2,'',ext_GotoIf('$['${ECID${CALLERID(number)}}' '=' '']?5'));   //check for CID override for exten
325 $ext->add(s,3,'',ext_Set('CALLERID(all) '=' ${ECID${CALLERID(number)}}'));
326 $ext->add(s,4,'',ext_Goto('7'));
327 $ext->add(s,5,'',ext_GotoIf('$['${OUTCID_${ARG1}}' '=' '']?7'));    //check for CID override for trunk
328 $ext->add(s,6,'',ext_Set('CALLERID(all) '=' ${OUTCID_${ARG1}}'));
329 $ext->add(s,7,'',ext_Set('length' '=' ${LEn,'${DIAL_OUT_${ARG1}})}'));
330 $ext->add(s,8,'',ext_Dial('${OUT_${ARG1}}/${ARG2:${length}}'));
331 $ext->add(s,9,'',ext_Playtones('congestion'));
332 $ext->add(s,10,'',ext_Congestion,('5'));
333 $ext->add(s,109,'',ext_Macro('outisbusy'));
334
335
336 // dialout using default OUT trunk - no prefix
337 $id  =  'macro-dialout-default';
338 $ext->add(s,1,'',ext_Macro('user-callerid,SKIPTTL'));
339 $ext->add(s,2,'',ext_Macro('record-enable,${CALLERID(number)},OUT'));
340 $ext->add(s,3,'',ext_Macro('outbound-callerid,${ARG1}'));
341 $ext->add(s,4,'',ext_Dial('${OUT}/${ARG1}'));
342 $ext->add(s,5,'',ext_Playtones('congestion'));
343 $ext->add(s,6,'',ext_Congestion,''5'));
344 $ext->add(s,105,'',ext_Macro('outisbusy'));
345
346 // dialout using a trunk, using pattern matching (don't strip any prefix)
347 // arg1  '='  trunk number, arg2  '='  number, arg3  '='  route password
348 //
349 // MODIFIED (PL)
350 //
351 // Modified both Dial() commands to include the new TRUNK_OPTIONS from the general
352 // screen of AMP
353 //
354 $id  =  'macro-dialout-trunk';
355 $ext->add(s,1,'',ext_Set('DIAL_TRUNK '=' ${ARG1}'));
356
357 // If NODEST is set, clear it. No point in remembering since dialout-trunk will just end in the
358 // bit bucket. But if answered by an outside line with transfer capability, we want NODEST to be
359 // clear so a subsequent transfer to an internal extension works and goes to voicmail or other
360 // destinations.
361 //
362 $ext->add(s,n,'',ext_Set('_NODEST '=' '));
363
364 $ext->add(s,n,'',ext_Set('DIAL_NUMBER '=' ${ARG2}'));
365 $ext->add(s,n,'',ext_Set('ROUTE_PASSWD '=' ${ARG3}'));
366 $ext->add(s,n,'',ext_Set('DIAL_TRUNK_OPTIONS '=' ${DIAL_OPTIONS}')); // will be reset to TRUNK_OPTIONS if not intra-company
367 $ext->add(s,n,'',ext_GotoIf('$['${ROUTE_PASSWD}' '=' '']?noauth')); // ; arg3 is pattern password
368 $ext->add(s,n,'auth',ext_Authenticate('${ROUTE_PASSWD}'));
369 $ext->add(s,n,'noauth',ext_Set('GROUP() '=' OUT_${DIAL_TRUNK}'));
370 $ext->add(s,n,'',ext_Macro('user-callerid,SKIPTTL'));
371 $ext->add(s,n,'',ext_Macro('record-enable,${CALLERID(number)},OUT'));
372 $ext->add(s,n,'',ext_GotoIf('$['${INTRACOMPANYROUTE}' '=' 'YES']?skipoutcid')); //Set to YES if treated like internal
373 $ext->add(s,n,'',ext_Set('DIAL_TRUNK_OPTIONS '=' ${TRUNK_OPTIONS}'));
374 $ext->add(s,n,'',ext_Macro('outbound-callerid,${DIAL_TRUNK}')):
375 $ext->add(s,n,'skipoutcid',ext_GotoIf('$['${OUTMAXCHANS_${DIAL_TRUNK}}foo'  '='  'foo']?nomax'));
376 $ext->add(s,n,'checkmax',ext_GotoIf('$[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${DIAL_TRUNK}} ]?chanfull'));
377 $ext->add(s,n,'nomax',ext_DeadAGI('fixlocalprefix')); // this sets DIAL_NUMBER to the proper dial string for this trunk
378 $ext->add(s,n,'',ext_Set('OUTNUM '=' ${OUTPREFIX_${DIAL_TRUNK}}${DIAL_NUMBER}')); // OUTNUM is the final dial number
379 $ext->add(s,n,'',ext_Set('custom '=' ${CUT(OUT_${DIAL_TRUNK},:,1)}')); // Custom trunks are prefixed with 'AMP:'
380 $ext->add(s,n,'',ext_GotoIf('$['${custom}'  '='  'AMP']?customtrunk'));
381 $ext->add(s,n,'',ext_Dial('${OUT_${DIAL_TRUNK}}/${OUTNUM},300,${DIAL_TRUNK_OPTIONS}')); // Regular Trunk Dial
382 $ext->add(s,n,'',ext_Goto('s-${DIALSTATUS},1'));
383 $ext->add(s,n,'customtrunk',ext_Set('pre_num '=' ${CUT(OUT_${DIAL_TRUNK},$,1)}'));
384 $ext->add(s,n,'',ext_Set('the_num '=' ${CUT(OUT_${DIAL_TRUNK},$,2)}')); // this is where we expect to find string OUTNUM
385 $ext->add(s,n,'',ext_Set('post_num '=' ${CUT(OUT_${DIAL_TRUNK},$,3)}'));
386 $ext->add(s,n,'',ext_GotoIf('$['${the_num}' '=' 'OUTNUM']?outnum:skipoutnum')); // if we didn't find 'OUTNUM', then skip to Dial
387 $ext->add(s,n,'outnum',ext_Set('the_num '=' ${OUTNUM}')); // ; replace 'OUTNUM' with the actual number to dial
388 $ext->add(s,n,'skipoutnum',ext_Dial('${pre_num:4}${the_num}${post_num},300,${DIAL_TRUNK_OPTIONS}'));
389 $ext->add(s,n,'',ext_Goto('s-${DIALSTATUS},1'));
390
391 $ext->add(s,n,'chanfull',ext_NoOp('max channels used up'));
392
393 $ext->add(s-BUSY,1,'',ext_NoOp('Dial failed due to trunk reporting BUSY - giving up'));
394 $ext->add(s-BUSY,2,'',ext_Busy('20'));
395
396 $ext->add(s-NOANSWER,1,'',ext_NoOp('Dial failed due to trunk reporting NOANSWER - giving up'));
397 $ext->add(s-NOANSWER,2,'',ext_Playtones('congestion'));
398 $ext->add(s-NOANSWER,3,'',ext_Congestion,''20'));
399
400 $ext->add(s-CANCEL,1,'',ext_NoOp('Dial failed due to trunk reporting CANCEL - giving up'));
401 $ext->add(s-CANCEL,2,'',ext_Playtones('congestion'));
402 $ext->add(s-CANCEL,3,'',ext_Congestion,''20'));
403
404 $ext->add(_s-.,1,'',ext_NoOp('Dial failed due to ${DIALSTATUS} - failing through to other trunks'));
405
406 $ext->add(h,1,'',ext_Macro('hangupcall'));
407
408 //; Adds a dynamic agent/member to a Queue
409 //; Prompts for call-back number - in not entered, uses CIDNum
410 $id  =  'macro-agent-add';
411 $ext->add(s,1,'',ext_Wait('1'));
412 $ext->add(s,2,'',ext_Macro('user-callerid,SKIPTTL'));
413 $ext->add(s,3,'',ext_Read('CALLBACKNUM,agent-user'));//   ; get callback number from user
414 $ext->add(s,4,'',ext_GotoIf('$['${CALLBACKNUM}' '=' '']?5:7')); //  ; if user just pressed # or timed out, use cidnum
415 $ext->add(s,5,'',ext_Set('CALLBACKNUM '=' ${CALLERID(number)}'));
416 $ext->add(s,6,'',ext_GotoIf('$['${CALLBACKNUM}' '=' '']?2')); //; if still no number, start over
417 $ext->add(s,7,'',ext_GotoIf('$['${ARG2}' '=' '']?9:8'));   //; arg2 is queue password
418 $ext->add(s,8,'',ext_Authenticate('${ARG2}'));
419 $ext->add(s,9,'',ext_AddQueueMember('${ARG1}|Local/${CALLBACKNUM}@from-internal/n')); // using chan_local allows us to have agents over trunks
420 $ext->add(s,10,'',ext_UserEvent('Agentlogin|Agent: ${CALLBACKNUM}'));
421 $ext->add(s,11,'',ext_Wait('1'));
422 $ext->add(s,12,'',ext_Playback('agent-loginok'));
423 $ext->add(s,13,'',ext_Macro('hangup'));
424
425 // Removes a dynamic agent/member from a Queue
426 // Prompts for call-back number - in not entered, uses CIDNum
427 $id  =  'macro-agent-del';
428 $ext->add(s,1,'',ext_Wait('1'));
429 $ext->add(s,2,'',ext_Macro('user-callerid,SKIPTTL'));
430 $ext->add(s,3,'',ext_Read('CALLBACKNUM,agent-user')); //  ; get callback number from user
431 $ext->add(s,4,'',ext_GotoIf('$['${CALLBACKNUM}' '=' '']?5:7')); // if user just pressed # or timed out, use cidnum
432 $ext->add(s,5,'',ext_Set('CALLBACKNUM '=' ${CALLERID(number)}'));
433 $ext->add(s,6,'',ext_GotoIf('$['${CALLBACKNUM}' '=' ]?2')); // if still no number, start over
434 $ext->add(s,7,'',ext_RemoveQueueMember('${ARG1}|Local/${CALLBACKNUM}@from-internal/n'));
435 $ext->add(s,8,'',ext_userevent('RefreshQueue'));
436 $ext->add(s,9,'',ext_Wait('1'));
437 $ext->add(s,10,'',ext_Playback('agent-loggedoff'));
438 $ext->add(s,11,'',ext_Macro('hangup'));
439
440 // arg1  '='  trunk number, arg2  '='  number
441 $id  =  'macro-dialout-enum';
442 // This has been violently beaten upon by Rob Thomas, xrobau@gmail.com
443 // to 1: Be compliant with all the depreciated bits in asterisk 1.2 and
444 // above, and 2: to give a good shot at attempting to be compliant with
445 // RFC3761 by honouring the order in which records are returned.
446 $ext->add(s,1,'',ext_GotoIf('$['${ARG3} '! '='  '']?PASSWD:NOPASSWD')); //arg3 is pattern password
447 $ext->add(s,n,'PASSWD',ext_Authenticate('${ARG3}'));
448 $ext->add(s,n,'NOPASSWD',ext_Macro('user-callerid,SKIPTTL')); 
449 $ext->add(s,n,'',ext_Macro('record-enable,${CALLERID(number)},OUT'));
450 $ext->add(s,n,'',ext_Macro('outbound-callerid,${ARG1}'));
451 $ext->add(s,n,'',ext_Set('GROUP() '=' OUT_${ARG1}'));
452 $ext->add(s,n,'',ext_GotoIf('$[ ${GROUP_COUNT()} '>' ${OUTMAXCHANS_${ARG1}} ]?nochans'));
453 $ext->add(s,n,'',ext_Set('DIAL_NUMBER '=' ${ARG2}'));
454 $ext->add(s,n,'',ext_Set('DIAL_TRUNK'  '='  '${ARG1}'));
455 $ext->add(s,n,'',ext_DeadAGI('fixlocalprefix'));  // this sets DIAL_NUMBER to the proper dial string for this trunk
456 $ext->add(s,n,'',ext_Set('E164NETWORKS'  '='  'e164.arpa-e164.info-e164.org')); // enum networks to check
457 $ext->add(s,n,'',ext_GotoIf('$['${DIAL_NUMBER:0:1}' '=' '+']?begin')); // Skip next line if it already is prefixed by a plus
458 $ext->add(s,n,'',ext_Set('DIAL_NUMBER '=' '+' '${DIAL_NUMBER}')); // Add a plus to the start, becasue ENUMLOOKUP needs it.
459
460 // start of main network loop
461 $ext->add(s,n,'begin',ext_NoOp('E164NETWORKS is ${E164NETWORKS}'));
462 $ext->add(s,n,'',ext_GotoIf('$['${E164NETWORKS:1:2}' '=' '']?failedtotally'));
463 $ext->add(s,n,'',ext_Set('ENUMNET '=' ${CUT(E164NETWORKS,-,1)}'));
464 $ext->add(s,n,'',ext_Set('E164NETWORKS '=' ${CUT(E164NETWORKS,'-',2-)}'));
465
466 $ext->add(s,n,'',ext_NoOp('E164NETWORKS is now ${E164NETWORKS}'));
467 $ext->add(s,n,'',ext_NoOp('ENUMNET is ${ENUMNET}'));
468
469 $ext->add(s,n,'',ext_Set('ENUMCOUNT '=' ${ENUMLOOKUP(${DIAL_NUMBER},all,c,${ENUMNET})}'));
470 $ext->add(s,n,'',ext_Set('ENUMPTR '=' 0'));
471 $ext->add(s,n,'',ext_Set('LOOKUPBUG '=' 0'));
472
473 // start of main lookup loop
474 $ext->add(s,n,'startloop',ext_GotoIf('$['${ENUMPTR}' '<' '${ENUMCOUNT}']?continue:failed'));
475
476 // Now, let's start through them.
477 $ext->add(s,n,'continue',ext_Set('ENUMPTR '=' $[${ENUMPTR}+1]'));
478 $ext->add(s,n,'',ext_NoOp('Doing ENUMLOOKUP(${DIAL_NUMBER},all,${ENUMPTR},${ENUMNET})'));
479 $ext->add(s,n,'',ext_Set('ENUM '=' ${ENUMLOOKUP(${DIAL_NUMBER},all,${ENUMPTR},${ENUMNET})}'));
480
481 // Deal with reponse
482 $ext->add(s,n,'',ext_GotoIf('$['${ENUM:0:3}'  '='  'sip' ]?sipuri'));
483 $ext->add(s,n,'',ext_GotoIf('$['${ENUM:0:3}'  '='  'iax' ]?iaxuri'));
484 // It doesn't matter if you don't have h323 enabled, as when it tries to dial, it cares
485 // about dialstatus and retries if there are any enum results left.
486 $ext->add(s,n,'',ext_GotoIf('$['${ENUM:0:3}'  '='  'h32' ]?h323uri'));
487
488 // e164.org can return 'ADDRESS' lines. Because of *'s poor handling of Enum
489 // lookups, we want to DECREMENT the enum pointer. Yes. That means we try more
490 // times than there actually exists entries.
491 $ext->add(s,n,'',ext_GotoIf('$['${ENUM:0:3}'  '='  'ADD' ]?enumbug'));
492
493 // OK. If we're here, we've still got some enum entries to go through. Back to
494 // the start with you!
495 $ext->add(s,n,'',ext_Goto('startloop'));
496
497 // We're here because of the poor implementation of ENUMLOOKUP in Asterisk. It
498 // is quite possible to do three ENUMLOOKUPS and get the same entry each time.
499 // The only workaround I can think of is when we hit an invalid entry, do a
500 // DECREMENT of the pointer, and keep trying.
501 $ext->add(s,n,'enumbug',ext_Set('ENUMPTR '=' $[${ENUMPTR}-1]'));
502 $ext->add(s,n,'',ext_NoOp('If this is looping with the same ENUM value, The ENUMLOOKUP function is fixed!'));
503 $ext->add(s,n,'',ext_Set('LOOKUPBUG '=' $[${LOOKUPBUG}+1]'));
504 // If we've done this more than, ooh, 5 times, then give up on this network. Sorry.
505 $ext->add(s,n,'',ext_GotoIf('$['${LOOKUPBUG}' > 5 ]?failed'));
506 $ext->add(s,n,'',ext_Goto('continue'));
507
508 // If the prefix is 'sip:'...
509 $ext->add(s,n,'sipuri',ext_Set('DIALSTR '=' SIP/${ENUM:4}'));
510 $ext->add(s,n,'',ext_Goto('dodial'));
511
512 //; If it's IAX2...
513 $ext->add(s,n,'iaxuri',ext_Set('DIALSTR '=' IAX2/${ENUM:5}'));
514 $ext->add(s,n,'',ext_Goto('dodial'));
515
516 // Or even if it's H323.
517 $ext->add(s,n,'h323uri','',ext_Set('DIALSTR '=' H323/${ENUM:5}'));
518
519 $ext->add(s,n,'dodial',ext_Dial('${DIALSTR}'));
520 $ext->add(s,n,'',ext_NoOp('Dial exited in macro-enum-dialout with' '${DIALSTATUS}'));
521
522 // Now, if we're still here, that means the Dial failed for some reason.
523 // If it's CONGESTION or CHANUNAVAIL we probably want to try again on a
524 // different channel. However, if it's the last one, we don't have any
525 // left, and I didn't keep any previous dialstatuses, so hopefully
526 // someone looking throught the logs would have seen the NoOp's
527 $ext->add(s,n,'',ext_GotoIf('$['${ENUMPTR}'<'${ENUMCOUNT}']?maybemore:dialfailed'));
528 $ext->add(s,n,'maybemore',ext_GotoIf('$[ $[ '${DIALSTATUS}'  '='  'CHANUNAVAIL' ] | $[ '${DIALSTATUS}'  '='  'CONGESTION' ] ]?continue'));
529
530 // If we're here, then it's BUSY or NOANSWER or something and well, deal with it.
531 $ext->add(s,n,'dialfailed',ext_Goto('s-${DIALSTATUS},1'));
532
533 // Here are the exit points for the macro.
534 $ext->add(s,n,'failed',ext_NoOp('EnumLookup failed on network ${ENUMNET}'));
535 $ext->add(s,n,'',ext_Goto('begin'));
536
537 $ext->add(s,n,'failedtotally',ext_NoOp('EnumLookup failed -- no more networks to try'));
538 $ext->add(s,n,'',ext_Goto('end'));
539
540 $ext->add(s,n,'nochains',ext_NoOp('max channels used up'));
541
542 $ext->add(s,n,'end',ext_NoOp('Exiting macro-dialout-enum'));
543
544 $ext->add(s-BUSY,1,'',ext_NoOp('Trunk is reporting BUSY'));
545 $ext->add(s-BUSY,2,'',ext_Busy('20'));
546
547 $ext->add(_s-.,1,'',ext_NoOp('Dial failed due to ${DIALSTATUS}'));
548
549 $id  =  'macro-record-enable';
550 $ext->add(s,1,'',ext_GotoIf('$[${LEn, ${BLINDTRANSFER})}' '>' '0]?2:4'));
551 $ext->add(s,2,'',ext_ResetCDR('w'));
552 $ext->add(s,3,'',ext_StopMonitor(''));
553 // I haven't figured out how, but occasionally a hung up
554 // call can end up here. If you don't use DeadAGI (which does
555 // work fine as a normal AGI), asterisk deadlocks a thread,
556 // and ends up grumpy.
557 $ext->add(s,4,'',ext_DeadAGI('recordingcheck,${TIMESTAMP},${UNIQUEID}'));
558 $ext->add(s,5,'',ext_NoOp('No recording needed'));
559 $ext->add(s,999,'',ext_MixMonitor('${CALLFILENAME}.wav'));
560
561 //$ext->add(s,3,'',ext_Background('for-quality-purposes)
562 //$ext->add(s,4,'',ext_Background('this-call-may-be)
563 //$ext->add(s,5,'',ext_Background('recorded)
564
565 // This macro is for dev purposes and just dumps channel/app variables.  Useful when designing new contexts.
566 $id  =  'macro-dumpvars';
567 $ext->add(s,1,'',ext_NoOp('ACCOUNTCODE '=' ${ACCOUNTCODE}'));
568 $ext->add(s,2,'',ext_NoOp('ANSWEREDTIME '=' ${ANSWEREDTIME}'));
569 $ext->add(s,3,'',ext_NoOp('BLINDTRANSFER '=' ${BLINDTRANSFER}'));
570 $ext->add(s,4,'',ext_NoOp('CALLERID '=' ${CALLERID(all)}'));
571 $ext->add(s,5,'',ext_NoOp('CALLERID(name) '=' ${CALLERID(name)}'));
572 $ext->add(s,6,'',ext_NoOp('CALLERID(number) '=' ${CALLERID(number)}'));
573 $ext->add(s,7,'',ext_NoOp('CALLINGPRES '=' ${CALLINGPRES}'));
574 $ext->add(s,8,'',ext_NoOp('CHANNEL '=' ${CHANNEL}'));
575 $ext->add(s,9,'',ext_NoOp('CONTEXT '=' ${CONTEXT}'));
576 $ext->add(s,10,'',ext_NoOp('DATETIME '=' ${DATETIME}'));
577 $ext->add(s,11,'',ext_NoOp('DIALEDPEERNAME '=' ${DIALEDPEERNAME}'));
578 $ext->add(s,12,'',ext_NoOp('DIALEDPEERNUMBER '=' ${DIALEDPEERNUMBER}'));
579 $ext->add(s,13,'',ext_NoOp('DIALEDTIME '=' ${DIALEDTIME}'));
580 $ext->add(s,14,'',ext_NoOp('DIALSTATUS '=' ${DIALSTATUS}'));
581 $ext->add(s,15,'',ext_NoOp('DNID '=' ${DNID}'));
582 $ext->add(s,16,'',ext_NoOp('EPOCH '=' ${EPOCH}'));
583 $ext->add(s,17,'',ext_NoOp('EXTEN '=' ${EXTEN}'));
584 $ext->add(s,18,'',ext_NoOp('HANGUPCAUSE '=' ${HANGUPCAUSE}'));
585 $ext->add(s,19,'',ext_NoOp('INVALID_EXTEN '=' ${INVALID_EXTEN}'));
586 $ext->add(s,20,'',ext_NoOp('LANGUAGE '=' ${LANGUAGE}'));
587 $ext->add(s,21,'',ext_NoOp('MEETMESECS '=' ${MEETMESECS}'));
588 $ext->add(s,22,'',ext_NoOp('PRIORITY '=' ${PRIORITY}'));
589 $ext->add(s,23,'',ext_NoOp('RDNIS '=' ${RDNIS}'));
590 $ext->add(s,24,'',ext_NoOp('SIPDOMAIN '=' ${SIPDOMAIN}'));
591 $ext->add(s,25,'',ext_NoOp('SIP_CODEC '=' ${SIP_CODEC}'));
592 $ext->add(s,26,'',ext_NoOp('SIPCALLID '=' ${SIPCALLID}'));
593 $ext->add(s,27,'',ext_NoOp('SIPUSERAGENT '=' ${SIPUSERAGENT}'));
594 $ext->add(s,28,'',ext_NoOp('TIMESTAMP '=' ${TIMESTAMP}'));
595 $ext->add(s,29,'',ext_NoOp('TXTCIDNAME '=' ${TXTCIDNAME}'));
596 $ext->add(s,30,'',ext_NoOp('UNIQUEID '=' ${UNIQUEID}'));
597 $ext->add(s,31,'',ext_NoOp('TOUCH_MONITOR '=' ${TOUCH_MONITOR}'));
598 $ext->add(s,32,'',ext_NoOp('MACRO_CONTEXT '=' ${MACRO_CONTEXT}'));
599 $ext->add(s,33,'',ext_NoOp('MACRO_EXTEN '=' ${MACRO_EXTEN}'));
600 $ext->add(s,34,'',ext_NoOp('MACRO_PRIORITY '=' ${MACRO_PRIORITY}'));
601
602 $id  =  'macro-user-logon';
603 // check device type
604 $ext->add(s,1,'',ext_Set('DEVICETYPE '=' ${DB(DEVICE/${CALLERID(number)}/type)}'));
605 $ext->add(s,2,'',ext_GotoIf('$['${DEVICETYPE}'  '='  'fixed']?s-FIXED,1'));
606 // get user's extension
607 $ext->add(s,3,'',ext_Set('AMPUSER '=' ${ARG1}'));
608 $ext->add(s,4,'',ext_GotoIf('$['${AMPUSER}'  '='  '']?5:9'));
609 $ext->add(s,5,'',ext_Background('please-enter-your'));
610 $ext->add(s,6,'',ext_Playback('extension'));
611 $ext->add(s,7,'',ext_Read('AMPUSER,then-press-pound'));
612 // get user's password and '',ext_Authenticate
613 $ext->add(s,8,'',ext_Wait('1'));
614 $ext->add(s,9,'',ext_Set('AMPUSERPASS '=' ${DB(AMPUSER/${AMPUSER}/password)}'));
615 $ext->add(s,10,'',ext_GotoIf('$[${LEn,${AMPUSERPASS})}'  '='  '0]?s-NOPASSWORD,1'));
616 // do not continue if the user has already logged onto this device
617 $ext->add(s,11,'',ext_Set('DEVICEUSER' '=' '${DB(DEVICE/${CALLERID(number)}/user)}'));
618 $ext->add(s,12,'',ext_GotoIf('$['${DEVICEUSER}'  '='  '${AMPUSER}']?s-ALREADYLOGGEDON,1'));
619 $ext->add(s,13,'',ext_Authenticate('${AMPUSERPASS}'));
620 // devices can only be mapped to one user - loggoff anyone else who is here
621 $ext->add(s,14,'',ext_Macro('user-logoff'));
622 // map user to device
623 $ext->add(s,15,'',ext_Set('AMPUSERDEVICES' '=' '${DB(AMPUSER/${AMPUSER}/device)}'));
624 $ext->add(s,16,'',ext_GotoIf('$[${LEn,'${AMPUSERDEVICES})'}'  '='  '0]?18'));
625 $ext->add(s,17,'',ext_Set('AMPUSERDEVICES' '=' '${AMPUSERDEVICES}&'));
626 $ext->add(s,18,'',ext_Set('AMPUSERDEVICES' '=' '${AMPUSERDEVICES}${CALLERID(number)}'));
627 $ext->add(s,19,'',ext_Set('DB(AMPUSER/${AMPUSER}/device) '=' ${AMPUSERDEVICES}'));
628 // map device to user
629 $ext->add(s,20,'',ext_Set('DB(DEVICE/${CALLERID(number)}/user)' '=' '${AMPUSER}'));
630 // create symlink from dummy device mailbox to user's mailbox
631 $ext->add(s,21,'',ext_System('/bin/ln -s /var/spool/asterisk/voicemail/default/${AMPUSER}/ /var/spool/asterisk/voicemail/device/${CALLERID(number)})s,21,System(/bin/ln -s /var/spool/asterisk/voicemail/default/${AMPUSER}/ /var/spool/asterisk/voicemail/device/${CALLERID(number)}'));
632
633 $ext->add(s-FIXED,1,'',ext_NoOp('Device is FIXED and cannot be logged into'));
634 $ext->add(s-FIXED,2,'',ext_Playback('ha/phone'));
635 $ext->add(s-FIXED,3,'',ext_SayDigits('${CALLERID(number)}'));
636 $ext->add(s-FIXED,4,'',ext_Playback('is-curntly-unavail'));
637 $ext->add(s-FIXED,5,'',ext_Playback('vm-goodbye'));
638 $ext->add(s-FIXED,6,'',ext_macro('hangup'); //;TODO should play msg indicated device cannot be logged into
639
640 $ext->add(s-ALREADYLOGGEDON,1,'',ext_NoOp('This device has already been logged into by this user'));
641 $ext->add(s-ALREADYLOGGEDON,2,'',ext_Playback('vm-goodbye'));
642 $ext->add(s-ALREADYLOGGEDON,3,'',ext_Macro('hangup')); //;TODO should play msg indicated device is already logged into
643
644 $ext->add(s-NOPASSWORD,1,'',ext_NoOp('This extension does not exist or no password is set'));
645 $ext->add(s-NOPASSWORD,2,'',ext_Playback('an-error-has-occured'));
646 $ext->add(s-NOPASSWORD,3,'',ext_Playback('vm-goodbye'));
647 $ext->add(s-NOPASSWORD,4,'',ext_Macro('hangup')); //;TODO should play msg indicated device is already logged into
648
649 $id  =  'macro-user-logoff';
650 // check device type
651 $ext->add(s,1,'',ext_Set('DEVICETYPE '=' ${DB(DEVICE/${CALLERID(number)}/type)}'));
652 $ext->add(s,2,'',ext_GotoIf('$['${DEVICETYPE}'  '='  'fixed']?s-FIXED,1'));
653 // remove entry from user's DEVICE key
654 // delete the symlink to user's voicemail box
655 $ext->add(s,3,'',ext_System('rm -f /var/spool/asterisk/voicemail/device/${CALLERID(number)}'));
656 $ext->add(s,4,'',ext_Set('DEVAMPUSER '=' ${DB(DEVICE/${CALLERID(number)}/user)}'));
657 $ext->add(s,5,'',ext_Set('AMPUSERDEVICES '=' ${DB(AMPUSER/${DEVAMPUSER}/device)}'));
658 $ext->add(s,6,'',ext_DeadAGI('list-item-remove.php,${AMPUSERDEVICES},${CALLERID(number)},AMPUSERDEVICES,&'));
659 //; reset user -> device mapping
660 //; users can log onto multiple devices, need to just remove device from value
661 $ext->add(s,7,'',ext_Set('DB(AMPUSER/${DEVAMPUSER}/device) '=' ${AMPUSERDEVICES}'));
662 $ext->add(s,7,'',ext_Set('DB(AMPUSER/${DEVAMPUSER}/device) '=' ${AMPUSERDEVICES}'));
663 //; reset device -> user mapping
664 $ext->add(s,8,'',ext_Set('DB(DEVICE/${CALLERID(number)}/user) '=' none'));
665 $ext->add(s,9,'',ext_Playback('vm-goodbye'));
666
667 $ext->add(s-FIXED,1,'',ext_NoOp('Device is FIXED and cannot be logged out of'));
668 $ext->add(s-FIXED,2,'',ext_Playback('an-error-has-occured'));
669 $ext->add(s-FIXED,3,'',ext_Playback('vm-goodbye'));
670 $ext->add(s-FIXED,4,'',ext_macro('hangup'); //TODO should play msg indicated device cannot be logged into
671
672 $id  =  'macro-systemrecording';
673 $ext->add(s,1,'',ext_Goto('${ARG1},1'));
674
675 $ext->add(dorecord,1,'',ext_Record('/tmp/${CALLERID(number)}-ivrrecording:wav'));
676 $ext->add(dorecord,n,'',ext_Wait('1'));
677 $ext->add(dorecord,n,'',ext_Goto('confmenu,1'));
678
679 $ext->add(docheck,1,'',ext_Playback('/tmp/${CALLERID(number)}-ivrrecording'));
680 $ext->add(docheck,n,'',ext_Wait('1'));
681 $ext->add(docheck,n,'',ext_Goto('confmenu,1'));
682
683 $ext->add(confmenu,1,'',ext_Background('to-listen-to-it&press-1&to-rerecord-it&press-star|m||macro-systemrecording'));
684 $ext->add(confmenu,n,'',ext_Read('RECRESULT||1|||4'));
685 $ext->add(confmenu,n,'',ext_GotoIf('$['x${RECRESULT}' '=' 'x*']?dorecord,1'));
686 $ext->add(confmenu,n,'',ext_GotoIf('$['x${RECRESULT}' '=' 'x1']?docheck,1'));
687 $ext->add(confmenu,n,'',ext_Goto('1'));
688
689 $ext->add(1,1,'',ext_Goto('docheck,1'));
690 $ext->add(*,1,'',ext_Goto('dorecord,1'));
691
692 $ext->add(t,1,'',ext_Playback('goodbye'));
693 $ext->add(t,n,'',ext_macro('hangup'););
694
695 $ext->add(i,1,'',ext_Playback('pm-invalid-option'));
696 $ext->add(i,n,'',ext_Goto('confmenu,1'));
697
698 $ext->add(h,1,'',ext_Macro('hangup'));
699
700
701 //
702 // ############################################################################
703 // CallerID Handling
704 // ############################################################################
705
706 //sets the callerid of the device to that of the logged in user
707 $id  =  'macro-user-callerid';
708 $ext->add(s,1,'',ext_NoOp('user-callerid: ${CALLERID(name)} ${CALLERID(number)}'));
709 $ext->add(s,n,'',ext_GotoIf('$['${CHANNEL:0:5}' '=' 'Local']?report')); 
710 $ext->add(s,n,'',ext_GotoIf('$['${REALCALLERIDNUM:1:2}' ! '='  '']?start'));
711 $ext->add(s,n,'',ext_Set('REALCALLERIDNUM '=' ${CALLERID(number)}'));
712 $ext->add(s,n,'start',ext_NoOp('REALCALLERIDNUM is ${REALCALLERIDNUM}'));
713 $ext->add(s,n,'',ext_Set('AMPUSER '=' ${DB(DEVICE/${REALCALLERIDNUM}/user)}'));
714 $ext->add(s,n,'',ext_Set('AMPUSERCIDNAME '=' ${DB(AMPUSER/${AMPUSER}/cidname)}'));
715 $ext->add(s,n,'',ext_GotoIf('$['x${AMPUSERCIDNAME:1:2}' '=' 'x']?report')); 
716 $ext->add(s,n,'',ext_Set('CALLERID(all) '=' ${AMPUSERCIDNAME} <${AMPUSER}>'));
717 $ext->add(s,n,'',ext_Set('REALCALLERIDNUM '=' ${DB(DEVICE/${REALCALLERIDNUM}/user)}'));
718 $ext->add(s,n,'report',ext_NoOp('TTL: ${TTL} ARG1: ${ARG1}'));
719 $ext->add(s,n,'',ext_GotoIf('$[ '${ARG1}'  '='  'SKIPTTL' ]?continue'));
720 $ext->add(s,n,'report2',ext_Set('_TTL '=' ${IF($['foo${TTL}'  '='  'foo']?64:$[ ${TTL} - 1 ])}'));
721 $ext->add(s,n,'',ext_GotoIf('$[ ${TTL} > 0 ]?continue')); 
722 $ext->add(s,n,'',ext_Wait('${RINGTIMER}')); // wait for a while, to give it a chance to be picked up by voicemail
723 $ext->add(s,n,'',ext_Answer(''));
724 $ext->add(s,n,'',ext_Wait('2'));
725 $ext->add(s,n,'',ext_Playback('im-sorry&an-error-has-occured&with&call-forwarding'));
726 $ext->add(s,n,'',ext_Macro('hangupcall'));
727 $ext->add(s,n,'',ext_Congestion,(''));
728 $ext->add(s,n,'continue',ext_NoOp('Using CallerID' '${CALLERID(all)}'));
729 $ext->add(h,1,'',ext_Macro('hangupcall'));
730
731 // overrides callerid out trunks
732 // arg1 is trunk
733 // macro-user-callerid should be called _before_ using this); macro
734 $id  =  'macro-outbound-callerid';
735 // Keep the original CallerID number, for failover to the next trunk.
736 $ext->add(s,1,'',ext_GotoIf('$['${REALCALLERIDNUM:1:2}' ! '='  '']?start'));
737 $ext->add(s,n,'',ext_Set('REALCALLERIDNUM' '=' '${CALLERID(number)}'));
738 $ext->add(s,n,'start',ext_NoOp('REALCALLERIDNUM is ${REALCALLERIDNUM}'));
739
740 // If this came through a ringgroup or CF, then we want to retain original CID unless
741 // OUTKEEPCID_${trunknum} is set.
742 //
743 $ext->add(s,n,'',ext_GotoIf('$['${KEEPCID}' ! '=' 'TRUE']?normcid')); //Set to TRUE if coming from ringgroups, CF, etc.
744 $ext->add(s,n,'',ext_GotoIf('$['x${OUTKEEPCID_${ARG1}}'  '='  'xon']?normcid'));
745 $ext->add(s,n,'',ext_GotoIf('$['foo${REALCALLERIDNUM}' '=' 'foo']?normcid')); //if not set to anything, go through normal processing
746 $ext->add(s,n,'',ext_Set('USEROUTCID '=' ${REALCALLERIDNUM}'));
747
748 // 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
749 // call (would be quite a conincidence if not) and go through the normal processing to get that CID. If a device
750 // is set for this CID, then it must be internal
751 //
752 $ext->add(s,n,'',ext_GotoIf('$['foo${DB(AMPUSER/${REALCALLERIDNUM}/device)}' '=' 'foo']?bypass:normcid')); 
753
754 $ext->add(s,n,'normcid',,ext_Set('USEROUTCID '=' ${DB(AMPUSER/${REALCALLERIDNUM}/outboundcid)}'));
755 $ext->add(s,n,'bypass',,ext_Set('EMERGENCYCID '=' ${DB(DEVICE/${REALCALLERIDNUM}/emergency_cid)}'));
756 $ext->add(s,n,'',ext_Set('TRUNKOUTCID '=' ${OUTCID_${ARG1}}'));
757 $ext->add(s,n,'',ext_GotoIf('$['${EMERGENCYROUTE:1:2}' '=' '']?trunkcid')); // check EMERGENCY ROUTE
758 $ext->add(s,n,'',ext_GotoIf('$['${EMERGENCYCID:1:2}' '=' '']?trunkcid')); // empty EMERGENCY CID, so default back to trunk
759 $ext->add(s,n,'',ext_Set('CALLERID(all) '=' ${EMERGENCYCID}')); // ; emergency cid for device
760 $ext->add(s,n,'',ext_Goto('report'));
761 $ext->add(s,n,'trunkcid',,ext_GotoIf('$['${TRUNKOUTCID:1:2}' '=' '']?usercid'));  //check for CID override for trunk (global var)
762 $ext->add(s,n,'',ext_Set('CALLERID(all) '=' ${TRUNKOUTCID}'));
763 $ext->add(s,n,'usercid',,ext_GotoIf('$['${USEROUTCID:1:2}' '=' '']?report')); // check CID override for extension
764 $ext->add(s,n,'',ext_Set('CALLERID(all) '=' ${USEROUTCID}'));
765 $ext->add(s,n,'',ext_GotoIf('$['x${CALLERID(name)}'! '=' 'xhidden']?report:hidecid')); // check CID blocking for extension
766 $ext->add(s,n,'hidecid',,ext_SetCallerPres(prohib_passed_screen')); // ; Only works with ISDN (T1/E1/BRI'));
767 $ext->add(s,n,'report',,ext_NoOp('CallerID set to ${CALLERID(all)}'));
768
769 // Privacy Manager Macro makes sure that any calls that don't pass the privacy manager are presented
770 // with congestion since there have been observed cases of the call continuing if not stopped with a
771 // congestion, and this provides a slightly more friendly 'sorry' message in case the user is
772 // legitamately trying to be cooperative.
773 //
774 // Note: the following options are configurable in privacy.conf:
775 //
776 //  maxretries  '='  3 ; default value, number of retries before failing
777 //  minlength  '='  10 ; default value, number of digits to be accepted as valid CID
778 //
779 $id  =  'macro-privacy-mgr';
780 $ext->add(s,1,'',ext_Set('KEEPCID '=' ${CALLERID(num)}'));
781 $ext->add(s,n,'',ext_GotoIf('$['foo${CALLERID(num):0:1}' '=' 'foo+']?CIDTEST2:CIDTEST1'));
782 $ext->add(s,n,'CIDTEST1',,ext_Set('TESTCID '=' ${MATH(1+${CALLERID(num)})}'));
783 $ext->add(s,n,'',ext_Goto('TESTRESULT'));
784 $ext->add(s,n,'CIDTEST2',,ext_Set('TESTCID '=' ${MATH(1+${CALLERID(num):1})}'));
785 $ext->add(s,n,'TESTRESULT',,ext_GotoIf('$['foo${TESTCID}' '=' 'foo']?CLEARCID:PRIVMGR'));
786 $ext->add(s,n,'CLEARCID',,ext_Set('CALLERID(num) '=' '));
787 $ext->add(s,n,'PRIVMGR',PrivacyManager(''));
788 $ext->add(s,n,'',ext_SetCallerPres('allowed_passed_screen')); //; stop gap until app_privacy.c clears unavailble bit
789 $ext->add(s,n,'PRIVMGR+101',ext_NoOp('STATUS: ${PRIVACYMGRSTATUS} CID: ${CALLERID(num)} ${CALLERID(name)} CALLPRES: ${CALLLINGPRES}'));
790 $ext->add(s,n,'',ext_Playback('sorry-youre-having-problems'));
791 $ext->add(s,n,'',ext_Playback('goodbye'));
792 $ext->add(s,n,'',ext_Playtones('congestion'));
793 $ext->add(s,n,'',ext_Congestion,('5'));
794
795
796 //
797 // ############################################################################
798 // Inbound Contexts [from]
799 // ############################################################################
800
801 $id  =  'from-sip-external';
802 //give external sip users congestion and hangup
803 // Yes. This is _really_ meant to be _. - I know asterisk whinges about it, but
804 // I do know what I'm doing. This is correct.
805 $ext->add(_.,1,'',ext_NoOp('Received incoming SIP connection from unknown peer to ${EXTEN}'));
806 $ext->add(_.,n,'',ext_Set('DID '=' ${IF($['${EXTEN:1:2}' '=' '']?s:${EXTEN})}'));
807 $ext->add(_.,n,'',ext_Goto('s,1'));
808 $ext->add(s,1,'',ext_Ringing(''));
809 $ext->add(s,n,'',ext_GotoIf('$['${ALLOW_SIP_ANON}' '=' 'yes']?from-trunk,${DID},1'));
810 $ext->add(s,n,'',ext_Set('TIMEOUT(absolute) '=' 15'));
811 $ext->add(s,n,'',ext_Answer(''));
812 $ext->add(s,n,'',ext_Wait('2'));
813 $ext->add(s,n,'',ext_Playback('ss-noservice'));
814 $ext->add(s,n,'',ext_Playtones('congestion'));
815 $ext->add(s,n,'',ext_Congestion,('5'));
816 $ext->add(h,1,'',ext_NoOp('Hangup'));
817 $ext->add(i,1,'',ext_NoOp('Invalid'));
818 $ext->add(t,1,'',ext_NoOp('Timeout'));
819
820 $id  =  'from-internal';
821 // applications are now mostly all found in from-internal-additional in _custom.conf
822 $ext->addInclude('include  parkedcalls');
823 $ext->addInclude('include  from-internal-custom');
824 //allow phones to dial other extensions
825 $ext->addInclude('include  ext-fax');
826 //allow phones to access generated contexts
827 //
828 // MODIFIED (PL)
829 //
830 // Currently the include for findmefollow is being auto-generated before ext-local which is the desired behavior.
831 // However, I haven't been able to do anything that I know of to force this. We need to determine if it should
832 // be hardcoded into here to make sure it doesn't change with some configuration. For now I will leave it out
833 // until we can discuss this.
834 //
835 $ext->addInclude('include  from-internal-additional');
836 $ext->addInclude('include  ext-local-confirm');
837 // This causes grief with '#' transfers, commenting out for the moment.
838 $ext->addInclude('include  bad-number');
839 $ext->add(s,1,'',ext_Macro('hangupcall'));
840 $ext->add(h,1,'',ext_Macro('hangupcall'));
841
842 //------------------------------------------------------------------------
843 // [bad-number]
844 //------------------------------------------------------------------------
845 // This is where all calls go that don't have any other destination provided
846 //
847 ;------------------------------------------------------------------------
848 $id  =  'bad-number';
849 $ext->add(_X.,1,'',ext_Wait('1'));
850 $ext->add(_X.,n,'',ext_Playback('silence/1&cannot-complete-as-dialed&check-number-dial-again,noanswer'));
851 $ext->add(_X.,n,'',ext_Wait('1'));
852 $ext->add(_X.,n,'',ext_Congestion,('20'));
853 $ext->add(_X.,n,'',ext_Macro('hangup'));
854
855 $ext->add(_*.,1,'',ext_Wait('1'));
856 $ext->add(_*.,n,'',ext_Playback('silence/1&feature-not-avail-line&silence/1&cannot-complete-as-dialed&check-number-dial-again,noanswer'));
857 $ext->add(_*.,n,'',ext_Wait('1'));
858 $ext->add(_*.,n,'',ext_Congestion,('20'));
859 $ext->add(_*.,n,'',ext_Macro('hangup'));
860 ;------------------------------------------------------------------------
861
862 $id  =  'from-zaptel';
863 $ext->add(_X.,1,'',ext_Set('DID '=' ${EXTEN}'));
864 $ext->add(_X.,n,'',ext_Goto('s,1'));
865 $ext->add(s,1,'',ext_NoOp('Entering from-zaptel with DID  '='  '='  ${DID}'));
866 // Some trunks _require_ a RINGING be sent before an Answer.
867 $ext->add(s,n,'',ext_Ringing(''));
868 // If ($did  '='  '='  '') { $did  '='  's'; }
869 $ext->add(s,n,'',ext_Set('DID '=' ${IF($['${DID}' '='  '']?s:${DID})}'));
870 $ext->add(s,n,'',ext_NoOp('DID is now ${DID}'));
871 $ext->add(s,n,'',ext_GotoIf('$['${CHANNEL:0:3}' '=' 'Zap']?zapok:notzap'));
872 $ext->add(s,n,'notzap',ext_Goto('from-pstn,${DID},1'));
873 // If there's no ext-did,s,1, that means there's not a no did/no cid route. Hangup.
874 $ext->add(s,n,'',ext_Macro('hangup'));
875 $ext->add(s,n,'zapok',ext_NoOp('Is a Zaptel Channel'));
876 $ext->add(s,n,'',ext_Set('CHAN' '=' '${CHANNEL:4}'));
877 $ext->add(s,n,'',ext_Set('CHAN' '=' '${CUT(CHAN,-,1)}'));
878 $ext->add(s,n,'',ext_Macro('from-zaptel-${CHAN},${DID},1'));
879 // If nothing there, then treat it as a DID
880 $ext->add(s,n,'',ext_NoOp('Returned from Macro from-zaptel-${CHAN}'));
881 $ext->add(s,n,'',ext_Goto('from-pstn,${DID},1'));
882 $ext->add(fax,1,'',ext_Goto('ext-fax,in_fax,1'));
883
884 // ##########################################
885 // ## Ring Groups with Confirmation macros ##
886 // ##########################################
887 // Used by followme and ringgroups
888
889 //------------------------------------------------------------------------
890 // $id  =  'macro-dial-confirm'
891 //------------------------------------------------------------------------
892 // This has now been incorporated into dialparties. It still only works with ringall
893 // and ringall-prim strategies. Have not investigated why it doesn't work with
894 // hunt and memory hunt.
895 //
896 //------------------------------------------------------------------------
897 $id  =  'macro-dial-confirm';
898 // This was written to make it easy to use macro-dial-confirm instead of macro-dial in generated dialplans.
899 // This takes the same paramaters, with an additional paramater of the ring group Number
900 // ARG1 is the timeout
901 // ARG2 is the DIAL_OPTIONS
902 // ARG3 is a list of xtns to call - 203-222-240-123123123#-211
903 // ARG4 is the ring group number
904
905 // This sets a unique value to indicate that the channel is ringing. This is used for warning slow
906 // users that the call has already been picked up.
907 //
908 $ext->add(s,1,'',ext_Set('DB(RG/${ARG4}/${CHANNEL}) '=' RINGING'));
909
910 // We need to keep that channel variable, because it'll change when we do this dial, so set it to
911 // fallthrough to every sibling.
912 //
913 $ext->add(s,n,'',ext_Set('__UNIQCHAN '=' ${CHANNEL}'));
914
915 // The calling ringgroup should have set RingGroupMethod appropriately. We need to set two
916 // additional parameters:
917 //
918 // USE_CONFIRMATION, RINGGROUP_INDEX
919 //
920 // Thse are passed to inform dialparties to place external calls through the [grps] context
921 //
922 $ext->add(s,n,'',ext_Set('USE_CONFIRMATION '=' TRUE'));
923 $ext->add(s,n,'',ext_Set('RINGGROUP_INDEX '=' ${ARG4}'));
924 $ext->add(s,n,'',ext_Set('ARG4' '=' '' ) // otherwise it gets passed to dialparties.agi which processes it (prob bug)
925
926 $ext->add(s,n,'',ext_Macro('dial,${ARG1},${ARG2},${ARG3}'));
927
928 // delete the variable, if we are here, we are done trying to dial and it may have been left around
929 //
930 $ext->add(s,n,ext_DBDel('RG/${RINGGROUP_INDEX}/${CHANNEL}'));
931 $ext->add(s,n,'',ext_Set('USE_CONFIRMATION' '=' ''));
932 $ext->add(s,n,'',ext_Set('RINGGROUP_INDEX' '=' ''));
933 //------------------------------------------------------------------------
934
935 //------------------------------------------------------------------------
936 // $id  =  'macro-auto-confirm'
937 //------------------------------------------------------------------------
938 // This macro is called from ext-local-confirm to auto-confirm a call so that other extensions
939 // are aware that the call has been answered.
940 //
941 //------------------------------------------------------------------------
942 $id  =  'macro-auto-confirm';
943 $ext->add(s,1,'',ext_Set('__MACRO_RESULT '=' '));
944 $ext->add(s,n,'',ext_DBDel('${BLKVM_OVERRIDE}'));
945 $ext->add(s,n,'',ext_DBDel('RG/${ARG1}/${UNIQCHAN}'));
946
947 //------------------------------------------------------------------------
948 // $id  =  'macro-auto-blkvm]
949 //------------------------------------------------------------------------
950 // This macro is called for any extension dialed form a queue, ringgroup
951 // or followme, so that the answering extension can clear the voicemail block
952 // override allow subsequent transfers to properly operate.
953 //
954 //------------------------------------------------------------------------
955 $id  =  'macro-auto-blkvm';
956 $ext->add(s,1,'',ext_Set('__MACRO_RESULT '=' '));
957 $ext->add(s,n,'',ext_DBDel('${BLKVM_OVERRIDE}'));
958
959 //------------------------------------------------------------------------
960 // [ext-local-confirm]
961 //------------------------------------------------------------------------
962 // If call confirm is being used in a ringgroup, then calls that do not require confirmation are sent
963 // to this extension instead of straight to the device.
964 //
965 // The sole purpose of sending them here is to make sure we run Macro(auto-confirm) if this
966 // extension answers the line. This takes care of clearing the database key that is used to inform
967 // other potential late comers that the extension has been answered by someone else.
968 //
969 //------------------------------------------------------------------------
970 $id  =  'ext-local-confirm';
971 $ext->add(_LC-.,1,'',ext_NoOp('IN ext-local-confirm with - RT: ${RT}, RG_IDX: ${RG_IDX}'));
972 $ext->add(_LC-.,n,'',ext_Dial('${DB(DEVICE/${EXTEN:3}/dial)},${RT},M(auto-confirm^${RG_IDX})${DIAL_OPTIONS}'));
973
974 //------------------------------------------------------------------------
975 // $id  =  'macro-confirm]
976 //------------------------------------------------------------------------
977 // CONTEXT:      macro-confirm                                                                                                             
978 // PURPOSE:      added default message if none supplied
979 //
980 // Follom-Me and Ringgroups provide an option to supply a message to be
981 // played as part of the confirmation. These changes have added a default
982 // message if none is supplied.
983 //
984 //------------------------------------------------------------------------
985 $id  =  'macro-confirm';
986 $ext->add(s,1,'',ext_Set('LOOPCOUNT '=' 0'));
987 $ext->add(s,n,'',ext_NoOp('CALLCONFIRMCID: ${CALLCONFIRMCID}'));
988
989 // We set ABORT rather than CONTINUE, as we want the server to forget about this channel
990 // if it's declined, hung up, or timed out. We don't want it to continue on to the next
991 // step in the dialplan, which could be anything!
992 $ext->add(s,n,'',ext_Set('__MACRO_RESULT '=' ABORT'));
993
994 // ARG1 is the announcement to play to tell the user that they've got a call they need
995 // to confirm. Something along the lines of 'You have an incoming call. Press 1 to accept, 9 to reject'
996 $ext->add(s,n,'',ext_Set('MSG1 '=' ${IF($['foo${ARG1}' ! '='  'foo']?${ARG1}:'incoming-call-1-accept-2-decline')}'));
997 $ext->add(s,n,'start',ext_Read('INPUT|${MSG1}|1||1|5'));
998
999 // So. We've now read something, or nothing. We should check to make sure that the call hasn't
1000 // already been answered by someone else. If it has, send this call to toolate
1001 $ext->add(s,n,'',ext_GotoIf('${DB_EXISTS(RG/${ARG3}/${UNIQCHAN})}?check:toolate'));
1002
1003 // We passed that test, so it means the call hasn't been answered. Has this user pushed 1? If so,
1004 // then go to OK.
1005 $ext->add(s,n,'check',,ext_GotoIf('$['${INPUT}' '=' '1']?ok'));
1006
1007 // If they've pushed 9, then they definately don't want the call. Just pretend there was no response
1008 // and go to noanswer (or 2 since that will be default for asterisk)
1009 $ext->add(s,n,'',ext_GotoIf('$['${INPUT}' '=' '9']?noanswer'));
1010 $ext->add(s,n,'',ext_GotoIf('$['${INPUT}' '=' '2']?noanswer'));
1011 $ext->add(s,n,'',ext_GotoIf('$['${INPUT}' '=' '3']?playcid'));
1012
1013 // Increment LOOPCOUNT, and check to make sure we haven't played it 5 times by now. We assume that
1014 // the person is able to push '1' in a reasonably short time.
1015 $ext->add(s,n,'',ext_Set('LOOPCOUNT '=' $[ ${LOOPCOUNT} + 1 ]'));
1016 $ext->add(s,n,'',ext_GotoIf('$[ ${LOOPCOUNT} < 5 ]?start'));
1017
1018 // If we're here, that means we've played it MORE than 5 times. Set __MACRO_RESULT '=' ABORT, well, just
1019 // coz, and goto fin, which is the last line, meaning it returns to the previous Dial, and pretends as
1020 // if nothing has happened.
1021 $ext->add(s,n,'noanswer',ext_Set(');__MACRO_RESULT '=' ABORT'));
1022 $ext->add(s,n,'',ext_Goto('fin'));
1023
1024 // Test play callerid
1025 //
1026 $ext->add(s,n,'playcid',ext_NoOp('Playing CID: ${CALLCONFIRMCID}'));
1027 $ext->add(s,n,'',ext_SayDigits('${CALLCONFIRMCID}'));
1028 $ext->add(s,n,'',ext_Goto('start'));
1029
1030 // If we're here, it's because the call was already accepted by someone else.
1031 $ext->add(s,n,'toolate',,ext_Set('MSG2 '=' ${IF($['foo${ARG2}' ! '='  'foo']?${ARG2}:'incoming-call-no-longer-avail')}'));
1032 $ext->add(s,n,'',ext_Playback('${MSG2}'));
1033 $ext->add(s,n,'',ext_Goto('noanswer'));
1034
1035 // If we made it here, it's because the call _WAS_ accepted, AND it's still ringing. We delete the
1036 // database entry (so that the DB_EXISTS line above will trigger a 'toolate' jump), and set the
1037 // MACRO_RESULT variable to NOTHING. This is the magic string that joins both legs of the call together
1038 $ext->add(s,n,'ok',ext_DBDel('RG/${ARG3}/${UNIQCHAN}'));
1039 $ext->add(s,n,'',ext_DBDel('${BLKVM_OVERRIDE}'));
1040 $ext->add(s,n,'',ext_Set('__MACRO_RESULT '=' '));
1041
1042 ; The end.
1043 $ext->add(s,n,'fin',ext_NoOp('Finished'));
1044 $ext->add(h,1,'',ext_NoOp('Hangup Extension in macro-confirm'));
1045 $ext->add(h,n,'',ext_Macro('hangupcall'));
1046
1047 //------------------------------------------------------------------------
1048
1049 // ############################################################################
1050 // Extension Contexts [ext]
1051 // ############################################################################
1052
1053 $id  = 'ext-fax';
1054 $ext->add(s,1,'',ext_Answer()):
1055 $ext->add(s,2,'',ext_Goto('in_fax,1'));
1056 $ext->add(in_fax,1,ext-StopPlayTones ;
1057 $ext->add(in_fax,2,'',ext_GotoIf('$['${FAX_RX}'  '='  'system']?3:analog_fax,1'));
1058 $ext->add(in_fax,3,'',ext_Macro('faxreceive'));
1059 $ext->add(in_fax,4,'',ext_macro('hangup');;
1060 $ext->add(analog_fax,1,'',ext_GotoIf('$['${FAX_RX}' '=' 'disabled']?4:2'));  //if fax is disabled, just hang up
1061 $ext->add(analog_fax,2,'',ext_Set('DIAL '=' ${DB(DEVICE/${FAX_RX}/dial)}'));
1062 $ext->add(analog_fax,3,'',ext_Dial('${DIAL},20,d'));
1063 $ext->add(analog_fax,4,'',ext_macro('hangup'););
1064 $ext->add(out_fax,1,'',ext_Wait('7'));
1065 $ext->add(out_fax,1,'',ext_txfax('${TXFAX_NAME}|caller'));
1066 $ext->add(out_fax,2,'',ext_macro('hangup');;
1067 $ext->add(h,1,'',ext_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}'));
1068 $ext->add(h,2,'',ext_Macro('hangup'));
1069
1070 //this is where parked calls go if they time-out.  Should probably re-ring
1071 $id  =  'default';
1072 $ext->addInclude('include  ext-local');
1073 $ext->add(s,1,'',ext_Playback('vm-goodbye'));
1074 $ext->add(s,2,'',ext_Macro('hangupcall'));
1075
1076 >?