- PrefsHelper: PREF_LABEL1, PREF_LABEL2 constants
- SettingsActivity: EditText fields with Done-keyboard action to save labels
- MainActivity: buttons show user label, colorAccent on press, textAllCaps disabled
- activity_main.xml: textAllCaps=false for case-sensitive labels
- Firmware: add explicit setScanResponseData with setCompleteServices for
128-bit service UUID so Android ScanFilter finds the device
- Android: hexStringToBytes accepts any even-length hex (fixes UUID=32chars
failing the hardcoded 64-char check)
- Android: onActivityResult matches SettingsActivity.RESULT_SCAN instead of
Activity.RESULT_OK
- MainActivity: RECONNECT_DELAY_MS, POST_SETTINGS_RESCAN_MS, ON_RESUME_SCAN_DELAY_MS
- SettingsActivity: FLUSH_TIMEOUT_MS, READ_CHUNK_TIMEOUT_MS, CDC_CONTROL_TIMEOUT_MS
- UsbSerialTransport: CONTROL_LINE_TIMEOUT_MS
- UsbUtils: shared CDC request constants (REQUEST_TYPE, SET_LINE_CODING, SET_CONTROL_LINE_STATE, DTR, RTS)
Pure refactor — no behavior change. All literals replaced by named private const val in companion objects or shared via UsbUtils.
1. Append 'probeer het opnieuw' to key exchange error toasts.
2. Add 'Annuleren' button to flash progress dialog that calls
flasher.cancel() and cleanupAction().
1. Dismiss waiting dialog when flash progress dialog starts,
preventing orphaned spinner dialog after flash completes.
2. Increase key exchange retries from 3 to 5 and initial delay
from 500ms to 1000ms to give ESP more time to be ready
after USB permission grant.
Add @Volatile cancelled flag with cancel() method. Check flag at 3
checkpoints (after initial sleep, after transport setup, before each
flash step) so the thread exits early and closes the USB connection
in the finally block. SettingsActivity.onDestroy now calls cancel().
Reviewed in codereview.md (recommendation 3.2).
Use AlertDialog with dialog_waiting.xml (spinner + message) and
dialog_progress.xml (horizontal ProgressBar + message) instead of
the deprecated ProgressDialog. Progress updates now use findViewById
on the dialog view.
Reviewed in codereview.md (recommendation 2.4).
Replace anonymous lambdas in handler.postDelayed with a shared
scanRunnable so that handler.removeCallbacks(scanRunnable) in onPause
cancels any pending scan. Prevents duplicate or orphaned scan starts
during rapid activity transitions.
Reviewed in codereview.md (recommendation 2.2).
When BLUETOOTH_SCAN, BLUETOOTH_CONNECT or ACCESS_FINE_LOCATION
permissions are denied, show 'Permissies geweigerd — open Instellingen'
and disable the relay button instead of silently hanging.
Reviewed in codereview.md (recommendation 2.1).
Log warning when status != GATT_SUCCESS in onConnectionStateChange,
onServicesDiscovered, and onMtuChanged. Service discovery failure now
shows 'Servicefout' and returns early to prevent MTU request on failed
discovery.
Reviewed in codereview.md (recommendation 5.2).
Kotlin 2.0 uses the K2 compiler for better build performance.
Compatible with AGP 8.5.2 which was upgraded previously.
Reviewed in codereview.md (recommendation 7.3).
AGP 8.5.2 is compatible with Gradle 8.14 and Kotlin 1.9.24.
Includes bug fixes and improved Kotlin support.
Reviewed in codereview.md (recommendation 7.1).
Implement onCharacteristicWrite in gattCallback to get confirmation
that packets are submitted to the local BLE stack. Logs success/failure
and shows 'Communicatiefout' on write failure. seq++ stays in
sendRelayCommand to ensure unique sequence numbers for rapid ON/OFF.
Reviewed in codereview.md (recommendation #5).
Change parity from 0x08 (SPACE) to 0x00 (NONE) to match 115200 8N1
specification. ESP32-S3 ignores this setting but the value was
technically incorrect.
Reviewed in codereview.md (recommendation #4).
UsbKeyReceiver was never registered in AndroidManifest or dynamically,
making it 318 lines of dead code duplicating SettingsActivity key-exchange
logic and UsbUtils USB helpers.
Reviewed in codereview.md (recommendation #3).
Replace plain-text SharedPreferences with AES256-GCM encrypted prefs
via androidx.security:security-crypto. Adds PrefsHelper utility to
centralize encrypted prefs access across MainActivity, SettingsActivity
and UsbKeyReceiver.
Reviewed in codereview.md (recommendation #2).
Replace full key values in Log.d() calls with length-only metadata
to prevent key material leakage via logcat access.
Reviewed in codereview.md (recommendation #1).
ESP firmware:
- Store HMAC key in NVS via Preferences library instead of compile-time
hmac_key.h
- KEY? responds with HMAC_KEY:<hex> (if provisioned) or NO_KEY
- New SET_KEY:<64-hex> command stores key in NVS and responds OK
- Boot messages updated to reflect provisioning state
Android app:
- UsbKeyReceiver detects NO_KEY response and auto-provisions:
generates random 32-byte key via SecureRandom, sends SET_KEY,
waits for OK, saves key to SharedPreferences
- Read loop now breaks on both HMAC_KEY: and NO_KEY responses
Cleanup:
- Removed tools/generate_hmac_key.py and src/hmac_key.h
- Removed hmac_key.h from .gitignore
- README updated for new provisioning flow