Using a Raspberry Pi, Asterisk and a Bluetooth dongle to route phone calls through a mobile phone
24 Feb 2016Mobile data is a strange thing in Australia. After taking advantage of an Optus ‘bonus data’ prepaid offer (5GB for $5, although I only got 3GB…), I was left with ‘unlimited’ calls that I was never going to make the best use of. However, I figured there was a better way to leverage more out of this offer - specifically by routing all my home phone calls through my mobile service.
After some thought, the above diagram is how the system works. As I was already routing home phone calls through an ATA to use VoIP, I only needed to add my own SIP server that somehow routed my calls through my mobile. Having a Windows Phone, writing an app to do this is impossible, given that the API is simply not there to perform remote calls. However, like many other smartphones, it does support making and receiving calls through a Bluetooth connection - and this is how, along with an Asterisk instance running the chan_mobile
module, this setup is possible. The only reason I’m using the Raspberry Pi to do this was because I had one laying around that wasn’t doing much of anything, and this seemed like the perfect opportunity to use it.
Contents
Getting Asterisk
For the Raspberry Pi, RasPBX seems to be the way to go.
- For a quickstart, download RasPBX (at the time of writing, I am using version 25-01-2016). Unzip and write the
.img
file to a microSD card that’s at least 4GB large. I like to use Win32 Disk Imager.- If like me, you don’t have (or aren’t willing to spare) a 4GB microSD card, but do have a bunch of USB sticks lying around, then you can follow these steps instead (be warned: it’s quite tedious and you should know your way around Linux)
- You will need a microSD card that is at least 100MB large and a USB stick that is at least 4GB large (you may get away with 2GB, but you’re really pushing it). Ensure the microSD card is FAT32 or FAT16 formatted (I prefer FAT32).
- Install Virtualbox and create a Linux VM. You will need some way of mounting shared folders from within the VM. I already had an Ubuntu VM which served this purpose. To the VM, add a hard drive specifically for the RasPBX image (at least 4GB large)
-
From inside the VM, I will assume the empty VM hard disk is on
/dev/sdb
, and the microSD card is on/dev/sdc
. I will also assume that you have setup a shared folder that contains the RasPBX image.1 2 3 4 5
mkdir share sudo mount -t vboxsf my_shared_folder share mkdir microsd sudo mount /dev/sdc1 share
-
Dump the contents of the image into the empty hard drive:
1 2
cd share sudo dd if=raspbx-25-01-2016.img of=/dev/sdb
Or if you want to see progress, install
pv
first, then run1 2
cd share pv raspbx-25-01-2016.img | sudo dd of=/dev/sdb
-
Refresh the partition table:
1
sudo partprobe /dev/sdb
You should now see
/dev/sdb1
(the boot partition) and/dev/sdb2
. -
Copy everything from
/dev/sdb1
into the microSD card:1 2 3 4 5 6
mkdir tmp sudo mount /dev/sdb1 tmp sudo cp -r tmp/* microsd/* sudo umount tmp sudo umount microsd
- From within your host machine, edit
cmdline.txt
on the microSD card: Where you seeroot=/dev/mmcblk0p2
, replace this with/dev/sda1
- this will make it boot from the USB stick. - Back in the VM, boot into Clonezilla (I use the stable ISO). Choose all the default options. When Clonezilla is started, choose to work
device-device
(notdevice-image
) thenpart_to_local_part
. The source partition will be/dev/sdb2
(the main partition of the RasPBX image). - Ensure that your USB stick is connected to the VM. This will be your destination partition. On my VM, this would be
/dev/sdc1
. If you don’t see this, check that it’s connected (underDevices->USB
) and re-try Clonezilla. - All the default options should work. Note: Double check that the source and destination partitions are correct! If you don’t, you may mistakenly wipe one of your other (virtual machine) drives. Once you confirm everything, Clonezilla should dump the main RasPBX partition onto your USB stick. It should also automatically expand the partition to match the size of your USB stick, which is nice. Once done, exit Clonezilla.
- Profit! To boot, ensure that the USB stick and your microSD card is connected to your Raspberry Pi before powering on. On bootup, you should see the red LED blink for a few seconds before switching off - then your USB LED (if you have one) should start blinking - it’s now booting off the USB stick. Yay (and phew)!
- If like me, you don’t have (or aren’t willing to spare) a 4GB microSD card, but do have a bunch of USB sticks lying around, then you can follow these steps instead (be warned: it’s quite tedious and you should know your way around Linux)
Configuring RasPBX
The following steps help setup and customise RasPBX to suit your situation. Essentially this follows the stock standard documentation:
- SSH into the RPi - using PuTTY to
raspbx
should work. Or just enter the IP address of the RPi. -
Inside the SSH session (login is root/raspberry), run
1
raspbx-upgrade
This will upgrade all the components. I found this took quite a while (30 mins on a RPi B+).
-
Run
1 2 3 4
regen-hostkeys configure-timezone dpkg-reconfigure locales passwd (to change the root password)
-
I skipped setting up the email. I also didn’t use the provided web GUI (FreePBX). I found it easier to just modify the config files and use Asterisk directly. In fact, FreePBX got in my way, so I disabled it:
1 2 3 4 5 6
update-rc.d freepbx remove update-rc.d apache2 remove wget http://repo.raspbx.org/download/asterisk -O /etc/init.d/asterisk chmod +x /etc/init.d/asterisk update-rc.d asterisk defaults reboot
Adding chan_mobile
support
-
You will need a USB Bluetooth module that works with the Raspberry Pi. I managed to procure one of the el-cheapo $1 eBay USB Bluetooth adaptors, which worked fine.
lsusb
lists it as:1
Bus 001 Device 005: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
-
Next up, you will need to install the Bluetooth drivers:
1
apt-get install bluetooth bluez
-
You will then need to pair it with your phone. With Bluetooth turned on in your phone, run:
1
bluetoothctl
This will provide you with a
bluetooth
console. From here, run1
list
You should see your Bluetooth controller. Take note of it’s ID (like a MAC address, e.g.
14:90:E2:1A:AC:80
).1
scan on
After a while, run
1
devices
You should see your phone listed, along with its own ID. Take note of the ID. Now enter
1
pair <your-phone-id>
And follow the prompts to pair the phone. Once done, you can type
quit
to exit the Bluetooth console. -
The next step is to enable
chan_mobile
support to Asterisk. Under/etc/asterisk
, create a file calledchan_mobile.conf
. You can base the contents on this sample file. My configuration goes along the lines of:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[general] interval=30 ; Number of seconds between trying to connect to devices. [adapter] id=blue address=14:90:E2:1A:AC:80 [WP530] address=0A:E2:10:C3:75:30 ; the address of the phone port=3 ; the rfcomm port number (from mobile search) context=incoming-mobile ; dialplan context for incoming calls adapter=blue ; adapter to use group=1 ; this phone is in channel group 1 ;sms=no ; support SMS, defaults to yes ;nocallsetup=yes ; set this only if your phone reports that it supports call progress notification, but does not do it. Motorola L6 for example.
The
adapter
section contains information on our USB Bluetooth adapter. TheWP530
section defines the mobile phone that I want to connect to. Don’t worry about the exact details for the phone as we’ll come back to that in a moment. - Bring up the Asterisk console by running
asterisk -rvvvv
(the number of v’s is how verbose the console will be) -
In this console, run
1 2
module load chan_mobile.so mobile search
Give it a while. Ensure your phone is unlocked and Bluetooth enabled during this process. You should see your phone pop up in the list. Importantly, it should display a
Usable
column and aPort
column - you want to make sure it saysyes
for usable. Take note of thePort
value and change the value inchan_mobile.conf
to match this if necessary. -
To autoload
chan_mobile
, append to the end of/etc/asterisk/modules.conf
:1
load = chan_mobile.so
-
At this point, the mobile configuration should be complete. Restart Asterisk by issuing:
1
core restart now
From the Asterisk terminal. After a short while, re-enter the Asterisk terminal. Once it has finished loading, run
1
mobile show devices
If you’ve set it up correctly, it should show something like:
1 2
ID Address Group Adapter Connected State SMS WP530 0A:E2:10:C3:75:30 1 blue Yes Free No
Configuring call routing
We now need to setup Asterisk to create a SIP server and to also route calls made through this server to the mobile phone. To setup the SIP server, append the following to /etc/asterisk/sip.conf
:
1
2
3
4
5
6
7
8
9
[test]
type=friend
host=dynamic
secret=test
dtmfmode=rfc2833
canreinvite=yes
nat=yes
qualify=yes
context=test
To connect to this server, from your client, enter the IP address of your Raspberry Pi. The username and password will both be test
. For quick testing on my computer, I used MicroSIP which worked quite well.
Now that the SIP server is setup, the routes need to be formed. Edit or create /etc/asterisk/extensions_custom.conf
, and to it, add:
1
2
3
4
5
6
7
[test]
exten => _X.,1,Dial(Mobile/WP530/${EXTEN},45)
_X.,n,Hangup
[incoming-mobile]
exten => s,1,Noop(Accepting mobile call from ${DID})
exten => s,n,Dial(SIP/test)
This should route all numbers made to the SIP server through to your mobile phone. It should also route any calls made to the phone back to the SIP connected device, although I’ve had less luck on this side.
Once the configuration is done, restart Asterisk as before. That’s it! We’re done! After adding this SIP server configuration to my ATA, I can now make home phone calls that get pushed through my mobile phone.
Adding SIP auto fallback
As it turns out, I wanted to slightly extend this a bit. Since I may not always have my phone present to make calls, I’d like it to auto-fallback to use the SIP providers that I’m already using. My ATA is not quite smart enough to do this itself, since it will just appear like the line is busy if Asterisk fails to connect the call. So instead, I’ve added my SIP providers directly to Asterisk:
-
For each provider, append to
/etc/asterisk/sip.conf
:1 2 3 4 5 6 7 8 9 10 11 12
[telecube-out] type=peer secret=XXXXXXXXX username=YYYYY host=sip.telecube.net.au fromuser=YYYYY fromdomain=192.168.0.10 canreinvite=no insecure=invite,port qualify=yes nat=yes context=from-telecube
Note: Replace
secret=XXXXXXXXX
withsecret=your-sip-password
andYYYYY
with your username. I don’t know iffromdomain
does anything, but I set it to the IP address of my Raspberry Pi. -
For routing, I’ve modified
/etc/asterisk/extensions_custom.conf
to:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[test] exten => _183[12].,1,Dial(Mobile/WP530/${EXTEN},45) exten => _*2.,1,Dial(SIP/${EXTEN:2}@pennytel-out,30,r) exten => _*3.,1,Dial(SIP/${EXTEN:2}@telecube-out,30,r) exten => _X.,1,Dial(Mobile/WP530/1831${EXTEN},45) exten => _04!,2,Dial(SIP/${EXTEN}@telecube-out,30,r) exten => _13!,2,Dial(SIP/${EXTEN}@telecube-out,30,r) exten => _X.,2,Dial(SIP/${EXTEN}@pennytel-out,30,r) exten => _X.,3,Dial(SIP/${EXTEN}@telecube-out,30,r) _X.,n,Hangup [incoming-mobile] exten => s,1,Noop(Accepting mobile call from ${DID}) exten => s,n,Dial(SIP/test)
At the top level, it diverts all numbers through my mobile phone (line 4). You’ll notice that it automatically prepends 1831
to the DID, unless 1831
or 1832
have already been specified by the user (line 1). 1831
(at least in Optus) prevents my caller ID from being displayed, while 1832
forces it to be displayed. Furthermore, if I prefix the DID with either *2
or *3
(lines 2 and 3), then these will be redirected to my SIP providers (I have both Telecube and Pennytel) - like a manual override.
At the second level, if my phone isn’t available, then mobile numbers (04 prefix) and 13 numbers get routed through Telecube, while everything else gets routed through Pennytel (taking advantage of what’s cheaper with which provider). At the third level, if Pennytel fails, then everything gets routed through Telecube. Neat!
Comments