In the early days of VoIP, most users were still using analog phones through ATAs and early softphones with services like Free World Dialup (later, FWD) which offered users free SIP accounts that could call within the FWD network for free, as well as limited “interexchange” connections sponsored by VoIP companies that allowed for landline users to “dial in” to a FWD number. Later on, as users began to join various independent voice service providers (VSPs), SIPBroker became a way they could call each other without cost across networks. Unfortunately, this has slowly fallen by the wayside and a number of mappings no longer work. Aside from these services, there was also VoXaLot which offered both paid and free options with even more sophisticated abilities such as making call routing decisions based on dial patterns and media transcoding which allowed me to make calls from a lowly 32kbit/s Unwired connection using G.723.1.
Needless to say, FWD and VoXaLot are both defunct and SIPBroker is looking a little anemic. If you’re still interested in using VoIP with ATAs and making free calls between them, chances are that you’ll have to go with the same VSP on both ends and possibly even pay a fee as “fee-free” accounts are no longer the norm (at least, in Australia).
But there is a better way, namely running your own PBX and the loss of these services definitely inspired me to explore it. In fact, I was already running my own when Project Fax started but I never made the effort to write anything about it. This time, I decided to start afresh with an old Raspberry Pi instead of an x86-64 virtual machine for low-powered goodness.
Why Might You Need a PBX?
As a home user, it might sound strange that you’d even want a PBX in the house. This was something traditionally reserved for a medium to large company, at least, in the older days. But there is a number of good reasons why you might want one:
- To allow you to demonstrate and experiment with old PSTN gear (including modems) using ATAs as line interfaces without routing your calls out over the public internet or relying on a VSP to handle your SIP sessions or paying your VSP for multiple lines.
- To run a virtual fax machine based on a hylafax to send and receive faxes without a fax machine over the internet through a VSP, or to local ATAs to test T.38 and pass-through audio capabilities.
- To allow you to use old handsets as intercoms throughout the house by dialling an internal extension for free calling. You could even replace a doorbell with an old phone – pick up the handset and it rings the phones inside the house automatically (hotline operation).
- To allow you to share a single VSP account amongst multiple phones (although only one call can be made at a time) without having to enter the VSP account credentials on all your devices and changing it every time you change your VSP. You can even set a password on the VSP trunk to prevent unauthorised use and set up dial patterns so that premium calls are not directed to the trunk.
- To allow you to use lowest-cost routing across multiple VSPs (or provide route failover) by setting appropriate dial-patterns and trunk orders, so you always get the best call price.
- To overcome certain NAT problems – get the ports forwarded correctly for your PBX and it will speak to all your devices within your home network free of firewall issues. A difficult situation in you have multiple ATAs trying to register through the same NAT using the same ports!
- To allow incoming calls on your DID to ring multiple phones – that way you can answer from whichever one is closest and transfer it around the house.
- To set up call recording so that all calls through the VSP are automatically recorded.
- To allow you to run your own “hotel-like” wake-up call service and wake up to the traditional ring-tone of a telephone.
- To allow you to use it as an “arbitrary” audio link for use in relaying radio (which is one of my favourite uses) both inside and outside the house.
- To provide teleconferencing services allowing multiple-parties to connect together in a bridge call.
- To perform codec transcoding between SIP devices with incompatible audio codec standards.
The easiest way to get started is to use an “all in one” package of sorts. For most people, this means choosing something like FreePBX or PBX in a Flash (PIAF) for a regular old desktop or laptop. The former is based around Asterisk and an open-source GUI for administration, whereas the latter is somewhat more proprietary being based around 3CX Phone System, both running on Linux.
The equivalent of FreePBX for Raspberry Pi is called RasPBX (or Asterisk for Raspberry Pi). Just like other Raspberry Pi operating systems, you need to download an image, write it to card, plug it in and turn it on. Once running, you’ll have a bit of configuration to do.
This isn’t going to be a complete guide to configuration, but will touch on some important points to check with a few hints for common issues. I encourage all users to take the time to familiarise themselves with the configuration options – make a mistake and you could end up with a PBX that could be externally exploited (where you have opened outside ports, allowed anonymous calls, set the inbound context strangely, not set passwords on outbound trunks, set weak secrets on your SIP extensions or administration users etc).
The first step is always to login via SSH and change the default password. Once that is done, then it’s probably a good idea to run raspi-config to expand the filesystem, set the locale, set up any overclocking and reboot. Once that’s done, it’s back to do raspbx-upgrade, install-fax and install-fail2ban.
At this point in time, it’s probably worth giving your device a static IP address. If you’re not going to do this by binding the MAC at the DHCP server, you can do so by editing /etc/dhcpcd.conf and uncommenting some of the example lines while changing the values to reflect your network.
Once that’s done, you can visit the address in your browser and configure the installation like any other FreePBX installation.
Once logged in, there’s a good chance there’s a list of things you need to do. The most important is probably to go to Module Admin, check online for module updates and apply them all by marking the necessary changes and hitting Process. It will take a few goes to fulfill all dependencies. Also choose any packages you’d like to have – e.g. Wake Up Calls for example (although it has an undocumented dependency on Calendar, as I later discovered).
Assuming you’ve gotten this far, it’s time to configure your extensions. Each of your ATAs and softphones will need an extension to register with the RasPBX. In my case, being lazy, I allocated three digit extensions sequentially – there’s no harm in making a few more than you need for later use. In the case of RasPBX, the default type is pjsip rather than Chan_SIP, which results in fewer configurable options but an easier experience overall.
Important values include the Secret, which is the password that the ATA will use to register with the RasPBX. The other password is for access to the user manager, which is not installed by default. You can configure per-user recording and features on the other tabs. Once you have extensions, you’re almost ready to make calls between endpoints!
Of note is that some extra features (e.g. echo test) are available via Feature Codes which can be redefined – this is necessary as many ATAs grab the *xx codes for their own feature code usage, making it impossible to dial these features from a ring tone. As a result, I reallocated the Wake-Up call from *68 to 800 to avoid this issue.
But you probably want more, so setting up conferences is probably a good idea as well. Conferences are numbers where multiple callers can dial in and talk to each other at the same time. However, you can use it as a broadcast as well – in my case, I configured the 999 conference to connect as muted with the conference control menu (*) available to unmute a user manually. The time limit to the conference was removed and a few other settings tweaked.
Aside from having these features, you might also want to set up a trunk. This is a line you get from a VSP, so you can route calls between your extensions and the outside world via these trunks or accept calls from the outside world through these trunks.
In my case, because the trunk is of pjsip type, the trunk name has to match the user ID. Setting it up is a breeze compared to the older Chan_SIP method where a number of voodoo settings had to be tweaked to make it work.
While you might have a trunk set up, it won’t be used unless an outbound route exists, so it’s time to set one up.
In my case, I have password protection on my outbound routes and I’ve configured a group of “Australian” type numbers to be passed through this route to the trunk configured above. Not all types of calls are routed out the trunk – notice the absence of 000, or 19xx numbers. This way, there’s no chance of accidentally making those sorts of calls.
Likewise, if you want inbound calling to work, you need to set up an inbound route too. This could be as simple as forwarding the call to one extension, or to an IVR menu or a ring group.
Finally, it also makes sense to configure the advanced settings just to make sure your addresses, interfaces, NAT settings, analytics settings are correct, as well as to choose the most important codecs you might want to use with your PBX. I’ve gone with a complement of ‘regular’ high quality codecs and some low bandwidth specials.
How I’m Using RasPBX
I primarily use my PBX with a number of ATAs and softphones (including CSIPSimple, LinPhone, MicroSIP and 3CXPhone). The main reason is as a way of distributing the audio from my DMR digital radio trunking set-up to wherever I might be listening. Instead of using an old-hat system such as running my own ShoutCast/ICECast server, I decided to go the VoIP route for a number of reasons – radio voice is inherently “low-fi”, such streaming servers incur high latency due to the compression and buffering as well as less-than-preferential treatment on the network due to being a non-realtime protocol and by using a VoIP based solution, I can use some older telephone equipment as part of the system as well.
In order for this system to work, I use the “999” conference which is muted by default. The computer that is decoding the DMR audio loops the output back into a softphone registered at extension “100” and dials 999, followed by * and 1 to unmute and send audio into the conference. As 999 is a conference, all other extensions are free to dial-in and can simultaneously receive the audio.
When around the house, I can use this Uniden DECT 1015 that I modified as my receiver. I desoldered the leads to the earpiece and connected it to a stereo 3.5mm socket with a 100 ohm resistor in series. I also soldered a bridge across the microphone, shorting it out, preventing “side-tone” and “hybrid mismatch” interference from the microphone pick up.
Because the battery in the unit had been roasted, I replaced it with a 2xAAA holder initially and cut off some of the pegs inside to make it fit. Unfortunately, the holder itself became faulty, so I soldered to the batteries directly and heatshrinked around it to rebuild the pack. It has been working well since with about 6-8 hours listen time on a charge! This way, I’m clogging up the DECT 1.8Ghz spectrum rather than my own Wi-Fi.
To ensure the best quality, the ATA (a Cisco SPA112) is configured to use G711a as the codec and is configured to “hotline” into the 999 conference – so all I have to do is pick up the phone and I’m on.
Just in case you’re wondering – there’s a few more settings worth tweaking for that “genuine” Australian phone line sound.
While I’m at my desk, I have a proper PC and I can connect to the stream via MicroSIP registering on another extension. Better yet, as the receiving computer has VNC control, I can even check the screen to determine which talk-group is active.
But the best part is when I’m not at home. There’s no way I can carry a laptop, two tuners and antenna around just to listen to some DMR, so instead, now I rely on the internet to link me back home to my set-up. That way, I can be out and about with my phone and look like anyone else on a phone call … but I’m actually scanning the air.
To do this, the RasPBX has been configured with a trunk to my VSP. As I still have $0 monthly accounts with my VSP and my VSP allows free calls between internal VSP numbers, I register my smartphone to my VSP when I am out and dial the VSP trunk number. The inbound rule routes it into the conference automatically and I’m listening on the go. Better yet, as I have another Raspberry Pi configured as an SSH tunnel – I can even get back into the home network to view the VNC screen if necessary.
This is, however, a simplified explanation, as I am relying on a triple-NAT to WAN which I cannot do anything about. While it’s much safer to “hide” behind your VSP and not expose your asterisk server to the world, it’s also a bit of a chore to make sure it works reliably owing to the complicated mechanics of NAT traversal (especially multiple). Luckily for me, it seems to work just fine – but for my SSH tunnel, this actually relies on me reverse-tunneling to my other house with a static IP and no such NATs in the way.
If I were just to end it here, having the audio would probably send me broke owing to the fact I’m paying LTE data rates on both ends, so this is where wise choice of codecs comes in. Because of computational limitations on the Raspberry Pi and codec support limitations, I settled on Speex as my preferred low-bitrate codec due to its quality and configurability, with iLBC coming second due to its high packet-loss tolerance and GSM coming third due to its broader support.
While there is no /etc/asterisk/codecs.conf in the distribution, I found that if it is created, the Speex encoder will use it!
[speex] ;0-10 quality => 3 ;0-10 complexity => 8 ; true / false enhancement => true ; true / false vad => true ; true / false vbr => true ; 0 = off, otherwise, target bitrate in bps abr => 0 ;0-10 vbr_quality => 8 ; true / false dtx => true [plc] ; for all codecs which do not support native PLC ; this determines whether to perform generic PLC ; there is a minor performance penalty for this genericplc => true
I decided to tune the configuration from an initial suggestion from this page. The tweaks improve the encoded voice quality at the cost of CPU (since lowering bandwidth is the aim) and enable VAD (voice activity detection) and DTX (discontinuous transmission) to allow for large bandwidth reductions when no audio is being sent. This is not something which other codecs seem to do with asterisk, even if the incoming audio to a conference is from a VAD source. Enabling VBR causes the bitrate to be allocated flexibly, which means overall better voice quality for the same data transacted and enhancement further provides a perceptual quality boost.
As a result, using CSIPSimple on my smartphone, it’s actually quite possible to have a 45 minute call consume around 4.11Mb of data, averaging 4.7kbit/s of payload for the audio with 11.1kbit/s including overhead. The transmitted audio consumes <1kbit/s due to the use of VAD in the softphone client and muting of the microphone. Add to this the ability to connect a Bluetooth headset so you can enjoy radio even more wirelessly!
Now you can have decent quality voice on the go without breaking the bank! It’s rather impressive that this is even possible, although there are a few downsides including the “irregular” data rate can cause occasional stuttering as the network struggles to meet “peak” demands or NATs start to act strange in regards to packet buffering. I have a second configuration I use with VBR turned off, which seems to behave slightly better in these regards – but even at home on the Wi-Fi where bandwidth is no issue, I still prefer Speex as it reduces network load and power consumption of the Wi-Fi radio in the phone.
There’s a few reasons why one might want a PBX of sorts for their home and in all honesty, it’s not that difficult to set one up. It can be rather useful for experiments but also for intercoms, conferencing, wake-up calls and arbitrary real-time audio linking.
In my case, I’ve used my system extensively to provide “at home” and “on-the-go” linking to my DMR trunked audio decoder and it has worked brilliantly with low latency and bandwidth consumption while mobile and transparent quality while at home. It’s a rather strange feeling when you’re sitting on the bus and you hear a transmission over the driver’s radio – all tinny and a little scratchy, but less than two seconds later, you’re hearing it crystal clear through your own headphones! Yet, nobody suspects a thing – it’s not like carrying a chunky radio scanner.
Later on, I will be using the same system to do some telephony demonstrations for fun as well, so having the RasPBX available means having the convenience to do rather nifty things without burning through a lot of electricity.