diago

package module
v0.21.37 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 19, 2026 License: MPL-2.0 Imports: 31 Imported by: 0

README

DIAGO

Go Report Card Coverage GitHub go.mod Go version

Short of dialog + GO.
Library for building VOIP solutions in GO!

Built on top of optimized SIPgo library!
In short it allows developing fast and easy testable VOIP apps to handle calls, registrations and more...

Diago is mainly project driven lib, so lot of API design will/should be challenged with real working apps needs

For more information and documentation visit the website

Quick links:

If you find this project useful and you want to support/sponzor or need help with your projects, you can contact me more on mail.

Follow me on X/Twitter for regular updates

Tools/Service developed with diago:

RFCS

SIP: RFC 3261|RFC3581|RFC6026

More refer to lib github.com/emiago/sipgo Full dialog control (client/server), Registering, Authentication ...

SDP: RFC8866.

Parsing + Auto Generating for media session/audio

RTP/AVP: RFC3550

RTP Packetizers, Media Forking, RTP Session control, RTCP Sender/Receiver reports, RTCP statistics tracking, DTMF reader/writer ...

NOTE: For specifics and questions what is covered by RFC, please open Issue. Note lot of functionality can be extended even if not built in library.

Contributions

Please open first issues instead PRs. Library is under development and could not have latest code pushed.

Usage

Checkout more on Getting started, but for quick view here is echotest (hello world) example.

ua, _ := sipgo.NewUA()
dg := diago.NewDiago(ua)

dg.Serve(ctx, func(inDialog *diago.DialogServerSession) {
	inDialog.Trying() // Progress -> 100 Trying
	inDialog.Answer(); // Answer

	// Make sure file below exists in work dir
	playfile, err := os.Open("demo-echotest.wav")
	if err != nil {
		fmt.Println("Failed to open file", err)
		return
	}
	defer playfile.Close()

	// Create playback and play file.
	pb, _ := inDialog.PlaybackCreate()
	if err := pb.Play(playfile, "audio/wav"); err != nil {
		fmt.Println("Playing failed", err)
	}
}

See more examples in this repo

Tracing SIP, RTP

While openning issue, consider having some traces enabled.

sip.SIPDebug = true // Enables SIP tracing
media.RTCPDebug = true // Enables RTCP tracing
media.RTPDebug = true // Enables RTP tracing. NOTE: It will dump every RTP Packet

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrDigestAuthNoChallenge = errors.New("no challenge")
	ErrDigestAuthBadCreds    = errors.New("bad credentials")
)
View Source
var (
	DefaultPlaybackURLRangeSize int = 65536
)
View Source
var (
	ErrClientEarlyMedia = errors.New("Early media detected")
)
View Source
var (
	HTTPDebug = os.Getenv("HTTP_DEBUG") == "true"
)
View Source
var (
	PlaybackBufferSize = 3840 // For now largest we support. 48000 sample rate with 2 channels
)

Functions

func NewConnRecorder

func NewConnRecorder() *connRecorder

Types

type AnswerOptions

type AnswerOptions struct {
	// OnMediaUpdate triggers when media update happens. It is blocking func, so make sure you exit
	OnMediaUpdate func(d *DialogMedia)
	OnRefer       func(referDialog *DialogClientSession)
	// Codecs that will be used
	Codecs []media.Codec
}

type AudioPlayback

type AudioPlayback struct {

	// Read only values
	// This will influence playout sampling buffer
	BitDepth    int
	NumChannels int
	// contains filtered or unexported fields
}

func NewAudioPlayback

func NewAudioPlayback(writer io.Writer, codec media.Codec) AudioPlayback

NewAudioPlayback creates a playback where writer is encoder/streamer to media codec Use dialog.PlaybackCreate() instead creating manually playback

func (*AudioPlayback) Play

func (p *AudioPlayback) Play(reader io.Reader, mimeType string) (int64, error)

Play is generic approach to play supported audio contents Empty mimeType will stream reader as buffer. Make sure that bitdepth and numchannels is set correctly

