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