Skip to content

Tethering Monitor (or an exploration of python and dbus)

The Bluetooth DUN package has been well received, but was hardly a profound programming endeavour. So, I’ve been trying to find suitable inspiration for a more substantial project. This morning, someone made a comment on the Bluetooth DUN page that there’s no way to tell if the phone has a tethered data connection or not – and he’s right: there’s no visual feedback on the phone, unlike Nokia’s Symbian devices or, I imagine, many other phones in the world. With that as a motivation, I decided to try and write a status indicator for tethering.

My first decision was language, and I went with Python as I’ve wanted to use it more and I know how laborious it would be to write this kind of utility in C. I then had to dig around to find out how to write a status area plugin in Python, and luckily there is a way, and it’sfairly well documented.
The biggest source of confusion is that the get_dbus_connection method isn’t exposed in the Python bindings. So, after that took *way* too much time to work out, I had to try and achieve the same thing with direct DBus calls (get a private connection that doesn’t kill the app if it dies), which I reckon I’ve got right.

Once you’ve got the basic stuff sorted out, it becomes really easy to iterate and test – you replace the python file and move .desktop file in and out of a specific directory and Hildon will reload it. Debugging was a real pain because the phone components that I’m talking too don’t exist inside the scratchbox dev environment – so I had to play a trial and error game on the N900 itself, where my only feedback was the icon failing to appear – what fun.

The next challenge was investigating what DBus interfaces to use to find the necessary information. The most important one is com.nokia.csd.GPRS. It’s not documented anywhere, but it’s fortunately introspectable and has obviously named methods and signals, so I was able to establish when a connection is made, suspended or disconnected.

Unfortunately, you see the same set of signals whether the connection is made by the phone itself or a tethered client, so then I had to find a way to detect if the phone was using the connection. I eventually found a way by using com.nokia.icd and com.nokia.icd2 – the first is undocumented and unintrospectable while the second is actually documented. For com.nokia.icd, I was able to use dbus-monitor to find a useful status signal and the get_ipinfo() method I needed had been explored by others. So, now I can avoid false positives from phone initiated connections.

There is one problem that remains, however: It’s possible to tether through the phone at the same time that the phone is using the connection for itself – this is apparently not as amazing as it sounds; all my old phones could do it. In this case, there appears to be no way to notice the tethered connection, so the monitor will not report it. At the moment, I’ve got no good ideas for doing this cleanly – I might be able to poke sysfs or look for pnatd processes, but neither is particularly attractive. But it’s not that common a case, so I consider the program useful before this gets solved.

And what does the program actually do? It shows an icon in the status area that reflects the connection state: disabled, attached, or suspended. I actually think that showing an icon when there’s no connection is a bad use of real eastate, so I’m going to take that out of the next release, but it’s there for now and helpful for confirming that the plugin actually started.

If you’re interested, you can grab it from extras-devel.

Enjoy!

{ 3 } Comments

  1. SMcV | 1st February 2010 at 06:32 | Permalink

    “try and achieve the same thing with direct DBus calls (get a private connection that doesn’t kill the app if it dies)”

    If using dbus-python, I think you want dbus.connection.Connection.

    (A dbus-python Connection and a dbus-glib DBusGConnection are only tenuously related – they’re both bindings for libdbus’ DBusConnection, but dbus-python never shares its connections anyway since it is/was impossible to rule out assertion failures if it did – so a C binding for get_dbus_connection wouldn’t be very easy or useful.)

  2. Philip Langdale | 1st February 2010 at 07:36 | Permalink

    It was not clear to me from reading the dbus-python API reference. There are still ways to say you want a private or public connection and one of them is marked deprecated but others are not.

    In the end I went with:

    bus = dbus.Bus.get_system(True)
    bus.set_exit_on_disconnect(False)

    but it sounds like you’re saying dbus.connection.Connection is always private.

  3. Danilo | 4th February 2010 at 15:55 | Permalink

    If you need inspiration, rSAP bluetooth profile might do it ;)

{ 1 } Trackback

  1. [...] This post was mentioned on Twitter by VMware Planet V12n, Zuissi and Knut, drano’s RSS Feeds. drano’s RSS Feeds said: [GNOME] Philip Langdale: Tethering Monitor (or an exploration of python and dbus) http://bit.ly/9KzL4d [...]