func (*AudioPlayback) PlayFile

func (p *AudioPlayback) PlayFile(filename string) (int64, error)

PlayFile will play file and close file when finished playing If you need to play same file multiple times, that use generic Play function

func (*AudioPlayback) PlayURL

func (p *AudioPlayback) PlayURL(urlStr string) (int64, error)

type AudioPlaybackControl

type AudioPlaybackControl struct {
	AudioPlayback
	// contains filtered or unexported fields
}

func (*AudioPlaybackControl) Mute

func (p *AudioPlaybackControl) Mute(mute bool)

func (*AudioPlaybackControl) Stop

func (p *AudioPlaybackControl) Stop()

type AudioReaderOption

type AudioReaderOption func(d *DialogMedia) error

func WithAudioReaderDTMF

func WithAudioReaderDTMF(r *DTMFReader) AudioReaderOption

WithAudioReaderDTMF creates DTMF interceptor

func WithAudioReaderMediaProps

func WithAudioReaderMediaProps(p *MediaProps) AudioReaderOption

func WithAudioReaderRTPStats

func WithAudioReaderRTPStats(hook media.OnRTPReadStats) AudioReaderOption

WithAudioReaderRTPStats creates RTP Statistics interceptor on audio reader

type AudioRingtone

type AudioRingtone struct {
	// contains filtered or unexported fields
}

AudioRingtone is playback for ringtone

Experimental

func (*AudioRingtone) Play

func (a *AudioRingtone) Play(ctx context.Context) error

func (*AudioRingtone) PlayBackground

func (a *AudioRingtone) PlayBackground() (func() error, error)

type AudioStereoRecordingWav

type AudioStereoRecordingWav struct {
	// contains filtered or unexported fields
}

func (*AudioStereoRecordingWav) AudioReader

func (*AudioStereoRecordingWav) AudioWriter

func (*AudioStereoRecordingWav) Close

func (r *AudioStereoRecordingWav) Close() error

type AudioWriterOption

type AudioWriterOption func(d *DialogMedia) error

func WithAudioWriterDTMF

func WithAudioWriterDTMF(r *DTMFWriter) AudioWriterOption

WithAudioWriterDTMF creates DTMF interceptor

func WithAudioWriterMediaProps

func WithAudioWriterMediaProps(p *MediaProps) AudioWriterOption

func WithAudioWriterRTPStats

func WithAudioWriterRTPStats(hook media.OnRTPWriteStats) AudioWriterOption

WithAudioReaderRTPStats creates RTP Statistics interceptor on audio reader

type Bridge

type Bridge struct {
	// Originator is dialog session that created bridge
	Originator DialogSession
	// DTMFpass is also dtmf pipeline and proxy. By default only audio media is proxied
	// NOTE: this may not work if you are already processing DTMF with AudioReaderDTMF
	DTMFpass bool

	// minDialogs is just helper flag when to start proxy
	WaitDialogsNum int
	// contains filtered or unexported fields
}

func NewBridge

func NewBridge() Bridge

func (*Bridge) AddDialogSession

func (b *Bridge) AddDialogSession(d DialogSession) error

func (*Bridge) GetDialogs

func (b *Bridge) GetDialogs() []DialogSession

func (*Bridge) Init

func (b *Bridge) Init(log *slog.Logger)

func (*Bridge) ProxyMedia

func (b *Bridge) ProxyMedia() error

ProxyMedia is explicit starting proxy media. In some cases you want to control and be signaled when bridge terminates

NOTE: Should be only called if you want to start manually proxying. It is required to set WaitDialogsNum higher than 2

Experimental

func (*Bridge) ProxyMediaControl

func (b *Bridge) ProxyMediaControl() (func() error, error)

ProxyMediaControl starts proxy in background and allows to stop proxy at any time. Stop should be called once and it is not needed to be called if call is terminating

Experimental

type Bridger

type Bridger interface {
	AddDialogSession(d DialogSession) error
}

type DTMFReader

