blob: e66febc12bb56c4574fd467ac84d62758fc4d4cf [file] [log] [blame]
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -07001/*
2 * Copyright 2019 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/composite_data_channel_transport.h"
12
13#include <utility>
14
15#include "absl/algorithm/container.h"
16
17namespace webrtc {
18
19CompositeDataChannelTransport::CompositeDataChannelTransport(
20 std::vector<DataChannelTransportInterface*> transports)
21 : transports_(std::move(transports)) {
22 for (auto transport : transports_) {
23 transport->SetDataSink(this);
24 }
25}
26
Bjorn A Mellemfc604aa2019-09-24 14:59:21 -070027CompositeDataChannelTransport::~CompositeDataChannelTransport() {
28 for (auto transport : transports_) {
29 transport->SetDataSink(nullptr);
30 }
31}
32
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -070033void CompositeDataChannelTransport::SetSendTransport(
34 DataChannelTransportInterface* send_transport) {
35 if (!absl::c_linear_search(transports_, send_transport)) {
36 return;
37 }
38 send_transport_ = send_transport;
39 // NB: OnReadyToSend() checks if we're actually ready to send, and signals
40 // |sink_| if appropriate. This signal is required upon setting the sink.
41 OnReadyToSend();
42}
43
44void CompositeDataChannelTransport::RemoveTransport(
45 DataChannelTransportInterface* transport) {
46 RTC_DCHECK(transport != send_transport_) << "Cannot remove send transport";
47
48 auto it = absl::c_find(transports_, transport);
49 if (it == transports_.end()) {
50 return;
51 }
52
53 transport->SetDataSink(nullptr);
54 transports_.erase(it);
55}
56
57RTCError CompositeDataChannelTransport::OpenChannel(int channel_id) {
58 RTCError error = RTCError::OK();
59 for (auto transport : transports_) {
60 RTCError e = transport->OpenChannel(channel_id);
61 if (!e.ok()) {
62 error = std::move(e);
63 }
64 }
65 return error;
66}
67
68RTCError CompositeDataChannelTransport::SendData(
69 int channel_id,
70 const SendDataParams& params,
71 const rtc::CopyOnWriteBuffer& buffer) {
72 if (send_transport_) {
73 return send_transport_->SendData(channel_id, params, buffer);
74 }
75 return RTCError(RTCErrorType::NETWORK_ERROR, "Send transport is not ready");
76}
77
78RTCError CompositeDataChannelTransport::CloseChannel(int channel_id) {
79 if (send_transport_) {
80 return send_transport_->CloseChannel(channel_id);
81 }
82 return RTCError(RTCErrorType::NETWORK_ERROR, "Send transport is not ready");
83}
84
85void CompositeDataChannelTransport::SetDataSink(DataChannelSink* sink) {
86 sink_ = sink;
87 // NB: OnReadyToSend() checks if we're actually ready to send, and signals
88 // |sink_| if appropriate. This signal is required upon setting the sink.
89 OnReadyToSend();
90}
91
92bool CompositeDataChannelTransport::IsReadyToSend() const {
93 return send_transport_ && send_transport_->IsReadyToSend();
94}
95
96void CompositeDataChannelTransport::OnDataReceived(
97 int channel_id,
98 DataMessageType type,
99 const rtc::CopyOnWriteBuffer& buffer) {
100 if (sink_) {
101 sink_->OnDataReceived(channel_id, type, buffer);
102 }
103}
104
105void CompositeDataChannelTransport::OnChannelClosing(int channel_id) {
106 if (sink_) {
107 sink_->OnChannelClosing(channel_id);
108 }
109}
110
111void CompositeDataChannelTransport::OnChannelClosed(int channel_id) {
112 if (sink_) {
113 sink_->OnChannelClosed(channel_id);
114 }
115}
116
117void CompositeDataChannelTransport::OnReadyToSend() {
118 if (sink_ && send_transport_ && send_transport_->IsReadyToSend()) {
119 sink_->OnReadyToSend();
120 }
121}
122
123} // namespace webrtc