Wednesday, October 10, 2007

Configuring Asterisk with Voice Network Inc VoIP / SIP service

After installing Asterisk and subscribing to a VoIP DID and PSTN Gateway service the next step was to configure the Asterisk server to actually do some meaningful work.

So here was my basic plan: I would set up some simple 'softphone' software on the family's PCs, give them each an extension and mail box on the Asterisk, then connect the Asterisk to the 'Voice Network Inc' VoIP services.

Then I would configure the Asterisk to: allow calling between extensions (so I can take my laptop to work and call my wife's or daughter's extension just as though I was at home;) allow incoming calls to be answered by Asterisk which then prompts for the caller to enter an extension; allow any of the extensions to make outgoing calls over the PSTN Gateway.

Note: Since one must already know the extension to enter when calling, the first stage of this project will only be used for friends and family whom I provide the extension numbers to use. I will not have a default as yet, as there is no charge for incoming calls, so if telemarketers get frustrated trying to get a valid extension, and can't "zero out" to an operator, big deal ... they can just hang up. Maybe later on, if and when I'm ready to make it a more general access system I'll build a better menu system that allows others to access a "general extension" to ring an extension, or leave a voice mail, but for now that isn't a priority.

The first step was to get a 'softphone' to use for initial testing (later on if this works I can buy some hardware based IP phones, but for now free software based phones will do for what I need.) The most popular VoIP softphone seem to be the X-Lite softphone from CounterPath. You can download a version of X-Lite for Linux, Mac, or Windows.

So with those requirements in mind, here are the related configuration files (note, an Asterisk install usually comes with some example configuration files, the ones I modified I did so by renaming the long and detailed sample files and building my own from scratch. I'll get around to examining the samples as they probably have some good information in them for some of the more advanced features, but that's for later.)

I will use "numbers" to reference comments to prevent as many unnecessary and confusing line wraps as possible.

[globals] ;Note 1

; Edit your EXTENSIONS.CONF and place the following information in it
[voicenetwork-incoming] ;Note 2
exten => [Assigned DID],1,Goto(s,1) ;2a
exten => s,1,Answer() ;2b
exten => s,2,Wait(1) ;2c
exten => s,3,Background(vm-extension) ;2d
exten => s,4,WaitExten(15) ;2e
exten => i,1,Playback(pbx-invalid) ;2f
exten => i,2,Goto(voicenetwork-incoming,s,1) ;2g
exten => t,1,Playback(vm-goodbye) ;2h
exten => t,2,Hangup() ;2i
exten => 101,1,Dial(${USER1},10) ;2j
exten => 101,2,VoiceMail(u101@default) ;2k
exten => 101,3,Hangup() ;2l
exten => 101,102,VoiceMail(b101@default) ;2m
exten => 101,103,Hangup() ;2n
exten => 102,1,Dial(SIP/user2,10) ;2p
exten => 102,2,VoiceMail(u102@default) ;2q
exten => 102,3,Hangup() ;2r
exten => 102,102,VoiceMail(b102@default) ;2s
exten => 102,103,Hangup() ;2t
exten => 500,1,VoiceMailMain() ;2u

; To use to termination your calls
; add the following line to your extensions.conf file
[outbound-local] ; Note 3
exten => _9NXXXXXXXXX,1,Dial(SIP/voicenetwork_peer/${EXTEN:1})
exten => _9NXXXXXXXXX,2,Congestion()
exten => _9NXXXXXXXXX,102,Congestion()

[outbound-long-distance] ; Note 4
exten => _91NXXNXXXXXX,1,Dial(SIP/voicenetwork_peer/${EXTEN:1})
exten => _91NXXNXXXXXX,2,Congestion()
exten => _91NXXNXXXXXX,102,Congestion()
exten => _9011.,1,Dial(SIP/voicenetwork_peer/${EXTEN:1})
exten => _9011.,2,Congestion()
exten => _9011.,102,Congestion()


[internal] ; Note 5
include => outbound-local
include => outbound-long-distance
exten => 101,hint,SIP/user1
exten => 101,1,Dial(SIP/user1,10)
exten => 101,2,VoiceMail(u101@default)
exten => 101,3,Hangup()
exten => 101,102,VoiceMail(b101@default)
exten => 101,103,Hangup()
exten => 102,hint,SIP/user2
exten => 102,1,Dial(SIP/user2,10)
exten => 102,2,VoiceMail(u102@default)
exten => 102,3,Hangup()
exten => 102,102,VoiceMail(b102@default)
exten => 102,103,Hangup()
exten => 500,1,VoiceMailMain()
exten => 611,1,Echo()

