Skip to content

Instantly share code, notes, and snippets.

@Juul
Last active March 29, 2024 03:06
Show Gist options
  • Star 73 You must be signed in to star a gist
  • Fork 19 You must be signed in to fork a gist
  • Save Juul/e42c5b6ec71ce11923526b36d3f1cb2c to your computer and use it in GitHub Desktop.
Save Juul/e42c5b6ec71ce11923526b36d3f1cb2c to your computer and use it in GitHub Desktop.
How to use 4G LTE modems like the MC7455 on both Debian/Ubuntu and OpenWRT using MBIM

The purpose of this document is to get you familiar with the concepts and command line tools involved with connecting to the internet using modern 4G LTE modems on both Debian/Ubuntu and OpenWRT.

This writeup is based on my experiences with the Sierra Wireless AirPrime MC7455 modem and a Calyx (Sprint) SIM card, but it should apply to most modern 4G LTE modems.

High level overview

These are the steps required:

  • Physically connect antennas
  • Physically connect modem to computer using USB adaptor
  • Flash latest firmware to modem
  • Configure modem using AT commands
  • Configure modem using QMI protocol (for some modems)
  • Use command-line tools to connect
  • Assign IP address, gateway and DNS

USB and adaptors

These modems come with a variety of connectors. Some use USB Type A, some use Mini PCI Express, and some use M.2 but they all communicate using USB 2 (with some supporting USB 3). This is possible because both the PCI Express Mini Card edge connector and the M.2 (aka NGFF) edge connector provide not just PCIe pins, but also USB and SIM card pins. This means that the PCIe Mini and M.2 modems can be connected to USB via an adaptor. These adaptors are cheap (e.g. on ebay) and usually include a slot for the SIM card.

For the MC7455 you will need such a Mini PCIe to USB adaptor, and probably a nanoSIM or microSIM to normal SIM adaptor since most PCIe to USB adaptors only accept a full-sized SIM card.

Frequencies and antennas

You will also need two antennas, or a single MIMO antenna. The frequencies used by Sprint in my area are:

  • 25: 1850 to 1995 MHz (FDD-LTE)
  • 26: 814 to 894 MHz (FDD-LTE)
  • 41: 2496 to 2690 MHz (TDD-LTE)

The MC7455 supports all frequencies and both FDD-LTE and TDD-LTE (which are just two different ways of splitting upstream and downstream bandwidth). You can check on cellmapper.net which channels are supported by the cell towers near you and look up the corresponding frequencies here. You can then either get a wideband antenna that covers all of the frequencies supported by your modem and the cell tower, or you can pick one or two frequencies and get an antenna for just those frequencies. Usually wideband antennas that support multiple frequencies don't have as much gain. You might want to try forcing your modem to use each of the frequencies in turn and check the bandwidth during peak times before you decide on the best antenna.

For the MC7455 you will probably need pigtails (antenna adaptors) from u.fl to either SMA or N-type connectors depending on your antenna. Other modems like the EM7565 use MHF4 connectors instead of u.fl. Remember that the longer the cable from your modem to the antenna, the more signal you will loose.

Upgrading the firmware

If you have a Sierra modem then you will probably want to upgrade the firmware to the latest version from Sierra.

I recommend using the bootable ISO from Daniel E Wood which includes everything you need.

Talking to the modem

USB modems use the USB Communications Device Class or USB CDC. They usually show up as multiple devices in /dev. I see three tty devices: /dev/ttyUSB0 to /dev/ttyUSB2 and one /dev/cdc-wdm0.

AT commands

One of the /dev/ttyUSBx devices should be a serial console for AT commands, probably using 9600 baud. If it isn't, refer to the Switching to NBIM section of this guide.

You can connect using minicom:

minicom -o -D /dev/ttyUSB2 -b 9600

For the MC7455 you can download an AT command guide from Sierra Wireless (though you have to create an account) but you hopefully won't need any commands that aren't in this guide. There is also a nice writeup on AT commands here.

Another one of these /dev/ttyUSBx devices will probably be for NMEA, meaning that it's for talking to the built-in GPS. This has no bearing on the 4G LTE connectivity.

Some background on protocols

There are several communications protocols used by modems. Years ago all modems used PPP, but even if your modern modem supports PPP you probably don't want to use it since it doesn't support very high bandwidth. For modern modems you will probably want to use either MBIM or QMI.

MBIM, or Mobile Broadband Interface Model, is an official USB standard created by the USB Implementors Forum.

QMI or Qualcomm Mobile Station Modem Interface was developed by Qualcomm and is only supported by Qualcomm chips.

Many Qualcomm chips like the Sierra MC7455 support both MBIM and QMI.

Both MBIM and QMI are actually just using existing Ethernet over USB standards with an added signalling channel.

MBIM is just the NCM protocol + a signalling channel and QMI is just the ECM protocol + a signalling channel.

ECM is the Ethernet Control Model and NCM is the Network Control Model. ECM is an earlier standard and has some issues with latency while NCM resolves those issues and is designed for high speed operation. You can read more here.

