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