CM4 & Sierra EM7345 Modem

Awesome thanks. Will give this a shot.

Hello @barryjump how is it going? it’s finally running on your side?

Not yet, although I did have to pause the effort briefly for some other work.

I’ll spend some time with @TJvV suggestion this weekend.

I can’t believe it, but I just spent 5 minutes with that article @TJvV linked and sure enough it worked!
Given how complex and finicky cellular modems have been for me I’m SHOCKED it worked just like that. Thank you @TJvV !!

Now, if only there was a way to automatically provision all that at build or boot.

I will say I didnt get modemmanager to see the connection yet, which will take some extra work since I am tracking LTE stats in Datadog using mmcli like RSSI, SNR, cell provider, uptime, network speed, rx/tx bytes, etc. and would love to do the same here. Maybe need to dig into mbimcli commands and outputs a bit more …


2 Likes

Glad to hear you got it working @barryjump :slight_smile:

Regarding the provisioning, you can probably incorporate some provisioning script in your container entrypoint.
In my case, my containers run a script that will first set up a few initialization and background tasks and then start the main executable.

You may also want to look into udev rules to trigger scripts when the modem is detected.
You will need to keep in mind the differences between the HostOS and the service containers for this though.

1 Like

Yeah thats what I was thinking.
I just did nmcli radio wifi off in the host os to test if it would hold the connection via cellular and it seems like it did.

So I have mbimcli installed inside another debian container. I installed it manually to test your method which worked, which is what I assume you did as well right? Installing it in the Host OS didnt seem to be an option. If thats the case did you also install a second copy of network and modem manager in the same container? I’m a little confused how that works and if two copies of modemmanager for example would conflict with each other since it is running inside the host os and then potentially the container as well where mbimcli is installed?

Hi,

I did install NetworkManager and ModemManager separately in my container to get access to nmcli and mmcli.
This works because nmcli and mmcli use DBus under the hood.
So, as long as you’ve set up your DBus properly, you should be good to go.

Here’s a snapshot of the Dockerfile I’ve used for my container.
I’m actively working on changing it :slight_smile:

FROM balenalib/rpi-raspbian:buster

# Enable udev
ENV UDEV on
ENV DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

# Setup directories we will be using
RUN mkdir -p /key

# Update repos
RUN apt-get -q update && \
    apt-get -q -y install wget && \
    wget -O raspberrypi.gpg.key http://archive.raspberrypi.org/debian/raspberrypi.gpg.key && \
    cp -a raspberrypi.gpg.key /key/ && \
    apt-key add /key/raspberrypi.gpg.key

# Install required packages

RUN apt-get -q -y install vim screen curl openssh-client iproute2 && \
        apt-get clean

RUN apt-get -q -y install libusb-1.0-0-dev libudev-dev usbutils usb-modeswitch usb-modeswitch-data udev && \
        apt-get clean

RUN apt-get -q -y install dbus

RUN apt-get -q -y install modemmanager network-manager libmbim-utils

RUN apt-get -q -y install openjdk-11-jdk && \
        apt-get clean


# Clean up repos
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Required for hid4java
# libudev0 is not available, link to the newer version
RUN ln -s /lib/arm-linux-gnueabihf/libudev.so.1 /lib/arm-linux-gnueabihf/libudev.so.0

COPY . /usr/src/app

# Make all shell scripts executable
RUN find /usr/src/app/ -name \*.sh -exec chmod +x {} \;

# Main process
CMD ["/usr/src/app/run.sh"]
1 Like

Cool thanks for sharing. I’ll give this a try.
Good tip on the mmcli and nmcli dbus relationship. Thats useful to know since it would imply that you can manipulate modemmanager in particular from any container and it wouldnt matter.

It’ll be useful since I have the Datadog agent with DogStatD along with a custom python script in a separate container querying Wifi stats like this to ship off metrics like rssi, wifi frequency, etc.

Inside the main.py:

cmd = "iw dev wlan0 link | grep signal | awk '{print $2}'"
msg = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
wlan0_signal = str(msg.stdout.read(),'UTF-8').rstrip('\r\n')
statsd.gauge('custom.backhaul.wlan0_signal.gauge', wlan0_signal)

