Crafter.Build's CI publishes a Flatpak and nothing else since 2026-10-02: the rolling `latest` release's `crafter-build-linux-x86_64-musl-v2.tar.gz` that build-package.sh fetched is gone (404 since 2026-10-03), so a push of a release would fail at `fetch crafter-build` and publish nothing. Install the Flatpak (`net.catcrafts.CrafterBuild//stable` from flatpak.catcrafts.net) in the job container and run it as crafter-build. bubblewrap inside the container needs a privileged runner, so the job runs on the `flatpak` label. The sysroot stays Alpine edge and gains llvm-runtimes, the package with the std module source of its own libc++ (libc++-dev ships none). make-sysroot.sh adds its list with --upgrade: run over a sysroot from before this change (libc++ 22.1.8, no std module source) a plain add installed llvm-runtimes 23.1.2 alone, and its std.cppm did not compile against the 22.1.8 headers (`'text_encoding' file not found`); with --upgrade libc++, libc++-dev and llvm-runtimes came out at 23.1.2 and it compiled. AGENTS.md §4.1, §4.3, §8.3 and §9.4 describe the route as it runs, and the README's Building section carries the install lines. Three comments in the files this touches said what is not so and are corrected: package.yml had fp6-img install the package by a pinned version and sha256 (it takes the newest in the registry), build-package.sh had fp6-img's image build run `make check` on the aarch64 binaries (it builds no imsd: no suite runs on them), and make-sysroot.sh's usage line lacked the --march without which the cross build fails on an x86 host. Tested: build-package.sh run end to end on this commit in a privileged alpine:edge container (podman) on the workstation.
144 lines
6.1 KiB
Markdown
144 lines
6.1 KiB
Markdown
<!-- SPDX-License-Identifier: GPL-3.0-only -->
|
|
<!-- SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® -->
|
|
|
|
# imsd
|
|
|
|
Userspace IMS/VoLTE daemon for mainline Linux phones.
|
|
|
|
Modem firmware on typical mainline-Linux phones will bring up the IMS PDN but
|
|
can't be used for actual call audio. imsd implements the whole IMS client in
|
|
userspace instead: SIP registration with USIM AKA authentication over kernel
|
|
IPsec (ESP), call signalling, and the AMR-WB RTP media plane wired into
|
|
PipeWire so a stock mobile dialer — Plasma Dialer, or GNOME Calls under Phosh
|
|
and GNOME Mobile — can place and receive real VoLTE calls on a commercial
|
|
network.
|
|
|
|
## Status
|
|
|
|
Call-capable, both directions: outgoing calls place, answer, carry full-duplex
|
|
AMR-WB audio and tear down; incoming calls ring, answer and carry media the
|
|
same way, driven end-to-end from a stock dialer over a frozen D-Bus ABI.
|
|
Not there yet: DTMF (`SendDtmf` is a stub), hold/multiparty/call waiting,
|
|
USSD, P-CSCF discovery (the address is configured by hand).
|
|
|
|
Verified by community members to be fully working:
|
|
|
|
| Device | OS | Carrier |
|
|
|---|---|---|
|
|
| The Fairphone (Gen. 6) | postmarketOS, Linux 7.1.2 | KPN NL |
|
|
| The Fairphone (Gen. 6) | postmarketOS, Linux 7.1.2 | Telekom Deutschland GER |
|
|
| The Fairphone (Gen. 6) | postmarketOS, Linux 7.1.2 | Phonero |
|
|
| The Fairphone (Gen. 6) | postmarketOS, Linux 7.1.2 | Telia Norge |
|
|
|
|
## What it needs
|
|
|
|
imsd talks to the modem through ModemManager plus `qmicli` over QRTR, installs
|
|
its security associations with `ip xfrm` and plays audio through PipeWire, so
|
|
in practice: a Qualcomm modem on a mainline kernel with working
|
|
WWAN/ModemManager integration, kernel ESP, PipeWire, systemd and polkit — and
|
|
your carrier's P-CSCF address.
|
|
|
|
## Install and configure
|
|
|
|
On a Catcrafts Fairphone 6 image imsd is installed from the project's apk
|
|
registry and upgrades with `apk upgrade` (an upgrade restarts the daemon; a
|
|
call in progress ends). Elsewhere, build it with `make` (below), run
|
|
`make install`, and enable the units yourself — `systemctl enable imsd`,
|
|
and `systemctl enable --now imsd-ofonod` for GNOME Calls: imsd's preset,
|
|
the `multi-user.target.wants` link and the `/etc/imsd.env` condition
|
|
below come with the apk, not with `make install`.
|
|
|
|
Configuration is environment variables in `/etc/imsd.env`; the one required
|
|
setting is the P-CSCF:
|
|
|
|
```sh
|
|
# your carrier's P-CSCF address — from a stock-firmware capture or the
|
|
# carrier's IMS documentation
|
|
PCSCF=2001:db8::105
|
|
```
|
|
|
|
The apk's `imsd.service` is enabled by preset and starts at boot once that
|
|
file exists (the condition is checked when the unit starts, so after writing
|
|
the file run `systemctl start imsd`). It first brings the `ims` PDN up through ModemManager, then registers:
|
|
resuming an existing registration when it can, registering fresh otherwise,
|
|
and waiting out whatever the network tells it to wait out. Check on it with:
|
|
|
|
```sh
|
|
journalctl -u imsd -f
|
|
busctl --system call net.catcrafts.IMS1 /net/catcrafts/IMS1 net.catcrafts.IMS1 GetStatus
|
|
```
|
|
|
|
Every variable, what the daemon does when the registration breaks, and
|
|
what the journal lines mean are in [AGENTS.md](AGENTS.md) (§10, §7.4, §7.8).
|
|
|
|
## Dialers
|
|
|
|
imsd itself is desktop-agnostic: everything a dialer needs is on the system
|
|
bus as `net.catcrafts.IMS1`. A small translation daemon per desktop speaks
|
|
the backend protocol its dialer already consumes, so dialer, shell and the
|
|
call-history/contacts stack run unmodified.
|
|
|
|
| Desktop | Daemon | Package | Owns | Consumed by |
|
|
|---|---|---|---|---|
|
|
| Plasma Mobile | `imsd-dialerd` | `imsd` | `org.kde.telephony.*` (session bus) | plasma-dialer + kde-telephony-daemon, replacing `modem-daemon` |
|
|
| Phosh / GNOME Mobile | `imsd-ofonod` | `imsd-ofono` | `org.ofono` (system bus) | GNOME Calls' `ofono` provider plugin |
|
|
|
|
Plasma Mobile needs nothing beyond the `imsd` package: `imsd-dialerd` is
|
|
autostarted in the session in place of plasma-dialer's `modem-daemon`, whose
|
|
own autostart must be off — the package hides it for accounts created after
|
|
the install (`/etc/skel`); an existing account hides it itself with a
|
|
`Hidden=true` copy of `org.kde.modem.daemon.desktop` in `~/.config/autostart`.
|
|
|
|
For Phosh and GNOME Mobile, `apk add imsd-ofono` enables `imsd-ofonod` and
|
|
points GNOME Calls at its `ofono` provider (a gschema override; the per-user
|
|
equivalent is `gsettings set org.gnome.Calls autoload-plugins "['ofono']"`).
|
|
Do not run it alongside a real `ofonod`. Known gaps — USSD, hold and
|
|
multiparty, caller-ID withholding, the empty emergency-call screen, and why a
|
|
restart of `imsd-ofonod` restarts GNOME Calls — are listed in
|
|
[AGENTS.md §8.3](AGENTS.md).
|
|
|
|
Call control is polkit's `net.catcrafts.IMS1.Voice`: the active local
|
|
session and root may place, answer and end calls; an ssh login may not.
|
|
|
|
## Building
|
|
|
|
With the [Crafter Build](https://forgejo.catcrafts.net/Catcrafts/Crafter.Build)
|
|
Flatpak, which carries the compiler:
|
|
|
|
```sh
|
|
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
|
flatpak remote-add --if-not-exists catcrafts https://flatpak.catcrafts.net/catcrafts.flatpakrepo
|
|
flatpak install catcrafts net.catcrafts.CrafterBuild//stable
|
|
alias crafter-build='flatpak run net.catcrafts.CrafterBuild//stable'
|
|
crafter-build # the daemon; -- --product=media|dialerd|ofonod for the others
|
|
crafter-build test # the seven unit-test suites
|
|
```
|
|
|
|
Or without crafter-build (distro packaging), with clang/libc++/lld and the
|
|
gio-2.0 headers:
|
|
|
|
```sh
|
|
make && make check
|
|
```
|
|
|
|
Cross-compiling for a phone, the Makefile's requirements, the package layout
|
|
and the CI that publishes the apks are in [AGENTS.md](AGENTS.md) (§4, §9).
|
|
|
|
## Documentation
|
|
|
|
[AGENTS.md](AGENTS.md) is the complete reference — for coding agents, and
|
|
for anyone who wants to know how imsd works or change it: the build products
|
|
and the rule that keeps the engine core free of GLib and I/O, the test
|
|
suites, the lint rules, the registration and recovery behaviour, the ims PDN
|
|
bring-up, upgrades, the frozen D-Bus ABI, packaging and release mechanics,
|
|
the full configuration reference, and the carrier behaviours the code was
|
|
shaped by.
|
|
|
|
## License
|
|
|
|
GPL-3.0-only — see [LICENSE](LICENSE).
|
|
|
|
## Copyright
|
|
|
|
Copyright (C) 2026 Catcrafts®
|
|
catcrafts.net
|