This post is part two of series on building a homebrew LTE router. In this post we dive into the software side of the build. If you haven’t see the hardware side of the build described in the first post, its worth a quick scan to give you some context.

The software is packaged as a bitbake layer on top of Yocto 2.1 Krogoth. I describe the steps to build Yocto Krogoth for the Intel Galileo Gen 1/2 in a previous post, again its worth a quick scan to give you some context.

You can find the layer described in this post in my meta-lte-modem github repo. For the impatent, you can just git clone the meta-lte-modem github repo, update the APN, add the layer to the krogoth build for Intel Quark and then build core-image-minimal as normal. As follows …

[17:14 ] yocto > git clone
Cloning into 'meta-lte-modem'...
remote: Counting objects: 39, done.
remote: Compressing objects: 100% (27/27), done.
remote: Total 39 (delta 3), reused 39 (delta 3), pack-reused 0
Unpacking objects: 100% (39/39), done.
Checking connectivity... done.

[17:14 ] echo "APN=MyISPsAPN" > ./meta-lte-modem/recipes-core/initscripts/initscripts/qmi-network.conf
[17:14 ] cd poky/
[17:15 ] poky >

17:15 ][silv-debian7-yocto-build 34] poky > . oe-init-build-env yocto_build
You had no conf/local.conf file. This configuration file has therefore been
created for you with some default values. You may wish to edit it to, for
example, select a different MACHINE (target hardware). See conf/local.conf
for more information as common configuration options are commented.

You can now run 'bitbake <target>'

Common targets are:

[17:16 ] yocto_build > bitbake-layers add-layer ../../meta-lte-modem/
[17:17 ] yocto_build > bitbake-layers show-layers
layer                 path                                      priority
meta                  /build/yocto/poky/meta                    5
meta-poky             /build/yocto/poky/meta-poky               5
meta-yocto-bsp        /build/yocto/poky/meta-yocto-bsp          5
meta-lte-modem        /build/yocto/meta-lte-modem               6

[17:12 ][silv-debian7-yocto-build 21] yocto_build > bitbake core-image-minimal
Parsing recipes:   0% |                                                       | ETA:  00:01:39

When the build is done, generate your sdcard image using wic and then dd to your as SDcard, all described in the build instructions.

Now diving into the detail of the code.

Adding CBC MBIM and QMI support to the kernel

First you will notice I have tweaked the yocto kernel.

    [21:29 ] meta-lte-modem > find recipes-kernel/

If you dig in here, what you will find I am doing is adding kernel configuration fragments to the kernel build. These add kernel support for CDC MBIM, QMI WWAN and NATing to the kernel’s configuration. You will also find I have tweaked the packages that are bundled with core-image-minimal.


In the core-image-minimal bbappend I add a bunch of the usually suspects dropbear, usbutils etc, however two important packages that are added are libmbim and libqmi, these add support for the CDC MBIM and QMI networking services.

Enabling DHCP Server on the Ethernet Port

I add a sysctl.conf to turn on IP forwarding automatically on startup.


I changed the interfaces files, so that the Galileo’s ethernet port has a static IP address set on it I also tweak dnsmasq to listen on the Galileo’s ethernet port and to allocate IPs in the range. Anything that wishes to connect to the internet through the Galileo will get an IP in the range and will connect through the gateway `


Connecting to the Cellular network

I have tweaked the SystemV initscripts to add a service to start the QMI Networking service. The service starts qmi-network to do the handshaking with the cellular network, calls udhcpc to get an IP address from the cellular provider and add the IP Tables rules for NATing.


The Huawei me906e

The file wwan.rules is a udev rule for Hauwei ME906E. The ME906E is a bit of a chameleon and took some figuring out, thankfully Bjørn Mork the Kernel Mantainer for the “USB QMI WWAN NETWORK DRIVER” was a huge help. Turns out the ME906E is a bit of a chameleon, it can present itself as three serial devices (yes really!) for a PPP setup, an ethernet interface, a CDC MBIM WWAN interface and finally a QMI WWAN interface - depending on how you configure it.

The ME906E is a USB device, even though it physically connects to the Intel Galileo over mini PCI express.

root@intel-quark:~# lsusb
Bus 001 Device 002: ID 12d1:1573 Huawei Technologies Co., Ltd.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

You can cycle through the various available configurations by writing a value to bConfigurationValue.

root@intel-quark:/sys/devices/pci0000:00/0000:00:14.3/usb1/1-2# cat bConfigurationValue

This is what the wwan.rules udev rules does. It tells udev when you see the ME906E device, if bConfigurationValue is not currently set to 1, set it to 1. As 1 is the QMI WWAN configuration.

root@intel-quark:~# cat /etc/udev/rules.d/wwan.rules

Once the value 1 is written to bConfigurationValue, the ME906E disappears and reappears as a QMI network device - ready to talk to the qmi-network service.

root@intel-quark:~# dmesg
qmi_wwan 1-2:1.4: cdc-wdm0: USB WDM device
qmi_wwan 1-2:1.4 wwan0: register 'qmi_wwan' at usb-0000:00:14.3-2, WWAN/QMI device, 02:bb:23:31:9b:84
usbcore: registered new interface driver qmi_wwan
ip_tables: (C) 2000-2006 Netfilter Core Team
nf_conntrack version 0.5.0 (3618 buckets, 14472 max)