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