Konfigurator updates to support fully automatic operation #1

Merged
Joe merged 1 commit from konfigurator_updates into main 2026-04-16 01:27:19 +00:00
Owner

Konfigurator updates

This pull request makes changes to the Konfigurator subapp to support fully automatic operation. It also fixes a longstanding BLE bug.

Changes to support fully automatic operation (and limited ammunition)

Three new device parameters are now configured via the Apply Settings flow, sent as two additional BLE packets per device (packet keys 7–9):

Parameter Key Default Description
Shot Capacity 7 30 Number of shots before reload is required
Reload on Reentry 8 true Whether ammo is refilled when a player re-enters after being tagged out
Min Time Between Shots 9 500 ms Minimum interval between shots

Shot Capacity and Reload on Reentry are paired in one packet (keys 7+8); Min Time Between Shots is sent separately (key 9 + PARAMETER_KEY_NONE). Both the global game config editor and the per-device detail dialog expose the new fields.

allSettingsMatch() on Device now checks all five configurable parameters (team, max health, special weapons on reentry, shot capacity, reload on reentry, min time between shots) so the "Ready All Devices" button is only offered once every field has been ACK'd.

Also on this branch:

  • Added SYSTEMK_STATE_* constants to Packet.java (replacing magic numbers 3, 7, 9 in state comparisons).
  • Fixed readyAllDevices(): advertising was never stopped between loop iterations, preventing the scan from receiving STATUS packets. Now advertises for 500 ms then scans for 1500 ms per cycle.
  • Fixed addOrRefreshDevice(): new devices now get DeviceState.Configurable assigned here rather than unconditionally in the Hello packet handler, which was overriding Ready state on every subsequent Hello broadcast.
  • Fixed broadcasted-team merge precedence: ACK'd value from configure now wins over a live STATUS packet value (which may be stale while the device is applying a new config).
  • DeviceList now uses device address as a stable LazyColumn item key.

Fix BLE scan throttling during multi-device configuration

Problem

Configuring more than one device in sequence would reliably fail on the second (and any subsequent) device — all retry attempts timed out with no ACK received.

The root cause was Android's BLE scan throttle. The OS silently rejects startScan calls (returning status=6, "registration failed because app is scanning too frequently") when an app starts and stops scans too many times within a 30-second window. The previous configureDevice implementation stopped the background scan and started a dedicated ACK scan for every attempt. With MAX_CONFIGURE_RETRIES = 3 and the potential for multiple packets per device, the quota was exhausted before the second device was reached. Because startScan fails silently (no onScanFailed callback), the ACK scan never started, so no ACK was ever received, and every attempt timed out after 5 seconds.

Confirmed in logcat:

BluetoothLeScanner: onScannerRegistered() - status=6 scannerId=-1 mScannerId=0
BluetoothLeScanner: registration failed because app is scanning too frequently
...
BLE Scanner: Config confirmation timed out for 84:FC:E6:6A:AF:C6

Fix

Replace the dedicated per-attempt ACK scan with a lightweight hook on the already-running background scan.

BleManager — added a pendingAckDetector lambda and a notifyScanResult() method. configureDevice now only advertises the config packet; it registers the ACK-matching logic in pendingAckDetector before advertising and clears it in the finally block. No scan is started or stopped during configuration.

StateMachineViewModelscanCallbackDefault.onScanResult now calls bleManager.notifyScanResult(result) for every packet, routing results to the ACK detector when a configuration is in progress.

BleManager.startScanning — added an early-return guard when the same callback is already registered and scanning, preventing a redundant scan cycle from the startScanning call at the end of configureDevices().

Result

The background scan runs uninterrupted throughout the entire multi-device configuration sequence. Zero scan start/stop cycles are consumed by configureDevice, so the Android throttle is never triggered regardless of how many devices or retries are needed.

