ModemManager speaks MBIM
MBIM!
Winter is over, Spring is here, and along with the heat, rains and insects, ModemManager arrives with support for modems using the new MBIM protocol, available through the new cdc-mbim kernel driver in Linux >= 3.8 and a preliminary version of libmbim.
The current implementation provides:
- PIN unlock/change/enable/disable capabilities
- 3GPP modem support (GSM, HSPA, LTE…)
- Basic connectivity support
It doesn’t provide yet most of the side-features available in other modems (e.g. SMS messaging, location…), but it is a good start. If you don’t want to use MBIM just yet, check Bjørn’s list of issues and alternatives.
Where do I get it?
The ‘libmbim’ library can be found in the following Lanedo-maintained gitorious repository:
We also released a tarball in libqmi’s release place:
http://www.freedesktop.org/software/libqmi/libmbim-0.0.1.tar.xz
If you’re part of the freedesktop.org sitewranglers group, please check the still open libmbim project request.
The support is already in ModemManager git master, and will be enabled if libmbim is found during configure. You can also explicitly request to use MBIM support with the new –with-mbim configure switch.
Thanks
Special thanks go to Lanedo for sponsoring the initial libmbim development, Bjørn Mork for his suggestions and tests with multiple MBIM-capable modems, and Huawei for sending me a E367 with MBIM firmware.
ModemManager (and latest udev) in OpenWRT
So I wanted to have ModemManager in OpenWRT to handle my mobile broadband connections.
OpenWRT has its own built-in support to handle mobile broadband modems of different types, mainly for AT-controlled modems, but also for QMI-controlled modems through libqmi and qmicli (now available in upstream OpenWRT). But hell, why not package ModemManager for that work, and provide a unified single DBus API to control any kind of mobile broadband modem in the same way?
ModemManager itself isn’t a very complex daemon, so it doesn’t have many dependencies, just: glib/gio, dbus, udev/gudev and libqmi. In the world of OpenWRT, though, none of these are blessed dependencies, as they have a lightweight replacement for everything: libubox (instead of glib), ubus (instead of dbus) and hotplug2 (instead of udev). These replacements target minimal embedded systems, and are perfectly integrated into OpenWRT and provide the building blocks of other core software like the netifd network interface daemon.
Still, having ModemManager available as a OpenWRT package seems like a good idea if you’re not very constrained by the hardware you’re going to use. If you are building a system which should support multiple broadband modems from different vendors, or just building a base system for one specific modem model but leaving the door open to change the model in the future, ModemManager seems a good choice.
systemd’s udev in OpenWRT
Since April 2012, udev sources are now integrated within the systemd source code. And that means that udev packages in OpenWRT would need to get updated in order to get built from that new repository. systemd provides some hints on what would be the best way of creating a minimal systemd build which can be used to gather just the udev-specific libraries and binaries. The easiest way involves compiling the whole systemd package with all optional features disabled, and that would get us not only systemd (which we won’t need), but also udevd and libudev. Easy, yes, but then we have some issues in the environment that we would need to handle…
In OpenWRT, the udev package is available in the trunk repository, where only the core OpenWRT packages are given. But in order to get the new udev compiled out of systemd we end up needing additional dependencies (dbus, libcap) which are only available in the packages repository. Moreover, if you also want to compile the glib-based gudev library, glib is also needed, which is also only available in the packages repository. And you cannot require a package from trunk to depend on a package from packages, so… ended up creating a new systemd-udev package within the packages repository.
As I was targeting the uClibc toolchain, I also ended up requiring some additional patches both in uClibc (e.g. to enable utmpx) and systemd to get the thing properly compiled. The patches applied in the systemd sources are just to handle missing features in uClibc (execvpe, secure_getenv…). Whenever uClibc includes those, we’ll be able to remove those patches.
ModemManager in OpenWRT
I prepared an easy setup of ModemManager packaging in OpenWRT, where all possible plugins get compiled. It wouldn’t have been difficult to allow selecting via configuration which plugins to get compiled, but didn’t want to spend time on that.
I sent the patches to the OpenWRT mailing list already, but if you want to give it a quick try, you can just clone the Lanedo OpenWRT repositories (trunk and packages) from gitorious.org:
$> git clone git://gitorious.org/lanedo/openwrt.git
$> git clone git://gitorious.org/lanedo/openwrt-packages.git
You’ll want both ‘modemmanager-support‘ branches in those git repositories.
ModemManager will be available under the ‘Network’ section in the OpenWRT build configuration; but only after explicitly selecting the following kernel modules (all under Kernel Modules/USB support):
- kmod-usb-net
- kmod-usb-serial
- kmod-usb-acm
Once all above are enabled, ModemManager can be selected, and it will itself pull all its other required dependencies (systemd-udev, glib, dbus, libqmi…).
No LuCI? No connection manager?
Well, not yet
. If you want to use ModemManager you still need to have your own connection manager software to manage the connectivity. ModemManager will get your mobile broadband modem connected, but you still need to either call pppd or setup the wwan interface yourself (depending on the data port type). This is really not a big deal; and you can just setup a shell script using the provided mmcli command line interface to talk to ModemManager.
An introduction to libmbim

Linux kernel 3.8 comes with a new ‘cdc-mbim‘ driver… let’s see what all this is about…
What is MBIM?
The Mobile Interface Broadband Model (MBIM) is a new standard developed by the USB Implementers Forum, specifically designed for high speed mobile broadband modem devices.
This new USB networking subclass defines two separate new features:
- A new MBIM USB device model, providing multiple IP connections over a single USB interface, and without the need of 802.3 frames (as was the case with ECM and NCM)
- A new MBIM control protocol to talk to modem devices
MBIM message types
The protocol defines different message types with different formats.
Some of them are used to establish the channel of communication with the modem:
- Open Message (Host->Modem): Initialization request.
- Open Done Message (Host<-Modem): Initialization response.
- Close Message (Host->Modem): Close request.
- Close Done Message (Host<-Modem): Close response.
Some of the messages are used to report errors in the protocol; which may be sent either from the host or from the modem:
- Host Error Message (Host->Modem): Host-reported error.
- Modem Error Message (Host<-Modem): Modem-reported error.
And finally, some messages provide access to the different CIDs (Command IDs) defined in each Service.
- Command Message (Host->Modem): Request of a given command.
- Command Done Message (Host<-Modem): Response to a given command.
- Indication Message (Host<-Modem): Unsolicited messages sent by the modem.
These last three messages support protocol-defined fragmentation. If the sender of the message finds out that the message is longer than the maximum control transfer size defined when the communication channel was opened (with an Open Message), it will be able to split it into sorted chunks and send them one by one over the wire. Each of these fragments specify the total amount of fragments expected, as well as the order in the sequence. The receiver of the fragments will therefore need to wait for all fragments to arrive – which should arrive in order – before processing the message.
MBIM services
The protocol defines a basic set of different Services:
- Basic Connect: Which provides the support for basic IP connectivity
- SMS: SMS messaging
- USSD: Unstructured Supplementary Service Data
- Phonebook: Handling contacts and such
- STK: SIM toolkit
- Authentication
- Device Service Stream
Only the Basic Connect one is mandatory in every MBIM device; others are optional. Vendors or even Network Operators can also extend the functionality of the device with other services; for example to support other protocols embedded within MBIM (e.g. QMI or AT within MBIM); or just to provide specific new features.
MBIM commands
For each service, MBIM defines a set of Commands (CIDs); and each command can then be divided into 3 actions:
- “Set“: An user-requested action to change the modem state or configuration
- “Query“: An user-requested action to query the modem state or configuration
- “Notification“: An unsolicited report of the modem state or configuration
Not every action is supported by every command. For example, the “Device Caps” command in the “Basic Connect” service only supports the “Query” action, while the “Radio State” command of the same service supports all “Set“, “Query” and “Notification“.
But how does this match with the message types defined before?
- Host-created “Set” and “Query” requests are sent using “Command Messages“.
- Modem-created “Set” and “Query” responses are sent using “Command Done Messages“.
- Modem-created “Notifications” are sent using “Indication Messages“.
MBIM basic types
The protocol not only defines which action is supported in each command; it also defines the contents of the request, response and indication messages. The contents of each message are composed of collections of basic types defined by the protocol:
- Unsigned 32bit integers: Even for the most simple values (e.g. booleans), little-endian 32 bit unsigned integers are used.
- Strings: UTF-16LE encoded strings are always used.
- UUIDs: The protocol defines a special 16-byte-long UUID type, e.g. to define Service IDs
- Arrays: Collection of N values of a given basic type.
- Structs: Sequence of other basic types, given in a specific order.
As you can see, there is not much effort (none, actually) into making the protocol efficient in terms of overhead introduced; more than half of the bytes in each message will very likely end up being NUL bytes. Also, it is assured that each field within a message is aligned in a 32bit boundary, which makes it easier to read independent fields directly from the binary stream.
How does this compare to QMI?
There are quite some differences between this protocol and QMI. To name a few:
- Less basic types in MBIM, specially regarding signed/unsigned integers. QMI defines many more integer types, of different sizes and with different sign.
- Basic strings are given in ASCII in QMI
- Struct types are re-used in MBIM, as opposed to QMI, where each TLV would define the struct contents as it needed.
- There is no ‘client allocation’ needed in MBIM, i.e. the process opening the MBIM port doesn’t need to allocate clients for the different services.
- Fragmentation is built-in in the MBIM protocol; QMI required special TLVs and logic to handle messages that may be longer than the standard message size (e.g. when transferring the PRL list).
- Binary representation of the message is completely different. In QMI you would have a list of TLVs, one after the other. In MBIM, the contents of the message are split into two different sections: one which contains the fixed-size values and one for the variable-size values. For example, a string in MBIM is defined by two values in the fixed-size region (offset and size), while the real string data is within the variable-size section.
libmbim
The ‘libmbim‘ library is an attempt to write a protocol support library, as previously done with ‘libqmi‘.
The current codebase, GLib/GObject/GIO based, is pretty similar to what libqmi provided, with a ‘MbimDevice‘ GObject to handle the communication through the /dev/cdc-wdm port, as well as ‘MbimMessage‘ types to handle the creation of commands. Given that there is no need for client allocations in MBIM, there is no ‘MbimClient‘ object needed. Also, given that the contents of each message are pre-defined, it wasn’t considered the need of input and output ‘bundles’ to handle collections of TLVs, as done in libqmi.
Fragmentation of incoming/outgoing messages is handled internally by the ‘MbimDevice‘, which is a nice thing to have, as it simplifies the usage of the API. The user just creates a message, as long as it needs it to be, and the ‘MbimDevice‘ will take care of splitting it into fragments. When receiving a message, the user will also receive already the full message, once all fragments have been combined internally.
The messages and the services are defined in a JSON dictionary, and as with libqmi, all the message handling code is auto-generated from there. The capabilities of the mbim-codegen are still not in pair with those in qmi-codegen yet, though. The generator doesn’t support e.g. “Set” requests with parameters, or “Indication” messages. As previously said, this currently is a proof-of-concept, someday we’ll support all those properly.
mbimcli
The project comes with a command line utility (mbimcli), which allows (will allow) running “Get” or “Set” commands directly from the shell. There aren’t many supported commands yet, so I cannot show many more examples than this one:
$ sudo mbimcli \
-d /dev/cdc-wdm1 \
--basic-connect-query-subscriber-ready-status
[/dev/cdc-wdm1] Subscriber ready status retrieved:
Ready state: 'device-locked'
Subscriber ID: 'unknown'
SIM ICCID: '984310311520086950F1'
Ready info: 'unknown'
Telephone numbers: ''
Hint: Using --verbose will show you the raw binary message contents!
Where do I get it?
The ‘libmbim’ library and the ‘mbimcli’ utility can be found in the following Lanedo-maintained gitorious repository:
There is already a request to host this project in the freedesktop.org infrastructure, so it may end up getting moved there at some point.
Help! Contribute! Sponsor!
This development was kindly sponsored by Lanedo GmbH. If you want to help, or sponsor further development in libmbim, mbimcli or the ModemManager integration, just let us know!
ModemManager-powered location indicator for gnome-shell
TL;DR: Show location information retrieved directly from ModemManager in a gnome-shell indicator.
I’ve been wanting to try to write a gnome-shell extension from some time, and I ended up finding enough free time during the past weeks. So I ended up writing a gnome-shell extension which would show information about your current location as provided by your modem. Note that this information is not coming from GeoClue; the new ModemManager1 interface is not integrated yet there.
ModemManager exposes these types of information in the Location interface:
- 3GPP location, which is given as a set of 4 parameters, and specifies which is the current network cell which is giving mobile coverage to the modem:
- MCC/MNC: Identifies the ‘mobile country code’ and the ‘mobile network code’; i.e. country and operator.
- LAC and Cell ID: Identifies the ‘location area code’ and ‘cell id’ pair.
Once all these items are known, a query to an open database of cell IDs can give us the exact location of the tower giving us coverage, and therefore a good approximation of where we are located.
- GPS location, given if the modem has a built-in GPS. Currently Option/HSO modems are supported, as well as QMI-powered modems with the ‘PDS’ service implemented.
- CDMA Base Station location, given as Latitude/Longitude coordinates, and available in QMI-powered modems prepared for CDMA networks. As with the 3GPP one, this location information specifies where the station giving coverage to your modem is located, which is a good approximation of where you are located.
Beware! You’ll need ModemManager >= 0.7 (i.e. git master) in order for this extension to work.
You can download and install the extension in the following link:
https://extensions.gnome.org/extension/569/location-indicator
The sources are kept in a git repository in gitorious.org:
https://gitorious.org/aleksander/gnome-shell-location-indicator
If you find the extension itself mostly useless, you may still want to take a look at the source code to see yet another example of how to talk to DBus interfaces from within gnome-shell, including the use of the new standard ObjectManager interface with a Gio.DBusObjectManagerClient.
Integrating the new ModemManager in GNOME3
It was something like September 2011, shortly after the last Desktop Summit in Berlin, when I started the work improving ModemManager with the new DBus API, GDBus-based DBus support, port-type-agnostic implementations, dynamic DBus interfaces, built-in org.freedesktop.DBus.ObjectManager interface support, built-in org.freedesktop.DBus.Properties.PropertiesChanged signal support, the new libmm-glib client library, the new mmcli command line tool… Took me around half a year to port most of the core stuff, and some more months to port all the plugins we had. And then, suddenly, git master wasn’t that unfinished thing any more, and we were even implementing lots of new features like GPS support in the Location interface, improved SMS Messaging capabilities, ability to switch Firmware on supported modems, and last but definitely not least, support for new QMI-enabled modems through the just officially released libqmi…
And when I thought it was all done already, I woke up from my dream and realized that not even me was really using the new ModemManager as it wasn’t integrated in the desktop… not even in NetworkManager. So there I was again, with a whole new set of things to fix…
NetworkManager integration
There is already a set of patches available to include integration of the new ModemManager interface in NetworkManager; pending for review in the NM mailing list. This is the second iteration already, after having some of the patches from the first iteration already merged in git master.
This integration is probably the most complex one in the list, as it really has to deal with quite different DBus interfaces, but the overall look of it seems to be quite good from my point of view. With the patches on, NetworkManager exposes a new –with-modem-manager-1 configure switch which defaults to ‘auto’ (compile the MM1 support if libmm-glib found). Note that both the old and new ModemManager would be supported in this case, to easier fallback to the old version if the user experiences problems with the new ModemManager.
All in all, the required changes to NetworkManager are quite well defined, implemented mainly as a new ‘NMModemBroadband’ object and some additional bits to monitor added/removed modems through the org.freedesktop.DBus.ObjectManager interface.
gnome-shell integration
A proper integration in my desktop of choice (gnome-shell based GNOME 3) required to integrate the new interface in the Network indicator of the shell. As in every good day, I first had to deal with several issues I found, but I ended up submitting a patch that properly talks to the new ModemManager1 interface when needed. As with NetworkManager, this patch would support both the old and the new interfaces at the same time.
Not that this was a big change, anyway. The Network indicator only uses the ModemManager interface to grab Operator Name, MCCMNC and/or SID, and signal strength. Something that could even be included directly in the NMDevice exposed by NetworkManager actually…
Right now the only big issue pending here is to properly unlock the modem when it gets enabled, something that I still need to check how to do it or where to do it.
Truth be told, hacking the shell has ended up being quite nice, even with my total lack of knowledge in JavaScript. My only suggestion here would be: get a new enough distribution with a recent enough GNOME3 (e.g. the unreleased Fedora 18) and jhbuild buildone from there. I think I’ve never seen a clean jhbuild from scratch succeed… maybe it’s just bad luck.
And then came the applet…
network-manager-applet integration
Why the hell would Bluetooth DUN not work with my implementation, I was thinking, until I found that even if GNOME3 doesn’t rely on nm-applet, it still uses some of its functionality through libnm-gtk/libnma, like the code to decide which kind of modem we’re dealing with and launch the appropriate mobile connection wizard. Ended up also submitting patches to include the missing functionality in network-manager-applet.
For those not using GNOME3 and gnome-shell; note that I didn’t implement the support for the new ModemManager1 interface in the nm-applet itself; I just did the bluetooth-guess-my-modem-type bits required in libnma. If I feel in the mood I may even try to implement the proper support in the applet, but I wouldn’t mind some help with this… patches welcome! Same goes for other desktops relying on NetworkManager (KDE, xfce…); I wouldn’t mind to update those myself as well, but I truly don’t have that much free time.
gnome-control-center integration
Ok, so gnome-shell integration is more or less ready now; we should be finished, right? Well, not just yet. gnome-control-center also talks to ModemManager, in this case to get Operator Name and Equipment Identifier, which btw were not getting properly loaded and updated. Once that fixed, I finally got a new patch to have the control center talk to the new interface.
Fedora 18 packages
I bet you won’t go one by one to all the patches I linked before and apply them in your custom compiled NetworkManager, gnome-shell, network-manager-applet and gnome-control-center… but for all those brave Fedora 18 users, you can try with the 64-bit packages that I built for me, all available here:
If you want to rebuild these packages yourself, you’ll find the source tarballs here and the packaging repositories here. The packaging is really awful – I suck at it – so you’ll probably need to install the RPMs with –force
Note that the git repo for packaging has several git submodules, one for each item packaged, so remember to “git submodule init” and “git submodule update“.
We done yet?
Are these all the patches needed to have the best ModemManager experience in GNOME3? No! The list of pending tasks for this purpose grows a bit every day…
- Common code to parse the mobile broadband providers database, exposed in libnm-gtk and used by the wizard, the control center and the shell
- Link mobile connection profiles to a specific SIM/modem
- Ensure modems are PIN-unlocked when they get enabled
- Rework the logic behind the Network indicator in gnome-shell, trying to make it easier to connect to a default connection profile. The same logic would then be need to be applied to the control center…
- Proper IPv6 support in mobile broadband connections
- Connection profiles with multiple APN/bearers
- SMS messaging
- Location information integration
- An independent UI application to manage advanced settings in ModemManager?
- …
Help!
Thanks
Special thanks go to my employer Lanedo GmbH, which sponsors quite a lot of the GNOME integration work; as well as to my girlfriend’s employer, which sends her 400km away from home from Monday to Thusday. Without them this job would have been impossible!
SMS goodies in ModemManager
Lots of new SMS-related features have landed in ModemManager this week, and as I have as much memory as a fish used to have, I need to write down all the commands I’ve used to test all this; hence this post.
Note that all the stuff I talk about here applies to both AT and QMI based modems.
Multiple storages
The current stable 0.5/0.6 releases will only use the core/plugin defined ‘default’ storages for reading and sending short messages. This means that if you happen to have stored SMS in another non-default storage ModemManager won’t show them to you.
In the new 0.7 codebase, ModemManager reads the messages from all the available storages. It is able to read not only DELIVER-type PDUs from received SMS, but also SUBMIT-type PDUs from user-created SMS which got stored. The “Sms.Store()” method in the interface now allows (optionally) specifying in which storage the SMS should be kept.
The following commands allow to create a new SMS and store it in the “sm” (SIM) storage:
$> sudo mmcli -m 0 \
--messaging-create-sms="text='Hello world',number='+1234567890'
Successfully created new SMS:
/org/freedesktop/ModemManager1/SMS/21 (unknown)
$> sudo mmcli -s 21 --store-in-storage="sm"
successfully stored the SMS
$> sudo mmcli -s 21
SMS '/org/freedesktop/ModemManager1/SMS/21'
-----------------------------------
Content | number: '+1234567890'
| text: 'Hello world'
-----------------------------------
Properties | PDU type: 'submit'
| state: 'stored'
| smsc: 'unknown'
| validity: '0'
| class: '0'
| storage: 'sm'
| delivery report: 'not requested'
| message reference: '0'
Note that you can create, store and send SMS objects regardless of what storage you’re using for each, ModemManager will take care of properly synchronizing the access to each of them.
The Messaging interface also defines new properties to list all the supported storages and to specify which is the default storage being used for received messages (and for stored ones when no specific one given in “Sms.Store()“):
$> sudo mmcli -m 0 --messaging-status
/org/freedesktop/ModemManager1/Modem/0
----------------------------
Messaging | supported storages: 'sm, me'
| default storage: 'me'
Text multipart SMS
We support receiving text multipart messages in ModemManager since some stable releases ago; but support for sending multipart messages was still missing. Not any more! Roberto Majadas of OpenShine started this work some months ago with a patch for MM 0.6, which I took over and ported to git master and the new 0.7 codebase.
Of course, we support both the default GSM 7-bit alphabet, as well as UCS-2:
- GSM 7 encoded multipart messages: If the message is less or equal than 160 septets a singlepart SMS will be used; otherwise the input text will be split into chunks of 153 septets and sent as a multipart message.
- UCS-2 encoded multipart messages: The GSM 7 alphabet and its extensions are not enough to cover all scripts available out there. Luckily, we can send PDUs with UCS-2 encoded text (UCS-2 covers all the basic plane of Unicode, and is equivalent to UTF-16 in that range). When using this encoding, if the input text is less or equal than 70 UCS-2 characters (140 bytes) a singlepart SMS will be used; otherwise the input text will be split into chunks of 67 UCS-2 characters (134 bytes) and sent as a multipart message. Note anyway that this doesn’t mean that we only allow 70-byte long input strings to fit into a singlepart message; as the conversion from the input UTF-8 text to UCS-2 isn’t always increasing the required number of bytes. As an example, we can now send 210 bytes of UTF-8 encoded chinese text into a single SMS with 140-bytes of UCS-2.
Note that from the API user’s point of view, the SMS objects are not considered multipart or singlepart; that is taken as internal information only required for the PDU-based implementation.
Multipart messages can be created by writing a long enough ‘text‘ value passed in the ‘--messaging-create-sms‘ command, as shown before.
Raw data multipart SMS
In addition to text short messages we now also properly support raw binary data singlepart and multipart messages (reported as 8bit encoded). This means that both the sender and receiver can agree in any text encoding to be used between them, or even send in one or more SMS whatever raw binary stream you have.
The ‘mmcli’ command line utility was improved with several commands to test this feature. For example, you can now send using just SMS messages whatever file you have in your system, just doing:
$> sudo mmcli -m 0 \
--messaging-create-sms="number='+1234567890'" \
--messaging-create-sms-with-data=/path/to/your/file
Successfully created new SMS:
/org/freedesktop/ModemManager1/SMS/22 (unknown)
$> sudo mmcli -s 22 --send
successfully sent the SMS
When the receiver gets all the parts of the message, she can now recover the sent file with another ‘mmcli’ command in her ModemManager setup:
$> sudo mmcli -m 0 \
--messaging-list-sms
Found 1 SMS messages:
/org/freedesktop/ModemManager1/SMS/0 (received)
$> sudo mmcli -s 0 \
--create-file-with-data=/path/to/the/output/file
But beware! The file is sent in chunks of 134 bytes, and there is a maximum of 255 parts in a given multipart SMS, so this leaves you with a maximum size of around 33 Kbytes
And not only that, if you’re paying e.g. 0.10€ for each SMS sent, you would be paying more than 25€ for those 33 Kbytes. Yes, needless to say, this is therefore the most useless use case ever. But still, works as a proof of concept.
Delivery reports
Last and least, you can now also request delivery reports when sending an SMS, by passing the ‘delivery-report-request=yes‘ key/value pair in the ‘--messaging-create-sms‘ command.
$> sudo mmcli -m 0 \
--messaging-create-sms="text='你好',\
number='+1234567890',\
delivery-report-request=yes"
Successfully created new SMS:
/org/freedesktop/ModemManager1/SMS/0 (unknown)
$> sudo mmcli -s 0 --send
successfully sent the SMS
$> sudo mmcli -m 0 --messaging-list-sms
Found 21 SMS messages:
/org/freedesktop/ModemManager1/SMS/0 (sent)
/org/freedesktop/ModemManager1/SMS/1 (received)
$> sudo mmcli -s 1
SMS '/org/freedesktop/ModemManager1/SMS/1'
-----------------------------------
Content | number: '+1234567890'
-----------------------------------
Properties | PDU type: 'status-report'
| state: 'received'
| smsc: '+9876543210'
| validity: '0'
| class: '0'
| storage: 'unknown'
| message reference: '137'
| timestamp: '120914120619+02'
| delivery state: 'temporary-error-sc-specific-reason' (0x30)
| discharge timestamp: '120914120619+02'
You can then match the delivery report with the message sent by using the ‘message reference‘ value, which should be the same in both. This also applies to multipart messages, where the ‘message reference’ of our SMS object is the one reported when sending the last part, and therefore we only request the delivery report in the last part sent.
Enjoy!
QMI-powered broadband connections in OpenWRT
Linux 3.2 kernel with QMI support
When I started to develop the QMI support in OpenWRT, latest trunk was based on the 3.2 kernel series. By the time you read this, OpenWRT may already have a recent enough kernel (>= 3.4), so this custom setup may not be needed any more, so keep it just for reference.
The ‘v3.2.5-qmi’ branch in the Lanedo stable kernel tree contains a set of patches on top of the 3.2.5. Linux kernel release. These patches add support for QMI ports (updated ‘cdc-wdm’ and new ‘qmi_wwan’ driver) in the 3.2 stable series:
git://gitorious.org/lanedo/linux-stable.git
OpenWRT with QMI support
The same set of patches was then added to the ‘qmi-support’ branch of the Lanedo openwrt tree, enabling OpenWRT builds with QMI support:
git://gitorious.org/lanedo/openwrt.git
When you compile this OpenWRT build, make sure you configure the kernel with the QMI-specific requirements enabled:
CONFIG_PACKAGE_kmod-qmi-wwan=m
CONFIG_PACKAGE_kmod-usb-wdm=m
...
For reference, you can find here the .config I used for the ar71xx-nand builds (installable in a RouterBoard 433UAH).
libqmi-glib and qmi4g
‘libqmi-glib’ and ‘qmi4g’ are two new packages added to the ‘qmi-support’ branch of the Lanedo openwrt-packages tree:
git://gitorious.org/lanedo/openwrt-packages.git
This repository can be added to your OpenWRT build by creating a new ‘feeds.conf‘ with the following contents:
src-git packages git://gitorious.org/lanedo/openwrt-packages.git;qmi-support
The new packages, in detail:
- libqmi-glib: This package provides a preliminary version of
libqmi-glib, as released unofficially by me. This package will provide thelibqmi-gliblibrary, theqmiclicommand line utility and theqmi-networkscript. - qmi4g: This package registers a new ‘
qmi4g‘ network protocol, which takes care of launching the network start/stop requests through QMI.
If you’re using the precompiled OpenWRT images I gave above, you can just install these packages using ‘opkg’ once you’ve added the ‘latest’ Lanedo repository.
Configuring qmi4g
Once the qmi4g package is installed, you are then allowed to include the
following configuration under /etc/config/network:
config 'interface' 'broadband'
option 'ifname' 'wwan0'
option 'proto' 'dhcp'
option 'auto' '0'
config 'interface' 'wdm0'
option 'proto' 'qmi4g'
option 'wdmif' '/dev/cdc-wdm0'
option 'wwanif' 'broadband'
The configuration is split into 2 interfaces:
- First, the configuration for the ‘
wwan0‘ interface. This interface needs to be set with ‘auto‘ equal to ‘0‘, so that it is never brought up automatically; and with ‘dhcp‘ as the protocol to be used. You should never ifup/ifdown this interface manually. - Second, a virtual interface using the new ‘
qmi4g‘ protocol, which needs 2 options set: ‘wdmif‘ with the cdc-wdm port to use for the QMI protocol, and ‘wwanif‘ with the uci-interface-name of the wwan iface to use.
Start/Stop the network
Once the qmi4g setup is added in /etc/config/network, you can now then just:
$> ifup wdm0
That command will internally first launch the network start QMI command, and if succeeds it will itself ifup wwan0. The wwan interface can be used as any other eth-based interface now, it can be added as part of multiwan or in a vlan or in a bonding, or anything.
Once the connection is no longer wanted, you can just:
$> ifdown wdm0
That command will stop the network with QMI and also ifdown wwan0.
LUCI
Once the network configuration is in place, the connection can also be started via web. Just log in to LUCI, go to Network interfaces and you’ll see both the wwan interface (“broadband“) and the virtual “wdm0“. Starting/Stopping the “wdm0” interface via LUCI should work. As said before, you shouldn’t touch the wwan interface directly.
Enjoy!



