| Index: talk/app/webrtc/webrtcsession.cc
|
| diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc
|
| index 1a5751a111ed089af01b63e25ec4c2728091c845..f17dd34b75bc794455dea0f1e7e3b59a591e675d 100644
|
| --- a/talk/app/webrtc/webrtcsession.cc
|
| +++ b/talk/app/webrtc/webrtcsession.cc
|
| @@ -331,7 +331,11 @@ static bool BadSdp(const std::string& source,
|
| const std::string& reason,
|
| std::string* err_desc) {
|
| std::ostringstream desc;
|
| - desc << "Failed to set " << source << " " << type << " sdp: " << reason;
|
| + desc << "Failed to set " << source;
|
| + if (!type.empty()) {
|
| + desc << " " << type;
|
| + }
|
| + desc << " sdp: " << reason;
|
|
|
| if (err_desc) {
|
| *err_desc = desc.str();
|
| @@ -382,30 +386,21 @@ static bool BadAnswerSdp(cricket::ContentSource source,
|
| return BadSdp(source, SessionDescriptionInterface::kAnswer, reason, err_desc);
|
| }
|
|
|
| -#define GET_STRING_OF_STATE(state) \
|
| - case cricket::BaseSession::state: \
|
| - result = #state; \
|
| +#define GET_STRING_OF_STATE(state) \
|
| + case webrtc::WebRtcSession::state: \
|
| + result = #state; \
|
| break;
|
|
|
| -static std::string GetStateString(cricket::BaseSession::State state) {
|
| +static std::string GetStateString(webrtc::WebRtcSession::State state) {
|
| std::string result;
|
| switch (state) {
|
| GET_STRING_OF_STATE(STATE_INIT)
|
| - GET_STRING_OF_STATE(STATE_SENTINITIATE)
|
| - GET_STRING_OF_STATE(STATE_RECEIVEDINITIATE)
|
| - GET_STRING_OF_STATE(STATE_SENTPRACCEPT)
|
| - GET_STRING_OF_STATE(STATE_SENTACCEPT)
|
| - GET_STRING_OF_STATE(STATE_RECEIVEDPRACCEPT)
|
| - GET_STRING_OF_STATE(STATE_RECEIVEDACCEPT)
|
| - GET_STRING_OF_STATE(STATE_SENTMODIFY)
|
| - GET_STRING_OF_STATE(STATE_RECEIVEDMODIFY)
|
| - GET_STRING_OF_STATE(STATE_SENTREJECT)
|
| - GET_STRING_OF_STATE(STATE_RECEIVEDREJECT)
|
| - GET_STRING_OF_STATE(STATE_SENTREDIRECT)
|
| - GET_STRING_OF_STATE(STATE_SENTTERMINATE)
|
| - GET_STRING_OF_STATE(STATE_RECEIVEDTERMINATE)
|
| + GET_STRING_OF_STATE(STATE_SENTOFFER)
|
| + GET_STRING_OF_STATE(STATE_RECEIVEDOFFER)
|
| + GET_STRING_OF_STATE(STATE_SENTPRANSWER)
|
| + GET_STRING_OF_STATE(STATE_RECEIVEDPRANSWER)
|
| GET_STRING_OF_STATE(STATE_INPROGRESS)
|
| - GET_STRING_OF_STATE(STATE_DEINIT)
|
| + GET_STRING_OF_STATE(STATE_CLOSED)
|
| default:
|
| ASSERT(false);
|
| break;
|
| @@ -413,22 +408,19 @@ static std::string GetStateString(cricket::BaseSession::State state) {
|
| return result;
|
| }
|
|
|
| -#define GET_STRING_OF_ERROR_CODE(err) \
|
| - case cricket::BaseSession::err: \
|
| - result = #err; \
|
| +#define GET_STRING_OF_ERROR_CODE(err) \
|
| + case webrtc::WebRtcSession::err: \
|
| + result = #err; \
|
| break;
|
|
|
| -static std::string GetErrorCodeString(cricket::BaseSession::Error err) {
|
| +static std::string GetErrorCodeString(webrtc::WebRtcSession::Error err) {
|
| std::string result;
|
| switch (err) {
|
| GET_STRING_OF_ERROR_CODE(ERROR_NONE)
|
| - GET_STRING_OF_ERROR_CODE(ERROR_TIME)
|
| - GET_STRING_OF_ERROR_CODE(ERROR_RESPONSE)
|
| - GET_STRING_OF_ERROR_CODE(ERROR_NETWORK)
|
| GET_STRING_OF_ERROR_CODE(ERROR_CONTENT)
|
| GET_STRING_OF_ERROR_CODE(ERROR_TRANSPORT)
|
| default:
|
| - ASSERT(false);
|
| + RTC_DCHECK(false);
|
| break;
|
| }
|
| return result;
|
| @@ -541,14 +533,16 @@ WebRtcSession::WebRtcSession(cricket::ChannelManager* channel_manager,
|
| rtc::Thread* signaling_thread,
|
| rtc::Thread* worker_thread,
|
| cricket::PortAllocator* port_allocator)
|
| - : cricket::BaseSession(signaling_thread,
|
| - worker_thread,
|
| - port_allocator,
|
| - rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX),
|
| - false),
|
| + : signaling_thread_(signaling_thread),
|
| + worker_thread_(worker_thread),
|
| + port_allocator_(port_allocator),
|
| // RFC 3264: The numeric value of the session id and version in the
|
| // o line MUST be representable with a "64 bit signed integer".
|
| // Due to this constraint session id |sid_| is max limited to LLONG_MAX.
|
| + sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
|
| + transport_controller_(new cricket::TransportController(signaling_thread,
|
| + worker_thread,
|
| + port_allocator)),
|
| channel_manager_(channel_manager),
|
| ice_observer_(NULL),
|
| ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
|
| @@ -558,13 +552,14 @@ WebRtcSession::WebRtcSession(cricket::ChannelManager* channel_manager,
|
| data_channel_type_(cricket::DCT_NONE),
|
| ice_restart_latch_(new IceRestartAnswerLatch),
|
| metrics_observer_(NULL) {
|
| - transport_controller()->SignalConnectionState.connect(
|
| + transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED);
|
| + transport_controller_->SignalConnectionState.connect(
|
| this, &WebRtcSession::OnTransportControllerConnectionState);
|
| - transport_controller()->SignalReceiving.connect(
|
| + transport_controller_->SignalReceiving.connect(
|
| this, &WebRtcSession::OnTransportControllerReceiving);
|
| - transport_controller()->SignalGatheringState.connect(
|
| + transport_controller_->SignalGatheringState.connect(
|
| this, &WebRtcSession::OnTransportControllerGatheringState);
|
| - transport_controller()->SignalCandidatesGathered.connect(
|
| + transport_controller_->SignalCandidatesGathered.connect(
|
| this, &WebRtcSession::OnTransportControllerCandidatesGathered);
|
| }
|
|
|
| @@ -584,9 +579,8 @@ WebRtcSession::~WebRtcSession() {
|
| SignalDataChannelDestroyed();
|
| channel_manager_->DestroyDataChannel(data_channel_.release());
|
| }
|
| - for (size_t i = 0; i < saved_candidates_.size(); ++i) {
|
| - delete saved_candidates_[i];
|
| - }
|
| +
|
| + LOG(LS_INFO) << "Session: " << id() << " is destroyed.";
|
| }
|
|
|
| bool WebRtcSession::Initialize(
|
| @@ -596,7 +590,7 @@ bool WebRtcSession::Initialize(
|
| const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
|
| bundle_policy_ = rtc_configuration.bundle_policy;
|
| rtcp_mux_policy_ = rtc_configuration.rtcp_mux_policy;
|
| - transport_controller()->SetSslMaxProtocolVersion(options.ssl_max_version);
|
| + transport_controller_->SetSslMaxProtocolVersion(options.ssl_max_version);
|
|
|
| // Obtain a certificate from RTCConfiguration if any were provided (optional).
|
| rtc::scoped_refptr<rtc::RTCCertificate> certificate;
|
| @@ -775,18 +769,9 @@ bool WebRtcSession::Initialize(
|
| return true;
|
| }
|
|
|
| -cricket::IceConfig WebRtcSession::ParseIceConfig(
|
| - const PeerConnectionInterface::RTCConfiguration& config) const {
|
| - cricket::IceConfig ice_config;
|
| - ice_config.receiving_timeout_ms = config.ice_connection_receiving_timeout;
|
| - ice_config.gather_continually = (config.continual_gathering_policy ==
|
| - PeerConnectionInterface::GATHER_CONTINUALLY);
|
| - return ice_config;
|
| -}
|
| -
|
| -void WebRtcSession::Terminate() {
|
| - SetState(STATE_RECEIVEDTERMINATE);
|
| - RemoveUnusedChannels(NULL);
|
| +void WebRtcSession::Close() {
|
| + SetState(STATE_CLOSED);
|
| + RemoveUnusedChannels(nullptr);
|
| ASSERT(!voice_channel_);
|
| ASSERT(!video_channel_);
|
| ASSERT(!data_channel_);
|
| @@ -801,13 +786,13 @@ cricket::SecurePolicy WebRtcSession::SdesPolicy() const {
|
| }
|
|
|
| bool WebRtcSession::GetSslRole(rtc::SSLRole* role) {
|
| - if (local_description() == NULL || remote_description() == NULL) {
|
| + if (!local_desc_ || !remote_desc_) {
|
| LOG(LS_INFO) << "Local and Remote descriptions must be applied to get "
|
| << "SSL Role of the session.";
|
| return false;
|
| }
|
|
|
| - return transport_controller()->GetSslRole(role);
|
| + return transport_controller_->GetSslRole(role);
|
| }
|
|
|
| void WebRtcSession::CreateOffer(
|
| @@ -837,10 +822,11 @@ bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,
|
| return false;
|
| }
|
|
|
| - // Update the initiator flag if this session is the initiator.
|
| + // Update the initial_offerer flag if this session is the initial_offerer.
|
| Action action = GetAction(desc->type());
|
| if (state() == STATE_INIT && action == kOffer) {
|
| - set_initiator(true);
|
| + initial_offerer_ = true;
|
| + transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING);
|
| }
|
|
|
| cricket::SecurePolicy sdes_policy =
|
| @@ -851,7 +837,6 @@ bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,
|
| // Update the MediaContentDescription crypto settings as per the policy set.
|
| UpdateSessionDescriptionSecurePolicy(crypto_required, desc->description());
|
|
|
| - set_local_description(desc->description()->Copy());
|
| local_desc_.reset(desc_temp.release());
|
|
|
| // Transport and Media channels will be created only when offer is set.
|
| @@ -868,19 +853,12 @@ bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,
|
| return false;
|
| }
|
|
|
| - if (remote_description()) {
|
| - // Now that we have a local description, we can push down remote candidates
|
| - // that we stored, and those from the remote description.
|
| - if (!saved_candidates_.empty()) {
|
| - // If there are saved candidates which arrived before the local
|
| - // description was set, copy those to the remote description.
|
| - CopySavedCandidates(remote_desc_.get());
|
| - }
|
| - // Push remote candidates in remote description to transport channels.
|
| + if (remote_desc_) {
|
| + // Now that we have a local description, we can push down remote candidates.
|
| UseCandidatesInSessionDescription(remote_desc_.get());
|
| }
|
|
|
| - if (error() != cricket::BaseSession::ERROR_NONE) {
|
| + if (error() != ERROR_NONE) {
|
| return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc);
|
| }
|
| return true;
|
| @@ -898,6 +876,10 @@ bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
|
| return false;
|
| }
|
|
|
| + rtc::scoped_ptr<SessionDescriptionInterface> old_remote_desc(
|
| + remote_desc_.release());
|
| + remote_desc_.reset(desc_temp.release());
|
| +
|
| // Transport and Media channels will be created only when offer is set.
|
| Action action = GetAction(desc->type());
|
| if (action == kOffer && !CreateChannels(desc->description())) {
|
| @@ -911,33 +893,31 @@ bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
|
|
|
| // NOTE: Candidates allocation will be initiated only when SetLocalDescription
|
| // is called.
|
| - set_remote_description(desc->description()->Copy());
|
| if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) {
|
| return false;
|
| }
|
|
|
| - if (local_description() && !UseCandidatesInSessionDescription(desc)) {
|
| + if (local_desc_ && !UseCandidatesInSessionDescription(desc)) {
|
| return BadRemoteSdp(desc->type(), kInvalidCandidates, err_desc);
|
| }
|
|
|
| - // Copy all saved candidates.
|
| - CopySavedCandidates(desc);
|
| -
|
| // Check if this new SessionDescription contains new ice ufrag and password
|
| // that indicates the remote peer requests ice restart.
|
| bool ice_restart =
|
| - ice_restart_latch_->CheckForRemoteIceRestart(remote_desc_.get(), desc);
|
| + ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), desc);
|
| // We retain all received candidates only if ICE is not restarted.
|
| // When ICE is restarted, all previous candidates belong to an old generation
|
| // and should not be kept.
|
| + // TODO(deadbeef): This goes against the W3C spec which says the remote
|
| + // description should only contain candidates from the last set remote
|
| + // description plus any candidates added since then. We should remove this
|
| + // once we're sure it won't break anything.
|
| if (!ice_restart) {
|
| WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription(
|
| - remote_desc_.get(), desc);
|
| + old_remote_desc.get(), desc);
|
| }
|
|
|
| - remote_desc_.reset(desc_temp.release());
|
| -
|
| - if (error() != cricket::BaseSession::ERROR_NONE) {
|
| + if (error() != ERROR_NONE) {
|
| return BadRemoteSdp(desc->type(), GetSessionErrorMsg(), err_desc);
|
| }
|
|
|
| @@ -956,6 +936,29 @@ bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
|
| return true;
|
| }
|
|
|
| +void WebRtcSession::LogState(State old_state, State new_state) {
|
| + LOG(LS_INFO) << "Session:" << id()
|
| + << " Old state:" << GetStateString(old_state)
|
| + << " New state:" << GetStateString(new_state);
|
| +}
|
| +
|
| +void WebRtcSession::SetState(State state) {
|
| + ASSERT(signaling_thread_->IsCurrent());
|
| + if (state != state_) {
|
| + LogState(state_, state);
|
| + state_ = state;
|
| + SignalState(this, state_);
|
| + }
|
| +}
|
| +
|
| +void WebRtcSession::SetError(Error error, const std::string& error_desc) {
|
| + ASSERT(signaling_thread_->IsCurrent());
|
| + if (error != error_) {
|
| + error_ = error;
|
| + error_desc_ = error_desc;
|
| + }
|
| +}
|
| +
|
| bool WebRtcSession::UpdateSessionState(
|
| Action action, cricket::ContentSource source,
|
| std::string* err_desc) {
|
| @@ -963,18 +966,18 @@ bool WebRtcSession::UpdateSessionState(
|
|
|
| // If there's already a pending error then no state transition should happen.
|
| // But all call-sites should be verifying this before calling us!
|
| - ASSERT(error() == cricket::BaseSession::ERROR_NONE);
|
| + ASSERT(error() == ERROR_NONE);
|
| std::string td_err;
|
| if (action == kOffer) {
|
| if (!PushdownTransportDescription(source, cricket::CA_OFFER, &td_err)) {
|
| return BadOfferSdp(source, MakeTdErrorString(td_err), err_desc);
|
| }
|
| - SetState(source == cricket::CS_LOCAL ?
|
| - STATE_SENTINITIATE : STATE_RECEIVEDINITIATE);
|
| + SetState(source == cricket::CS_LOCAL ? STATE_SENTOFFER
|
| + : STATE_RECEIVEDOFFER);
|
| if (!PushdownMediaDescription(cricket::CA_OFFER, source, err_desc)) {
|
| - SetError(BaseSession::ERROR_CONTENT, *err_desc);
|
| + SetError(ERROR_CONTENT, *err_desc);
|
| }
|
| - if (error() != cricket::BaseSession::ERROR_NONE) {
|
| + if (error() != ERROR_NONE) {
|
| return BadOfferSdp(source, GetSessionErrorMsg(), err_desc);
|
| }
|
| } else if (action == kPrAnswer) {
|
| @@ -982,12 +985,12 @@ bool WebRtcSession::UpdateSessionState(
|
| return BadPranswerSdp(source, MakeTdErrorString(td_err), err_desc);
|
| }
|
| EnableChannels();
|
| - SetState(source == cricket::CS_LOCAL ?
|
| - STATE_SENTPRACCEPT : STATE_RECEIVEDPRACCEPT);
|
| + SetState(source == cricket::CS_LOCAL ? STATE_SENTPRANSWER
|
| + : STATE_RECEIVEDPRANSWER);
|
| if (!PushdownMediaDescription(cricket::CA_PRANSWER, source, err_desc)) {
|
| - SetError(BaseSession::ERROR_CONTENT, *err_desc);
|
| + SetError(ERROR_CONTENT, *err_desc);
|
| }
|
| - if (error() != cricket::BaseSession::ERROR_NONE) {
|
| + if (error() != ERROR_NONE) {
|
| return BadPranswerSdp(source, GetSessionErrorMsg(), err_desc);
|
| }
|
| } else if (action == kAnswer) {
|
| @@ -995,11 +998,9 @@ bool WebRtcSession::UpdateSessionState(
|
| return BadAnswerSdp(source, MakeTdErrorString(td_err), err_desc);
|
| }
|
| const cricket::ContentGroup* local_bundle =
|
| - BaseSession::local_description()->GetGroupByName(
|
| - cricket::GROUP_TYPE_BUNDLE);
|
| + local_desc_->description()->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
|
| const cricket::ContentGroup* remote_bundle =
|
| - BaseSession::remote_description()->GetGroupByName(
|
| - cricket::GROUP_TYPE_BUNDLE);
|
| + remote_desc_->description()->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
|
| if (local_bundle && remote_bundle) {
|
| // The answerer decides the transport to bundle on
|
| const cricket::ContentGroup* answer_bundle =
|
| @@ -1010,18 +1011,29 @@ bool WebRtcSession::UpdateSessionState(
|
| }
|
| }
|
| EnableChannels();
|
| - SetState(source == cricket::CS_LOCAL ?
|
| - STATE_SENTACCEPT : STATE_RECEIVEDACCEPT);
|
| + SetState(STATE_INPROGRESS);
|
| if (!PushdownMediaDescription(cricket::CA_ANSWER, source, err_desc)) {
|
| - SetError(BaseSession::ERROR_CONTENT, *err_desc);
|
| + SetError(ERROR_CONTENT, *err_desc);
|
| }
|
| - if (error() != cricket::BaseSession::ERROR_NONE) {
|
| + if (error() != ERROR_NONE) {
|
| return BadAnswerSdp(source, GetSessionErrorMsg(), err_desc);
|
| }
|
| }
|
| return true;
|
| }
|
|
|
| +WebRtcSession::Action WebRtcSession::GetAction(const std::string& type) {
|
| + if (type == SessionDescriptionInterface::kOffer) {
|
| + return WebRtcSession::kOffer;
|
| + } else if (type == SessionDescriptionInterface::kPrAnswer) {
|
| + return WebRtcSession::kPrAnswer;
|
| + } else if (type == SessionDescriptionInterface::kAnswer) {
|
| + return WebRtcSession::kAnswer;
|
| + }
|
| + ASSERT(false && "unknown action type");
|
| + return WebRtcSession::kOffer;
|
| +}
|
| +
|
| bool WebRtcSession::PushdownMediaDescription(
|
| cricket::ContentAction action,
|
| cricket::ContentSource source,
|
| @@ -1030,11 +1042,11 @@ bool WebRtcSession::PushdownMediaDescription(
|
| if (!ch) {
|
| return true;
|
| } else if (source == cricket::CS_LOCAL) {
|
| - return ch->PushdownLocalDescription(
|
| - base_local_description(), action, err);
|
| + return ch->PushdownLocalDescription(local_desc_->description(), action,
|
| + err);
|
| } else {
|
| - return ch->PushdownRemoteDescription(
|
| - base_remote_description(), action, err);
|
| + return ch->PushdownRemoteDescription(remote_desc_->description(), action,
|
| + err);
|
| }
|
| };
|
|
|
| @@ -1043,19 +1055,76 @@ bool WebRtcSession::PushdownMediaDescription(
|
| set_content(data_channel()));
|
| }
|
|
|
| -WebRtcSession::Action WebRtcSession::GetAction(const std::string& type) {
|
| - if (type == SessionDescriptionInterface::kOffer) {
|
| - return WebRtcSession::kOffer;
|
| - } else if (type == SessionDescriptionInterface::kPrAnswer) {
|
| - return WebRtcSession::kPrAnswer;
|
| - } else if (type == SessionDescriptionInterface::kAnswer) {
|
| - return WebRtcSession::kAnswer;
|
| +bool WebRtcSession::PushdownTransportDescription(cricket::ContentSource source,
|
| + cricket::ContentAction action,
|
| + std::string* error_desc) {
|
| + RTC_DCHECK(signaling_thread()->IsCurrent());
|
| +
|
| + if (source == cricket::CS_LOCAL) {
|
| + return PushdownLocalTransportDescription(local_desc_->description(), action,
|
| + error_desc);
|
| }
|
| - ASSERT(false && "unknown action type");
|
| - return WebRtcSession::kOffer;
|
| + return PushdownRemoteTransportDescription(remote_desc_->description(), action,
|
| + error_desc);
|
| }
|
|
|
| -bool WebRtcSession::GetTransportStats(cricket::SessionStats* stats) {
|
| +bool WebRtcSession::PushdownLocalTransportDescription(
|
| + const SessionDescription* sdesc,
|
| + cricket::ContentAction action,
|
| + std::string* err) {
|
| + RTC_DCHECK(signaling_thread()->IsCurrent());
|
| +
|
| + if (!sdesc) {
|
| + return false;
|
| + }
|
| +
|
| + for (const TransportInfo& tinfo : sdesc->transport_infos()) {
|
| + if (!transport_controller_->SetLocalTransportDescription(
|
| + tinfo.content_name, tinfo.description, action, err)) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool WebRtcSession::PushdownRemoteTransportDescription(
|
| + const SessionDescription* sdesc,
|
| + cricket::ContentAction action,
|
| + std::string* err) {
|
| + RTC_DCHECK(signaling_thread()->IsCurrent());
|
| +
|
| + if (!sdesc) {
|
| + return false;
|
| + }
|
| +
|
| + for (const TransportInfo& tinfo : sdesc->transport_infos()) {
|
| + if (!transport_controller_->SetRemoteTransportDescription(
|
| + tinfo.content_name, tinfo.description, action, err)) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool WebRtcSession::GetTransportDescription(
|
| + const SessionDescription* description,
|
| + const std::string& content_name,
|
| + cricket::TransportDescription* tdesc) {
|
| + if (!description || !tdesc) {
|
| + return false;
|
| + }
|
| + const TransportInfo* transport_info =
|
| + description->GetTransportInfoByName(content_name);
|
| + if (!transport_info) {
|
| + return false;
|
| + }
|
| + *tdesc = transport_info->description;
|
| + return true;
|
| +}
|
| +
|
| +bool WebRtcSession::GetTransportStats(SessionStats* stats) {
|
| ASSERT(signaling_thread()->IsCurrent());
|
| return (GetChannelTransportStats(voice_channel(), stats) &&
|
| GetChannelTransportStats(video_channel(), stats) &&
|
| @@ -1063,7 +1132,7 @@ bool WebRtcSession::GetTransportStats(cricket::SessionStats* stats) {
|
| }
|
|
|
| bool WebRtcSession::GetChannelTransportStats(cricket::BaseChannel* ch,
|
| - cricket::SessionStats* stats) {
|
| + SessionStats* stats) {
|
| ASSERT(signaling_thread()->IsCurrent());
|
| if (!ch) {
|
| // Not using this channel.
|
| @@ -1080,7 +1149,7 @@ bool WebRtcSession::GetChannelTransportStats(cricket::BaseChannel* ch,
|
| }
|
|
|
| cricket::TransportStats tstats;
|
| - if (!transport_controller()->GetStats(transport_name, &tstats)) {
|
| + if (!transport_controller_->GetStats(transport_name, &tstats)) {
|
| return false;
|
| }
|
|
|
| @@ -1092,14 +1161,14 @@ bool WebRtcSession::GetLocalCertificate(
|
| const std::string& transport_name,
|
| rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
|
| ASSERT(signaling_thread()->IsCurrent());
|
| - return transport_controller()->GetLocalCertificate(transport_name,
|
| - certificate);
|
| + return transport_controller_->GetLocalCertificate(transport_name,
|
| + certificate);
|
| }
|
|
|
| bool WebRtcSession::GetRemoteSSLCertificate(const std::string& transport_name,
|
| rtc::SSLCertificate** cert) {
|
| ASSERT(signaling_thread()->IsCurrent());
|
| - return transport_controller()->GetRemoteSSLCertificate(transport_name, cert);
|
| + return transport_controller_->GetRemoteSSLCertificate(transport_name, cert);
|
| }
|
|
|
| cricket::BaseChannel* WebRtcSession::GetChannel(
|
| @@ -1156,37 +1225,35 @@ bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) {
|
| }
|
|
|
| bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) {
|
| - if (state() == STATE_INIT) {
|
| - LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added "
|
| - << "without any offer (local or remote) "
|
| - << "session description.";
|
| + if (!remote_desc_) {
|
| + LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added "
|
| + << "without any remote session description.";
|
| return false;
|
| }
|
|
|
| if (!candidate) {
|
| - LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL";
|
| + LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL.";
|
| return false;
|
| }
|
|
|
| bool valid = false;
|
| - if (!ReadyToUseRemoteCandidate(candidate, NULL, &valid)) {
|
| - if (valid) {
|
| - LOG(LS_INFO) << "ProcessIceMessage: Candidate saved";
|
| - saved_candidates_.push_back(
|
| - new JsepIceCandidate(candidate->sdp_mid(),
|
| - candidate->sdp_mline_index(),
|
| - candidate->candidate()));
|
| - }
|
| - return valid;
|
| + bool ready = ReadyToUseRemoteCandidate(candidate, NULL, &valid);
|
| + if (!valid) {
|
| + return false;
|
| }
|
|
|
| // Add this candidate to the remote session description.
|
| if (!remote_desc_->AddCandidate(candidate)) {
|
| - LOG(LS_ERROR) << "ProcessIceMessage: Candidate cannot be used";
|
| + LOG(LS_ERROR) << "ProcessIceMessage: Candidate cannot be used.";
|
| return false;
|
| }
|
|
|
| - return UseCandidate(candidate);
|
| + if (ready) {
|
| + return UseCandidate(candidate);
|
| + } else {
|
| + LOG(LS_INFO) << "ProcessIceMessage: Not ready to use candidate.";
|
| + return true;
|
| + }
|
| }
|
|
|
| bool WebRtcSession::SetIceTransports(
|
| @@ -1195,18 +1262,37 @@ bool WebRtcSession::SetIceTransports(
|
| ConvertIceTransportTypeToCandidateFilter(type));
|
| }
|
|
|
| +cricket::IceConfig WebRtcSession::ParseIceConfig(
|
| + const PeerConnectionInterface::RTCConfiguration& config) const {
|
| + cricket::IceConfig ice_config;
|
| + ice_config.receiving_timeout_ms = config.ice_connection_receiving_timeout;
|
| + ice_config.gather_continually = (config.continual_gathering_policy ==
|
| + PeerConnectionInterface::GATHER_CONTINUALLY);
|
| + return ice_config;
|
| +}
|
| +
|
| +void WebRtcSession::SetIceConfig(const cricket::IceConfig& config) {
|
| + transport_controller_->SetIceConfig(config);
|
| +}
|
| +
|
| +void WebRtcSession::MaybeStartGathering() {
|
| + transport_controller_->MaybeStartGathering();
|
| +}
|
| +
|
| bool WebRtcSession::GetLocalTrackIdBySsrc(uint32_t ssrc,
|
| std::string* track_id) {
|
| - if (!base_local_description())
|
| + if (!local_desc_) {
|
| return false;
|
| - return webrtc::GetTrackIdBySsrc(base_local_description(), ssrc, track_id);
|
| + }
|
| + return webrtc::GetTrackIdBySsrc(local_desc_->description(), ssrc, track_id);
|
| }
|
|
|
| bool WebRtcSession::GetRemoteTrackIdBySsrc(uint32_t ssrc,
|
| std::string* track_id) {
|
| - if (!base_remote_description())
|
| + if (!remote_desc_) {
|
| return false;
|
| - return webrtc::GetTrackIdBySsrc(base_remote_description(), ssrc, track_id);
|
| + }
|
| + return webrtc::GetTrackIdBySsrc(remote_desc_->description(), ssrc, track_id);
|
| }
|
|
|
| std::string WebRtcSession::BadStateErrMsg(State state) {
|
| @@ -1317,7 +1403,8 @@ bool WebRtcSession::CanInsertDtmf(const std::string& track_id) {
|
| uint32_t send_ssrc = 0;
|
| // The Dtmf is negotiated per channel not ssrc, so we only check if the ssrc
|
| // exists.
|
| - if (!GetAudioSsrcByTrackId(base_local_description(), track_id,
|
| + if (!local_desc_ ||
|
| + !GetAudioSsrcByTrackId(local_desc_->description(), track_id,
|
| &send_ssrc)) {
|
| LOG(LS_ERROR) << "CanInsertDtmf: Track does not exist: " << track_id;
|
| return false;
|
| @@ -1333,8 +1420,8 @@ bool WebRtcSession::InsertDtmf(const std::string& track_id,
|
| return false;
|
| }
|
| uint32_t send_ssrc = 0;
|
| - if (!VERIFY(GetAudioSsrcByTrackId(base_local_description(),
|
| - track_id, &send_ssrc))) {
|
| + if (!VERIFY(local_desc_ && GetAudioSsrcByTrackId(local_desc_->description(),
|
| + track_id, &send_ssrc))) {
|
| LOG(LS_ERROR) << "InsertDtmf: Track does not exist: " << track_id;
|
| return false;
|
| }
|
| @@ -1421,7 +1508,7 @@ void WebRtcSession::ResetIceRestartLatch() {
|
|
|
| void WebRtcSession::OnCertificateReady(
|
| const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
|
| - transport_controller()->SetLocalCertificate(certificate);
|
| + transport_controller_->SetLocalCertificate(certificate);
|
| }
|
|
|
| bool WebRtcSession::waiting_for_certificate_for_testing() const {
|
| @@ -1430,7 +1517,7 @@ bool WebRtcSession::waiting_for_certificate_for_testing() const {
|
|
|
| const rtc::scoped_refptr<rtc::RTCCertificate>&
|
| WebRtcSession::certificate_for_testing() {
|
| - return transport_controller()->certificate_for_testing();
|
| + return transport_controller_->certificate_for_testing();
|
| }
|
|
|
| void WebRtcSession::SetIceConnectionState(
|
| @@ -1583,11 +1670,12 @@ void WebRtcSession::EnableChannels() {
|
| // Returns the media index for a local ice candidate given the content name.
|
| bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name,
|
| int* sdp_mline_index) {
|
| - if (!base_local_description() || !sdp_mline_index)
|
| + if (!local_desc_ || !sdp_mline_index) {
|
| return false;
|
| + }
|
|
|
| bool content_found = false;
|
| - const ContentInfos& contents = base_local_description()->contents();
|
| + const ContentInfos& contents = local_desc_->description()->contents();
|
| for (size_t index = 0; index < contents.size(); ++index) {
|
| if (contents[index].name == content_name) {
|
| *sdp_mline_index = static_cast<int>(index);
|
| @@ -1600,28 +1688,27 @@ bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name,
|
|
|
| bool WebRtcSession::UseCandidatesInSessionDescription(
|
| const SessionDescriptionInterface* remote_desc) {
|
| - if (!remote_desc)
|
| + if (!remote_desc) {
|
| return true;
|
| + }
|
| bool ret = true;
|
|
|
| for (size_t m = 0; m < remote_desc->number_of_mediasections(); ++m) {
|
| const IceCandidateCollection* candidates = remote_desc->candidates(m);
|
| - for (size_t n = 0; n < candidates->count(); ++n) {
|
| + for (size_t n = 0; n < candidates->count(); ++n) {
|
| const IceCandidateInterface* candidate = candidates->at(n);
|
| bool valid = false;
|
| if (!ReadyToUseRemoteCandidate(candidate, remote_desc, &valid)) {
|
| if (valid) {
|
| - LOG(LS_INFO) << "UseCandidatesInSessionDescription: Candidate saved.";
|
| - saved_candidates_.push_back(
|
| - new JsepIceCandidate(candidate->sdp_mid(),
|
| - candidate->sdp_mline_index(),
|
| - candidate->candidate()));
|
| + LOG(LS_INFO) << "UseCandidatesInSessionDescription: Not ready to use "
|
| + << "candidate.";
|
| }
|
| continue;
|
| }
|
| ret = UseCandidate(candidate);
|
| - if (!ret)
|
| + if (!ret) {
|
| break;
|
| + }
|
| }
|
| }
|
| return ret;
|
| @@ -1631,7 +1718,7 @@ bool WebRtcSession::UseCandidate(
|
| const IceCandidateInterface* candidate) {
|
|
|
| size_t mediacontent_index = static_cast<size_t>(candidate->sdp_mline_index());
|
| - size_t remote_content_size = base_remote_description()->contents().size();
|
| + size_t remote_content_size = remote_desc_->description()->contents().size();
|
| if (mediacontent_index >= remote_content_size) {
|
| LOG(LS_ERROR)
|
| << "UseRemoteCandidateInSession: Invalid candidate media index.";
|
| @@ -1639,13 +1726,13 @@ bool WebRtcSession::UseCandidate(
|
| }
|
|
|
| cricket::ContentInfo content =
|
| - base_remote_description()->contents()[mediacontent_index];
|
| + remote_desc_->description()->contents()[mediacontent_index];
|
| std::vector<cricket::Candidate> candidates;
|
| candidates.push_back(candidate->candidate());
|
| // Invoking BaseSession method to handle remote candidates.
|
| std::string error;
|
| - if (transport_controller()->AddRemoteCandidates(content.name, candidates,
|
| - &error)) {
|
| + if (transport_controller_->AddRemoteCandidates(content.name, candidates,
|
| + &error)) {
|
| // Candidates successfully submitted for checking.
|
| if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew ||
|
| ice_connection_state_ ==
|
| @@ -1757,7 +1844,7 @@ bool WebRtcSession::CreateChannels(const SessionDescription* desc) {
|
|
|
| bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) {
|
| voice_channel_.reset(channel_manager_->CreateVoiceChannel(
|
| - media_controller_.get(), transport_controller(), content->name, true,
|
| + media_controller_.get(), transport_controller_.get(), content->name, true,
|
| audio_options_));
|
| if (!voice_channel_) {
|
| return false;
|
| @@ -1772,7 +1859,7 @@ bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) {
|
|
|
| bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) {
|
| video_channel_.reset(channel_manager_->CreateVideoChannel(
|
| - media_controller_.get(), transport_controller(), content->name, true,
|
| + media_controller_.get(), transport_controller_.get(), content->name, true,
|
| video_options_));
|
| if (!video_channel_) {
|
| return false;
|
| @@ -1788,7 +1875,7 @@ bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) {
|
| bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) {
|
| bool sctp = (data_channel_type_ == cricket::DCT_SCTP);
|
| data_channel_.reset(channel_manager_->CreateDataChannel(
|
| - transport_controller(), content->name, !sctp, data_channel_type_));
|
| + transport_controller_.get(), content->name, !sctp, data_channel_type_));
|
| if (!data_channel_) {
|
| return false;
|
| }
|
| @@ -1806,21 +1893,8 @@ bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) {
|
| }
|
|
|
| void WebRtcSession::OnDtlsSetupFailure(cricket::BaseChannel*, bool rtcp) {
|
| - SetError(BaseSession::ERROR_TRANSPORT, rtcp ? kDtlsSetupFailureRtcp :
|
| - kDtlsSetupFailureRtp);
|
| -}
|
| -
|
| -void WebRtcSession::CopySavedCandidates(
|
| - SessionDescriptionInterface* dest_desc) {
|
| - if (!dest_desc) {
|
| - ASSERT(false);
|
| - return;
|
| - }
|
| - for (size_t i = 0; i < saved_candidates_.size(); ++i) {
|
| - dest_desc->AddCandidate(saved_candidates_[i]);
|
| - delete saved_candidates_[i];
|
| - }
|
| - saved_candidates_.clear();
|
| + SetError(ERROR_TRANSPORT,
|
| + rtcp ? kDtlsSetupFailureRtcp : kDtlsSetupFailureRtp);
|
| }
|
|
|
| void WebRtcSession::OnDataChannelMessageReceived(
|
| @@ -1881,7 +1955,7 @@ bool WebRtcSession::ValidateSessionDescription(
|
| const SessionDescriptionInterface* sdesc,
|
| cricket::ContentSource source, std::string* err_desc) {
|
| std::string type;
|
| - if (error() != cricket::BaseSession::ERROR_NONE) {
|
| + if (error() != ERROR_NONE) {
|
| return BadSdp(source, type, GetSessionErrorMsg(), err_desc);
|
| }
|
|
|
| @@ -1919,8 +1993,8 @@ bool WebRtcSession::ValidateSessionDescription(
|
| // Verify m-lines in Answer when compared against Offer.
|
| if (action == kAnswer) {
|
| const cricket::SessionDescription* offer_desc =
|
| - (source == cricket::CS_LOCAL) ? remote_description()->description() :
|
| - local_description()->description();
|
| + (source == cricket::CS_LOCAL) ? remote_desc_->description()
|
| + : local_desc_->description();
|
| if (!VerifyMediaDescriptions(sdesc->description(), offer_desc)) {
|
| return BadAnswerSdp(source, kMlineMismatch, err_desc);
|
| }
|
| @@ -1932,31 +2006,27 @@ bool WebRtcSession::ValidateSessionDescription(
|
| bool WebRtcSession::ExpectSetLocalDescription(Action action) {
|
| return ((action == kOffer && state() == STATE_INIT) ||
|
| // update local offer
|
| - (action == kOffer && state() == STATE_SENTINITIATE) ||
|
| + (action == kOffer && state() == STATE_SENTOFFER) ||
|
| // update the current ongoing session.
|
| - (action == kOffer && state() == STATE_RECEIVEDACCEPT) ||
|
| - (action == kOffer && state() == STATE_SENTACCEPT) ||
|
| (action == kOffer && state() == STATE_INPROGRESS) ||
|
| // accept remote offer
|
| - (action == kAnswer && state() == STATE_RECEIVEDINITIATE) ||
|
| - (action == kAnswer && state() == STATE_SENTPRACCEPT) ||
|
| - (action == kPrAnswer && state() == STATE_RECEIVEDINITIATE) ||
|
| - (action == kPrAnswer && state() == STATE_SENTPRACCEPT));
|
| + (action == kAnswer && state() == STATE_RECEIVEDOFFER) ||
|
| + (action == kAnswer && state() == STATE_SENTPRANSWER) ||
|
| + (action == kPrAnswer && state() == STATE_RECEIVEDOFFER) ||
|
| + (action == kPrAnswer && state() == STATE_SENTPRANSWER));
|
| }
|
|
|
| bool WebRtcSession::ExpectSetRemoteDescription(Action action) {
|
| return ((action == kOffer && state() == STATE_INIT) ||
|
| // update remote offer
|
| - (action == kOffer && state() == STATE_RECEIVEDINITIATE) ||
|
| + (action == kOffer && state() == STATE_RECEIVEDOFFER) ||
|
| // update the current ongoing session
|
| - (action == kOffer && state() == STATE_RECEIVEDACCEPT) ||
|
| - (action == kOffer && state() == STATE_SENTACCEPT) ||
|
| (action == kOffer && state() == STATE_INPROGRESS) ||
|
| // accept local offer
|
| - (action == kAnswer && state() == STATE_SENTINITIATE) ||
|
| - (action == kAnswer && state() == STATE_RECEIVEDPRACCEPT) ||
|
| - (action == kPrAnswer && state() == STATE_SENTINITIATE) ||
|
| - (action == kPrAnswer && state() == STATE_RECEIVEDPRACCEPT));
|
| + (action == kAnswer && state() == STATE_SENTOFFER) ||
|
| + (action == kAnswer && state() == STATE_RECEIVEDPRANSWER) ||
|
| + (action == kPrAnswer && state() == STATE_SENTOFFER) ||
|
| + (action == kPrAnswer && state() == STATE_RECEIVEDPRANSWER));
|
| }
|
|
|
| std::string WebRtcSession::GetSessionErrorMsg() {
|
| @@ -1978,10 +2048,11 @@ bool WebRtcSession::ReadyToUseRemoteCandidate(
|
| *valid = true;;
|
|
|
| const SessionDescriptionInterface* current_remote_desc =
|
| - remote_desc ? remote_desc : remote_description();
|
| + remote_desc ? remote_desc : remote_desc_.get();
|
|
|
| - if (!current_remote_desc)
|
| + if (!current_remote_desc) {
|
| return false;
|
| + }
|
|
|
| size_t mediacontent_index =
|
| static_cast<size_t>(candidate->sdp_mline_index());
|
| @@ -2002,7 +2073,7 @@ bool WebRtcSession::ReadyToUseRemoteCandidate(
|
| return false;
|
| }
|
|
|
| - return transport_controller()->ReadyForRemoteCandidates(
|
| + return transport_controller_->ReadyForRemoteCandidates(
|
| channel->transport_name());
|
| }
|
|
|
| @@ -2038,7 +2109,7 @@ void WebRtcSession::ReportTransportStats() {
|
| }
|
| for (const auto& name : transport_names) {
|
| cricket::TransportStats stats;
|
| - if (transport_controller()->GetStats(name, &stats)) {
|
| + if (transport_controller_->GetStats(name, &stats)) {
|
| ReportBestConnectionState(stats);
|
| ReportNegotiatedCiphers(stats);
|
| }
|
|
|