time.sleep(.5)

cmd = "iw dev wlan0 link | grep freq | awk '{print $2}'"
msg = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
wlan0_freq = str(msg.stdout.read(),'UTF-8').rstrip('\r\n')
statsd.gauge('custom.backhaul.wlan0_freq.gauge', wlan0_freq)

Which produces some nice charts in a Datadog dashboard that I can set alerts against…

I’d like to also do the same for LTE with commands like this:

cmd = "mmcli -m 0 --signal-get --output-json | jq '.modem.signal.lte.rssi'"
msg = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
lte_rssi = str(msg.stdout.read(),'UTF-8').rstrip('\r\n')
statsd.gauge('custom.backhaul.lte_rssi.gauge', lte_rssi)
1 Like

Keep us posted Barry, and thanks again @TJvV - great knowledge sharing here. :slight_smile:

Hey @TJvV I’m pretty close to finishing an automation script to make the connection per your help and that tutorial you linked, but I’m stuck on the command above, when trying to finish everything up and give the modem over to NetworkManager.

I’m getting the following error:

root@5254c10:/# nmcli d /dev/cdc-wdm0 connect
Error: argument '/dev/cdc-wdm0' not understood. Try passing --help instead.

Was there a typo? Or perhaps I’m missing something? Thanks!

@barryjump could you please print nmcli d?

It was indeed a typo and should have been nmcli d connect cdc-wdm0 instead.

I will try to get a full start-up sequence today, but I’m hitting a few snags at the moment.

Hi,

The issues I had this morning were related to two things it seemed.

  1. The USB device interface of my custom board (is a work in progresss) confused modemmanager;
  2. Bad signal quality on my modem resulted in it being reset every now and then.

To see point 2 in action, I ran watch -n5 mmcli -m 0, this showed me signal qualities below 30% and modem state stuck in “connecting”, after a few minutes I got an error saying the modem was gone. mmcli -M showed no modems for a while and then it came back.

After disabling the USB device interface and moving the antenna, here is my start up sequence this morning.

In this case my modem started up as QMI, so I switched it to MBIM.
After that, everything came up automatically, so there is definitely some caching going on.
Also tried it after a fresh reboot, and everything was the same, except the modem came up in MBIM mode from the start.

My best guess is that the configuration from earlier mbim-network and mbimcli commands is stored somewhere and run when it detects the device.
I have not yet found where it’s stored, or how to clear this (so I can test it on a clean setup, without nuking this one).

  1. Power up modem
root@df8f8df:/# /data/power.sh -m 1

root@df8f8df:/# dmesg
[...]
[   91.368111] usb 1-1.3: new high-speed USB device number 5 using dwc_otg
[   91.498974] usb 1-1.3: config 1 has an invalid interface number: 8 but max is 3
[   91.506329] usb 1-1.3: config 1 has no interface number 1
[   91.513119] usb 1-1.3: New USB device found, idVendor=1199, idProduct=9071, bcdDevice= 0.06
[   91.521597] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[   91.528979] usb 1-1.3: Product: Sierra Wireless EM7455 Qualcomm® Snapdragon™ X7 LTE-A
[   91.537183] usb 1-1.3: Manufacturer: Sierra Wireless, Incorporated
[   91.543436] usb 1-1.3: SerialNumber: LF83417306031024
[   91.577564] usbcore: registered new interface driver cdc_wdm
[   91.585335] usbcore: registered new interface driver qcserial
[   91.593026] usbserial: USB Serial support registered for Qualcomm USB modem
[   91.600551] qmi_wwan 1-1.3:1.8: cdc-wdm0: USB WDM device
[   91.607079] qmi_wwan 1-1.3:1.8 wwan0: register 'qmi_wwan' at usb-3f980000.usb-1.3, WWAN/QMI device, 22:0d:19:dc:45:61
[   91.618076] usbcore: registered new interface driver qmi_wwan
[   91.624902] qcserial 1-1.3:1.0: Qualcomm USB modem converter detected
[   91.632352] usb 1-1.3: Qualcomm USB modem converter now attached to ttyUSB4
[   91.640310] qcserial 1-1.3:1.2: Qualcomm USB modem converter detected
[   91.647448] usb 1-1.3: Qualcomm USB modem converter now attached to ttyUSB5
[   91.655683] qcserial 1-1.3:1.3: Qualcomm USB modem converter detected
[   91.663331] usb 1-1.3: Qualcomm USB modem converter now attached to ttyUSB6

  1. Check modem state
