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@asterisk.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.