Index: talk/app/webrtc/webrtcsession.cc |
diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc |
index 1a5751a111ed089af01b63e25ec4c2728091c845..bdc47840bd1274380b10c906a4287ac63e9a9ba4 100644 |
--- a/talk/app/webrtc/webrtcsession.cc |
+++ b/talk/app/webrtc/webrtcsession.cc |
@@ -38,7 +38,6 @@ |
#include "talk/app/webrtc/mediaconstraintsinterface.h" |
#include "talk/app/webrtc/mediastreamsignaling.h" |
#include "talk/app/webrtc/peerconnectioninterface.h" |
-#include "talk/app/webrtc/sctputils.h" |
#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h" |
#include "talk/media/base/constants.h" |
#include "talk/media/base/videocapturer.h" |
@@ -537,10 +536,12 @@ |
bool ice_restart_; |
}; |
-WebRtcSession::WebRtcSession(cricket::ChannelManager* channel_manager, |
- rtc::Thread* signaling_thread, |
- rtc::Thread* worker_thread, |
- cricket::PortAllocator* port_allocator) |
+WebRtcSession::WebRtcSession( |
+ cricket::ChannelManager* channel_manager, |
+ rtc::Thread* signaling_thread, |
+ rtc::Thread* worker_thread, |
+ cricket::PortAllocator* port_allocator, |
+ MediaStreamSignaling* mediastream_signaling) |
: cricket::BaseSession(signaling_thread, |
worker_thread, |
port_allocator, |
@@ -550,6 +551,7 @@ |
// o line MUST be representable with a "64 bit signed integer". |
// Due to this constraint session id |sid_| is max limited to LLONG_MAX. |
channel_manager_(channel_manager), |
+ mediastream_signaling_(mediastream_signaling), |
ice_observer_(NULL), |
ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), |
ice_connection_receiving_(true), |
@@ -640,6 +642,9 @@ |
LOG(LS_INFO) << "Allowing SCTP data engine."; |
data_channel_type_ = cricket::DCT_SCTP; |
} |
+ } |
+ if (data_channel_type_ != cricket::DCT_NONE) { |
+ mediastream_signaling_->SetDataChannelFactory(this); |
} |
// Find DSCP constraint. |
@@ -738,19 +743,21 @@ |
if (!dtls_enabled_) { |
// Construct with DTLS disabled. |
webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( |
- signaling_thread(), channel_manager_, this, id())); |
+ signaling_thread(), channel_manager_, mediastream_signaling_, this, |
+ id(), data_channel_type_)); |
} else { |
// Construct with DTLS enabled. |
if (!certificate) { |
// Use the |dtls_identity_store| to generate a certificate. |
RTC_DCHECK(dtls_identity_store); |
webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( |
- signaling_thread(), channel_manager_, dtls_identity_store.Pass(), |
- this, id())); |
+ signaling_thread(), channel_manager_, mediastream_signaling_, |
+ dtls_identity_store.Pass(), this, id(), data_channel_type_)); |
} else { |
// Use the already generated certificate. |
webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( |
- signaling_thread(), channel_manager_, certificate, this, id())); |
+ signaling_thread(), channel_manager_, mediastream_signaling_, |
+ certificate, this, id(), data_channel_type_)); |
} |
} |
@@ -812,17 +819,13 @@ |
void WebRtcSession::CreateOffer( |
CreateSessionDescriptionObserver* observer, |
- const PeerConnectionInterface::RTCOfferAnswerOptions& options, |
- const cricket::MediaSessionOptions& session_options) { |
- webrtc_session_desc_factory_->CreateOffer(observer, options, session_options); |
-} |
- |
-void WebRtcSession::CreateAnswer( |
- CreateSessionDescriptionObserver* observer, |
- const MediaConstraintsInterface* constraints, |
- const cricket::MediaSessionOptions& session_options) { |
- webrtc_session_desc_factory_->CreateAnswer(observer, constraints, |
- session_options); |
+ const PeerConnectionInterface::RTCOfferAnswerOptions& options) { |
+ webrtc_session_desc_factory_->CreateOffer(observer, options); |
+} |
+ |
+void WebRtcSession::CreateAnswer(CreateSessionDescriptionObserver* observer, |
+ const MediaConstraintsInterface* constraints) { |
+ webrtc_session_desc_factory_->CreateAnswer(observer, constraints); |
} |
bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc, |
@@ -880,6 +883,14 @@ |
UseCandidatesInSessionDescription(remote_desc_.get()); |
} |
+ // Update state and SSRC of local MediaStreams and DataChannels based on the |
+ // local session description. |
+ mediastream_signaling_->OnLocalDescriptionChanged(local_desc_.get()); |
+ |
+ rtc::SSLRole role; |
+ if (data_channel_type_ == cricket::DCT_SCTP && GetSslRole(&role)) { |
+ mediastream_signaling_->OnDtlsRoleReadyForSctp(role); |
+ } |
if (error() != cricket::BaseSession::ERROR_NONE) { |
return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc); |
} |
@@ -916,6 +927,8 @@ |
return false; |
} |
+ // Update remote MediaStreams. |
+ mediastream_signaling_->OnRemoteDescriptionChanged(desc); |
if (local_description() && !UseCandidatesInSessionDescription(desc)) { |
return BadRemoteSdp(desc->type(), kInvalidCandidates, err_desc); |
} |
@@ -936,6 +949,11 @@ |
} |
remote_desc_.reset(desc_temp.release()); |
+ |
+ rtc::SSLRole role; |
+ if (data_channel_type_ == cricket::DCT_SCTP && GetSslRole(&role)) { |
+ mediastream_signaling_->OnDtlsRoleReadyForSctp(role); |
+ } |
if (error() != cricket::BaseSession::ERROR_NONE) { |
return BadRemoteSdp(desc->type(), GetSessionErrorMsg(), err_desc); |
@@ -1369,8 +1387,6 @@ |
&DataChannel::OnChannelReady); |
data_channel_->SignalDataReceived.connect(webrtc_data_channel, |
&DataChannel::OnDataReceived); |
- data_channel_->SignalStreamClosedRemotely.connect( |
- webrtc_data_channel, &DataChannel::OnStreamClosedRemotely); |
return true; |
} |
@@ -1381,7 +1397,6 @@ |
} |
data_channel_->SignalReadyToSendData.disconnect(webrtc_data_channel); |
data_channel_->SignalDataReceived.disconnect(webrtc_data_channel); |
- data_channel_->SignalStreamClosedRemotely.disconnect(webrtc_data_channel); |
} |
void WebRtcSession::AddSctpDataStream(int sid) { |
@@ -1394,6 +1409,8 @@ |
} |
void WebRtcSession::RemoveSctpDataStream(int sid) { |
+ mediastream_signaling_->RemoveSctpDataChannel(sid); |
+ |
if (!data_channel_) { |
LOG(LS_ERROR) << "RemoveDataChannelStreams called when data_channel_ is " |
<< "NULL."; |
@@ -1405,6 +1422,41 @@ |
bool WebRtcSession::ReadyToSendData() const { |
return data_channel_ && data_channel_->ready_to_send_data(); |
+} |
+ |
+rtc::scoped_refptr<DataChannel> WebRtcSession::CreateDataChannel( |
+ const std::string& label, |
+ const InternalDataChannelInit* config) { |
+ if (state() == STATE_RECEIVEDTERMINATE) { |
+ return NULL; |
+ } |
+ if (data_channel_type_ == cricket::DCT_NONE) { |
+ LOG(LS_ERROR) << "CreateDataChannel: Data is not supported in this call."; |
+ return NULL; |
+ } |
+ InternalDataChannelInit new_config = |
+ config ? (*config) : InternalDataChannelInit(); |
+ if (data_channel_type_ == cricket::DCT_SCTP) { |
+ if (new_config.id < 0) { |
+ rtc::SSLRole role; |
+ if (GetSslRole(&role) && |
+ !mediastream_signaling_->AllocateSctpSid(role, &new_config.id)) { |
+ LOG(LS_ERROR) << "No id can be allocated for the SCTP data channel."; |
+ return NULL; |
+ } |
+ } else if (!mediastream_signaling_->IsSctpSidAvailable(new_config.id)) { |
+ LOG(LS_ERROR) << "Failed to create a SCTP data channel " |
+ << "because the id is already in use or out of range."; |
+ return NULL; |
+ } |
+ } |
+ |
+ rtc::scoped_refptr<DataChannel> channel(DataChannel::Create( |
+ this, data_channel_type_, label, new_config)); |
+ if (channel && !mediastream_signaling_->AddDataChannel(channel)) |
+ return NULL; |
+ |
+ return channel; |
} |
cricket::DataChannelType WebRtcSession::data_channel_type() const { |
@@ -1675,6 +1727,7 @@ |
const cricket::ContentInfo* video_info = |
cricket::GetFirstVideoContent(desc); |
if ((!video_info || video_info->rejected) && video_channel_) { |
+ mediastream_signaling_->OnVideoChannelClose(); |
SignalVideoChannelDestroyed(); |
const std::string content_name = video_channel_->content_name(); |
channel_manager_->DestroyVideoChannel(video_channel_.release()); |
@@ -1683,6 +1736,7 @@ |
const cricket::ContentInfo* voice_info = |
cricket::GetFirstAudioContent(desc); |
if ((!voice_info || voice_info->rejected) && voice_channel_) { |
+ mediastream_signaling_->OnAudioChannelClose(); |
SignalVoiceChannelDestroyed(); |
const std::string content_name = voice_channel_->content_name(); |
channel_manager_->DestroyVoiceChannel(voice_channel_.release()); |
@@ -1691,6 +1745,7 @@ |
const cricket::ContentInfo* data_info = |
cricket::GetFirstDataContent(desc); |
if ((!data_info || data_info->rejected) && data_channel_) { |
+ mediastream_signaling_->OnDataChannelClose(); |
SignalDataChannelDestroyed(); |
const std::string content_name = data_channel_->content_name(); |
channel_manager_->DestroyDataChannel(data_channel_.release()); |
@@ -1765,8 +1820,6 @@ |
voice_channel_->SignalDtlsSetupFailure.connect( |
this, &WebRtcSession::OnDtlsSetupFailure); |
- |
- SignalVoiceChannelCreated(); |
return true; |
} |
@@ -1780,8 +1833,6 @@ |
video_channel_->SignalDtlsSetupFailure.connect( |
this, &WebRtcSession::OnDtlsSetupFailure); |
- |
- SignalVideoChannelCreated(); |
return true; |
} |
@@ -1794,14 +1845,16 @@ |
} |
if (sctp) { |
+ mediastream_signaling_->OnDataTransportCreatedForSctp(); |
data_channel_->SignalDataReceived.connect( |
this, &WebRtcSession::OnDataChannelMessageReceived); |
+ data_channel_->SignalStreamClosedRemotely.connect( |
+ mediastream_signaling_, |
+ &MediaStreamSignaling::OnRemoteSctpDataChannelClosed); |
} |
data_channel_->SignalDtlsSetupFailure.connect( |
this, &WebRtcSession::OnDtlsSetupFailure); |
- |
- SignalDataChannelCreated(); |
return true; |
} |
@@ -1827,22 +1880,13 @@ |
cricket::DataChannel* channel, |
const cricket::ReceiveDataParams& params, |
const rtc::Buffer& payload) { |
- RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); |
- if (params.type == cricket::DMT_CONTROL && IsOpenMessage(payload)) { |
- // Received OPEN message; parse and signal that a new data channel should |
- // be created. |
- std::string label; |
- InternalDataChannelInit config; |
- config.id = params.ssrc; |
- if (!ParseDataChannelOpenMessage(payload, &label, &config)) { |
- LOG(LS_WARNING) << "Failed to parse the OPEN message for sid " |
- << params.ssrc; |
- return; |
- } |
- config.open_handshake_role = InternalDataChannelInit::kAcker; |
- SignalDataChannelOpenMessage(label, config); |
- } |
- // Otherwise ignore the message. |
+ ASSERT(data_channel_type_ == cricket::DCT_SCTP); |
+ if (params.type == cricket::DMT_CONTROL && |
+ mediastream_signaling_->IsSctpSidAvailable(params.ssrc)) { |
+ // Received CONTROL on unused sid, process as an OPEN message. |
+ mediastream_signaling_->AddDataChannelFromOpenMessage(params, payload); |
+ } |
+ // otherwise ignore the message. |
} |
// Returns false if bundle is enabled and rtcp_mux is disabled. |