Hi all,
I've been running the MikroTik Chateau 5G R17 ax (qualcommax/ipq60xx, Quectel RG650E-EU) on OpenWrt and want to share wwand โ a small connection manager I wrote to replace the old bash qmi-advanced dialer.
https://github.com/ddimension/wwand
It's an event-driven daemon written entirely in ucode that talks QMI, MBIM and NCM/AT natively over /dev/cdc-wdmX (or the tty) โ no uqmi, qmicli, libqmi, umbim or glib. It drives netifd directly (no per-interface monitor process), so a daemon restart or a transient signal loss doesn't bounce your WAN (IPv6-PD/VRF survive). On the Chateau it does 5G NSA with two parallel PDP contexts (IPv4 + IPv6) over QMAP multiplexing, ~3 MB RSS, no polling.
It installs alongside the stock stack, it does not replace it. There is no CONFLICTS on uqmi/umbim/comgt-ncm, and the netifd shim registers proto wwand and nothing else โ your existing proto qmi interfaces stay with uqmi until you decide otherwise. Moving one across is always an explicit act (see Configuration below).
Features
- One daemon, three modem backends: QMI, native MBIM and NCM/ECM (AT-driven) โ one
proto 'wwand'for all of them - Multiple modems + multiple parallel PDP contexts (QMAP: rmnet / qmimux, auto-selected), with the QMAP header version negotiated down a ladder (v5 โ v4 โ v1)
- The mux datapath is a plug-in interface, not a hard-coded branch: an out-of-tree package can add its own without patching wwand. Two exist for the vendor QMAP drivers (
qmi_wwan_q,pcie_mhi) so Qualcomm NSS offload survives - PCIe/MHI transport (
wwand-mhi) for modems whose control port appears under/sys/class/wwan, incl. AT over the MBIM channel for modems with no DUN channel - IPv4 / IPv6 / dual-stack per context; IPv6 prefix delegation
- Recovery ladder: retry โ op-mode cycle โ modem reset โ board power-cycle / reset-GPIO โ reboot, plus a zero-rx watchdog
- Board profiles (MikroTik Chateau, Zyxel LTE33xx / NR7101): modem power/reset GPIOs and status LEDs (5-bar signal graph) โ replaces the vendor helper scripts
- SIM: PIN, multi-slot switching, PIN-lock, per-SIM overrides by ICCID โ and eSIM/eUICC: native ES10c profile management (list/enable/disable/EID) plus SM-DP+ provisioning (profile download) via a bundled lpac; the HTTPS runs on the router over your existing WAN, no dedicated provisioning APN. The eSIM APDU transport is auto-chosen (QMI UIM โ native MBIM UICC โ AT), so it also works on MBIM modems without an AT port
- SMS: receive/list/read/delete with a full GSM 03.40 PDU decoder (7-bit incl. umlauts, UCS2, multipart merge) + LuCI inbox
- Registration diagnostics: EMM reject cause + limited-service flag over ubus/log (handy when an attach is rejected, e.g. IPv4-only โ cause 33); attach profile is programmed from config before registration to avoid exactly that
- Telemetry: serving + neighbour cells, signal, operator, data-system mode (LTE/NSA/SA) โ uniform across all backends
- Quectel cell locking (4G anchor / 5G SA), network scan/selection, QMI LOC/GPS
- Zero-config autosetup: a modem on an unconfigured box gets an interface and an APN filled in from ICCID/IMSI, copied once into uci and then yours to edit
- Stable modem binding by path / serial / IMEI (wireless-style
option path), so nothing depends on enumeration order - LuCI integration (proto handler + Status โ Modem page + settings/eSIM/SMS UI)
- Configuration lives entirely in
/etc/config/network(WireGuard-stylewwand_modemsections)
Installation
Option 1: prebuilt packages (no buildroot needed)
CI publishes signed binary repositories for snapshot, 25.12 and 24.10 across seven architectures (aarch64_cortex-a53/-a72, arm_cortex-a7/-a15, mips_24kc, mipsel_24kc, x86_64):
https://ddimension.github.io/openwrt-repo/<release>/<arch>/
apk (snapshot / 25.12), example for a Chateau on snapshot:
wget -O /etc/apk/keys/wwand.pem https://ddimension.github.io/openwrt-repo/keys/public-key.pem
echo "https://ddimension.github.io/openwrt-repo/snapshot/aarch64_cortex-a53/packages.adb" > /etc/apk/repositories.d/wwand.list
apk update
apk add wwand-qmi luci-proto-wwand luci-app-wwand
apk add wwand-esim wwand-lpac # optional: eSIM management + provisioning
Option 2: build it yourself
The package definitions live in a separate feed repo (the wwand repo itself is the pure source tree):
echo "src-git wwand https://github.com/ddimension/openwrt-repo.git" >> feeds.conf.default
./scripts/feeds update wwand
./scripts/feeds install -a -p wwand
make menuconfig
Network โ WWAN โ wwand-qmi # the common case; pulls in the wwand base
# wwand-mbim # for MBIM modems (includes the QMI passthrough)
# wwand-ncm # for NCM/ECM (AT-driven) modems
# wwand-mhi # PCIe/MHI transport; pair with -qmi or -mbim
LuCI โ Protocols โ luci-proto-wwand
LuCI โ Applications โ luci-app-wwand
# optional eSIM: wwand-esim + wwand-lpac
make
Pick the backend package(s) matching your modems โ the wwand base carries no backend on its own and is pulled in automatically. Nothing here removes or conflicts with uqmi, umbim, comgt-ncm or luci-proto-qmi; they can stay installed.
Configuration
Create a proto 'wwand' interface, or hand an existing one over. Migration is always user-triggered and rewrites the interface in place: the Migratable interfaces list on the LuCI modem page, the migrate ubus method, or /usr/libexec/wwand/migrate --apply. Nothing is installed under /etc/uci-defaults, so installing or upgrading wwand never rewrites a configuration of yours; an example hook ships inert under /usr/share/wwand/examples/.
Full config/ubus reference, quirk handling and an FAQ: https://github.com/ddimension/wwand/blob/main/docs/reference.md
Tested
MikroTik Chateau 5G R17 ax (RG650E, 5G NSA) ยท Zyxel NR7101 (RG502Q) ยท Zyxel LTE3301-Plus (EG06) ยท GL.iNet GL-X3000 (RM520N-GL, MBIM) ยท Cudy LT300 v3 (MeiG SLM770A, NCM) ยท Fibocom FM350-GL (RNDIS/NCM).
3268 host-side checks across 50 suites run without hardware (cd tests && sh run_tests.sh).
Both halves are up for review upstream: openwrt/packages#30185 and openwrt/luci#8917.
Feedback / testers on other modems very welcome!
Cheers!
