OpenWrt support for Zyxel LTE5398-M904

This is somewhat under-documented, but there seem to be an additional failsafe option to allow roaming:

        case $reg_status in
                0)      echo "mbim[$$]" "Registered in home mode"
                        tid=$((tid + 1))
                        connected=1;;
                4)      if [ "$allow_roaming" = "1" ]; then
                                echo "mbim[$$]" "Registered in roaming mode"
                                tid=$((tid + 1))
                                connected=1
                        fi;;
                5)      if [ "$allow_partner" = "1" ]; then
                                echo "mbim[$$]" "Registered in partner mode"
                                tid=$((tid + 1))
                                connected=1
                        fi;;
        esac
        if [ $connected -ne 1 ]; then
                echo "mbim[$$]" "Subscriber registration failed (code $reg_status)"
                tid=$((tid + 1))
                umbim $DBG -t $tid -d "$device" disconnect
                proto_notify_error "$interface" NO_REGISTRATION
                return 1
        fi

As you can see, status code 4 is expected when roaming. But you need to set the boolean allow_roaming to allow it.

I assume this was added to prevent unwanted and/or extremely expensive roaming.

2 Likes

I tried this but it did not do anything I could see. Still the same issues in MBIM. Only I had problems going back to QMI. It also would not connect. So I did a reset of the modem AT&F and ATZ. After some fiddling I got back online in QMI. But as before QMI fails to restart after an outage. Seems it does not discover it's been disconnected.

I checked the modem manual from Quectel EM12&EG12&EG18
AT Commands Manual. I can not find any reference to AT+QMBNCFG and what it does. How do I see if a MBN profile is selected?

So I just add option allow_roaming '1' under mbim interface?

My wife is again dependent of the mobile internet. I will have to wait until tomorrow evening to test.

In an ideal world QMI should work es expected as it's the default protocol.

I found that uqmi -d /dev/cdc-wdm0 --get-data-status gives status "connected" when its working and "disconnected" when I'm disconnected. Pretty self explanatory.

Whenever it gets to "disconnected" the interface should restart by it self in my opinion. option autoconnect is supposed to be default true.

This just happened now and ifdown wlan_qmi and ifup wlan_qmi managed to get the connection back up after a few tried when looking at logread. Isn't that what should happen automatically?

How can I help to debug this?

I assume so. Haven't tried myself. Only briefly looked through the code.

I did try to find the documentation, but for some reason it seems to be missing. The closest thing to mbim config help I could find is the link @AndrewZ already posted:
https://openwrt.org/docs/guide-user/network/wan/wwan/ltedongle#mbim_protocol_support

Which doesn't actually document the mbim proto settings, only points to the similar qmi proto settings. But it lists the available mbim settings:

device apn pincode delay auth username password allow_roaming allow_partner dhcp dhcpv6 pdptype ip4table ip6table mtu

and if you look closely you'll see that this isn't a 1-1 match with qmi settings.

I don't understand why code like the mbim proto is accepted without proper end user documentation. Not exactly user friendly. But I guess it's up to anyone with some spare time to get a wiki account and fix it :slight_smile:

1 Like

You're absolutely correct. I have this option set on my travel router. I didn't notice this code 4 in the log at first.

P.S. wiki is updated now

1 Like

@bmork Thanks, it seems it did the trick. But I did not think so at first but one roaming operator had some down time this night and it seemed the modem had switched to an operator network I'm pretty sure is "forbidden".

I got MBIM working now. Time will tell if it's more stable than QMI.

How can I get stats from the MBIM device like QMI?
Similar to this with QMI:

# uqmi -d /dev/cdc-wdm0 --get-data-status
"connected"
or
"disconnected"

Seems that mqmi --mbim just freezes and never return anything.

When I try umbim -d /dev/cdc-wdm0 registration it looks like I get disconnected and have to restart the interface.

Yes. The MBIM spec mandates a strict OPEN, do session stuff, CLOSE sequence. If you send OPEN then there's an implicit CLOSE which will destroy all existing session context. And umbim will send OPEN for you by default.

To run umbim without disconnecting you have to use the -t and -n options. -t requires a numeric id, but most modems will accept anything. It's only a transaction label.

1 Like

if you want you can do this (with a 20 second timeout)

uqmi -m -d /dev/cdc-wdm0 -t 20000 --get-data-status
"connected"

show:

uqmi
No device given
Usage: uqmi <options|actions>
Options:
  --single, -s:                     Print output as a single line (for scripts)
  --device=NAME, -d NAME:           Set device name to NAME (required)
  --keep-client-id <name>:          Keep Client ID for service <name>
  --release-client-id <name>:       Release Client ID after exiting
  --mbim, -m                        NAME is an MBIM device with EXT_QMUX support
  --timeout, -t                     response timeout in msecs

Services:                           dms, nas, pds, wds, wms

Actions:
  --get-versions:                   Get service versions
  --set-client-id <name>,<id>:      Set Client ID for service <name> to <id>
                                    (implies --keep-client-id)
  --get-client-id <name>:           Connect and get Client ID for service <name>
                                    (implies --keep-client-id)
  --sync:                           Release all Client IDs
  --start-network:                  Start network connection (use with options below)
    --apn <apn>:                    Use APN
    --auth-type pap|chap|both|none: Use network authentication type
    --username <name>:              Use network username
    --password <password>:          Use network password
    --ip-family <family>:           Use ip-family for the connection (ipv4, ipv6, unspecified)
    --autoconnect:                  Enable automatic connect/reconnect
    --profile <index>:              Use connection profile
  --stop-network <pdh>:             Stop network connection (use with option below)
    --autoconnect:                  Disable automatic connect/reconnect
  --get-data-status:                Get current data access status
  --set-ip-family <val>:            Set ip-family (ipv4, ipv6, unspecified)
  --set-autoconnect <val>:          Set automatic connect/reconnect (disabled, enabled, paused)
  --get-profile-settings <val,#>:   Get APN profile settings (3gpp, 3gpp2),#
  --get-default-profile <val>:      Get default profile number (3gpp, 3gpp2)
  --create-profile <val>            Create profile (3gpp, 3gpp2)
    --apn <apn>:                    Use APN
    --pdp-type ipv4|ipv6|ipv4v6>:   Use pdp-type for the connection
    --username <name>:              Use network username
    --password <password>:          Use network password
    --auth-type pap|chap|both|none: Use network authentication type
    --no-roaming false|true         To allow roaming, set to false
  --modify-profile <val>,#          Modify profile number (3gpp, 3gpp2)
    --apn <apn>:                    Use APN
    --pdp-type ipv4|ipv6|ipv4v6>:   Use pdp-type for the connection
    --username <name>:              Use network username
    --password <password>:          Use network password
    --auth-type pap|chap|both|none: Use network authentication type
    --no-roaming false|true         To allow roaming, set to false
  --get-current-settings:           Get current connection settings
  --get-capabilities:               List device capabilities
  --get-pin-status:                 Get PIN verification status
  --verify-pin1 <pin>:              Verify PIN1
  --verify-pin2 <pin>:              Verify PIN2
  --set-pin1-protection <state>:    Set PIN1 protection state (disabled, enabled)
    --pin <pin>:                    PIN1 needed to change state
  --set-pin2-protection <state>:    Set PIN2 protection state (disabled, enabled)
    --pin <pin2>:                   PIN2 needed to change state
  --change-pin1:                    Change PIN1
    --pin <old pin>:                Current PIN1
    --new-pin <new pin>:            New pin
  --change-pin2:                    Change PIN2
    --pin <old pin>:                Current PIN2
    --new-pin <new pin>:            New pin
  --unblock-pin1:                   Unblock PIN1
    --puk <puk>:                    PUK needed to unblock
    --new-pin <new pin>:            New pin
  --unblock-pin2:                   Unblock PIN2
    --puk <puk>:                    PUK needed to unblock
    --new-pin <new pin>:            New pin
  --get-iccid:                      Get the ICCID
  --get-imsi:                       Get International Mobile Subscriber ID
  --get-imei:                       Get International Mobile Equipment ID
  --get-msisdn:                     Get the MSISDN (telephone number)
  --reset-dms:                      Reset the DMS service
  --get-device-operating-mode       Get the device operating mode
  --set-device-operating-mode <m>   Set the device operating mode
                                    (modes: online, low_power, factory_test, offline
                                     reset, shutting_down, persistent_low_power,
                                     mode_only_low_power)
  --fcc-auth:                       Set FCC authentication
  --uim-verify-pin1 <pin>:          Verify PIN1 (new devices)
  --uim-verify-pin2 <pin>:          Verify PIN2 (new devices)
  --uim-get-sim-state:              Get current SIM state
  --uim-power-off:                  Power off SIM card
    --uim-slot:                     SIM slot [1-2]
  --uim-power-on:                   Power on SIM card
    --uim-slot:                     SIM slot [1-2]
  --set-network-modes <modes>:      Set usable network modes (Syntax: <mode1>[,<mode2>,...])
                                    Available modes: all, lte, umts, gsm, cdma, td-scdma, 5gnr
  --set-network-preference <mode>:  Set preferred network mode to <mode>
                                    Available modes: auto, gsm, wcdma
  --set-network-roaming <mode>:     Set roaming preference:
                                    Available modes: any, off, only
  --network-scan:                   Initiate network scan
  --network-register:               Initiate network register
  --set-plmn:                       Register at specified network
    --mcc <mcc>:                    Mobile Country Code (0 - auto)
    --mnc <mnc>:                    Mobile Network Code
  --get-plmn:                       Get preferred network selection info
  --get-signal-info:                Get signal strength info
  --get-serving-system:             Get serving system info
  --get-system-info:                Get system info
  --get-lte-cphy-ca-info:           Get LTE Cphy CA Info
  --get-cell-location-info:         Get Cell Location Info
  --get-tx-rx-info <radio>:         Get TX/RX Info (gsm, umts, lte, 5gnr)
  --list-messages:                  List SMS messages
    --storage <mem>:                Messages storage (sim (default), me)
  --delete-message <id>:            Delete SMS message at index <id>
    --storage <mem>:                Messages storage (sim (default), me)
  --get-message <id>:               Get SMS message at index <id>
    --storage <mem>:                Messages storage (sim (default), me)
  --get-raw-message <id>:           Get SMS raw message contents at index <id>
    --storage <mem>:                Messages storage (sim (default), me)
  --send-message <data>:            Send SMS message (use options below)
    --send-message-smsc <nr>:       SMSC number
    --send-message-target <nr>:     Destination number (required)
    --send-message-flash:           Send as Flash SMS
  --wda-set-data-format <type>:     Set data format (type: 802.3|raw-ip)
  --wda-get-data-format:            Get data format

