Generate context for adding callerid name with proper sequences.
[project/luci.git] / contrib / package / asterisk-xip / files / uci / dialplanconf
1 #!/bin/sh
2
3 # Dialplans (extensions.conf)
4
5 # Implicit: ast_add_conf dialplan
6 init_dialplanconf() {
7         ast_enable_type dialplangeneral
8         ast_enable_type dialplan
9         ast_enable_type dialplanexten
10         ast_enable_type dialplangoto
11         ast_enable_type dialplansaytime
12         ast_enable_type dialzone
13         ast_enable_type inzone
14         ast_enable_type incominggeneral
15         ast_enable_type incoming
16
17         dialplan_allowtransfer=no
18         dialplan_dialtimeout=30
19         dialplan_answerfirst=no
20         dialplan_static=yes
21         dialplan_writeprotect=no
22         dialplan_canreinvite=no
23         dialplan_includes=
24         dialplan_globals=
25         return 0
26 }
27
28 match_all="_[0-9*+#]."
29
30 dialplangeneral_list="static writeprotect canreinvite clearglobalvars"
31 dialplangeneral_list_ex="lastdialed lastdialedtype voiceboxext answerfirst dialtimeout allowtransfer international internationalout"
32
33 valid_dialplangeneral() {
34         for i in  ${dialplangeneral_list} ${dialplangeneral_list_ex} ; do
35                 [ "$i" == "$1" ] && return 0
36         done            
37         return 1
38 }
39
40
41 check_add_context() {
42         local context="${1}"
43         local check="${context#macro-}"
44         [ "${context}" == ${check} ] || check="macro__${check}"
45         eval "local isadded=\"\${dialplan_add_context_${check}-0}\""
46         if [ "$isadded" != "1" ] ; then
47                 eval "dialplan_add_context_${check}=1"
48                 append dialplan_contexts "$context"
49                 return 0
50         else
51                 return 1
52         fi
53 }
54 append_dialplan_context() {
55         local context="${1}"
56         local check="${context#macro-}"
57         [ "${context}" == ${check} ] || check="macro__${check}"
58         append dialplan_context_${check} "${2}" "${N}"
59 }
60
61 reload_dialplan() astcmd "dialplan reload"
62
63 # Voicemail
64
65 enable_voicemail() {
66         enable_module res_adsi
67         enable_module app_voicemail
68         enable_format gsm
69 }
70
71 add_dialplan_exten() {
72         local context=$1
73         logdebug 3 "Exten: $2"
74         local ext="exten => $2,"
75         local planopt=
76         local timeout=${dialplan_dialtimeout}
77                 # Answer extensions first.
78         local answerfirst=${dialplan_answerfirst}
79         local mailbox=$4
80         [ -z "$5" ] || timeout=$5
81         [ -z "$6" ] || answerfirst=$6
82
83         check_add_context "$context"
84
85         if [ "$dialplan_allowtransfer" == "yes" ] ; then
86                 planopt=${planopt}t
87         fi
88         if [ ! -z "${planopt}" ] ; then
89                 planopt=",${timeout},${planopt}"
90         elif [ ! -z "${timeout}" ] ; then
91                 planopt=",${timeout}"
92         fi
93         local dial="Dial($3$planopt)"
94         local item="1,"
95         if [ "$answerfirst" == "yes" ] ; then
96                 append_dialplan_context ${context}  "${ext}1,Answer"
97                 item="n,"
98         fi
99         append_dialplan_context ${context}  "${ext}${item}${dial}"
100         if [ ! -z "${mailbox}" ] ; then
101                 enable_voicemail
102                 append_dialplan_context ${context}  "${ext}n,VoiceMail(${mailbox})"
103         fi
104
105         append_dialplan_context ${context}  "${ext}n,Congestion"
106 }
107
108 add_dialplan_include() {
109         local context=$1
110         logdebug 1 "Adding Dialplan Include $1 $2"
111         check_add_context "$context"
112
113         split_append dialplan_context_${context} "include => " "$2" "${N}"
114 }
115
116 add_dialplan_saytime() {
117         local context=$1
118         logdebug 1 "Adding Dialplan saytime $1 $2"
119         check_add_context "$context"
120         local ext="exten => $2,"
121         if [ "$dialplan_add_context_saytime" != 1 ] ; then
122                 append dialplan_contexts saytime " "
123                 dialplan_add_context_saytime=1
124                 enable_format gsm
125                 enable_module app_sayunixtime
126                 local zone=${asterisk_zone}
127                 [ ! -z "$3" ] && zone="$3"
128                 local format="IMp AdbY"
129                 [ ! -z "$4" ] && format="$4"
130                 append dialplan_context_saytime "exten => s,1,SayUnixTime(,${zone},${format})" "${N}"
131         fi
132         append_dialplan_context ${context}  "${ext}1,Goto(saytime,s,1)"
133 }
134
135 add_dialplan_goto() {
136         local context=$1
137         logdebug 1 "Adding Dialplan goto $1 $2 $3"
138         check_add_context "$context"
139         append dialplan_context_${context} "exten => $2,1,Goto($3,\${EXTEN},1)" "${N}"
140 }
141
142 dialplan_inzone_list="match caller goto"
143
144 valid_dialplan_inzone() {
145         is_in_list $1 ${valid_inzone_list}
146         return $?
147 }
148
149 check_append_inzone() {
150         local context="${1}"
151         eval "local isadded=\"\${dialplan_add_inzone_${context}-0}\""
152         if [ "$isadded" != "1" ] ; then
153                 eval "dialplan_add_inzone_${check}=1"
154                 append inzone_contexts "$context"
155                 return 0
156         else
157                 return 1
158         fi
159 }
160
161 handle_inzone() {
162
163         context_name=${1}
164         check_append_inzone ${context_name}
165
166         option_cb(){
167                 case $1 in
168                         goto)       eval "inzone_${context_name}_goto=\"\$2\"" ;;
169                         match_ITEM*|match)   append inzone_${context_name}_match "$2" " " ;;
170                         caller_ITEM*|caller) append inzone_${context_name}_caller "$2" " " ;;
171                         include_ITEM*|include) append inzone_${context_name}_include "$2" " " ;;
172                         match_LENGTH|caller_LENGTH|include_LENGTH) ;;
173                         *) logerror "Invalid Dialplan inzone option: $1" ;;
174                 esac
175         }
176 }
177
178
179 append_dialplan_inzone() {
180         local file=$1
181         for context in ${inzone_contexts} ; do
182                 for i in goto match caller include ; do
183                         eval "iz_$i=\"\${inzone_${context}_${i}}\""
184                 done
185                 if [ -z "${iz_goto}" ] ; then
186                         logerror "Missing goto for inzone: ${context}"
187                 elif [ -z "${iz_match}" -a -z "${iz_caller}" ] ; then
188                         logerror "Missing match for inzone: ${context}"
189                 else
190                         echo "${N}[${context}]" >> ${file}
191                         for curmatch in ${iz_include} ; do
192                                 echo "include => ${curmatch}" >> $file
193                         done
194
195                         local gotoline="Goto(${iz_goto},\${EXTEN},1)"
196                         [ -z "${iz_match}" ] && iz_match=${match_all}
197                         for curmatch in ${iz_match} ; do
198                                 if [ -z "${iz_caller}" ] ; then
199                                         echo "exten => ${curmatch},1,${gotoline}" >> $file
200                                 else
201                                         for curcaller in ${iz_caller} ; do
202                                                 echo "exten => ${curmatch}/${curcaller},1,${gotoline}" >> $file
203                                         done
204                                 fi
205                         done
206                 fi
207         done
208 }
209
210 append_dialplan_dialzone()  {
211         local file=$1
212
213         # Add the dialzone contexts
214         logdebug 1 "Dialplan: Add the dialzone contexts"
215         for zonename in ${dzones_match} ; do
216                 eval "local diallist=\${dzone_${zonename}_match-}"
217                 echo "${N}[${zonename}]" >> $file
218                 eval "dialz=\${dzone_match_use_${zonename}-}"
219
220                 logdebug 3 "Find international options for zone ${zonename} from ${dialz}"
221                 for v in prefix internationalprefix alwaysinternational countrycode ; do
222                         eval "local $v=\${target_${v}_${dialz}:-}"
223                         eval logdebug 3 "\"${v} = '\${$v}'\""
224                 done
225
226                 for v in localzone addprefix localprefix; do
227                         eval "local $v=\${dzone_${zonename}_${v}:-}"
228                 done
229                 while [ ! -z "$diallist" ] ; do
230                         cur=${diallist%%,*}
231                         nvar=${diallist#*,}
232                         if [ "${alwaysinternational}" = "yes" ] ; then
233                                 # Always dial international number with this target
234                                 # remove 'localprefix' (usually 0) from  'addprefix'
235                                 logdebug 3 "Removing ${localprefix} from ${addprefix}"
236                                 addprefix=${addprefix#$localprefix}
237                                 local curlen=`expr length "${localprefix}"`
238                                 if [ $curlen != 0 ] ; then
239                                         # remove 0 (or local prefix)
240                                         echo "exten => _${localprefix}${cur},1,Goto(${dialz}_dial,${countrycode}${addprefix}\${EXTEN:$curlen},1)" >> $file
241                                 fi
242                                 echo "exten => _${cur},1,Goto(${dialz}_dial,${countrycode}${addprefix}\${EXTEN},1)" >> $file
243                         else
244                                 echo "exten => _${cur},1,Goto(${dialz}_dial,${addprefix}\${EXTEN},1)" >> $file
245                         fi
246                         [ "$nvar" == "$diallist" ] && break
247                         diallist=${nvar}
248                 done
249                 eval "local diallist=\${dzone_${zonename}_international-}"
250                 if [ ! -z "${diallist}" ] ; then
251                         logdebug 2 "International: ${diallist}"
252                         while [ ! -z "$diallist" ] ; do
253                                 cur="${diallist%%,*}"
254                                 nvar="${diallist#*,}"
255                                 logdebug 4 "Adding international ${cur}"
256
257                                 local curlen=`expr length "${cur}"`
258                                 if [ "$alwaysinternational" = "yes" ]  ; then
259                                         echo "exten => _${cur},1,Goto(${dialz}_dial,${addprefix}\${EXTEN:${curlen}},1)" >> $file
260                                 else
261                                         echo "exten => _${cur}.,1,Goto(${zonename}_check,${addprefix}\${EXTEN:${curlen}},1)" >> $file
262                                 fi
263                                 [ "$nvar" == "$diallist" ] && break
264                                 diallist="${nvar}"
265                         done
266
267                         if [ "$alwaysinternational" != "yes" ]  ; then
268                                 logdebug 2 "Not Always International:"
269                                 # Check for local country code
270                                 echo "[${zonename}_check]" >> $file
271
272                                 local locallen=`expr length "${countrycode}"`
273                                 echo "exten => _${countrycode}X.,1,Goto(${localzone-default},${localprefix-0}\${EXTEN:${locallen}},1)" >> $file
274                                 echo "exten => _X.,1,Goto(${dialz}_dial,${internationalprefix}\${EXTEN},1)" >> $file
275                         fi
276                 fi
277         done
278         logdebug 1 "Dialplan: Finish the dialzone contexts"
279
280 }
281
282 append_dialplan_dialzone_out(){
283         local file=$1
284
285         # Add the dialzone target contexts (dialing out)
286         logdebug 1 "Dialplan: Add the dialzone target contexts"
287         for contype in SIP IAX ; do
288                 eval local conlist=\${dzones_${contype}-}
289                 logdebug 1 "Adding ${contype} targets: ${conlist}"
290                 for conname in $conlist ; do
291                         echo "${N}[${contype}_${conname}_dial]" >> $file
292                         for  v in prefix internationalprefix alwaysinternational countrycode timeout lastdialed lastdialedtype ; do
293                                 eval "local $v=\${target_${v}_${contype}_${conname}:-}"
294                         done
295
296                         if [ -z "${lastdialed}" ] ; then
297                                 lastdialed=${dialplan_lastdialed}
298                                 lastdialedtype=${dialplan_lastdialedtype}
299                         fi
300
301                         # [ -z "${lastcallout}" ] && lastcallout=${feature_lastcall_outqueue}
302                         # if [ ! -z "${lastcalloutexten}" ] ; then
303                         #       eval "local added=\${lastcallout_outqueue_extension_${lastcalloutexten}}"
304                         #       if [ ! "${added}" == 1 ] ; then
305                         #               add_dialplan_lastcall extensions "${lastcalloutexten}" "${lastcallout}" "${feature_lastcall_outcount}"
306                         #               eval "local lastcallout_outqueue_extension_${lastcalloutexten}=1"
307                         #       fi
308                         # fi
309                         local ext="exten => _X.,"
310                         local en="1,"
311                         # Do not use prefix unles 'alwaysinternational' is yes
312                         [ "$alwaysinternational" != "yes" ]  && internationalprefix=
313
314                         # if [ ! -z "${lastcallout}" ] ; then # Add lastcall out
315                         #       enable_lastcall
316                         #       echo "${ext}${en}Macro(lastcallstore,${internationalprefix}\${EXTEN},${lastcallout},${feature_lastcall_outcount})" >> $file
317                         #       en="n,"
318                         # fi
319
320                         if [ ! -z "${lastdialed}" ] ; then
321                                 enable_module func_callerid
322                                 local lastparam="\${EXTEN}"
323                                 local lastmacro=${lastdialed}
324                                 local lastmacrotype=${lastdialedtype}
325                                 [ -z ${lastdialedtype} ]  && lastdialedtype=macro
326
327                                 local jumpmacroline=
328                                 gen_jumpmacro jumpmacroline "${ext}${en}" "" "${lastmacrotype}" "${lastmacro}" "${lastparam}"
329                                 echo ${jumpmacroline} >> $file
330                                 en="n,"
331                         fi
332                         echo "${ext}${en}Dial(${contype}/${prefix}${internationalprefix}\${EXTEN}@${conname},$timeout)" >> $file
333                         echo "exten => _X.,n,Congestion" >> $file
334                 done
335         done
336 }
337
338
339 gen_jumpmacro() {
340         logdebug 3 "Gen JumpMacro /$1/=/$2/$3/$4/$5/$6/"
341         local leader=$2
342         local condition=$3
343         local macrotype=$4
344         local name=$5
345         local param=$6
346
347         if [ -z "${condition}" ] ; then
348                 local cond="("
349         else
350                 local cond="If(${condition}?"
351         fi
352         case ${macrotype} in
353                 gosub)
354                         enable_module app_stack # for gosub
355                         logdebug 1 "${1}=\"\${leader}Gosub\${cond}\${name},\${param},1)\""
356                         eval "${1}=\"\${leader}Gosub\${cond}\${name},\${param},1)\"" ;;
357                 gosub_s)
358                         enable_module app_stack # for gosub
359                         logdebug 1 "${1}=\"\${leader}Gosub\${cond}\${name},s,1(\${param}))\""
360                         eval "${1}=\"\${leader}Gosub\${cond}\${name},s,1(\${param}))\"" ;;
361                 macro)
362                         enable_module app_macro
363                         logdebug 1 "${1}=\"\${leader}Macro\${cond}\${name},\${param})\""
364                         eval  "${1}=\"\${leader}Macro\${cond}\${name},\${param})\"" ;;
365
366                 s|start)
367                         enable_module app_goto
368                         logdebug 1 "${1}=\"\${leader}Goto(\${iz_target},s,1)\"" 
369                         eval "${1}=\"\${leader}Goto(\${iz_target},s,1)\"" ;;
370                 *)
371                         enable_module app_goto
372                         logdebug 1 "${1}=\"\${leader}Goto\${cond}\${name},\${param},1)\""
373                         eval "${1}=\"\${leader}Goto\${cond}\${name},\${param},1)\"" ;;
374         esac
375 }
376
377 append_jumpmacro(){
378         local context=$1
379         local jumpmacroline=""
380         gen_jumpmacro "jumpmacroline" "$2" "$3" "$4" "$5" "$6"
381         append_dialplan_context ${context}  "${jumpmacroline}"
382 }
383
384 append_dialplan_incoming(){
385         local file=$1
386         # Evaluate the incoming ringing dialplans
387         logdebug 1 "Add the 'incoming' dialplans: ${dialplan_extensions_incoming}"
388         for context in ${dialplan_extensions_incoming} ; do
389                 eval "local curext=\"\${dialplan_incoming_$context}\""
390                 logdebug 2 "Adding incoming ${curext}"
391
392                 check_add_context "$context"
393                 # lastcall lastcallexten lastmissed lastmissedexten 
394                 for i in answerfirst beforeanswer timeout menucontext \
395                                          lastcall lastcalltype missed missedtype allowtransfer mailbox match matchcaller aftertimeout aftertimeouttype; do
396                         eval "local iz_$i=\"\${incoming_${context}_$i}\""
397                         eval "logdebug 1 \"Incoming \$context: iz_\$i=\${iz_$i}\""
398                 done
399                 [ ! -z ${iz_menucontext} ] && iz_answerfirst=yes
400
401                 if [ ! -z ${curext} ] ; then
402                         [ -z ${iz_answerfirst} ]   && iz_answerfirst=${incoming_answerfirst}
403 #                       [ -z ${iz_lastcall} ]      && iz_lastcall=${feature_lastcall_inqueue}
404                         if [ -z ${iz_lastcall} ] ; then
405                                 iz_lastcall=${incoming_lastcall}
406                                 iz_lastcalltype=${incoming_lastcalltype}
407                         fi
408                         if [ -z ${iz_missed} ] ; then
409                                 iz_missed=${incoming_missed}
410                                 iz_missedtype=${incoming_missedtype}
411                         fi
412                         [ -z ${iz_mailbox} ]       && iz_mailbox=${incoming_mailbox}
413                         [ -z ${iz_timeout} ]       && iz_timeout=${incoming_timeout}
414                         [ -z ${iz_allowtransfer} ] && iz_allowtransfer=${incoming_allowtransfer}
415                 fi
416
417                 [ -z ${iz_match} ]         && iz_match=_X.
418                 [ ! -z ${iz_matchcaller} ] && iz_match=${iz_match}/${iz_matchcaller}
419
420                 local ext="exten => ${iz_match},"
421                 local planopt=
422                 [ "${iz_allowtransfer}" == "yes" ] && planopt=${planopt}t
423                 local item="1,"
424
425                 #append_dialplan_context ${context}  "${ext}${item}Ringing()"
426                 if [ ! -z "${iz_lastcall}" ] ; then
427
428                         enable_module func_callerid
429                         local lastparam="\${CALLERID(num)}"
430                         local lastmacrotype="${iz_lastcalltype}"
431                         [ -z "${iz_lastcalltype}" ] && lastmacrotype=macro
432                         local lastmacro=${iz_lastcall}
433                         append_jumpmacro "${context}" "${ext}${item}" "" "${lastmacrotype}" "${lastmacro}" "${lastparam}"
434                         item="n,"
435                 fi
436                 if [ ! -z "${iz_missed}" ] ; then
437                         enable_module func_callerid
438                         local missedparam="\${CALLERID(num)}"
439                         [ -z "${iz_missedtype}" ] && iz_missedtype=macro
440
441                         append_dialplan_context ${context}  "${ext}${item}Set(lcsMissed=\${CALLERID(num)})"
442                         item="n,"
443                 fi
444                 # Ring before answering
445                 if [ ! -z "${iz_beforeanswer}" -a ! -z "${curext}" ] ; then
446                         append_dialplan_context ${context}  "${ext}${item}Dial(${curext},${iz_beforeanswer},${planopt})"
447                         iz_answerfirst=yes
448                         item="n,"
449                 fi
450                 # Now answer
451                 if [ "$iz_answerfirst" == "yes" ] ; then
452                         append_dialplan_context ${context}  "${ext}${item}Answer"
453                         item="n,"
454                 fi
455                 # if [ ! -z ${iz_lastcallexten} ] ; then
456                 #       enable_lastcall
457                 #       add_dialplan_lastcall extensions "${iz_lastcallexten}" "${iz_lastcall}" "${feature_lastcall_incount}"
458                 # fi
459
460                 if [ ! -z ${curext} ] ; then
461                         if [ ! -z ${iz_menucontext} ] ; then
462                                 planopt=${planopt}rd
463                                 enable_module res_indications
464                                 # wait so the next ring connects.
465                                 append_dialplan_context ${context}  "${ext}${item}Wait(1)"
466                                 append_dialplan_context ${context}  "${ext}n,Set(EXITCONTEXT=${iz_menucontext})"
467                         fi
468
469                         if [ ! -z ${planopt} ] ; then
470                                 planopt=",${iz_timeout-},${planopt}"
471                         elif [ ! -z ${iz_timeout-} ] ; then
472                                 planopt=",${iz_timeout-}"
473                         fi
474                         local dial="Dial(${curext}${planopt})"
475
476                         append_dialplan_context ${context}  "${ext}n,${dial})"
477
478                         if [ ! -z ${iz_missed} ] ; then
479                                 # It went to voicemail or was hung up - consider missed
480                                 append_jumpmacro ${context} "${ext}${item}" "" "${iz_missedtype}" "${iz_missed}" "\${lcsMissed}"
481                         fi
482                 fi
483                 
484                 local need_hangup=1
485                 # Add a goto or macro at the end
486                 if [ ! -z ${iz_target} ] ; then
487                         case ${iz_aftertimeouttype} in
488                                 macro) append_dialplan_context ${context}  "${ext}${item}Macro(${iz_target})";;
489                                 s|start) append_dialplan_context ${context}  "${ext}${item}Goto(${iz_target},s,1)"
490                                          need_hangup=0;;
491                                 *) append_dialplan_context ${context}  "${ext}${item}Goto(${iz_target},\${EXTEN},1)"
492                                          need_hangup=0;;
493                         esac
494                 fi
495
496                 if [ ! -z ${iz_mailbox} ] ; then
497                         enable_voicemail
498                         append_dialplan_context ${context}  "${ext}n,VoiceMail(${iz_mailbox})"
499                 fi
500
501                 [ "${need_hangup}" = "1" ] && append_dialplan_context ${context}  "${ext}n,Hangup"
502
503                 if [ ! -z ${iz_missed} ] ; then
504                         # Check for missed call
505
506                         append_jumpmacro ${context} "exten => h,1," "\$[\"\${DIALSTATUS}\" = \"CANCEL\"]" "${iz_missedtype}" "${iz_missed}" "\${lcsMissed}"
507                         #append dialplan_context_${context} \
508                         #       "exten => h,1,MacroIf(\$[\"\${DIALSTATUS}\" = \"CANCEL\"]?lastcallstore,\${lcsMissed},${iz_lastmissed},${feature_lastcall_incount})" "${N}"
509                         # [ ! -z ${iz_lastmissedexten} ] && \
510                         #       add_dialplan_lastcall extensions "${iz_lastmissedexten}" "${iz_lastmissed}" "${feature_lastcall_incount}"
511                 fi
512         done
513 }
514
515 append_dialplan_extensions(){
516         local file=$1
517         # Evaluate the 'extension' dialplans
518         logdebug 1 "Add the 'extension' dialplans: ${dialplan_exts}"
519         for i in ${dialplan_exts} ; do
520                 eval "local curext=\"\${dialplan_ext_$i}\""
521                 add_dialplan_exten extensions $i $curext
522         done
523 }
524
525 append_include() {
526         append dialplan_includes "#include <$1>" "$N"
527 }
528
529
530 create_dialplanconf() {
531         # Add general section
532         logdebug 1 "Dialplan: Add general section"
533         local file=${DEST_DIR}/extensions.conf
534         get_checksum dialplan_conf $file
535
536         echo "${asteriskuci_gen}" > $file
537         
538         [ -z "${dialplan_includes}" ] || (echo "${dialplan_includes}${N}" >> $file)
539
540         if [ ! -z "${dialplan_globals}" ] ; then
541                 echo "[globals]${N}${dialplan_globals}${N}" >> $file
542         fi
543
544         echo "[general]" >> $file
545         for i in  ${dialplangeneral_list} ; do
546                 eval "local val=\"\$dialplan_$i\""
547                 if [ ! -z "$val" ] ; then
548                         echo "$i=$val" >> $file
549                 fi
550         done
551
552         append_dialplan_dialzone "$file"
553
554         append_dialplan_dialzone_out "$file"
555
556         append_dialplan_park "$file"
557
558         append_dialplan_extensions "$file"
559
560         append_dialplan_inzone "$file"
561
562         append_dialplan_incoming "$file"
563
564
565         # append_dialplan_lastcall "$file"
566
567         # Add all the contexts
568         logdebug 1 "Dialplan: Add all the contexts"
569         for i in ${dialplan_contexts} ; do
570                 echo "${N}[$i]" >> $file
571                 [ "${i#macro-}" == "${i}" ] || i=macro__${i#macro-}
572                 eval "local curcontext=\"\${dialplan_context_$i-}\""
573                 echo "$curcontext">> $file
574                 eval unset dialplan_context_$i
575         done
576
577         check_checksum "$dialplan_conf" "$file"  || ast_dialplan_restart=1
578
579         return 0
580 }
581
582 handle_dialplangeneral() {
583         option_cb(){
584                 if valid_dialplangeneral $1 $2 ; then
585                         eval "dialplan_$1=\"$2\""
586                 else
587                         logerror "Invalid Dialplan General option: $1"
588                 fi
589         }
590 }
591
592
593 handle_dialplan(){
594         context_name=$1
595         if [ -z ${context_name} ] ; then
596                 logerror "Context name required for dialplan"
597                 context_name=default
598         fi
599         option_cb() {
600                 logdebug 4 "dialplan ${context_name}: '$1' '$2'"
601                 case $1 in
602                         include_LENGTH) ;;
603                         include|include_ITEM*) add_dialplan_include ${context_name} $2 ;;
604                         *)
605                                 lhs=$1
606                                 logdebug 4 "Add extension $lhs"
607                                 if [ "$(expr $lhs : [0-9][0-9]\*)" != 0 ] ; then
608                                         addtype=${2%%:*}
609                                         if [ "${addtype}" == "$2" ]; then
610                                                 addparam=
611                                         else
612                                                 addparam=${2#*:}
613                                         fi
614                                         case ${addtype} in
615                                                 mailbox|voice)
616                                                         add_dialplan_voice ${context_name} $1 $addparam ;;
617                                                 meetme|conf|conference)  add_dialplan_meetme ${context_name} $1 $addparam ;;
618                                                 saytime|time) add_dialplan_saytime ${context_name} $1 $addparam ;;
619                                                 clock) add_dialplan_talkclock ${context_name} $1 $addparam ;;
620                                                 *) logerror "Unknown type '${addtype}' in dialplan ${context_name}, extension ${1}"
621                                         esac
622                                 else
623                                         logerror "Invalid option: $1 for dialplan ${context_name}"
624                                 fi
625                 esac
626         }
627 }
628
629 handle_dialplanexten() {
630         check_add dialplanexten
631         option_cb() {
632                 case $1 in
633                         dialplan|extension|type|target|dialextension|voicebox|timeout|answerfirst)
634                                 eval "dial_exten_$1=\"$2\""
635                 esac
636         }
637 }
638
639 check_add_dialplanexten() {
640         if [ ! -z "${dial_exten_dialplan}" -a ! -z "${dial_exten_extension}" ] ; then
641
642                 local dialext_type=
643                 local dialext_ext=
644                 if ! split_targettype dialext_type dialext_ext "${dial_exten_target}" ; then
645                         if [ -z "${dial_exten_type}" ] ; then
646                                 logerror "No extension type specified for ${dial_exten_dialplan} ${dial_exten_extension}"
647                                 return 1
648                         fi
649                         dialext_type="${dial_exten_type}"
650                         dialext_ext="${dial_exten_target}"
651                 fi
652
653
654                 local dialtarget="${dialext_type}/${dialexten_ext}${dial_exten_dialextension+/}${dial_exten_dialextension}"
655
656                 check_add_context ${dial_exten_dialplan}
657                 add_dialplan_exten "${dial_exten_dialplan}" "${dial_exten_extension}" \
658                     "${dialtarget}" "${dial_exten_voicebox}" "${dial_exten_timeout}" \
659                                 "${dial_exten_answerfirst}"
660         fi
661         for i in dialplan extension voicebox type target dialextension timeout answerfirst ; do
662                 eval "unset dial_voice_$i"
663         done
664 }
665
666 handle_dialplansaytime() {
667         check_add dialplansaytime
668         option_cb() {
669                 case $1 in
670                         dialplan|extension|zone|format)
671                                 eval "dial_saytime_$1=\"$2\""
672                 esac
673         }
674 }
675
676 check_add_dialplansaytime() {
677         logdebug 1 "Add Saytime to $1 / $2"
678         if [ ! -z "${dial_saytime_dialplan}" -a ! -z "${dial_saytime_extension}" ] ; then
679                 #               local ext="exten => ${dial_saytime_extension},"
680                 [ -z "${dial_saytime_dialplan}" ] && dial_saytime_dialplan=default
681
682                 add_dialplan_saytime "${dial_saytime_dialplan}" "${dial_saytime_extension}" \
683                         "${dial_saytime_zone}" "${dial_saytime_format}"
684         fi
685         for i in dialplan extension zone format; do
686                 eval "unset dial_saytime_$i"
687         done
688         
689 }
690
691 handle_dialzone_match() {
692         eval "local isadded=\"\${dzone_${zone_name}-0}\""
693         if [ "${isadded}" != "1" ] ; then
694                 eval "dzone_${zone_name}=1"
695                 append dzones_match ${zone_name} " "
696         fi
697         append dzone_${zone_name}_match $1 ","
698 }
699
700 # Set up outgoing zones (match patterns)
701 handle_dialzone() {
702         zone_name=$1
703         logdebug 2 "Loading dialzone: $zone_name"
704         option_cb(){
705                 logdebug 2 "Dialzone $1/$2"
706                 case $1  in
707                         uses)
708                                 local areatype=
709                                 local areaname=
710                                 split_targettype areatype areaname "$2"
711                                 logdebug 3 "Added: $areatype $areaname"
712                                 eval "local isadded=\"\${dzone_${areatype}_${areaname}-0}\""
713                                 if [ "${isadded}" != "1" ] ; then
714                                         eval dzone_${areatype}_${areaname}=1
715                                         append dzones_${areatype} "${areaname}" " "
716                                 fi
717                                 eval "dzone_match_use_${zone_name}=${areatype}_${areaname}"
718                                 logdebug 3 "Finished uses"
719                                 ;;
720                         match_LENGTH) ;;
721                         match|match_ITEM*)
722                                 handle_dialzone_match "$2"
723                                 ;;
724                         international_LENGTH) ;;
725                         international|international_ITEM*)
726                                 eval "local isadded=\"$dzone_${zone_name}\""
727                                 if [ "${isadded}" != "1" ] ; then
728                                         eval "dzone_${zone_name}=1"
729                                         append dzones_match ${zone_name} " "
730                                 fi
731                                 append dzone_${zone_name}_international $2 ","
732                                 ;;
733                         countrycode|localzone|addprefix|localprefix)
734                                 eval "dzone_${zone_name}_${1}=\"$2\""
735                                 eval "y=\${dzone_${zone_name}_${1}}"
736                                 ;;
737                         *)
738                                 logerror "Invalid Dialzone option: $1 in zone '${zone_name}'" ;;
739                 esac
740         }
741 }
742
743 check_add_dialplangoto() {
744         logdebug 1 "Add Goto to $1 / $2"
745         if [ ! -z "${dial_goto_dialplan}" -a ! -z "${dial_goto_extension}" ] ; then
746                 local ext="exten => ${dial_goto_extension},"
747                 check_add_context ${dial_goto_dialplan}
748                 append_dialplan_context ${dial_goto_dialplan}  "${ext}1,Goto(${dial_goto_target})"
749         fi
750         for i in dialplan extension room ; do
751                 eval "unset dial_goto_$i"
752         done
753 }
754
755 handle_dialplangoto(){
756         check_add dialplangoto
757         option_cb() {
758                 case $1 in
759                         dialplan|extension|target)
760                                 eval "dial_goto_$1=\"$2\"" ;;
761                         *) logerror "Invalid dialplangoto option: $1"
762                 esac
763         }
764 }
765
766 # Options for incoming calls.
767
768 valid_incoming_list="allowtransfer timeout answerfirst mailbox lastcall lastcalltype missed missedtype"
769
770 valid_incoming_option() {
771         is_in_list $1 ${valid_incoming_list}
772         return $?
773 }
774
775 handle_incominggeneral() {
776         option_cb() {
777                 if valid_incoming_option $1 ; then
778                         logdebug 3 "Add Incoming General option $1=$2"
779                         eval "incoming_${1}=\"$2\""
780                 else
781                         logerror "Invalid incominggeneral option $1"
782                 fi
783         }
784 }
785
786 add_incoming_context() {
787         local context=$1
788         eval "local added=\${dialplan_incoming_${context}_added}"
789         if [ "${added}" != "1" ] ; then
790                 append dialplan_extensions_incoming "${context}" " "
791                 eval "dialplan_incoming_${context}_added=1"
792         fi
793
794 }
795
796 # Add to incoming ringing
797 add_incoming() {
798         local rhs="$3"
799         
800         while [ ! -z "$rhs" ] ; do
801                 cur=${rhs%%,*}
802                 nvar=${rhs#*,}
803                 add_incoming_context ${cur}
804                 append dialplan_incoming_${cur} "$1/$2" "&" 
805                 [ "$nvar" == "$rhs" ] && break
806                 rhs=${nvar}
807         done
808 }
809
810 to_upper() {
811         eval "$1=`echo \"$2\"|tr [a-z] [A-Z]`"
812 }
813 to_lower() {
814         eval "$1=`echo \"$2\"|tr [A-Z] [a-z]`"
815 }
816
817 split_targettype() { # TYPE target inputEntry
818         local l_targettype="${3%[-_/]*}"
819         if [ "${l_targettype}" == "$3" ] ; then
820                 return 1
821         fi
822         local l_targetname="${3#*[-_/]}"
823         to_upper "$1" "${l_targettype}"
824         eval "$2=\"${l_targetname}\""
825         return 0
826 }
827
828
829 handle_incoming() {
830         incoming_context=$1
831         incoming_list=
832         add_incoming_context "${incoming_context}"
833
834         option_cb() {
835                 logdebug 1 "Incoming ${incoming_context} $1=$2"
836                 case $1 in
837                         lastcall|lastcalltype|missed|missedtype) eval "incoming_${incoming_context}_${1}=\"$2\"" ;;
838 #                       lastcall|lastcallexten|lastmissed|lastmissedexten)
839 #                               enable_lastcall
840 #                               eval "incoming_${incoming_context}_${1}=\"$2\""
841 #                               ;;
842                         mailbox|allowtransfer|answerfirst|beforeanswer|timeout|menucontext|match|matchcaller|aftertimeout|aftertimeouttype)
843                                 eval "incoming_${incoming_context}_${1}=\"$2\""
844                                 ;;
845                         target|target_ITEM*)
846                                 local targettype=
847                                 local targetname=
848                                 if split_targettype targettype targetname "${2}" ; then
849                                         append dialplan_incoming_${incoming_context} "${targettype}/${targetname}" "&"
850                                 else
851                                         logerror "No target type specified for target=$2 in ${incoming_context}"
852                                 fi
853                                 ;;
854                         target_COUNT|member_COUNT) ;;
855                         *) logerror "Invalid option $1 in incoming" ;;
856                 esac
857         }
858 }
859
860 # vim: ts=2 sw=2 noet foldmethod=indent