Extracted business logic from ViewModels and UI components into testable utility classes (InterfaceFormattingUtils, DeviceNameValidator, RssiThrottler, DeviceClassifier) to enable comprehensive unit testing without platform dependencies. Added 116 new tests covering formatting, validation, throttling, and device classification logic, increasing patch coverage from 23.5% to approximately 35-40%.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
When pairing a USB-connected RNode via Bluetooth, the wizard now:
- Adds "Pair via USB" option to the Bluetooth tab
- Receives PIN from RNode over USB connection
- Scans for unbonded RNodes and shows device selection list
- Auto-selects if only one unbonded RNode is found
- Uses BroadcastReceiver to properly detect bond state changes
This solves the issue where multiple RNodes in range would cause
pairing failures because the PIN belongs to the USB-connected device,
not necessarily the first discovered one.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive unit tests for the USB bridge and RNode interface:
Python tests (test_usb_bridge.py - 43 tests):
- USB bridge setup and initialization
- Device enumeration
- Permission handling
- Connection/disconnection
- Read/write operations
- Callback setters
Python tests (test_rnode_interface.py - added USB tests):
- USB mode constants (MODE_USB, CMD_BT_PIN, BT_CTRL_PAIRING_MODE)
- USB mode interface configuration
- Bluetooth pairing mode over USB
- KISS Bluetooth command framing
- Fixed existing tests to work with new connection_mode field
Kotlin tests (KotlinUSBBridgeTest.kt - 21 tests):
- Bridge initialization
- Connection listener registration/removal
- Duplicate listener prevention
- Listener exception isolation
- Bluetooth PIN callback handling
- Write/read operations when not connected
- Permission checking
- Thread safety for concurrent listener registration
- Coroutine scope shutdown
- Disconnect state clearing
- UsbDeviceInfo data class
- Supported VID verification
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix BLE cooldown asymmetry: set deduplication cooldown BEFORE deciding
which connection to keep, ensuring cooldown is applied regardless of
whether central or peripheral connection is retained
- Fix InterfaceManagementViewModel test OOM: make STATUS_POLL_INTERVAL_MS
testable (const→var) and add conditional return when interval <= 0
- Fix KISS.unescape() to properly skip invalid escape sequences (0xDB
followed by invalid byte) and trailing FESC bytes instead of corrupting
the data buffer
- Add comprehensive unit tests for all fixes following strict TDD approach
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Python RNode interface hardcoded a 22 dBm maximum TX power, which
rejected valid regional settings (US allows 30 dBm, NZ allows 36 dBm).
Changes:
- Update Python validation to accept TX power up to 36 dBm (NZ max)
- Add Python tests for regional TX power limits (US 30, EU 27, NZ 36)
- Add Kotlin tests for NZ region validation (36 dBm max)
The Kotlin validator already correctly uses regional limits. The RNode
firmware provides final hardware validation and returns error 0x40 if
TX power exceeds device capability.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add lock around self.online status in _set_online() and process_outgoing()
to prevent frame loss during online/offline transitions
- Add lock around RSSI/SNR updates for consistency with other radio state
- Log warning for malformed KISS escape sequences instead of silent ignore
- Add Python unit tests for thread safety fixes (6 new tests, 68 total)
- Add Python pytest step to CI workflow before Gradle tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract validation logic from RNodeWizardViewModel into RNodeConfigValidator
- Add unit tests for FrequencySlotCalculator, ModemPreset, FrequencyRegion
- Add unit tests for RNodeRegionalPresets, CommunitySlots
- Add unit tests for RNodeConfigValidator (45 tests)
- Add Python tests for KISS protocol and config validation (52 tests)
- Refactor startDeviceScan() into smaller helper methods
- Update detekt baseline for new code structure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>