Category Archives: Development

Profiles in Devhelp

I’m at the GNOME Development Experience Hackfest in Berlin, and one of the things that I wanted to target during these days was to keep on looking at how we can enable different profiles in Devhelp.

devhelp-profiles

As you probably know, Devhelp will show you the documentation of libraries installed in your system (usually only if you have the -devel or -docs package of the library installed). While this is already enough for most users, there is also the case where a developer wants to target a different version (older or newer) of the library than the one installed in the system.

A typical case for this is developing applications using GNOME’s jhbuild infrastructure, targeted either to a given GNOME release or to git master of the involved modules. In this case, if you want to use new methods of let’s say GTK+, you usually end up needing to fire up a web browser and looking for the latest GTK+ documentation either in developer.gnome.org or in your jhbuild’s ${prefix}/share/gtk-doc/html directory.

In order to avoid this, I’m prototyping some ideas to let the users switch between different profiles, e.g.:

  • The ‘local’ profile, which is equivalent to what Devhelp currently shows.
  • A user-defined ‘jhbuild’ profile, which could point to the install prefix of the jhbuild setup.
  • Other user-defined profiles, which could point to other prefixes where the user has installed the newer (or older) libraries and their documentation.
  • Profiles for each new GNOME release, e.g. 3.12, which could get downloaded from developer.gnome.org as a tarball containing all documentation for a given release.

The most challenging case is probably the last one, given that it would require some extra work in the website in order to make sure the documentation tarball is generated and published in every new release, plus of course client-side management of these downloaded profiles in Devhelp.

For now this is just a basic set of ideas, the final result may or may not be similar; we’re of course open to suggestions!

sponsored-badge-simple

Mobile Radio Monitor

mrm-launcher

The Mobile Radio Monitor is a new (GPLv3+ licensed) application I wrote this summer, which lets you grab signal and power information from QMI-powered modems, and displays it in time-based graphs. I really wanted to use some of the shiny new things available in GTK+ 3.9.x, so this application seemed a good excuse to play around with the GtkStack, GtkListBox, templates and such.

Internally, this application does not talk to ModemManager at all. The other thing that I wanted to try out with this application was the use of the ‘qmi-proxy‘ approach in libqmi, which lets you share a QMI port between different processes, and therefore this UI application can run alongside ModemManager without much collision between the two.

Launching

The Mobile Radio Application installs a desktop file, so it can be launched directly from the desktop shell. It needs to run as root, so “pkexec” takes care of requesting user authentication to gain privileges through polkit. The other option, of course is to just launch it from the command line using “sudo” or the like.

BTW, yes, the icon is the same one from gnome-system-monitor with just different colors. Quick and dirty hack, but looks good to me. Thanks to jimmac, who I think draw the icon originally ;)

Device list

When the application starts you’ll be greeted with the QMI device list detected by the application. Unusable modems will be shown as deactivated items (e.g. when modem requires a SIM but there is no SIM inserted), and for the usable ones you’ll be able to insert the PIN if required.

mrm-device-list

Signal information

Once a device has been selected, the application will switch to the Signal information tab, where you can see graphs for things like RSSI, Ec/Io, S/N, RSRP and RSRQ

mrm-signal-tab

Not every technology exposes all the previous values, though. GSM will only show RSSI, while UMTS/HSPA will show RSSI and Ec/Io. In addition to the graphs, the current instant value of each signal property is also given in the legend box.

Hiding/showing graphs based on the current used access technology was an idea, but I left it out because you can actually switch the preferred technology using e.g. qmicli’s --nas-set-system-selection-preference, and therefore you would be able to see graphs with both access technologies.

Power information

In addition to signal information, the application also exposes receiver and transmitter power values in the Power information tab.

mrm-power-tab

Thanks to being able to have ModemManager running at the same time, you can actually get the modem connected and see how both the RX and TX power values go up and down.

Want to try it?

You can grab the sources from the following gitorious.org repo:
https://gitorious.org/aleksander/mobile-radio-monitor.

As said previously, it uses unstable GTK+ plus unstable libqmi, so you’ll need these sorted out before trying to compile the project. I have tried it myself both in a Fedora 19 setup (under jhbuild to get latest GTK+ and self-compiled libqmi from git master) and in a Fedora 20 (just grab these packages).

As always, comments and patches welcome :)

Sharing a QMI port between processes

A bit of background…

I’ve blogged earlier about how the QMI protocol defines different services and allows to have multiple clients allocated for each service. Allowing multiple clients (i.e. QMI transactions with different client ids) was originally implemented in the protocol to allow multiple user-space applications to talk to the Gobi device, as the original Qualcomm kernel drivers allowed this. In these drivers, the management of client allocations and releases (through the implicit CTL service) was done by the kernel itself, and thus, multiple user-space applications could request new clients at the same time, leaving the work of managing the actual QMI communication with the device to the kernel.

