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