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