Introduction

Arguably the most critical functionality in a phone is the ability to make and receive calls through the Public Switched Telephone Network (PSTN), that is normal cellular calls using phone numbers. While at Purism we are eager to implement communication systems that enable much greater privacy and security than one can expect from PSTN calls, the PSTN is still the most ubiquitous network and for the time being we can’t very well go around selling a phone that isn’t able to make PSTN calls.⁰

My task has been to develop a dialer and call handler for PSTN calls. Like all of our work on the Librem 5, this is intended to make use of existing code wherever possible and also target the GNOME platform which our PureOS defaults to. There is currently no GNOME PSTN dialer so we intend to contribute our program to the GNOME project.

Initial ideas

After some research, the initial goal was to use the Telepathy framework, the idea being that we could write a Telepathy PSTN dialer and get a SIP dialer for free because Telepathy has both PSTN and SIP connection managers. What’s more, the PSTN connection manager, telepathy-ring, is used in shipped phones. And, while it has its issues, in my opinion Telepathy is pretty awesome 🙂

Furthermore, my colleague François Téchené wrote a blog post describing a “feature”-based approach rather than an application-based approach to the phone UX. Telepathy could provide the technical underpinnings of such an approach.

It’s worth noting however, that Telepathy is a contentious framework. There are a number of voices within the GNOME project who would seemingly have it die a fiery death. Telepathy is a complex system and is notorious for the difficulty of making changes to the framework itself. To do so, one must synchronise changes to formal D-Bus API specifications and a multitude of distinct software components. A long discussion of Telepathy and possible replacements took place on GNOME’s desktop-devel mailing list in August and September 2017.

Wider discussions

After starting to work on some preliminary Telepathy code, given that our goal is for the dialer to be GNOME’s dialer, and the intention to use the contentious Telepathy framework, I checked in with the GNOME desktop-devel mailing list again to see what they thought.

Discussion ensued of both Telepathy and general issues around consolidating different communication systems. The main take away from this discussion was that creating a consolidated system like our “feature”-based approach is difficult to say the least. Like the previous discussion in 2017, a Telepathy-NG was touted. This is future work for us to take on once the basic phone functionality is in place. For now though, there was no major push-back against the idea of creating a PSTN dialer using Telepathy.

I also spoke to Robert McQueen, one of the original guys behind Telepathy, on IRC. The telepathy-ring connection manager makes use of a mobile telephony framework called oFono. Given the complexity of writing a Telepathy client, Robert suggested that a good approach might be to create a UI with a thin abstraction layer, first implementing a simple oFono backend and then afterwards implementing a more complex Telepathy backend. We’ve taken on Robert’s suggestion and our dialer program has been built using this approach.

Introducing Calls

Our program is named Calls. It has a GTK+ 3 user interface and makes use of oFono through a thin abstraction layer. We also make use of our libhandy for the dialpad widget.

“Can it make a phone call?!”

Yes, it can! 🙂

Internals

The following diagram shows a UMLish representation of the abstraction layer underlying the architecture of Calls:

The classes are actually GInterfaces. To give a better understanding of the semantics behind each interface, here is a table of objects that possible implementations could make use of:

Interface Example implementation objects Provider oFono Manager, Telepathy Account Manager Origin oFono Modem/VoiceCallManager, Telepathy Account Call oFono VoiceCall, Telepathy Channel

The name “Origin” was chosen because it is an object which “originates” a call.

The MessageSource super-interface is used to issue messages to the user. The abstraction layer is intended as a very thin layer to the user interface so implementations are expected to report information, including error messages, warnings and so on, in a manner suitable for presentation to the user. Hence, methods usually do not return error

information but instead rely on the implementation issuing appropriate message signals.

The source code is available in our community group in GNOME’s gitlab.

Modems, oFono and ModemManager

The demo above is using a SIM7100E modem from SIMCom which you may be able to see mounted on the prototype board, with the red top border, to the bottom right of the display. Like many cellular modems, this modem supports both AT commands and QMI.

When the SIM7100E was first plugged in, oFono didn’t recognise it. However, there is a different mobile telephony framework, ModemManager which did recognise the modem and could make calls, send SMS messages and make data connections out of the box. We considered using ModemManager instead of oFono but unfortunately ModemManager’s voice call support is rudimentary and it has no support for supplementary call services like call waiting or conference calling.

Meanwhile, QMI is preferable to AT commands but oFono has no support for voice calls using QMI. Hence, to get voice calls working, we needed a new driver for the SIM7100E using AT commands. This driver has been upstreamed.

Where next

We’ve done a decent amount of work so far but there’s still some way to go before we have a dialer that you can stick in your pocket and use every day. Here are some of the things we have to work on:

Add ringtones. At present, the program doesn’t play any sound when there’s an incoming call. It would also be good to play DTMF noises to the user when they press digits in the dial pad. Implement call history and integration with GNOME Contacts. At present Calls makes no records of any kind so we need suitable record storage and a UI for it. Similarly, we need to be able to search for contacts from within Calls and add phone numbers from call records to contacts. The UI is currently basic but functional. It is a far cry from the polished beauty our designers have envisioned. A lot of effort will be needed to rework and polish the UI. Implement phone settings in GNOME Settings. We need a new page for phone settings like selecting the mobile network to connect to and so on and so forth. Deal with multiple SIMs and bringing the modem online. At present, Calls is a pretty dumb frontend on top of oFono D-Bus objects and only makes use of modems that are already in a usable state. There needs to be some mechanism to configure which modems Calls should make use of and to bring them online automatically when the device starts. Similarly, there need to be mechanisms for configuring and selecting between multiple SIMs. Implement the Telepathy backend so we can get SIP calls and calls with whatever else supports Telepathy. The final choice of modems has not been made yet so we’re not investing too much effort in developing support for the SIM7100E; just enough to test Calls as it is. Assuming we do choose the SIM7100E, we could implement QMI voice call support in oFono. In fact, as I write this post I see there is a discussion on the ofono mailing list about doing just that so QMI voice call support may be done for us. Alternatively, we could implement support for supplementary services in ModemManager, which is more closely aligned with the GNOME platform. Add support for supplementary services and complex call operations. Just as ModemManager has rudimentary support, so does Calls in its present state. We want to ensure that our dialer has complete support for mobile telephony standards and call control operations.

That’s all for now, stay tuned for further updates! 🙂