type DTMFReader struct {
	// contains filtered or unexported fields
}

func (*DTMFReader) Listen

func (d *DTMFReader) Listen(onDTMF func(dtmf rune) error, dur time.Duration) error

func (*DTMFReader) OnDTMF

func (d *DTMFReader) OnDTMF(onDTMF func(dtmf rune) error)

OnDTMF must be called before audio reading

func (*DTMFReader) Read

func (d *DTMFReader) Read(buf []byte) (n int, err error)

Read exposes io.Reader that can be used as AudioReader

type DTMFWriter

type DTMFWriter struct {
	// contains filtered or unexported fields
}

func (*DTMFWriter) AudioWriter

func (w *DTMFWriter) AudioWriter() *media.RTPDtmfWriter

AudioReader exposes DTMF audio writer. You should use this for parallel audio processing

func (*DTMFWriter) Write

func (w *DTMFWriter) Write(buf []byte) (n int, err error)

Write exposes as io.Writer that can be used as AudioWriter

func (*DTMFWriter) WriteDTMF

func (w *DTMFWriter) WriteDTMF(dtmf rune) error

type Diago

type Diago struct {
	// contains filtered or unexported fields
}

func NewDiago

func NewDiago(ua *sipgo.UserAgent, opts ...DiagoOption) *Diago

NewDiago construct b2b user agent that will act as server and client

func (*Diago) DialogCacheClient

func (dg *Diago) DialogCacheClient() DialogCache[*DialogClientSession]

func (*Diago) DialogCacheServer

func (dg *Diago) DialogCacheServer() DialogCache[*DialogServerSession]

func (*Diago) HandleFunc

func (dg *Diago) HandleFunc(f ServeDialogFunc)

HandleFunc registers you handler function for dialog. Must be called before serving request

func (*Diago) Invite

func (dg *Diago) Invite(ctx context.Context, recipient sip.Uri, opts InviteOptions) (d *DialogClientSession, err error)

Invite makes outgoing call leg and waits for answer. If you want to bridge call then use helper InviteBridge

func (*Diago) InviteBridge

func (dg *Diago) InviteBridge(ctx context.Context, recipient sip.Uri, bridge *Bridge, opts InviteOptions) (d *DialogClientSession, err error)

InviteBridge makes outgoing call leg and does bridging. Outgoing session will be added into bridge on answer If bridge has Originator (first participant) it will be used for creating outgoing call leg as in B2BUA When bridge is provided then this call will be bridged with any participant already present in bridge

func (*Diago) NewDialog

func (dg *Diago) NewDialog(recipient sip.Uri, opts NewDialogOptions) (d *DialogClientSession, err error)

NewDialog creates a new client dialog session after you can perform dialog Invite - You call Invite(...) after this call followed with ACK

func (*Diago) Register

func (dg *Diago) Register(ctx context.Context, recipient sip.Uri, opts RegisterOptions) error

Register will create register transaction and keep registration ongoing until error is hit. For more granular control over registraions user RegisterTransaction

func (*Diago) RegisterTransaction

func (dg *Diago) RegisterTransaction(ctx context.Context, recipient sip.Uri, opts RegisterOptions) (*RegisterTransaction, error)

Register transaction creates register transaction object that can be used for Register Unregister requests

func (*Diago) Serve

func (dg *Diago) Serve(ctx context.Context, f ServeDialogFunc) error

Serve starts 'Server' handle for SIP. Should be called for UAS but can be skipped for UAC behavior

func (*Diago) ServeBackground

func (dg *Diago) ServeBackground(ctx context.Context, f ServeDialogFunc) error

ServeBackground starts serving in background, but waits server listener to be started before returning Checkout more info on Serve()

type DiagoOption

type DiagoOption func(dg *Diago)

func WithAuth

func WithAuth(auth sipgo.DigestAuth) DiagoOption

func WithClient

func WithClient(client *sipgo.Client) DiagoOption

WithClient allows providing custom client handle. Consider still it needs to use same UA as diago

func WithLogger

func WithLogger(l *slog.Logger) DiagoOption

func WithMediaConfig

func WithMediaConfig(conf MediaConfig) DiagoOption

func WithServer

func WithServer(srv *sipgo.Server) DiagoOption

WithServer allows providing custom server handle. Consider still it needs to use same UA as diago

func WithTransport

func WithTransport(t Transport) DiagoOption

type DialogCache

type DialogCache[T DialogSession] interface {
	DialogStore(ctx context.Context, id string, v T) error
	DialogLoad(ctx context.Context, id string) (T, error)
	DialogDelete(ctx context.Context, id string) error
	DialogRange(ctx context.Context, f func(id string, d T) bool) error
}

type DialogCachePool

type DialogCachePool struct {
	// contains filtered or unexported fields
}

func (*DialogCachePool) MatchDialog

func (*DialogCachePool) MatchDialogClient

func (p *DialogCachePool) MatchDialogClient(req *sip.Request) (*DialogClientSession, error)

func (*DialogCachePool) MatchDialogServer

func (p *DialogCachePool) MatchDialogServer(req *sip.Request) (*DialogServerSession, error)

type DialogClientSession

type DialogClientSession struct {
	*sipgo.DialogClientSession

	DialogMedia
	// contains filtered or unexported fields
}

DialogClientSession represents outbound channel

func (*DialogClientSession) Ack

Ack acknowledgeds media Before Ack normally you want to setup more stuff like bridging

func (*DialogClientSession) Close

func (d *DialogClientSession) Close() error

func (*DialogClientSession) DialogSIP

func (d *DialogClientSession) DialogSIP() *sipgo.Dialog

func (*DialogClientSession) FromUser

func (d *DialogClientSession) FromUser() string

func (*DialogClientSession) Hangup

func (d *DialogClientSession) Hangup(ctx context.Context) error

func (*DialogClientSession) Id

func (d *DialogClientSession) Id() string

func (*DialogClientSession) Invite

Invite sends Invite request and establishes [early] media.

Early Media Detect: - It RETURNS ErrClientEarlyMedia if remote answers with 183 Session in Progress - Media is negotiated and setuped - You need to call WaitAnswer() if you want to proceed with answering call

Normal Answer with 200 OK (SDP) - You MUST call Ack() after to acknowledge session.

Errors: - sipgo.ErrDialogResponse - ErrClientEarlyMedia

NOTE: It updates internal invite request so NOT THREAD SAFE. If you pass originator it will use originator to set correct from header and avoid media transcoding

Experimental: Note API may have changes

func (*DialogClientSession) ReInvite

func (d *DialogClientSession) ReInvite(ctx context.Context) error

ReInvite sends new invite based on current media session

func (*DialogClientSession) Refer

func (d *DialogClientSession) Refer(ctx context.Context, referTo sip.Uri) error

Refer tries todo refer (blind transfer) on call TODO: not complete

func (*DialogClientSession) RemoteContact

func (d *DialogClientSession) RemoteContact() *sip.ContactHeader

func (*DialogClientSession) ToUser

func (d *DialogClientSession) ToUser() string

func (*DialogClientSession) WaitAnswer

func (d *DialogClientSession) WaitAnswer(ctx context.Context, opts sipgo.AnswerOptions) error

WaitAnswer waits dialog on answer. It should only be used if you have error Invite but still want to continue ex. ErrClientEarlyMedia was returned but you want to proceed with answering

type DialogData

type DialogData struct {
	InviteRequest sip.Request
	State         sip.DialogState
}

type DialogMedia

type DialogMedia struct {

	// Packet reader is default reader for RTP audio stream
	// Use always AudioReader to get current Audio reader
	// Use this only as read only
	// It MUST be always created on Media Session Init
	// Only safe to use after dialog Answered (Completed state)
	RTPPacketReader *media.RTPPacketReader

	// Packet writer is default writer for RTP audio stream
	// Use always AudioWriter to get current Audio reader
	// Use this only as read only
	RTPPacketWriter *media.RTPPacketWriter

	// Video RTP packet reader and writer
	VideoRTPPacketReader *media.RTPPacketReader
	VideoRTPPacketWriter *media.RTPPacketWriter
	// contains filtered or unexported fields
}

