blob: 99270e2eec1843d9f2cad141127f7df8c9661f02 [file] [log] [blame]
Harald Alvestrandc85328f2019-02-28 07:51:00 +01001/*
2 * Copyright 2018 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "pc/sctp_transport.h"
12
13#include <utility>
14
15namespace webrtc {
16
17SctpTransport::SctpTransport(
18 std::unique_ptr<cricket::SctpTransportInternal> internal)
19 : owner_thread_(rtc::Thread::Current()),
20 info_(SctpTransportState::kNew),
21 internal_sctp_transport_(std::move(internal)) {
22 RTC_DCHECK(internal_sctp_transport_.get());
23 internal_sctp_transport_->SignalReadyToSendData.connect(
24 this, &SctpTransport::OnInternalReadyToSendData);
25 // TODO(https://bugs.webrtc.org/10360): Add handlers for transport closing.
26
27 if (dtls_transport_) {
28 UpdateInformation(SctpTransportState::kConnecting);
29 } else {
30 UpdateInformation(SctpTransportState::kNew);
31 }
32}
33
34SctpTransport::~SctpTransport() {
35 // We depend on the network thread to call Clear() before dropping
36 // its last reference to this object.
37 RTC_DCHECK(owner_thread_->IsCurrent() || !internal_sctp_transport_);
38}
39
40SctpTransportInformation SctpTransport::Information() const {
41 rtc::CritScope scope(&lock_);
42 return info_;
43}
44
45void SctpTransport::RegisterObserver(SctpTransportObserverInterface* observer) {
46 RTC_DCHECK_RUN_ON(owner_thread_);
47 RTC_DCHECK(observer);
48 RTC_DCHECK(!observer_);
49 observer_ = observer;
50}
51
52void SctpTransport::UnregisterObserver() {
53 RTC_DCHECK_RUN_ON(owner_thread_);
54 observer_ = nullptr;
55}
56
57rtc::scoped_refptr<DtlsTransportInterface> SctpTransport::dtls_transport()
58 const {
59 RTC_DCHECK_RUN_ON(owner_thread_);
60 return dtls_transport_;
61}
62
63// Internal functions
64void SctpTransport::Clear() {
65 RTC_DCHECK_RUN_ON(owner_thread_);
66 RTC_DCHECK(internal());
67 {
68 rtc::CritScope scope(&lock_);
69 // Note that we delete internal_sctp_transport_, but
70 // only drop the reference to dtls_transport_.
71 dtls_transport_ = nullptr;
72 internal_sctp_transport_ = nullptr;
73 }
74 UpdateInformation(SctpTransportState::kClosed);
75}
76
77void SctpTransport::SetDtlsTransport(
78 rtc::scoped_refptr<DtlsTransport> transport) {
79 RTC_DCHECK_RUN_ON(owner_thread_);
80 rtc::CritScope scope(&lock_);
81 dtls_transport_ = transport;
82 if (internal_sctp_transport_) {
83 if (transport) {
84 internal_sctp_transport_->SetDtlsTransport(transport->internal());
85 if (info_.state() == SctpTransportState::kNew) {
86 UpdateInformation(SctpTransportState::kConnecting);
87 }
88 } else {
89 internal_sctp_transport_->SetDtlsTransport(nullptr);
90 }
91 }
92}
93
94void SctpTransport::UpdateInformation(SctpTransportState state) {
95 RTC_DCHECK_RUN_ON(owner_thread_);
96 bool must_send_update;
97 SctpTransportInformation info_copy(SctpTransportState::kNew);
98 {
99 rtc::CritScope scope(&lock_);
100 must_send_update = (state != info_.state());
101 // TODO(https://bugs.webrtc.org/10358): Update max message size and
102 // max channels from internal SCTP transport when available.
103 info_ = SctpTransportInformation(
104 state, dtls_transport_, info_.MaxMessageSize(), info_.MaxChannels());
105 if (observer_ && must_send_update) {
106 info_copy = info_;
107 }
108 }
109 // We call the observer without holding the lock.
110 if (observer_ && must_send_update) {
111 observer_->OnStateChange(info_copy);
112 }
113}
114
115void SctpTransport::OnInternalReadyToSendData() {
116 UpdateInformation(SctpTransportState::kConnected);
117}
118
119} // namespace webrtc