OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... | |
26 #include "webrtc/base/basictypes.h" | 26 #include "webrtc/base/basictypes.h" |
27 #include "webrtc/base/bind.h" | 27 #include "webrtc/base/bind.h" |
28 #include "webrtc/base/checks.h" | 28 #include "webrtc/base/checks.h" |
29 #include "webrtc/base/helpers.h" | 29 #include "webrtc/base/helpers.h" |
30 #include "webrtc/base/logging.h" | 30 #include "webrtc/base/logging.h" |
31 #include "webrtc/base/stringencode.h" | 31 #include "webrtc/base/stringencode.h" |
32 #include "webrtc/base/stringutils.h" | 32 #include "webrtc/base/stringutils.h" |
33 #include "webrtc/call/call.h" | 33 #include "webrtc/call/call.h" |
34 #include "webrtc/media/base/mediaconstants.h" | 34 #include "webrtc/media/base/mediaconstants.h" |
35 #include "webrtc/media/base/videocapturer.h" | 35 #include "webrtc/media/base/videocapturer.h" |
36 #include "webrtc/media/sctp/sctptransportinternal.h" | |
36 #include "webrtc/p2p/base/portallocator.h" | 37 #include "webrtc/p2p/base/portallocator.h" |
37 #include "webrtc/p2p/base/transportchannel.h" | 38 #include "webrtc/p2p/base/transportchannel.h" |
38 #include "webrtc/pc/channel.h" | 39 #include "webrtc/pc/channel.h" |
39 #include "webrtc/pc/channelmanager.h" | 40 #include "webrtc/pc/channelmanager.h" |
40 #include "webrtc/pc/mediasession.h" | 41 #include "webrtc/pc/mediasession.h" |
41 | 42 |
42 #ifdef HAVE_QUIC | 43 #ifdef HAVE_QUIC |
43 #include "webrtc/p2p/quic/quictransportchannel.h" | 44 #include "webrtc/p2p/quic/quictransportchannel.h" |
44 #endif // HAVE_QUIC | 45 #endif // HAVE_QUIC |
45 | 46 |
(...skipping 21 matching lines...) Expand all Loading... | |
67 const char kPushDownTDFailed[] = | 68 const char kPushDownTDFailed[] = |
68 "Failed to push down transport description:"; | 69 "Failed to push down transport description:"; |
69 const char kSdpWithoutDtlsFingerprint[] = | 70 const char kSdpWithoutDtlsFingerprint[] = |
70 "Called with SDP without DTLS fingerprint."; | 71 "Called with SDP without DTLS fingerprint."; |
71 const char kSdpWithoutSdesCrypto[] = | 72 const char kSdpWithoutSdesCrypto[] = |
72 "Called with SDP without SDES crypto."; | 73 "Called with SDP without SDES crypto."; |
73 const char kSdpWithoutIceUfragPwd[] = | 74 const char kSdpWithoutIceUfragPwd[] = |
74 "Called with SDP without ice-ufrag and ice-pwd."; | 75 "Called with SDP without ice-ufrag and ice-pwd."; |
75 const char kSessionError[] = "Session error code: "; | 76 const char kSessionError[] = "Session error code: "; |
76 const char kSessionErrorDesc[] = "Session error description: "; | 77 const char kSessionErrorDesc[] = "Session error description: "; |
77 const char kDtlsSetupFailureRtp[] = | 78 const char kDtlsSrtpSetupFailureRtp[] = |
78 "Couldn't set up DTLS-SRTP on RTP channel."; | 79 "Couldn't set up DTLS-SRTP on RTP channel."; |
79 const char kDtlsSetupFailureRtcp[] = | 80 const char kDtlsSrtpSetupFailureRtcp[] = |
80 "Couldn't set up DTLS-SRTP on RTCP channel."; | 81 "Couldn't set up DTLS-SRTP on RTCP channel."; |
81 const char kEnableBundleFailed[] = "Failed to enable BUNDLE."; | 82 const char kEnableBundleFailed[] = "Failed to enable BUNDLE."; |
82 | 83 |
83 IceCandidatePairType GetIceCandidatePairCounter( | 84 IceCandidatePairType GetIceCandidatePairCounter( |
84 const cricket::Candidate& local, | 85 const cricket::Candidate& local, |
85 const cricket::Candidate& remote) { | 86 const cricket::Candidate& remote) { |
86 const auto& l = local.type(); | 87 const auto& l = local.type(); |
87 const auto& r = remote.type(); | 88 const auto& r = remote.type(); |
88 const auto& host = LOCAL_PORT_TYPE; | 89 const auto& host = LOCAL_PORT_TYPE; |
89 const auto& srflx = STUN_PORT_TYPE; | 90 const auto& srflx = STUN_PORT_TYPE; |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 const auto* found = | 285 const auto* found = |
285 cricket::GetStreamBySsrc(video_content->streams(), ssrc); | 286 cricket::GetStreamBySsrc(video_content->streams(), ssrc); |
286 if (found) { | 287 if (found) { |
287 *track_id = found->id; | 288 *track_id = found->id; |
288 return true; | 289 return true; |
289 } | 290 } |
290 } | 291 } |
291 return false; | 292 return false; |
292 } | 293 } |
293 | 294 |
295 // Get the SCTP port out of a SessionDescription. | |
296 // Return -1 if not found. | |
297 static int GetSctpPort(const SessionDescription* session_description) { | |
298 const ContentInfo* content_info = GetFirstDataContent(session_description); | |
299 RTC_DCHECK(content_info); | |
300 if (!content_info) { | |
301 return -1; | |
302 } | |
303 const cricket::DataContentDescription* data = | |
304 static_cast<const cricket::DataContentDescription*>( | |
305 (content_info->description)); | |
306 std::string value; | |
307 cricket::DataCodec match_pattern(cricket::kGoogleSctpDataCodecPlType, | |
308 cricket::kGoogleSctpDataCodecName); | |
309 for (const cricket::DataCodec& codec : data->codecs()) { | |
310 if (!codec.Matches(match_pattern)) { | |
311 continue; | |
312 } | |
313 if (codec.GetParam(cricket::kCodecParamPort, &value)) { | |
314 return rtc::FromString<int>(value); | |
315 } | |
316 } | |
317 return -1; | |
318 } | |
319 | |
294 static bool BadSdp(const std::string& source, | 320 static bool BadSdp(const std::string& source, |
295 const std::string& type, | 321 const std::string& type, |
296 const std::string& reason, | 322 const std::string& reason, |
297 std::string* err_desc) { | 323 std::string* err_desc) { |
298 std::ostringstream desc; | 324 std::ostringstream desc; |
299 desc << "Failed to set " << source; | 325 desc << "Failed to set " << source; |
300 if (!type.empty()) { | 326 if (!type.empty()) { |
301 desc << " " << type; | 327 desc << " " << type; |
302 } | 328 } |
303 desc << " sdp: " << reason; | 329 desc << " sdp: " << reason; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
433 } | 459 } |
434 return false; | 460 return false; |
435 } | 461 } |
436 | 462 |
437 WebRtcSession::WebRtcSession( | 463 WebRtcSession::WebRtcSession( |
438 webrtc::MediaControllerInterface* media_controller, | 464 webrtc::MediaControllerInterface* media_controller, |
439 rtc::Thread* network_thread, | 465 rtc::Thread* network_thread, |
440 rtc::Thread* worker_thread, | 466 rtc::Thread* worker_thread, |
441 rtc::Thread* signaling_thread, | 467 rtc::Thread* signaling_thread, |
442 cricket::PortAllocator* port_allocator, | 468 cricket::PortAllocator* port_allocator, |
443 std::unique_ptr<cricket::TransportController> transport_controller) | 469 std::unique_ptr<cricket::TransportController> transport_controller, |
470 std::unique_ptr<cricket::SctpTransportInternalFactory> sctp_factory) | |
444 : network_thread_(network_thread), | 471 : network_thread_(network_thread), |
445 worker_thread_(worker_thread), | 472 worker_thread_(worker_thread), |
446 signaling_thread_(signaling_thread), | 473 signaling_thread_(signaling_thread), |
447 // RFC 3264: The numeric value of the session id and version in the | 474 // RFC 3264: The numeric value of the session id and version in the |
448 // o line MUST be representable with a "64 bit signed integer". | 475 // o line MUST be representable with a "64 bit signed integer". |
449 // Due to this constraint session id |sid_| is max limited to LLONG_MAX. | 476 // Due to this constraint session id |sid_| is max limited to LLONG_MAX. |
450 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)), | 477 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)), |
451 transport_controller_(std::move(transport_controller)), | 478 transport_controller_(std::move(transport_controller)), |
479 sctp_factory_(std::move(sctp_factory)), | |
452 media_controller_(media_controller), | 480 media_controller_(media_controller), |
453 channel_manager_(media_controller_->channel_manager()), | 481 channel_manager_(media_controller_->channel_manager()), |
454 ice_observer_(NULL), | 482 ice_observer_(NULL), |
455 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), | 483 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), |
456 ice_connection_receiving_(true), | 484 ice_connection_receiving_(true), |
457 older_version_remote_peer_(false), | 485 older_version_remote_peer_(false), |
458 dtls_enabled_(false), | 486 dtls_enabled_(false), |
459 data_channel_type_(cricket::DCT_NONE), | 487 data_channel_type_(cricket::DCT_NONE), |
460 metrics_observer_(NULL) { | 488 metrics_observer_(NULL) { |
461 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); | 489 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); |
462 transport_controller_->SignalConnectionState.connect( | 490 transport_controller_->SignalConnectionState.connect( |
463 this, &WebRtcSession::OnTransportControllerConnectionState); | 491 this, &WebRtcSession::OnTransportControllerConnectionState); |
464 transport_controller_->SignalReceiving.connect( | 492 transport_controller_->SignalReceiving.connect( |
465 this, &WebRtcSession::OnTransportControllerReceiving); | 493 this, &WebRtcSession::OnTransportControllerReceiving); |
466 transport_controller_->SignalGatheringState.connect( | 494 transport_controller_->SignalGatheringState.connect( |
467 this, &WebRtcSession::OnTransportControllerGatheringState); | 495 this, &WebRtcSession::OnTransportControllerGatheringState); |
468 transport_controller_->SignalCandidatesGathered.connect( | 496 transport_controller_->SignalCandidatesGathered.connect( |
469 this, &WebRtcSession::OnTransportControllerCandidatesGathered); | 497 this, &WebRtcSession::OnTransportControllerCandidatesGathered); |
470 transport_controller_->SignalCandidatesRemoved.connect( | 498 transport_controller_->SignalCandidatesRemoved.connect( |
471 this, &WebRtcSession::OnTransportControllerCandidatesRemoved); | 499 this, &WebRtcSession::OnTransportControllerCandidatesRemoved); |
472 transport_controller_->SignalDtlsHandshakeError.connect( | 500 transport_controller_->SignalDtlsHandshakeError.connect( |
473 this, &WebRtcSession::OnDtlsHandshakeError); | 501 this, &WebRtcSession::OnTransportControllerDtlsHandshakeError); |
474 } | 502 } |
475 | 503 |
476 WebRtcSession::~WebRtcSession() { | 504 WebRtcSession::~WebRtcSession() { |
477 ASSERT(signaling_thread()->IsCurrent()); | 505 ASSERT(signaling_thread()->IsCurrent()); |
478 // Destroy video_channel_ first since it may have a pointer to the | 506 // Destroy video_channel_ first since it may have a pointer to the |
479 // voice_channel_. | 507 // voice_channel_. |
480 if (video_channel_) { | 508 if (video_channel_) { |
481 SignalVideoChannelDestroyed(); | 509 SignalVideoChannelDestroyed(); |
482 channel_manager_->DestroyVideoChannel(video_channel_.release()); | 510 channel_manager_->DestroyVideoChannel(video_channel_.release()); |
483 } | 511 } |
484 if (voice_channel_) { | 512 if (voice_channel_) { |
485 SignalVoiceChannelDestroyed(); | 513 SignalVoiceChannelDestroyed(); |
486 channel_manager_->DestroyVoiceChannel(voice_channel_.release()); | 514 channel_manager_->DestroyVoiceChannel(voice_channel_.release()); |
487 } | 515 } |
488 if (data_channel_) { | 516 if (rtp_data_channel_) { |
489 SignalDataChannelDestroyed(); | 517 SignalDataChannelDestroyed(); |
490 channel_manager_->DestroyDataChannel(data_channel_.release()); | 518 channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release()); |
519 } | |
520 if (sctp_transport_) { | |
521 SignalDataChannelDestroyed(); | |
pthatcher1
2016/12/23 01:39:31
Should this be SignalSctpTransportDestroyed()?
Taylor Brandstetter
2016/12/23 06:29:05
It could also be an RtpDataChannel though.
| |
522 network_thread_->Invoke<void>( | |
523 RTC_FROM_HERE, rtc::Bind(&WebRtcSession::DestroySctpTransport_n, this)); | |
491 } | 524 } |
492 #ifdef HAVE_QUIC | 525 #ifdef HAVE_QUIC |
493 if (quic_data_transport_) { | 526 if (quic_data_transport_) { |
494 quic_data_transport_.reset(); | 527 quic_data_transport_.reset(); |
495 } | 528 } |
496 #endif | 529 #endif |
497 SignalDestroyed(); | 530 SignalDestroyed(); |
498 | 531 |
499 LOG(LS_INFO) << "Session: " << id() << " is destroyed."; | 532 LOG(LS_INFO) << "Session: " << id() << " is destroyed."; |
500 } | 533 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 if (options.disable_encryption) { | 623 if (options.disable_encryption) { |
591 webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED); | 624 webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED); |
592 } | 625 } |
593 | 626 |
594 return true; | 627 return true; |
595 } | 628 } |
596 | 629 |
597 void WebRtcSession::Close() { | 630 void WebRtcSession::Close() { |
598 SetState(STATE_CLOSED); | 631 SetState(STATE_CLOSED); |
599 RemoveUnusedChannels(nullptr); | 632 RemoveUnusedChannels(nullptr); |
600 ASSERT(!voice_channel_); | 633 RTC_DCHECK(!voice_channel_); |
601 ASSERT(!video_channel_); | 634 RTC_DCHECK(!video_channel_); |
602 ASSERT(!data_channel_); | 635 RTC_DCHECK(!rtp_data_channel_); |
636 RTC_DCHECK(!sctp_transport_); | |
603 media_controller_->Close(); | 637 media_controller_->Close(); |
604 } | 638 } |
605 | 639 |
606 cricket::BaseChannel* WebRtcSession::GetChannel( | 640 cricket::BaseChannel* WebRtcSession::GetChannel( |
607 const std::string& content_name) { | 641 const std::string& content_name) { |
608 if (voice_channel() && voice_channel()->content_name() == content_name) { | 642 if (voice_channel() && voice_channel()->content_name() == content_name) { |
609 return voice_channel(); | 643 return voice_channel(); |
610 } | 644 } |
611 if (video_channel() && video_channel()->content_name() == content_name) { | 645 if (video_channel() && video_channel()->content_name() == content_name) { |
612 return video_channel(); | 646 return video_channel(); |
613 } | 647 } |
614 if (data_channel() && data_channel()->content_name() == content_name) { | 648 if (rtp_data_channel() && |
615 return data_channel(); | 649 rtp_data_channel()->content_name() == content_name) { |
650 return rtp_data_channel(); | |
616 } | 651 } |
617 return nullptr; | 652 return nullptr; |
618 } | 653 } |
619 | 654 |
620 cricket::SecurePolicy WebRtcSession::SdesPolicy() const { | 655 cricket::SecurePolicy WebRtcSession::SdesPolicy() const { |
621 return webrtc_session_desc_factory_->SdesPolicy(); | 656 return webrtc_session_desc_factory_->SdesPolicy(); |
622 } | 657 } |
623 | 658 |
624 bool WebRtcSession::GetSslRole(const std::string& transport_name, | 659 bool WebRtcSession::GetSctpSslRole(rtc::SSLRole* role) { |
660 if (!local_description() || !remote_description()) { | |
661 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get the " | |
662 << "SSL Role of the SCTP transport."; | |
663 return false; | |
664 } | |
665 if (!sctp_transport_) { | |
666 LOG(LS_INFO) << "Non-rejected SCTP m= section is needed to get the " | |
667 << "SSL Role of the SCTP transport."; | |
668 return false; | |
669 } | |
670 | |
671 return transport_controller_->GetSslRole(sctp_transport_name_, role); | |
672 } | |
673 | |
674 bool WebRtcSession::GetSslRole(const std::string& content_name, | |
625 rtc::SSLRole* role) { | 675 rtc::SSLRole* role) { |
626 if (!local_description() || !remote_description()) { | 676 if (!local_description() || !remote_description()) { |
627 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get " | 677 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get the " |
628 << "SSL Role of the session."; | 678 << "SSL Role of the session."; |
629 return false; | 679 return false; |
630 } | 680 } |
631 | 681 |
632 return transport_controller_->GetSslRole(transport_name, role); | 682 return transport_controller_->GetSslRole(GetTransportName(content_name), |
633 } | 683 role); |
634 | |
635 bool WebRtcSession::GetSslRole(const cricket::BaseChannel* channel, | |
636 rtc::SSLRole* role) { | |
637 return channel && GetSslRole(channel->transport_name(), role); | |
638 } | 684 } |
639 | 685 |
640 void WebRtcSession::CreateOffer( | 686 void WebRtcSession::CreateOffer( |
641 CreateSessionDescriptionObserver* observer, | 687 CreateSessionDescriptionObserver* observer, |
642 const PeerConnectionInterface::RTCOfferAnswerOptions& options, | 688 const PeerConnectionInterface::RTCOfferAnswerOptions& options, |
643 const cricket::MediaSessionOptions& session_options) { | 689 const cricket::MediaSessionOptions& session_options) { |
644 webrtc_session_desc_factory_->CreateOffer(observer, options, session_options); | 690 webrtc_session_desc_factory_->CreateOffer(observer, options, session_options); |
645 } | 691 } |
646 | 692 |
647 void WebRtcSession::CreateAnswer( | 693 void WebRtcSession::CreateAnswer( |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
911 return true; | 957 return true; |
912 } else if (source == cricket::CS_LOCAL) { | 958 } else if (source == cricket::CS_LOCAL) { |
913 return ch->PushdownLocalDescription(local_description()->description(), | 959 return ch->PushdownLocalDescription(local_description()->description(), |
914 action, err); | 960 action, err); |
915 } else { | 961 } else { |
916 return ch->PushdownRemoteDescription(remote_description()->description(), | 962 return ch->PushdownRemoteDescription(remote_description()->description(), |
917 action, err); | 963 action, err); |
918 } | 964 } |
919 }; | 965 }; |
920 | 966 |
921 return (set_content(voice_channel()) && | 967 bool ret = (set_content(voice_channel()) && set_content(video_channel()) && |
922 set_content(video_channel()) && | 968 set_content(rtp_data_channel())); |
923 set_content(data_channel())); | 969 // Need complete offer/answer before starting SCTP, according to |
970 // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-19 | |
971 if (sctp_transport_ && local_description() && remote_description()) { | |
972 ret &= network_thread_->Invoke<bool>( | |
973 RTC_FROM_HERE, | |
974 rtc::Bind(&WebRtcSession::PushdownSctpParameters_n, this, source)); | |
975 } | |
976 return ret; | |
977 } | |
978 | |
979 bool WebRtcSession::PushdownSctpParameters_n(cricket::ContentSource source) { | |
980 RTC_DCHECK(network_thread_->IsCurrent()); | |
981 RTC_DCHECK(local_description()); | |
982 RTC_DCHECK(remote_description()); | |
983 // Apply the SCTP port (which is hidden inside a DataCodec structure...) | |
984 // When we support "max-message-size", that would also be pushed down here. | |
985 return sctp_transport_->Start( | |
986 GetSctpPort(local_description()->description()), | |
987 GetSctpPort(remote_description()->description())); | |
924 } | 988 } |
925 | 989 |
926 bool WebRtcSession::PushdownTransportDescription(cricket::ContentSource source, | 990 bool WebRtcSession::PushdownTransportDescription(cricket::ContentSource source, |
927 cricket::ContentAction action, | 991 cricket::ContentAction action, |
928 std::string* error_desc) { | 992 std::string* error_desc) { |
929 RTC_DCHECK(signaling_thread()->IsCurrent()); | 993 RTC_DCHECK(signaling_thread()->IsCurrent()); |
930 | 994 |
931 if (source == cricket::CS_LOCAL) { | 995 if (source == cricket::CS_LOCAL) { |
932 return PushdownLocalTransportDescription(local_description()->description(), | 996 return PushdownLocalTransportDescription(local_description()->description(), |
933 action, error_desc); | 997 action, error_desc); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
985 } | 1049 } |
986 const TransportInfo* transport_info = | 1050 const TransportInfo* transport_info = |
987 description->GetTransportInfoByName(content_name); | 1051 description->GetTransportInfoByName(content_name); |
988 if (!transport_info) { | 1052 if (!transport_info) { |
989 return false; | 1053 return false; |
990 } | 1054 } |
991 *tdesc = transport_info->description; | 1055 *tdesc = transport_info->description; |
992 return true; | 1056 return true; |
993 } | 1057 } |
994 | 1058 |
995 std::unique_ptr<SessionStats> WebRtcSession::GetStats_s() { | |
996 ASSERT(signaling_thread()->IsCurrent()); | |
997 ChannelNamePairs channel_name_pairs; | |
998 if (voice_channel()) { | |
999 channel_name_pairs.voice = rtc::Optional<ChannelNamePair>(ChannelNamePair( | |
1000 voice_channel()->content_name(), voice_channel()->transport_name())); | |
1001 } | |
1002 if (video_channel()) { | |
1003 channel_name_pairs.video = rtc::Optional<ChannelNamePair>(ChannelNamePair( | |
1004 video_channel()->content_name(), video_channel()->transport_name())); | |
1005 } | |
1006 if (data_channel()) { | |
1007 channel_name_pairs.data = rtc::Optional<ChannelNamePair>(ChannelNamePair( | |
1008 data_channel()->content_name(), data_channel()->transport_name())); | |
1009 } | |
1010 return GetStats(channel_name_pairs); | |
1011 } | |
1012 | |
1013 std::unique_ptr<SessionStats> WebRtcSession::GetStats( | |
1014 const ChannelNamePairs& channel_name_pairs) { | |
1015 if (network_thread()->IsCurrent()) { | |
1016 return GetStats_n(channel_name_pairs); | |
1017 } | |
1018 return network_thread()->Invoke<std::unique_ptr<SessionStats>>( | |
1019 RTC_FROM_HERE, | |
1020 rtc::Bind(&WebRtcSession::GetStats_n, this, channel_name_pairs)); | |
1021 } | |
1022 | |
1023 bool WebRtcSession::GetLocalCertificate( | |
1024 const std::string& transport_name, | |
1025 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { | |
1026 return transport_controller_->GetLocalCertificate(transport_name, | |
1027 certificate); | |
1028 } | |
1029 | |
1030 std::unique_ptr<rtc::SSLCertificate> WebRtcSession::GetRemoteSSLCertificate( | |
1031 const std::string& transport_name) { | |
1032 return transport_controller_->GetRemoteSSLCertificate(transport_name); | |
1033 } | |
1034 | |
1035 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) { | 1059 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) { |
1036 const std::string* first_content_name = bundle.FirstContentName(); | 1060 const std::string* first_content_name = bundle.FirstContentName(); |
1037 if (!first_content_name) { | 1061 if (!first_content_name) { |
1038 LOG(LS_WARNING) << "Tried to BUNDLE with no contents."; | 1062 LOG(LS_WARNING) << "Tried to BUNDLE with no contents."; |
1039 return false; | 1063 return false; |
1040 } | 1064 } |
1041 const std::string& transport_name = *first_content_name; | 1065 const std::string& transport_name = *first_content_name; |
1042 cricket::BaseChannel* first_channel = GetChannel(transport_name); | |
1043 | 1066 |
1044 #ifdef HAVE_QUIC | 1067 #ifdef HAVE_QUIC |
1045 if (quic_data_transport_ && | 1068 if (quic_data_transport_ && |
1046 bundle.HasContentName(quic_data_transport_->content_name()) && | 1069 bundle.HasContentName(quic_data_transport_->content_name()) && |
1047 quic_data_transport_->transport_name() != transport_name) { | 1070 quic_data_transport_->transport_name() != transport_name) { |
1048 LOG(LS_ERROR) << "Unable to BUNDLE " << quic_data_transport_->content_name() | 1071 LOG(LS_ERROR) << "Unable to BUNDLE " << quic_data_transport_->content_name() |
1049 << " on " << transport_name << "with QUIC."; | 1072 << " on " << transport_name << "with QUIC."; |
1050 } | 1073 } |
1051 #endif | 1074 #endif |
1052 | 1075 |
1053 auto maybe_set_transport = [this, bundle, transport_name, | 1076 auto maybe_set_transport = [this, bundle, |
1054 first_channel](cricket::BaseChannel* ch) { | 1077 transport_name](cricket::BaseChannel* ch) { |
1055 if (!ch || !bundle.HasContentName(ch->content_name())) { | 1078 if (!ch || !bundle.HasContentName(ch->content_name())) { |
1056 return true; | 1079 return true; |
1057 } | 1080 } |
1058 | 1081 |
1059 if (ch->transport_name() == transport_name) { | 1082 if (ch->transport_name() == transport_name) { |
1060 LOG(LS_INFO) << "BUNDLE already enabled for " << ch->content_name() | 1083 LOG(LS_INFO) << "BUNDLE already enabled for " << ch->content_name() |
1061 << " on " << transport_name << "."; | 1084 << " on " << transport_name << "."; |
1062 return true; | 1085 return true; |
1063 } | 1086 } |
1064 | 1087 |
1065 if (!ch->SetTransport(transport_name)) { | 1088 if (!ch->SetTransport(transport_name)) { |
1066 LOG(LS_WARNING) << "Failed to enable BUNDLE for " << ch->content_name(); | 1089 LOG(LS_WARNING) << "Failed to enable BUNDLE for " << ch->content_name(); |
1067 return false; | 1090 return false; |
1068 } | 1091 } |
1069 LOG(LS_INFO) << "Enabled BUNDLE for " << ch->content_name() << " on " | 1092 LOG(LS_INFO) << "Enabled BUNDLE for " << ch->content_name() << " on " |
1070 << transport_name << "."; | 1093 << transport_name << "."; |
1071 return true; | 1094 return true; |
1072 }; | 1095 }; |
1073 | 1096 |
1074 if (!maybe_set_transport(voice_channel()) || | 1097 if (!maybe_set_transport(voice_channel()) || |
1075 !maybe_set_transport(video_channel()) || | 1098 !maybe_set_transport(video_channel()) || |
1076 !maybe_set_transport(data_channel())) { | 1099 !maybe_set_transport(rtp_data_channel())) { |
1077 return false; | 1100 return false; |
1078 } | 1101 } |
1102 // For SCTP, transport creation/deletion happens here instead of in the | |
1103 // object itself. | |
1104 if (sctp_transport_ && transport_name != sctp_transport_name_ && | |
1105 bundle.HasContentName(sctp_content_name_)) { | |
1106 network_thread_->Invoke<void>( | |
1107 RTC_FROM_HERE, | |
1108 rtc::Bind(&WebRtcSession::ChangeSctpTransport_n, this, transport_name)); | |
1109 } | |
1079 | 1110 |
1080 return true; | 1111 return true; |
1081 } | 1112 } |
1082 | 1113 |
1083 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) { | 1114 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) { |
1084 if (!remote_description()) { | 1115 if (!remote_description()) { |
1085 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added " | 1116 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added " |
1086 << "without any remote session description."; | 1117 << "without any remote session description."; |
1087 return false; | 1118 return false; |
1088 } | 1119 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1241 return true; | 1272 return true; |
1242 } | 1273 } |
1243 | 1274 |
1244 sigslot::signal0<>* WebRtcSession::GetOnDestroyedSignal() { | 1275 sigslot::signal0<>* WebRtcSession::GetOnDestroyedSignal() { |
1245 return &SignalDestroyed; | 1276 return &SignalDestroyed; |
1246 } | 1277 } |
1247 | 1278 |
1248 bool WebRtcSession::SendData(const cricket::SendDataParams& params, | 1279 bool WebRtcSession::SendData(const cricket::SendDataParams& params, |
1249 const rtc::CopyOnWriteBuffer& payload, | 1280 const rtc::CopyOnWriteBuffer& payload, |
1250 cricket::SendDataResult* result) { | 1281 cricket::SendDataResult* result) { |
1251 if (!data_channel_) { | 1282 if (!rtp_data_channel_ && !sctp_transport_) { |
1252 LOG(LS_ERROR) << "SendData called when data_channel_ is NULL."; | 1283 LOG(LS_ERROR) << "SendData called when rtp_data_channel_ " |
1284 << "and sctp_transport_ are NULL."; | |
1253 return false; | 1285 return false; |
1254 } | 1286 } |
1255 return data_channel_->SendData(params, payload, result); | 1287 return rtp_data_channel_ |
1288 ? rtp_data_channel_->SendData(params, payload, result) | |
1289 : network_thread_->Invoke<bool>( | |
1290 RTC_FROM_HERE, | |
1291 Bind(&cricket::SctpTransportInternal::SendData, | |
1292 sctp_transport_.get(), params, payload, result)); | |
pthatcher1
2016/12/23 01:39:31
Similar to passing a "fire events on this thread"
| |
1256 } | 1293 } |
1257 | 1294 |
1258 bool WebRtcSession::ConnectDataChannel(DataChannel* webrtc_data_channel) { | 1295 bool WebRtcSession::ConnectDataChannel(DataChannel* webrtc_data_channel) { |
1259 if (!data_channel_) { | 1296 if (!rtp_data_channel_ && !sctp_transport_) { |
1260 // Don't log an error here, because DataChannels are expected to call | 1297 // Don't log an error here, because DataChannels are expected to call |
1261 // ConnectDataChannel in this state. It's the only way to initially tell | 1298 // ConnectDataChannel in this state. It's the only way to initially tell |
1262 // whether or not the underlying transport is ready. | 1299 // whether or not the underlying transport is ready. |
1263 return false; | 1300 return false; |
1264 } | 1301 } |
1265 data_channel_->SignalReadyToSendData.connect(webrtc_data_channel, | 1302 if (rtp_data_channel_) { |
1266 &DataChannel::OnChannelReady); | 1303 rtp_data_channel_->SignalReadyToSendData.connect( |
1267 data_channel_->SignalDataReceived.connect(webrtc_data_channel, | 1304 webrtc_data_channel, &DataChannel::OnChannelReady); |
1268 &DataChannel::OnDataReceived); | 1305 rtp_data_channel_->SignalDataReceived.connect(webrtc_data_channel, |
1269 data_channel_->SignalStreamClosedRemotely.connect( | 1306 &DataChannel::OnDataReceived); |
1270 webrtc_data_channel, &DataChannel::OnStreamClosedRemotely); | 1307 } else { |
1308 SignalSctpReadyToSendData.connect(webrtc_data_channel, | |
1309 &DataChannel::OnChannelReady); | |
1310 SignalSctpDataReceived.connect(webrtc_data_channel, | |
1311 &DataChannel::OnDataReceived); | |
1312 SignalSctpStreamClosedRemotely.connect( | |
1313 webrtc_data_channel, &DataChannel::OnStreamClosedRemotely); | |
1314 } | |
1271 return true; | 1315 return true; |
1272 } | 1316 } |
1273 | 1317 |
1274 void WebRtcSession::DisconnectDataChannel(DataChannel* webrtc_data_channel) { | 1318 void WebRtcSession::DisconnectDataChannel(DataChannel* webrtc_data_channel) { |
1275 if (!data_channel_) { | 1319 if (!rtp_data_channel_ && !sctp_transport_) { |
1276 LOG(LS_ERROR) << "DisconnectDataChannel called when data_channel_ is NULL."; | 1320 LOG(LS_ERROR) << "DisconnectDataChannel called when rtp_data_channel_ and " |
1321 "sctp_transport_ are NULL."; | |
1277 return; | 1322 return; |
1278 } | 1323 } |
1279 data_channel_->SignalReadyToSendData.disconnect(webrtc_data_channel); | 1324 if (rtp_data_channel_) { |
1280 data_channel_->SignalDataReceived.disconnect(webrtc_data_channel); | 1325 rtp_data_channel_->SignalReadyToSendData.disconnect(webrtc_data_channel); |
1281 data_channel_->SignalStreamClosedRemotely.disconnect(webrtc_data_channel); | 1326 rtp_data_channel_->SignalDataReceived.disconnect(webrtc_data_channel); |
1327 } else { | |
1328 SignalSctpReadyToSendData.disconnect(webrtc_data_channel); | |
1329 SignalSctpDataReceived.disconnect(webrtc_data_channel); | |
1330 SignalSctpStreamClosedRemotely.disconnect(webrtc_data_channel); | |
1331 } | |
1282 } | 1332 } |
1283 | 1333 |
1284 void WebRtcSession::AddSctpDataStream(int sid) { | 1334 void WebRtcSession::AddSctpDataStream(int sid) { |
1285 if (!data_channel_) { | 1335 if (!sctp_transport_) { |
1286 LOG(LS_ERROR) << "AddDataChannelStreams called when data_channel_ is NULL."; | 1336 LOG(LS_ERROR) << "AddSctpDataStream called when sctp_transport_ is NULL."; |
1287 return; | 1337 return; |
1288 } | 1338 } |
1289 data_channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(sid)); | 1339 network_thread_->Invoke<void>( |
1290 data_channel_->AddSendStream(cricket::StreamParams::CreateLegacy(sid)); | 1340 RTC_FROM_HERE, rtc::Bind(&cricket::SctpTransportInternal::OpenStream, |
1341 sctp_transport_.get(), sid)); | |
1291 } | 1342 } |
1292 | 1343 |
1293 void WebRtcSession::RemoveSctpDataStream(int sid) { | 1344 void WebRtcSession::RemoveSctpDataStream(int sid) { |
1294 if (!data_channel_) { | 1345 if (!sctp_transport_) { |
1295 LOG(LS_ERROR) << "RemoveDataChannelStreams called when data_channel_ is " | 1346 LOG(LS_ERROR) << "RemoveSctpDataStream called when sctp_transport_ is " |
1296 << "NULL."; | 1347 << "NULL."; |
1297 return; | 1348 return; |
1298 } | 1349 } |
1299 data_channel_->RemoveRecvStream(sid); | 1350 network_thread_->Invoke<void>( |
1300 data_channel_->RemoveSendStream(sid); | 1351 RTC_FROM_HERE, rtc::Bind(&cricket::SctpTransportInternal::ResetStream, |
1352 sctp_transport_.get(), sid)); | |
1301 } | 1353 } |
1302 | 1354 |
1303 bool WebRtcSession::ReadyToSendData() const { | 1355 bool WebRtcSession::ReadyToSendData() const { |
1304 return data_channel_ && data_channel_->ready_to_send_data(); | 1356 return (rtp_data_channel_ && rtp_data_channel_->ready_to_send_data()) || |
1357 sctp_ready_to_send_data_; | |
1358 } | |
1359 | |
1360 std::unique_ptr<SessionStats> WebRtcSession::GetStats_s() { | |
1361 ASSERT(signaling_thread()->IsCurrent()); | |
1362 ChannelNamePairs channel_name_pairs; | |
1363 if (voice_channel()) { | |
1364 channel_name_pairs.voice = rtc::Optional<ChannelNamePair>(ChannelNamePair( | |
1365 voice_channel()->content_name(), voice_channel()->transport_name())); | |
1366 } | |
1367 if (video_channel()) { | |
1368 channel_name_pairs.video = rtc::Optional<ChannelNamePair>(ChannelNamePair( | |
1369 video_channel()->content_name(), video_channel()->transport_name())); | |
1370 } | |
1371 if (rtp_data_channel()) { | |
1372 channel_name_pairs.data = rtc::Optional<ChannelNamePair>( | |
1373 ChannelNamePair(rtp_data_channel()->content_name(), | |
1374 rtp_data_channel()->transport_name())); | |
1375 } | |
1376 if (sctp_transport_) { | |
1377 channel_name_pairs.data = rtc::Optional<ChannelNamePair>( | |
1378 ChannelNamePair(sctp_content_name_, sctp_transport_name_)); | |
1379 } | |
1380 return GetStats(channel_name_pairs); | |
1381 } | |
1382 | |
1383 std::unique_ptr<SessionStats> WebRtcSession::GetStats( | |
1384 const ChannelNamePairs& channel_name_pairs) { | |
1385 if (network_thread()->IsCurrent()) { | |
1386 return GetStats_n(channel_name_pairs); | |
1387 } | |
1388 return network_thread()->Invoke<std::unique_ptr<SessionStats>>( | |
1389 RTC_FROM_HERE, | |
1390 rtc::Bind(&WebRtcSession::GetStats_n, this, channel_name_pairs)); | |
1391 } | |
1392 | |
1393 bool WebRtcSession::GetLocalCertificate( | |
1394 const std::string& transport_name, | |
1395 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { | |
1396 return transport_controller_->GetLocalCertificate(transport_name, | |
1397 certificate); | |
1398 } | |
1399 | |
1400 std::unique_ptr<rtc::SSLCertificate> WebRtcSession::GetRemoteSSLCertificate( | |
1401 const std::string& transport_name) { | |
1402 return transport_controller_->GetRemoteSSLCertificate(transport_name); | |
1305 } | 1403 } |
1306 | 1404 |
1307 cricket::DataChannelType WebRtcSession::data_channel_type() const { | 1405 cricket::DataChannelType WebRtcSession::data_channel_type() const { |
1308 return data_channel_type_; | 1406 return data_channel_type_; |
1309 } | 1407 } |
1310 | 1408 |
1311 bool WebRtcSession::IceRestartPending(const std::string& content_name) const { | 1409 bool WebRtcSession::IceRestartPending(const std::string& content_name) const { |
1312 return pending_ice_restarts_.find(content_name) != | 1410 return pending_ice_restarts_.find(content_name) != |
1313 pending_ice_restarts_.end(); | 1411 pending_ice_restarts_.end(); |
1314 } | 1412 } |
1315 | 1413 |
1316 void WebRtcSession::SetNeedsIceRestartFlag() { | 1414 void WebRtcSession::SetNeedsIceRestartFlag() { |
1317 transport_controller_->SetNeedsIceRestartFlag(); | 1415 transport_controller_->SetNeedsIceRestartFlag(); |
1318 } | 1416 } |
1319 | 1417 |
1320 bool WebRtcSession::NeedsIceRestart(const std::string& content_name) const { | 1418 bool WebRtcSession::NeedsIceRestart(const std::string& content_name) const { |
1321 return transport_controller_->NeedsIceRestart(content_name); | 1419 return transport_controller_->NeedsIceRestart(content_name); |
1322 } | 1420 } |
1323 | 1421 |
1324 void WebRtcSession::OnCertificateReady( | 1422 void WebRtcSession::OnCertificateReady( |
1325 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { | 1423 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
1326 transport_controller_->SetLocalCertificate(certificate); | 1424 transport_controller_->SetLocalCertificate(certificate); |
1327 } | 1425 } |
1328 | 1426 |
1427 void WebRtcSession::OnDtlsSrtpSetupFailure(cricket::BaseChannel*, bool rtcp) { | |
1428 SetError(ERROR_TRANSPORT, | |
1429 rtcp ? kDtlsSrtpSetupFailureRtcp : kDtlsSrtpSetupFailureRtp); | |
1430 } | |
1431 | |
1329 bool WebRtcSession::waiting_for_certificate_for_testing() const { | 1432 bool WebRtcSession::waiting_for_certificate_for_testing() const { |
1330 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); | 1433 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); |
1331 } | 1434 } |
1332 | 1435 |
1333 const rtc::scoped_refptr<rtc::RTCCertificate>& | 1436 const rtc::scoped_refptr<rtc::RTCCertificate>& |
1334 WebRtcSession::certificate_for_testing() { | 1437 WebRtcSession::certificate_for_testing() { |
1335 return transport_controller_->certificate_for_testing(); | 1438 return transport_controller_->certificate_for_testing(); |
1336 } | 1439 } |
1337 | 1440 |
1338 void WebRtcSession::SetIceConnectionState( | 1441 void WebRtcSession::SetIceConnectionState( |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1448 } | 1551 } |
1449 | 1552 |
1450 if (local_description()) { | 1553 if (local_description()) { |
1451 mutable_local_description()->RemoveCandidates(candidates); | 1554 mutable_local_description()->RemoveCandidates(candidates); |
1452 } | 1555 } |
1453 if (ice_observer_) { | 1556 if (ice_observer_) { |
1454 ice_observer_->OnIceCandidatesRemoved(candidates); | 1557 ice_observer_->OnIceCandidatesRemoved(candidates); |
1455 } | 1558 } |
1456 } | 1559 } |
1457 | 1560 |
1458 // Enabling voice and video channel. | 1561 void WebRtcSession::OnTransportControllerDtlsHandshakeError( |
1562 rtc::SSLHandshakeError error) { | |
1563 if (metrics_observer_) { | |
1564 metrics_observer_->IncrementEnumCounter( | |
1565 webrtc::kEnumCounterDtlsHandshakeError, static_cast<int>(error), | |
1566 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE)); | |
1567 } | |
1568 } | |
1569 | |
1570 // Enabling voice and video (and RTP data) channel. | |
1459 void WebRtcSession::EnableChannels() { | 1571 void WebRtcSession::EnableChannels() { |
1460 if (voice_channel_ && !voice_channel_->enabled()) | 1572 if (voice_channel_ && !voice_channel_->enabled()) |
1461 voice_channel_->Enable(true); | 1573 voice_channel_->Enable(true); |
1462 | 1574 |
1463 if (video_channel_ && !video_channel_->enabled()) | 1575 if (video_channel_ && !video_channel_->enabled()) |
1464 video_channel_->Enable(true); | 1576 video_channel_->Enable(true); |
1465 | 1577 |
1466 if (data_channel_ && !data_channel_->enabled()) | 1578 if (rtp_data_channel_ && !rtp_data_channel_->enabled()) |
1467 data_channel_->Enable(true); | 1579 rtp_data_channel_->Enable(true); |
1468 } | 1580 } |
1469 | 1581 |
1470 // Returns the media index for a local ice candidate given the content name. | 1582 // Returns the media index for a local ice candidate given the content name. |
1471 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name, | 1583 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name, |
1472 int* sdp_mline_index) { | 1584 int* sdp_mline_index) { |
1473 if (!local_description() || !sdp_mline_index) { | 1585 if (!local_description() || !sdp_mline_index) { |
1474 return false; | 1586 return false; |
1475 } | 1587 } |
1476 | 1588 |
1477 bool content_found = false; | 1589 bool content_found = false; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1567 const cricket::ContentInfo* voice_info = | 1679 const cricket::ContentInfo* voice_info = |
1568 cricket::GetFirstAudioContent(desc); | 1680 cricket::GetFirstAudioContent(desc); |
1569 if ((!voice_info || voice_info->rejected) && voice_channel_) { | 1681 if ((!voice_info || voice_info->rejected) && voice_channel_) { |
1570 SignalVoiceChannelDestroyed(); | 1682 SignalVoiceChannelDestroyed(); |
1571 channel_manager_->DestroyVoiceChannel(voice_channel_.release()); | 1683 channel_manager_->DestroyVoiceChannel(voice_channel_.release()); |
1572 } | 1684 } |
1573 | 1685 |
1574 const cricket::ContentInfo* data_info = | 1686 const cricket::ContentInfo* data_info = |
1575 cricket::GetFirstDataContent(desc); | 1687 cricket::GetFirstDataContent(desc); |
1576 if (!data_info || data_info->rejected) { | 1688 if (!data_info || data_info->rejected) { |
1577 if (data_channel_) { | 1689 if (rtp_data_channel_) { |
1578 SignalDataChannelDestroyed(); | 1690 SignalDataChannelDestroyed(); |
1579 channel_manager_->DestroyDataChannel(data_channel_.release()); | 1691 channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release()); |
1692 } | |
1693 if (sctp_transport_) { | |
1694 SignalDataChannelDestroyed(); | |
1695 network_thread_->Invoke<void>( | |
1696 RTC_FROM_HERE, | |
1697 rtc::Bind(&WebRtcSession::DestroySctpTransport_n, this)); | |
1580 } | 1698 } |
1581 #ifdef HAVE_QUIC | 1699 #ifdef HAVE_QUIC |
1582 // Clean up the existing QuicDataTransport and its QuicTransportChannels. | 1700 // Clean up the existing QuicDataTransport and its QuicTransportChannels. |
1583 if (quic_data_transport_) { | 1701 if (quic_data_transport_) { |
1584 quic_data_transport_.reset(); | 1702 quic_data_transport_.reset(); |
1585 } | 1703 } |
1586 #endif | 1704 #endif |
1587 } | 1705 } |
1588 } | 1706 } |
1589 | 1707 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1630 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc); | 1748 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc); |
1631 if (video && !video->rejected && !video_channel_) { | 1749 if (video && !video->rejected && !video_channel_) { |
1632 if (!CreateVideoChannel(video, | 1750 if (!CreateVideoChannel(video, |
1633 GetBundleTransportName(video, bundle_group))) { | 1751 GetBundleTransportName(video, bundle_group))) { |
1634 LOG(LS_ERROR) << "Failed to create video channel."; | 1752 LOG(LS_ERROR) << "Failed to create video channel."; |
1635 return false; | 1753 return false; |
1636 } | 1754 } |
1637 } | 1755 } |
1638 | 1756 |
1639 const cricket::ContentInfo* data = cricket::GetFirstDataContent(desc); | 1757 const cricket::ContentInfo* data = cricket::GetFirstDataContent(desc); |
1640 if (data_channel_type_ != cricket::DCT_NONE && | 1758 if (data_channel_type_ != cricket::DCT_NONE && data && !data->rejected && |
1641 data && !data->rejected && !data_channel_) { | 1759 !rtp_data_channel_ && !sctp_transport_) { |
1642 if (!CreateDataChannel(data, GetBundleTransportName(data, bundle_group))) { | 1760 if (!CreateDataChannel(data, GetBundleTransportName(data, bundle_group))) { |
1643 LOG(LS_ERROR) << "Failed to create data channel."; | 1761 LOG(LS_ERROR) << "Failed to create data channel."; |
1644 return false; | 1762 return false; |
1645 } | 1763 } |
1646 } | 1764 } |
1647 | 1765 |
1648 return true; | 1766 return true; |
1649 } | 1767 } |
1650 | 1768 |
1651 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content, | 1769 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content, |
1652 const std::string* bundle_transport) { | 1770 const std::string* bundle_transport) { |
1653 bool require_rtcp_mux = | 1771 bool require_rtcp_mux = |
1654 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; | 1772 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; |
1655 bool create_rtcp_transport_channel = !require_rtcp_mux; | 1773 bool create_rtcp_transport_channel = !require_rtcp_mux; |
1656 voice_channel_.reset(channel_manager_->CreateVoiceChannel( | 1774 voice_channel_.reset(channel_manager_->CreateVoiceChannel( |
1657 media_controller_, transport_controller_.get(), content->name, | 1775 media_controller_, transport_controller_.get(), content->name, |
1658 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), | 1776 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), |
1659 audio_options_)); | 1777 audio_options_)); |
1660 if (!voice_channel_) { | 1778 if (!voice_channel_) { |
1661 return false; | 1779 return false; |
1662 } | 1780 } |
1663 if (require_rtcp_mux) { | 1781 if (require_rtcp_mux) { |
1664 voice_channel_->ActivateRtcpMux(); | 1782 voice_channel_->ActivateRtcpMux(); |
1665 } | 1783 } |
1666 | 1784 |
1667 voice_channel_->SignalDtlsSetupFailure.connect( | 1785 voice_channel_->SignalDtlsSrtpSetupFailure.connect( |
1668 this, &WebRtcSession::OnDtlsSetupFailure); | 1786 this, &WebRtcSession::OnDtlsSrtpSetupFailure); |
1669 | 1787 |
1670 SignalVoiceChannelCreated(); | 1788 SignalVoiceChannelCreated(); |
1671 voice_channel_->SignalSentPacket.connect(this, | 1789 voice_channel_->SignalSentPacket.connect(this, |
1672 &WebRtcSession::OnSentPacket_w); | 1790 &WebRtcSession::OnSentPacket_w); |
1673 return true; | 1791 return true; |
1674 } | 1792 } |
1675 | 1793 |
1676 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content, | 1794 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content, |
1677 const std::string* bundle_transport) { | 1795 const std::string* bundle_transport) { |
1678 bool require_rtcp_mux = | 1796 bool require_rtcp_mux = |
1679 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; | 1797 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; |
1680 bool create_rtcp_transport_channel = !require_rtcp_mux; | 1798 bool create_rtcp_transport_channel = !require_rtcp_mux; |
1681 video_channel_.reset(channel_manager_->CreateVideoChannel( | 1799 video_channel_.reset(channel_manager_->CreateVideoChannel( |
1682 media_controller_, transport_controller_.get(), content->name, | 1800 media_controller_, transport_controller_.get(), content->name, |
1683 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), | 1801 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), |
1684 video_options_)); | 1802 video_options_)); |
1685 if (!video_channel_) { | 1803 if (!video_channel_) { |
1686 return false; | 1804 return false; |
1687 } | 1805 } |
1688 if (require_rtcp_mux) { | 1806 if (require_rtcp_mux) { |
1689 video_channel_->ActivateRtcpMux(); | 1807 video_channel_->ActivateRtcpMux(); |
1690 } | 1808 } |
1691 video_channel_->SignalDtlsSetupFailure.connect( | 1809 video_channel_->SignalDtlsSrtpSetupFailure.connect( |
1692 this, &WebRtcSession::OnDtlsSetupFailure); | 1810 this, &WebRtcSession::OnDtlsSrtpSetupFailure); |
1693 | 1811 |
1694 SignalVideoChannelCreated(); | 1812 SignalVideoChannelCreated(); |
1695 video_channel_->SignalSentPacket.connect(this, | 1813 video_channel_->SignalSentPacket.connect(this, |
1696 &WebRtcSession::OnSentPacket_w); | 1814 &WebRtcSession::OnSentPacket_w); |
1697 return true; | 1815 return true; |
1698 } | 1816 } |
1699 | 1817 |
1700 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content, | 1818 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content, |
1701 const std::string* bundle_transport) { | 1819 const std::string* bundle_transport) { |
1820 const std::string transport_name = | |
1821 bundle_transport ? *bundle_transport : content->name; | |
1702 #ifdef HAVE_QUIC | 1822 #ifdef HAVE_QUIC |
1703 if (data_channel_type_ == cricket::DCT_QUIC) { | 1823 if (data_channel_type_ == cricket::DCT_QUIC) { |
1704 RTC_DCHECK(transport_controller_->quic()); | 1824 RTC_DCHECK(transport_controller_->quic()); |
1705 const std::string transport_name = | |
1706 bundle_transport ? *bundle_transport : content->name; | |
1707 quic_data_transport_->SetTransport(transport_name); | 1825 quic_data_transport_->SetTransport(transport_name); |
1708 return true; | 1826 return true; |
1709 } | 1827 } |
1710 #endif // HAVE_QUIC | 1828 #endif // HAVE_QUIC |
1711 bool sctp = (data_channel_type_ == cricket::DCT_SCTP); | 1829 bool sctp = (data_channel_type_ == cricket::DCT_SCTP); |
1712 bool require_rtcp_mux = | 1830 if (sctp) { |
1713 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; | 1831 if (!sctp_factory_) { |
1714 bool create_rtcp_transport_channel = !sctp && !require_rtcp_mux; | 1832 LOG(LS_ERROR) |
1715 data_channel_.reset(channel_manager_->CreateDataChannel( | 1833 << "Trying to create SCTP transport, but didn't compile with " |
1716 media_controller_, transport_controller_.get(), content->name, | 1834 "SCTP support (HAVE_SCTP)"; |
1717 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), | 1835 return false; |
1718 data_channel_type_)); | 1836 } |
1719 if (!data_channel_) { | 1837 if (!network_thread_->Invoke<bool>( |
1720 return false; | 1838 RTC_FROM_HERE, rtc::Bind(&WebRtcSession::CreateSctpTransport_n, |
1721 } | 1839 this, content->name, transport_name))) { |
1722 if (require_rtcp_mux) { | 1840 return false; |
1723 data_channel_->ActivateRtcpMux(); | 1841 }; |
1842 } else { | |
1843 bool require_rtcp_mux = | |
1844 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; | |
1845 bool create_rtcp_transport_channel = !sctp && !require_rtcp_mux; | |
1846 rtp_data_channel_.reset(channel_manager_->CreateRtpDataChannel( | |
1847 media_controller_, transport_controller_.get(), content->name, | |
1848 bundle_transport, create_rtcp_transport_channel, SrtpRequired())); | |
1849 if (!rtp_data_channel_) { | |
1850 return false; | |
1851 } | |
1852 if (require_rtcp_mux) { | |
1853 rtp_data_channel_->ActivateRtcpMux(); | |
1854 } | |
1855 rtp_data_channel_->SignalDtlsSrtpSetupFailure.connect( | |
1856 this, &WebRtcSession::OnDtlsSrtpSetupFailure); | |
1857 rtp_data_channel_->SignalSentPacket.connect(this, | |
1858 &WebRtcSession::OnSentPacket_w); | |
1724 } | 1859 } |
1725 | 1860 |
1726 if (sctp) { | |
1727 data_channel_->SignalDataReceived.connect( | |
1728 this, &WebRtcSession::OnDataChannelMessageReceived); | |
1729 } | |
1730 | |
1731 data_channel_->SignalDtlsSetupFailure.connect( | |
1732 this, &WebRtcSession::OnDtlsSetupFailure); | |
1733 | |
1734 SignalDataChannelCreated(); | 1861 SignalDataChannelCreated(); |
1735 data_channel_->SignalSentPacket.connect(this, &WebRtcSession::OnSentPacket_w); | |
1736 return true; | 1862 return true; |
1737 } | 1863 } |
1738 | 1864 |
1739 std::unique_ptr<SessionStats> WebRtcSession::GetStats_n( | 1865 std::unique_ptr<SessionStats> WebRtcSession::GetStats_n( |
1740 const ChannelNamePairs& channel_name_pairs) { | 1866 const ChannelNamePairs& channel_name_pairs) { |
1741 ASSERT(network_thread()->IsCurrent()); | 1867 ASSERT(network_thread()->IsCurrent()); |
1742 std::unique_ptr<SessionStats> session_stats(new SessionStats()); | 1868 std::unique_ptr<SessionStats> session_stats(new SessionStats()); |
1743 for (const auto channel_name_pair : { &channel_name_pairs.voice, | 1869 for (const auto channel_name_pair : { &channel_name_pairs.voice, |
1744 &channel_name_pairs.video, | 1870 &channel_name_pairs.video, |
1745 &channel_name_pairs.data }) { | 1871 &channel_name_pairs.data }) { |
1746 if (*channel_name_pair) { | 1872 if (*channel_name_pair) { |
1747 cricket::TransportStats transport_stats; | 1873 cricket::TransportStats transport_stats; |
1748 if (!transport_controller_->GetStats((*channel_name_pair)->transport_name, | 1874 if (!transport_controller_->GetStats((*channel_name_pair)->transport_name, |
1749 &transport_stats)) { | 1875 &transport_stats)) { |
1750 return nullptr; | 1876 return nullptr; |
1751 } | 1877 } |
1752 session_stats->proxy_to_transport[(*channel_name_pair)->content_name] = | 1878 session_stats->proxy_to_transport[(*channel_name_pair)->content_name] = |
1753 (*channel_name_pair)->transport_name; | 1879 (*channel_name_pair)->transport_name; |
1754 session_stats->transport_stats[(*channel_name_pair)->transport_name] = | 1880 session_stats->transport_stats[(*channel_name_pair)->transport_name] = |
1755 std::move(transport_stats); | 1881 std::move(transport_stats); |
1756 } | 1882 } |
1757 } | 1883 } |
1758 return session_stats; | 1884 return session_stats; |
1759 } | 1885 } |
1760 | 1886 |
1761 void WebRtcSession::OnDtlsSetupFailure(cricket::BaseChannel*, bool rtcp) { | 1887 bool WebRtcSession::CreateSctpTransport_n(const std::string& content_name, |
1762 SetError(ERROR_TRANSPORT, | 1888 const std::string& transport_name) { |
1763 rtcp ? kDtlsSetupFailureRtcp : kDtlsSetupFailureRtp); | 1889 RTC_DCHECK(network_thread_->IsCurrent()); |
1890 RTC_DCHECK(sctp_factory_); | |
1891 cricket::TransportChannel* tc = | |
1892 transport_controller_->CreateTransportChannel_n( | |
1893 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); | |
1894 sctp_transport_ = sctp_factory_->CreateSctpTransport(tc); | |
1895 RTC_DCHECK(sctp_transport_); | |
1896 sctp_invoker_.reset(new rtc::AsyncInvoker()); | |
1897 sctp_transport_->SignalReadyToSendData.connect( | |
1898 this, &WebRtcSession::OnSctpTransportReadyToSendData_n); | |
1899 sctp_transport_->SignalDataReceived.connect( | |
1900 this, &WebRtcSession::OnSctpTransportDataReceived_n); | |
1901 sctp_transport_->SignalStreamClosedRemotely.connect( | |
1902 this, &WebRtcSession::OnSctpStreamClosedRemotely_n); | |
1903 sctp_transport_name_ = transport_name; | |
1904 sctp_content_name_ = content_name; | |
1905 return true; | |
1764 } | 1906 } |
1765 | 1907 |
1766 void WebRtcSession::OnDataChannelMessageReceived( | 1908 void WebRtcSession::ChangeSctpTransport_n(const std::string& transport_name) { |
1767 cricket::DataChannel* channel, | 1909 RTC_DCHECK(network_thread_->IsCurrent()); |
1910 RTC_DCHECK(sctp_transport_); | |
1911 std::string old_sctp_transport_name = sctp_transport_name_; | |
1912 sctp_transport_name_ = transport_name; | |
1913 cricket::TransportChannel* tc = | |
1914 transport_controller_->CreateTransportChannel_n( | |
1915 sctp_transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTP); | |
1916 sctp_transport_->SetTransportChannel(tc); | |
1917 transport_controller_->DestroyTransportChannel_n( | |
1918 old_sctp_transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); | |
1919 } | |
1920 | |
1921 void WebRtcSession::DestroySctpTransport_n() { | |
1922 RTC_DCHECK(network_thread_->IsCurrent()); | |
1923 sctp_transport_.reset(nullptr); | |
1924 sctp_invoker_.reset(nullptr); | |
1925 sctp_ready_to_send_data_ = false; | |
1926 } | |
1927 | |
1928 void WebRtcSession::OnSctpTransportReadyToSendData_n() { | |
1929 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); | |
1930 RTC_DCHECK(network_thread_->IsCurrent()); | |
1931 sctp_invoker_->AsyncInvoke<void>( | |
1932 RTC_FROM_HERE, signaling_thread_, | |
1933 rtc::Bind(&WebRtcSession::OnSctpTransportReadyToSendData_s, this, true)); | |
1934 } | |
1935 | |
1936 void WebRtcSession::OnSctpTransportReadyToSendData_s(bool ready) { | |
1937 RTC_DCHECK(signaling_thread_->IsCurrent()); | |
1938 sctp_ready_to_send_data_ = ready; | |
1939 SignalSctpReadyToSendData(ready); | |
1940 } | |
1941 | |
1942 void WebRtcSession::OnSctpTransportDataReceived_n( | |
1768 const cricket::ReceiveDataParams& params, | 1943 const cricket::ReceiveDataParams& params, |
1769 const rtc::CopyOnWriteBuffer& payload) { | 1944 const rtc::CopyOnWriteBuffer& payload) { |
1770 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); | 1945 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); |
1946 RTC_DCHECK(network_thread_->IsCurrent()); | |
1947 sctp_invoker_->AsyncInvoke<void>( | |
1948 RTC_FROM_HERE, signaling_thread_, | |
1949 rtc::Bind(&WebRtcSession::OnSctpTransportDataReceived_s, this, params, | |
1950 payload)); | |
1951 } | |
1952 | |
1953 void WebRtcSession::OnSctpTransportDataReceived_s( | |
1954 const cricket::ReceiveDataParams& params, | |
1955 const rtc::CopyOnWriteBuffer& payload) { | |
1956 RTC_DCHECK(signaling_thread_->IsCurrent()); | |
1771 if (params.type == cricket::DMT_CONTROL && IsOpenMessage(payload)) { | 1957 if (params.type == cricket::DMT_CONTROL && IsOpenMessage(payload)) { |
1772 // Received OPEN message; parse and signal that a new data channel should | 1958 // Received OPEN message; parse and signal that a new data channel should |
1773 // be created. | 1959 // be created. |
1774 std::string label; | 1960 std::string label; |
1775 InternalDataChannelInit config; | 1961 InternalDataChannelInit config; |
1776 config.id = params.ssrc; | 1962 config.id = params.ssrc; |
1777 if (!ParseDataChannelOpenMessage(payload, &label, &config)) { | 1963 if (!ParseDataChannelOpenMessage(payload, &label, &config)) { |
1778 LOG(LS_WARNING) << "Failed to parse the OPEN message for sid " | 1964 LOG(LS_WARNING) << "Failed to parse the OPEN message for sid " |
1779 << params.ssrc; | 1965 << params.ssrc; |
1780 return; | 1966 return; |
1781 } | 1967 } |
1782 config.open_handshake_role = InternalDataChannelInit::kAcker; | 1968 config.open_handshake_role = InternalDataChannelInit::kAcker; |
1783 SignalDataChannelOpenMessage(label, config); | 1969 SignalDataChannelOpenMessage(label, config); |
1970 } else { | |
1971 // Otherwise just forward the signal. | |
1972 SignalSctpDataReceived(params, payload); | |
1784 } | 1973 } |
1785 // Otherwise ignore the message. | 1974 } |
1975 | |
1976 void WebRtcSession::OnSctpStreamClosedRemotely_n(int sid) { | |
1977 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); | |
1978 RTC_DCHECK(network_thread_->IsCurrent()); | |
1979 sctp_invoker_->AsyncInvoke<void>( | |
1980 RTC_FROM_HERE, signaling_thread_, | |
1981 rtc::Bind(&sigslot::signal1<int>::operator(), | |
1982 &SignalSctpStreamClosedRemotely, sid)); | |
1786 } | 1983 } |
1787 | 1984 |
1788 // Returns false if bundle is enabled and rtcp_mux is disabled. | 1985 // Returns false if bundle is enabled and rtcp_mux is disabled. |
1789 bool WebRtcSession::ValidateBundleSettings(const SessionDescription* desc) { | 1986 bool WebRtcSession::ValidateBundleSettings(const SessionDescription* desc) { |
1790 bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE); | 1987 bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE); |
1791 if (!bundle_enabled) | 1988 if (!bundle_enabled) |
1792 return true; | 1989 return true; |
1793 | 1990 |
1794 const cricket::ContentGroup* bundle_group = | 1991 const cricket::ContentGroup* bundle_group = |
1795 desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); | 1992 desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1969 void WebRtcSession::ReportTransportStats() { | 2166 void WebRtcSession::ReportTransportStats() { |
1970 // Use a set so we don't report the same stats twice if two channels share | 2167 // Use a set so we don't report the same stats twice if two channels share |
1971 // a transport. | 2168 // a transport. |
1972 std::set<std::string> transport_names; | 2169 std::set<std::string> transport_names; |
1973 if (voice_channel()) { | 2170 if (voice_channel()) { |
1974 transport_names.insert(voice_channel()->transport_name()); | 2171 transport_names.insert(voice_channel()->transport_name()); |
1975 } | 2172 } |
1976 if (video_channel()) { | 2173 if (video_channel()) { |
1977 transport_names.insert(video_channel()->transport_name()); | 2174 transport_names.insert(video_channel()->transport_name()); |
1978 } | 2175 } |
1979 if (data_channel()) { | 2176 if (rtp_data_channel()) { |
1980 transport_names.insert(data_channel()->transport_name()); | 2177 transport_names.insert(rtp_data_channel()->transport_name()); |
2178 } | |
2179 if (sctp_transport_) { | |
2180 transport_names.insert(sctp_transport_name_); | |
1981 } | 2181 } |
1982 for (const auto& name : transport_names) { | 2182 for (const auto& name : transport_names) { |
1983 cricket::TransportStats stats; | 2183 cricket::TransportStats stats; |
1984 if (transport_controller_->GetStats(name, &stats)) { | 2184 if (transport_controller_->GetStats(name, &stats)) { |
1985 ReportBestConnectionState(stats); | 2185 ReportBestConnectionState(stats); |
1986 ReportNegotiatedCiphers(stats); | 2186 ReportNegotiatedCiphers(stats); |
1987 } | 2187 } |
1988 } | 2188 } |
1989 } | 2189 } |
1990 // Walk through the ConnectionInfos to gather best connection usage | 2190 // Walk through the ConnectionInfos to gather best connection usage |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2087 const std::string WebRtcSession::GetTransportName( | 2287 const std::string WebRtcSession::GetTransportName( |
2088 const std::string& content_name) { | 2288 const std::string& content_name) { |
2089 cricket::BaseChannel* channel = GetChannel(content_name); | 2289 cricket::BaseChannel* channel = GetChannel(content_name); |
2090 if (!channel) { | 2290 if (!channel) { |
2091 #ifdef HAVE_QUIC | 2291 #ifdef HAVE_QUIC |
2092 if (data_channel_type_ == cricket::DCT_QUIC && quic_data_transport_ && | 2292 if (data_channel_type_ == cricket::DCT_QUIC && quic_data_transport_ && |
2093 content_name == quic_data_transport_->transport_name()) { | 2293 content_name == quic_data_transport_->transport_name()) { |
2094 return quic_data_transport_->transport_name(); | 2294 return quic_data_transport_->transport_name(); |
2095 } | 2295 } |
2096 #endif | 2296 #endif |
2297 if (sctp_transport_ && content_name == sctp_content_name_) { | |
2298 return sctp_transport_name_; | |
2299 } | |
2097 // Return an empty string if failed to retrieve the transport name. | 2300 // Return an empty string if failed to retrieve the transport name. |
2098 return ""; | 2301 return ""; |
2099 } | 2302 } |
2100 return channel->transport_name(); | 2303 return channel->transport_name(); |
2101 } | 2304 } |
2102 | 2305 |
2103 void WebRtcSession::OnDtlsHandshakeError(rtc::SSLHandshakeError error) { | |
2104 if (metrics_observer_) { | |
2105 metrics_observer_->IncrementEnumCounter( | |
2106 webrtc::kEnumCounterDtlsHandshakeError, static_cast<int>(error), | |
2107 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE)); | |
2108 } | |
2109 } | |
2110 } // namespace webrtc | 2306 } // namespace webrtc |
OLD | NEW |