Skip to content

Commit

Permalink
Pass remote SIP tag and SIP call ID to attrs. (#217)
Browse files Browse the repository at this point in the history
  • Loading branch information
dennwc authored Oct 31, 2024
1 parent 994e0d4 commit 87392f4
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 14 deletions.
9 changes: 8 additions & 1 deletion pkg/sip/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -840,14 +840,17 @@ func (s *Server) newInbound(id LocalTag, contact URI, invite *sip.Request, invit
if h != nil {
c.nextRequestCSeq = h.SeqNo + 1
}

if callID, _ := invite.CallID(); callID != nil {
c.callID = callID.Value()
}
return c
}

type sipInbound struct {
s *Server
id LocalTag
tag RemoteTag
callID string
invite *sip.Request
inviteTx sip.ServerTransaction
contact *sip.ContactHeader
Expand Down Expand Up @@ -934,6 +937,10 @@ func (c *sipInbound) Tag() RemoteTag {
return c.tag
}

func (c *sipInbound) CallID() string {
return c.callID
}

func (c *sipInbound) RemoteHeaders() Headers {
c.mu.RLock()
defer c.mu.RUnlock()
Expand Down
26 changes: 17 additions & 9 deletions pkg/sip/outbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,15 +422,13 @@ func (c *outboundCall) sipSignal(ctx context.Context) error {
}
joinDur()

if len(c.cc.RemoteHeaders()) != 0 {
extra := HeadersToAttrs(nil, c.sipConf.headersToAttrs, c.cc)
if c.lkRoom != nil && len(extra) != 0 {
room := c.lkRoom.Room()
if room != nil {
room.LocalParticipant.SetAttributes(extra)
} else {
c.log.Warnw("could not set attributes on nil room", nil, "attrs", extra)
}
extra := HeadersToAttrs(nil, c.sipConf.headersToAttrs, c.cc)
if c.lkRoom != nil && len(extra) != 0 {
room := c.lkRoom.Room()
if room != nil {
room.LocalParticipant.SetAttributes(extra)
} else {
c.log.Warnw("could not set attributes on nil room", nil, "attrs", extra)
}
}
return nil
Expand Down Expand Up @@ -512,6 +510,7 @@ type sipOutbound struct {

mu sync.RWMutex
tag RemoteTag
callID string
invite *sip.Request
inviteOk *sip.Response
to *sip.ToHeader
Expand Down Expand Up @@ -544,6 +543,12 @@ func (c *sipOutbound) Tag() RemoteTag {
return c.tag
}

func (c *sipOutbound) CallID() string {
c.mu.RLock()
defer c.mu.RUnlock()
return c.callID
}

func (c *sipOutbound) RemoteHeaders() Headers {
c.mu.RLock()
defer c.mu.RUnlock()
Expand Down Expand Up @@ -647,6 +652,9 @@ authLoop:
if !ok {
return nil, errors.New("no tag in To header in INVITE response")
}
if callID, _ := c.invite.CallID(); callID != nil {
c.callID = callID.Value()
}
h, _ := c.invite.CSeq()
if h != nil {
c.nextRequestCSeq = h.SeqNo + 1
Expand Down
5 changes: 5 additions & 0 deletions pkg/sip/participant.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ const (
defaultRingingTimeout = 3 * time.Minute
)

const (
AttrSIPCallIDFull = livekit.AttrSIPPrefix + "callIDFull"
AttrSIPCallTag = livekit.AttrSIPPrefix + "callTag"
)

var headerToLog = map[string]string{
"X-Twilio-AccountSid": "twilioAccSID",
"X-Twilio-CallSid": "twilioCallSID",
Expand Down
1 change: 1 addition & 0 deletions pkg/sip/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type Signaling interface {
To() sip.Uri
ID() LocalTag
Tag() RemoteTag
CallID() string
RemoteHeaders() Headers

WriteRequest(req *sip.Request) error
Expand Down
6 changes: 6 additions & 0 deletions pkg/sip/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,5 +213,11 @@ func HeadersToAttrs(attrs, hdrToAttr map[string]string, c Signaling) map[string]
attrs[name] = h.Value()
}
}
if tag := c.Tag(); tag != "" {
attrs[AttrSIPCallTag] = string(tag)
}
if cid := c.CallID(); cid != "" {
attrs[AttrSIPCallIDFull] = cid
}
return attrs
}
36 changes: 32 additions & 4 deletions test/lktest/sip.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package lktest
import (
"context"
"maps"
"slices"
"strings"

"github.com/livekit/protocol/livekit"
Expand All @@ -27,13 +28,36 @@ import (

func checkSIPAttrs(t TB, exp, got map[string]string) (_, _ map[string]string) {
exp, got = maps.Clone(exp), maps.Clone(got)
if _, ok := exp[livekit.AttrSIPCallID]; ok {
require.True(t, strings.HasPrefix(got[livekit.AttrSIPCallID], guid.SIPCallPrefix))
delete(exp, livekit.AttrSIPCallID)
delete(got, livekit.AttrSIPCallID)

var keepKeys []string
for _, a := range []string{
livekit.AttrSIPCallID,
livekit.AttrSIPPrefix + "callIDFull",
livekit.AttrSIPPrefix + "callTag",
} {
if _, ok := exp[a]; !ok {
continue
}
v, ok := got[a]
if !ok {
// let the caller fail
keepKeys = append(keepKeys, a)
continue
}
require.True(t, ok, "missing attribute %q", a)
require.NotEmpty(t, v, "empty attribute %q", a)
switch a {
case livekit.AttrSIPCallID:
require.True(t, strings.HasPrefix(v, guid.SIPCallPrefix))
}
delete(exp, a)
delete(got, a)
}
// remove extra attributes from comparison
for key := range got {
if slices.Contains(keepKeys, key) {
continue
}
if _, ok := exp[key]; !ok {
delete(got, key)
}
Expand Down Expand Up @@ -129,6 +153,8 @@ func TestSIPOutbound(t TB, ctx context.Context, lkOut, lkIn *LiveKit, params SIP
t.Log("checking rooms (outbound)")
expAttrsOut := map[string]string{
"sip.callID": "<test>", // special case
"sip.callTag": "<test>", // special case
"sip.callIDFull": "<test>", // special case
"sip.callStatus": "active",
"sip.trunkPhoneNumber": params.NumberOut,
"sip.phoneNumber": params.NumberIn,
Expand All @@ -150,6 +176,8 @@ func TestSIPOutbound(t TB, ctx context.Context, lkOut, lkIn *LiveKit, params SIP
t.Log("checking rooms (inbound)")
expAttrsIn := map[string]string{
"sip.callID": "<test>", // special case
"sip.callTag": "<test>", // special case
"sip.callIDFull": "<test>", // special case
"sip.callStatus": "active",
"sip.trunkPhoneNumber": params.NumberIn,
"sip.phoneNumber": params.NumberOut,
Expand Down

0 comments on commit 87392f4

Please sign in to comment.