luci-app-adblock: sync with adblock 3.5.0
[project/luci.git] / applications / luci-app-pbx / root / etc / init.d / pbx-asterisk
1 #!/bin/sh /etc/rc.common
2 #
3 # Copyright 2011 Iordan Iordanov <iiordanov (AT) gmail.com>
4 #
5 #    This file is part of luci-pbx.
6 #
7 #    luci-pbx is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU General Public License as published by
9 #    the Free Software Foundation, either version 3 of the License, or
10 #    (at your option) any later version.
11 #
12 #    luci-pbx is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU General Public License for more details.
16 #
17 #    You should have received a copy of the GNU General Public License
18 #    along with luci-pbx.  If not, see <http://www.gnu.org/licenses/>.
19
20 . /lib/functions.sh
21
22 START=60
23
24 # Some global variables
25 MODULENAME=pbx
26 USERAGENT="PBX"
27 HANGUPCNTXT=hangup-call-context
28 GTALKUNVL=unavailable
29
30 ASTUSER=nobody
31 ASTGROUP=nogroup
32 ASTDIRSRECURSIVE="/var/run/asterisk /var/log/asterisk /var/spool/asterisk"
33 ASTDIRS="/usr/lib/asterisk"
34 ASTSOUNDSDIR="/usr/lib/asterisk/sounds"
35
36 TEMPLATEDIR=/etc/${MODULENAME}-asterisk
37 PBXSOUNDSDIR=$TEMPLATEDIR/sounds
38 VMTEMPLATEDIR=/etc/${MODULENAME}-voicemail
39 VMSOUNDSDIR=$VMTEMPLATEDIR/sounds
40 ASTERISKDIR=/etc/asterisk
41 WORKDIR=/tmp/$MODULENAME.$$
42 MD5SUMSFILE=/tmp/$MODULENAME-sums.$$
43
44 TMPL_ASTERISK=$TEMPLATEDIR/asterisk.conf.TEMPLATE
45 TMPL_GTALK=$TEMPLATEDIR/gtalk.conf.TEMPLATE
46 TMPL_INDICATIONS=$TEMPLATEDIR/indications.conf.TEMPLATE
47 TMPL_LOGGER=$TEMPLATEDIR/logger.conf.TEMPLATE
48 TMPL_MANAGER=$TEMPLATEDIR/manager.conf.TEMPLATE
49 TMPL_MODULES=$TEMPLATEDIR/modules.conf.TEMPLATE
50 TMPL_RTP=$TEMPLATEDIR/rtp.conf.TEMPLATE
51
52 TMPL_EXTCTHRUCHECKHDR=$TEMPLATEDIR/extensions_disa-check_header.conf.TEMPLATE
53 TMPL_EXTCTHRUCHECK=$TEMPLATEDIR/extensions_disa-check.conf.TEMPLATE
54 TMPL_EXTCTHRUCHECKFTR=$TEMPLATEDIR/extensions_disa-check_footer.conf.TEMPLATE
55 TMPL_EXTCTHRUHDR=$TEMPLATEDIR/extensions_disa_header.conf.TEMPLATE
56 TMPL_EXTCTHRU=$TEMPLATEDIR/extensions_disa.conf.TEMPLATE
57 TMPL_EXTCTHRUNOPIN=$TEMPLATEDIR/extensions_disa-nopin.conf.TEMPLATE
58
59 TMPL_EXTCBACKCHECKHDR=$TEMPLATEDIR/extensions_callback-check_header.conf.TEMPLATE
60 TMPL_EXTCBACKCHECK=$TEMPLATEDIR/extensions_callback-check.conf.TEMPLATE
61 TMPL_EXTCBACKCHECKFTR=$TEMPLATEDIR/extensions_callback-check_footer.conf.TEMPLATE
62 TMPL_EXTCBACKHDR=$TEMPLATEDIR/extensions_callback_header.conf.TEMPLATE
63 TMPL_EXTCBACKSIP=$TEMPLATEDIR/extensions_callback_sip.conf.TEMPLATE
64 TMPL_EXTCBACKGTALK=$TEMPLATEDIR/extensions_callback_gtalk.conf.TEMPLATE
65
66 TMPL_EXTENSIONS=$TEMPLATEDIR/extensions.conf.TEMPLATE
67
68 TMPL_EXTVMDISABLED=$TEMPLATEDIR/extensions_voicemail_disabled.conf.TEMPLATE
69 TMPL_EXTVMENABLED=$TEMPLATEDIR/extensions_voicemail_enabled.conf.TEMPLATE
70
71 TMPL_EXTBLKLIST=$TEMPLATEDIR/extensions_blacklist.conf.TEMPLATE
72 TMPL_EXTBLKLISTFTR=$TEMPLATEDIR/extensions_blacklist_footer.conf.TEMPLATE
73 TMPL_EXTBLKLISTHDR=$TEMPLATEDIR/extensions_blacklist_header.conf.TEMPLATE
74
75 TMPL_EXTDEFAULT=$TEMPLATEDIR/extensions_default.conf.TEMPLATE
76 TMPL_EXTDEFAULTUSER=$TEMPLATEDIR/extensions_default_user.conf.TEMPLATE
77
78 TMPL_EXTINCNTXTSIP=$TEMPLATEDIR/extensions_incoming_context_sip.conf.TEMPLATE
79 TMPL_EXTINCNTXTGTALKHDR=$TEMPLATEDIR/extensions_incoming_context_gtalk_header.conf.TEMPLATE
80 TMPL_EXTINCNTXTGTALK=$TEMPLATEDIR/extensions_incoming_context_gtalk.conf.TEMPLATE
81
82 TMPL_EXTUSERCNTXT=$TEMPLATEDIR/extensions_user_context.conf.TEMPLATE
83 TMPL_EXTUSERCNTXTFTR=$TEMPLATEDIR/extensions_user_context_footer.conf.TEMPLATE
84 TMPL_EXTUSERCNTXTHDR=$TEMPLATEDIR/extensions_user_context_header.conf.TEMPLATE
85
86 TMPL_EXTOUTHDR=$TEMPLATEDIR/extensions_default_outgoing_header.conf.TEMPLATE
87 TMPL_EXTOUTGTALK=$TEMPLATEDIR/extensions_outgoing_gtalk.conf.TEMPLATE
88 TMPL_EXTOUTLOCAL=$TEMPLATEDIR/extensions_outgoing_dial_local_user.conf.TEMPLATE
89 TMPL_EXTOUTSIP=$TEMPLATEDIR/extensions_outgoing_sip.conf.TEMPLATE
90
91 TMPL_JABBER=$TEMPLATEDIR/jabber.conf.TEMPLATE
92 TMPL_JABBERUSER=$TEMPLATEDIR/jabber_users.conf.TEMPLATE
93 TMPL_SIP=$TEMPLATEDIR/sip.conf.TEMPLATE
94 TMPL_SIPPEER=$TEMPLATEDIR/sip_peer.TEMPLATE
95 TMPL_SIPREG=$TEMPLATEDIR/sip_registration.TEMPLATE
96 TMPL_SIPUSR=$TEMPLATEDIR/sip_user.TEMPLATE
97
98 TMPL_MSMTPDEFAULT=$VMTEMPLATEDIR/pbx-msmtprc-defaults.TEMPLATE
99 TMPL_MSMTPACCOUNT=$VMTEMPLATEDIR/pbx-msmtprc-account.TEMPLATE
100 TMPL_MSMTPAUTH=$VMTEMPLATEDIR/pbx-msmtprc-account-auth.TEMPLATE
101 TMPL_MSMTPACCTDFLT=$VMTEMPLATEDIR/pbx-msmtprc-account-default.TEMPLATE
102
103
104 INCLUDED_FILES="$WORKDIR/extensions_blacklist.conf $WORKDIR/extensions_callthrough.conf\
105                 $WORKDIR/extensions_incoming.conf  $WORKDIR/extensions_incoming_gtalk.conf\
106                 $WORKDIR/extensions_user.conf      $WORKDIR/jabber_users.conf\
107                 $WORKDIR/sip_peers.conf            $WORKDIR/sip_registrations.conf\
108                 $WORKDIR/sip_users.conf            $WORKDIR/extensions_voicemail.conf\
109                 $WORKDIR/extensions_default.conf"
110
111
112 # In this string, we concatenate all local users enabled to receive calls
113 # readily formatted for the Dial command.
114 localusers_to_ring=""
115
116 # In this string, we keep a list of all users that are enabled for outgoing
117 # calls. It is used at the end to create the user contexts.
118 localusers_can_dial=""
119
120 # In this string, we put together a space-separated list of provider names
121 # (alphanumeric, with all non-alpha characters replaced with underscores),
122 # which will be used to dial out by default (whose outgoing contexts will
123 # be included in users' contexts by default.
124 outbound_providers=""
125 sip_outbound_providers=""
126 gtalk_outbound_providers=""
127
128 # Function which escapes non-alpha-numeric characters in a string
129 escape_non_alpha() {
130     echo $@ | sed 's/\([^a-zA-Z0-9]\)/\\\1/g'
131 }
132
133 # Function which replaces non-alpha-numeric characters with an underscore
134 sub_underscore_for_non_alpha() {
135     echo $@ | sed 's/[^a-zA-Z0-9]/_/g'
136 }
137
138 # Copies the template files which we don't edit.
139 copy_unedited_templates_over()
140 {
141     cp $TMPL_ASTERISK      $WORKDIR/asterisk.conf
142     cp $TMPL_GTALK         $WORKDIR/gtalk.conf
143     cp $TMPL_INDICATIONS   $WORKDIR/indications.conf
144     cp $TMPL_LOGGER        $WORKDIR/logger.conf
145     cp $TMPL_MANAGER       $WORKDIR/manager.conf
146     cp $TMPL_MODULES       $WORKDIR/modules.conf
147     # If this file isn't present at this stage, voicemail is disabled.
148     [ ! -f $WORKDIR/extensions_voicemail.conf ] && \
149       cp $TMPL_EXTVMDISABLED $WORKDIR/extensions_voicemail.conf
150 }
151
152 # Touches all the included files, to prevent asterisk from refusing to
153 # start if a config item is missing and an included config file isn't created.
154 create_included_files()
155 {
156     touch $INCLUDED_FILES
157 }
158
159 # Puts together all the extensions.conf related configuration.
160 pbx_create_extensions_config()
161 {
162     local ringtime
163     config_get ringtime advanced ringtime
164
165     sed "s/|RINGTIME|/$ringtime/" $TMPL_EXTENSIONS > $WORKDIR/extensions.conf
166     mv  $WORKDIR/inext.TMP                           $WORKDIR/extensions_incoming.conf
167     cp  $TMPL_EXTINCNTXTGTALKHDR                     $WORKDIR/extensions_incoming_gtalk.conf
168     cat $WORKDIR/outextgtalk.TMP                  >> $WORKDIR/extensions_incoming_gtalk.conf 2>/dev/null
169     rm -f $WORKDIR/outextgtalk.TMP
170     mv  $WORKDIR/blacklist.TMP                       $WORKDIR/extensions_blacklist.conf
171     mv  $WORKDIR/userext.TMP                         $WORKDIR/extensions_user.conf
172
173     cp  $TMPL_EXTCTHRUHDR                            $WORKDIR/extensions_callthrough.conf
174     cat $WORKDIR/callthrough.TMP                  >> $WORKDIR/extensions_callthrough.conf 2>/dev/null
175     rm -f $WORKDIR/callthrough.TMP
176     cat $TMPL_EXTCTHRUCHECKHDR                    >> $WORKDIR/extensions_callthrough.conf 2>/dev/null
177     cat $WORKDIR/callthroughcheck.TMP             >> $WORKDIR/extensions_callthrough.conf 2>/dev/null
178     rm -f $WORKDIR/callthroughcheck.TMP
179     cat $TMPL_EXTCTHRUCHECKFTR                    >> $WORKDIR/extensions_callthrough.conf 2>/dev/null
180
181     cp  $TMPL_EXTCBACKHDR                            $WORKDIR/extensions_callback.conf
182     cat $WORKDIR/callback.TMP                     >> $WORKDIR/extensions_callback.conf 2>/dev/null
183     rm -f $WORKDIR/callback.TMP
184     cat $TMPL_EXTCBACKCHECKHDR                    >> $WORKDIR/extensions_callback.conf 2>/dev/null
185     cat $WORKDIR/callbackcheck.TMP                >> $WORKDIR/extensions_callback.conf 2>/dev/null
186     rm -f $WORKDIR/callbackcheck.TMP
187     cat $TMPL_EXTCBACKCHECKFTR                    >> $WORKDIR/extensions_callback.conf 2>/dev/null
188
189     rm -f $WORKDIR/outext-*.TMP
190     rm -f $WORKDIR/localext.TMP
191     sed "s/|LOCALUSERS|/$localusers_to_ring/g" $TMPL_EXTDEFAULT \
192                                                    > $WORKDIR/extensions_default.conf
193     cat $WORKDIR/inextuser.TMP                    >> $WORKDIR/extensions_default.conf
194     rm -f $WORKDIR/inextuser.TMP
195 }
196
197 # Puts together all the sip.conf related configuration.
198 pbx_create_sip_config()
199 {
200     mv $WORKDIR/sip_regs.TMP    $WORKDIR/sip_registrations.conf
201     mv $WORKDIR/sip_peers.TMP   $WORKDIR/sip_peers.conf
202     mv $WORKDIR/sip_users.TMP   $WORKDIR/sip_users.conf
203 }
204
205 # Creates the jabber.conf related config
206 pbx_create_jabber_config()
207 {
208     cp  $TMPL_JABBER        $WORKDIR/jabber.conf
209     mv  $WORKDIR/jabber.TMP $WORKDIR/jabber_users.conf
210 }
211
212 # Gets rid of any config files from $ASTERISKDIR not found in $WORKDIR.
213 clean_up_asterisk_config_dir()
214 {
215     for f in $ASTERISKDIR/* ; do
216         basef="`basename $f`"
217         if [ ! -e "$WORKDIR/$basef" ] ; then
218             rm -rf "$f"
219         fi
220     done
221 }
222
223 # Compares md5sums of the config files in $WORKDIR to those
224 # in $ASTERISKDIR, and copies only changed files over to reduce
225 # wear on flash in embedded devices.
226 compare_configs_and_copy_changed()
227 {
228     # First, compute md5sums of the config files in $WORKDIR.
229     cd $WORKDIR/
230     md5sum * > $MD5SUMSFILE
231
232     # Now, check the files in $ASTERISKDIR against the md5sums.
233     cd $ASTERISKDIR/
234     changed_files="`md5sum -c $MD5SUMSFILE 2>/dev/null | fgrep ": FAILED" | awk -F: '{print $1}'`"
235
236     rm -f $MD5SUMSFILE
237
238     [ -z "$changed_files" ] && return
239
240     # Now copy over the changed files.
241     for f in $changed_files ; do
242         cp "$WORKDIR/$f" "$ASTERISKDIR/$f"
243     done
244 }
245
246 # Calls the functions that create the final config files
247 # Calls the function which compares which files have changed
248 # Puts the final touches on $ASTERISKDIR
249 # Gets rid of $WORKDIR
250 pbx_assemble_and_copy_config()
251 {
252     mkdir -p $ASTERISKDIR
253
254     copy_unedited_templates_over
255     create_included_files
256     pbx_create_extensions_config
257     pbx_create_sip_config
258     pbx_create_jabber_config
259
260     touch    $WORKDIR/features.conf
261
262     # At this point, $WORKDIR should contain a complete, working config.
263     clean_up_asterisk_config_dir
264
265     compare_configs_and_copy_changed
266
267     [ ! -d $ASTERISKDIR/manager.d ] && mkdir -p $ASTERISKDIR/manager.d/
268
269     # Get rid of the working directory
270     rm -rf $WORKDIR/
271 }
272
273 # Creates configuration for a user and adds it to the temporary file that holds
274 # all users configured so far.
275 pbx_add_user()
276 {
277     local fullname
278     local defaultuser
279     local rawdefaultuser
280     local secret
281     local ring
282     local can_call
283
284     config_get fullname    $1 fullname
285     fullname=`escape_non_alpha $fullname`
286     config_get rawdefaultuser $1 defaultuser
287     defaultuser=`escape_non_alpha $rawdefaultuser`
288     config_get secret      $1 secret
289     secret=`escape_non_alpha $secret`
290     config_get ring        $1 ring
291     config_get can_call    $1 can_call
292
293     [ -z "$defaultuser" -o -z "$secret" ] && return
294     [ -z "$fullname" ] && fullname="$defaultuser"
295
296     sed "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_SIPUSR > $WORKDIR/sip_user.tmp
297
298     if [ "$can_call" = "yes" ] ; then
299         # Add user to list of all users that are allowed to make calls.
300         localusers_can_dial="$localusers_can_dial $rawdefaultuser"
301         sed -i "s/|CONTEXTNAME|/$defaultuser/g"     $WORKDIR/sip_user.tmp
302     else
303         sed -i "s/|CONTEXTNAME|/$HANGUPCNTXT/g"     $WORKDIR/sip_user.tmp
304     fi
305
306     # Add this user's configuration to the temp file containing all user configs.
307     sed "s/|FULLNAME|/$fullname/" $WORKDIR/sip_user.tmp |\
308              sed "s/|SECRET|/$secret/g"                       >> $WORKDIR/sip_users.TMP
309
310     if [ "$ring" = "yes" ] ; then
311         if [ -z "$localusers_to_ring" ] ; then
312             localusers_to_ring="SIP\/$defaultuser"
313         else
314             localusers_to_ring="$localusers_to_ring\&SIP\/$defaultuser"
315         fi
316     fi
317
318     # Add configuration which allows local users to call each other.
319     sed "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_EXTOUTLOCAL    >> $WORKDIR/localext.TMP
320
321     # Add configuration which puts calls to users through the default
322     # context, so that blacklists and voicemail take effect for this user.
323     sed "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_EXTDEFAULTUSER >> $WORKDIR/inextuser.TMP
324
325     rm -f $WORKDIR/sip_user.tmp
326 }
327
328 # Creates configuration for a Google account, and adds it to the temporary file that holds
329 # all accounts configured so far.
330 # Also creates the outgoing extensions which are used in users' outgoing contexts.
331 pbx_add_jabber()
332 {
333     local username
334     local secret
335     local numprefix
336     local register
337     local make_outgoing_calls
338     local name
339     local users_to_ring
340     local status
341     local statusmessage
342
343     config_get username $1 username
344     username=`escape_non_alpha $username`
345     config_get secret $1 secret
346     secret=`escape_non_alpha $secret`
347     #TODO: Is this really necessary here? Numprefix is retrieved below.
348     config_get numprefix $1 numprefix
349     config_get register $1 register
350     config_get make_outgoing_calls $1 make_outgoing_calls
351     config_get name $1 name
352     config_get status $1 status
353     status=`escape_non_alpha $status`
354     config_get statusmessage $1 statusmessage
355     statusmessage=`escape_non_alpha $statusmessage`
356
357     [ -z "$username" -o -z "$secret" ] && return
358
359     # Construct a jabber entry for this provider.
360     sed     "s/|USERNAME|/$username/g" $TMPL_JABBERUSER |\
361             sed "s/|NAME|/$name/g"                            > $WORKDIR/jabber.tmp
362
363     if [ "$register" = yes ] ; then
364         # If this provider is enabled for incoming calls, we need to set the
365         # status of the user to something other than unavailable in order to receive calls.
366         sed -i "s/|STATUS|/$status/g"                   $WORKDIR/jabber.tmp
367         sed -i "s/|STATUSMESSAGE|/\"$statusmessage\"/g" $WORKDIR/jabber.tmp
368
369         users_to_ring="`uci -q get ${MODULENAME}-calls.incoming_calls.$name`"
370         # If no users have been specified to ring, we ring all users enabled for incoming calls.
371         if [ -z "$users_to_ring" ] ; then
372             users_to_ring=$localusers_to_ring
373         else
374             # Else, we cook up a string formatted for the Dial command
375             # with the specified users (SIP/user1&SIP/user2&...). We do it
376             # with set, shift and a loop in order to be more tolerant of ugly whitespace
377             # messes entered by users.
378             set $users_to_ring
379             users_to_ring="SIP\/$1" && shift
380             for u in $@ ; do u=`escape_non_alpha $u` ; users_to_ring=$users_to_ring\\\&SIP\\\/$u ; done
381         fi
382
383         # Now, we add this account to the gtalk incoming context.
384         sed    "s/|USERNAME|/$username/g" $TMPL_EXTINCNTXTGTALK |\
385                    sed "s/|LOCALUSERS|/$users_to_ring/g"    >> $WORKDIR/outextgtalk.TMP
386     else
387         sed -i "s/|STATUS|/$GTALKUNVL/g"               $WORKDIR/jabber.tmp
388         sed -i "s/|STATUSMESSAGE|/\"\"/g"              $WORKDIR/jabber.tmp
389     fi
390
391     # Add this account's configuration to the temp file containing all account configs.
392     sed "s/|SECRET|/$secret/g" $WORKDIR/jabber.tmp      >> $WORKDIR/jabber.TMP
393
394     # If this provider is enabled for outgoing calls.
395     if [ "$make_outgoing_calls" = "yes" ] ; then
396
397         numprefix="`uci -q get ${MODULENAME}-calls.outgoing_calls.$name`"
398
399         # If no prefixes are specified, then we use "X" which matches any prefix.
400         [ -z "$numprefix" ]  && numprefix="X"
401
402         for p in $numprefix ; do
403             p=`escape_non_alpha $p`
404             sed "s/|NUMPREFIX|/$p/g" $TMPL_EXTOUTGTALK |\
405                             sed "s/|NAME|/$name/g"            >> $WORKDIR/outext-$name.TMP
406         done
407
408         # Add this provider to the list of enabled outbound providers.
409         if [ -z "$outbound_providers" ] ; then
410             outbound_providers="$name"
411         else
412             outbound_providers="$outbound_providers $name"
413         fi
414
415         # Add this provider to the list of enabled gtalk outbound providers.
416         if [ -z "$gtalk_outbound_providers" ] ; then
417             gtalk_outbound_providers="$name"
418         else
419             gtalk_outbound_providers="$gtalk_outbound_providers $name"
420         fi
421     fi
422
423     rm -f $WORKDIR/jabber.tmp
424 }
425
426 # Creates configuration for a SIP provider account, and adds it to the temporary file that holds
427 # all accounts configured so far.
428 # Also creates the outgoing extensions which are used in users' outgoing contexts.
429 pbx_add_peer()
430 {
431     local defaultuser
432     local secret
433     local host
434     local fromdomain
435     local register
436     local numprefix
437     local make_outgoing_calls
438     local name
439     local users_to_ring
440     local port
441     local outboundproxy
442
443     config_get defaultuser $1 defaultuser
444     defaultuser=`escape_non_alpha $defaultuser`
445     config_get secret $1 secret
446     secret=`escape_non_alpha $secret`
447     config_get host $1 host
448     host=`escape_non_alpha $host`
449     config_get port $1 port
450     config_get outbountproxy $1 outboundproxy
451     outbountproxy=`escape_non_alpha $outbountproxy`
452     config_get fromdomain $1 fromdomain
453     fromdomain=`escape_non_alpha $fromdomain`
454     config_get register $1 register
455     config_get numprefix $1 numprefix
456     config_get make_outgoing_calls $1 make_outgoing_calls
457     config_get name $1 name
458
459     [ -z "$defaultuser" -o -z "$secret" -o -z "$host" ] && return
460     [ -z "$fromdomain" ]    && fromdomain=$host
461     [ -n "$port" ]          && port="port=$port"
462     [ -n "$outboundproxy" ] && outboundproxy="outboundproxy=$outboundproxy"
463
464     # Construct a sip peer entry for this provider.
465     sed    "s/|DEFAULTUSER|/$defaultuser/" $TMPL_SIPPEER  >  $WORKDIR/sip_peer.tmp
466     sed -i "s/|NAME|/$name/"                                 $WORKDIR/sip_peer.tmp
467     sed -i "s/|FROMUSER|/$defaultuser/"                      $WORKDIR/sip_peer.tmp
468     sed -i "s/|SECRET|/$secret/"                             $WORKDIR/sip_peer.tmp
469     sed -i "s/|HOST|/$host/"                                 $WORKDIR/sip_peer.tmp
470     sed -i "s/|PORT|/$port/"                                 $WORKDIR/sip_peer.tmp
471     sed -i "s/|OUTBOUNDPROXY|/$outboundproxy/"               $WORKDIR/sip_peer.tmp
472     # Add this account's configuration to the temp file containing all account configs.
473     sed    "s/|FROMDOMAIN|/$host/" $WORKDIR/sip_peer.tmp >>  $WORKDIR/sip_peers.TMP
474
475     # If this provider is enabled for incoming calls.
476     if [ "$register" = "yes" ] ; then
477         # Then we create a registration string for this provider.
478         sed    "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_SIPREG         > $WORKDIR/sip_reg.tmp
479         sed -i "s/|SECRET|/$secret/g"                                  $WORKDIR/sip_reg.tmp
480         sed    "s/|NAME|/$name/g" $WORKDIR/sip_reg.tmp              >> $WORKDIR/sip_regs.TMP
481
482         users_to_ring="`uci -q get ${MODULENAME}-calls.incoming_calls.$name`"
483         # If no users have been specified to ring, we ring all users enabled for incoming calls.
484         if [ -z "$users_to_ring" ] ; then
485             users_to_ring=$localusers_to_ring
486         else
487             # Else, we cook up a string formatted for the Dial command
488             # with the specified users (SIP/user1&SIP/user2&...). We do it
489             # with set, shift and a loop in order to be more tolerant of ugly whitespace
490             # messes entered by users.
491             set $users_to_ring
492             users_to_ring="SIP\/$1" && shift
493             for u in $@ ; do users_to_ring=$users_to_ring\\\&SIP\\\/$u ; done
494         fi
495
496         # And we create an incoming calls context for this provider.
497         sed    "s/|NAME|/$name/g"                          $TMPL_EXTINCNTXTSIP |\
498                     sed "s/|LOCALUSERS|/$users_to_ring/g"       >> $WORKDIR/inext.TMP
499     fi
500
501     # If this provider is enabled for outgoing calls.
502     if [ "$make_outgoing_calls" = "yes" ] ; then
503
504         numprefix="`uci -q get ${MODULENAME}-calls.outgoing_calls.$name`"
505         # If no prefixes are specified, then we use "X" which matches any prefix.
506         [ -z "$numprefix" ]  && numprefix="X"
507         for p in $numprefix ; do
508             p=`escape_non_alpha $p`
509             sed "s/|NUMPREFIX|/$p/g" $TMPL_EXTOUTSIP |\
510                             sed "s/|NAME|/$name/g"              >> $WORKDIR/outext-$name.TMP
511         done
512
513         # Add this provider to the list of enabled outbound providers.
514         if [ -z "$outbound_providers" ] ; then
515             outbound_providers="$name"
516         else
517             outbound_providers="$outbound_providers $name"
518         fi
519
520         # Add this provider to the list of enabled sip outbound providers.
521         if [ -z "$sip_outbound_providers" ] ; then
522             sip_outbound_providers="$name"
523         else
524             sip_outbound_providers="$sip_outbound_providers $name"
525         fi
526     fi
527
528     rm -f $WORKDIR/sip_peer.tmp
529     rm -f $WORKDIR/sip_reg.tmp
530 }
531
532 # For all local users enabled for outbound calls, creates a context
533 # containing the extensions for Google and SIP accounts this user is
534 # allowed to use.
535 pbx_create_user_contexts()
536 {
537     local providers
538
539     for u in $localusers_can_dial ; do
540         u=`escape_non_alpha $u`
541         sed "s/|DEFAULTUSER|/$u/g" $TMPL_EXTUSERCNTXTHDR                >> $WORKDIR/userext.TMP
542         cat $WORKDIR/localext.TMP                                       >> $WORKDIR/userext.TMP
543         providers="`uci -q get ${MODULENAME}-calls.providers_user_can_use.$u`"
544         [ -z "$providers" ] && providers="$outbound_providers"
545
546         # For each provider, cat the contents of outext-$name.TMP into the user's outgoing calls extension
547         for p in $providers ; do
548             [ -f $WORKDIR/outext-$p.TMP ] && cat $WORKDIR/outext-$p.TMP >> $WORKDIR/userext.TMP
549         done
550         cat $TMPL_EXTUSERCNTXTFTR                                       >> $WORKDIR/userext.TMP
551     done
552 }
553
554 # Creates the blacklist context which hangs up on blacklisted numbers.
555 pbx_add_blacklist()
556 {
557     local blacklist1
558     local blacklist2
559
560     config_get blacklist1 blacklisting blacklist1
561     config_get blacklist2 blacklisting blacklist2
562
563     # We create the blacklist context no matter whether the blacklist
564     # actually contains entries or not, since the PBX will send calls
565     # to the context for a check against the list anyway.
566     cp $TMPL_EXTBLKLISTHDR                                   $WORKDIR/blacklist.TMP
567     for n in $blacklist1 $blacklist2 ; do
568         n=`escape_non_alpha $n`
569         sed "s/|BLACKLISTITEM|/$n/g" $TMPL_EXTBLKLIST >> $WORKDIR/blacklist.TMP 
570     done
571     cat $TMPL_EXTBLKLISTFTR                               >> $WORKDIR/blacklist.TMP
572 }
573
574 # Creates the callthrough context which allows specified numbers to get
575 # into the PBX and dial out as the configured user.
576 pbx_add_callthrough()
577 {
578     local callthrough_number_list
579     local defaultuser
580     local pin
581     local enabled
582     local F
583
584     config_get callthrough_number_list $1 callthrough_number_list
585     config_get defaultuser $1 defaultuser
586     defaultuser=`escape_non_alpha $defaultuser`
587     config_get pin $1 pin
588     pin=`escape_non_alpha $pin`
589     config_get enabled $1 enabled
590
591     [ "$enabled" = "no" ]   && return
592     [ "$defaultuser" = "" ] && return
593
594     for callthrough_number in $callthrough_number_list ; do
595         sed "s/|NUMBER|/$callthrough_number/g" $TMPL_EXTCTHRUCHECK >> $WORKDIR/callthroughcheck.TMP
596
597         if [ -n "$pin" ] ; then F=$TMPL_EXTCTHRU ; else F=$TMPL_EXTCTHRUNOPIN ; fi
598         sed "s/|NUMBER|/$callthrough_number/g" $F             |\
599                     sed "s/|DEFAULTUSER|/$defaultuser/"       |\
600                         sed "s/|PIN|/$pin/"                        >> $WORKDIR/callthrough.TMP
601     done
602 }
603
604
605 # Creates the callback context which allows specified numbers to get
606 # a callback into the PBX and dial out as the configured user.
607 pbx_add_callback()
608 {
609     local callback_number_list
610     local defaultuser
611     local pin
612     local enabled
613     local callback_provider
614     local callback_hangup_delay
615     local FB
616     local FT
617
618     config_get callback_number_list $1 callback_number_list
619     config_get defaultuser $1 defaultuser
620     defaultuser=`escape_non_alpha $defaultuser`
621     config_get pin $1 pin
622     pin=`escape_non_alpha $pin`
623     config_get enabled $1 enabled
624     config_get callback_provider $1 callback_provider
625     callback_provider=`sub_underscore_for_non_alpha $callback_provider`
626     config_get callback_hangup_delay $1 callback_hangup_delay
627
628     [ "$enabled" = "no" ]   && return
629     [ "$defaultuser" = "" ] && return
630
631     # If the provider is a SIP provider, set the file to use to $TMPL_EXTCBACKSIP
632     # otherwise, set it to $TMPL_EXTCBACKGTALK
633     if echo $sip_outbound_providers | grep -q $callback_provider 2>/dev/null
634     then
635         FB=$TMPL_EXTCBACKSIP
636     else
637         FB=$TMPL_EXTCBACKGTALK
638     fi
639
640     for callback_number in $callback_number_list ; do
641         sed "s/|NUMBER|/$callback_number/g" $TMPL_EXTCBACKCHECK    >> $WORKDIR/callbackcheck.TMP
642
643         sed "s/|NUMBER|/$callback_number/g" $FB            |\
644             sed "s/|CALLBACKPROVIDER|/$callback_provider/" |\
645                 sed "s/|CALLBACKHUPDELAY|/$callback_hangup_delay/" >> $WORKDIR/callback.TMP
646
647         # Perhaps a bit confusingly, we create "callthrough" configuration for callback
648         # numbers, because we use the same DISA construct as for callthrough.
649         if [ -n "$pin" ] ; then FT=$TMPL_EXTCTHRU ; else FT=$TMPL_EXTCTHRUNOPIN ; fi
650         sed "s/|NUMBER|/$callback_number/g" $FT            |\
651             sed "s/|DEFAULTUSER|/$defaultuser/"            |\
652                 sed "s/|PIN|/$pin/"                                >> $WORKDIR/callthrough.TMP
653     done
654 }
655
656
657 # Creates sip.conf from its template.
658 pbx_cook_sip_template()
659 {
660     local useragent
661     local externhost
662     local bindport
663
664     config_get useragent advanced useragent
665     useragent=`escape_non_alpha $useragent`
666     config_get externhost advanced externhost
667     config_get bindport advanced bindport
668
669     [ -z "$useragent" ] && useragent="$USERAGENT"
670
671     sed "s/|USERAGENT|/$useragent/g" $TMPL_SIP  > $WORKDIR/sip.conf
672
673     if [ -z "$externhost" ] ; then
674         sed -i "s/externhost=|EXTERNHOST|//g" $WORKDIR/sip.conf
675     else
676         sed -i "s/|EXTERNHOST|/$externhost/g" $WORKDIR/sip.conf
677     fi
678
679     if [ -z "$bindport" ] ; then
680         sed -i "s/bindport=|BINDPORT|//g"     $WORKDIR/sip.conf
681     else
682         sed -i "s/|BINDPORT|/$bindport/g"     $WORKDIR/sip.conf
683     fi
684
685
686 }
687
688 # Creates rtp.conf from its template.
689 pbx_cook_rtp_template()
690 {
691     local rtpstart
692     local rtpend
693
694     config_get rtpstart advanced rtpstart
695     config_get rtpend   advanced rtpend
696
697     sed "s/|RTPSTART|/$rtpstart/" $TMPL_RTP |\
698             sed "s/|RTPEND|/$rtpend/"               > $WORKDIR/rtp.conf
699 }
700
701 # Links any sound files found in $PBXSOUNDSDIR and $VMSOUNDSDIR
702 # into $ASTSOUNDSDIR for use by Asterisk. Does not overwrite files.
703 pbx_link_sounds()
704 {
705     mkdir -p $ASTSOUNDSDIR
706
707     for dir in $PBXSOUNDSDIR $VMSOUNDSDIR ; do
708         if [ -d $dir ] ; then
709             for f in $dir/* ; do
710                 ln -s $f $ASTSOUNDSDIR 2>/dev/null
711             done
712         fi
713     done
714 }
715
716
717 # Makes sure the ownership of specified directories is proper.
718 pbx_fix_ownership()
719 {
720     chown $ASTUSER:$ASTGROUP    $ASTDIRS
721     chown $ASTUSER:$ASTGROUP -R $ASTDIRSRECURSIVE
722 }
723
724
725 # Creates voicemail config if installed and enabled.
726 pbx_configure_voicemail()
727 {
728     local enabled
729     local global_timeout
730     local global_email_addresses
731
732     local smtp_tls
733     local smtp_server
734     local smtp_port
735     local smtp_auth
736     local smtp_user
737     local smtp_password
738
739     config_get enabled global_voicemail enabled
740
741     # First check if voicemail is enabled.
742     [ "$enabled" != "yes" ] && return
743
744     config_get global_timeout         global_voicemail global_timeout
745     #config_get global_email_addresses global_voicemail global_email_addresses
746     config_get smtp_auth              voicemail_smtp   smtp_auth
747     config_get smtp_tls               voicemail_smtp   smtp_tls
748     config_get smtp_server            voicemail_smtp   smtp_server
749     config_get smtp_port              voicemail_smtp   smtp_port
750     config_get smtp_user              voicemail_smtp   smtp_user
751     smtp_user=`escape_non_alpha $smtp_user`
752     config_get smtp_password          voicemail_smtp   smtp_password
753     smtp_password=`escape_non_alpha $smtp_password`
754
755     sed "s/|AUTH|/$smtp_auth/"   $TMPL_MSMTPDEFAULT |\
756              sed "s/|TLS|/$smtp_tls/"               >  $WORKDIR/pbx-msmtprc
757
758     sed "s/|HOST|/$smtp_server/" $TMPL_MSMTPACCOUNT |\
759              sed "s/|PORT|/$smtp_port/"             >> $WORKDIR/pbx-msmtprc
760
761     if [ "$smtp_auth" = "on" ] ; then
762         sed "s/|USER|/$smtp_user/"  $TMPL_MSMTPAUTH |\
763              sed "s/|PASSWORD|/$smtp_password/"     >> $WORKDIR/pbx-msmtprc
764     fi
765
766     cat $TMPL_MSMTPACCTDFLT                         >> $WORKDIR/pbx-msmtprc
767
768     [ ! -f /etc/pbx-msmtprc ] && cp $WORKDIR/pbx-msmtprc /etc/pbx-msmtprc
769     cmp -s  $WORKDIR/pbx-msmtprc /etc/pbx-msmtprc 1>/dev/null \
770                                 || mv $WORKDIR/pbx-msmtprc /etc/pbx-msmtprc
771     chmod 600                                              /etc/pbx-msmtprc
772     chown nobody                                           /etc/pbx-msmtprc
773
774     # Copy over the extensions file which has voicemail enabled.
775     cp $TMPL_EXTVMENABLED                $WORKDIR/extensions_voicemail.conf
776
777     # Create the voicemail directory in /tmp
778     mkdir -p     /tmp/voicemail
779     chown nobody /tmp/voicemail
780
781     # Create the recordings directory
782     mkdir -p     /etc/pbx-voicemail/recordings
783     chown nobody /etc/pbx-voicemail/recordings
784
785     # Working around a bug in OpenWRT 12.09-rc1
786     # TODO: REMOVE AS SOON AS POSSIBLE
787     chmod ugo+w /tmp
788 }
789
790
791 start() {
792     mkdir -p $WORKDIR
793
794     # Create the users.
795     config_load ${MODULENAME}-users
796     config_foreach pbx_add_user local_user
797
798     # Create configuration for each google account.
799     config_unset
800     config_load ${MODULENAME}-google
801     config_foreach pbx_add_jabber gtalk_jabber
802
803     # Create configuration for each voip provider.
804     config_unset
805     config_load ${MODULENAME}-voip
806     config_foreach pbx_add_peer voip_provider
807
808     # Create the user contexts, callthroug/back, and phone blacklist.
809     config_unset
810     config_load ${MODULENAME}-calls
811     pbx_create_user_contexts
812     pbx_add_blacklist
813     config_foreach pbx_add_callthrough callthrough_numbers
814     config_foreach pbx_add_callback callback_numbers
815
816     # Prepare sip.conf using settings from the "advanced" section.
817     config_unset
818     config_load ${MODULENAME}-advanced
819     pbx_cook_sip_template
820     pbx_cook_rtp_template
821
822     # Prepare voicemail config.
823     config_unset
824     config_load ${MODULENAME}-voicemail
825     pbx_configure_voicemail
826
827     # Assemble the configuration, and copy changed files over.
828     config_unset
829     config_load ${MODULENAME}-advanced
830     pbx_assemble_and_copy_config
831
832     # Link sound files
833     pbx_link_sounds
834
835     # Enforce ownership of specified files and directories.
836     pbx_fix_ownership
837 }