DialogMedia is common struct for server and client session and it shares same functionality which is mostly arround media

func (*DialogMedia) AddVideoSession added in v0.21.3

func (d *DialogMedia) AddVideoSession(codecs []media.Codec, mode string) error

AddVideoSession dynamically adds video session during active call This allows adding video to an audio-only call using re-INVITE codecs: video codecs to use (e.g., media.CodecVideoH264) mode: SDP mode (sdp.ModeSendrecv, sdp.ModeRecvonly, sdp.ModeSendonly)

func (*DialogMedia) AudioReader

func (d *DialogMedia) AudioReader(opts ...AudioReaderOption) (io.Reader, error)

AudioReader gets current audio reader. It MUST be called after Answer. Use AuidioListen for optimized reading. Reading buffer should be equal or bigger of media.RTPBufSize Options allow more intercepting audio reading like Stats or DTMF NOTE that this interceptors will stay,

func (*DialogMedia) AudioReaderDTMF

func (m *DialogMedia) AudioReaderDTMF() *DTMFReader

AudioReaderDTMF is DTMF over RTP. It reads audio and provides hook for dtmf while listening for audio Use Listen or OnDTMF after this call

func (*DialogMedia) AudioStereoRecordingCreate

func (d *DialogMedia) AudioStereoRecordingCreate(wawFile *os.File) (AudioStereoRecordingWav, error)

AudioStereoRecordingCreate creates Stereo Recording audio Pipeline and stores as Wav file format For audio to be recorded use AudioReader and AudioWriter from Recording

Tips: If you want to make permanent in audio pipeline use SetAudioReader, SetAudioWriter

NOTE: API WILL change

func (*DialogMedia) AudioWriter

func (d *DialogMedia) AudioWriter(opts ...AudioWriterOption) (io.Writer, error)

func (*DialogMedia) AudioWriterDTMF

func (m *DialogMedia) AudioWriterDTMF() *DTMFWriter

func (*DialogMedia) Close

func (d *DialogMedia) Close() error

func (*DialogMedia) Echo

func (d *DialogMedia) Echo() error

Echo does audio echo for you

func (*DialogMedia) InitMediaSession

func (d *DialogMedia) InitMediaSession(m *media.MediaSession, r *media.RTPPacketReader, w *media.RTPPacketWriter)

func (*DialogMedia) Listen

func (d *DialogMedia) Listen() (err error)

Listen keeps reading stream until it gets closed or deadlined Use ListenBackground or ListenContext for better control

func (*DialogMedia) ListenBackground

func (d *DialogMedia) ListenBackground() (stop func() error, err error)

ListenBackground listens on stream in background and allows correct stoping of stream on network layer

func (*DialogMedia) ListenContext

func (d *DialogMedia) ListenContext(pctx context.Context) error

ListenContext listens until context is canceled.

func (*DialogMedia) ListenUntil

func (d *DialogMedia) ListenUntil(dur time.Duration) error

func (*DialogMedia) Media

func (d *DialogMedia) Media() *DialogMedia

func (*DialogMedia) MediaSession

func (d *DialogMedia) MediaSession() *media.MediaSession

func (*DialogMedia) OnClose

func (d *DialogMedia) OnClose(f func() error)

func (*DialogMedia) PlaybackControlCreate

func (d *DialogMedia) PlaybackControlCreate() (AudioPlaybackControl, error)

PlaybackControlCreate creates playback for audio with controls like mute unmute

func (*DialogMedia) PlaybackCreate

func (d *DialogMedia) PlaybackCreate() (AudioPlayback, error)

PlaybackCreate creates playback for audio

func (*DialogMedia) PlaybackRingtoneCreate

func (d *DialogMedia) PlaybackRingtoneCreate() (AudioRingtone, error)

