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_rtp_transport.h"
12
13 #include <string>
14 #include <utility>
15
16 #include "absl/memory/memory.h"
17 #include "p2p/base/packet_transport_internal.h"
18
19 namespace webrtc {
20
CompositeRtpTransport(std::vector<RtpTransportInternal * > transports)21 CompositeRtpTransport::CompositeRtpTransport(
22 std::vector<RtpTransportInternal*> transports)
23 : transports_(std::move(transports)) {
24 RTC_DCHECK(!transports_.empty()) << "Cannot have an empty composite";
25 std::vector<rtc::PacketTransportInternal*> rtp_transports;
26 std::vector<rtc::PacketTransportInternal*> rtcp_transports;
27 for (RtpTransportInternal* transport : transports_) {
28 RTC_DCHECK_EQ(transport->rtcp_mux_enabled(), rtcp_mux_enabled())
29 << "Either all or none of the transports in a composite must enable "
30 "rtcp mux";
31 RTC_DCHECK_EQ(transport->transport_name(), transport_name())
32 << "All transports in a composite must have the same transport name";
33
34 transport->SignalNetworkRouteChanged.connect(
35 this, &CompositeRtpTransport::OnNetworkRouteChanged);
36 transport->SignalRtcpPacketReceived.connect(
37 this, &CompositeRtpTransport::OnRtcpPacketReceived);
38 }
39 }
40
SetSendTransport(RtpTransportInternal * send_transport)41 void CompositeRtpTransport::SetSendTransport(
42 RtpTransportInternal* send_transport) {
43 if (send_transport_ == send_transport) {
44 return;
45 }
46
47 RTC_DCHECK(absl::c_linear_search(transports_, send_transport))
48 << "Cannot set a send transport that isn't part of the composite";
49
50 if (send_transport_) {
51 send_transport_->SignalReadyToSend.disconnect(this);
52 send_transport_->SignalWritableState.disconnect(this);
53 send_transport_->SignalSentPacket.disconnect(this);
54 }
55
56 send_transport_ = send_transport;
57 send_transport_->SignalReadyToSend.connect(
58 this, &CompositeRtpTransport::OnReadyToSend);
59 send_transport_->SignalWritableState.connect(
60 this, &CompositeRtpTransport::OnWritableState);
61 send_transport_->SignalSentPacket.connect(
62 this, &CompositeRtpTransport::OnSentPacket);
63
64 SignalWritableState(send_transport_->IsWritable(/*rtcp=*/true) &&
65 send_transport_->IsWritable(/*rtcp=*/false));
66 if (send_transport_->IsReadyToSend()) {
67 SignalReadyToSend(true);
68 }
69 }
70
RemoveTransport(RtpTransportInternal * transport)71 void CompositeRtpTransport::RemoveTransport(RtpTransportInternal* transport) {
72 RTC_DCHECK(transport != send_transport_) << "Cannot remove send transport";
73
74 auto it = absl::c_find(transports_, transport);
75 if (it == transports_.end()) {
76 return;
77 }
78
79 transport->SignalNetworkRouteChanged.disconnect(this);
80 transport->SignalRtcpPacketReceived.disconnect(this);
81 for (auto sink : rtp_demuxer_sinks_) {
82 transport->UnregisterRtpDemuxerSink(sink);
83 }
84
85 transports_.erase(it);
86 }
87
transport_name() const88 const std::string& CompositeRtpTransport::transport_name() const {
89 return transports_.front()->transport_name();
90 }
91
SetRtpOption(rtc::Socket::Option opt,int value)92 int CompositeRtpTransport::SetRtpOption(rtc::Socket::Option opt, int value) {
93 int result = 0;
94 for (auto transport : transports_) {
95 result |= transport->SetRtpOption(opt, value);
96 }
97 return result;
98 }
99
SetRtcpOption(rtc::Socket::Option opt,int value)100 int CompositeRtpTransport::SetRtcpOption(rtc::Socket::Option opt, int value) {
101 int result = 0;
102 for (auto transport : transports_) {
103 result |= transport->SetRtcpOption(opt, value);
104 }
105 return result;
106 }
107
rtcp_mux_enabled() const108 bool CompositeRtpTransport::rtcp_mux_enabled() const {
109 return transports_.front()->rtcp_mux_enabled();
110 }
111
SetRtcpMuxEnabled(bool enabled)112 void CompositeRtpTransport::SetRtcpMuxEnabled(bool enabled) {
113 for (auto transport : transports_) {
114 transport->SetRtcpMuxEnabled(enabled);
115 }
116 }
117
IsReadyToSend() const118 bool CompositeRtpTransport::IsReadyToSend() const {
119 return send_transport_ && send_transport_->IsReadyToSend();
120 }
121
IsWritable(bool rtcp) const122 bool CompositeRtpTransport::IsWritable(bool rtcp) const {
123 return send_transport_ && send_transport_->IsWritable(rtcp);
124 }
125
SendRtpPacket(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options,int flags)126 bool CompositeRtpTransport::SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
127 const rtc::PacketOptions& options,
128 int flags) {
129 if (!send_transport_) {
130 return false;
131 }
132 return send_transport_->SendRtpPacket(packet, options, flags);
133 }
134
SendRtcpPacket(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options,int flags)135 bool CompositeRtpTransport::SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
136 const rtc::PacketOptions& options,
137 int flags) {
138 if (!send_transport_) {
139 return false;
140 }
141 return send_transport_->SendRtcpPacket(packet, options, flags);
142 }
143
UpdateRtpHeaderExtensionMap(const cricket::RtpHeaderExtensions & header_extensions)144 void CompositeRtpTransport::UpdateRtpHeaderExtensionMap(
145 const cricket::RtpHeaderExtensions& header_extensions) {
146 for (RtpTransportInternal* transport : transports_) {
147 transport->UpdateRtpHeaderExtensionMap(header_extensions);
148 }
149 }
150
IsSrtpActive() const151 bool CompositeRtpTransport::IsSrtpActive() const {
152 bool active = true;
153 for (RtpTransportInternal* transport : transports_) {
154 active &= transport->IsSrtpActive();
155 }
156 return active;
157 }
158
RegisterRtpDemuxerSink(const RtpDemuxerCriteria & criteria,RtpPacketSinkInterface * sink)159 bool CompositeRtpTransport::RegisterRtpDemuxerSink(
160 const RtpDemuxerCriteria& criteria,
161 RtpPacketSinkInterface* sink) {
162 for (RtpTransportInternal* transport : transports_) {
163 transport->RegisterRtpDemuxerSink(criteria, sink);
164 }
165 rtp_demuxer_sinks_.insert(sink);
166 return true;
167 }
168
UnregisterRtpDemuxerSink(RtpPacketSinkInterface * sink)169 bool CompositeRtpTransport::UnregisterRtpDemuxerSink(
170 RtpPacketSinkInterface* sink) {
171 for (RtpTransportInternal* transport : transports_) {
172 transport->UnregisterRtpDemuxerSink(sink);
173 }
174 rtp_demuxer_sinks_.erase(sink);
175 return true;
176 }
177
OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> route)178 void CompositeRtpTransport::OnNetworkRouteChanged(
179 absl::optional<rtc::NetworkRoute> route) {
180 SignalNetworkRouteChanged(route);
181 }
182
OnRtcpPacketReceived(rtc::CopyOnWriteBuffer * packet,int64_t packet_time_us)183 void CompositeRtpTransport::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
184 int64_t packet_time_us) {
185 SignalRtcpPacketReceived(packet, packet_time_us);
186 }
187
OnWritableState(bool writable)188 void CompositeRtpTransport::OnWritableState(bool writable) {
189 SignalWritableState(writable);
190 }
191
OnReadyToSend(bool ready_to_send)192 void CompositeRtpTransport::OnReadyToSend(bool ready_to_send) {
193 SignalReadyToSend(ready_to_send);
194 }
195
OnSentPacket(const rtc::SentPacket & packet)196 void CompositeRtpTransport::OnSentPacket(const rtc::SentPacket& packet) {
197 SignalSentPacket(packet);
198 }
199
200 } // namespace webrtc
201