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