fix(ims): omit empty PANI call headers

This commit is contained in:
MengMengCode
2026-08-21 23:10:04 +08:00
parent 54288e5657
commit b12ea27123
2 changed files with 63 additions and 4 deletions
+17 -4
View File
@@ -115,7 +115,9 @@ func (session *Session) DialCall(ctx context.Context, number string) (vowifi.Cal
"P-Preferred-Identity: <"+preferredIdentity+">",
"P-Preferred-Service: "+mmtelServiceURN,
`Accept-Contact: *;+g.3gpp.icsi-ref="`+mmtelFeatureTag+`"`,
"P-Access-Network-Info: "+session.pAccessNetworkInfo(),
)
lines = session.appendPAccessNetworkInfoHeader(lines)
lines = append(lines,
"User-Agent: "+session.imsUserAgent(),
"Allow: INVITE, ACK, CANCEL, BYE, OPTIONS, MESSAGE, PRACK, UPDATE, INFO",
"Supported: 100rel, timer, replaces",
@@ -499,7 +501,9 @@ func (session *Session) sendRejectedInviteACK(call *imsCall, response *sipRespon
"To: "+to,
"Call-ID: "+call.callID,
fmt.Sprintf("CSeq: %d ACK", call.cseq),
"P-Access-Network-Info: "+session.pAccessNetworkInfo(),
)
lines = session.appendPAccessNetworkInfoHeader(lines)
lines = append(lines,
"User-Agent: "+session.imsUserAgent(),
"Content-Length: 0", "", "",
)
@@ -577,7 +581,9 @@ func (session *Session) sendPRACK(call *imsCall, response *sipResponse) {
lines = append(lines,
"From: "+from, "To: "+to, "Call-ID: "+call.callID,
fmt.Sprintf("CSeq: %d PRACK", cseq), "RAck: "+rseq+" "+inviteCSeq,
"P-Access-Network-Info: "+session.pAccessNetworkInfo(),
)
lines = session.appendPAccessNetworkInfoHeader(lines)
lines = append(lines,
"User-Agent: "+session.imsUserAgent(),
"Content-Length: 0", "", "",
)
@@ -712,7 +718,7 @@ func (session *Session) buildDialogRequest(call *imsCall, method string, cseq ui
"User-Agent: "+session.imsUserAgent(),
)
if method != "CANCEL" {
lines = append(lines, "P-Access-Network-Info: "+session.pAccessNetworkInfo())
lines = session.appendPAccessNetworkInfoHeader(lines)
}
if method == "UPDATE" {
lines = append(lines, session.dialogContactHeader())
@@ -827,6 +833,13 @@ func (session *Session) pAccessNetworkInfo() string {
return resolveSessionPAccessNetworkInfo(session.request.Identity, session.imsLogger())
}
func (session *Session) appendPAccessNetworkInfoHeader(lines []string) []string {
if pani := session.pAccessNetworkInfo(); pani != "" {
return append(lines, "P-Access-Network-Info: "+pani)
}
return lines
}
func callResponseDiagnostic(response *sipResponse) string {
if response == nil {
return ""
+46
View File
@@ -4,6 +4,8 @@ import (
"context"
"io"
"net"
"os"
"path/filepath"
"strings"
"testing"
"time"
@@ -239,6 +241,50 @@ func TestOutgoingLocalNumberUsesIMSPhoneContextAndMMTelHeaders(t *testing.T) {
}
}
func TestDialogRequestOmitsPAccessNetworkInfoWhenProfileDisablesPANI(t *testing.T) {
profileDir := t.TempDir()
profile := `{"version":1,"profiles":[{"id":"test-pani-disabled","match":{"home_plmns":["00101"]},"ims":{"pani_enabled":false}}]}`
if err := os.WriteFile(filepath.Join(profileDir, "pani-disabled.json"), []byte(profile), 0o600); err != nil {
t.Fatal(err)
}
emptyProfileDir := t.TempDir()
t.Cleanup(func() {
if err := vowifi.LoadCarrierProfileDirectory(emptyProfileDir); err != nil {
t.Errorf("clear external carrier profiles: %v", err)
}
})
if err := vowifi.LoadCarrierProfileDirectory(profileDir); err != nil {
t.Fatal(err)
}
identity := vowifi.SIMIdentity{HomeMCC: "001", HomeMNC: "01", IMSI: "001010123456789"}
pani := resolveSessionPAccessNetworkInfo(identity, nil)
if pani != "" {
t.Fatalf("disabled profile PANI = %q, want empty", pani)
}
client, peer := net.Pipe()
defer client.Close()
defer peer.Close()
session := &Session{
request: vowifi.IMSRequest{Identity: identity},
transport: "tcp",
conn: client,
pani: pani,
paniResolved: true,
}
call := &imsCall{
target: "sip:[email protected]",
from: "<sip:[email protected]>;tag=local",
to: "<sip:[email protected]>;tag=remote",
callID: "pani-disabled-call",
}
request := string(session.buildDialogRequest(call, "BYE", 2))
if strings.Contains(request, "\r\nP-Access-Network-Info:") {
t.Fatalf("BYE contains disabled P-Access-Network-Info header:\n%s", request)
}
}
func TestCallOriginatingIdentitiesFallBackToRegisteredIMPU(t *testing.T) {
session := &Session{
identity: identitySet{