Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: talk/app/webrtc/webrtcsession.cc

Issue 1246913005: TransportController refactoring (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2012 Google Inc. 3 * Copyright 2012 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 13 matching lines...) Expand all
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28 #include "talk/app/webrtc/webrtcsession.h" 28 #include "talk/app/webrtc/webrtcsession.h"
29 29
30 #include <limits.h> 30 #include <limits.h>
31 31
32 #include <algorithm> 32 #include <algorithm>
33 #include <vector> 33 #include <vector>
34 #include <set>
34 35
35 #include "talk/app/webrtc/jsepicecandidate.h" 36 #include "talk/app/webrtc/jsepicecandidate.h"
36 #include "talk/app/webrtc/jsepsessiondescription.h" 37 #include "talk/app/webrtc/jsepsessiondescription.h"
37 #include "talk/app/webrtc/mediaconstraintsinterface.h" 38 #include "talk/app/webrtc/mediaconstraintsinterface.h"
38 #include "talk/app/webrtc/mediastreamsignaling.h" 39 #include "talk/app/webrtc/mediastreamsignaling.h"
39 #include "talk/app/webrtc/peerconnectioninterface.h" 40 #include "talk/app/webrtc/peerconnectioninterface.h"
40 #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h" 41 #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
41 #include "talk/media/base/constants.h" 42 #include "talk/media/base/constants.h"
42 #include "talk/media/base/videocapturer.h" 43 #include "talk/media/base/videocapturer.h"
43 #include "talk/session/media/channel.h" 44 #include "talk/session/media/channel.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 const char kSdpWithoutSdesCrypto[] = 80 const char kSdpWithoutSdesCrypto[] =
80 "Called with SDP without SDES crypto."; 81 "Called with SDP without SDES crypto.";
81 const char kSdpWithoutIceUfragPwd[] = 82 const char kSdpWithoutIceUfragPwd[] =
82 "Called with SDP without ice-ufrag and ice-pwd."; 83 "Called with SDP without ice-ufrag and ice-pwd.";
83 const char kSessionError[] = "Session error code: "; 84 const char kSessionError[] = "Session error code: ";
84 const char kSessionErrorDesc[] = "Session error description: "; 85 const char kSessionErrorDesc[] = "Session error description: ";
85 const char kDtlsSetupFailureRtp[] = 86 const char kDtlsSetupFailureRtp[] =
86 "Couldn't set up DTLS-SRTP on RTP channel."; 87 "Couldn't set up DTLS-SRTP on RTP channel.";
87 const char kDtlsSetupFailureRtcp[] = 88 const char kDtlsSetupFailureRtcp[] =
88 "Couldn't set up DTLS-SRTP on RTCP channel."; 89 "Couldn't set up DTLS-SRTP on RTCP channel.";
90 const char kEnableBundleFailed[] = "Failed to enable BUNDLE.";
89 const int kMaxUnsignalledRecvStreams = 20; 91 const int kMaxUnsignalledRecvStreams = 20;
90 92
91 IceCandidatePairType GetIceCandidatePairCounter( 93 IceCandidatePairType GetIceCandidatePairCounter(
92 const cricket::Candidate& local, 94 const cricket::Candidate& local,
93 const cricket::Candidate& remote) { 95 const cricket::Candidate& remote) {
94 const auto& l = local.type(); 96 const auto& l = local.type();
95 const auto& r = remote.type(); 97 const auto& r = remote.type();
96 const auto& host = LOCAL_PORT_TYPE; 98 const auto& host = LOCAL_PORT_TYPE;
97 const auto& srflx = STUN_PORT_TYPE; 99 const auto& srflx = STUN_PORT_TYPE;
98 const auto& relay = RELAY_PORT_TYPE; 100 const auto& relay = RELAY_PORT_TYPE;
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 WebRtcSession::WebRtcSession( 523 WebRtcSession::WebRtcSession(
522 cricket::ChannelManager* channel_manager, 524 cricket::ChannelManager* channel_manager,
523 rtc::Thread* signaling_thread, 525 rtc::Thread* signaling_thread,
524 rtc::Thread* worker_thread, 526 rtc::Thread* worker_thread,
525 cricket::PortAllocator* port_allocator, 527 cricket::PortAllocator* port_allocator,
526 MediaStreamSignaling* mediastream_signaling) 528 MediaStreamSignaling* mediastream_signaling)
527 : cricket::BaseSession(signaling_thread, 529 : cricket::BaseSession(signaling_thread,
528 worker_thread, 530 worker_thread,
529 port_allocator, 531 port_allocator,
530 rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX), 532 rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX),
531 cricket::NS_JINGLE_RTP,
532 false), 533 false),
533 // RFC 3264: The numeric value of the session id and version in the 534 // RFC 3264: The numeric value of the session id and version in the
534 // o line MUST be representable with a "64 bit signed integer". 535 // o line MUST be representable with a "64 bit signed integer".
535 // Due to this constraint session id |sid_| is max limited to LLONG_MAX. 536 // Due to this constraint session id |sid_| is max limited to LLONG_MAX.
536 channel_manager_(channel_manager), 537 channel_manager_(channel_manager),
537 mediastream_signaling_(mediastream_signaling), 538 mediastream_signaling_(mediastream_signaling),
538 ice_observer_(NULL), 539 ice_observer_(NULL),
539 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), 540 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
540 ice_connection_receiving_(true), 541 ice_connection_receiving_(true),
541 older_version_remote_peer_(false), 542 older_version_remote_peer_(false),
542 dtls_enabled_(false), 543 dtls_enabled_(false),
543 data_channel_type_(cricket::DCT_NONE), 544 data_channel_type_(cricket::DCT_NONE),
544 ice_restart_latch_(new IceRestartAnswerLatch), 545 ice_restart_latch_(new IceRestartAnswerLatch),
545 metrics_observer_(NULL) { 546 metrics_observer_(NULL) {
547 transport_controller()->SignalConnectionState.connect(
548 this, &WebRtcSession::OnTransportControllerConnectionState);
549 transport_controller()->SignalReceiving.connect(
550 this, &WebRtcSession::OnTransportControllerReceiving);
551 transport_controller()->SignalGatheringState.connect(
552 this, &WebRtcSession::OnTransportControllerGatheringState);
553 transport_controller()->SignalCandidatesGathered.connect(
554 this, &WebRtcSession::OnTransportControllerCandidatesGathered);
546 } 555 }
547 556
548 WebRtcSession::~WebRtcSession() { 557 WebRtcSession::~WebRtcSession() {
549 ASSERT(signaling_thread()->IsCurrent()); 558 ASSERT(signaling_thread()->IsCurrent());
550 // Destroy video_channel_ first since it may have a pointer to the 559 // Destroy video_channel_ first since it may have a pointer to the
551 // voice_channel_. 560 // voice_channel_.
552 if (video_channel_) { 561 if (video_channel_) {
553 SignalVideoChannelDestroyed(); 562 SignalVideoChannelDestroyed();
554 channel_manager_->DestroyVideoChannel(video_channel_.release()); 563 channel_manager_->DestroyVideoChannel(video_channel_.release());
555 } 564 }
(...skipping 10 matching lines...) Expand all
566 } 575 }
567 } 576 }
568 577
569 bool WebRtcSession::Initialize( 578 bool WebRtcSession::Initialize(
570 const PeerConnectionFactoryInterface::Options& options, 579 const PeerConnectionFactoryInterface::Options& options,
571 const MediaConstraintsInterface* constraints, 580 const MediaConstraintsInterface* constraints,
572 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, 581 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
573 const PeerConnectionInterface::RTCConfiguration& rtc_configuration) { 582 const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
574 bundle_policy_ = rtc_configuration.bundle_policy; 583 bundle_policy_ = rtc_configuration.bundle_policy;
575 rtcp_mux_policy_ = rtc_configuration.rtcp_mux_policy; 584 rtcp_mux_policy_ = rtc_configuration.rtcp_mux_policy;
576 SetSslMaxProtocolVersion(options.ssl_max_version); 585 transport_controller()->SetSslMaxProtocolVersion(options.ssl_max_version);
577 586
578 // Obtain a certificate from RTCConfiguration if any were provided (optional). 587 // Obtain a certificate from RTCConfiguration if any were provided (optional).
579 rtc::scoped_refptr<rtc::RTCCertificate> certificate; 588 rtc::scoped_refptr<rtc::RTCCertificate> certificate;
580 if (!rtc_configuration.certificates.empty()) { 589 if (!rtc_configuration.certificates.empty()) {
581 // TODO(hbos,torbjorng): Decide on certificate-selection strategy instead of 590 // TODO(hbos,torbjorng): Decide on certificate-selection strategy instead of
582 // just picking the first one. The decision should be made based on the DTLS 591 // just picking the first one. The decision should be made based on the DTLS
583 // handshake. The DTLS negotiations need to know about all certificates. 592 // handshake. The DTLS negotiations need to know about all certificates.
584 certificate = rtc_configuration.certificates[0]; 593 certificate = rtc_configuration.certificates[0];
585 } 594 }
586 595
587 // TODO(perkj): Take |constraints| into consideration. Return false if not all 596 // TODO(perkj): Take |constraints| into consideration. Return false if not all
588 // mandatory constraints can be fulfilled. Note that |constraints| 597 // mandatory constraints can be fulfilled. Note that |constraints|
589 // can be null. 598 // can be null.
590 bool value; 599 bool value;
591 600
592 if (options.disable_encryption) { 601 if (options.disable_encryption) {
593 dtls_enabled_ = false; 602 dtls_enabled_ = false;
594 } else { 603 } else {
595 // Enable DTLS by default if we have an identity store or a certificate. 604 // Enable DTLS by default if we have an identity store or a certificate.
596 dtls_enabled_ = (dtls_identity_store || certificate); 605 dtls_enabled_ = (dtls_identity_store || certificate);
597 // |constraints| can override the default |dtls_enabled_| value. 606 // |constraints| can override the default |dtls_enabled_| value.
598 if (FindConstraint( 607 if (FindConstraint(constraints, MediaConstraintsInterface::kEnableDtlsSrtp,
599 constraints, 608 &value, nullptr)) {
600 MediaConstraintsInterface::kEnableDtlsSrtp,
601 &value, nullptr)) {
602 dtls_enabled_ = value; 609 dtls_enabled_ = value;
603 } 610 }
604 } 611 }
605 612
606 // Enable creation of RTP data channels if the kEnableRtpDataChannels is set. 613 // Enable creation of RTP data channels if the kEnableRtpDataChannels is set.
607 // It takes precendence over the disable_sctp_data_channels 614 // It takes precendence over the disable_sctp_data_channels
608 // PeerConnectionFactoryInterface::Options. 615 // PeerConnectionFactoryInterface::Options.
609 if (FindConstraint( 616 if (FindConstraint(
610 constraints, MediaConstraintsInterface::kEnableRtpDataChannels, 617 constraints, MediaConstraintsInterface::kEnableRtpDataChannels,
611 &value, NULL) && value) { 618 &value, NULL) && value) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 JsepSessionDescription::kMaxVideoCodecWidth, 718 JsepSessionDescription::kMaxVideoCodecWidth,
712 JsepSessionDescription::kMaxVideoCodecHeight, 719 JsepSessionDescription::kMaxVideoCodecHeight,
713 JsepSessionDescription::kDefaultVideoCodecFramerate, 720 JsepSessionDescription::kDefaultVideoCodecFramerate,
714 JsepSessionDescription::kDefaultVideoCodecPreference); 721 JsepSessionDescription::kDefaultVideoCodecPreference);
715 channel_manager_->SetDefaultVideoEncoderConfig( 722 channel_manager_->SetDefaultVideoEncoderConfig(
716 cricket::VideoEncoderConfig(default_codec)); 723 cricket::VideoEncoderConfig(default_codec));
717 724
718 if (!dtls_enabled_) { 725 if (!dtls_enabled_) {
719 // Construct with DTLS disabled. 726 // Construct with DTLS disabled.
720 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( 727 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory(
721 signaling_thread(), 728 signaling_thread(), channel_manager_, mediastream_signaling_, this,
722 channel_manager_, 729 id(), data_channel_type_));
723 mediastream_signaling_,
724 this,
725 id(),
726 data_channel_type_));
727 } else { 730 } else {
728 // Construct with DTLS enabled. 731 // Construct with DTLS enabled.
729 if (!certificate) { 732 if (!certificate) {
730 // Use the |dtls_identity_store| to generate a certificate. 733 // Use the |dtls_identity_store| to generate a certificate.
731 DCHECK(dtls_identity_store); 734 DCHECK(dtls_identity_store);
732 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( 735 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory(
733 signaling_thread(), 736 signaling_thread(), channel_manager_, mediastream_signaling_,
734 channel_manager_, 737 dtls_identity_store.Pass(), this, id(), data_channel_type_));
735 mediastream_signaling_,
736 dtls_identity_store.Pass(),
737 this,
738 id(),
739 data_channel_type_));
740 } else { 738 } else {
741 // Use the already generated certificate. 739 // Use the already generated certificate.
742 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( 740 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory(
743 signaling_thread(), 741 signaling_thread(), channel_manager_, mediastream_signaling_,
744 channel_manager_, 742 certificate, this, id(), data_channel_type_));
745 mediastream_signaling_,
746 certificate,
747 this,
748 id(),
749 data_channel_type_));
750 } 743 }
751 } 744 }
752 745
753 webrtc_session_desc_factory_->SignalCertificateReady.connect( 746 webrtc_session_desc_factory_->SignalCertificateReady.connect(
754 this, &WebRtcSession::OnCertificateReady); 747 this, &WebRtcSession::OnCertificateReady);
755 748
756 if (options.disable_encryption) { 749 if (options.disable_encryption) {
757 webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED); 750 webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED);
758 } 751 }
759 port_allocator()->set_candidate_filter( 752 port_allocator()->set_candidate_filter(
760 ConvertIceTransportTypeToCandidateFilter(rtc_configuration.type)); 753 ConvertIceTransportTypeToCandidateFilter(rtc_configuration.type));
761 754
762 if (rtc_configuration.enable_localhost_ice_candidate) { 755 if (rtc_configuration.enable_localhost_ice_candidate) {
763 port_allocator()->set_flags( 756 port_allocator()->set_flags(
764 port_allocator()->flags() | 757 port_allocator()->flags() |
765 cricket::PORTALLOCATOR_ENABLE_LOCALHOST_CANDIDATE); 758 cricket::PORTALLOCATOR_ENABLE_LOCALHOST_CANDIDATE);
766 } 759 }
767 760
768 return true; 761 return true;
769 } 762 }
770 763
771 void WebRtcSession::Terminate() { 764 void WebRtcSession::Terminate() {
772 SetState(STATE_RECEIVEDTERMINATE); 765 SetState(STATE_RECEIVEDTERMINATE);
773 RemoveUnusedChannelsAndTransports(NULL); 766 RemoveUnusedChannels(NULL);
774 ASSERT(!voice_channel_); 767 ASSERT(!voice_channel_);
775 ASSERT(!video_channel_); 768 ASSERT(!video_channel_);
776 ASSERT(!data_channel_); 769 ASSERT(!data_channel_);
777 } 770 }
778 771
779 bool WebRtcSession::StartCandidatesAllocation() {
780 // SpeculativelyConnectTransportChannels, will call ConnectChannels method
781 // from TransportProxy to start gathering ice candidates.
782 SpeculativelyConnectAllTransportChannels();
783 if (!saved_candidates_.empty()) {
784 // If there are saved candidates which arrived before local description is
785 // set, copy those to remote description.
786 CopySavedCandidates(remote_desc_.get());
787 }
788 // Push remote candidates present in remote description to transport channels.
789 UseCandidatesInSessionDescription(remote_desc_.get());
790 return true;
791 }
792
793 void WebRtcSession::SetSdesPolicy(cricket::SecurePolicy secure_policy) { 772 void WebRtcSession::SetSdesPolicy(cricket::SecurePolicy secure_policy) {
794 webrtc_session_desc_factory_->SetSdesPolicy(secure_policy); 773 webrtc_session_desc_factory_->SetSdesPolicy(secure_policy);
795 } 774 }
796 775
797 cricket::SecurePolicy WebRtcSession::SdesPolicy() const { 776 cricket::SecurePolicy WebRtcSession::SdesPolicy() const {
798 return webrtc_session_desc_factory_->SdesPolicy(); 777 return webrtc_session_desc_factory_->SdesPolicy();
799 } 778 }
800 779
801 bool WebRtcSession::GetSslRole(rtc::SSLRole* role) { 780 bool WebRtcSession::GetSslRole(rtc::SSLRole* role) {
802 if (local_description() == NULL || remote_description() == NULL) { 781 if (local_description() == NULL || remote_description() == NULL) {
803 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get " 782 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get "
804 << "SSL Role of the session."; 783 << "SSL Role of the session.";
805 return false; 784 return false;
806 } 785 }
807 786
808 // TODO(mallinath) - Return role of each transport, as role may differ from 787 return transport_controller()->GetSslRole(role);
809 // one another.
810 // In current implementaion we just return the role of first transport in the
811 // transport map.
812 for (cricket::TransportMap::const_iterator iter = transport_proxies().begin();
813 iter != transport_proxies().end(); ++iter) {
814 if (iter->second->impl()) {
815 return iter->second->impl()->GetSslRole(role);
816 }
817 }
818 return false;
819 } 788 }
820 789
821 void WebRtcSession::CreateOffer( 790 void WebRtcSession::CreateOffer(
822 CreateSessionDescriptionObserver* observer, 791 CreateSessionDescriptionObserver* observer,
823 const PeerConnectionInterface::RTCOfferAnswerOptions& options) { 792 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
824 webrtc_session_desc_factory_->CreateOffer(observer, options); 793 webrtc_session_desc_factory_->CreateOffer(observer, options);
825 } 794 }
826 795
827 void WebRtcSession::CreateAnswer(CreateSessionDescriptionObserver* observer, 796 void WebRtcSession::CreateAnswer(CreateSessionDescriptionObserver* observer,
828 const MediaConstraintsInterface* constraints) { 797 const MediaConstraintsInterface* constraints) {
829 webrtc_session_desc_factory_->CreateAnswer(observer, constraints); 798 webrtc_session_desc_factory_->CreateAnswer(observer, constraints);
830 } 799 }
831 800
832 bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc, 801 bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,
833 std::string* err_desc) { 802 std::string* err_desc) {
803 ASSERT(signaling_thread()->IsCurrent());
804
834 // Takes the ownership of |desc| regardless of the result. 805 // Takes the ownership of |desc| regardless of the result.
835 rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc); 806 rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc);
836 807
837 // Validate SDP. 808 // Validate SDP.
838 if (!ValidateSessionDescription(desc, cricket::CS_LOCAL, err_desc)) { 809 if (!ValidateSessionDescription(desc, cricket::CS_LOCAL, err_desc)) {
839 return false; 810 return false;
840 } 811 }
841 812
842 // Update the initiator flag if this session is the initiator. 813 // Update the initiator flag if this session is the initiator.
843 Action action = GetAction(desc->type()); 814 Action action = GetAction(desc->type());
(...skipping 12 matching lines...) Expand all
856 set_local_description(desc->description()->Copy()); 827 set_local_description(desc->description()->Copy());
857 local_desc_.reset(desc_temp.release()); 828 local_desc_.reset(desc_temp.release());
858 829
859 // Transport and Media channels will be created only when offer is set. 830 // Transport and Media channels will be created only when offer is set.
860 if (action == kOffer && !CreateChannels(local_desc_->description())) { 831 if (action == kOffer && !CreateChannels(local_desc_->description())) {
861 // TODO(mallinath) - Handle CreateChannel failure, as new local description 832 // TODO(mallinath) - Handle CreateChannel failure, as new local description
862 // is applied. Restore back to old description. 833 // is applied. Restore back to old description.
863 return BadLocalSdp(desc->type(), kCreateChannelFailed, err_desc); 834 return BadLocalSdp(desc->type(), kCreateChannelFailed, err_desc);
864 } 835 }
865 836
866 // Remove channel and transport proxies, if MediaContentDescription is 837 // Even though we already enable BUNDLE in CreateChannels when using
867 // rejected. 838 // kBundlePolicyMaxBundle, this handles the situation where the remote peer
868 RemoveUnusedChannelsAndTransports(local_desc_->description()); 839 // doesn't support BUNDLE, and we only should end up connecting one transport.
pthatcher1 2015/08/31 22:01:35 only should => should only
Taylor Brandstetter 2015/09/01 23:53:29 Done.
840 if (bundle_policy_ == PeerConnectionInterface::kBundlePolicyMaxBundle) {
841 const cricket::ContentGroup* local_bundle =
842 BaseSession::local_description()->GetGroupByName(
843 cricket::GROUP_TYPE_BUNDLE);
844 if (!local_bundle) {
845 LOG(LS_WARNING) << "max-bundle specified without BUNDLE specified";
846 return false;
847 }
848 if (!EnableBundle(*local_bundle)) {
849 LOG(LS_WARNING) << "max-bundle failed to enable bundling.";
850 return false;
851 }
852 }
853
854 // Remove unused channels if MediaContentDescription is rejected.
855 RemoveUnusedChannels(local_desc_->description());
869 856
870 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) { 857 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) {
871 return false; 858 return false;
872 } 859 }
873 860
874 // Kick starting the ice candidates allocation. 861 if (remote_description()) {
875 StartCandidatesAllocation(); 862 // Now that we have a local description, we can push down remote candidates
863 // that we stored, and those from the remote description.
864 if (!saved_candidates_.empty()) {
865 // If there are saved candidates which arrived before the local
866 // description was set, copy those to the remote description.
867 CopySavedCandidates(remote_desc_.get());
868 }
869 // Push remote candidates in remote description to transport channels.
870 UseCandidatesInSessionDescription(remote_desc_.get());
871 }
876 872
877 // Update state and SSRC of local MediaStreams and DataChannels based on the 873 // Update state and SSRC of local MediaStreams and DataChannels based on the
878 // local session description. 874 // local session description.
879 mediastream_signaling_->OnLocalDescriptionChanged(local_desc_.get()); 875 mediastream_signaling_->OnLocalDescriptionChanged(local_desc_.get());
880 876
881 rtc::SSLRole role; 877 rtc::SSLRole role;
882 if (data_channel_type_ == cricket::DCT_SCTP && GetSslRole(&role)) { 878 if (data_channel_type_ == cricket::DCT_SCTP && GetSslRole(&role)) {
883 mediastream_signaling_->OnDtlsRoleReadyForSctp(role); 879 mediastream_signaling_->OnDtlsRoleReadyForSctp(role);
884 } 880 }
885 if (error() != cricket::BaseSession::ERROR_NONE) { 881 if (error() != cricket::BaseSession::ERROR_NONE) {
886 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc); 882 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc);
887 } 883 }
888 return true; 884 return true;
889 } 885 }
890 886
891 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc, 887 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
892 std::string* err_desc) { 888 std::string* err_desc) {
889 ASSERT(signaling_thread()->IsCurrent());
890
893 // Takes the ownership of |desc| regardless of the result. 891 // Takes the ownership of |desc| regardless of the result.
894 rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc); 892 rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc);
895 893
896 // Validate SDP. 894 // Validate SDP.
897 if (!ValidateSessionDescription(desc, cricket::CS_REMOTE, err_desc)) { 895 if (!ValidateSessionDescription(desc, cricket::CS_REMOTE, err_desc)) {
898 return false; 896 return false;
899 } 897 }
900 898
901 // Transport and Media channels will be created only when offer is set. 899 // Transport and Media channels will be created only when offer is set.
902 Action action = GetAction(desc->type()); 900 Action action = GetAction(desc->type());
903 if (action == kOffer && !CreateChannels(desc->description())) { 901 if (action == kOffer && !CreateChannels(desc->description())) {
904 // TODO(mallinath) - Handle CreateChannel failure, as new local description 902 // TODO(mallinath) - Handle CreateChannel failure, as new local description
905 // is applied. Restore back to old description. 903 // is applied. Restore back to old description.
906 return BadRemoteSdp(desc->type(), kCreateChannelFailed, err_desc); 904 return BadRemoteSdp(desc->type(), kCreateChannelFailed, err_desc);
907 } 905 }
908 906
909 // Remove channel and transport proxies, if MediaContentDescription is 907 // Remove unused channels if MediaContentDescription is rejected.
910 // rejected. 908 RemoveUnusedChannels(desc->description());
911 RemoveUnusedChannelsAndTransports(desc->description());
912 909
913 // NOTE: Candidates allocation will be initiated only when SetLocalDescription 910 // NOTE: Candidates allocation will be initiated only when SetLocalDescription
914 // is called. 911 // is called.
915 set_remote_description(desc->description()->Copy()); 912 set_remote_description(desc->description()->Copy());
916 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) { 913 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) {
917 return false; 914 return false;
918 } 915 }
919 916
920 // Update remote MediaStreams. 917 // Update remote MediaStreams.
921 mediastream_signaling_->OnRemoteDescriptionChanged(desc); 918 mediastream_signaling_->OnRemoteDescriptionChanged(desc);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 if (desc->type() != SessionDescriptionInterface::kOffer && 957 if (desc->type() != SessionDescriptionInterface::kOffer &&
961 ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew) { 958 ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew) {
962 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking); 959 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
963 } 960 }
964 return true; 961 return true;
965 } 962 }
966 963
967 bool WebRtcSession::UpdateSessionState( 964 bool WebRtcSession::UpdateSessionState(
968 Action action, cricket::ContentSource source, 965 Action action, cricket::ContentSource source,
969 std::string* err_desc) { 966 std::string* err_desc) {
967 ASSERT(signaling_thread()->IsCurrent());
968
970 // If there's already a pending error then no state transition should happen. 969 // If there's already a pending error then no state transition should happen.
971 // But all call-sites should be verifying this before calling us! 970 // But all call-sites should be verifying this before calling us!
972 ASSERT(error() == cricket::BaseSession::ERROR_NONE); 971 ASSERT(error() == cricket::BaseSession::ERROR_NONE);
973 std::string td_err; 972 std::string td_err;
974 if (action == kOffer) { 973 if (action == kOffer) {
975 if (!PushdownTransportDescription(source, cricket::CA_OFFER, &td_err)) { 974 if (!PushdownTransportDescription(source, cricket::CA_OFFER, &td_err)) {
976 return BadOfferSdp(source, MakeTdErrorString(td_err), err_desc); 975 return BadOfferSdp(source, MakeTdErrorString(td_err), err_desc);
977 } 976 }
978 SetState(source == cricket::CS_LOCAL ? 977 SetState(source == cricket::CS_LOCAL ?
979 STATE_SENTINITIATE : STATE_RECEIVEDINITIATE); 978 STATE_SENTINITIATE : STATE_RECEIVEDINITIATE);
(...skipping 13 matching lines...) Expand all
993 if (!PushdownMediaDescription(cricket::CA_PRANSWER, source, err_desc)) { 992 if (!PushdownMediaDescription(cricket::CA_PRANSWER, source, err_desc)) {
994 SetError(BaseSession::ERROR_CONTENT, *err_desc); 993 SetError(BaseSession::ERROR_CONTENT, *err_desc);
995 } 994 }
996 if (error() != cricket::BaseSession::ERROR_NONE) { 995 if (error() != cricket::BaseSession::ERROR_NONE) {
997 return BadPranswerSdp(source, GetSessionErrorMsg(), err_desc); 996 return BadPranswerSdp(source, GetSessionErrorMsg(), err_desc);
998 } 997 }
999 } else if (action == kAnswer) { 998 } else if (action == kAnswer) {
1000 if (!PushdownTransportDescription(source, cricket::CA_ANSWER, &td_err)) { 999 if (!PushdownTransportDescription(source, cricket::CA_ANSWER, &td_err)) {
1001 return BadAnswerSdp(source, MakeTdErrorString(td_err), err_desc); 1000 return BadAnswerSdp(source, MakeTdErrorString(td_err), err_desc);
1002 } 1001 }
1003 MaybeEnableMuxingSupport(); 1002 const cricket::ContentGroup* local_bundle =
1003 BaseSession::local_description()->GetGroupByName(
1004 cricket::GROUP_TYPE_BUNDLE);
1005 const cricket::ContentGroup* remote_bundle =
1006 BaseSession::remote_description()->GetGroupByName(
1007 cricket::GROUP_TYPE_BUNDLE);
1008 if (local_bundle && remote_bundle) {
1009 // The answerer decides the transport to bundle on
1010 const cricket::ContentGroup* answer_bundle =
1011 (source == cricket::CS_LOCAL ? local_bundle : remote_bundle);
1012 if (!EnableBundle(*answer_bundle)) {
1013 LOG(LS_WARNING) << "Failed to enable BUNDLE.";
1014 return BadAnswerSdp(source, kEnableBundleFailed, err_desc);
1015 }
1016 }
1004 EnableChannels(); 1017 EnableChannels();
1005 SetState(source == cricket::CS_LOCAL ? 1018 SetState(source == cricket::CS_LOCAL ?
1006 STATE_SENTACCEPT : STATE_RECEIVEDACCEPT); 1019 STATE_SENTACCEPT : STATE_RECEIVEDACCEPT);
1007 if (!PushdownMediaDescription(cricket::CA_ANSWER, source, err_desc)) { 1020 if (!PushdownMediaDescription(cricket::CA_ANSWER, source, err_desc)) {
1008 SetError(BaseSession::ERROR_CONTENT, *err_desc); 1021 SetError(BaseSession::ERROR_CONTENT, *err_desc);
1009 } 1022 }
1010 if (error() != cricket::BaseSession::ERROR_NONE) { 1023 if (error() != cricket::BaseSession::ERROR_NONE) {
1011 return BadAnswerSdp(source, GetSessionErrorMsg(), err_desc); 1024 return BadAnswerSdp(source, GetSessionErrorMsg(), err_desc);
1012 } 1025 }
1013 } 1026 }
(...skipping 28 matching lines...) Expand all
1042 return WebRtcSession::kPrAnswer; 1055 return WebRtcSession::kPrAnswer;
1043 } else if (type == SessionDescriptionInterface::kAnswer) { 1056 } else if (type == SessionDescriptionInterface::kAnswer) {
1044 return WebRtcSession::kAnswer; 1057 return WebRtcSession::kAnswer;
1045 } 1058 }
1046 ASSERT(false && "unknown action type"); 1059 ASSERT(false && "unknown action type");
1047 return WebRtcSession::kOffer; 1060 return WebRtcSession::kOffer;
1048 } 1061 }
1049 1062
1050 bool WebRtcSession::GetTransportStats(cricket::SessionStats* stats) { 1063 bool WebRtcSession::GetTransportStats(cricket::SessionStats* stats) {
1051 ASSERT(signaling_thread()->IsCurrent()); 1064 ASSERT(signaling_thread()->IsCurrent());
1065 return (GetChannelTransportStats(voice_channel(), stats) &&
1066 GetChannelTransportStats(video_channel(), stats) &&
1067 GetChannelTransportStats(data_channel(), stats));
1068 }
1052 1069
1053 const auto get_transport_stats = [stats](const std::string& content_name, 1070 bool WebRtcSession::GetChannelTransportStats(cricket::BaseChannel* ch,
1054 cricket::Transport* transport) { 1071 cricket::SessionStats* stats) {
1055 const std::string& transport_id = transport->content_name(); 1072 ASSERT(signaling_thread()->IsCurrent());
1056 stats->proxy_to_transport[content_name] = transport_id; 1073 if (!ch) {
1057 if (stats->transport_stats.find(transport_id) 1074 // Not using this channel.
1058 != stats->transport_stats.end()) { 1075 return true;
1059 // Transport stats already done for this transport. 1076 }
1060 return true;
1061 }
1062 1077
1063 cricket::TransportStats tstats; 1078 const std::string& content_name = ch->content_name();
1064 if (!transport->GetStats(&tstats)) { 1079 const std::string& transport_name = ch->transport_name();
1065 return false; 1080 stats->proxy_to_transport[content_name] = transport_name;
1066 } 1081 if (stats->transport_stats.find(transport_name) !=
1082 stats->transport_stats.end()) {
1083 // Transport stats already done for this transport.
1084 return true;
1085 }
1067 1086
1068 stats->transport_stats[transport_id] = tstats; 1087 cricket::TransportStats tstats;
1069 return true; 1088 if (!transport_controller()->GetStats(transport_name, &tstats)) {
1070 }; 1089 return false;
1090 }
1071 1091
1072 for (const auto& kv : transport_proxies()) { 1092 stats->transport_stats[transport_name] = tstats;
1073 cricket::Transport* transport = kv.second->impl();
1074 if (transport && !get_transport_stats(kv.first, transport)) {
1075 return false;
1076 }
1077 }
1078 return true; 1093 return true;
1079 } 1094 }
1080 1095
1096 bool WebRtcSession::GetCertificate(
1097 const std::string& content_name,
1098 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
1099 ASSERT(signaling_thread()->IsCurrent());
1100
1101 cricket::BaseChannel* ch = GetChannel(content_name);
1102 if (!ch) {
1103 return false;
1104 }
1105
1106 return transport_controller()->GetCertificate(ch->transport_name(),
1107 certificate);
1108 }
1109
1110 bool WebRtcSession::GetRemoteCertificate(const std::string& content_name,
1111 rtc::SSLCertificate** cert) {
1112 ASSERT(signaling_thread()->IsCurrent());
1113
1114 cricket::BaseChannel* ch = GetChannel(content_name);
1115 if (!ch) {
1116 return false;
1117 }
1118
1119 return transport_controller()->GetRemoteCertificate(ch->transport_name(),
1120 cert);
1121 }
1122
1123 cricket::BaseChannel* WebRtcSession::GetChannel(
1124 const std::string& content_name) {
1125 if (voice_channel() && voice_channel()->content_name() == content_name) {
1126 return voice_channel();
1127 }
1128 if (video_channel() && video_channel()->content_name() == content_name) {
1129 return video_channel();
1130 }
1131 if (data_channel() && data_channel()->content_name() == content_name) {
1132 return data_channel();
1133 }
1134 return nullptr;
1135 }
1136
1137 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) {
1138 const std::string* first_content_name = bundle.FirstContentName();
1139 if (!first_content_name) {
1140 LOG(LS_WARNING) << "Tried to BUNDLE with no contents.";
1141 return false;
1142 }
1143 const std::string& transport_name = *first_content_name;
1144 cricket::BaseChannel* first_channel = GetChannel(transport_name);
1145
1146 auto maybe_set_transport =
1147 [this, bundle, transport_name, first_channel](cricket::BaseChannel* ch) {
1148 if (!ch || !bundle.HasContentName(ch->content_name())) {
1149 return true;
1150 }
1151
1152 if (ch->transport_name() == transport_name) {
1153 LOG(LS_INFO) << "BUNDLE already enabled for " << ch->content_name()
1154 << " on " << transport_name << ".";
1155 return true;
1156 }
1157
1158 if (!ch->SetTransport(transport_name)) {
1159 LOG(LS_WARNING) << "Failed to enable BUNDLE for "
1160 << ch->content_name();
1161 return false;
1162 }
1163 LOG(LS_INFO) << "Enabled BUNDLE for " << ch->content_name() << " on "
1164 << transport_name << ".";
1165 return true;
1166 };
1167
1168 if (!maybe_set_transport(voice_channel()) ||
1169 !maybe_set_transport(video_channel()) ||
1170 !maybe_set_transport(data_channel())) {
1171 return false;
1172 }
1173
1174 return true;
1175 }
1176
1081 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) { 1177 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) {
1082 if (state() == STATE_INIT) { 1178 if (state() == STATE_INIT) {
1083 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added " 1179 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added "
1084 << "without any offer (local or remote) " 1180 << "without any offer (local or remote) "
1085 << "session description."; 1181 << "session description.";
1086 return false; 1182 return false;
1087 } 1183 }
1088 1184
1089 if (!candidate) { 1185 if (!candidate) {
1090 LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL"; 1186 LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL";
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 bool WebRtcSession::IceRestartPending() const { 1482 bool WebRtcSession::IceRestartPending() const {
1387 return ice_restart_latch_->Get(); 1483 return ice_restart_latch_->Get();
1388 } 1484 }
1389 1485
1390 void WebRtcSession::ResetIceRestartLatch() { 1486 void WebRtcSession::ResetIceRestartLatch() {
1391 ice_restart_latch_->Reset(); 1487 ice_restart_latch_->Reset();
1392 } 1488 }
1393 1489
1394 void WebRtcSession::OnCertificateReady( 1490 void WebRtcSession::OnCertificateReady(
1395 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { 1491 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
1396 SetCertificate(certificate); 1492 transport_controller()->SetCertificate(certificate);
1397 } 1493 }
1398 1494
1399 bool WebRtcSession::waiting_for_certificate_for_testing() const { 1495 bool WebRtcSession::waiting_for_certificate_for_testing() const {
1400 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); 1496 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing();
1401 } 1497 }
1402 1498
1499 rtc::scoped_refptr<rtc::RTCCertificate>
1500 WebRtcSession::certificate_for_testing() {
1501 return transport_controller()->certificate_for_testing();
1502 }
1503
1403 void WebRtcSession::SetIceConnectionState( 1504 void WebRtcSession::SetIceConnectionState(
1404 PeerConnectionInterface::IceConnectionState state) { 1505 PeerConnectionInterface::IceConnectionState state) {
1405 if (ice_connection_state_ == state) { 1506 if (ice_connection_state_ == state) {
1406 return; 1507 return;
1407 } 1508 }
1408 1509
1409 // ASSERT that the requested transition is allowed. Note that 1510 // ASSERT that the requested transition is allowed. Note that
1410 // WebRtcSession does not implement "kIceConnectionClosed" (that is handled 1511 // WebRtcSession does not implement "kIceConnectionClosed" (that is handled
1411 // within PeerConnection). This switch statement should compile away when 1512 // within PeerConnection). This switch statement should compile away when
1412 // ASSERTs are disabled. 1513 // ASSERTs are disabled.
1514 LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1515 << " => " << state;
1413 switch (ice_connection_state_) { 1516 switch (ice_connection_state_) {
1414 case PeerConnectionInterface::kIceConnectionNew: 1517 case PeerConnectionInterface::kIceConnectionNew:
1415 ASSERT(state == PeerConnectionInterface::kIceConnectionChecking); 1518 ASSERT(state == PeerConnectionInterface::kIceConnectionChecking);
1416 break; 1519 break;
1417 case PeerConnectionInterface::kIceConnectionChecking: 1520 case PeerConnectionInterface::kIceConnectionChecking:
1418 ASSERT(state == PeerConnectionInterface::kIceConnectionFailed || 1521 ASSERT(state == PeerConnectionInterface::kIceConnectionFailed ||
1419 state == PeerConnectionInterface::kIceConnectionConnected); 1522 state == PeerConnectionInterface::kIceConnectionConnected);
1420 break; 1523 break;
1421 case PeerConnectionInterface::kIceConnectionConnected: 1524 case PeerConnectionInterface::kIceConnectionConnected:
1422 ASSERT(state == PeerConnectionInterface::kIceConnectionDisconnected || 1525 ASSERT(state == PeerConnectionInterface::kIceConnectionDisconnected ||
(...skipping 20 matching lines...) Expand all
1443 ASSERT(false); 1546 ASSERT(false);
1444 break; 1547 break;
1445 } 1548 }
1446 1549
1447 ice_connection_state_ = state; 1550 ice_connection_state_ = state;
1448 if (ice_observer_) { 1551 if (ice_observer_) {
1449 ice_observer_->OnIceConnectionChange(ice_connection_state_); 1552 ice_observer_->OnIceConnectionChange(ice_connection_state_);
1450 } 1553 }
1451 } 1554 }
1452 1555
1453 void WebRtcSession::OnTransportRequestSignaling( 1556 void WebRtcSession::OnTransportControllerConnectionState(
1454 cricket::Transport* transport) { 1557 cricket::IceConnectionState state) {
1455 ASSERT(signaling_thread()->IsCurrent()); 1558 switch (state) {
1456 transport->OnSignalingReady(); 1559 case cricket::kIceConnectionConnecting:
1457 if (ice_observer_) { 1560 // If the current state is Connected or Completed, then there were
1458 ice_observer_->OnIceGatheringChange( 1561 // writable channels but now there are not, so the next state must
1459 PeerConnectionInterface::kIceGatheringGathering); 1562 // be Disconnected.
1563 if (ice_connection_state_ ==
1564 PeerConnectionInterface::kIceConnectionConnected ||
1565 ice_connection_state_ ==
1566 PeerConnectionInterface::kIceConnectionCompleted) {
1567 SetIceConnectionState(
1568 PeerConnectionInterface::kIceConnectionDisconnected);
1569 }
pthatcher1 2015/08/31 22:01:35 Can you put a comment about why we don't move to k
Taylor Brandstetter 2015/09/01 23:53:30 Done. This will all get cleaned up later in a sepa
1570 break;
1571 case cricket::kIceConnectionFailed:
1572 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
1573 break;
1574 case cricket::kIceConnectionConnected:
1575 LOG(LS_INFO) << "Changing to ICE connected state because "
1576 << "all transports are writable.";
1577 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
1578 break;
1579 case cricket::kIceConnectionCompleted:
1580 LOG(LS_INFO) << "Changing to ICE completed state because "
1581 << "all transports are complete.";
1582 if (ice_connection_state_ !=
1583 PeerConnectionInterface::kIceConnectionConnected) {
1584 // If jumping directly from "checking" to "connected",
1585 // signal "connected" first.
1586 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
1587 }
1588 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
1589 if (metrics_observer_) {
pthatcher1 2015/08/31 22:01:35 Can you move this block into a ReportTranportStats
Taylor Brandstetter 2015/09/01 23:53:30 Done.
1590 // Once ICE connection is completed, report stats for all transports
1591 // in use.
1592 std::set<std::string> transport_names;
1593 if (voice_channel()) {
1594 transport_names.insert(voice_channel()->transport_name());
1595 }
1596 if (video_channel()) {
1597 transport_names.insert(video_channel()->transport_name());
1598 }
1599 if (data_channel()) {
1600 transport_names.insert(data_channel()->transport_name());
1601 }
1602 for (auto name : transport_names) {
1603 cricket::TransportStats stats;
1604 if (transport_controller()->GetStats(name, &stats)) {
1605 ReportBestConnectionState(stats);
1606 ReportNegotiatedCiphers(stats);
1607 }
1608 }
1609 }
1610 break;
1611 default:
1612 ASSERT(false);
1460 } 1613 }
1461 } 1614 }
1462 1615
1463 void WebRtcSession::OnTransportConnecting(cricket::Transport* transport) { 1616 void WebRtcSession::OnTransportControllerReceiving(bool receiving) {
1464 ASSERT(signaling_thread()->IsCurrent());
1465 // start monitoring for the write state of the transport.
1466 OnTransportWritable(transport);
1467 }
1468
1469 void WebRtcSession::OnTransportWritable(cricket::Transport* transport) {
1470 ASSERT(signaling_thread()->IsCurrent());
1471 if (transport->all_channels_writable()) {
1472 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
1473 } else if (transport->HasChannels()) {
1474 // If the current state is Connected or Completed, then there were writable
1475 // channels but now there are not, so the next state must be Disconnected.
1476 if (ice_connection_state_ ==
1477 PeerConnectionInterface::kIceConnectionConnected ||
1478 ice_connection_state_ ==
1479 PeerConnectionInterface::kIceConnectionCompleted) {
1480 SetIceConnectionState(
1481 PeerConnectionInterface::kIceConnectionDisconnected);
1482 }
1483 }
1484 }
1485
1486 void WebRtcSession::OnTransportCompleted(cricket::Transport* transport) {
1487 ASSERT(signaling_thread()->IsCurrent());
1488 PeerConnectionInterface::IceConnectionState old_state = ice_connection_state_;
1489 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
1490 // Only report once when Ice connection is completed.
1491 if (old_state != PeerConnectionInterface::kIceConnectionCompleted) {
1492 cricket::TransportStats stats;
1493 if (metrics_observer_ && transport->GetStats(&stats)) {
1494 ReportBestConnectionState(stats);
1495 ReportNegotiatedCiphers(stats);
1496 }
1497 }
1498 }
1499
1500 void WebRtcSession::OnTransportFailed(cricket::Transport* transport) {
1501 ASSERT(signaling_thread()->IsCurrent());
1502 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
1503 }
1504
1505 void WebRtcSession::OnTransportReceiving(cricket::Transport* transport) {
1506 ASSERT(signaling_thread()->IsCurrent());
1507 // The ice connection is considered receiving if at least one transport is
1508 // receiving on any channels.
1509 bool receiving = false;
1510 for (const auto& kv : transport_proxies()) {
1511 cricket::Transport* transport = kv.second->impl();
1512 if (transport && transport->any_channel_receiving()) {
1513 receiving = true;
1514 break;
1515 }
1516 }
1517 SetIceConnectionReceiving(receiving); 1617 SetIceConnectionReceiving(receiving);
1518 } 1618 }
1519 1619
1520 void WebRtcSession::SetIceConnectionReceiving(bool receiving) { 1620 void WebRtcSession::SetIceConnectionReceiving(bool receiving) {
1521 if (ice_connection_receiving_ == receiving) { 1621 if (ice_connection_receiving_ == receiving) {
1522 return; 1622 return;
1523 } 1623 }
1524 ice_connection_receiving_ = receiving; 1624 ice_connection_receiving_ = receiving;
1525 if (ice_observer_) { 1625 if (ice_observer_) {
1526 ice_observer_->OnIceConnectionReceivingChange(receiving); 1626 ice_observer_->OnIceConnectionReceivingChange(receiving);
1527 } 1627 }
1528 } 1628 }
1529 1629
1530 void WebRtcSession::OnTransportProxyCandidatesReady( 1630 void WebRtcSession::OnTransportControllerCandidatesGathered(
1531 cricket::TransportProxy* proxy, const cricket::Candidates& candidates) { 1631 const std::string& transport_name,
1632 const cricket::Candidates& candidates) {
1532 ASSERT(signaling_thread()->IsCurrent()); 1633 ASSERT(signaling_thread()->IsCurrent());
1533 ProcessNewLocalCandidate(proxy->content_name(), candidates); 1634 int sdp_mline_index;
1534 } 1635 if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
1636 LOG(LS_ERROR) << "OnTransportControllerCandidatesGathered: content name "
1637 << transport_name << " not found";
1638 return;
1639 }
1535 1640
1536 void WebRtcSession::OnCandidatesAllocationDone() { 1641 for (cricket::Candidates::const_iterator citer = candidates.begin();
1537 ASSERT(signaling_thread()->IsCurrent()); 1642 citer != candidates.end(); ++citer) {
1538 if (ice_observer_) { 1643 // Use transport_name as the candidate media id.
1539 ice_observer_->OnIceGatheringChange( 1644 JsepIceCandidate candidate(transport_name, sdp_mline_index, *citer);
1540 PeerConnectionInterface::kIceGatheringComplete); 1645 if (ice_observer_) {
1541 ice_observer_->OnIceComplete(); 1646 ice_observer_->OnIceCandidate(&candidate);
1647 }
1648 if (local_desc_) {
1649 local_desc_->AddCandidate(&candidate);
1650 }
1542 } 1651 }
1543 } 1652 }
1544 1653
1545 // Enabling voice and video channel. 1654 // Enabling voice and video channel.
1546 void WebRtcSession::EnableChannels() { 1655 void WebRtcSession::EnableChannels() {
1547 if (voice_channel_ && !voice_channel_->enabled()) 1656 if (voice_channel_ && !voice_channel_->enabled())
1548 voice_channel_->Enable(true); 1657 voice_channel_->Enable(true);
1549 1658
1550 if (video_channel_ && !video_channel_->enabled()) 1659 if (video_channel_ && !video_channel_->enabled())
1551 video_channel_->Enable(true); 1660 video_channel_->Enable(true);
1552 1661
1553 if (data_channel_ && !data_channel_->enabled()) 1662 if (data_channel_ && !data_channel_->enabled())
1554 data_channel_->Enable(true); 1663 data_channel_->Enable(true);
1555 } 1664 }
1556 1665
1557 void WebRtcSession::ProcessNewLocalCandidate(
1558 const std::string& content_name,
1559 const cricket::Candidates& candidates) {
1560 int sdp_mline_index;
1561 if (!GetLocalCandidateMediaIndex(content_name, &sdp_mline_index)) {
1562 LOG(LS_ERROR) << "ProcessNewLocalCandidate: content name "
1563 << content_name << " not found";
1564 return;
1565 }
1566
1567 for (cricket::Candidates::const_iterator citer = candidates.begin();
1568 citer != candidates.end(); ++citer) {
1569 // Use content_name as the candidate media id.
1570 JsepIceCandidate candidate(content_name, sdp_mline_index, *citer);
1571 if (ice_observer_) {
1572 ice_observer_->OnIceCandidate(&candidate);
1573 }
1574 if (local_desc_) {
1575 local_desc_->AddCandidate(&candidate);
1576 }
1577 }
1578 }
1579
1580 // Returns the media index for a local ice candidate given the content name. 1666 // Returns the media index for a local ice candidate given the content name.
1581 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name, 1667 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name,
1582 int* sdp_mline_index) { 1668 int* sdp_mline_index) {
1583 if (!base_local_description() || !sdp_mline_index) 1669 if (!base_local_description() || !sdp_mline_index)
1584 return false; 1670 return false;
1585 1671
1586 bool content_found = false; 1672 bool content_found = false;
1587 const ContentInfos& contents = base_local_description()->contents(); 1673 const ContentInfos& contents = base_local_description()->contents();
1588 for (size_t index = 0; index < contents.size(); ++index) { 1674 for (size_t index = 0; index < contents.size(); ++index) {
1589 if (contents[index].name == content_name) { 1675 if (contents[index].name == content_name) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 << "UseRemoteCandidateInSession: Invalid candidate media index."; 1720 << "UseRemoteCandidateInSession: Invalid candidate media index.";
1635 return false; 1721 return false;
1636 } 1722 }
1637 1723
1638 cricket::ContentInfo content = 1724 cricket::ContentInfo content =
1639 base_remote_description()->contents()[mediacontent_index]; 1725 base_remote_description()->contents()[mediacontent_index];
1640 std::vector<cricket::Candidate> candidates; 1726 std::vector<cricket::Candidate> candidates;
1641 candidates.push_back(candidate->candidate()); 1727 candidates.push_back(candidate->candidate());
1642 // Invoking BaseSession method to handle remote candidates. 1728 // Invoking BaseSession method to handle remote candidates.
1643 std::string error; 1729 std::string error;
1644 if (OnRemoteCandidates(content.name, candidates, &error)) { 1730 if (transport_controller()->AddRemoteCandidates(content.name, candidates,
1731 &error)) {
1645 // Candidates successfully submitted for checking. 1732 // Candidates successfully submitted for checking.
1646 if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew || 1733 if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew ||
1647 ice_connection_state_ == 1734 ice_connection_state_ ==
1648 PeerConnectionInterface::kIceConnectionDisconnected) { 1735 PeerConnectionInterface::kIceConnectionDisconnected) {
1649 // If state is New, then the session has just gotten its first remote ICE 1736 // If state is New, then the session has just gotten its first remote ICE
1650 // candidates, so go to Checking. 1737 // candidates, so go to Checking.
1651 // If state is Disconnected, the session is re-using old candidates or 1738 // If state is Disconnected, the session is re-using old candidates or
1652 // receiving additional ones, so go to Checking. 1739 // receiving additional ones, so go to Checking.
1653 // If state is Connected, stay Connected. 1740 // If state is Connected, stay Connected.
1654 // TODO(bemasc): If state is Connected, and the new candidates are for a 1741 // TODO(bemasc): If state is Connected, and the new candidates are for a
1655 // newly added transport, then the state actually _should_ move to 1742 // newly added transport, then the state actually _should_ move to
1656 // checking. Add a way to distinguish that case. 1743 // checking. Add a way to distinguish that case.
1657 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking); 1744 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
1658 } 1745 }
1659 // TODO(bemasc): If state is Completed, go back to Connected. 1746 // TODO(bemasc): If state is Completed, go back to Connected.
1660 } else { 1747 } else {
1661 if (!error.empty()) { 1748 if (!error.empty()) {
1662 LOG(LS_WARNING) << error; 1749 LOG(LS_WARNING) << error;
1663 } 1750 }
1664 } 1751 }
1665 return true; 1752 return true;
1666 } 1753 }
1667 1754
1668 void WebRtcSession::RemoveUnusedChannelsAndTransports( 1755 void WebRtcSession::RemoveUnusedChannels(const SessionDescription* desc) {
1669 const SessionDescription* desc) {
1670 // Destroy video_channel_ first since it may have a pointer to the 1756 // Destroy video_channel_ first since it may have a pointer to the
1671 // voice_channel_. 1757 // voice_channel_.
1672 const cricket::ContentInfo* video_info = 1758 const cricket::ContentInfo* video_info =
1673 cricket::GetFirstVideoContent(desc); 1759 cricket::GetFirstVideoContent(desc);
1674 if ((!video_info || video_info->rejected) && video_channel_) { 1760 if ((!video_info || video_info->rejected) && video_channel_) {
1675 mediastream_signaling_->OnVideoChannelClose(); 1761 mediastream_signaling_->OnVideoChannelClose();
1676 SignalVideoChannelDestroyed(); 1762 SignalVideoChannelDestroyed();
1677 const std::string content_name = video_channel_->content_name(); 1763 const std::string content_name = video_channel_->content_name();
1678 channel_manager_->DestroyVideoChannel(video_channel_.release()); 1764 channel_manager_->DestroyVideoChannel(video_channel_.release());
1679 DestroyTransportProxy(content_name);
1680 } 1765 }
1681 1766
1682 const cricket::ContentInfo* voice_info = 1767 const cricket::ContentInfo* voice_info =
1683 cricket::GetFirstAudioContent(desc); 1768 cricket::GetFirstAudioContent(desc);
1684 if ((!voice_info || voice_info->rejected) && voice_channel_) { 1769 if ((!voice_info || voice_info->rejected) && voice_channel_) {
1685 mediastream_signaling_->OnAudioChannelClose(); 1770 mediastream_signaling_->OnAudioChannelClose();
1686 SignalVoiceChannelDestroyed(); 1771 SignalVoiceChannelDestroyed();
1687 const std::string content_name = voice_channel_->content_name(); 1772 const std::string content_name = voice_channel_->content_name();
1688 channel_manager_->DestroyVoiceChannel(voice_channel_.release(), 1773 channel_manager_->DestroyVoiceChannel(voice_channel_.release(),
1689 video_channel_.get()); 1774 video_channel_.get());
1690 DestroyTransportProxy(content_name);
1691 } 1775 }
1692 1776
1693 const cricket::ContentInfo* data_info = 1777 const cricket::ContentInfo* data_info =
1694 cricket::GetFirstDataContent(desc); 1778 cricket::GetFirstDataContent(desc);
1695 if ((!data_info || data_info->rejected) && data_channel_) { 1779 if ((!data_info || data_info->rejected) && data_channel_) {
1696 mediastream_signaling_->OnDataChannelClose(); 1780 mediastream_signaling_->OnDataChannelClose();
1697 SignalDataChannelDestroyed(); 1781 SignalDataChannelDestroyed();
1698 const std::string content_name = data_channel_->content_name(); 1782 const std::string content_name = data_channel_->content_name();
1699 channel_manager_->DestroyDataChannel(data_channel_.release()); 1783 channel_manager_->DestroyDataChannel(data_channel_.release());
1700 DestroyTransportProxy(content_name);
1701 } 1784 }
1702 } 1785 }
1703 1786
1704 // TODO(mallinath) - Add a correct error code if the channels are not creatued 1787 // TODO(mallinath) - Add a correct error code if the channels are not creatued
1705 // due to BUNDLE is enabled but rtcp-mux is disabled. 1788 // due to BUNDLE is enabled but rtcp-mux is disabled.
1706 bool WebRtcSession::CreateChannels(const SessionDescription* desc) { 1789 bool WebRtcSession::CreateChannels(const SessionDescription* desc) {
1707 // Creating the media channels and transport proxies. 1790 // Creating the media channels and transport proxies.
1708 const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc); 1791 const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc);
1709 if (voice && !voice->rejected && !voice_channel_) { 1792 if (voice && !voice->rejected && !voice_channel_) {
1710 if (!CreateVoiceChannel(voice)) { 1793 if (!CreateVoiceChannel(voice)) {
(...skipping 24 matching lines...) Expand all
1735 voice_channel()->ActivateRtcpMux(); 1818 voice_channel()->ActivateRtcpMux();
1736 } 1819 }
1737 if (video_channel()) { 1820 if (video_channel()) {
1738 video_channel()->ActivateRtcpMux(); 1821 video_channel()->ActivateRtcpMux();
1739 } 1822 }
1740 if (data_channel()) { 1823 if (data_channel()) {
1741 data_channel()->ActivateRtcpMux(); 1824 data_channel()->ActivateRtcpMux();
1742 } 1825 }
1743 } 1826 }
1744 1827
1745 // Enable bundle before when kMaxBundle policy is in effect. 1828 // Enable BUNDLE immediately when kBundlePolicyMaxBundle is in effect.
1746 if (bundle_policy_ == PeerConnectionInterface::kBundlePolicyMaxBundle) { 1829 if (bundle_policy_ == PeerConnectionInterface::kBundlePolicyMaxBundle) {
1747 const cricket::ContentGroup* bundle_group = desc->GetGroupByName( 1830 const cricket::ContentGroup* bundle_group = desc->GetGroupByName(
1748 cricket::GROUP_TYPE_BUNDLE); 1831 cricket::GROUP_TYPE_BUNDLE);
1749 if (!bundle_group) { 1832 if (!bundle_group) {
1750 LOG(LS_WARNING) << "max-bundle specified without BUNDLE specified"; 1833 LOG(LS_WARNING) << "max-bundle specified without BUNDLE specified";
1751 return false; 1834 return false;
1752 } 1835 }
1753 if (!BaseSession::BundleContentGroup(bundle_group)) { 1836 if (!EnableBundle(*bundle_group)) {
1754 LOG(LS_WARNING) << "max-bundle failed to enable bundling."; 1837 LOG(LS_WARNING) << "max-bundle failed to enable bundling.";
1755 return false; 1838 return false;
1756 } 1839 }
1757 } 1840 }
1758 1841
1759 return true; 1842 return true;
1760 } 1843 }
1761 1844
1762 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) { 1845 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) {
1763 voice_channel_.reset(channel_manager_->CreateVoiceChannel( 1846 voice_channel_.reset(channel_manager_->CreateVoiceChannel(
1764 this, content->name, true, audio_options_)); 1847 transport_controller(), content->name, true, audio_options_));
1765 if (!voice_channel_) { 1848 if (!voice_channel_) {
1766 return false; 1849 return false;
1767 } 1850 }
1768 1851
1769 voice_channel_->SignalDtlsSetupFailure.connect( 1852 voice_channel_->SignalDtlsSetupFailure.connect(
1770 this, &WebRtcSession::OnDtlsSetupFailure); 1853 this, &WebRtcSession::OnDtlsSetupFailure);
1771 return true; 1854 return true;
1772 } 1855 }
1773 1856
1774 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) { 1857 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) {
1775 video_channel_.reset(channel_manager_->CreateVideoChannel( 1858 video_channel_.reset(channel_manager_->CreateVideoChannel(
1776 this, content->name, true, video_options_, voice_channel_.get())); 1859 transport_controller(), content->name, true, video_options_,
1860 voice_channel_.get()));
1777 if (!video_channel_) { 1861 if (!video_channel_) {
1778 return false; 1862 return false;
1779 } 1863 }
1780 1864
1781 video_channel_->SignalDtlsSetupFailure.connect( 1865 video_channel_->SignalDtlsSetupFailure.connect(
1782 this, &WebRtcSession::OnDtlsSetupFailure); 1866 this, &WebRtcSession::OnDtlsSetupFailure);
1783 return true; 1867 return true;
1784 } 1868 }
1785 1869
1786 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) { 1870 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) {
1787 bool sctp = (data_channel_type_ == cricket::DCT_SCTP); 1871 bool sctp = (data_channel_type_ == cricket::DCT_SCTP);
1788 data_channel_.reset(channel_manager_->CreateDataChannel( 1872 data_channel_.reset(channel_manager_->CreateDataChannel(
1789 this, content->name, !sctp, data_channel_type_)); 1873 transport_controller(), content->name, !sctp, data_channel_type_));
1790 if (!data_channel_) { 1874 if (!data_channel_) {
1791 return false; 1875 return false;
1792 } 1876 }
1793 1877
1794 if (sctp) { 1878 if (sctp) {
1795 mediastream_signaling_->OnDataTransportCreatedForSctp(); 1879 mediastream_signaling_->OnDataTransportCreatedForSctp();
1796 data_channel_->SignalDataReceived.connect( 1880 data_channel_->SignalDataReceived.connect(
1797 this, &WebRtcSession::OnDataChannelMessageReceived); 1881 this, &WebRtcSession::OnDataChannelMessageReceived);
1798 data_channel_->SignalStreamClosedRemotely.connect( 1882 data_channel_->SignalStreamClosedRemotely.connect(
1799 mediastream_signaling_, 1883 mediastream_signaling_,
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1960 // We need to check the local/remote description for the Transport instead of 2044 // We need to check the local/remote description for the Transport instead of
1961 // the session, because a new Transport added during renegotiation may have 2045 // the session, because a new Transport added during renegotiation may have
1962 // them unset while the session has them set from the previous negotiation. 2046 // them unset while the session has them set from the previous negotiation.
1963 // Not doing so may trigger the auto generation of transport description and 2047 // Not doing so may trigger the auto generation of transport description and
1964 // mess up DTLS identity information, ICE credential, etc. 2048 // mess up DTLS identity information, ICE credential, etc.
1965 bool WebRtcSession::ReadyToUseRemoteCandidate( 2049 bool WebRtcSession::ReadyToUseRemoteCandidate(
1966 const IceCandidateInterface* candidate, 2050 const IceCandidateInterface* candidate,
1967 const SessionDescriptionInterface* remote_desc, 2051 const SessionDescriptionInterface* remote_desc,
1968 bool* valid) { 2052 bool* valid) {
1969 *valid = true;; 2053 *valid = true;;
1970 cricket::TransportProxy* transport_proxy = NULL;
1971 2054
1972 const SessionDescriptionInterface* current_remote_desc = 2055 const SessionDescriptionInterface* current_remote_desc =
1973 remote_desc ? remote_desc : remote_description(); 2056 remote_desc ? remote_desc : remote_description();
1974 2057
1975 if (!current_remote_desc) 2058 if (!current_remote_desc)
1976 return false; 2059 return false;
1977 2060
1978 size_t mediacontent_index = 2061 size_t mediacontent_index =
1979 static_cast<size_t>(candidate->sdp_mline_index()); 2062 static_cast<size_t>(candidate->sdp_mline_index());
1980 size_t remote_content_size = 2063 size_t remote_content_size =
1981 current_remote_desc->description()->contents().size(); 2064 current_remote_desc->description()->contents().size();
1982 if (mediacontent_index >= remote_content_size) { 2065 if (mediacontent_index >= remote_content_size) {
1983 LOG(LS_ERROR) 2066 LOG(LS_ERROR)
1984 << "ReadyToUseRemoteCandidate: Invalid candidate media index."; 2067 << "ReadyToUseRemoteCandidate: Invalid candidate media index.";
1985 2068
1986 *valid = false; 2069 *valid = false;
1987 return false; 2070 return false;
1988 } 2071 }
1989 2072
1990 cricket::ContentInfo content = 2073 cricket::ContentInfo content =
1991 current_remote_desc->description()->contents()[mediacontent_index]; 2074 current_remote_desc->description()->contents()[mediacontent_index];
1992 transport_proxy = GetTransportProxy(content.name); 2075 cricket::BaseChannel* channel = GetChannel(content.name);
2076 if (!channel) {
2077 return false;
2078 }
1993 2079
1994 return transport_proxy && transport_proxy->local_description_set() && 2080 return transport_controller()->ReadyForRemoteCandidates(
1995 transport_proxy->remote_description_set(); 2081 channel->transport_name());
2082 }
2083
2084 void WebRtcSession::OnTransportControllerGatheringState(
2085 cricket::IceGatheringState state) {
2086 ASSERT(signaling_thread()->IsCurrent());
2087 if (state == cricket::kIceGatheringGathering) {
2088 if (ice_observer_) {
2089 ice_observer_->OnIceGatheringChange(
2090 PeerConnectionInterface::kIceGatheringGathering);
2091 }
2092 } else if (state == cricket::kIceGatheringComplete) {
2093 if (ice_observer_) {
2094 ice_observer_->OnIceGatheringChange(
2095 PeerConnectionInterface::kIceGatheringComplete);
2096 ice_observer_->OnIceComplete();
2097 }
2098 }
1996 } 2099 }
1997 2100
1998 // Walk through the ConnectionInfos to gather best connection usage 2101 // Walk through the ConnectionInfos to gather best connection usage
1999 // for IPv4 and IPv6. 2102 // for IPv4 and IPv6.
2000 void WebRtcSession::ReportBestConnectionState( 2103 void WebRtcSession::ReportBestConnectionState(
2001 const cricket::TransportStats& stats) { 2104 const cricket::TransportStats& stats) {
2002 DCHECK(metrics_observer_ != NULL); 2105 DCHECK(metrics_observer_ != NULL);
2003 for (cricket::TransportChannelStatsList::const_iterator it = 2106 for (cricket::TransportChannelStatsList::const_iterator it =
2004 stats.channel_stats.begin(); 2107 stats.channel_stats.begin();
2005 it != stats.channel_stats.end(); ++it) { 2108 it != stats.channel_stats.end(); ++it) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2085 2188
2086 if (!srtp_cipher.empty()) { 2189 if (!srtp_cipher.empty()) {
2087 metrics_observer_->AddHistogramSample(srtp_name, srtp_cipher); 2190 metrics_observer_->AddHistogramSample(srtp_name, srtp_cipher);
2088 } 2191 }
2089 if (!ssl_cipher.empty()) { 2192 if (!ssl_cipher.empty()) {
2090 metrics_observer_->AddHistogramSample(ssl_name, ssl_cipher); 2193 metrics_observer_->AddHistogramSample(ssl_name, ssl_cipher);
2091 } 2194 }
2092 } 2195 }
2093 2196
2094 } // namespace webrtc 2197 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698