Skip to content

Commit 49b6607

Browse files
Implement TransferParticipant using SIP REFER messages (#182)
1 parent ff95fd0 commit 49b6607

File tree

13 files changed

+707
-49
lines changed

13 files changed

+707
-49
lines changed

cmd/livekit-sip/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func runService(c *cli.Context) error {
9191
}
9292

9393
sipsrv := sip.NewService(conf, mon, log)
94-
svc := service.NewService(conf, log, sipsrv.InternalServerImpl(), sipsrv.Stop, sipsrv.ActiveCalls, psrpcClient, bus, mon)
94+
svc := service.NewService(conf, log, sipsrv, sipsrv.Stop, sipsrv.ActiveCalls, psrpcClient, bus, mon)
9595
sipsrv.SetHandler(svc)
9696

9797
if err = sipsrv.Start(); err != nil {

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ require (
1313
github.com/jfreymuth/oggvorbis v1.0.5
1414
github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1
1515
github.com/livekit/mediatransportutil v0.0.0-20240625074155-301bb4a816b7
16-
github.com/livekit/protocol v1.21.1-0.20240913074525-1f5de7d620c4
16+
github.com/livekit/protocol v1.22.1-0.20240920184753-71b9c184e5c8
1717
github.com/livekit/psrpc v0.5.3-0.20240616012458-ac39c8549a0a
1818
github.com/livekit/server-sdk-go/v2 v2.2.1-0.20240726160203-3f7f396734c3
1919
github.com/mjibson/go-dsp v0.0.0-20180508042940-11479a337f12
@@ -22,12 +22,14 @@ require (
2222
github.com/pion/rtp v1.8.6
2323
github.com/pion/sdp/v3 v3.0.9
2424
github.com/pion/webrtc/v3 v3.2.47
25+
github.com/pkg/errors v0.9.1
2526
github.com/prometheus/client_golang v1.19.1
2627
github.com/sirupsen/logrus v1.9.3
2728
github.com/stretchr/testify v1.9.0
2829
github.com/urfave/cli/v2 v2.27.2
2930
github.com/zaf/resample v1.5.0
3031
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
32+
google.golang.org/protobuf v1.34.2
3133
gopkg.in/hraban/opus.v2 v2.0.0-20230925203106-0188a62cb302
3234
gopkg.in/yaml.v3 v3.0.1
3335
)
@@ -96,7 +98,6 @@ require (
9698
github.com/pion/stun v0.6.1 // indirect
9799
github.com/pion/transport/v2 v2.2.5 // indirect
98100
github.com/pion/turn/v2 v2.1.6 // indirect
99-
github.com/pkg/errors v0.9.1 // indirect
100101
github.com/pmezard/go-difflib v1.0.0 // indirect
101102
github.com/prometheus/client_model v0.5.0 // indirect
102103
github.com/prometheus/common v0.48.0 // indirect
@@ -126,7 +127,6 @@ require (
126127
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
127128
google.golang.org/genproto/googleapis/rpc v0.0.0-20240725223205-93522f1f2a9f // indirect
128129
google.golang.org/grpc v1.65.0 // indirect
129-
google.golang.org/protobuf v1.34.2 // indirect
130130
gopkg.in/yaml.v2 v2.4.0 // indirect
131131
)
132132

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 h1:jm09419p0lqTkD
124124
github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ=
125125
github.com/livekit/mediatransportutil v0.0.0-20240625074155-301bb4a816b7 h1:F1L8inJoynwIAYpZENNYS+1xHJMF5RFRorsnAlcxfSY=
126126
github.com/livekit/mediatransportutil v0.0.0-20240625074155-301bb4a816b7/go.mod h1:jwKUCmObuiEDH0iiuJHaGMXwRs3RjrB4G6qqgkr/5oE=
127-
github.com/livekit/protocol v1.21.1-0.20240913074525-1f5de7d620c4 h1:JhLovaAv+UxOTYpjQxN3IRV3kuJFb9f3LZmg/KqvHkc=
128-
github.com/livekit/protocol v1.21.1-0.20240913074525-1f5de7d620c4/go.mod h1:AFuwk3+uIWFeO5ohKjx5w606Djl940+wktaZ441VoCI=
127+
github.com/livekit/protocol v1.22.1-0.20240920184753-71b9c184e5c8 h1:Tt/INVn5HOgyy/OknLzEK46sWDKRnQ+NvsjFkMZDbWc=
128+
github.com/livekit/protocol v1.22.1-0.20240920184753-71b9c184e5c8/go.mod h1:AFuwk3+uIWFeO5ohKjx5w606Djl940+wktaZ441VoCI=
129129
github.com/livekit/psrpc v0.5.3-0.20240616012458-ac39c8549a0a h1:EQAHmcYEGlc6V517cQ3Iy0+jHgP6+tM/B4l2vGuLpQo=
130130
github.com/livekit/psrpc v0.5.3-0.20240616012458-ac39c8549a0a/go.mod h1:CQUBSPfYYAaevg1TNCc6/aYsa8DJH4jSRFdCeSZk5u0=
131131
github.com/livekit/server-sdk-go/v2 v2.2.1-0.20240726160203-3f7f396734c3 h1:I/XGsUSnB4ajiWNokzpuRLl8VirnaYyLPwKdjHxOHiE=

pkg/service/service.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,17 @@ func (s *Service) DeregisterCreateSIPParticipantTopic() {
193193
s.rpcSIPServer.DeregisterCreateSIPParticipantTopic(s.conf.ClusterID)
194194
}
195195
}
196+
197+
func (s *Service) RegisterTransferSIPParticipantTopic(sipCallId string) error {
198+
if s.rpcSIPServer != nil {
199+
return s.rpcSIPServer.RegisterTransferSIPParticipantTopic(sipCallId)
200+
}
201+
202+
return psrpc.NewErrorf(psrpc.Internal, "RPC server not started")
203+
}
204+
205+
func (s *Service) DeregisterTransferSIPParticipantTopic(sipCallId string) {
206+
if s.rpcSIPServer != nil {
207+
s.rpcSIPServer.DeregisterTransferSIPParticipantTopic(sipCallId)
208+
}
209+
}

pkg/sip/client.go

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
"github.com/livekit/protocol/rpc"
3030
"github.com/livekit/protocol/tracer"
3131
"github.com/livekit/sip/pkg/config"
32-
"github.com/livekit/sip/pkg/errors"
32+
siperrors "github.com/livekit/sip/pkg/errors"
3333
"github.com/livekit/sip/pkg/stats"
3434
)
3535

@@ -46,6 +46,8 @@ type Client struct {
4646
cmu sync.Mutex
4747
activeCalls map[LocalTag]*outboundCall
4848
byRemote map[RemoteTag]*outboundCall
49+
50+
handler Handler
4951
}
5052

5153
func NewClient(conf *config.Config, log logger.Logger, mon *stats.Monitor) *Client {
@@ -119,6 +121,10 @@ func (c *Client) Stop() {
119121
}
120122
}
121123

124+
func (c *Client) SetHandler(handler Handler) {
125+
c.handler = handler
126+
}
127+
122128
func (c *Client) CreateSIPParticipant(ctx context.Context, req *rpc.InternalCreateSIPParticipantRequest) (*rpc.InternalCreateSIPParticipantResponse, error) {
123129
ctx, span := tracer.Start(ctx, "Client.CreateSIPParticipant")
124130
defer span.End()
@@ -127,7 +133,7 @@ func (c *Client) CreateSIPParticipant(ctx context.Context, req *rpc.InternalCrea
127133

128134
func (c *Client) createSIPParticipant(ctx context.Context, req *rpc.InternalCreateSIPParticipantRequest) (*rpc.InternalCreateSIPParticipantResponse, error) {
129135
if !c.mon.CanAccept() {
130-
return nil, errors.ErrUnavailable
136+
return nil, siperrors.ErrUnavailable
131137
}
132138
if req.CallTo == "" {
133139
return nil, fmt.Errorf("call-to number must be set")
@@ -193,6 +199,7 @@ func (c *Client) createSIPParticipant(ctx context.Context, req *rpc.InternalCrea
193199
ParticipantIdentity: p.Identity,
194200
SipCallId: req.SipCallId,
195201
}, nil
202+
196203
}
197204

198205
func (c *Client) OnRequest(req *sip.Request, tx sip.ServerTransaction) bool {
@@ -201,6 +208,8 @@ func (c *Client) OnRequest(req *sip.Request, tx sip.ServerTransaction) bool {
201208
return false
202209
case "BYE":
203210
return c.onBye(req, tx)
211+
case "NOTIFY":
212+
return c.onNotify(req, tx)
204213
}
205214
}
206215

@@ -219,7 +228,29 @@ func (c *Client) onBye(req *sip.Request, tx sip.ServerTransaction) bool {
219228
return true
220229
}
221230

222-
func (c *Client) CreateSIPParticipantAffinity(ctx context.Context, req *rpc.InternalCreateSIPParticipantRequest) float32 {
223-
// TODO: scale affinity based on a number or active calls?
224-
return 0.5
231+
func (c *Client) onNotify(req *sip.Request, tx sip.ServerTransaction) bool {
232+
tag, _ := getFromTag(req)
233+
c.cmu.Lock()
234+
call := c.byRemote[tag]
235+
c.cmu.Unlock()
236+
if call == nil {
237+
return false
238+
}
239+
call.log.Infow("NOTIFY")
240+
go func() {
241+
err := call.cc.handleNotify(req, tx)
242+
243+
code, msg := sipCodeAndMessageFromError(err)
244+
245+
tx.Respond(sip.NewResponseFromRequest(req, code, msg, nil))
246+
}()
247+
return true
248+
}
249+
250+
func (c *Client) RegisterTransferSIPParticipant(sipCallID string, o *outboundCall) error {
251+
return c.handler.RegisterTransferSIPParticipantTopic(sipCallID)
252+
}
253+
254+
func (c *Client) DeregisterTransferSIPParticipant(sipCallID string) {
255+
c.handler.DeregisterTransferSIPParticipantTopic(sipCallID)
225256
}

0 commit comments

Comments
 (0)