Redial: Interactive Telephony : Week 2
Asterisk 101: Voicemail, Manager Interface, 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 the Comedian mail system, voicemail messages are saved to a specific location on the file system.
/var/spool/asterisk/voicemail/context/boxnumber/INBOX/
For this class, we are using the "redial" context and the "boxnumber" is your extension. I also set your passwords to be the same as your extension (I think you can change this through the "VoiceMailMain" interface).
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.
For this class, I have pre-configured Asterisk to email voicemail messages to your NET-ID@nyu.edu. This can obviously change and you should mark the wiki page with the email address you would like to use instead.
StudentExtensions Wiki Page
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
gabcast
ifbyphone
audblog
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:
[redial_sve204]
exten => s,1,Wait(1);
exten => s,n,SayDigits(${CALLERIDNUM});
exten => s,n,Playback(beep);
exten => s,n,Voicemail(u10@redial);
exten => s,n,Hangup();
exten => a,1,VoiceMailMain(10@redial);
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 resample -ql
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). "resample -ql" means to use a higher quality algorithm for the conversion that the default.
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 in the Asterisk Sounds directory:
/var/lib/asterisk/sounds/
This allows you to call it by name (minus the extension and directory).
exten => s,n,Playback(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 /var/lib/asterisk/sounds/mynewsound.gsm
chmod 664 /var/lib/asterisk/sounds/mynewsound.gsm
More Information:
SoX - Sound eXchange
Hacks 24, 25 and 26 from O'Reilly's VoIP Hacks book
Asterisk Manager Interface
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) Asterisk Manager Interface, issue the following command:
/usr/sbin/asterisk -r
You should see something like this:
Asterisk 1.2.4, Copyright (C) 1999 - 2006 Digium, Inc. and others.
Created by Mark Spencer
Asterisk comes with ABSOLUTELY NO WARRANTY; type '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 'show license' for details.
=========================================================================
Connected to Asterisk 1.2.4 currently running on social (pid = 27680)
Verbosity is at least 3
social*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 debug - gives you all kinds of information regarding SIP processes (the means we are using to communication with our TSP).
sip no debug - 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)
add extension Add new extension into context
cdr status Display the CDR status
debug channel Enable debugging on a channel
debug level Set global debug level
extensions reload Reload extensions and *only* extensions
help Display help list, or specific help on a command
include context Include context in other context
local show channels Show status of local channels
logger reload Reopens the log files
logger rotate Rotates and reopens the log files
logger show channels List configured log channels
no debug channel Disable debugging on a channel
reload Reload configuration
remove extension Remove a specified extension
remove ignorepat Remove ignore pattern from context
restart gracefully Restart Asterisk gracefully
restart now Restart Asterisk immediately
restart when convenient Restart Asterisk at empty call volume
save dialplan Save dialplan
set debug Set level of debug chattiness
set verbose Set level of verboseness
show applications Shows registered dialplan applications
show application Describe a specific dialplan application
show audio codecs Shows audio codecs
show channel Display information on a specific channel
show channels Display information on channels
show channeltypes Show available channel types
show codecs Shows codecs
show codec Shows a specific codec
show config mappings Show Config mappings (file names to config engines)
show dialplan Show dialplan
show features Lists configured features
show file formats Displays file formats
show functions Shows registered dialplan functions
show function Describe a specific dialplan function
show hints Show dialplan hints
show license Show the license(s) for this copy of Asterisk
show manager command Show a manager interface command
show manager commands List manager interface commands
show manager connected Show connected manager interface users
show modules List modules and info
show modules like List modules and info
show parkedcalls Lists parked calls
show queue Show status of a specified queue
show queues Show status of queues
show switches Show alternative switches
show translation Display translation matrix
show uptime Show uptime information
show version Display version info
show version files Show versions of files used to build Asterisk
show voicemail users List defined voicemail boxes
show voicemail zones List zone message formats
show warranty Show the warranty (if any) for this copy of Asterisk
sip debug Enable SIP debugging
sip debug ip Enable SIP debugging on IP
sip debug peer Enable SIP debugging on Peername
sip history Enable SIP history
sip no debug Disable SIP debugging
sip no history Disable SIP history
sip notify Send a notify packet to a SIP peer
sip reload Reload SIP configuration
sip show channels Show 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 objects Show all SIP object allocations
sip show peer Show details on specific SIP peer
sip show peers Show defined SIP peers
sip show registry Show SIP registration status
sip show settings Show SIP global settings
sip show subscriptions Show active SIP subscriptions
sip show users Show defined SIP users
sip show user Show details on specific SIP user
soft hangup Request a hangup on a given channel
stop gracefully Gracefully shut down Asterisk
stop now Shut down Asterisk immediately
stop when convenient Shut down Asterisk at empty call volume
Probably the most useful part of having access to the manager interface 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: 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:
[2127960961]
This context is defined in itp_jnctn_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.
[2127960961]
exten => s,1,NoOp,${CALLERIDNAME}
exten => s,n,Answer();
exten => s,n,Wait(1);
exten => s,n,DigitTimeout(5);
exten => s,n,ResponseTimeout(10);
exten => s,n,Background(vm-extension);
exten => t,1,Goto(s,4);
exten => i,1,Playback(invalid);
exten => i,n,Goto(s,4);
exten => 10,1,Goto(redial_sve204,s,1);
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 make my Goto commands easier to deal with:
[2127960961]
exten => s,1,NoOp,${CALLERIDNAME}
exten => s,n,Answer();
exten => s,n,Wait(1);
exten => s,n,DigitTimeout(5);
exten => s,n,ResponseTimeout(10);
exten => s,n(play_extension),Background(vm-extension);
exten => t,1,Goto(s,play_extension);
exten => i,1,Playback(invalid);
exten => i,n,Goto(s,play_extension);
exten => 10,1,Goto(redial_sve204,s,1);
More Information:
Asterisk Priorities - voip-info.org
Variables
You can use variables in the dialplan to have greater flow control over a dialplan.
[2127960961]
exten => s,1,NoOp,${CALLERIDNAME}
exten => s,n,Set(numtimeouts=0);
exten => s,n,Answer();
exten => s,n,Wait(1);
exten => s,n,DigitTimeout(5);
exten => s,n,ResponseTimeout(10);
exten => s,n(PlayExtension),Background(vm-extension);
exten => t,1,Set(numtimeouts=$[${numtimeouts} + 1]);
exten => t,n,GotoIf($[${numtimeouts} >= 4]?999,1);
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);
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 Manager Interface:
(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 a file while awaiting extension
BackgroundDetect: Background a file with talk detect
Busy: Indicate the Busy condition
ChangeMonitor: Change monitoring filename of a channel
ControlPlayback: Play a file with fast forward and rewind
DateTime: Says a specified time in a custom format
DigitTimeout: Set maximum timeout between digits
Echo: Echo audio read back to the user
EndWhile: End A While Loop
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
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
NoOp: Do Nothing
Playback: Play a file
PlayTones: Play a tone list
Read: Read a variable
Record: Record to a file
ResponseTimeout: Set maximum timeout awaiting response
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
SetCIDName: Set CallerID Name
SetCIDNum: Set CallerID Number
SetGlobalVar: Set a global variable to a given value
SetVar: Set channel variable(s)
StopMonitor: Stop monitoring a channel
StopPlayTones: Stop playing a tone list
Verbose: Send arbitrary text to verbose output
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
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.