You can learn more about MBIM in Linux via the kernel documentation.

When configuring your modem, some settings can be changed with AT commands and others using the QMI signalling channel. I had problems changing the mode from QMI to MBIM using AT commands but was successful using the QMI signalling channel.

Switching to MBIM

Since MBIM is an official USB standard and uses the more modern NCM protocol, that's what I ended up using.

With the SIM card and modem installed in the USB adaptor, plug the modem into a USB port and wait. It taked a while for the modem to boot up. Maybe give it 30 seconds.

Now use the minicom command from earlier to verify that you can talk to the modem and the SIM card is connected:

at!entercnd="A710"
at+cpin?

It should respond with "READY".

Now let's enable IPv6 while we're at it:

at!custom="IPV6ENABLE",1
at+cgdcont=1,"ipv4v6","r.ispsn"

If you want, you can ensure that the modem uses only 4G LTE:

at!selrat=06

You can also attempt to set the USB composition mode. For the MC7455 use this:

at!usbcomp = 1,1,1009

Don't worry if the at!usbcomp command fails or you have a different modem, but if it succeeds you can skip using the swi_setusbcomp script below.

When you're done, reboot the modem:

at!reset

Exit minicom.

Now we need to change the USB composition mode of the modem. "USB composition" refers to the set and types of the devices in /dev associated with the modem.

For this we'll use this swi_setusbcomp script.

First list the supported USB compositions using:

swi_setusbcomp.pl --device=/dev/cdc-wdm0

You will see a list with entries that look something like this:

  6  => 'DM   NMEA  AT    QMI',
  7  => 'DM   NMEA  AT    RMNET1 RMNET2 RMNET3',
  8  => 'DM   NMEA  AT    MBIM',
  9  => 'MBIM',
  10 => 'NMEA MBIM',

Pick an entry that includes both AT and NBIM and note down the number, then run:

swi_setusbcomp.pl --device=/dev/cdc-wdm0 --usbcomp=<number>

Replacing <number> with the number of that entry. I used number 1.

Now unplug the modem and plug it back in.

Connecting from Debian / Ubuntu

Connecting using MBIM

You should now be able to connect. For testing this on Debian/Ubuntu you can install libqmi-utils:

sudo apt install libmbim-utils

