BLE: maa throttle을 state-based 게이트로 강화

이전 응답이 완료되기 전에 새 maa가 송신되면 piezoCollector.startMultiChannel(6)이
호출되며 collector가 reset → 큐에 떠다니던 reb 패킷이 폐기되어 BV_FAIL/BV_SKIP가
발생하던 문제 대응.

변경:
- 시간 단독 게이트(800ms) → state + 시간 복합 게이트
- (A) piezoCollector.isMultiChannel && !isComplete 이면 차단
       단 5초 넘으면 강제 통과(영영 deadlock 방지)
- (B) 최소 간격 800ms → 1500ms (펌웨어 응답 시간 ~1.2~1.4s 반영)
- sendAllChannels/sendChannelsOnly가 공유하는 canSendMaa() 헬퍼로 일원화

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-26 08:53:43 +09:00
parent 11dd8fb58f
commit cac3712b8c
@@ -400,12 +400,8 @@ class BleManager private constructor(private val context: Context) {
}
fun sendAllChannels(mode: Int = 0): Boolean {
val now = System.currentTimeMillis()
if (now - lastMaaSentMs < 800) {
android.util.Log.w("BleManager", "maa THROTTLED — ${now - lastMaaSentMs}ms since last")
return false
}
lastMaaSentMs = now
if (!canSendMaa("sendAllChannels")) return false
lastMaaSentMs = System.currentTimeMillis()
piezoCollector.startMultiChannel(6)
sendRaw(CRC16.buildCommandASCII("maa", " "))
return true
@@ -457,15 +453,34 @@ class BleManager private constructor(private val context: Context) {
sendRaw(CRC16.buildCommandASCII("mbb", " "))
}
/** 6채널 측정만 (maa) — 최소 800ms 간격 throttle */
/**
* 6채널 측정 명령(maa) 송신 가능 여부:
* (A) 이전 응답이 아직 진행 중(isMultiChannel && !isComplete)이면 차단.
* 단 5초 넘게 응답이 안 오면 강제 통과(영영 deadlock 방지).
* (B) 마지막 송신으로부터 1500ms 미만이면 차단(펌웨어 burst 방어).
*/
private var lastMaaSentMs = 0L
fun sendChannelsOnly(): Boolean {
private fun canSendMaa(caller: String): Boolean {
val now = System.currentTimeMillis()
if (now - lastMaaSentMs < 800) {
android.util.Log.w("BleManager", "maa THROTTLED — ${now - lastMaaSentMs}ms since last")
val collectorBusy = piezoCollector.isMultiChannel && !piezoCollector.isComplete
val sinceLast = now - lastMaaSentMs
if (collectorBusy) {
if (sinceLast < 5000) {
android.util.Log.w("BleManager", "maa BUSY [$caller] — prev response in progress (${sinceLast}ms)")
return false
}
lastMaaSentMs = now
android.util.Log.w("BleManager", "maa FORCE [$caller] — prev incomplete after ${sinceLast}ms, abandoning")
}
if (sinceLast < 1500) {
android.util.Log.w("BleManager", "maa THROTTLED [$caller] — ${sinceLast}ms since last")
return false
}
return true
}
fun sendChannelsOnly(): Boolean {
if (!canSendMaa("sendChannelsOnly")) return false
lastMaaSentMs = System.currentTimeMillis()
piezoCollector.startMultiChannel(6)
sendRaw(CRC16.buildCommandASCII("maa", " "))
return true