Skip to content

Commit

Permalink
Add methods to set up callbacks on 3xx ACK and CANCEL request building
Browse files Browse the repository at this point in the history
`OnAck(fn func(sip.Request))` - sets callback on 3xx ACK request building during INVITE transaction;
`OnCancel(fn func(sip.Request))` - sets callback on CANCEL request building during INVITE transaction.
  • Loading branch information
ghettovoice committed Aug 27, 2024
1 parent f0e1df9 commit 24d12c0
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 3 deletions.
18 changes: 18 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ type RequestWithContextOption interface {
type RequestWithContextOptions struct {
ResponseHandler func(res sip.Response, request sip.Request)
Authorizer sip.Authorizer
ClientTransactionCallbacks
}

type ClientTransactionCallbacks struct {
OnAck, OnCancel func(sip.Request)
}

type withResponseHandler struct {
Expand All @@ -34,3 +39,16 @@ func (o withAuthorizer) ApplyRequestWithContext(options *RequestWithContextOptio
func WithAuthorizer(authorizer sip.Authorizer) RequestWithContextOption {
return withAuthorizer{authorizer}
}

type withClientTxCallbacks struct {
onAckFn, onCancFn func(sip.Request)
}

func WithClientTransactionCallbacks(callbacks ClientTransactionCallbacks) RequestWithContextOption {
return withClientTxCallbacks{callbacks.OnAck, callbacks.OnCancel}
}

func (o withClientTxCallbacks) ApplyRequestWithContext(options *RequestWithContextOptions) {
options.OnAck = o.onAckFn
options.OnCancel = o.onCancFn
}
13 changes: 10 additions & 3 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,21 @@ func (srv *server) requestWithContext(
attempt int,
options ...RequestWithContextOption,
) (sip.Response, error) {
optionsHash := &RequestWithContextOptions{}
for _, opt := range options {
opt.ApplyRequestWithContext(optionsHash)
}

tx, err := srv.Request(request)
if err != nil {
return nil, err
}

optionsHash := &RequestWithContextOptions{}
for _, opt := range options {
opt.ApplyRequestWithContext(optionsHash)
if optionsHash.OnAck != nil {
tx.OnAck(optionsHash.OnAck)
}
if optionsHash.OnCancel != nil {
tx.OnCancel(optionsHash.OnCancel)
}

txResponses := tx.Responses()
Expand Down
3 changes: 3 additions & 0 deletions sip/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ type ClientTransaction interface {
Transaction
Responses() <-chan Response
Cancel() error

OnAck(fn func(Request))
OnCancel(fn func(Request))
}
25 changes: 25 additions & 0 deletions transaction/client_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ type ClientTx interface {
Tx
Responses() <-chan sip.Response
Cancel() error

OnAck(fn func(sip.Request))
OnCancel(fn func(sip.Request))
}

type clientTx struct {
Expand All @@ -31,6 +34,8 @@ type clientTx struct {

mu sync.RWMutex
closeOnce sync.Once

onAckFn, onCancFn func(sip.Request)
}

func NewClientTx(origin sip.Request, tpl sip.Transport, logger log.Logger) (ClientTx, error) {
Expand Down Expand Up @@ -231,11 +236,15 @@ func (tx *clientTx) cancel() {

tx.mu.RLock()
lastResp := tx.lastResp
onCanc := tx.onCancFn
tx.mu.RUnlock()

cancelRequest := sip.NewCancelRequest("", tx.Origin(), log.Fields{
"sent_at": time.Now(),
})
if onCanc != nil {
onCanc(cancelRequest)
}
if err := tx.tpl.Send(cancelRequest); err != nil {
var lastRespStr string
if lastResp != nil {
Expand Down Expand Up @@ -264,11 +273,15 @@ func (tx *clientTx) cancel() {
func (tx *clientTx) ack() {
tx.mu.RLock()
lastResp := tx.lastResp
onAck := tx.onAckFn
tx.mu.RUnlock()

ack := sip.NewAckRequest("", tx.Origin(), lastResp, "", log.Fields{
"sent_at": time.Now(),
})
if onAck != nil {
onAck(ack)
}
err := tx.tpl.Send(ack)
if err != nil {
tx.Log().WithFields(log.Fields{
Expand Down Expand Up @@ -626,6 +639,18 @@ func (tx *clientTx) delete() {
tx.mu.Unlock()
}

func (tx *clientTx) OnAck(fn func(sip.Request)) {
tx.mu.Lock()
tx.onAckFn = fn
tx.mu.Unlock()
}

func (tx *clientTx) OnCancel(fn func(sip.Request)) {
tx.mu.Lock()
tx.onCancFn = fn
tx.mu.Unlock()
}

// Define actions
func (tx *clientTx) act_invite_resend() fsm.Input {
tx.Log().Debug("act_invite_resend")
Expand Down

0 comments on commit 24d12c0

Please sign in to comment.