mirror of
https://github.com/MengMengCode/VoCat.git
synced 2026-08-21 23:33:42 +08:00
fix: ignore non-voice CLCC records in call monitor (#71)
Co-authored-by: geekouc <[email protected]>
This commit is contained in:
@@ -325,11 +325,7 @@ func (s *Server) pollCellularCalls(ctx context.Context) {
|
||||
}
|
||||
calls := parseCLCC(response)
|
||||
for _, call := range calls {
|
||||
direction, _ := call["direction"].(int)
|
||||
state, _ := call["state"].(int)
|
||||
// direction 1 = incoming (Mobile Terminated)
|
||||
// state 4 = incoming/ringing, 5 = waiting, 0 = active, 3 = alerting
|
||||
if direction == 1 && (state == 4 || state == 5 || state == 0 || state == 3) {
|
||||
if isIncomingVoiceCLCC(call) {
|
||||
caller, _ := call["number"].(string)
|
||||
if caller == "" {
|
||||
caller = "未知号码"
|
||||
@@ -351,3 +347,13 @@ func (s *Server) pollCellularCalls(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isIncomingVoiceCLCC(call map[string]any) bool {
|
||||
direction, _ := call["direction"].(int)
|
||||
state, _ := call["state"].(int)
|
||||
mode, _ := call["mode"].(int)
|
||||
// direction 1 = incoming (Mobile Terminated)
|
||||
// mode 0 = voice; some modems also expose packet-data sessions as CLCC mode 1
|
||||
// state 4 = incoming/ringing, 5 = waiting, 0 = active, 3 = alerting
|
||||
return direction == 1 && mode == 0 && (state == 4 || state == 5 || state == 0 || state == 3)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"vocat/internal/modem"
|
||||
)
|
||||
|
||||
func TestIncomingCallNotificationTextFormatting(t *testing.T) {
|
||||
@@ -61,6 +63,56 @@ func TestIncomingCallDeduplication(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIncomingVoiceCLCCIgnoresDataSessions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
call map[string]any
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "incoming voice ringing",
|
||||
call: map[string]any{"direction": 1, "state": 4, "mode": 0},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "incoming voice active",
|
||||
call: map[string]any{"direction": 1, "state": 0, "mode": 0},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "incoming packet data active",
|
||||
call: map[string]any{"direction": 1, "state": 0, "mode": 1},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "outgoing voice alerting",
|
||||
call: map[string]any{"direction": 0, "state": 3, "mode": 0},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if got := isIncomingVoiceCLCC(test.call); got != test.want {
|
||||
t.Fatalf("isIncomingVoiceCLCC() = %v, want %v", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// EC20/EC25 firmware may expose an active packet-data session in CLCC.
|
||||
// It must not be treated as an incoming voice call.
|
||||
dataCalls := parseCLCC(modem.Response{
|
||||
Lines: []string{`+CLCC: 1,1,0,1,0,"",128`},
|
||||
Final: "OK",
|
||||
})
|
||||
if len(dataCalls) != 1 {
|
||||
t.Fatalf("parseCLCC() returned %d data calls, want 1", len(dataCalls))
|
||||
}
|
||||
if isIncomingVoiceCLCC(dataCalls[0]) {
|
||||
t.Fatal("active packet-data CLCC record was treated as an incoming voice call")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderCallWebhookTemplate(t *testing.T) {
|
||||
now := time.Date(2026, 8, 20, 10, 30, 0, 0, time.UTC)
|
||||
message := IncomingCallNotification{
|
||||
|
||||
Reference in New Issue
Block a user