Linux Modem Manager

Wireless Modem

FCC Lock

A mechanism called "FCC Lock" prevents the radio from being enabled until it is unlocked.
It has been done for regulatory purposes.
The ModemAuthenticator.exe comes with the driver in Windows, the unlock key is stored in the system's SMBIOS.
Lenovo only tested the Windows configuration, and possibly implemented this locking mechanism to maintain compliance.

SAR Information

Your wireless modem is a radio transmitter and receiver. It is designed and manufactured not to exceed the emission limits for exposure to radiofrequency (RF) energy set by the FCC of the U.S Government.
The exposure standard for wireless mobile modem employs a unit of measurement known as the Specific Absorption Rate, or SAR.
The SAR limit set by the FCC is 1.6 W/kg.

5G Modems

5G NR (New Radio) is a new radio access technology (RAT) developed by 3GPP for the 5G (fifth generation) mobile network.
5G NR uses two frequency ranges:
  • FR1
  • Frequency Range 1, Utilizes a lot of what 4G was using.
  • FR2
  • Frequency Range 2, Shorter Range but Higher Bandwidth. Millimeter waves (mmWave).
Initial 5G NR launches will depend on existing 4G LTE infrastructure in non-standalone (NSA) mode, before maturation of the standalone (SA) mode with the 5G core network.
Additionally, the spectrum can be dynamically shared between 4G LTE and 5G NR.

  • The non-standalone (NSA) mode of 5G NR refers to an option of 5G NR deployment that depends on the control plane of an existing 4G LTE network( relying on the 4G Evolved Packet Core) for control functions, while 5G NR is exclusively focused on the user plane.
  • The standalone (SA) mode of 5G NR refers to using 5G cells for both signalling and information transfer.[8] It includes the new 5G Packet Core architecture
Many 5G cards are in the M.2 form factor and a size of 3052 (30mm wide by 52mm long).

5G connectivity depends on several factors, so before wasting a bunch of time trying to connect to 5G, make sure that all the following criterias are met.

  • The modem variant has to match the carrier you’re using in your country
  • (ex. RM500Q-AE for NSA bands in the US / RM500Q-GL for SA/NSA bands in most other countries).
  • While carriers might offer 5G, it’s not always available on all their plans.
  • Check with them to make sure that your plan includes 5G access at no additional cost or might have to pay extra for it.
    The following AT command can show the 5G connectivity by querying the service cell information,
    
    $ sudo mmcli -m 0 --command='AT+QENG="Servingcell"'
    	
    But, the carrier/plan may not actually allow an active data channel.
  • In 5G NSA mode, the modem normally idles in LTE mode, and will only connect to 5G during large data transfers controlled exclusively by the carrier’s tower
  • Since the system is 5G NSA (none stand alone), only the user data is used with the 5G, the control data is still using LTE.
    Therefor if there are no active user data, the 5G NSA status would not be active, it will activate during data usage (this would be the normal behaviour).
    So, when the modem is idle (on LTE) you will not get 5G NR signal data.
    You need an active connection in order to get the signal info of the 5G part of NSA.
You need to set a list of allowed modes and only then you can select one of them to be preferred. The modem may not support the combination you provide, though.


$ sudo mmcli -m 0 --set-allowed-modes='3g|4g|5g' --set-preferred-mode='4g'
Test Foxconn modem:
  • Supported modes
  • 
      Modes    |               supported: allowed: 3g; preferred: none
               |                          allowed: 4g; preferred: none
               |                          allowed: 3g, 4g; preferred: 4g
               |                          allowed: 3g, 4g; preferred: 3g
               |                          allowed: 5g; preferred: none
               |                          allowed: 3g, 5g; preferred: 5g
               |                          allowed: 3g, 5g; preferred: 3g
               |                          allowed: 4g, 5g; preferred: 5g
               |                          allowed: 4g, 5g; preferred: 4g
               |                          allowed: 3g, 4g, 5g; preferred: 5g
               |                          allowed: 3g, 4g, 5g; preferred: 4g
               |                          allowed: 3g, 4g, 5g; preferred: 3g
    	
  • Test
  • 
    
    $ sudo mmcli -m 0 --set-allowed-modes='3g|4g|5g' --set-preferred-mode='5g'
    error: couldn't set current modes: 'GDBus.Error:org.freedesktop.libqmi.Error.Core.Timeout: Transaction timed out'
    
    $ sudo mmcli -m 0 --set-allowed-modes='3g|4g|5g' --set-preferred-mode='4g'
    
    $ sudo mmcli -m 0 --command='AT^DEBUG?'
    response: 'RAT:LTE
    mcc:466,mnc:92
    lte_cell_id:55519256
    lte_tac:11200
    lte_tx_pwr:0.0dB
    lte_ant_rsrp:rx_diversity:3 (-117.7dBm,-77.6dBm,-256.0dBm,-256.0dBm)
    pcell: lte_band:7 lte_band_width:20.0MHz
    channel:3050 pci:18
    lte_rsrp:-77.3dBm,rsrq:-8.9dB
    lte_rssi:-48.8dBm,lte_snr:15.4dB'
    
    $ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --nas-get-system-selection-preference
    [/dev/wwan0p2MBIM] Successfully got system selection preference
    	Emergency mode: 'no'
    	Mode preference: 'umts, lte, 5gnr'
    	Disabled modes: '(null)'
    	Band preference: 'wcdma-2100, wcdma-pcs-1900, wcdma-1700-us, wcdma-850-us, wcdma-800, wcdma-900, wcdma-1700-japan, wcdma-850-japan'
    	LTE band preference: '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42'
    	LTE band preference (extended): '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42, 46, 48, 66, 71'
    	TD-SCDMA band preference: 'a, b, c, d, e, f'
    	Roaming preference: 'any'
    	Network selection preference: 'automatic'
    	Service domain preference: 'ps-only'
    	GSM/WCDMA acquisition order preference: 'automatic'
    	Usage preference: 'data-centric'
    	Voice domain preference: 'ps-preferred'
    	Registration restriction: 'unrestricted'
    	Acquisition order preference: 'lte, umts'
    
    $ sudo mmcli --modem 0 --enable
    successfully enabled the modem
    
    $ sudo mmcli -m 0 --simple-connect="pin=0000,apn=emome"
    successfully connected the modem
    
    $ sudo nmcli radio wwan on
    
    $ sudo nmcli connection add type gsm ifname wwan0p2MBIM con-name mymodem apn emome
    Connection 'mymodem' (7cc0945f-9d6b-412f-8266-8c297257651f) successfully added.
    
    $ sudo nmcli connection up id mymodem 
    Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5)
    
    
    $ sudo qmicli --device=/dev/wwan0p2MBIM --device-open-proxy --dms-get-manufacturer
    [/dev/wwan0p2MBIM] Device manufacturer retrieved:
    	Manufacturer: 'Qualcomm'
    
    $ sudo qmicli --device=/dev/wwan0p2MBIM --device-open-proxy --dms-get-ids 
    [/dev/wwan0p2MBIM] Device IDs retrieved:
    	    ESN: '0'
    	   IMEI: '***'
    	   MEID: 'unknown'
    	IMEI SV: '1'
    
    $ sudo qmicli --device=/dev/wwan0p2MBIM --device-open-proxy --dms-get-band-capabilities
    [/dev/wwan0p2MBIM] Device band capabilities retrieved:
    	Bands: 'wcdma-2100, wcdma-pcs-1900, wcdma-dcs-1800, wcdma-1700-us, wcdma-850-us, wcdma-800, wcdma-900, wcdma-1700-japan, wcdma-850-japan'
    	LTE bands: '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42'
    	LTE bands (extended): '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42, 46, 48, 66, 71'
        
    $ sudo qmicli --device=/dev/wwan0p2MBIM --device-open-proxy --nas-get-system-info      
    [/dev/wwan0p2MBIM] Successfully got system info:
    	WCDMA service:
    		Status: 'none'
    		True Status: 'none'
    		Preferred data path: 'no'
    	LTE service:
    		Status: 'available'
    		True Status: 'none'
    		Preferred data path: 'no'
    		Domain: 'ps'
    		Service capability: 'ps'
    		Roaming status: 'off'
    		Forbidden: 'no'
    		Cell ID: '55519256'
    		MCC: '466'
    		MNC: '92'
    		Tracking Area Code: '11200'
    		Voice support: 'no'
    		IMS voice support: 'yes'
    		eMBMS coverage info support: 'no'
    		eMBMS coverage info trace ID: '65535'
    		Cell access: 'all-calls'
    		Registration restriction: 'unrestricted'
    		Registration domain: 'not-applicable'
    	SIM reject info: 'available'
        
    $ sudo qmicli --device=/dev/wwan0p2MBIM --device-open-proxy --nas-get-signal-info
    [/dev/wwan0p2MBIM] Successfully got signal info
    LTE:
    RSSI: '-41 dBm'
    RSRQ: '-14 dB'
    RSRP: '-75 dBm'
    SNR: '2.4 dB'
    5G:
    RSRP: '-32768 dBm'
    SNR: '-3276.8 dB'
    RSRQ: '-32768 dB'
    

Carrier Approval / Certification

Production hardware needs to be Carrier Approved - a process that the end-customer needs to work through with the Cellular provider on the finished device.
Part of the carrier approval also includes FCC testing of the fully integrated device.

Mobile Termination

The Cellular Carrier dictates if your plan provides 'mobile termination' (the ability to accept connections from the Internet) and the IP address provisioning (IP class, static vs dynamic, IP range).

Modem Firmware

Modems typically require non-volatile firmware that gets flashed onto the device.
This firmware is available from the modem manufacturer and/or carrier.
Often you will need a different firmware version for different carriers and the firmware can also drastically change the behavior and control protocol the modem uses.
Qualcomm's QMI based modems can update their firmware using libqmi-firmware.

Modem Control

Modem's require additional configuration and control to perform the following types of details before moving on to configuring a network interface:
  • Dialing (in the old days for dial-up modems)
  • SIM pin control and unlocking (security)
  • Network provider registration
  • Data Protocol selection
Once all of the above is completed, a modem driver will provide a network interface to the Linux OS:
  • IP over ethernet
  • raw IP
  • IP over serial (sometimes via PPP daemon)
