Commit graph Project_SylDa/src
Author SHA1 Message Date
eddy
cd2d949f87 Fix BLE scan + touch logic + UUID + version read
Some checks failed
CI / android (push) Has been cancelled
CI / firmware (push) Has been cancelled
- Client: change passive BLE scan to active scan (setActiveScan(true))
  Server puts name/UUID in scan response; passive scan never
  received them, so isAdvertisingService() and getName() failed.
- Server: add INPUT_PULLUP on touch pins to prevent floating
  triggers when sensors disconnected
- Server: update BLE UUID characteristic in SET_ID handler
  (pUuidChar->setValue) so reconnecting clients see correct UUID
- Server: touch logic changed from t1Active/t2Active to
  !t1Active/!t2Active (door closed = relay ON)
- Android: flushReadBuffer before VERSION? to discard stale
  boot log output; use Regex for BUILD_NR parsing
- copy_firmware.sh: copy to firmware/server/ and firmware/client/
  subdirectories to match EspFlasher.assetPath()
- version.txt: server=20 client=5
2026-08-03 16:38:26 +02:00
eddy
6a07505d02 ci: add version consistency check and fully automate release pipeline
Some checks failed
CI / firmware (push) Successful in 1m13s
CI / android (push) Failing after 13s
- New tools/check_versions.sh: verifies version.txt, version.h, SylDaVersions.kt match
- release.yml: 'Verify version consistency' step after build, aborts release if mismatch
- ci.yml: same check after debug APK build
- scripts/release.sh: now runs full pipeline (pio run -> copy firmware -> gradle -> check)
  and refuses dirty working tree
- Untrack version.h, SylDaVersions.kt, release/ — always regenerated fresh from version.txt

Prevents the v1.1 bug where stale generated files caused version mismatch
and infinite re-flash loop.
2026-08-03 15:28:00 +02:00
eddy
07a2d22f76 fix: sync firmware version.h (16->17) and SylDaVersions.kt (18->17) with version.txt
Some checks failed
CI / firmware (push) Has been cancelled
CI / android (push) Has been cancelled
Release / build (push) Has been cancelled
Root cause: version.h and SylDaVersions.kt were stale, causing
app to expect BUILD_NR:18 while firmware reports BUILD_NR:16.
This triggered infinite re-flash loop on every 'Module bijwerken'.

