1 /*
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
17 namespace webrtc {
18
CompositeDataChannelTransport(std::vector<DataChannelTransportInterface * > transports)19 CompositeDataChannelTransport::CompositeDataChannelTransport(
20 std::vector<DataChannelTransportInterface*> transports)
21 : transports_(std::move(transports)) {
22 for (auto transport : transports_) {
23 transport->SetDataSink(this);
24 }
25 }
26
~CompositeDataChannelTransport()27 CompositeDataChannelTransport::~CompositeDataChannelTransport() {
28 for (auto transport : transports_) {
29 transport->SetDataSink(nullptr);
30 }
31 }
32
SetSendTransport(DataChannelTransportInterface * send_transport)33 void 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
RemoveTransport(DataChannelTransportInterface * transport)44 void 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
OpenChannel(int channel_id)57 RTCError 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
SendData(int channel_id,const SendDataParams & params,const rtc::CopyOnWriteBuffer & buffer)68 RTCError 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
CloseChannel(int channel_id)78 RTCError 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
SetDataSink(DataChannelSink * sink)85 void 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
IsReadyToSend() const92 bool CompositeDataChannelTransport::IsReadyToSend() const {
93 return send_transport_ && send_transport_->IsReadyToSend();
94 }
95
OnDataReceived(int channel_id,DataMessageType type,const rtc::CopyOnWriteBuffer & buffer)96 void 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
OnChannelClosing(int channel_id)105 void CompositeDataChannelTransport::OnChannelClosing(int channel_id) {
106 if (sink_) {
107 sink_->OnChannelClosing(channel_id);
108 }
109 }
110
OnChannelClosed(int channel_id)111 void CompositeDataChannelTransport::OnChannelClosed(int channel_id) {
112 if (sink_) {
113 sink_->OnChannelClosed(channel_id);
114 }
115 }
116
OnReadyToSend()117 void CompositeDataChannelTransport::OnReadyToSend() {
118 if (sink_ && send_transport_ && send_transport_->IsReadyToSend()) {
119 sink_->OnReadyToSend();
120 }
121 }
122
123 } // namespace webrtc
124