Documentation
¶
Overview ¶
Package session binds pkg/sip1/rtp to pkg/media using pkg/sip1/sdp negotiation (no duplicate codec math).
Use NewMediaLeg after sdp.Parse on the INVITE body and configuring the RTP session remote address from the offer. Media uses pkg/media/encoder CreateDecode/CreateEncode only.
Index ¶
- Constants
- func ApplyRemoteSDP(sess *siprtp.Session, info *sdp.Info) error
- func InternalPCMSampleRate(src media.CodecConfig) int
- func NegotiateOffer(offer []sdp.Codec) (src media.CodecConfig, neg sdp.Codec, err error)
- type CallSession
- func (cs *CallSession) AppendRecordingSample(dir byte, seq uint16, ts uint32, payload []byte)
- func (cs *CallSession) ArmSessionTimerWatchdog(interval time.Duration, onExpiry func())
- func (cs *CallSession) AttachVoiceConversation(fn func() error) error
- func (cs *CallSession) CloseRTPOnly()
- func (cs *CallSession) DTMFPayloadType() uint8
- func (cs *CallSession) EnableRecorder(cfg RecorderConfig) bool
- func (cs *CallSession) FlushRecorder(ctx context.Context) (RecordingInfo, bool)
- func (cs *CallSession) HasRecorder() bool
- func (cs *CallSession) InboundRetargetHeaders() (string, string, string)
- func (cs *CallSession) InboundUnboundTenant() bool
- func (cs *CallSession) MediaSession() *media.MediaSession
- func (cs *CallSession) NegotiatedCodec() sdp.Codec
- func (cs *CallSession) PCMSampleRate() int
- func (cs *CallSession) RTCPStats() rtp.RTCPStats
- func (cs *CallSession) RTPSession() *rtp.Session
- func (cs *CallSession) RemoteFromHeader() string
- func (cs *CallSession) SetInboundRetargetHeaders(toHdr, historyInfo, diversion string)
- func (cs *CallSession) SetInboundUnboundTenant(v bool)
- func (cs *CallSession) SetRemoteFromHeader(v string)
- func (cs *CallSession) SetTenantID(id uint)
- func (cs *CallSession) SourceCodec() media.CodecConfig
- func (cs *CallSession) Start()
- func (cs *CallSession) StartOnACK()
- func (cs *CallSession) Stop()
- func (cs *CallSession) StopMediaPreserveRTP()
- func (cs *CallSession) StopSessionTimer()
- func (cs *CallSession) TakeRecording() []byte
- func (cs *CallSession) TenantID() uint
- func (cs *CallSession) TouchSessionTimer()
- func (cs *CallSession) WireTransferBridgeRecording(callerRx, callerTx *rtp.SIPRTPTransport)
- func (cs *CallSession) WriteAIPCM(pcm []byte)
- func (cs *CallSession) WriteCallerPCM(pcm []byte)
- type MediaLeg
- func (l *MediaLeg) CloseRTPOnly()
- func (l *MediaLeg) DTMFPayloadType() uint8
- func (l *MediaLeg) MediaSession() *media.MediaSession
- func (l *MediaLeg) NegotiatedSDP() sdp.Codec
- func (l *MediaLeg) PCMSampleRate() int
- func (l *MediaLeg) RTPSession() *siprtp.Session
- func (l *MediaLeg) SourceCodec() media.CodecConfig
- func (l *MediaLeg) Start()
- func (l *MediaLeg) Stop()
- func (l *MediaLeg) StopMediaPreserveRTP()
- type MediaLegConfig
- type RecorderConfig
- type RecordingInfo
Constants ¶
const ( RecordingDirUser = recDirUser RecordingDirAI = recDirAI )
RecordingDirUser / RecordingDirAI match SN3 dir bytes for AppendRecordingSample (e.g. SIP transfer raw relay).
Variables ¶
This section is empty.
Functions ¶
func ApplyRemoteSDP ¶
ApplyRemoteSDP sets RTP remote address from sdp.Info (m= / c=).
func InternalPCMSampleRate ¶
func InternalPCMSampleRate(src media.CodecConfig) int
InternalPCMSampleRate chooses the MediaSession PCM bridge rate for a negotiated RTP codec so decode/encode avoids unnecessary resampling (e.g. keep G.711 at 8 kHz, Opus at negotiated clock, G.722 at 16 kHz PCM).
func NegotiateOffer ¶
NegotiateOffer picks the first supported audio codec from a remote SDP offer (ordered by preference).
Types ¶
type CallSession ¶
type CallSession struct {
CallID string
// contains filtered or unexported fields
}
CallSession binds an RTP session to a MediaSession for SIP calls.
Uplink: RTP -> decode -> PCM for ASR processors. Downlink: only synthesized (TTS) PCM is encoded and sent as RTP; uplink is not echoed (see media.KeySIPSuppressUplinkEcho).
func NewCallSession ¶
func NewCallSession(callID string, rtpSess *rtp.Session, sdpCodecs []sdp.Codec) (*CallSession, error)
NewCallSession creates a call session with codec negotiation from SDP.
func (*CallSession) AppendRecordingSample ¶
func (cs *CallSession) AppendRecordingSample(dir byte, seq uint16, ts uint32, payload []byte)
AppendRecordingSample appends one RTP payload to the SN3 blob (used during transfer bridge when media bypasses the original rx/tx transports).
func (*CallSession) ArmSessionTimerWatchdog ¶
func (cs *CallSession) ArmSessionTimerWatchdog(interval time.Duration, onExpiry func())
ArmSessionTimerWatchdog starts an RFC 4028 watchdog. If no TouchSessionTimer call arrives within `interval`, onExpiry runs (the SIP server wires this to "send BYE with Reason: SIP;cause=408").
Calling Arm a second time replaces any prior watchdog (e.g. timer was renegotiated by a re-INVITE). interval <= 0 stops the watchdog.
Safe to call on nil receiver (no-op).
func (*CallSession) AttachVoiceConversation ¶
func (cs *CallSession) AttachVoiceConversation(fn func() error) error
AttachVoiceConversation runs fn once before media Serve() (typically from ACK) to register processors or other hooks. If fn fails, a later call may retry.
func (*CallSession) CloseRTPOnly ¶
func (cs *CallSession) CloseRTPOnly()
CloseRTPOnly closes the RTP UDP socket after a bridge or full teardown path.
func (*CallSession) DTMFPayloadType ¶
func (cs *CallSession) DTMFPayloadType() uint8
DTMFPayloadType is the negotiated telephone-event PT, or 0 if none.
func (*CallSession) EnableRecorder ¶
func (cs *CallSession) EnableRecorder(cfg RecorderConfig) bool
EnableRecorder arms stereo PCM taps when the sink accepts BeginRecording.
func (*CallSession) FlushRecorder ¶
func (cs *CallSession) FlushRecorder(ctx context.Context) (RecordingInfo, bool)
FlushRecorder delivers the SN3 blob to RecordingSink.FinishRecording.
func (*CallSession) HasRecorder ¶
func (cs *CallSession) HasRecorder() bool
HasRecorder reports whether stereo PCM taps are armed.
func (*CallSession) InboundRetargetHeaders ¶
func (cs *CallSession) InboundRetargetHeaders() (string, string, string)
InboundRetargetHeaders returns (rawTo, rawHistoryInfo, rawDiversion) captured at INVITE intake. Empty strings when not set (e.g. outbound- originated CallSession). Consumers should treat the strings as opaque SIP header values and pass them through historyinfo.ParseChain / ParseDiversionChain.
func (*CallSession) InboundUnboundTenant ¶
func (cs *CallSession) InboundUnboundTenant() bool
InboundUnboundTenant is true when the inbound number is not bound to a tenant (play not_bind.wav).
func (*CallSession) MediaSession ¶
func (cs *CallSession) MediaSession() *media.MediaSession
MediaSession exposes the underlying media pipeline for voice processors (ASR/TTS hooks).
func (*CallSession) NegotiatedCodec ¶
func (cs *CallSession) NegotiatedCodec() sdp.Codec
func (*CallSession) PCMSampleRate ¶
func (cs *CallSession) PCMSampleRate() int
PCMSampleRate is the internal mono PCM rate produced by RTP decode (and fed to ASR processors).
func (*CallSession) RTCPStats ¶
func (cs *CallSession) RTCPStats() rtp.RTCPStats
RTCPStats returns a one-shot RTCP counter snapshot (safe at BYE; O(1)).
func (*CallSession) RTPSession ¶
func (cs *CallSession) RTPSession() *rtp.Session
RTPSession returns the underlying RTP/UDP session (for building a transfer bridge).
func (*CallSession) RemoteFromHeader ¶
func (cs *CallSession) RemoteFromHeader() string
RemoteFromHeader 返回入站 INVITE 的 From header;nil 或未注入时返回 ""。
func (*CallSession) SetInboundRetargetHeaders ¶
func (cs *CallSession) SetInboundRetargetHeaders(toHdr, historyInfo, diversion string)
SetInboundRetargetHeaders captures the raw To header plus any pre-existing History-Info / Diversion headers from the inbound INVITE. Called by sip/server at INVITE intake. Arguments are trimmed; empty ones are ignored so re-calling with partial info doesn't clobber previously-stored values.
func (*CallSession) SetInboundUnboundTenant ¶
func (cs *CallSession) SetInboundUnboundTenant(v bool)
SetInboundUnboundTenant marks inbound calls where the called DID is not assigned to any tenant.
func (*CallSession) SetRemoteFromHeader ¶
func (cs *CallSession) SetRemoteFromHeader(v string)
SetRemoteFromHeader 由 sip/server 在 INVITE 入站时调用,记录 PSTN 主叫 的原始 From header 供转接路径回显。nil-safe / 空值跳过。
func (*CallSession) SetTenantID ¶
func (cs *CallSession) SetTenantID(id uint)
SetTenantID records the tenant scope for media/AI (inbound DID or outbound campaign).
func (*CallSession) SourceCodec ¶
func (cs *CallSession) SourceCodec() media.CodecConfig
SourceCodec is the negotiated RTP codec (PCMU/PCMA/G722/OPUS) for this leg.
func (*CallSession) Start ¶
func (cs *CallSession) Start()
Start starts MediaSession serving in background.
func (*CallSession) StartOnACK ¶
func (cs *CallSession) StartOnACK()
StartOnACK starts media pipeline once (idempotent) when ACK is received.
func (*CallSession) Stop ¶
func (cs *CallSession) Stop()
Stop stops the session and closes underlying RTP resources.
func (*CallSession) StopMediaPreserveRTP ¶
func (cs *CallSession) StopMediaPreserveRTP()
StopMediaPreserveRTP stops the MediaSession (AI pipeline, RTP read/write loops) but keeps the UDP socket open so new SIPRTPTransport instances can attach for bridging.
func (*CallSession) StopSessionTimer ¶
func (cs *CallSession) StopSessionTimer()
StopSessionTimer cancels any pending watchdog. Called automatically from Stop(); also called by the server when BYE arrives before expiry.
func (*CallSession) TakeRecording ¶
func (cs *CallSession) TakeRecording() []byte
TakeRecording returns buffered RTP recording (SN3 …) and clears the buffer.
func (*CallSession) TenantID ¶
func (cs *CallSession) TenantID() uint
TenantID returns the tenant id bound to this call (0 = none / legacy).
func (*CallSession) TouchSessionTimer ¶
func (cs *CallSession) TouchSessionTimer()
TouchSessionTimer resets the watchdog back to the full interval. Call this every time we accept a refresh re-INVITE or UPDATE in the dialog. No-op when no watchdog is armed.
func (*CallSession) WireTransferBridgeRecording ¶
func (cs *CallSession) WireTransferBridgeRecording(callerRx, callerTx *rtp.SIPRTPTransport)
WireTransferBridgeRecording attaches SN3 callbacks to PCM-bridge transports sharing inbound RTP session.
func (*CallSession) WriteAIPCM ¶
func (cs *CallSession) WriteAIPCM(pcm []byte)
WriteAIPCM forwards decoded agent/AI PCM to the recording sink when armed.
func (*CallSession) WriteCallerPCM ¶
func (cs *CallSession) WriteCallerPCM(pcm []byte)
WriteCallerPCM forwards decoded caller PCM to the recording sink when armed.
type MediaLeg ¶
type MediaLeg struct {
// contains filtered or unexported fields
}
MediaLeg is one RTP leg wired to a MediaSession (decode uplink / encode downlink) using pkg/media/encoder.
func NewMediaLeg ¶
func NewMediaLeg(parent context.Context, callID string, rtpSess *siprtp.Session, offer []sdp.Codec, cfg MediaLegConfig) (*MediaLeg, error)
NewMediaLeg builds decode/encode chain from the remote SDP offer codecs and attaches RTP transports. rtpSess must already be listening; call ApplyRemoteSDP before Start if offer contains c=/m=.
func (*MediaLeg) CloseRTPOnly ¶
func (l *MediaLeg) CloseRTPOnly()
CloseRTPOnly closes the RTP UDP socket without touching a nil MediaSession (e.g. after WebRTC bridge teardown).
func (*MediaLeg) DTMFPayloadType ¶
DTMFPayloadType returns the negotiated RFC 2833 telephone-event PT, or 0.
func (*MediaLeg) MediaSession ¶
func (l *MediaLeg) MediaSession() *media.MediaSession
MediaSession exposes the underlying media pipeline.
func (*MediaLeg) NegotiatedSDP ¶
NegotiatedSDP returns the chosen sdp.Codec line.
func (*MediaLeg) PCMSampleRate ¶
PCMSampleRate returns the internal mono PCM sample rate between decode and encode.
func (*MediaLeg) RTPSession ¶
RTPSession exposes the RTP UDP session.
func (*MediaLeg) SourceCodec ¶
func (l *MediaLeg) SourceCodec() media.CodecConfig
SourceCodec returns the negotiated RTP media.CodecConfig.
func (*MediaLeg) Start ¶
func (l *MediaLeg) Start()
Start runs MediaSession.Serve in a background goroutine (idempotent).
func (*MediaLeg) StopMediaPreserveRTP ¶
func (l *MediaLeg) StopMediaPreserveRTP()
StopMediaPreserveRTP stops the MediaSession and RTP transport loops but keeps the UDP socket open so new SIPRTPTransport instances can attach for a two-leg bridge (same idea as pkg/sip/session.CallSession).
type MediaLegConfig ¶
type MediaLegConfig struct {
OutputQueueSize int // default 512
MaxSessionSeconds int // 0 = no limit; passed to media.MediaSession.MaxSessionDuration (seconds)
AllowUplinkEcho bool // if false (default), set media.KeySIPSuppressUplinkEcho
}
MediaLegConfig optional tuning for MediaLeg.
type RecorderConfig ¶
type RecorderConfig struct {
Meta hooks.CallMeta
SampleRate int
Codec string
Sink hooks.RecordingSink // nil → hooks.DefaultRegistry.Recording
}
RecorderConfig configures optional stereo PCM taps via hooks.RecordingSink. SN3 RTP capture in CallSession is always available via TakeRecording regardless of this config.
type RecordingInfo ¶
RecordingInfo is a durable handle returned after FlushRecorder (URL/object key from hooks.RecordingSink).