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