Repository navigation
Conversation
abcaefa to
009b31d
Compare
|
The interface behavior is very similar how it works in Wi-Fi, one interface is created automatic by the kernel, but Infix general design demands confd to own all interfaces. The solution for this in Wi-Fi was:
In wi-fi i went for 2, now all wi-fi interfaces is the same as other interfaces, reference from other ip commands etc. Claude suggested this to me: |
Thank you for the review, this is definitely worth considering since so much in Infix hinges on the interface existing when everything else is unleashed. I'll have a look at it and see what I can do! |
| - Add cellular modem (WWAN) support for USB-attached MBIM/QMI modems, | ||
| including USB dongles, mPCIe cards, and M.2 Key-B modules. Multiple | ||
| APNs per modem, SIM PIN configuration, and NMEA routing from modem | ||
| GPS to gpsd. See the [Modem User's Guide][modem] for details |
There was a problem hiding this comment.
Maybe strip the gpsd part here (implementation detail), instead point to how we handle GPSes?
|
Marking as draft again to look into @mattiaswal's very valid comments. |
|
Back at it again, short answer: there's no Plan for USB modems instead:
So Bonus: the same |
Since be8fe35 the hardware handler runs after the interfaces, so USB ports are unlocked only after the interfaces have been set up. A netdev behind a USB port, e.g. a WiFi radio or a modem, is then missing when its interface is set up. Run the hardware handler before the interfaces again, and move only the hostapd handling, which binds to the WiFi netdevs, to after them. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Removing a USB component from the configuration left its port unlocked. The component loop skips a component that is no longer in the configuration, so the code locking the port of a deleted component was never reached. Lock the port when its component is gone from the configuration. The USB test removed the components only after locking them, remove them while unlocked instead. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A startup-config with DHCP enabled fails validation on boards with
parentheses in their model name, e.g. Banana Pi BPI-R4:
Unsatisfied pattern - "Banana Pi BPI-R4 (1x SFP+, 1x 2.5GbE)" does
not conform to "[a-zA-Z0-9 _.:/@=,+-]+".
The DHCP client copies the model name to its vendor-class option, and
since c2bc873 option values are limited to a small character set, so
the system rejects a value it wrote itself and the device boots into
failure-config.
Only the characters that can break out of the quoting on the udhcpc
command line need to be rejected, issue #1657: quotes, '$', '\', '`',
and control characters. Allow anything else, Unicode included, and
size the buffers holding the value for 255 UTF-8 characters.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since 1b8a917 the syslog pattern-match and property-filter value only allow a small set of characters, so a startup-config with, e.g., a '\' in a regular expression fails validation after upgrade: pattern-match "error\s+\d+" The values are written into quoted fields in syslog.conf, where syslogd drops a '\' in front of any character, so only an unescaped '"' or a line break can break out of the field. Escape '\' and '"' when writing them and allow anything but control characters. As a bonus, a '\' now reaches the regular expression as written. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since a55ebf1 the DHCP server static-host client-id string only allows letters, digits, and '_.:+-', so a startup-config with, e.g., a space in it fails validation after upgrade. The value is written into the comma-separated dnsmasq dhcp-host line. Quote it, with '\' and '"' escaped, so dnsmasq takes commas and other separators in it literally, and allow anything but control characters. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A startup-config written by a build of main between the confd 1.10 bump, 2beb143, and the move of NETCONF to the SSH daemon, 80716e7, fails to load after upgrade: libyang[0]: No module named "ietf-netconf-server" in the context. Such a configuration is already version 1.10, so the 1.10 migration that removes ietf-netconf-server never runs for it. Run the migration again for 1.11. It now leaves a configuration without ietf-netconf-server as is, otherwise a migrated configuration would get NETCONF disabled. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
No PCIe card is detected on the Banana Pi BPI-R4, every port reports: mtk-pcie-gen3 11300000.pcie: PCIe link down, current LTSSM state: detect.quiet (0x0) The clocks feeding the PCIe ports have no consumer in the device tree, so the kernel gates them before the PCIe driver module loads. Mark them critical. See issue #1714 for the proper fix. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The README builds the bootloaders and the system with targets that do not exist: make x-bpi-r4-emmc-boot make: *** No rule to make target 'x-bpi-r4-emmc-boot'. Stop. Build each in its own output directory, and point mkimage.sh at them. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The M.2 LTE slot uses the USB2 bus. Add it as an unlocked component so the modem hardware is accessible and visible to users in the config. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In the last major refactor of confd to a stand-alone daemon, new command line options were added, one of which -v <LEVEL>. Unfortunately opening up for a few corner cases where the debug flag or the log_level was not set properly. This fixes that and also adds a CONFD_ARGS for /etc/default/confd, which is customary for all daemons. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Integrates the modem management subsystem, donated by Avvero Pty Ltd,
adapted to work on any platform without proprietary hardware (simctrl,
modules.json, /sys/class/sim/).
Components:
- package/feature-modem: Buildroot feature package pulling in modemd,
ModemManager, libmbim, libqmi, and USB serial/MBIM/QMI kernel drivers
- package/modemd: Buildroot package for the modemd daemon and helpers
- src/modemd: modem management daemon — detects modems via ModemManager,
connects bearers, configures IP addresses, handles SMS and location
- src/confd/src/modem.c: confd plugin — enables/disables modemd and
modem-manager via sysrepo, forwards RPCs (restart/reset/send-sms)
- src/confd/src/interfaces.{c,h}: IFT_MODEM type for wwan* interfaces;
confd manages address/route assignment, modem daemon owns link state
- src/confd/yang/confd/infix-modem.yang: YANG model for modem config and
operational state (bearers, APN, bands, modes, location, SMS)
- src/statd/python/yanger/infix_modem.py: operational state collector
- patches/modem-manager: name multiplexed links after the data port,
and trust the ID_MM_PORT_TYPE_MBIM udev tag (fixes Dell DW5811e /
Sierra EM7455 on cold boot), from the kkit-1.22.0 branch of our fork
- patches/libqmi: skip the sysfs path check in download mode, from the
kkit-1.34.0 branch of our fork
Platform portability fixes for boards without simctrl hardware:
- modem-info: fall back to /run/modems.json when /run/modules.json is
absent; discover wwan interfaces via sysfs scan; provide synthetic SIM
entry when /sys/class/sim/ is not present; fix dbg() to respect flag
- modemd: make --set-allowed-modes=any best-effort (some modems only
support one mode combination and reject any change); skip mode set
when current mode already matches requested mode
- sim-setup: guard simctrl open, return None when modules.json absent
to skip SIM slot switching entirely on non-simctrl hardware
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Two bugs found while testing modem support on hardware: ietf_system.py: "interface": null written to DNS server entries when no interface is associated, causing LY_EVALID in the ietf-system schema validator. Only include the key when the interface name is non-empty. ietf_system.py: empty list inserts (user [], server [], options [], search []) overwrote configured data in the operational store instead of leaving it intact. Guard each insert so operational data only shadows configured data when there is something to report. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
defconfig.sh used $# (find result, incl. *~ / *.bak) for the TAP total but then 'continue'd past backups without decrementing — so a stray bpi_r4_*_defconfig~ in the tree made TAP see "1..23" followed by only 21 results, and the harness treated the missing 2 as failures. Filter the patterns at find instead; $# now matches what the loop iterates over Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The initial modem import used a standalone infix-modem YANG module with
an integer-indexed list under /infix-modem:modems carrying a bearer
config mixed in with hardware config. Infix has adopted the ietf-hardware
model to allow for a clearer separation of concerns, this commit aims to
improve on that situation by refactoring the modem model to use the same
architectural pattern already used for WiFi radios, GPS receivers, and
USB ports:
Hardware:
/ietf-hardware:hardware/component[class=infix-hardware:modem]
/ietf-hardware:hardware/component[class=infix-hardware:sim]
Interface:
/ietf-interfaces:interfaces/interface[type=infix-if-type:modem]
Configuration split:
modem component — admin-state (enable/disable), radio access mode,
frequency bands, location services, probe-timeout
sim component — PIN, PUK, carrier profile
wwan interface — APN, IP type, roaming, route-preference, auth
This also enables the modem to appear in 'show hardware' alongside
other hardware components, and to be managed over NETCONF/RESTCONF
using the same ietf-hardware RPCs used for USB and WiFi.
YANG changes:
- infix-modem.yang removed (1089 lines, standalone module)
- infix-hardware.yang: new modem and sim containers, modem-state and
sim-state operational state, typedefs for bands/modes/location,
notification status-update; actions restart/reset/send-sms are
augmented directly on the component list entry (not inside container
modem) to work around sysrepo NP-container parent validation — when
checking a nested action's parent, sysrepo restricts its operational
data fetch to the container path, excluding the sibling 'class' leaf
needed to evaluate the container's 'when' condition, so the container
is never instantiated and the parent check fails
- infix-if-modem.yang: new submodule (same pattern as wifi/wireguard)
adds the wwan bearer container to ietf-interfaces
- infix-if-type.yang: new modem identity for wwan interface type
confd:
- if-modem.c: new file replaces the stub modem_gen() in modem.c;
generates dagger init scripts with probe-timeout wait loop and
unconditional dummy wwan creation so downstream IP config succeeds
when a USB modem is slow to enumerate at boot
- hardware.c: start/stop/enable/disable modemd (and modem-manager)
in response to admin-state changes on the modem hardware component;
use finit_enable/disable consistently
- hardware_cand_infer_class(): auto-set class for modemN/simN names
- modem.c: stripped to RPC/notification forwarding only; the old
genconf() / enable() / disable() logic is gone — hardware.c owns
the lifecycle now
- interfaces.c: remove wwan from wait-interface timeout (the modem
interface appearance is managed by modemd, not confd's init scripts)
modemd:
- load_config() replaces the infix-modem sysrepocfg call; reads from
ietf-hardware (modem/sim config), ietf-interfaces (bearer config),
and ietf-keystore (credentials) — three standard modules instead of
one proprietary one; modems absent from sysrepo config but present
in system.json are still started (physical detection wins)
- Default route written to /etc/net.d/<iface>.conf (picked up by
netd/staticd/zebra) instead of a direct 'ip route add'; routes are
now visible to FRR for redistribution and metric-based failover
- Addresses tagged with proto wwan (rt_addrprotos entry 7) for
precise flush on disconnect without touching other address sources
- _derive_gateway() handles point-to-point bearers where modem
reports gateway as "--"; derives peer from link-scope subnet route
- SimThread exits cleanly on platforms without /dev/simctrl
- sim-setup, modem-info, modem-udev, modem-rpc, modem-sms all ported
to the ietf-hardware/ietf-interfaces namespace
statd:
- infix_modem.py now emits modem-state and sim-state into ietf-hardware
component entries (modem0, sim0, ...) instead of a separate tree;
sim-state reports physical slot, lock state, and SIM operator name
- show hardware: Cellular Modems and SIM Cards tables added; sensor
table width now adapts to the widest section in the output
- 00-probe: USB modem detection writes to system.json["modem"], same
source as wifi-radios, feeding gen-hardware which emits the
ietf-hardware component entries at factory config generation time
CLI:
- 'show modem [ref]': without ref shows Cellular Modems and SIM Cards
tables (same data subset as 'show hardware'); with ref shows a full
per-modem dump (hardware info, status, cellular, SIM, bearers, GPS)
- 'modem restart <ref>': disconnect and reconnect all bearers without
a full hardware reset
- 'modem reset <ref>': factory-reset the modem firmware
- 'modem sms <ref> <number> <message>': send an SMS via the modem
(uses the signalling plane; no active data bearer required)
- MODEMS PTYPE provides tab-completion reading modem names from
/run/system.json
doc:
- Add initial User Guide for modems
- Update ChangeLog with modem news
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Python scripts without a .py extension are never cached as bytecode by CPython — every invocation re-parses the source. Packaging as a wheel pre-compiles all modules to .pyc and installs thin import stubs as the executables, matching the approach used by bin/show and statd. Restructure the modemd Python scripts into a proper Python package (src/modemd/modemd/): each script becomes a module with a main() entry point. pyproject.toml declares 11 entry points; the Buildroot MODEMD_BUILD_PYTHON hook builds a wheel via PEP 517, then pyinstaller.py installs compiled stubs to /usr/libexec/modemd/ and pre-compiled .pyc modules to site-packages. /sbin/modemd is now a symlink to the compiled stub. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
On SIGHUP, modemd stops all ModemThreads, re-runs sim-setup, then restarts the modem threads from fresh sysrepo config. The pidfile is touched with os.utime() once the reload is complete, satisfying Finit's default pidfile-based notify so confd can signal a reload and wait for it to finish before proceeding. This allows operator and APN changes to take effect without a full daemon restart. Also extract start_modem_threads() to remove the duplicated thread startup loop shared between initial startup and reload, and align sighandler() to use isinstance(th, ModemThread) consistently with the rest of the thread-management code. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Cellular modem location data (GPS coordinates, 3GPP cell info) was
CLI-only: 'show modem modem0' shelled out to modem-info, which queried
mmcli on demand and rendered straight to the terminal. NETCONF and
RESTCONF clients had no view into modem location, and there was no
way to tell how stale any modem-state field was.
Move both into the YANG operational tree so they are available on
every northbound interface, not just the CLI.
YANG (infix-hardware.yang, revision 2026-10-11):
- modem-state/last-change (yang:date-and-time): freshness indicator
for the modem-state subtree, bumped on each modemd poll cycle
- modem-state/location-state container: source (gps|3gpp|...),
latitude/longitude/altitude (decimal64 6/6/1 fraction-digits),
cell-id/lac/tac/mcc/mnc, and its own last-change
Runtime path:
- modemd's check_location() now writes
/run/modemd/modemN/location/data.json with the full location data
plus an RFC3339 last-change. Atomic via tmp+rename. Walks the
mmcli output once instead of twice.
- check() touches /run/modemd/modemN/state.json with a fresh
last-change after each successful state poll.
- yanger/infix_modem.py reads both files via HOST.read_json and
folds them into the modem-state operational subtree. It also
populates hardware-revision, selected-carrier, phone-number and
supported-carrier, which the model already had but nothing filled.
- yanger/ietf_interfaces/modem.py (new): wwan interfaces are typed
infix-if-type:modem and report infix-interfaces:wwan/bearer-state
from modemd's bearer data. Disconnected bearers are matched to
wwanN by modem index, which only holds for one bearer per modem.
- cli_pretty show_modem_detail rewritten to consume the operational
tree: modem-state from ietf-hardware, bearers from the wwan
interfaces. New 'Last Update' lines for both top-level state and
location.
- bin/show/modem() consolidated: both 'show modem' and
'show modem REF' read the operational tree, no more direct
modem-info subprocess call.
Cleanup along the way:
- Removed the legacy /run/modemd/modemN/location/{up,down,disabled,
failed} marker file writes, they had no readers anywhere in the
tree. In-memory self.location['state'] is kept purely as the
edge-trigger for the 'Retrieved GPS location' log line.
- Aligned now_rfc3339() output with yanger.common.YangDate (+00:00
form, not Z) so consumers see one consistent yang:date-and-time
format regardless of producer.
- Fixed multi-modem SIM scoping in show_modem_detail: now derives
sim<N> from modem<N> instead of picking the first SIM globally.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Cellular modems (Quectel EM05/EM06/EM12, Sierra EM7565, ...) expose
GPS data as NMEA on a dedicated USB serial interface. Until now we
relied on ModemManager's --location-enable-gps-nmea, which makes MM
hold the NMEA port and parse the stream itself. Useful for mmcli,
but a dead end for the rest of the system: modem GPS was visible only
via 'show modem' and could not act as an NTP fallback time source on
devices without dedicated GPS hardware.
Reroute the NMEA stream into the existing gpsd and chronyd pipeline
so cellular modems behave like any other NMEA-over-USB GPS dongle.
No changes to gpsd, chronyd, or the ietf-hardware:gps component; the
user activates it the same way as for a dedicated receiver, by adding
a 'gps' hardware component that references /dev/gpsN.
udev (src/modemd/77-mm-modem-gps.rules):
- For known vendor:product:interface tuples, set ID_MM_PORT_IGNORE
so ModemManager keeps off the NMEA port, and add
SYMLINK+="gps%n" so gpsd's existing udev hook picks up the
device automatically.
- Interface-number match uses ENV{ID_USB_INTERFACE_NUM} rather
than ATTRS{bInterfaceNumber}: udev requires all ATTRS{} matches
in a rule to share one parent, but idVendor/idProduct live on
the USB device while bInterfaceNumber lives on the USB
interface. ENV{} matching has no parent constraint and udev
already populates ID_USB_INTERFACE_NUM from bInterfaceNumber.
- Initial entries: Quectel EM05 (2c7c:0125), EM06-E (2c7c:0306),
EM12-G (2c7c:0512), Sierra Wireless EM7565 (1199:9091).
Easy to extend.
modemd (modemd/__init__.py):
- GPS_AT_COMMANDS table maps manufacturer -> (enable, disable) AT
command pair. prepare_location() issues the vendor AT command
via 'mmcli --command=AT+QGPS=1' (or AT+CGPS=1 for Sierra)
instead of --location-enable-gps-{nmea,raw}. Vendor lookup is
substring-based ('Quectel' matches both 'Quectel' and 'Quectel
Incorporated') because ModemManager normalises differently
across firmware revisions. For unrecognised vendors the
high-level MM path is still used as a fallback, so nothing
regresses for hardware not yet in the table.
- The AT path runs based on the udev/vendor table, not on MM's
--location-status capabilities. Setting ID_MM_PORT_IGNORE on
the NMEA port removes 'gps' from MM's capability list even
though the GPS hardware is still there, so a capability gate
would mistakenly skip GPS for the very modems we're targeting.
- _location_capabilities() filters MM-managed sources so a single
unsupported flag (e.g. CDMA on an LTE-only modem) doesn't fail
the whole batched call. Sources the modem doesn't support are
silently skipped; a warning is logged only if the user's YANG
config explicitly lists one.
- Subprocess fan-out collapsed: agps-msa, agps-msb, 3gpp and cdma
flags share a single batched mmcli invocation.
prepare_location() drops from 5 subprocess calls to 1 (unknown
vendor) or 2 (known vendor, AT + batched MM).
- Stringly-typed if/elif source dispatch replaced with a
dict-driven table (LOCATION_MM_FLAGS).
- Two helpers eliminate the ['mmcli', '-m', self.path, ...]
boilerplate at ~30 ModemThread call sites:
self._mmcli(*args, check=True) # runcmd wrapper
self._mmclij(*args) # runcmdj wrapper
build (package/feature-modem/Config.in):
- Select BR2_PACKAGE_MODEM_MANAGER_ATVIADBUS so ModemManager
accepts raw AT commands over D-Bus without being started in
--debug mode. Required by the AT path above; without it
'mmcli --command' is rejected with MM_CORE_ERROR_UNAUTHORIZED.
doc (doc/modem.md):
- New Location and GPS section: enabling location, the source
options, and the antenna bias caveat.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some cellular modems (notably Quectel EM05) don't expose a RESET capability
over MBIM/QMI. Both 'mmcli --reset' and 'mmcli --factory-reset' return
Unsupported immediately, the AT command is never forwarded to the firmware,
and there's nothing modemd can do over the management bus to recover. Until
now modemd's failed-state retry kept calling --reset every 30 s for the rest
of uptime, producing pure log noise:
modemd: <error> [modem0] Resetting after being 30s in state failed
modemd: <info> [modem0] Resetting
ModemManager: <wrn> [modem0] failed requesting modem reset: Unsupported
ModemManager: <wrn> [modem0] failed requesting modem factory reset: Unsupported
modemd: <error> [modem0] Unable to reset
... and the same five lines again 30 s later, indefinitely.
Mitigate this by caching the Unsupported state per modem per session.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Setting just preferred-mode in YANG (no allowed-mode leaf-list) built an invalid mode string with an empty allowed: Mode 'allowed: ; preferred: 4g' is not supported The empty allowed: can never match anything in the modem's supported-modes list, so the user got a cryptic 'is not supported' even when their preferred mode was, in principle, supported. When only preferred-mode is configured, walk the modem's supported-modes list for an entry that already has that preferred, and reuse its allowed set. If no supported entry has that preferred mode, fail with a message that lists every combination the modem does support, easier to diagnose than the silent 'empty allowed' case. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Nothing ties the modem0 component to a physical device: the kernel
names wwan interfaces first-come-first-served and ModemManager
numbers modems by discovery order. With two modems, or one slow to
boot, the configuration can end up applied to the wrong interface.
Anchor the component to its USB port using the standard
ietf-hardware uri leaf-list, previously deviated out:
uri "usb:///sys/bus/usb/devices/3-1.2.1"
The generated factory config anchors detected modems automatically.
On systems with a device-specific factory config the user finds the
URI with the new 'show hardware modem0' detail view, which also
lists probed but unconfigured modems, and pastes it into the
component configuration.
An anchored component is authoritative: the data interface is named
after the configured interface as it appears, so enumeration order
never decides names, and ModemManager only gets the devices confd
has tagged for it. When every unlocked modem is anchored,
ModemManager runs with an allowlist-only filter policy and never
probes unconfigured devices. Components without a uri keep the old
discovery-based behavior. Modem services are now driven from the
aggregate state of all modem components instead of the last one
changed.
The probe-timeout contract is unchanged: hardware must be present
within the timeout, otherwise the dummy placeholder holds the name
and a reboot is required, same recovery model as WiFi radios.
Limitations:
- anchored components must be named modemN
- the uri leaf-list becomes writable on all component classes;
schemes other than usb: are accepted and ignored
- the URI is validated at apply time, not by the YANG model
The same anchoring pattern fits USB GPS receivers, and PCIe
wwan-core modems can later reuse the anchor with true link creation
on top.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
On a Quectel EM05 the bearer is created but never connected, modemd
keeps preparing the modem every few seconds:
Unable to send AT command 'AT+QGPS=1'
Unable to prepare location
GNSS stays on in the modem across modemd restarts and reboots, and
AT+QGPS=1 on a running session fails with CME ERROR 504. A failed
location setup failed prepare(), so modemd never got as far as
connecting the bearer.
Query the GPS state first and only send the AT command when it
differs. Location is optional, so a failure no longer fails prepare()
or skips the other location sources. The setup is instead retried
from check_location() until it succeeds.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
modemd only handled bearers where ModemManager hands out the address. Bearers with IP method ppp or dhcp were skipped, the address being "--", so these modems connected but never got an IP link: - AT-only modems, e.g. on cdc_acm, carry data as PPP on the tty ModemManager dialed on, and have no netdev at all. lookup() also refused them, "No modem interface", and 00-probe only looked for cdc-wdm and ttyUSB ports. - Modems with an Ethernet-style data port get their address by DHCP. For PPP, run pppd on the tty with the link named after the configured interface, replacing confd's placeholder. The route and DNS servers go through the same ip-up and ip-down scripts as PPPoE, with the bearer's route-preference. For DHCP, run udhcpc on the data port with a script that records the lease, then apply it like an address from ModemManager. The kernel needs PPP_ASYNC for PPP on a tty. 00-probe now also records ttyACM ports, but only interfaces that speak AT commands, the same rule ModemManager uses, so GPS receivers and serial consoles on cdc_acm are not taken for modems. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
While a bearer comes up, each check queries ModemManager for the modem status twice: check() refreshes it, then pullup() does it again through get_bearers(). pullup() is only called from check_state(), right after the refresh, so let it skip get_bearers()'s own. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A modem with a single AT port and a vendor ID no plugin claims is never
picked up:
task 0,ttyACM0: deferring support check until result suggested
task 0,ttyACM0: not supported by any plugin
The nokia plugin only sets ALLOWED_SINGLE_AT, which port probing does
not count as wanting AT probes, so it defers the port until another
port of the device suggests a plugin. With one port, nothing does,
and the generic plugin is never tried.
Backport the upstream fix, ModemManager issue #822, from the
kkit-1.22.0 branch of our fork.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The modem YANG models and services are only installed with the modem feature, so the x86_64 image used for the test system has no way to test the modem configuration. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
There is no way to test modem support without modem hardware, neither in QEMU nor in CI. Add FEATURE_MODEM_VIRTUAL, enabled in the x86_64 image: a USB gadget with one ACM function on dummy_hcd, which loops it back to the host side of the same kernel. The host side is an AT modem on ttyACM, probed by ModemManager and anchored by confd like a real one. The gadget side, ttyGS0, is served by an AT command emulator, and a data call is answered by a pppd in its own network namespace. The modem is created at boot by 00-modemsim, only on nodes the topology gives a modem through the opt/modem fw_cfg. Its bus is authorized by 00-modemsim and not listed as a USB port by 00-probe, it is not a port anyone plugs into. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
get_iface() is documented to return None when the interface does not
exist, but get_data() returns None for an empty reply, so it crashed
instead:
AttributeError: 'NoneType' object has no attribute 'get'
Return None when there is no data.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
New test suite for cellular modems. The first test runs without modem hardware: it configures a modem and a SIM component and a wwan interface on top of them, verifies the placeholder interface, that a wwan interface referencing a SIM as its modem is rejected, and that the placeholder is removed with the interface. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
New test, modem/connect, on the DUT with the virtual modem: anchor the detected modem to its USB port, configure its SIM and a wwan interface, then verify that the modem registers, that wwan0 gets its address and default route from the network, and that locking the modem takes the data connection down. The qn_modem node attribute in the physical topology gives a node the virtual modem, through the opt/modem fw_cfg. dut1 has one in both the dual and quad topologies, and provides "modem" for tests to require. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Modem support pulls ModemManager, libqmi, libmbim, and modemd into the
build, and there is no modem hardware in any test system yet. Keep it
out of the default builds for now.
Drop it from the aarch64 and x86_64 defconfigs and add a modem snippet
instead, which also enables the virtual modem for the QEMU test target:
make x86_64_defconfig apply-modem
The modem tests skip on builds without it.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The weekly build was meant to catch flaky tests, but it never ran any. Opt-in features, e.g. modem support, are not in the defconfigs, so CI never builds or tests them either. Test the weekly release build on x86_64. After it is tested and published, build x86_64 and aarch64 with all configuration snippets applied, like 'make dev', and test that on x86_64 too. The dev build runs after the release build and its tests, the two must not run at the same time. 'make dev' applies the snippets and then builds, so CI cannot use it to configure a build it runs itself. Split out the configuration part as 'make dev-config', 'make dev' works as before. build.yml and test.yml get a 'config' input for extra make goals after the defconfig. A build or test with another name than the default gets the name in its artifact names, the dev build runs in the same workflow as the release build and artifact names must be unique within a run. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
An MT7615D card with an unprogrammed EEPROM, e.g., the BPI-MT7615, comes up with one radio for either 2.4 or 5 GHz instead of one radio per band. The driver cannot tell an MT7615D from a single radio MT7615N, so add a force_dbdc option to the mt7615_common module to run both bands. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A WiFi card with an unprogrammed EEPROM gets a random MAC address and, for an MT7615D, a single radio. The script shows or changes the MAC address and band selection in an image dumped from such a card, so the image can be handed to the driver instead. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A WiFi card with an unprogrammed EEPROM, e.g., the BPI-MT7615, gets a random MAC address and, for an MT7615D, a single radio. Let the boot loader copy /mnt/aux/wifi-eeprom.bin to reserved memory, handed to the driver of the card in mPCIe slot CN14 as its EEPROM. The region is zeroed when there is no file, which the driver rejects for the card's own EEPROM. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The BPI-R4 has no VPD EEPROM, so every port gets a random address on each boot, and the hostname, derived from the base address, changes with it. Let the boot loader copy /mnt/aux/vpd.bin to reserved memory, like on the BPI-R3, and give each port a fixed offset from its base MAC address. U-Boot writes its random ethaddr into the nodes behind the ethernet aliases, which takes precedence, and an overlay cannot delete them in U-Boot, so point the aliases at nothing. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
There, two modem tests added, and ~/src/x-misc(modem)$ cat configs/snippets/modem.conf
# Cellular modem support, opt-in since it pulls in ModemManager, libqmi,
# libmbim, and modemd. The virtual modem is for the QEMU test target,
# it does nothing on hardware.
BR2_PACKAGE_FEATURE_MODEM=y
BR2_PACKAGE_FEATURE_MODEM_VIRTUAL=yEnable with |
mattiaswal
left a comment
There was a problem hiding this comment.
Cool feature, lets go!
Description
Add cellular modem (WWAN) support for USB-attached MBIM/QMI modems, including USB dongles, mPCIe cards, and M.2 Key-B modules. Multiple APNs per modem, SIM PIN configuration, and NMEA routing from modem GPS to gpsd.
See the Modem User's Guide for details.
Initially donated by Avvero Pty, the original YANG model has been significantly redesigned, split into modem and sim components under ietf-hardware, and wwan as a dedicated interface type in ietf-interfaces. Finally, the location handling is now fully handed off to the Infix GPS subsystem (another ietf-hardware component), allowing chrony to use the modem as a time source.
AT-only modems, e.g. on cdc_acm, are supported too, with the data call over PPP.
Notes
make <arch>_defconfig apply-modemmodem/basicandmodem/connect, use a virtual modem in QEMU: a USB gadget looped back by dummy_hcd, served by an AT command emulatormake dev-config)build.yml/test.ymlcalled with a non-defaultnamenow get the name in their artifact names, e.g.artifact-<name>-x86_64Checklist
Tick relevant boxes, this PR is-a or has-a: