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
This commit is contained in:
eddy 2026-08-03 16:38:26 +02:00
commit cd2d949f87
7 changed files with 64 additions and 31 deletions

View file

@ -440,6 +440,8 @@ class SettingsActivity : AppCompatActivity() {
showProgressDialog(getString(R.string.title_firmware_flash), getString(R.string.msg_checking_version), STYLE_SPINNER)
lifecycleScope.launch {
val expected = getExpectedFirmwareVersion()
Log.d(TAG, "doFlashing: expected firmware version=$expected, expectingReboot=$expectingReboot")
val version = readEspVersion(usbManager, device)
if (version == getExpectedFirmwareVersion() && !expectingReboot) {
Log.d(TAG, "Firmware version $version matches, up to date")
@ -583,7 +585,17 @@ class SettingsActivity : AppCompatActivity() {
}
private fun readEspVersion(usbManager: UsbManager, device: UsbDevice): String? {
val intf = UsbUtils.findCdcDataInterface(device) ?: return null
Log.d(TAG, "readEspVersion: device=${device.deviceName}, id=${device.deviceId}, interfaces=${device.interfaceCount}")
for (i in 0 until device.interfaceCount) {
val intf = device.getInterface(i)
Log.d(TAG, "readEspVersion: intf[$i]=class:0x${intf.interfaceClass.toString(16)} subclass:0x${intf.interfaceSubclass.toString(16)} proto:0x${intf.interfaceProtocol.toString(16)} eps=${intf.endpointCount}")
}
val intf = UsbUtils.findCdcDataInterface(device)
if (intf == null) {
Log.w(TAG, "readEspVersion: no CDC data interface (class 0x0A) found")
return null
}
Log.d(TAG, "readEspVersion: found CDC data iface=${intf.id}")
val connection = usbManager.openDevice(device) ?: return null
if (!connection.claimInterface(intf, true)) { connection.close(); return null }
@ -595,12 +607,18 @@ class SettingsActivity : AppCompatActivity() {
return try {
setupCdcControl(connection, device)
Thread.sleep(KEY_SETTLE_MS)
flushReadBuffer(connection, epIn)
val cmd = "VERSION?\n".toByteArray(StandardCharsets.US_ASCII)
connection.bulkTransfer(epOut, cmd, cmd.size, USB_BULK_TIMEOUT_MS)
val writeResult = connection.bulkTransfer(epOut, cmd, cmd.size, USB_BULK_TIMEOUT_MS)
Log.d(TAG, "readEspVersion: bulkTransfer OUT result=$writeResult (expected ${cmd.size})")
Thread.sleep(RESPONSE_WAIT_MS)
val response = readResponse(connection, epIn, VERSION_TIMEOUT_MS)
val versionLine = response.lines().firstOrNull { it.startsWith("BUILD_NR:") }
versionLine?.removePrefix("BUILD_NR:")?.trim()
Log.d(TAG, "readEspVersion: raw response='${response.replace("\r", "\\r").replace("\n", "\\n")}' (len=${response.length})")
val match = Regex("BUILD_NR:(\\d+)").find(response)
Log.d(TAG, "readEspVersion: regex match=$match, group1=${match?.groupValues?.get(1)}")
match?.groupValues?.get(1)
} finally {
connection.close()
}
@ -753,16 +771,20 @@ class SettingsActivity : AppCompatActivity() {
val sb = StringBuilder()
val startTime = System.currentTimeMillis()
var reads = 0
while (System.currentTimeMillis() - startTime < timeoutMs) {
val len = connection.bulkTransfer(epIn, buf, buf.size, READ_CHUNK_TIMEOUT_MS)
if (len > 0) {
reads++
sb.append(String(buf, 0, len, StandardCharsets.US_ASCII))
Log.d(TAG, "readResponse: chunk len=$len, sb now='${sb.toString().replace("\r","\\r").replace("\n","\\n")}'")
if ((sb.contains("HMAC_KEY:") || sb.contains("NO_KEY") || sb.contains("OK") || sb.contains("ERROR")) && sb.contains("\n")) {
break
}
}
}
Log.d(TAG, "readResponse: done after ${System.currentTimeMillis()-startTime}ms, ${reads} reads, response='${sb.toString().replace("\r","\\r").replace("\n","\\n")}'")
return sb.toString()
}