| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
- // SPDX-License-Identifier: MIT
- package webrtc
- import (
- "fmt"
- "github.com/pion/ice/v2"
- )
- // ICECandidate represents a ice candidate
- type ICECandidate struct {
- statsID string
- Foundation string `json:"foundation"`
- Priority uint32 `json:"priority"`
- Address string `json:"address"`
- Protocol ICEProtocol `json:"protocol"`
- Port uint16 `json:"port"`
- Typ ICECandidateType `json:"type"`
- Component uint16 `json:"component"`
- RelatedAddress string `json:"relatedAddress"`
- RelatedPort uint16 `json:"relatedPort"`
- TCPType string `json:"tcpType"`
- }
- // Conversion for package ice
- func newICECandidatesFromICE(iceCandidates []ice.Candidate) ([]ICECandidate, error) {
- candidates := []ICECandidate{}
- for _, i := range iceCandidates {
- c, err := newICECandidateFromICE(i)
- if err != nil {
- return nil, err
- }
- candidates = append(candidates, c)
- }
- return candidates, nil
- }
- func newICECandidateFromICE(i ice.Candidate) (ICECandidate, error) {
- typ, err := convertTypeFromICE(i.Type())
- if err != nil {
- return ICECandidate{}, err
- }
- protocol, err := NewICEProtocol(i.NetworkType().NetworkShort())
- if err != nil {
- return ICECandidate{}, err
- }
- c := ICECandidate{
- statsID: i.ID(),
- Foundation: i.Foundation(),
- Priority: i.Priority(),
- Address: i.Address(),
- Protocol: protocol,
- Port: uint16(i.Port()),
- Component: i.Component(),
- Typ: typ,
- TCPType: i.TCPType().String(),
- }
- if i.RelatedAddress() != nil {
- c.RelatedAddress = i.RelatedAddress().Address
- c.RelatedPort = uint16(i.RelatedAddress().Port)
- }
- return c, nil
- }
- func (c ICECandidate) toICE() (ice.Candidate, error) {
- candidateID := c.statsID
- switch c.Typ {
- case ICECandidateTypeHost:
- config := ice.CandidateHostConfig{
- CandidateID: candidateID,
- Network: c.Protocol.String(),
- Address: c.Address,
- Port: int(c.Port),
- Component: c.Component,
- TCPType: ice.NewTCPType(c.TCPType),
- Foundation: c.Foundation,
- Priority: c.Priority,
- }
- return ice.NewCandidateHost(&config)
- case ICECandidateTypeSrflx:
- config := ice.CandidateServerReflexiveConfig{
- CandidateID: candidateID,
- Network: c.Protocol.String(),
- Address: c.Address,
- Port: int(c.Port),
- Component: c.Component,
- Foundation: c.Foundation,
- Priority: c.Priority,
- RelAddr: c.RelatedAddress,
- RelPort: int(c.RelatedPort),
- }
- return ice.NewCandidateServerReflexive(&config)
- case ICECandidateTypePrflx:
- config := ice.CandidatePeerReflexiveConfig{
- CandidateID: candidateID,
- Network: c.Protocol.String(),
- Address: c.Address,
- Port: int(c.Port),
- Component: c.Component,
- Foundation: c.Foundation,
- Priority: c.Priority,
- RelAddr: c.RelatedAddress,
- RelPort: int(c.RelatedPort),
- }
- return ice.NewCandidatePeerReflexive(&config)
- case ICECandidateTypeRelay:
- config := ice.CandidateRelayConfig{
- CandidateID: candidateID,
- Network: c.Protocol.String(),
- Address: c.Address,
- Port: int(c.Port),
- Component: c.Component,
- Foundation: c.Foundation,
- Priority: c.Priority,
- RelAddr: c.RelatedAddress,
- RelPort: int(c.RelatedPort),
- }
- return ice.NewCandidateRelay(&config)
- default:
- return nil, fmt.Errorf("%w: %s", errICECandidateTypeUnknown, c.Typ)
- }
- }
- func convertTypeFromICE(t ice.CandidateType) (ICECandidateType, error) {
- switch t {
- case ice.CandidateTypeHost:
- return ICECandidateTypeHost, nil
- case ice.CandidateTypeServerReflexive:
- return ICECandidateTypeSrflx, nil
- case ice.CandidateTypePeerReflexive:
- return ICECandidateTypePrflx, nil
- case ice.CandidateTypeRelay:
- return ICECandidateTypeRelay, nil
- default:
- return ICECandidateType(t), fmt.Errorf("%w: %s", errICECandidateTypeUnknown, t)
- }
- }
- func (c ICECandidate) String() string {
- ic, err := c.toICE()
- if err != nil {
- return fmt.Sprintf("%#v failed to convert to ICE: %s", c, err)
- }
- return ic.String()
- }
- // ToJSON returns an ICECandidateInit
- // as indicated by the spec https://w3c.github.io/webrtc-pc/#dom-rtcicecandidate-tojson
- func (c ICECandidate) ToJSON() ICECandidateInit {
- zeroVal := uint16(0)
- emptyStr := ""
- candidateStr := ""
- candidate, err := c.toICE()
- if err == nil {
- candidateStr = candidate.Marshal()
- }
- return ICECandidateInit{
- Candidate: fmt.Sprintf("candidate:%s", candidateStr),
- SDPMid: &emptyStr,
- SDPMLineIndex: &zeroVal,
- }
- }
|