Repository navigation
Releases
v1.4.8
Two changes from @h3nnes:
- Restart modem while read-only is on (#8). The menu item now opens a confirmation explaining that a restart requires write mode. Confirming enables writes and restarts the modem. Writes remain enabled afterwards. With writes already enabled, restart works as before.
- Disable NR 1024QAM TDD (#9). A new per-SIM feature toggle updates
cap_feature_band_nr_v2with a read-modify-write operation, preserving the other existing bytes. A failed read prevents the write.
The app and bundled helper both report 1.4.8.
Validation: 223 daemon protocol checks and 89 Android unit tests passed; the release APK was built and its signing certificate verified. No physical-device testing was performed for this release. The new 1024QAM toggle's effect on modem capabilities has not been independently verified on hardware.
v1.4.7
Snapdragon 865/870 with the X55 modem
Phones built on the Snapdragon 865, 865+ and 870 — Poco F3, Mi 10/11i, OnePlus 8, ROG Phone 3, the US Galaxy S20 and others — could not connect at all. They failed with "EFS2 did not answer on subsystem 0x3E or 0x13 (bad command)". Thanks to @victor186 for the verbose log that pinned it down (#5).
On these phones the modem is a separate chip, the X55, attached over PCIe. Its DIAG never appears on the QRTR bus, where the helper looks: only the phone's DSPs publish DIAG there. The helper took the first of those, an audio DSP with no EFS behind it.
Two changes:
- Only the modem's own DIAG is used. DIAG endpoints that belong to a DSP are skipped, and the error names them instead of failing with a puzzling "bad command".
- An external modem is reached through
/dev/diag. When the bus has no modem DIAG, the helper opens/dev/diag, asks the kernel driver to route to the external modem, and takes only the answers that come from it. SELinux is not touched; it works under enforcing.
Phones that already worked are unaffected: QRTR is still tried first, and they take exactly the path they took before.
Status on the X55: confirmed on a Poco F3 that the app connects and lists the EFS. Reading file contents, writing and restarting the modem over /dev/diag have not been confirmed on that hardware yet — if you try them, a report with Verbose helper log ticked is very welcome. Back up EFS before writing anything, as always.
The verbose log's bus scan now tells the modem's DIAG apart from a DSP's, so on any phone it says plainly whether the modem is on the bus.
The bundled helper is 1.4.7, matching the app.
v1.4.6
Disable TDD-only UL MIMO
A new one-way toggle in Disable features. It limits the TDD NR bands n38, n40, n41, n48, n77, n78, n79 and n104 to a single transmit layer — no UL MIMO on those bands — and leaves everything else as it was. It is the counterpart of the existing Disable FDD-only UL MIMO.
It writes cap_limit_rf_mimo, the same file that Disable UL MIMO and Disable Lowbands 4Rx use, so the three toggles are mutually exclusive: turning one on replaces whichever of the others was in effect. After every write the dialog re-reads all statuses, so it always shows which one is actually active.
The band list covers the common TDD bands rather than every one: the file has room for ten band entries.
As with every toggle on this screen, back up EFS first, and restart the modem afterwards for the change to take effect.
The bundled helper is 1.4.6, matching the app; nothing in the helper changed besides its version.
v1.4.5
Everything here is about waiting less. All of it was measured on an SM8350, old build against new on the same session.
Restarting the modem: 8.1s → 3.1-6.2s
The helper used to sleep a flat 8 seconds and hope the modem was back. It now watches the QRTR bus instead: DIAG is registered again when the modem is up, and that is the moment the session is rebuilt. So the wait is as long as the restart really takes, and no longer — and a modem slower than the old 8 seconds is no longer given up on, which it used to be.
Every change commits ~3x faster
Since 1.4.1 each delete, mkdir, chmod, save and NV write commits the EFS journal, and that commit waited up to a second for a "done" this target never reports. 1.03s → 0.11-0.32s, on every one of them.
Flush EFS journal twice in a row used to sit for 1.2 seconds and then report efs errno=306. Nothing has changed since the last commit in that case, so the helper no longer asks the modem at all: it is instant, and it is not an error.
Connecting: about a second quicker
Starting the helper waited a fixed second. It now waits for the helper to say it is listening — 1.03s → 0.03-0.12s.
File-by-file backup: a quarter faster
The walk stated every file for a size the directory listing had already given it. That round trip is gone: over 52 files, 271 DIAG round trips → 219, 0.58s → 0.45s. Empty files cost nothing at all now.
Two other ideas were measured and dropped: this modem caps every read at 1024 bytes however much is asked for, and item files open through the ordinary file interface perfectly well, so neither bigger chunks nor a different item-file path had anything to give.
Housekeeping
Listings were being sorted twice, the inline-read limit was written down in two places (the helper reports it now), the hex dump formatted every byte through String.format, and Ui.kt had grown to 1300 lines — it is now three files. No visible change from any of it.
The bundled helper is 1.4.5, matching the app.
v1.4.4
Reconnect without leaving the browser
The overflow menu has a Reconnect item. It starts a fresh helper and session and puts you back in the folder you were in — or on the root, if that folder is gone. Before, getting back from a dropped session meant returning to the start screen and navigating all the way down again.
It is always there while browsing. A session can go stale in ways the app cannot detect — the helper killed while the app sat in the background, or a modem restart sent as a raw DIAG packet, which leaves the helper talking to a modem that went away — and reconnecting a healthy session costs only a couple of seconds. The read-only lock comes back on afterwards, as on any fresh connection.
A helper that died now shows up as "lost the connection to the helper … use Reconnect in the menu" instead of a bare "Broken pipe".
"Done!" after a restart from a dialog
The Restart modem (SSR) buttons in the Bulk import and Disable features dialogs now say "– Done!" once the modem has come back with a working session, so you can tell the restart went through and the changes are live. Disabling another feature clears it again, since that change needs a restart of its own.
The bundled helper is 1.4.4, matching the app.
v1.4.3
Finding out why the app cannot connect
On some custom kernels and firmware the app cannot connect at all, and until now nothing said why. Tick Verbose helper log before connecting, and the helper now scans the whole QRTR bus and prints what it finds under "Helper output":
- one line per processor on the bus, listing the services it offers — the familiar ones by name (
2 DMS,14 RMTFS,4097 DIAG…), the rest as numbers; - a verdict at the end: the modem publishes DIAG and the helper has something to talk to; only this CPU publishes it; nobody does; or the bus is empty.
If the verdict says there is no DIAG, the helper simply has nothing to connect to on that firmware — it is not a bug in the app. That output is also the useful thing to paste into a bug report.
A clearer error on kernels without QRTR
A kernel built without QRTR used to fail with a bare socket(AF_QIPCRTR) failed: Address family not supported by protocol. It now says plainly that the kernel has no QRTR support, so there is no bus to reach the modem through. This one shows even without the verbose log.
Nothing changes for devices that already connect: without the verbose tick the helper behaves exactly as before.
The bundled helper is 1.4.3, matching the app.
v1.4.2
Search the current folder
A search field in the top bar filters the folder you are in as you type — case-insensitive, matching anywhere in the name. Back (or the ✕) leaves search and puts the full listing back; opening a folder from the results clears it too. A filter that hides everything says so, rather than looking like an empty directory.
Sorting
A sort menu offers name, size and date. Picking a key gives it its useful direction (name A→Z, but size and date biggest and newest first); tapping the key again flips it. Directories stay grouped first in every order, and the choice is remembered across restarts.
Coloured hex
In the preview sheet each hex pair is tinted by its byte value, so repeated bytes and patterns stand out at a glance. The same value always gets the same colour, neighbouring values get very different ones, and zero bytes stay faded grey so real data reads first. The ASCII gutter and offsets are unchanged.
Thanks to @h3nnes for all three (#4).
Measured on an SM8350: flinging through the coloured dump of a 10 KiB file renders 2060 frames with 0.49% janky and a 6 ms 99th percentile, so the colouring costs nothing noticeable.
The bundled helper is 1.4.2, matching the app — the two carry one version number from 1.4.1 onwards.
v1.4.1
Every EFS change now survives a modem restart
1.4.0 committed the EFS journal after a file save, which fixed "I edited a file, restarted the modem, and my edit was gone" — but only for file saves. Deleting a file, creating a directory, changing a mode and writing an NV item are journaled exactly the same way, so each of them could still be rolled back by a restart. They all commit now.
The Disable features dialog needed it most: it asks you to restart the modem so the change takes effect, and that restart was the very thing that threw the change away.
Measured on an SM8350, restarting through a raw 4b250300 (which does no commit of its own): an uncommitted mkdir is gone afterwards, while a delete, a mkdir and a chmod made through the app all survive.
The helper carries the app's version number
The bundled helper had its own version — 1.3.0 while the app was 1.4.0 — and that number is what the title bar shows, so it read as if an old helper had been left behind. Both are 1.4.1 from here on, and the build fails if they ever drift apart.
v1.4.0 - native modem restart, and edits that survive it
Modem restart on any Qualcomm modem
Restarting the modem used to work only on Xiaomi, by replaying a proprietary vendor QMI service. That path is gone. The helper now sends a native Qualcomm DIAG request (subsystem 0x25, command 3) over the ordinary DIAG transport, which needs no vendor endpoint — so it works on any Qualcomm modem. Confirmed on an SM8350: the subsystem restarts and comes back online with both SIMs in service in about two seconds.
There is a Restart modem entry in the overflow menu now, greyed out while the read-only lock is on.
Your EFS edits now survive that restart
Fixes a data-loss bug: "I edited a file, restarted the modem, and my edit was gone."
An EFS write lands in the modem's journal and only reaches flash when the journal is committed — so a restart before that quietly rolled the file back to its old contents. Saving or importing a file now commits, and so does restarting the modem. A restart that would lose an edit is refused rather than performed.
Committing itself was broken too. The modem never reports the commit as finished even though it happens, so the helper polled for thirty seconds and then declared failure: sync, the Flush EFS journal menu item and bulk import's final flush have all been reporting failures that were not real. That is fixed.
Restarting the modem also takes the DIAG session down with it, so the helper now drops its session, waits for the modem and builds a fresh one — no manual reconnect, and the listing is re-read for you.
File contents inline
Tapping a file now shows its contents directly in the detail sheet, loaded as the sheet opens — no more View button and separate dialog. Drag the sheet up to read more, switch between text and hex, and Save sits next to the filename. Large files say so instead of attempting a read the helper would refuse, and a failed read shows inline with Retry. Thanks to @h3nnes (#3).
Smaller fixes
- The Raw DIAG field no longer starts pre-filled, and Send is disabled while it is empty.
- Sending a raw packet no longer makes the keyboard spring back up.
- Messages are shown as system toasts, so an open dialog no longer draws over and dims them and the keyboard no longer covers them.
- The helper's "read-only" and "not connected" refusals are written in plain English instead of quoting JSON at you.
The bundled helper goes to 1.3.0 in this release; it is shown in the app's title bar.
v1.3.0 - modem feature toggles
Modem feature toggles
A new Disable features entry in the overflow menu turns off 12 NR5G modem capabilities — UL MIMO, FDD-only UL MIMO, NR UL-CA and DL-CA, the T+F / F+F / T+T NSA CA combinations, R16 and R17 Tx switching, DSS, segmentation and Lowbands 4Rx — on any rooted Qualcomm device, without the mtb binary. The item paths and payloads are a byte-for-byte port of mtbtool's features screen.
Each toggle reads its item files first, so what is already off shows as off. Per-SIM (SIM 1 through the _Subscription01 suffix), gated by the read-only lock and an SPC check, with a reminder to take an EFS backup before the first change. Changes reach the modem only after a restart — the button below the list triggers one on Xiaomi; elsewhere toggle airplane mode or reboot.
The switches are one-way. Turning a capability back on means restoring EFS from a backup, so take one first.
Also in this release
- The feature list is re-read from the modem after every write, so it never claims a capability is off once a later write has undone it — UL MIMO and Lowbands 4Rx share a single item file with mutually exclusive contents.
- The modem-restart button no longer requires writes to be enabled; restarting after re-arming the read-only lock is the careful order.
- Bulk-import log: long item names wrap instead of being cut off, and the W/D and SIM0/SIM1 markers are colored, in both the light and dark theme.