blob: 780dd93dd533a5203a5e9fef66ccbf6dcf386675 [file] [log] [blame]
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00001/*
2 * Copyright 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef PC_SDP_OFFER_ANSWER_H_
12#define PC_SDP_OFFER_ANSWER_H_
13
14#include <map>
15#include <memory>
16#include <set>
17#include <string>
18#include <utility>
19#include <vector>
20
21#include "api/jsep_ice_candidate.h"
22#include "api/peer_connection_interface.h"
23#include "api/transport/data_channel_transport_interface.h"
24#include "api/turn_customizer.h"
25#include "pc/data_channel_controller.h"
26#include "pc/ice_server_parsing.h"
27#include "pc/jsep_transport_controller.h"
28#include "pc/peer_connection_factory.h"
29#include "pc/peer_connection_internal.h"
30#include "pc/rtc_stats_collector.h"
31#include "pc/rtp_sender.h"
32#include "pc/rtp_transceiver.h"
33#include "pc/sctp_transport.h"
34#include "pc/stats_collector.h"
35#include "pc/stream_collection.h"
36#include "pc/webrtc_session_description_factory.h"
37#include "rtc_base/experiments/field_trial_parser.h"
38#include "rtc_base/operations_chain.h"
39#include "rtc_base/race_checker.h"
40#include "rtc_base/unique_id_generator.h"
41#include "rtc_base/weak_ptr.h"
42
43namespace webrtc {
44
45class MediaStreamObserver;
46class PeerConnection;
47class VideoRtpReceiver;
48class RtcEventLog;
49
50// SdpOfferAnswerHandler is a component
51// of the PeerConnection object as defined
52// by the PeerConnectionInterface API surface.
53// The class is responsible for the following:
54// - Parsing and interpreting SDP.
55// - Generating offers and answers based on the current state.
56// This class lives on the signaling thread.
57class SdpOfferAnswerHandler {
58 public:
59 explicit SdpOfferAnswerHandler(PeerConnection* pc);
60 ~SdpOfferAnswerHandler();
61
62 void SetSessionDescFactory(
63 std::unique_ptr<WebRtcSessionDescriptionFactory> factory) {
64 RTC_DCHECK_RUN_ON(signaling_thread());
65 webrtc_session_desc_factory_ = std::move(factory);
66 }
67 void ResetSessionDescFactory() {
68 RTC_DCHECK_RUN_ON(signaling_thread());
69 webrtc_session_desc_factory_.reset();
70 }
71 const WebRtcSessionDescriptionFactory* webrtc_session_desc_factory() const {
72 RTC_DCHECK_RUN_ON(signaling_thread());
73 return webrtc_session_desc_factory_.get();
74 }
75
76 // Change signaling state to Closed, and perform appropriate actions.
77 void Close();
78
79 // Called as part of destroying the owning PeerConnection.
80 void PrepareForShutdown();
81
82 PeerConnectionInterface::SignalingState signaling_state() const;
83
84 const SessionDescriptionInterface* local_description() const;
85 const SessionDescriptionInterface* remote_description() const;
86 const SessionDescriptionInterface* current_local_description() const;
87 const SessionDescriptionInterface* current_remote_description() const;
88 const SessionDescriptionInterface* pending_local_description() const;
89 const SessionDescriptionInterface* pending_remote_description() const;
90
91 void RestartIce();
92
93 // JSEP01
94 void CreateOffer(
95 CreateSessionDescriptionObserver* observer,
96 const PeerConnectionInterface::RTCOfferAnswerOptions& options);
97 void CreateAnswer(
98 CreateSessionDescriptionObserver* observer,
99 const PeerConnectionInterface::RTCOfferAnswerOptions& options);
100
101 void SetLocalDescription(
102 std::unique_ptr<SessionDescriptionInterface> desc,
103 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer);
104 void SetLocalDescription(
105 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer);
106 void SetLocalDescription(SetSessionDescriptionObserver* observer,
107 SessionDescriptionInterface* desc);
108 void SetLocalDescription(SetSessionDescriptionObserver* observer);
109
110 void SetRemoteDescription(
111 std::unique_ptr<SessionDescriptionInterface> desc,
112 rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer);
113 void SetRemoteDescription(SetSessionDescriptionObserver* observer,
114 SessionDescriptionInterface* desc);
115
116 PeerConnectionInterface::RTCConfiguration GetConfiguration();
117 RTCError SetConfiguration(
118 const PeerConnectionInterface::RTCConfiguration& configuration);
119 bool AddIceCandidate(const IceCandidateInterface* candidate);
120 void AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate,
121 std::function<void(RTCError)> callback);
122 bool RemoveIceCandidates(const std::vector<cricket::Candidate>& candidates);
123 // Adds a locally generated candidate to the local description.
124 void AddLocalIceCandidate(const JsepIceCandidate* candidate);
125 void RemoveLocalIceCandidates(
126 const std::vector<cricket::Candidate>& candidates);
127 bool ShouldFireNegotiationNeededEvent(uint32_t event_id);
128
129 absl::optional<bool> is_caller();
130 bool HasNewIceCredentials();
131 bool IceRestartPending(const std::string& content_name) const;
132 void UpdateNegotiationNeeded();
133
134 private:
135 class ImplicitCreateSessionDescriptionObserver;
136 friend class ImplicitCreateSessionDescriptionObserver;
137 class SetSessionDescriptionObserverAdapter;
138 friend class SetSessionDescriptionObserverAdapter;
139
140 // Represents the [[LocalIceCredentialsToReplace]] internal slot in the spec.
141 // It makes the next CreateOffer() produce new ICE credentials even if
142 // RTCOfferAnswerOptions::ice_restart is false.
143 // https://w3c.github.io/webrtc-pc/#dfn-localufragstoreplace
144 // TODO(hbos): When JsepTransportController/JsepTransport supports rollback,
145 // move this type of logic to JsepTransportController/JsepTransport.
146 class LocalIceCredentialsToReplace;
147
148 rtc::Thread* signaling_thread() const;
149 // Non-const versions of local_description()/remote_description(), for use
150 // internally.
151 SessionDescriptionInterface* mutable_local_description()
152 RTC_RUN_ON(signaling_thread()) {
153 return pending_local_description_ ? pending_local_description_.get()
154 : current_local_description_.get();
155 }
156 SessionDescriptionInterface* mutable_remote_description()
157 RTC_RUN_ON(signaling_thread()) {
158 return pending_remote_description_ ? pending_remote_description_.get()
159 : current_remote_description_.get();
160 }
161
162 // Synchronous implementations of SetLocalDescription/SetRemoteDescription
163 // that return an RTCError instead of invoking a callback.
164 RTCError ApplyLocalDescription(
165 std::unique_ptr<SessionDescriptionInterface> desc);
166 RTCError ApplyRemoteDescription(
167 std::unique_ptr<SessionDescriptionInterface> desc);
168
169 // Implementation of the offer/answer exchange operations. These are chained
170 // onto the |operations_chain_| when the public CreateOffer(), CreateAnswer(),
171 // SetLocalDescription() and SetRemoteDescription() methods are invoked.
172 void DoCreateOffer(
173 const PeerConnectionInterface::RTCOfferAnswerOptions& options,
174 rtc::scoped_refptr<CreateSessionDescriptionObserver> observer);
175 void DoCreateAnswer(
176 const PeerConnectionInterface::RTCOfferAnswerOptions& options,
177 rtc::scoped_refptr<CreateSessionDescriptionObserver> observer);
178 void DoSetLocalDescription(
179 std::unique_ptr<SessionDescriptionInterface> desc,
180 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer);
181 void DoSetRemoteDescription(
182 std::unique_ptr<SessionDescriptionInterface> desc,
183 rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer);
184
185 // Update the state, signaling if necessary.
186 void ChangeSignalingState(
187 PeerConnectionInterface::SignalingState signaling_state);
188
189 RTCError UpdateSessionState(SdpType type,
190 cricket::ContentSource source,
191 const cricket::SessionDescription* description);
192
193 bool IsUnifiedPlan() const RTC_RUN_ON(signaling_thread());
194
195 // | desc_type | is the type of the description that caused the rollback.
196 RTCError Rollback(SdpType desc_type);
197 void OnOperationsChainEmpty();
198
199 // Runs the algorithm **set the associated remote streams** specified in
200 // https://w3c.github.io/webrtc-pc/#set-associated-remote-streams.
201 void SetAssociatedRemoteStreams(
202 rtc::scoped_refptr<RtpReceiverInternal> receiver,
203 const std::vector<std::string>& stream_ids,
204 std::vector<rtc::scoped_refptr<MediaStreamInterface>>* added_streams,
205 std::vector<rtc::scoped_refptr<MediaStreamInterface>>* removed_streams);
206
207 bool CheckIfNegotiationIsNeeded();
208 void GenerateNegotiationNeededEvent();
209 // Helper method which verifies SDP.
210 RTCError ValidateSessionDescription(const SessionDescriptionInterface* sdesc,
211 cricket::ContentSource source)
212 RTC_RUN_ON(signaling_thread());
213
214 // Updates the local RtpTransceivers according to the JSEP rules. Called as
215 // part of setting the local/remote description.
216 RTCError UpdateTransceiversAndDataChannels(
217 cricket::ContentSource source,
218 const SessionDescriptionInterface& new_session,
219 const SessionDescriptionInterface* old_local_description,
220 const SessionDescriptionInterface* old_remote_description);
221
222 // Associate the given transceiver according to the JSEP rules.
223 RTCErrorOr<
224 rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
225 AssociateTransceiver(cricket::ContentSource source,
226 SdpType type,
227 size_t mline_index,
228 const cricket::ContentInfo& content,
229 const cricket::ContentInfo* old_local_content,
230 const cricket::ContentInfo* old_remote_content)
231 RTC_RUN_ON(signaling_thread());
232
233 // If the BUNDLE policy is max-bundle, then we know for sure that all
234 // transports will be bundled from the start. This method returns the BUNDLE
235 // group if that's the case, or null if BUNDLE will be negotiated later. An
236 // error is returned if max-bundle is specified but the session description
237 // does not have a BUNDLE group.
238 RTCErrorOr<const cricket::ContentGroup*> GetEarlyBundleGroup(
239 const cricket::SessionDescription& desc) const
240 RTC_RUN_ON(signaling_thread());
241
242 // Either creates or destroys the transceiver's BaseChannel according to the
243 // given media section.
244 RTCError UpdateTransceiverChannel(
245 rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
246 transceiver,
247 const cricket::ContentInfo& content,
248 const cricket::ContentGroup* bundle_group) RTC_RUN_ON(signaling_thread());
249
250 // Either creates or destroys the local data channel according to the given
251 // media section.
252 RTCError UpdateDataChannel(cricket::ContentSource source,
253 const cricket::ContentInfo& content,
254 const cricket::ContentGroup* bundle_group)
255 RTC_RUN_ON(signaling_thread());
256
257 // ===================================================================
258
259 PeerConnection* const pc_;
260
261 std::unique_ptr<WebRtcSessionDescriptionFactory> webrtc_session_desc_factory_
262 RTC_GUARDED_BY(signaling_thread());
263
264 std::unique_ptr<SessionDescriptionInterface> current_local_description_
265 RTC_GUARDED_BY(signaling_thread());
266 std::unique_ptr<SessionDescriptionInterface> pending_local_description_
267 RTC_GUARDED_BY(signaling_thread());
268 std::unique_ptr<SessionDescriptionInterface> current_remote_description_
269 RTC_GUARDED_BY(signaling_thread());
270 std::unique_ptr<SessionDescriptionInterface> pending_remote_description_
271 RTC_GUARDED_BY(signaling_thread());
272
273 PeerConnectionInterface::SignalingState signaling_state_
274 RTC_GUARDED_BY(signaling_thread()) = PeerConnectionInterface::kStable;
275
276 // Whether this peer is the caller. Set when the local description is applied.
277 absl::optional<bool> is_caller_ RTC_GUARDED_BY(signaling_thread());
278
279 // The operations chain is used by the offer/answer exchange methods to ensure
280 // they are executed in the right order. For example, if
281 // SetRemoteDescription() is invoked while CreateOffer() is still pending, the
282 // SRD operation will not start until CreateOffer() has completed. See
283 // https://w3c.github.io/webrtc-pc/#dfn-operations-chain.
284 rtc::scoped_refptr<rtc::OperationsChain> operations_chain_
285 RTC_GUARDED_BY(signaling_thread());
286
287 // List of content names for which the remote side triggered an ICE restart.
288 std::set<std::string> pending_ice_restarts_
289 RTC_GUARDED_BY(signaling_thread());
290
291 std::unique_ptr<LocalIceCredentialsToReplace>
292 local_ice_credentials_to_replace_ RTC_GUARDED_BY(signaling_thread());
293
294 bool remote_peer_supports_msid_ RTC_GUARDED_BY(signaling_thread()) = false;
295 bool is_negotiation_needed_ RTC_GUARDED_BY(signaling_thread()) = false;
296 uint32_t negotiation_needed_event_id_ = 0;
297 bool update_negotiation_needed_on_empty_chain_
298 RTC_GUARDED_BY(signaling_thread()) = false;
299
300 // In Unified Plan, if we encounter remote SDP that does not contain an a=msid
301 // line we create and use a stream with a random ID for our receivers. This is
302 // to support legacy endpoints that do not support the a=msid attribute (as
303 // opposed to streamless tracks with "a=msid:-").
304 rtc::scoped_refptr<MediaStreamInterface> missing_msid_default_stream_
305 RTC_GUARDED_BY(signaling_thread());
306
307 rtc::WeakPtrFactory<SdpOfferAnswerHandler> weak_ptr_factory_
308 RTC_GUARDED_BY(signaling_thread());
309};
310
311} // namespace webrtc
312
313#endif // PC_SDP_OFFER_ANSWER_H_