Thursday, January 24, 2008

IP Over Bluetooth and Connection Manager Integration

How do I get Internet access from my Internet Tablet at work with no WiFi access point available? The only solution I have is to use IP over Bluetooth (i.e. L2CAP), and connect through my laptop. After a lot of google-ing I eventually found a solution that works on OS2008 (aka maemo 4 , aka chinook). Well, that sorts out the "getting connected" part of the problem.

For Integration in the connection manager the solution described in the maemo community wiki seemed to fit the bill but the binary provided for the dbus listening daemon won't run on OS2008. Bummer. Digging around I found an enhanced version that can launch scripts based on user defined filters: dbus-scripts written by Graham Cobb.

Now on to the interesting stuff...
  1. For the PC or phone side configuration, refer to the BluetoothNetworking page at maemo.org.

  2. On the N810, you need root access as described in the previous post.

  3. Install the dbus-scrips package from the maemo xtras-devel repository. (thanks Graham for uploading!)

  4. Run X term and login as root:

    sudo su -

  5. Create a dummy access point:

    gconftool-2 -s -t string /system/osso/connectivity/IAP/BluetoothIP/type DUMMY

  6. create the filter for the dbus-scripts daemon. Put the following in a file named for example bluetooth-ip.filter then copy the file on your Tablet in /etc/dbus-scripts.d/

    /usr/local/share/dbus-scripts/bluetooth-ip * * com.nokia.icd status_changed BluetoothIP DUMMY

    This will launch the script /usr/local/share/dbus-scripts/bluetooth-ip as soon as the BluetoothIP connection is brought up or down from the connection manager.

  7. And here's the actual bluetooth-ip script that does all the dbus magic:

    #!/bin/sh

    #BT MAC of PC/phone
    BTADDR='00:19:CC:EB:42:3E' # replace with your own!
    #bluetooth name of PC/phone, not important, just for infoprints
    BTNAME="PC-Bluetooth"
    #desired IP address of your tablet
    IP=192.168.0.2
    #default gateway - IP address of PC/phone
    GW=192.168.0.1
    #DNS server
    NS=123.45.67.89

    # remote PAN role, one of NAP, GN
    PAN_ROLE=NAP

    infoprint(){
    DBUS_SESSION_BUS_ADDRESS='unix:path=/tmp/session_bus_socket' dbus-send --session --print-reply --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint "string:$*" &
    }

    dbus_method(){
    local dest=$1
    shift
    DBUS_REPLY=$(dbus-send 2>&1 --system --type=method_call --print-reply --dest="$dest" $* )
    }

    dbus_result(){
    echo $DBUS_REPLY | cut -d ' ' -f 7 | tr -d \"
    }

    find_connection(){
    #find or create connection

    echo "Searching for $BTADDR ..."
    [ -t 1 ] || infoprint "Searching for $BTADDR"

    if dbus_method org.bluez /org/bluez org.bluez.Manager.ActivateService string:network ; then
    NET_BUS=$(dbus_result)
    # echo destination $NET_BUS
    if dbus_method "${NET_BUS}" /org/bluez/network org.bluez.network.Manager.FindConnection string:"${BTADDR}" ; then
    CONN=$(dbus_result)
    else
    if dbus_method "${NET_BUS}" /org/bluez/network org.bluez.network.Manager.CreateConnection string:"${BTADDR}" string:"$PAN_ROLE" ; then
    CONN=$(dbus_result)
    fi
    fi
    fi

    if [ "$CONN" = "" ] ; then
    echo $DBUS_REPLY
    echo "Setting up connection to $BTADDR failed"
    [ -t 1 ] || infoprint "Connection to $BTADDR failed"
    exit
    fi
    }

    bnep_start(){
    find_connection
    if dbus_method "${NET_BUS}" ${CONN} org.bluez.network.Connection.Connect ; then
    BNEPDEV=$(dbus_result)
    echo connected to $BNEPDEV
    ifconfig $BNEPDEV $IP up
    if route -n | grep -q '^0.0.0.0' ; then
    echo "default gateway already set, skipping GW and DNS setting"
    else
    route add default gw $GW
    echo "nameserver $NS" >/tmp/resolv.conf.lo
    fi
    [ -t 1 ] || infoprint "Connected to $BTNAME"
    fi
    }

    bnep_stop(){
    find_connection
    if [ "$CONN" != "" ] ; then
    echo connection $CONN
    if dbus_method "${NET_BUS}" ${CONN} org.bluez.network.Connection.Disconnect ; then
    echo "OK, bringing down"
    echo -n '' >/tmp/resolv.conf.lo
    [ -t 1 ] || infoprint "$BTNAME disconnected"
    fi
    fi
    }

    [ "$3" = "com.nokia.icd" ] || exit 0
    [ "$7" = "CONNECTED" ] && bnep_start
    [ "$7" = "IDLE" ] && bnep_stop

    Place this script in /usr/local/share/dbus-scripts (you may have to create the folder) and make it executable:

    chmod +x /usr/local/share/dbus-scripts/bluetooth-ip

    This is heavily based on this forum thread at InternetTabletTalk.com. You'll find additional info on the various parameters of the script in that thread. And thanks to fanoush for his hard work on this!

  8. Now all you have to do is restart the dbus-scripts daemon:

    /etc/init.d/dbus-scripts restart

  9. Make sure that your N810 and PC or phone have been paired: Settings -> Control Panel -> Bluetooth -> Devices -> New.

  10. Go to the connection manager and select your new BluetoothIP connection..... and cross your fingers!

Troubleshooting tips:
  • From Xterm you can run the dbus-scripts daemon in debug mode. Stop it first (as root):

    /etc/init.d/dbus-scripts stop

    Now start it manually in debug mode:

    dbus-scripts --system --debug

    Try to connect again and go back to the Xterm window to see if there's any error message (scroll up!)

  • If you get a notification that the connection is established but you can't access any web site, check that the DNS in the bluetooth-ip script is set to the same as on your computer (try ipconfig from the command line). You can also try to ping your computer or phone. If you get a reply, then the problem is very likely on the computer or phone.

  • Make sure that the IP addresses in the bluetooth-ip script match with your computer's or phone. Also make sure you select IP addresses in the same subnet.

  • If you're trying this while you have a WiFi access point nearby and your Tablet is set to automatically connect to it, disable automatic connections, otherwise the connection manager will automatically pick up the access point instead of starting the dummy connection.
Granted, it's not really for the faint of heart. But in the end it's quite rewarding. What would one do to avoid typing a few commands in a terminal? ;)

2 comments:

Graham Cobb said...

I have now built dbus-scripts for chinook and made it available from my repository (http://www.cobb.uk.net/NokiaIT/) and uploaded it into extras-devel.

Denis Bernard said...

Thanks Graham!