fix(ble): mtb 응답 중 다른 명령 끼어들어 firmware freeze — 3-layer 근본 fix
실측 로그 (2026-07-08 11:18~11:19) 분석: mtb 응답 stream (reb×6 + raa
+ rim, 총 8개 패킷) 중간에 msn (battery) / mim (IMU) 이 TX 로 끼어들면
firmware GATT queue 가 꼬여 응답 실종 → 이어지는 mls mode 0 명령에서
완전 freeze (BLE 광고까지 중단, 재연결 10회 모두 실패).
핵심 원인:
- BleManager 의 batteryTimer / mim polling 이 시간 간격 기반이라 mtb
응답 진행 중에도 무조건 TX 발사.
- 특히 sendImuFifoQuery 는 imuCollector.reset() 을 먼저 호출 → mtb 의
rim (IMU) 이 파괴됨.
Layer 1 — BleManager gating
- isMtbBusy 프로퍼티 추가 (piezoCollector.isMultiChannel && !isComplete)
- batteryTimer / batteryRetryTimer: sendBatteryQuery 앞에 isMtbBusy skip
- Watchdog silence heartbeat: sendImuQuery (msp) → sendImuFifoQuery
(mim) 로 교체 + isMtbBusy skip
- sendImuQuery 함수 자체 삭제 — msp 명령 코드에서 완전 제거
(rsp 파서는 legacy 응답용 유지)
Layer 2 — PiezoMonitoringView mim polling gating
- LaunchedEffect while 루프의 sendImuFifoQuery 앞에 isMtbBusy skip
Layer 3 — mtb 3초 timeout + UI 안내
- sendMtb: 3초 timeout runnable, raa 응답 오면 취소
- lastMtbTimeoutAt / consecutiveMtbTimeouts state 노출
- PlacementGuideView 가 관찰 → 1~2회: "기기 응답 지연" 안내
3회 연속: "재연결" 안내 + forceDisconnectAndReconnect 자동 호출
- forceDisconnectAndReconnect 를 public 으로 승격
부가:
- disconnect 3곳 (GATT_ERROR / STATE_DISCONNECTED / watchdog forced)
에서 mtbTimeoutRunnable 도 함께 정리.
Firmware VBTFW0121 의 mls mode 0 handler 취약점은 별도로 펌웨어 팀에
리포트 필요 (본 fix 는 큐 혼잡 방지로 근본적으로 회피).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -322,6 +322,8 @@
|
||||
<string name="placement_skip">건너뛰기</string>
|
||||
<string name="placement_in_position">최적의 위치입니다!</string>
|
||||
<string name="placement_position_lost">위치를 놓쳤습니다. 치골 위에서 다시 시작해주세요.</string>
|
||||
<string name="mtb_response_delayed">기기 응답이 지연되고 있습니다. 잠시만 기다려주세요…</string>
|
||||
<string name="mtb_response_reconnect">기기가 응답하지 않습니다. 연결을 재시도합니다.</string>
|
||||
<string name="placement_detached_restart">센서가 분리되었습니다. 치골 위에서 다시 시작해주세요.</string>
|
||||
<string name="placement_signal_lost">신호를 놓쳤습니다 — 위로 올려주세요 ↑</string>
|
||||
<string name="placement_sweep_start">배꼽 근처에서 시작해 천천히 아래로 내려주세요 ↓</string>
|
||||
|
||||
@@ -322,6 +322,8 @@
|
||||
<string name="placement_skip">Skip</string>
|
||||
<string name="placement_in_position">Optimal position!</string>
|
||||
<string name="placement_position_lost">Position lost. Restart above pubic bone.</string>
|
||||
<string name="mtb_response_delayed">Device response delayed. Please wait…</string>
|
||||
<string name="mtb_response_reconnect">Device not responding. Reconnecting.</string>
|
||||
<string name="placement_detached_restart">Sensor detached. Restart above pubic bone.</string>
|
||||
<string name="placement_signal_lost">Signal lost — slide up ↑</string>
|
||||
<string name="placement_sweep_start">Start near navel, slide down slowly ↓</string>
|
||||
|
||||
Reference in New Issue
Block a user