fix(ble): 반쪽 연결에서 자동 재연결하지 않는다 — 무한 반복 대신 조작자에게 알린다
사용자 지시(2026-09-15, 병원 임상 당일). 실측에서 23초 주기로 영원히 반복했다.
## 무엇이 일어났나 (Xiaomi 23021RAA2Y · VBT2607R300 · RSSI −46)
11:08:41 연결 → MTU×2 → 20초 뒤 HALF_CONNECTED → 3초 뒤 재연결
11:09:04 연결 → MTU×2 → 20초 뒤 HALF_CONNECTED → 3초 뒤 재연결
11:09:27 연결 → MTU×2 → 20초 뒤 HALF_CONNECTED → 3초 뒤 재연결
11:09:50 연결 → MTU×2 → (반복)
신호는 강했고(−46) 프로브는 매번 연결을 받았다. 그런데 GATT 서비스를 끝까지 내주지
않아 `isServiceReady` 가 한 번도 서지 않았다. **프로브가 갇힌 상태**이고, 같은 프로브가
같은 날 13회 정상 동작했으므로 도중에 그 상태로 빠진 것이다.
다시 붙어도 같은 결과가 나온다. 그리고 링크는 매번 붙으므로 재시도 카운터가 1 로
리셋돼(`attempt=1/-1`) escalation 도 없었다 — 화면에는 "재연결 중" 만 계속 뜨고
조작자는 무엇을 해야 하는지 알 수 없다. 임상에서 이게 제일 나쁘다.
## 바꾼 것
반쪽 연결 가드에서 `scheduleAutoReconnect()` 를 뺐다. 멈추고 `connectionError` 를
`HALF_CONNECTED` 로 남긴다 — 표시 경로는 이미 있었다(DeviceScanView).
문구도 사실에 맞게 고쳤다. "다시 연결합니다" 라고 적혀 있었는데 이제 재연결하지
않으므로 거짓이 된다. 대신 **해야 할 일**을 적었다 — 이 상태를 푸는 것은 프로브 전원
재투입이고 앱이 할 수 있는 일이 아니다.
연결이 끝까지 되지 않았습니다 — 기기가 응답했지만 준비를 마치지 못했습니다.
프로브 전원을 껐다 켠 뒤 다시 연결해 주세요. 다시 시도해도 같으면 다른 프로브를 쓰세요.
## 건드리지 않은 것
진짜 링크 유실(범위 이탈·간섭·`status 8`)의 자동 재연결은 그대로다. 그쪽은 다시 붙으면
실제로 복구되고 `MAX_RECONNECT_ATTEMPTS`(5) 로 escalation 이 있다. 반쪽 연결만 예외로
뺐다 — 재시도가 의미 없는 유일한 경우다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -603,8 +603,20 @@ class BleManager private constructor(private val context: Context) {
|
||||
isServiceReady.value = false
|
||||
isConnecting.value = false
|
||||
connectionError.value = "HALF_CONNECTED"
|
||||
// 사용자가 끊은 게 아니면 계속 되살린다.
|
||||
if (!isUserDisconnect && lastConnectedAddress != null) scheduleAutoReconnect()
|
||||
// 2026-09-15: **여기서 재연결하지 않는다** (사용자 지시).
|
||||
//
|
||||
// 종전에는 `scheduleAutoReconnect()` 를 걸었는데, 반쪽 연결은 프로브가 갇힌
|
||||
// 상태라 다시 붙어도 같은 결과가 나온다. 실측에서 23초 주기로 무한 반복했다
|
||||
// (11:08~11:10 Xiaomi · RSSI −46 · 4회 연속 HALF_CONNECTED):
|
||||
//
|
||||
// 연결 → MTU×2 → 20초 뒤 HALF_CONNECTED → 3초 뒤 재연결 → 반복
|
||||
//
|
||||
// 링크는 매번 붙으므로 재시도 카운터가 1 로 리셋돼 escalation 도 없었다
|
||||
// (`attempt=1/-1`). 화면에는 "재연결 중" 만 계속 뜨고, 조작자는 무엇을 해야
|
||||
// 하는지 알 수 없다 — 임상에서 이게 제일 나쁘다.
|
||||
//
|
||||
// 이 상태를 푸는 것은 **프로브 전원 재투입**이고 앱이 할 수 있는 일이 아니다.
|
||||
// 그래서 멈추고 `connectionError` 로 알린다 — 사용자가 판단한다.
|
||||
}
|
||||
halfConnGuard = r
|
||||
handler.postDelayed(r, SERVICE_READY_GUARD_MS)
|
||||
|
||||
@@ -371,7 +371,9 @@
|
||||
<string name="device_scan_enter_measurement_dev">측정 모드 진입 (Dev)</string>
|
||||
<string name="device_scan_saved_devices">저장된 기기</string>
|
||||
<string name="device_scan_connect_stuck_err">연결이 끝나지 않았습니다. 기기를 다시 눌러 주세요.</string>
|
||||
<string name="ble_error_half_connected">연결이 끝까지 되지 않았습니다 — 기기가 응답했지만 준비를 마치지 못했습니다. 다시 연결합니다.</string>
|
||||
<string name="ble_error_half_connected">연결이 끝까지 되지 않았습니다 — 기기가 응답했지만 준비를 마치지 못했습니다.
|
||||
|
||||
프로브 전원을 껐다 켠 뒤 다시 연결해 주세요. 다시 시도해도 같으면 다른 프로브를 쓰세요.</string>
|
||||
<string name="ble_error_unbond_unreachable">페어링을 삭제할 수 없습니다: 기기에 명령이 닿지 않습니다. 기기 버튼을 15초 길게 눌러 초기화한 뒤, 저장된 기기를 삭제하고 다시 페어링하세요.</string>
|
||||
<string name="ble_error_not_advertising">기기 신호가 잡히지 않습니다. 방금 연결을 끊었다면 기기가 다시 신호를 보낼 때까지 10~20초 걸릴 수 있습니다 — 잠시 뒤 다시 눌러 주세요. 계속 안 되면 전원을 확인하세요.</string>
|
||||
<string name="device_scan_new_devices">새 기기</string>
|
||||
|
||||
@@ -371,7 +371,9 @@
|
||||
<string name="device_scan_enter_measurement_dev">Enter Measurement Mode (Dev)</string>
|
||||
<string name="device_scan_saved_devices">Saved Devices</string>
|
||||
<string name="device_scan_connect_stuck_err">Connection did not finish. Tap the device again.</string>
|
||||
<string name="ble_error_half_connected">Connection was incomplete — the device answered but did not finish setup. Reconnecting.</string>
|
||||
<string name="ble_error_half_connected">Connection was incomplete — the device answered but did not finish setup.
|
||||
|
||||
Power the probe off and on, then connect again. If it repeats, use a different probe.</string>
|
||||
<string name="ble_error_unbond_unreachable">Cannot delete pairing: the device is not reachable. Hold the device button for 15 seconds to reset it, then delete the saved device and pair again.</string>
|
||||
<string name="ble_error_not_advertising">No signal from the device. If you just disconnected, it can take 10-20 seconds to start advertising again — wait a moment and tap it again. If it keeps failing, check the power.</string>
|
||||
<string name="device_scan_new_devices">New Devices</string>
|
||||
|
||||
Reference in New Issue
Block a user