# Konfigurator updates This pull request makes changes to the Konfigurator subapp to support [fully automatic operation](https://git.ktag.clubk.club/Software/SystemK/commit/f1f881bf3bd02fe92abde261da06c98e620faaa0). It also fixes a longstanding BLE bug. ## Changes to support fully automatic operation (and limited ammunition) Three new device parameters are now configured via the Apply Settings flow, sent as two additional BLE packets per device (packet keys 7–9): | Parameter | Key | Default | Description | |---|---|---|---| | Shot Capacity | 7 | 30 | Number of shots before reload is required | | Reload on Reentry | 8 | true | Whether ammo is refilled when a player re-enters after being tagged out | | Min Time Between Shots | 9 | 500 ms | Minimum interval between shots | Shot Capacity and Reload on Reentry are paired in one packet (keys 7+8); Min Time Between Shots is sent separately (key 9 + `PARAMETER_KEY_NONE`). Both the global game config editor and the per-device detail dialog expose the new fields. `allSettingsMatch()` on `Device` now checks all five configurable parameters (team, max health, special weapons on reentry, shot capacity, reload on reentry, min time between shots) so the "Ready All Devices" button is only offered once every field has been ACK'd. Also on this branch: - Added `SYSTEMK_STATE_*` constants to `Packet.java` (replacing magic numbers 3, 7, 9 in state comparisons). - Fixed `readyAllDevices()`: advertising was never stopped between loop iterations, preventing the scan from receiving STATUS packets. Now advertises for 500 ms then scans for 1500 ms per cycle. - Fixed `addOrRefreshDevice()`: new devices now get `DeviceState.Configurable` assigned here rather than unconditionally in the Hello packet handler, which was overriding `Ready` state on every subsequent Hello broadcast. - Fixed broadcasted-team merge precedence: ACK'd value from configure now wins over a live STATUS packet value (which may be stale while the device is applying a new config). - `DeviceList` now uses device address as a stable `LazyColumn` item key. --- ## Fix BLE scan throttling during multi-device configuration ### Problem Configuring more than one device in sequence would reliably fail on the second (and any subsequent) device — all retry attempts timed out with no ACK received. The root cause was Android's BLE scan throttle. The OS silently rejects `startScan` calls (returning `status=6`, "registration failed because app is scanning too frequently") when an app starts and stops scans too many times within a 30-second window. The previous `configureDevice` implementation stopped the background scan and started a dedicated ACK scan for every attempt. With `MAX_CONFIGURE_RETRIES = 3` and the potential for multiple packets per device, the quota was exhausted before the second device was reached. Because `startScan` fails silently (no `onScanFailed` callback), the ACK scan never started, so no ACK was ever received, and every attempt timed out after 5 seconds. Confirmed in logcat: ``` BluetoothLeScanner: onScannerRegistered() - status=6 scannerId=-1 mScannerId=0 BluetoothLeScanner: registration failed because app is scanning too frequently ... BLE Scanner: Config confirmation timed out for 84:FC:E6:6A:AF:C6 ``` ### Fix Replace the dedicated per-attempt ACK scan with a lightweight hook on the already-running background scan. **`BleManager`** — added a `pendingAckDetector` lambda and a `notifyScanResult()` method. `configureDevice` now only advertises the config packet; it registers the ACK-matching logic in `pendingAckDetector` before advertising and clears it in the `finally` block. No scan is started or stopped during configuration. **`StateMachineViewModel`** — `scanCallbackDefault.onScanResult` now calls `bleManager.notifyScanResult(result)` for every packet, routing results to the ACK detector when a configuration is in progress. **`BleManager.startScanning`** — added an early-return guard when the same callback is already registered and scanning, preventing a redundant scan cycle from the `startScanning` call at the end of `configureDevices()`. ### Result The background scan runs uninterrupted throughout the entire multi-device configuration sequence. Zero scan start/stop cycles are consumed by `configureDevice`, so the Android throttle is never triggered regardless of how many devices or retries are needed.
Joe merged commit 7410cdbc6e into main 2026-04-16 01:27:19 +00:00
Joe deleted branch konfigurator_updates 2026-04-16 01:27:32 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Software/Android-KTag-Apps!1
No description provided.