root@df8f8df:/# mmcli -L
    /org/freedesktop/ModemManager1/Modem/0 [Sierra Wireless, Incorporated] EM7455
	
root@df8f8df:/# nmcli d
DEVICE           TYPE      STATE         CONNECTION
eth0             ethernet  connected     Wired connection 1
supervisor0      bridge    connected     supervisor0
cdc-wdm0         gsm       disconnected  --
balena0          bridge    unmanaged     --
br-6e8b780802d5  bridge    unmanaged     --
resin-dns        bridge    unmanaged     --
lo               loopback  unmanaged     --
resin-vpn        tun       unmanaged     --
  1. Modem is in QMI modem, switch to MBIM
root@df8f8df:/# perl /data/swi_setusbcomp.pl /dev/cdc-wdm0 --usbcomp=8
Running in QMI mode (driver=qmi_wwan)
QMI msg '0x0021' returned status = 1
QMI support verified
supports 33 QMI subsystems:
  0x00 (1.5)    'QMI_CTL'       - Control service
  0x01 (1.67)   'QMI_WDS'       - Wireless data service
  0x02 (1.14)   'QMI_DMS'       - Device management service
  0x03 (1.25)   'QMI_NAS'       - Network access service
  0x04 (1.6)    'QMI_QOS'       - Quality of service, err, service
  0x05 (1.10)   'QMI_WMS'       - Wireless messaging service
  0x07 (1.3)    'QMI_AUTH'      - Authentication service
  0x08 (1.2)    'QMI_AT'        - AT command processor service
  0x09 (2.1)    'QMI_VOICE'     - Voice service
  0x0a (2.24)   'QMI_CAT2'      - Card application toolkit service (new)
  0x0b (1.45)   'QMI_UIM'       - UIM service
  0x0c (1.4)    'QMI_PBM'       - Phonebook service
  0x0f (1.0)    'QMI_TEST'      - Test service
  0x10 (2.0)    'QMI_LOC'       - Location service
  0x11 (1.0)    'QMI_SAR'       - Specific absorption rate service
  0x17 (1.0)    'QMI_TS'        - Thermal sensors service
  0x18 (1.0)    'QMI_TMD'       - Thermal mitigation device service
  0x1a (1.16)   'QMI_WDA'       - Wireless data administrative service
  0x1d (1.1)    'QMI_CSVT'      - Circuit switched videotelephony service
  0x22 (1.0)    'QMI_COEX'      - Coexistence service
  0x24 (1.0)    'QMI_PDC'       - Persistent device configuration service
  0x29 (1.0)    'QMI_RFRPE'     - RF radiated performance enhancement service
  0x2a (1.0)    'QMI_DSD'       - Data system determination service
  0x2b (1.0)    'QMI_SSCTL'     - Subsystem control service
  0x2e (1.0)    'unknown'       -
  0x30 (1.0)    'unknown'       -
  0x31 (1.0)    'unknown'       -
  0x36 (1.0)    'unknown'       -
  0xe1 (1.0)    'QMI_RMS'       - Remote management service
  0xf0 (1.0)    'unknown'       -
  0xf3 (1.0)    'unknown'       -
  0xf5 (1.0)    'unknown'       -
  0xf6 (1.0)    'unknown'       -
