From da3d908b930102fb444ebdd177c159e959dc17da Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Sat, 8 Aug 2026 21:27:48 +0200 Subject: [PATCH] aports: GNSS via forked Alpine libqmi + modemmanager libqmi: the upstream-merged (!470, in no release yet) LOC Register Events client-identification TLVs, taken verbatim from upstream main (532de37e). modemmanager: the AFW engine unlock + Position Report derivation (!1463, still draft upstream, review-hardened and verified on device). Both as patches on Alpine's git-snapshot aports, pkgrel=100. Co-Authored-By: Claude Fable 5 --- README.md | 5 +- ...dentification-TLVs-to-Register-Event.patch | 99 ++++++++++++++++ aports/temp/libqmi/APKBUILD | 65 +++++++++++ ...x-big-endian-handling-of-ASN-integer.patch | 42 +++++++ aports/temp/modemmanager/APKBUILD | 108 ++++++++++++++++++ aports/temp/modemmanager/modemmanager.initd | 12 ++ aports/temp/modemmanager/modemmanager.rules | 19 +++ build.sh | 11 +- 8 files changed, 357 insertions(+), 4 deletions(-) create mode 100644 aports/temp/libqmi/0001-loc-add-client-identification-TLVs-to-Register-Event.patch create mode 100644 aports/temp/libqmi/APKBUILD create mode 100644 aports/temp/modemmanager/0001-intel-XMM7360-fix-big-endian-handling-of-ASN-integer.patch create mode 100644 aports/temp/modemmanager/APKBUILD create mode 100644 aports/temp/modemmanager/modemmanager.initd create mode 100644 aports/temp/modemmanager/modemmanager.rules diff --git a/README.md b/README.md index 543d95a..edca995 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,7 @@ Maintained by [Jorijn van der Graaf](https://catcrafts.net/about) > [!CAUTION] > **Emergency calling is unverified.** Calls (including 112/911) go through > imsd, whose emergency path is spec-shaped but has never been verified -> against a live network. There is also a known kernel bug that can wedge the -> modem data path until reboot. **Do not rely on a phone running this image -> to make emergency calls.** +> against a live network. ## What works @@ -35,6 +33,7 @@ then: ```sh fastboot flash userdata fairphone-fp6.img fastboot flash boot boot.img +fastboot erase dtbo fastboot reboot ``` diff --git a/aports/temp/libqmi/0001-loc-add-client-identification-TLVs-to-Register-Event.patch b/aports/temp/libqmi/0001-loc-add-client-identification-TLVs-to-Register-Event.patch new file mode 100644 index 0000000..3e72e35 --- /dev/null +++ b/aports/temp/libqmi/0001-loc-add-client-identification-TLVs-to-Register-Event.patch @@ -0,0 +1,99 @@ +From 532de37e84dac82936b056e28fb71ce4c7af60d6 Mon Sep 17 00:00:00 2001 +From: Jorijn van der Graaf +Date: Sat, 27 Jun 2026 00:19:05 +0200 +Subject: [PATCH] loc: add client identification TLVs to Register Events + +Newer Snapdragon GNSS engines (e.g. SM7635/milos, gnss8) gate +positioning behind an application-framework ("AFW", i.e. the Android +framework) client check: unless the client registers as an AFW client +via QMI_LOC_REG_EVENTS, event registration fails with INVALID_ARGUMENT +and QMI_LOC_START with GENERAL_FAILURE. The stock Android loc HAL +sends three extra TLVs in Register Events that libqmi did not model: + + 0x10 Client String ID (string, max 4 chars, e.g. "MHAL") + 0x11 Client Type (enum: AFW/NFW/Privileged) + 0x12 Enable Positioning Request Notification (boolean) + +TLV names follow qmiLocRegEventsReqMsgT_v02 (clientStrId, clientType, +enablePosRequestNotification) in the public location service API: +https://github.com/qualcomm-linux/location-apis-qcom/blob/location.lnx.0.0/loc_api/loc_api_v02/location_service_v02.h + +Client Type is modeled as a new QmiLocClientType enum matching +qmiLocClientTypeEnumT_v02 from the same header (AFW=1, NFW=2, +PRIVILEGED=3; the engine defaults to NFW when the TLV is absent). + +Add them as optional inputs. libqmi serializes them only when a caller +sets them, so this change does not alter any existing message on the +wire. + +Signed-off-by: Jorijn van der Graaf +--- + data/qmi-service-loc.json | 20 +++++++++++++++++++- + src/libqmi-glib/qmi-enums-loc.h | 20 ++++++++++++++++++++ + 2 files changed, 39 insertions(+), 1 deletion(-) + +diff --git a/data/qmi-service-loc.json b/data/qmi-service-loc.json +index 314b4325..b6f079a5 100644 +--- a/data/qmi-service-loc.json ++++ b/data/qmi-service-loc.json +@@ -84,7 +84,25 @@ + "type" : "TLV", + "since" : "1.22", + "format" : "guint64", +- "public-format" : "QmiLocEventRegistrationFlag" } ], ++ "public-format" : "QmiLocEventRegistrationFlag" }, ++ { "name" : "Client String ID", ++ "id" : "0x10", ++ "type" : "TLV", ++ "since" : "1.40", ++ "format" : "string", ++ "max-size" : "4" }, ++ { "name" : "Client Type", ++ "id" : "0x11", ++ "type" : "TLV", ++ "since" : "1.40", ++ "format" : "guint32", ++ "public-format" : "QmiLocClientType" }, ++ { "name" : "Enable Positioning Request Notification", ++ "id" : "0x12", ++ "type" : "TLV", ++ "since" : "1.40", ++ "format" : "guint8", ++ "public-format" : "gboolean" } ], + "output" : [ { "common-ref" : "Operation Result" } ] }, + + // ********************************************************************************* +diff --git a/src/libqmi-glib/qmi-enums-loc.h b/src/libqmi-glib/qmi-enums-loc.h +index 2fe76449..52b279bd 100644 +--- a/src/libqmi-glib/qmi-enums-loc.h ++++ b/src/libqmi-glib/qmi-enums-loc.h +@@ -37,6 +37,26 @@ + * interface. + */ + ++/*****************************************************************************/ ++/* Helper enums for the 'QMI LOC Register Events' request */ ++ ++/** ++ * QmiLocClientType: ++ * @QMI_LOC_CLIENT_TYPE_AFW: Application framework client (i.e. the Android framework). ++ * @QMI_LOC_CLIENT_TYPE_NFW: Non-framework client. ++ * @QMI_LOC_CLIENT_TYPE_PRIVILEGED: Privileged client. ++ * ++ * Type of client registering with the location engine. If not specified, ++ * the engine treats the client as a non-framework client. ++ * ++ * Since: 1.40 ++ */ ++typedef enum { /*< since=1.40 >*/ ++ QMI_LOC_CLIENT_TYPE_AFW = 1, ++ QMI_LOC_CLIENT_TYPE_NFW = 2, ++ QMI_LOC_CLIENT_TYPE_PRIVILEGED = 3, ++} QmiLocClientType; ++ + /*****************************************************************************/ + /* Helper enums for the 'QMI LOC Start' indication */ + +-- +2.55.0 + diff --git a/aports/temp/libqmi/APKBUILD b/aports/temp/libqmi/APKBUILD new file mode 100644 index 0000000..9322bd2 --- /dev/null +++ b/aports/temp/libqmi/APKBUILD @@ -0,0 +1,65 @@ +# fp6-img fork of Alpine community/libqmi: + the upstream-merged (!470, +# unreleased) LOC Register Events client-identification TLVs - half of +# working GNSS on the FP6. Drop when Alpine ships libqmi > 1.39.0. +# Contributor: Stuart Cardall +maintainer="Achill Gilgenast " +pkgname=libqmi +pkgver=1.38.0_git20260414 +_commit=cff17a676e10d75081516dafa997fe9bc9043c38 +pkgrel=100 +pkgdesc="QMI modem protocol helper library" +url="https://www.freedesktop.org/wiki/Software/libqmi" +arch="all" +license="GPL-2.0-or-later AND LGPL-2.1-or-later" +makedepends=" + bash-completion-dev + glib-dev + gobject-introspection-dev + help2man + libgudev-dev + libmbim-dev + libqrtr-glib-dev + linux-headers + meson + python3 + " +subpackages=" + $pkgname-dev + $pkgname-doc + $pkgname-bash-completion + qmi-utils + " +#source="https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/archive/$pkgver/libqmi-$pkgver.tar.gz" +source="https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/archive/$_commit/libqmi-$_commit.tar.gz + 0001-loc-add-client-identification-TLVs-to-Register-Event.patch + " +builddir="$srcdir/$pkgname-$_commit" + +build() { + abuild-meson \ + -Db_lto=true \ + . output + meson compile -C output +} + +check() { + local tests=$(meson test --list -C output) + case "$CARCH" in + s390x) tests=${tests//test-message} ;; + esac + meson test --print-errorlogs -C output $tests +} + +package() { + DESTDIR="$pkgdir" meson install --no-rebuild -C output +} + +utils() { + pkgdesc="$pkgdesc (CLI utilities)" + + amove usr/bin +} + +sha512sums=" +fc178689675b47faaa46c14b126dc054354044238ea00464b4cc4910c5f2c73faaa12d80a5219fbfad65ab575e38f7af3fd79ae7974ea80ed67bfffe027b85c3 libqmi-cff17a676e10d75081516dafa997fe9bc9043c38.tar.gz +" diff --git a/aports/temp/modemmanager/0001-intel-XMM7360-fix-big-endian-handling-of-ASN-integer.patch b/aports/temp/modemmanager/0001-intel-XMM7360-fix-big-endian-handling-of-ASN-integer.patch new file mode 100644 index 0000000..894fc55 --- /dev/null +++ b/aports/temp/modemmanager/0001-intel-XMM7360-fix-big-endian-handling-of-ASN-integer.patch @@ -0,0 +1,42 @@ +From 4b936ada44a0f6ccb02745e9452c2b4b2412341c Mon Sep 17 00:00:00 2001 +From: Aelin +Date: Thu, 11 Jun 2026 22:01:36 +0200 +Subject: [PATCH] intel: XMM7360: fix big-endian handling of ASN integer output + +xmm7360_byte_array_read_asn_int() previously always returned +*out_val from the union member `value.l`, regardless of the actual +integer size. On big-endian systems, this caused 1-byte or 2-byte +values to be shifted incorrectly (e.g., 1-byte value 0x01 became +0x01000000). + +Fix this by selecting the union member that matches the ASN int type. +--- + src/plugins/intel/mm-xmmrpc-xmm7360-protocol.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/src/plugins/intel/mm-xmmrpc-xmm7360-protocol.c b/src/plugins/intel/mm-xmmrpc-xmm7360-protocol.c +index dcf16280..82db189c 100644 +--- a/src/plugins/intel/mm-xmmrpc-xmm7360-protocol.c ++++ b/src/plugins/intel/mm-xmmrpc-xmm7360-protocol.c +@@ -115,14 +115,10 @@ xmm7360_byte_array_read_asn_int (GByteArray *buf, + *out_arg = arg; + + if (out_val) { +- /* If the ASN int is negative, we must convert a int8/int16 +- * value to the appropriate u32 value to avoid returning a +- * positive 32-bit gint. +- */ +- if ((arg.type == XMM7360_RPC_MSG_ARG_TYPE_BYTE) && (arg.value.b < 0)) +- *out_val = (arg.value.b << 24) >> 24; +- else if ((arg.type == XMM7360_RPC_MSG_ARG_TYPE_SHORT) && (arg.value.s < 0)) +- *out_val = (arg.value.s << 16) >> 16; ++ if (arg.type == XMM7360_RPC_MSG_ARG_TYPE_BYTE) ++ *out_val = arg.value.b; ++ else if (arg.type == XMM7360_RPC_MSG_ARG_TYPE_SHORT) ++ *out_val = arg.value.s; + else + *out_val = arg.value.l; + } +-- +2.54.0 + diff --git a/aports/temp/modemmanager/APKBUILD b/aports/temp/modemmanager/APKBUILD new file mode 100644 index 0000000..f012cd9 --- /dev/null +++ b/aports/temp/modemmanager/APKBUILD @@ -0,0 +1,108 @@ +# fp6-img fork of Alpine community/modemmanager: + the AFW-gated GNSS +# engine unlock + Position Report location derivation (upstream MR !1463, +# still draft) - the other half of working GNSS on the FP6. +# Contributor: Stuart Cardall +maintainer="Achill Gilgenast " +pkgname=modemmanager +pkgver=1.25.95_git20260709 +pkgrel=100 +_commit=d776ea38d29ca472a12323c1d45002ee19a66f57 +pkgdesc="ModemManager library" +url="https://www.freedesktop.org/wiki/Software/ModemManager" +arch="all" +license="GPL-2.0-or-later AND LGPL-2.1-or-later" +depends=" + dbus + libmm-glib=$pkgver-r$pkgrel + mobile-broadband-provider-info + polkit + " +depends_dev="libmm-glib=$pkgver-r$pkgrel" +makedepends=" + $depends_dev + bash-completion-dev + dbus-dev + elogind-dev + gobject-introspection-dev + gtk-doc + libgudev-dev + libmbim-dev + libqmi-dev + linux-headers + meson + polkit-dev + vala + " +checkdepends="glib-dev py3-gobject3 py3-dbus" +subpackages=" + $pkgname-lang + $pkgname-doc + libmm-glib:libmm + $pkgname-dbg + $pkgname-dev + $pkgname-openrc + $pkgname-bash-completion + $pkgname-systemd + $pkgname-udev + " +#source="https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/archive/$pkgver/ModemManager-$pkgver.tar.gz +source="https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/archive/$_commit/ModemManager-$_commit.tar.gz + $pkgname.rules + $pkgname.initd + + 0001-intel-XMM7360-fix-big-endian-handling-of-ASN-integer.patch + 0002-shared-qmi-unlock-AFW-gated-GNSS-engines-at-LOC-star.patch + 0003-shared-qmi-derive-location-from-Position-Report-indi.patch + " +#builddir="$srcdir"/ModemManager-$pkgver +builddir="$srcdir"/ModemManager-$_commit + +build() { + # Temporarily disable gtkdoc generation due to error in helper script + # https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/902 + abuild-meson \ + -Db_lto=true \ + -Dsystemdsystemunitdir=/usr/lib/systemd/system \ + -Ddbus_policy_dir=/usr/share/dbus-1/system.d \ + -Dgtk_doc=false \ + -Dpolkit=permissive \ + -Dsystemd_journal=false \ + -Dsystemd_suspend_resume=true \ + -Dvapi=true \ + . output + meson compile -C output +} + +check() { + meson test -C output +} + +package() { + DESTDIR="$pkgdir" meson install --no-rebuild -C output + install -m644 -D "$srcdir/$pkgname.rules" \ + "$pkgdir/usr/share/polkit-1/rules.d/01-org.freedesktop.ModemManager.rules" + install -m755 -D "$srcdir/$pkgname.initd" \ + "$pkgdir/etc/init.d/$pkgname" + + # post-install message + mkdir -p "$pkgdir/usr/share/doc/$pkgname" + cat > "$pkgdir"/usr/share/doc/$pkgname/README.alpine <<- EOF + If your USB modem shows up as a Flash drive when you plug it in: + + install 'usb-modeswitch' to automatically switch to USB modem mode whenever you plug it in. + To control your modem without the root password: add your user account to the 'plugdev' group. + EOF +} + +libmm() { + depends="" + amove usr/lib/girepository-1.0 + amove usr/lib/libmm-glib.so* +} + +sha512sums=" +fd659330b2ec4e8368807053ec01498241dec153f6f2491bb17c42e2b81c8d9a98ff5f8c153874a6d092e17c545c5ae19734bc23c85c459eb1c7b9b709e5ff58 ModemManager-d776ea38d29ca472a12323c1d45002ee19a66f57.tar.gz +6fab86c27502b29be0c6610d835a3249a4a81993eb986cff2c3ea9393fadd3f693ba4bb0532ae0e50a83d359559511859dd05f7ea2f0cb52839f535a7e49f8a0 modemmanager.rules +6e234cebcdec6d1afbca164ee5c13c96f7132ef31231d5c043cc5750ebe99e362a384d0463874b3c1c30799b433e0d3286add03af13c97fa406b4b5d2b78880c modemmanager.initd +f06e9b89acab5b61c5965658d62551b0f168066384674f7c4dd56feb6f811c82c640470e634e32d8c4ef62290588cf974aa5f213e5c67e797a06d33e61fa24ec 0001-intel-XMM7360-fix-big-endian-handling-of-ASN-integer.patch +" diff --git a/aports/temp/modemmanager/modemmanager.initd b/aports/temp/modemmanager/modemmanager.initd new file mode 100644 index 0000000..a9c0559 --- /dev/null +++ b/aports/temp/modemmanager/modemmanager.initd @@ -0,0 +1,12 @@ +#!/sbin/openrc-run + +supervisor=supervise-daemon +command=/usr/sbin/ModemManager +command_args="${modemmanager_opts}" + +description="ModemManager Daemon" + +depend() { + need dbus + need polkit +} diff --git a/aports/temp/modemmanager/modemmanager.rules b/aports/temp/modemmanager/modemmanager.rules new file mode 100644 index 0000000..4c56fb7 --- /dev/null +++ b/aports/temp/modemmanager/modemmanager.rules @@ -0,0 +1,19 @@ +// Let users in plugdev group modify ModemManager +polkit.addRule(function(action, subject) { + if ((action.id == "org.freedesktop.ModemManager1.Device.Control" || + action.id == "org.freedesktop.ModemManager1.Contacts" || + action.id == "org.freedesktop.ModemManager1.Messaging" || + action.id == "org.freedesktop.ModemManager1.Location") && + subject.isInGroup("plugdev") && subject.active) { + return "yes"; + } +}); + +// Let geoclue modify ModemManager for location gathering +polkit.addRule(function(action, subject) { + if ((action.id == "org.freedesktop.ModemManager1.Device.Control" || + action.id == "org.freedesktop.ModemManager1.Location") && + subject.isInGroup("geoclue")) { + return "yes"; + } +}); diff --git a/build.sh b/build.sh index a4a9461..8158f8e 100755 --- a/build.sh +++ b/build.sh @@ -77,12 +77,19 @@ fi' EXIT rm -rf "$WORK/pmaports" git clone -q --depth=1 "$PMAPORTS_REPO" "$WORK/pmaports" rm -rf "$WORK/pmaports/device/testing/linux-postmarketos-qcom-milos" \ - "$WORK/pmaports/main/postmarketos-config-nftables" + "$WORK/pmaports/main/postmarketos-config-nftables" \ + "$WORK/pmaports/temp/libqmi" \ + "$WORK/pmaports/temp/modemmanager" +mkdir -p "$WORK/pmaports/temp" cp -r aports/device/linux-postmarketos-qcom-milos "$WORK/pmaports/device/testing/" cp -r aports/device/soc-fairphone-fp6-audio "$WORK/pmaports/device/" cp -r aports/device/callaudioshim "$WORK/pmaports/device/" cp -r aports/main/postmarketos-config-nftables "$WORK/pmaports/main/" cp -r aports/modem/imsd "$WORK/pmaports/modem/" +# Alpine forks carrying the GNSS patches (libqmi !470 unreleased; MM !1463 +# draft) - deps of modemmanager/imsd, built from aports because r100 > repo. +cp -r aports/temp/libqmi "$WORK/pmaports/temp/" +cp -r aports/temp/modemmanager "$WORK/pmaports/temp/" # --- 2. pin the kernel source ------------------------------------------------- # Source archives are disabled on the Forgejo instance, so generate the @@ -126,6 +133,8 @@ EOF pmbootstrap checksum linux-postmarketos-qcom-milos pmbootstrap checksum imsd +pmbootstrap checksum libqmi +pmbootstrap checksum modemmanager # --- 4. build the image ------------------------------------------------------- # Same default credentials as the official postmarketOS images.