From personal experience I still notice some disconnections with both QMI and MBIM and ECM

log:

Mon Oct 14 21:52:01 2024 user.notice root: exec /root/wan2_connect: lost connection detected exec ifdown wan; ifup wan
Tue Oct 15 09:51:00 2024 user.notice root: exec /root/wan2_connect: lost connection detected exec ifdown wan; ifup wan
Tue Oct 15 21:46:01 2024 user.notice root: exec /root/wan2_connect: lost connection detected exec ifdown wan; ifup wan
Wed Oct 16 09:45:01 2024 user.notice root: exec /root/wan2_connect: lost connection detected exec ifdown wan; ifup wan
Wed Oct 16 21:43:01 2024 user.notice root: exec /root/wan2_connect: lost connection detected exec ifdown wan; ifup wan

script (for MBIM):

#!/bin/sh

# from 600 sec form boot not exec
if [ $(awk -F "." '{print $1}' /proc/uptime) -lt "600" ]; then
exit 0
fi

# if proto=mbim then it proceeds otherwise it does nothing
LTEPROTO=$(cat /etc/config/network | grep "proto 'mbim'" | wc -l)
if [ ${LTEPROTO} -eq "1" ]; then


    LTESTATUS=$(uqmi -m -d /dev/cdc-wdm0 -t 20000 --get-data-status)
    LTEERROR=$?
    LTEFIND=$(echo ${LTESTATUS} | grep "\"connected\"" | wc -l)

    if [ ${LTEERROR} -ne 0 ]; then
    logger "exec /root/wan2_connect: uqmi not response into 20 sec exec ifdown wan; ifup wan"
    ifdown wan
    ifup wan
    exit 0
    fi

    if [ ${LTEFIND} -eq "0" ]; then
    logger "exec /root/wan2_connect: lost connection detected exec ifdown wan; ifup wan"
    ifdown wan
    ifup wan
    #usbreset 2c7c:0512
    fi

fi

script (for QMI):

#!/bin/sh

# from 600 sec form boot not exec
if [ $(awk -F "." '{print $1}' /proc/uptime) -lt "600" ]; then
exit 0
fi

# if proto=qmi then it proceeds otherwise it does nothing
LTEPROTO=$(cat /etc/config/network | grep "proto 'qmi'" | wc -l)
if [ ${LTEPROTO} -eq "1" ]; then

    LTESTATUS=$(uqmi -d /dev/cdc-wdm0 -t 20000 --get-data-status)
    LTEERROR=$?
    LTEFIND=$(echo ${LTESTATUS} | grep "\"connected\"" | wc -l)

    if [ ${LTEERROR} -ne 0 ]; then
    logger "exec /root/wan_connect: uqmi not response into 20 sec exec ifdown wan; ifup wan"
    ifdown wan
    ifup wan
    exit 0
    fi

    if [ ${LTEFIND} -eq "0" ]; then
    logger "exec /root/wan_connect: lost connection detected exec ifdown wan; ifup wan"
    ifdown wan
    ifup wan
    #usbreset 2c7c:0512
    fi

