2026-07-22 22:53:28 +02:00
|
|
|
# SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
|
# SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
|
|
|
|
[Unit]
|
|
|
|
|
Description=Userspace IMS/VoLTE daemon (SIP register + calls over the ims PDN)
|
|
|
|
|
# needs the ims PDN (multiplexed netdev + global v6) — ims-pdn-up.sh
|
|
|
|
|
# creates/connects the bearer through ModemManager and configures the netdev
|
|
|
|
|
After=ModemManager.service network.target
|
|
|
|
|
Wants=ModemManager.service
|
|
|
|
|
|
|
|
|
|
[Service]
|
|
|
|
|
Type=simple
|
2026-09-01 18:10:04 +02:00
|
|
|
# bring up the ims PDN first; waits for modem + network registration,
|
|
|
|
|
# idempotent. worst case ~14 min (2 min modem wait + 5 min registration
|
|
|
|
|
# gate + connect retries), hence TimeoutStartSec
|
2026-07-22 22:53:28 +02:00
|
|
|
ExecStartPre=/usr/libexec/ims-pdn-up.sh
|
packaging: restart imsd and imsd-ofonod on upgrade
An upgrade left the old imsd and imsd-ofonod running until they were
next restarted, while a changed bus policy is live the moment apk writes
it: dbus-broker-launch reloads on its own. A policy that relies on a
check inside the daemons would face the old daemons in between.
Mark imsd.service and imsd-ofonod.service needs-restart in post-upgrade
scripts; the systemd trigger restarts them once the transaction is done
(enqueue-marked). A call in progress ends. The same scripts run as
post-install: `apk del` removes a package's files and leaves its daemon
running, so a later `apk add` of the package is this upgrade for that
daemon — and apk runs the post-install script, not post-upgrade, for a
package it adds. GNOME Calls 50.0 dials nothing after imsd-ofonod
restarts under it until it restarts too, so imsd-ofonod's ExecStartPost
restarts the Calls daemon of each user running one — not at the unit's
first start since boot, when a Calls that runs already is left alone.
A daemon older than 0.3.10 kept its bring-up throttle wait in memory
only, so a restart lost it. imsd's post-upgrade records that daemon's
invocation, and imsd-handover.sh, an ExecStartPre after ims-pdn-up.sh,
reads the invocation's journal and, while the fresh-SA throttle's wait
it finds there still runs (`spi-s=0`; the old daemon's other deferrals
are not handed over), writes what is left of it to the holds file when
this start's LOCAL is the address the wait was earned on, or when that
address cannot be read; when LOCAL is another address, only the verdict
that the old registration is gone.
Tested on the dev phone (KPN) in builds of this series; not every path
has run there.
2026-10-04 00:09:37 +02:00
|
|
|
# a daemon older than 0.3.10 that an upgrade restarted inside its bring-up
|
|
|
|
|
# throttle wait: the wait — on another address only the verdict that its
|
|
|
|
|
# registration is gone — is handed over from its journal now that it has
|
|
|
|
|
# stopped (imsd.post-upgrade recorded the invocation in /run/imsd.handover)
|
|
|
|
|
ExecStartPre=-/usr/libexec/imsd-handover.sh
|
2026-09-01 18:10:04 +02:00
|
|
|
TimeoutStartSec=900
|
ims-pdn-up, imsd: register on the PDN's own address, not the kernel's temporary one
imsd took the first global IPv6 on the ims netdev as its address, and
the kernel lists the temporary (privacy) SLAAC address first: `temporary
dynamic`, preferred for a day and valid for two by its lifetimes (read
2026-09-24). Contact, Via and the four SAs were bound to it, so once the
kernel removes it the registration has lost its address. The address
ModemManager assigned — the one the script installs — sat third on the
list. Seen on the dev phone; a field unit's journal shows the split too
— imsd registered on an address other than the one the script installed
(ims ledger F18).
Hand the assigned address to the daemon as LOCAL through /run/imsd.env,
next to DEV. For a manual run without it, prefer a global address that
is neither `temporary` nor `dynamic`, then any non-temporary one.
A restart after the upgrade finds the registration's SAs on the old
address. It resumes there while that address is still on the link, and
moves to the PDN's address in place: with its next fresh registration,
or when the old address leaves the link first. When the address it is
registered on leaves the netdev and the PDN's own address is not there
to move to, a registered imsd exits at its next recovery step, non-zero,
for a systemd restart, which runs the PDN bring-up again.
Tested on the dev phone (KPN) in builds of this series; not every path
has run there.
2026-09-28 18:28:58 +02:00
|
|
|
# /run/imsd.env: written by ims-pdn-up.sh (DEV= the connected ims netdev,
|
|
|
|
|
# LOCAL= the PDN address ModemManager assigned to it).
|
2026-07-22 22:53:28 +02:00
|
|
|
# /etc/imsd.env: admin configuration — PCSCF= is REQUIRED (the carrier's
|
|
|
|
|
# P-CSCF address; see the README's Configuration section) and wins over the
|
|
|
|
|
# runtime-derived values.
|
|
|
|
|
EnvironmentFile=-/run/imsd.env
|
|
|
|
|
EnvironmentFile=-/etc/imsd.env
|
|
|
|
|
# registration state (imsreg.state) + media stats live here
|
|
|
|
|
StateDirectory=imsd
|
|
|
|
|
ExecStart=/usr/bin/imsd
|
|
|
|
|
# registration: resume an existing SA when possible (avoids fresh-SA
|
ims-pdn-up, imsd: register on the PDN's own address, not the kernel's temporary one
imsd took the first global IPv6 on the ims netdev as its address, and
the kernel lists the temporary (privacy) SLAAC address first: `temporary
dynamic`, preferred for a day and valid for two by its lifetimes (read
2026-09-24). Contact, Via and the four SAs were bound to it, so once the
kernel removes it the registration has lost its address. The address
ModemManager assigned — the one the script installs — sat third on the
list. Seen on the dev phone; a field unit's journal shows the split too
— imsd registered on an address other than the one the script installed
(ims ledger F18).
Hand the assigned address to the daemon as LOCAL through /run/imsd.env,
next to DEV. For a manual run without it, prefer a global address that
is neither `temporary` nor `dynamic`, then any non-temporary one.
A restart after the upgrade finds the registration's SAs on the old
address. It resumes there while that address is still on the link, and
moves to the PDN's address in place: with its next fresh registration,
or when the old address leaves the link first. When the address it is
registered on leaves the netdev and the PDN's own address is not there
to move to, a registered imsd exits at its next recovery step, non-zero,
for a systemd restart, which runs the PDN bring-up again.
Tested on the dev phone (KPN) in builds of this series; not every path
has run there.
2026-09-28 18:28:58 +02:00
|
|
|
# throttles); a failed bring-up exits nonzero and systemd retries, as does
|
|
|
|
|
# a registered imsd whose PDN address left the netdev
|
2026-07-22 22:53:28 +02:00
|
|
|
Restart=on-failure
|
|
|
|
|
RestartSec=120
|
|
|
|
|
# SIGTERM: engine keeps the SA + registration state for the next resume
|
|
|
|
|
KillMode=mixed
|
|
|
|
|
TimeoutStopSec=10
|
|
|
|
|
|
|
|
|
|
[Install]
|
|
|
|
|
WantedBy=multi-user.target
|