; Note 6
exten = executecommand,1,System(${command})
exten = executecommand,n,Hangup()
exten = record_vmenu,1,Answer
exten = record_vmenu,n,Playback(vm-intro)
exten = record_vmenu,n,Record(${var1})
exten = record_vmenu,n,Playback(vm-saved)
exten = record_vmenu,n,Playback(vm-goodbye)
exten = record_vmenu,n,Hangup
exten = play_file,1,Answer
exten = play_file,n,Playback(${var1})
exten = play_file,n,Hangup
hasbeensetup = Y

plancomment = DialPlan1
include = default
include = parkedcalls
include = parkedcalls

Note 1: This is where you put global Variables. Global variables can save on typing and make reading the information more "human friendly". In this case I really only use one of these variables (USER1) later in the config file just to show how they work (see "2j".)

Note 2: This is the context to define what users in the voicenetwork-incoming context can do. Here's a detailed explanation:

exten => [Assigned DID],1,Goto(s,1) Replace "[Assigned DID]" with the phone number you selected when you purchased a DID from Voice Network Inc. This causes a call coming in on that "etension" to be transfered to the "s" extension at priority "1". Some VoIP SIP providers pass the phone number you purchased, some pass a special ID number. What I did in order to determine what was being sent was to set up a temporary voicenetwork-incoming context that had the following:
exten => _X.,1,Answer
exten => _X.,2,Wait(1)
exten => _X.,3,SayDigits(${EXTEN})
exten => _X.,4,Wait(1)
exten => _X.,6,Hangup
Which answers anything that comes in, speaks out the number it answered on, then hangs up. The Number it speaks is the number you need to use as the [Assigned DID]

exten => s,1,Answer() Answers the call

exten => s,2,Wait(1) Pause for a second

exten => s,3,Background(vm-extension) Ask use to enter an extension

exten => s,4,WaitExten(15) Wait for 15 seconds for the user to enter an extension

exten => i,1,Playback(pbx-invalid) The special "i" extension is called when a user enters an invalid extension. In this case it tells the caller they entered an invalid extension.

exten => i,2,Goto(voicenetwork-incoming,s,1) The caller is then sent back to the start: extension "s", priority "1".

exten => t,1,Playback(vm-goodbye) If a caller doesn't enter any extension number before the 15 second wait time, this causes a "timeout" and sends the process to the special "t" extension. It says "goodbye" to the users ...

exten => t,2,Hangup() ... and hangs up the call.

exten => 101,1,Dial(${USER1},10) If the user enters a valid extension, in this case if they enter the extension "101", they are taken to this section which dials the phone registered to user ${USER1} (USER1 is a global variable defined in the [globals] section that evaluates to "user1") for 10 seconds. If it is answered then it ends there, if not, after 10 seconds it goes to the next "priority" for that extension; in this case that is "priority" 2.

exten => 101,2,VoiceMail(u101@default) if the phone isn't answered within 10 seconds, the caller is sent to the voice mail define in the "voicemail.conf" file as voice mail box "101" in the "default" context. The "u101" reference plays a message to the caller telling them that the person at extension 101 is "unavailable" (ie. didn't pick up the ringing phone.) ...

exten => 101,3,Hangup() ... and then hangs up

exten => 101,102,VoiceMail(b101@default) This is similar to step "2k" in that it sends the caller to voice mail of the extension dialed. The difference here is that this step is reached only if the extension "rings busy", rather than simply is not picked up (ie. the user is already on the phone and has all the lines in use.) The "b101" tells the voice mail system to play the "user is busy, or already on a call" message when it takes the caller to to the voice mail system ...

exten => 101,103,Hangup() ... and then hangs up.

2p, 2q, 2r, 2s, and 2t are the same configuration as 2j,2k,2l,2m & 2n except they are for "user2" rather than "user1" (you can create more users by replicating these lines with a new user name, extension number, and voice mail box number.) The only notable difference is in step "2p" where instead of using the ${USER2} variable I use the full "SIP/user2" user definition.

