Skip to main content

Using ModemManager to control cellular modules

Support Module List:

Install ModemMamager tools

  • For [Ubuntu 20.04] / [Debian 9/10/11]
apt-get install modemmanager -y
  • For CentOS 7.9
yum install ModemManager -y

Check DIP switch status

  • Power on module
    • Ensure DIP switch status is 'OFF' on target slot
    • Power on cellular module
  • Check SIM slot is selected (if using dual SIM card slots)

Check QMI wwan driver is loaded

$ dmesg | grep qmi
[ 783.731551] qmi_wwan 1-7:1.2: cdc-wdm0: USB WDM device
[ 783.732748] qmi_wwan 1-7:1.2 wwan0: register 'qmi_wwan' at usb-0000:00:14.0-7, WWAN/QMI device, d2:c4:e0:a2:4f:95
[ 783.732862] usbcore: registered new interface driver qmi_wwan

$ ip a | grep wwan
5: wwan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000

Check Cellular module can be detected by ModemManager

$ mmcli -L
/org/freedesktop/ModemManager1/Modem/0 [Telit] LE910C4-AP

Here ModemManager have detected a Telit Wireless cellular device and it has here been given the the identifier number 0 by ModemManager.

Get Cellular module information

$ mmcli -m 0
----------------------------------
General | path: /org/freedesktop/ModemManager1/Modem/0
| device id: e13881209ca107437f75920428e922072f6743a4
----------------------------------
Hardware | manufacturer: Telit
| model: LE910C4-AP
| firmware revision: 25.21.680 1 [Mar 04 2021 12:00:00]
| carrier config: default
| h/w revision: 1.20
| supported: gsm-umts, lte
| current: gsm-umts, lte
| equipment id: 357575100312792
----------------------------------
System | device: /sys/devices/platform/soc/30800000.bus/30b10000.usb/ci_hdrc.0/usb1/1-1
| drivers: option, qmi_wwan
| plugin: Moxa-Telit-LE910CX
| primary port: cdc-wdm0
| ports: cdc-wdm0 (qmi), ttyUSB4 (ignored), ttyUSB5 (gps),
| ttyUSB6 (at), ttyUSB7 (at), ttyUSB8 (ignored), wwan0 (net)
----------------------------------
Numbers | own: +886909811277
----------------------------------
Status | lock: sim-puk2
| unlock retries: sim-pin (3), sim-puk (10), sim-pin2 (0), sim-puk2 (9)
| state: registered
| power state: on
| access tech: lte
| signal quality: 75% (cached)
----------------------------------
Modes | supported: allowed: 3g; preferred: none
| allowed: 4g; preferred: none
| allowed: 3g, 4g; preferred: 4g
| allowed: 3g, 4g; preferred: 3g
| current: allowed: 3g, 4g; preferred: 4g
----------------------------------
Bands | supported: utran-1, utran-6, utran-5, utran-8, eutran-1, eutran-3,
| eutran-5, eutran-8, eutran-9, eutran-18, eutran-19, eutran-26,
| eutran-28, utran-19
| current: utran-1, utran-6, utran-5, utran-8, eutran-1, eutran-3,
| eutran-5, eutran-8, eutran-9, eutran-18, eutran-19, eutran-26,
| eutran-28, utran-19
----------------------------------
IP | supported: ipv4, ipv6, ipv4v6
----------------------------------
3GPP | imei: 357575100312792
| enabled locks: fixed-dialing
| operator id: 46697
| operator name: TWM
| registration: home
----------------------------------
3GPP EPS | ue mode of operation: csps-1
| initial bearer path: /org/freedesktop/ModemManager1/Bearer/0
| initial bearer apn: internet
| initial bearer ip type: ipv4v6
----------------------------------
SIM | primary sim path: /org/freedesktop/ModemManager1/SIM/0
| sim slot paths: slot 1: /org/freedesktop/ModemManager1/SIM/0 (active)
| slot 2: none
----------------------------------

Check SIM status

if lock: sim-pin is displayed in the module information, the indicates that inserted SIM card is PIN locked, so a unlock by --pin command is necessary

$ mmcli --sim=1 --pin=****
successfully sent PIN code to the SIM

Check registration status

           |            power state: on
| access tech: lte
| signal quality: 62% (cached)

The status output shows that devices is registered in network using LTE technology with a good signal strength. If access tech is not displayed or the signal quality is very low, please check if the antenna is installed correctly.

Start connection

$ mmcli -m 0 --simple-connect='apn=internet,ip-type=ipv4v6'
successfully connected the modem

if we check modem status again we can see that a bearer have been established.

$ mmcli -m 0
...
----------------------------------
Bearer | paths: /org/freedesktop/ModemManager1/Bearer/1
...

The bearer have got identifier number 1 so we can request more details for it to acquire the IP details:

$ mmcli --bearer=1
------------------------------------
General | path: /org/freedesktop/ModemManager1/Bearer/1
| type: default
------------------------------------
Status | connected: yes
| suspended: no
| multiplexed: no
| interface: wwan0
| ip timeout: 20
------------------------------------
Properties | apn: internet
| roaming: allowed
| ip type: ipv4v6
------------------------------------
IPv4 configuration | method: static
| address: 10.96.111.196
| prefix: 29
| gateway: 10.96.111.197
| dns: 61.31.1.1, 61.31.233.1
| mtu: 1500
------------------------------------
IPv6 configuration | method: static
| address: 2402:7500:488:33f2:4069:3529:ff29:a03f
| prefix: 64
| gateway: 2402:7500:488:33f2:dd08:aa15:d429:1761
| dns: 2001:4546:1::1, 2001:4546:2::1
| mtu: 1500
------------------------------------
Statistics | duration: 60
| attempts: 2
| total-duration: 510
| total-bytes rx: 352

From here we can see the IP details we've been assigned by the cellular network. ModemManager does not assign IPv4 address details to the cellular modules network interface in Linux by itself. When ModemManager is used in conjunction with NetworkManager and the cellular connection is managed by it, then the IPv4 address details will be collected by NetworkManager through ModemManager and automatically assigned to network interface when connection is established. If the system does not implement NetworkManager, then the IP and routing configuration needs to be handled by user software/scripting.

Setup cellular network interface

$ ip link set wwan0 up
  • Set the IPv4 address acquired from bearer information above, the CIDR subnet mask can always be set to 32:
$ ip addr add 10.96.111.196/32 dev wwan0
  • Set MTU value acquired from network:
$ ip link set dev wwan0 mtu 1500
  • Set default route
$ ip route add default dev wwan0
  • Set DNS
$ echo 'nameserver 61.31.1.1' >> /etc/resolv.conf
$ echo 'nameserver 61.31.233.1' >> /etc/resolv.conf

ping google test

$ ping -4  google.com -Iwwan0 -c 10

GPS

  • Enable AT Command
$ vi /lib/systemd/system/ModemManager.service

Add --debug option to service file.

[Unit]
Description=Modem Manager
After=polkit.service
Requires=polkit.service

[Service]
Type=dbus
BusName=org.freedesktop.ModemManager1
ExecStart=/usr/sbin/ModemManager --debug
StandardError=null
Restart=on-abort
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_NET_ADMIN
ProtectSystem=true
ProtectHome=true
PrivateTmp=true
RestrictAddressFamilies=AF_NETLINK AF_UNIX AF_QIPCRTR
NoNewPrivileges=true
User=root

[Install]
WantedBy=multi-user.target
Alias=dbus-org.freedesktop.ModemManager1.service

Restart ModemManager service.

$ systemctl daemon-reload
$ systemctl restart ModemManager
  • Enable GPS function
mmcli -m 0 --command="AT\$GPSRST"
mmcli -m 0 --command="AT\$GPSNMUN=2,1,1,1,1,1,1"
mmcli -m 0 --command="AT\$GPSP=1"
mmcli -m 0 --command="AT\$GPSSAV"
  • Disable GPS function
mmcli -m 0 --command="AT\$GPSRST"
mmcli -m 0 --command="AT\$GPSSAV"
  • Disable AT Command
$ vi /lib/systemd/system/ModemManager.service

Remove --debug option from service file.

[Unit]
Description=Modem Manager
After=polkit.service
Requires=polkit.service

[Service]
Type=dbus
BusName=org.freedesktop.ModemManager1
ExecStart=/usr/sbin/ModemManager
StandardError=null
Restart=on-abort
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_NET_ADMIN
ProtectSystem=true
ProtectHome=true
PrivateTmp=true
RestrictAddressFamilies=AF_NETLINK AF_UNIX AF_QIPCRTR
NoNewPrivileges=true
User=root

[Install]
WantedBy=multi-user.target
Alias=dbus-org.freedesktop.ModemManager1.service

Restart ModemManager service.

$ systemctl daemon-reload
$ systemctl restart ModemManager
  • Get GPS NMEA data

We get GPS tty serial port: e.g. ttyUSB5

$ mmcli -m 0
...
| ports: cdc-wdm0 (qmi), ttyUSB4 (ignored), ttyUSB5 (gps),
| ttyUSB6 (at), ttyUSB7 (at), ttyUSB8 (ignored), wwan0 (net)
...

Get GPS information from tty serial port:

$ cat /dev/ttyUSB5

$GPVTG,,T,,M,,N,,K,N*2C

$GPGSA,A,1,,,,,,,,,,,,,,,,*32

$GPGGA,,,,,,0,,,,,,,,*66

$GPRMC,,V,,,,,,,,,,N,V*29

$GPGLL,,,,,,V,N*64

Reference

Last updated on 2023-05-17 by Tzongyen Lin (林宗彥)