O'Reilly logo

VoIP Hacks by Theodore Wallingford

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Hack #44. Connect a Legacy Phone Line Using Zaptel

You don't need to buy a VoIP phone to make use of Asterisk—use your home phone instead.

About a dozen interface cards support the Zaptel standard, allowing you to connect something as simple as a two-wire analog telephone, or something as sophisticated as a digital T1 breakout box (called a channel bank) for connecting digital business phones. In this hack, you'll see how to connect a phone line using such an interface card—either an X100P or a TDM400P, both manufactured by Digium.

To build a Linux PBX that can communicate with the PSTN (the network that 90 percent of the world still uses for telephony), you'll need at least one trunk channel to communicate with the FXS interface in the phone company's central office switch. This channel will provide you with a dial tone from your local phone company, so calls to and from the PSTN can be handled by the Asterisk server. There's not much to setting up an FXO channel with Asterisk. One way, covered in this hack, is to install an X100P, TDM400P, or similar FXO line card in the Asterisk server. (The other way is to use an FXO media gateway [Hack #43] ).


The connection from your premises to the phone company's switch is called the local loop.

Install an Interface Card

To get started, you'll need to obtain an Intel i537-based FXO interface card such as the Digium X100P. (If you'd like to save a few bucks and build your own X100P clone, check out "Brew Your Own Zaptel Interface Card" [Hack #64] .) Install the X100P card into your PC's PCI bus (sorry Mac users, you're stuck using a media gateway, as covered in the previous hack) and connect an RJ11 standard phone patch cord from the wall jack of an active telephone company Plain Old Telephone Service (POTS) line into the appropriate port of the X100P. On the X100P, this port is the one marked with an etching of a telephone wall jack.

Now, download and compile the Zaptel driver and Asterisk [Hack #41] . This creates the zaptel and wctdm modules, which need to be loaded during startup, by adding this code to the script that launches Asterisk, right before the line where Asterisk itself is launched:

	              modprobe zaptel
	              modprobe wctdm
	/etc/rc.d/init.d/asterisk start

By now, the card is in a PCI slot on the Asterisk server, the phone line is connected, and you've compiled and installed the Zaptel drivers. Your next step is to define the FXO trunk connection as a channel that is usable by Asterisk. Once defined, you can reference the channel within your Asterisk call-routing scheme. The POTS line can serve as the full-time gateway for all PSTN calls and all telephones in your home or office. Or the POTS line can just be a connection mechanism so that the Asterisk server can answer incoming calls on the POTS line if they aren't answered by a person within a certain number of rings. But first, the FXO connection must become a named Asterisk channel.

Each voice channel in Asterisk has a number. This number consistently represents the same channel throughout all of Asterisk's configuration files and in its logging output. The numbering of voice channels—especially those that require a dedicated piece of interface hardware in the server—is determined by the order in which their drivers are loaded and the order in which they are identified in the PC's PCI bus. Figuring out which card is which—say, in a situation where you have just installed three or four X100P cards, each with its own POTS line—can require a bit of trial and error. In this project, we're using only one card and one line, so it should be a breeze.

The voice channel we're going to create will be called Zap/1-1. Asterisk follows a similar convention when naming all voice channels, even if they aren't analog phone line channels. The channel name is divided into two pieces. The first piece, Zap/1, refers to the physical Zaptel interface channel (which is either an FXO/FXS interface or a PRI channel). The second piece, -1, refers to the line number (more on multiple-line interfaces later).


For Zaptel interfaces that support only a single line, you can refer to them without the line number—i.e., Zap/1 and not Zap/1-1.

Assuming you haven't touched the Asterisk configuration files since running make samples in the first Asterisk hack, you'll have to make only two quick config changes to fire up your POTS line. The first change is in /etc/zaptel.conf. Add the following lines to the end of the file:


The first line tells the Zaptel configuration program, ztcfg, to set the X100P card to use FXS Kewlstart signaling—a variation of conventional FXS loop-start signaling. The number 1 is referenced because only one Digium card is installed, and it has only one channel, like the X100P card, so it's card number one and its channel will be 1 as well. If two cards were installed side by side, the first line would say fxsks=1-2 instead. If there were more than one channel per card (like the TDM400P), a single channel number would be used for each channel on that card—i.e., fxsks=1-4 for a card with four lines attached. fxsks=1-8 would work fine if you had two TDM400Ps installed with four FXS modules apiece. The next two lines in the code snippet localize the FXS signaling functionality of the X100P interface with loadzone and defaultzone. Other valid zones include fr, de, and uk.

Now, you might be asking yourself, "Why am I configuring the FXO interface card to use FXS signaling?" The answer is simple: to communicate with the FXS device interface at the central office, the local interface must use FXS signaling. Recall from this chapter's introduction that only FXS devices can receive signals meaningfully from FXO devices, and vice versa.


To alleviate confusion over FXS/FXO kernel module naming, wcfxs has been deprecated in favor of wctdm in releases of Asterisk later than 1.0.5.

The next change you need to make is in the /etc/asterisk/zapata.conf file. The sample configuration should be completely commented out (comments are denoted by semicolons at the beginning of the line). If it's not commented out, place a semicolon at the front of each line. Then, add the following lines to the end of the file:


The first line tells Asterisk what set of assumptions to make (i.e., what "context" to choose) when handling calls coming in on the POTS line. The second line tells Asterisk (not ztcfg) what type of signaling the X100P has been set to use. The following lines turn on a few traditional telephony features—caller ID, echo cancellation, and other stuff that's covered in more detail later. The last line assigns all the previous settings to channel 1. The assignment of these inherited settings uses the => assignment operator rather than just an equals sign (=). The Asterisk configuration parser doesn't distinguish between them; the convention is merely for ease of human readability.


Contexts are Asterisk's way of meaningfully grouping call-flow scenarios. A context describes what behavior is caused by dialing 1 at the outset of a call, while another context describes what behavior is caused by dialing 1 at some point thereafter. These contextual behaviors are defined in /etc/asterisk/extensions.conf.

You'll need to make one more quick change to Asterisk's sample configs: change the Zap/g2 definition for $TRUNK in extensions.conf to Zap/1. (This step might not be necessary with earlier versions of the sample config.) This will allow outbound dialing to be directed to the correct channel, Zap/1, the one that represents the connection to the PSTN.

Now, since you've added a new hardware interface, you must restart Asterisk. Once you've done that, try calling the POTS line you've connected to the X100P using a second phone line or your cell phone. After a few rings, assuming you haven't changed the configuration, Asterisk will answer and you should hear the familiar demo greeting that you heard in "Turn Your Linux Box into a PBX" [Hack #41] . If you examine Asterisk's console output during this demo, you'll see something like this:

	-- Starting simple switch on 'Zap/1-1'
	-- Executing Wait("Zap/1-1", "1") in new stack
	-- Executing Answer("Zap/1-1", "1") in new stack
	-- Playing 'demo-abouttotry'
	-- Executing Dial("Zap/1-1", IAX@/guest@misery.digium.com/s@default) in new stack

Through the console output, you can trace every step Asterisk took to recognize, answer, and process the incoming analog call from the PSTN and to connect it using the IAX protocol to a remote server across the Internet. Note that although this chapter is about legacy, circuit-switched telephony, we're using IAX to get our feet wet with VoIP. Plus, the IAX demo is so easy to run with Asterisk "out of the box" (it isn't broken by broadband routers the way SIP often is) that it's a great way to demonstrate how a VoIP signaling protocol can be used with legacy signaling on the PBX.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required