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

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: Fixed bugs with ICE connection state that occur when destroying transports 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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 WebRtcSession::WebRtcSession( 538 WebRtcSession::WebRtcSession(
537 cricket::ChannelManager* channel_manager, 539 cricket::ChannelManager* channel_manager,
538 rtc::Thread* signaling_thread, 540 rtc::Thread* signaling_thread,
539 rtc::Thread* worker_thread, 541 rtc::Thread* worker_thread,
540 cricket::PortAllocator* port_allocator, 542 cricket::PortAllocator* port_allocator,
541 MediaStreamSignaling* mediastream_signaling) 543 MediaStreamSignaling* mediastream_signaling)
542 : cricket::BaseSession(signaling_thread, 544 : cricket::BaseSession(signaling_thread,
543 worker_thread, 545 worker_thread,
544 port_allocator, 546 port_allocator,
545 rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX), 547 rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX),
546 cricket::NS_JINGLE_RTP,
547 false), 548 false),
548 // RFC 3264: The numeric value of the session id and version in the 549 // RFC 3264: The numeric value of the session id and version in the
549 // o line MUST be representable with a "64 bit signed integer". 550 // o line MUST be representable with a "64 bit signed integer".
550 // Due to this constraint session id |sid_| is max limited to LLONG_MAX. 551 // Due to this constraint session id |sid_| is max limited to LLONG_MAX.
551 channel_manager_(channel_manager), 552 channel_manager_(channel_manager),
552 mediastream_signaling_(mediastream_signaling), 553 mediastream_signaling_(mediastream_signaling),
553 ice_observer_(NULL), 554 ice_observer_(NULL),
554 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), 555 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
555 ice_connection_receiving_(true), 556 ice_connection_receiving_(true),
556 older_version_remote_peer_(false), 557 older_version_remote_peer_(false),
557 dtls_enabled_(false), 558 dtls_enabled_(false),
558 data_channel_type_(cricket::DCT_NONE), 559 data_channel_type_(cricket::DCT_NONE),
559 ice_restart_latch_(new IceRestartAnswerLatch), 560 ice_restart_latch_(new IceRestartAnswerLatch),
560 metrics_observer_(NULL) { 561 metrics_observer_(NULL) {
562 transport_controller()->SignalConnectionState.connect(
563 this, &WebRtcSession::OnTransportControllerConnectionState);
564 transport_controller()->SignalReceiving.connect(
565 this, &WebRtcSession::OnTransportControllerReceiving);
566 transport_controller()->SignalGatheringState.connect(
567 this, &WebRtcSession::OnTransportControllerGatheringState);
568 transport_controller()->SignalCandidatesGathered.connect(
569 this, &WebRtcSession::OnTransportControllerCandidatesGathered);
561 } 570 }
562 571
563 WebRtcSession::~WebRtcSession() { 572 WebRtcSession::~WebRtcSession() {
564 ASSERT(signaling_thread()->IsCurrent()); 573 ASSERT(signaling_thread()->IsCurrent());
565 // Destroy video_channel_ first since it may have a pointer to the 574 // Destroy video_channel_ first since it may have a pointer to the
566 // voice_channel_. 575 // voice_channel_.
567 if (video_channel_) { 576 if (video_channel_) {
568 SignalVideoChannelDestroyed(); 577 SignalVideoChannelDestroyed();
569 channel_manager_->DestroyVideoChannel(video_channel_.release()); 578 channel_manager_->DestroyVideoChannel(video_channel_.release());
570 } 579 }
(...skipping 10 matching lines...) Expand all
581 } 590 }
582 } 591 }
583 592
584 bool WebRtcSession::Initialize( 593 bool WebRtcSession::Initialize(
585 const PeerConnectionFactoryInterface::Options& options, 594 const PeerConnectionFactoryInterface::Options& options,
586 const MediaConstraintsInterface* constraints, 595 const MediaConstraintsInterface* constraints,
587 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, 596 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
588 const PeerConnectionInterface::RTCConfiguration& rtc_configuration) { 597 const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
589 bundle_policy_ = rtc_configuration.bundle_policy; 598 bundle_policy_ = rtc_configuration.bundle_policy;
590 rtcp_mux_policy_ = rtc_configuration.rtcp_mux_policy; 599 rtcp_mux_policy_ = rtc_configuration.rtcp_mux_policy;
591 SetSslMaxProtocolVersion(options.ssl_max_version); 600 transport_controller()->SetSslMaxProtocolVersion(options.ssl_max_version);
592 601
593 // Obtain a certificate from RTCConfiguration if any were provided (optional). 602 // Obtain a certificate from RTCConfiguration if any were provided (optional).
594 rtc::scoped_refptr<rtc::RTCCertificate> certificate; 603 rtc::scoped_refptr<rtc::RTCCertificate> certificate;
595 if (!rtc_configuration.certificates.empty()) { 604 if (!rtc_configuration.certificates.empty()) {
596 // TODO(hbos,torbjorng): Decide on certificate-selection strategy instead of 605 // TODO(hbos,torbjorng): Decide on certificate-selection strategy instead of
597 // just picking the first one. The decision should be made based on the DTLS 606 // just picking the first one. The decision should be made based on the DTLS
598 // handshake. The DTLS negotiations need to know about all certificates. 607 // handshake. The DTLS negotiations need to know about all certificates.
599 certificate = rtc_configuration.certificates[0]; 608 certificate = rtc_configuration.certificates[0];
600 } 609 }
601 610
602 SetIceConnectionReceivingTimeout( 611 SetIceConnectionReceivingTimeout(
603 rtc_configuration.ice_connection_receiving_timeout); 612 rtc_configuration.ice_connection_receiving_timeout);
604 613
605 // TODO(perkj): Take |constraints| into consideration. Return false if not all 614 // TODO(perkj): Take |constraints| into consideration. Return false if not all
606 // mandatory constraints can be fulfilled. Note that |constraints| 615 // mandatory constraints can be fulfilled. Note that |constraints|
607 // can be null. 616 // can be null.
608 bool value; 617 bool value;
609 618
610 if (options.disable_encryption) { 619 if (options.disable_encryption) {
611 dtls_enabled_ = false; 620 dtls_enabled_ = false;
612 } else { 621 } else {
613 // Enable DTLS by default if we have an identity store or a certificate. 622 // Enable DTLS by default if we have an identity store or a certificate.
614 dtls_enabled_ = (dtls_identity_store || certificate); 623 dtls_enabled_ = (dtls_identity_store || certificate);
615 // |constraints| can override the default |dtls_enabled_| value. 624 // |constraints| can override the default |dtls_enabled_| value.
616 if (FindConstraint( 625 if (FindConstraint(constraints, MediaConstraintsInterface::kEnableDtlsSrtp,
617 constraints, 626 &value, nullptr)) {
618 MediaConstraintsInterface::kEnableDtlsSrtp,
619 &value, nullptr)) {
620 dtls_enabled_ = value; 627 dtls_enabled_ = value;
621 } 628 }
622 } 629 }
623 630
624 // Enable creation of RTP data channels if the kEnableRtpDataChannels is set. 631 // Enable creation of RTP data channels if the kEnableRtpDataChannels is set.
625 // It takes precendence over the disable_sctp_data_channels 632 // It takes precendence over the disable_sctp_data_channels
626 // PeerConnectionFactoryInterface::Options. 633 // PeerConnectionFactoryInterface::Options.
627 if (FindConstraint( 634 if (FindConstraint(
628 constraints, MediaConstraintsInterface::kEnableRtpDataChannels, 635 constraints, MediaConstraintsInterface::kEnableRtpDataChannels,
629 &value, NULL) && value) { 636 &value, NULL) && value) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 JsepSessionDescription::kMaxVideoCodecWidth, 736 JsepSessionDescription::kMaxVideoCodecWidth,
730 JsepSessionDescription::kMaxVideoCodecHeight, 737 JsepSessionDescription::kMaxVideoCodecHeight,
731 JsepSessionDescription::kDefaultVideoCodecFramerate, 738 JsepSessionDescription::kDefaultVideoCodecFramerate,
732 JsepSessionDescription::kDefaultVideoCodecPreference); 739 JsepSessionDescription::kDefaultVideoCodecPreference);
733 channel_manager_->SetDefaultVideoEncoderConfig( 740 channel_manager_->SetDefaultVideoEncoderConfig(
734 cricket::VideoEncoderConfig(default_codec)); 741 cricket::VideoEncoderConfig(default_codec));
735 742
736 if (!dtls_enabled_) { 743 if (!dtls_enabled_) {
737 // Construct with DTLS disabled. 744 // Construct with DTLS disabled.
738 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( 745 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory(
739 signaling_thread(), 746 signaling_thread(), channel_manager_, mediastream_signaling_, this,
740 channel_manager_, 747 id(), data_channel_type_));
741 mediastream_signaling_,
742 this,
743 id(),
744 data_channel_type_));
745 } else { 748 } else {
746 // Construct with DTLS enabled. 749 // Construct with DTLS enabled.
747 if (!certificate) { 750 if (!certificate) {
748 // Use the |dtls_identity_store| to generate a certificate. 751 // Use the |dtls_identity_store| to generate a certificate.
749 DCHECK(dtls_identity_store); 752 DCHECK(dtls_identity_store);
750 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( 753 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory(
751 signaling_thread(), 754 signaling_thread(), channel_manager_, mediastream_signaling_,
752 channel_manager_, 755 dtls_identity_store.Pass(), this, id(), data_channel_type_));
753 mediastream_signaling_,
754 dtls_identity_store.Pass(),
755 this,
756 id(),
757 data_channel_type_));
758 } else { 756 } else {
759 // Use the already generated certificate. 757 // Use the already generated certificate.
760 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( 758 webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory(
761 signaling_thread(), 759 signaling_thread(), channel_manager_, mediastream_signaling_,
762 channel_manager_, 760 certificate, this, id(), data_channel_type_));
763 mediastream_signaling_,
764 certificate,
765 this,
766 id(),
767 data_channel_type_));
768 } 761 }
769 } 762 }
770 763
771 webrtc_session_desc_factory_->SignalCertificateReady.connect( 764 webrtc_session_desc_factory_->SignalCertificateReady.connect(
772 this, &WebRtcSession::OnCertificateReady); 765 this, &WebRtcSession::OnCertificateReady);
773 766
774 if (options.disable_encryption) { 767 if (options.disable_encryption) {
775 webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED); 768 webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED);
776 } 769 }
777 port_allocator()->set_candidate_filter( 770 port_allocator()->set_candidate_filter(
778 ConvertIceTransportTypeToCandidateFilter(rtc_configuration.type)); 771 ConvertIceTransportTypeToCandidateFilter(rtc_configuration.type));
779 772
780 if (rtc_configuration.enable_localhost_ice_candidate) { 773 if (rtc_configuration.enable_localhost_ice_candidate) {
781 port_allocator()->set_flags( 774 port_allocator()->set_flags(
782 port_allocator()->flags() | 775 port_allocator()->flags() |
783 cricket::PORTALLOCATOR_ENABLE_LOCALHOST_CANDIDATE); 776 cricket::PORTALLOCATOR_ENABLE_LOCALHOST_CANDIDATE);
784 } 777 }
785 778
786 return true; 779 return true;
787 } 780 }
788 781
789 void WebRtcSession::Terminate() { 782 void WebRtcSession::Terminate() {
790 SetState(STATE_RECEIVEDTERMINATE); 783 SetState(STATE_RECEIVEDTERMINATE);
791 RemoveUnusedChannelsAndTransports(NULL); 784 RemoveUnusedChannels(NULL);
792 ASSERT(!voice_channel_); 785 ASSERT(!voice_channel_);
793 ASSERT(!video_channel_); 786 ASSERT(!video_channel_);
794 ASSERT(!data_channel_); 787 ASSERT(!data_channel_);
795 } 788 }
796 789
797 bool WebRtcSession::StartCandidatesAllocation() {
798 // SpeculativelyConnectTransportChannels, will call ConnectChannels method
799 // from TransportProxy to start gathering ice candidates.
800 SpeculativelyConnectAllTransportChannels();
801 if (!saved_candidates_.empty()) {
802 // If there are saved candidates which arrived before local description is
803 // set, copy those to remote description.
804 CopySavedCandidates(remote_desc_.get());
805 }
806 // Push remote candidates present in remote description to transport channels.
807 UseCandidatesInSessionDescription(remote_desc_.get());
808 return true;
809 }
810
811 void WebRtcSession::SetSdesPolicy(cricket::SecurePolicy secure_policy) { 790 void WebRtcSession::SetSdesPolicy(cricket::SecurePolicy secure_policy) {
812 webrtc_session_desc_factory_->SetSdesPolicy(secure_policy); 791 webrtc_session_desc_factory_->SetSdesPolicy(secure_policy);
813 } 792 }
814 793
815 cricket::SecurePolicy WebRtcSession::SdesPolicy() const { 794 cricket::SecurePolicy WebRtcSession::SdesPolicy() const {
816 return webrtc_session_desc_factory_->SdesPolicy(); 795 return webrtc_session_desc_factory_->SdesPolicy();
817 } 796 }
818 797
819 bool WebRtcSession::GetSslRole(rtc::SSLRole* role) { 798 bool WebRtcSession::GetSslRole(rtc::SSLRole* role) {
820 if (local_description() == NULL || remote_description() == NULL) { 799 if (local_description() == NULL || remote_description() == NULL) {
821 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get " 800 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get "
822 << "SSL Role of the session."; 801 << "SSL Role of the session.";
823 return false; 802 return false;
824 } 803 }
825 804
826 // TODO(mallinath) - Return role of each transport, as role may differ from 805 return transport_controller()->GetSslRole(role);
827 // one another.
828 // In current implementaion we just return the role of first transport in the
829 // transport map.
830 for (cricket::TransportMap::const_iterator iter = transport_proxies().begin();
831 iter != transport_proxies().end(); ++iter) {
832 if (iter->second->impl()) {
833 return iter->second->impl()->GetSslRole(role);
834 }
835 }
836 return false;
837 } 806 }
838 807
839 void WebRtcSession::CreateOffer( 808 void WebRtcSession::CreateOffer(
840 CreateSessionDescriptionObserver* observer, 809 CreateSessionDescriptionObserver* observer,
841 const PeerConnectionInterface::RTCOfferAnswerOptions& options) { 810 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
842 webrtc_session_desc_factory_->CreateOffer(observer, options); 811 webrtc_session_desc_factory_->CreateOffer(observer, options);
843 } 812 }
844 813
845 void WebRtcSession::CreateAnswer(CreateSessionDescriptionObserver* observer, 814 void WebRtcSession::CreateAnswer(CreateSessionDescriptionObserver* observer,
846 const MediaConstraintsInterface* constraints) { 815 const MediaConstraintsInterface* constraints) {
847 webrtc_session_desc_factory_->CreateAnswer(observer, constraints); 816 webrtc_session_desc_factory_->CreateAnswer(observer, constraints);
848 } 817 }
849 818
850 bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc, 819 bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,
851 std::string* err_desc) { 820 std::string* err_desc) {
821 ASSERT(signaling_thread()->IsCurrent());
822
852 // Takes the ownership of |desc| regardless of the result. 823 // Takes the ownership of |desc| regardless of the result.
853 rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc); 824 rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc);
854 825
855 // Validate SDP. 826 // Validate SDP.
856 if (!ValidateSessionDescription(desc, cricket::CS_LOCAL, err_desc)) { 827 if (!ValidateSessionDescription(desc, cricket::CS_LOCAL, err_desc)) {
857 return false; 828 return false;
858 } 829 }
859 830
860 // Update the initiator flag if this session is the initiator. 831 // Update the initiator flag if this session is the initiator.
861 Action action = GetAction(desc->type()); 832 Action action = GetAction(desc->type());
(...skipping 12 matching lines...) Expand all
874 set_local_description(desc->description()->Copy()); 845 set_local_description(desc->description()->Copy());
875 local_desc_.reset(desc_temp.release()); 846 local_desc_.reset(desc_temp.release());
876 847
877 // Transport and Media channels will be created only when offer is set. 848 // Transport and Media channels will be created only when offer is set.
878 if (action == kOffer && !CreateChannels(local_desc_->description())) { 849 if (action == kOffer && !CreateChannels(local_desc_->description())) {
879 // TODO(mallinath) - Handle CreateChannel failure, as new local description 850 // TODO(mallinath) - Handle CreateChannel failure, as new local description
880 // is applied. Restore back to old description. 851 // is applied. Restore back to old description.
881 return BadLocalSdp(desc->type(), kCreateChannelFailed, err_desc); 852 return BadLocalSdp(desc->type(), kCreateChannelFailed, err_desc);
882 } 853 }
883 854
884 // Remove channel and transport proxies, if MediaContentDescription is 855 // Remove unused channels if MediaContentDescription is rejected.
885 // rejected. 856 RemoveUnusedChannels(local_desc_->description());
886 RemoveUnusedChannelsAndTransports(local_desc_->description());
887 857
888 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) { 858 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) {
889 return false; 859 return false;
890 } 860 }
891 861
892 // Kick starting the ice candidates allocation. 862 if (remote_description()) {
893 StartCandidatesAllocation(); 863 // Now that we have a local description, we can push down remote candidates
864 // that we stored, and those from the remote description.
865 if (!saved_candidates_.empty()) {
866 // If there are saved candidates which arrived before the local
867 // description was set, copy those to the remote description.
868 CopySavedCandidates(remote_desc_.get());
869 }
870 // Push remote candidates in remote description to transport channels.
871 UseCandidatesInSessionDescription(remote_desc_.get());
872 }
894 873
895 // Update state and SSRC of local MediaStreams and DataChannels based on the 874 // Update state and SSRC of local MediaStreams and DataChannels based on the
896 // local session description. 875 // local session description.
897 mediastream_signaling_->OnLocalDescriptionChanged(local_desc_.get()); 876 mediastream_signaling_->OnLocalDescriptionChanged(local_desc_.get());
898 877
899 rtc::SSLRole role; 878 rtc::SSLRole role;
900 if (data_channel_type_ == cricket::DCT_SCTP && GetSslRole(&role)) { 879 if (data_channel_type_ == cricket::DCT_SCTP && GetSslRole(&role)) {
901 mediastream_signaling_->OnDtlsRoleReadyForSctp(role); 880 mediastream_signaling_->OnDtlsRoleReadyForSctp(role);
902 } 881 }
903 if (error() != cricket::BaseSession::ERROR_NONE) { 882 if (error() != cricket::BaseSession::ERROR_NONE) {
904 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc); 883 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc);
905 } 884 }
906 return true; 885 return true;
907 } 886 }
908 887
909 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc, 888 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
910 std::string* err_desc) { 889 std::string* err_desc) {
890 ASSERT(signaling_thread()->IsCurrent());
891
911 // Takes the ownership of |desc| regardless of the result. 892 // Takes the ownership of |desc| regardless of the result.
912 rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc); 893 rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc);
913 894
914 // Validate SDP. 895 // Validate SDP.
915 if (!ValidateSessionDescription(desc, cricket::CS_REMOTE, err_desc)) { 896 if (!ValidateSessionDescription(desc, cricket::CS_REMOTE, err_desc)) {
916 return false; 897 return false;
917 } 898 }
918 899
919 // Transport and Media channels will be created only when offer is set. 900 // Transport and Media channels will be created only when offer is set.
920 Action action = GetAction(desc->type()); 901 Action action = GetAction(desc->type());
921 if (action == kOffer && !CreateChannels(desc->description())) { 902 if (action == kOffer && !CreateChannels(desc->description())) {
922 // TODO(mallinath) - Handle CreateChannel failure, as new local description 903 // TODO(mallinath) - Handle CreateChannel failure, as new local description
923 // is applied. Restore back to old description. 904 // is applied. Restore back to old description.
924 return BadRemoteSdp(desc->type(), kCreateChannelFailed, err_desc); 905 return BadRemoteSdp(desc->type(), kCreateChannelFailed, err_desc);
925 } 906 }
926 907
927 // Remove channel and transport proxies, if MediaContentDescription is 908 // Remove unused channels if MediaContentDescription is rejected.
928 // rejected. 909 RemoveUnusedChannels(desc->description());
929 RemoveUnusedChannelsAndTransports(desc->description());
930 910
931 // NOTE: Candidates allocation will be initiated only when SetLocalDescription 911 // NOTE: Candidates allocation will be initiated only when SetLocalDescription
932 // is called. 912 // is called.
933 set_remote_description(desc->description()->Copy()); 913 set_remote_description(desc->description()->Copy());
934 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) { 914 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) {
935 return false; 915 return false;
936 } 916 }
937 917
938 // Update remote MediaStreams. 918 // Update remote MediaStreams.
939 mediastream_signaling_->OnRemoteDescriptionChanged(desc); 919 mediastream_signaling_->OnRemoteDescriptionChanged(desc);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 if (desc->type() != SessionDescriptionInterface::kOffer && 958 if (desc->type() != SessionDescriptionInterface::kOffer &&
979 ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew) { 959 ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew) {
980 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking); 960 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
981 } 961 }
982 return true; 962 return true;
983 } 963 }
984 964
985 bool WebRtcSession::UpdateSessionState( 965 bool WebRtcSession::UpdateSessionState(
986 Action action, cricket::ContentSource source, 966 Action action, cricket::ContentSource source,
987 std::string* err_desc) { 967 std::string* err_desc) {
968 ASSERT(signaling_thread()->IsCurrent());
969
988 // If there's already a pending error then no state transition should happen. 970 // If there's already a pending error then no state transition should happen.
989 // But all call-sites should be verifying this before calling us! 971 // But all call-sites should be verifying this before calling us!
990 ASSERT(error() == cricket::BaseSession::ERROR_NONE); 972 ASSERT(error() == cricket::BaseSession::ERROR_NONE);
991 std::string td_err; 973 std::string td_err;
992 if (action == kOffer) { 974 if (action == kOffer) {
993 if (!PushdownTransportDescription(source, cricket::CA_OFFER, &td_err)) { 975 if (!PushdownTransportDescription(source, cricket::CA_OFFER, &td_err)) {
994 return BadOfferSdp(source, MakeTdErrorString(td_err), err_desc); 976 return BadOfferSdp(source, MakeTdErrorString(td_err), err_desc);
995 } 977 }
996 SetState(source == cricket::CS_LOCAL ? 978 SetState(source == cricket::CS_LOCAL ?
997 STATE_SENTINITIATE : STATE_RECEIVEDINITIATE); 979 STATE_SENTINITIATE : STATE_RECEIVEDINITIATE);
(...skipping 13 matching lines...) Expand all
1011 if (!PushdownMediaDescription(cricket::CA_PRANSWER, source, err_desc)) { 993 if (!PushdownMediaDescription(cricket::CA_PRANSWER, source, err_desc)) {
1012 SetError(BaseSession::ERROR_CONTENT, *err_desc); 994 SetError(BaseSession::ERROR_CONTENT, *err_desc);
1013 } 995 }
1014 if (error() != cricket::BaseSession::ERROR_NONE) { 996 if (error() != cricket::BaseSession::ERROR_NONE) {
1015 return BadPranswerSdp(source, GetSessionErrorMsg(), err_desc); 997 return BadPranswerSdp(source, GetSessionErrorMsg(), err_desc);
1016 } 998 }
1017 } else if (action == kAnswer) { 999 } else if (action == kAnswer) {
1018 if (!PushdownTransportDescription(source, cricket::CA_ANSWER, &td_err)) { 1000 if (!PushdownTransportDescription(source, cricket::CA_ANSWER, &td_err)) {
1019 return BadAnswerSdp(source, MakeTdErrorString(td_err), err_desc); 1001 return BadAnswerSdp(source, MakeTdErrorString(td_err), err_desc);
1020 } 1002 }
1021 MaybeEnableMuxingSupport(); 1003 const cricket::ContentGroup* local_bundle =
1004 BaseSession::local_description()->GetGroupByName(
1005 cricket::GROUP_TYPE_BUNDLE);
1006 const cricket::ContentGroup* remote_bundle =
1007 BaseSession::remote_description()->GetGroupByName(
1008 cricket::GROUP_TYPE_BUNDLE);
1009 if (local_bundle && remote_bundle) {
1010 // The answerer decides the transport to bundle on
1011 const cricket::ContentGroup* answer_bundle =
1012 (source == cricket::CS_LOCAL ? local_bundle : remote_bundle);
1013 if (!EnableBundle(*answer_bundle)) {
1014 LOG(LS_WARNING) << "Failed to enable BUNDLE.";
1015 return BadAnswerSdp(source, kEnableBundleFailed, err_desc);
1016 }
1017 }
1022 EnableChannels(); 1018 EnableChannels();
1023 SetState(source == cricket::CS_LOCAL ? 1019 SetState(source == cricket::CS_LOCAL ?
1024 STATE_SENTACCEPT : STATE_RECEIVEDACCEPT); 1020 STATE_SENTACCEPT : STATE_RECEIVEDACCEPT);
1025 if (!PushdownMediaDescription(cricket::CA_ANSWER, source, err_desc)) { 1021 if (!PushdownMediaDescription(cricket::CA_ANSWER, source, err_desc)) {
1026 SetError(BaseSession::ERROR_CONTENT, *err_desc); 1022 SetError(BaseSession::ERROR_CONTENT, *err_desc);
1027 } 1023 }
1028 if (error() != cricket::BaseSession::ERROR_NONE) { 1024 if (error() != cricket::BaseSession::ERROR_NONE) {
1029 return BadAnswerSdp(source, GetSessionErrorMsg(), err_desc); 1025 return BadAnswerSdp(source, GetSessionErrorMsg(), err_desc);
1030 } 1026 }
1031 } 1027 }
(...skipping 28 matching lines...) Expand all
1060 return WebRtcSession::kPrAnswer; 1056 return WebRtcSession::kPrAnswer;
1061 } else if (type == SessionDescriptionInterface::kAnswer) { 1057 } else if (type == SessionDescriptionInterface::kAnswer) {
1062 return WebRtcSession::kAnswer; 1058 return WebRtcSession::kAnswer;
1063 } 1059 }
1064 ASSERT(false && "unknown action type"); 1060 ASSERT(false && "unknown action type");
1065 return WebRtcSession::kOffer; 1061 return WebRtcSession::kOffer;
1066 } 1062 }
1067 1063
1068 bool WebRtcSession::GetTransportStats(cricket::SessionStats* stats) { 1064 bool WebRtcSession::GetTransportStats(cricket::SessionStats* stats) {
1069 ASSERT(signaling_thread()->IsCurrent()); 1065 ASSERT(signaling_thread()->IsCurrent());
1066 return (GetChannelTransportStats(voice_channel(), stats) &&
1067 GetChannelTransportStats(video_channel(), stats) &&
1068 GetChannelTransportStats(data_channel(), stats));
1069 }
1070 1070
1071 const auto get_transport_stats = [stats](const std::string& content_name, 1071 bool WebRtcSession::GetChannelTransportStats(cricket::BaseChannel* ch,
1072 cricket::Transport* transport) { 1072 cricket::SessionStats* stats) {
1073 const std::string& transport_id = transport->content_name(); 1073 ASSERT(signaling_thread()->IsCurrent());
1074 stats->proxy_to_transport[content_name] = transport_id; 1074 if (!ch) {
1075 if (stats->transport_stats.find(transport_id) 1075 // Not using this channel.
1076 != stats->transport_stats.end()) { 1076 return true;
1077 // Transport stats already done for this transport. 1077 }
1078 return true;
1079 }
1080 1078
1081 cricket::TransportStats tstats; 1079 const std::string& content_name = ch->content_name();
1082 if (!transport->GetStats(&tstats)) { 1080 const std::string& transport_name = ch->transport_name();
1083 return false; 1081 stats->proxy_to_transport[content_name] = transport_name;
1084 } 1082 if (stats->transport_stats.find(transport_name) !=
1083 stats->transport_stats.end()) {
1084 // Transport stats already done for this transport.
1085 return true;
1086 }
1085 1087
1086 stats->transport_stats[transport_id] = tstats; 1088 cricket::TransportStats tstats;
1087 return true; 1089 if (!transport_controller()->GetStats(transport_name, &tstats)) {
1088 }; 1090 return false;
1091 }
1089 1092
1090 for (const auto& kv : transport_proxies()) { 1093 stats->transport_stats[transport_name] = tstats;
1091 cricket::Transport* transport = kv.second->impl();
1092 if (transport && !get_transport_stats(kv.first, transport)) {
1093 return false;
1094 }
1095 }
1096 return true; 1094 return true;
1097 } 1095 }
1098 1096
1097 bool WebRtcSession::GetLocalCertificate(
1098 const std::string& transport_name,
1099 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
1100 ASSERT(signaling_thread()->IsCurrent());
1101 return transport_controller()->GetLocalCertificate(transport_name,
1102 certificate);
1103 }
1104
1105 bool WebRtcSession::GetRemoteSSLCertificate(const std::string& transport_name,
1106 rtc::SSLCertificate** cert) {
1107 ASSERT(signaling_thread()->IsCurrent());
1108 return transport_controller()->GetRemoteSSLCertificate(transport_name, cert);
1109 }
1110
1111 cricket::BaseChannel* WebRtcSession::GetChannel(
1112 const std::string& content_name) {
1113 if (voice_channel() && voice_channel()->content_name() == content_name) {
1114 return voice_channel();
1115 }
1116 if (video_channel() && video_channel()->content_name() == content_name) {
1117 return video_channel();
1118 }
1119 if (data_channel() && data_channel()->content_name() == content_name) {
1120 return data_channel();
1121 }
1122 return nullptr;
1123 }
1124
1125 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) {
1126 const std::string* first_content_name = bundle.FirstContentName();
1127 if (!first_content_name) {
1128 LOG(LS_WARNING) << "Tried to BUNDLE with no contents.";
1129 return false;
1130 }
1131 const std::string& transport_name = *first_content_name;
1132 cricket::BaseChannel* first_channel = GetChannel(transport_name);
1133
1134 auto maybe_set_transport =
1135 [this, bundle, transport_name, first_channel](cricket::BaseChannel* ch) {
1136 if (!ch || !bundle.HasContentName(ch->content_name())) {
1137 return true;
1138 }
1139
1140 if (ch->transport_name() == transport_name) {
1141 LOG(LS_INFO) << "BUNDLE already enabled for " << ch->content_name()
1142 << " on " << transport_name << ".";
1143 return true;
1144 }
1145
1146 if (!ch->SetTransport(transport_name)) {
1147 LOG(LS_WARNING) << "Failed to enable BUNDLE for "
1148 << ch->content_name();
1149 return false;
1150 }
1151 LOG(LS_INFO) << "Enabled BUNDLE for " << ch->content_name() << " on "
1152 << transport_name << ".";
1153 return true;
1154 };
1155
1156 if (!maybe_set_transport(voice_channel()) ||
1157 !maybe_set_transport(video_channel()) ||
1158 !maybe_set_transport(data_channel())) {
1159 return false;
1160 }
1161
1162 return true;
1163 }
1164
1099 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) { 1165 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) {
1100 if (state() == STATE_INIT) { 1166 if (state() == STATE_INIT) {
1101 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added " 1167 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added "
1102 << "without any offer (local or remote) " 1168 << "without any offer (local or remote) "
1103 << "session description."; 1169 << "session description.";
1104 return false; 1170 return false;
1105 } 1171 }
1106 1172
1107 if (!candidate) { 1173 if (!candidate) {
1108 LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL"; 1174 LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL";
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 bool WebRtcSession::IceRestartPending() const { 1471 bool WebRtcSession::IceRestartPending() const {
1406 return ice_restart_latch_->Get(); 1472 return ice_restart_latch_->Get();
1407 } 1473 }
1408 1474
1409 void WebRtcSession::ResetIceRestartLatch() { 1475 void WebRtcSession::ResetIceRestartLatch() {
1410 ice_restart_latch_->Reset(); 1476 ice_restart_latch_->Reset();
1411 } 1477 }
1412 1478
1413 void WebRtcSession::OnCertificateReady( 1479 void WebRtcSession::OnCertificateReady(
1414 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { 1480 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
1415 SetCertificate(certificate); 1481 transport_controller()->SetLocalCertificate(certificate);
1416 } 1482 }
1417 1483
1418 bool WebRtcSession::waiting_for_certificate_for_testing() const { 1484 bool WebRtcSession::waiting_for_certificate_for_testing() const {
1419 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); 1485 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing();
1420 } 1486 }
1421 1487
1488 const rtc::scoped_refptr<rtc::RTCCertificate>&
1489 WebRtcSession::certificate_for_testing() {
1490 return transport_controller()->certificate_for_testing();
1491 }
1492
1422 void WebRtcSession::SetIceConnectionState( 1493 void WebRtcSession::SetIceConnectionState(
1423 PeerConnectionInterface::IceConnectionState state) { 1494 PeerConnectionInterface::IceConnectionState state) {
1424 if (ice_connection_state_ == state) { 1495 if (ice_connection_state_ == state) {
1425 return; 1496 return;
1426 } 1497 }
1427 1498
1428 // ASSERT that the requested transition is allowed. Note that 1499 // ASSERT that the requested transition is allowed. Note that
1429 // WebRtcSession does not implement "kIceConnectionClosed" (that is handled 1500 // WebRtcSession does not implement "kIceConnectionClosed" (that is handled
1430 // within PeerConnection). This switch statement should compile away when 1501 // within PeerConnection). This switch statement should compile away when
1431 // ASSERTs are disabled. 1502 // ASSERTs are disabled.
1503 LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1504 << " => " << state;
1432 switch (ice_connection_state_) { 1505 switch (ice_connection_state_) {
1433 case PeerConnectionInterface::kIceConnectionNew: 1506 case PeerConnectionInterface::kIceConnectionNew:
1434 ASSERT(state == PeerConnectionInterface::kIceConnectionChecking); 1507 ASSERT(state == PeerConnectionInterface::kIceConnectionChecking);
1435 break; 1508 break;
1436 case PeerConnectionInterface::kIceConnectionChecking: 1509 case PeerConnectionInterface::kIceConnectionChecking:
1437 ASSERT(state == PeerConnectionInterface::kIceConnectionFailed || 1510 ASSERT(state == PeerConnectionInterface::kIceConnectionFailed ||
1438 state == PeerConnectionInterface::kIceConnectionConnected); 1511 state == PeerConnectionInterface::kIceConnectionConnected);
1439 break; 1512 break;
1440 case PeerConnectionInterface::kIceConnectionConnected: 1513 case PeerConnectionInterface::kIceConnectionConnected:
1441 ASSERT(state == PeerConnectionInterface::kIceConnectionDisconnected || 1514 ASSERT(state == PeerConnectionInterface::kIceConnectionDisconnected ||
(...skipping 20 matching lines...) Expand all
1462 ASSERT(false); 1535 ASSERT(false);
1463 break; 1536 break;
1464 } 1537 }
1465 1538
1466 ice_connection_state_ = state; 1539 ice_connection_state_ = state;
1467 if (ice_observer_) { 1540 if (ice_observer_) {
1468 ice_observer_->OnIceConnectionChange(ice_connection_state_); 1541 ice_observer_->OnIceConnectionChange(ice_connection_state_);
1469 } 1542 }
1470 } 1543 }
1471 1544
1472 void WebRtcSession::OnTransportRequestSignaling( 1545 void WebRtcSession::OnTransportControllerConnectionState(
1473 cricket::Transport* transport) { 1546 cricket::IceConnectionState state) {
1474 ASSERT(signaling_thread()->IsCurrent()); 1547 switch (state) {
1475 transport->OnSignalingReady(); 1548 case cricket::kIceConnectionConnecting:
1476 if (ice_observer_) { 1549 // If the current state is Connected or Completed, then there were
1477 ice_observer_->OnIceGatheringChange( 1550 // writable channels but now there are not, so the next state must
1478 PeerConnectionInterface::kIceGatheringGathering); 1551 // be Disconnected.
1552 // kIceConnectionConnecting is currently used as the default,
1553 // un-connected state by the TransportController, so its only use is
1554 // detecting disconnections.
1555 if (ice_connection_state_ ==
1556 PeerConnectionInterface::kIceConnectionConnected ||
1557 ice_connection_state_ ==
1558 PeerConnectionInterface::kIceConnectionCompleted) {
1559 SetIceConnectionState(
1560 PeerConnectionInterface::kIceConnectionDisconnected);
1561 }
1562 break;
1563 case cricket::kIceConnectionFailed:
1564 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
1565 break;
1566 case cricket::kIceConnectionConnected:
1567 LOG(LS_INFO) << "Changing to ICE connected state because "
1568 << "all transports are writable.";
1569 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
1570 break;
1571 case cricket::kIceConnectionCompleted:
1572 LOG(LS_INFO) << "Changing to ICE completed state because "
1573 << "all transports are complete.";
1574 if (ice_connection_state_ !=
1575 PeerConnectionInterface::kIceConnectionConnected) {
1576 // If jumping directly from "checking" to "connected",
1577 // signal "connected" first.
1578 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
1579 }
1580 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
1581 if (metrics_observer_) {
1582 ReportTransportStats();
1583 }
1584 break;
1585 default:
1586 ASSERT(false);
1479 } 1587 }
1480 } 1588 }
1481 1589
1482 void WebRtcSession::OnTransportConnecting(cricket::Transport* transport) { 1590 void WebRtcSession::OnTransportControllerReceiving(bool receiving) {
1483 ASSERT(signaling_thread()->IsCurrent());
1484 // start monitoring for the write state of the transport.
1485 OnTransportWritable(transport);
1486 }
1487
1488 void WebRtcSession::OnTransportWritable(cricket::Transport* transport) {
1489 ASSERT(signaling_thread()->IsCurrent());
1490 if (transport->all_channels_writable()) {
1491 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
1492 } else if (transport->HasChannels()) {
1493 // If the current state is Connected or Completed, then there were writable
1494 // channels but now there are not, so the next state must be Disconnected.
1495 if (ice_connection_state_ ==
1496 PeerConnectionInterface::kIceConnectionConnected ||
1497 ice_connection_state_ ==
1498 PeerConnectionInterface::kIceConnectionCompleted) {
1499 SetIceConnectionState(
1500 PeerConnectionInterface::kIceConnectionDisconnected);
1501 }
1502 }
1503 }
1504
1505 void WebRtcSession::OnTransportCompleted(cricket::Transport* transport) {
1506 ASSERT(signaling_thread()->IsCurrent());
1507 PeerConnectionInterface::IceConnectionState old_state = ice_connection_state_;
1508 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
1509 // Only report once when Ice connection is completed.
1510 if (old_state != PeerConnectionInterface::kIceConnectionCompleted) {
1511 cricket::TransportStats stats;
1512 if (metrics_observer_ && transport->GetStats(&stats)) {
1513 ReportBestConnectionState(stats);
1514 ReportNegotiatedCiphers(stats);
1515 }
1516 }
1517 }
1518
1519 void WebRtcSession::OnTransportFailed(cricket::Transport* transport) {
1520 ASSERT(signaling_thread()->IsCurrent());
1521 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
1522 }
1523
1524 void WebRtcSession::OnTransportReceiving(cricket::Transport* transport) {
1525 ASSERT(signaling_thread()->IsCurrent());
1526 // The ice connection is considered receiving if at least one transport is
1527 // receiving on any channels.
1528 bool receiving = false;
1529 for (const auto& kv : transport_proxies()) {
1530 cricket::Transport* transport = kv.second->impl();
1531 if (transport && transport->any_channel_receiving()) {
1532 receiving = true;
1533 break;
1534 }
1535 }
1536 SetIceConnectionReceiving(receiving); 1591 SetIceConnectionReceiving(receiving);
1537 } 1592 }
1538 1593
1539 void WebRtcSession::SetIceConnectionReceiving(bool receiving) { 1594 void WebRtcSession::SetIceConnectionReceiving(bool receiving) {
1540 if (ice_connection_receiving_ == receiving) { 1595 if (ice_connection_receiving_ == receiving) {
1541 return; 1596 return;
1542 } 1597 }
1543 ice_connection_receiving_ = receiving; 1598 ice_connection_receiving_ = receiving;
1544 if (ice_observer_) { 1599 if (ice_observer_) {
1545 ice_observer_->OnIceConnectionReceivingChange(receiving); 1600 ice_observer_->OnIceConnectionReceivingChange(receiving);
1546 } 1601 }
1547 } 1602 }
1548 1603
1549 void WebRtcSession::OnTransportProxyCandidatesReady( 1604 void WebRtcSession::OnTransportControllerCandidatesGathered(
1550 cricket::TransportProxy* proxy, const cricket::Candidates& candidates) { 1605 const std::string& transport_name,
1606 const cricket::Candidates& candidates) {
1551 ASSERT(signaling_thread()->IsCurrent()); 1607 ASSERT(signaling_thread()->IsCurrent());
1552 ProcessNewLocalCandidate(proxy->content_name(), candidates); 1608 int sdp_mline_index;
1553 } 1609 if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
1610 LOG(LS_ERROR) << "OnTransportControllerCandidatesGathered: content name "
1611 << transport_name << " not found";
1612 return;
1613 }
1554 1614
1555 void WebRtcSession::OnCandidatesAllocationDone() { 1615 for (cricket::Candidates::const_iterator citer = candidates.begin();
1556 ASSERT(signaling_thread()->IsCurrent()); 1616 citer != candidates.end(); ++citer) {
1557 if (ice_observer_) { 1617 // Use transport_name as the candidate media id.
1558 ice_observer_->OnIceGatheringChange( 1618 JsepIceCandidate candidate(transport_name, sdp_mline_index, *citer);
1559 PeerConnectionInterface::kIceGatheringComplete); 1619 if (ice_observer_) {
1560 ice_observer_->OnIceComplete(); 1620 ice_observer_->OnIceCandidate(&candidate);
1621 }
1622 if (local_desc_) {
1623 local_desc_->AddCandidate(&candidate);
1624 }
1561 } 1625 }
1562 } 1626 }
1563 1627
1564 // Enabling voice and video channel. 1628 // Enabling voice and video channel.
1565 void WebRtcSession::EnableChannels() { 1629 void WebRtcSession::EnableChannels() {
1566 if (voice_channel_ && !voice_channel_->enabled()) 1630 if (voice_channel_ && !voice_channel_->enabled())
1567 voice_channel_->Enable(true); 1631 voice_channel_->Enable(true);
1568 1632
1569 if (video_channel_ && !video_channel_->enabled()) 1633 if (video_channel_ && !video_channel_->enabled())
1570 video_channel_->Enable(true); 1634 video_channel_->Enable(true);
1571 1635
1572 if (data_channel_ && !data_channel_->enabled()) 1636 if (data_channel_ && !data_channel_->enabled())
1573 data_channel_->Enable(true); 1637 data_channel_->Enable(true);
1574 } 1638 }
1575 1639
1576 void WebRtcSession::ProcessNewLocalCandidate(
1577 const std::string& content_name,
1578 const cricket::Candidates& candidates) {
1579 int sdp_mline_index;
1580 if (!GetLocalCandidateMediaIndex(content_name, &sdp_mline_index)) {
1581 LOG(LS_ERROR) << "ProcessNewLocalCandidate: content name "
1582 << content_name << " not found";
1583 return;
1584 }
1585
1586 for (cricket::Candidates::const_iterator citer = candidates.begin();
1587 citer != candidates.end(); ++citer) {
1588 // Use content_name as the candidate media id.
1589 JsepIceCandidate candidate(content_name, sdp_mline_index, *citer);
1590 if (ice_observer_) {
1591 ice_observer_->OnIceCandidate(&candidate);
1592 }
1593 if (local_desc_) {
1594 local_desc_->AddCandidate(&candidate);
1595 }
1596 }
1597 }
1598
1599 // Returns the media index for a local ice candidate given the content name. 1640 // Returns the media index for a local ice candidate given the content name.
1600 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name, 1641 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name,
1601 int* sdp_mline_index) { 1642 int* sdp_mline_index) {
1602 if (!base_local_description() || !sdp_mline_index) 1643 if (!base_local_description() || !sdp_mline_index)
1603 return false; 1644 return false;
1604 1645
1605 bool content_found = false; 1646 bool content_found = false;
1606 const ContentInfos& contents = base_local_description()->contents(); 1647 const ContentInfos& contents = base_local_description()->contents();
1607 for (size_t index = 0; index < contents.size(); ++index) { 1648 for (size_t index = 0; index < contents.size(); ++index) {
1608 if (contents[index].name == content_name) { 1649 if (contents[index].name == content_name) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1653 << "UseRemoteCandidateInSession: Invalid candidate media index."; 1694 << "UseRemoteCandidateInSession: Invalid candidate media index.";
1654 return false; 1695 return false;
1655 } 1696 }
1656 1697
1657 cricket::ContentInfo content = 1698 cricket::ContentInfo content =
1658 base_remote_description()->contents()[mediacontent_index]; 1699 base_remote_description()->contents()[mediacontent_index];
1659 std::vector<cricket::Candidate> candidates; 1700 std::vector<cricket::Candidate> candidates;
1660 candidates.push_back(candidate->candidate()); 1701 candidates.push_back(candidate->candidate());
1661 // Invoking BaseSession method to handle remote candidates. 1702 // Invoking BaseSession method to handle remote candidates.
1662 std::string error; 1703 std::string error;
1663 if (OnRemoteCandidates(content.name, candidates, &error)) { 1704 if (transport_controller()->AddRemoteCandidates(content.name, candidates,
1705 &error)) {
1664 // Candidates successfully submitted for checking. 1706 // Candidates successfully submitted for checking.
1665 if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew || 1707 if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew ||
1666 ice_connection_state_ == 1708 ice_connection_state_ ==
1667 PeerConnectionInterface::kIceConnectionDisconnected) { 1709 PeerConnectionInterface::kIceConnectionDisconnected) {
1668 // If state is New, then the session has just gotten its first remote ICE 1710 // If state is New, then the session has just gotten its first remote ICE
1669 // candidates, so go to Checking. 1711 // candidates, so go to Checking.
1670 // If state is Disconnected, the session is re-using old candidates or 1712 // If state is Disconnected, the session is re-using old candidates or
1671 // receiving additional ones, so go to Checking. 1713 // receiving additional ones, so go to Checking.
1672 // If state is Connected, stay Connected. 1714 // If state is Connected, stay Connected.
1673 // TODO(bemasc): If state is Connected, and the new candidates are for a 1715 // TODO(bemasc): If state is Connected, and the new candidates are for a
1674 // newly added transport, then the state actually _should_ move to 1716 // newly added transport, then the state actually _should_ move to
1675 // checking. Add a way to distinguish that case. 1717 // checking. Add a way to distinguish that case.
1676 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking); 1718 SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
1677 } 1719 }
1678 // TODO(bemasc): If state is Completed, go back to Connected. 1720 // TODO(bemasc): If state is Completed, go back to Connected.
1679 } else { 1721 } else {
1680 if (!error.empty()) { 1722 if (!error.empty()) {
1681 LOG(LS_WARNING) << error; 1723 LOG(LS_WARNING) << error;
1682 } 1724 }
1683 } 1725 }
1684 return true; 1726 return true;
1685 } 1727 }
1686 1728
1687 void WebRtcSession::RemoveUnusedChannelsAndTransports( 1729 void WebRtcSession::RemoveUnusedChannels(const SessionDescription* desc) {
1688 const SessionDescription* desc) {
1689 // Destroy video_channel_ first since it may have a pointer to the 1730 // Destroy video_channel_ first since it may have a pointer to the
1690 // voice_channel_. 1731 // voice_channel_.
1691 const cricket::ContentInfo* video_info = 1732 const cricket::ContentInfo* video_info =
1692 cricket::GetFirstVideoContent(desc); 1733 cricket::GetFirstVideoContent(desc);
1693 if ((!video_info || video_info->rejected) && video_channel_) { 1734 if ((!video_info || video_info->rejected) && video_channel_) {
1694 mediastream_signaling_->OnVideoChannelClose(); 1735 mediastream_signaling_->OnVideoChannelClose();
1695 SignalVideoChannelDestroyed(); 1736 SignalVideoChannelDestroyed();
1696 const std::string content_name = video_channel_->content_name(); 1737 const std::string content_name = video_channel_->content_name();
1697 channel_manager_->DestroyVideoChannel(video_channel_.release()); 1738 channel_manager_->DestroyVideoChannel(video_channel_.release());
1698 DestroyTransportProxy(content_name);
1699 } 1739 }
1700 1740
1701 const cricket::ContentInfo* voice_info = 1741 const cricket::ContentInfo* voice_info =
1702 cricket::GetFirstAudioContent(desc); 1742 cricket::GetFirstAudioContent(desc);
1703 if ((!voice_info || voice_info->rejected) && voice_channel_) { 1743 if ((!voice_info || voice_info->rejected) && voice_channel_) {
1704 mediastream_signaling_->OnAudioChannelClose(); 1744 mediastream_signaling_->OnAudioChannelClose();
1705 SignalVoiceChannelDestroyed(); 1745 SignalVoiceChannelDestroyed();
1706 const std::string content_name = voice_channel_->content_name(); 1746 const std::string content_name = voice_channel_->content_name();
1707 channel_manager_->DestroyVoiceChannel(voice_channel_.release(), 1747 channel_manager_->DestroyVoiceChannel(voice_channel_.release(),
1708 video_channel_.get()); 1748 video_channel_.get());
1709 DestroyTransportProxy(content_name);
1710 } 1749 }
1711 1750
1712 const cricket::ContentInfo* data_info = 1751 const cricket::ContentInfo* data_info =
1713 cricket::GetFirstDataContent(desc); 1752 cricket::GetFirstDataContent(desc);
1714 if ((!data_info || data_info->rejected) && data_channel_) { 1753 if ((!data_info || data_info->rejected) && data_channel_) {
1715 mediastream_signaling_->OnDataChannelClose(); 1754 mediastream_signaling_->OnDataChannelClose();
1716 SignalDataChannelDestroyed(); 1755 SignalDataChannelDestroyed();
1717 const std::string content_name = data_channel_->content_name(); 1756 const std::string content_name = data_channel_->content_name();
1718 channel_manager_->DestroyDataChannel(data_channel_.release()); 1757 channel_manager_->DestroyDataChannel(data_channel_.release());
1719 DestroyTransportProxy(content_name);
1720 } 1758 }
1721 } 1759 }
1722 1760
1723 // TODO(mallinath) - Add a correct error code if the channels are not creatued 1761 // TODO(mallinath) - Add a correct error code if the channels are not creatued
1724 // due to BUNDLE is enabled but rtcp-mux is disabled. 1762 // due to BUNDLE is enabled but rtcp-mux is disabled.
1725 bool WebRtcSession::CreateChannels(const SessionDescription* desc) { 1763 bool WebRtcSession::CreateChannels(const SessionDescription* desc) {
1726 // Creating the media channels and transport proxies. 1764 // Creating the media channels and transport proxies.
1727 const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc); 1765 const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc);
1728 if (voice && !voice->rejected && !voice_channel_) { 1766 if (voice && !voice->rejected && !voice_channel_) {
1729 if (!CreateVoiceChannel(voice)) { 1767 if (!CreateVoiceChannel(voice)) {
(...skipping 24 matching lines...) Expand all
1754 voice_channel()->ActivateRtcpMux(); 1792 voice_channel()->ActivateRtcpMux();
1755 } 1793 }
1756 if (video_channel()) { 1794 if (video_channel()) {
1757 video_channel()->ActivateRtcpMux(); 1795 video_channel()->ActivateRtcpMux();
1758 } 1796 }
1759 if (data_channel()) { 1797 if (data_channel()) {
1760 data_channel()->ActivateRtcpMux(); 1798 data_channel()->ActivateRtcpMux();
1761 } 1799 }
1762 } 1800 }
1763 1801
1764 // Enable bundle before when kMaxBundle policy is in effect. 1802 // Enable BUNDLE immediately when kBundlePolicyMaxBundle is in effect.
1765 if (bundle_policy_ == PeerConnectionInterface::kBundlePolicyMaxBundle) { 1803 if (bundle_policy_ == PeerConnectionInterface::kBundlePolicyMaxBundle) {
1766 const cricket::ContentGroup* bundle_group = desc->GetGroupByName( 1804 const cricket::ContentGroup* bundle_group = desc->GetGroupByName(
1767 cricket::GROUP_TYPE_BUNDLE); 1805 cricket::GROUP_TYPE_BUNDLE);
1768 if (!bundle_group) { 1806 if (!bundle_group) {
1769 LOG(LS_WARNING) << "max-bundle specified without BUNDLE specified"; 1807 LOG(LS_WARNING) << "max-bundle specified without BUNDLE specified";
1770 return false; 1808 return false;
1771 } 1809 }
1772 if (!BaseSession::BundleContentGroup(bundle_group)) { 1810 if (!EnableBundle(*bundle_group)) {
1773 LOG(LS_WARNING) << "max-bundle failed to enable bundling."; 1811 LOG(LS_WARNING) << "max-bundle failed to enable bundling.";
1774 return false; 1812 return false;
1775 } 1813 }
1776 } 1814 }
1777 1815
1778 return true; 1816 return true;
1779 } 1817 }
1780 1818
1781 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) { 1819 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) {
1782 voice_channel_.reset(channel_manager_->CreateVoiceChannel( 1820 voice_channel_.reset(channel_manager_->CreateVoiceChannel(
1783 this, content->name, true, audio_options_)); 1821 transport_controller(), content->name, true, audio_options_));
1784 if (!voice_channel_) { 1822 if (!voice_channel_) {
1785 return false; 1823 return false;
1786 } 1824 }
1787 1825
1788 voice_channel_->SignalDtlsSetupFailure.connect( 1826 voice_channel_->SignalDtlsSetupFailure.connect(
1789 this, &WebRtcSession::OnDtlsSetupFailure); 1827 this, &WebRtcSession::OnDtlsSetupFailure);
1790 return true; 1828 return true;
1791 } 1829 }
1792 1830
1793 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) { 1831 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) {
1794 video_channel_.reset(channel_manager_->CreateVideoChannel( 1832 video_channel_.reset(channel_manager_->CreateVideoChannel(
1795 this, content->name, true, video_options_, voice_channel_.get())); 1833 transport_controller(), content->name, true, video_options_,
1834 voice_channel_.get()));
1796 if (!video_channel_) { 1835 if (!video_channel_) {
1797 return false; 1836 return false;
1798 } 1837 }
1799 1838
1800 video_channel_->SignalDtlsSetupFailure.connect( 1839 video_channel_->SignalDtlsSetupFailure.connect(
1801 this, &WebRtcSession::OnDtlsSetupFailure); 1840 this, &WebRtcSession::OnDtlsSetupFailure);
1802 return true; 1841 return true;
1803 } 1842 }
1804 1843
1805 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) { 1844 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) {
1806 bool sctp = (data_channel_type_ == cricket::DCT_SCTP); 1845 bool sctp = (data_channel_type_ == cricket::DCT_SCTP);
1807 data_channel_.reset(channel_manager_->CreateDataChannel( 1846 data_channel_.reset(channel_manager_->CreateDataChannel(
1808 this, content->name, !sctp, data_channel_type_)); 1847 transport_controller(), content->name, !sctp, data_channel_type_));
1809 if (!data_channel_) { 1848 if (!data_channel_) {
1810 return false; 1849 return false;
1811 } 1850 }
1812 1851
1813 if (sctp) { 1852 if (sctp) {
1814 mediastream_signaling_->OnDataTransportCreatedForSctp(); 1853 mediastream_signaling_->OnDataTransportCreatedForSctp();
1815 data_channel_->SignalDataReceived.connect( 1854 data_channel_->SignalDataReceived.connect(
1816 this, &WebRtcSession::OnDataChannelMessageReceived); 1855 this, &WebRtcSession::OnDataChannelMessageReceived);
1817 data_channel_->SignalStreamClosedRemotely.connect( 1856 data_channel_->SignalStreamClosedRemotely.connect(
1818 mediastream_signaling_, 1857 mediastream_signaling_,
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1979 // We need to check the local/remote description for the Transport instead of 2018 // We need to check the local/remote description for the Transport instead of
1980 // the session, because a new Transport added during renegotiation may have 2019 // the session, because a new Transport added during renegotiation may have
1981 // them unset while the session has them set from the previous negotiation. 2020 // them unset while the session has them set from the previous negotiation.
1982 // Not doing so may trigger the auto generation of transport description and 2021 // Not doing so may trigger the auto generation of transport description and
1983 // mess up DTLS identity information, ICE credential, etc. 2022 // mess up DTLS identity information, ICE credential, etc.
1984 bool WebRtcSession::ReadyToUseRemoteCandidate( 2023 bool WebRtcSession::ReadyToUseRemoteCandidate(
1985 const IceCandidateInterface* candidate, 2024 const IceCandidateInterface* candidate,
1986 const SessionDescriptionInterface* remote_desc, 2025 const SessionDescriptionInterface* remote_desc,
1987 bool* valid) { 2026 bool* valid) {
1988 *valid = true;; 2027 *valid = true;;
1989 cricket::TransportProxy* transport_proxy = NULL;
1990 2028
1991 const SessionDescriptionInterface* current_remote_desc = 2029 const SessionDescriptionInterface* current_remote_desc =
1992 remote_desc ? remote_desc : remote_description(); 2030 remote_desc ? remote_desc : remote_description();
1993 2031
1994 if (!current_remote_desc) 2032 if (!current_remote_desc)
1995 return false; 2033 return false;
1996 2034
1997 size_t mediacontent_index = 2035 size_t mediacontent_index =
1998 static_cast<size_t>(candidate->sdp_mline_index()); 2036 static_cast<size_t>(candidate->sdp_mline_index());
1999 size_t remote_content_size = 2037 size_t remote_content_size =
2000 current_remote_desc->description()->contents().size(); 2038 current_remote_desc->description()->contents().size();
2001 if (mediacontent_index >= remote_content_size) { 2039 if (mediacontent_index >= remote_content_size) {
2002 LOG(LS_ERROR) 2040 LOG(LS_ERROR)
2003 << "ReadyToUseRemoteCandidate: Invalid candidate media index."; 2041 << "ReadyToUseRemoteCandidate: Invalid candidate media index.";
2004 2042
2005 *valid = false; 2043 *valid = false;
2006 return false; 2044 return false;
2007 } 2045 }
2008 2046
2009 cricket::ContentInfo content = 2047 cricket::ContentInfo content =
2010 current_remote_desc->description()->contents()[mediacontent_index]; 2048 current_remote_desc->description()->contents()[mediacontent_index];
2011 transport_proxy = GetTransportProxy(content.name); 2049 cricket::BaseChannel* channel = GetChannel(content.name);
2050 if (!channel) {
2051 return false;
2052 }
2012 2053
2013 return transport_proxy && transport_proxy->local_description_set() && 2054 return transport_controller()->ReadyForRemoteCandidates(
2014 transport_proxy->remote_description_set(); 2055 channel->transport_name());
2015 } 2056 }
2016 2057
2058 void WebRtcSession::OnTransportControllerGatheringState(
2059 cricket::IceGatheringState state) {
2060 ASSERT(signaling_thread()->IsCurrent());
2061 if (state == cricket::kIceGatheringGathering) {
2062 if (ice_observer_) {
2063 ice_observer_->OnIceGatheringChange(
2064 PeerConnectionInterface::kIceGatheringGathering);
2065 }
2066 } else if (state == cricket::kIceGatheringComplete) {
2067 if (ice_observer_) {
2068 ice_observer_->OnIceGatheringChange(
2069 PeerConnectionInterface::kIceGatheringComplete);
2070 ice_observer_->OnIceComplete();
2071 }
2072 }
2073 }
2074
2075 void WebRtcSession::ReportTransportStats() {
2076 // Use a set so we don't report the same stats twice if two channels share
2077 // a transport.
2078 std::set<std::string> transport_names;
2079 if (voice_channel()) {
2080 transport_names.insert(voice_channel()->transport_name());
2081 }
2082 if (video_channel()) {
2083 transport_names.insert(video_channel()->transport_name());
2084 }
2085 if (data_channel()) {
2086 transport_names.insert(data_channel()->transport_name());
2087 }
2088 for (const auto& name : transport_names) {
2089 cricket::TransportStats stats;
2090 if (transport_controller()->GetStats(name, &stats)) {
2091 ReportBestConnectionState(stats);
2092 ReportNegotiatedCiphers(stats);
2093 }
2094 }
2095 }
2017 // Walk through the ConnectionInfos to gather best connection usage 2096 // Walk through the ConnectionInfos to gather best connection usage
2018 // for IPv4 and IPv6. 2097 // for IPv4 and IPv6.
2019 void WebRtcSession::ReportBestConnectionState( 2098 void WebRtcSession::ReportBestConnectionState(
2020 const cricket::TransportStats& stats) { 2099 const cricket::TransportStats& stats) {
2021 DCHECK(metrics_observer_ != NULL); 2100 DCHECK(metrics_observer_ != NULL);
2022 for (cricket::TransportChannelStatsList::const_iterator it = 2101 for (cricket::TransportChannelStatsList::const_iterator it =
2023 stats.channel_stats.begin(); 2102 stats.channel_stats.begin();
2024 it != stats.channel_stats.end(); ++it) { 2103 it != stats.channel_stats.end(); ++it) {
2025 for (cricket::ConnectionInfos::const_iterator it_info = 2104 for (cricket::ConnectionInfos::const_iterator it_info =
2026 it->connection_infos.begin(); 2105 it->connection_infos.begin();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2074 } 2153 }
2075 2154
2076 const std::string& srtp_cipher = stats.channel_stats[0].srtp_cipher; 2155 const std::string& srtp_cipher = stats.channel_stats[0].srtp_cipher;
2077 const std::string& ssl_cipher = stats.channel_stats[0].ssl_cipher; 2156 const std::string& ssl_cipher = stats.channel_stats[0].ssl_cipher;
2078 if (srtp_cipher.empty() && ssl_cipher.empty()) { 2157 if (srtp_cipher.empty() && ssl_cipher.empty()) {
2079 return; 2158 return;
2080 } 2159 }
2081 2160
2082 PeerConnectionMetricsName srtp_name; 2161 PeerConnectionMetricsName srtp_name;
2083 PeerConnectionMetricsName ssl_name; 2162 PeerConnectionMetricsName ssl_name;
2084 if (stats.content_name == cricket::CN_AUDIO) { 2163 if (stats.transport_name == cricket::CN_AUDIO) {
2085 srtp_name = kAudioSrtpCipher; 2164 srtp_name = kAudioSrtpCipher;
2086 ssl_name = kAudioSslCipher; 2165 ssl_name = kAudioSslCipher;
2087 } else if (stats.content_name == cricket::CN_VIDEO) { 2166 } else if (stats.transport_name == cricket::CN_VIDEO) {
2088 srtp_name = kVideoSrtpCipher; 2167 srtp_name = kVideoSrtpCipher;
2089 ssl_name = kVideoSslCipher; 2168 ssl_name = kVideoSslCipher;
2090 } else if (stats.content_name == cricket::CN_DATA) { 2169 } else if (stats.transport_name == cricket::CN_DATA) {
2091 srtp_name = kDataSrtpCipher; 2170 srtp_name = kDataSrtpCipher;
2092 ssl_name = kDataSslCipher; 2171 ssl_name = kDataSslCipher;
2093 } else { 2172 } else {
2094 RTC_NOTREACHED(); 2173 RTC_NOTREACHED();
2095 return; 2174 return;
2096 } 2175 }
2097 2176
2098 if (!srtp_cipher.empty()) { 2177 if (!srtp_cipher.empty()) {
2099 metrics_observer_->AddHistogramSample(srtp_name, srtp_cipher); 2178 metrics_observer_->AddHistogramSample(srtp_name, srtp_cipher);
2100 } 2179 }
2101 if (!ssl_cipher.empty()) { 2180 if (!ssl_cipher.empty()) {
2102 metrics_observer_->AddHistogramSample(ssl_name, ssl_cipher); 2181 metrics_observer_->AddHistogramSample(ssl_name, ssl_cipher);
2103 } 2182 }
2104 } 2183 }
2105 2184
2106 } // namespace webrtc 2185 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698