From 337aa3c0ab92bf7a3be6426bfe9df9fdbb5200a3 Mon Sep 17 00:00:00 2001 From: MengMengCode Date: Sun, 9 Aug 2026 21:31:24 +0800 Subject: [PATCH] fix: route calls only through ready IMS sessions --- internal/server/call_api.go | 6 +++++- internal/server/call_api_test.go | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/internal/server/call_api.go b/internal/server/call_api.go index 0949cbe..a44e069 100644 --- a/internal/server/call_api.go +++ b/internal/server/call_api.go @@ -203,7 +203,11 @@ func (s *Server) hangupVoWiFiAfter(deviceID, callID string, duration time.Durati func (s *Server) callTransport(deviceID string) string { if s.vowifi != nil { - if state, err := s.vowifi.State(deviceID); err == nil && state.Enabled { + // Enabled is only the desired card policy. Calls can use IMS only after + // registration has actually completed; otherwise keep using the modem's + // circuit-switched call path instead of routing into an unavailable IMS + // session. + if state, err := s.vowifi.State(deviceID); err == nil && state.IMSReady { return "vowifi" } } diff --git a/internal/server/call_api_test.go b/internal/server/call_api_test.go index b277396..f3538d4 100644 --- a/internal/server/call_api_test.go +++ b/internal/server/call_api_test.go @@ -4,6 +4,7 @@ import ( "testing" "vocat/internal/modem" + "vocat/internal/vowifi" ) func TestParseCLCC(t *testing.T) { @@ -28,3 +29,15 @@ func TestValidDialNumber(t *testing.T) { } } } + +func TestCallTransportRequiresIMSReady(t *testing.T) { + controller := &fakeVoWiFiController{state: vowifi.State{Enabled: true}} + server := &Server{vowifi: controller} + if got := server.callTransport("ec20"); got != "cellular" { + t.Fatalf("callTransport before IMS registration = %q, want cellular", got) + } + controller.state.IMSReady = true + if got := server.callTransport("ec20"); got != "vowifi" { + t.Fatalf("callTransport with IMS ready = %q, want vowifi", got) + } +}