mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-29 20:23:01 +02:00
modem
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
600483c35b |
modem: route NMEA from cellular modems to gpsd
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. The result was that
modem GPS was visible only via 'show modem' and could not act as an
NTP fallback time source on devices without dedicated GPS hardware.
This commit reroutes the NMEA stream into the existing
gpsd → chronyd pipeline so cellular modems behave just 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.
This is Phase 2 of the modem GPS / location integration plan
(.notes/modem-gps-plan.md).
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.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||
|
|
f78f161dbe |
modem: migrate from infix-modem to ietf-hardware/ietf-interfaces
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 version bumped to 1.9
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)
- migrate/1.9: script fully migrates /infix-modem:modems to the new
split model; each modem[N] becomes a modemN hardware component and
simN sim component; each bearer becomes a wwanN interface (bearers
numbered globally across modems); APN, IP type, roaming, preferred-
mode, bands, location, PIN/PUK/carrier are all carried over; plain-
text bearer credentials are moved to a named keystore symmetric-key
(base64-encoded) referenced from bearer/authentication/password;
apn-type, firewall-enabled, dns-enabled and default-route are
dropped (no equivalent in the new model)
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
- ietf_hardware.py: hardware component names deduplicated by rename
(cpu → cpu, cpu1, ...) to prevent LY_EVALID when hwmon and thermal
sysfs both normalise to the same sensor 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
- Use absolute URLs in ChangeLog. Relative links only work for in-tree
references, not in release notes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||
|
|
314b0b425f |
Add cellular modem support via modemd daemon
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: upstream patches for udev install path,
multiplexed interface naming, and MBIM port trust from udev hint
(the last fixes Dell DW5811e / Sierra EM7455 on cold boot)
- patches/libqmi: ignore sysfs in download mode
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>
|