But that is no longer the case with the ‘qmi_wwan‘ driver available in the upstream Linux kernel. In this case, the implicit CTL service is also managed in user-space, and there should be a single process involved in talking to the QMI port. The side effect of this behavior was that the whole client allocation logic didn’t make much sense any longer, as the process owning the port would be the only one being able to create clients.

Luckily, we designed the libqmi interface in a way that the CTL service was completely hidden to the user of the library. A user would just create a ‘QmiDevice‘ object, and afterwards allocate new ‘QmiClient‘ objects using the device object. All the internal CTL service communication between the user-space process and the actual modem device would be run internally by objects we created.

So, with the target of allowing multiple user-space processes to use the same QMI port in mind, a new ‘qmi-proxy‘ daemon was created in libqmi. Whenever a ‘QmiDevice‘ is opened with the new ‘QMI_DEVICE_OPEN_FLAGS_PROXY‘ flag, we will try to launch the ‘qmi-proxy’, which will be the only process talking to the actual QMI port. Every other process using the ‘QMI_DEVICE_OPEN_FLAGS_PROXY‘ flag, including the one which launched the proxy, will now send the QMI requests to the proxy, and receive the QMI responses and indications from the proxy.

Internals

In order to implement the proxy-based communication in libqmi’s ‘QmiDevice‘, we didn’t have to do many changes:

  • We extended our implementation of the CTL service with a new ‘Internal Proxy Open’ command, which allows the application to tell the proxy which QMI port wants to use. This command uses the 0xFF00 command id, far away from the current set of command ids currently available for the CTL service, so not likely to collide with any new update of the service ever.
  • All the communication from and to the proxy are plain QMI commands, including requests and responses in the CTL service. The only critical thing to do was to make sure that the ‘QmiDevice‘-side CTL transaction ids (i.e. unique CTL transaction in a given process) were translated to the ‘qmi-proxy’-side CTL transaction ids (i.e. unique CTL transaction with the actual device).
  • The CTL service is the only one requiring the transaction id translation, as for every other service clients need to be explicitly allocated and released. In other words, different applications will allocate different clients with different client ids, and once they all have its own client id, they can just use the transaction id that they prefer.
  • The ‘qmi-proxy’ only analyzes each transferred QMI message in very specific situations. In addition to the CTL transaction id translation mentioned above, the proxy will also take care of forwarding QMI indications (unsolicited messages) to the process owning the client id stated in the indication itself, or to all processes with a client for the service if the ‘broadcast’ client id is used. As an example, a process could request to get notified about signal quality updates via unsolicited “NAS signal info” messages, and the qmi-proxy will make sure that those indications are only sent to the specific process which requested them.
  • In order not to use resources when not needed, the ‘qmi-proxy’ is automatically started when first requested, and will be automatically stopped 30s after the last process disappears or releases the last client. We are using a unix socket with an abstract name, so there are no worries of race conditions where proxies are launched at the same time, and no need to make sure that a socket file is never left in the filesystem when the ‘qmi-proxy’ crashes unexpectedly.
  • To simplify the logic of the ‘qmi-proxy’, it will not take care of following which QMI ports are available in the system. As with the case of not using the proxy, each application needs to know which ports are available and can be requested to be open. If a port disappears and the proxy still receives requests to that port, it will just return a QMI error to the application which sent the request.

All the previous logic, as said earlier, is managed internally by libqmi and hidden to the user of the library. The key point is to modify your application to use the ‘QMI_DEVICE_OPEN_FLAGS_PROXY‘ flag.

ModemManager and qmicli

We also improved the ‘qmicli’ command line interface to allow a new ‘--device-open-proxy‘ argument (or the shorter ‘-p‘), which will make use of the new flag to request the ‘qmi-proxy’ to be used. And same for ModemManager; if the version of libqmi is >= 1.7 (currently git master), the new flag will be used by default. We can finally use both ‘qmicli’ and ModemManager at the same time, as ModemManager won’t be the only process owning the port.

Wait…

But why would anyone want to let other applications use the QMI port? Wouldn’t that collide with the logic of ModemManager?

Well, yes and no. It really depends on which kind of other applications you want to have running alongside ModemManager. If you want to run yet another connection manager, taking care of connecting and disconnecting the QMI port and such, then yes, it will likely collide with ModemManager’s own logic. But that should never be the case. The QMI protocol provides access to tons of features which are not handled by ModemManager, and that is where other applications will benefit from the proxy. Think of custom applications which want to get a deeper view of the status of the radio network using the NAS service, or a GPS application which wants more than what ModemManager provides, or a SIM browser application reading SIM files with the UIM service, or… well, you name it.

When will this be available?

The ‘qmi-proxy’ support is currently available in libqmi git master and is scheduled to be released in version 1.8 some day in the future. We just released 1.6 last week, so it may still take some time.

TL;DR

You can now write applications to use a QMI port with libqmi, even if ModemManager is running.

Follow

Get every new post delivered to your Inbox.

Join 42 other followers