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