QMI msg '0x0022' returned status = 1
Got QMI DMS client ID '3'
QMI msg '0x555b' returned status = 1
Current USB composition: 6
USB compositions:
   0 - HIP  DM    NMEA  AT    MDM1  MDM2  MDM3  MS      NOT SUPPORTED
   1 - HIP  DM    NMEA  AT    MDM1  MS                  NOT SUPPORTED
   2 - HIP  DM    NMEA  AT    NIC1  MS                  NOT SUPPORTED
   3 - HIP  DM    NMEA  AT    MDM1  NIC1  MS            NOT SUPPORTED
   4 - HIP  DM    NMEA  AT    NIC1  NIC2  NIC3  MS      NOT SUPPORTED
   5 - HIP  DM    NMEA  AT    ECM1  MS                  NOT SUPPORTED
*  6 - DM   NMEA  AT    QMI                             SUPPORTED
   7 - DM   NMEA  AT    RMNET1 RMNET2 RMNET3            NOT SUPPORTED
   8 - DM   NMEA  AT    MBIM                            SUPPORTED
   9 - MBIM                                             SUPPORTED
  10 - NMEA MBIM                                        NOT SUPPORTED
  11 - DM   MBIM                                        NOT SUPPORTED
  12 - DM   NMEA  MBIM                                  NOT SUPPORTED
  13 - Config1: comp6    Config2: comp8                 NOT SUPPORTED
  14 - Config1: comp6    Config2: comp9                 NOT SUPPORTED
  15 - Config1: comp6    Config2: comp10                NOT SUPPORTED
  16 - Config1: comp6    Config2: comp11                NOT SUPPORTED
  17 - Config1: comp6    Config2: comp12                NOT SUPPORTED
  18 - Config1: comp7    Config2: comp8                 NOT SUPPORTED
  19 - Config1: comp7    Config2: comp9                 NOT SUPPORTED
  20 - Config1: comp7    Config2: comp10                NOT SUPPORTED
  21 - Config1: comp7    Config2: comp11                NOT SUPPORTED
  22 - Config1: comp7    Config2: comp12                NOT SUPPORTED
QMI msg '0x555c' returned status = 1
QMI msg '0x0023' returned status = 1


root@df8f8df:/# /data/power.sh -m 0


root@df8f8df:/# dmesg
[...]
[  248.483978] qmi_wwan 1-1.3:1.8: nonzero urb status received: -71
[  248.489990] qmi_wwan 1-1.3:1.8: wdm_int_callback - 0 bytes
[  248.510305] usb 1-1.3: USB disconnect, device number 5
[  248.516064] qcserial ttyUSB4: Qualcomm USB modem converter now disconnected from ttyUSB4
[  248.524373] qcserial 1-1.3:1.0: device disconnected
[  248.532365] qcserial ttyUSB5: Qualcomm USB modem converter now disconnected from ttyUSB5
[  248.540738] qcserial 1-1.3:1.2: device disconnected
[  248.546339] qcserial ttyUSB6: Qualcomm USB modem converter now disconnected from ttyUSB6
[  248.554751] qcserial 1-1.3:1.3: device disconnected
[  248.560005] qmi_wwan 1-1.3:1.8 wwan0: unregister 'qmi_wwan' usb-3f980000.usb-1.3, WWAN/QMI device


root@df8f8df:/# /data/power.sh -m 1

