blob: aab24cf0654b01054355842d54c22ea470c2c3d7 [file] [log] [blame]
wu@webrtc.org91053e72013-08-10 07:18:04 +00001/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 * Copyright 2013 Google Inc.
wu@webrtc.org91053e72013-08-10 07:18:04 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
29
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000030#include "talk/app/webrtc/dtlsidentitystore.h"
wu@webrtc.org91053e72013-08-10 07:18:04 +000031#include "talk/app/webrtc/jsep.h"
32#include "talk/app/webrtc/jsepsessiondescription.h"
33#include "talk/app/webrtc/mediaconstraintsinterface.h"
34#include "talk/app/webrtc/mediastreamsignaling.h"
35#include "talk/app/webrtc/webrtcsession.h"
36
wu@webrtc.org364f2042013-11-20 21:49:41 +000037using cricket::MediaSessionOptions;
38
wu@webrtc.org91053e72013-08-10 07:18:04 +000039namespace webrtc {
wu@webrtc.org91053e72013-08-10 07:18:04 +000040namespace {
wu@webrtc.org91053e72013-08-10 07:18:04 +000041static const char kFailedDueToIdentityFailed[] =
42 " failed because DTLS identity request failed";
43
wu@webrtc.org91053e72013-08-10 07:18:04 +000044static const uint64 kInitSessionVersion = 2;
45
wu@webrtc.org364f2042013-11-20 21:49:41 +000046static bool CompareStream(const MediaSessionOptions::Stream& stream1,
47 const MediaSessionOptions::Stream& stream2) {
48 return stream1.id < stream2.id;
wu@webrtc.org91053e72013-08-10 07:18:04 +000049}
50
wu@webrtc.org364f2042013-11-20 21:49:41 +000051static bool SameId(const MediaSessionOptions::Stream& stream1,
52 const MediaSessionOptions::Stream& stream2) {
53 return stream1.id == stream2.id;
wu@webrtc.org91053e72013-08-10 07:18:04 +000054}
55
56// Checks if each Stream within the |streams| has unique id.
wu@webrtc.org364f2042013-11-20 21:49:41 +000057static bool ValidStreams(const MediaSessionOptions::Streams& streams) {
58 MediaSessionOptions::Streams sorted_streams = streams;
wu@webrtc.org91053e72013-08-10 07:18:04 +000059 std::sort(sorted_streams.begin(), sorted_streams.end(), CompareStream);
wu@webrtc.org364f2042013-11-20 21:49:41 +000060 MediaSessionOptions::Streams::iterator it =
wu@webrtc.org91053e72013-08-10 07:18:04 +000061 std::adjacent_find(sorted_streams.begin(), sorted_streams.end(),
62 SameId);
wu@webrtc.org364f2042013-11-20 21:49:41 +000063 return it == sorted_streams.end();
wu@webrtc.org91053e72013-08-10 07:18:04 +000064}
65
66enum {
67 MSG_CREATE_SESSIONDESCRIPTION_SUCCESS,
68 MSG_CREATE_SESSIONDESCRIPTION_FAILED,
69 MSG_GENERATE_IDENTITY,
70};
71
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000072struct CreateSessionDescriptionMsg : public rtc::MessageData {
wu@webrtc.org91053e72013-08-10 07:18:04 +000073 explicit CreateSessionDescriptionMsg(
74 webrtc::CreateSessionDescriptionObserver* observer)
75 : observer(observer) {
76 }
77
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000078 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer;
wu@webrtc.org91053e72013-08-10 07:18:04 +000079 std::string error;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000080 rtc::scoped_ptr<webrtc::SessionDescriptionInterface> description;
wu@webrtc.org91053e72013-08-10 07:18:04 +000081};
wu@webrtc.org91053e72013-08-10 07:18:04 +000082} // namespace
83
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000084void WebRtcIdentityRequestObserver::OnFailure(int error) {
85 SignalRequestFailed(error);
86}
87
88void WebRtcIdentityRequestObserver::OnSuccess(
89 const std::string& der_cert, const std::string& der_private_key) {
90 std::string pem_cert = rtc::SSLIdentity::DerToPem(
91 rtc::kPemTypeCertificate,
92 reinterpret_cast<const unsigned char*>(der_cert.data()),
93 der_cert.length());
94 std::string pem_key = rtc::SSLIdentity::DerToPem(
95 rtc::kPemTypeRsaPrivateKey,
96 reinterpret_cast<const unsigned char*>(der_private_key.data()),
97 der_private_key.length());
98 rtc::SSLIdentity* identity =
99 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert);
100 SignalIdentityReady(identity);
101}
102
103void WebRtcIdentityRequestObserver::OnSuccessWithIdentityObj(
104 rtc::scoped_ptr<rtc::SSLIdentity> identity) {
105 SignalIdentityReady(identity.release());
106}
107
wu@webrtc.org91053e72013-08-10 07:18:04 +0000108// static
109void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription(
110 const SessionDescriptionInterface* source_desc,
111 SessionDescriptionInterface* dest_desc) {
112 if (!source_desc)
113 return;
114 for (size_t m = 0; m < source_desc->number_of_mediasections() &&
115 m < dest_desc->number_of_mediasections(); ++m) {
116 const IceCandidateCollection* source_candidates =
117 source_desc->candidates(m);
118 const IceCandidateCollection* dest_candidates = dest_desc->candidates(m);
119 for (size_t n = 0; n < source_candidates->count(); ++n) {
120 const IceCandidateInterface* new_candidate = source_candidates->at(n);
121 if (!dest_candidates->HasCandidate(new_candidate))
122 dest_desc->AddCandidate(source_candidates->at(n));
123 }
124 }
125}
126
127WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000128 rtc::Thread* signaling_thread,
wu@webrtc.org91053e72013-08-10 07:18:04 +0000129 cricket::ChannelManager* channel_manager,
130 MediaStreamSignaling* mediastream_signaling,
131 DTLSIdentityServiceInterface* dtls_identity_service,
132 WebRtcSession* session,
133 const std::string& session_id,
134 cricket::DataChannelType dct,
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +0000135 bool dtls_enabled)
wu@webrtc.org91053e72013-08-10 07:18:04 +0000136 : signaling_thread_(signaling_thread),
137 mediastream_signaling_(mediastream_signaling),
138 session_desc_factory_(channel_manager, &transport_desc_factory_),
139 // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp
140 // as the session id and session version. To simplify, it should be fine
141 // to just use a random number as session id and start version from
142 // |kInitSessionVersion|.
143 session_version_(kInitSessionVersion),
144 identity_service_(dtls_identity_service),
145 session_(session),
146 session_id_(session_id),
147 data_channel_type_(dct),
148 identity_request_state_(IDENTITY_NOT_NEEDED) {
jlmiller@webrtc.org804eb462015-02-20 02:20:03 +0000149 transport_desc_factory_.set_protocol(cricket::ICEPROTO_RFC5245);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000150 session_desc_factory_.set_add_legacy_streams(false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000151 // SRTP-SDES is disabled if DTLS is on.
152 SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000153
wu@webrtc.org364f2042013-11-20 21:49:41 +0000154 if (!dtls_enabled) {
155 return;
156 }
wu@webrtc.org91053e72013-08-10 07:18:04 +0000157
wu@webrtc.org364f2042013-11-20 21:49:41 +0000158 if (identity_service_.get()) {
159 identity_request_observer_ =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000160 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000161
wu@webrtc.org364f2042013-11-20 21:49:41 +0000162 identity_request_observer_->SignalRequestFailed.connect(
163 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed);
164 identity_request_observer_->SignalIdentityReady.connect(
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000165 this, &WebRtcSessionDescriptionFactory::SetIdentity);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000166
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000167 if (identity_service_->RequestIdentity(
168 DtlsIdentityStore::kIdentityName,
169 DtlsIdentityStore::kIdentityName,
170 identity_request_observer_)) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000171 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sent DTLS identity request.";
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +0000172 identity_request_state_ = IDENTITY_WAITING;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000173 } else {
174 LOG(LS_ERROR) << "Failed to send DTLS identity request.";
175 identity_request_state_ = IDENTITY_FAILED;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000176 }
wu@webrtc.org364f2042013-11-20 21:49:41 +0000177 } else {
178 identity_request_state_ = IDENTITY_WAITING;
179 // Do not generate the identity in the constructor since the caller has
180 // not got a chance to connect to SignalIdentityReady.
181 signaling_thread_->Post(this, MSG_GENERATE_IDENTITY, NULL);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000182 }
183}
184
185WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() {
186 transport_desc_factory_.set_identity(NULL);
187}
188
189void WebRtcSessionDescriptionFactory::CreateOffer(
190 CreateSessionDescriptionObserver* observer,
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000191 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
192 cricket::MediaSessionOptions session_options;
193
wu@webrtc.org91053e72013-08-10 07:18:04 +0000194 std::string error = "CreateOffer";
195 if (identity_request_state_ == IDENTITY_FAILED) {
196 error += kFailedDueToIdentityFailed;
197 LOG(LS_ERROR) << error;
198 PostCreateSessionDescriptionFailed(observer, error);
199 return;
200 }
201
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000202 if (!mediastream_signaling_->GetOptionsForOffer(options,
203 &session_options)) {
204 error += " called with invalid options.";
wu@webrtc.org91053e72013-08-10 07:18:04 +0000205 LOG(LS_ERROR) << error;
206 PostCreateSessionDescriptionFailed(observer, error);
207 return;
208 }
209
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000210 if (!ValidStreams(session_options.streams)) {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000211 error += " called with invalid media streams.";
212 LOG(LS_ERROR) << error;
213 PostCreateSessionDescriptionFailed(observer, error);
214 return;
215 }
216
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +0000217 if (data_channel_type_ == cricket::DCT_SCTP &&
218 mediastream_signaling_->HasDataChannels()) {
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000219 session_options.data_channel_type = cricket::DCT_SCTP;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000220 }
221
222 CreateSessionDescriptionRequest request(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000223 CreateSessionDescriptionRequest::kOffer, observer, session_options);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000224 if (identity_request_state_ == IDENTITY_WAITING) {
225 create_session_description_requests_.push(request);
226 } else {
227 ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED ||
228 identity_request_state_ == IDENTITY_NOT_NEEDED);
229 InternalCreateOffer(request);
230 }
231}
232
233void WebRtcSessionDescriptionFactory::CreateAnswer(
234 CreateSessionDescriptionObserver* observer,
235 const MediaConstraintsInterface* constraints) {
236 std::string error = "CreateAnswer";
237 if (identity_request_state_ == IDENTITY_FAILED) {
238 error += kFailedDueToIdentityFailed;
239 LOG(LS_ERROR) << error;
240 PostCreateSessionDescriptionFailed(observer, error);
241 return;
242 }
243 if (!session_->remote_description()) {
244 error += " can't be called before SetRemoteDescription.";
245 LOG(LS_ERROR) << error;
246 PostCreateSessionDescriptionFailed(observer, error);
247 return;
248 }
249 if (session_->remote_description()->type() !=
250 JsepSessionDescription::kOffer) {
251 error += " failed because remote_description is not an offer.";
252 LOG(LS_ERROR) << error;
253 PostCreateSessionDescriptionFailed(observer, error);
254 return;
255 }
256
257 cricket::MediaSessionOptions options;
258 if (!mediastream_signaling_->GetOptionsForAnswer(constraints, &options)) {
259 error += " called with invalid constraints.";
260 LOG(LS_ERROR) << error;
261 PostCreateSessionDescriptionFailed(observer, error);
262 return;
263 }
264 if (!ValidStreams(options.streams)) {
265 error += " called with invalid media streams.";
266 LOG(LS_ERROR) << error;
267 PostCreateSessionDescriptionFailed(observer, error);
268 return;
269 }
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000270 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams
271 // are not signaled in the SDP so does not go through that path and must be
272 // handled here.
273 if (data_channel_type_ == cricket::DCT_SCTP) {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000274 options.data_channel_type = cricket::DCT_SCTP;
275 }
276
277 CreateSessionDescriptionRequest request(
278 CreateSessionDescriptionRequest::kAnswer, observer, options);
279 if (identity_request_state_ == IDENTITY_WAITING) {
280 create_session_description_requests_.push(request);
281 } else {
282 ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED ||
283 identity_request_state_ == IDENTITY_NOT_NEEDED);
284 InternalCreateAnswer(request);
285 }
286}
287
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000288void WebRtcSessionDescriptionFactory::SetSdesPolicy(
289 cricket::SecurePolicy secure_policy) {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000290 session_desc_factory_.set_secure(secure_policy);
291}
292
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000293cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000294 return session_desc_factory_.secure();
295}
296
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000297void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000298 switch (msg->message_id) {
299 case MSG_CREATE_SESSIONDESCRIPTION_SUCCESS: {
300 CreateSessionDescriptionMsg* param =
301 static_cast<CreateSessionDescriptionMsg*>(msg->pdata);
302 param->observer->OnSuccess(param->description.release());
303 delete param;
304 break;
305 }
306 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: {
307 CreateSessionDescriptionMsg* param =
308 static_cast<CreateSessionDescriptionMsg*>(msg->pdata);
309 param->observer->OnFailure(param->error);
310 delete param;
311 break;
312 }
313 case MSG_GENERATE_IDENTITY: {
314 LOG(LS_INFO) << "Generating identity.";
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000315 SetIdentity(rtc::SSLIdentity::Generate(DtlsIdentityStore::kIdentityName));
wu@webrtc.org91053e72013-08-10 07:18:04 +0000316 break;
317 }
318 default:
319 ASSERT(false);
320 break;
321 }
322}
323
324void WebRtcSessionDescriptionFactory::InternalCreateOffer(
325 CreateSessionDescriptionRequest request) {
326 cricket::SessionDescription* desc(
327 session_desc_factory_.CreateOffer(
328 request.options,
329 static_cast<cricket::BaseSession*>(session_)->local_description()));
330 // RFC 3264
331 // When issuing an offer that modifies the session,
332 // the "o=" line of the new SDP MUST be identical to that in the
333 // previous SDP, except that the version in the origin field MUST
334 // increment by one from the previous SDP.
335
336 // Just increase the version number by one each time when a new offer
337 // is created regardless if it's identical to the previous one or not.
338 // The |session_version_| is a uint64, the wrap around should not happen.
339 ASSERT(session_version_ + 1 > session_version_);
340 JsepSessionDescription* offer(new JsepSessionDescription(
341 JsepSessionDescription::kOffer));
342 if (!offer->Initialize(desc, session_id_,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000343 rtc::ToString(session_version_++))) {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000344 delete offer;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000345 PostCreateSessionDescriptionFailed(request.observer,
346 "Failed to initialize the offer.");
wu@webrtc.org91053e72013-08-10 07:18:04 +0000347 return;
348 }
349 if (session_->local_description() &&
350 !request.options.transport_options.ice_restart) {
351 // Include all local ice candidates in the SessionDescription unless
352 // the an ice restart has been requested.
353 CopyCandidatesFromSessionDescription(session_->local_description(), offer);
354 }
355 PostCreateSessionDescriptionSucceeded(request.observer, offer);
356}
357
358void WebRtcSessionDescriptionFactory::InternalCreateAnswer(
359 CreateSessionDescriptionRequest request) {
360 // According to http://tools.ietf.org/html/rfc5245#section-9.2.1.1
361 // an answer should also contain new ice ufrag and password if an offer has
362 // been received with new ufrag and password.
363 request.options.transport_options.ice_restart = session_->IceRestartPending();
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000364 // We should pass current ssl role to the transport description factory, if
365 // there is already an existing ongoing session.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000366 rtc::SSLRole ssl_role;
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000367 if (session_->GetSslRole(&ssl_role)) {
368 request.options.transport_options.prefer_passive_role =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000369 (rtc::SSL_SERVER == ssl_role);
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +0000370 }
wu@webrtc.org91053e72013-08-10 07:18:04 +0000371
372 cricket::SessionDescription* desc(session_desc_factory_.CreateAnswer(
373 static_cast<cricket::BaseSession*>(session_)->remote_description(),
374 request.options,
375 static_cast<cricket::BaseSession*>(session_)->local_description()));
376 // RFC 3264
377 // If the answer is different from the offer in any way (different IP
378 // addresses, ports, etc.), the origin line MUST be different in the answer.
379 // In that case, the version number in the "o=" line of the answer is
380 // unrelated to the version number in the o line of the offer.
381 // Get a new version number by increasing the |session_version_answer_|.
382 // The |session_version_| is a uint64, the wrap around should not happen.
383 ASSERT(session_version_ + 1 > session_version_);
384 JsepSessionDescription* answer(new JsepSessionDescription(
385 JsepSessionDescription::kAnswer));
386 if (!answer->Initialize(desc, session_id_,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000387 rtc::ToString(session_version_++))) {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000388 delete answer;
389 PostCreateSessionDescriptionFailed(request.observer,
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000390 "Failed to initialize the answer.");
wu@webrtc.org91053e72013-08-10 07:18:04 +0000391 return;
392 }
393 if (session_->local_description() &&
394 !request.options.transport_options.ice_restart) {
395 // Include all local ice candidates in the SessionDescription unless
396 // the remote peer has requested an ice restart.
397 CopyCandidatesFromSessionDescription(session_->local_description(), answer);
398 }
399 session_->ResetIceRestartLatch();
400 PostCreateSessionDescriptionSucceeded(request.observer, answer);
401}
402
403void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionFailed(
404 CreateSessionDescriptionObserver* observer, const std::string& error) {
405 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer);
406 msg->error = error;
407 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000408 LOG(LS_ERROR) << "Create SDP failed: " << error;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000409}
410
411void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionSucceeded(
412 CreateSessionDescriptionObserver* observer,
413 SessionDescriptionInterface* description) {
414 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer);
415 msg->description.reset(description);
416 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg);
417}
418
419void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) {
420 ASSERT(signaling_thread_->IsCurrent());
421
422 LOG(LS_ERROR) << "Async identity request failed: error = " << error;
423 identity_request_state_ = IDENTITY_FAILED;
424
425 std::string msg = kFailedDueToIdentityFailed;
426 while (!create_session_description_requests_.empty()) {
427 const CreateSessionDescriptionRequest& request =
428 create_session_description_requests_.front();
429 PostCreateSessionDescriptionFailed(
430 request.observer,
431 ((request.type == CreateSessionDescriptionRequest::kOffer) ?
432 "CreateOffer" : "CreateAnswer") + msg);
433 create_session_description_requests_.pop();
434 }
435}
436
wu@webrtc.org91053e72013-08-10 07:18:04 +0000437void WebRtcSessionDescriptionFactory::SetIdentity(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000438 rtc::SSLIdentity* identity) {
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000439 LOG(LS_VERBOSE) << "Setting new identity";
440
wu@webrtc.org91053e72013-08-10 07:18:04 +0000441 identity_request_state_ = IDENTITY_SUCCEEDED;
442 SignalIdentityReady(identity);
443
444 transport_desc_factory_.set_identity(identity);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000445 transport_desc_factory_.set_secure(cricket::SEC_ENABLED);
446
447 while (!create_session_description_requests_.empty()) {
448 if (create_session_description_requests_.front().type ==
449 CreateSessionDescriptionRequest::kOffer) {
450 InternalCreateOffer(create_session_description_requests_.front());
451 } else {
452 InternalCreateAnswer(create_session_description_requests_.front());
453 }
454 create_session_description_requests_.pop();
455 }
456}
wu@webrtc.org91053e72013-08-10 07:18:04 +0000457} // namespace webrtc