Rebuilt firmware and APK so all versions agree on server=17/client=3.
Replace v1.1 release with corrected builds.
2026-08-03 15:19:12 +02:00
eddy
7bdd50b16e Scan on service UUID instead of device name (issue #10)
All checks were successful
CI / firmware (pull_request) Successful in 1m16s
CI / android (pull_request) Successful in 5s
- Replace name-based scan filter (getName() == 'SylDa_Server') with
  isAdvertisingService(SERVICE_UUID) to prevent BLE name spoofing
- Post-connect UUID verification via UUID_CHAR_UUID was already in place
- Update log messages to reflect service-UUID-based scanning
2026-08-02 21:27:19 +02:00
eddy
bf6619aa54 Auto-detect upload port via ID? serial query (issue #11)
All checks were successful
CI / firmware (pull_request) Successful in 1m22s
CI / android (pull_request) Successful in 7s
- Add ID? command to firmware: server responds 'SylDa_Server', client 'SylDa_Client'
- Add tools/pio_upload_port.py POST-script that queries connected ESP32s
- Remove hardcoded upload_port from platformio.ini
- Script logic: 1 ESP32 → use directly, 2+ → ID? query, no match → prompt user
- Requires pyserial for serial queries (graceful fallback if missing)
2026-08-02 21:18:26 +02:00
eddy
4aa2a750d9 Review fixes: Serial ERROR→ESP_LOGE, heartbeat→ESP_LOGD
All checks were successful
CI / firmware (pull_request) Successful in 1m26s
CI / android (pull_request) Successful in 5s
- Replace remaining Serial.println("ERROR:...") with ESP_LOGE in client.cpp
- Add Serial.println("ERROR") for protocol response where needed
- Downgrade heartbeat from ESP_LOGI to ESP_LOGD (not needed in production)
2026-08-02 20:56:37 +02:00
eddy
32489fbabb Replace Serial.* logging with ESP_LOG* macros (issue #8)
All checks were successful
CI / firmware (pull_request) Successful in 1m21s
CI / android (pull_request) Successful in 7s
- Convert all Serial.println/printf debug logging to ESP_LOGE/W/I/D
- Add TAG-based log identification (server/client)
- Lower CORE_DEBUG_LEVEL from 5 to 3 for production
- Keep Serial.printf for USB serial protocol commands (KEY?, VERSION?, etc.)
2026-08-02 20:51:21 +02:00
eddy
95f440eec8 fix: relay buttons always enabled, touch sensor inversion, version bump
All checks were successful
CI / firmware (pull_request) Successful in 1m19s
CI / android (pull_request) Successful in 9s
- MainActivity: remove isServer check — relay buttons always enabled when
  connected, regardless of device mode (fixes silently broken buttons when
  device mode accidentally set to 'client')
- client.cpp: invert HS-S43A touch sensor readings (!tActive) — sensors
  are active LOW
- build.gradle: bump versionCode 2, versionName 1.1
- platformio.ini: use stable by-id port for server ESP32
- firmware/*.bin: rebuilt with LED signaling and touch fixes
2026-08-02 20:12:07 +02:00
eddy
84e6ca8100 fix(server): defer 0xFF OTA confirm to fix race condition
All checks were successful
CI / firmware (pull_request) Successful in 1m4s
CI / android (pull_request) Successful in 8s
2026-08-02 18:42:07 +02:00
eddy
6d027fd35b chore: bump server v16, client v2
All checks were successful
CI / firmware (pull_request) Successful in 1m1s
CI / android (pull_request) Successful in 48s
2026-08-02 18:21:05 +02:00
eddy
ebaaa8cc4b feat(client): uniform LED signaling — off after 60s stable connection 2026-08-02 18:20:55 +02:00
eddy
d9ac8a578b feat(server): uniform LED signaling — off after 60s stable connection 2026-08-02 18:20:30 +02:00
eddy
0bf2dcd00f Merge fix/issue-5-hs-s43a-s3r-cleanup: HS-S43A touch migration + S3R cleanup (closes #5)
All checks were successful
CI / firmware (push) Successful in 1m18s
CI / android (push) Successful in 14s
2026-08-02 00:54:12 +02:00
eddy
109088cf52 Merge branch 'fix/issue-5-hs-s43a-s3r-cleanup' 2026-08-02 00:53:03 +02:00
eddy
516a938c7b fix: OTA wait for 0xFF confirm before reboot, version bump to 15, improved logging 2026-08-02 00:48:28 +02:00
eddy
5bb87ed4a4 fix: remove pullups, invert touch logic for HS-S43A sensors 2026-08-01 22:54:31 +02:00
eddy
a84727abdc fix: relay pins G1/G2, OTA CCCD+retry, single version source
Some checks failed
CI / firmware (push) Failing after 57s
CI / android (push) Has been skipped
- Relay pins: G39→G1, G38→G2
- BUNDLED_FIRMWARE_VERSION → SylDaVersions.SERVER (version.txt)
- OTA: explicit CCCD descriptor write for Android 13+
- OTA: start packet retry (previously no retry, blocked by pending CCCD)
- OTA: firmware path device-mode-aware (server/client subdirs)
- Removed stale root firmware.bin, flashMethodGroup, dialog_overwrite_confirm
- PrefsHelper: serverUUID/clientUUID persistence
2026-08-01 03:11:43 +02:00
eddy
bce5fc4107 fix: client — spec compliance, memory leak, LED order 2026-08-01 00:35:15 +02:00
eddy
97c79b9f4c feat: client firmware — touch/button, BLE scan, HMAC, server UUID verify, USB CDC provisioning 2026-08-01 00:32:23 +02:00
eddy
1e47fc3de7 fix: button toggle logic for relay1 2026-08-01 00:26:50 +02:00
eddy
84503f3a24 fix: revert SDK 36 bump, fix NimBLE setMTU crash, add --no-stub for OPI flash 2026-07-30 23:38:32 +02:00
eddy
fcbf1e9b5f feat: ESP MTU 512 + dynamic Android chunk size based on negotiated MTU 2026-07-30 19:15:55 +02:00
eddy
ea8bab4571 feat: incremental SHA256 verification before esp_ota_set_boot_partition 2026-07-30 19:13:27 +02:00
eddy
0513e7777d fix: USB/OTA update flow - version check, chunk size, UX improvements
- MainActivity: suppress toast when activity not resumed, auto-navigate to
  Settings on new firmware
- SettingsActivity: unified BLE/USB radio buttons + single update button,
  version check before OTA, show dialog before loadFirmware, spinner timeout
- BleRelayManager: expose getEspVersion()
- OtaManager: reduce chunk size 500→248 to fit BLE MTU 255
- ESP: WRITE→WRITE_NR on OTA characteristic (was silently dropping data)
- Layout/strings: remove intro text, add method radio buttons
- Bump all firmware versions to v5
2026-07-30 18:59:08 +02:00
eddy
3e880c9635 feat: bump firmware to v2, update bundled firmware asset 2026-07-30 17:09:09 +02:00
eddy
a1b0daee37 feat: add BLE OTA characteristic with esp_ota integration 2026-07-30 17:08:48 +02:00
eddy
d34dfec1ce feat: add firmware version BLE characteristic (VERSION_UUID) 2026-07-30 17:07:26 +02:00
eddy
0833327cea fix: code review fixes — SharedPreferences docs, Log.e, dead notify code 2026-07-29 23:51:16 +02:00
eddy
d6d6f6674a Combined flash + key exchange flow with version check and USB permission persistence
- Firmware: add VERSION? command returning BUILD_NR for version check
- Android: flash button checks firmware version first, skips flash if current
- After flash: auto key exchange via reboot detection (expectingReboot flag)
- device_filter.xml + intent-filter: USB permission 'always allow' checkbox
- singleTop + onNewIntent prevents unwanted SettingsActivity launch on USB connect
- platformio.ini: upload_port updated to /dev/ttyACM1
2026-07-29 22:56:40 +02:00
eddy
d6e37322f3 fix: NimBLE 128-bit UUID scan response + Android key/UUID loading
- 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
2026-07-29 19:30:46 +02:00
eddy
96d3620535 feat: migrate BLE to NimBLE — 45% flash, 33% RAM reduction
- Replaced ESP32 BLE Arduino with h2zero/NimBLE-Arduino@^2
- -DCONFIG_BT_NIMBLE_ENABLED to disable built-in Bluedroid
- NIMBLE_PROPERTY::* replaces BLECharacteristic::PROPERTY_* + setAccessPermissions
- BLE2902 descriptor removed (NimBLE auto-creates it)
- pService->start() removed (NimBLE starts services with server)
- setMinPreferred → setMinInterval/setMaxInterval
- onConnect/onDisconnect/onWrite get extra NimBLEConnInfo& param
- Re-advertise: BLEDevice → NimBLEDevice::startAdvertising()
- Firmware: 533KB flash (was 964KB), 29KB RAM (was 44KB)
2026-07-29 18:58:49 +02:00
eddy
348c55d830 feat: add device UUID pairing — unique identity per ESP-phone pair
- Firmware: auto-generate 16-byte UUID on first boot (NVS), new READ characteristic
- BLE name: AtomS3R-Relay → SylDa_Server
- KEY? now returns DEVICE_ID + HMAC_KEY, SET_ID command for UUID provisioning
- App: UUID+HMAC loaded from prefs, scan by service UUID, verify UUID after connect
- UUID mismatch → disconnect + skip address + rescan
- Key conflict dialog: keep ESP keys, overwrite ESP (with checkbox confirm), or cancel
- NO_KEY with existing app keys: send existing pair instead of generating new
- Added design spec doc
2026-07-29 18:12:13 +02:00
eddy
81abf2d824 Replace BLE encryption with HMAC-only auth, add buildnr, fix post-flash flow
BLE bonding/encryption removed — HMAC-SHA256 on application level provides
authentication + replay protection. Eliminates bonding state bugs, write
queue issues, and GATT_INSUFFICIENT_AUTHENTICATION complexity.

Firmware:
- Remove BLESecurity, setRespEncryptionKey, ESP_GATT_PERM_WRITE_ENCRYPTED
- Characteristic permission: ESP_GATT_PERM_WRITE (no encryption required)
- Characteristic property: PROPERTY_WRITE_NR (Write Without Response)
  Enables direct ON/OFF sequences without ACK wait time

Android:
- Remove bondReceiver, createBond, bonding state handling
- Remove write queue / pendingRelayState / writeInProgress
- Use WRITE_TYPE_NO_RESPONSE for minimal latency
- Post-flash dialog auto-dismisses on USB detach (currentAction = NONE)
- Separate progressDialog (flash progress) from dialog (post-flash info)
- Detach during active action now calls cleanupAction()

Build number:
- BuildConfig.BUILD_NUMBER in build.gradle as yyyyMMddHHmmss timestamp
- buildFeatures.buildConfig enabled
- Displayed in SettingsActivity bottom (12sp, secondary color)

Gradle:
- Wrapper upgraded 8.5 → 8.14
- minSdk 24 → 26 (Android 8+)

README updated to reflect HMAC-only security model.
2026-07-26 15:46:28 +02:00
eddy
9a84b05b8a Replace compile-time HMAC key with USB provisioning
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
2026-07-26 09:30:21 +02:00
eddy
4518aec34e Add USB auto-read key transfer + UI redesign
USB auto-read:
- ESP responds to 'KEY?\n' over USB serial with 'HMAC_KEY:<hex>'
- Android UsbKeyReceiver (manifest BroadcastReceiver) catches USB_DEVICE_ATTACHED
- Filters on Espressif vendor 0x303a, requests USB permission
- Opens CDC-ACM serial (115200), sends KEY?, parses response, saves to SharedPreferences
- Works even when app not in foreground
- usb-serial-for-android v3.7.3 via JitPack

UI redesign:
- activity_main.xml: FrameLayout with settings icon top-right, relay button center, status bottom-left (14sp)
- Scan & Connect button moved to SettingsActivity
- SettingsActivity: hint text 'Voer de HMAC sleutel in of sluit de relaismodule aan op de telefoon'
- SettingsActivity: scan button saves key + returns RESULT_OK to trigger scanning
- MainActivity: removed scanButton, auto-scan on onResume when key is set
- Back button removed from settings (ActionBar up navigation only)

README updated with USB protocol docs, new UI description, and updated setup guide
2026-07-26 08:39:28 +02:00
eddy
7f68e9ad70 Add BLE security: Just Works pairing + HMAC-SHA256 authentication
Two-layer security for the BLE relay:

1. BLE Just Works pairing (link-layer encryption)
   - ESP32 requires bonding before accepting writes
   - Characteristic permissions set to ESP_GATT_PERM_WRITE_ENCRYPTED
   - IO capability NO_INPUT_NO_OUTPUT (no passkey needed)
   - LE Secure Connections with bonding (ESP_LE_AUTH_REQ_SC_BOND)

2. HMAC-SHA256 authentication (application-level)
   - 32-byte shared secret in src/hmac_key.h (generated, gitignored)
   - Each command signed: HMAC-SHA256(key, command || sequence)
   - 37-byte packet format: [cmd:1][seq:4][hmac:32]
   - Sequence counter prevents replay (strictly increasing, starts at 1)
   - mbedtls on ESP, javax.crypto.Mac on Android

Key management:
- tools/generate_hmac_key.py generates random key + writes src/hmac_key.h
- ESP prints hex key to serial 5 seconds after boot
- Android app: SettingsActivity with eye-toggle password field
- Key stored in SharedPreferences, supports multiple ESP modules

Other changes:
- Android app: bonding flow (createBond -> BOND_BONDED -> discover)
- Android app: MTU negotiation (request 256)
- Android app: settings button (gear icon) in main screen
- Fix: sequence counter starts at 1 to prevent first-packet rejection
- Updated README with full security documentation
2026-07-26 08:18:52 +02:00
eddy
7c9dde172a Initial commit: BLE relay controller for Atom VoiceS3R 2026-07-26 01:17:31 +02:00