Saturday, March 7, 2009

Multiple networks and GUPnP

When GUPnP was first used at Maemo software, one of the first questions I was asked was: Can't GUPnP handle multiple network interfaces just like ClinkC (the now deprecated UPnP framework in Maemo)? The answer to that question was "yes but you have to take care of creating GUPnPContext objects for each network interface yourself" and that wasn't very convenient. This issue, accompanied by the fact that applications had to know when the interfaces go up and down to create and destroy the associated GUPnPContext object themselves, made the lives of application developers not so easy.

Recently when this issue was raised on the mailing-list and bugzilla by two different people, I started to think about how to solve this issue. Keeping in view Ross' advice I came-up with the following solution

A GUPnPContextManager class that basically just have two signals: "context-available" and "context-unavailable", that it uses to create/destroy and report GUPnPContext object for each network interface as it goes up/down. While the API was easy, the implemenation wasn't as there is no portable way of doing this. So what I did was that I wrote two different implementations that user (packager) can choose at configure time:
  1. GUPnPUnixContextManager: Unix-specific implementation of GUPnPContextManager that only checks for all the up interfaces and creates a GUPnPContext object for each one of them. It doesn't unfortunately have any way of knowing when the interfaces go down. One can monitor network interfaces using netlink but that will be linux-specific and therefore should go into a separate implementation. Such an implementation will also be something that will be feasable for maemo so in case you are interested in small tasks for maemo, this is yet another chance. :)
  2. GUPnPNetworkManager: Implementation of GUPnPContextManager based on NetworkManager. This is a full-features implementation and hence the default one.

Although I got this working last week, I realized that Jorn might have overlooked something in his great plan: Every GUPnPContext was joining and watching the multicast channel on the same (default) interface no matter which interface it was created for so the discovery/announcement part wasn't quite functional on each interface. Since this required some fundamental changes in GUPnP stack and the fact that it had been quite some time since I last touched unix socket APIs, it took me a week to get this right. Fortunately, GUPnP API/ABI didn't need to be broken for all this and all that changed in the API was the move of a property from one class in gupnp package to it's parent class in gssdp package (this implied deprecation of one getter and addition of another though).

So after two weeks of hard work, the world seems to be a better place now. The needed changes are yet to be reviewed and merged by Ross so for now if you are interested to try these out, you need to use my 'multinet' branches from gitorious repos:

No comments: