Some details about the GSM infrastructure on the Neo1973 / OpenMoko
I've posted this publicly to some mailing lists in mid-November, but thought it was good to have this information in the blog, too:
First of all, there is a ts0710 multiplex layer, architecture-wise similar to what Motorola uses in their 2.4.x kernels. This ts0710 (de)multiplex takes care of handling GSM TS 07.10 "advanced mode" (the HDLC framing). It will be easy to add "basic mode" for chips that doesn't support advanced mode, and I'm also planning to add support for the Motorola proprietary 07.10 extensions (see OpenEZX wiki) once Neo1973 has been released.
This demultiplex is implemented as a line discipline. Therefore some userspace program (in our case the GSM daemon) attaches as a line discipline to the underlying physical UART.
devices that don't have a physical UART (such as the Motorola phones) will provide a small glue layer that provides a virtual UART on top of e.g. USB as underlying layer.
The GSM mux layer then provides itself one virtual serial port per DLC of the multiplex.
On top of those virtual serial ports, there is a GPRS line discipline, or a PPP line discipline for implementing full in-kernel data connection support, with no need for sending data packets for network traffic from/to userspace.
Both the GPRS line discipline and the ts0710 multiplex are written according to the style and requirements ("good taste") of kernel code, and will be submitted to the mainline kernel as soon as the Neo1973 goes public. I really hope to make this a standard component of the mainline kernel, supporting as many GSM modems as possible over time.
On top of the virtual serial ports, we have a GSM daemon. This daemon takes care of almost all communication with the GSM modem. The daemon initializes AT+CMUX and then attaches the kernel line discipline. It also attaches GPRS line discipline to a virtual serial port afterwards.
The daemon provides a Unix domain socket based protocol for other applications (at some later point this might become a network-enabled protocol by running it over TCP). The "other applications" (such as the contact manager, the dialer program, etc.) link against a library called "libgsmd" which wraps the protocol into a C language API.
This means that programs have a high-level API for initiating and receiving voice calls, for receiving and sending SMS, obtaining list of operators, reading/storing contacts from/to SIM card, etc.
The daemon will be GPL licensed, for the library we're not sure whether to GPL or LGPL it (probably LGPL). All applications shipped on the Neo1973 linking to the library are GPL licensed, so there will be enough example code for people to understand how that API works.
The gsmd/libgsmd code will be run (just like any other program on the Neo1973) as any other free software / open source program. Please understand that while FIC sponsors the OpenMoko project, they don't really exert control over it. So as soon as the device and code is released, I'm happy for any input and discussions the community has on improving such a system, including support for more devices, etc.
Oh, and yes, the daemon has a plug-in interface for vendor-specific extensions, since every GSM modem vendor has commands beyond the GSM07.07 specification. Also, the C API and the Unix domain protocol provide for transparent pass-through of AT commends from application to daemon. This is not meant to be a single-vendor-single-product code, but is at least designed to make it easy to add support for other devices.
Anyway, even without gsmd/libgsmd, I think the kernel-level serial multiplexer (which is not a very complicated thing) is a valuable feature to anyone doing GSM/GPRS on Linux - be it on a PC with GSM modem, or a smartphone.
The reason for doing this (de)multiplex in the kernel:
- the individual virtual serial ports have all the features of real serial ports. hardware/software flow control, modem status lines, etc. - and the kernel has a standard API, well known in Unix over decades, to work with serial ports from a userspace program
- especially when it comes to data sessions (packet data or circuit switched data), then you don't want to push all data to userspace and back in the kernel. you want to have a fast path for that, both from a CPU consumption (battery!) point of life, but also from a latency point of view. mobile data latencies are already high enough, we don't want to have additional unneccesary latencies in the handset