Documentation
¶
Index ¶
- Constants
- Variables
- func AttrsToHeaders(attrs, attrToHdr, headers map[string]string) map[string]string
- func ConfigureTLS(c *tls.Config)
- func DefaultCodecs() *msdk.CodecSet
- func Diff16(cur, prev uint16) int16
- func DrainPort(log logger.Logger, conn *net.UDPConn, idleTimeout, maxDuration time.Duration, ...)
- func HeadersToAttrs(attrs, hdrToAttr map[string]string, opts livekit.SIPHeaderOptions, c Signaling, ...) map[string]string
- func LoggerWithHeaders(log logger.Logger, c Signaling) logger.Logger
- func NewChangeSetSummary(current, new *sdp.MediaConfig) changeSetSummary
- func NewMediaPortPipeline(conf *MediaPortPipelineConfig, mc *sdp.MediaConfig, port *udpConn, ...) (*mediaPortPipeline, error)
- func NewReferRequest(inviteRequest *sip.Request, inviteResponse *sip.Response, ...) *sip.Request
- func NewSerializedRTPHandler(w rtp.HandlerCloser) rtp.HandlerCloser
- func NewSignalLogger(log logger.Logger, name string, next msdk.PCM16Writer, ...) (msdk.PCM16Writer, error)
- func SIPTransportFrom(t Transport) livekit.SIPTransport
- func SelectValue[T any](then, els T, probElse float64) T
- func SelectValueBool(then bool, probElse float64) bool
- func ToSIPUri(ip string, u sip.Uri) *livekit.SIPUri
- type ActiveCalls
- type AuthInfo
- type AuthResult
- type CallDispatch
- type CallIdentifier
- type CallInfo
- type CallInterface
- type CallState
- func (s *CallState) CloneInfo() *livekit.SIPCallInfo
- func (s *CallState) DeferUpdate(update func(info *livekit.SIPCallInfo))
- func (s *CallState) EndTransfer(transferID string, inErr error)
- func (s *CallState) Flush()
- func (s *CallState) ForceFlush()
- func (s *CallState) Info() *livekit.SIPCallInfo
- func (s *CallState) RecordCallContext(appendInfo func(info *livekit.SIPCallInfo))
- func (s *CallState) StartTransfer(transferTo string) string
- func (s *CallState) Update(update func(info *livekit.SIPCallInfo))
- type CallStatus
- type Client
- func (c *Client) ContactURI(tr Transport) URI
- func (c *Client) CreateSIPParticipant(ctx context.Context, req *rpc.InternalCreateSIPParticipantRequest) (*rpc.InternalCreateSIPParticipantResponse, error)
- func (c *Client) DeregisterTransferSIPParticipant(sipCallID string)
- func (c *Client) OnRequest(req *sip.Request, tx sip.ServerTransaction) bool
- func (c *Client) RegisterTransferSIPParticipant(sipCallID string, o *outboundCall) error
- func (c *Client) SetHandler(handler Handler)
- func (c *Client) Start(agent *sipgo.UserAgent, sc *ServiceConfig) error
- func (c *Client) Stop()
- type ClientOption
- type DispatchResult
- type EndCall
- type GetRoomFunc
- type GetSipClientFunc
- type GetStateHandler
- type Handler
- type HandlerInterceptor
- type Headers
- type InboundAuth
- type LatencyStats
- type LatencyStatsSnapshot
- type LocalTag
- type MediaOptions
- type MediaPort
- type MediaPortPipelineConfig
- type MediaProcessorOpts
- type MixerStatsSnapshot
- type ParticipantConfig
- type ParticipantInfo
- type PendingTransfer
- type PortStats
- type PortStatsSnapshot
- type ReasonHeader
- type RemoteTag
- type RequestHandler
- type Result
- type Room
- func (r *Room) Close() error
- func (r *Room) CloseWithReason(reason livekit.DisconnectReason) error
- func (r *Room) Closed() <-chan struct{}
- func (r *Room) ClosedReason() livekit.DisconnectReason
- func (r *Room) Connect(ctx context.Context, conf *config.Config, rconf RoomConfig) error
- func (r *Room) GetInboundAudioWriter() (msdk.PCM16Writer, error)
- func (r *Room) GetInboundDTMFWriter() msdk.WriteCloser[string]
- func (r *Room) NewParticipantTrack(sampleRate int) (msdk.WriteCloser[msdk.PCM16Sample], error)
- func (r *Room) NewTrack() *mixer.Input
- func (r *Room) Participant() ParticipantInfo
- func (r *Room) RegisterRpcCtxMethod(method string, handler lksdk.RpcHandlerCtxFunc) error
- func (r *Room) Room() *lksdk.Room
- func (r *Room) SendData(data lksdk.DataPacket, opts ...lksdk.DataPublishOption) error
- func (r *Room) Subscribe()
- func (r *Room) Subscribed() <-chan struct{}
- func (r *Room) WriteOutboundAudioTo(w msdk.PCM16Writer) msdk.PCM16Writer
- func (r *Room) WriteOutboundDTMFTo(w msdk.WriteCloser[string]) msdk.WriteCloser[string]
- type RoomConfig
- type RoomInterface
- type RoomStats
- type RoomStatsSnapshot
- type SDPError
- type SIPClient
- type Server
- func (s *Server) ContactURI(tr Transport) URI
- func (s *Server) DeregisterTransferSIPParticipant(sipCallID LocalTag)
- func (s *Server) OnNoRoute(log *slog.Logger, req *sip.Request, tx sip.ServerTransaction)
- func (s *Server) RegisterTransferSIPParticipant(sipCallID LocalTag, i *inboundCall) error
- func (s *Server) SetHandler(handler Handler)
- func (s *Server) Start(agent *sipgo.UserAgent, sc *ServiceConfig, tlsConf *tls.Config, ...) error
- func (s *Server) Stop()
- type ServerOption
- type Service
- func (s *Service) ActiveCalls() ActiveCalls
- func (s *Service) CreateSIPParticipant(ctx context.Context, req *rpc.InternalCreateSIPParticipantRequest) (*rpc.InternalCreateSIPParticipantResponse, error)
- func (s *Service) CreateSIPParticipantAffinity(ctx context.Context, req *rpc.InternalCreateSIPParticipantRequest) float32
- func (s *Service) SetHandler(handler Handler)
- func (s *Service) Start() error
- func (s *Service) Stop()
- func (s *Service) TransferSIPParticipant(ctx context.Context, req *rpc.InternalTransferSIPParticipantRequest) (*rpc.InternalTransferSIPParticipantResponse, error)
- type ServiceConfig
- type SignalLogger
- type SignalLoggerOption
- type Signaling
- type SignalingTimestamps
- type SilenceSuppressionOption
- type StateHandler
- type StateUpdater
- type Stats
- type StatsSnapshot
- type SubscriptionState
- type Transport
- type UDPConn
- type URI
Constants ¶
const ( AttrSIPCallIDFull = livekit.AttrSIPPrefix + "callIDFull" AttrSIPCallTag = livekit.AttrSIPPrefix + "callTag" )
const ( CallDialing CallRinging CallAutomation CallActive CallHangup CallCancelled )
const ( AuthNotFound = AuthResult(iota) AuthDrop AuthPassword AuthAccept AuthQuotaExceeded AuthNoTrunkFound )
const ( DispatchAccept = DispatchResult(iota) DispatchRequestPin DispatchNoRuleReject // reject the call with an error DispatchNoRuleDrop // silently drop the call )
const ( // DefaultInitialNoiseFloorDB is the default noise floor in dBFS. DefaultInitialNoiseFloorDB = -50 // DefaultHangoverDuration is how long we stay in "signal" after level drops below exit threshold. DefaultHangoverDuration = 1 * time.Second // DefaultEnterVoiceOffsetDB is the default offset above noise floor to enter voice (hysteresis high). DefaultEnterVoiceOffsetDB = 10 // DefaultExitVoiceOffsetDB is the default offset above noise floor to exit voice (hysteresis low). DefaultExitVoiceOffsetDB = 5 )
const ( TransportUDP = Transport("udp") TransportTCP = Transport("tcp") TransportTLS = Transport("tls") )
const (
RoomSampleRate = 48000
)
const (
UserAgent = "LiveKit"
)
Variables ¶
var ( ErrSIPRequestTimeout = errors.New("sip request timed out") ErrAuthMaxRetry = errors.New("max auth retry attempts reached for SIP invite") ErrAuthMissingCreds = errors.New("sip server required auth, but no username or password was provided") ErrAuthNoHeader = errors.New("no auth header in sip invite response") )
Sentinel errors emitted on outbound dial failure paths so callers can match them with errors.Is without depending on the human-readable message.
var Tracer = otel.Tracer( "github.com/livekit/sip", trace.WithInstrumentationAttributes(getSIPVersions()...), )
Functions ¶
func AttrsToHeaders ¶
func ConfigureTLS ¶
func DefaultCodecs ¶ added in v1.9.0
func HeadersToAttrs ¶
func NewChangeSetSummary ¶ added in v1.13.0
func NewChangeSetSummary(current, new *sdp.MediaConfig) changeSetSummary
func NewMediaPortPipeline ¶ added in v1.13.0
func NewMediaPortPipeline( conf *MediaPortPipelineConfig, mc *sdp.MediaConfig, port *udpConn, audioToRoom msdk.PCM16Writer, dtmfToRoom msdk.WriteCloser[string], incomingSampleRate int, ) (*mediaPortPipeline, error)
func NewReferRequest ¶
func NewSerializedRTPHandler ¶ added in v1.13.0
func NewSerializedRTPHandler(w rtp.HandlerCloser) rtp.HandlerCloser
func NewSignalLogger ¶ added in v1.3.0
func NewSignalLogger(log logger.Logger, name string, next msdk.PCM16Writer, options ...SignalLoggerOption) (msdk.PCM16Writer, error)
func SIPTransportFrom ¶
func SIPTransportFrom(t Transport) livekit.SIPTransport
func SelectValue ¶
func SelectValueBool ¶
Types ¶
type ActiveCalls ¶
func (ActiveCalls) Total ¶
func (st ActiveCalls) Total() int
type AuthInfo ¶
type AuthInfo struct {
Result AuthResult
ProjectID string
TrunkID string
Auth InboundAuth
ProviderInfo *livekit.ProviderInfo
Observability *rpc.SIPCallObservability
}
type AuthResult ¶
type AuthResult int
type CallDispatch ¶
type CallDispatch struct {
Result DispatchResult
Room RoomConfig
ProjectID string
TrunkID string
DispatchRuleID string
Headers map[string]string
HeadersToAttributes map[string]string
IncludeHeaders livekit.SIPHeaderOptions
AttributesToHeaders map[string]string
EnabledFeatures []livekit.SIPFeature
FeatureFlags map[string]string
RingingTimeout time.Duration
MaxCallDuration time.Duration
MediaConfig *livekit.SIPMediaConfig
}
type CallIdentifier ¶
type CallInterface ¶ added in v1.6.0
type CallState ¶
type CallState struct {
// contains filtered or unexported fields
}
func NewCallState ¶
func NewCallState(handler StateHandler, initial *livekit.SIPCallInfo) *CallState
func (*CallState) CloneInfo ¶ added in v1.5.0
func (s *CallState) CloneInfo() *livekit.SIPCallInfo
func (*CallState) DeferUpdate ¶
func (s *CallState) DeferUpdate(update func(info *livekit.SIPCallInfo))
func (*CallState) EndTransfer ¶
func (*CallState) ForceFlush ¶
func (s *CallState) ForceFlush()
func (*CallState) Info ¶ added in v1.5.0
func (s *CallState) Info() *livekit.SIPCallInfo
func (*CallState) RecordCallContext ¶ added in v1.5.0
func (s *CallState) RecordCallContext(appendInfo func(info *livekit.SIPCallInfo))
RecordCallContext appends late-arriving context to the canonical callInfo (e.g. PCAP links published after the call has ended) and signals the handler that the post-call context has been recorded. Does not touch the dirty bit: this is a terminal post-call signal, not a regular flush.
func (*CallState) StartTransfer ¶
func (*CallState) Update ¶
func (s *CallState) Update(update func(info *livekit.SIPCallInfo))
type CallStatus ¶
type CallStatus int
func (CallStatus) Attribute ¶
func (v CallStatus) Attribute() string
func (CallStatus) DisconnectReason ¶
func (v CallStatus) DisconnectReason() livekit.DisconnectReason
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func NewClient ¶
func NewClient(region string, conf *config.Config, log logger.Logger, mon *stats.Monitor, getStateHandler GetStateHandler, options ...ClientOption) *Client
func (*Client) ContactURI ¶
func (*Client) CreateSIPParticipant ¶
func (c *Client) CreateSIPParticipant(ctx context.Context, req *rpc.InternalCreateSIPParticipantRequest) (*rpc.InternalCreateSIPParticipantResponse, error)
func (*Client) DeregisterTransferSIPParticipant ¶
func (*Client) RegisterTransferSIPParticipant ¶
func (*Client) SetHandler ¶
type ClientOption ¶ added in v1.3.0
type ClientOption func(c *Client)
func WithGetRoomClient ¶ added in v1.3.0
func WithGetRoomClient(fn GetRoomFunc) ClientOption
func WithGetSipClient ¶ added in v1.3.0
func WithGetSipClient(fn GetSipClientFunc) ClientOption
type DispatchResult ¶
type DispatchResult int
type EndCall ¶ added in v1.6.0
type EndCall struct {
Report error // reported to LiveKit analytics
Status CallStatus // TODO: legacy
Term stats.Termination
Reason livekit.DisconnectReason // disconnect reason for LiveKit participant
Headers map[string]string // extra headers to send to SIP peer
}
type GetRoomFunc ¶ added in v1.3.0
type GetRoomFunc func(log logger.Logger, st *RoomStats) RoomInterface
type GetSipClientFunc ¶ added in v1.3.0
type GetStateHandler ¶ added in v1.5.0
type GetStateHandler func(projectID string, obs *rpc.SIPCallObservability, initial *livekit.SIPCallInfo) StateHandler
GetStateHandler returns the per-call StateHandler that CallState forwards outgoing changes to. cloud builds typically return a handler that forks the stream to both the upstream RPC and local observability; the default non-cloud build returns NewRPCStateHandler(client). obs may be nil; initial is the SIPCallInfo that NewCallState will own immediately after.
type Handler ¶
type Handler interface {
GetAuthCredentials(ctx context.Context, call *rpc.SIPCall) (AuthInfo, error)
DispatchCall(ctx context.Context, info *CallInfo) CallDispatch
GetMediaProcessor(features []livekit.SIPFeature, featureFlags map[string]string, callID string, opts MediaProcessorOpts) msdk.PCM16Processor
RegisterTransferSIPParticipantTopic(sipCallId string) error
DeregisterTransferSIPParticipantTopic(sipCallId string)
OnInboundInfo(log logger.Logger, callInfo *rpc.SIPCall, headers Headers)
OnSessionEnd(ctx context.Context, callIdentifier *CallIdentifier, state *CallState, reason string)
}
type HandlerInterceptor ¶ added in v1.10.0
type HandlerInterceptor func(sipgo.RequestHandler) sipgo.RequestHandler
HandlerInterceptor wraps a handler function.
type InboundAuth ¶ added in v1.3.1
type LatencyStats ¶ added in v1.3.0
LatencyStats is a lock-free accumulator for per-frame latency measurements. It tracks count, sum (for average), and max.
func (*LatencyStats) Load ¶ added in v1.3.0
func (s *LatencyStats) Load() LatencyStatsSnapshot
func (*LatencyStats) Record ¶ added in v1.3.0
func (s *LatencyStats) Record(d time.Duration)
type LatencyStatsSnapshot ¶ added in v1.3.0
type MediaOptions ¶
type MediaOptions struct {
IP netip.Addr
Ports rtcconfig.PortRange
MediaTimeoutInitial time.Duration
MediaTimeout time.Duration
SymmetricRTP bool
IgnoreLocalAddrInSDP bool // enable symmetric RTP if local IP is specified in SDP
Stats *PortStats
EnableJitterBuffer bool
LogSignalChanges bool
DrainingIdleTimeout time.Duration
DrainingDuration time.Duration
Codecs *msdk.CodecSet
Encryption sdp.Encryption
DTMFAudio bool
}
func (*MediaOptions) ApplyDefaults ¶ added in v1.13.0
func (o *MediaOptions) ApplyDefaults()
type MediaPort ¶
type MediaPort interface {
Close()
CloseWait()
// GetOutboundAudioWriter returns the LK room -> SIP writer.
GetOutboundAudioWriter() msdk.PCM16Writer
// GetOutboundDTMFWriter returns the LK room -> SIP DTMF writer.
GetOutboundDTMFWriter() msdk.WriteCloser[string]
// WriteInboundAudioTo tells port where to write inbound SIP audio.
//
// MediaPort.Close() will propagate to the argument writer. The caller is
// responsible for closing the returned media writer.
WriteInboundAudioTo(w msdk.PCM16Writer) msdk.PCM16Writer
// WriteInboundDTMFTo tells port where to write inbound SIP DTMF.
//
// MediaPort.Close() will propagate to the argument writer. The caller is
// responsible for closing the returned media writer.
WriteInboundDTMFTo(w msdk.WriteCloser[string]) msdk.WriteCloser[string]
// If there is no offer, this generates an offer.
// If there is an offer, this simply returns the SDP of that offer.
// An offer is cleared once a negotiation is successful.
GenerateOffer() ([]byte, error)
// GenerateAnswer returns an encoded SDP answer for the given offer.
// This does not arm the media timeout, use SetTimeout to do so.
//
// SIDE EFFECT: May cause a rebuild of the pipeline.
GenerateAnswer(offer []byte) ([]byte, error)
// ProcessAnswer processes an encoded SDP answer from the remote client. Returns an
// error if the answer is invalid, the offer has not yet been generated, or
// if media has already been negotiated.
//
// SIDE EFFECT: May cause a rebuild of the pipeline.
ProcessAnswer(answer []byte) error
GetLocalSDP() ([]byte, error)
// NegotiatedAudio returns the audio configuration chosen by SDP negotiation.
// Returns nil if media has not been negotiated yet.
//
// REQUIRES: The caller should not mutate the returned audio config.
NegotiatedAudio() *sdp.AudioConfig
// SetTimeout resets the media timeout with the given values.
//
// NOTE: This method is likely to go through additional changes.
SetTimeout(initial, general time.Duration)
Received() <-chan struct{}
MediaTimeout() <-chan struct{}
}
MediaPort is the insulated media-plane API: UDP/RTP to the wire, SDP negotiation, and audio/DTMF endpoints. It does not know about calls, rooms, or SIP dialogs.
func NewMediaPort ¶
func NewMediaPort(log logger.Logger, mon *stats.CallMonitor, opts *MediaOptions, targetSampleRate int) (MediaPort, error)
func NewMediaPortWith ¶
func NewMediaPortWith(log logger.Logger, mon *stats.CallMonitor, conn UDPConn, opts *MediaOptions, targetSampleRate int) (MediaPort, error)
type MediaPortPipelineConfig ¶ added in v1.13.0
type MediaPortPipelineConfig struct {
// contains filtered or unexported fields
}
type MediaProcessorOpts ¶ added in v1.3.1
type MediaProcessorOpts struct {
InputSampleRate int
}
type MixerStatsSnapshot ¶
type MixerStatsSnapshot struct {
Tracks int64 `json:"tracks"`
TracksTotal uint64 `json:"tracks_total"`
Restarts uint64 `json:"restarts"`
TimingResets uint64 `json:"timing_resets"`
Mixes uint64 `json:"mixes"`
TimedMixes uint64 `json:"mixes_timed"`
JumpMixes uint64 `json:"mixes_jump"`
ZeroMixes uint64 `json:"mixes_zero"`
NegativeMixes uint64 `json:"mixes_negative"`
InputSamples uint64 `json:"input_samples"`
InputFrames uint64 `json:"input_frames"`
InputSamplesDropped uint64 `json:"input_samples_dropped"`
InputFramesDropped uint64 `json:"input_frames_dropped"`
MixedSamples uint64 `json:"mixed_samples"`
MixedFrames uint64 `json:"mixed_frames"`
OutputSamples uint64 `json:"output_samples"`
OutputFrames uint64 `json:"output_frames"`
WriteErrors uint64 `json:"write_errors"`
BlockedMixes uint64 `json:"blocked_mixes"`
}
type ParticipantConfig ¶
type ParticipantInfo ¶
type PendingTransfer ¶ added in v1.3.0
type PendingTransfer struct {
CallID string
TransferTo string
// TODO: record the transfer id here as soon as the transfer starts. It is
// only known inside the worker goroutine today, so a waiter that gives up
// before the outcome arrives reports a failure with no transfer id, and the
// caller cannot match it against the transfer in their logs.
Outcome atomic.Pointer[transferOutcome]
Done chan transferOutcome
}
type PortStats ¶
type PortStats struct {
Streams atomic.Uint64
Packets atomic.Uint64
IgnoredPackets atomic.Uint64
InputPackets atomic.Uint64
FailedPackets atomic.Uint64
MuxStats rtpCountingStats
AudioPackets atomic.Uint64
AudioBytes atomic.Uint64
AudioInFrames atomic.Uint64
AudioInSamples atomic.Uint64
AudioOutFrames atomic.Uint64
AudioOutSamples atomic.Uint64
AudioRX atomic.Uint64 // based on AudioInSamples
AudioTX atomic.Uint64 // based on AudioOutSamples
DTMFPackets atomic.Uint64
DTMFBytes atomic.Uint64
JitterBufferPacketsLost atomic.Uint64
JitterBufferPacketsDropped atomic.Uint64
LatencyInE2E LatencyStats
LatencyOut LatencyStats
Closed atomic.Bool
// contains filtered or unexported fields
}
func (*PortStats) Load ¶ added in v1.3.0
func (s *PortStats) Load() PortStatsSnapshot
type PortStatsSnapshot ¶
type PortStatsSnapshot struct {
Streams uint64 `json:"streams"`
Packets uint64 `json:"packets"`
IgnoredPackets uint64 `json:"packets_ignored"`
InputPackets uint64 `json:"packets_input"`
FailedPackets uint64 `json:"packets_failed"`
MuxPackets uint64 `json:"mux_packets"`
MuxBytes uint64 `json:"mux_bytes"`
MuxResets uint64 `json:"mux_resets"`
MuxGaps uint64 `json:"mux_gaps"`
MuxGapsSum uint64 `json:"mux_gaps_sum"`
MuxLate uint64 `json:"mux_late"`
MuxLateSum uint64 `json:"mux_late_sum"`
MuxRapidPackets uint64 `json:"mux_rapid_packets"`
MuxDelayedPackets uint64 `json:"mux_delayed_packets"`
MuxDelayedSum uint64 `json:"mux_delayed_sum"`
AudioPackets uint64 `json:"audio_packets"`
AudioBytes uint64 `json:"audio_bytes"`
AudioInFrames uint64 `json:"audio_in_frames"`
AudioInSamples uint64 `json:"audio_in_samples"`
AudioOutFrames uint64 `json:"audio_out_frames"`
AudioOutSamples uint64 `json:"audio_out_samples"`
AudioRX float64 `json:"audio_rx"`
AudioTX float64 `json:"audio_tx"`
DTMFPackets uint64 `json:"dtmf_packets"`
DTMFBytes uint64 `json:"dtmf_bytes"`
JitterBufferPacketsLost uint64 `json:"jitter_buffer_packets_lost"`
JitterBufferPacketsDropped uint64 `json:"jitter_buffer_packets_dropped"`
LatencyInE2E LatencyStatsSnapshot `json:"latency_in_e2e"`
LatencyOut LatencyStatsSnapshot `json:"latency_out"`
Closed bool `json:"closed"`
}
type ReasonHeader ¶
func ParseReasonHeader ¶
func ParseReasonHeader(header string) (ReasonHeader, error)
func (ReasonHeader) IsNormal ¶
func (r ReasonHeader) IsNormal() bool
func (ReasonHeader) IsZero ¶
func (r ReasonHeader) IsZero() bool
func (ReasonHeader) String ¶
func (r ReasonHeader) String() string
type RequestHandler ¶
type RequestHandler func(req *sip.Request, tx sip.ServerTransaction) bool
type Result ¶ added in v1.6.0
type Result struct {
Code sip.StatusCode
Status string
}
type Room ¶
type Room struct {
// contains filtered or unexported fields
}
func (*Room) CloseWithReason ¶
func (r *Room) CloseWithReason(reason livekit.DisconnectReason) error
func (*Room) ClosedReason ¶ added in v1.3.1
func (r *Room) ClosedReason() livekit.DisconnectReason
ClosedReason returns the raw protocol disconnect reason once Closed() has fired. Returns livekit.DisconnectReason_UNKNOWN_REASON if the room hasn't disconnected or no reason was reported.
func (*Room) GetInboundAudioWriter ¶ added in v1.13.0
func (r *Room) GetInboundAudioWriter() (msdk.PCM16Writer, error)
func (*Room) GetInboundDTMFWriter ¶ added in v1.13.0
func (r *Room) GetInboundDTMFWriter() msdk.WriteCloser[string]
func (*Room) NewParticipantTrack ¶
func (r *Room) NewParticipantTrack(sampleRate int) (msdk.WriteCloser[msdk.PCM16Sample], error)
NewParticipantTrack publishes a local Opus audio track into the LiveKit room. TODO(alexfish): Remove this from the public interface.
func (*Room) Participant ¶
func (r *Room) Participant() ParticipantInfo
func (*Room) RegisterRpcCtxMethod ¶ added in v1.6.0
func (r *Room) RegisterRpcCtxMethod(method string, handler lksdk.RpcHandlerCtxFunc) error
func (*Room) SendData ¶
func (r *Room) SendData(data lksdk.DataPacket, opts ...lksdk.DataPublishOption) error
func (*Room) Subscribed ¶
func (r *Room) Subscribed() <-chan struct{}
func (*Room) WriteOutboundAudioTo ¶ added in v1.13.0
func (r *Room) WriteOutboundAudioTo(w msdk.PCM16Writer) msdk.PCM16Writer
func (*Room) WriteOutboundDTMFTo ¶ added in v1.13.0
func (r *Room) WriteOutboundDTMFTo(w msdk.WriteCloser[string]) msdk.WriteCloser[string]
type RoomConfig ¶
type RoomConfig struct {
WsUrl string
Token string
RoomName string
Participant ParticipantConfig
RoomPreset string
RoomConfig *livekit.RoomConfiguration
JitterBuf bool
LogSignalChanges bool
}
type RoomInterface ¶ added in v1.3.0
type RoomInterface interface {
Connect(ctx context.Context, conf *config.Config, rconf RoomConfig) error
Closed() <-chan struct{}
ClosedReason() livekit.DisconnectReason
Subscribed() <-chan struct{}
Room() *lksdk.Room
Subscribe()
Close() error
CloseWithReason(reason livekit.DisconnectReason) error
Participant() ParticipantInfo
NewParticipantTrack(sampleRate int) (msdk.WriteCloser[msdk.PCM16Sample], error)
NewTrack() *mixer.Input
lksdk.RoomRPCInterface
// WriteOutboundAudioTo tells the room where to send audio to.
// Returns the previously-set writer (if one exists).
WriteOutboundAudioTo(w msdk.PCM16Writer) msdk.PCM16Writer
// WriteOutboundDTMFTo tells the room where to send DTMF to.
// Returns the previously-set writer (if one exists).
WriteOutboundDTMFTo(w msdk.WriteCloser[string]) msdk.WriteCloser[string]
// GetInboundAudioWriter returns a writer that, when written to, writes
// audio to the room.
GetInboundAudioWriter() (msdk.PCM16Writer, error)
// GetInboundDTMFWriter returns a writer that, when written to, writes DTMF
// to the room.
GetInboundDTMFWriter() msdk.WriteCloser[string]
}
RoomInterface defines the interface for room operations
func DefaultGetRoomFunc ¶ added in v1.3.0
func DefaultGetRoomFunc(log logger.Logger, st *RoomStats) RoomInterface
type RoomStats ¶
type RoomStats struct {
PublishedFrames atomic.Uint64
PublishedSamples atomic.Uint64
PublishTX atomic.Uint64
// TrackSubscribes counts subscribe requests issued for remote tracks.
// Attempts, not confirmations.
TrackSubscribes atomic.Uint64
// Resumes and Reconnects count the two ways the signal connection recovers
// during a call, and are mutually exclusive. A resume keeps the peer
// connections and subscriptions; a reconnect rebuilds them. Neither is
// counted until the recovery succeeds.
Resumes atomic.Uint64
Reconnects atomic.Uint64
// Recovering is set while the signal connection is down. PublishedFrames
// and PublishTX are counted before the track write, so they keep reporting a
// healthy rate even though the audio is being dropped. Read them only when
// this is false.
Recovering atomic.Bool
JitterBufferPacketsLost atomic.Uint64
JitterBufferPacketsDropped atomic.Uint64
LatencyOutRecv LatencyStats // measures track recv → opus decode → mixer input.
Mixer mixer.Stats
Closed atomic.Bool
// contains filtered or unexported fields
}
func (*RoomStats) Load ¶ added in v1.3.0
func (s *RoomStats) Load() RoomStatsSnapshot
type RoomStatsSnapshot ¶
type RoomStatsSnapshot struct {
// Stats quantifying total incoming traffic from all tracks
InputPackets uint64 `json:"input_packets"`
InputBytes uint64 `json:"input_bytes"`
Resets uint64 `json:"resets"`
Gaps uint64 `json:"gaps"`
GapsSum uint64 `json:"gaps_sum"`
Late uint64 `json:"late"`
LateSum uint64 `json:"late_sum"`
DelayedPackets uint64 `json:"delayed_packets"`
DelayedSum uint64 `json:"delayed_sum"`
RapidPackets uint64 `json:"rapid_packets"`
DataPackets uint64 `json:"data_packets"`
// Stats quantifying total outgoing traffic
PublishedFrames uint64 `json:"published_frames"`
PublishedSamples uint64 `json:"published_samples"`
PublishTX float64 `json:"publish_tx"`
JitterBufferPacketsLost uint64 `json:"jitter_buffer_packets_lost"`
JitterBufferPacketsDropped uint64 `json:"jitter_buffer_packets_dropped"`
TrackSubscribes uint64 `json:"track_subscribes"`
Resumes uint64 `json:"resumes"`
Reconnects uint64 `json:"reconnects"`
// Recovering reports whether the signal connection was down when the
// snapshot was taken. PublishedFrames and PublishTX are unreliable while set.
Recovering bool `json:"recovering"`
LatencyOutRecv LatencyStatsSnapshot `json:"latency_out_recv"`
Closed bool `json:"closed"`
}
type SDPError ¶ added in v1.3.0
type SDPError struct {
Err error
}
func (SDPError) ClassifyInvite ¶ added in v1.4.0
func (e SDPError) ClassifyInvite() inviteFailure
func (SDPError) GRPCStatus ¶ added in v1.4.0
GRPCStatus lets psrpc.GetErrorCode (and any gRPC-aware caller) extract the failed-precondition code without manual psrpc.NewError wrapping.
type SIPClient ¶ added in v1.3.0
type SIPClient interface {
TransactionRequest(req *sip.Request, options ...sipgo.ClientRequestOption) (sip.ClientTransaction, error)
WriteRequest(req *sip.Request, options ...sipgo.ClientRequestOption) error
Close() error
}
SIPClient is an interface mirroring sipgo.Client to be able to mock it in tests.
Note: *sipgo.Client implements this interface directly, so no wrapper is needed.
func DefaultGetSipClientFunc ¶ added in v1.3.0
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func NewServer ¶
func NewServer(region string, conf *config.Config, log logger.Logger, mon *stats.Monitor, getStateHandler GetStateHandler, options ...ServerOption) *Server
func (*Server) ContactURI ¶
func (*Server) DeregisterTransferSIPParticipant ¶
func (*Server) RegisterTransferSIPParticipant ¶
func (*Server) SetHandler ¶
func (*Server) Start ¶
func (s *Server) Start(agent *sipgo.UserAgent, sc *ServiceConfig, tlsConf *tls.Config, unhandled RequestHandler) error
type ServerOption ¶ added in v1.3.0
type ServerOption func(s *Server)
func WithClient ¶ added in v1.3.0
func WithClient(cli *Client) ServerOption
func WithGetRoomServer ¶ added in v1.3.0
func WithGetRoomServer(fn GetRoomFunc) ServerOption
func WithInterceptors ¶ added in v1.10.0
func WithInterceptors(interceptors ...HandlerInterceptor) ServerOption
WithInterceptors configures all sip handlers to be wrapped with the given set of interceptors. Interceptors are applied s.t. the first interceptor is the outermost one.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func (*Service) ActiveCalls ¶
func (s *Service) ActiveCalls() ActiveCalls
func (*Service) CreateSIPParticipant ¶
func (s *Service) CreateSIPParticipant(ctx context.Context, req *rpc.InternalCreateSIPParticipantRequest) (*rpc.InternalCreateSIPParticipantResponse, error)
func (*Service) CreateSIPParticipantAffinity ¶
func (*Service) SetHandler ¶
func (*Service) TransferSIPParticipant ¶
func (s *Service) TransferSIPParticipant(ctx context.Context, req *rpc.InternalTransferSIPParticipantRequest) (*rpc.InternalTransferSIPParticipantResponse, error)
type ServiceConfig ¶
func GetServiceConfig ¶
func GetServiceConfig(conf *config.Config) (*ServiceConfig, error)
type SignalLogger ¶ added in v1.3.0
type SignalLogger struct {
// contains filtered or unexported fields
}
SignalLogger keeps internal state of whether we're in voice or silence, using RMS → dBFS and a fixed noise floor with hysteresis. It implements msdk.PCM16Writer and logs state changes.
func (*SignalLogger) Close ¶ added in v1.3.0
func (s *SignalLogger) Close() error
func (*SignalLogger) SampleRate ¶ added in v1.3.0
func (s *SignalLogger) SampleRate() int
func (*SignalLogger) String ¶ added in v1.3.0
func (s *SignalLogger) String() string
func (*SignalLogger) WriteSample ¶ added in v1.3.0
func (s *SignalLogger) WriteSample(sample msdk.PCM16Sample) error
type SignalLoggerOption ¶ added in v1.3.0
type SignalLoggerOption func(*SignalLogger) error
func WithEnterVoiceOffsetDB ¶ added in v1.3.0
func WithEnterVoiceOffsetDB(db float64) SignalLoggerOption
WithEnterVoiceOffsetDB sets the offset (dB) above noise floor to enter voice. Default is DefaultEnterVoiceOffsetDB.
func WithExitVoiceOffsetDB ¶ added in v1.3.0
func WithExitVoiceOffsetDB(db float64) SignalLoggerOption
WithExitVoiceOffsetDB sets the offset (dB) above noise floor to exit voice. Default is DefaultExitVoiceOffsetDB.
func WithHangoverDuration ¶ added in v1.3.0
func WithHangoverDuration(hangoverDuration time.Duration) SignalLoggerOption
func WithNoiseFloor ¶ added in v1.3.0
func WithNoiseFloor(noiseFloorDB float64) SignalLoggerOption
WithNoiseFloor sets the noise floor in dBFS (e.g. -40). Must be >= minDBFS.
type SignalingTimestamps ¶ added in v1.3.1
type SignalingTimestamps struct {
// Inbound: INVITE received; Outbound: INVITE sent.
InviteTime time.Time
// Inbound: 100 Trying sent; Outbound: 100 Trying received.
// Zero if 100 Trying was never sent/received.
TryingTime time.Time
// Inbound: first 180/183 sent; Outbound: first 180/183 received.
RingingTime time.Time
// Inbound: 200 OK sent; Outbound: 200 OK received.
AcceptTime time.Time
// Outbound only: time the API request was received (call creation).
APITime time.Time
// Outbound only: ACK sent after receiving 200 OK.
AckTime time.Time
}
SignalingTimestamps records wall-clock times for key SIP signaling events so that setup latency can be logged at the end of a session.
func (*SignalingTimestamps) Log ¶ added in v1.3.1
func (ts *SignalingTimestamps) Log(log logger.Logger)
type SilenceSuppressionOption ¶ added in v1.3.0
type SilenceSuppressionOption func(*silenceFiller)
func WithMaxGapSize ¶ added in v1.3.0
func WithMaxGapSize(maxGapSize int) SilenceSuppressionOption
type StateHandler ¶ added in v1.5.0
type StateHandler interface {
HandleUpdate(info *livekit.SIPCallInfo)
HandleTransfer(ti *livekit.SIPTransferInfo)
HandleCallContextRecorded(info *livekit.SIPCallInfo)
}
StateHandler receives outgoing CallState changes. CallState invokes the handler whenever the proto needs to be sent upstream (HandleUpdate) or a transfer transitions (HandleTransfer). Implementations forward to an RPC sink, drive in-process observability, or both.
Methods are called while CallState holds its internal mutex. Implementations must not call back into the same CallState. The supplied protos remain owned by CallState; implementations that retain them past the call must clone.
Resend / retry semantics belong to the implementation — CallState clears dirty after every call regardless of upstream outcome.
func NewRPCStateHandler ¶ added in v1.5.0
func NewRPCStateHandler(cli StateUpdater) StateHandler
NewRPCStateHandler returns a StateHandler that forwards updates to a StateUpdater. nil cli yields a no-op handler — useful for tests that don't care about the upstream sink.
type StateUpdater ¶
type StateUpdater interface {
UpdateSIPCallState(ctx context.Context, req *rpc.UpdateSIPCallStateRequest, opts ...psrpc.RequestOption) (*emptypb.Empty, error)
RecordCallContext(ctx context.Context, req *rpc.RecordCallContextRequest, opts ...psrpc.RequestOption) (*emptypb.Empty, error)
}
StateUpdater is the upstream RPC surface CallState's default StateHandler forwards to.
type StatsSnapshot ¶
type StatsSnapshot struct {
Port PortStatsSnapshot `json:"port"`
Room RoomStatsSnapshot `json:"room"`
Mixer MixerStatsSnapshot `json:"mixer"`
Closed bool `json:"closed"`
}
type SubscriptionState ¶ added in v1.12.0
type SubscriptionState struct {
State string // substate: "active", "pending", "terminated", or an extension
Reason string // reason param: noresource, giveup, timeout, rejected, ...
Expires int // expires param in seconds, 0 if absent
}
SubscriptionState is a parsed Subscription-State header. Every NOTIFY must carry one, including the NOTIFYs of the subscription a REFER creates implicitly, but not every provider sends it.
func ParseSubscriptionState ¶ added in v1.12.0
func ParseSubscriptionState(header string) SubscriptionState
ParseSubscriptionState parses a Subscription-State header value. It has no error return on purpose: a handleNotify error becomes a non-2xx answer to the NOTIFY, and an odd value in this header is no reason to reject one. An unrecognized state yields the zero value, which is not Terminated, so the transfer keeps waiting.
func (SubscriptionState) String ¶ added in v1.12.0
func (s SubscriptionState) String() string
func (SubscriptionState) Terminated ¶ added in v1.12.0
func (s SubscriptionState) Terminated() bool
Terminated reports whether the notifier ended the subscription, meaning no further NOTIFY will arrive for it.
type Transport ¶
type Transport string
func TransportFrom ¶
func TransportFrom(t livekit.SIPTransport) Transport
type URI ¶
func ConvertURI ¶
func (URI) GetContactURI ¶
func (URI) GetHostPort ¶
func (URI) GetPortOrNone ¶
Source Files
¶
- analytics.go
- client.go
- config.go
- draining_port.go
- errors.go
- features.go
- inbound.go
- media.go
- media_codecs.go
- media_file.go
- media_latency.go
- media_pipeline.go
- media_port.go
- otel.go
- outbound.go
- participant.go
- protocol.go
- room.go
- rpc.go
- server.go
- service.go
- signal_logger.go
- signaling_timestamps.go
- silence_filler.go
- tls.go
- types.go