Cellular modem location data (GPS coordinates, 3GPP cell info) was
previously CLI-only — 'show modem modem0' shelled out to modem-info
which queried mmcli on demand and rendered straight to terminal.
NETCONF/RESTCONF clients had no view into modem location, and there
was no way to tell how stale any modem-state field was.
This commit moves both into the YANG operational tree so they are
accessible through every northbound interface, not just the CLI. It
is Phase 1 of the modem GPS / location integration plan; Phase 2 will
route the modem's NMEA TTY into the existing gpsd → chronyd pipeline
so cellular modems can also serve as an NTP fallback time source.
YANG (infix-hardware.yang, revision 2026-05-10):
- 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.
- cli_pretty show_modem_detail rewritten to consume the operational
tree (same path as 'show modem' overview), with new 'Last Update'
lines for both top-level state and location.
- bin/show/modem() consolidated: both 'show modem' and
'show modem REF' use get_json('/ietf-hardware:hardware') — 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.
The bearer / hardware-revision / phone-number / supported-carrier
sections of 'show modem REF' are deliberately omitted for now —
those fields are not yet in the YANG tree. Bearer details in
particular likely belong on the wwan interface
(ietf-interfaces:interfaces-state) rather than on the modem hardware
component, and can be addressed in a follow-up.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>