Skip to content

Add QRP Labs QMX to Android rig picker (#945) - #946

Open
patrickrb wants to merge 2 commits into
devfrom
fix/945-qmx-rig-picker
Open

patrickrb wants to merge 2 commits into
devfrom
fix/945-qmx-rig-picker

Conversation

@patrickrb

@patrickrb patrickrb commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

Fixes #945 (Android half): "Android does not recognize the QMX."

Debug APK

Download FT8AF-pr945-6f3d5a2-debug.apk (built from 6f3d5a2, before the MD6 change in 8a605b6; it still sends MD2; to the QMX, so rebuild to test mode switching)

Manual test checklist

  1. Install the debug APK, open Settings → Rig, and open the rig model picker.
  2. Scroll to the end of the list. QRP Labs QMX is the last entry. Select it. The baud should be 9600, the same as Qrp Labs QDX.
  3. Connect a QMX over USB (OTG) and accept the USB permission prompt. Check that CAT connects: the frequency follows the band you select in FT8AF, the radio switches to its Digi mode (not USB/SSB) on connect and band change, and PTT keys the radio on a TX cycle.
  4. Upgrade check: on a phone that already has a saved rig (for example IC-7300MK2 or (tr)uSDX), install this APK over the old build and check that the same rig is still selected.

Steps 3 and 4 need hardware. Step 3 is for the founder or the #945 reporter.

What changed

  • assets/rigaddress.txt: added QRP Labs QMX,00,9600,27. Instruction set 27 (QRPLABS_QMX, new) is the QDX's KENWOOD_TS590 CAT path via QrpLabsQmxRig, except the mode command is MD6; (QMX digital mode) instead of MD2;, which selects USB voice on SSB-capable QMX firmware (found on real hardware in Add QRP Labs QMX via the hamlib backend #925). Baud doesn't matter over USB CDC. USB detection was already in place: device_filter.xml lists ST CDC 0483:A34C, which uses CdcAcmSerialDriver. The QMX was just missing from the picker.
  • The row goes at the end of the file, not right after the QDX row. The selected rig is saved as a raw list index (ConfigFragment → writeConfig("model", i)). Inserting after the QDX would shift every later entry, so users with Wolf SDR, (tr)uSDX, FT-891 (Hamlib), or IC-7300MK2 selected would silently get the wrong rig after upgrading. RigAddressAssetTest already enforces this append-only rule.
  • RigAddressAssetTest: added the QMX to GOLDEN_ORDER. Added qmx_isListedWithItsOwnInstructionSetAndQdxBaud, plus QrpLabsQmxRigTest (sends MD6;, TS-590 still sends MD2;, TS-590 frequency framing). Changed the "last entry" test from IC-7300MK2 to the QMX.
  • Not added: the optional QRP Labs QMX (Hamlib) row (809,9600,26). The task only allowed it if I could confirm that HamlibRig opens model 2057 cleanly, and I can't run the native lib here: no emulator or device. The Kenwood row is the same path the QDX already uses. A Hamlib row can follow once someone checks it on a device.

Risks

  • Low. A new rig class used only by the QMX row; the QDX/TS-480/TS-590 rows are unchanged.
  • Apart from the mode command, the QMX CAT behaviour is assumed to match the QDX (both use the TS-480-style subset). MD6; = Digi is from the QMX CAT manual and the Add QRP Labs QMX via the hamlib backend #925 hardware test (via hamlib); this exact path hasn't been tested on a real QMX.
  • Picker order: the QMX sits at the end, apart from the QDX. That's cosmetic, and it's the price of not breaking saved selections.

Tested automatically

  • ./gradlew testDebugUnitTest: 4036 tests, 0 failures, 0 errors (local, JDK 17). RigAddressAssetTest: 6/6 pass.
  • assembleDebug succeeded. apksigner verify passes, and assets/rigaddress.txt inside the APK ends with the QMX row.
  • CI (Android CI & Release): all checks green on 6f3d5a2.

Review

  • Copilot review unavailable: requesting @copilot as reviewer returns OK, but no reviewer gets attached (same on Wrap frequency-picker alternate chips instead of squeezing them (#930) #932), so Copilot review looks disabled on this repo. I self-reviewed the diff (asset row + test) and found nothing to fix.
  • CI: the first Build APK run failed in lintVitalAnalyzeRelease with a 502 Bad Gateway from dl.google.com while resolving lint-gradle deps. That is an infrastructure flake, not this change; I re-ran the failed jobs and they passed. All CI checks are green on 6f3d5a2 (Build APK, unit tests & coverage, instrumented emulator tests, lint/detekt/ktlint, codecov).

Out of scope: the desktop/Linux libhamlib4 conflict (second half of #945). desktop/linux/run-ft8af.sh on dev already handles it.

🤖 Generated with Claude Code

@codecov

codecov Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 41.97%. Comparing base (bee2722) to head (4ba9178).

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##                dev     #946      +/-   ##
============================================
- Coverage     42.06%   41.97%   -0.10%     
  Complexity      309      309              
============================================
  Files           282      283       +1     
  Lines         34300    34516     +216     
  Branches       4145     4189      +44     
============================================
+ Hits          14429    14487      +58     
- Misses        19547    19701     +154     
- Partials        324      328       +4     
Flag Coverage Δ
android 18.75% <ø> (+0.08%) ⬆️
native 12.70% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 14 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@patrickrb

Copy link
Copy Markdown
Owner Author

Review round 1

This is the Claude code-review (high) fallback, because Copilot review isn't available on this repo. I reviewed the diff, and also checked the real-QMX findings in #925's thread that apply to the Kenwood-emulation path.

# Finding Outcome
1 The QMX row used the KENWOOD_TS590 instruction set, which sends MD2;. That's harmless on the digital-only QDX, but on SSB-capable QMX firmware it selects USB voice. #925's tester confirmed this on hardware: the QDX profile on a QMX needed a manual switch to Digital. Fixed. New instruction set 27 (QRPLABS_QMX) and QrpLabsQmxRig, which extends KenwoodTS590Rig and sends MD6; (Digi in the QMX CAT manual, and the same command #925 confirmed on hardware). Frequency, PTT, VFO and meter commands are unchanged. The QDX, TS-480 and TS-590 rows still send MD2;.
2 Should we also send FT8TW's Q41; "stay in digital" command? Not changed. The QMX CAT manual has no such command: Q4 sets the TX rise threshold, so Q41; would set it to 1%. #925 tried it and reverted it for that reason.
3 Label versus a later hamlib row. Not changed. "QRP Labs QMX" now and "QRP Labs QMX (Hamlib)" later follow the "Yaesu FT-891" / "Yaesu FT-891 (Hamlib)" pattern. #925 currently names its row Qrp Labs QMX (Hamlib) (QDX-style casing), so the pair would differ only in case. Worth renaming it to QRP Labs QMX (Hamlib) when #925 rebases.
4 QMX TX drive: #925 reports that the QMX needs mono/left-channel TX audio, and the app defaults txAudioChannel to BOTH. Left for the maintainer. Whether to default to LEFT when a QMX row is selected, or just document it, is a product call. It affects both QMX rows, not only this one.
5 USB-audio failures on Android 15 and after reattach, reported in #925. Not changed. #925's tester showed these happen with both the QDX profile and the hamlib row, so they're in the audio layer, not CAT. They need their own issue.
6 Merge conflict with #933. Both PRs append to the end of rigaddress.txt and GOLDEN_ORDER, and #933 (4327bed) replaces the per-rig last-entry test with lastEntry_isTheLastGoldenName. Left for the maintainer. Whichever PR merges second must re-append its row after the other's and keep both GOLDEN_ORDER names in file order. If #933 merges first, drop qmx_isTheLastEntry here, because the generalised test covers it.
7 KenwoodTS590Rig.supportsAtuTune() returns true, and the QMX has no ATU. Not changed. The QDX has always behaved the same way, and an AC command to a rig without an ATU is ignored. Out of scope here.

Fix commit: 8a605b6. I also updated the PR body: the instruction set changed, and the draft APK predates this fix.

Tests run locally (testDebugUnitTest --tests): QrpLabsQmxRigTest (new, 5), RigAddressAssetTest (6), RigNameListTest (8), DiscoveryTX500RigTest (5). All pass.

Not verified on hardware: MD6; and the inherited TX1;/FR0;/RM; on a real QMX via this path. #925 verified MD6; on hardware, but through hamlib.

patrickrb added a commit to jedisdead666/FT8AF that referenced this pull request Oct 22, 2026
- Android: XIEGU_G106 collided with HAMLIB (26), a duplicate switch
  case; move it to 28 (27 is claimed by the open QMX PR patrickrb#946) and add
  a uniqueness test over InstructionSet.
- Android: the keepalive re-entered setPTT(true) from the poll thread,
  so racing an unkey could re-key the rig indefinitely. It now resends
  the frame only, under a lock shared with setPTT.
- rigaddress.txt is append-only: move the new G106(USB) row to the end
  and pin it in GOLDEN_ORDER.
- Desktop: only the G106 backend rejects a connection on failed
  PTT-off (FLrig/Hamlib keep their lazy behaviour); drive the keepalive
  off a monotonic clock; end the over when a keepalive fails.
- Desktop: move audioDeviceLabel to a tested module and stop calling
  every generic C-Media card a DE-19.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
patrickrb and others added 2 commits October 26, 2026 19:05
Append a 'QRP Labs QMX' row to rigaddress.txt mirroring the QDX
(KENWOOD_TS590 instruction set, 9600 baud). USB detection (0483:A34C)
was already in place; the radio was just missing from the picker.

Appended at the end rather than next to the QDX because the selected
rig is persisted as a raw list index.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The QMX entry reused the KENWOOD_TS590 instruction set, which sends MD2;.
That is harmless on the digital-only QDX but selects USB voice on
SSB-capable QMX firmware, so FT8 needed a manual switch to Digi (reported
on real hardware in #925). Give the QMX its own instruction set and a
KenwoodTS590Rig subclass that sends MD6;, the QMX CAT manual's digital
mode. Frequency, PTT, VFO and meter commands are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@patrickrb
patrickrb force-pushed the fix/945-qmx-rig-picker branch from 8a605b6 to 4ba9178 Compare October 27, 2026 00:07
@github-actions

Copy link
Copy Markdown

Debug APK

Download FT8AF-pr946-4ba9178-debug.zip (built from 4ba9178, run)

Unzip it and install the .apk on the phone. The download needs a signed-in GitHub account, and the link expires after 30 days.
This build is signed with the shared debug key, so it installs over any earlier PR debug APK. Android will not install it over the Play Store build (or a debug build made on your own machine), because those are signed with a different key; you have to uninstall that one first.

Uninstalling deletes all of the app data: the QSO log, settings, and saved logbook and rig configuration. Export your log as ADIF before you do this on a phone you operate from.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant