Documentation
¶
Index ¶
- Variables
- func DiscoverPublicIPs(stunURLs []string, log *slog.Logger) []string
- type Leg
- type LegState
- type LegType
- type LiveKitParticipantLeg
- func (l *LiveKitParticipantLeg) AcceptDTMF() bool
- func (l *LiveKitParticipantLeg) AcceptText() bool
- func (l *LiveKitParticipantLeg) Answer(_ context.Context) error
- func (l *LiveKitParticipantLeg) AnsweredAt() time.Time
- func (l *LiveKitParticipantLeg) AppID() string
- func (l *LiveKitParticipantLeg) AudioReader() io.Reader
- func (l *LiveKitParticipantLeg) AudioWriter() io.Writer
- func (l *LiveKitParticipantLeg) ClaimDisconnect() bool
- func (l *LiveKitParticipantLeg) ClearSpeakingTap()
- func (l *LiveKitParticipantLeg) Context() context.Context
- func (l *LiveKitParticipantLeg) CreatedAt() time.Time
- func (l *LiveKitParticipantLeg) Hangup(_ context.Context) error
- func (l *LiveKitParticipantLeg) Headers() map[string]string
- func (l *LiveKitParticipantLeg) ID() string
- func (l *LiveKitParticipantLeg) Identity() string
- func (l *LiveKitParticipantLeg) IsDeaf() bool
- func (l *LiveKitParticipantLeg) IsHeld() bool
- func (l *LiveKitParticipantLeg) IsMuted() bool
- func (l *LiveKitParticipantLeg) OnDTMF(_ func(rune))
- func (l *LiveKitParticipantLeg) OnTextReceived(_ func(text string, lossMarker bool))
- func (l *LiveKitParticipantLeg) RTPStats() RTPStats
- func (l *LiveKitParticipantLeg) RTTNegotiated() bool
- func (l *LiveKitParticipantLeg) Role() string
- func (l *LiveKitParticipantLeg) RoomID() string
- func (l *LiveKitParticipantLeg) SIPHeaders() map[string]string
- func (l *LiveKitParticipantLeg) SampleRate() int
- func (l *LiveKitParticipantLeg) SendDTMF(_ context.Context, _ string) error
- func (l *LiveKitParticipantLeg) SendText(_ context.Context, _ string) error
- func (l *LiveKitParticipantLeg) SetAcceptDTMF(a bool)
- func (l *LiveKitParticipantLeg) SetAcceptText(a bool)
- func (l *LiveKitParticipantLeg) SetAppID(id string)
- func (l *LiveKitParticipantLeg) SetDeaf(d bool)
- func (l *LiveKitParticipantLeg) SetMuted(m bool)
- func (l *LiveKitParticipantLeg) SetRole(r string)
- func (l *LiveKitParticipantLeg) SetRoomID(id string)
- func (l *LiveKitParticipantLeg) SetSpeakingTap(io.Writer)
- func (l *LiveKitParticipantLeg) State() LegState
- func (l *LiveKitParticipantLeg) TrackSID() string
- func (l *LiveKitParticipantLeg) Type() LegType
- type LiveKitPublishLeg
- func (l *LiveKitPublishLeg) AcceptDTMF() bool
- func (l *LiveKitPublishLeg) AcceptText() bool
- func (l *LiveKitPublishLeg) Answer(_ context.Context) error
- func (l *LiveKitPublishLeg) AnsweredAt() time.Time
- func (l *LiveKitPublishLeg) AppID() string
- func (l *LiveKitPublishLeg) AudioReader() io.Reader
- func (l *LiveKitPublishLeg) AudioWriter() io.Writer
- func (l *LiveKitPublishLeg) ClaimDisconnect() bool
- func (l *LiveKitPublishLeg) ClearSpeakingTap()
- func (l *LiveKitPublishLeg) Context() context.Context
- func (l *LiveKitPublishLeg) CreatedAt() time.Time
- func (l *LiveKitPublishLeg) Hangup(_ context.Context) error
- func (l *LiveKitPublishLeg) Headers() map[string]string
- func (l *LiveKitPublishLeg) ID() string
- func (l *LiveKitPublishLeg) IsDeaf() bool
- func (l *LiveKitPublishLeg) IsHeld() bool
- func (l *LiveKitPublishLeg) IsMuted() bool
- func (l *LiveKitPublishLeg) OnDTMF(_ func(rune))
- func (l *LiveKitPublishLeg) OnTextReceived(_ func(text string, lossMarker bool))
- func (l *LiveKitPublishLeg) RTPStats() RTPStats
- func (l *LiveKitPublishLeg) RTTNegotiated() bool
- func (l *LiveKitPublishLeg) Role() string
- func (l *LiveKitPublishLeg) RoomID() string
- func (l *LiveKitPublishLeg) SIPHeaders() map[string]string
- func (l *LiveKitPublishLeg) SampleRate() int
- func (l *LiveKitPublishLeg) SendDTMF(_ context.Context, _ string) error
- func (l *LiveKitPublishLeg) SendText(_ context.Context, _ string) error
- func (l *LiveKitPublishLeg) SetAcceptDTMF(a bool)
- func (l *LiveKitPublishLeg) SetAcceptText(a bool)
- func (l *LiveKitPublishLeg) SetAppID(id string)
- func (l *LiveKitPublishLeg) SetDeaf(d bool)
- func (l *LiveKitPublishLeg) SetMuted(m bool)
- func (l *LiveKitPublishLeg) SetRole(r string)
- func (l *LiveKitPublishLeg) SetRoomID(id string)
- func (l *LiveKitPublishLeg) SetSpeakingTap(io.Writer)
- func (l *LiveKitPublishLeg) State() LegState
- func (l *LiveKitPublishLeg) Transport() *lkmedia.Transport
- func (l *LiveKitPublishLeg) Type() LegType
- type Manager
- type MoQLeg
- func (l *MoQLeg) AcceptDTMF() bool
- func (l *MoQLeg) AcceptText() bool
- func (l *MoQLeg) Answer(_ context.Context) error
- func (l *MoQLeg) AnsweredAt() time.Time
- func (l *MoQLeg) AppID() string
- func (l *MoQLeg) AudioReader() io.Reader
- func (l *MoQLeg) AudioWriter() io.Writer
- func (l *MoQLeg) ClaimDisconnect() bool
- func (l *MoQLeg) ClearSpeakingTap()
- func (l *MoQLeg) Context() context.Context
- func (l *MoQLeg) CreatedAt() time.Time
- func (l *MoQLeg) Hangup(_ context.Context) error
- func (l *MoQLeg) Headers() map[string]string
- func (l *MoQLeg) ID() string
- func (l *MoQLeg) IsDeaf() bool
- func (l *MoQLeg) IsHeld() bool
- func (l *MoQLeg) IsMuted() bool
- func (l *MoQLeg) OnDTMF(_ func(rune))
- func (l *MoQLeg) OnTextReceived(_ func(text string, lossMarker bool))
- func (l *MoQLeg) RTPStats() RTPStats
- func (l *MoQLeg) RTTNegotiated() bool
- func (l *MoQLeg) Role() string
- func (l *MoQLeg) RoomID() string
- func (l *MoQLeg) SIPHeaders() map[string]string
- func (l *MoQLeg) SampleRate() int
- func (l *MoQLeg) SendDTMF(_ context.Context, _ string) error
- func (l *MoQLeg) SendText(_ context.Context, _ string) error
- func (l *MoQLeg) SetAcceptDTMF(a bool)
- func (l *MoQLeg) SetAcceptText(a bool)
- func (l *MoQLeg) SetAppID(id string)
- func (l *MoQLeg) SetDeaf(d bool)
- func (l *MoQLeg) SetMuted(m bool)
- func (l *MoQLeg) SetRole(r string)
- func (l *MoQLeg) SetRoomID(id string)
- func (l *MoQLeg) SetSpeakingTap(io.Writer)
- func (l *MoQLeg) State() LegState
- func (l *MoQLeg) Transport() *moqmedia.Transport
- func (l *MoQLeg) Type() LegType
- type PCMedia
- func (m *PCMedia) AddICECandidate(c webrtc.ICECandidateInit) error
- func (m *PCMedia) AudioReader() io.Reader
- func (m *PCMedia) AudioWriter() io.Writer
- func (m *PCMedia) ClearSpeakingTap()
- func (m *PCMedia) Close() error
- func (m *PCMedia) Codec() codec.CodecType
- func (m *PCMedia) Context() context.Context
- func (m *PCMedia) DrainLocalCandidates() ([]webrtc.ICECandidateInit, bool)
- func (m *PCMedia) PC() *webrtc.PeerConnection
- func (m *PCMedia) SampleRate() int
- func (m *PCMedia) SetOnDTMF(fn func(digit rune))
- func (m *PCMedia) SetSpeakingTap(w io.Writer)
- func (m *PCMedia) Start()
- type PCMediaConfig
- type RTPStats
- type SIPLeg
- func NewSIPInboundLeg(call *sipmod.InboundCall, engine *sipmod.Engine, log *slog.Logger) *SIPLeg
- func NewSIPOutboundLeg(call *sipmod.OutboundCall, engine *sipmod.Engine, log *slog.Logger) *SIPLeg
- func NewSIPOutboundPendingLeg(engine *sipmod.Engine, codecs []codec.CodecType, log *slog.Logger) *SIPLeg
- func NewSIPRECInboundLeg(call *sipmod.InboundCall, engine *sipmod.Engine, log *slog.Logger) *SIPLeg
- func NewSIPRECOutboundLeg(call *sipmod.OutboundCall, engine *sipmod.Engine, log *slog.Logger) *SIPLeg
- func (l *SIPLeg) AcceptDTMF() bool
- func (l *SIPLeg) AcceptText() bool
- func (l *SIPLeg) AddStream(ctx context.Context, req StreamRequest) (StreamInfo, error)
- func (l *SIPLeg) Answer(ctx context.Context) error
- func (l *SIPLeg) AnswerCh() <-chan struct{}
- func (l *SIPLeg) AnsweredAt() time.Time
- func (l *SIPLeg) AppID() string
- func (l *SIPLeg) ApplyRemoteOffer(body []byte) (answer []byte, direction string)
- func (l *SIPLeg) AudioReader() io.Reader
- func (l *SIPLeg) AudioWriter() io.Writer
- func (l *SIPLeg) CallID() string
- func (l *SIPLeg) Challenge(ctx context.Context, params sipmod.ChallengeParams) error
- func (l *SIPLeg) ClaimDisconnect() bool
- func (l *SIPLeg) ClearAMDTapIf(w io.Writer) bool
- func (l *SIPLeg) ClearInTap()
- func (l *SIPLeg) ClearOutTap()
- func (l *SIPLeg) ClearSRCTaps()
- func (l *SIPLeg) ClearSpeakingTap()
- func (l *SIPLeg) ClearStreamInTap(streamID string)
- func (l *SIPLeg) ConnectOutbound(call *sipmod.OutboundCall) error
- func (l *SIPLeg) Context() context.Context
- func (l *SIPLeg) CreatedAt() time.Time
- func (l *SIPLeg) DialogIdentity() (callID, localTag, remoteTag string, ok bool)
- func (l *SIPLeg) DisconnectReason() string
- func (l *SIPLeg) EnableEarlyMedia(ctx context.Context, preferred codec.CodecType) error
- func (l *SIPLeg) HandleRemoteHold(direction string)
- func (l *SIPLeg) Hangup(ctx context.Context) error
- func (l *SIPLeg) Headers() map[string]string
- func (l *SIPLeg) Hold(ctx context.Context) error
- func (l *SIPLeg) ID() string
- func (l *SIPLeg) IsDeaf() bool
- func (l *SIPLeg) IsHeld() bool
- func (l *SIPLeg) IsMuted() bool
- func (l *SIPLeg) JitterBufferMs() int
- func (l *SIPLeg) OnDTMF(f func(digit rune))
- func (l *SIPLeg) OnHold(f func())
- func (l *SIPLeg) OnRTPTimeout(f func())
- func (l *SIPLeg) OnSessionExpired(f func())
- func (l *SIPLeg) OnTextReceived(f func(text string, lossMarker bool))
- func (l *SIPLeg) OnUnhold(f func())
- func (l *SIPLeg) OriginatingIdentity() (user, host string)
- func (l *SIPLeg) OwnsAMDTap(w io.Writer) bool
- func (l *SIPLeg) RTPStats() RTPStats
- func (l *SIPLeg) RTTNegotiated() bool
- func (l *SIPLeg) ReInviteAnswerSDP(remoteDirection string) []bytedeprecated
- func (l *SIPLeg) Reject(ctx context.Context, statusCode int, reasonPhrase string) error
- func (l *SIPLeg) RemoteOfferCodecs() []codec.CodecType
- func (l *SIPLeg) RemoveStream(ctx context.Context, streamID string) error
- func (l *SIPLeg) ResetSessionTimer()
- func (l *SIPLeg) Role() string
- func (l *SIPLeg) RoomID() string
- func (l *SIPLeg) SIPHeaders() map[string]string
- func (l *SIPLeg) SampleRate() int
- func (l *SIPLeg) SecondaryStreamIDs() []string
- func (l *SIPLeg) SendDTMF(ctx context.Context, digits string) error
- func (l *SIPLeg) SendNotifySipfrag(ctx context.Context, statusCode int, reason string, terminated bool) error
- func (l *SIPLeg) SendRinging(ctx context.Context) error
- func (l *SIPLeg) SendText(ctx context.Context, text string) error
- func (l *SIPLeg) SessionTimerParams() (interval uint32, refresher string)
- func (l *SIPLeg) SetAMDTap(w io.Writer)
- func (l *SIPLeg) SetAcceptDTMF(accept bool)
- func (l *SIPLeg) SetAcceptText(accept bool)
- func (l *SIPLeg) SetAppID(id string)
- func (l *SIPLeg) SetDeaf(d bool)
- func (l *SIPLeg) SetDisconnectReason(reason string)
- func (l *SIPLeg) SetHeld(held bool)
- func (l *SIPLeg) SetInTap(w io.Writer)
- func (l *SIPLeg) SetJitterBuffer(targetMs, maxMs int)
- func (l *SIPLeg) SetMuted(m bool)
- func (l *SIPLeg) SetOriginatingIdentity(user, host string)
- func (l *SIPLeg) SetOutTap(w io.Writer)
- func (l *SIPLeg) SetRole(r string)
- func (l *SIPLeg) SetRoomID(id string)
- func (l *SIPLeg) SetSRCTaps(in, out io.Writer)
- func (l *SIPLeg) SetSpeakingTap(w io.Writer)
- func (l *SIPLeg) SetStreamInTap(streamID string, w io.Writer) bool
- func (l *SIPLeg) SetStreamRole(streamID, role string)
- func (l *SIPLeg) SetStreamRoom(streamID, roomID string)
- func (l *SIPLeg) SetTrunkID(id string)
- func (l *SIPLeg) SetupEarlyMediaOutbound(remoteSDP *sipmod.SDPMedia, rtpSess *sipmod.RTPSession) error
- func (l *SIPLeg) SignalAnswer(preferred codec.CodecType)
- func (l *SIPLeg) State() LegState
- func (l *SIPLeg) Stream(streamID string) (StreamInfo, bool)
- func (l *SIPLeg) StreamCount() int
- func (l *SIPLeg) StreamMedia(streamID string) (StreamMedia, bool)
- func (l *SIPLeg) StreamRooms() map[string]string
- func (l *SIPLeg) Streams() []StreamInfo
- func (l *SIPLeg) StreamsIndependent() bool
- func (l *SIPLeg) SupportedCodecs() []codec.CodecType
- func (l *SIPLeg) Transfer(ctx context.Context, target string, replaces *sipmod.ReplacesParams) error
- func (l *SIPLeg) TrunkID() string
- func (l *SIPLeg) Type() LegType
- func (l *SIPLeg) Unhold(ctx context.Context) error
- func (l *SIPLeg) WaitConnected(ctx context.Context) error
- type SIPResponseLogger
- type StreamInfo
- type StreamMedia
- type StreamRequest
- type WebRTCLeg
- func (l *WebRTCLeg) AcceptDTMF() bool
- func (l *WebRTCLeg) AcceptText() bool
- func (l *WebRTCLeg) AddICECandidate(c webrtc.ICECandidateInit) error
- func (l *WebRTCLeg) Answer(_ context.Context) error
- func (l *WebRTCLeg) AnsweredAt() time.Time
- func (l *WebRTCLeg) AppID() string
- func (l *WebRTCLeg) AudioReader() io.Reader
- func (l *WebRTCLeg) AudioWriter() io.Writer
- func (l *WebRTCLeg) ClaimDisconnect() bool
- func (l *WebRTCLeg) ClearSpeakingTap()
- func (l *WebRTCLeg) Context() context.Context
- func (l *WebRTCLeg) CreatedAt() time.Time
- func (l *WebRTCLeg) DrainCandidates() ([]webrtc.ICECandidateInit, bool)
- func (l *WebRTCLeg) Hangup(_ context.Context) error
- func (l *WebRTCLeg) Headers() map[string]string
- func (l *WebRTCLeg) ID() string
- func (l *WebRTCLeg) IsDeaf() bool
- func (l *WebRTCLeg) IsHeld() bool
- func (l *WebRTCLeg) IsMuted() bool
- func (l *WebRTCLeg) Media() *PCMedia
- func (l *WebRTCLeg) OnDTMF(f func(digit rune))
- func (l *WebRTCLeg) OnTextReceived(_ func(text string, lossMarker bool))
- func (l *WebRTCLeg) RTPStats() RTPStats
- func (l *WebRTCLeg) RTTNegotiated() bool
- func (l *WebRTCLeg) Role() string
- func (l *WebRTCLeg) RoomID() string
- func (l *WebRTCLeg) SIPHeaders() map[string]string
- func (l *WebRTCLeg) SampleRate() int
- func (l *WebRTCLeg) SendDTMF(_ context.Context, _ string) error
- func (l *WebRTCLeg) SendText(_ context.Context, _ string) error
- func (l *WebRTCLeg) SetAcceptDTMF(a bool)
- func (l *WebRTCLeg) SetAcceptText(_ bool)
- func (l *WebRTCLeg) SetAppID(id string)
- func (l *WebRTCLeg) SetDeaf(d bool)
- func (l *WebRTCLeg) SetMuted(m bool)
- func (l *WebRTCLeg) SetRole(r string)
- func (l *WebRTCLeg) SetRoomID(id string)
- func (l *WebRTCLeg) SetSpeakingTap(w io.Writer)
- func (l *WebRTCLeg) State() LegState
- func (l *WebRTCLeg) Type() LegType
- type WebSocketLeg
- func (l *WebSocketLeg) AcceptDTMF() bool
- func (l *WebSocketLeg) AcceptText() bool
- func (l *WebSocketLeg) Answer(_ context.Context) error
- func (l *WebSocketLeg) AnsweredAt() time.Time
- func (l *WebSocketLeg) AppID() string
- func (l *WebSocketLeg) AttachTransport(t *wsmedia.Transport, headers map[string]string)
- func (l *WebSocketLeg) AudioReader() io.Reader
- func (l *WebSocketLeg) AudioWriter() io.Writer
- func (l *WebSocketLeg) ClaimDisconnect() bool
- func (l *WebSocketLeg) ClearSpeakingTap()
- func (l *WebSocketLeg) Context() context.Context
- func (l *WebSocketLeg) CreatedAt() time.Time
- func (l *WebSocketLeg) Hangup(_ context.Context) error
- func (l *WebSocketLeg) Headers() map[string]string
- func (l *WebSocketLeg) ID() string
- func (l *WebSocketLeg) IsDeaf() bool
- func (l *WebSocketLeg) IsHeld() bool
- func (l *WebSocketLeg) IsMuted() bool
- func (l *WebSocketLeg) OnDTMF(_ func(rune))
- func (l *WebSocketLeg) OnTextReceived(fn func(text string, lossMarker bool))
- func (l *WebSocketLeg) RTPStats() RTPStats
- func (l *WebSocketLeg) RTTNegotiated() bool
- func (l *WebSocketLeg) Role() string
- func (l *WebSocketLeg) RoomID() string
- func (l *WebSocketLeg) SIPHeaders() map[string]string
- func (l *WebSocketLeg) SampleRate() int
- func (l *WebSocketLeg) SendDTMF(_ context.Context, _ string) error
- func (l *WebSocketLeg) SendText(ctx context.Context, text string) error
- func (l *WebSocketLeg) SetAcceptDTMF(a bool)
- func (l *WebSocketLeg) SetAcceptText(a bool)
- func (l *WebSocketLeg) SetAppID(id string)
- func (l *WebSocketLeg) SetDeaf(d bool)
- func (l *WebSocketLeg) SetMuted(m bool)
- func (l *WebSocketLeg) SetRole(r string)
- func (l *WebSocketLeg) SetRoomID(id string)
- func (l *WebSocketLeg) SetSpeakingTap(io.Writer)
- func (l *WebSocketLeg) State() LegState
- func (l *WebSocketLeg) Transport() *wsmedia.Transport
- func (l *WebSocketLeg) Type() LegType
- type WhatsAppLeg
- func (l *WhatsAppLeg) AcceptDTMF() bool
- func (l *WhatsAppLeg) AcceptText() bool
- func (l *WhatsAppLeg) Answer(_ context.Context) error
- func (l *WhatsAppLeg) AnswerCh() <-chan struct{}
- func (l *WhatsAppLeg) AnsweredAt() time.Time
- func (l *WhatsAppLeg) AppID() string
- func (l *WhatsAppLeg) AudioReader() io.Reader
- func (l *WhatsAppLeg) AudioWriter() io.Writer
- func (l *WhatsAppLeg) ClaimDisconnect() bool
- func (l *WhatsAppLeg) ClearSpeakingTap()
- func (l *WhatsAppLeg) ClientDialog() *sipgo.DialogClientSession
- func (l *WhatsAppLeg) ConnectOutbound(dialog *sipgo.DialogClientSession) error
- func (l *WhatsAppLeg) Context() context.Context
- func (l *WhatsAppLeg) CreatedAt() time.Time
- func (l *WhatsAppLeg) From() string
- func (l *WhatsAppLeg) Hangup(ctx context.Context) error
- func (l *WhatsAppLeg) Headers() map[string]string
- func (l *WhatsAppLeg) ID() string
- func (l *WhatsAppLeg) IsDeaf() bool
- func (l *WhatsAppLeg) IsHeld() bool
- func (l *WhatsAppLeg) IsMuted() bool
- func (l *WhatsAppLeg) Media() *PCMedia
- func (l *WhatsAppLeg) OnDTMF(f func(digit rune))
- func (l *WhatsAppLeg) OnTextReceived(_ func(text string, lossMarker bool))
- func (l *WhatsAppLeg) RTPStats() RTPStats
- func (l *WhatsAppLeg) RTTNegotiated() bool
- func (l *WhatsAppLeg) RequestAnswer() error
- func (l *WhatsAppLeg) Role() string
- func (l *WhatsAppLeg) RoomID() string
- func (l *WhatsAppLeg) SIPHeaders() map[string]string
- func (l *WhatsAppLeg) SampleRate() int
- func (l *WhatsAppLeg) SendDTMF(_ context.Context, _ string) error
- func (l *WhatsAppLeg) SendText(_ context.Context, _ string) error
- func (l *WhatsAppLeg) ServerDialog() *sipgo.DialogServerSession
- func (l *WhatsAppLeg) SetAcceptDTMF(a bool)
- func (l *WhatsAppLeg) SetAcceptText(_ bool)
- func (l *WhatsAppLeg) SetAppID(id string)
- func (l *WhatsAppLeg) SetDeaf(d bool)
- func (l *WhatsAppLeg) SetMuted(m bool)
- func (l *WhatsAppLeg) SetRole(r string)
- func (l *WhatsAppLeg) SetRoomID(id string)
- func (l *WhatsAppLeg) SetSIPController(c WhatsAppSIPController)
- func (l *WhatsAppLeg) SetSIPResponseLogger(c SIPResponseLogger)
- func (l *WhatsAppLeg) SetSpeakingTap(w io.Writer)
- func (l *WhatsAppLeg) State() LegState
- func (l *WhatsAppLeg) To() string
- func (l *WhatsAppLeg) Type() LegType
- type WhatsAppSIPController
Constants ¶
This section is empty.
Variables ¶
var ErrRTTNotNegotiated = errors.New("RTT not negotiated for this leg")
ErrRTTNotNegotiated is returned by SendText when RTT was not agreed in the SDP offer/answer exchange (or the leg type does not support RTT).
var ErrStreamNotFound = fmt.Errorf("stream not found")
ErrStreamNotFound is returned for an unknown stream ID.
Functions ¶
func DiscoverPublicIPs ¶ added in v0.9.0
DiscoverPublicIPs queries each STUN server in turn and returns the first IPv4 and IPv6 reflexive addresses learned. The result is suitable for PCMediaConfig.ExternalIPs (and pion's SetNAT1To1IPs). Returns nil when no STUN URL is reachable.
Each lookup is bounded by stunDiscoverTimeout. Failures are logged at warn level and the next server is tried; if every server fails the caller should fall back to gathering host candidates as-is.
Types ¶
type Leg ¶
type Leg interface {
ID() string
Type() LegType
State() LegState
SampleRate() int
AudioReader() io.Reader
AudioWriter() io.Writer
OnDTMF(func(digit rune))
SendDTMF(ctx context.Context, digits string) error
AcceptDTMF() bool
SetAcceptDTMF(accept bool)
OnTextReceived(func(text string, lossMarker bool))
SendText(ctx context.Context, text string) error
AcceptText() bool
SetAcceptText(accept bool)
RTTNegotiated() bool
Hangup(ctx context.Context) error
Answer(ctx context.Context) error
Context() context.Context
RoomID() string
SetRoomID(id string)
AppID() string
SetAppID(id string)
IsMuted() bool
SetMuted(muted bool)
IsDeaf() bool
SetDeaf(deaf bool)
// Role returns the routing role used by the room's audio routing matrix.
// Empty string means unroled (full mesh).
Role() string
SetRole(role string)
SetSpeakingTap(w io.Writer)
ClearSpeakingTap()
IsHeld() bool
CreatedAt() time.Time
AnsweredAt() time.Time
SIPHeaders() map[string]string
// Headers returns custom protocol headers exposed by the leg's
// transport (X-/P- headers from a SIP INVITE or from a WebSocket HTTP
// upgrade, caller-supplied headers on an outbound WebSocket dial,
// etc.). Returns nil for leg types with no header concept.
Headers() map[string]string
RTPStats() RTPStats
// ClaimDisconnect returns true exactly once per leg. Termination paths
// (API hangup, remote BYE, RTP timeout, session expiry, etc.) call this
// before publishing leg.disconnected so concurrent paths cannot emit
// duplicate events.
ClaimDisconnect() bool
}
type LegType ¶
type LegType string
const ( TypeSIPInbound LegType = "sip_inbound" TypeSIPOutbound LegType = "sip_outbound" TypeWebRTC LegType = "webrtc" TypeWhatsAppInbound LegType = "whatsapp_in" TypeWhatsAppOutbound LegType = "whatsapp_out" TypeWebSocketInbound LegType = "websocket_in" TypeWebSocketOutbound LegType = "websocket_out" TypeMoQInbound LegType = "moq_in" TypeLiveKitPublish LegType = "livekit_publish" TypeLiveKitParticipant LegType = "livekit_participant" // SIPREC recording sessions (RFC 7866). Inbound is the recording server // role, outbound the recording client role. TypeSIPRECInbound LegType = "siprec_in" TypeSIPRECOutbound LegType = "siprec_out" )
type LiveKitParticipantLeg ¶ added in v0.8.0
type LiveKitParticipantLeg struct {
// contains filtered or unexported fields
}
LiveKitParticipantLeg represents a single remote LiveKit participant — auto-created when the umbrella LiveKitPublishLeg's transport receives an inbound audio track for that participant. From VoiceBlender's room perspective the participant is a normal leg whose AudioReader is the decoded PCM of the LK participant's published audio. The AudioWriter is io.Discard — the LK side already mixes outbound audio for the participant, so we have nothing meaningful to send back to them at the leg level.
State machine: created in StateConnected. No ringing, no early-media. DTMF and RTT are not negotiated over LiveKit, so SendDTMF/SendText return errors. Hangup tears down the leg locally; the API layer is responsible for asking the LK server to unsubscribe via the umbrella transport (so we stop receiving the participant's RTP).
func NewLiveKitParticipantLeg ¶ added in v0.8.0
func NewLiveKitParticipantLeg(identity, trackSID string, pcmReader io.Reader, sampleRate int, log *slog.Logger) *LiveKitParticipantLeg
NewLiveKitParticipantLeg builds a participant leg already bound to its decoded-PCM source. The reader is owned by the caller (typically the umbrella transport's per-track decoder goroutine); the leg only reads from it.
`identity` is the LK participant identity from JoinResponse / ParticipantUpdate. `trackSID` is the LK track ID of the audio track. Both are surfaced via Headers().
The leg starts in StateConnected; the API layer is responsible for adding it to the LegMgr, emitting `leg.connected`, and adding it to the VoiceBlender room.
func (*LiveKitParticipantLeg) AcceptDTMF ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) AcceptDTMF() bool
func (*LiveKitParticipantLeg) AcceptText ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) AcceptText() bool
func (*LiveKitParticipantLeg) Answer ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) Answer(_ context.Context) error
Answer is a no-op for LK participant legs — connection completes when the leg is constructed.
func (*LiveKitParticipantLeg) AnsweredAt ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) AnsweredAt() time.Time
func (*LiveKitParticipantLeg) AppID ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) AppID() string
func (*LiveKitParticipantLeg) AudioReader ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) AudioReader() io.Reader
AudioReader yields the decoded PCM of the LK participant's audio track. Driven by the umbrella transport's per-track decoder goroutine.
func (*LiveKitParticipantLeg) AudioWriter ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) AudioWriter() io.Writer
AudioWriter is io.Discard: the LK side already mixes outbound audio for this participant, so anything VB tried to write would not reach them anyway. Reads from the VB room mixer's mixed-minus-self output land here and are dropped.
func (*LiveKitParticipantLeg) ClaimDisconnect ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) ClaimDisconnect() bool
func (*LiveKitParticipantLeg) ClearSpeakingTap ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) ClearSpeakingTap()
func (*LiveKitParticipantLeg) Context ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) Context() context.Context
func (*LiveKitParticipantLeg) CreatedAt ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) CreatedAt() time.Time
func (*LiveKitParticipantLeg) Hangup ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) Hangup(_ context.Context) error
Hangup transitions to StateHungUp and cancels the leg's context. The API layer is responsible for telling the umbrella transport to drop the LK subscription (so the server stops sending us this participant's RTP). Idempotent.
func (*LiveKitParticipantLeg) Headers ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) Headers() map[string]string
func (*LiveKitParticipantLeg) ID ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) ID() string
func (*LiveKitParticipantLeg) Identity ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) Identity() string
Identity returns the LK participant identity from JoinResponse.
func (*LiveKitParticipantLeg) IsDeaf ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) IsDeaf() bool
func (*LiveKitParticipantLeg) IsHeld ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) IsHeld() bool
func (*LiveKitParticipantLeg) IsMuted ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) IsMuted() bool
func (*LiveKitParticipantLeg) OnDTMF ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) OnDTMF(_ func(rune))
func (*LiveKitParticipantLeg) OnTextReceived ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) OnTextReceived(_ func(text string, lossMarker bool))
func (*LiveKitParticipantLeg) RTPStats ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) RTPStats() RTPStats
func (*LiveKitParticipantLeg) RTTNegotiated ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) RTTNegotiated() bool
func (*LiveKitParticipantLeg) Role ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) Role() string
func (*LiveKitParticipantLeg) RoomID ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) RoomID() string
func (*LiveKitParticipantLeg) SIPHeaders ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SIPHeaders() map[string]string
func (*LiveKitParticipantLeg) SampleRate ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SampleRate() int
func (*LiveKitParticipantLeg) SendDTMF ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SendDTMF(_ context.Context, _ string) error
func (*LiveKitParticipantLeg) SendText ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SendText(_ context.Context, _ string) error
func (*LiveKitParticipantLeg) SetAcceptDTMF ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SetAcceptDTMF(a bool)
func (*LiveKitParticipantLeg) SetAcceptText ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SetAcceptText(a bool)
func (*LiveKitParticipantLeg) SetAppID ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SetAppID(id string)
func (*LiveKitParticipantLeg) SetDeaf ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SetDeaf(d bool)
func (*LiveKitParticipantLeg) SetMuted ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SetMuted(m bool)
func (*LiveKitParticipantLeg) SetRole ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SetRole(r string)
func (*LiveKitParticipantLeg) SetRoomID ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SetRoomID(id string)
func (*LiveKitParticipantLeg) SetSpeakingTap ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) SetSpeakingTap(io.Writer)
func (*LiveKitParticipantLeg) State ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) State() LegState
func (*LiveKitParticipantLeg) TrackSID ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) TrackSID() string
TrackSID returns the LK audio track ID this leg is bound to.
func (*LiveKitParticipantLeg) Type ¶ added in v0.8.0
func (l *LiveKitParticipantLeg) Type() LegType
type LiveKitPublishLeg ¶ added in v0.8.0
type LiveKitPublishLeg struct {
// contains filtered or unexported fields
}
LiveKitPublishLeg represents the outbound (publish) audio direction of a LiveKit-room connection. One per umbrella `POST /v1/legs type=livekit_room` call; it owns the lkmedia.Transport (signaling + publisher PC + subscriber PC).
Audio model: the publish leg's AudioWriter is fed by the VB room mixer with mixed-minus-self PCM; that PCM is Opus-encoded and pushed onto the local LiveKit track. The leg has no upstream audio of its own — AudioReader returns emptyReader{}. Remote LK participants surface as separate LiveKitParticipantLeg entries in the same VB room (auto-managed by the API layer).
State machine: created in StateConnected (LK signaling already completed during the transport's Connect). No ringing, no early-media. DTMF and RTT are not negotiated over LiveKit (browser SDKs don't carry them), so SendDTMF/SendText return errors.
func NewLiveKitPublishLeg ¶ added in v0.8.0
func NewLiveKitPublishLeg(t *lkmedia.Transport, headers map[string]string, sampleRate int, log *slog.Logger) *LiveKitPublishLeg
NewLiveKitPublishLeg constructs the umbrella publish leg already bound to a connected transport. The leg is StateConnected immediately — the LK signaling JOIN completed during Connect, so there is no ringing phase to wait on.
The headers map is expected to carry observability fields surfaced via Leg.Headers (livekit_identity, livekit_room). The leg merges these with the transport's identity/room values so callers can pass nil or partial maps.
func (*LiveKitPublishLeg) AcceptDTMF ¶ added in v0.8.0
func (l *LiveKitPublishLeg) AcceptDTMF() bool
func (*LiveKitPublishLeg) AcceptText ¶ added in v0.8.0
func (l *LiveKitPublishLeg) AcceptText() bool
func (*LiveKitPublishLeg) Answer ¶ added in v0.8.0
func (l *LiveKitPublishLeg) Answer(_ context.Context) error
Answer is a no-op for LK legs — connection completes during NewTransport.
func (*LiveKitPublishLeg) AnsweredAt ¶ added in v0.8.0
func (l *LiveKitPublishLeg) AnsweredAt() time.Time
func (*LiveKitPublishLeg) AppID ¶ added in v0.8.0
func (l *LiveKitPublishLeg) AppID() string
func (*LiveKitPublishLeg) AudioReader ¶ added in v0.8.0
func (l *LiveKitPublishLeg) AudioReader() io.Reader
AudioReader returns emptyReader{} — the publish leg has no upstream audio of its own. Remote LK participants' audio arrives via separate LiveKitParticipantLeg entries managed by the API layer.
func (*LiveKitPublishLeg) AudioWriter ¶ added in v0.8.0
func (l *LiveKitPublishLeg) AudioWriter() io.Writer
func (*LiveKitPublishLeg) ClaimDisconnect ¶ added in v0.8.0
func (l *LiveKitPublishLeg) ClaimDisconnect() bool
func (*LiveKitPublishLeg) ClearSpeakingTap ¶ added in v0.8.0
func (l *LiveKitPublishLeg) ClearSpeakingTap()
func (*LiveKitPublishLeg) Context ¶ added in v0.8.0
func (l *LiveKitPublishLeg) Context() context.Context
func (*LiveKitPublishLeg) CreatedAt ¶ added in v0.8.0
func (l *LiveKitPublishLeg) CreatedAt() time.Time
func (*LiveKitPublishLeg) Hangup ¶ added in v0.8.0
func (l *LiveKitPublishLeg) Hangup(_ context.Context) error
Hangup tears down the transport (sends Leave + closes peer connections). Idempotent.
func (*LiveKitPublishLeg) Headers ¶ added in v0.8.0
func (l *LiveKitPublishLeg) Headers() map[string]string
func (*LiveKitPublishLeg) ID ¶ added in v0.8.0
func (l *LiveKitPublishLeg) ID() string
func (*LiveKitPublishLeg) IsDeaf ¶ added in v0.8.0
func (l *LiveKitPublishLeg) IsDeaf() bool
func (*LiveKitPublishLeg) IsHeld ¶ added in v0.8.0
func (l *LiveKitPublishLeg) IsHeld() bool
func (*LiveKitPublishLeg) IsMuted ¶ added in v0.8.0
func (l *LiveKitPublishLeg) IsMuted() bool
func (*LiveKitPublishLeg) OnDTMF ¶ added in v0.8.0
func (l *LiveKitPublishLeg) OnDTMF(_ func(rune))
func (*LiveKitPublishLeg) OnTextReceived ¶ added in v0.8.0
func (l *LiveKitPublishLeg) OnTextReceived(_ func(text string, lossMarker bool))
func (*LiveKitPublishLeg) RTPStats ¶ added in v0.8.0
func (l *LiveKitPublishLeg) RTPStats() RTPStats
func (*LiveKitPublishLeg) RTTNegotiated ¶ added in v0.8.0
func (l *LiveKitPublishLeg) RTTNegotiated() bool
func (*LiveKitPublishLeg) Role ¶ added in v0.8.0
func (l *LiveKitPublishLeg) Role() string
func (*LiveKitPublishLeg) RoomID ¶ added in v0.8.0
func (l *LiveKitPublishLeg) RoomID() string
func (*LiveKitPublishLeg) SIPHeaders ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SIPHeaders() map[string]string
func (*LiveKitPublishLeg) SampleRate ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SampleRate() int
func (*LiveKitPublishLeg) SendDTMF ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SendDTMF(_ context.Context, _ string) error
func (*LiveKitPublishLeg) SendText ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SendText(_ context.Context, _ string) error
func (*LiveKitPublishLeg) SetAcceptDTMF ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SetAcceptDTMF(a bool)
func (*LiveKitPublishLeg) SetAcceptText ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SetAcceptText(a bool)
func (*LiveKitPublishLeg) SetAppID ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SetAppID(id string)
func (*LiveKitPublishLeg) SetDeaf ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SetDeaf(d bool)
func (*LiveKitPublishLeg) SetMuted ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SetMuted(m bool)
func (*LiveKitPublishLeg) SetRole ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SetRole(r string)
func (*LiveKitPublishLeg) SetRoomID ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SetRoomID(id string)
func (*LiveKitPublishLeg) SetSpeakingTap ¶ added in v0.8.0
func (l *LiveKitPublishLeg) SetSpeakingTap(io.Writer)
func (*LiveKitPublishLeg) State ¶ added in v0.8.0
func (l *LiveKitPublishLeg) State() LegState
func (*LiveKitPublishLeg) Transport ¶ added in v0.8.0
func (l *LiveKitPublishLeg) Transport() *lkmedia.Transport
Transport returns the underlying lkmedia.Transport. Used by the API handler to wait on Done() and surface CloseReason on disconnect.
func (*LiveKitPublishLeg) Type ¶ added in v0.8.0
func (l *LiveKitPublishLeg) Type() LegType
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
func NewManager ¶
func NewManager() *Manager
func (*Manager) FindSIPByCallID ¶ added in v0.3.0
FindSIPByCallID returns the SIPLeg whose dialog Call-ID matches the given value, or nil if none. Used to route in-dialog requests (e.g. REFER, NOTIFY) back to the leg that owns the dialog.
func (*Manager) Remove ¶
Remove deletes the leg from the manager and returns it together with a boolean indicating whether this call performed the removal. The boolean is the single-flight signal: termination paths use it to ensure only one of several racing callers (API DELETE × N, remote BYE, RTP timeout, session expiry) actually drives leg shutdown. Callers that get false should treat the leg as already being torn down by someone else.
type MoQLeg ¶ added in v0.6.0
type MoQLeg struct {
// contains filtered or unexported fields
}
MoQLeg wraps a moqmedia.Transport as a Leg. PoC scope: inbound only, straight to StateConnected, no DTMF, no RTT/text, no mute parity beyond the atomic bit. Mute/deaf are honored by the room's mixer adapter because the leg exposes IsMuted/IsDeaf.
func NewMoQInboundLeg ¶ added in v0.6.0
func NewMoQInboundLeg(t *moqmedia.Transport, headers map[string]string, sampleRate int, log *slog.Logger) *MoQLeg
NewMoQInboundLeg constructs an inbound MoQ leg already bound to a transport and starts the transport's send loop reading from the egress pipe. The leg goes straight to StateConnected (no ringing flow).
func (*MoQLeg) AcceptDTMF ¶ added in v0.6.0
func (*MoQLeg) AcceptText ¶ added in v0.6.0
func (*MoQLeg) AnsweredAt ¶ added in v0.6.0
func (*MoQLeg) AudioReader ¶ added in v0.6.0
func (*MoQLeg) AudioWriter ¶ added in v0.6.0
func (*MoQLeg) ClaimDisconnect ¶ added in v0.6.0
func (*MoQLeg) ClearSpeakingTap ¶ added in v0.6.0
func (l *MoQLeg) ClearSpeakingTap()
func (*MoQLeg) OnTextReceived ¶ added in v0.6.0
func (*MoQLeg) RTTNegotiated ¶ added in v0.6.0
func (*MoQLeg) SIPHeaders ¶ added in v0.6.0
func (*MoQLeg) SampleRate ¶ added in v0.6.0
func (*MoQLeg) SetAcceptDTMF ¶ added in v0.6.0
func (*MoQLeg) SetAcceptText ¶ added in v0.6.0
func (*MoQLeg) SetSpeakingTap ¶ added in v0.6.0
type PCMedia ¶ added in v0.5.0
type PCMedia struct {
// contains filtered or unexported fields
}
PCMedia wraps a pion PeerConnection and exposes PCM16 io.Reader/io.Writer at the codec's native sample rate. Inbound RTP is decoded to PCM on a per-packet goroutine; outbound PCM is chunked into 20 ms frames, encoded, and written to the local RTP track.
func NewPCMedia ¶ added in v0.5.0
func NewPCMedia(cfg PCMediaConfig) (*PCMedia, error)
func (*PCMedia) AddICECandidate ¶ added in v0.5.0
func (m *PCMedia) AddICECandidate(c webrtc.ICECandidateInit) error
func (*PCMedia) AudioReader ¶ added in v0.5.0
AudioReader yields decoded PCM (16-bit LE) at the codec's native rate.
func (*PCMedia) AudioWriter ¶ added in v0.5.0
AudioWriter accepts PCM (16-bit LE) at the codec's native rate.
func (*PCMedia) ClearSpeakingTap ¶ added in v0.5.0
func (m *PCMedia) ClearSpeakingTap()
ClearSpeakingTap removes the installed tap.
func (*PCMedia) DrainLocalCandidates ¶ added in v0.5.0
func (m *PCMedia) DrainLocalCandidates() ([]webrtc.ICECandidateInit, bool)
DrainLocalCandidates returns buffered local ICE candidates and the gathering-complete flag, clearing the buffer.
func (*PCMedia) PC ¶ added in v0.5.0
func (m *PCMedia) PC() *webrtc.PeerConnection
func (*PCMedia) SampleRate ¶ added in v0.5.0
func (*PCMedia) SetSpeakingTap ¶ added in v0.5.0
type PCMediaConfig ¶ added in v0.5.0
type PCMediaConfig struct {
Codec codec.CodecType
ICEServers []string
RTPPortMin uint16
RTPPortMax uint16
Log *slog.Logger
// ExternalIPs are public addresses substituted into local host ICE
// candidates via pion's SetNAT1To1IPs. Required when VB runs behind
// NAT/Docker and the gathered host interface IPs aren't routable
// from the remote peer.
ExternalIPs []string
OnDisconnect func(reason string)
// OnConnected fires once when the peer connection reaches the
// Connected state. Subsequent state transitions don't re-fire.
OnConnected func()
// AnsweringDTLSRole forces the DTLS role on actpass offers. Use
// DTLSRoleClient against ice-lite peers (e.g. WhatsApp).
AnsweringDTLSRole webrtc.DTLSRole
// EnableTelephoneEvent advertises RFC 4733 DTMF (PT 126) in the
// answer and routes inbound telephone-event packets to OnDTMF.
EnableTelephoneEvent bool
// LoopbackICE gathers host candidates on loopback only. Intended for
// same-process tests: gathering on every interface of a developer or
// CI host (docker bridges, VPN tunnels, VM adapters) yields hundreds
// of candidate pairs and lets ICE nominate a virtual interface that
// carries STUN but drops the DTLS handshake.
LoopbackICE bool
}
PCMediaConfig configures a pion PeerConnection + audio pipeline shared by WebRTC and WhatsApp legs. The peer connection is created by NewPCMedia; the caller drives SDP negotiation via PC().
type RTPStats ¶
type RTPStats struct {
PacketsReceived uint32
PacketsLost uint32
JitterMs float64
MOSScore float64 // 1.0–5.0; 0 if insufficient data (< 2 packets)
}
RTPStats holds inbound RTP stream quality metrics.
type SIPLeg ¶
type SIPLeg struct {
// contains filtered or unexported fields
}
SIPLeg wraps a SIP dialog (inbound or outbound) with RTP media handling.
func NewSIPInboundLeg ¶
func NewSIPOutboundLeg ¶
func NewSIPOutboundPendingLeg ¶
func NewSIPOutboundPendingLeg(engine *sipmod.Engine, codecs []codec.CodecType, log *slog.Logger) *SIPLeg
NewSIPOutboundPendingLeg creates an outbound leg in ringing state with its own context. Call ConnectOutbound after the INVITE succeeds. If codecs is non-empty it overrides the engine's default codec list.
func NewSIPRECInboundLeg ¶ added in v0.12.0
NewSIPRECInboundLeg builds the leg for an inbound SIPREC recording session (RFC 7866). It shares every media path with an ordinary inbound leg and differs only in negotiation policy: it never transmits, and m-line 0 carries one recorded party's audio rather than "the call".
func NewSIPRECOutboundLeg ¶ added in v0.12.0
func NewSIPRECOutboundLeg(call *sipmod.OutboundCall, engine *sipmod.Engine, log *slog.Logger) *SIPLeg
NewSIPRECOutboundLeg builds the leg for an outbound SIPREC recording session (RFC 7866): VoiceBlender as the recording client, forking a call's audio to an external recording server. It shares every media path with an ordinary outbound leg and differs only in policy — each m= section carries one recorded party rather than "the call", and nothing is received.
func (*SIPLeg) AcceptDTMF ¶ added in v0.3.0
func (*SIPLeg) AcceptText ¶ added in v0.6.0
AcceptText reports whether this leg currently accepts inbound RTT events.
func (*SIPLeg) AddStream ¶ added in v0.12.0
func (l *SIPLeg) AddStream(ctx context.Context, req StreamRequest) (StreamInfo, error)
AddStream negotiates an additional m=audio section on the live dialog via a re-INVITE, per RFC 3264 §8.1. The new section is appended below the existing ones; it never reuses a tombstoned slot, so the peer's positional matching stays valid.
A peer that rejects the new section with port 0 leaves the call untouched and yields an error naming the rejection.
func (*SIPLeg) Answer ¶
Answer sends 200 OK to the inbound INVITE. Codec selection respects any hint set via SignalAnswer; a CodecUnknown hint falls back to the default offer-order preference. The hint is ignored when the leg is already in StateEarlyMedia (the codec was locked in at 183).
func (*SIPLeg) AnswerCh ¶
func (l *SIPLeg) AnswerCh() <-chan struct{}
AnswerCh returns the channel that is closed when the REST answer endpoint is called.
func (*SIPLeg) AnsweredAt ¶
func (*SIPLeg) ApplyRemoteOffer ¶ added in v0.12.0
ApplyRemoteOffer processes a peer's re-INVITE/UPDATE offer and returns the SDP answer plus the offered direction (empty when the body carried none).
Unlike the direction-only path it replaces, this re-applies the peer's media address: an SBC that re-anchors media on a re-INVITE used to leave the call one-way because nothing ever called SetRemote again.
func (*SIPLeg) AudioReader ¶
func (*SIPLeg) AudioWriter ¶
func (*SIPLeg) Challenge ¶ added in v0.10.0
Challenge sends a 401 Unauthorized with a digest WWW-Authenticate challenge on an unanswered inbound leg, terminating the dialog. The credentialed re-INVITE arrives as a fresh inbound call (same Call-ID) which the engine verifies via VerifyInboundAuth. Like Reject, this is a terminal response on the INVITE transaction and is guarded by the same once-gate.
Only valid on inbound legs in StateRinging or StateEarlyMedia.
func (*SIPLeg) ClaimDisconnect ¶ added in v0.6.0
ClaimDisconnect returns true on the first caller and false on every subsequent caller. Termination paths use this gate so only one publishes leg.disconnected, even when DELETE racing with remote BYE or RTP timeout.
func (*SIPLeg) ClearAMDTapIf ¶ added in v0.12.0
ClearAMDTapIf removes the AMD tap only if w is the writer currently installed, reporting whether it was. A second AMD start replaces the tap outright, so an unconditional clear would let the superseded analysis rip out the live one's tap when its own deadline expires. The identity check makes the clear a no-op for a writer that no longer owns the slot.
func (*SIPLeg) ClearSRCTaps ¶ added in v0.12.0
func (l *SIPLeg) ClearSRCTaps()
ClearSRCTaps removes the recording-server taps.
func (*SIPLeg) ClearSpeakingTap ¶ added in v0.2.0
func (l *SIPLeg) ClearSpeakingTap()
ClearSpeakingTap removes the speaking detection tap.
func (*SIPLeg) ClearStreamInTap ¶ added in v0.12.0
ClearStreamInTap removes one stream's incoming tap.
func (*SIPLeg) ConnectOutbound ¶
func (l *SIPLeg) ConnectOutbound(call *sipmod.OutboundCall) error
ConnectOutbound sets the answered outbound call on the leg, negotiates the codec, starts media, and transitions to connected.
func (*SIPLeg) DialogIdentity ¶ added in v0.3.0
DialogIdentity returns (callID, localTag, remoteTag) from this leg's view.
func (*SIPLeg) DisconnectReason ¶ added in v0.6.0
DisconnectReason returns the override set by SetDisconnectReason, or "" if none. Consumed by the inbound-call goroutine when publishing leg.disconnected.
func (*SIPLeg) EnableEarlyMedia ¶
EnableEarlyMedia sends 183 Session Progress with SDP and sets up the media pipeline so audio can flow before the call is answered. Only valid for inbound legs in StateRinging.
preferred biases codec selection: when non-zero and present in both the remote offer and the supported list, it wins; otherwise selection falls back to the default offer-order preference.
func (*SIPLeg) HandleRemoteHold ¶
HandleRemoteHold processes a remote re-INVITE's SDP direction for hold/unhold.
func (*SIPLeg) Hangup ¶
Hangup transitions the leg to StateHungUp and (exactly once) sends a BYE on the underlying SIP dialog. State transition, context cancel, RTP-session close, and timer cleanup happen on every call (idempotent operations); the SIP BYE is gated by sync.Once so concurrent termination paths cannot emit duplicate BYEs.
func (*SIPLeg) JitterBufferMs ¶ added in v0.3.0
JitterBufferMs returns the configured target delay in milliseconds (0 = disabled).
func (*SIPLeg) OnHold ¶
func (l *SIPLeg) OnHold(f func())
OnHold registers a callback for when the leg is put on hold.
func (*SIPLeg) OnRTPTimeout ¶
func (l *SIPLeg) OnRTPTimeout(f func())
OnRTPTimeout sets a callback that fires when no RTP packets are received within the timeout period (30s). Called at most once.
func (*SIPLeg) OnSessionExpired ¶
func (l *SIPLeg) OnSessionExpired(f func())
OnSessionExpired registers a callback for when the session timer expires without a refresh. Typically used to hang up the call.
func (*SIPLeg) OnTextReceived ¶ added in v0.6.0
OnTextReceived registers a callback for inbound T.140 text. The callback runs on the dispatcher goroutine so the caller can do moderately expensive work (e.g. publish webhook events) without blocking the RTP read loop.
func (*SIPLeg) OnUnhold ¶
func (l *SIPLeg) OnUnhold(f func())
OnUnhold registers a callback for when the leg is taken off hold.
func (*SIPLeg) OriginatingIdentity ¶ added in v0.12.0
OriginatingIdentity returns the user and host to place in the From URI when VoiceBlender originates a call on this leg's behalf — today only the REFER transfer path. For an inbound leg that is the caller's From (the party asking for the transfer); for an outbound leg it is the From VoiceBlender itself sent. An empty user means no identity is known, leaving the From to sipgo.
No lock: both fields are written once during leg setup, before the leg is reachable through the manager.
func (*SIPLeg) OwnsAMDTap ¶ added in v0.12.0
OwnsAMDTap reports whether w is the AMD tap currently installed, without clearing it. A machine verdict keeps its tap installed through the beep window, so it gates its publish on ownership through this check rather than the clearing ClearAMDTapIf.
func (*SIPLeg) RTTNegotiated ¶ added in v0.6.0
RTTNegotiated reports whether SDP agreed on an m=text section for this leg.
func (*SIPLeg) ReInviteAnswerSDP
deprecated
Deprecated: use ApplyRemoteOffer, which also re-applies the peer's media address. Retained for callers that only have a direction string.
ReInviteAnswerSDP builds an SDP body for responding to a remote re-INVITE. The direction is mirrored: if the remote sent "sendonly" (hold), we respond with "recvonly"; if "sendrecv" we respond with "sendrecv".
func (*SIPLeg) Reject ¶ added in v0.6.0
Reject sends a final non-2xx response on an unanswered inbound leg, terminating the dialog without ever creating a session. statusCode is the SIP status code (e.g. 486, 603); reasonPhrase is the SIP reason phrase shown after the status code on the response line.
Only valid on inbound legs in StateRinging or StateEarlyMedia. After Reject succeeds the dialog context is cancelled by sipgo, so the inbound-call goroutine wakes up and publishes leg.disconnected — if the caller wants the disconnect event to carry a specific reason, it should call SetDisconnectReason first.
func (*SIPLeg) RemoteOfferCodecs ¶ added in v0.6.0
RemoteOfferCodecs returns the codecs offered by the remote in the inbound INVITE SDP, in offer order. Returns nil for outbound legs or when no offer has been parsed yet.
func (*SIPLeg) RemoveStream ¶ added in v0.12.0
RemoveStream disables one of the leg's secondary streams with a re-INVITE carrying port 0 for its section (RFC 3264 §8.2). The m-line slot survives as a tombstone — the count never decreases for the life of the dialog.
func (*SIPLeg) ResetSessionTimer ¶
func (l *SIPLeg) ResetSessionTimer()
ResetSessionTimer resets the session timer, called when a refresh re-INVITE is received from the remote UA.
func (*SIPLeg) SIPHeaders ¶
func (*SIPLeg) SampleRate ¶
func (*SIPLeg) SecondaryStreamIDs ¶ added in v0.12.0
SecondaryStreamIDs returns the IDs of every stream other than the primary, in m-line order. A leg whose streams are independent has no privileged primary, so every stream is returned.
func (*SIPLeg) SendNotifySipfrag ¶ added in v0.3.0
func (l *SIPLeg) SendNotifySipfrag(ctx context.Context, statusCode int, reason string, terminated bool) error
SendNotifySipfrag emits a NOTIFY sipfrag for the implicit refer subscription.
func (*SIPLeg) SendRinging ¶ added in v0.6.0
SendRinging sends a 180 Ringing provisional response with no SDP. Only valid for inbound legs in StateRinging. May be called multiple times — each call emits another 180 (RFC-allowed; receivers tolerate re-sends).
func (*SIPLeg) SendText ¶ added in v0.6.0
SendText queues UTF-8 text for transmission as RFC 4103 RTP. Returns ErrRTTNotNegotiated when the SDP exchange did not agree on m=text.
func (*SIPLeg) SessionTimerParams ¶
SessionTimerParams returns the negotiated session timer interval and refresher. Returns (0, "") if session timers are not active.
func (*SIPLeg) SetAMDTap ¶ added in v0.2.0
SetAMDTap sets a writer that receives decoded incoming PCM for answering machine detection. Separate from inTap so AMD and recording can coexist.
func (*SIPLeg) SetAcceptDTMF ¶ added in v0.3.0
func (*SIPLeg) SetAcceptText ¶ added in v0.6.0
SetAcceptText toggles inbound RTT event acceptance on this leg.
func (*SIPLeg) SetDisconnectReason ¶ added in v0.6.0
SetDisconnectReason stores a reason that will be used in the next leg.disconnected event published for this leg, in place of the goroutine's default. Set by the API DELETE handler before calling Reject or Hangup so the user-provided cause flows through to the event.
func (*SIPLeg) SetInTap ¶
SetInTap sets a writer that receives a copy of every decoded incoming PCM frame (before it enters inFrames). Used for standalone leg recording.
func (*SIPLeg) SetJitterBuffer ¶ added in v0.3.0
SetJitterBuffer configures the SIP ingress jitter buffer. targetMs is the target play-out delay (e.g. 60 for 60 ms); 0 disables the buffer entirely (passthrough). maxMs caps the queue depth; 0 means "use a sensible default" (300 ms). Call before the leg's media pipeline is established.
func (*SIPLeg) SetOriginatingIdentity ¶ added in v0.12.0
SetOriginatingIdentity records the From identity an outbound leg was dialled under. Must be called during setup, before the leg is added to the manager.
func (*SIPLeg) SetOutTap ¶
SetOutTap sets a writer that receives a copy of every outgoing PCM frame (including silence) from the writeLoop. Used for standalone leg recording.
func (*SIPLeg) SetSRCTaps ¶ added in v0.12.0
SetSRCTaps forks a leg's own audio to a recording server: w receives every decoded incoming frame, out every outgoing one. Kept separate from SetInTap/SetOutTap so a recording session and a file recording can run on the same leg at once.
func (*SIPLeg) SetSpeakingTap ¶ added in v0.2.0
SetSpeakingTap sets a writer that receives decoded incoming PCM for voice activity detection.
func (*SIPLeg) SetStreamInTap ¶ added in v0.12.0
SetStreamInTap routes a copy of one stream's decoded incoming PCM to w. SetInTap is the leg-wide equivalent, which only ever reaches the primary; a recording session needs each participant's stream captured separately.
func (*SIPLeg) SetStreamRole ¶ added in v0.12.0
SetStreamRole records a secondary stream's routing role inside its room.
func (*SIPLeg) SetStreamRoom ¶ added in v0.12.0
SetStreamRoom records which room a secondary stream is mixed into.
func (*SIPLeg) SetTrunkID ¶ added in v0.12.0
SetTrunkID records the leg's trunk association. Must be called during setup, before the leg is added to the manager.
func (*SIPLeg) SetupEarlyMediaOutbound ¶
func (l *SIPLeg) SetupEarlyMediaOutbound(remoteSDP *sipmod.SDPMedia, rtpSess *sipmod.RTPSession) error
SetupEarlyMediaOutbound configures the media pipeline from a 183 response's SDP before the call is answered. Only valid in StateRinging.
func (*SIPLeg) SignalAnswer ¶
SignalAnswer signals the leg to answer (called from REST API). preferred is an optional codec hint passed to Answer; pass CodecUnknown for none.
func (*SIPLeg) Stream ¶ added in v0.12.0
func (l *SIPLeg) Stream(streamID string) (StreamInfo, bool)
Stream returns a view of one audio stream.
func (*SIPLeg) StreamCount ¶ added in v0.12.0
StreamCount returns how many audio streams the leg is currently carrying.
func (*SIPLeg) StreamMedia ¶ added in v0.12.0
func (l *SIPLeg) StreamMedia(streamID string) (StreamMedia, bool)
StreamMedia returns the media endpoints of one of the leg's audio streams.
func (*SIPLeg) StreamRooms ¶ added in v0.12.0
StreamRooms returns the room each secondary stream is attached to, keyed by stream ID. The primary stream is excluded — its room is the leg's own RoomID, which every existing caller already tracks — unless the leg's streams are independent, where it has a room of its own and teardown must see it.
func (*SIPLeg) Streams ¶ added in v0.12.0
func (l *SIPLeg) Streams() []StreamInfo
Streams returns a view of every audio stream on the leg, in m-line order.
func (*SIPLeg) StreamsIndependent ¶ added in v0.12.0
StreamsIndependent reports whether the leg's m-line 0 is an ordinary stream rather than "the call". True for recording sessions.
func (*SIPLeg) SupportedCodecs ¶ added in v0.9.0
SupportedCodecs returns the engine's supported codecs for this leg, in preference order. Used by the REST layer to reject answer/early-media requests that name a codec the engine wasn't configured for.
func (*SIPLeg) Transfer ¶ added in v0.3.0
func (l *SIPLeg) Transfer(ctx context.Context, target string, replaces *sipmod.ReplacesParams) error
Transfer sends an in-dialog REFER. replaces non-nil = attended (RFC 3891).
func (*SIPLeg) TrunkID ¶ added in v0.12.0
TrunkID returns the trunk this leg arrived on (inbound) or was dialled over (outbound), or "" when the leg has no trunk association. The REFER path uses it to originate the transfer target over the same trunk.
No lock: written once during leg setup, before the leg is reachable through the manager.
type SIPResponseLogger ¶ added in v0.5.0
type SIPResponseLogger = WhatsAppSIPController
SIPResponseLogger is an alias retained for older call sites.
type StreamInfo ¶ added in v0.12.0
type StreamInfo struct {
ID string
MID string
Index int
Primary bool
State string
Direction string
Desired string
Codec string
SampleRate int
LocalPort int
RemoteAddr string
Label string
Content string
Lang string
RoomID string
Role string
}
StreamInfo is a read-only view of one negotiated audio stream.
type StreamMedia ¶ added in v0.12.0
type StreamMedia struct {
ID string
MID string
Primary bool
SampleRate int
Direction string // negotiated direction, from our point of view
Reader io.Reader
Writer io.Writer
}
StreamMedia describes one negotiated audio stream's media endpoints, so a room can mix it without knowing how the leg is put together.
Reader is nil when the stream does not receive from the peer, Writer nil when it does not transmit; a fully inactive stream has neither.
type StreamRequest ¶ added in v0.12.0
type StreamRequest struct {
Direction string // "" means sendrecv
Lang string
Content string
Label string
}
StreamRequest describes an audio stream to add to a live dialog.
type WebRTCLeg ¶
type WebRTCLeg struct {
// contains filtered or unexported fields
}
WebRTCLeg wraps a pion PeerConnection (via PCMedia) as a Leg.
func NewWebRTCLeg ¶
NewWebRTCLeg wraps a PCMedia and starts its outbound write loop.
func (*WebRTCLeg) AcceptDTMF ¶ added in v0.3.0
func (*WebRTCLeg) AcceptText ¶ added in v0.6.0
func (*WebRTCLeg) AddICECandidate ¶
func (l *WebRTCLeg) AddICECandidate(c webrtc.ICECandidateInit) error
AddICECandidate adds a remote ICE candidate.
func (*WebRTCLeg) AnsweredAt ¶
func (*WebRTCLeg) AudioReader ¶
func (*WebRTCLeg) AudioWriter ¶
func (*WebRTCLeg) ClaimDisconnect ¶ added in v0.6.0
ClaimDisconnect returns true on the first caller and false on every subsequent caller. Termination paths use this gate so only one publishes leg.disconnected.
func (*WebRTCLeg) ClearSpeakingTap ¶ added in v0.2.0
func (l *WebRTCLeg) ClearSpeakingTap()
func (*WebRTCLeg) DrainCandidates ¶
func (l *WebRTCLeg) DrainCandidates() ([]webrtc.ICECandidateInit, bool)
DrainCandidates returns buffered local ICE candidates and whether gathering is done.
func (*WebRTCLeg) Media ¶ added in v0.5.0
Media returns the underlying PCMedia (for SDP negotiation + ICE trickle).
func (*WebRTCLeg) OnTextReceived ¶ added in v0.6.0
func (*WebRTCLeg) RTTNegotiated ¶ added in v0.6.0
func (*WebRTCLeg) SIPHeaders ¶
func (*WebRTCLeg) SampleRate ¶
func (*WebRTCLeg) SetAcceptDTMF ¶ added in v0.3.0
func (*WebRTCLeg) SetAcceptText ¶ added in v0.6.0
func (*WebRTCLeg) SetSpeakingTap ¶ added in v0.2.0
type WebSocketLeg ¶ added in v0.6.0
type WebSocketLeg struct {
// contains filtered or unexported fields
}
WebSocketLeg wraps a wsmedia.Transport as a Leg, supporting both inbound (server-side upgrade) and outbound (client-side dial) directions. Both share state machinery; only Type() differs.
func NewWebSocketInboundLeg ¶ added in v0.6.0
func NewWebSocketInboundLeg(t *wsmedia.Transport, headers map[string]string, sampleRate int, rtt bool, log *slog.Logger) *WebSocketLeg
NewWebSocketInboundLeg constructs an inbound WS leg already bound to a transport. The leg goes straight to StateConnected (no ringing).
func NewWebSocketOutboundPendingLeg ¶ added in v0.6.0
func NewWebSocketOutboundPendingLeg(sampleRate int, rtt bool, log *slog.Logger) *WebSocketLeg
NewWebSocketOutboundPendingLeg constructs an outbound WS leg in StateRinging. Call AttachTransport once DialClient completes to transition to StateConnected.
func (*WebSocketLeg) AcceptDTMF ¶ added in v0.6.0
func (l *WebSocketLeg) AcceptDTMF() bool
func (*WebSocketLeg) AcceptText ¶ added in v0.6.0
func (l *WebSocketLeg) AcceptText() bool
func (*WebSocketLeg) Answer ¶ added in v0.6.0
func (l *WebSocketLeg) Answer(_ context.Context) error
func (*WebSocketLeg) AnsweredAt ¶ added in v0.6.0
func (l *WebSocketLeg) AnsweredAt() time.Time
func (*WebSocketLeg) AppID ¶ added in v0.6.0
func (l *WebSocketLeg) AppID() string
func (*WebSocketLeg) AttachTransport ¶ added in v0.6.0
func (l *WebSocketLeg) AttachTransport(t *wsmedia.Transport, headers map[string]string)
AttachTransport binds the wsmedia.Transport to the leg and starts the send loop reading from the egress pipe. headers may be nil for outbound dials where the server returned no relevant response headers.
func (*WebSocketLeg) AudioReader ¶ added in v0.6.0
func (l *WebSocketLeg) AudioReader() io.Reader
AudioReader returns inbound PCM as it arrives off the WebSocket.
func (*WebSocketLeg) AudioWriter ¶ added in v0.6.0
func (l *WebSocketLeg) AudioWriter() io.Writer
AudioWriter returns the write side of the egress pipe; the room writes mixed-minus-self PCM here, the transport's send loop reads it.
func (*WebSocketLeg) ClaimDisconnect ¶ added in v0.6.0
func (l *WebSocketLeg) ClaimDisconnect() bool
ClaimDisconnect single-flights the disconnect publication.
func (*WebSocketLeg) ClearSpeakingTap ¶ added in v0.6.0
func (l *WebSocketLeg) ClearSpeakingTap()
func (*WebSocketLeg) Context ¶ added in v0.6.0
func (l *WebSocketLeg) Context() context.Context
func (*WebSocketLeg) CreatedAt ¶ added in v0.6.0
func (l *WebSocketLeg) CreatedAt() time.Time
func (*WebSocketLeg) Hangup ¶ added in v0.6.0
func (l *WebSocketLeg) Hangup(_ context.Context) error
func (*WebSocketLeg) Headers ¶ added in v0.6.0
func (l *WebSocketLeg) Headers() map[string]string
func (*WebSocketLeg) ID ¶ added in v0.6.0
func (l *WebSocketLeg) ID() string
func (*WebSocketLeg) IsDeaf ¶ added in v0.6.0
func (l *WebSocketLeg) IsDeaf() bool
func (*WebSocketLeg) IsHeld ¶ added in v0.6.0
func (l *WebSocketLeg) IsHeld() bool
func (*WebSocketLeg) IsMuted ¶ added in v0.6.0
func (l *WebSocketLeg) IsMuted() bool
func (*WebSocketLeg) OnDTMF ¶ added in v0.6.0
func (l *WebSocketLeg) OnDTMF(_ func(rune))
func (*WebSocketLeg) OnTextReceived ¶ added in v0.6.0
func (l *WebSocketLeg) OnTextReceived(fn func(text string, lossMarker bool))
func (*WebSocketLeg) RTPStats ¶ added in v0.6.0
func (l *WebSocketLeg) RTPStats() RTPStats
func (*WebSocketLeg) RTTNegotiated ¶ added in v0.6.0
func (l *WebSocketLeg) RTTNegotiated() bool
func (*WebSocketLeg) Role ¶ added in v0.7.0
func (l *WebSocketLeg) Role() string
func (*WebSocketLeg) RoomID ¶ added in v0.6.0
func (l *WebSocketLeg) RoomID() string
func (*WebSocketLeg) SIPHeaders ¶ added in v0.6.0
func (l *WebSocketLeg) SIPHeaders() map[string]string
func (*WebSocketLeg) SampleRate ¶ added in v0.6.0
func (l *WebSocketLeg) SampleRate() int
func (*WebSocketLeg) SendDTMF ¶ added in v0.6.0
func (l *WebSocketLeg) SendDTMF(_ context.Context, _ string) error
func (*WebSocketLeg) SendText ¶ added in v0.6.0
func (l *WebSocketLeg) SendText(ctx context.Context, text string) error
func (*WebSocketLeg) SetAcceptDTMF ¶ added in v0.6.0
func (l *WebSocketLeg) SetAcceptDTMF(a bool)
func (*WebSocketLeg) SetAcceptText ¶ added in v0.6.0
func (l *WebSocketLeg) SetAcceptText(a bool)
func (*WebSocketLeg) SetAppID ¶ added in v0.6.0
func (l *WebSocketLeg) SetAppID(id string)
func (*WebSocketLeg) SetDeaf ¶ added in v0.6.0
func (l *WebSocketLeg) SetDeaf(d bool)
func (*WebSocketLeg) SetMuted ¶ added in v0.6.0
func (l *WebSocketLeg) SetMuted(m bool)
func (*WebSocketLeg) SetRole ¶ added in v0.7.0
func (l *WebSocketLeg) SetRole(r string)
func (*WebSocketLeg) SetRoomID ¶ added in v0.6.0
func (l *WebSocketLeg) SetRoomID(id string)
func (*WebSocketLeg) SetSpeakingTap ¶ added in v0.6.0
func (l *WebSocketLeg) SetSpeakingTap(io.Writer)
func (*WebSocketLeg) State ¶ added in v0.6.0
func (l *WebSocketLeg) State() LegState
func (*WebSocketLeg) Transport ¶ added in v0.6.0
func (l *WebSocketLeg) Transport() *wsmedia.Transport
Transport returns the underlying wsmedia.Transport.
func (*WebSocketLeg) Type ¶ added in v0.6.0
func (l *WebSocketLeg) Type() LegType
type WhatsAppLeg ¶ added in v0.5.0
type WhatsAppLeg struct {
// contains filtered or unexported fields
}
WhatsAppLeg is a SIP-over-TLS leg with Opus media via ICE+DTLS-SRTP. Hold/unhold/transfer are unsupported (Meta rejects re-INVITE).
func NewWhatsAppInboundLeg ¶ added in v0.5.0
func NewWhatsAppInboundLeg(dialog *sipgo.DialogServerSession, media *PCMedia, from, to string, headers map[string]string, answerSDP []byte, log *slog.Logger) *WhatsAppLeg
NewWhatsAppInboundLeg wraps an accepted UAS dialog. The 200 OK is sent by Answer() once REST issues POST /v1/legs/{id}/answer.
func NewWhatsAppOutboundPendingLeg ¶ added in v0.5.0
func NewWhatsAppOutboundPendingLeg(media *PCMedia, from, to string, log *slog.Logger) *WhatsAppLeg
NewWhatsAppOutboundPendingLeg creates a ringing-state leg without a dialog. Caller drives the INVITE asynchronously and upgrades via ConnectOutbound on 200 OK.
func (*WhatsAppLeg) AcceptDTMF ¶ added in v0.5.0
func (l *WhatsAppLeg) AcceptDTMF() bool
func (*WhatsAppLeg) AcceptText ¶ added in v0.6.0
func (l *WhatsAppLeg) AcceptText() bool
func (*WhatsAppLeg) AnswerCh ¶ added in v0.5.0
func (l *WhatsAppLeg) AnswerCh() <-chan struct{}
func (*WhatsAppLeg) AnsweredAt ¶ added in v0.5.0
func (l *WhatsAppLeg) AnsweredAt() time.Time
func (*WhatsAppLeg) AppID ¶ added in v0.5.0
func (l *WhatsAppLeg) AppID() string
func (*WhatsAppLeg) AudioReader ¶ added in v0.5.0
func (l *WhatsAppLeg) AudioReader() io.Reader
func (*WhatsAppLeg) AudioWriter ¶ added in v0.5.0
func (l *WhatsAppLeg) AudioWriter() io.Writer
func (*WhatsAppLeg) ClaimDisconnect ¶ added in v0.6.0
func (l *WhatsAppLeg) ClaimDisconnect() bool
ClaimDisconnect returns true on the first caller and false on every subsequent caller. Termination paths use this gate so only one publishes leg.disconnected.
func (*WhatsAppLeg) ClearSpeakingTap ¶ added in v0.5.0
func (l *WhatsAppLeg) ClearSpeakingTap()
func (*WhatsAppLeg) ClientDialog ¶ added in v0.5.0
func (l *WhatsAppLeg) ClientDialog() *sipgo.DialogClientSession
func (*WhatsAppLeg) ConnectOutbound ¶ added in v0.5.0
func (l *WhatsAppLeg) ConnectOutbound(dialog *sipgo.DialogClientSession) error
func (*WhatsAppLeg) Context ¶ added in v0.5.0
func (l *WhatsAppLeg) Context() context.Context
func (*WhatsAppLeg) CreatedAt ¶ added in v0.5.0
func (l *WhatsAppLeg) CreatedAt() time.Time
func (*WhatsAppLeg) From ¶ added in v0.5.0
func (l *WhatsAppLeg) From() string
func (*WhatsAppLeg) Hangup ¶ added in v0.5.0
func (l *WhatsAppLeg) Hangup(ctx context.Context) error
func (*WhatsAppLeg) Headers ¶ added in v0.6.0
func (l *WhatsAppLeg) Headers() map[string]string
func (*WhatsAppLeg) ID ¶ added in v0.5.0
func (l *WhatsAppLeg) ID() string
func (*WhatsAppLeg) IsDeaf ¶ added in v0.5.0
func (l *WhatsAppLeg) IsDeaf() bool
func (*WhatsAppLeg) IsHeld ¶ added in v0.5.0
func (l *WhatsAppLeg) IsHeld() bool
func (*WhatsAppLeg) IsMuted ¶ added in v0.5.0
func (l *WhatsAppLeg) IsMuted() bool
func (*WhatsAppLeg) Media ¶ added in v0.5.0
func (l *WhatsAppLeg) Media() *PCMedia
func (*WhatsAppLeg) OnDTMF ¶ added in v0.5.0
func (l *WhatsAppLeg) OnDTMF(f func(digit rune))
func (*WhatsAppLeg) OnTextReceived ¶ added in v0.6.0
func (l *WhatsAppLeg) OnTextReceived(_ func(text string, lossMarker bool))
func (*WhatsAppLeg) RTPStats ¶ added in v0.5.0
func (l *WhatsAppLeg) RTPStats() RTPStats
func (*WhatsAppLeg) RTTNegotiated ¶ added in v0.6.0
func (l *WhatsAppLeg) RTTNegotiated() bool
func (*WhatsAppLeg) RequestAnswer ¶ added in v0.5.0
func (l *WhatsAppLeg) RequestAnswer() error
func (*WhatsAppLeg) Role ¶ added in v0.7.0
func (l *WhatsAppLeg) Role() string
func (*WhatsAppLeg) RoomID ¶ added in v0.5.0
func (l *WhatsAppLeg) RoomID() string
func (*WhatsAppLeg) SIPHeaders ¶ added in v0.5.0
func (l *WhatsAppLeg) SIPHeaders() map[string]string
func (*WhatsAppLeg) SampleRate ¶ added in v0.5.0
func (l *WhatsAppLeg) SampleRate() int
func (*WhatsAppLeg) SendDTMF ¶ added in v0.5.0
func (l *WhatsAppLeg) SendDTMF(_ context.Context, _ string) error
func (*WhatsAppLeg) SendText ¶ added in v0.6.0
func (l *WhatsAppLeg) SendText(_ context.Context, _ string) error
func (*WhatsAppLeg) ServerDialog ¶ added in v0.5.0
func (l *WhatsAppLeg) ServerDialog() *sipgo.DialogServerSession
func (*WhatsAppLeg) SetAcceptDTMF ¶ added in v0.5.0
func (l *WhatsAppLeg) SetAcceptDTMF(a bool)
func (*WhatsAppLeg) SetAcceptText ¶ added in v0.6.0
func (l *WhatsAppLeg) SetAcceptText(_ bool)
func (*WhatsAppLeg) SetAppID ¶ added in v0.5.0
func (l *WhatsAppLeg) SetAppID(id string)
func (*WhatsAppLeg) SetDeaf ¶ added in v0.5.0
func (l *WhatsAppLeg) SetDeaf(d bool)
func (*WhatsAppLeg) SetMuted ¶ added in v0.5.0
func (l *WhatsAppLeg) SetMuted(m bool)
func (*WhatsAppLeg) SetRole ¶ added in v0.7.0
func (l *WhatsAppLeg) SetRole(r string)
func (*WhatsAppLeg) SetRoomID ¶ added in v0.5.0
func (l *WhatsAppLeg) SetRoomID(id string)
func (*WhatsAppLeg) SetSIPController ¶ added in v0.5.0
func (l *WhatsAppLeg) SetSIPController(c WhatsAppSIPController)
func (*WhatsAppLeg) SetSIPResponseLogger ¶ added in v0.5.0
func (l *WhatsAppLeg) SetSIPResponseLogger(c SIPResponseLogger)
func (*WhatsAppLeg) SetSpeakingTap ¶ added in v0.5.0
func (l *WhatsAppLeg) SetSpeakingTap(w io.Writer)
func (*WhatsAppLeg) State ¶ added in v0.5.0
func (l *WhatsAppLeg) State() LegState
func (*WhatsAppLeg) To ¶ added in v0.5.0
func (l *WhatsAppLeg) To() string
func (*WhatsAppLeg) Type ¶ added in v0.5.0
func (l *WhatsAppLeg) Type() LegType
type WhatsAppSIPController ¶ added in v0.5.0
type WhatsAppSIPController interface {
LogSyntheticResponse(req *sipproto.Request, statusCode int, reason string, body []byte, headers ...sipproto.Header)
RespondInviteSDP(dialog *sipgo.DialogServerSession, sdp []byte) error
}
WhatsAppSIPController is satisfied by *sip.Engine. The interface lives here to avoid a cyclic import on internal/sip.