root@df8f8df:/# dmesg
[...]
[  305.379068] usb 1-1.3: new high-speed USB device number 6 using dwc_otg
[  305.510018] usb 1-1.3: config 1 has an invalid interface number: 12 but max is 4
[  305.517449] usb 1-1.3: config 1 has an invalid interface number: 13 but max is 4
[  305.524925] usb 1-1.3: config 1 has an invalid interface number: 13 but max is 4
[  305.532370] usb 1-1.3: config 1 has no interface number 1
[  305.537780] usb 1-1.3: config 1 has no interface number 4
[  305.543893] usb 1-1.3: New USB device found, idVendor=1199, idProduct=9071, bcdDevice= 0.06
[  305.552312] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  305.559672] usb 1-1.3: Product: Sierra Wireless EM7455 Qualcomm® Snapdragon™ X7 LTE-A
[  305.567771] usb 1-1.3: Manufacturer: Sierra Wireless, Incorporated
[  305.573965] usb 1-1.3: SerialNumber: LF83417306031024
[  305.580193] qcserial 1-1.3:1.0: Qualcomm USB modem converter detected
[  305.587009] usb 1-1.3: Qualcomm USB modem converter now attached to ttyUSB4
[  305.594635] qcserial 1-1.3:1.2: Qualcomm USB modem converter detected
[  305.601450] usb 1-1.3: Qualcomm USB modem converter now attached to ttyUSB5
[  305.608925] qcserial 1-1.3:1.3: Qualcomm USB modem converter detected
[  305.615630] usb 1-1.3: Qualcomm USB modem converter now attached to ttyUSB6
[  305.655791] usbcore: registered new interface driver cdc_ncm
[  305.680114] cdc_mbim 1-1.3:1.12: cdc-wdm0: USB WDM device
[  305.687452] cdc_mbim 1-1.3:1.12 wwan0: register 'cdc_mbim' at usb-3f980000.usb-1.3, CDC MBIM, 62:0d:19:dc:45:61
[  305.700175] usbcore: registered new interface driver cdc_mbim

  1. Check modem state now that it’s running in MBIM mode
root@df8f8df:/# mmcli -L
    /org/freedesktop/ModemManager1/Modem/1 [Sierra Wireless, Incorporated] Sierra Wireless EM7455 Qualcomm® Snapdragon™ X7 LTE-A
	
	
root@df8f8df:/# nmcli d
DEVICE           TYPE      STATE      CONNECTION
eth0             ethernet  connected  Wired connection 1
supervisor0      bridge    connected  supervisor0
cdc-wdm0         gsm       connected  cdc-wdm0
balena0          bridge    unmanaged  --
br-6e8b780802d5  bridge    unmanaged  --
resin-dns        bridge    unmanaged  --
lo               loopback  unmanaged  --
resin-vpn        tun       unmanaged  --	


root@df8f8df:/# ip a s wwan0
10: wwan0: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether 62:0d:19:dc:45:61 brd ff:ff:ff:ff:ff:ff
    inet 10.210.170.230/30 brd 10.210.170.231 scope global noprefixroute wwan0
       valid_lft forever preferred_lft forever
	   

Hi,

I found that the automatic part was stored in the HostOS.
After removing the contents from /etc/NetworkManager/system-connections and rebooting, the modem did not come online by itself anymore.

From that point I retraced my steps while running journalctl -fam in HostOS and found the issue.

What I found is that the system connection it creates when trying nmcli d connect cdc-wdm0 assumes no APN.
Changing the APN in the system connection, made it connect properly.

I guess this was just me mixing the ModemManager/NetworkManager and the mbim-utils setups.

Here are my steps to get my network going in both flavors :slight_smile:

Common:
Enable power to modem.

/data/power.sh -m 1

Wait for modem to be powered up.

dmesg --follow

Modem/NetworkManager:
Check if ModemManager picked it up:

root@df8f8df:/# mmcli -L
    /org/freedesktop/ModemManager1/Modem/0 [Sierra Wireless, Incorporated] Sierra Wireless EM7455 Qualcomm® Snapdragon™ X7 LTE-A

Check if NetworkManager picked it up:

root@df8f8df:/# nmcli d
DEVICE           TYPE      STATE         CONNECTION
eth0             ethernet  connected     Wired connection 1
supervisor0      bridge    connected     supervisor0
cdc-wdm0         gsm       disconnected  --
balena0          bridge    unmanaged     --
br-6e8b780802d5  bridge    unmanaged     --
resin-dns        bridge    unmanaged     --
lo               loopback  unmanaged     --
resin-vpn        tun       unmanaged     --

Create new system connection:

root@df8f8df:/# nmcli connection add type gsm con-name sierra ifname cdc-wdm0 gsm.apn simpoint.m2m
Connection 'sierra' (dadc526f-6773-4e25-a874-e4b41364fa16) successfully added.

Check if it connected (not shown here: green text for connected):

