March 24, 2014

Bluetooth DUN Tethering with Linux and a Nokia Symbian Phone

Filed under: Technical — Tags: , , , , , — James Bunton @ 6:06 pm

A small Python script to connect to the internet over Bluetooth DUN (dialup networking) using my Nokia Symbian phone and my Linux laptop.

This was written on Arch Linux but should work elsewhere too. It uses bluez5 to enable bluetooth, rfcomm to create the serial port and wvdial to create the PPP connection and manage routes/DNS. Many newer phones use Bluetooth PAN instead of DUN so this method won’t be applicable.

Once upon a time this all worked automagically with NetworkManager. Since bluez5 it fails with this error:

Method "Connect" with signature "s" on interface "org.bluez.Serial" doesn't exist

Apparently we’re supposed to use the new Serial.ConnectFD DBUS API instead.

Install Bluetooth

# pacman -S bluez bluez-libs bluez-utils
# gpasswd -a <your-username> lp # No idea why the lp group gives access to bluetooth [1]
# systemctl enable bluetooth
# systemctl start bluetooth

[1] See the policy in /etc/dbus-1/system.d/bluetooth.conf

Find your phone

First set your phone to be discoverable. Then run this command, the output should be comparable to mine.

$ sdptool search DUN
Inquiring ...
Searching for DUN on DE:AD:BE:EF:12:34 ...
Service Name: Dial-Up Networking
Service RecHandle: 0x10021
Service Class ID List:
  "Dialup Networking" (0x1103)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 42
Language Base Attr List:
  code_ISO639: 0x454e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Dialup Networking" (0x1103)
    Version: 0x0100

Make a note of the Bluetooth MAC address and the channel number. In the example above these are DE:AD:BE:EF:12:34 and 42 respectively.

Pair with your phone

Ensure your phone is still discoverable. Use your phone’s real Bluetooth MAC address below.

$ bluetoothctl
[bluetooth]# agent KeyboardOnly
[bluetooth]# default-agent
[bluetooth]# connect DE:AD:BE:EF:12:34

Accept the pairing request and type any PINs that each device asks for. I’d also recommend setting your mobile phone to trust incoming connections from your laptop. Otherwise you’ll need to unlock your phone and accept each incoming connection request.

Configure bt-dun-connect

Create a file: ~/.config/bt-dun-connect.json with the Bluetooth MAC address and channel that you found earlier.

{
  "apn": "internet",
  "bluetooth_addr": "DE:AD:BE:EF:12:34",
  "bluetooth_channel": "42"
}

Install bt-dun-connect

Install the dependencies:

  • python3
  • python-dbus
  • wvdial
  • bluez and bluez-utils

Download bt-dun-connect somewhere. Maybe in ~/bin?

Now just run it as root at it should connect.

What does it do exactly?

  1. Connects to Bluez over DBUS and switches on your Bluetooth hardware. Assumes hci0
  2. Resets any existing rfcomm serial ports.
  3. Connects the next rfcomm port, this should always be /dev/rfcomm0
  4. Sleep loop until the bluetooth serial port has been set up.
  5. Create a temporary wvdial configuration file using the rfcomm serial port established earlier.
  6. Run wvdial to establish the PPP connection, wait for it to exit.

Upon failure of anything above, or if you just CTRL-C to stop wvdial everything is cleaned up.

  1. wvdial is terminated.
  2. rfcomm ports are stopped.
  3. wvdial temporary config file is deleted.
  4. Bluetooth is disconnected but not switched off.

2 comments

clime says:

Works nicely. Thx!

works fine says:

Thanks for your posting, it works to me on my openSUSE 13.1

Leave a Reply

Your email address will not be published. Required fields are marked *