PlaybackRingtoneCreate is creating playback for ringtone

Experimental

func (*DialogMedia) RTPSession

func (d *DialogMedia) RTPSession() *media.RTPSession

RTPSession returns underhood rtp session NOTE: this can be nil

func (*DialogMedia) RemoveVideoSession added in v0.21.3

func (d *DialogMedia) RemoveVideoSession() error

RemoveVideoSession removes video session during active call This allows removing video from a video call using re-INVITE

func (*DialogMedia) SetAudioReader

func (d *DialogMedia) SetAudioReader(r io.Reader)

SetAudioReader adds/changes audio reader. Use this when you want to have interceptors of your audio

func (*DialogMedia) SetAudioWriter

func (d *DialogMedia) SetAudioWriter(r io.Writer)

SetAudioWriter adds/changes audio reader. Use this when you want to have pipelines of your audio

func (*DialogMedia) SetVideoReader added in v0.21.3

func (d *DialogMedia) SetVideoReader(r io.Reader)

SetVideoReader adds/changes video reader. Use this when you want to have interceptors of your video

func (*DialogMedia) SetVideoWriter added in v0.21.3

func (d *DialogMedia) SetVideoWriter(r io.Writer)

SetVideoWriter adds/changes video writer. Use this when you want to have pipelines of your video

func (*DialogMedia) StartRTP

func (d *DialogMedia) StartRTP(rw int8, dur time.Duration) error

func (*DialogMedia) StopRTP

func (d *DialogMedia) StopRTP(rw int8, dur time.Duration) error

func (*DialogMedia) VideoMediaSession added in v0.21.3

func (d *DialogMedia) VideoMediaSession() *media.MediaSession

VideoMediaSession returns video media session

func (*DialogMedia) VideoReader added in v0.21.3

func (d *DialogMedia) VideoReader() (io.Reader, error)

VideoReader gets current video reader. It MUST be called after Answer. Reading buffer should be equal or bigger of media.RTPBufSize

func (*DialogMedia) VideoWriter added in v0.21.3

func (d *DialogMedia) VideoWriter() (io.Writer, error)

VideoWriter gets current video writer. It MUST be called after Answer.

type DialogServerSession

type DialogServerSession struct {
	*sipgo.DialogServerSession

	// MediaSession *media.MediaSession
	DialogMedia
	// contains filtered or unexported fields
}

DialogServerSession represents inbound channel

func (*DialogServerSession) Answer

func (d *DialogServerSession) Answer() error

Answer creates media session and answers After this new AudioReader and AudioWriter are created for audio manipulation NOTE: Not final API

func (*DialogServerSession) AnswerLate

func (d *DialogServerSession) AnswerLate() error

AnswerLate does answer with Late offer.

func (*DialogServerSession) AnswerOptions

func (d *DialogServerSession) AnswerOptions(opt AnswerOptions) error

AnswerOptions allows to answer dialog with options Experimental

NOTE: API may change

func (*DialogServerSession) Close

func (d *DialogServerSession) Close() error

func (*DialogServerSession) DialogSIP

func (d *DialogServerSession) DialogSIP() *sipgo.Dialog

func (*DialogServerSession) FromUser

func (d *DialogServerSession) FromUser() string

func (*DialogServerSession) Hangup

func (d *DialogServerSession) Hangup(ctx context.Context) error

func (*DialogServerSession) Id

func (d *DialogServerSession) Id() string

func (*DialogServerSession) Progress deprecated

func (d *DialogServerSession) Progress() error

Progress sends 100 trying.

Deprecated: Use Trying. It will change behavior to 183 Sesion Progress in future releases

func (*DialogServerSession) ProgressMedia

func (d *DialogServerSession) ProgressMedia() error

ProgressMedia sends 183 Session Progress and creates early media

Experimental: Naming of API might change

func (*DialogServerSession) ReInvite

func (d *DialogServerSession) ReInvite(ctx context.Context) error

func (*DialogServerSession) ReadAck

