One huge expense that most companies (small and large) have to absorb at one point or another is the cost of a phone system (PBX). PBX systems are extremely expensive (even systems that only support a few users can cost upwards of $10,000 USD).
As most companies rely on phone communications, this expense cannot be avoided. The benefits of having a PBX are numerous and necessary:
So how can you save money for your company? Switch to Asterisk, the open source PBX.
Asterisk is an extremely popular open source PBX system. It costs nothing, can be installed on almost any computer system, and is stable and reliable. Equally important is the fact that Asterisk has a large user base, a plethora of documentation, and tons of developers and consultants who can help you set it up (even if you aren’t a tech person) for cheap.
So, let’s get down to business. Here are 5 ways that Asterisk can save your company money:
Obviously, the factor which drives most companies to ditch their current PBX is cost. Asterisk is free, and it is hard to justify paying $10,000 or more for a small office phone system when the competition offers better functionality, reliability, and costs nothing.
With most commercial PBX systems, you have to buy into the licensing schemes that come with them. For example, check out the Shoretel PBX system price list [pdf] (effective Jan. 1st, 2010).
Look at those licenses. Every phone you want to hook up requires an extension license and voicemail license. And it isn’t cheap, either.
My thought is: Why pay recurring costs just to use a phone? You’ve already got to pay for phone service, why not only pay for your hardware, and be done with it?
With Asterisk, you’ll be paying only for your hardware. This usually includes:
If you want to add a new employee to the system and get a phone, no problem. Just buy another phone, and plug it into the network.
If you need to support video calls, no problem. Just purchase a video phone, and plug it into the network.
Let’s face it, traditional business is dying out. With high-speed internet widely available, there is no reason to have a centralized office. There is a continuously growing amount of new companies which are completely distributed.
There are a lot of benefits to running a distributed business. You have no office rental costs. You can hire better workers by selecting from a larger area (get the best expert in the US instead of the best expert in your city). And lots of other things.
Supporting remote workers couldn’t be easier in Asterisk. Just ship your employees a VoIP phone with the IP of your Asterisk PBX programmed in, and they’re instantly online. All they have to do is plug their phone into their network and they’re ready to work.
With traditional PBX systems, getting unique and custom functionality can be not only time consuming, but very expensive. And unfortunately, customizing PBX systems is a very common need for most companies.
Here are some custom features that companies like to request:
Obviously, things like the above require custom development. When dealing with large companies (Cisco, Avaya, Shoretel), custom development is insanely expensive.
Asterisk has an extremely active business community, filled with thousands of products specifically designed to work with Asterisk to add almost any functionality you can imagine to your PBX. Let’s say you want to have a queue system where callers call in, and the system calls them back automatically when it is their turn in line–there’s an app for that!
And if you can’t find an app for what you need, you can always build it yourself, or hire an Asterisk developer for cheap online.
Asterisk is a game changing tool for small and medium businesses. It allows your small company to operate like a large company, free.
Many small companies get stuck in the ’small business syndrome’ where they never grow beyond a small market audience because their ‘presentation’ is small. When customers call your company, and hear a professional auto attendant, they instantly feel like they’re dealing with a professional, organized company. When customers call a business, and wait for 50 rings before hearing a choppy sounding answering machine, they are annoyed, frustrated, and far less likely to return.
Asterisk is a great tool for companies looking to save money, and improve their communications infrastructure. It has all the functionality (and more) that large PBX companies (Cisco, Avaya, Shoretel) advertise, and costs nothing.
If you want to learn more, check out Asterisk’s official website.
Welcome back to the Transparent Telephony series. If you’re a new reader, you may want to start at the beginning: Part 1 – An Introduction.
In the previous installment, we walked through installing Asterisk. In this article, we’ll be picking up where we left off and configuring Asterisk to make and receive phone calls using VoIP!
Specifically, we’ll:
So let’s get started!
The first thing we need to do is sign up with a VoIP (voice over IP) provider. To quote from Part 1 – An Introduction,
VoIP (voice over IP) is a relatively new way to connect to the PSTN using the Internet. VoIP is extremely low-cost compared to other methods, and very easy to set up as it only requires an active Internet connection to use. More and more businesses are switching over to VoIP for cost reasons.
There are two main types of VoIP protocols that people use with Asterisk. There is SIP (session initiation protocol) and IAX (inter-asterisk exchange). While both of these protocols are still widely in use, SIP has become the dominant VoIP protocol in today’s world. In fact, the term SIP has mostly replaced VoIP. When speaking to people in the telephony industry, it is common to hear people say ‘I have so and so as my SIP provider’. So from now on, we’ll use that terminology as well.
Picking a SIP provider is a very important task. If you Google for ‘SIP providers’ you’ll find thousands of options. Here are the top few I recommend (I’ve experimented with tons of different SIP providers):
Flowroute is my favorite SIP provider because they have a great website, low prices, and business-class reliability. So instead of walking through the set up for each of the above providers (that would take forever) I’ll just cover Flowroute. If you choose to go with another provider, you can still follow along with this article and get a sense of what to do.
To create an account with Flowroute, visit their sign up page and fill in your information. You don’t need a credit card, and they’ll give you 25 cents of credit (enough to make approximately 30 minutes of calls). If you want to be able to receive calls as well as make them, then you’ll have to deposit some money into your account as you’ll need to own a DID (more commonly known as phone number) which costs a bit more than 25 cents.
Once your account has been created, you’ll be directed to the account dashboard:
Where if you want, you can deposit some money via Amazon Payments.
In the telephony world, SIP accounts are commonly referred to as SIP trunks. Trunk meaning a single account connection to the PSTN.
Now that we’ve got a SIP trunk ready for us to use, we need to hook it up to our Asterisk PBX. To get started, go to your Flowroute account management page, and navigate to the ‘Interconnection’ page, then click on the ‘System Configurator’ link towards the middle of the page. Next click on the drop down menu and select ‘Asterisk’ as this is what we’re using. The System Configurator will give us all of the Asterisk settings we need to put into our PBX (with only slight modifications required). You should now see a page that looks like this:
Never ever give out any of your SIP account information! If someone knows your secret and account number, they can easily connect your SIP trunk to their PBX, and begin placing calls on your tab! This happens frequently as many system administrators are not familiar with VoIP security, and don’t know what information is valuable, and what isn’t.
A good deal of phone scams and telemarketing campaigns originate from hacked SIP accounts, so be careful!
If you read your System Configurator page, the first thing you’ll notice is a section labeled sip.conf. The file sip.conf (located at: /etc/asterisk/sip.conf) is the SIP configuration file that Asterisk uses to define SIP trunks, and other SIP settings. In order to connect our Flowroute SIP trunk to Asterisk, we’ll need to edit this file and add in the SIP trunk information specified on the System Configurator page of the Flowroute account dashboard.
The first bit of the Flowroute instructions say:
Add the following to the sip.conf right after general settings.
allow=ulaw
allow=g729
register => xxx:xxx@sip.flowroute.com
So go ahead and open /etc/asterisk/sip.conf in your favorite text editor (I prefer vim). You’ll notice a lot of text, but ignore it for now. These configuration options will be covered in another article in this series.
Scroll down until you see a line that says only:
[authentication]
This line marks the end of the [general] section (which is where we need to put the settings mentioned above). Now go ahead and insert the settings Flowroute gave you directly above the [authentication] line. Your configuration file should now show something like:
If you are running your Asterisk PBX behind a router (eg: your Asterisk system has a private IP), then you’ll need to add the following configurations to your sip.conf file directly above the [authentication] line:
nat=yes
externip=xx.xx.xx.xx
localnet=192.168.0.0/255.255.255.0
Where xx.xx.xx.xx is your external IP (visit IP Chicken if you don’t know it), 192.168.0.0 is your subnet, and 255.255.255.0 is your subnet mask. In this example, I’m allowing connections to my Asterisk PBX from any device on the 192.168.0.x network.
The reason we need to add our networking information here is because Asterisk needs to modify the SIP packet headers to ensure that our SIP packets get to the right destination.
The next thing the Flowroute instructions tell us to do is:
Add the following near the bottom of sip.conf
[flowroute]
type=friend
secret=xxx
username=xxx
host=sip.flowroute.com
dtmfmode=rfc2833
context=inbound
canreinvite=no
allow=ulaw
allow=g729
insecure=port,invite
fromdomain=sip.flowroute.com
So go ahead and scroll to the bottom of your sip.conf file, and then insert those settings along with a single addition: at the very bottom of your configurations (on a new line after the fromdomain=sip.flowroute.conf) line, insert the following:
qualify=yes
As this will give us some additional information about our SIP connection later on.
Now that we’ve set up our SIP trunk, it’s time to create an extension. An extension is just another term for ‘phone’. SIP extensions (IP phones) are the most common type of extensions in use on modern phone systems. Sure, you can still hook up those old analog phones to your Asterisk PBX, but we’ll save that for another day. Today we’ll create a simple SIP extension which we will later hook up a soft phone to and use to make and receive calls.
To define a SIP extension, we need to pick several things:
Now that you’ve picked your extension number and secret, let’s create it!
Scroll down to the very bottom of your /etc/asterisk/sip.conf file, (below the SIP trunk we created in the previous section), and insert the following (make sure you swap out my extension number for yours, and my secret for yours):
I’ll skip over the configuration options for now, I’ll cover these in great depth in a later part of the series. If you want to read more about them now, check out the VoIP Info page which describes them in detail.
At this point we’ve fully configured a Flowroute SIP trunk and a SIP extension with Asterisk. The next thing for us to do will be configuring our network so that our SIP trunk works. So keep reading!
Before our SIP set up is finished, we need to configure our network to pass SIP and RTP (voice traffic) to our Asterisk server. If your server is not behind a router, you can skip this section.
To do this, configure port forwarding on your router to forward ports 5060 UDP, and 10,000 -> 20,000 UDP to your Asterisk server.
Port 5060 UDP is used for SIP traffic.
Ports 10,000 -> 20,000 UDP are used to pass voice traffic (audio).
If your router has any SIP options such as SIP ALG (application layer gateway) or SIP fixup, you’ll want to disable them.
Before moving on to the actual call configuration, let’s make sure our SIP trunk is actually connected to Asterisk and working.
From the command line, type the following:
asterisk -rx 'sip reload'
Which will force Asterisk to reload our SIP configuration file that we just edited (/etc/asterisk/sip.conf).
Next, let’s check to make sure that our Flowroute trunk is registered (connected and in service):
asterisk -rx 'sip show registry'
If your State shows Registered:
Then you know that your SIP trunk is connected and working!
Since we have our SIP trunk working, we now need to program Asterisk, and teach it how to route calls for us. There are two things that we need to teach Asterisk to do: how to route outgoing calls, and how to route incoming calls. Each of these requires separate Asterisk configuration to work.
Our goal will be to write the following two rules:
There are several ways to program Asterisk to handle call routing, but the simplest (and native) way to do it is via ‘dial plan’. Dial plan is the name of Asterisk’s own scripting language. It is very simple, and easy to understand (even for non-programmers).
In the next few sections, we’ll write dial plan code to route calls according to our rules above.
All Asterisk dial plan code resides in the file /etc/asterisk/extensions.conf. So when working on dial plan code, always have this file open.
There are two main sections of the extensions.conf file that are always present. There is a [general] context which contains dial plan settings. These settings control Asterisk dial plan parsing options for the most part. The other context is [globals] which contains a list of global variables that can be accessed by any dial plan code.
All Asterisk dial plan code is kept in contexts (much like the SIP configuration we walked through earlier). You can create as many contexts as you like.
Each context should have a clear, meaningful name, which describes what the code inside of it does.
Each line of dial plan code is of the form:
exten => extension,priority,application
Where:
If you don’t understand all of this now, don’t worry!
Before we begin writing our code, let’s quickly create a nice clean extensions.conf file to work in. Remove your current dial plan file (/etc/asterisk/extensions.conf) and replace it with the following:
All I did here was remove all comments and clutter from the file, so that we can clearly see what we’re doing. I also added a global variable called TRUNK which contains the name of our SIP trunk defined earlier in the article. We’ll use this global variable later on to make outbound calls.
The goal here is to allow our extension to dial an 11-digit US phone number, and connect it to the PSTN via our Flowroute SIP trunk.
Remember when we configured our SIP extension? One of the keys we specified in the configuration file was:
context=outgoing
The context field of an extension determines what dial plan context the pattern matching will start at. This is similar to the main() function in most programming languages.
The context specified in our SIP extension plays an important role in routing outbound calls. It says (in human English):
When any extension who’s ‘context’ key is equal to ‘outgoing’ dials a number, send the number that was dialed to the [outgoing] context to be processed. Let the [outgoing] context determine what to do at this point.
So now that we know what context we need to create (the [outgoing] context), let’s make it!
Open your extensions.conf file and add the following code to it at the bottom:
Let’s go through the code and analyze exactly what is happening.
The first bit:
exten =>
Is standard. All Asterisk dial plan code starts with this bit.
The extension:
_1NXXNXXXXXX
Is a regular expression that Asterisk will use to pattern match the number dialed. Remember above how we said that we’re going to route all 11-digit US telephone numbers outbound? This pattern represents an 11-digit US telephone number. Since all 11-digit US telephone numbers begin with the number 1, we hard-code that number. The variable N represents a number (2 through 9), and the variable X represents a number (0 through 9). Therefore, the pattern _1NXXNXXXXXX will match any 11-digit US telephone number.
After the extension (pattern), you’ll see a comma character followed by the number 1. The number 1 is the priority. Asterisk dial plan code can contain more than a single line of instructions. In cases where there are multiple lines of code that need to be executed, Asterisk relies on the priority number to determine what to do first.
Imagine that we had code which looked like:
exten => _1NXXNXXXXXX,2,Dial(18002223333@flowroute)
exten => _1NXXNXXXXXX,1,Dial(19999999999@flowroute)
In this case, Asterisk would execute the code at priority number 1 first, then the code at priority number 2. So always check for priority numbers when looking at code as they will help determine what is going on.
The last part of the code you see is the called the application:
Dial(SIP/${EXTEN}@${GLOBAL(TRUNK)})
The application we’re using here is the Dial() command. This application instructs Asterisk to dial the phone number out of our Flowroute SIP trunk and connect the call to our extension (eg: make an outbound call)!
Everything inside of the ${} characters is a variable reference. Asterisk has several pre-defined ‘channel variables’ which are always accessible. In our Dial() code, we reference the ${EXTEN} channel variable, which contains the number that was dialed and pattern matched. If we dialed the number 18002223333, then ${EXTEN} would expand to 18002223333.
The ${GLOBAL(TRUNK)} code references the global variable TRUNK which we defined at the top of our extensions.conf file. This code will expand to flowroute before executing the Dial() application.
So after all of the variable expansion is finished, Asterisk actually sees the following (assuming that we dialed the number 18002223333):
Dial(SIP/18002223333@flowroute)
Which is a lot easier to understand! The first part of the line that says SIP/ tells Asterisk that the number we’re going to dial should be sent out of our SIP trunk. The @flowroute part tells Asterisk to dial the number 18002223333 on the flowroute SIP trunk, specifically. Doing it this way gives us flexibility. Imagine if we had many SIP trunks on our Asterisk system, and wanted to route certain calls through certain SIP trunks.
Let’s quickly perform a full walk through of what happens when we dial the number 18002223333 on our extension. (Don’t worry that we haven’t set up the soft phone yet, we’ll get to that later.)
That’s it for outbound routing! Simple right?
In order to route calls inbound, you will need a DID (phone number) with your SIP provider. This way, you can call your number, and it will direct to your Asterisk PBX system. A phone number is a lot like an IP address, each one is unique, and routes to a specific location.
Unfortunately, DIDs cost money (just like you pay for cell phone service and house phone service, you need to pay for VoIP service to rent a DID). If you would like to try out the code that follows, you’ll need to deposit some money into your Flowroute account, and then purchase a DID from the web panel. At this point in time, a single DID from Flowroute costs approximately $1.39 per month.
Once you’ve purchased a DID, write the number down somewhere. It will be an 11-digit phone number. For the code that follows, simply substitute in your DID where necessary, as I will be using the ficticious DID 18182223333.
Open your /etc/asterisk/extensions.conf file and add a new context called [inbound] to the bottom of your file (it can go beneath the [outgoing] context we created in the last section). The context should look like:
The code here should look familiar to the code in the previous section. All we’re doing is dialing the SIP extension 1000 (which is the extension we created earlier). You’ve probably noticed that there is no @trunk syntax at the end of our Dial() application. If you look back at your SIP configuration file (/etc/asterisk/sip.conf) you’ll notice that when we created our extension, one of the keys we defined was:
dial=SIP/1000
Which tells Asterisk that in order to connect a call to that extension, we have to dial SIP/1000.
Let’s quickly perform a full walk through of what happens when someone calls our DID (18182223333) from the PSTN.
Not too bad! We’ve set up the ability to receive incoming calls in only a single line of code!
At this point, we’ve created dial plan rules for both the outgoing and incoming call routing. Save your extensions.conf file, and let’s move on.
Now that we’ve finished writing our dial plan code, we need to reload Asterisk to have it re-scan our extensions.conf file. To do this, simply type:
asterisk -rx 'dialplan reload'
From the command line.
The next section which will teach you how to hook up a soft phone to your Asterisk system so you can actually test your system!
In this section, we’ll set up a soft phone to use to make calls. Soft phones are just SIP clients that can connect to Asterisk and act as normal phones. Asterisk can work with normal analog telephones as well as fancier (and more expensive) SIP phones, but SIP phones are much easier to set up, so we’ll be configuring a soft phone today. If you want to hook up your analog phone to your Asterisk server–don’t despair–that will be covered in another article in this series.
There are tons of soft phones to choose from, but I’ll be walking you through using X-Lite, as it is one of the most popular and widely used.
First thing you’ll want to do is download and install X-Lite on your computer (it runs on all platforms).
Once you’ve got it installed, open it up. If you don’t have your extension information in front of you, open up your SIP configuration file (/etc/asterisk/sip.conf) and look at your extension definition.
Right click on the main window display in X-Lite and click on ‘SIP Account Settings’. Now click ‘Add…’ to add a SIP account.
Here are the values you should fill in:
Once you’ve configured all those settings, press OK and then close out of the configuration menu.
If your network and SIP configuration files have been properly configured, your X-Lite phone will now say ‘Registered’ at the top of the window! If it is not working, read back through the setup instructions and make sure you didn’t miss anything. If you are using a virtual machine, also make sure your host network settings have been configured to receive incoming traffic.
Now that we’ve gotten everything set up, let’s actually make some calls!
On your X-Lite soft phone, go ahead and dial any 11-digit US telephone number (since this is the rule that we configured for outbound routing). When you hit dial (the green button) you’ll make a call just like you would on a normal phone, and you’ll be connected to the phone number you dialed!
If you want to receive a call, use your cell phone to call your DID, and Asterisk will route the call directly to your X-Lite phone. You will see and hear you X-Lite phone ring, and you can pick up the call by clicking the green button.
This was a very large article, and took a considerable amount of time to write. I hope that if you got this far, you were able to clearly configure and understand the basic Asterisk setup required to make outbound calls, and to receive inbound calls.
The material covered in this part of the series is bulky, but very important in understanding the way Asterisk works. In future parts of the Transparent Telephony series, we’ll have significantly shorter, more targeted articles, so following along should be easier.
If you have any questions, comments, or suggestions about this article, please leave a comment and I’ll be happy to respond.
Earlier today I received a patch from EvilZluk. The problem he pointed out to me is that when moving the temporary call files to the Asterisk spooling directory, if the spooling directory is on a separate device, an exception would be raised as the os.rename function cannot support moving files across devices. In order to resolve this issue, I instead used the shutil.move function which is safe for cross-device file operations.
This can be extremely useful, especially in situations where there are NFS mounts for the spooling directory shared across multiple boxes.
So if you’re using pycall, please update your install and visit pycall’s website for more information / examples!
One thing I really hate is browsing websites using my smartphone (I exclusively use Android phones). Only a few large websites have really made mobile themes usable (Amazon, Google, and a few others). Most of the time, when you Google to find information, the websites you load will be largely impossible to read through, and load enormous images, etc.
Earlier today, I made up my mind to do something about it for projectb14ck, so I started hunting around for some mobile themes. Luckily, I found a few great ones, and after a lot of testing and tweaking I’ve finally got things configured just the way I want them.
So I’m happy to announce that as of a few minutes ago, projectb14ck is fully mobile! We now have an extremely usable and friendly mobile theme, so if you’re on your smartphone, the website will still look great. Be sure to check us out next time you’re on the go!
Welcome back to the Transparent Telephony series. If you’re new, you may want to check out part 1 here: Transparent Telephony – Part 1 – An Introduction.
This series is designed for technical people, programmers, and just general enthusiasts who want to learn: how telephony works, how to setup your own phone server (PBX), how to write telephony applications, and how to reduce your phone expenses. There are tons of neat things you can do with telephony knowledge, so keep reading!
This article will walk you through installing Asterisk on your CentOS or Ubuntu server. If you are going to install on a virtual machine to follow along, I recommend using VirtualBox, as everything should work out of the box. Certain virtual machine programs like Xen have kernel issues which makes installing Asterisk difficult. Also, never ever use Asterisk in production on a virtual machine! You’ll have timing issues (this will be explained later in the series).
Before we get started, go ahead and install either CentOS or Ubuntu on your system. Update everything to the latest version. I’ll be showing you how to install the latest version of Asterisk stable, so we might as well update our operating system and packages.
You can skip this step as Digium provides yum repositories which will automatically install the latest version of Asterisk for us as well as any dependencies.
First of all, let’s install the appropriate kernel sources. We will need these to build against. To figure out what kernel version you’re using, run the uname command:
uname -a
Next you’ll want to search for the appropriate kernel packages to install:
apt-cache search 2.6.31
(where 2.6.31 is your kernel version). Once you get a list of packages, install the appropriate linux-headers, linux-image, and linux-source packages that correspond to your kernel version. For me this was:
apt-get install linux-headers-2.6.31-14-generic linux-image-2.6.31-14-generic linux-source-2.6.31
Now install the SSL libraries required to encryption. We’ll also install SSH so that you can remotely administrate your server:
apt-get install openssl libssl-dev ssh
Next we’ll install all of the tools required to build Asterisk:
apt-get install gcc g++ make automake autoconf build-essential bison flex libtool libncurses5 libncurses5-dev libgsm1 libgsm1-dev libnewt-dev libnewt-pic curl libcurl3 tclcurl libwww-dev mysql-common mysql-client libmysqlclient16 libmysqlclient16-dev sox libsox-fmt-all madplay libxml2 libxml2-dev doxygen
You may also want to install ntp as it’s a safer alternative to ntpdate which most system administrators use to adjust the system time. DAHDI, the Digium Asterisk Hardware Device Interface, is very picky about system time, and has been known to crash servers which experience large time corrections. ntp will prevent this from happening as it will periodically adjust the time in small increments which is much safer than performing a single large time adjustment with ntpdate. If you’d like to install ntp, just run:
apt-get install ntp
Now that we’ve got our dependencies worked out, it’s time to actually install Asterisk! We’ll install DAHDI, Asterisk, Asterisk Addons, and all of the Asterisk default sound files. We’ll also ensure that Asterisk starts at boot, and runs as a system service.
As a disclaimer, these instructions have been largely taken from Digium’s website. They have excellent documentation for installing Asterisk using their yum repositories which I will be mirroring here.
yum clean all
yum install asterisk16 asterisk16-configs asterisk16-voicemail dahdi-linux dahdi-tools libpri
chkconfig dahdi on; chkconfig asterisk on; reboot;
Once the system comes back up, run the following command to make sure DAHDI and Asterisk are working properly:
service dahdi status; asterisk -rx 'core show version'
If all is working, you should see something similar to:
### Span 1: DAHDI_DUMMY/1 "DAHDI_DUMMY/1 (source: Linux26) 1" (MASTER)
Asterisk 1.6.0.25 built by root @ localhost.localdomain on a i686 running Linux on 2010-02-26 20:30:00 UTC
To install Asterisk on Ubuntu, we need to compile it from source.
wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-1.6.2.5.tar.gz
wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-addons-1.6.2.0.tar.gz
wget http://downloads.asterisk.org/pub/telephony/dahdi-linux-complete/releases/dahdi-linux-complete-2.2.1+2.2.1.tar.gz
wget http://downloads.asterisk.org/pub/telephony/libpri/releases/libpri-1.4.10.2.tar.gz
tar zxvf dahdi-linux-complete-2.2.1+2.2.1.tar.gz
cd dahdi-linux-complete-2.2.1+2.2.1
make
make install
make config
tar zxvf libpri-1.4.10.2.tar.gz
cd libpri-1.4.10.2/
make
make install
tar zxvf asterisk-1.6.2.5.tar.gz
cd asterisk-1.6.2.5/
./configure
make
make install
make config
make samples
make progdocs
tar zxvf asterisk-addons-1.6.2.0.tar.gz
cd asterisk-addons-1.6.2.0/
./configure
make
make install
make samples
Now that we’ve got everything installed, go ahead and reboot the system to make sure that everything starts up automatically on boot. Once the system is back up and running, run the following two commands:
/etc/init.d/dahdi status; asterisk -rx 'core show version'
If all is working, you should see something similar to:
### Span 1: DAHDI_DUMMY/1 "DAHDI_DUMMY/1 (source: HRtimer) 1" (MASTER)
Asterisk 1.6.2.5 built by root @ ubuntu on a i686 running Linux on 2010-02-28 22:30:53 UTC
Now that you’ve got DAHDI, Libpri, Asterisk, and Asterisk-Addons installed, your server is ready for production usage!
Our next article will cover configuring Asterisk and making calls to the outside world. Be sure to subscribe to our RSS feed to get notified when our next instalment is released!
If you’re looking for some other great Asterisk documentation, you can’t do any better than Asterisk: The Future of Telephony, 2nd Edition. It’s the most thorough book on Asterisk that you can find, and will teach you everything you need to know to get started with Asterisk.
Earlier today I received an email from Marcelo Araujo (marcelo@midivts.org) which contained a patch for pycall to add support for local trunks. So I patched pycall up, updated the changelog, the builds, and pushed everything out.
The problem with the earlier versions of pycall is that they didn’t properly support local trunks. In Asterisk, local trunks allow you to dial numbers locally to your system, which is useful for people who want to let their Asterisk dial plan configurations control the dialing logic of the call. I completely overlooked that when I was first writing pycall. The reason why (specifically) it didn’t work before was that pycall would build all dial strings in this format:
TRUNK_TYPE/TRUNK_NAME/NUMBER
So that the Channel directive of the call file would look something like:
Channel: Local/internal/18882223333
Which works great for SIP, ZAP, DAHDI, IAX2, and other trunks–but not for local! Local trunks have to be written in the following manner to work:
Channel: Local/18882223333@internal
So thanks again Marcelo for helping find and fix that annoying issue! And to anyone else out there who finds issues with pycall, please let me know!
Hi everyone. I’ve re-themed my website once again in hopes (this time) of making all content easier on the eyes. I, of course, prefer dark designs, but I’ve been receiving a stream of complaints over the past several months asking me to please tone down the contrast ratio so that users can read the code easier.
I finally caved in. So please check out the new theme and critique it. Like it? Hate it? Let me know!
This article will teach you how to authenticate users with Django in a simple, quick, and secure manner. You’ll also learn how to require authentication on certain pages of your website, and how to gracefully handle login and logout functionality.
The target audience is people who have had minimal experience with Django, and are aware of how Django works in a basic manner.
To demonstrate how user authentication works, we’ll be building an extremely minimalistic website and user portal. We’ll create a home page that directs users to the web portal (which is for authenticated users only). We’ll create a login page, a logout page, and a basic web portal home page.
The goal of this article is not to teach you web design, or how to make websites, but merely to show you how simple user authentication can be with Django.
Before we get started, create a new Django project. For the rest of this article, we’ll be building a website for the fictitious company “Django Consultants”.
Be sure to create a user account when you run the:
python manage.py syncdb
Command, as you will need that later to test your login.
There are many ways to design a website, but I prefer to build the URL schema first, then build the site to match the URL schema. So let’s decide on what URLs we will need now. If you are going to build a real website and not just this simple example, feel free to add whatever else you need.
This should be sufficient for what we are doing.
Below is my settings.py for the project. Make changes where necessary.
Take note of the LOGIN_URL setting. This needs to be changed to whatever URL your login view will be at. For us, this should be /login/, as that is the URL we decided will supply users with a login page.
Everything else is pretty standard. Nothing special going on.
Now let’s write our main urls.py file which will control what content is served based on our URL schema.
There are two things to notice here. First off, the login view:
(r'^login/$', 'django.contrib.auth.views.login')
Is defined as using ‘django.contrib.auth.views.login’ which is a pre-defined view for logging in users. We won’t need to make any changes to this, as it does all of the Django magic to securely authenticate users.
Next, you’ll notice that the view for our web portal will be part of a separate application:
(r'^portal/', include('portal.urls'))
You don’t have to do it this way, but breaking your website up into independent applications is useful for keeping logic separated. For example, a login and logout are useful to have as part of your main site (eg: not in an application) because you may have multiple parts of your website that perform different actions but that all require authentication for users to access. In our case, one of these applications will be a user portal, so we’ll be making it into a separate application.
Now that we’ve defined the URLs for our site, let’s go ahead and write the views that our main site will use. Here’s the views.py:
Since the login page already has a view defined (thanks to django.contrib.auth), we only need to define our main page (which will tell users to go to the portal) and a logout page that allows users to logout anywhere on the website.
The main_page view is pretty simple, it just renders an index.html template (don’t worry, we’ll write all of the templates later).
The logout_page view calls the logout function on the request object. This magically logs users out and kills their sessions. After logging them out, we then direct them back to the main page of the website. You can always spice this up (by adding a custom log out page or something), but for simplicity’s sake, we will just send them back home.
Now let’s create our web portal application. We’ll call it portal and it will be used to display the portal homepage and other portal functionality (if you choose to add it):
Again, let’s quick write up a URL schema for our portal application. If you are designing an actual website, you’ll want to add more functionality. For now, all we will do is create a single page (that will be accessed via /portal/) which gives users some basic options.
Now that we’ve come up with a schema for our portal application, let’s implement it and write the urls.py:
Nothing complicated here. Moving on.
Now let’s write our portal views:
This is where things get interesting. Since we decided a while back that our /portal/ page was going to require users to be authenticated, we are going to import the login_required function from djang.contrib.auth. This decorator allows us to specify which views require users to be authenticated to use! All we need to do is place
@login_required
Above each view definition that we have which requires user authentication, and BAM. Everything magically works!
If you were to visit /portal/ without being logged in, the login_required function would see that you are not authenticated, and would read the variable value in your settings.py file called LOGIN_URL which currently contains ‘/login/’, and would then direct you to the login page. Pretty awesome right? Full user authentication in only 1 line of code!
Now that we’ve done all the hard work, let’s go ahead and write our templates.
To start, let’s create all of the necessary directories and files:
Next, let’s define a generic template (base.html) for our main pages to use as a generic template. Since I like to do things fancy, we might as well make it HTML5 :)
Now that we have a base template, let’s create the main page of the website (index.html) as our main_page view renders:
At this point, we’ve got the basic templates done for the main page of our website. Mind you, they are very basic. The next thing we need to do is create a template for our user portal page. So let’s do that:
This is a generic template which will be used for all portal pages. As you can see, there isn’t much functionality except to return to the main page and logout. If you are developing an actual portal, you’ll obviously want to add lots more features! Now we’ll create the actual portal home page:
This page is special in that it uses the:
{{ user.username }}
Variable to print the user name of the logged in user. The Django authentication system passes the user object to each template that requires authentication (using the login_required decorator), that we can use to fetch information on the user. In this case, we are going to display a simple welcome message.
The last thing we need to do is create a template for our login page (remember that it uses the magical view that we didn’t have to write?) Here it is:
Now, as you can see, we create a form which performs a POST to itself. This lets the django login view do its magic. The interesting thing here are the hidden fields and how they are processed:
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% else %}
<input type="hidden" name="next" value="/portal/" />
{% endif %}
The hidden field next is special to the login view. It determines where the user is re-directed to after logging in. Let’s say, for example, that a user visits our homepage, and clicks the link there that directs them to /portal/. Since /portal/ requires authentication, it will direct the user to the URL /login/?next=/portal/. This GET argument is sent automatically by the login_required decorator to help inform the login page of where to direct the user after they’ve logged in.
Our code above says “If the user requests a page, and they are not authenticated–then direct them to the login page, and after they’ve logged in send them back to the page they originally requested. If the user simply visited the /login/ page directly, then by default send them to /portal/ once they’ve logged in.
This is the correct way to handle login and redirection in complex websites as it gives users the maximum amount of flexibility. Don’t you just hate it when you try to visit a website and get into an important protected section, only to discover that after you’ve logged in you are redirected to the main page instead of the page you were trying to get to? You won’t have that problem using Django’s auth as long as you implement the login template as we did above.
We’re done. So give everything a test. Go to your django_consultants directory and run the command
python manage.py runserver
To start up the development webserver. Then open a browser and visit http://localhost:8000/.
You should be greeted by the main page, and provided with a link to log into the web portal. So click the portal link, and since you are not authenticated, you will be directed to the login page.
Now log in using the username and password you generated when you ran
python manage.py syncdb
And you’ll see the portal home page! Feel free to play around with logout / login / etc.
For more information and advanced usage of Django authentication, check out the official documentation here: http://docs.djangoproject.com/en/dev/topics/auth/. The best way to learn is to play around with things, test them out, and get a good feel for how everything works.
Hopefully this article has helped you understand how Django authentication works, and how easy it is to add secure authentication to your website without going through too much trouble. If you have any questions, suggestions, or anything else, leave a comment and I’ll try to answer it.
The Asterisk Gateway Interface, commonly referred to as AGI, is a language-independent API for processing calls. It allows programmers to write simple programs to manipulate and route calls on Asterisk servers in a simple, easy manner.
This article provides a technical introduction to the AGI, explaining how it works, how it can be used, where you can find API documentation, and even provides some basic code samples which demonstrate how to use the AGI. The intended audience is programmers, telephony enthusiasts, or IT people who want to learn more about adding functionality to their Asterisk PBX systems. This is not a full programming reference, and will not explain how to write AGI programs, it will merely teach you what the AGI provides and how to use it high-level.
One question that arises frequently is Why do I need to use AGI? This is a great question, worth discussing. Asterisk provides several ways to perform call logic, namely dial plan, AMI, and AGI.
Dial plan is Asterisk’s native scripting language which is parsed by Asterisk and stored in memory to use for performing call logic. Dial plan is quick, efficient, and easy to learn. There are, however, downsides associated with dial plan. It is very un-sophisticated, and doesn’t support standard procedural language constructs (like loops). This means that you will be doing mostly assembly type coding using Gotos and simple constructs. This makes writing large software tedious and difficult to maintain.
The Asterisk Manager Interface (AMI) is a sophisticated, language independent API for controlling Asterisk through TCP sockets. The AMI is a great solution for software that needs to be ran on remote servers as it can interact with Asterisk across networks. Many click-to-call programs are written using the AMI, as are nearly all of the Asterisk manager programs like HUD, FOP, and Asterisk Assistant. The AMI is great because it allows remote software to completely control the Asterisk PBX: get even status updates, make calls, receive calls, route calls, etc. The downside to using the AMI is that it does not have any good documentation, is known to be buggy and error-prone, and causes significant stress on the PBX.
The AGI is a middle man, lying somewhere between dial plan and the AMI in terms of functionality. The AGI can not be completely independent of the PBX, and requires some dial plan modification to run (unlike the AMI), is not bound to a specific programming language (like the AMI), and can be used either locally or across networks (like the AMI). The AGI is usable only for incoming calls, and is thus no good for purely outbound telephony development. The AGI uses little overhead compared to the AMI, and is a good solution for developers who want to write a module or plugin for Asterisk which can be used on any PBX and implemented quickly and simply without stressing the server. AGI is also a great solution for developers who would like to create telephony programs without learning the Asterisk dial plan. It lets you build applications in whatever programming language you are comfortable with, which can rapidly decrease development time.
The AGI actually has four ways in which it can be used, each different from the other. There is the standard AGI, dead AGI, fast AGI, and enhanced AGI.
Standard AGI is the simplest, and most widely used form of AGI. Standard AGI scripts run on the local PBX and communicate with Asterisk through socket descriptors (namely STDIN and STDOUT). The standard AGI allows for usage of all AGI commands, and is what this article will be discussing.
The dead AGI is a simplified form of AGI which continues to run after the call has been hung up. This is useful in situations where programming logic needs to be performed after a call has hung up. As dead AGI allows developers to control logic after the call, certain AGI commands are not permitted in its usage. Dead AGI is also deprecated as of Asterisk 1.6, and should not be used.
Fast AGI is the AGI over TCP sockets protocol. It allows for all AGI functionality except EAGI, and is provided as a solution to developers who need to run resource intensive AGI programs. By running the bulk of the AGI logic on another server, the Asterisk server itself can process calls and not worry about handling complex computation for other services. This is the recommended protocol for large applications.
Last is the EAGI. The EAGI communications through file descriptors on the local machine using STDIN and STDOUT, and provides developers a way to access the audio channel directly for the calls being processed. This is rarely used, but gives developers a way to analyze raw audio data.
When calls come into the Asterisk server, the dial plan rules process the call and determine where to route it. To launch an AGI program and hand off call processing the AGI program, you will need to use the Asterisk dial plan command AGI. Below is an extremely simple example dial plan which passes all calls to an AGI script for processing.
By default, if no path is specified, Asterisk will look for the script, in this case call-processor.sh, in the directory /var/lib/asterisk/agi-bin/. This is the default location for all AGI programs, and should probably be used to store your AGI software. If your program resides in another directory, you may specify an absolute path to the program for Asterisk to use instead.
The program must be executable (on linux systems that means that the executable bit must be set on your program). You can do this by using the linux command chmod +x to add the executable bit to your program.
The program must also be readable by Asterisk, this means that it must be in a public directory tree, or a tree that is owned by the user account under which Asterisk runs. Also, don’t forget that your AGI program will be ran by Asterisk, so permissions are necessary to plan out in advance. A common problem new Asterisk developers run into is that they will have their AGI programs write files to a system location, like /etc/, but Asterisk will be running in a restricted environment, so their programs will fail and they will not know why.
Running AGI scripts, as explained in the previous section is a simple task. Sometimes, however, debugging AGI scripts can be difficult and time consuming. Often, it is difficult to test AGI programs as you cannot simply ‘print’ output to the screen as you normally would for debugging purposes. This section briefly covers using the Asterisk command line to watch and debug AGI applications live.
To get started, log into the asterisk console via the asterisk -r command from the shell. Once inside the CLI, run the agi set debug on command to enable verbose AGI output. This will come in handy when troubleshooting your programs. Below is an AGI debug of an AGI application which shows a wide array of information about my AGI application. Take a close look at this debug, and try to make sense of it. I’ll explain what each bit means below.
Now, the first thing to note is that every line starts with the channel ID of the call, this way, calls can be traced even on very busy servers. If you have a lot of call traffic, filtering out lines by their channel ID can help improve visibility. A great way to do this is to use grep, ex: asterisk -r | grep <channel ID> from the command line.
AGI applications send commands to Asterisk via STDOUT, and Asterisk sends data to your AGI programs via STDIN.
After the channel ID, you’ll see AGI followed by either Tx or Rx. Tx stands for transmit, and means that Asterisk is transmitting the following information into the STDIN buffer for your AGI program to use if it desires. Lines which begin with Rx (receive) display information that your AGI program is sending to Asterisk into the STDOUT buffer. If you ever find yourself wondering what response you are getting after sending a command to Asterisk via AGI, you can always look at the Tx lines to see what Asterisk says.
The first 21 lines of output are all transmissions from Asterisk, which are sent into the STDIN buffer for your program to use if it wishes. Each of these lines defines a call variable which contains information about the call that is currently being processed. This information may be used by your programs to figure out things like what caller ID the person calling is using, what number they called, what dial plan context were they in before hitting your AGI application, what language the call is in, what version of Asterisk is being used, etc.
Note that this initial list of variables is terminated by a single empty line. So when writing software to parse in these variables, always keep parsing until you read in an empty line. That is how you can tell that there is no further input.
The next few lines are dialog between our AGI application and Asterisk. The Rx lines show AGI commands which were sent to Asterisk for processing, and the following Tx lines show Asterisk responses.
In the previous section, we looked at an AGI call log. Now let’s examine the AGI application which ran and generated that call log. What follows is an extremely simple AGI application which simply outputs “hello, world!” to the AGI debug output.
This program completely disregards all of the variables that Asterisk passed into STDIN when it spawned a new thread for our AGI application, and only writes three AGI commands to STDOUT (which is how our application communicates with Asterisk).
The first command we send is ANSWER, which does nothing but answer the call (establishes an audio connection with the remote end, so that the call starts getting billed). The second command we send is a NOOP, which only outputs the text that follows it onto the AGI debug screen of the CLI. Lastly, we send the HANGUP command which ends the call.
Simple enough? Now, go ahead and try to run this program yourself. Test it out, understand what is happening, and make it work.
One thing you may notice is that you may get some errors on the CLI while watching your program run. Usually they look something like this:
Feel free to ignore those errors. Those are generated when your AGI application does not read in all data from STDIN before your program closes.
In most real world applications, you’ll want to read in Asterisk responses so that you know whether or not your commands executed successfully, and can grab important information about the call being processed, but for this example, we don’t care, so we didn’t.
Now that you know how to write and use basic AGI scripts, let’s get a little more advanced. Many complex AGI applications may need more advanced data given to them than what Asterisk natively provides. Luckily, the Asterisk dial plan command AGI allows for us to pass up to 127 arguments to our AGI application. This should be sufficient for most needs.
To pass arguments from the dial plan to your AGI script, you can simply add them in a comma delimited list after your AGI application path is specified:
As you’ll notice in the above example, I did not put spaces after each comma. That is because if you add spaces, Asterisk will interpret them literally and your program will receive the argument with a space character prepended to it. This may (or may not) be desirable, based on your application specifications.
The arguments will be available to your AGI application both via the standard argument list AND via the initial Asterisk variable list. Each programming language handles it differently. Here is an AGI log which shows our old hello-world.sh program being called with 3 arguments:
As you can see, after the initial arguments have been passed, Asterisk simply adds a new line with for each additional argument passed to the AGI script. This makes reading in these variables easy and doesn’t require any extra effort on your part.
Now that we’ve introduced and explained how AGI programs work, there is nothing left to do except start writing some for yourself. The definitive reference to AGI commands and functions can be found on voip info’s AGI page.
If you are comfortable with Asterisk dial plan, you’ll easily pick up the AGI commands. If you have no prior experience, then look for some references / examples in the voip info page as they have numerous examples and help available.
Got any questions, comments, suggestions, or other things? Feel free to leave a comment and I’ll respond when I can.
The stereotype of a computer programmer is a harsh (and mostly true) one. The typical computer programmer lives inside, in small dark rooms, typing away for hours at a time behind large monitors and drinking highly caffinated drinks. Now, this isn’t a bad thing (quite the other way, actually), but it does definitely have an effect on your life. I have been living this lifestyle for quite a while, and only recently begun to change my habits around to avoid the madness that was once my life. While I definitely love the hacker lifestyle, and it totally suits my personality, something was definitely missing: real life.
For me, the change happened when I got out of school and started working full time. I actually had a schedule to follow, had to wake up early, drive into the office, etc. This was a huge change, as I was actually awake during the day AND night instead of just the night. I really hated it at first, but after a while it grows on you. The sunlight made a big difference. And over time, I just gradually came to appreciate the outdoors more and more. Now, I have a hard time going for an entire day without stepping outside for at least a few minutes to get some fresh air. Being outside clears my head, makes me feel refreshed, and just generally de-frustrates me. Sometimes sitting inside for like 20 hours straight trying to figure out why my CSS won’t render on IE, Chrome, and Firefox will drive me mad, and the only way to escape is to go outside for a few minutes and walk around.
So after analysing this situation for a while in my head. I came to the conclusion that many programmers, like myself, probably never go outside because they’ve never really gotten the time. There are tons of things that prevent you from doing it: work, learning, trying to finish that one bit of code, munchies, sleep schedules, etc.
So why should you ever go outside anyway? Lots of reasons. It helps clear your head, gets you some vitamin D, makes you feel more human, and just generally increases your happiness.
So now you just need to find a way to get outside more often. Here are my suggestions (learned from experience):
While these suggestions are obvious, clear things, they really do help. If nothing else, I’d recommend getting a laptop and doing some work outside. Just make sure you have one of those glare-resistant screens (nothing is worse than sitting outside with a laptop if it has one of those shitty reflective screens).
So, in conclusion: get outside every now and then. It’ll clear your head, help you program better, and keep your sanity in check.