fi

ps: I tried both QMI and MBIM and ECM

1 Like

Thanks for the scripts.

I can still not get the data status in MBIM:

root@airborne:~# uqmi -m -d /dev/cdc-wdm0 -t 20000 --get-data-status
Request timed out
"Failed to connect to service"

root@airborne:~# uqmi -m -d /dev/cdc-wdm0 -t 20000 --get-data-status
Request timed out
"Failed to connect to service"

root@airborne:~# uqmi -m -d /dev/cdc-wdm0 -t 60000 --get-data-status
Request timed out
"Failed to connect to service"

really strange, the commands work for me ....

when you switched from QMI to MBIM did you reboot the router?

is the connection still active and available?

if you connect via "picocom" you can give the following commands:

AT
ATI
AT+QENG="servingcell"
AT+CGPADDR
1 Like

It might not have rebooted. It works now and have rebooted multiple times since.

root@airborne:~# uqmi -m -d /dev/cdc-wdm0 -t 60000 --get-data-status
"connected"

Anyways I also did the AT commands.


Terminal ready
AT
OK
ATI
Quectel
EG18
Revision: EG18EAPAR01A12M4G

OK
AT+QENG="servingcell"
+QENG: "servingcell","NOCONN","LTE","FDD",214,01,DBC3565,64,3050,7,5,5,1C52,-95,-9,-67,18,12,140,-

OK
AT+CGPADDR
+CGPADDR: 1,"100.71.16.169"

OK

Terminating...
Thanks for using picocom

ok then you solved it...

It was just to understand if the modem would respond late or not at all to AT commands.

if you run this script every minute you will find out if the connection is interrupted and possibly if there is no response to the command in 20 seconds

cat /etc/crontabs/root

#min hour day month day-week command
* * * * * /root/wan2_connect

cat /root/wan2_connect

#!/bin/sh

# from 600 sec form boot not exec
if [ $(awk -F "." '{print $1}' /proc/uptime) -lt "600" ]; then
exit 0
fi

# if proto=mbim then it proceeds otherwise it does nothing
LTEPROTO=$(cat /etc/config/network | grep "proto 'mbim'" | wc -l)
if [ ${LTEPROTO} -eq "1" ]; then


    LTESTATUS=$(uqmi -m -d /dev/cdc-wdm0 -t 20000 --get-data-status)
    LTEERROR=$?
    LTEFIND=$(echo ${LTESTATUS} | grep "\"connected\"" | wc -l)

    if [ ${LTEERROR} -ne 0 ]; then
    logger "exec /root/wan2_connect: uqmi not response into 20 sec exec ifdown wan; ifup wan"
    ifdown wan
    ifup wan
    exit 0
    fi

    if [ ${LTEFIND} -eq "0" ]; then
    logger "exec /root/wan2_connect: lost connection detected exec ifdown wan; ifup wan"
    ifdown wan
    ifup wan
    #usbreset 2c7c:0512
    fi

fi
1 Like

Awsome help here. I just got my Starlink while staying in Gran Canaria so the LTE/4G part will be demoted to backup and extending the wifi.

Can anyone answer me why both ethernet ports are named lan1 and lan2? Instead of WAN/LAN and LAN2 as on the back of the router?

I have not been able to find how to rename these "VLANS" to the built in switch. I'm looking into imagebuilder and is this something that can be modified in the source code?

I am able to split up the ports so I have lan1 as a WAN-port and lan2 as LAN-port but it's kind of annoying to my OCD :rofl:

That’s on me. The back of my box says LAN1/WAN and LAN2, so based on that, the predominant use case, and other similar devices in OpenWRT I went for lan1 and lan2.

1 Like

Ok :slight_smile:

Is it a trivial task to change without changing any source code? If not I'll just live with it.

Is there something wrong with the new snapshot? (r28003-e99b5832e8)
I tried three times (from Luci, SSH and fresh install from stock Zyxel firmware.


Network device is not present.

Did it work for you on previous snapshot builds? I don't have access to my box to test, but this looks weird - IIRC it should say 'wwan0' instead of 'qmi-wan'.

Probably yes, as discovered earlier:

1 Like

Yes, it worked - but on old snapshot (2months).
Now I'm using stock firmware.