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