root@df8f8df:/# nmcli c
NAME                UUID                                  TYPE      DEVICE
Wired connection 1  e20ee45a-dc11-33fa-8505-1b80e8b82b18  ethernet  eth0
sierra              dadc526f-6773-4e25-a874-e4b41364fa16  gsm       cdc-wdm0
supervisor0         a96a090f-a58f-474a-92b3-bcac2dd07849  bridge    supervisor0

root@df8f8df:/# ip a s wwan0
8: wwan0: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether f6:63:be:29:61:48 brd ff:ff:ff:ff:ff:ff
    inet 10.84.234.185/30 brd 10.84.234.187 scope global noprefixroute wwan0
       valid_lft forever preferred_lft forever
    inet6 fe80::a3ac:b5c3:d72f:4b9f/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

root@df8f8df:/# ping -I wwan0 google.com
PING google.com (142.251.36.46) from 10.84.234.185 wwan0: 56(84) bytes of data.
64 bytes from ams17s12-in-f14.1e100.net (142.251.36.46): icmp_seq=1 ttl=117 time=23.7 ms

mbim-utils:
Start network

root@df8f8df:/# mbim-network --profile=/data/mbim-network.conf /dev/cdc-wdm0 start
Loading profile at /data/mbim-network.conf...
    APN: simpoint.m2m
    APN auth protocol: unset
    APN user: unset
    APN password: unset
    mbim-proxy: yes
Loading previous state from /tmp/mbim-network-state-cdc-wdm0...
    Previous Transaction ID: 11
error: no actions specified
Clearing state at /tmp/mbim-network-state-cdc-wdm0...
Querying subscriber ready status 'mbimcli -d /dev/cdc-wdm0 --query-subscriber-ready-status --no-close --device-open-proxy'...
[/dev/cdc-wdm0] Subscriber ready status retrieved: Ready state: 'initialized' Subscriber ID: '204080810226303' SIM ICCID: '89310891180
50622630' Ready info: 'none' Telephone numbers: (0) 'unknown' [/dev/cdc-wdm0] Session not closed: TRID: '4'
Saving state at /tmp/mbim-network-state-cdc-wdm0... (TRID: 4)
Querying registration state 'mbimcli -d /dev/cdc-wdm0 --query-registration-state --no-open=4 --no-close --device-open-proxy'...
[/dev/cdc-wdm0] Registration status: Network error: 'unknown' Register state: 'home' Register mode: 'automatic' Available data classes
: 'lte' Current cellular class: 'gsm' Provider ID: '20408' Provider name: 'KPN' Roaming text: 'unknown' Registration flags: 'packet-se
rvice-automatic-attach' [/dev/cdc-wdm0] Session not closed: TRID: '6'
Saving state at /tmp/mbim-network-state-cdc-wdm0... (TRID: 6)
Attaching to packet service with 'mbimcli -d /dev/cdc-wdm0 --attach-packet-service --no-open=6 --no-close --device-open-proxy'...
Saving state at /tmp/mbim-network-state-cdc-wdm0... (TRID: 8)
Starting network with 'mbimcli -d /dev/cdc-wdm0 --connect=apn='simpoint.m2m' --no-open=8 --no-close --device-open-proxy'...
Network started successfully
Saving state at /tmp/mbim-network-state-cdc-wdm0... (TRID: 11)

Ensure radio is on

root@df8f8df:/# mbimcli --device=/dev/cdc-wdm0 --device-open-proxy --set-radio-state=on
[/dev/cdc-wdm0] Radio state retrieved:
             Hardware radio state: 'on'
             Software radio state: 'on'

Check modem connection

root@df8f8df:/# mbimcli -d /dev/cdc-wdm0 -p --query-ip-configuration

[/dev/cdc-wdm0] IPv4 configuration available: 'address, gateway, dns, mtu'
     IP [0]: '10.33.68.92/29'
    Gateway: '10.33.68.93'
    DNS [0]: '194.151.228.34'
    DNS [1]: '194.151.228.18'
        MTU: '1500'

[/dev/cdc-wdm0] IPv6 configuration available: 'none'

Configure ip and routing

