Fun with VoIP

When I read for then n-th time about Asterisk, an Open Source PBX solution, I deceided to team up with Christoph and tame the beast.

I have actually two problems with asterisk as it stands now:

  1. There’s not much really useful newbie-documentation or tutorials. There are some sample configurations, but they are not very useful because…
  2. the tool has a incredibly intransparent and difficult to understand syntax for it’s main configuration file (extension.conf). I’t just like it’s with sendmail: Many extremely low-level things to care of for getting complex high-level results.

I thought, that teamed up with Christoph, we’ll more likely to see some results.

The first thing was defining the parameters of our experiment. Here’s what we wanted to do:

  • Act as a SIP-Proxy, so two softphones (we did not want to buy too much actual hardware yet) could talk to each other.
  • Provide a gateway to the ISDN-Network, so both SIP-Phones can dial out to the rest of the world.
  • The same gateway should be able to receive incoming calls and direct them to one of the Phones (just one for now).

In the next session, we want more advanced features, like voicemail and waiting music. A third session should provide us with a webbased frontend (I know there are some). But for now, we wanted to concentrate on the basics.

The next step was to get the required hardware. I already have Gentoo running on my Thinkpad, so that was a good base. Furthermore, we needed any ISDN-Solution being supported by Asterisk. As we had a plain old BRI interface and a very limited budget (it was just an experiment after all), we went with the Fritz Card USB by AVM which has Linux CAPI drivers, albeit only binary ones (we could also have used the PCMCIA-version, but this is three times as expensive as the USB one).

Said piece of hardware proved to be a real pearl: It’s very compact, does not need a power adaptor and was very easily installed under Linux. I would not be using this for a real-world solution (which most likely requires PRI support and absolutely would require open sourced drivers), but for our test, this was very, very nice.

Installing the needed software is where gentoo really shined as everything needed was already in the distribution: After hooking up all the stuff, we emerged net-dialup/fritzcapi, net-misc/asterisk and net-misc/asterisk-chan_capi which suked in some more dependencies.

The next step is to reconfigure the kernel for the CAPI-stuff to work. Just include everything you find under “Device Drivers / ISDN Support / CAPI” – even the one option marked as Experimental (as the CAPIFS is needed and only available when enabling “CAPI2.0 Middleware support”)

Then, we made sure that CAPI (a common ISDN access API) was running by issuing capiinit start.

Then we went on to asterisk.

The fist thing, you have to do is to set up the phones you’re using. As we worked with SIP-Phones, we used sip.conf:

[general]
port = 5060
bindaddr = 0.0.0.0
tos = none
realm = sen.work
srvlookup = yes

[12345]
context = theflintstones
dtmfmode = rfc2833
disallow = all
allow = gsm
callerid = "Fred Flintstone" <12345>
secret = blah
auth = md5
host = dynamic
reinvite = no
canreinvite = no
nat = no
qualify = 1000
type = friend

[12346]
accountcode = 12346
dmtfmode = rfc2833
host = dynamic
auth = md5
secret = blah
canreinvite = no
context = theflintstones
qualify = 2000
type = friend
disallow = all
allow = gsm

This worked with our two test-phones running X-Lite

Interesting are the following settings:

realm The realm. I used our internal domain here. The default is asterisk. Your VoIP-Address will be identifier@[realm].
accountcode This is the username you’re going to use on the phone
context The context will be used when we create the dial plan in the feared extension.conf

Then, we configured CAPI in capi.conf

[general]
nationalprefix=0
internationalprefix=00
rxgain=0.8
txgain=0.8

[interfaces]
msn=44260XXXX
incomingmsn=*
controller=1
softdtmf=1
accountcode=
context=demo
devices=2

Those settings are said to work in Switzerland. Interesting is the setting for msn. This is where you enter the MSNs (phone numbers) assigned to your NT. I somewhat X-ed it out. Just don’t use any leading zeroes in most countries. You can enter up to five using commas as separator.

The next thing is to update modules.conf. In the [modules]-Section, add load => chan_capi.so, in the [global]-section, add chan_capi.so=yes.

Without those entries, asterisk will complain about unresolved symbols when loading the CAPI modules and will finally terminate with a “broken pipe”-Error. Thrust us. We tried. ;-)

The best thing now is that you can already test your setup so far. Launch asterisk with asterisk -vvvvvc (each v adds a bit of verbosity, while -c tells it not to detach from the console). If it works well, you’ll end up at a console. If not, make sure, that capiinit did not report any error and that you’ve really added those lines to module.conf.

Now for the fun of it, call one of your MSNs with any phone.

Asterisk should answer and provide you with a demo-menu

The next step is configuring extensions.conf. This is somewhat complex and I will go into more detail, as soon as I’ve figured out, what’s wrong with our test-configuration. We’ve added this to the end:

[ch-fest-netz]
exten => _0[1-9].,1,Dial(CAPI/44260XXXX:b${EXTEN},30)
exten => _0[1-9].,2,Hangup

[theflintstones]
include => ch-fest-netz

Just look that you enter one of the MSNs you have configured in capi.conf.

Now what this configuration should do is to allow those SIP-phones (recognize the “context” we used in sip.conf?) to dial out via CAPI.

You best learn how to configure this beast by calling the demo-voicebox and then comparing the log output of Asterisk with the entries in extension.conf. Basically, exten => defines a dial plan to execute. Then comes the pattern of numbers dialed to recognize. After that comes a (BASIC-like) sequence-number, followed by the action to execute.

The format of the number-pattern is explained in one of the comments in extension.conf

Now, this configuration does not work for us: When I dial on the SIP-Phone, Asterisk notices this, actually connects the ISDN-line (the target phone actually rings), but does not seem to notice when the target phone is answered.

If I answer the phone, it’s just silence in the line. The SIP-phone is still in the “trying to connect”-state.

This stays this way until I cancel the dial attempt in the SIP-phone. After that, asterisk prints more log entries – one of them the notice that the connection was successfully established.

A question in the malinglist was promptly answered: My configuration is correct, but maybe I’m running into a bug of Kernel 2.6.11. I was told to downgrade to 2.6.10, which is what I’m going to do next.

After this, I will extend the dial plan so I can call the internal SIP-phones both from another softphone or from a real phone over the ISDN

It’s hacky, it’s just somewhat working, but it’s a lot of fun!

I’ll keep you updated.