Asterisk on Kamikaze
From Crashcourse Wiki
This page contains information on how to build a VOIP appliance using an Asus WL500g Premium (v.1) and the Asterisk packages included in Kamikaze. This includes instructions to configure Asterisk for the Canadian VOIP provider Unlimitel, voicemail, extensions and other interesting features. In order to install all the required packages, it is necessary to augment the flash memory of the WL500gP with USB-connected memory.
[edit] Asterisk on the WL500g Premium (v.1)
At the original time of writing, OpenWrt Kamikaze 8.09 was available and the core Asterisk package available in that release (asterisk14) did not have gsm to ulaw codec translation enabled. Consequently, since all sounds in OpenWRT Asterisk are included in gsm, including those for voicemail, much of the functionality described below is not available for stock Kamikaze 8.09 installations. In order to make all aspects of this project function it was necessary to compile the firmware and packages directly from svn trunk as described here. In the following we will only require the asterisk14 modules, ssmtp mail server and usb kernel modules for storage.
Update March 13/09: Asterisk packages for Kamikaze 8.09 with gsm translation correctly implemented are available here. There is no need to compile the firmware and modules from source. Just get the distributed Kamikaze 8.09 trx firmware image from here and use the built-in opkg packaging system - except for the repaired Asterisk packages which have to be manually installed.
Update June 19/09: OpenWRT Kamikaze 8.09.1 aims is available. One of the bug fixes in this release include the problem with gsm translation in Asterisk. Asterisk 1.4 is now fully functional in OpenWRT Kamikaze.
[edit] Initial Setup of Router
We will need some initial setup for the programme described below. For a basic Asterisk VOIP system with no voicemail, one can safely avoid adding external storage via USB. If voicemail is used, external storage is necessary to avoid having long-winded callers (or undeleted voicemail) crash the system by running it out of flash disk space. It also allows the installation of practically all available OpenWRT packages. Similarly, wireless access is not a must, but is convenient and allows the router/VOIP PBX to double as a wireless access point.
NOTE: If you are building the firmware and packages from source code to take advantage of the full functionality of Asterisk, it is very useful to build the USB storage modules and activate the USB storage. This way one can use USB storage to keep a local repository of packages compatible with your custom image for easy access. An alternative is to copy the necessary packages to the router via scp as they are required.
Installing new firmware on the router and initial login: Here.
USB storage setup: Here.
Installing packages to USB storage instead of root: Here.
Wireless: Wireless works on the WL500gP (V.1) as of Kamikaze 8.09. WPA can be used on the router by simply modifying the configuration file at /etc/config/wireless to:
config wifi-device wlan0 option type mac80211 option channel 5 # REMOVE THIS LINE TO ENABLE WIFI: # option disabled 1 *********< Note that this line is commented out! config wifi-iface option device wlan0 option network lan option mode ap option ssid OpenWrt option encryption psk option key mystrongpasskey
A reboot of the system is recommended to implement all changes in a coherent fashion.
[edit] Installation of Asterisk Packages
With a network connection, the OpenWRT package management system can easily install Asterisk on your router. Start with an update of the system
opkg update
Then install Asterisk 1.4 (1.6 is available as well, but many support packages (eg. ALSA, database are not yet ready)
opkg install asterisk14
Dependencies will be taken care of automatically by opkg: libpthread, libpopt, libncurses will be installed on the router. This will install the basic Asterisk system on the router and create and populate the configuration directory /etc/asterisk. The service will not be started automatically. In order to have Asterisk start on reboot, run
/etc/init.d/asterisk enable
Similarly, asterisk can be started with
/etc/init.d/asterisk start
Now, in order to obtain a working VOIP system, the configuration files will have to modified to interact appropriately with the external VOIP provider.
[edit] Configuration for Unlimitel trunks
For this project, we will use the Ottawa, Ontario based VOIP provider Unlimitel to supply us with a DID (phone number) and access to the POTS (Plain Old Telephone Sytem) for our incoming and outgoing calls. One advantage of using Unlimitel is that they have a very convenient online configuration tool which produces a set of Asterisk configuration files from basic account information (supplied via e-mail when the account is setup).
Simply copy the supplied files to /etc/asterisk on the router.
/etc/asterisk/sip.conf
[general] context=sipdefault allowoverlap=no allowtransfer=no maxexpiry=3600 minexpiry=60 defaultexpiry=3600 checkmwi=10 buggymwi=no vmexten=voicemail disallow=all allow=ulaw language=en relaxdtmf=yes useragent=Asterisk PBX dtmfmode = rfc2833 rfc2833compensate=yes alwaysauthreject = yes rtptimeout=60 rtpholdtimeout=300 register => 5558888:passw0rd@sip02.unlimitel.ca/5558888 canreinvite=yes jbenable = yes jbforce = no jbmaxsize = 200 jbresyncthreshold = 1000 jbimpl = fixed jblog = no [5558888] type=peer auth=md5 username=5558888 fromuser=5558888 fromdomain=unlimitel.ca secret=passw0rd host=sip02.unlimitel.ca port=5060 nat=yes canreinvite=no qualify=no disallow=all allow=ulaw dtmfmode=rfc2833 insecure=very [5558888-in] type=peer host=sip02.unlimitel.ca context=5558888-in canreinvite=no
/etc/asterisk/rtp.conf
[general] rtpstart=10000 rtpend=20000 dtmftimeout=3000 rtcpinterval = 5000
/etc/asterisk/extensions.conf
[general]
static=yes
writeprotect=no
clearglobalvars=no
[globals]
[default]
exten => _X.,1,Hangup(3)
[sipdefault]
exten => _X.,1,Hangup(3)
[5558888-in]
exten => 5558888,1,Dial(SIP/{Your extension to ring},50)
exten => 5558888,n,Goto(in5558888-${DIALSTATUS},1)
exten => 5558888,n,Hangup
exten => in5558888-BUSY,1,Hangup(17)
exten => in5558888-CONGESTION,1,Hangup(3)
exten => in5558888-CHANUNAVAIL,1,Hangup(3)
exten => in5558888-NOANSWER,1,Hangup(16)
exten => _in5558888-.,1,Hangup(16)
[internal-sip]
exten => _NXXNXXXXXX,1,SetCallerPres(allowed)
exten => _NXXNXXXXXX,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _NXXNXXXXXX,n,Dial(SIP/${EXTEN}@5558888,60)
exten => _NXXNXXXXXX,n,Goto(out1-${DIALSTATUS},1)
exten => _NXXNXXXXXX,n,Hangup
exten => out1-BUSY,1,Hangup(17)
exten => out1-CONGESTION,1,Hangup(3)
exten => out1-CHANUNAVAIL,1,Hangup(3)
exten => out1-NOANSWER,1,Hangup(16)
exten => _out1-.,1,Hangup(16)
exten => _1800NXXXXXX,1,SetCallerPres(allowed)
exten => _1800NXXXXXX,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _1800NXXXXXX,n,Dial(SIP/${EXTEN}@5558888,60)
exten => _1800NXXXXXX,n,Goto(out2-${DIALSTATUS},1)
exten => _1800NXXXXXX,n,Hangup
exten => out2-BUSY,1,Hangup(17)
exten => out2-CONGESTION,1,Hangup(3)
exten => out2-CHANUNAVAIL,1,Hangup(3)
exten => out2-NOANSWER,1,Hangup(16)
exten => _out2-.,1,Hangup(16)
exten => _1888NXXXXXX,1,SetCallerPres(allowed)
exten => _1888NXXXXXX,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _1888NXXXXXX,n,Dial(SIP/${EXTEN}@5558888,60)
exten => _1888NXXXXXX,n,Goto(out3-${DIALSTATUS},1)
exten => _1888NXXXXXX,n,Hangup
exten => out3-BUSY,1,Hangup(17)
exten => out3-CONGESTION,1,Hangup(3)
exten => out3-CHANUNAVAIL,1,Hangup(3)
exten => out3-NOANSWER,1,Hangup(16)
exten => _out3-.,1,Hangup(16)
exten => _1877NXXXXXX,1,SetCallerPres(allowed)
exten => _1877NXXXXXX,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _1877NXXXXXX,n,Dial(SIP/${EXTEN}@5558888,60)
exten => _1877NXXXXXX,n,Goto(out4-${DIALSTATUS},1)
exten => _1877NXXXXXX,n,Hangup
exten => out4-BUSY,1,Hangup(17)
exten => out4-CONGESTION,1,Hangup(3)
exten => out4-CHANUNAVAIL,1,Hangup(3)
exten => out4-NOANSWER,1,Hangup(16)
exten => _out4-.,1,Hangup(16)
exten => _1866NXXXXXX,1,SetCallerPres(allowed)
exten => _1866NXXXXXX,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _1866NXXXXXX,n,Dial(SIP/${EXTEN}@5558888,60)
exten => _1866NXXXXXX,n,Goto(out5-${DIALSTATUS},1)
exten => _1866NXXXXXX,n,Hangup
exten => out5-BUSY,1,Hangup(17)
exten => out5-CONGESTION,1,Hangup(3)
exten => out5-CHANUNAVAIL,1,Hangup(3)
exten => out5-NOANSWER,1,Hangup(16)
exten => _out5-.,1,Hangup(16)
exten => _1NXXNXXXXXX,1,SetCallerPres(allowed)
exten => _1NXXNXXXXXX,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _1NXXNXXXXXX,n,Dial(SIP/${EXTEN:1}@5558888,60)
exten => _1NXXNXXXXXX,n,Goto(out6-${DIALSTATUS},1)
exten => _1NXXNXXXXXX,n,Hangup
exten => out6-BUSY,1,Hangup(17)
exten => out6-CONGESTION,1,Hangup(3)
exten => out6-CHANUNAVAIL,1,Hangup(3)
exten => out6-NOANSWER,1,Hangup(16)
exten => _out6-.,1,Hangup(16)
exten => _011X.,1,SetCallerPres(allowed)
exten => _011X.,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _011X.,n,Dial(SIP/${EXTEN}@5558888,60)
exten => _011X.,n,Goto(out7-${DIALSTATUS},1)
exten => _011X.,n,Hangup
exten => out7-BUSY,1,Hangup(17)
exten => out7-CONGESTION,1,Hangup(3)
exten => out7-CHANUNAVAIL,1,Hangup(3)
exten => out7-NOANSWER,1,Hangup(16)
exten => _out7-.,1,Hangup(16)
exten => _911,1,SetCallerPres(allowed)
exten => _911,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _911,n,Dial(SIP/${EXTEN}@5558888,60)
exten => _911,n,Goto(out8-${DIALSTATUS},1)
exten => _911,n,Hangup
exten => out8-BUSY,1,Hangup(17)
exten => out8-CONGESTION,1,Hangup(3)
exten => out8-CHANUNAVAIL,1,Hangup(3)
exten => out8-NOANSWER,1,Hangup(16)
exten => _out8-.,1,Hangup(16)
exten => _0011X.,1,SetCallerPres(allowed)
exten => _0011X.,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _0011X.,n,Dial(SIP/${EXTEN}@5558888,60)
exten => _0011X.,n,Goto(out9-${DIALSTATUS},1)
exten => _0011X.,n,Hangup
exten => out9-BUSY,1,Hangup(17)
exten => out9-CONGESTION,1,Hangup(3)
exten => out9-CHANUNAVAIL,1,Hangup(3)
exten => out9-NOANSWER,1,Hangup(16)
exten => _out9-.,1,Hangup(16)
exten => _0NXXNXXXXXX,1,SetCallerPres(allowed)
exten => _0NXXNXXXXXX,n,Set(CALLERID(all)=OpenWRT-test <5558888>)
exten => _0NXXNXXXXXX,n,Dial(SIP/${EXTEN}@5558888,60)
exten => _0NXXNXXXXXX,n,Goto(out10-${DIALSTATUS},1)
exten => _0NXXNXXXXXX,n,Hangup
exten => out10-BUSY,1,Hangup(17)
exten => out10-CONGESTION,1,Hangup(3)
exten => out10-CHANUNAVAIL,1,Hangup(3)
exten => out10-NOANSWER,1,Hangup(16)
exten => _out10-.,1,Hangup(16)
[edit] Adding local SIP extensions
For extension 301 with voicemail, add to the end of sip.conf (be sure to change secret to a secure password!)
[301] type=friend secret=passw0rd qualify=yes port=5060 pickupgroup= nat=yes mailbox=301@default host=dynamic dtmfmode=rfc2833 dial=SIP/301 context=internal-sip canreinvite=no callgroup= callerid=device <301> accountcode= call-limit=50
[edit] The First Phone: Ekiga softphone
For testing, it will be convenient to have a phone at our first extension. There are many options for phones that can be attached to a SIP-based VOIP system like Asterisk. The least expensive and one of the easiest to configure is the Ekiga softphone which is included with most Linux distributions. Starting Ekiga for the first time, the user is lead through a sequence of setup menus. With the address of the router (192.168.1.1 by default), the extension number (301 for our first extension) and the extension password as defined in sip.conf (passw0rd), Ekiga will make a connection to the Asterisk server.
The connection can be tested by connecting to the Asterisk command line on the router:
asterisk -r
sip show peers
will show all sip connections to the server, including extensions and trunks to the VOIP provider. A connection for the softphone will produce an entry like:
301/301 192.168.1.143 D N 1024 OK (2 ms)
[edit] The Dialplan: Modifying extensions.conf
Be sure to enable modules in modules.conf to allow macros to work. Can test by running asterisk -r and looking for errors when making test calls. The working (non-minimal) modules.conf we used is:
; ; Asterisk configuration file ; ; Module Loader configuration file ; [modules] autoload=yes ; ; Any modules that need to be loaded before the Asterisk core has been ; initialized (just after the logger has been initialized) can be loaded ; using 'preload'. This will frequently be needed if you wish to map all ; module configuration files into Realtime storage, since the Realtime ; driver will need to be loaded before the modules using those configuration ; files are initialized. ; ; An example of loading ODBC support would be: ;preload => res_odbc.so ;preload => res_config_odbc.so ; noload => res_config_mysql.so ; noload => res_crypto.so ; Cryptographic Digital Signatures ; load => res_features.so ; Call Parking Resource noload => res_indications.so ; Indications Configuration noload => res_monitor.so ; Call Monitoring Resource ; load => res_musiconhold.so ; Music On Hold Resource noload => cdr_csv.so ; Comma Separated Values CDR Backend noload => cdr_custom.so ; Customizable Comma Separated Values CDR Backend noload => cdr_manager.so ; Asterisk Call Manager CDR Backend noload => cdr_mysql.so ; MySQL CDR Backend noload => cdr_pgsql.so ; PostgreSQL CDR Backend noload => cdr_sqlite.so ; SQLite CDR Backend noload => chan_alsa.so ; Channel driver for GTalk noload => chan_agent.so ; Agent Proxy Channel noload => chan_gtalk.so ; Channel driver for GTalk ; load => chan_iax2.so ; Inter Asterisk eXchange (Ver 2) ; load => chan_local.so ; Local Proxy Channel ; load => chan_sip.so ; Session Initiation Protocol (SIP) noload => codec_a_mu.so ; A-law and Mulaw direct Coder/Decoder noload => codec_adpcm.so ; Adaptive Differential PCM Coder/Decoder noload => codec_alaw.so ; A-law Coder/Decoder noload => codec_g726.so ; ITU G.726-32kbps G726 Transcoder ; load => codec_gsm.so ; GSM/PCM16 (signed linear) Codec Translation ; load => codec_ulaw.so ; Mu-law Coder/Decoder noload => codec_speex.so ; Speex/PCM16 (signed linear) Codec Translator noload => format_au.so ; Sun Microsystems AU format (signed linear) noload => format_g723.so ; G.723.1 Simple Timestamp File Format noload => format_g726.so ; Raw G.726 (16/24/32/40kbps) data noload => format_g729.so ; Raw G729 data ; load => format_gsm.so ; Raw GSM data noload => format_h263.so ; Raw h263 data noload => format_jpeg.so ; JPEG (Joint Picture Experts Group) Image ; load => format_pcm.so ; Raw uLaw 8khz Audio support (PCM) noload => format_pcm_alaw.so ; Raw aLaw 8khz PCM Audio support noload => format_sln.so ; Raw Signed Linear Audio support (SLN) noload => format_vox.so ; Dialogic VOX (ADPCM) File Format ; load => format_wav.so ; Microsoft WAV format (8000hz Signed Line ; load => format_wav_gsm.so ; Microsoft WAV format (Proprietary GSM) noload => app_alarmreceiver.so ; Alarm Receiver Application noload => app_authenticate.so ; Authentication Application noload => app_cdr.so ; Make sure asterisk doesn't save CDR noload => app_chanisavail.so ; Check if channel is available noload => app_chanspy.so ; Listen in on any channel noload => app_controlplayback.so ; Control Playback Application noload => app_cut.so ; Cuts up variables noload => app_db.so ; Database access functions ; load => app_dial.so ; Dialing Application noload => app_dictate.so ; Virtual Dictation Machine Application noload => app_directory.so ; Extension Directory noload => app_directed_pickup.so ; Directed Call Pickup Support noload => app_disa.so ; DISA (Direct Inward System Access) Application noload => app_dumpchan.so ; Dump channel variables Application ; load => app_echo.so ; Simple Echo Application noload => app_enumlookup.so ; ENUM Lookup noload => app_eval.so ; Reevaluates strings noload => app_exec.so ; Executes applications noload => app_externalivr.so ; External IVR application interface noload => app_forkcdr.so ; Fork The CDR into 2 seperate entities noload => app_getcpeid.so ; Get ADSI CPE ID noload => app_groupcount.so ; Group Management Routines noload => app_ices.so ; Encode and Stream via icecast and ices noload => app_image.so ; Image Transmission Application noload => app_lookupblacklist.so ; Look up Caller*ID name/number from black noload => app_lookupcidname.so ; Look up CallerID Name from local databas ; load => app_macro.so ; Extension Macros noload => app_math.so ; A simple math Application noload => app_md5.so ; MD5 checksum Application ; load => app_milliwatt.so ; Digital Milliwatt (mu-law) Test Application noload => app_mixmonitor.so ; Record a call and mix the audio during the recording noload => app_parkandannounce.so ; Call Parking and Announce Application ; load => app_playback.so ; Trivial Playback Application noload => app_privacy.so ; Require phone number to be entered noload => app_queue.so ; True Call Queueing noload => app_random.so ; Random goto noload => app_read.so ; Read Variable Application noload => app_readfile.so ; Read in a file noload => app_realtime.so ; Realtime Data Lookup/Rewrite noload => app_record.so ; Trivial Record Application ; load => app_sayunixtime.so ; Say time noload => app_senddtmf.so ; Send DTMF digits Application noload => app_sendtext.so ; Send Text Applications ; load => app_setcallerid.so ; Set CallerID Application noload => app_setcdruserfield.so ; CDR user field apps ; load => app_setcidname.so ; Set CallerID Name ; load => app_setcidnum.so ; Set CallerID Number noload => app_setrdnis.so ; Set RDNIS Number noload => app_settransfercapability.so ; Set ISDN Transfer Capability noload => app_sms.so ; SMS/PSTN handler noload => app_softhangup.so ; Hangs up the requested channel noload => app_stack.so ; Stack Routines noload => app_system.so ; Generic System() application noload => app_talkdetect.so ; Playback with Talk Detection noload => app_test.so ; Interface Test Application noload => app_transfer.so ; Transfer noload => app_txtcidname.so ; TXTCIDName noload => app_url.so ; Send URL Applications noload => app_userevent.so ; Custom User Event Application ; load => app_verbose.so ; Send verbose output noload => app_waitforring.so ; Waits until first ring after time noload => app_waitforsilence.so ; Wait For Silence Application noload => app_while.so ; While Loops and Conditional Execution ; load => func_callerid.so ; Caller ID related dialplan functions noload => func_enum.so ; ENUM Functions noload => func_uri.so ; URI encoding / decoding functions noload => pbx_ael.so ; Asterisk Extension Language Compiler ; load => pbx_config.so ; Text Extension Configuration noload => pbx_functions.so ; Builtin dialplan functions noload => pbx_loopback.so ; Loopback Switch noload => pbx_realtime.so ; Realtime Switch noload => pbx_spool.so ; Outgoing Spool Support noload => pbx_wilcalu.so ; Wil Cal U (Auto Dialer) ; ; Module names listed in "global" section will have symbols globally ; exported to modules loaded after them. ; [global] chan_modem.so=no
Add basic extension macro in the [globals] section of extensions.conf
[macro-stdexten];
; ${ARG1} - Extension (we could have used ${MACRO_EXTEN} here as well
; ${ARG2} - Device(s) to ring
;
exten => s,1,Dial(${ARG2},20) ; Ring the interface, 20 seconds maximum
exten => s,2,Goto(s-${DIALSTATUS},1) ; Jump based on status (NOANSWER,BUSY,CHANUNAVAIL,CONGESTION,ANSWER)
exten => s-NOANSWER,1,Voicemail(u${ARG1}) ; If unavailable, send to voicemail w/ unavail announce
exten => s-NOANSWER,2,Goto(default,s,1) ; If they press #, return to start
exten => s-BUSY,1,Voicemail(b${ARG1}) ; If busy, send to voicemail w/ busy announce
exten => s-BUSY,2,Goto(default,s,1) ; If they press #, return to start
exten => _s-.,1,Goto(s-NOANSWER,1) ; Treat anything else as no answer
exten => a,1,VoicemailMain(${ARG1}) ; If they press *, send the user into VoicemailMain
Finally, to allow incoming calls to reach our first extension, modify [5558888-in] in extensions.conf to read:
[5558888-in] exten => 5558888,1,Macro(stdexten,301,SIP/301)
Restart asterisk with /etc/init.d/asterisk and check that incoming and outgoing calls work.
[edit] Voicemail
From the local repository of Asterisk packages, install voicemail and sound packages:
opkg install asterisk14-voicemail* opkg install asterisk14-sounds*
If many optional packages have been installed, there may not be enough space left on the device flash drive and it will be necessary to remove some packages or direct packages to install to external storage as described here.
To allow extensions to reach their voice mailboxes, add to the end of extensions.conf
; Voicemail
exten => *97,1,VoiceMailMain(s${CALLERIDNUM})
exten => *97,2,Hangup
Add to the end of voicemail.conf for each extension an entry of the form:
301 => 301,OpenWRT Test,,,attach=no|saycid=no|envelope=no|delete=no
By now the router is almost out of storage space and it is a good idea to use the attached USB storage device for voicemail. The 1GB USB stick we used was automatically mounted at /mnt/sda1. For this configuration, modify the astspooldir variable in /etc/asterisk.conf to:
astspooldir => /mnt/sda1/var/spool/asterisk
and add the appropriate directory structure on the USB stick:
mkdir -p /mnt/sda1/var/spool/asterisk/voicemail/default
Restart asterisk
/etc/init.d/asterisk restart
and test the voicemail system. Voicemail can be recovered by dialing *97 on extension 301.
[edit] Extra extensions ---- Voice menus
Adding extra extensions to the system is easily done by adding stanzas to sip.conf so that Asterisk will recognize registration requests from SIP extension devices. Add an analogous extension definition immediately following the entry for 301. For example:
[302] type=friend secret=passw0rd qualify=yes port=5060 pickupgroup= nat=yes mailbox=302@default host=dynamic dtmfmode=rfc2833 dial=SIP/302 context=internal-sip canreinvite=no callgroup= callerid=device <302> accountcode= call-limit=50
The entry in sip.conf will allow new extensions to register, but changes need to be made in extensions.conf for calls to be routed to these extensions. One of the most simple ways to involve two extensions in incoming calls is to construct a rudimentary automated receptionist. In the example below, callers hear a beep and then are expected to press 1 to choose extension 301 or 2 for extension 302. After three incorrect tries, the receptionist drops the call. This is implemented by replacing the [555888-in] stanza in extensions.conf with
[5558888-in] exten => 5558888,1,Answer() exten => 5558888,2(start),SET(TRY=0) exten => 5558888,3,Playback(beep) exten => 5558888,4,WaitExten(3) exten => 5558888,5,Goto(start) exten => 5558888,6,Hangup exten => 1,1,Macro(stdexten,301,SIP/301) exten => 1,n,Hangup(3) exten => 2,1,Macro(stdexten,302,SIP/302) exten => 2,n,Hangup(3)
In order for extensions to call one another - complete with voicemail if busy or on the line- add the following to the end to extensions.conf
; Include calling internal extensions exten => 301,1,Macro(stdexten,301,SIP/301) exten => 301,n,Hangup(3) exten => 302,1,Macro(stdexten,302,SIP/302) exten => 302,n,Hangup(3)
For a more friendly calling experience, it is a good idea to have voice prompts to direct callers on how to use the menu system. The first step in getting this done is to add an extension whose job it is to record the caller's voice to a file. Adding this stanza to the end of extensions.conf will record calls on extension 205 to a particular file (/mnt/sda1/lib/asterisk/sounds/asterisk-recording.gsm) with gsm encoding. Pressing # will end the recording and then the system will playback what it has recorded.
; Record voice file to /tmp directory exten => 205,1,Wait(2) ; Call 205 to Record new Sound Files exten => 205,2,Record(/mnt/sda1/lib/asterisk/sounds/asterisk-recording:gsm) ; Press # to stop recording exten => 205,3,Wait(2) exten => 205,4,Playback(/mnt/sda1/lib/asterisk/sounds/asterisk-recording) ; Listen to your voice exten => 205,5,wait(2) exten => 205,6,Hangup
Be sure that the path for the recorded files exists:
mkdir -p /mnt/sda1/lib/asterisk/sounds
Restart Asterisk, record your greeting, then change the name of the file to something descriptive (without changing the file extension). We used choose.gsm
In order to use the new sound file in Asterisk just include a Playback command with the path to the file (the path is not necessary if the file is copied to the default sound file location: /usr/lib/asterisk/sounds). For example, we can personalize the automated receptionist above by changing the "beep" to a recorded greeting with instructions.
[5558888-in] exten => 5558888,1,Answer() exten => 5558888,2(start),SET(TRY=0) exten => 5558888,3,Playback(/mnt/sda1/lib/asterisk/sounds/choose) exten => 5558888,4,WaitExten(5) exten => 5558888,5,Goto(start) exten => 5558888,6,Hangup
[edit] Voicemail to e-mail
Install ssmtp mail server. This was possible on our system without running out of onboard flash storage. Installing the ssmtp package requires the libopenssl package be installed first. A configuration, /etc/ssmtp/ssmtp.conf that worked for our mail server which supports SSL encryption is:
root=mymailname@mydomain.com mailhub=smtp.mailserver.com:465 rewriteDomain=mydomain.com UseTLS=YES AuthUser=wl500gp@mydomain.com AuthPass=superpwd
In order to have voicemail sent out via e-mail, the voicemail.conf configuration needs to be adjusted to use the ssmtp mailer and tell Asterisk to attach the recorded message (attach=yes). A voicemail.conf that worked for us is:
; ; Voicemail Configuration ; [general] format=wav serveremail=asterisk attach=yes skipms=3000 maxsilence=10 silencethreshold=128 maxlogins=3 emaildateformat=%A, %B %d, %Y at %r mailcmd=/usr/sbin/ssmtp mymailname@mydomain.com -f asterisk@mydomain.com sendvoicemail=yes ; Allow the user to compose and send a voicemail while inside [zonemessages] eastern=America/New_York|'vm-received' Q 'digits/at' IMp central=America/Chicago|'vm-received' Q 'digits/at' IMp central24=America/Chicago|'vm-received' q 'digits/at' H N 'hours' military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p' european=Europe/Copenhagen|'vm-received' a d b 'digits/at' HM [default] 301 => 301,Test1,mymailname@mydomain.com,,attach=no|saycid=no|envelope=no|delete=no 302 => 302,Test2,myothermailname@mydomain.com,,attach=yes|saycid=no|envelope=no|delete=no
The other options for voicemail per extension are useful. For instance, the delete=yes option will delete the voicemail after sending it via e-mail.