func (*DialogServerSession) Refer

func (d *DialogServerSession) Refer(ctx context.Context, referTo sip.Uri, headers ...sip.Header) error

Refer tries todo refer (blind transfer) on call

func (*DialogServerSession) RemoteContact

func (d *DialogServerSession) RemoteContact() *sip.ContactHeader

func (*DialogServerSession) RespondSDP

func (d *DialogServerSession) RespondSDP(body []byte) error

func (*DialogServerSession) Ringing

func (d *DialogServerSession) Ringing() error

func (*DialogServerSession) ToUser

func (d *DialogServerSession) ToUser() string

User that was dialed

func (*DialogServerSession) Transport

func (d *DialogServerSession) Transport() string

func (*DialogServerSession) Trying

func (d *DialogServerSession) Trying() error

type DialogSession

type DialogSession interface {
	Id() string
	Context() context.Context
	Hangup(ctx context.Context) error
	Media() *DialogMedia
	DialogSIP() *sipgo.Dialog
	Do(ctx context.Context, req *sip.Request) (*sip.Response, error)
	Close() error
}

type DigestAuth

type DigestAuth struct {
	Username string
	Password string
	Realm    string
	Expire   time.Duration
}

type DigestAuthServer

type DigestAuthServer struct {
	// contains filtered or unexported fields
}

func NewDigestServer

func NewDigestServer() *DigestAuthServer

func (*DigestAuthServer) AuthorizeDialog

func (s *DigestAuthServer) AuthorizeDialog(d *DialogServerSession, auth DigestAuth) error

func (*DigestAuthServer) AuthorizeRequest

func (s *DigestAuthServer) AuthorizeRequest(req *sip.Request, auth DigestAuth) (res *sip.Response, err error)

AuthorizeRequest authorizes request. Returns SIP response that can be passed with error

func (*DigestAuthServer) Close

func (s *DigestAuthServer) Close()

type InviteClientOptions

type InviteClientOptions struct {
	Originator DialogSession
	OnResponse func(res *sip.Response) error
	// OnMediaUpdate called when media is changed.
	// NOTE: you should not block this call as it blocks response processing.
	OnMediaUpdate func(d *DialogMedia)
	OnRefer       func(referDialog *DialogClientSession)
	// For digest authentication
	Username string
	Password string

	// Custom headers to pass. DO NOT SET THIS to nil
	Headers []sip.Header
	// Stop on early media. ErrClientEarlyMedia will be returned
	EarlyMediaDetect bool
}

InviteClientOptions is passed on dialog client Invite with extra control over dialog

func (*InviteClientOptions) WithAnonymousCaller

func (o *InviteClientOptions) WithAnonymousCaller()

WithAnonymousCaller sets from user Anonymous per RFC

func (*InviteClientOptions) WithCaller

func (o *InviteClientOptions) WithCaller(displayName string, callerID string, host string)

WithCaller allows simpler way modifying caller

type InviteOptions

type InviteOptions struct {
	Originator DialogSession
	OnResponse func(res *sip.Response) error
	Transport  string
	// For digest authentication
	Username string
	Password string
	// Custom headers to pass. DO NOT SET THIS to nil
	Headers []sip.Header
	// WithVideo overrides MediaConfig.WithVideo for this specific call
	// If not set (nil), uses global MediaConfig.WithVideo
	// Use: WithVideo: &true (с видео) or WithVideo: &false (без видео)
	WithVideo *bool
}

type MediaConfig

type MediaConfig struct {
	Codecs []media.Codec
	// Currently supported Single. Check media.SRTP... constants
	// Experimental
	SecureRTPAlg uint16

	// AudioMode sets SDP mode for audio media (sendrecv, recvonly, sendonly)
	// If not set, defaults to sendrecv
	// Use constants: sdp.ModeSendrecv, sdp.ModeRecvonly, sdp.ModeSendonly
	AudioMode string
	// VideoMode sets SDP mode for video media (sendrecv, recvonly, sendonly)
	// If not set, defaults to sendrecv
	// Use constants: sdp.ModeSendrecv, sdp.ModeRecvonly, sdp.ModeSendonly
	VideoMode string

	// WithVideo controls whether to enable video stream
	// If true, video session will be created if video codecs are present in Codecs
	// If false (default), only audio will be used
	// Default: false (только аудио, видео нужно включить явно)
	// Для включения видео: установите WithVideo: true в MediaConfig или передайте в InviteOptions
	WithVideo bool
	// contains filtered or unexported fields
}