which installs the command mbim-network. To connect you will need your APN for your 4G LTE provider. For the Sprint connection you get from Calyx this is r.ispsn. Edit /etc/mbim-network.conf (create it if it doesn't exist) and make sure a line says "APN=<your_apn>" so for Calyx Sprint it would be "APN=r.ispsn". Also ensure that the file has a line that says "PROXY=yes". If you don't use a proxy then you can't query the active connection while it is being used. If you have a username and password see man mbim-network.

You might want to stop network-manager before you run this test:

sudo service network-manager stop

Check that you can use mbimcli to talk to the device at all:

sudo mbimcli --device=/dev/cdc-wdm0  --query-device-caps

Start the network connection:

sudo mbim-network /dev/cdc-wdm0 start

If it works you should see a new network interface probably called wwan0 when you run ip link.

Now to figure out which IP, gateway and DNS to use you can run:

sudo mbimcli -d /dev/cdc-wdm0 -p --query-ip-configuration

I got the IPv4 IP and subnet 184.250.142.38/30 so to set it I did:

sudo ip link set dev wwan0 up
sudo ip addr add 184.250.142.38/30 dev wwan0

and then to set the gateway (in my case 184.250.142.37):

sudo ip route add default via 184.250.142.37 dev wwan0

You should now be able to ping 8.8.8.8.

If you want to configure a nameserver then you can edit /etc/resolv.conf but remember to put it back the way it was before re-starting network-manager.

Connecting using QMI

If MBIM doesn't work for you, you can try using swi_setusbcomp.pl to switch to a USB composition that includes QMI.

Then you can repeat the above instructions for MBIM but with the package libqmi-utils, the config file /etc/qmi-network.conf and the commands qmi-network and qmicli. The command to get the IP and gateway is different though and I don't know what it is for qmicli.

OpenWRT

OpenWRT doesn't seem to have complete official support for MBIM/QMI modems. An updated (as of late 2018) patch-set that uses ModemManager is available here. The problem with this solution (and why it will probably not get merged) is that it requires DBus rather than ubus.

The other option is to use the GoldenOrb ROOter firmware which automates everything via a nice web UI, but then you're no longer running stock OpenWRT.

For now it just doesn't seem that MBIM and QMI is well-integrated into OpenWRT, but I could be wrong. It could be that it's simply not documented. The only mention seems to be here. For QMI, using the uqmi utility manually is documented here but it doesn't seem to be integrated into uci or ubus.

Manually configuring using umbim

OpenWRT does have a utility for mbim called umbim. You can install it using:

opkg update
opkg install umbim

If you want to use it on a non-openwrt system you can compile it like so:

sudo apt install libjson-c-dev lua5.1 lua-json liblua5.1-0-dev

# bit hacky
sudo cp /usr/include/lua.h /usr/include/lua.h.old
sudo cp /usr/include/lua5.1/lua.h /usr/include/ 

git clone https://git.openwrt.org/project/libubox.git
cd libubox
mkdir build
cd build/
cmake ..
make
sudo make install
cd ../..

sudo cp /usr/include/lua.h.old /usr/include/lua.h
# or delete /usr/include/lua.h if there is no lua.h.old

git clone https://git.openwrt.org/project/umbim.git
cd umbim/
mkdir build
cd build/
cmake ..
make
sudo make install
sudo ldconfig -v

Now you can run umbim.

To install all the required packages for umbim on OpenWRT:

opkg update
opkg install umbim kmod-usb-net-cdc-mbim kmod-usb-net-sierrawireless kmod-usb-serial-wwan kmod-usb-serial-sierrawireless kmod-usb-serial-qualcomm 

With umbim you can connect like so:

sudo umbim -d /dev/cdc-wdm0 -n -t 2 subscriber
sudo umbim -d /dev/cdc-wdm0 -n -t 2 attach # don't worry if you get a timeout error
sudo umbim -d /dev/cdc-wdm0 connect <apn> [pap|chap|mscapv2] [username] [password]

E.g. for Calyx Sprint the last command is just:

sudo umbim -d /dev/cdc-wdm0 connect r.ispsn

When you are connected you should get some output from umbim like:

  sessionid: 0
  activationstate: 0001 - activated
  voicecallstate: 0000 - none
  nwerror: 0000 - unknown
  iptype: 0003 - ipv4v6

and an interface, probably named wwan0 will appear.

To get the IP config do:

sudo umbim -d /dev/cdc-wdm0 -n -t 2 config

Now set your IP and gateway based on the config, e.g:

sudo ip link set dev wwan0 up
sudo ip addr add 184.250.142.38/30 dev wwan0
sudo ip route add default via 184.250.142.37 dev wwan0

That's it! (well maybe you want to set DNS as well, but otherwise you should be online).

Integration with OpenWRT

Manually running a bunch of commands to connect after each reboot is obviously not ideal.

I found a nice guide for how to get MBIM working properly in OpenWRT here but unfortunately the links to the files are broken. I did find a working link to the /lib/netifd/proto/mbim.sh file here and that seems to be the core of it. It seems like the rest of the missing files implement some sort of automatic ping and re-connect when the 4G LTE connection stops working.

Locking to specific channel/frequency

TODO There is a way to force the modem to only use specified channels using AT commands. This could be useful if some channels are more crowded than others or if you have an antenna which doesn't work well for some channels.

Disconnection issues

It seems that many people experience intermittent disconnections with the MC7455. I've seen this happen myself and the GoldenOrb ROOter firmware has a nice feature for detecting these disconnects and re-connecting automatically. You have to enable this feature using the web UI. Remember to specify the IP to ping, otherwise it won't work.

For OpenWRT you could write a simple scripts that pings some server and then reboots or re-initializes the modem when pings begin failing. Or maybe you could look at how it's done in GoldebOrb ROOter.

Some have reported that the newer and faster EM7565 modem doesn't suffer from these disconnection issues but I have not tested this.

Troubleshooting

For troubleshooting modem configuration, I recommend this guide.

@Juul
Copy link
Author

Juul commented Aug 18, 2020

Wow hyc that's amazing! Very much looking forward to trying this!

@pt-wr
Copy link

pt-wr commented Oct 21, 2021

This is very good! I'm glad to see more modem operation stuff is being shared openly.

@freezir12
Copy link

freezir12 commented Jan 14, 2022

Hey there, thanks for your post and the explanation. I have learned some new stuff! But I am still struggling with my project here. I connected an MC770 LTE Card (https://www.amazon.de/dp/B07WPYPZMF/ref=pe_27091401_487027711_TE_SCE_dp_1) via this adaptor ( https://www.amazon.de/dp/B089N34HPV/ref=pe_27091401_487027711_TE_SCE_dp_2) to an M.2 port of my Intel NUC running Ubuntu 20.04. I have checked with lsusb and lspci and other commands if the card shows up somehow somewhere but I could not find anything. Do I have to connect the USB Signal cable (see amazon pictures) to the adaptor board to make it work? But where to connect the other end of the cable, it is just raw copper end)? Am I missing sth here? (LEDs on the adaptor board are lighting up when the NUC is running. My fingers are bloody from googling, help would be appreciated a lot! Thx and Greetz!

@Juul
Copy link
Author

Juul commented Jan 15, 2022

Hey @freezir12 it is possible that your LTE card only speaks USB. If that is the case then you will need to use an M.2 adapter and slot that uses the A, B or E keying or like you mentioned perhaps you can use the USB signal cable. If the cable is only raw copper then it will need a normal USB-A plug soldered onto it. But do check which communication protocols your LTE card supports.

@freezir12
Copy link

@Juul Thx so much for your support, i am pretty sure you solved that "mystery" for me! I am going to order a A,B or E key adapter and give it another try! Thx so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment