Redial: Interactive Telephony : Week 2
Asterisk 101: Voicemail, Asterisk Console, Basic Unix and more with the Dialplan
Asterisk Voicemail
Asterisk has a built-in voicemail system called "Comedian Mail". This is similar to built-in systems used by companies with other PBX systems installed and it allows message leaving, retrieval forwarding and so on. As with the rest of Asterisk the voicemail system is highly configurable (but perhaps not as configurable as developing your own system).
Voicemail Command
(for use in Dialplans)
VoiceMail([flags]boxnumber[@context][&boxnumber2[@context]][&boxnumber3])
Example:
exten => s,n,Voicemail(u10@redial); (Note: the "u" means play "unavailable" message.)
In my extensions.conf:
[sve204_voicemail]
exten => s,1,Voicemail(u10@redial_sve204); play "unavailable" message, box 10, redial_sve204 voicemail context.
exten => s,n,Goto(redial_sve204,s,1); go back to my main dialplan context
(You see that I created a new "context" for my voicemail (sve204_voicemail). I use a "goto" command in my main context to get to it.)
To create your own voicemail box on the asterisk system you need to create a file called NETID_voicemail.conf inside your asterisk_conf directory.
This file should contain something like the following:
[redial_NETID]
;extension_number => voicemail_password,user_name,user_email_address,user_pager_email_address,user_option(s)
10 => 10,sve204,sve204@nyu.edu,,attach=yes|serveremail=sve204@nyu.edu|tz=eastern|saycid=yes|callback=fromvm|operator=yes|envelope=yes
The first line is the voicemail "context". The next line is a comment which shows the syntax that you should use for any remaining lines.
For this class, you should use the "redial" context and set the "extension_number" the same as your extension. Since we are using our own contexts you can add in more voicemail extensions if you like.
In the Comedian mail system, voicemail messages are saved to a specific location on the file system.
/var/spool/asterisk/voicemail/context/boxnumber/INBOX/
My voicemail messages are therefore located here: /var/spool/asterisk/voicemail/redial/10/INBOX/
Looking in this directory, you will see that the naming convention for the files is pretty simple:
msg####.format starting with number 0.
Asterisik also saves data of the call in a text file. Furthermore, it converts the audio to multiple formats so you can use it in other ways on the server.
msg0000.gsm msg0000.txt msg0000.wav msg0000.WAV
More Information:
Asterisk Voicemail - voip-info.org
Asterisk cmd Voicemail - voip-info.org
Voicemail to Email
One of the most powerful features of the built-in voicemail system is that it can easily be configured to send any voicemail messages to email. This is our first foray into something that breaks us out of standard telephony applications and lets us doing more than is typical with phone systems.
The contents of the emailed message are follows:
Format String (in configuration, not per user or per context unfortunately): ${VM_NAME}\n${VM_DUR}\n${VM_MSGNUM}\n${VM_MAILBOX}\n${VM_CALLERID}\n${VM_DATE}
This is all of the variables that are available in the built-in system. I configured it to put a line break in between each variable and to attach the audio file of the message itself.
This results in messages that have a body as follows:
sve204
0:07
2
10
"7188096659" <17188096659>
Wednesday, September 13, 2006 at 01:51:57 AM
If we need to come up with a different format for specific uses, we can change this but since we all have to use the same format I don't want to change it around too much or too many times.
What can you do with this?
I have used this system in the past to automatically post audio to my blog.
This Perl script automatically downloads email from a specific mailbox and uses something called "XML-RPC" to post the messages to a blog:
Parse Mail Script
Many companies out there do something similar:
Audioblogger (defunct?)
gabcast
audblog (defunt? apparently they come and go)
Voicemail Management
Asterisk has another command "VoiceMailMain()" which allows a caller into the management portion of the voicemail system.
VoiceMailMain(mailbox@context[|options])
Example:
exten => a,1,VoiceMailMain(10@redial);
Notice the "a" extension listed above. If you are in the normal VoiceMail application and you press the asterisk "*", it will kick you out to where you came from but with the extension "a". I am using this to put the caller into the VoiceMailMain application.
Full Example:
[sve204_voicemail]
exten => s,1,Voicemail(u10@redial_sve204);
exten => s,n,Goto(redial_sve204,s,1);
exten => a,1,VoiceMailMain(10@redial_sve204);
exten => s,n,Goto(redial_sve204,s,1);
One of the options that is particularly useful in the VoiceMailMain application is the ability to record personal messages to playback for different purposes:
This is where the "flags" when going to the VoiceMail command come in handy. Check this page for a rundown: Asterisk cmd VoiceMail - voip-info.org
Try it out!
More Information:
Asterisk cmd VoiceMailMain - voip-info.org
Basic Unix
Since Asterisk is a young project and doesn't yet have a good fully developed GUI we are going to need to have a bit of experience with the *nix command line to work with it.
Some useful commands for working with Asterisk:
ssh netid@social.itp.tsoa.nyu.edu - Log into social via SSH (secure shell).
ls - List the contents of the current working directory. ls -al ~
cd - Change directories. cd / OR cd someotherdir
ln -s - Create a symbolic link. ln -s /var/log/asterisk/ asterisk_logs OR ln -s /var/spool/asterisk/voicemail/ asterisk_voicemail
less textfile - Page through a text file.
cp onefile anotherfile - Copy a file to a new file.
rm something - Delete a file.
pwd - Where am I.
chmod - Change permissions on a file.
chown - Change the owner of a file.
chgrp - Chage the group of a file. Same as change user but for groups.
More Information:
Webmonkey | Reference: Unix Guide
Recording Audio for Asterisk
Software
Perhaps the best utility for recording audio on your computer is Audacity (I say the "best" because it is cross platform, open source and works very well.)
Unfortunately, while Audacity is great at what it does, the formats that it can save audio files to aren't ideal for telephony applications. By default Asterisk "likes" audio files that encoded with the GSM codec (which uses only 13 kbps and has a sample rate of 8kHz).
This is not to say that Asterisk can't deal with WAV or other types of files (it can in some cases) but for transmission over VoIP connections those formats will have to be converted on the fly which uses processing power and you can't be sure of the results.
Fortunately we have an application called SoX (Sound eXchange) installed on the server to help you out.
Command:
sox originalfile.wav -r 8000 -c1 newfile.gsm
The "-r 8000" means resample the file. "-c1" means only one channel in the output file (just in case you start with a stereo file).
SoX has a lot more capabilities as well which you will find out about in your reading.
To use your brand new sound with Asterisk, you should copy it into your Asterisk Sounds directory (asterisk_sounds):
When you call it up for playback you must use the full path (minus the extension).
exten => s,n,Playback(/home/sve204/asterisk_sounds/mynewsound.gsm);
It is probably also a good idea to change the group and permissions of the file if you later want to have Asterisk modify it in some way.
chgrp asterisk /home/sve204/asterisk_sounds/mynewsound.gsm
chmod 664 /home/sve204/asterisk_sounds/mynewsound.gsm
More Information:
SoX - Sound eXchange
Hacks 24, 25 and 26 from O'Reilly's VoIP Hacks book
Asterisk Console
As I mentioned previously, I am not terribly fond of any of the Asterisk GUI attempts. Therefore, we are going to learn the command line means to playing with a running instance of Asterisk (hence all of the Unix background knowledge and so forth).
To enter the CLI (Command Line Interface) for Asterisk (the console), issue the following command:
/usr/sbin/asterisk -r
You should see something like this:
Asterisk 1.4.10.1, Copyright (C) 1999 - 2007 Digium, Inc. and others.
Created by Mark Spencer
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk 1.4.10.1 currently running on asterisk (pid = 15927)
Verbosity is at least 3
asterisk*CLI>
At the prompt you can enter commands. Probably the best one to start with is "help" which will give you a long list of commands and a short description of each. You can get more information about any particular command by typing:
help command_name
Some commands in particular that you should learn and learn well are:
help
exit - gets you out of the Asterisk CLI
reload - reloads the configuration (but not as good as hitting the web page I setup).
sip set debug - gives you all kinds of information regarding SIP processes (the means we are using to communication with our TSP).
sip set debug off - when you get sick of all of that information.
Other Useful commands that you might want to try (stay away from the restart and stop commands please)
! Execute a shell command
core set global Set global dialplan variable
core set verbose Set level of verboseness
core show applications Shows registered dialplan applications
core show application Describe a specific dialplan application
core show audio codecs Displays a list of audio codecs
core show channels Display information on channels
core show channel Display information on a specific channel
core show channeltypes List available channel types
core show channeltype Give more details on that channel type
core show codecs Displays a list of codecs
core show codec Shows a specific codec
core show config mappings Display config mappings (file names to config engines)
core show file formats Displays file formats
core show file version List versions of files used to build Asterisk
core show functions Shows registered dialplan functions
core show function Describe a specific dialplan function
core show globals Show global dialplan variables
core show hints Show dialplan hints
core show license Show the license(s) for this copy of Asterisk
core show profile Display profiling info
core show switches Show alternative switches
core show threads Show running threads
core show translation Display translation matrix
core show uptime Show uptime information
core show version Display version info
core show warranty Show the warranty (if any) for this copy of Asterisk
dialplan reload Reload extensions and *only* extensions
dialplan show Show dialplan
feature show Lists configured features
feature show channels List status of feature channels
file convert Convert audio file
group show channels Display active channels with group(s)
help Display help list, or specific help on a command
http show status Display HTTP server status
indication add Add the given indication to the country
indication remove Remove the given indication from the country
indication show Display a list of all countries/indications
local show channels List status of local channels
logger mute Toggle logging output to a console
logger reload Reopens the log files
logger rotate Rotates and reopens the log files
logger show channels List configured log channels
mixmonitor Execute a MixMonitor command.
module show List modules and info
module show like List modules and info
moh reload Music On Hold
moh show classes List MOH classes
moh show files List MOH file-based classes
no debug channel
originate Originate a call
sip set debug Enable SIP debugging
sip set debug ip Enable SIP debugging on IP
sip set debug off Disable SIP debugging
sip set debug peer Enable SIP debugging on Peername
sip show channels List active SIP channels
sip show channel Show detailed SIP channel info
sip show domains List our local SIP domains.
sip show history Show SIP dialog history
sip show inuse List all inuse/limits
sip show peers List defined SIP peers
sip show peer Show details on specific SIP peer
sip show registry List SIP registration status
sip show settings Show SIP global settings
sip show subscriptions List active SIP subscriptions
sip show users List defined SIP users
sip show user Show details on specific SIP user
soft hangup Request a hangup on a given channel
voicemail show users List defined voicemail boxes
voicemail show zones List zone message formats
Probably the most useful part of having access to the console is being able to debug your dialplan.
When a call comes in you start to see output such as this:
-- Executing Playback("SIP/vanevery-7716", "beep") in new stack
-- Playing 'beep' (language 'en')
-- Executing VoiceMail("SIP/vanevery-7716", "u10@testingtesting") in new stack
-- Playing 'vm-theperson' (language 'en')
-- Playing 'digits/1' (language 'en')
-- Playing 'digits/0' (language 'en')
-- Playing 'vm-isunavail' (language 'en')
-- Playing 'vm-intro' (language 'en')
-- Playing 'beep' (language 'en')
-- Recording the message
-- x=0, open writing: /var/spool/asterisk/voicemail/testingtesting/10/INBOX/msg0002 format: wav49, 0x8869280
-- x=1, open writing: /var/spool/asterisk/voicemail/testingtesting/10/INBOX/msg0002 format: gsm, 0x886d080
-- x=2, open writing: /var/spool/asterisk/voicemail/testingtesting/10/INBOX/msg0002 format: wav, 0x88780c0
You will also see error messages which helps immensly when trying to debug a problematic dialplan.
Dialplan
You all now have some familiarity with the Asterisk Dialplan. It is what you are using to construct the logic that occurs when a call comes to your extension.
Generally the dialplan is defined in a configuration file called: /etc/asterisk/extensions.conf. For us, I am dynamically including each of your dialplan files into this file when we "reload" asterisk through the web page that was setup. For all practical purposes, you are directly editing that file when you write your own dialplan files.
Let's revisit some of the dialplan concepts we talked about last week:
Context
A context is a central idea to asterisk dialplans. It defines a section of the dialplan that any incoming or outgoing call is executing. There can be hundreds of contexts defined and logic within those contexts can move calls from one to another.
For instance, when a call comes in via our number, it is put into the context that our SIP service is registered to:
[2127960729]
This context is defined in extensions.conf if you want to have a look.
This context does a couple of things but most important is that it asks the caller for an extension and then uses the "Goto()" command based on the extension that was entered to send the call to another context (the ones we have defined).
exten => 10,1,Goto(redial_sve204,s,1);
If they enter extension 10, it goes into the context that I have defined for myself with the "s" extension for start and to the command with priority 1.
Extensions
Extensions are the means that asterisk uses to match a command within a context. There are a couple of special extensions as follows:
s - The "start" or "special" extension. Where things generally start within a context. More
t - The "timeout" extension. If a Digit or Response timeout has occurred. More
i - The "invalid" extension. If the user enters an extension that isn't matched. More
h - The "hangup" extension. Executes after a call has hungup. More
Priority
Within a context and an extension Asterisk uses priorities to determine which command to run.
Generally these go in order from 1 to 2 and so on. Last week we talked about the "n" priority which is essentially the previous priority + 1 which makes it much easier to work with dialplans.
[2127960729]
exten => s,1,Answer();
exten => s,n,Wait(1);
exten => s,n,Background(vm-extension);
exten => s,n,WaitExten(10);
exten => t,1,Goto(s,3);
exten => i,1,Playback(invalid);
exten => i,n,Goto(s,3);
exten => 10,1,Goto(redial_sve204,s,1);
exten => 11,1,Goto(redial_slb414,s,1);
;and so on..
There is also the ability to label priorities which allows you to jump to priorities without knowing the number (such as when you use the "n" priority). This would makes Goto commands easier to deal with:
[2127960729]
exten => s,1,Answer();
exten => s,n,Wait(1);
exten => s,n(PlayExtension),Background(vm-extension); Defines the PlayExtension label
exten => s,n,WaitExten(10);
exten => t,1,Goto(s,PlayExtension); Go to the PlayExtension label instead of priority 3
exten => i,1,Playback(invalid);
exten => i,n,Goto(s,PlayExtension); Go to the PlayExtension label instead of priority 3
exten => 10,1,Goto(redial_sve204,s,1);
exten => 11,1,Goto(redial_slb414,s,1);
;and so on..
More Information:
Asterisk Priorities - voip-info.org
Variables
You can use variables in the dialplan to have greater flow control over a dialplan.
[2127960729]
exten => s,1,NoOp,${CALLERID(NAME)}
exten => s,n,Set(TIMEOUT(digit)=5); Global TIMEOUT variable for digits
exten => s,n,Set(TIMEOUT(response)=10); Global TIMEOUT variabe for response time
exten => s,n,Set(TIMEOUT(absolute)=600); Global TIMEOUT variable for total call length
exten => s,n,Set(numtimeouts=0); Local variable, nutimeouts that keeps track of number of timeouts
exten => s,n,Answer();
exten => s,n,Wait(1);
exten => s,n(PlayExtension),Background(vm-extension);
exten => s,n,WaitExten(10);
exten => t,1,Set(numtimeouts=$[${numtimeouts} + 1]); Update the numtimeouts variable
exten => t,n,GotoIf($[${numtimeouts} >= 4]?999,1); If the number of timeouts is greater than 4 jump to extension 999
exten => t,1,Goto(s,PlayExtension);
exten => t,n,Goto(s,PlayExtension);
exten => i,1,Playback(invalid);
exten => i,n,Goto(s,PlayExtension);
exten => 10,1,Goto(redial_sve204,s,1);
exten => 11,1,Goto(redial_slb414,s,1);
;and so on..
exten => 999,1,Hangup(); Hangup if they get here
exten => T,1,Hangup(); Absolute Timeout occurred
Variable Name: numtimeouts
Set a variable: Set(numtimeouts=0)
Retrieve a variable: ${numtimeouts}
Use a variable in an expression: $[${numtimeouts} + 1]
Lots More Information: Asterisk variables - voip-info.org
Applications and Commands
Rather than go in-depth into all of the applications available this week, I would rather you explored them on your own. Here are some suggestions for exploration:
Answer, Wait, DigitTimeout, ResponseTimout, Background, Playback, Goto, GotoIf, Hangup, DateTime, Record, Monitor, NoOp, GotoIfTime
Here is a handy dandy list of some obtained through the show applications command on the console:
(Don't forget Appendix B in the Asterisk book as well as the voip-info.org wiki
-= Registered Asterisk Applications =-
Answer: Answer a channel if ringing
BackGround: Play an audio file while waiting for digits of an extension to go to.
BackgroundDetect: Background a file with talk detect
Busy: Indicate the Busy condition
ChangeMonitor: Change monitoring filename of a channel
ChanIsAvail: Check channel availability
ChannelRedirect: Redirects given channel to a dialplan target.
ChanSpy: Listen to a channel, and optionally whisper into it
Congestion: Indicate the Congestion condition
ContinueWhile: Restart a While loop
ControlPlayback: Play a file with fast forward and rewind
DateTime: Says a specified time in a custom format
Dial: Place a call and connect to the current channel
Dictate: Virtual Dictation Machine
Directory: Provide directory of voicemail extensions
DumpChan: Dump Info About The Calling Channel
EAGI: Executes an EAGI compliant application
Echo: Echo audio, video, or DTMF back to the calling party
EndWhile: End a while loop
Exec: Executes dialplan application
ExecIf: Executes dialplan application, conditionally
ExecIfTime: Conditional application execution based on the current time
ExitWhile: End a While loop
ExtenSpy: Listen to a channel, and optionally whisper into it
Gosub: Jump to label, saving return address
GosubIf: Conditionally jump to label, saving return address
Goto: Jump to a particular priority, extension, or context
GotoIf: Conditional goto
GotoIfTime: Conditional Goto based on the current time
Hangup: Hang up the calling channel
HasNewVoicemail: Conditionally branches to priority + 101 with the right options set
HasVoicemail: Conditionally branches to priority + 101 with the right options set
ImportVar: Import a variable from a channel into a new variable
Log: Send arbitrary text to a selected log level
LookupCIDName: Look up CallerID Name from local database
Macro: Macro Implementation
MacroExclusive: Exclusive Macro Implementation
MacroExit: Exit From Macro
MacroIf: Conditional Macro Implementation
MailboxExists: Check to see if Voicemail mailbox exists
Milliwatt: Generate a Constant 1000Hz tone at 0dbm (mu-law)
MixMonitor: Record a call and mix the audio during the recording
Monitor: Monitor a channel
Morsecode: Plays morse code
MP3Player: Play an MP3 file or stream
MusicOnHold: Play Music On Hold indefinitely
NoCDR: Tell Asterisk to not maintain a CDR for the current call
NoOp: Do Nothing
PauseMonitor: Pause monitoring of a channel
Playback: Play a file
PlayTones: Play a tone list
Random: Conditionally branches, based upon a probability
Read: Read a variable
Record: Record to a file
RetryDial: Place a call, retrying on failure allowing optional exit extension.
Return: Return from gosub routine
Ringing: Indicate ringing tone
SayAlpha: Say Alpha
SayDigits: Say Digits
SayNumber: Say Number
SayPhonetic: Say Phonetic
SayUnixTime: Says a specified time in a custom format
SendDTMF: Sends arbitrary DTMF digits
Set: Set channel variable(s) or function value(s)
SetCallerID: Set CallerID
SetCallerPres: Set CallerID Presentation
SetCDRUserField: Set the CDR user field
SetGlobalVar: Set a global variable to a given value
SetMusicOnHold: Set default Music On Hold class
SetTransferCapability: Set ISDN Transfer Capability
SoftHangup: Soft Hangup Application
StartMusicOnHold: Play Music On Hold
StopMixMonitor: Stop recording a call through MixMonitor
StopMonitor: Stop monitoring a channel
StopMusicOnHold: Stop Playing Music On Hold
StopPlayTones: Stop playing a tone list
System: Execute a system command
Transfer: Transfer caller to remote extension
TryExec: Executes dialplan application, always returning
TrySystem: Try executing a system command
UnpauseMonitor: Unpause monitoring of a channel
Verbose: Send arbitrary text to verbose output
VMAuthenticate: Authenticate with Voicemail passwords
VoiceMail: Leave a Voicemail message
VoiceMailMain: Check Voicemail messages
Wait: Waits for some time
WaitExten: Waits for an extension to be entered
WaitForRing: Wait for Ring Application
WaitForSilence: Waits for a specified amount of silence
WaitMusicOnHold: Wait, playing Music On Hold
While: Start a while loop
Next week we will get into Macros, Pattern Matching, MusicOn Hold, Database Interaction, Outbound Calling (Dial), MP3Player, Queues, Conference Rooms, Streaming, System Commands and so on.