Tidy up some bugs with quoting.
[project/luci.git] / contrib / package / asterisk-xip / files / uci / sipiaxconf
1 #!/bin/sh
2 # Sip / IAX extensions
3
4 add_incoming_context() {
5         local context=$1
6         eval "local added=\${dialplan_incoming_${context}_added}"
7         if [ "${added}" != "1" ] ; then
8                 append dialplan_extensions_incoming "${context}" " "
9                 eval "dialplan_incoming_${context}_added=1"
10         fi
11
12 }
13
14 # Add to incoming ringing
15 add_incoming() {
16         local rhs="$3"
17         
18         while [ ! -z "$rhs" ] ; do
19                 cur=${rhs%%,*}
20                 nvar=${rhs#*,}
21                 add_incoming_context ${cur}
22                 append dialplan_incoming_${cur} "$1/$2" "&" 
23                 [ "$nvar" == "$rhs" ] && break
24                 rhs=${nvar}
25         done
26 }
27
28 # Add to internal extensions
29 add_extension() {
30         logdebug 1 "Adding $1/$2 extension to $3"
31         eval "local ext=\"\${dialplan_ext_$3}\""
32         [ -z "${ext}" ] && append dialplan_exts "$3" " "
33         local lower=`echo $1|tr [A-Z] [a-z]`
34         eval "local ext=\"\${${lower}_last_extension}\""
35         [ -z "${ext}" ] && eval "${lower}_last_extension=\"$3\""
36         append dialplan_ext_$3 $1/${2} "&"
37 }
38
39 check_append_local() {
40         local extension="${1}"
41         logdebug 3 "added local context for ${1}"
42         eval "local isadded=\"\${dialplan_add_local_${extension}-0}\""
43         if [ "$isadded" != "1" ] ; then
44                 logdebug 3 "Not added before - adding"
45                 eval "dialplan_add_local_${extension}=1"
46                 append dialplan_locals "$extension"
47                 eval  "dialplan_local_${1}_context=\"${2}\""
48                 eval  "dialplan_local_${1}_selfmailbox=\"${3}\""
49                 eval  "dialplan_local_${1}_mailbox=\"${4}\""
50                 return 0
51         else
52                 return 1
53         fi
54 }
55 append_dialplan_locals(){
56         for i in ${dialplan_locals} ; do
57                 local extension=$i
58                 for x in context selfmailbox mailbox ; do
59                         eval "x_${x}=\${dialplan_local_${i}_${x}}"
60                 done
61                 local newcontext=local_${extension}
62
63                 if check_add_context ${newcontext} ; then
64                         # add_dialplan_voice ${newcontext} ${x_last_extension} ${x_last_mailbox}
65                         # Make sure as much is matched as possible
66                         #add_dialplan_goto ${newcontext} _[0-9#*+]. ${x_last_context}
67                         # add_dialplan_include ${newcontext}  ${x_last_context}
68
69                         append_dialplan_context ${newcontext} "exten => ${match_all},1,Set(CALLERID(num)=${extension})"
70                         if [ ! -z "${x_mailbox}" ] ; then
71                                 [ "${x_selfmailbox}" = "yes" ] && append_dialplan_context ${newcontext} "exten => ${extension},2,VoiceMailMain(${x_mailbox})"
72                                 [ ! -z "${dialplan_voiceboxext}" ]  && append_dialplan_context ${newcontext} "exten => ${dialplan_voiceboxext},2,VoiceMailMain(${x_mailbox})"
73                         fi
74                         append_dialplan_context ${newcontext} "exten => ${match_all},2,Goto(${x_context},\${EXTEN},1)"
75                 fi
76         done
77 }
78
79 # Sip
80
81 check_add_sipitems() {
82         if [ "${sip_doregister}" == "1" ] ; then
83                 local line="register => ${sip_last_username}@${sip_last_fromdomain}:${sip_last_secret}:${sip_last_username}@${sip_sectionname}"
84                 case ${sip_last_registerextension}  in
85                         -) line="$line/${sip_last_username}" ;;
86                         .*) line="$line/${sip_last_registerextension}" ;;
87                 esac
88                 append sip_register "$line" "$N"
89                 sip_doregister=0
90         fi
91         do_check_add_items sip
92 }
93 check_add_iaxitems() {
94         do_check_add_items iax
95 }
96
97 do_check_add_items(){
98
99         for i in type last_host last_context selfmailbox last_extension last_mailbox ; do
100                 eval "x_${i}=\"\${${1}_${i}-}\""
101         done
102
103         if [ ! -z "${x_last_context}" ] ; then
104                 if [ ! -z "${x_last_extension}" ] ; then
105                         [ "${x_last_context}" = "-" ] && eval "x_last_context=\"\${${1}_opt_context}\""
106                         check_append_local "${x_last_extension}" "${x_last_context}" "${x_selfmailbox}" "${x_last_mailbox}"
107                         x_last_context=local_${x_last_extension}
108                 fi
109                 if [ "${x_last_context}" != "-" ] ; then
110                         append ${1}_sections "context=${x_last_context}" "$N"
111                 fi
112                 if [ "${x_type}" != "user"  -a  -z "${x_last_host}" ] ; then
113                         append ${1}_sections "host=dynamic" "$N"
114                 fi
115         fi
116
117         for i in last_username last_fromdomain last_secret last_username \
118                 sectionname last_fromuser last_context last_extension last_mailbox last_type last_host ; do
119                 eval unset $1_$i
120         done
121
122         eval ${1}_selfmailbox=no
123         eval ${1}_last_registerextension=-
124 }
125
126 reload_sip() {
127         astcmd "sip reload"
128         return 1 # reboot
129 }
130 unload_sip() astcmd "unload chan_sip.so"
131
132 rtp_option_list="rtpstart rtpend rtpdtmftimeout rtcpinterval rtpchecksums"
133 # Validate RTP options
134 valid_rtp_option() {
135         is_in_list $1 ${rtp_option_list}
136 }
137
138 # Validate sip options, depending on context.
139 valid_sipiax_option() {
140         local use_glob=1
141         local use_glob_iax=1
142         local use_glob_sip=1
143         local use_user=1
144         local use_peer=1
145         local use_user_sip=1
146         local use_user_iax=1
147         local use_peer_sip=1
148         local use_peer_iax=1
149         case "$1" in
150                 globalsip)
151                         use_glob_sip=0
152                         use_glob=0 ;;
153                 usersip)
154                         use_glob_sip=0
155                         use_glob=0
156                         use_user=0 ;;
157                 peersip|friendsip)
158                         use_glob_sip=0
159                         use_glob=0
160                         use_user=0
161                         use_peer=0
162                         use_user_sip=0
163                         use_peer_sip=0 ;;
164                 globaliax)
165                         use_glob_iax=0
166                         use_glob=0 ;;
167                 useriax)
168                         use_glob_iax=0
169                         use_glob=0
170                         use_user=0 ;;
171                 peeriax|friendiax)
172                         use_glob_iax=0
173                         use_glob=0
174                         use_user=0
175                         use_peer=0
176                         use_user_iax=0
177                         use_peer_iax=0 ;;
178         esac
179
180         case "$2" in
181                 writeprotect|static) return ${use_glob_iax} ;;
182 # Integer
183                 port|\
184                 maxexpirey|\
185                 rtptimeout|\
186                 rtpholdtimeout|\
187                 defaultexpirey|\
188                 registertimeout|\
189                 registerattempts|\
190                 call-limit) return ${use_glob_sip} ;;
191 # ip addr
192                 bindaddr|\
193                 externip)   return ${use_glob_sip} ;;
194 # net/mask
195                 localnet)   return ${use_glob_sip} ;;
196                 permit|\
197                 deny)  return ${use_user_sip} ;;
198 # Domain name
199                 realm|\
200                 domain)                                 return ${use_glob_sip} ;;
201 # valid context
202                 context)    return ${use_glob} ;;
203 # Mime type
204                 notifymimetype) return ${use_glob_sip} ;;
205 # Yes/No
206                 canreinvite)            return ${use_glob} ;;
207                 nat|allowoverlap|allowsubscribe|allowtransfer|\
208                 videosupport)   return ${use_glob_sip} ;;
209                 pedantic|\
210                 trustrpid|\
211                 promiscredir|\
212                 useclientcode)  return ${use_user_sip} ;;
213 # Enums
214                 dtmfmode)                       return ${use_glob_sip} ;;
215                 type)                                   return ${use_user} ;;
216                 insecure|callingpres|\
217                 progressinband)  return ${use_user_sip} ;;
218 # List 
219                 allow|\
220                 disallow)  return ${use_glob_sip} ;;
221 # Register string
222                 register) return ${use_glob_sip} ;;
223 # String
224                 username|secret|md5secret|host|\
225                 mailbox) return ${use_user} ;;
226                 auth) return ${use_user_iax} ;;
227                 callgroup|pickupgroup|language|accountcode|\
228                 setvar|callerid|amaflags|subscribecontext|\
229                 maxcallbitrate|rfc2833compensate|\
230                 mailbox) return ${use_user_sip};;
231                 template|fromdomain|regexten|fromuser|\
232                 qualify|defaultip|sendrpid|\
233                 outboundproxy) return ${use_peer_sip};;
234                 extension) return 0;;
235                 *) return 1;;
236         esac
237 }
238
239 ast_add_conf sip
240 init_sipconf() {
241         ast_add_reload sip
242         ast_enable_type sipgeneral
243         ast_enable_type sip
244         ast_enable_type target
245
246         sip_opt_port=5060
247         sip_opt_bindaddr=0.0.0.0
248         sip_opt_context=default
249         sip_opt_maxexpirey=3600
250         sip_opt_defaultexpirey=3600
251         sip_opt_notifymimetype=text/plain
252         sip_opt_rtptimeout=60
253         sip_opt_rtpholdtimeout=300
254         config_get WAN_IP wan ipaddr
255         # TODO check why the above does not work all the time
256         if [ -z "${WAN_IP}" ] ; then
257                 config_get WAN_IF wan ifname
258                 WAN_IP=$(ifconfig ${WAN_IF} | grep "inet addr:" | sed 's/^.*inet addr:\([^ ]*\) .*$/\1/')
259         fi
260
261         sip_opt_externip=${WAN_IP}
262
263         sip_opt_realm=asterisk
264         config_get LAN_MASK lan netmask
265         config_get LAN_IP lan ipaddr
266         LAN_NET=$(/bin/ipcalc.sh $LAN_IP $LAN_MASK | grep NETWORK | cut -d= -f2)
267         sip_opt_localnet=$LAN_NET/$LAN_MASK
268
269         # default to ulaw only
270         sip_opt_allow=
271         sip_opt_registertimeout=20
272         sip_opt_registerattempts=10
273         sip_opt_canreinvite=no
274
275         sip_sections=
276 }
277
278 sip_list="port bindaddr context maxexpirey defaultexpirey notifymimetype \
279 rtptimeout rtpholdtimeout realm domain localnet externip"
280
281 create_sipconf() {
282
283         append_dialplan_locals
284
285         file=${DEST_DIR}/sip.conf
286         get_checksum sip_conf $file
287         local isempty=1
288         if [ -z "${sip_sections}" ] ; then
289                 rm -f $file
290                 isempty=2
291         else
292                 [ -z "${sip_opt_domain}" ]  && sip_opt_domain=${sip_opt_realm}
293
294                 echo "${asteriskuci_gen}[general]" > $file
295                 for i in ${sip_list} ; do
296                         eval value=\$sip_opt_$i
297                         [ ! -z "$value" ] && ( echo "$i=$value" >> $file )
298                 done
299                 echo "disallow=all" >> $file
300                 local rhs="${sip_opt_allow}"
301                 if [ -z "$rhs" ] ; then
302                         rhs=ulaw
303                 fi
304                 while [ ! -z "$rhs" ] ; do
305                         cur=${rhs%%,*}
306                         nvar=${rhs#*,}
307                         enable_format ${cur}
308                         echo "allow=${cur}" >> $file
309                         [ "$nvar" == "$rhs" ] && break
310                         rhs=${nvar}
311                 done
312
313                 echo "${N}${sip_register}${N}${N}${sip_sections}" >> $file
314                 unset sip_register
315                 unset sip_sections
316         fi
317         check_checksum "$sip_conf" "$file" || ast_sip_restart=$isempty
318 }
319
320
321 handle_sipgeneral() {
322         option_cb(){
323                 if valid_sipiax_option globalsip $1 $2 ; then
324                         case "$1" in
325                                 host)
326                                         if  [ -z "$2" ] ; then
327                                                 sip_opt_host=dynamic
328                                         else
329                                                 sip_opt_host="$2"
330                                         fi ;;
331                                 allow_LENGTH) ;;
332                                 allow|allow_ITEM*)
333                                         append sip_opt_allow "$2" "," ;;
334                                 *) eval "sip_opt_$1=\"\$2\"" ;;
335                         esac
336                 elif valid_rtp_option $1 $2 ; then
337                         eval "rtp_opt_$1=\"\$2\""
338                 else
339                         logerror "Invalid SIP global option: $1"
340                 fi
341         }
342 }
343
344 handle_sip() {
345         check_add sipitems
346         append sip_sections [$1] "$N$N"
347         enable_module chan_sip
348         sip_sectionname=${1#sip_}
349         sip_type=peer
350         sip_doregister=0
351         sip_last_context=-
352         sip_last_doregister=-
353         sip_selfmailbox=no
354         option_cb() {
355                 logdebug 3 "SIP/${sip_sectionname}: '$1' '$2'"
356                 case $1 in
357                         type) sip_type=$2
358                                 append sip_sections "$1=$2" "$N"
359                                 ;;
360                         register)
361                                 if [ "$2" == "yes" ]; then
362                                         sip_doregister=1
363                                 fi ;;
364                         registerextension) eval sip_last_$1="$2";;
365                         allow|allow_ITEM*) split_append sip_sections allow= "$2" "${N}" enable_format ;;
366                         extension|extension_ITEM*)    add_extension SIP ${sip_sectionname} "$2" ;;
367                         context)      sip_last_context="$2" ;;
368                         selfmailbox)  sip_selfmailbox="$2" ;;
369                         incoming|incoming_ITEM*)
370                                 add_incoming SIP ${sip_sectionname} "$2" ;;
371                         timeout|prefix|internationalprefix|alwaysinternational|countrycode)
372                                 eval "target_$1_SIP_${sectionname}=\"$2\""
373                         ;;
374                         allow_LENGTH|incoming_LENGTH|extension_LENGTH) ;;
375                         *)
376                                 eval sip_last_$1="$2"
377                                 if valid_sipiax_option ${sip_type}sip $1 $2 ; then
378                                         append sip_sections "$1=$2" "$N"
379                                 else
380                                         logerror "Invalid SIP option for ${sip_type}: $1"
381                                 fi
382                 esac
383         }
384 }
385
386 # rtp.conf
387
388 ast_add_conf rtp
389 init_rtpconf() {
390         ast_add_reload rtp
391         rtp_opt_rtpstart=5000
392         rtp_opt_rtpend=31000
393         rtp_opt_rtpchecksums=
394         rtp_opt_rtpdtmftimeout=
395         rtp_opt_rtcpinterval=5000
396 }
397
398 create_rtpconf() {
399         file=${DEST_DIR}/rtp.conf
400         get_checksum rtp_conf $file
401         local isempty=1
402         if module_enabled chan_sip ; then
403                 echo "${asteriskuci_gen}[general]" > $file
404                 for i in $rtp_option_list ; do
405                         eval "local val=\"\$rtp_opt_$i\""
406                         if [ ! -z "$val" ] ; then
407                                 lhs=$i
408                                 case "$i" in
409                                         rtpdtmftimeout) lhs=dtmftimeout
410                                 esac
411                                 echo "$lhs=$val" >> $file
412                         fi
413                 done
414         else
415                 rm -f $file
416                 isempty=2
417         fi
418
419         check_checksum "$rtp_conf" "$file" || ast_rtp_restart=$isempty
420 }
421 reload_rtp() astcmd "rtp reload"
422 unload_rtp() astcmd "unload rtp"
423
424
425 # Iax
426
427 ast_add_conf iax
428
429 init_iaxconf() {
430         ast_add_reload iax
431         ast_enable_type iaxgeneral
432         ast_enable_type iax
433
434         return 0
435 }
436
437 create_iaxconf() {
438         local file=$DEST_DIR/iax.conf
439         get_checksum iax_conf $file
440         local isempty=1
441         if [ -z "${iax_sections}" ] ; then
442                 rm -f $file
443                 isempty=2
444         else
445                 echo "${asteriskuci_gen}${iax_general}$N$N${iax_sections}" > $file
446         fi
447         check_checksum "$iax_conf" "$file"  || ast_iax_restart=${isempty}
448 }
449
450 handle_iaxgeneral() {
451         iax_general="[general]"
452         option_cb() {
453                 case $1 in
454                         allow_LENGTH) ;;
455                         allow|allow_ITEM*) split_append iax_general allow= "$2" "${N}" enable_format ;;
456                         *)
457                                 if valid_sipiax_option globaliax $1 $2 ; then
458                                         eval "iax_opt_$1=\"$2\""
459                                         append iax_general "$1=$2" "$N"
460                                 else
461                                         logerror "Invalid IAX global option: $1"
462                                 fi ;;
463                 esac
464         }
465 }
466
467 handle_iax() {
468         check_add iaxitems
469         iax_type=peer
470         iax_sectionname="${1#iax_}"
471         append iax_sections "[${iax_sectionname}]" "$N$N"
472         iax_last_context=-
473         iax_selfmailbox=no
474         enable_module chan_iax2
475         option_cb() {
476                 case $1 in
477                         type)
478                                 iax_type=$2
479                                 append iax_sections "type=$2" "$N" ;;
480                         allow_LENGTH|incoming_LENGTH) ;;
481                         allow|allow_ITEM*)
482                                 split_append iax_sections allow= "$2" "${N}" enable_format ;;
483                         extension_LENGTH) ;;
484                         extension|extension_ITEM*)    add_extension IAX ${iax_sectionname} "$2" ;;
485                         context)
486                                 eval iax_last_context="$2" ;;
487                         selfmailbox)
488                                 eval iax_selfmailbox="$2" ;;
489                         incoming|incoming_ITEM*)
490                                 add_incoming IAX ${iax_sectionname} "$3" ;;
491                         timeout|prefix|internationalprefix|alwaysinternational|countrycode)
492                                 eval "target_$1_IAX_${sectionname}=\"$2\"" ;;
493                         *)
494                                 eval iax_last_$1="$2"
495                                 if valid_sipiax_option ${iax_type}iax $1 $2 ; then
496                                         append iax_sections "$1=$2" "$N"
497                                 else
498                                         logerror "Invalid IAX option for ${iax_type}: $1"
499                                 fi
500                 esac
501         }
502 }
503
504 reload_iax() {
505         astcmd "iax2 reload"
506         return 1
507 }
508 unload_iax() astcmd "unload chan_iax2.so"
509
510 handle_target() {
511         # Target name
512         targettype=${1%[-_]*}
513         if [ ${targettype} == $1 ] ; then
514                 logerror "No target type specified (SIP-$1 IAX-$1)"
515                 return 1
516         fi
517         targetname=${1#*[-_]}
518
519         case $targettype in
520                 [Ss][Ii][Pp])  handle_dialtarget SIP $targetname ;;
521                 [Ii][Aa][Xx])  handle_dialtarget IAX $targetname ;;
522                 *) logerror "Invalid target type specified: $targettype"
523         esac
524 }
525
526 # Set up options sip/iax targets for outgoing sip/iax
527 handle_dialtarget() {
528         # Dialzone target option
529         areatype=$1
530         areaname=$2
531         logdebug 1 "Dialzone Target for ${areatype}/${areaname}"
532         option_cb(){
533                 case $1 in
534                         timeout|prefix|internationalprefix|alwaysinternational|countrycode)
535                                 eval target_$1_${areatype}_${areaname}=$2 
536                         ;;
537                         *) 
538                                 logerror "Invalid target for $areatype/$areaname: ${1}"
539                 esac
540         }
541 }
542
543 # vim: ts=2 sw=2 noet foldmethod=indent