github.com/pion/webrtc/v4@v4.0.1/ortc_test.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  //go:build !js
     5  // +build !js
     6  
     7  package webrtc
     8  
     9  import (
    10  	"github.com/pion/webrtc/v4/internal/util"
    11  )
    12  
    13  type testORTCStack struct {
    14  	api      *API
    15  	gatherer *ICEGatherer
    16  	ice      *ICETransport
    17  	dtls     *DTLSTransport
    18  	sctp     *SCTPTransport
    19  }
    20  
    21  func (s *testORTCStack) setSignal(sig *testORTCSignal, isOffer bool) error {
    22  	iceRole := ICERoleControlled
    23  	if isOffer {
    24  		iceRole = ICERoleControlling
    25  	}
    26  
    27  	err := s.ice.SetRemoteCandidates(sig.ICECandidates)
    28  	if err != nil {
    29  		return err
    30  	}
    31  
    32  	// Start the ICE transport
    33  	err = s.ice.Start(nil, sig.ICEParameters, &iceRole)
    34  	if err != nil {
    35  		return err
    36  	}
    37  
    38  	// Start the DTLS transport
    39  	err = s.dtls.Start(sig.DTLSParameters)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	// Start the SCTP transport
    45  	err = s.sctp.Start(sig.SCTPCapabilities)
    46  	if err != nil {
    47  		return err
    48  	}
    49  
    50  	return nil
    51  }
    52  
    53  func (s *testORTCStack) getSignal() (*testORTCSignal, error) {
    54  	gatherFinished := make(chan struct{})
    55  	s.gatherer.OnLocalCandidate(func(i *ICECandidate) {
    56  		if i == nil {
    57  			close(gatherFinished)
    58  		}
    59  	})
    60  
    61  	if err := s.gatherer.Gather(); err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	<-gatherFinished
    66  	iceCandidates, err := s.gatherer.GetLocalCandidates()
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	iceParams, err := s.gatherer.GetLocalParameters()
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	dtlsParams, err := s.dtls.GetLocalParameters()
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  
    81  	sctpCapabilities := s.sctp.GetCapabilities()
    82  
    83  	return &testORTCSignal{
    84  		ICECandidates:    iceCandidates,
    85  		ICEParameters:    iceParams,
    86  		DTLSParameters:   dtlsParams,
    87  		SCTPCapabilities: sctpCapabilities,
    88  	}, nil
    89  }
    90  
    91  func (s *testORTCStack) close() error {
    92  	var closeErrs []error
    93  
    94  	if err := s.sctp.Stop(); err != nil {
    95  		closeErrs = append(closeErrs, err)
    96  	}
    97  
    98  	if err := s.ice.Stop(); err != nil {
    99  		closeErrs = append(closeErrs, err)
   100  	}
   101  
   102  	return util.FlattenErrs(closeErrs)
   103  }
   104  
   105  type testORTCSignal struct {
   106  	ICECandidates    []ICECandidate
   107  	ICEParameters    ICEParameters
   108  	DTLSParameters   DTLSParameters
   109  	SCTPCapabilities SCTPCapabilities
   110  }
   111  
   112  func newORTCPair() (stackA *testORTCStack, stackB *testORTCStack, err error) {
   113  	sa, err := newORTCStack()
   114  	if err != nil {
   115  		return nil, nil, err
   116  	}
   117  
   118  	sb, err := newORTCStack()
   119  	if err != nil {
   120  		return nil, nil, err
   121  	}
   122  
   123  	return sa, sb, nil
   124  }
   125  
   126  func newORTCStack() (*testORTCStack, error) {
   127  	// Create an API object
   128  	api := NewAPI()
   129  
   130  	// Create the ICE gatherer
   131  	gatherer, err := api.NewICEGatherer(ICEGatherOptions{})
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  
   136  	// Construct the ICE transport
   137  	ice := api.NewICETransport(gatherer)
   138  
   139  	// Construct the DTLS transport
   140  	dtls, err := api.NewDTLSTransport(ice, nil)
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  
   145  	// Construct the SCTP transport
   146  	sctp := api.NewSCTPTransport(dtls)
   147  
   148  	return &testORTCStack{
   149  		api:      api,
   150  		gatherer: gatherer,
   151  		ice:      ice,
   152  		dtls:     dtls,
   153  		sctp:     sctp,
   154  	}, nil
   155  }
   156  
   157  func signalORTCPair(stackA *testORTCStack, stackB *testORTCStack) error {
   158  	sigA, err := stackA.getSignal()
   159  	if err != nil {
   160  		return err
   161  	}
   162  	sigB, err := stackB.getSignal()
   163  	if err != nil {
   164  		return err
   165  	}
   166  
   167  	a := make(chan error)
   168  	b := make(chan error)
   169  
   170  	go func() {
   171  		a <- stackB.setSignal(sigA, false)
   172  	}()
   173  
   174  	go func() {
   175  		b <- stackA.setSignal(sigB, true)
   176  	}()
   177  
   178  	errA := <-a
   179  	errB := <-b
   180  
   181  	closeErrs := []error{errA, errB}
   182  
   183  	return util.FlattenErrs(closeErrs)
   184  }