root@df8f8df:/# ip link set wwan0 up
root@df8f8df:/# ip addr add 10.33.68.92/29 dev wwan0 broadcast +
root@df8f8df:/# ip route add default via 10.33.68.93 dev wwan0
root@df8f8df:/# ip link set mtu 1500 dev wwan0

Check OS connection

root@df8f8df:/# ip a s wwan0
9: wwan0: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether 22:07:0e:54:82:8c brd ff:ff:ff:ff:ff:ff
    inet 10.33.68.92/29 brd 10.33.68.95 scope global wwan0
       valid_lft forever preferred_lft forever
    inet6 fe80::2007:eff:fe54:828c/64 scope link
       valid_lft forever preferred_lft forever

root@df8f8df:/# ping -I wwan0 google.com
PING google.com (142.251.36.46) from 10.33.68.92 wwan0: 56(84) bytes of data.
64 bytes from ams17s12-in-f14.1e100.net (142.251.36.46): icmp_seq=1 ttl=117 time=23.7 ms
1 Like

This is excellent @TJvV. I didnt get a chance to test any automation yet, but what I came up with is very similar to what you laid out.

I DID get a chance to use the nmcli connection add type gsm con-name sierra ifname cdc-wdm0 gsm.apn m2mglobal command and it worked.

DEVICE           TYPE      STATE      CONNECTION         
eth0             ethernet  connected  Wired connection 1 
wlan0            wifi      connected  MyWifi          
cdc-wdm0         gsm       connected  sierra             
supervisor0      bridge    connected  supervisor0

A little taste of the script I mentioned looked like this approach using variables to account for other users particular hardware.

## CREATE SCRIPT HERE 
## USE INSTRUCTIONS: https://forums.balena.io/t/cm4-sierra-em7345-modem/328468/27
## AND THIS! https://www.thinkpenguin.com/gnu-linux/using-your-4g-lte-modem-terminal

if [ -z ${APN+x} ]
then
  echo "ERROR: APN IS NOT SET"
  exit 1
fi

echo "IMPORTANT: The modem will not work when powering the Tofu with USB-C. Use an external power adapter instead."

# Get the APN from balena's variables and add that to the config file
echo APN=$APN > /etc/mbim-network.conf

echo PROXY=yes >> /etc/mbim-network.conf

# Get the modem's device address
# Assumes you have only one modem on the device.  If you have two... why?
MODEM_ADDRESS=$(ls /dev/cdc*)

# Turn the modem on
mbimcli --device=$MODEM_ADDRESS --device-open-proxy --set-radio-state=on


# Start the modem
mbim-network $MODEM_ADDRESS start


# Get the modem IP address
# MODEM_IP=$(mbimcli -d /dev/cdc-wdm0 -p --query-ip-configuration | awk '$1 == "IP" {gsub(/\047/, "", $NF); print $NF}') ***OR*** MODEM_IP=$(mbimcli -d /dev/cdc-wdm0 -p --query-ip-configuration | grep '[0-9]/' | awk '{print $NF}' | sed "s/'//g")
MODEM_IP=$(mbimcli -d $MODEM_ADDRESS -p --query-ip-configuration | awk -F"'" '/IP \[/{print $2}')

# Get the modem gateway IP address
MODEM_GATEWAY_IP=$(mbimcli -d $MODEM_ADDRESS -p --query-ip-configuration | awk -F"'" '/Gateway/{print $2}')
# OR
# MODEM_GATEWAY_IP=$(mbimcli -d /dev/cdc-wdm0 -p --query-ip-configuration | grep 'Gateway' | awk '{print $NF}' | sed "s/'//g")


# Flush any old IP addresses. TODO make wwan0 a variable?
ip addr flush dev wwan0
ip -6 addr flush dev wwan0

# Link wwan0.  TODO make wwan0 a variable?
ip link set wwan0 up

# Set the new modem IP address. TODO make wwan0 a variable?
ip addr add $MODEM_IP dev wwan0 broadcast +

# Add the modem gateway IP to wwan0. TODO make wwan0 a variable?
ip route add default via $MODEM_GATEWAY_IP dev wwan0

