8b42996797
병원 임상 당일 빌드의 추적성을 위해 커밋한다 — 설치된 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>