type MediaProps

type MediaProps struct {
	Codec media.Codec
	Laddr string
	Raddr string
}

type NewDialogOptions

type NewDialogOptions struct {
	// Transport or protocol that should be used
	Transport string
	// TransportID matches diago transport by ID instead protocol
	TransportID string

	// WithVideo overrides MediaConfig.WithVideo for this specific call
	// If not set (nil), uses global MediaConfig.WithVideo
	// Use: WithVideo: &true (с видео) or WithVideo: &false (без видео)
	WithVideo *bool
}

type RegisterOptions

type RegisterOptions struct {
	// Digest auth
	Username  string
	Password  string
	ProxyHost string

	// Expiry is for Expire header
	Expiry time.Duration
	// Retry interval is interval before next Register is sent
	RetryInterval time.Duration
	AllowHeaders  []string
}

type RegisterResponseError

type RegisterResponseError struct {
	RegisterReq *sip.Request
	RegisterRes *sip.Response

	Msg string
}

func (RegisterResponseError) Error

func (e RegisterResponseError) Error() string

func (*RegisterResponseError) StatusCode

func (e *RegisterResponseError) StatusCode() int

type RegisterTransaction

type RegisterTransaction struct {
	Origin *sip.Request
	// contains filtered or unexported fields
}

func (*RegisterTransaction) Qualify

func (t *RegisterTransaction) Qualify(ctx context.Context) error

func (*RegisterTransaction) QualifyLoop

func (t *RegisterTransaction) QualifyLoop(ctx context.Context) error

func (*RegisterTransaction) Register

func (t *RegisterTransaction) Register(ctx context.Context) error

func (*RegisterTransaction) Unregister

func (t *RegisterTransaction) Unregister(ctx context.Context) error

type ServeDialogFunc

type ServeDialogFunc func(d *DialogServerSession)

type Transport

type Transport struct {
	ID string

	// Transport must be udp,tcp or ws, or even forcing v4 like udp4, tcp4
	Transport string

	// BindHost sets IP to bind. If specified (not 0.0.0.0) it will be used same for media IP unless MediaExternalIP is set.
	BindHost string
	// BindPort sets port to bind. Leaving at 0 will use empheral port and apply on Contact addr
	BindPort int

	ExternalHost string // SIP signaling and media external addr
	ExternalPort int

	// MediaExternalIP changes SDP IP, by default it tries to use external host if it is IP defined
	MediaExternalIP net.IP
	// MediaSRTP offers SRTP. Values: 0-none, 1-sdes
	MediaSRTP int

	// In case TLS protocol
	TLSConf *tls.Config
	// Avoiding SIPS in contact uri https://datatracker.ietf.org/doc/html/rfc5630#section-3.3
	TLSURINoSIPS bool

	RewriteContact bool
	// contains filtered or unexported fields
}

Directories

Path Synopsis
183ringing command
SPDX-License-Identifier: MPL-2.0 SPDX-FileCopyrightText: Copyright (c) 2024, Emir Aganovic
SPDX-License-Identifier: MPL-2.0 SPDX-FileCopyrightText: Copyright (c) 2024, Emir Aganovic
bridge command
dtmf command
playback command
readmedia command
register command
wav_record command
SPDX-License-Identifier: MPL-2.0 SPDX-FileCopyrightText: Copyright (c) 2024, Emir Aganovic
SPDX-License-Identifier: MPL-2.0 SPDX-FileCopyrightText: Copyright (c) 2024, Emir Aganovic
sdp

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL