PAF becomes saf/device (history kept), STATE.md dissolves into saf/state.md with the dated era archived, the substrate SAF moves up from souveraine, and every agreement points at saf/INDEX.md and nowhere else. one map, nothing to remember
311 lines
24 KiB
Markdown
311 lines
24 KiB
Markdown
# PAF · The modem userspace CONSUMER CHAIN — why the modem stays OFFLINE (2026-06-26, Opus)
|
||
|
||
> ## SESSION-3 UPDATE (2026-06-27, Opus) — SLPI SAR CRASH LOOP **FIXED**; ~~PROVEN the SLPI does NOT gate the modem 52~~
|
||
>
|
||
> ### TL;DR
|
||
> Built the missing **AP-side SNS registry provider** (a patched `hexagonrpcd`) that feeds the
|
||
> SLPI its sensor registry over FastRPC `apps_std`. The SLPI's `sar.cc:27:chre_utils fatal`
|
||
> crash-loop (150+ crashes/boot) is **broken — SLPI now stays up indefinitely** (0 crashes over
|
||
> multiple 25–40s windows). **Then enabled the modem anyway → still `QMI error 52
|
||
> DeviceNotReady`.** So the SLPI/SAR subsystem is **independent of** the modem-52 wall. That
|
||
> question (could not be answered by *disabling* SLPI — only by making it actually work) is now
|
||
> settled: **error 52 is not SLPI-gated.**
|
||
>
|
||
> **🟠 SUPERSEDED 2026-06-29 (Casey) — this conclusion is INVALID.** The "SLPI fixed / 0 crashes / stays
|
||
> up" above was only *remoteproc-not-crashing*: this doc's own body (search *"never exposes an SNS QMI
|
||
> service"*) shows the SLPI firmware never completed CHRE init / never exposed SNS QMI — i.e. **not a
|
||
> functioning sensor stack.** The reasoning "disabling couldn't answer it, only making it work can" was
|
||
> correct — but "making it work" was never achieved, only "stopped crashing." If the modem's RF-init
|
||
> queries the SLPI and gets silence from a never-initialized sensor stack, it parks OFFLINE regardless.
|
||
> The SLPI is a **candidate root-cause**, NOT proven-independent. See `slpi.md` top banner + `HANDOFF.md`.
|
||
>
|
||
> ### HOW the SLPI was fixed (the real consumer chain Android calls `sscrpcd`)
|
||
> The SLPI boots → makes FastRPC **reverse** calls (`apps_std` fopen/fread) back to the AP to read
|
||
> `/persist/sensors/registry/...`. pmOS shipped **no AP-side listener**, so the registry sensor
|
||
> starved and the SAR (sx932x) CHRE nanoapp fataled → crash loop. The pmOS-native listener
|
||
> **`hexagonrpcd`** (linux-msm, already in the repo, `-s` = attach sensorspd on `/dev/fastrpc-sdsp`)
|
||
> is the right tool but had two gaps:
|
||
> 1. **Ran as `User=fastrpc`** → couldn't read the persist registry files. Fixed with a systemd
|
||
> drop-in `User=root` (`/etc/systemd/system/hexagonrpcd-sdsp.service.d/10-root.conf`).
|
||
> 2. **`construct_root_dir()` (rpcd_builder.c) only mapped `registry/registry/*`** — its virtual
|
||
> FS had **no nodes** for the top-level `sns_reg_config` / `sns_reg_version` / `sns_reg_ctrl`
|
||
> that blueline's SLPI requests at `/persist/sensors/registry/<file>`. hexagonfs is node-based
|
||
> (no real-FS fallthrough), so those ENOENT'd no matter what was on disk. **Patched** to add
|
||
> those three nodes (`hfs_map_or_empty`). NOTE: `hfs_map_or_empty` presents a missing physical
|
||
> file as an empty **directory** (`S_IFDIR`), which still fails a *file* open — so the physical
|
||
> file must EXIST (even 0 bytes). `sns_reg_version` is absent from the Android dump → `touch` an
|
||
> empty one and it serves as a regular empty file, which satisfies the SLPI.
|
||
> 3. Registry DATA staged to **`/usr/share/qcom/sensors/registry/`** (hexagonrpcd's default `-R`
|
||
> root; the 177 groups from the LineageOS persist dump + `sns_reg_config`, empty `sns_reg_version`,
|
||
> `sns_reg_ctrl`). Persist files also `chmod -R a+rX` (they were `0600 casey:casey` from a tar
|
||
> restore).
|
||
>
|
||
> ### STATE OF THE FIXES — now converted from live temps to REAL in-code fixes (2026-06-27)
|
||
> All of the live drop-in/temp changes have been turned into aport sources so a clean
|
||
> `pmbootstrap install` reproduces them (idempotent fresh + upgrade). What's in code now:
|
||
> - **hexagonrpcd patch → local aport** `pmaports/temp/hexagonrpcd/` (fork of Alpine community
|
||
> aport, `pkgrel=4`, adds `hexagonrpcd-blueline-registry-nodes.patch`, checksums regenerated).
|
||
> `pmbootstrap build hexagonrpcd` produces the patched binary instead of the live hand-installed
|
||
> `/usr/bin/hexagonrpcd` overwrite.
|
||
> - **root drop-in** → `device-google-blueline/hexagonrpcd-sdsp-root.conf`, installed to
|
||
> `/usr/lib/systemd/system/hexagonrpcd-sdsp.service.d/10-root.conf` (APKBUILD `package()`).
|
||
> - **registry data** → NOT shipped as blobs. `blueline-sns-registry-stage.sh` +
|
||
> `.service` (oneshot, `Before=hexagonrpcd-sdsp`, ordered after persist mount) stage the registry
|
||
> from the device's OWN `/mnt/vendor/persist/sensors/registry` into `/usr/share/qcom/sensors/registry`
|
||
> (hexagonrpcd's served root; persist layout is off-by-one for a single `-R`). Touches the empty
|
||
> `sns_reg_version`. Idempotent, ships no proprietary calibration.
|
||
> - **service enable** → preset enables `blueline-sns-registry-stage.service` + `hexagonrpcd-sdsp.service`.
|
||
> - **persist perms**: handled by the stage script's `chmod -R a+rX` on the served copy; the persist
|
||
> `chmod` I did live is NOT needed by the real fix (hexagonrpcd reads `/usr/share/qcom`, not persist).
|
||
>
|
||
> **REMAINING build/verify steps (need device + reflash — do NOT half-run unattended):**
|
||
> 1. `pmbootstrap build hexagonrpcd` (local aport) + `pmbootstrap build device-google-blueline`.
|
||
> 2. Install/upgrade on device (`pmbootstrap` sideload or apk add the built .apk) — replaces the
|
||
> hand-installed binary + lands the drop-in/stage-service/preset.
|
||
> 3. Reboot clean and VERIFY idempotency: SLPI stays up (0 `crash #` delta), provider active,
|
||
> `blueline-sns-registry-stage` populated `/usr/share/qcom/sensors/registry`.
|
||
> 4. Revert the hand-installed temps once the packages own them: restore `/usr/bin/hexagonrpcd.orig`
|
||
> is NOT needed (apk upgrade overwrites), remove the manual `systemctl enable` (preset handles it).
|
||
> - **Kernel DT vmid change** (`sdm845.dtsi` sdsp fastrpc `qcom,vmids = <HLOS SSC_Q6>`): I hand-patched
|
||
> the DTB into boot_a to test the TZ hyp-assign theory. LOGGED RESULT: with `<3 5>` live (confirmed
|
||
> via `dtc` decompile of `/sys/firmware/fdt`), `dmesg` still prints
|
||
> `SDSP fastrpc hyp-assign rejected by TZ (-22); registering node without reserved-heap assignment`
|
||
> (32 occurrences). So the vmid change did NOT change the TZ result — the crash fix was the registry
|
||
> serving, not the heap. The change is harmless but unnecessary.
|
||
> - Orig boot.img backups: scratchpad `boot.img` + `/tmp/boot-backup_a.img` on device.
|
||
> - NOTE on a reboot during testing: `lsusb` showed `18d1:d001` and SSH returned `Network is
|
||
> unreachable`; root cause was the HOST iface `enp0s20f0u6 DOWN` (per `ip -br addr`), fixed by
|
||
> `ip link set up` + `ip addr add 172.16.42.2/24` → phone answered, `uptime` = up 2 min. The
|
||
> phone had booted normally; it was a host USB-net enumeration issue, not a device boot failure.
|
||
>
|
||
> ### THE REMAINING WALL — modem `QMI 52 DeviceNotReady`, now provably INDEPENDENT of SLPI
|
||
> With SLPI fully up + sensors registry served, `mmcli -m 0 -e` still fails at DMS
|
||
> `set-operating-mode` with **QMI 52**. modem0 enumerates (QUALCOMM, SIM present, slot 2 active),
|
||
> sits `disabled / power off`, enable → `enabling → (QMI 52) → disabled`. The MSS remoteproc
|
||
> (`4080000.remoteproc`) is `running`. LOGGED: `mmcli -m 0 -e` → `state changed (disabled ->
|
||
> enabling)`, `couldn't enable interface: 'Couldn't set operating mode: QMI protocol error (52):
|
||
> DeviceNotReady'`, `state changed (enabling -> disabled)`. So 52 comes from the modem path, with the
|
||
> SLPI fully up — the two are independent.
|
||
> **Scope note:** the goal is the WHOLE device, not just telephony. The SLPI/sensors fix is a real
|
||
> bringup win on its own (sensors infra now functional). For the 52 specifically, the SLPI is not the
|
||
> lever. **Next session for 52: modem NV/EFS/identity** (the `model 0` / LOW_POWER hypothesis from
|
||
> session 2), rmtfs/EFS sync, or modem firmware-init.
|
||
>
|
||
> ### Open loose end (minor): hexagonrpcd reconnect churn
|
||
> Provider shows `activating` with ~18 restarts/min — it exits on FastRPC "Broken pipe" when the
|
||
> SLPI closes the session after serving, then `Restart=always` reattaches. SLPI stays up regardless
|
||
> (0 crashes), so it's cosmetic, but worth a `RestartSec`/keepalive tweak later.
|
||
>
|
||
> ---
|
||
>
|
||
> ## SESSION-2 UPDATE (2026-06-26 late, Opus) — CHAIN BUILT + WORKING; wall is now the modem 52 / SLPI-SAR firmware crash
|
||
>
|
||
> ### What got BUILT this session (all in pmaports `device/testing/device-google-blueline/`, deployed live + wired into APKBUILD/preset — idempotent)
|
||
> The whole consumer chain now comes up automatically on a clean boot and ModemManager
|
||
> starts + creates the modem. Verified on hardware.
|
||
> 1. **`modem-qrtr-ready.service` + `modem-qrtr-ready.sh`** (NEW) — the pmOS equivalent of
|
||
> Android's `wait_for_prop vendor.qcom.devup 1`. Blocks until modem QMI answers and is stable
|
||
> (2 probes/3s) before releasing consumers. Killed the boot race
|
||
> (`node with id 0 not found in QRTR bus`). VERIFIED: gate waits, then releases.
|
||
> 2. **UIM-selection fix** — `blueline-uim-select.sh` (NEW) wraps the stock binary: it selects the
|
||
> SIM app fine but then a trailing QMI op times out (SLPI/XPU churn) and exits 1 — a false
|
||
> negative that failed MM's hard `Requires=`. Wrapper treats "app selected" as success.
|
||
> `uim-wait.conf` rewritten: gate on modem-qrtr-ready, Type=oneshot, run the wrapper. VERIFIED
|
||
> `msm-modem-uim-selection` now = active.
|
||
> 3. **`qcril-prov.py` — fully fixed** (was crashing on `out.get_configs()`):
|
||
> - `list_configs` + `get_selected_config` reworked to read the PDC **indication**
|
||
> (`IndicationPdc*Output.get_configs()/get_active_id()`), not the response.
|
||
> - GI array-length args fixed (`set_id(id)`, `set_type_with_id_v2(t,id)`).
|
||
> - Targets configs by **sha1(.mbn) == PDC config id**; selects+activates HW + Rogers SW.
|
||
> - **Skip-if-already-active**: checks get_selected_config; if the inherited config is already
|
||
> active, skips select/activate → **0 modem restarts** (was 2). VERIFIED:
|
||
> "HW/SW already SELECTED+ACTIVE — no restart".
|
||
> - **Deadlock fix**: exits 0 after provisioning even if RF not armed (RF arming is MM's job,
|
||
> and MM is gated behind this service — requiring RF here deadlocked). VERIFIED exit 0.
|
||
> 4. **`blueline-dpm-open-port.service` / `qcril-prov.service`** — gated on modem-qrtr-ready + retry.
|
||
> 5. Kernel: mem-protect skip reverted (`980c4ae1f`); on clean baseline 7.1.1; `verify-fixes.sh` green.
|
||
>
|
||
> ### THE WALL NOW (single, precise)
|
||
> Full chain runs → **ModemManager starts, creates `modem0`** (qcom-soc plugin, 3 ports), reads the
|
||
> SIM ATR, goes `disabled → enabling` → calls set-operating-mode → **`QMI error 52 DeviceNotReady`**
|
||
> → falls back to `disabled`. This is the SAME 52 from day one. The modem is **OFFLINE, model `0`**
|
||
> (up-but-unprovisioned) and **refuses to enable even when driven correctly by MM**. So the entire
|
||
> userspace plumbing is now proven-good; the wall is the modem itself refusing RF.
|
||
>
|
||
> ### SLPI / SAR — the suspected gate (Casey's thesis), what we proved
|
||
> - SLPI **crash-loops `sar.cc:27:chre_utils fatal` every ~10s** (crash #15+). SAR = Semtech
|
||
> **SX932x**, the modem's RF SAR/TX-power sensor.
|
||
> - It is a **CHRE nanoapp crash INSIDE the SLPI firmware at init**, and **qrtr-lookup is empty —
|
||
> the SLPI never exposes an SNS QMI service before it dies**. So an AP-side QMI "SAR consumer"
|
||
> has nothing to attach to; the producer fatals first. A downstream subscribe-consumer is NOT
|
||
> the missing piece.
|
||
> - The real missing piece is whatever **feeds the SLPI its sensor registry / CHRE settings at
|
||
> init**: the SAR registry data (`sx932x_0.sar`, `.config`, `_platform.*`) IS present at
|
||
> `/persist/sensors/registry/registry/` but is **NOT delivered to the SLPI** (its RFS dir
|
||
> `/persist/rfs/msm/slpi` is empty; tqftpserv serves only `/persist/rfs`, not `/sensors`).
|
||
> - Android's consumer stack (proprietary, NO open-source equivalent):
|
||
> **`chre_daemon_msm` + `sensors.qti` + `sscrpcd`** (in `android-reference/vendor-stack-.../vendor/bin/`),
|
||
> plus the registry under `android-reference/persist-sensors-20260625/`. Our
|
||
> `drivers/soc/qcom/qcom_ssc_sensors.c` is a **passive ABI shim** — it does NOT deliver the
|
||
> registry or run CHRE, so it cannot prevent the firmware crash. This is the "shim lacking
|
||
> components LineageOS has" Casey referenced.
|
||
>
|
||
> ### NEXT ANGLE (Casey's call — start here next session)
|
||
> 1. **DECISIVE CHEAP TEST FIRST — is SAR actually the modem gate?** Stop the SLPI remoteproc so it
|
||
> is NOT crash-looping (`echo stop > /sys/class/remoteproc/remoteproc2/state`), then let MM try
|
||
> to enable the modem (or `qmicli --dms-set-operating-mode=online` once). If still **52** →
|
||
> SLPI/SAR is NOT the modem gate (independent symptoms) → stop chasing SAR for telephony and look
|
||
> elsewhere for the 52. If it **goes online** → the SLPI churn was the blocker and the SAR/CHRE
|
||
> consumer becomes critical. **Run this before building anything.**
|
||
> 2. If SAR IS the gate: the buildable "consumer" is a **registry/CHRE provider** that feeds the
|
||
> SLPI at boot (reverse the SNS/CHRE QMI registry protocol; or port pieces; or boot SLPI
|
||
> on-demand AFTER preparing its env, like LineageOS `sensors_ssc.c` does — it does NOT auto-boot
|
||
> the SLPI raw). Investigate `chre_daemon_msm` / `sscrpcd` behaviour + how the registry reaches
|
||
> the SLPI on Android (RFS path? SNS QMI? direct?).
|
||
> 3. Independent of SAR: chase **why the modem boots OFFLINE/model-0** (vs Android's LOW_POWER).
|
||
> model `0` = NV/identity not fully loaded — possible EFS/NV or firmware-init issue.
|
||
> 4. Fallback: downstream-kernel hybrid (Droidian/Halium) — the realistic telephony path if mainline
|
||
> SLPI/CHRE proves intractable.
|
||
>
|
||
> ### SAR consumer — EXACT mechanism (from slpi.mbn strings) + the build blocker
|
||
> The SLPI firmware reveals precisely what the consumer must be:
|
||
> - Reads registry from **`/persist/sensors/registry/registry`** (+ `sns_reg_config`, `sns_reg_version`).
|
||
> - **`Sending registry request for group name:%s` / `SNS_REG_INIT` / `Decoding registry group %s` /
|
||
> `Error decoding registry event`** → the SLPI **requests registry groups over the SNS QMI service
|
||
> and expects encoded registry-event responses**. The SAR (sx932x) nanoapp fatals (`sar.cc:27
|
||
> chre_utils fatal`) when it can't get its group → crash-loop.
|
||
> - Fallback strings exist: **`Registry disabled, leaving default mode enabled` / `LPI Registry
|
||
> Disabled`** — there may be a registry-disabled mode worth forcing (SAR likely still needs its
|
||
> device config though).
|
||
> - **The consumer = an SNS registry provider** (QRTR/QMI daemon) that reads
|
||
> `/persist/sensors/registry/registry/<group>` and answers the SLPI's requests. On Android this is
|
||
> `sensors.qti` + `sscrpcd` + `chre_daemon_msm` (binary-only in
|
||
> `android-reference/vendor-stack-20260621/vendor/bin/`).
|
||
> - **BUILD BLOCKER (why it's not done):** the SNS protocol is Qualcomm proprietary protobuf
|
||
> (`sns_client.proto` / `sns_registry`); there are **NO .proto defs or SNS source anywhere in the
|
||
> tree** — only the registry DATA and the binary daemons. A working provider needs that encoding;
|
||
> building blind yields non-functional code. Options: (a) extract/RE the SNS protobuf from the
|
||
> vendor .so (`libsnsapi`/`sensors.qti`) — multi-day; (b) find an open SNS impl to port;
|
||
> (c) run the vendor `sscrpcd`/`sensors.qti` binaries under a libhybris/Halium shim;
|
||
> (d) downstream-kernel hybrid (sidesteps mainline SLPI entirely).
|
||
>
|
||
> ### CLEAN decisive test to run next boot (settles whether SAR even gates the modem — do BEFORE any SNS build)
|
||
> The session test was contaminated (modem already poisoned by prior online attempts). Clean version:
|
||
> `systemctl mask ModemManager qcril-prov qcril-autoselect blueline-dpm-open-port` → reboot →
|
||
> on boot immediately `echo stop > /sys/class/remoteproc/remoteproc2/state` (kill SLPI before it
|
||
> crash-loops) → wait for modem QMI up → ONE `qmicli -p -d qrtr://0 --dms-set-operating-mode=online`.
|
||
> - Still **52** with SLPI cleanly stopped from boot → **SLPI/SAR is NOT the modem gate** (the 52 /
|
||
> model-0 is independent — chase modem NV/EFS/firmware-init instead; don't invest in the SNS build).
|
||
> - **Goes online** → SLPI/SAR churn WAS the blocker → the SNS registry provider is worth the build.
|
||
> Unmask afterwards: `systemctl unmask ModemManager qcril-prov qcril-autoselect blueline-dpm-open-port`.
|
||
>
|
||
> ### Files touched this session (for the next agent)
|
||
> - `references/linux-7.1.1-sdm845-CANONICAL` @ `980c4ae1f` (revert skip); `tools/verify-fixes.sh` (skip-absent check)
|
||
> - pmaports `device/testing/device-google-blueline/`: `qcril-prov.py`, `modem-qrtr-ready.sh`+`.service`,
|
||
> `blueline-uim-select.sh`, `uim-wait.conf`, `blueline-dpm-open-port.service`, `qcril-prov.service`,
|
||
> `APKBUILD`, `80-device-google-blueline.preset`. All also deployed live to the phone.
|
||
> - NOTE: APKBUILD `sha512sums` NOT yet regenerated for the new/changed sources — run
|
||
> `pmbootstrap checksum device-google-blueline` before the next package build.
|
||
|
||
---
|
||
|
||
|
||
THE session that reframed the whole problem. The modem-online blocker is **not** (only) a
|
||
kernel/secure-load issue — it is that the **userspace consumer chain that drives the modem is
|
||
half-built / failing**, exactly as Casey kept saying. Everything below is VERIFIED LIVE on the
|
||
reverted-baseline 7.1.1 build, not inference.
|
||
|
||
## TL;DR causal chain (verified end to end)
|
||
1. Modem firmware boots, MBA loads MPSS, modem reaches `running`. It has identity (IMEI
|
||
990012001581294, ESN 8074BB5D, MEID, SW `g845-00194-210812`). **The assign/-22/secure-load is
|
||
NOT the modem blocker** — the modem loads. (The only `-22`s are fastrpc + ath10k wifi, both
|
||
tolerated.) One XPU violation at boot, self-recovers (Casey was right).
|
||
2. BUT the modem comes up **op-mode OFFLINE (3), model `0`** = up-but-unprovisioned/not-ready.
|
||
`--dms-set-operating-mode=online` → **QMI 52 DeviceNotReady**. Forcing online does nothing.
|
||
3. **SLPI crash-loops every ~10s**: `err_qdi.c:456:EF:sensor_process:1:sar.cc:27:chre_utils fatal`
|
||
→ recover → up → crash. SAR (Semtech SX932x) is the modem's RF SAR/TX-power sensor.
|
||
4. The modem+SLPI instability makes the **QRTR node flap**, so the boot-time consumer services
|
||
race an unready modem and **fail**:
|
||
- `msm-modem-uim-selection.service` → `node with id 0 not found in QRTR bus` (boot) /
|
||
`Transaction timed out` (later). **This is a hard `Requires=` of ModemManager.**
|
||
- `blueline-dpm-open-port.service` → `node with id 0 not found` at boot (succeeds if re-run later).
|
||
- `qcril-prov.service` → crashed on a code bug (now FIXED, see below).
|
||
5. Because `msm-modem-uim-selection` (hard dep) failed → **ModemManager never started at boot.**
|
||
So nothing ever drove the modem: enable → set-power → register. It just sits OFFLINE.
|
||
6. Started MM manually (bypassing deps): it DOES reach the modem over qrtr://0, creates `modem0`,
|
||
reads the SIM ATR — then fails: **`couldn't start parent initialization: Couldn't get primary
|
||
port`** and `couldn't load carrier config: Operation timed out`. MM can't initialize a modem
|
||
that's OFFLINE/flapping.
|
||
|
||
## What is SOLID now (do not redo)
|
||
- On reverted-baseline 7.1.1 (`blueline` branch, mem-protect skip reverted `980c4ae1f`). Built,
|
||
flashed `boot_a`, deployed. `verify-fixes.sh` green (13 checks; mem-protect check now asserts the
|
||
skip is ABSENT). Android slot B / EFS / userdata untouched.
|
||
- ~~pd-mapper: in-kernel `CONFIG_QCOM_PD_MAPPER=m`, module loaded … **pd-mapper is fine — ruled
|
||
out.**~~ **WRONG (corrected 2026-06-29).** The pmaports config sets `=m`, but the running kernel
|
||
has `# CONFIG_QCOM_PD_MAPPER is not set` — the in-tree `arch/arm64/configs/sdm845.config` carries
|
||
the upstream `=n` and `merge_config.sh -m` applies it *after* the pmaports config, so `=n` wins
|
||
every build. Userspace pd-mapper is also uninstalled ⇒ **no pd-mapper of either kind runs.** Caught
|
||
via the wifi outage (no `wlan0`; ath10k_snoc bound but probe defers with no wlan PD). The Mobian
|
||
0171 observation stands, but "pd-mapper is fine" did not. Fixed: in-tree fragment → `=m` (commit
|
||
pending), then rebuild+reflash. Whether this also unblocks the modem-52 is now an open re-test, not
|
||
a closed lead.
|
||
- Infra present & correct: `rmtfs -P -s` (block EFS), `tqftpserv` (serves `/persist/rfs` →
|
||
modem mcfg), sensor registry 177 files at `/mnt/vendor/persist/sensors/registry/registry/`,
|
||
all mcfg carrier configs incl `mcfg_sw/generic/NA/Rogers/Commercial/CA/mcfg_sw.mbn`.
|
||
- udev tags MM correctly: `ID_MM_QCOM_SOC=1`, `ID_MM_CANDIDATE=1` on rmnet_ipa0; MM qcom-soc
|
||
plugin loads. Transport (QMI-over-QRTR) works — MM exchanges QMI with the modem.
|
||
|
||
## FIXED this session — qcril-prov.py (the MBN provisioner)
|
||
Source: `pmaports/device/testing/device-google-blueline/qcril-prov.py` (also live-deployed to
|
||
`/usr/bin/qcril-prov.py` on phone). Was crashing; now runs end-to-end and provisions Rogers.
|
||
Bugs fixed (all real, in code):
|
||
1. `list_configs` read configs from the response (`out.get_configs()` — doesn't exist;
|
||
`MessagePdcListConfigsOutput` only has `get_result`). The config list arrives via the
|
||
**`list-configs` INDICATION** → `IndicationPdcListConfigsOutput.get_configs()`; each element has
|
||
`.id` + `.config_type` only. Reworked to indication-driven (mirrors the working `load-config`).
|
||
2. GI array-length args: `set_id(cfg_id, len)` → `set_id(cfg_id)`; `set_type_with_id_v2(t,id,len)`
|
||
→ `set_type_with_id_v2(t,id)`. (`set_config_chunk` was already correct.)
|
||
3. Strategy: blueline INHERITS Android's full mcfg set (1 platform + 25 software) on shared
|
||
persist. Don't delete+reload (delete is a no-op; reload → error 41 "already exists"). Instead:
|
||
compute target id = **sha1 of the .mbn file** (== the PDC config id, verified: HW sha1
|
||
`6fe571a9…` matched the on-modem id), confirm present, **select + activate by sha1**. Treat
|
||
load error_code=41 as success. Helpers added: `_sha1_id`, `_hex`, `_id_present`.
|
||
Result: provisioner selects+activates HW (platform) and Rogers (software) configs cleanly. The
|
||
modem still ends OFFLINE afterward (carrier config alone doesn't lift it — needs MM to drive it).
|
||
|
||
## THE PLAN (next session — ordered)
|
||
Goal: get ModemManager to fully initialize the modem and drive OFFLINE → online → registered.
|
||
Two intertwined blockers: (A) modem won't initialize while OFFLINE/flapping; (B) SLPI crash-loop.
|
||
|
||
1. **Make MM actually manage the modem (primary blocker).**
|
||
- Why `Couldn't get primary port`? Check MM qcom-soc plugin port expectations for a pure-QRTR
|
||
SDM845 modem; check nothing else holds the QMI client (our qcril-* one-shots, the stray
|
||
`dbus-monitor`, manual `qmicli -p`). Try MM with everything else stopped.
|
||
- Fix the boot ORDERING/retry so `msm-modem-uim-selection` + `blueline-dpm-open-port` +
|
||
`qcril-prov` don't race the unready modem: add wait-for-QRTR-node / Restart=on-failure /
|
||
proper `After=` on a "modem-qrtr-up" condition. This is how the chain stays up like Lineage
|
||
(Lineage's RIL waits for the modem to be ready before UIM select / PDC).
|
||
- Once MM inits: it should set-power-up and the OFFLINE→online may resolve via MM's sequence
|
||
(it owns DMS set-operating-mode). The manual `online`=52 is because nothing did the proper
|
||
enable sequence first.
|
||
|
||
2. **SLPI SAR crash-loop (`sar.cc:27`).** SAR = SX932x, governs RF TX-power; Casey's position is
|
||
it gates modem RF. The SLPI sensor REGISTRY (`/persist/sensors/registry`) is NOT served to the
|
||
SLPI — tqftpserv serves `/persist/rfs` only (sibling tree). Leads:
|
||
- Does the SLPI read registry via tqftpserv (needs `/sensors` served too) or a different path?
|
||
The tqftp log shows only modem mcfg requests, no `/sensors` requests → SAR may crash BEFORE
|
||
requesting registry (early init / SX932x i2c on the SLPI bus). Investigate how LineageOS
|
||
`sensors_ssc.c` + sensor HAL bring SAR up (registry delivery + SX932x i2c/GPIO).
|
||
- Our `qcom_ssc_sensors.c` is a passive ABI shim; it does NOT boot or feed the SLPI. Mainline
|
||
auto-boots the SLPI (DTS firmware-name) with no consumer → SAR talks to nobody → crash.
|
||
LineageOS boots SLPI ON DEMAND after the sensor HAL is up.
|
||
|
||
3. **Verify on a clean boot**: fix the services so the whole chain comes up at boot (not manually),
|
||
reboot, confirm MM auto-starts, modem → registered. One online attempt per boot still applies.
|
||
|
||
## Hard constraints (unchanged)
|
||
- pmOS = slot A; flash ONLY boot_a. NEVER touch Android slot B / EFS (modemst1/2,fsg,fsc) /
|
||
userdata / TZ-XBL-ABL. rmtfs `-P -s`. No pmic@4/5 SPMI nodes. One `online` attempt per boot.
|
||
sudo pw 147147. USB 172.16.42.1 (host iface enp0s20f0u6 → `ip addr add 172.16.42.10/24`).
|
||
- pmOS is Alpine/ash: embedded `sh -c "...(...)..."` with parens fails — use script files via scp.
|