Raspberry Pi Bluetooth iPhone Tethering
For the truckputer project, I want to pair with my iPhone for various things from file transfer to hand-free calling to Internet access. Towards that end, I picked up a Cirago Bluetooth / WiFi USB mini adapter (BTA7300) since it was cheap and reviews showed it Just Works with Linux. Happily, it did not disappoint.
Prereqs
First, you want to install the bluetooth packages:
pi@raspberrypi ~ $ sudo aptitude install bluetooth bluez-utils bluez-compat
Getting Started
Plug in the Bluetooth dongle and immediately the Pi knows what’s up:
pi@raspberrypi ~ $ lsusb | grep -i bluetooth
Bus 001 Device 006: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
pi@raspberrypi ~ $
Scanning for Devices
In my case, I’m pairing with an iPhone 4S. Go to Settings->Bluetooth, and set Bluetooth to “on”. At the bottom of your screen, you’ll see the text “Now Discoverable”. If the device you’re pairing with isn’t discoverable, the Pi isn’t going to see it. In the case of the iPhone, it’s only discoverable while this screen is active. Yes, that means you have to poke the screen every now and again to keep the phone awake if you’re doing extended testing.
At any rate, once you’ve got the phone discoverable, you can do a scan from the Pi:
pi@raspberrypi ~ $ hcitool scan
Scanning ...
18:34:51:DE:AD:BE:EF Fanboy ][
pi@raspberrypi ~ $
Happily, there’s my iPhone. The hex string is the Bluetooth MAC address of the phone and “Fanboy ][” is phone’s name defined in Settings->General->About. Remember to use the MAC address of your phone and not mine throughout the rest of this walkthrough.
Pairing
Now that we know that we can see the phone, we want to actually pair with it
pi@raspberrypi ~ $ sudo bluez-simple-agent hci0 18:34:51:DE:AD:BE:EF
Creating device failed: org.bluez.Error.ConnectionAttemptFailed: Page Timeout
pi@raspberrypi ~ $
Oh no! That doesn’t look like what we want to see. Did your phone fall asleep? Wake it back up, make sure you’re on the Settings->Bluetooth screen, then try it again.
pi@raspberrypi ~ $ sudo bluez-simple-agent hci0 18:34:51:DE:AD:BE:EF
Creating device failed: org.bluez.Error.AuthenticationRejected: Authentication Rejected
pi@raspberrypi ~ $
Oh no, again! It still didn’t work, even with the phone discoverable! This time the problem is a little bug in bluez-simple-agent. By default, bluez-simple-agent wants to use a capability called “KeyboardDisplay” that isn’t going to work for us. We need to change that to “DisplayYesNo” so that we can get a nice Yes/No prompt on the command line when pairing devices.
pi@raspberrypi ~ $ grep KeyboardDisplay /usr/bin/bluez-simple-agent
capability = "KeyboardDisplay"
pi@raspberrypi ~ $ sudo perl -i -pe 's/KeyboardDisplay/DisplayYesNo/' /usr/bin/bluez-simple-agent
pi@raspberrypi ~ $ grep DisplayYesNo /usr/bin/bluez-simple-agent
capability = "DisplayYesNo"
pi@raspberrypi ~ $
Remember to wake your phone up before trying to pair. When the CLI on the Pi prompts you, type “yes” and hit [enter].
pi@raspberrypi ~ $ sudo bluez-simple-agent hci0 18:34:51:DE:AD:BE:EF
RequestConfirmation (/org/bluez/18868/hci0/dev_18_34_DE_AD_BE_EF, 160178)
Confirm passkey (yes/no): yes
Release
New device (/org/bluez/18868/hci0/dev_18_34_DE_AD_BE_EF)
pi@raspberrypi ~ $
This time, you should see a prompt on your phone to pair with your Pi. The code on your phone should match the request confirmation on the Pi. Hit “Pair” on the phone and you’ll be dropped back to the Settings->Bluetooth page, but this time you’ll see your Pi on the device list.
Unless you really want to manually pair with a code every single time, add your phone as a trusted device on the Pi:
pi@raspberrypi ~ $ sudo bluez-test-device trusted 18:34:51:DE:AD:BE:EF yes
If your phone ever becomes evil and you don’t want to trust it anymore, that’s easy too:
pi@raspberrypi ~ $ sudo bluez-test-device remove 18:34:51:DE:AD:BE:EF
Internet Access
Personally, I actually pay AT&T for the privelege of tethering legally. Crazy, eh? Yeah, it’s stupidly expensive and I had to give up my unlimited data plan, but the last thing I need is to be sued by AT&T and honestly, I’ve never come close to my cap. If you jailbroke your phone to get tethering, you probably already know what you need to adjust here to make things work. Anyway. In order to access the world through your phone, you need to setup a new Personal Area Network using pand
and add a line to your /etc/network/interfaces
so that the Pi knows to grab an address from DHCP when bnep0
comes up:
pi@raspberrypi ~ $ echo "echo 'iface bnep0 inet dhcp' >> /etc/network/interfaces" | sudo sh
pi@raspberrypi ~ $ sudo pand -c 18:34:51:DE:AD:BE:EF -role PANU --persist 30
Give the Pi and phone a second or two to get their act together. Your phone may prompt you to pair with the Pi if it isn’t already paired.
Once you accept, you should see that bnep0
on the Pi now has an address and is ready to rock.
pi@raspberrypi ~ $ ifconfig bnep0
bnep0 Link encap:Ethernet HWaddr e0:91:DE:AD:BE:EF
inet addr:172.20.10.10 Bcast:172.20.10.15 Mask:255.255.255.240
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4426 (4.3 KiB) TX bytes:802 (802.0 B)