Files
webrtc/icegatherer.go
Sean DuBois 1cdfc10c84 Mass replace pions -> pion
Pions organization was renamed to pion
2019-04-04 15:32:03 -07:00

141 lines
3.2 KiB
Go

// +build !js
package webrtc
import (
"errors"
"sync"
"github.com/pion/ice"
)
// The ICEGatherer gathers local host, server reflexive and relay
// candidates, as well as enabling the retrieval of local Interactive
// Connectivity Establishment (ICE) parameters which can be
// exchanged in signaling.
type ICEGatherer struct {
lock sync.RWMutex
state ICEGathererState
validatedServers []*ice.URL
agent *ice.Agent
api *API
}
// NewICEGatherer creates a new NewICEGatherer.
// This constructor is part of the ORTC API. It is not
// meant to be used together with the basic WebRTC API.
func (api *API) NewICEGatherer(opts ICEGatherOptions) (*ICEGatherer, error) {
var validatedServers []*ice.URL
if len(opts.ICEServers) > 0 {
for _, server := range opts.ICEServers {
url, err := server.validate()
if err != nil {
return nil, err
}
validatedServers = append(validatedServers, url...)
}
}
return &ICEGatherer{
state: ICEGathererStateNew,
validatedServers: validatedServers,
api: api,
}, nil
}
// State indicates the current state of the ICE gatherer.
func (g *ICEGatherer) State() ICEGathererState {
g.lock.RLock()
defer g.lock.RUnlock()
return g.state
}
// Gather ICE candidates.
func (g *ICEGatherer) Gather() error {
g.lock.Lock()
defer g.lock.Unlock()
config := &ice.AgentConfig{
Urls: g.validatedServers,
PortMin: g.api.settingEngine.ephemeralUDP.PortMin,
PortMax: g.api.settingEngine.ephemeralUDP.PortMax,
ConnectionTimeout: g.api.settingEngine.timeout.ICEConnection,
KeepaliveInterval: g.api.settingEngine.timeout.ICEKeepalive,
LoggerFactory: g.api.settingEngine.LoggerFactory,
}
requestedNetworkTypes := g.api.settingEngine.candidates.ICENetworkTypes
if len(requestedNetworkTypes) == 0 {
requestedNetworkTypes = supportedNetworkTypes
}
for _, typ := range requestedNetworkTypes {
config.NetworkTypes = append(config.NetworkTypes, ice.NetworkType(typ))
}
agent, err := ice.NewAgent(config)
if err != nil {
return err
}
g.agent = agent
g.state = ICEGathererStateComplete
return nil
}
// Close prunes all local candidates, and closes the ports.
func (g *ICEGatherer) Close() error {
g.lock.Lock()
defer g.lock.Unlock()
if g.agent == nil {
return nil
}
err := g.agent.Close()
if err != nil {
return err
}
g.agent = nil
return nil
}
// GetLocalParameters returns the ICE parameters of the ICEGatherer.
func (g *ICEGatherer) GetLocalParameters() (ICEParameters, error) {
g.lock.RLock()
defer g.lock.RUnlock()
if g.agent == nil {
return ICEParameters{}, errors.New("gatherer not started")
}
frag, pwd := g.agent.GetLocalUserCredentials()
return ICEParameters{
UsernameFragment: frag,
Password: pwd,
ICELite: false,
}, nil
}
// GetLocalCandidates returns the sequence of valid local candidates associated with the ICEGatherer.
func (g *ICEGatherer) GetLocalCandidates() ([]ICECandidate, error) {
g.lock.RLock()
defer g.lock.RUnlock()
if g.agent == nil {
return nil, errors.New("gatherer not started")
}
iceCandidates, err := g.agent.GetLocalCandidates()
if err != nil {
return nil, err
}
return newICECandidatesFromICE(iceCandidates)
}