Monday, August 10, 2009

Using PAN/NAP instead of rfcomm/ppd

I finally got a new mobile phone - one that not only supports rfcomm ("serial port" via bluetooth) but also the "PAN Network Access Point" profile - which allows a computer to connect to the internet easily, without many extra layers like PPP etc.

It's actually quite easy to use. (Note: I'm doing all that on recent openSUSE Factory, but I am pretty sure that it would work just as good on plain 11.1)

It is very handy to have the bluez-test package installed, many of the tools I am using are in that package.
First, we need to create a connection to the phone, exchange PIN numbers etc. I use bluetooth-applet from the gnome-bluetooth package (or the one from bluez-gnome) for that, it's just the best maintained tool for the task, even if you are a KDE guy like I am, I'd highly recommend it.

Now we need to find out the phones Bluetooth-Address (bdaddr):

seife@stoetzler:~> test-discovery
[ 00:24:EF:xx:xx:xx ]
Name = seife C510
Paired = 1
LegacyPairing = 1
Alias = seife C510
Address = 00:24:EF:xx:xx:xx
RSSI = -54
Class = 0x5a0204
Icon = phone

The hex number after "Address" is the bdaddr of your device.

Now we can create a network device:
seife@stoetzler:~> test-network 00:24:EF:xx:xx:xx nap
Connected /org/bluez/16833/hci0/dev_00_24_EF_XX_XX_XX to 00:24:EF:xx:xx:xx
Press CTRL-C to disconnect


Now you should have a bnep0 network interface and can (as root) either run dhcpcd directly on it, or create a config file "ifcfg-bnep0" in /etc/sysconfig/network like this:
BOOTPROTO='dhcp'
NAME='pand network device'
STARTMODE='auto'
USERCONTROL='no'

and then call "ifup-dhcp bnep0".

Two things to consider:
First, if your system is using NetworkManager, you don't get DNS addresses into resolv.conv. See this post for details. I now have
NETCONFIG_DNS_POLICY="STATIC_FALLBACK ppp0 bnep0 NetworkManager"

in my /etc/sysconfig/network/config

Second, test-network will terminate the connection after 1000 seconds (it is only a test tool), but it is easy to fix, just copy it to ~/bin/my-test-network (or whatever name you like) and apply the following trivial diff:
--- /usr/bin/test-network
+++ ~/bin/my-test-network
@@ -35,9 +35,10 @@
print "Press CTRL-C to disconnect"

try:
- time.sleep(1000)
- print "Terminating connection"
+ while 1:
+ time.sleep(1000)
except:
pass

+print "Terminating connection"
network.Disconnect()


I'm not a python wizard, so I'm pretty sure you can do better, but it works well for me.