With the P-CSCF coming from the PDN's PCO, the configuration file has no required line left, so the apk's ConditionPathExists=/etc/imsd.env drop-in goes: the unit starts on every phone with the package, and VoLTE is on by default. Installing the package and inserting a SIM is the opt-in; the file holds overrides only, and its existence changes nothing. By the versioning rule (AGENTS §11, the first commit of this series) that is what moves the major number: the release is 1.0.0, and §11 now records it. What used to be the file's job — keeping a phone nobody configured out of a failing unit — is now a rule on facts, the same for every phone: a modem in the failed state with a SIM reason makes the script write IMSD_IDLE=no-sim to /run/imsd.env and exit 0; a profile-indexed connect series the network refuses ten times in a row — each a persistent 3GPP cause in ModemManager's typed error (not subscribed, unknown APN, barred, not authorised in the PLMN, authentication failed, the service option not supported, the wrong PDN type) with packet service at the time; counted only while the modem reads registered, connecting or connected with packet service not detached — stricter than the daemon's PacketServiceUp; any other read, a timeout or a transient cause starts the count again — writes IMSD_IDLE=no-ims-pdn; and a bring-up that ends with no P-CSCF — none configured, none discovered: no IPv6 P-CSCF read from the PCO (PCSCF_DISCOVERY=none in the hand-off, the reader's exit 2: the list absent, empty, unreadable or IPv4/FQDN only), discovery skipped (no rmnet mux id) or no hand-off at all (a manual run) — and no registration of imsd's own to resume is the daemon's own idle, decided before it takes the bus name (SaPeer and the holds' old_gone say what can be resumed; a pair the holds wrote off is taken out of the kernel there) and at the no-target bring-up, where a pair nothing can resume is written off and taken out of the kernel first. imsd reads the key, logs idle: … and exits 0, which Restart=on-failure leaves alone, so the unit stays inactive until the next boot, a systemctl start or a start of imsd-ofonod where that runs (its Wants starts an idle imsd again). What is not a fact keeps the retry: no coverage, a SIM still waiting for its PIN, a modem without an ims profile (the APN-string connect is tried), an APN-string series (the modem's own wall), a resumable pair whose attempt failed (the fatal), and a P-CSCF reader that did not answer (PCSCF_DISCOVERY=failed: the daemon exits 1 and the restart runs discovery again). A phone that never had the file keeps its stopped unit through the upgrade and starts at its next boot, registering where the rule above lets it — at the upgrade itself where imsd-ofonod runs, whose restart pulls imsd in through its Wants (systemd queues the marked unit's try-restart, collapses it to a restart and starts what the unit Wants in the same transaction: job_type_collapse, transaction_add_job_and_dependencies, 262~rc3); the opt-out is systemctl mask --now imsd, since a plain disable is undone by that Wants. imsd-ofonod.service loses its After=imsd.service: with imsd starting on every phone, GNOME Calls' backend would otherwise wait behind the ims PDN bring-up at every boot and at its marked restart at an upgrade, for the whole bring-up (up to its TimeoutStartSec=900); it starts at once and republishes when imsd's name appears (OnImsdAppeared). The configuration file's path is the IMSD_ENV seam the mock bench uses. AGENTS §6's lint figures are this tree's (109 findings in 16 of 20 files, 2026-10-13; the 72 of 2026-10-06 predate the Qmi files). Tested: crafter-build test, 8 passed; on the host build the daemon's idle exit for the script's keys and, with no pair, for every discovery verdict but failed (none, skipped, no hand-off) — exit 0 — and the exit 1 for failed; the script's arms on the mock bench; on the dev phone (KPN), in builds of this series: the daemon's idle at the no-target bring-up with the dead pair removed and before the bus name for a pair the holds had written off, the discovery-failed exit 1 and its restart, the start without the file, the pull-in by an imsd-ofonod restart and the mask holding against it and a reboot, and imsd-ofonod starting at once with imsd stopped and republishing when imsd's name appeared.
33 lines
1.5 KiB
Desktop File
33 lines
1.5 KiB
Desktop File
# SPDX-License-Identifier: GPL-3.0-only
|
|
# SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
|
[Unit]
|
|
Description=oFono-compatible GNOME Calls backend for imsd
|
|
Documentation=https://forgejo.catcrafts.net/Catcrafts/imsd
|
|
# org.ofono is a system-bus name only root may own (org.ofono.conf), so this
|
|
# is a system service run as root: imsd admits the calls it forwards as
|
|
# root's (it has asked polkit about its own caller), and its start hook
|
|
# restarts GNOME Calls in the users' own managers. Only enable it on a
|
|
# GNOME/Phosh session
|
|
# — Plasma Mobile uses imsd-dialerd instead. Both may run at once (different
|
|
# buses, different consumers), but a real ofonod must not.
|
|
Conflicts=ofono.service
|
|
# Wants, not After: imsd starts on every phone since 1.0.0 and its start runs
|
|
# the ims PDN bring-up (the whole ExecStartPre, up to TimeoutStartSec=900);
|
|
# this backend starts at once and republishes when imsd's name appears (OnImsdAppeared)
|
|
Wants=imsd.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
# EMERGENCY_NUMBERS only, and only so the oFono EmergencyNumbers property
|
|
# matches imsd's configuration; imsd itself owns emergency classification.
|
|
EnvironmentFile=-/etc/imsd.env
|
|
ExecStart=/usr/bin/imsd-ofonod
|
|
# GNOME Calls keeps a stale modem when org.ofono restarts and dials nothing
|
|
# until it restarts too: restart the Calls daemon of each user running one
|
|
ExecStartPost=-/usr/libexec/imsd-ofono-restart-calls.sh
|
|
# it holds no call state of its own — imsd is re-queried on every reconnect
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|