Files
VesiscanClinicalAndroid/app
dw.jang 8b42996797 fix(ble): 중복 MTU 콜백에 서비스 탐색을 두 번 걸지 않는다 (효과는 미확인)
병원 임상 당일 빌드의 추적성을 위해 커밋한다 — 설치된 APK 가 기록된 커밋과
일치해야 한다.

## 무엇을 넣었나

`onMtuChanged` 에서 무조건 `discoverServices()` 를 부르던 것을, 연결당 한 번만
부르도록 가드를 뒀다(`discoverServicesOnce`). 중복 호출 자체는 없어진다 —
로그에 `DISCOVER_SKIPPED` 로 남는다.

## ⚠ 이것이 반쪽 연결을 고치지 못한다 — 실측으로 확인

2026-09-15 Xiaomi 23021RAA2Y · 프로브 VBT2607R300:

    10:52:56  MTU×2, 가드 미발동            → HALF_CONNECTED
    10:53:19  MTU×2, DISCOVER_SKIPPED       → 정상
    10:57:01  MTU×2, DISCOVER_SKIPPED       → HALF_CONNECTED
    10:57:25  MTU×2, DISCOVER_SKIPPED       → ADVERT_TIMEOUT
    10:57:46  MTU×2, DISCOVER_SKIPPED       → HALF_CONNECTED
    10:58:10  MTU×2, DISCOVER_SKIPPED       → 정상

가드가 발동한 5회 중 3회가 여전히 반쪽 연결이다. **중복 MTU 는 증상이고 원인이
아니다.** 464건 전수의 상관관계(1회 97.0% vs 2회 22.6%)를 인과로 읽은 것이 잘못이었다.

그래서 이 커밋은 수정이 아니라 **중복 호출 제거 + 진단 로그**로만 취급해야 한다.
`DISCOVER_SKIPPED` 는 중복 MTU 가 언제 오는지를 기록에 남겨, 임상 후 분석의 근거가
된다. 펌웨어팀에 "MTU 를 먼저 걸지 말라"는 요청은 **보내지 않는다** — 근거가 무너졌다.

## 관찰된 패턴 (가설, 표본 4건)

성공한 회차는 두 번째 콜백이 1~2ms 뒤에 오고, 실패한 회차는 ~300ms 뒤에 온다.
300ms 뒤의 두 번째 MTU 협상이 진행 중인 서비스 탐색을 깨뜨리는 것으로 보이는데,
그렇다면 탐색을 다시 부르지 않아도 실패하므로 앱에서 막을 수 없다. 미검증이다.

동작이 나빠질 경로는 없다(중복 호출을 건너뛰는 것뿐). 임상 로그로 표본을 늘린다.

⚠ 반쪽 연결 자체는 기존 `HALF_CONNECTED` 가드가 20초 안에 잡아 재연결한다.
  다만 그 20초 동안 측정 명령(`mcf`/`mcs`)이 큐에 들어가 타임아웃까지 대기한다 —
  사용자에게는 "0cm · 프로브가 응답이 없습니다" 로 보인다. 이 경로는 아직 손대지 않았다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 11:06:43 +09:00
..