Note 3: This is the context for regular outbound dialing to local 10 digit dialing (my area requires the complete 10 digits for even local dialing, some areas may only require 7 digits, they can change the line _9NXXXXXXXXX,1,Dial(SIP/voicenetwork_peer/${EXTEN:1}) to _9NXXXXXX,1,Dial(SIP/voicenetwork_peer/${EXTEN:1}) or add a new conext if they have local 7 digit dialing for your own area code and local 10 digit dialing for local calls to a different area code.

What that statement says is any number dialed that starts with "9", has the second number in the range of 2 to 9 ("N") followed by any other 6 digits, then send it to the "SIP/voicenetwork_peer" context with the first digit (the "9") removed (the ${EXTEN:1} macro.)

The next two lines are in case of any problems with sending the number to the outbound context. If the lines are all in use, you only dial 9 numbers, you dial 91xxxxxxxxx or 90xxxxxxxxx, or some other problem, you get the message that the number couldn't be dialed.

Note 4: Same as Note 3, except this allows those in this context to also dial long distance numbers (91* for North America long distance, and 9011* for international long distance.)

Note 5: This context is to determine what internal phones can do. First we add the outbound-local and outbound-long-distance contexts to this context to allow them to make outside calls. Then for each internal extension we configure what happens when an internal line dials that extension number: In this case we dial the number for 10 seconds, and fail over to voicemail then hang up just as we did in Step 2.


[general] ; Note 7
externip=[your external IP address] ;7a
localnet= ;7b
register => [peer number]:[password] ;7c

[user1] ; Note 8
type=friend ;8a
secret=[password] ;8b
nat=yes ;8c
host=dynamic ;8d
canreinvite=no ;8e
context=internal ;8f

[user2] ; Note 9

Note 7: The general context.

7a: This is your external IP address as seen by those out on the Internet. You will need this if you want anyone to initiate a connection from the Internet side. Not really needed for Voice Network Inc. to connect to you as you will be initiating the connection from your asterisk server To determine your external IP address, browse to or some similar website which will show you what address they see you as, or look at your routers "status page" which should (but doesn't always depending upon the ISP you use) show the same information.

7b: Your local IP subnet definition, hopefully you know what yours is, but on most home networks it is either or

7c: You get your peer number when you create one on the Voice Network Inc. website, and the password is the one you define in the "password" field when you configure that peer. Voice Network Inc has a "How-to-videos" section where they show the setup of a Trixbox configuration ... the first part of that video goes into how to create and configure the peer on the Voice Network Inc side of things. You can follow these instructions until they start talking about the Trixbox specifically as those instructions do not directly apply at that point.

Note 8: This section details the configuration of the typical internal IP phone.

8a: Use "friend" here, which simply means that the device both makes and receives connections from the Asterisk box.

8b: This password is one shared by the Asterisk server and the IP phone (the ID will be whatever is in the square brackets, which in this case is "user1". Use this information when configuring the IP phone.

8c: I set "nat=yes" by default as it seems to work even when the address isn't nat-ed ... I may find out later that this is a mistake somehow, but at this point it works, so until I learn otherwise so it shall stay, but this is a warning to those reading that I don't have a clue as to what I'm doing here.

8d: I believe that "dynamic" means that the IP address of the device is handled by DHCP. Again this is just guessing.

8e: "canreinvite=no" causes all communications to be forced to go through the asterisk server. The "yes" option means the asterisk sets up the call and then the two end-point IP devices start talking directly after that and only check back with the asterisk when needed. This is ok if there is no NAT in the way, but NAT ruins the whole process, so it is usually better in the case of a home system like this to just let everything stay connected to the asterisk server.

8f: "context=internal" put this user in the "internal context", which as we say earlier also puts them in the outbound-local and outbound-long-distance contexts as well.

Note 9: The same thing as Note 8, but for user2 this time.

; Make sure that you have checked the Send DID option under the EDIT DID option
; Edit your SIP.CONF file and place the following lines in it

[voicenetwork_peer] ; Note 10
context=voicenetwork-incoming ; incoming DID calls will arrive in the voicenetwork-incoming context

Note 10: Add this to your sip.conf file. You get this from Voice Netowrk Inc when you create a peer. After the peer is created, there will be a link in the "configuration example" called "asterisk", click on that to find this same information and a bit more, of which I have already explained in this post.

: (This file was one sample file I left alone, and just added the following lines to the default section.)

[default] ;Note 11

101 => [password],user1
102 => [password],user2
Note 11: This section "creates" the users voice mail, assigns the extension to the voicemail, and sets the password.

X-Lite Configuration: To be determined. I have a working configuration, but only for internal phones. I am having some trouble getting external phones to work fully, even if I connect using a VPN ... more on this later.

1 comment:

Anonymous said...

Hi All, This solution is great all work as described in the above post. Only issue i find is when it ask for the extension and you enter the number it goes directly to voicemeail ...