And once you finally have an IP networking interface up and running from the modem, you can use the standard IP configuration tools within Linux (like NetworkManager or the lower-level tools such as ip, route, ifconfig, etc).
Different modem control protocols have been developed:
  • AT commands
  • text commands and responses typically preceded by 'AT' and terminated with a CR (carriage return or 0x0d
  • QMI
  • Qualcomm Modem Interface (A binary protocol used for modern Qualcomm based modems)
  • MBIM - Mobile Interface Broadband Model
  • A new standard by the USB Implementers Forum specifying a new MBIM USB device model with multiple IP connections over a single USB interface without the need of 802.3 frames and a new MBIM control protocol
The QMI protocol is proprietary protocol by Qualcomm.
In contrast to QMI, MBIM is more standardized protocol for 3G/4G dongles.

ModemManager

ModemManager is a package containing a background service/daemon and a command-line-interfalce (mmcli) that can be used to configure and connect modems.
Note that after starting the service (if manually started) it does take 20 to 30 seconds to finish modem detection.
  • List detected modems
  • 
    $ sudo mmcli --list-modems
        /org/freedesktop/ModemManager1/Modem/0 [generic] EM160R_GL	
  • Show details for the first modem
  • 
    $ sudo mmcli --modem 0
    ...
      -----------------------------
      System   |            device: /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0
               |           drivers: mhi_net, mhi-pci-generic
               |            plugin: foxconn
               |      primary port: wwan0p2MBIM
               |             ports: mhi_mbim0 (net), wwan0p2MBIM (mbim)
      -----------------------------
      Status   |             state: failed
               |     failed reason: sim-missing
               |       power state: low
               |    signal quality: 0% (cached)
      -----------------------------
    ...
    
    	
    It may be that the SIM is not working properly or the modem is not recognizing it.
    • SIM card is not plugged in
    • 
      $ sudo mmcli -m 0
      …
        -----------------------------------
        Status   |                   state: failed
      
                 |           failed reason: sim-missing
      …
       -----------------------------------
        SIM      |          sim slot paths: slot 1: none (active)
                 |                          slot 2: /org/freedesktop/ModemManager1/SIM/0
      
      $ sudo mmcli -i 0
        -------------------------------
        General    |              path: /org/freedesktop/ModemManager1/SIM/0
        -------------------------------
        Properties |            active: no      
        
      $ sudo mmcli -i 1
      error: couldn't find SIM
              
      Common options:
      • -m, --modem=[PATH|INDEX]
      • Specify a modem.
      • -b, --bearer=[PATH|INDEX]
      • Specify a bearer.
      • -i, --sim=[PATH|INDEX]
      • Specify a SIM card.
      • -s, --sms=[PATH|INDEX]
      • Specify an SMS.
      The modem's PATH and INDEX are created automatically when the modem is plugged in.
      For the bearers, SIMs and SMS cases, object name is used. For ex., the SIM
      
      $ sudo mmcli -i 0
        -------------------------------
        General    |              path: /org/freedesktop/ModemManager1/SIM/0
      		
      SIM slots and modem cards are two different objects.
      The DBus object numbers for the SIM objects, or for the modem objects for that matter, represent a given SIM card or modem at a given time.
      If there is a SIM switch operation, or a modem reboot, the DBus object numbers will bump.
    • Change the SIM card
    • The SIM interface is powered by an internal regulator in the module.
      Both 1.8V and 3.0V SIM Cards are supported.
      Insert this SIM into your phone to check if it can be detected normally .
    • The problem might be that PolKit is not able to find MM files.
    • By default, MM will install to /usr/local and PolKit on Ubuntu usually looks into /usr dir only.
      You can try to fix this problem by running ./configure --prefix=/usr in MM source dir before building and installing.
    For a successfull initialization,
      
    $ sudo mmcli -m 0
      -----------------------------------
      General  |                    path: /org/freedesktop/ModemManager1/Modem/0
               |               device id: 3211b80fb2ccecd5e0695490f578bcb2ec7cc37c
      -----------------------------------
      Hardware |            manufacturer: generic
               |                   model: EM160R_GL
               |       firmware revision: EM160RGLAPR02A07M4G
               |          carrier config: ROW_Commercial
               | carrier config revision: 08010809
               |            h/w revision: EM160R_GL
               |               supported: gsm-umts, lte
               |                 current: gsm-umts, lte
               |            equipment id: 864292050076577
      -----------------------------------
      System   |                  device: /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0
               |                 drivers: mhi_net, mhi-pci-generic
               |                  plugin: generic
               |            primary port: wwan0p2MBIM
               |                   ports: mhi_mbim0 (net), wwan0p2MBIM (mbim), wwan0p3AT (at)
      -----------------------------------
      Status   |          unlock retries: sim-pin (3), sim-pin2 (3)
               |                   state: connected
               |             power state: on
               |             access tech: lte
               |          signal quality: 35% (recent)
      -----------------------------------
      Modes    |               supported: allowed: 3g; preferred: none
               |                          allowed: 4g; preferred: none
               |                          allowed: 3g, 4g; preferred: 4g
               |                          allowed: 3g, 4g; preferred: 3g
               |                 current: allowed: 2g, 3g, 4g; preferred: 4g
      -----------------------------------
      Bands    |               supported: utran-1, utran-3, utran-4, utran-6, utran-5, utran-8, 
               |                          utran-2, eutran-1, eutran-2, eutran-3, eutran-4, eutran-5, eutran-7, 
               |                          eutran-8, eutran-12, eutran-13, eutran-14, eutran-17, eutran-18, 
               |                          eutran-19, eutran-20, eutran-25, eutran-26, eutran-28, eutran-29, 
               |                          eutran-30, eutran-32, eutran-38, eutran-39, eutran-40, eutran-41, 
               |                          eutran-42, eutran-43, eutran-46, eutran-48, eutran-66, utran-19
               |                 current: utran-1, utran-3, utran-4, utran-6, utran-5, utran-8, 
               |                          utran-2, eutran-1, eutran-2, eutran-3, eutran-4, eutran-5, eutran-7, 
               |                          eutran-8, eutran-12, eutran-13, eutran-14, eutran-18, eutran-19, 
               |                          eutran-20, eutran-25, eutran-26, eutran-28, eutran-29, eutran-30, 
               |                          eutran-32, eutran-38, eutran-39, eutran-40, eutran-41, eutran-42, 
               |                          eutran-43, eutran-46, eutran-48, eutran-66, utran-19
      -----------------------------------
      IP       |               supported: ipv4, ipv6, ipv4v6
      -----------------------------------
      3GPP     |                    imei: ***
               |           enabled locks: sim, fixed-dialing
               |             operator id: 46692
               |           operator name: Chunghwa Telecom
               |            registration: home
      -----------------------------------
      3GPP EPS |    ue mode of operation: csps-2
               |     initial bearer path: /org/freedesktop/ModemManager1/Bearer/0
               |  initial bearer ip type: ipv4v6
      -----------------------------------
      SIM      |        primary sim path: /org/freedesktop/ModemManager1/SIM/0
      -----------------------------------
      Bearer   |                   paths: /org/freedesktop/ModemManager1/Bearer/1
      	
  • Unlock SIM PIN
  • You'll need first to know which the proper path/index is for the SIM in your modem:
    
    $ sudo mmcli -m 0 -K | grep "modem.generic.sim"
    modem.generic.sim                               : /org/freedesktop/ModemManager1/SIM/0
    modem.generic.sim-slots                         : --
    	
    The SIM card failure caused the following debug messages:
    
    ModemManager[1668]: <debug> [1622019182.949132] [modem0] couldn't setup SIM hot swap using QMI over MBIM: Couldn't peek client for service 'uim'
    ModemManager[1668]: <debug> [1622019182.949165] [modem0] SIM hot swap setup succeeded
    ModemManager[1668]: <warn>  [1622019182.949250] [modem0] couldn't query SIM slots: Couldn't peek client for service 'uim'    
    couldn't open ports during Modem SIM hot swap enabling: Couldn't get primary port
    	
    If success, you can just use the SIM index:
    
    $ sudo mmcli -i 0 --pin=0000
    successfully sent PIN code to the SIM
    	
    Some additional commands for handling SIM PINs are
    • '--enable-pin'
    • enable PIN locking
    • '--disable-pin'
    • disable PIN locking
    • '--change-pin=NEW_PIN'
    • changing the PIN
    • '--puk=PUK'
    • unlocking a PUK-locked (Personal unblocking code)
  • Enable first modem
  • 
    $ sudo mmcli --modem 0 --enable
    successfully enabled the modem    
        
    The modem can not be enabled if there is a failure
    if you get a failure here, make sure that the status shown by the "mmcli --modem 0".
    For ex., the following error is due to the PIN is not entered:
    
    $ mmcli --modem 0 --enable
    error: couldn't enable the modem: 'GDBus.Error:org.freedesktop.ModemManager1.Error.Core.WrongState: Cannot enable modem: device locked'  
    
    $ mmcli -m 0
    ...
      Status   |              lock: sim-pin
               |    unlock retries: sim-pin (3)
               |             state: locked
               |       power state: low
               |    signal quality: 0% (cached)
    ...
        
    The above error can be resolved after enter the PIN:
    
    $ sudo mmcli -i 0 --pin=0000
    successfully sent PIN code to the SIM
    
    $ mmcli -m 0
      Status   |         unlock retries: sim-pin (3), sim-pin2 (3)
               |                  state: enabled
               |            power state: on
               |         signal quality: 0% (cached)
    	
  • Scan available 3GPP networks
  • 
    $ sudo mmcli --modem 0 --3gpp-scan --timeout=300    
      ---------------------
      3GPP scan | networks: 46689 - T Star (gprs, available)
                |           46605 - TWN APT (gprs, available)
                |           46697 - TW Mobile (gprs, available)
                |           46601 - Far EasTone (gprs, available)
                |           46692 - Chunghwa Telecom (gprs, unknown)
    
        
  • Simple connect
  • 
    $ sudo mmcli -m 0 --simple-connect="pin=0000,apn=internet"
        successfully connected the modem    
        
  • Get IP Configuration
  • 
    $ sudo mmcli --modem 0 | grep Bearer
               |     initial bearer path: /org/freedesktop/ModemManager1/Bearer/0
      Bearer   |                   paths: /org/freedesktop/ModemManager1/Bearer/2
               |                          /org/freedesktop/ModemManager1/Bearer/1
    
    $ mmcli --bearer 1
      ------------------------------------
      General            |           path: /org/freedesktop/ModemManager1/Bearer/1
                         |           type: default
      ------------------------------------
      Status             |      connected: yes
                         |      suspended: no
                         |    multiplexed: no
                         |      interface: mhi_mbim0
                         |     ip timeout: 20
      ------------------------------------
      Properties         |            apn: internet
                         |        roaming: allowed
                         |        ip type: ipv4v6
      ------------------------------------
      IPv4 configuration |         method: static
                         |        address: 10.192.121.73
                         |         prefix: 30
                         |        gateway: 10.192.121.74
                         |            dns: 168.95.1.1, 168.95.192.1
                         |            mtu: 1500
      ------------------------------------
      IPv6 configuration |         method: static
                         |        address: 2001:b400:e208:1569:4d94:a146:7184:acee
                         |         prefix: 64
                         |        gateway: 2001:b400:e208:1569:5d88:82f1:cd7e:8f74
                         |            dns: 2001:b000:168::1, 2001:b000:168::2
                         |            mtu: 1500
      ------------------------------------
      Statistics         |       duration: 10050
                         |       bytes rx: 36706
                         |       bytes tx: 21462
                         |       attempts: 1
                         | total-duration: 10050
                         | total-bytes rx: 36706
                         | total-bytes tx: 21462
    
        
    All left is to set the appropriate WWAN interface with the IP and netmask setting given.
    However you would also have to route the traffic you want to go over the interface to the defined gateway.
    • by NetworkManager
    • 
      $ sudo nmcli radio wwan on
      $ sudo nmcli connection add type gsm ifname wwan0p2MBIM con-name mymodem apn emome
      $ sudo nmcli connection up id mymodem      
            	
    • by yourself
    • 
      $ sudo ip link set mhi_mbim0 up
      $ sudo ip addr add 10.192.121.73/30 dev mhi_mbim0
      $ sudo ip link set dev mhi_mbim0 arp off
      $ sudo ip route add default dev mhi_mbim0 metric 200
          	
  • Sending SMS
    • Create a message
    • 
      $ sudo mmcli -m 0 --messaging-create-sms="text='Hello from SE30',number='+1234567890'"
      Successfully created new SMS: /org/freedesktop/ModemManager1/SMS/1
              
      Write down the SMS id from output (here: 1)
    • Send the message
    • 
      $ sudo mmcli -s 1 --send        
      successfully sent the SMS
              
  • Simple disconnect
  • 
    $ mmcli -m 0 --simple-disconnect
        

Configure Cellular Connections via Ubuntu Snap

  • install the modem-manager snap
  • 
    $ snap install modem-manager    
        
  • Check whether a modem was properly detected
  • 
    $ sudo modem-manager.mmcli -L
    Found 1 modems:
        /org/freedesktop/ModemManager1/Modem/0 [description]    
        
  • Debug
  • Enable Debug:
    
    $ snap set modem-manager debug.enable=true  
      	
    Viewing logs:
    
    $ journalctl --no-pager -u snap.modem-manager.modemmanager.service  
      	
    Disable Debug:
    
    $ snap set modem-manager debug.enable=false  
      	
  • Show detailed information about the modem using that index
  • 
    $ sudo modem-manager.mmcli -m 0    
    ...
      System   |         device: '/sys/devices/pci0000:00/0000:00:01.2/usb1/1-1'
               |        drivers: 'option1'
               |         plugin: 'ZTE'
               |   primary port: 'ttyUSB3'
               |          ports: 'ttyUSB0 (qcdm), ttyUSB1 (at), ttyUSB3 (at)'
    ...
      Status   |           lock: 'sim-pin'
               | unlock retries: 'sim-pin (3), sim-puk (10)'
               |          state: 'locked'
               |    power state: 'on'
               |    access tech: 'unknown'
               | signal quality: '0' (cached)
    ...
    SIM      |           path: '/org/freedesktop/ModemManager1/SIM/0'
    ...
        
    The SIM has PIN locking enabled and its state is ‘locked’.
    The SIM index is 0 (it is the number at the end of SIM path: /org/freedesktop/ModemManager1/SIM/0)
  • enter the SIM PIN
  • With the assigned SIM index:
    
    $ sudo modem-manager.mmcli -i 0 --pin=PIN    
        
    Some more commands for handling SIM PINs
    • enables PIN locking
    • 
      $ sudo modem-manager.mmcli -i 0 --pin=PIN --enable-pin    
          		
    • disables PIN locking
    • 
      $ sudo modem-manager.mmcli -i 0 --pin=PIN --disable-pin    
          		
    • changes the PIN code
    • 
      $ sudo modem-manager.mmcli -i 0 --pin=PIN --change-pin=NEW_PIN    
          		
    • unlocks a PUK-locked SIM
    • 
      $ sudo modem-manager.mmcli -i 0 --puk=PUK    
          		
  • Use NetworkManager to add a cellular connection
  • 
    $ nmcli c add type gsm ifname interface con-name name apn operator_apn    
        
    where:
    • interface
    • is the string listed as “primary port:” in the output from "sudo mmcli -m N".
      interface names might change depending on the devices present in the system, a better alternative is to use the sysfs path shown by mmcli ("device:") or use ‘*’, which will use any modem device detected by MM:
      
      $ sudo nmcli c add type gsm ifname '*' ...        
              
    • name
    • an arbitrary name used to identify the MM connection
    • operator_apn
    • the APN name for your cellular data plan
  • Use NetworkManager to enable a cellular connection
  • 
    $ nmcli r wwan on    
        
  • Use NetworkManager to disable a cellular connection
  • 
        After executing these commands, NetworkManager will automatically try to bring up the cellular connection whenever ModemManager reports that the modem has registered (the state of the modem can be checked with the previously introduced command “sudo modem-manager.mmcli -m ”).
    When done successfully, NetworkManager will create routes for the new network interface, with less priority than Ethernet or WiFi interfaces. $ nmcli r wwan off
  • change the autoconnect property in NetworkManager
  • 
    $ nmcli c modify name connection.autoconnect [yes|no]    
        
  • turn the connection off in NetworkManager
  • 
    $ nmcli c down name    
        

Modem Manager

Cellular modem control and connectivity.

ModemManager provides a unified high level API for communicating with mobile broadband modems, regardless of the protocol used to communicate with the actual device (Generic AT, vendor-specific AT, QCDM, QMI, MBIM...).

ModemManager is a system daemon and is not meant to be used directly from the command line.
However, since it provides a DBus API, it is possible to use 'dbus-send' commands or the new 'mmcli' command line interface to control it from the terminal.
The devices are queried from udev and automatically updated based on hardware events, although a manual re-scan can also be requested to look for RS232 modems.

ModemManager is a DBus system bus activated service (meaning it's started automatically when a request arrives).
It is written in C, using glib and gio.

Several GInterfaces specify different features that the modems support, including the generic MMIfaceModem3gpp and MMIfaceModemCdma which provide basic operations for 3GPP (GSM, UMTS, LTE) or CDMA (CDMA1x, EV-DO) modems.
If a given feature is not available in the modem, the specific interface will not be exported in DBus.

Plugins are loaded on startup, and must implement the MMPlugin interface.
It consists of a couple of methods which tell the daemon whether the plugin supports a port and to create custom MMBroadbandModem implementations.
It most likely makes sense to derive custom modem implementations from one of the generic classes and just add (or override) operations which are not standard.
There are multiple fully working plugins in the plugins/ directory that can be used as an example for writing new plugins.
Writing new plugins is highly encouraged! The plugin API is open for changes, so if you're writing a plugin and need to add or change some public method, feel free to suggest it!

To disable modemmanager

ModemManager has dependencies on other packages
  
  libmm-glib0 modemmanager network-manager network-manager-pptp
File list of package:
  • libmm-glib0
  • 
    /usr/lib/x86_64-linux-gnu/libmm-glib.so.0
    /usr/lib/x86_64-linux-gnu/libmm-glib.so.0.5.0
    /usr/share/doc/libmm-glib0/changelog.Debian.gz
    /usr/share/doc/libmm-glib0/copyright    
        
  • modemmanager
  • 
    /etc/dbus-1/system.d/org.freedesktop.ModemManager1.conf
    /lib/systemd/system/ModemManager.service
    /lib/udev/rules.d/77-mm-cinterion-port-types.rules
    ...
    /usr/bin/mmcli
    /usr/lib/x86_64-linux-gnu/ModemManager/libmm-plugin-altair-lte.so
    ...
    /usr/sbin/ModemManager
    /usr/share/ModemManager/mm-dell-dw5821e-carrier-mapping.conf
    /usr/share/bash-completion/completions/mmcli
    /usr/share/dbus-1/system-services/org.freedesktop.ModemManager1.service
        
To keep networking controlled by the NetworkManager, we can't remove the ModemManager package.

$ sudo systemctl status ModemManager.service
[sudo] password for ubuntu: 
* ModemManager.service - Modem Manager
     Loaded: loaded (/lib/systemd/system/ModemManager.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2021-05-24 20:01:46 UTC; 8min ago
   Main PID: 845 (ModemManager)
      Tasks: 3 (limit: 8992)
     Memory: 6.5M
     CGroup: /system.slice/ModemManager.service
             `-845 /usr/sbin/ModemManager --filter-policy=strict

May 24 20:01:45 ubuntu systemd[1]: Starting Modem Manager...
...
We can disable it for testing the newer version:

$ sudo systemctl stop ModemManager.service
$ sudo systemctl disable ModemManager.service
Removed /etc/systemd/system/dbus-org.freedesktop.ModemManager1.service.
Removed /etc/systemd/system/multi-user.target.wants/ModemManager.service.
If you are building and installing from source you should remove all other packages that install libmbim or libqmi:

$ sudo apt purge libmbim-glib-dev llibmbim-glib-doc libmbim-glib4 libmbim-glib4-dbg libmbim-proxy libmbim-utils
$ sudo apt purge libqmi-glib-dev libqmi-glib-doc libqmi-glib1 libqmi-glib1-dbg libqmi-proxy libqmi-utils
  • "apt remove" just removes the binaries of a package. It leaves residue configuration files.
  • "apt purge" removes everything related to a package including the configuration files.

Ubuntu Cellular Modem Support (libqmi/libmbim/modemmanager)

Installing pre-built latest stable libqmi/libmbim/modemmanager via PPA

Aleksander Morgado (https://aleksander.es), a key developer behind the ModemManager, libqmi, and libmbim projects that provide modem support on Ubuntu provides up-to-date Ubuntu PPA's for Ubuntu.
Focal release:

$ sudo apt install software-properties-common # contains add-apt-repository
$ sudo add-apt-repository ppa:aleksander-m/modemmanager-focal
$ sudo apt update
$ sudo apt install modemmanager libqmi-utils libmbim-utils policykit-1

Building

How to build and install the ModemManager daemon and libraries.

For the Latest Releases

For the Releases < 17.0

ldconfig

ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified :
  • on the command line
  • in the file /etc/ld.so.conf
  • in the trusted directories
  • /lib and /usr/lib.
    On some 64-bit architectures such as x86-64,
    • /lib and /usr/lib are the trusted directories for 32-bit libraries
    • /lib64 and /usr/lib64 are used for 64-bit libraries)
FILES:
  • /lib/ld.so
  • Run-time linker/loader.
  • /etc/ld.so.conf
  • File containing a list of directories, one per line, in which to search for libraries.
  • /etc/ld.so.cache
  • File containing an ordered list of libraries found in the directories specified in /etc/ld.so.conf, as well as those found in the trusted directories.

Download the code


$ git clone https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git

Setup Build Environment

Install packages


$ sudo apt update
$ sudo apt install -y git make autoconf autoconf-archive libtool build-essential autopoint libglib2.0-dev xsltproc gtk-doc-tools libgudev-1.0-dev libmbim-glib-dev gobject-introspection

Install libmbim-glib

The current version of libmbim-glib4/libmbim-glib-dev is 1.22.0-2.
But, the latest ModemManager requires that libmbim-glib >= 1.25.4.

  • Remove the old libmbim-glib-dev
  •   
    $ sudo apt purge libmbim-glib-dev
        
  • Download the source code
  • 
    $ git clone https://gitlab.freedesktop.org/mobile-broadband/libmbim.git    
        
  • Build and install
  • 
    $ cd libmbim
    $ NOCONFIGURE=1 ./autogen.sh
    $ ./configure --prefix=/usr
    $ make
    $ sudo make install
        

Install libqmi-glib

The current version of libqmi-glib is 1.24.8-1.
But, the latest ModemManager requires that libqmi-glib >= 1.29.6.

  • Download the source code
  • 
    $ git clone https://gitlab.freedesktop.org/mobile-broadband/libqmi.git    
        
  • Build and install
  • 
    $ cd libqmi
    $ NOCONFIGURE=1 ./autogen.sh
    $ ./configure --prefix=/usr
    $ make
    $ sudo make install
        

Build ModemManager


$ cd ModemManager
$ NOCONFIGURE=1 ./autogen.sh
$ ./configure --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
$ make
$ sudo make install
If you see the configure error:

configure: error: Couldn't find libqmi-glib >= 1.28.6. Install it, or otherwise configure using --without-qmi to disable QMI support.
Check the serach path:

$ pkg-config --variable pc_path pkg-config
/usr/local/lib/x86_64-linux-gnu/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
Find the qmi-glib.pc in these paths ten investigate its content:

$ cat /usr/lib/x86_64-linux-gnu/pkgconfig/qmi-glib.pc
prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib/x86_64-linux-gnu
includedir=${prefix}/include
qmi_qrtr_supported=0
qmi_mbim_qmux_supported=1

Name: qmi-glib
Description: Library to communicate with QMI-powered modems
Version: 1.28.4
Requires: glib-2.0 gobject-2.0 gio-2.0 
Cflags: -I${includedir}/libqmi-glib
Libs: -L${libdir} -lqmi-glib
Libs.Private: -lmbim-glib -lgio-2.0 -lgobject-2.0 -lglib-2.0
Remove the incorrect .pc file then configure ModemManage again.

Remember to configure the shared library path on Ubuntu:

  • Create a file /etc/ld.so.conf.d/modem-manager.conf
  • Withe the content:
    
    /usr/lib    
        
  • configure dynamic linker run-time bindings
  • 
    $ sudo ldconfig 
        
Enable debug mode in ModemManager service, /lib/systemd/system/ModemManager.service:

...
ExecStart=/usr/sbin/ModemManager --debug
...
Reboot the system :
  • Enale and retstart the MomdemManager service
  • 
    $ sudo systemctl enable ModemManager.service
    $ sudo systemctl restart ModemManager.service  
      	
  • monitor the ModemManager:
  • 
    $ journalctl -u ModemManager -b
    	

Test on SE30


$ mmcli -V
mmcli 1.16.6

$ qmicli -V
qmicli 1.29.7

  • Request Modem and Application Firmware Versions
  • 
    $ sudo mmcli -m 0 --command='AT+qgmr'    
    response: 'EM120RGLAPR02A07M4G_13.013.13.013'
        
  • sets the level of functionality
  • 
    $ sudo mmcli -m 0 --command='AT+cfun?'  
    response: '+CFUN: 1'
        
  • query whether or not the module requires a password
  • 
    $ sudo mmcli -m 0 --command='AT+cpin?'   
    response: '+CPIN: READY'
        
  • Query
  • 
    $ sudo mmcli -m 0 --command='AT+qcfg="fcc_enable"'   
    response: '+QCFG: "fcc_enable",0'  
        

$ sudo LD_LIBRARY_PATH=/usr/local/lib ModemManager --debug
...
ModemManager[247780]: <debug> [1621778032.453754] [plugin-manager] successfully loaded 38 plugins registering 4 subsystems: tty, net, usbmisc, wwan
ModemManager[247780]: <debug> [1621778032.455336] service name 'org.freedesktop.ModemManager1' was acquired
ModemManager[247780]: <debug> [1621778032.455400] [base-manager] starting automatic device scan...
...

Run-time errors

  • "symbol lookup error: mmcli: undefined symbol: mm_sim_preferred_network_free"
  • 
    $ ModemManager -V
    ModemManager: symbol lookup error: ModemManager: undefined symbol: mm_sim_preferred_network_free   
        
    Built using ./configure but without specifying any --prefix, so ModemManager and all its libraries were installed in /usr/local.
    Ubuntu has a big problem that it doesn't give preference to /usr/local/lib when loading libraries.
    To explicitly provide LD_LIBRARY_PATH=/usr/local/lib as envvar to the commands you run can resolve this issue.
    
    $ LD_LIBRARY_PATH=/usr/local/lib ModemManager -V
    ModemManager 1.17.1
    Copyright (C) 2008-2021 The ModemManager authors
    License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
        
  • Modem manager "could not acquire the 'org.freedesktop.ModemManager1' service name"
  • ModemManager will grab the "org.freedesktop.ModemManager1" name in the system bus exposed by DBus; mmcli talks to ModemManager through that bus.
    Check if the ModemManager service is running.
    
    $ systemctl status ModemManager.service
    * ModemManager.service
         Loaded: masked (Reason: Unit ModemManager.service is masked.)
         Active: failed (Result: exit-code) since Sun 2021-05-23 16:20:31 CST; 4h 4min ago
       Main PID: 2021 (code=exited, status=127)
    
    systemd[1]: Starting Modem Manager...
    systemd[1]: ModemManager.service: Main process exited, code=exited, status=127/n/a
    systemd[1]: ModemManager.service: Failed with result 'exit-code'.
    systemd[1]: Failed to start Modem Manager.    
    $ sudo systemctl is-enabled ModemManager.service
    masked-runtime
    $ sudo systemctl enable ModemManager.service
    Failed to enable unit: Unit file /run/systemd/system/ModemManager.service is masked.
    $ file /run/systemd/system/ModemManager.service
    /run/systemd/system/ModemManager.service: symbolic link to /dev/null
    $ sudo rm /run/systemd/system/ModemManager.service
    $ sudo systemctl start ModemManager.service
    Job for ModemManager.service failed because the control process exited with error code.
    See "systemctl status ModemManager.service" and "journalctl -xe" for details.
    $ sudo ModemManager --debug
    ...
    ModemManager[11785]: <debug> [1621774381.733221] [plugin-manager] successfully loaded 38 plugins registering 4 subsystems: tty, net, usbmisc, wwan
    ModemManager[11785]: <debug> [1621774381.734131] service name 'org.freedesktop.ModemManager1' was acquired
    ModemManager[11785]: <debug> [1621774381.734162] [base-manager] starting automatic device scan...
    ModemManager[11785]: <debug> [1621774381.740998] [base-manager] finished device scan...
    ModemManager[11785]: <debug> [1621774381.741188] [ttyS0] port contents loaded:
    ModemManager[11785]: <debug> [1621774381.741220] [ttyS0]   bus: platform
    ModemManager[11785]: <debug> [1621774381.741227] [ttyS0]   device: /sys/devices/platform/serial8250
    ModemManager[11785]: <debug> [1621774381.741232] [ttyS0]   driver: serial8250
    ...
        

    After compiling ModemManager you need to copy the its dbus rule from /usr/local/etc/dbus-1/system.d/ to /etc/dbus-1/system.d/.

    
    $ sudo cp /usr/local/etc/dbus-1/system.d/org.freedesktop.ModemManager1.conf /etc/dbus-1/system.d/    
        
    If you don't do this ModemManager is unable to acquire its service name from dbus

NetworkManager

NetworkManager is a package containing a background service/daemon and a command-line-interfalce (nmcli) that can be used to configure and connect network interfaces.
It is often used in conjunction with ModemManager for Cellular modems.

  • Show version
  • 
    # nmcli --version    
        
  • Show Device Status
  • 
    # nmcli device status    
        
  • Bring down 'Wired Connection 1'
  • 
    # nmcli connection down id 'Wired connection 1'    
        
  • Add a modem
    • QMI controlled modem with an APN=h2g2 (Google Fi)
    • 
      # nmcli connection add type gsm ifname cdc-wdm0 con-name mymodem apn h2g2    
          	
    • AT controlled modem with a Verizon Dynamic IP SIM
    • 
      # nmcli connection add type gsm ifname ttyACM0 con-name mymodem apn vzwinternet
          	
  • Connect to mymodem device
  • 
    # nmcli connection up id mymodem    
        

Troubleshooting

If you find your modem's primary interface that ModemManager detects is inconsistent, you will need to modify the /etc/NetworkManager/system-connections/ file for your modem :
  • remove the interface-name= line from the [conneciton] section of your modem configuration
  • add a device-id= line to the [gsm] section that refers to the unique modem id string that ModemManager defines for the modem shown on the 2nd line output from "mmcli -m 0"
  • You can also use dbus to get the device-id:
    
    # dbus-send --print-reply --system \
       --dest=org.freedesktop.ModemManager1 \
       /org/freedesktop/ModemManager1/Modem/0 \
       org.freedesktop.DBus.Properties.Get \
       string:org.freedesktop.ModemManager1.Modem string:DeviceIdentifier    
        

Troubleshooting Modem support on Ubuntu

Make sure your modem is being recognized

A lsusb/lspci will show the Vendor ID and Product ID of your device which typically need to match known ID's in drivers.
  • USB modems
  • PCIE modems

Does your modem require a driver or driver update that is not available in the Linux kernel version you are using?

Look at the kernel messages from the dmesg command for messages that might indicate a modem is not supported or lack of a known driver supporting that device.

$ lspci | grep Wireless
2d:00.0 Wireless controller [0d40]: Foxconn International, Inc. Device e0ab

$ sudo find /sys | grep drivers | grep 0000:2d:00
/sys/bus/pci/drivers/mhi-pci-generic/0000:2d:00.0

$ ls -l /sys/class/net/mhi_mbim0/device/driver
lrwxrwxrwx 1 root root 0 Jan  1  2020 /sys/class/net/mhi_mbim0/device/driver -> ../../../../../../bus/mhi/drivers/mhi_net

$ lsmod | grep mhi
mhi_wwan_ctrl          20480  0
mhi_net                20480  0
wwan                   16384  3 mhi_wwan_ctrl
mhi_pci_generic        24576  0
mhi                    73728  3 mhi_wwan_ctrl,mhi_net,mhi_pci_generic

$ sudo LD_LIBRARY_PATH=/usr/local/lib mmcli --modem 0 | grep  -i -E ports\|driver
           |           drivers: mhi_net, mhi-pci-generic
           |             ports: mhi_mbim0 (net), wwan0p2MBIM (mbim)
Here, we see that the modem in the system is supported by the 'mhi_net' driver and the 'mhi-pci-generic' driver.
It speaks 'mbim' control protocols, and it uses the 'mhi_mbim0' network device for data.


ModemManager[1668]:  [wwan0] port contents loaded:
ModemManager[1668]:  [wwan0]   bus: pci
ModemManager[1668]:  [wwan0]   device: /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0
ModemManager[1668]:  [wwan0]   driver: mhi-pci-generic
ModemManager[1668]: [wwan0]   vendor: 105b
ModemManager[1668]:  [wwan0]   product: e0ab
ModemManager[1668]:  [base-manager] adding port wwan0 at sysfs path: /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0/mhi0/wwan/wwan0
ModemManager[1668]:  [filter] (wwan/wwan0) port allowed: device is whitelisted by plugin (vid)
ModemManager[1668]:  [base-manager] additional port wwan0 in device /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0
ModemManager[1668]:  [plugin-manager] task 0: port grabbed: wwan0
ModemManager[1668]:  [plugin-manager] task 0,wwan0: new support task for port
ModemManager[1668]:  [plugin-manager] task 0,wwan0: deferred until min wait time elapsed
ModemManager[1668]:  [wwan0p1QCDM] port contents loaded:
ModemManager[1668]:  [wwan0p1QCDM]   bus: pci
ModemManager[1668]:  [wwan0p1QCDM]   device: /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0
ModemManager[1668]:  [wwan0p1QCDM]   driver: mhi-pci-generic
ModemManager[1668]:  [wwan0p1QCDM]   vendor: 105b
ModemManager[1668]:  [wwan0p1QCDM]   product: e0ab
ModemManager[1668]:  [base-manager] adding port wwan0p1QCDM at sysfs path: /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0/mhi0/wwan/wwan0/wwan0p1QCDM
ModemManager[1668]:  [filter] (wwan/wwan0p1QCDM) port allowed: device is whitelisted by plugin (vid)
ModemManager[1668]:  [base-manager] additional port wwan0p1QCDM in device /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0
ModemManager[1668]:  [plugin-manager] task 0: port grabbed: wwan0p1QCDM
ModemManager[1668]:  [plugin-manager] task 0,wwan0p1QCDM: new support task for port
ModemManager[1668]:  [plugin-manager] task 0,wwan0p1QCDM: deferred until min wait time elapsed
ModemManager[1668]:  [wwan0p2MBIM] port contents loaded:
ModemManager[1668]:  [wwan0p2MBIM]   bus: pci
ModemManager[1668]:  [wwan0p2MBIM]   device: /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0
ModemManager[1668]:  [wwan0p2MBIM]   driver: mhi-pci-generic
ModemManager[1668]:  [wwan0p2MBIM]   vendor: 105b
ModemManager[1668]:  [wwan0p2MBIM]   product: e0ab
ModemManager[1668]:  [base-manager] adding port wwan0p2MBIM at sysfs path: /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0/mhi0/wwan/wwan0/wwan0p2MBIM
ModemManager[1668]:  [filter] (wwan/wwan0p2MBIM) port allowed: device is whitelisted by plugin (vid)
ModemManager[1668]:  [base-manager] additional port wwan0p2MBIM in device /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0
ModemManager[1668]:  [plugin-manager] task 0: port grabbed: wwan0p2MBIM
ModemManager[1668]:  [plugin-manager] task 0,wwan0p2MBIM: new support task for port
ModemManager[1668]:  [plugin-manager] task 0,wwan0p2MBIM: deferred until min wait time elapsed
ModemManager[1668]:  [plugin-manager] task 0: min wait time elapsed
...
ModemManager[1668]:  [plugin-manager] task 0,wwan0p2MBIM: checking with plugin 'foxconn'
ModemManager[1668]:  [plugin/foxconn] probes required for port wwan0p2MBIM: 'at, qcdm, qmi, mbim'
ModemManager[1668]:  [wwan0p2MBIM/probe] no AT/QCDM/QMI probing in possible MBIM port
ModemManager[1668]:  [wwan0p2MBIM/probe] port is not AT-capable
ModemManager[1668]:  [wwan0p2MBIM/probe] port is not QCDM-capable
ModemManager[1668]:  [wwan0p2MBIM/probe] port is not QMI-capable
ModemManager[1668]:  [wwan0p2MBIM/probe] launching port probing: 'mbim'
...
ModemManager[1668]:  [plugin-manager] task 0,wwan0p1QCDM: checking with plugin 'foxconn'
ModemManager[1668]:  [plugin/foxconn] probes required for port wwan0p1QCDM: 'at, qcdm, qmi, mbim'
ModemManager[1668]:  [wwan0p1QCDM/probe] no AT/QMI/MBIM probing in possible QCDM port
ModemManager[1668]:  [wwan0p1QCDM/probe] port is not AT-capable
ModemManager[1668]:  [wwan0p1QCDM/probe] port is not QMI-capable
ModemManager[1668]:  [wwan0p1QCDM/probe] port is not MBIM-capable
ModemManager[1668]:  [wwan0p1QCDM/probe] launching port probing: 'qcdm'
...
ModemManager[1668]:  [plugin-manager] task 0,wwan0: checking with plugin 'foxconn'
ModemManager[1668]:  [plugin/foxconn] probes required for port wwan0: 'at, qcdm, qmi, mbim'
ModemManager[1668]:  [wwan0/probe] launching port probing: 'at, qcdm, qmi, mbim'
...
ModemManager[1668]:  [plugin-manager] task 0,mhi_mbim0: checking with plugin 'foxconn'
ModemManager[1668]:  [plugin/foxconn] probing of port mhi_mbim0 deferred until result suggested
ModemManager[1668]:  [plugin-manager] task 1: min wait time elapsed
...
ModemManager[1668]:  [plugin-manager] task 0: still 4 running probes (4 active): wwan0p2MBIM, wwan0p1QCDM, wwan0, mhi_mbim0
...
ModemManager[1668]:  [wwan0p2MBIM/probe] probing MBIM...
ModemManager[1668]:  [wwan0p1QCDM/probe] probing QCDM...
ModemManager[1668]:  [wwan0p1QCDM/qcdm] opening serial port...
ModemManager[1668]:  [wwan0p1QCDM/qcdm] failed to configure serial device
ModemManager[1668]:  [wwan0p1QCDM/qcdm] failed to open serial device
ModemManager[1668]:  [plugin-manager] task 0,wwan0p1QCDM: error when checking support with plugin 'foxconn': (wwan/wwan0p1QCDM) Failed to open QCDM port: Failed to open QCDM port: -2
ModemManager[1668]:  [plugin-manager] task 0,wwan0p1QCDM: checking with plugin 'generic'
ModemManager[1668]:  [plugin/generic] probes required for port wwan0p1QCDM: 'at, qcdm, qmi, mbim'
ModemManager[1668]:  [wwan0p1QCDM/probe] no AT/QMI/MBIM probing in possible QCDM port
ModemManager[1668]:  [wwan0p1QCDM/probe] port is not AT-capable
ModemManager[1668]:  [wwan0p1QCDM/probe] port is not QMI-capable
ModemManager[1668]:  [wwan0p1QCDM/probe] port is not MBIM-capable
ModemManager[1668]:  [wwan0p1QCDM/probe] launching port probing: 'qcdm'
ModemManager[1668]:  [wwan0p1QCDM/qcdm] forced to close port
ModemManager[1668]:  [wwan0/at] opening serial port...
ModemManager[1668]:  [plugin-manager] task 0,wwan0: error when checking support with plugin 'foxconn': (wwan/wwan0) failed to open port: Could not open serial device wwan0: No such file or directory
ModemManager[1668]:  [plugin-manager] task 0,wwan0: checking with plugin 'generic'
ModemManager[1668]:  [plugin/generic] probes required for port wwan0: 'at, qcdm, qmi, mbim'
ModemManager[1668]:  [wwan0/probe] launching port probing: 'at, qcdm, qmi, mbim'
ModemManager[1668]:  [wwan0/at] forced to close port
ModemManager[1668]: opening device...
ModemManager[1668]: [/dev/wwan0p2MBIM] Couldn't find descriptors file, possibly not using cdc_mbim
ModemManager[1668]: [/dev/wwan0p2MBIM] Fallback to default max control message size: 4096
ModemManager[1668]: [/dev/wwan0p2MBIM] Sent message...
ModemManager[1668]: [/dev/wwan0p2MBIM] Sent message (translated)...
 Header:
   length      = 92
   type        = command (0x00000003)
   transaction = 1
 Fragment header:
  total   = 1
  current = 0
 Contents:
   service = 'proxy-control' (838cf7fb-8d0d-4d7f-871e-d71dbefbb39b)
   cid     = 'configuration' (0x00000001)
   type    = 'set' (0x00000001)
 Fields:
   DevicePath = '/dev/wwan0p2MBIM'
   Timeout = '30'
...
ModemManager[1668]:  [plugin-manager] task 0,wwan0p2MBIM: found best plugin for port (foxconn)
ModemManager[1668]:  [plugin-manager] task 0,wwan0p2MBIM: finished in '1.648350' seconds
ModemManager[1668]:  [plugin-manager] task 0,wwan0p2MBIM: found best plugin: foxconn
ModemManager[1668]:  [plugin-manager] task 0,mhi_mbim0: deferred task completed, got suggested plugin (foxconn)
...
ModemManager[1668]:   [1622019182.201676] [device /sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0] creating modem with plugin 'foxconn' and '2' ports
ModemManager[1668]:  [plugin/foxconn] (foxconn) MBIM-powered Foxconn-branded modem found...
ModemManager[1668]:  [modem0] port 'wwan/wwan0p2MBIM' grabbed
ModemManager[1668]:  [modem0] port 'net/mhi_mbim0' grabbed
ModemManager[1668]:  [modem0] net/mhi_mbim0 net (data)
ModemManager[1668]:  [modem0] wwan/wwan0p2MBIM mbim
ModemManager[1668]:  [modem0] running MBIM port 'wwan0p2MBIM' reset with data interface 'mhi_mbim0'
ModemManager[1668]:  [base-manager] modem for device '/sys/devices/pci0000:00/0000:00:1c.0/0000:2d:00.0' successfully created
...
ModemManager[1668]:  [modem0] couldn't setup SIM hot swap using QMI over MBIM: Couldn't peek client for service 'uim'
ModemManager[1668]:  [modem0] SIM hot swap setup succeeded
ModemManager[1668]:  [modem0] couldn't query SIM slots: Couldn't peek client for service 'uim'
...
ModemManager[1668]:  couldn't check if unlock required: SIM failure
ModemManager[1668]:  [modem0] state changed (unknown -> locked)
ModemManager[1668]:  [modem0] modem couldn't be initialized: Couldn't check unlock status: SIM failure
ModemManager[1668]:  [modem0] state changed (locked -> failed)
ModemManager[1668]:  [modem0] voice support check failed: No AT port available to run command
ModemManager[1668]:  [modem0] couldn't initialize interface: 'Voice not supported'
...
ModemManager[1668]:  [modem0] creating ports context for SIM hot swap
ModemManager[1668]:  couldn't open ports during Modem SIM hot swap enabling: Couldn't get primary port
ModemManager[1668]:  SIM is missing and SIM hot swap is configured, but ports are not opened.
ModemManager[1668]:  couldn't finish initialization in the current state: 'Modem is unusable, cannot fully initialize'
The above did not get the SIM detected, which is what the modem is reporting.

$ nmcli d
DEVICE           TYPE      STATE         CONNECTION                        
wwan0p2MBIM      gsm       unavailable   --    

$ sudo nmcli d connect wwan0p2MBIM
Error: Failed to add/activate new connection: Connection 'wwan0p2MBIM' is not available on device wwan0p2MBIM because device is not available

Most modem drivers will create a number of 'tty' devices in /dev/tty* - if you see no messages about this you may be missing driver support.

Is your GSM module locked to a Carrier/Network? SIM/PIN?

If so, you have to unlock it (if possible/allowed).

Can you not send AT commands to a card?

Have you specified the correct APN for your GSM module?

Your carrier can provide you with the proper APN

Are you using the correct serial device?

Most modules provide several, not all of which can be used with pppd/chat/gcom

Is your CDMA/EVDO module 'activated'?

You may need to do this on a Windows system with vendor-supplied application/drivers.

Issue a reset command to the card when starting up (varies by card)


[ -e /dev/ttyUSBX ] && echo -e -n "AT~RESET\r" > /dev/ttyUSBX

There cannot be two routes to the internet.

Only one interface in the routing table can connect to the internet.
Thus, it can be important to check other interfaces, such as eth0, and ensure they are not configured to connect to a WAN / or to a gateway.

Use a serial COM program o connect to the modem's control port and issue AT commands directly

  • AT+CREG?
  • will return your network registration state:
    • 0 - registered to home network
    • 1 - roaming
    • -1 not registered
  • AT+COPS?
  • will return the operator selection:
    
      mode[,format,operator
      

Post-installation issues


$ sudo mmcli -L
error: couldn't find the ModemManager process in the bus
$ sudo systemctl enable ModemManager.service
Failed to enable unit: Unit file /run/systemd/system/ModemManager.service is masked.
$ file /run/systemd/system/ModemManager.service
/run/systemd/system/ModemManager.service: symbolic link to /dev/null
$ sudo rm /run/systemd/system/ModemManager.service
$ sudo systemctl restart ModemManager.service
Failed to restart ModemManager.service: Unit ModemManager.service is masked.
$ file /run/systemd/system/ModemManager.service
/run/systemd/system/ModemManager.service: cannot open `/run/systemd/system/ModemManager.service' (No such file or directory)
$ sudo systemctl enable ModemManager.service
$ sudo systemctl restart ModemManager.service

MHI (Modem Host Interface)

MHI is a protocol developed by Qualcomm Innovation Center, Inc.
It is used by the host processors to control and communicate with modem devices over high speed peripheral buses or shared memory.
Even though MHI can be easily adapted to any peripheral buses, it is primarily used with PCIe based devices.
MHI provides logical channels over the physical buses and allows transporting the modem protocols, such as IP data packets, modem control messages, and diagnostics over at least one of those logical channels.

bus: mhi: Add MHI PCI support for WWAN modems

This is a generic MHI-over-PCI controller driver for MHI only devices such as QCOM modems.
For now it supports registering of Qualcomm SDX55 based PCIe modules.
The MHI channels have been extracted from mhi downstream driver.

This driver is for MHI-only devices which have all functionalities exposed through MHI channels and accessed by the corresponding MHI device drivers (no out-of-band communication).

Add MHI/WWAN support

The MHI support for control channels/ports has recently been merged in Linux along with a new 'wwan subsystem'.
The wwan subsystem handles wwan devices (e.g. /sys/class/wwan/wan0) and related ports (e.g. /sys/class/wwan/wwan0p1MBIM...).

$ ls -l /sys/class/wwan
lrwxrwxrwx 1 root root 0  四   2  2020 wwan0 -> ../../devices/pci0000:00/0000:00:1c.0/0000:2d:00.0/mhi0/wwan/wwan0
lrwxrwxrwx 1 root root 0  四   2  2020 wwan0p1QCDM -> ../../devices/pci0000:00/0000:00:1c.0/0000:2d:00.0/mhi0/wwan/wwan0/wwan0p1QCDM
lrwxrwxrwx 1 root root 0  四   2  2020 wwan0p2MBIM -> ../../devices/pci0000:00/0000:00:1c.0/0000:2d:00.0/mhi0/wwan/wwan0/wwan0p2MBIM
Each WWAN control port is exposed as a character device for usermode access to control protocols (QMI, MBIM, AT...), and so can be used by ModemManager as standard modem port.

On the other side mhi_net is the driver for the network data path, exposed as a standard netdev.
The mhi_net netdev exposes either as a IP/QMAP(rmnet) interface (e.g. mhi_hwip0) or a MBIM interface (e.g mhi_mbim0).

  • In the case of IP/QMAP, the netdev can be used either to transport raw IP data (no aggregation protocol) or QMAP data (and so needs extra upper rmnet link/netdev to be configured).
  • In case of MBIM, interface is exposing raw IP and MBIM protocol is directly handled inside mhi_net driver. Since it's a simplified version of MBIM. multiplexing is not yet supported, and all data received by mhi_mbim0 is directed to session 0.

Using NetworkManager and ModemManager in Linux to automatically establish and maintain a connection

How to use NetworkManager and ModemManager in Linux to automatically establish and maintain a cellular data connection?

NetworkManager and ModemManager are open source tool for Linux to manage several types of networks and interfaces such as ethernet, wifi, etc. It can also manage cellular WWAN interfaces through the ModemManager tool.

Check on Ubuntu 20.04:

  
$ NetworkManager -V
1.22.10
$ ModemManager -V
ModemManager 1.12.8
$ ModemManager --debug
...
ModemManager[2630]: <debug> [1621771580.373388] [plugin manager] successfully loaded 35 plugins
ModemManager[2630]: <warn>  [1621771580.373784] Could not acquire the 'org.freedesktop.ModemManager1' service name
ModemManager[2630]: <debug> [1621771580.373813] Stopping connection in object manager server
ModemManager[2630]: <info>  [1621771580.374477] ModemManager is shut down
ModemManager[2630]: <debug> [1621771580.374548] disposing MMSleepMonitor singleton (0x55efb1d2f750)
Both NetworkManager and ModemManager have command line interfaces (nmcli and mmcli respectively) where you can interact with the management tools.

ModemManager is capable of communicating over several types of device control channels such as QMI/RMNET, MBIM, MODEM / AT command etc.
But support for vendor proprietary or out-of-kernel drivers are limited.

  • Scan modem
  • ModemManager normally listen, probes and detects cellular devices automatically when operating correctly but a forced scan can be triggered with command:
    
    $ mmcli --scan-modems
    	
  • List all the cellular device ModemManager has detected
  • Finding the index number of a modem (The modem index frequently changes during a suspend-resume cycle):
    
    $ mmcli -L
        /org/freedesktop/ModemManager1/Modem/0 [foxconn] Qualcomm Snapdragon X55 5G
        
  • To acquire more device information and status
  • 
    $ mmcli --modem=0    
        
  • If the device status indicates that inserted SIM card is PIN locked
  • 
    $ mmcli --modem=0 --sim=0 --pin=**** 
        
  • Enable the modem
  • 
    $ mmcli --modem=0 --enable
    	
  • activate the data connection
  • 
    $ mmcli -m 0 --simple-connect='apn=data.tre.se,ip-type=ipv4v6'
    	
  • Set logging level
  • to maximium
    
    $ mmcli-G DEBUG
    	
    to minimium
    
    $ mmcli-G ERR
    	
  • AT commands are available if ModemManager is started with the --debug flag
  • This is a good test command to see if ModemManager is speaking to the modem.
    You can check /var/log/messages for the message exchange if you've previously turned up the logging level to maximum.
    
      
      	
ModemManager does not assign IPv4 address details to the cellular modules network interface in Linux .
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.

Use NetworkManager to check

  • Check that the cellular device is managed by NetworkManager
  • 
    $ nmcli device status    
        
  • Create a connection profile in NetworkManager for your specific network carrier and SIM card
  • 
    $ nmcli connection add type gsm ifname '*' con-name '3-sweden' apn 'data.tre.se' connection.autoconnect yes gsm.pin 0000  
        
    • type
    • is gsm for all typical cellular connections unless it is of cdma type.
    • ifname
    • is the control interface name, in this case cdc-wdm0, wildcard can be used also to have it autoselect.
    • con-name
    • is the profile name you want to give it.
    • apn
    • is provided by your network carrier and tells the modem what attach point it should use for the data connection.
    • connection.autoconnect
    • set to yes will make NetworkManager always try to auto connect and maintain this profile connection.
    • gsm.pin
    • lets you provide a pin code for the SIM card, that NetworkManager will try to use if PIN check is enabled for SIM card.
    There are several additional commands and attributes available such as username and password settings for the APNs etc.
  • list the current status
  • 
    $ nmcli radio
    	
  • 
    $ nmcli device show device_name
    	
  • 
    $ nmcli connection show
    	

mmcli – Control and monitor the ModemManager

Send the PIN to the SIM card

Find out the proper path/index is for the SIM in your modem:

$ mmcli -m 0 | grep SIM
SIM | path: '/org/freedesktop/ModemManager1/SIM/0'
Use the SIM index to configure the PIN:

$ mmcli -i 0 --pin=1234
successfully sent PIN code to the SIM

Simple connect and disconnect

Launch the simple connection process

$ mmcli -m 0 --simple-connect="pin=1234,apn=internet"
successfully connected the modem
Disconnect

$ mmcli -m 0 --simple-disconnect
successfully disconnected all bearers in the modem

How-to guide: control and set up a data connection in Linux using ModemManager as connection manager?

Cellular Modems (GSM/GPRS/EDGE/UMTS/HSPA/LTE)

cdc_mbim - Driver for CDC MBIM Mobile Broadband modems

(QMI)

QMI is a binary protocol designed to replace the AT command based communication with modems, and is available in devices with Qualcomm chipsets from multiple vendors (Novatel, Huawei, Sierra Wireless, ZTE… and of course Qualcomm itself).

An introduction to libqmi

The protocol defines different ‘services‘, each of them related to different actions that may be requested to the modem.
For example,
  • the ‘DMS’ (Device Management) service provides actions to load device information
  • the ‘NAS’ (Network Access) service provides actions to register in the network
Similarly, other services will allow the user to request data connections (WDS), setup GPS location reporting (PDS), or manage internals of the user identity module (UIM service).
The user needs to handle the creation of ‘clients’ for those services by allocating/deallocating ‘client IDs’ using the generic always-on ‘control’ (CTL) service.

libqmi

libqmi is a glib-based library for talking to WWAN modems and devices which speak the Qualcomm MSM Interface (QMI) protocol. QMI is a binary protocol designed to replace the AT command based communication with modems, and is available in devices with Qualcomm chipsets from multiple vendors.
The protocol defines different ‘services‘, each of them related to different actions that may be requested to the modem.

Each service in the protocol defines ‘Request and Responses‘ as well as ‘Indications‘.

  • Each pair of request/response has a maching ID which lets the user concatenate multiple requests and get out-of-order responses that can be afterwards matched through the common ID.
  • Indications arrive as unsolicited messages, sent either to a specific client or as a broadcast message to all the clients of a given service. Usually the user needs to request the enabling of the indications to receive via some request/response.

Using the QMI protocol

This protocol is implemented in recent enough Linux kernels (>= 3.4) and can be accessible through the cdc-wdm and qmi_wwan drivers.

$ lsmod | grep wan
qmi_wwan               36864  0
cdc_wdm                24576  2 qmi_wwan
usbnet                 49152  1 qmi_wwan
usb_wwan               24576  1 option
usbserial              57344  8 usb_wwan,option
Once these drivers are in place and the modem gets plugged in, the kernel will expose a new /dev/cdc-wdm device which can talk QMI protocol, along with a wwan interface associated to each QMI port.

libqmi is a library providing easy access to Qualcomm’s ‘QMI’ protocol.
qmicli is used as a developer tool for testing the libqmi-glib library.
The project also comes with a small bash script called ‘qmi-network‘, which allows you to launch a broadband connection using libqmi-glib and qmicli.
This script requires two arguments;

  1. the cdc-wdm device to talk to
  2. the action (start|stop|status) to execute

Usin QMI commands directly

QMI(Qualcomm MSM Interface,官方名稱應該是Qualcomm Message Interface)是高通用來替代OneRPC/DM的協議,用來與modem通信。

QMI協議定義了多個服務:

  • DMS(設備管理Device Management)
  • 提供載入 設備信息的功能
  • NAS(網絡訪問Network Access)
  • 提供歐冠你註冊網絡的動作
  • WDS(數據連接)
  • PDS(GPS定位報告)
  • UIM(管理User Identity Module)
  • CTL(控制服務
  • 發起其他服務請求前,必須先申請 ClientID, 這個ID就是由控制服務分配的, 這個服務永遠在線)
協議裏的每個服務都定義了請求和響應(也叫做 Indication), 每個請求響應都有一個匹配的ID,這樣用戶可以一次發出多個請求。並且響應也不必嚴格按照請求的順序進行回應。

If not using a higher level manager which utilizes libqmi such as ModemManager, you can use libqmi directly (make sure ModemManager is not installed or running!).

How to step by step set up a data connection over QMI interface using qmicli and in-kernel driver qmi_wwan in Linux?

Several cellular modules based on Qualcomm chipsets implements the Qualcomm Qualcomm MSM (QMI) Interface.
There is a open source Linux in-kernel driver supporting this interface and it is called qmi_wwan.
This driver can be used together with ModemManager and NetworkManager to automate connection establishment and as a connection manager.

The library libqmi which ModemManager uses can also be used to communicate in a more direct way with the cellular devices over the QMI interface and to step by step do necessary configurations and trigger the data connection over the cellular netwowk.

Example on how to set up the data connection step by step manually with libqmi:

  • Install the libqmi Linux library
  • Verify that you have the Linux in-kernel qmi_wwan driver installed and attached for the cellular modules QMI interface over USB
  • 
    $ lsusb -t
    Can look e.g. like this:
    ...
    |__ Port 1: Dev 3, If 2, Class=Vendor Specific Class, Driver=qmi_wwan, 480M
    ...
        	
    If the driver is not correctly loaded, please verify that the module is set to expose the correct USB endpoints configuration on the target system.
  • Use qmicli to control the modem
  • The cellular modules QMI control interface are usually named cdc-wdm*.

QMICLI man page


qmicli [OPTION?]

Help Options

DMS options


$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --dms-get-manufacturer     
[/dev/wwan0p2MBIM] Device manufacturer retrieved:
	Manufacturer: 'Qualcomm'

$ sudo qmicli --device=/dev/wwan0p2MBIM --device-open-proxy --dms-get-manufacturer
[/dev/wwan0p2MBIM] Device manufacturer retrieved:
	Manufacturer: 'Qualcomm'

$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --dms-get-model       
[/dev/wwan0p2MBIM] Device model retrieved:
	Model: 'Qualcomm Snapdragon X55 5G'
    
$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --dms-get-revision
[/dev/wwan0p2MBIM] Device revision retrieved:
	Revision: 'T99W175.F0.0.0.5.5.GC.004
066  1  [Sep 11 2020 11:00:00]'

$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --dms-get-hardware-revision
[/dev/wwan0p2MBIM] Hardware revision retrieved:
	Revision: 'V065'
    
$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --dms-get-software-version 
[/dev/wwan0p2MBIM] Software version: T99W175.F0.0.0.5.5

$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --dms-get-power-state     
[/dev/wwan0p2MBIM] Device power state retrieved:
	Power state: 'external-source'
	Battery level: '0 %'

$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --dms-get-operating-mode
[/dev/wwan0p2MBIM] Operating mode retrieved:
	Mode: 'online'
	HW restricted: 'no'
    
$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --nas-get-technology-preference
[/dev/wwan0p2MBIM] Successfully got technology preference
	Active: 'auto', duration: 'permanent'
    
$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --dms-get-band-capabilities
[/dev/wwan0p2MBIM] Device band capabilities retrieved:
	Bands: 'wcdma-2100, wcdma-pcs-1900, wcdma-dcs-1800, wcdma-1700-us, wcdma-850-us, wcdma-800, wcdma-900, wcdma-1700-japan, wcdma-850-japan'
	LTE bands: '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42'
	LTE bands (extended): '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42, 46, 48, 66, 71'

$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --nas-get-system-selection-preference
[/dev/wwan0p2MBIM] Successfully got system selection preference
	Emergency mode: 'no'
	Mode preference: '5gnr'
	Disabled modes: '(null)'
	Band preference: 'wcdma-2100, wcdma-pcs-1900, wcdma-1700-us, wcdma-850-us, wcdma-800, wcdma-900, wcdma-1700-japan, wcdma-850-japan'
	LTE band preference: '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42'
	LTE band preference (extended): '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42, 46, 48, 66, 71'
	TD-SCDMA band preference: 'a, b, c, d, e, f'
	Roaming preference: 'any'
	Network selection preference: 'automatic'
	Service domain preference: 'ps-only'
	GSM/WCDMA acquisition order preference: 'automatic'
	Usage preference: 'data-centric'
	Voice domain preference: 'ps-preferred'
	Registration restriction: 'unrestricted'
	Acquisition order preference: 'umts, lte'

$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --nas-get-cell-location-info         
error: couldn't get cell location info: QMI protocol error (13): 'NoNetworkFound'

$ sudo qmicli --device=/dev/wwan0p2MBIM -p --device-open-proxy --nas-get-operator-name     
error: couldn't get operator name data: QMI protocol error (74): 'InformationUnavailable'



NAS options



WDS options


$ sudo qmicli --device=/dev/wwan0p2MBIM -p --wds-get-profile-list=3gpp
Profile list retrieved:
	[1] 3gpp - profile1
		APN: ''
		PDP type: 'ipv4-or-ipv6'
		PDP context number: '1'
		Username: ''
		Password: ''
		Auth: 'none'
		No roaming: 'no'
		APN disabled: 'no'
        

PBM options

PDC options

UIM options

  • --uim-get-slot-status
  • Get slot status
    
        
        
  • --uim-switch-slot=,[/(slot number)]
  • Switch active physical slot
    
        
        

SAR options

WMS options

WDA options

VOICE options

LOC options

QoS options

GAS options

GMS options

DSD options

Ling management options

qmi_wwan specific options

Application Options

  • SIM details (UIM service)
  • 
    $ sudo qmicli --device=/dev/wwan0p2MBIM --device-open-proxy --uim-get-card-status
    [/dev/wwan0p2MBIM] Successfully got card status
    Provisioning applications:
    	Primary GW:   slot '1', application '1'
    	Primary 1X:   session doesn't exist
    	Secondary GW: session doesn't exist
    	Secondary 1X: session doesn't exist
    Slot [1]:
    	Card state: 'present'
    	UPIN state: 'not-initialized'
    		UPIN retries: '0'
    		UPUK retries: '0'
    	Application [1]:
    		Application type:  'usim (2)'
    		Application state: 'ready'
    		Application ID:
    			A0:00:00:00:87:10:02:FF:49:FF:FF:89:04:0B:00:FF
    		Personalization state: 'ready'
    		UPIN replaces PIN1: 'no'
    		PIN1 state: 'disabled'
    			PIN1 retries: '3'
    			PUK1 retries: '10'
    		PIN2 state: 'enabled-not-verified'
    			PIN2 retries: '3'
    			PUK2 retries: '10'
    
        
  • Signal strength
  • 
    # qmicli -d /dev/cdc-wdm0 --nas-get-signal-info  
    # qmicli -d /dev/cdc-wdm0 --nas-get-signal-strength
        
  • Network details (NAS service)
  • 
    $ sudo qmicli --device=/dev/wwan0p2MBIM -p --nas-get-system-selection-preference
    [/dev/wwan0p2MBIM] Successfully got system selection preference
    	Emergency mode: 'no'
    	Mode preference: '5gnr'
    	Disabled modes: '(null)'
    	Band preference: 'wcdma-2100, wcdma-pcs-1900, wcdma-1700-us, wcdma-850-us, wcdma-800, wcdma-900, wcdma-1700-japan, wcdma-850-japan'
    	LTE band preference: '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42'
    	LTE band preference (extended): '1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42, 46, 48, 66, 71'
    	TD-SCDMA band preference: 'a, b, c, d, e, f'
    	Roaming preference: 'any'
    	Network selection preference: 'automatic'
    	Service domain preference: 'ps-only'
    	GSM/WCDMA acquisition order preference: 'automatic'
    	Usage preference: 'data-centric'
    	Voice domain preference: 'ps-preferred'
    	Registration restriction: 'unrestricted'
    	Acquisition order preference: 'umts, lte'
    
    
    $ sudo qmicli --device=/dev/wwan0p2MBIM -p --nas-network-scan                   
    [/dev/wwan0p2MBIM] Successfully scanned networks
    Network [0]:
    	MCC: '466'
    	MNC: '92'
    	Status: 'available, home, not-forbidden, preferred'
    	Description: 'Chunghwa'
    Network [1]:
    	MCC: '466'
    	MNC: '92'
    	Status: 'available, home, not-forbidden, preferred'
    	Description: 'Chunghwa'
    Network [2]:
    	MCC: '466'
    	MNC: '97'
    	Status: 'available, roaming, not-forbidden, not-preferred'
    	Description: 'TWM'
    Network [3]:
    	MCC: '466'
    	MNC: '89'
    	Status: 'available, roaming, not-forbidden, not-preferred'
    	Description: 'T Star'
    Network [4]:
    	MCC: '466'
    	MNC: '1'
    	Status: 'available, roaming, not-forbidden, not-preferred'
    	Description: 'FET'
    Network [5]:
    	MCC: '466'
    	MNC: '12'
    	Status: 'available, roaming, not-forbidden, not-preferred'
    	Description: 'APT'
    Network [6]:
    	MCC: '466'
    	MNC: '97'
    	Status: 'available, roaming, not-forbidden, not-preferred'
    	Description: 'TWM'
    Network [7]:
    	MCC: '466'
    	MNC: '89'
    	Status: 'available, roaming, not-forbidden, not-preferred'
    	Description: 'T Star'
    Network [8]:
    	MCC: '466'
    	MNC: '5'
    	Status: 'available, roaming, not-forbidden, not-preferred'
    	Description: 'APT'
    Network [0]:
    	MCC: '466'
    	MNC: '92'
    	RAT: 'umts'
    Network [1]:
    	MCC: '466'
    	MNC: '92'
    	RAT: 'lte'
    Network [2]:
    	MCC: '466'
    	MNC: '97'
    	RAT: 'lte'
    Network [3]:
    	MCC: '466'
    	MNC: '89'
    	RAT: 'umts'
    Network [4]:
    	MCC: '466'
    	MNC: '1'
    	RAT: 'lte'
    Network [5]:
    	MCC: '466'
    	MNC: '12'
    	RAT: 'lte'
    Network [6]:
    	MCC: '466'
    	MNC: '97'
    	RAT: 'umts'
    Network [7]:
    	MCC: '466'
    	MNC: '89'
    	RAT: 'lte'
    Network [8]:
    	MCC: '466'
    	MNC: '5'
    	RAT: 'lte'
    Network [0]:
    	MCC: '466'
    	MNC: '92'
    	MCC with PCS digit: 'no'
    Network [1]:
    	MCC: '466'
    	MNC: '92'
    	MCC with PCS digit: 'no'
    Network [2]:
    	MCC: '466'
    	MNC: '97'
    	MCC with PCS digit: 'no'
    Network [3]:
    	MCC: '466'
    	MNC: '89'
    	MCC with PCS digit: 'no'
    Network [4]:
    	MCC: '466'
    	MNC: '1'
    	MCC with PCS digit: 'no'
    Network [5]:
    	MCC: '466'
    	MNC: '12'
    	MCC with PCS digit: 'no'
    Network [6]:
    	MCC: '466'
    	MNC: '97'
    	MCC with PCS digit: 'no'
    Network [7]:
    	MCC: '466'
    	MNC: '89'
    	MCC with PCS digit: 'no'
    Network [8]:
    	MCC: '466'
    	MNC: '5'
    	MCC with PCS digit: 'no'
    Network scan result: success
    
    
    $ sudo qmicli --device=/dev/wwan0p2MBIM -p --nas-get-serving-system
    [/dev/wwan0p2MBIM] Successfully got serving system:
    	Registration state: 'not-registered'
    	CS: 'detached'
    	PS: 'detached'
    	Selected network: 'unknown'
    	Radio interfaces: '1'
    		[0]: 'none'
    	Data service capabilities: '0'
    	Detailed status:
    		Status: 'power-save'
    		Capability: 'none'
    		HDR Status: 'none'
    		HDR Hybrid: 'no'
    		Forbidden: 'no'
    
    
    $ sudo qmicli --device=/dev/wwan0p2MBIM -p --nas-get-system-info     
    [/dev/wwan0p2MBIM] Successfully got system info:
    	WCDMA service:
    		Status: 'power-save'
    		True Status: 'none'
    		Preferred data path: 'no'
    	LTE service:
    		Status: 'power-save'
    		True Status: 'none'
    		Preferred data path: 'no'
    		Registration restriction: 'unrestricted'
    	SIM reject info: 'available'
    
    # qmicli -d /dev/cdc-wdm0 --nas-get-home-network
    # qmicli -d /dev/cdc-wdm0 --nas-get-operator-name
    
        
  • Configure Link Protocol
  • QMI modems support multiple link protocols:
    • 802.3
    • wraps IP packets within Ethernet frames (similar to an Ethernet device) like traditional modems
    • raw-ip
    • does away with the Ethernet layer and provides raw IP frames which is more efficient and allows higher throughput, but disallows things that rely on 802-3 such as DHCP
    Make sure you choose a link protocol (802-3 or raw-ip) that is compatible with your modem/firmware/SIM.
    
    # qmicli -p -d /dev/cdc-wdm0 --wda-set-data-format=802-3 # set data format (raw-ip/802-3)
    # qmicli -p -d /dev/cdc-wdm0 --set-expected-data-format=802-3 # set expected format, should match above    
        
  • Connect to Google Fi network (WDS service)
  • 
    # echo "APN=h2g2" > /etc/qmi-network.conf # specify APN
    # echo "PROXY=yes" >> /etc/qmi-network.conf # allow ports to be shared by multiple libqmi apps
    # qmi-network /dev/cdc-wdm0 start    
        
  • Configuring IP
  • If your modem/firmware/SIM combination supports 802.3 link protocol and is configured to do so, you can use DHCP to get IP automatically:
    
    # dhclient wwan0    
        
    Or, you can use -wds-get-current-settings to obtain the IP settings provided to the conneciton from the carrier then configure them manually.
    
    # qmicli --device /dev/cdc-wdm0 --client-no-release-cid --client-cid=ClientID --wds-get-current-settings
    	
    To use QMI services you need a 'Client ID' or CID. The CID's can be created then released when they are no longer needed.
  • Show firmware versions
  • 
    # qmicli -d /dev/cdc-wdm0 --dms-get-firmware-preference    
        
  • update firmware
  • 
    # qmi-firmware-update --update -d 1199:68c0 9999999_9902196_SWI9X15C_05.05.58.00_00_ATT_005.026_000-field.spk    
        

libqmi-glib

Linux Mobile Broadband Interface Model (MBIM)

Linux kernel 3.8 comes with a new ‘cdc-mbim‘ driver...

The cdc-mbim driver, which supports broadband modems that implement Mobile Broadband Interface Model (MBIM⁠⁠) 1.0, specified⁠ by the USB Implementers Forum, is also new (1, 2).
MBIM is a USB protocol for connecting modems for laptops, tablets and desktop computers that provide an internet connection using GSM and CDMA-based 3G and 4G (including LTE). 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

An introduction to libmbim

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.
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 the type “Command Messages“.
  • Modem-created “Set” and “Query” responses are sent using the type “Command Done Messages“.
  • Modem-created “Notifications” are sent using the type “Indication Messages“.

MBIM basic types

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.
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.

libmbim

mbimcli


  mbimcli [OPTION?] - Control MBIM devices
List all available options for mbimcli:

$ mbimcli --help-all    
	

Basic Connect options

  • --query-device-caps
  • Query device capabilities
    
    $ sudo mbimcli --device=/dev/wwan0p2MBIM  --query-device-caps
    [/dev/wwan0p2MBIM] Device capabilities retrieved:
    	      Device type: 'embedded'
    	   Cellular class: 'gsm'
    	      Voice class: 'no-voice'
    	        SIM class: 'removable'
    	       Data class: 'umts, hsdpa, hsupa, lte, custom'
    	         SMS caps: 'pdu-receive, pdu-send'
    	        Ctrl caps: 'reg-manual'
    	     Max sessions: '15'
    	Custom data class: '5G'
    	        Device ID: '352264110046477'
    	    Firmware info: 'T99W175.F0.1.0.0.9.GC.004
    061'
    	    Hardware info: 'Qualcomm Snapdragon X55 5G'
       
        
  • --query-pin-list
  • Query PIN list
    
    $ sudo mbimcli --device=/dev/wwan0p2MBIM --query-pin-list 
    error: operation failed: NotInitialized
      	
  • --query-pin-state
  • Query PIN state
  • --enter-pin=[(PIN type),(current PIN)]
  • Enter PIN (PIN type is optional, defaults to PIN1, allowed options: (pin1,network-pin,network-subset-pin,service-provider-pin,corporate-pin)
  • --change-pin=[(current PIN),(new PIN)]
  • Change PIN
  • --enable-pin=[(current PIN)]
  • Enable PIN
  • --disable-pin=[(PIN type),(current PIN)]
  • Disable PIN (PIN type is optional, see enter-pin for details)
  • --enter-puk=[(PUK type),(PUK),(new PIN)]
  • Enter PUK (PUK type is optional, defaults to PUK1, allowed options: (puk1,network-puk,network-subset-puk,service-provider-puk,corporate-puk)
  • --query-subscriber-ready-status
  • Query subscriber ready status
  • --query-radio-state
  • Query radio state
  • --set-radio-state=[(on|off)]
  • Set radio state
  • --query-device-services
  • Query device services
  • --query-home-provider
  • Query home provider
  • --query-preferred-providers
  • Query preferred providers
  • --query-visible-providers
  • Query visible providers
  • --query-registration-state
  • Query registration state
  • --register-automatic
  • Launch automatic registration
  • --query-signal-state
  • Query signal state
  • --query-packet-service-state
  • Query packet service state
  • --attach-packet-service
  • Attach to the packet service
  • --detach-packet-service
  • Detach from the packet service
  • --query-connection-state=[SessionID]
  • Query connection state (SessionID is optional, defaults to 0)
  • --connect=["key=value,..."]
  • Connect (allowed keys: session-id, apn, ip-type (ipv4|ipv6|ipv4v6), auth (PAP|CHAP|MSCHAPV2), username, password)
  • --query-ip-configuration=[SessionID]
  • Query IP configuration (SessionID is optional, defaults to 0)
  • --disconnect=[SessionID]
  • Disconnect (SessionID is optional, defaults to 0)
  • --query-packet-statistics
  • Query packet statistics
  • --query-ip-packet-filters=[SessionID]
  • Query IP packet filters (SessionID is optional, defaults to 0)
  • --query-provisioned-contexts

Phonebook options

  • --phonebook-query-configuration
  • Query the phonebook configuration
    
    
    	
  • --phonebook-read=[(Phonebook index)]
  • Read phonebook entry with given index
  • --phonebook-read-all
  • Read all phonebook entries
  • --phonebook-write=[(Name),(Number)[,(Index)]]
  • Add new phonebook entry or update an existing one
  • --phonebook-delete=[(Phonebook index)]
  • Delete phonebook entry with given index
  • --phonebook-delete-all
  • Delete all phonebook entries

Modem AT Commands

AT commands are instructions that are used to control modems.
AT stands for ATTENTION.
There are 2 types of modem AT commands.
  • Basic commands
  • Basic commands are AT commands that do not start with “+”.
  • Extended commands
  • Extended commands are AT commands that start with a “+”.
    All GSM/GPRS uses the extended commands for SMS/DATA services.

Task which can be done by using AT commands

Here are few list of tasks which can be done by using the AT commands.
  • Get basic information about the subscriber
  • Get the information about signal strength and battery strength
  • Establish a data/voice connection
  • Send and receive fax
  • Send and receive SMS
  • Read/Search phonebook entries
Note that not all modems will support all the AT commands.

Configuring minicom to interface with the modem via USB

Once the device is connected via USB, you will see output similar to the following using dmesg.

[ 1071.120084] cdc_acm 1-1.3:1.1: ttyACM0: USB ACM device
[ 1071.120916] usbcore: registered new interface driver cdc_acm
[ 1071.120917] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
In this case, the modem got detected as /dev/ttyACM0.
To configure minicom to access modem,
  • change the serial device from /dev/tty0 to /dev/ttyACM0
  • change the Baud rate at which the modem can support
To test whether we have configured minicom successfully to communicate with modem, type “AT” in the minicom. You should get a “OK” response as follows.

Welcome to minicom 2.6.1

OPTIONS: I18n                                                                
Compiled on Feb 11 2012, 18:12:55.                                           
Port /dev/ttyACM0                                                            

Press CTRL-A Z for help on special keys

AT                                                                                               
OK

Test AT Commands

  • Answer an Incoming call
  • When there is an incoming call, you can see a ‘RING’ message in the minicom. You can input “ATA” to answer the incoming call.
    
    RING
    ATA
    OK 
      
  • Dialing out
  • 
    ATD 99769XXXXX;
    OK
      
  • Hanging out
  • 
    ATH
    OK
      
  • Getting the Manufacture/IMEI(International Mobile Equipment Identity)/IMSI(International Mobile Subscriber Identity) information
  • 
    AT+CGMI
    Nokia
    
    OK
    AT+CGSN
    xxxxxxxxxxxxxxx
    
    OK
    AT+CIMI
    xxxxxxxxxxxxxxx
    
    OK  
    
  • Getting Signal quality and battery charge status
  • 
    AT+CSQ
    +CSQ: 29,99
    
    OK
    AT+CBC
    +CBC: 1,96
    
    OK
    
    The returned responses:
    • +CSQ: 29,99
    • Represent <Received signal strength indicator>,<Bit Error Rate>
    • +CBC: 1,96
    • Represent <current charging status>,<charged %>
  • Sending SMS using AT commands
  • 
    AT+CMGF=1
    OK
    AT+CMGS="99xxxxxxxx"
    > This is a test message
    > 
    OK
      	
    • The command AT+CMGF=1 sets the “Message format” to “text mode”.
    • The command AT+CMGS, send the SMS to the specified number.
    • "Ctrl + z" is used to terminate the message input.

List of AT commands


$ sudo mmcli -m 0 --command='CMD'
CMD:
  • AT
  • AT command returns OK which implies that the communication between the device and the application has been verified.
    
    $ sudo mmcli -m 0 --command='AT'
    response: ''
    	
  • AT+CGMI
  • This AT command returns information about device manufacturer.
    
    $ sudo mmcli -m 0 --command='AT+CGMI'
    response: 'Quectel'
    	
  • AT+CGSN
  • This command returns the IMEI (International Mobile station Equipment Identity) of the mobile terminal.
    
    $ sudo mmcli -m 0 --command='AT+CGSN'
    response: '***'
    	
  • AT+CIMI
  • This AT command returns IMSI (International Mobile Subscriber Identity) of the mobile terminal.
    
    $ sudo mmcli -m 0 --command='AT+CIMI'
    error: command failed: 'GDBus.Error:org.freedesktop.ModemManager1.Error.MobileEquipment.NotAllowed: Operation not allowed'  
    	
  • AT+CFUN
  • AT+CFUN AT command sets the level of functionality in the MT.
    • Level "full functionality" is where the highest level of power is drawn.
    • "Minimum functionality" is where minimum power is drawn.
    Possible values are,
    • 0
    • minimum functionality
    • 1
    • full functionality
    • 2
    • disable phone transmit RF circuits only
    • 3
    • disable phone receive RF circuits only
    • 4
    • disable phone both transmit and receive RF circuits
    
    $ sudo mmcli -m 0 --command='AT+cfun?'
    response: '+CFUN: 1'   
       
  • AT+CPIN
  • The commandis used to enter a password or query whether or not the module requires a password which is necessary before it can be operated.
    • TestCommand: AT+CPIN=?
    • Response: OK
      
      $ sudo mmcli -m 0 --command='AT+CPIN=?'
      response: ''
         		
    • Read Command: AT+CPIN?
    • 
      $ sudo mmcli -m 0 --command='AT+cpin?'
      error: command failed: 'GDBus.Error:org.freedesktop.ModemManager1.Error.MobileEquipment.SimBusy: SIM busy    
         		
  • AT+QCFG
    • Query all options of the configuration
    • 
      $ sudo mmcli -m 0 --command='AT+QCFG=?'
      response: '+QCFG: "gprsattach",(0,1)
      +QCFG: "nwscanseq",(00-0102030405),(0,1)
      +QCFG: "rrc",(0-5)
      +QCFG: "msc",(0-2)
      +QCFG: "sgsn",(0-2)
      +QCFG: "hsdpacat",(6,8,10-24)
      +QCFG: "hsupacat",(5,6)
      +QCFG: "pdp/duplicatechk",(0,1)
      +QCFG: "ledmode",(0,1)
      +QCFG: "ltesms/format"[,(0-2)]
      +QCFG: "ModemRstLevel",(0,1)
      +QCFG: "mdlogcfg",(0,1)
      +QCFG: "lte4x4mimo/disable",(0,1)
      +QCFG: "lte4x4mimo/swmethod",(0,AT)(1,check_PIN68)
      +QCFG: "ApRstLevel",(0,1)
      +QCFG: "ims",(0,1)
      +QCFG: "pcmclk",(0,1)
      +QCFG: "thermal/modem"[,<level>,<trig>,<clr>]
      +QCFG: "thermal/limit_rates"[,<enable>]
      +QCFG: "lte/bandprior",(1-43),(1-43),(1-43)
      +QCFG: "qsar/qsardpr",(0,1)
      +QCFG: "vts/async",(0,1)
      +QCFG: "imsreg/iptype",(0,1)
      +QCFG: "sim/onchip",(0,1)
      +QCFG: "powerup/regctl",(0,1)
      +QCFG: "volte_disable",(0,1)
      +QCFG: "sim/clk_freq",(0,1)
      +QCFG: "diversity/config",<0-5>,<0-7>,<0-2>
      +QCFG: "div_test_mode",<0-1>
      +QCFG: "usbid",<vid>,<pid>
      +QCFG: "usbcfg",<vid>,<pid>,<diag>,<nmea>,<at_port>,<modem>,<rmnet>,<adb>
      +QCFG: "usbnet",<0-3>
      +QCFG: "data_interface",(0,1),(0,1)
      +QCFG: "stkauto/setupmenutr",(0,1)
      +QCFG: "fcc_enable",(0,1)
      +QCFG: "soft_hotswap",(0,1),(5-60)'
              
      it will return ERROR if you query an option that is unset
    • Query a setting
    • 
      $ sudo mmcli -m 0 --command='AT+qcfg="fcc_enable",0'        
      $ sudo mmcli -m 0 --command='AT+qcfg="fcc_enable"'
      response: '+QCFG: "fcc_enable",0'        
              

Un-documented AT Commands

References:
  • https://sixfab.com/wp-content/uploads/2018/10/Quectel_BG96_AT_Commands_Manual_V2.2.pdf
CMD:
  • AT+qgmr
  • Request Modem and Application Firmware Versions
    
    $ sudo mmcli -m 0 --command='AT+qgmr'
    response: 'EM160RGLAPR02A07M4G_01.001.01.001'    
        
  • AT+QCFG
  • Extended Configuration Settings.
    The command is used to query and configure various settings.
    • AT+qcfg="fcc_enable"
    • 
          
          		
    • AT+qcfg="fcc_enable",0
    • 
          
          		

Short Message Service / SMS Tutorial

How to Send SMS Messages ?

The following table lists the AT commands that are related to the writing and sending of SMS messages:
  • operate in SMS text mode
  • 
    AT+CMGF=1
    	
  • Write message to memory
  • 
    AT+CMGW="+85291234567"
    > A simple demo of SMS text messaging.
    +CMGW: 1
    	
    "+CMGW: 1" tells us that the index assigned to the SMS text message is 1.
    It indicates the location of the SMS text message in the message storage.
  • Send message from storage
  • 
    AT+CMSS=1
    
    "1" is the index of the SMS text message in the message storage.
  • Send message
  • 
    AT+CMGS
    	
  • Delete message
  • 
    +CMGD
    
  • Send command
  • 
    +CMGC
    
  • More messages to send
  • 
    +CMMS
    
In most cases, instead of writing your own code for interacting with the mobile phone or GSM/GPRS modem via AT commands, a better solution is to use a high-level SMS messaging API (Application programming interface) / SDK (Software development kit) / library.
The links to some open source and free SMS messaging libraries can be found in the article "Free Libraries/Tools for Sending/Receiving SMS with a Computer".

How to set up a simple data connection over the MBIM interface using libmbim and driver cdc_mbim in Linux?

Most 4G/LTE cellular modules implements the USB Implementers Forums Mobile Broadband Interface Model (MBIM) Interface.
Microsoft request cellular module vendors to include the MBIM interface for good compatibility with Windows 8, 8.1, 10 and later systems. The Windows built-in connection manager also rely on MBIM interface for control of the cellular modules.

There is a open source Linux in-kernel driver supporting MBIM interface and it is called cdc_mbim.
The library libmbim can be used to communicate with the cellular devices over the interface and do necessary configurations to trigger the data connection over the cellular network.

Verify that you have the Linux in-kernel cdc_mbim driver installed for the cellular modules exposed MBIM interface endpoint over USB.

  
$ lsusb -t  
The libmbim provides a command line utility mbimcli:
  
$ mbimcli --version
The cellular modules mbim interface is usually named the device cdc-wdm* .

Telit module's Application GUide

FT980 family cellular module

How to check current SW version

  • Show SW package version
  • 
    AT#SWPKGV
        
  • Show modem version
  • 
    AT+GMR
    	
  • Show product parameter version
  • 
    AT#CGMF
    	
  • Change modem FW binary and network configuration
  • Switch to Rest of World. Generic GCF Config
    
    AT#FWSWITCH=0
    	

FUNCTIONAL DESCRIPTION

The FT980 family of cellular modules feature 5G NR / LTE and multi-RAT modem together with an on-chip powerful application processor(32bit Cortex-A7@1.5GHz) and a rich set of interfaces.

The following software runs on the application processor:

  • Telit Unified AT command set. this is the main control interface, including the following:
    • Hayes standard AT command set
    • Standard 3GPP AT command and GPRS-specific commands.
    • Standard 3GPP AT commands for SMS (Short Message Service) and CBS (Cell Broadcast Service)
  • Firmware Over-The-Air (FOTA) update supporting selective update.
The FT980 family includes a USB3.1 port which is typically used for:
  • Flashing of firmware and module configuration
  • Production testing
  • Accessing the Application Processor’s filesystem (debug bridge)
  • AT command access (2 modem ports)
  • High speed WWAN access to external host
  • Diagnostic monitoring and debugging
  • NMEA data to an external host CPU
  • The following standardized device classes can be supported:
  • CDC-ACM, CDC-ECM, MBIM, RNDIS, RMNET (Qualcomm proprietary)

ModemManager Reference Manual

ModemManager Overview

Introduction

ModemManager provides a unified high level API for communicating with mobile broadband modems, regardless of the protocol used to communicate with the actual device (Generic AT, vendor-specific AT, QCDM, QMI, MBIM...).

ModemManager is a system daemon, since it provides a DBus API, it is possible to use 'dbus-send' commands or the new 'mmcli' command line interface to control it from the terminal.

The devices are queried from udev and automatically updated based on hardware events, although a manual re-scan can also be requested to look for RS232 modems.

ModemManager is a DBus system bus activated service (meaning it's started automatically when a request arrives).

Modem detection

ModemManager requires udev-powered Linux kernels in order to get notified of possible available Modems.
  • udev will report each of the ports found in the device
  • ModemManager will consider for probing each of the ports marked with the ID_MM_CANDIDATE tag in udev
Aditionally, users of RS232-based devices may need to request additional manual scans via DBus, in order to detect modems that may have been connected to RS232 to USB adapters. In this case, udev just knows about the USB adapter being connected, not about the RS232 modem connected to the adapter, if any.

Modem filter

ModemManager will not probe all TTYs, NET and cdc-wdm ports found in the system because TTYs that have nothing to do with modem devices.

The daemon comes with several predefined filter policies, each of them composed of one or more filter rules.

  • MM_FILTER_RULE_EXPLICIT_WHITELIST
  • src/mm-filter.c:
    
    mm_filter_register_plugin_whitelist_vendor_id(MMFilter *self, guint16   vid){
    ...
        for (i = 0; i < self->priv->plugin_whitelist_vendor_ids->len; i++) {
            guint16 item;
    
            item = g_array_index (self->priv->plugin_whitelist_vendor_ids, guint16, i);
            if (item == vid)
                return;
        }
    ...
      mm_obj_dbg (self, "registered plugin whitelist vendor id: %04x", vid);
    ...
    }
        
    src/mm-plugin-manager.c:
    
    static void
    register_plugin_whitelist_vendor_ids (MMPluginManager *self, MMPlugin        *plugin){
    ...
        vendor_ids = mm_plugin_get_allowed_vendor_ids (plugin);
        for (i = 0; vendor_ids && vendor_ids[i]; i++)
            mm_filter_register_plugin_whitelist_vendor_id (self->priv->filter, vendor_ids[i]);
    ...
    }
    
    static gboolean load_plugins (MMPluginManager  *self,
                  GError          **error)
    {
    ...
        mm_obj_dbg (self, "looking for plugins in '%s'", plugindir_display);
    ...
        /* Load all plugins */
        subsystems = g_ptr_array_new ();
        for (l = plugin_paths; l; l = g_list_next (l)) {
            MMPlugin     *plugin;
            const gchar **plugin_subsystems;
            guint         i;
    
            plugin = load_plugin (self, (const gchar *)(l->data));
    ...
            /* Register plugin whitelist rules in filter, if any */
            register_plugin_whitelist_tags        (self, plugin);
            register_plugin_whitelist_vendor_ids  (self, plugin);
            register_plugin_whitelist_product_ids (self, plugin);
        }
    ...
    
    }
        
    ./plugins/quectel/mm-plugin-quectel.c:
    
      G_MODULE_EXPORT MMPlugin *
    mm_plugin_create (void)
    {
        static const gchar *subsystems[] = { "tty", "net", "usbmisc", NULL };
        static const gchar *vendor_strings[] = { "quectel", NULL };
        static const guint16 vendor_ids[] = { 0x2c7c, 0 };
    
        return MM_PLUGIN (
            g_object_new (MM_TYPE_PLUGIN_QUECTEL,
                          MM_PLUGIN_NAME,                   MM_MODULE_NAME,
                          MM_PLUGIN_ALLOWED_SUBSYSTEMS,     subsystems,
                          MM_PLUGIN_ALLOWED_VENDOR_IDS,     vendor_ids,
                          MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings,
                          MM_PLUGIN_ALLOWED_AT,             TRUE,
                          MM_PLUGIN_ALLOWED_QCDM,           TRUE,
                          MM_PLUGIN_ALLOWED_QMI,            TRUE,
                          MM_PLUGIN_ALLOWED_MBIM,           TRUE,
                          NULL));
    }
    	
  • MM_FILTER_RULE_EXPLICIT_BLACKLIST
  • MM_FILTER_RULE_VIRTUAL
  • MM_FILTER_RULE_NET

Port probing

Whenever a new device is detected by ModemManager, port probing process will get started, so that we can determine which kind of ports we have, and also which plugin we need to use for the specific device.
Devices may expose one or more ports, and all of them will follow the same probing logic.

The whole probing process, including pre-probing and post-probing filters, is implemented in the core ModemManager daemon.
Plugins will just configure their own special needs in the probing process, so that only the steps required by the given plugin are executed.

Pre-probing filters are those which control whether the probing, as requested by the specific plugin, takes place.

  • Allowed vendor IDs
  • Plugins can provide a list of udev-reported vendor IDs to be used as pre-probing filters.
    If the vendor ID reported by the device via udev is found in the list provided by the plugin, port probing will be launched as requested by the given plugin.
    This filter is specified by the MM_PLUGIN_ALLOWED_VENDOR_IDS property in the MMPlugin object provided by the plugin.
  • Product IDs
  • Plugins can provide a list of udev-reported pairs of vendor and product IDs to be used as pre-probing filters.
    If the vendor ID and product ID pair reported by the device via udev is found in the list of 'allowed' pairs provided by the plugin, port probing will be launched as requested by the given plugin. This additional filter should be used when the plugin is expected to work only with a given specific product of a given vendor.
    If the vendor ID and product ID pair reported by the device via udev is found in the list of 'forbidden' pairs provided by the plugin, port probing will not be launched by this plugin. This additional filter should be used when the plugin supports all devices of a given vendor except for some specific ones.
    These filters are specified by the MM_PLUGIN_ALLOWED_PRODUCT_IDS and MM_PLUGIN_FORBIDDEN_PRODUCT_IDS properties in the MMPlugin object provided by the plugin.
  • Subsystems
  • Plugins can specify which subsystems they expect, so that we filter out any port detected with a subsystem not listed by the plugin.
    This filter is specified by the MM_PLUGIN_ALLOWED_SUBSYSTEMS property in the MMPlugin object provided by the plugin.
  • Drivers
  • Plugins can specify which drivers they expect, so that we filter out any port detected being managed by a driver not listed by the plugin.
    Plugins can also specify which drivers they do not expect, so that we filter out any port detected being managed by a driver listed by the plugin.
    These filters are specified by the MM_PLUGIN_ALLOWED_DRIVERS and MM_PLUGIN_FORBIDDEN_DRIVERS properties in the MMPlugin object provided by the plugin.
  • udev tags
  • Plugins can provide a list of udev tags, so that we filter out any port detected which doesn't expose any of the given tags.
    This filter is specified by the MM_PLUGIN_ALLOWED_UDEV_TAGS property in the MMPlugin object provided by the plugin.

Common types and definitions

Flags and Enumerations

Common enumerations and types in the API.

  • enum MMModemMode
  • Bitfield to indicate which access modes are supported, allowed or preferred in a given device.
    • MM_MODEM_MODE_NONE
    • None
    • MM_MODEM_MODE_CS
    • CSD, GSM, and other circuit-switched technologies.
    • MM_MODEM_MODE_2G
    • GPRS, EDGE.
    • MM_MODEM_MODE_3G
    • UMTS, HSxPA
    • MM_MODEM_MODE_4G
    • LTE
    • MM_MODEM_MODE_5G
    • 5GNR. Since 1.14
    • MM_MODEM_MODE_ANY
    • Any mode can be used (only this value allowed for POTS modems).

Common udev tag definitions

D-Bus Reference

The org.freedesktop.ModemManager1 bus name

The D-Bus name org.freedesktop.ModemManager1 on the system bus is used by the ModemManager daemon.
If this daemon isn't running, it will be started if D-Bus messages are sent to the name.

Standard interfaces

Standard interfaces

org.freedesktop.DBus.Properties

All objects (Manager, Modems, Bearers, SIMs, SMSs) exported at the org.freedesktop.ModemManager1 bus name implement the standard org.freedesktop.DBus.Properties interface.
Objects implementing this interface provide a common way to query for property values and also a generic signal to get notified about changes in those properties.

org.freedesktop.DBus.Introspectable

All objects (Manager, Modems, Bearers, SIMs, SMSs) exported at the org.freedesktop.ModemManager1 bus name implement the standard org.freedesktop.DBus.Introspectable interface.
Objects implementing this interface will provide an XML-based description of the object and its interfaces.

org.freedesktop.DBus.ObjectManager

The Manager object exported at the org.freedesktop.ModemManager1 bus name implements the standard org.freedesktop.DBus.ObjectManager interface.
This interface allows a generic way to control the addition and removal of Modem objects, as well as the addition and removal of interfaces in the given objects.

The /org/freedesktop/ModemManager1 object

The /org/freedesktop/ModemManager/Modems objects

The /org/freedesktop/ModemManager/Bearers objects

The /org/freedesktop/ModemManager/SIMs objects

The /org/freedesktop/ModemManager/SMSs objects

The /org/freedesktop/ModemManager/Calls objects

USB_ModeSwitch - Handling Mode-Switching USB Devices on Linux

Introduction

USB_ModeSwitch is a mode switching tool for controlling 'multi-mode' USB devices.

Several new USB devices have their proprietary Windows drivers onboard, most of them WWAN and WLAN dongles.

  • When plugged in for the first time, they act like a flash storage and start installing the Windows driver from there.
  • If the driver is installed, it makes the storage device disappear and a new device, mainly composite (e.g. with modem ports), shows up.
The Modem maker "Option" called that feature "ZeroCD (TM)" since it eliminates the need for shipping a separate driver carrier.

It is possible to 'eavesdrop' the communication of the Windows driver, to isolate the command or action that triggers the mode switching, and finally to 'replay' the same sequence under the rule of Linux or the BSD variants.
USB_ModeSwitch makes the process easy to handle by taking the important parameters from a configuration file and doing all the initialization and communication stuff, with considerable help from "libusb".
It is mainly used automatically - via udev events and rules - to do the mode switch without any user interaction, but it can also be run as a command line tool, usually when trying to make unknown devices work. Nowadays, this tool is part of most major distributions; you should not be having to install from the source packages here unless you run into problems and need the very latest version.

How to use

How to Use USB Mobile Modem on Linux?

The HP lt4132 LTE/HSPA+ 4G Module comes with 3 different configurations;
  • USB configuration 1: QMI and TTY
  • USB configuration 2: ECM(Ethernet Control Model))
  • USB configuration 3: MBIM
By default Linux kernel will use ECM configuration. This mode doesn’t work properly with ModemManager.
Configuration 3 MBIM mode is more suitable to run drivers with ModemManager.
You need to reconfigure the USB device to change configuration to MBIM mode.

  1. Find your mobile modem device path
    1. Use lsusb or usb-devices to find the keyword of the modem's Product name
    2. 
      $ usb-devices
      T:  Bus=01 Lev=01 Prnt=01 Port=04 Cnt=02 Dev#=  3 Spd=480 MxCh= 0
      D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=ff MxPS=64 #Cfgs=  3
      P:  Vendor=03f0 ProdID=a31d Rev=01.02
      S:  Manufacturer=HP Inc.
      S:  Product=HP lt4132 LTE/HSPA+ 4G Module
      S:  SerialNumber=0123456789ABCDEF
      C:  #Ifs= 3 Cfg#= 3 Atr=a0 MxPwr=2mA
      I:  If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim
      I:  If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim
      I:  If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=14 Driver=(none)        
              
    3. Get the device path of the modem
    4. 
      $ grep lt4132 /sys/bus/usb/devices/*/product
      /sys/bus/usb/devices/1-5/product:HP lt4132 LTE/HSPA+ 4G Module        
              
  2. Deconfigure and enable MBIM mode to verify it can be probed by ModemManager
    • Send “0” to the deconfigure device then wait 1 second then send “3” to enable MBIM mode
    • 
      $ sudo echo 0 > /sys/bus/usb/devices/1-5/bConfigurationValue
      $ sleep 1
      $ sudo echo 3 > /sys/bus/usb/devices/1-5/bConfigurationValue        
              
    • Verify this can let the modem be probed by ModemManager
    • 
      $ sudo mmcli  -L
      /org/freedesktop/ModemManager1/Modem/7 [Generic] MBIM [03F0:A31D]
              
  3. Add udev rules and restart server
  4. Provide the above workable commands in a udev rules, /etc/udev/rules.d/hp_lt4132.rules:
    
    ACTION=="add|change", SUBSYSTEM=="usb", ATTR{idVendor}=="03f0", ATTR{idProduct}=="a31d", ATTR{bConfigurationValue}!="3", ATTR{bConfigurationValue}:="0"
    ACTION=="add|change", SUBSYSTEM=="usb", ATTR{idVendor}=="03f0", ATTR{idProduct}=="a31d", ATTR{bConfigurationValue}!="3", RUN+="/bin/sh -c 'sleep 1; echo 3 > %S%p/bConfigurationValue'"
    ACTION=="add|change", SUBSYSTEM=="net", ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="a31d", ATTR{cdc_ncm/ndp_to_end}=="N", ATTR{cdc_ncm/ndp_to_end}:="Y"
      	

Discussions

The ModemManager-devel Archives

May 2021 Archives by subject

留言

Lamegaton (SP)寫道…
Thank you so much Jay's father. Your post cover most of my questions. It's very detail.

熱門文章