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

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: More renaming, formatting and other polish 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 should only end up connecting one transport.
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::GetLocalCertificate(
1097 const std::string& transport_name,
1098 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
1099 ASSERT(signaling_thread()->IsCurrent());
1100 return transport_controller()->GetLocalCertificate(transport_name,
1101 certificate);
1102 }
1103
1104 bool WebRtcSession::GetRemoteCertificate(const std::string& transport_name,
1105 rtc::SSLCertificate** cert) {
1106 ASSERT(signaling_thread()->IsCurrent());
1107 return transport_controller()->GetRemoteCertificate(transport_name, cert);
1108 }
1109
1110 cricket::BaseChannel* WebRtcSession::GetChannel(
1111 const std::string& content_name) {
1112 if (voice_channel() && voice_channel()->content_name() == content_name) {
1113 return voice_channel();
1114 }
1115 if (video_channel() && video_channel()->content_name() == content_name) {
1116 return video_channel();
1117 }
1118 if (data_channel() && data_channel()->content_name() == content_name) {
1119 return data_channel();
1120 }
1121 return nullptr;
1122 }
1123
1124 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) {
1125 const std::string* first_content_name = bundle.FirstContentName();
1126 if (!first_content_name) {
1127 LOG(LS_WARNING) << "Tried to BUNDLE with no contents.";
1128 return false;
1129 }
1130 const std::string& transport_name = *first_content_name;
1131 cricket::BaseChannel* first_channel = GetChannel(transport_name);
1132
1133 auto maybe_set_transport =
1134 [this, bundle, transport_name, first_channel](cricket::BaseChannel* ch) {
1135 if (!ch || !bundle.HasContentName(ch->content_name())) {
1136 return true;
1137 }
1138
1139 if (ch->transport_name() == transport_name) {
1140 LOG(LS_INFO) << "BUNDLE already enabled for " << ch->content_name()
1141 << " on " << transport_name << ".";
1142 return true;
1143 }
1144
1145 if (!ch->SetTransport(transport_name)) {
1146 LOG(LS_WARNING) << "Failed to enable BUNDLE for "
1147 << ch->content_name();
1148 return false;
1149 }
1150 LOG(LS_INFO) << "Enabled BUNDLE for " << ch->content_name() << " on "
1151 << transport_name << ".";
1152 return true;
1153 };
1154
1155 if (!maybe_set_transport(voice_channel()) ||
1156 !maybe_set_transport(video_channel()) ||
1157 !maybe_set_transport(data_channel())) {
1158 return false;
1159 }
1160
1161 return true;
1162 }
1163
1081 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) { 1164 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) {
1082 if (state() == STATE_INIT) { 1165 if (state() == STATE_INIT) {
1083 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added " 1166 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added "
1084 << "without any offer (local or remote) " 1167 << "without any offer (local or remote) "
1085 << "session description."; 1168 << "session description.";
1086 return false; 1169 return false;
1087 } 1170 }
1088 1171
1089 if (!candidate) { 1172 if (!candidate) {
1090 LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL"; 1173 LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL";
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 bool WebRtcSession::IceRestartPending() const { 1469 bool WebRtcSession::IceRestartPending() const {
1387 return ice_restart_latch_->Get(); 1470 return ice_restart_latch_->Get();
1388 } 1471 }
1389 1472
1390 void WebRtcSession::ResetIceRestartLatch() { 1473 void WebRtcSession::ResetIceRestartLatch() {
1391 ice_restart_latch_->Reset(); 1474 ice_restart_latch_->Reset();
1392 } 1475 }
1393 1476
1394 void WebRtcSession::OnCertificateReady( 1477 void WebRtcSession::OnCertificateReady(
1395 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { 1478 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
1396 SetCertificate(certificate); 1479 transport_controller()->SetLocalCertificate(certificate);
1397 } 1480 }
1398 1481
1399 bool WebRtcSession::waiting_for_certificate_for_testing() const { 1482 bool WebRtcSession::waiting_for_certificate_for_testing() const {
1400 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); 1483 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing();
1401 } 1484 }
1402 1485
1486 const rtc::scoped_refptr<rtc::RTCCertificate>&
1487 WebRtcSession::certificate_for_testing() {
1488 return transport_controller()->certificate_for_testing();
1489 }
1490
1403 void WebRtcSession::SetIceConnectionState( 1491 void WebRtcSession::SetIceConnectionState(
1404 PeerConnectionInterface::IceConnectionState state) { 1492 PeerConnectionInterface::IceConnectionState state) {
1405 if (ice_connection_state_ == state) { 1493 if (ice_connection_state_ == state) {
1406 return; 1494 return;
1407 } 1495 }
1408 1496
1409 // ASSERT that the requested transition is allowed. Note that 1497 // ASSERT that the requested transition is allowed. Note that
1410 // WebRtcSession does not implement "kIceConnectionClosed" (that is handled 1498 // WebRtcSession does not implement "kIceConnectionClosed" (that is handled
1411 // within PeerConnection). This switch statement should compile away when 1499 // within PeerConnection). This switch statement should compile away when
1412 // ASSERTs are disabled. 1500 // ASSERTs are disabled.
1501 LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1502 << " => " << state;
1413 switch (ice_connection_state_) { 1503 switch (ice_connection_state_) {
1414 case PeerConnectionInterface::kIceConnectionNew: 1504 case PeerConnectionInterface::kIceConnectionNew:
1415 ASSERT(state == PeerConnectionInterface::kIceConnectionChecking); 1505 ASSERT(state == PeerConnectionInterface::kIceConnectionChecking);
1416 break; 1506 break;
1417 case PeerConnectionInterface::kIceConnectionChecking: 1507 case PeerConnectionInterface::kIceConnectionChecking:
1418 ASSERT(state == PeerConnectionInterface::kIceConnectionFailed || 1508 ASSERT(state == PeerConnectionInterface::kIceConnectionFailed ||
1419 state == PeerConnectionInterface::kIceConnectionConnected); 1509 state == PeerConnectionInterface::kIceConnectionConnected);
1420 break; 1510 break;
1421 case PeerConnectionInterface::kIceConnectionConnected: 1511 case PeerConnectionInterface::kIceConnectionConnected:
1422 ASSERT(state == PeerConnectionInterface::kIceConnectionDisconnected || 1512 ASSERT(state == PeerConnectionInterface::kIceConnectionDisconnected ||
(...skipping 20 matching lines...) Expand all
1443 ASSERT(false); 1533 ASSERT(false);
1444 break; 1534 break;
1445 } 1535 }
1446 1536
1447 ice_connection_state_ = state; 1537 ice_connection_state_ = state;
1448 if (ice_observer_) { 1538 if (ice_observer_) {
1449 ice_observer_->OnIceConnectionChange(ice_connection_state_); 1539 ice_observer_->OnIceConnectionChange(ice_connection_state_);
1450 } 1540 }
1451 } 1541 }
1452 1542
1453 void WebRtcSession::OnTransportRequestSignaling( 1543 void WebRtcSession::OnTransportControllerConnectionState(
1454 cricket::Transport* transport) { 1544 cricket::IceConnectionState state) {
1455 ASSERT(signaling_thread()->IsCurrent()); 1545 switch (state) {
1456 transport->OnSignalingReady(); 1546 case cricket::kIceConnectionConnecting:
1457 if (ice_observer_) { 1547 // If the current state is Connected or Completed, then there were
1458 ice_observer_->OnIceGatheringChange( 1548 // writable channels but now there are not, so the next state must
1459 PeerConnectionInterface::kIceGatheringGathering); 1549 // be Disconnected.
1550 // kIceConnectionConnecting is currently used as the default,
1551 // un-connected state by the TransportController, so its only use is
1552 // detecting disconnections.
1553 if (ice_connection_state_ ==
1554 PeerConnectionInterface::kIceConnectionConnected ||
1555 ice_connection_state_ ==
1556 PeerConnectionInterface::kIceConnectionCompleted) {
1557 SetIceConnectionState(
1558 PeerConnectionInterface::kIceConnectionDisconnected);
1559 }
1560 break;
1561 case cricket::kIceConnectionFailed:
1562 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
1563 break;
1564 case cricket::kIceConnectionConnected:
1565 LOG(LS_INFO) << "Changing to ICE connected state because "
1566 << "all transports are writable.";
1567 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
1568 break;
1569 case cricket::kIceConnectionCompleted:
1570 LOG(LS_INFO) << "Changing to ICE completed state because "
1571 << "all transports are complete.";
1572 if (ice_connection_state_ !=
1573 PeerConnectionInterface::kIceConnectionConnected) {
1574 // If jumping directly from "checking" to "connected",
1575 // signal "connected" first.
1576 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
1577 }
1578 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
1579 if (metrics_observer_) {
1580 ReportTransportStats();
1581 }
1582 break;
1583 default:
1584 ASSERT(false);
1460 } 1585 }
1461 } 1586 }
1462 1587
1463 void WebRtcSession::OnTransportConnecting(cricket::Transport* transport) { 1588 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); 1589 SetIceConnectionReceiving(receiving);
1518 } 1590 }
1519 1591
1520 void WebRtcSession::SetIceConnectionReceiving(bool receiving) { 1592 void WebRtcSession::SetIceConnectionReceiving(bool receiving) {
1521 if (ice_connection_receiving_ == receiving) { 1593 if (ice_connection_receiving_ == receiving) {
1522 return; 1594 return;
1523 } 1595 }
1524 ice_connection_receiving_ = receiving; 1596 ice_connection_receiving_ = receiving;
1525 if (ice_observer_) { 1597 if (ice_observer_) {
1526 ice_observer_->OnIceConnectionReceivingChange(receiving); 1598 ice_observer_->OnIceConnectionReceivingChange(receiving);
1527 } 1599 }
1528 } 1600 }
1529 1601
1530 void WebRtcSession::OnTransportProxyCandidatesReady( 1602 void WebRtcSession::OnTransportControllerCandidatesGathered(
1531 cricket::TransportProxy* proxy, const cricket::Candidates& candidates) { 1603 const std::string& transport_name,
1604 const cricket::Candidates& candidates) {
1532 ASSERT(signaling_thread()->IsCurrent()); 1605 ASSERT(signaling_thread()->IsCurrent());
1533 ProcessNewLocalCandidate(proxy->content_name(), candidates); 1606 int sdp_mline_index;
1534 } 1607 if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
1608 LOG(LS_ERROR) << "OnTransportControllerCandidatesGathered: content name "
1609 << transport_name << " not found";
1610 return;
1611 }
1535 1612
1536 void WebRtcSession::OnCandidatesAllocationDone() { 1613 for (cricket::Candidates::const_iterator citer = candidates.begin();
1537 ASSERT(signaling_thread()->IsCurrent()); 1614 citer != candidates.end(); ++citer) {
1538 if (ice_observer_) { 1615 // Use transport_name as the candidate media id.
1539 ice_observer_->OnIceGatheringChange( 1616 JsepIceCandidate candidate(transport_name, sdp_mline_index, *citer);
1540 PeerConnectionInterface::kIceGatheringComplete); 1617 if (ice_observer_) {
1541 ice_observer_->OnIceComplete(); 1618 ice_observer_->OnIceCandidate(&candidate);
1619 }
1620 if (local_desc_) {
1621 local_desc_->AddCandidate(&candidate);
1622 }
1542 } 1623 }
1543 } 1624 }
1544 1625
1545 // Enabling voice and video channel. 1626 // Enabling voice and video channel.
1546 void WebRtcSession::EnableChannels() { 1627 void WebRtcSession::EnableChannels() {
1547 if (voice_channel_ && !voice_channel_->enabled()) 1628 if (voice_channel_ && !voice_channel_->enabled())
1548 voice_channel_->Enable(true); 1629 voice_channel_->Enable(true);
1549 1630
1550 if (video_channel_ && !video_channel_->enabled()) 1631 if (video_channel_ && !video_channel_->enabled())
1551 video_channel_->Enable(true); 1632 video_channel_->Enable(true);
1552 1633
1553 if (data_channel_ && !data_channel_->enabled()) 1634 if (data_channel_ && !data_channel_->enabled())
1554 data_channel_->Enable(true); 1635 data_channel_->Enable(true);
1555 } 1636 }
1556 1637
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. 1638 // Returns the media index for a local ice candidate given the content name.
1581 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name, 1639 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name,
1582 int* sdp_mline_index) { 1640 int* sdp_mline_index) {
1583 if (!base_local_description() || !sdp_mline_index) 1641 if (!base_local_description() || !sdp_mline_index)
1584 return false; 1642 return false;
1585 1643
1586 bool content_found = false; 1644 bool content_found = false;
1587 const ContentInfos& contents = base_local_description()->contents(); 1645 const ContentInfos& contents = base_local_description()->contents();
1588 for (size_t index = 0; index < contents.size(); ++index) { 1646 for (size_t index = 0; index < contents.size(); ++index) {
1589 if (contents[index].name == content_name) { 1647 if (contents[index].name == content_name) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 << "UseRemoteCandidateInSession: Invalid candidate media index."; 1692 << "UseRemoteCandidateInSession: Invalid candidate media index.";
1635 return false; 1693 return false;
1636 } 1694 }
1637 1695
1638 cricket::ContentInfo content = 1696 cricket::ContentInfo content =
1639 base_remote_description()->contents()[mediacontent_index]; 1697 base_remote_description()->contents()[mediacontent_index];
1640 std::vector<cricket::Candidate> candidates; 1698 std::vector<cricket::Candidate> candidates;
1641 candidates.push_back(candidate->candidate()); 1699 candidates.push_back(candidate->candidate());
1642 // Invoking BaseSession method to handle remote candidates. 1700 // Invoking BaseSession method to handle remote candidates.
1643 std::string error; 1701 std::string error;
1644 if (OnRemoteCandidates(content.name, candidates, &error)) { 1702 if (transport_controller()->AddRemoteCandidates(content.name, candidates,
1703 &error)) {
1645 // Candidates successfully submitted for checking. 1704 // Candidates successfully submitted for checking.
1646 if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew || 1705 if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew ||
1647 ice_connection_state_ == 1706 ice_connection_state_ ==
1648 PeerConnectionInterface::kIceConnectionDisconnected) { 1707 PeerConnectionInterface::kIceConnectionDisconnected) {
1649 // If state is New, then the session has just gotten its first remote ICE 1708 // If state is New, then the session has just gotten its first remote ICE
1650 // candidates, so go to Checking. 1709 // candidates, so go to Checking.
1651 // If state is Disconnected, the session is re-using old candidates or 1710 // If state is Disconnected, the session is re-using old candidates or
1652 // receiving additional ones, so go to Checking. 1711 // receiving additional ones, so go to Checking.
1653 // If state is Connected, stay Connected. 1712 // If state is Connected, stay Connected.
1654 // TODO(bemasc): If state is Connected, and the new candidates are for a 1713 // TODO(bemasc): If state is Connected, and the new candidates are for a
1655 // newly added transport, then the state actually _should_ move to 1714 // newly added transport, then the state actually _should_ move to
1656 // checking. Add a way to distinguish that case. 1715 // checking. Add a way to distinguish that case.
1657 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking); 1716 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
1658 } 1717 }
1659 // TODO(bemasc): If state is Completed, go back to Connected. 1718 // TODO(bemasc): If state is Completed, go back to Connected.
1660 } else { 1719 } else {
1661 if (!error.empty()) { 1720 if (!error.empty()) {
1662 LOG(LS_WARNING) << error; 1721 LOG(LS_WARNING) << error;
1663 } 1722 }
1664 } 1723 }
1665 return true; 1724 return true;
1666 } 1725 }
1667 1726
1668 void WebRtcSession::RemoveUnusedChannelsAndTransports( 1727 void WebRtcSession::RemoveUnusedChannels(const SessionDescription* desc) {
1669 const SessionDescription* desc) {
1670 // Destroy video_channel_ first since it may have a pointer to the 1728 // Destroy video_channel_ first since it may have a pointer to the
1671 // voice_channel_. 1729 // voice_channel_.
1672 const cricket::ContentInfo* video_info = 1730 const cricket::ContentInfo* video_info =
1673 cricket::GetFirstVideoContent(desc); 1731 cricket::GetFirstVideoContent(desc);
1674 if ((!video_info || video_info->rejected) && video_channel_) { 1732 if ((!video_info || video_info->rejected) && video_channel_) {
1675 mediastream_signaling_->OnVideoChannelClose(); 1733 mediastream_signaling_->OnVideoChannelClose();
1676 SignalVideoChannelDestroyed(); 1734 SignalVideoChannelDestroyed();
1677 const std::string content_name = video_channel_->content_name(); 1735 const std::string content_name = video_channel_->content_name();
1678 channel_manager_->DestroyVideoChannel(video_channel_.release()); 1736 channel_manager_->DestroyVideoChannel(video_channel_.release());
1679 DestroyTransportProxy(content_name);
1680 } 1737 }
1681 1738
1682 const cricket::ContentInfo* voice_info = 1739 const cricket::ContentInfo* voice_info =
1683 cricket::GetFirstAudioContent(desc); 1740 cricket::GetFirstAudioContent(desc);
1684 if ((!voice_info || voice_info->rejected) && voice_channel_) { 1741 if ((!voice_info || voice_info->rejected) && voice_channel_) {
1685 mediastream_signaling_->OnAudioChannelClose(); 1742 mediastream_signaling_->OnAudioChannelClose();
1686 SignalVoiceChannelDestroyed(); 1743 SignalVoiceChannelDestroyed();
1687 const std::string content_name = voice_channel_->content_name(); 1744 const std::string content_name = voice_channel_->content_name();
1688 channel_manager_->DestroyVoiceChannel(voice_channel_.release(), 1745 channel_manager_->DestroyVoiceChannel(voice_channel_.release(),
1689 video_channel_.get()); 1746 video_channel_.get());
1690 DestroyTransportProxy(content_name);
1691 } 1747 }
1692 1748
1693 const cricket::ContentInfo* data_info = 1749 const cricket::ContentInfo* data_info =
1694 cricket::GetFirstDataContent(desc); 1750 cricket::GetFirstDataContent(desc);
1695 if ((!data_info || data_info->rejected) && data_channel_) { 1751 if ((!data_info || data_info->rejected) && data_channel_) {
1696 mediastream_signaling_->OnDataChannelClose(); 1752 mediastream_signaling_->OnDataChannelClose();
1697 SignalDataChannelDestroyed(); 1753 SignalDataChannelDestroyed();
1698 const std::string content_name = data_channel_->content_name(); 1754 const std::string content_name = data_channel_->content_name();
1699 channel_manager_->DestroyDataChannel(data_channel_.release()); 1755 channel_manager_->DestroyDataChannel(data_channel_.release());
1700 DestroyTransportProxy(content_name);
1701 } 1756 }
1702 } 1757 }
1703 1758
1704 // TODO(mallinath) - Add a correct error code if the channels are not creatued 1759 // TODO(mallinath) - Add a correct error code if the channels are not creatued
1705 // due to BUNDLE is enabled but rtcp-mux is disabled. 1760 // due to BUNDLE is enabled but rtcp-mux is disabled.
1706 bool WebRtcSession::CreateChannels(const SessionDescription* desc) { 1761 bool WebRtcSession::CreateChannels(const SessionDescription* desc) {
1707 // Creating the media channels and transport proxies. 1762 // Creating the media channels and transport proxies.
1708 const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc); 1763 const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc);
1709 if (voice && !voice->rejected && !voice_channel_) { 1764 if (voice && !voice->rejected && !voice_channel_) {
1710 if (!CreateVoiceChannel(voice)) { 1765 if (!CreateVoiceChannel(voice)) {
(...skipping 24 matching lines...) Expand all
1735 voice_channel()->ActivateRtcpMux(); 1790 voice_channel()->ActivateRtcpMux();
1736 } 1791 }
1737 if (video_channel()) { 1792 if (video_channel()) {
1738 video_channel()->ActivateRtcpMux(); 1793 video_channel()->ActivateRtcpMux();
1739 } 1794 }
1740 if (data_channel()) { 1795 if (data_channel()) {
1741 data_channel()->ActivateRtcpMux(); 1796 data_channel()->ActivateRtcpMux();
1742 } 1797 }
1743 } 1798 }
1744 1799
1745 // Enable bundle before when kMaxBundle policy is in effect. 1800 // Enable BUNDLE immediately when kBundlePolicyMaxBundle is in effect.
1746 if (bundle_policy_ == PeerConnectionInterface::kBundlePolicyMaxBundle) { 1801 if (bundle_policy_ == PeerConnectionInterface::kBundlePolicyMaxBundle) {
1747 const cricket::ContentGroup* bundle_group = desc->GetGroupByName( 1802 const cricket::ContentGroup* bundle_group = desc->GetGroupByName(
1748 cricket::GROUP_TYPE_BUNDLE); 1803 cricket::GROUP_TYPE_BUNDLE);
1749 if (!bundle_group) { 1804 if (!bundle_group) {
1750 LOG(LS_WARNING) << "max-bundle specified without BUNDLE specified"; 1805 LOG(LS_WARNING) << "max-bundle specified without BUNDLE specified";
1751 return false; 1806 return false;
1752 } 1807 }
1753 if (!BaseSession::BundleContentGroup(bundle_group)) { 1808 if (!EnableBundle(*bundle_group)) {
1754 LOG(LS_WARNING) << "max-bundle failed to enable bundling."; 1809 LOG(LS_WARNING) << "max-bundle failed to enable bundling.";
1755 return false; 1810 return false;
1756 } 1811 }
1757 } 1812 }
1758 1813
1759 return true; 1814 return true;
1760 } 1815 }
1761 1816
1762 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) { 1817 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) {
1763 voice_channel_.reset(channel_manager_->CreateVoiceChannel( 1818 voice_channel_.reset(channel_manager_->CreateVoiceChannel(
1764 this, content->name, true, audio_options_)); 1819 transport_controller(), content->name, true, audio_options_));
1765 if (!voice_channel_) { 1820 if (!voice_channel_) {
1766 return false; 1821 return false;
1767 } 1822 }
1768 1823
1769 voice_channel_->SignalDtlsSetupFailure.connect( 1824 voice_channel_->SignalDtlsSetupFailure.connect(
1770 this, &WebRtcSession::OnDtlsSetupFailure); 1825 this, &WebRtcSession::OnDtlsSetupFailure);
1771 return true; 1826 return true;
1772 } 1827 }
1773 1828
1774 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) { 1829 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) {
1775 video_channel_.reset(channel_manager_->CreateVideoChannel( 1830 video_channel_.reset(channel_manager_->CreateVideoChannel(
1776 this, content->name, true, video_options_, voice_channel_.get())); 1831 transport_controller(), content->name, true, video_options_,
1832 voice_channel_.get()));
1777 if (!video_channel_) { 1833 if (!video_channel_) {
1778 return false; 1834 return false;
1779 } 1835 }
1780 1836
1781 video_channel_->SignalDtlsSetupFailure.connect( 1837 video_channel_->SignalDtlsSetupFailure.connect(
1782 this, &WebRtcSession::OnDtlsSetupFailure); 1838 this, &WebRtcSession::OnDtlsSetupFailure);
1783 return true; 1839 return true;
1784 } 1840 }
1785 1841
1786 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) { 1842 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) {
1787 bool sctp = (data_channel_type_ == cricket::DCT_SCTP); 1843 bool sctp = (data_channel_type_ == cricket::DCT_SCTP);
1788 data_channel_.reset(channel_manager_->CreateDataChannel( 1844 data_channel_.reset(channel_manager_->CreateDataChannel(
1789 this, content->name, !sctp, data_channel_type_)); 1845 transport_controller(), content->name, !sctp, data_channel_type_));
1790 if (!data_channel_) { 1846 if (!data_channel_) {
1791 return false; 1847 return false;
1792 } 1848 }
1793 1849
1794 if (sctp) { 1850 if (sctp) {
1795 mediastream_signaling_->OnDataTransportCreatedForSctp(); 1851 mediastream_signaling_->OnDataTransportCreatedForSctp();
1796 data_channel_->SignalDataReceived.connect( 1852 data_channel_->SignalDataReceived.connect(
1797 this, &WebRtcSession::OnDataChannelMessageReceived); 1853 this, &WebRtcSession::OnDataChannelMessageReceived);
1798 data_channel_->SignalStreamClosedRemotely.connect( 1854 data_channel_->SignalStreamClosedRemotely.connect(
1799 mediastream_signaling_, 1855 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 2016 // 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 2017 // the session, because a new Transport added during renegotiation may have
1962 // them unset while the session has them set from the previous negotiation. 2018 // 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 2019 // Not doing so may trigger the auto generation of transport description and
1964 // mess up DTLS identity information, ICE credential, etc. 2020 // mess up DTLS identity information, ICE credential, etc.
1965 bool WebRtcSession::ReadyToUseRemoteCandidate( 2021 bool WebRtcSession::ReadyToUseRemoteCandidate(
1966 const IceCandidateInterface* candidate, 2022 const IceCandidateInterface* candidate,
1967 const SessionDescriptionInterface* remote_desc, 2023 const SessionDescriptionInterface* remote_desc,
1968 bool* valid) { 2024 bool* valid) {
1969 *valid = true;; 2025 *valid = true;;
1970 cricket::TransportProxy* transport_proxy = NULL;
1971 2026
1972 const SessionDescriptionInterface* current_remote_desc = 2027 const SessionDescriptionInterface* current_remote_desc =
1973 remote_desc ? remote_desc : remote_description(); 2028 remote_desc ? remote_desc : remote_description();
1974 2029
1975 if (!current_remote_desc) 2030 if (!current_remote_desc)
1976 return false; 2031 return false;
1977 2032
1978 size_t mediacontent_index = 2033 size_t mediacontent_index =
1979 static_cast<size_t>(candidate->sdp_mline_index()); 2034 static_cast<size_t>(candidate->sdp_mline_index());
1980 size_t remote_content_size = 2035 size_t remote_content_size =
1981 current_remote_desc->description()->contents().size(); 2036 current_remote_desc->description()->contents().size();
1982 if (mediacontent_index >= remote_content_size) { 2037 if (mediacontent_index >= remote_content_size) {
1983 LOG(LS_ERROR) 2038 LOG(LS_ERROR)
1984 << "ReadyToUseRemoteCandidate: Invalid candidate media index."; 2039 << "ReadyToUseRemoteCandidate: Invalid candidate media index.";
1985 2040
1986 *valid = false; 2041 *valid = false;
1987 return false; 2042 return false;
1988 } 2043 }
1989 2044
1990 cricket::ContentInfo content = 2045 cricket::ContentInfo content =
1991 current_remote_desc->description()->contents()[mediacontent_index]; 2046 current_remote_desc->description()->contents()[mediacontent_index];
1992 transport_proxy = GetTransportProxy(content.name); 2047 cricket::BaseChannel* channel = GetChannel(content.name);
2048 if (!channel) {
2049 return false;
2050 }
1993 2051
1994 return transport_proxy && transport_proxy->local_description_set() && 2052 return transport_controller()->ReadyForRemoteCandidates(
1995 transport_proxy->remote_description_set(); 2053 channel->transport_name());
1996 } 2054 }
1997 2055
2056 void WebRtcSession::OnTransportControllerGatheringState(
2057 cricket::IceGatheringState state) {
2058 ASSERT(signaling_thread()->IsCurrent());
2059 if (state == cricket::kIceGatheringGathering) {
2060 if (ice_observer_) {
2061 ice_observer_->OnIceGatheringChange(
2062 PeerConnectionInterface::kIceGatheringGathering);
2063 }
2064 } else if (state == cricket::kIceGatheringComplete) {
2065 if (ice_observer_) {
2066 ice_observer_->OnIceGatheringChange(
2067 PeerConnectionInterface::kIceGatheringComplete);
2068 ice_observer_->OnIceComplete();
2069 }
2070 }
2071 }
2072
2073 void WebRtcSession::ReportTransportStats() {
2074 // Use a set so we don't report the same stats twice if two channels share
2075 // a transport.
2076 std::set<std::string> transport_names;
2077 if (voice_channel()) {
2078 transport_names.insert(voice_channel()->transport_name());
2079 }
2080 if (video_channel()) {
2081 transport_names.insert(video_channel()->transport_name());
2082 }
2083 if (data_channel()) {
2084 transport_names.insert(data_channel()->transport_name());
2085 }
2086 for (const auto& name : transport_names) {
2087 cricket::TransportStats stats;
2088 if (transport_controller()->GetStats(name, &stats)) {
2089 ReportBestConnectionState(stats);
2090 ReportNegotiatedCiphers(stats);
2091 }
2092 }
2093 }
1998 // Walk through the ConnectionInfos to gather best connection usage 2094 // Walk through the ConnectionInfos to gather best connection usage
1999 // for IPv4 and IPv6. 2095 // for IPv4 and IPv6.
2000 void WebRtcSession::ReportBestConnectionState( 2096 void WebRtcSession::ReportBestConnectionState(
2001 const cricket::TransportStats& stats) { 2097 const cricket::TransportStats& stats) {
2002 DCHECK(metrics_observer_ != NULL); 2098 DCHECK(metrics_observer_ != NULL);
2003 for (cricket::TransportChannelStatsList::const_iterator it = 2099 for (cricket::TransportChannelStatsList::const_iterator it =
2004 stats.channel_stats.begin(); 2100 stats.channel_stats.begin();
2005 it != stats.channel_stats.end(); ++it) { 2101 it != stats.channel_stats.end(); ++it) {
2006 for (cricket::ConnectionInfos::const_iterator it_info = 2102 for (cricket::ConnectionInfos::const_iterator it_info =
2007 it->connection_infos.begin(); 2103 it->connection_infos.begin();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2062 } 2158 }
2063 2159
2064 const std::string& srtp_cipher = stats.channel_stats[0].srtp_cipher; 2160 const std::string& srtp_cipher = stats.channel_stats[0].srtp_cipher;
2065 const std::string& ssl_cipher = stats.channel_stats[0].ssl_cipher; 2161 const std::string& ssl_cipher = stats.channel_stats[0].ssl_cipher;
2066 if (srtp_cipher.empty() && ssl_cipher.empty()) { 2162 if (srtp_cipher.empty() && ssl_cipher.empty()) {
2067 return; 2163 return;
2068 } 2164 }
2069 2165
2070 PeerConnectionMetricsName srtp_name; 2166 PeerConnectionMetricsName srtp_name;
2071 PeerConnectionMetricsName ssl_name; 2167 PeerConnectionMetricsName ssl_name;
2072 if (stats.content_name == cricket::CN_AUDIO) { 2168 if (stats.transport_name == cricket::CN_AUDIO) {
2073 srtp_name = kAudioSrtpCipher; 2169 srtp_name = kAudioSrtpCipher;
2074 ssl_name = kAudioSslCipher; 2170 ssl_name = kAudioSslCipher;
2075 } else if (stats.content_name == cricket::CN_VIDEO) { 2171 } else if (stats.transport_name == cricket::CN_VIDEO) {
2076 srtp_name = kVideoSrtpCipher; 2172 srtp_name = kVideoSrtpCipher;
2077 ssl_name = kVideoSslCipher; 2173 ssl_name = kVideoSslCipher;
2078 } else if (stats.content_name == cricket::CN_DATA) { 2174 } else if (stats.transport_name == cricket::CN_DATA) {
2079 srtp_name = kDataSrtpCipher; 2175 srtp_name = kDataSrtpCipher;
2080 ssl_name = kDataSslCipher; 2176 ssl_name = kDataSslCipher;
2081 } else { 2177 } else {
2082 RTC_NOTREACHED(); 2178 RTC_NOTREACHED();
2083 return; 2179 return;
2084 } 2180 }
2085 2181
2086 if (!srtp_cipher.empty()) { 2182 if (!srtp_cipher.empty()) {
2087 metrics_observer_->AddHistogramSample(srtp_name, srtp_cipher); 2183 metrics_observer_->AddHistogramSample(srtp_name, srtp_cipher);
2088 } 2184 }
2089 if (!ssl_cipher.empty()) { 2185 if (!ssl_cipher.empty()) {
2090 metrics_observer_->AddHistogramSample(ssl_name, ssl_cipher); 2186 metrics_observer_->AddHistogramSample(ssl_name, ssl_cipher);
2091 } 2187 }
2092 } 2188 }
2093 2189
2094 } // namespace webrtc 2190 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698