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