watchdog이 실제로 돌고 있는지, 어디서 멈추는지 진단용.
매 5초: WATCHDOG_CHECK silence=Xms connected=true/false
interrupt 시: WATCHDOG_THREAD interrupted
flag 종료 시: WATCHDOG_THREAD stopped
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
기존: handler.post 안에서 로그+disconnect → handler 블로킹 시 둘 다 안 됨
변경:
- debugLogger.error() → watchdog Thread에서 직접 호출 (CopyOnWriteArrayList 스레드 안전)
- gatt.disconnect()/close() → watchdog Thread에서 직접 호출 (GATT는 any thread OK)
- UI 업데이트 + reconnect만 handler.post로 전달
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CCCD 없는 경로(no CCCD, no RX)에서도 startWatchdog() + startBatteryPolling() 호출
- watchdog 시작 시 WATCHDOG_STARTED 로그 기록 (실제 동작 확인용)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
기존: handler.postDelayed로 watchdog 실행 → BLE 스택이 handler를
블로킹하면 watchdog도 멈춤 (좀비 상태 감지 불가)
변경: 별도 daemon Thread에서 5초마다 lastRxTimestamp 체크
→ BLE handler가 블로킹되어도 독립적으로 15초 타임아웃 감지
→ 감지 시 handler.post로 메인 스레드에서 forceDisconnectAndReconnect 실행
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
기존: connectGatt(autoConnect=true) — Android에서 매우 불안정, 수분 걸림
변경: BLE 스캔으로 기기를 다시 찾은 후 connectGatt(autoConnect=false)로 빠르게 연결
재연결 흐름:
1. watchdog 15초 타임아웃 → forceDisconnectAndReconnect()
2. scheduleAutoReconnect() → 3s/5s/10s 백오프
3. attemptAutoReconnect():
- BLE 스캔 시작 (기기 이름 or MAC 주소 매칭)
- 발견 시 즉시 connectGatt(autoConnect=false) → 빠른 연결
- 8초 스캔 타임아웃 → 다음 attempt
- 최대 5회 시도 후 실패 처리
4. 모든 단계 BleDebugLogger에 기록
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Android BLE가 disconnect 콜백을 안 보내는 경우(좀비 연결) 대응:
- 마지막 RX로부터 15초간 응답 없으면 강제 disconnect → auto reconnect
- processReceivedData()에서 lastRxTimestamp 갱신
- 5초마다 watchdog 체크
- WATCHDOG_TIMEOUT 이벤트 BleDebugLogger에 기록
- 수동 disconnect 시 watchdog 해제
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- BleManager: 배터리 폴링 30초→5초 (펌웨어 15초 타임아웃 방지, iOS 동일)
- BleManager: 자동 reconnect with 백오프 (3s→5s→10s, 최대 5회)
- scheduleAutoReconnect() + attemptAutoReconnect()
- GATT 에러 시에도 백오프 재시도
- 수동 disconnect 시 자동 reconnect 취소
- PiezoMonitoringView: 끊김 시 즉시 파란 배너(RECONNECTING)
- 성공 시 배너 자동 숨김 + 배터리 폴링 재시작
- 5회 실패 시 빨간 배너 + 수동 Reconnect 버튼
- 측정 중 끊김 → isMeasuring 리셋 + 자동측정 중지
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A. Reminder: ReminderService (AlarmManager chain), ReminderSettingsView,
bell icon in Piezo top bar, reschedule on catheterization
B. Consent: ConsentView (3 mandatory items), onboarding→consent→registration flow,
persistent consent storage, sex field in User + Registration Step 2
C. Diary: 24hUV, NUV, NPI, max capacity, day/night frequency metrics card
D. Design: DesignTokens.kt, 48dp touch targets, DonutChart semantics, pressScale modifier
E. Quality: BuildConfig.DEBUG log wrapping, DateFormatter caching, background I/O for diary store
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clear mcj callback immediately on stop to prevent stale responses from
triggering new polling chains. Delay battery polling resume by 500ms to
avoid command collision with in-flight mcj response. Add sendNirsPowerOff
for future use.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix BLE API deprecation warnings with API 33+ version checks
- Move isServiceReady to onDescriptorWrite for reliable CCCD setup
- Fix battery polling: immediate query on connect, pause during NIRS streaming
- Add mcj retry mechanism for NIRS streaming reliability
- Add debug logging to BLE, NIRS parsing, and processing pipeline
- Add catheter count feature to Piezo monitoring (persistent count, add dialog, auto-decrement on catheterize)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Port of MedilightV2 iOS app to Android with Kotlin + Jetpack Compose.
Includes BLE connectivity, NIRS/Piezo sensor modes, Rive animations,
interactive measurement history charts, and foldable device support.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>