CreateAnswer starts the PeerConnection and generates the localDescription. nolint:cyclop
(options *AnswerOptions)
| 911 | // |
| 912 | //nolint:cyclop |
| 913 | func (pc *PeerConnection) CreateAnswer(options *AnswerOptions) (SessionDescription, error) { |
| 914 | useIdentity := pc.idpLoginURL != nil |
| 915 | remoteDesc := pc.RemoteDescription() |
| 916 | switch { |
| 917 | case remoteDesc == nil: |
| 918 | return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrNoRemoteDescription} |
| 919 | case useIdentity: |
| 920 | return SessionDescription{}, errIdentityProviderNotImplemented |
| 921 | case pc.isClosed.Load(): |
| 922 | return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrConnectionClosed} |
| 923 | case pc.signalingState.Get() != SignalingStateHaveRemoteOffer && |
| 924 | pc.signalingState.Get() != SignalingStateHaveLocalPranswer: |
| 925 | return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrIncorrectSignalingState} |
| 926 | } |
| 927 | |
| 928 | connectionRole := connectionRoleFromDtlsRole(pc.api.settingEngine.answeringDTLSRole) |
| 929 | if connectionRole == sdp.ConnectionRole(0) { |
| 930 | dtlsRole := dtlsRoleFromSDP(remoteDesc.parsed) |
| 931 | switch dtlsRole { |
| 932 | case DTLSRoleClient: |
| 933 | connectionRole = connectionRoleFromDtlsRole(DTLSRoleServer) |
| 934 | case DTLSRoleServer: |
| 935 | connectionRole = connectionRoleFromDtlsRole(DTLSRoleClient) |
| 936 | default: |
| 937 | connectionRole = connectionRoleFromDtlsRole(defaultDtlsRoleAnswer) |
| 938 | } |
| 939 | |
| 940 | // If one of the agents is lite and the other one is not, the lite agent must be the controlled agent. |
| 941 | // If both or neither agents are lite the offering agent is controlling. |
| 942 | // RFC 8445 S6.1.1 |
| 943 | if isIceLiteSet(remoteDesc.parsed) && !pc.api.settingEngine.candidates.ICELite { |
| 944 | connectionRole = connectionRoleFromDtlsRole(DTLSRoleServer) |
| 945 | } |
| 946 | } |
| 947 | pc.mu.Lock() |
| 948 | defer pc.mu.Unlock() |
| 949 | |
| 950 | descr, err := pc.generateMatchedSDP( |
| 951 | pc.rtpTransceivers, |
| 952 | useIdentity, |
| 953 | false, /*includeUnmatched */ |
| 954 | connectionRole, |
| 955 | pc.api.settingEngine.ignoreRidPauseForRecv, |
| 956 | ) |
| 957 | if err != nil { |
| 958 | return SessionDescription{}, err |
| 959 | } |
| 960 | |
| 961 | if options != nil && options.ICETricklingSupported { |
| 962 | descr.WithICETrickleAdvertised() |
| 963 | } |
| 964 | if pc.api.settingEngine.renomination.enabled { |
| 965 | descr.WithICERenomination() |
| 966 | } |
| 967 | |
| 968 | updateSDPOrigin(&pc.sdpOrigin, descr) |
| 969 | sdpBytes, err := descr.Marshal() |
| 970 | if err != nil { |