Asterisk: Time to remove the "flash filling" config clutter and move it to uci
Since a long time we have the problem that asterisk is very unfriendly to configure. It contains a lot of config files which are mostly full commented out.
i decided to write a uci file togehter with an init script to make it easier and flash friendlier.
my way is to move "our" generated config files into /tmp/asterisk/ instead of overwriting the
/etc/ this allows us a first step to make configs upgrade persistent.
In fact we cant cover all situations but generate a starting base to make asterisk more useable for embedded devices.
config asterisk
option verbose '0'
option dontwarn 'yes'
option maxcalls '2'
option maxload '0.9'
option minmemfree '1'
option tansmit_silence 'yes'
option language 'de'
option systemname '10.21.0.1'
option autosystemname 'yes'
option mindtmfduration '80'
# modules
option autoload 'yes'
# user
option userbase '6000'
# sip
option port '5060'
option bindaddr '0.0.0.0'
option context 'default'
option srvlookup 'yes'
option nat 'yes'
option allowguest 'no'
option transport 'udp'
list networks '10.21.0.0/255.255.255.0'
list networks '10.22.0.0/255.255.255.0'
list networks '10.30.0.0/255.255.255.0'
list networks '10.40.0.0/255.255.255.0'
# rtp
option rtpstart '15000'
option rtpend '30000'
option dnsmgr 'yes'
option refreshinterval '1200'
config asterisk_user
option fullname 'Lipke'
option description 'Linksys'
option email '[email protected]'
option secret '1234'
option vmsecret '1234'
option hasvoicemail 'no'
option hassip 'yes'
option hasiax 'no'
option hash323 'no'
option hasmanager 'no'
option callwaiting 'no'
option macaddress '000E083B586F'
option autoprov 'yes'
option linekeys '1'
option linenumber '1'
option cidnumber '6000'
option treewaycalling 'yes'
option callwaitingcallerid 'yes'
option transfer 'yes'
option canpark 'yes'
option cancallforward 'yes'
option callreturn 'yes'
option callgroup '1'
option pickupgroup '1'
config asterisk_register
option defaultuser '##########'
option password '##########'
option domain 'sipgate.de'
config asterisk_peer
option number '6000'
option type 'friend'
option secret '1234'
option host 'dynamic'
option qualify 'yes'
option description 'IP Device'
option context 'default'
config asterisk_peer
option number 'sipgate'
option context 'sipgate-in'
option type 'peer'
option secret '########'
option host 'sipgate.de'
option canreinvite 'no'
option fromdomain 'sipgate.de'
option defaultuser '########'
option fromuser '########'
option insecure 'port,invite'
option dtmfmode 'rfc2833'
option disallow 'all'
option allow 'alaw&ulaw'
option outboundproxy 'sipgate.de'
config asterisk_dialplan
option context '_default'
option pattern '_[0-9].'
list entries '1,Answer()'
list entries '2,Hangup()'
config asterisk_dialplan
option context 'internal'
option pattern '_01.'
list entries '1,Answer()'
list entries '2,Playback(pls-hold-while-try&one-moment-please)'
list entries '3,Wait(1)'
list entries '4,Dial(SIP/${EXTEN:2},30)'
list entries '5,Playback(number-not-answering&please-try-call-later,noanswer)'
list entries '6,Wait(1)'
list entries '7,Hangup()'
config asterisk_dialplan
option context 'sipgate-out'
option pattern '_02.'
option source 'exten'
list entries '1,Answer()'
list entries '2,Playback(pls-hold-while-try&one-moment-please)'
list entries '3,Wait(1)'
list entries '4,Dial(SIP/${EXTEN:2}@sipgate,30)'
list entries '5,Playback(number-not-answering&please-try-call-later,noanswer)'
list entries '6,Wait(1)'
list entries '7,Hangup()'
config asterisk_dialplan
option context 'sipgate-in'
option pattern '########'
option source 'exten'
list entries '1,Answer()'
list entries '2,Playback(pls-hold-while-try&one-moment-please)'
list entries '3,Wait(1)'
list entries '4,Dial(SIP/6000,30)'
list entries '5,Playback(number-not-answering&please-try-call-later,noanswer)'
list entries '6,Wait(1)'
list entries '7,Hangup()'
/etc/init.d/asterisk contains so far:
#!/bin/sh /etc/rc.common
# Copyright (C) 2018 OpenWrt.org
START=99
APP=asterisk
OPTIONS=
DEST=
DEFAULT=$DEST/etc/default/$APP
BIN_FILE=$DEST/usr/sbin/$APP
PID_FILE=$DEST/var/run/$APP/$APP.pid
# creates the config files and its general settings...
asterisk_set_header() {
local verbose
local dontwarn
local maxcalls
local maxload
local minmemfree
local transmit_silence
local language
local systemname
local autosystemname
local mindtmfduration
local autoload
# user template
local userbase
# sip
local port
local bindaddr
local context
local srvlookup
local nat
local allowguest
local networks
# rtp
local rtpstart
local rtpend
# dnsmgr
local dnsmgr
local refreshinterval
# main
config_get verbose $1 verbose
config_get dontwarn $1 dontwarn
config_get maxcalls $1 maxcalls
config_get maxload $1 maxload
config_get minmemfree $1 minmemfree
config_get transmit_silence $1 transmit_silence
config_get language $1 language
config_get systemname $1 systemname
config_get autosystemname $1 autosystemname
config_get mindtmfduration $1 mindtmfduration
# modules
config_get autoload $1 autoload
# user template
config_get userbase $1 userbase
# sip
config_get port $1 port
config_get allowguest $1 allowguest
config_get transport $1 transport
config_get networks $1 networks
config_get bindaddr $1 bindaddr
config_get context $1 context
config_get srvlookup $1 srvlookup
config_get nat $1 nat
# rtp
config_get rtpstart $1 rtpstart
config_get rtpend $1 rtpend
# dns
config_get dnsmgr $1 dnsmgr
config_get refreshinterval $1 refreshinterval
echo -e "[directories](!)\n
astetcdir => /tmp/asterisk
astmoddir => /usr/lib/asterisk/modules
astvarlibdir => /usr/lib/asterisk
astdbdir => /usr/lib/asterisk
astkeydir => /usr/lib/asterisk
astdatadir => /usr/lib/asterisk
astagidir => /usr/lib/asterisk/agi-bin
astspooldir => /var/spool/asterisk
astrundir => /var/run/asterisk
astlogdir => /var/log/asterisk
astsbindir => /usr/sbin" > /etc/asterisk/asterisk.conf
mkdir -p /tmp/asterisk/
echo -e "[options]" >> /tmp/asterisk/asterisk.conf
[ -n "$verbose" ] && echo -e "verbose=$verbose" >> /tmp/asterisk/asterisk.conf
[ -n "$dontwarn" ] && echo -e "dontwarn=$dontwarn" >> /tmp/asterisk/asterisk.conf
[ -n "$maxcalls" ] && echo -e "maxcalls=$maxcalls" >> /tmp/asterisk/asterisk.conf
[ -n "$maxload" ] && echo -e "maxload=$maxload" >> /tmp/asterisk/asterisk.conf
[ -n "$minmemfree" ] && echo -e "minmemfree=$minmemfree" >> /tmp/asterisk/asterisk.conf
[ -n "$transmit_silence" ] && echo -e "transmit_silence=$transmit_silence" >> /tmp/asterisk/asterisk.conf
[ -n "$language" ] && echo -e "language=$language" >> /tmp/asterisk/asterisk.conf
[ -n "$systemname" ] && echo -e "systemname=$systemname" >> /tmp/asterisk/asterisk.conf
[ -n "$autosystemname" ] && echo -e "autosystemname=$autosystemname" >> /tmp/asterisk/asterisk.conf
[ -n "$mindtmfduration" ] && echo -e "mindtmfduration=$mindtmfduration" >> /tmp/asterisk/asterisk.conf
# modules (autoload by default....)
echo -e "[modules]" > /tmp/asterisk/modules.conf
echo -e "autoload = yes" >> /tmp/asterisk/modules.conf
# user template
echo -e "[general]" > /tmp/asterisk/users.conf
[ -n "$userbase" ] && echo -e "userbase = $userbase" >> /tmp/asterisk/users.conf
# sip
echo -e "[general]" > /tmp/asterisk/sip.conf
[ -n "$port" ] && echo -e "port = $port" >> /tmp/asterisk/sip.conf
[ -n "$allowguest" ] && echo -e "allowguest = $allowguest" >> /tmp/asterisk/sip.conf
[ -n "$transport" ] && echo -e "transport = $transport" >> /tmp/asterisk/sip.conf
[ -n "$bindaddr" ] && echo -e "bindaddr = $bindaddr" >> /tmp/asterisk/sip.conf
[ -n "$context" ] && echo -e "context = $context" >> /tmp/asterisk/sip.conf
[ -n "$srvlookup" ] && echo -e "srvlookup = $srvlookup" >> /tmp/asterisk/sip.conf
for network in $networks; do
[ -n "$network" ] && echo -e "localnet = $network" >> /tmp/asterisk/sip.conf
done
# rtp
echo -e "[general]" > /tmp/asterisk/rtp.conf
[ -n "$rtpstart" ] && echo -e "rtpstart = $rtpstart" >> /tmp/asterisk/rtp.conf
[ -n "$rtpend" ] && echo -e "rtpend = $rtpend" >> /tmp/asterisk/rtp.conf
# dns
echo -e "[general]" > /tmp/asterisk/dnsmgr.conf
[ -n "$dnsmgr" ] && echo -e "enabled = $dnsmgr" >> /tmp/asterisk/dnsmgr.conf
[ -n "$refreshinterval" ] && echo -e "refreshinterval = $refreshinterval" >> /tmp/asterisk/dnsmgr.conf
echo -e "[general]" > /tmp/asterisk/extensions.conf
}
asterisk_adduser() {
local fullname
local description
local email
local secret
local vmsecret
local dahdichan
local hasvoicemail
local hassip
local hasiax
local hash323
local hasmanager
local callwaiting
local context
local alternateexts
local macaddress
local autoprov
local linekeys
local linenumber
local cidnumber
local treewaycalling
local callwaitingcallerid
local transfer
local canpark
local cancallforward
local callreturn
local callgroup
local pickupgroup
config_get fullname $1 fullname
config_get description $1 description
config_get email $1 email
config_get secret $1 secret
config_get vmsecret $1 vmsecret
config_get dahdichan $1 dahdichan
config_get hasvoicemail $1 hasvoicemail
config_get hassip $1 hassip
config_get hasiax $1 hasiax
config_get hasmanager $1 hasmanager
config_get callwaiting $1 callwaiting
config_get context $1 context
config_get alternateexts $1 alternateexts
config_get macaddress $1 macaddress
config_get autoprov $1 autoprov
config_get linekeys $1 linekeys
config_get linenumber $1 linenumber
config_get cidnumber $1 cidnumber
config_get threewaycalling $1 threewaycalling
config_get callwaitingcallerid $1 callwaitingcallerid
config_get transfer $1 transfer
config_get canpark $1 canpark
config_get cancallforward $1 cancallforward
config_get callreturn $1 callreturn
config_get callgroup $1 callgroup
config_get pickupgroup $1 pickupgroup
echo -e "\n[$cidnumber]" >> /tmp/asterisk/users.conf
[ -n "$fullname" ] && echo -e "fullname = $fullname" >> /tmp/asterisk/users.conf
[ -n "$description" ] && echo -e "description = $description" >> /tmp/asterisk/users.conf
[ -n "$email" ] && echo -e "email = $email" >> /tmp/asterisk/users.conf
[ -n "$secret" ] && echo -e "secret = $secret" >> /tmp/asterisk/users.conf
[ -n "$vmsecret" ] && echo -e "vmsecret = $vmsecret" >> /tmp/asterisk/users.conf
[ -n "$dahdichan" ] && echo -e "dahdichan = $dahdichan" >> /tmp/asterisk/users.conf
[ -n "$hasvoicemail" ] && echo -e "hasvoicemail = $hasvoicemail" >> /tmp/asterisk/users.conf
[ -n "$hassip" ] && echo -e "hassip = $hassip" >> /tmp/asterisk/users.conf
[ -n "$hasiax" ] && echo -e "hasiax = $hasiax" >> /tmp/asterisk/users.conf
[ -n "$hash323" ] && echo -e "hash323 = $hash323" >> /tmp/asterisk/users.conf
[ -n "$hasmanager" ] && echo -e "hasmanager = $hasmanager" >> /tmp/asterisk/users.conf
[ -n "$callwaiting" ] && echo -e "callwaiting = $callwaiting" >> /tmp/asterisk/users.conf
[ -n "$context" ] && echo -e "context = $context" >> /tmp/asterisk/users.conf
[ -n "$alternateexts" ] && echo -e "alternateexts = $alternateexts" >> /tmp/asterisk/users.conf
[ -n "$macaddress" ] && echo -e "macaddress = $macaddress" >> /tmp/asterisk/users.conf
[ -n "$autoprov" ] && echo -e "autoprov = $autoprov" >> /tmp/asterisk/users.conf
[ -n "$linekeys" ] && echo -e "linekeys = $linekeys" >> /tmp/asterisk/users.conf
[ -n "$linenumber" ] && echo -e "linenumber = $linenumber" >> /tmp/asterisk/users.conf
[ -n "$cidnumber" ] && echo -e "cidnumber = $cidnumber" >> /tmp/asterisk/users.conf
[ -n "$threewaycalling" ] && echo -e "threewaycalling = $threewaycalling" >> /tmp/asterisk/users.conf
[ -n "$callwaitingcallerid" ] && echo -e "callwaitingcallerid = $callwaitingcallerid" >> /tmp/asterisk/users.conf
[ -n "$transfer" ] && echo -e "transfer = $transfer" >> /tmp/asterisk/users.conf
[ -n "$canpark" ] && echo -e "canpark = $canpark" >> /tmp/asterisk/users.conf
[ -n "$cancallforward" ] && echo -e "cancallforward = $cancallforward" >> /tmp/asterisk/users.conf
[ -n "$callreturn" ] && echo -e "callreturn = $callreturn" >> /tmp/asterisk/users.conf
[ -n "$callgroup" ] && echo -e "callgroup = $callgroup" >> /tmp/asterisk/users.conf
[ -n "$pickupgroup" ] && echo -e "pickupgroup = $pickupgroup" >> /tmp/asterisk/users.conf
}
# creates the peer sections...
asterisk_addpeer() {
local number
local type
local host
local fromuser
local defaultuser
local secret
local fromdomain
local context
local canreinvite
local qualify
local insecure
local dtmfmode
local disallow
local outboundproxy
config_get number $1 number
config_get type $1 type
config_get host $1 host
config_get fromuser $1 fromuser
config_get defaultuser $1 defaultuser
config_get secret $1 secret
config_get fromdomain $1 fromdomain
config_get context $1 context
config_get canreinvite $1 canreinvite
config_get qualify $1 qualify
config_get insecure $1 insecure
config_get dtmfmode $1 dtmfmode
config_get disallow $1 disallow
config_get allow $1 allow
config_get outboundproxy $1 outboundproxy
config_get transport $1 transport
[ -n "$number" ] && echo -e "\n[$number]" >> /tmp/asterisk/sip.conf
[ -n "$type" ] && echo -e "type = $type" >> /tmp/asterisk/sip.conf
[ -n "$host" ] && echo -e "host = $host" >> /tmp/asterisk/sip.conf
[ -n "$fromuser" ] && echo -e "fromuser = $fromuser" >> /tmp/asterisk/sip.conf
[ -n "$defaultuser" ] && echo -e "defaultuser = $defaultuser" >> /tmp/asterisk/sip.conf
[ -n "$secret" ] && echo -e "secret = $secret" >> /tmp/asterisk/sip.conf
[ -n "$fromdomain" ] && echo -e "fromdomain = $fromdomain" >> /tmp/asterisk/sip.conf
[ -n "$context" ] && echo -e "context = $context" >> /tmp/asterisk/sip.conf
[ -n "$canreinvite" ] && echo -e "canreinvite = $canreinvite" >> /tmp/asterisk/sip.conf
[ -n "$qualify" ] && echo -e "qualify = $qualify" >> /tmp/asterisk/sip.conf
[ -n "$insecure" ] && echo -e "insecure = $insecure" >> /tmp/asterisk/sip.conf
[ -n "$dtmfmode" ] && echo -e "dtmfmode = $dtmfmode" >> /tmp/asterisk/sip.conf
[ -n "$disallow" ] && echo -e "disallow = $disallow" >> /tmp/asterisk/sip.conf
[ -n "$allow" ] && echo -e "allow = $allow" >> /tmp/asterisk/sip.conf
[ -n "$outboundproxy" ] && echo -e "outboundproxy = $outboundproxy" >> /tmp/asterisk/sip.conf
[ -n "$transport" ] && echo -e "transport = $transport" >> /tmp/asterisk/sip.conf
}
# writes out the "register" lines in sip.cond -> comes from the equaling uci section
asterisk_dialplan() {
local context
local pattern
local entries
local preincludes
local postincludes
config_get context $1 context
config_get pattern $1 pattern
config_get entries $1 entries
config_get preincludes $1 preincludes
config_get postincludes $1 postincludes
[ -n "$context" ] && echo -e "[$context]" >> /tmp/asterisk/extensions.conf
for include in $preincludes; do
[ -n "$context" ] && echo -e "include => $include" >> /tmp/asterisk/extensions.conf
done
for entrie in $entries; do
[ -n "$context" ] && echo -e "exten => $pattern,$entrie" >> /tmp/asterisk/extensions.conf
done
for include in $postincludes; do
[ -n "$context" ] && echo -e "include => $include" >> /tmp/asterisk/extensions.conf
done
[ -n "$context" ] && echo -e "" >> /tmp/asterisk/extensions.conf
}
asterisk_register() {
local defaultuser
local password
local domain
local prefix
config_get defaultuser $1 defaultuser
config_get password $1 password
config_get domain $1 domain
config_get prefix $1 prefix
[ -n "$defaultuser" ] && echo -e "register => $defaultuser$prefix:$password@$domain/$defaultuser" >> /tmp/asterisk/sip.conf
}
start() {
config_load asterisk
config_foreach asterisk_set_header asterisk
config_foreach asterisk_register asterisk_register
config_foreach asterisk_adduser asterisk_user
config_foreach asterisk_addpeer asterisk_peer
config_foreach asterisk_dialplan asterisk_dialplan
[ -f $DEFAULT ] && . $DEFAULT
[ -d $DEST/var/run/asterisk ] || mkdir -p $DEST/var/run/asterisk
[ -d $DEST/var/log/asterisk ] || mkdir -p $DEST/var/log/asterisk
[ -d $DEST/var/spool/asterisk ] || mkdir -p $DEST/var/spool/asterisk
[ -d $DEST/var/lib ] || mkdir -p $DEST/var/lib
[ -h $DEST/var/lib/asterisk ] || ln -s /usr/lib/asterisk /var/lib/asterisk
[ -d $DEST/var/lib/asterisk/keys ] || mkdir -p $DEST/var/lib/asterisk/keys
[ -d $DEST/var/log/asterisk/cdr-csv ] || mkdir -p $DEST/var/log/asterisk/cdr-csv
[ -d $DEST/var/lib/asterisk/moh ] || mkdir -p $DEST/var/lib/asterisk/moh
SERVICE_PID_FILE="/var/run/asterisk/asterisk.pid" \
service_start $BIN_FILE $OPTIONS
}
stop() {
SERVICE_PID_FILE="/var/run/asterisk/asterisk.pid" \
service_stop $BIN_FILE
}
reload() {
SERVICE_PID_FILE="/var/run/asterisk/asterisk.pid" \
service_reload $BIN_FILE
}
Im currently using it and it makes (except the dialplan patterns) the life of my box alot easier... Any suggestions?
Update 1:
- Its now able to specify modules which has to be loaded.
- Remove all configfile definitions in the MakeFile.
- Logging is now entirely disabled (Messages) to keep the FS away from blowing up...
update 2
- ship a starting base (SIP) as ready to run config. a hidden "prefix" variable can be used to prefix the usernames (ex: T-Online voip users needs a prefix).
- testing...
Hi @LipkeGu,
I like the idea of transforming config to uci. However I miss the possibility of configuring modules that your provided uci config does not handle. Have you thought about it?
@LipkeGu Have you considered using asterisk-realtime + sqlite3 instead. Most of the asterisk config can be moved to a database (odbc, mysql, postgresql, sqlite3 and/or ldap). For example sippeers / iaxpeers / voicemail / sccp / queues / musiconhold / meetme / confbridge and even dialplan (there are some caveats with extensions.conf though). That should/would get rid of a lot of the clutter and might make a nice frontend simpler. See:
Note:You would have to make sure to retain this sqlite3 db over openwrt upgrades though. Also note: setting up realtime can be a little bit daunting though (getting extconfig.conf + res_sqlite.conf right the first time). but once it is up and running it works really well and reduces the need for "module reload [all]" in a lot of cases.
When you are going to use files: do note that almost all asterisk config files parameters have sensible defaults don't have to be defined, which can reduce the size of files considerably.