## 11. Run the command below, but replace wwan0 with your wwan network interface found in step 6 and mtu found in step 7:
ip link set mtu 1430 dev wwan0

# Test the connection!
ping -c 4 8.8.8.8

# Now hand it over to networkmanager!
# TODO turn cdc-wdm0 into a variable. Currently have /dev/cdc-wdm0 as MODEM_ADDRESS, need a way to trim?
nmcli connection add type gsm con-name sierra ifname cdc-wdm0 gsm.apn $APN

This is untested, will likely need to add the export command to setting some of the variables, but this was the direction I was thinking and popping it all into a start.sh script. You can see I haven’t figured out how to turn wwan0 into a variable in case others have wwan1 (rare) but I think I can figure it out …
But, if you run each step manually one by one, it works.

Hi,

Glad to hear you’re getting so close to a full solution.
If you want to make wwan0 a variable, you will also need cdc-wdm0 as a variable.
If you have the latter defined as DEV=cdc-wdm0, you can probably find the former by doing something like this.

INTERFACE=$(ls -d /sys/class/usbmisc/$DEV/device/net/*)
IFNAME=$(basename $INTERFACE)

You could also pull the inteface name from dmesg

root@df8f8df:/# dmesg | grep cdc_mbim
[17775.897984] cdc_mbim 1-1.3:1.12: cdc-wdm0: USB WDM device
[17775.903961] cdc_mbim 1-1.3:1.12 wwan0: register 'cdc_mbim' at usb-3f980000.usb-1.3, CDC MBIM, f2:28:f8:30:72:2e
[17775.914579] usbcore: registered new interface driver cdc_mbim

Here you can match the cdc-wdm0 and wwan0 based on the path 1-1.3:1.12

Yes! Works perfectly thanks. I was not familiar with basename, good tip.

Any idea how you’d get the mmcli modem number as a variable too?

root@5254c10:/# mmcli -L
    /org/freedesktop/ModemManager1/Modem/2 [Sierra Wireless Inc.] Sierra Wireless EM7345 4G LTE

Ideally end up with a something like $MMCLI_DEV

I was hoping to also script some other sanity checks at the end, like checking to see the the modem reports connected and with a decent signal quality with something similar to:

mmcli -m $MMCLI_DEV --output-json | jq '.modem.generic."signal-quality".value'
and
mmcli -m $MMCLI_DEV --output-json | jq '.modem.generic.state'

Hi Barry,
The nice part of the mmcli -L output is that it can be quite easily parsed.
Note that here I assume a single modem.
Handling multiple lines goes beyond scope for now, but the same goes for the part of finding the interface name :wink:

root@df8f8df:/# MMCLI_DEVS=$(mmcli -L | sed -nre 's_/org/freedesktop/ModemManager1/Modem/([0-9]+).*_\1_gp')
root@df8f8df:/# mmcli -m ${MMCLI_DEVS} | egrep "(state|quality)"
           |                state: connected
           |          power state: on
           |       signal quality: 19% (cached)

Here I simply strip away the dbus path and modem name to get to the actual instance.
By using -n in sed, I’m ensuring the variable stays empty when there are no modems.

I’m pretty sure someone out there has already written a script to get these stats in a better way.

Note that you could also use the mmcli -m ${MMCLI_DEVS} output to find the find the device path.

root@df8f8df:/# SYSFS_DEV=$(mmcli -m ${MMCLI_DEVS} | sed -nre 's_.*device:\s*([^\s]+)_\1_gp')
root@df8f8df:/# find ${SYSFS_DEV} -type d -name usbmisc -exec ls {} \;
cdc-wdm0
root@df8f8df:/# find ${SYSFS_DEV} -type d -name net -exec ls {} \;
wwan0
1 Like

I came across this thread and have to ask – does the TOFU Board work well with the general CM4 IO BalenaOS release? We’ve been relying on the BalenaFin board for years but are now in need of a replacement :cry:

Hello @jonathanlundstrom did you try it? did you contact with the Oratek team?