blob: e6c8da7ec33a5bf3ee7973e76378f4ecb23cd124 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellander65c7f672016-02-12 00:05:01 -08002 * Copyright 2004 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellander65c7f672016-02-12 00:05:01 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
jbauch5869f502017-06-29 12:31:36 -070011#include <algorithm>
12#include <iterator>
kwiberg0eb15ed2015-12-17 03:04:15 -080013#include <utility>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "pc/channel.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/call/audio_sink.h"
18#include "media/base/mediaconstants.h"
19#include "media/base/rtputils.h"
20#include "rtc_base/bind.h"
21#include "rtc_base/byteorder.h"
22#include "rtc_base/checks.h"
23#include "rtc_base/copyonwritebuffer.h"
24#include "rtc_base/dscp.h"
25#include "rtc_base/logging.h"
26#include "rtc_base/networkroute.h"
27#include "rtc_base/ptr_util.h"
28#include "rtc_base/trace_event.h"
Patrik Höglund42805f32018-01-18 19:15:38 +000029// Adding 'nogncheck' to disable the gn include headers check to support modular
30// WebRTC build targets.
31#include "media/engine/webrtcvoiceengine.h" // nogncheck
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "p2p/base/packettransportinternal.h"
33#include "pc/channelmanager.h"
Steve Anton4e70a722017-11-28 14:57:10 -080034#include "pc/rtpmediautils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035
36namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000037using rtc::Bind;
Steve Anton3828c062017-12-06 10:34:51 -080038using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000039
deadbeef2d110be2016-01-13 12:00:26 -080040namespace {
Danil Chapovalov33b01f22016-05-11 19:55:27 +020041
42struct SendPacketMessageData : public rtc::MessageData {
43 rtc::CopyOnWriteBuffer packet;
44 rtc::PacketOptions options;
45};
46
deadbeef2d110be2016-01-13 12:00:26 -080047} // namespace
48
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049enum {
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000050 MSG_EARLYMEDIATIMEOUT = 1,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020051 MSG_SEND_RTP_PACKET,
52 MSG_SEND_RTCP_PACKET,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053 MSG_READYTOSENDDATA,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 MSG_DATARECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055 MSG_FIRSTPACKETRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056};
57
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000058static void SafeSetError(const std::string& message, std::string* error_desc) {
59 if (error_desc) {
60 *error_desc = message;
61 }
62}
63
jbaucheec21bd2016-03-20 06:15:43 -070064static bool ValidPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 // Check the packet size. We could check the header too if needed.
zstein3dcf0e92017-06-01 13:22:42 -070066 return packet && IsValidRtpRtcpPacketSize(rtcp, packet->size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067}
68
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070069template <class Codec>
70void RtpParametersFromMediaDescription(
71 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070072 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070073 RtpParameters<Codec>* params) {
74 // TODO(pthatcher): Remove this once we're sure no one will give us
Zhi Huang801b8682017-11-15 11:36:43 -080075 // a description without codecs. Currently the ORTC implementation is relying
76 // on this.
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070077 if (desc->has_codecs()) {
78 params->codecs = desc->codecs();
79 }
80 // TODO(pthatcher): See if we really need
81 // rtp_header_extensions_set() and remove it if we don't.
82 if (desc->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -070083 params->extensions = extensions;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070084 }
deadbeef13871492015-12-09 12:37:51 -080085 params->rtcp.reduced_size = desc->rtcp_reduced_size();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070086}
87
nisse05103312016-03-16 02:22:50 -070088template <class Codec>
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070089void RtpSendParametersFromMediaDescription(
90 const MediaContentDescriptionImpl<Codec>* desc,
jbauch5869f502017-06-29 12:31:36 -070091 const RtpHeaderExtensions& extensions,
nisse05103312016-03-16 02:22:50 -070092 RtpSendParameters<Codec>* send_params) {
jbauch5869f502017-06-29 12:31:36 -070093 RtpParametersFromMediaDescription(desc, extensions, send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -070094 send_params->max_bandwidth_bps = desc->bandwidth();
95}
96
Danil Chapovalov33b01f22016-05-11 19:55:27 +020097BaseChannel::BaseChannel(rtc::Thread* worker_thread,
98 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -080099 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -0800100 std::unique_ptr<MediaChannel> media_channel,
deadbeefcbecd352015-09-23 11:50:27 -0700101 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -0800102 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -0800103 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200104 : worker_thread_(worker_thread),
105 network_thread_(network_thread),
zhihuangf5b251b2017-01-12 19:37:48 -0800106 signaling_thread_(signaling_thread),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000107 content_name_(content_name),
zstein56162b92017-04-24 16:54:35 -0700108 rtcp_mux_required_(rtcp_mux_required),
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800109 unencrypted_rtp_transport_(
110 rtc::MakeUnique<webrtc::RtpTransport>(rtcp_mux_required)),
deadbeef7af91dd2016-12-13 11:29:11 -0800111 srtp_required_(srtp_required),
Zhi Huang1d88d742017-11-15 15:58:49 -0800112 media_channel_(std::move(media_channel)) {
Steve Anton8699a322017-11-06 15:53:33 -0800113 RTC_DCHECK_RUN_ON(worker_thread_);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800114 rtp_transport_ = unencrypted_rtp_transport_.get();
115 ConnectToRtpTransport();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100116 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000117}
118
119BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800120 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800121 RTC_DCHECK_RUN_ON(worker_thread_);
wu@webrtc.org78187522013-10-07 23:32:02 +0000122 Deinit();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200123 // Eats any outstanding messages or packets.
124 worker_thread_->Clear(&invoker_);
125 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000126 // We must destroy the media channel before the transport channel, otherwise
127 // the media channel may try to send on the dead transport channel. NULLing
128 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800129 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100130 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200131}
132
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800133void BaseChannel::ConnectToRtpTransport() {
134 RTC_DCHECK(rtp_transport_);
135 rtp_transport_->SignalReadyToSend.connect(
136 this, &BaseChannel::OnTransportReadyToSend);
137 // TODO(zstein): RtpTransport::SignalPacketReceived will probably be replaced
138 // with a callback interface later so that the demuxer can select which
139 // channel to signal.
140 rtp_transport_->SignalPacketReceived.connect(this,
141 &BaseChannel::OnPacketReceived);
142 rtp_transport_->SignalNetworkRouteChanged.connect(
143 this, &BaseChannel::OnNetworkRouteChanged);
144 rtp_transport_->SignalWritableState.connect(this,
145 &BaseChannel::OnWritableState);
146 rtp_transport_->SignalSentPacket.connect(this,
147 &BaseChannel::SignalSentPacket_n);
148}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200149
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800150void BaseChannel::DisconnectFromRtpTransport() {
151 RTC_DCHECK(rtp_transport_);
152 rtp_transport_->SignalReadyToSend.disconnect(this);
153 rtp_transport_->SignalPacketReceived.disconnect(this);
154 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
155 rtp_transport_->SignalWritableState.disconnect(this);
156 rtp_transport_->SignalSentPacket.disconnect(this);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200157}
158
Steve Anton8699a322017-11-06 15:53:33 -0800159void BaseChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
deadbeeff5346592017-01-24 21:51:21 -0800160 DtlsTransportInternal* rtcp_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -0800161 rtc::PacketTransportInternal* rtp_packet_transport,
162 rtc::PacketTransportInternal* rtcp_packet_transport) {
Steve Anton8699a322017-11-06 15:53:33 -0800163 RTC_DCHECK_RUN_ON(worker_thread_);
164 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800165 SetTransports_n(rtp_dtls_transport, rtcp_dtls_transport,
166 rtp_packet_transport, rtcp_packet_transport);
167
168 if (rtcp_mux_required_) {
169 rtcp_mux_filter_.SetActive();
170 }
Steve Anton8699a322017-11-06 15:53:33 -0800171 });
172
deadbeeff5346592017-01-24 21:51:21 -0800173 // Both RTP and RTCP channels should be set, we can call SetInterface on
174 // the media channel and it can set network options.
wu@webrtc.orgde305012013-10-31 15:40:38 +0000175 media_channel_->SetInterface(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176}
177
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800178void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
179 RTC_DCHECK_RUN_ON(worker_thread_);
180 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
181 SetRtpTransport(rtp_transport);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200182
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800183 if (rtcp_mux_required_) {
184 rtcp_mux_filter_.SetActive();
185 }
186 });
187
188 // Both RTP and RTCP channels should be set, we can call SetInterface on
189 // the media channel and it can set network options.
190 media_channel_->SetInterface(this);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200191}
192
wu@webrtc.org78187522013-10-07 23:32:02 +0000193void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200194 RTC_DCHECK(worker_thread_->IsCurrent());
wu@webrtc.org78187522013-10-07 23:32:02 +0000195 media_channel_->SetInterface(NULL);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200196 // Packets arrive on the network thread, processing packets calls virtual
197 // functions, so need to stop this process in Deinit that is called in
198 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800199 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
200 FlushRtcpMessages_n();
201
202 if (dtls_srtp_transport_) {
203 dtls_srtp_transport_->SetDtlsTransports(nullptr, nullptr);
204 } else {
205 rtp_transport_->SetRtpPacketTransport(nullptr);
206 rtp_transport_->SetRtcpPacketTransport(nullptr);
207 }
208 // Clear pending read packets/messages.
209 network_thread_->Clear(&invoker_);
210 network_thread_->Clear(this);
211 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000212}
213
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800214void BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
215 if (!network_thread_->IsCurrent()) {
216 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
217 SetRtpTransport(rtp_transport);
218 return;
219 });
220 }
221
222 RTC_DCHECK(rtp_transport);
223
224 if (rtp_transport_) {
225 DisconnectFromRtpTransport();
226 }
227 rtp_transport_ = rtp_transport;
228 RTC_LOG(LS_INFO) << "Setting the RtpTransport for " << content_name();
229 ConnectToRtpTransport();
230
231 UpdateWritableState_n();
232}
233
zhihuangb2cdd932017-01-19 16:54:25 -0800234void BaseChannel::SetTransports(DtlsTransportInternal* rtp_dtls_transport,
235 DtlsTransportInternal* rtcp_dtls_transport) {
deadbeeff5346592017-01-24 21:51:21 -0800236 network_thread_->Invoke<void>(
237 RTC_FROM_HERE,
238 Bind(&BaseChannel::SetTransports_n, this, rtp_dtls_transport,
239 rtcp_dtls_transport, rtp_dtls_transport, rtcp_dtls_transport));
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000240}
241
deadbeeff5346592017-01-24 21:51:21 -0800242void BaseChannel::SetTransports(
deadbeef5bd5ca32017-02-10 11:31:50 -0800243 rtc::PacketTransportInternal* rtp_packet_transport,
244 rtc::PacketTransportInternal* rtcp_packet_transport) {
deadbeeff5346592017-01-24 21:51:21 -0800245 network_thread_->Invoke<void>(
246 RTC_FROM_HERE, Bind(&BaseChannel::SetTransports_n, this, nullptr, nullptr,
247 rtp_packet_transport, rtcp_packet_transport));
248}
zhihuangf5b251b2017-01-12 19:37:48 -0800249
deadbeeff5346592017-01-24 21:51:21 -0800250void BaseChannel::SetTransports_n(
251 DtlsTransportInternal* rtp_dtls_transport,
252 DtlsTransportInternal* rtcp_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -0800253 rtc::PacketTransportInternal* rtp_packet_transport,
254 rtc::PacketTransportInternal* rtcp_packet_transport) {
deadbeeff5346592017-01-24 21:51:21 -0800255 RTC_DCHECK(network_thread_->IsCurrent());
256 // Validate some assertions about the input.
257 RTC_DCHECK(rtp_packet_transport);
258 RTC_DCHECK_EQ(NeedsRtcpTransport(), rtcp_packet_transport != nullptr);
259 if (rtp_dtls_transport || rtcp_dtls_transport) {
260 // DTLS/non-DTLS pointers should be to the same object.
261 RTC_DCHECK(rtp_dtls_transport == rtp_packet_transport);
262 RTC_DCHECK(rtcp_dtls_transport == rtcp_packet_transport);
263 // Can't go from non-DTLS to DTLS.
zsteine8ab5432017-07-12 11:48:11 -0700264 RTC_DCHECK(!rtp_transport_->rtp_packet_transport() || rtp_dtls_transport_);
deadbeeff5346592017-01-24 21:51:21 -0800265 } else {
266 // Can't go from DTLS to non-DTLS.
267 RTC_DCHECK(!rtp_dtls_transport_);
268 }
269 // Transport names should be the same.
zhihuangb2cdd932017-01-19 16:54:25 -0800270 if (rtp_dtls_transport && rtcp_dtls_transport) {
271 RTC_DCHECK(rtp_dtls_transport->transport_name() ==
272 rtcp_dtls_transport->transport_name());
zhihuangb2cdd932017-01-19 16:54:25 -0800273 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800274
275 if (rtp_packet_transport == rtp_transport_->rtp_packet_transport()) {
276 // Nothing to do if transport isn't changing.
277 return;
278 }
279
deadbeeff5346592017-01-24 21:51:21 -0800280 std::string debug_name;
281 if (rtp_dtls_transport) {
282 transport_name_ = rtp_dtls_transport->transport_name();
283 debug_name = transport_name_;
284 } else {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800285 debug_name = rtp_packet_transport->transport_name();
deadbeeff5346592017-01-24 21:51:21 -0800286 }
deadbeefac22f702017-01-12 21:59:29 -0800287 // If this BaseChannel doesn't require RTCP mux and we haven't fully
288 // negotiated RTCP mux, we need an RTCP transport.
deadbeeff5346592017-01-24 21:51:21 -0800289 if (rtcp_packet_transport) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100290 RTC_LOG(LS_INFO) << "Setting RTCP Transport for " << content_name()
291 << " on " << debug_name << " transport "
292 << rtcp_packet_transport;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800293 SetTransport_n(/*rtcp=*/true, rtcp_dtls_transport, rtcp_packet_transport);
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000294 }
295
Mirko Bonadei675513b2017-11-09 11:09:25 +0100296 RTC_LOG(LS_INFO) << "Setting RTP Transport for " << content_name() << " on "
297 << debug_name << " transport " << rtp_packet_transport;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800298 SetTransport_n(/*rtcp=*/false, rtp_dtls_transport, rtp_packet_transport);
299
300 // Set DtlsTransport/PacketTransport for RTP-level transport.
301 if ((rtp_dtls_transport_ || rtcp_dtls_transport_) && dtls_srtp_transport_) {
302 // When setting the transport with non-null |dtls_srtp_transport_|, we are
303 // using DTLS-SRTP. This could happen for bundling. If the
304 // |dtls_srtp_transport| is null, we cannot tell if it doing DTLS-SRTP or
305 // SDES until the description is set. So don't call |EnableDtlsSrtp_n| here.
306 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport,
307 rtcp_dtls_transport);
308 } else {
309 rtp_transport_->SetRtpPacketTransport(rtp_packet_transport);
310 rtp_transport_->SetRtcpPacketTransport(rtcp_packet_transport);
311 }
guoweis46383312015-12-17 16:45:59 -0800312
deadbeefcbecd352015-09-23 11:50:27 -0700313 // Update aggregate writable/ready-to-send state between RTP and RTCP upon
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700314 // setting new transport channels.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200315 UpdateWritableState_n();
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000316}
317
deadbeeff5346592017-01-24 21:51:21 -0800318void BaseChannel::SetTransport_n(
319 bool rtcp,
320 DtlsTransportInternal* new_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -0800321 rtc::PacketTransportInternal* new_packet_transport) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200322 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800323 if (new_dtls_transport) {
324 RTC_DCHECK(new_dtls_transport == new_packet_transport);
325 }
deadbeeff5346592017-01-24 21:51:21 -0800326 DtlsTransportInternal*& old_dtls_transport =
zhihuangb2cdd932017-01-19 16:54:25 -0800327 rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_;
zsteind48dbda2017-04-04 19:45:57 -0700328 rtc::PacketTransportInternal* old_packet_transport =
zsteine8ab5432017-07-12 11:48:11 -0700329 rtcp ? rtp_transport_->rtcp_packet_transport()
330 : rtp_transport_->rtp_packet_transport();
zhihuangb2cdd932017-01-19 16:54:25 -0800331
deadbeeff5346592017-01-24 21:51:21 -0800332 if (!old_packet_transport && !new_packet_transport) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700333 // Nothing to do.
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000334 return;
335 }
zhihuangb2cdd932017-01-19 16:54:25 -0800336
deadbeeff5346592017-01-24 21:51:21 -0800337 RTC_DCHECK(old_packet_transport != new_packet_transport);
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000338
deadbeeff5346592017-01-24 21:51:21 -0800339 old_dtls_transport = new_dtls_transport;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000340
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800341 // If there's no new transport, we're done.
deadbeeff5346592017-01-24 21:51:21 -0800342 if (!new_packet_transport) {
343 return;
344 }
345
346 if (rtcp && new_dtls_transport) {
Zhi Huangcf990f52017-09-22 12:12:30 -0700347 RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_active()))
348 << "Setting RTCP for DTLS/SRTP after the DTLS is active "
deadbeeff5346592017-01-24 21:51:21 -0800349 << "should never happen.";
350 }
zstein56162b92017-04-24 16:54:35 -0700351
deadbeeff5346592017-01-24 21:51:21 -0800352 auto& socket_options = rtcp ? rtcp_socket_options_ : socket_options_;
353 for (const auto& pair : socket_options) {
354 new_packet_transport->SetOption(pair.first, pair.second);
guoweis46383312015-12-17 16:45:59 -0800355 }
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000356}
357
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000358bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700359 worker_thread_->Invoke<void>(
360 RTC_FROM_HERE,
361 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
362 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363 return true;
364}
365
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000366bool BaseChannel::AddRecvStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700367 return InvokeOnWorker<bool>(RTC_FROM_HERE,
368 Bind(&BaseChannel::AddRecvStream_w, this, sp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369}
370
Peter Boström0c4e06b2015-10-07 12:23:21 +0200371bool BaseChannel::RemoveRecvStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700372 return InvokeOnWorker<bool>(
373 RTC_FROM_HERE, Bind(&BaseChannel::RemoveRecvStream_w, this, ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374}
375
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000376bool BaseChannel::AddSendStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700377 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700378 RTC_FROM_HERE, Bind(&MediaChannel::AddSendStream, media_channel(), sp));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000379}
380
Peter Boström0c4e06b2015-10-07 12:23:21 +0200381bool BaseChannel::RemoveSendStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700382 return InvokeOnWorker<bool>(
383 RTC_FROM_HERE,
384 Bind(&MediaChannel::RemoveSendStream, media_channel(), ssrc));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000385}
386
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000387bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800388 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000389 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100390 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700391 return InvokeOnWorker<bool>(
392 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800393 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000394}
395
396bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800397 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000398 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100399 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700400 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800401 RTC_FROM_HERE,
402 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000403}
404
zhihuangf5b251b2017-01-12 19:37:48 -0800405bool BaseChannel::NeedsRtcpTransport() {
deadbeefac22f702017-01-12 21:59:29 -0800406 // If this BaseChannel doesn't require RTCP mux and we haven't fully
407 // negotiated RTCP mux, we need an RTCP transport.
zstein56162b92017-04-24 16:54:35 -0700408 return !rtcp_mux_required_ && !rtcp_mux_filter_.IsFullyActive();
pthatcher@webrtc.orgb4aac132015-03-13 18:25:21 +0000409}
410
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700411bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000412 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800413 return enabled() &&
414 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000415}
416
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700417bool BaseChannel::IsReadyToSendMedia_w() const {
418 // Need to access some state updated on the network thread.
419 return network_thread_->Invoke<bool>(
420 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
421}
422
423bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000424 // Send outgoing data if we are enabled, have local and remote content,
425 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800426 return enabled() &&
427 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
428 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huangcf990f52017-09-22 12:12:30 -0700429 was_ever_writable() && (srtp_active() || !ShouldSetupDtlsSrtp_n());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000430}
431
jbaucheec21bd2016-03-20 06:15:43 -0700432bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700433 const rtc::PacketOptions& options) {
434 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000435}
436
jbaucheec21bd2016-03-20 06:15:43 -0700437bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700438 const rtc::PacketOptions& options) {
439 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000440}
441
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000442int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000443 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200444 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700445 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200446}
447
448int BaseChannel::SetOption_n(SocketType type,
449 rtc::Socket::Option opt,
450 int value) {
451 RTC_DCHECK(network_thread_->IsCurrent());
deadbeef5bd5ca32017-02-10 11:31:50 -0800452 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000453 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000454 case ST_RTP:
zsteine8ab5432017-07-12 11:48:11 -0700455 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700456 socket_options_.push_back(
457 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000458 break;
459 case ST_RTCP:
zsteine8ab5432017-07-12 11:48:11 -0700460 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700461 rtcp_socket_options_.push_back(
462 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000463 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000464 }
deadbeeff5346592017-01-24 21:51:21 -0800465 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000466}
467
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800468void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200469 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800470 if (writable) {
471 // This is used to cover the scenario when the DTLS handshake is completed
472 // and DtlsTransport becomes writable before the remote description is set.
473 if (ShouldSetupDtlsSrtp_n()) {
474 EnableDtlsSrtp_n();
Zhi Huangcf990f52017-09-22 12:12:30 -0700475 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800476 ChannelWritable_n();
477 } else {
478 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800479 }
480}
481
Zhi Huang942bc2e2017-11-13 13:26:07 -0800482void BaseChannel::OnNetworkRouteChanged(
483 rtc::Optional<rtc::NetworkRoute> network_route) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200484 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800485 rtc::NetworkRoute new_route;
486 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800487 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000488 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800489 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
490 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
491 // work correctly. Intentionally leave it broken to simplify the code and
492 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800493 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800494 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800495 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700496}
497
zstein56162b92017-04-24 16:54:35 -0700498void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800499 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
500 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000501}
502
stefanc1aeaf02015-10-15 07:26:07 -0700503bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700504 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700505 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200506 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
507 // If the thread is not our network thread, we will post to our network
508 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000509 // synchronize access to all the pieces of the send path, including
510 // SRTP and the inner workings of the transport channels.
511 // The only downside is that we can't return a proper failure code if
512 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200513 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000514 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200515 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
516 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800517 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700518 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700519 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520 return true;
521 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200522 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000523
524 // Now that we are on the correct thread, ensure we have a place to send this
525 // packet before doing anything. (We might get RTCP packets that we don't
526 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
527 // transport.
zsteine8ab5432017-07-12 11:48:11 -0700528 if (!rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000529 return false;
530 }
531
532 // Protect ourselves against crazy data.
533 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100534 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
535 << RtpRtcpStringLiteral(rtcp)
536 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000537 return false;
538 }
539
Zhi Huangcf990f52017-09-22 12:12:30 -0700540 if (!srtp_active()) {
541 if (srtp_required_) {
542 // The audio/video engines may attempt to send RTCP packets as soon as the
543 // streams are created, so don't treat this as an error for RTCP.
544 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
545 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000546 return false;
547 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700548 // However, there shouldn't be any RTP packets sent before SRTP is set up
549 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100550 RTC_LOG(LS_ERROR)
551 << "Can't send outgoing RTP packet when SRTP is inactive"
552 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700553 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800554 return false;
555 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800556
557 std::string packet_type = rtcp ? "RTCP" : "RTP";
558 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
559 << " packet without encryption.";
560 } else {
561 // Make sure we didn't accidentally send any packets without encryption.
562 RTC_DCHECK(rtp_transport_ == sdes_transport_.get() ||
563 rtp_transport_ == dtls_srtp_transport_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000564 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000565 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800566 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
567 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000568}
569
zstein3dcf0e92017-06-01 13:22:42 -0700570bool BaseChannel::HandlesPayloadType(int packet_type) const {
zsteine8ab5432017-07-12 11:48:11 -0700571 return rtp_transport_->HandlesPayloadType(packet_type);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000572}
573
zstein3dcf0e92017-06-01 13:22:42 -0700574void BaseChannel::OnPacketReceived(bool rtcp,
zstein634977b2017-07-14 12:30:04 -0700575 rtc::CopyOnWriteBuffer* packet,
zstein3dcf0e92017-06-01 13:22:42 -0700576 const rtc::PacketTime& packet_time) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000577 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700579 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000580 }
581
Zhi Huangcf990f52017-09-22 12:12:30 -0700582 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000583 // Our session description indicates that SRTP is required, but we got a
584 // packet before our SRTP filter is active. This means either that
585 // a) we got SRTP packets before we received the SDES keys, in which case
586 // we can't decrypt it anyway, or
587 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800588 // transports, so we haven't yet extracted keys, even if DTLS did
589 // complete on the transport that the packets are being sent on. It's
590 // really good practice to wait for both RTP and RTCP to be good to go
591 // before sending media, to prevent weird failure modes, so it's fine
592 // for us to just eat packets here. This is all sidestepped if RTCP mux
593 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100594 RTC_LOG(LS_WARNING)
595 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
596 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000597 return;
598 }
599
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200600 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700601 RTC_FROM_HERE, worker_thread_,
zstein634977b2017-07-14 12:30:04 -0700602 Bind(&BaseChannel::ProcessPacket, this, rtcp, *packet, packet_time));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200603}
604
zstein3dcf0e92017-06-01 13:22:42 -0700605void BaseChannel::ProcessPacket(bool rtcp,
606 const rtc::CopyOnWriteBuffer& packet,
607 const rtc::PacketTime& packet_time) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200608 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700609
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200610 // Need to copy variable because OnRtcpReceived/OnPacketReceived
611 // requires non-const pointer to buffer. This doesn't memcpy the actual data.
612 rtc::CopyOnWriteBuffer data(packet);
613 if (rtcp) {
614 media_channel_->OnRtcpReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000615 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200616 media_channel_->OnPacketReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000617 }
618}
619
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000620void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700621 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000622 if (enabled_)
623 return;
624
Mirko Bonadei675513b2017-11-09 11:09:25 +0100625 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000626 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700627 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000628}
629
630void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700631 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632 if (!enabled_)
633 return;
634
Mirko Bonadei675513b2017-11-09 11:09:25 +0100635 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000636 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700637 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000638}
639
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200640void BaseChannel::UpdateWritableState_n() {
zsteind48dbda2017-04-04 19:45:57 -0700641 rtc::PacketTransportInternal* rtp_packet_transport =
zsteine8ab5432017-07-12 11:48:11 -0700642 rtp_transport_->rtp_packet_transport();
zsteind48dbda2017-04-04 19:45:57 -0700643 rtc::PacketTransportInternal* rtcp_packet_transport =
zsteine8ab5432017-07-12 11:48:11 -0700644 rtp_transport_->rtcp_packet_transport();
zsteind48dbda2017-04-04 19:45:57 -0700645 if (rtp_packet_transport && rtp_packet_transport->writable() &&
646 (!rtcp_packet_transport || rtcp_packet_transport->writable())) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200647 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700648 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200649 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700650 }
651}
652
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200653void BaseChannel::ChannelWritable_n() {
654 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800655 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000656 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800657 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658
Mirko Bonadei675513b2017-11-09 11:09:25 +0100659 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
660 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000661
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000662 was_ever_writable_ = true;
663 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700664 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000665}
666
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200667bool BaseChannel::ShouldSetupDtlsSrtp_n() const {
zhihuangb2cdd932017-01-19 16:54:25 -0800668 // Since DTLS is applied to all transports, checking RTP should be enough.
669 return rtp_dtls_transport_ && rtp_dtls_transport_->IsDtlsActive();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670}
671
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200672void BaseChannel::ChannelNotWritable_n() {
673 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000674 if (!writable_)
675 return;
676
Mirko Bonadei675513b2017-11-09 11:09:25 +0100677 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000678 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700679 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000680}
681
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200682bool BaseChannel::SetRtpTransportParameters(
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700683 const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800684 SdpType type,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700685 ContentSource src,
jbauch5869f502017-06-29 12:31:36 -0700686 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700687 std::string* error_desc) {
jbauch5869f502017-06-29 12:31:36 -0700688 std::vector<int> encrypted_extension_ids;
689 for (const webrtc::RtpExtension& extension : extensions) {
690 if (extension.encrypt) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100691 RTC_LOG(LS_INFO) << "Using " << (src == CS_LOCAL ? "local" : "remote")
692 << " encrypted extension: " << extension.ToString();
jbauch5869f502017-06-29 12:31:36 -0700693 encrypted_extension_ids.push_back(extension.id);
694 }
695 }
696
deadbeef7af91dd2016-12-13 11:29:11 -0800697 // Cache srtp_required_ for belt and suspenders check on SendPacket
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200698 return network_thread_->Invoke<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800699 RTC_FROM_HERE,
700 Bind(&BaseChannel::SetRtpTransportParameters_n, this, content, type, src,
701 encrypted_extension_ids, error_desc));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200702}
703
704bool BaseChannel::SetRtpTransportParameters_n(
705 const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800706 SdpType type,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200707 ContentSource src,
jbauch5869f502017-06-29 12:31:36 -0700708 const std::vector<int>& encrypted_extension_ids,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200709 std::string* error_desc) {
710 RTC_DCHECK(network_thread_->IsCurrent());
711
Steve Anton3828c062017-12-06 10:34:51 -0800712 if (!SetSrtp_n(content->cryptos(), type, src, encrypted_extension_ids,
713 error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700714 return false;
715 }
716
Steve Anton3828c062017-12-06 10:34:51 -0800717 if (!SetRtcpMux_n(content->rtcp_mux(), type, src, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700718 return false;
719 }
720
721 return true;
722}
723
zhihuangb2cdd932017-01-19 16:54:25 -0800724// |dtls| will be set to true if DTLS is active for transport and crypto is
725// empty.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200726bool BaseChannel::CheckSrtpConfig_n(const std::vector<CryptoParams>& cryptos,
727 bool* dtls,
728 std::string* error_desc) {
deadbeeff5346592017-01-24 21:51:21 -0800729 *dtls = rtp_dtls_transport_ && rtp_dtls_transport_->IsDtlsActive();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000730 if (*dtls && !cryptos.empty()) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200731 SafeSetError("Cryptos must be empty when DTLS is active.", error_desc);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000732 return false;
733 }
734 return true;
735}
736
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800737void BaseChannel::EnableSdes_n() {
738 if (sdes_transport_) {
739 return;
Zhi Huangcf990f52017-09-22 12:12:30 -0700740 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800741 // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
742 // time.
743 RTC_DCHECK(!dtls_srtp_transport_);
744 RTC_DCHECK(unencrypted_rtp_transport_);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800745 sdes_transport_ = rtc::MakeUnique<webrtc::SrtpTransport>(
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800746 std::move(unencrypted_rtp_transport_));
Zhi Huangd7455782017-11-30 14:50:52 -0800747#if defined(ENABLE_EXTERNAL_AUTH)
748 sdes_transport_->EnableExternalAuth();
749#endif
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800750 SetRtpTransport(sdes_transport_.get());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800751 RTC_LOG(LS_INFO) << "Wrapping RtpTransport in SrtpTransport.";
752}
753
754void BaseChannel::EnableDtlsSrtp_n() {
755 if (dtls_srtp_transport_) {
756 return;
757 }
758 // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
759 // time.
760 RTC_DCHECK(!sdes_transport_);
761 RTC_DCHECK(unencrypted_rtp_transport_);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800762
763 auto srtp_transport = rtc::MakeUnique<webrtc::SrtpTransport>(
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800764 std::move(unencrypted_rtp_transport_));
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800765#if defined(ENABLE_EXTERNAL_AUTH)
766 srtp_transport->EnableExternalAuth();
767#endif
768 dtls_srtp_transport_ =
769 rtc::MakeUnique<webrtc::DtlsSrtpTransport>(std::move(srtp_transport));
770
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800771 SetRtpTransport(dtls_srtp_transport_.get());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800772 if (cached_send_extension_ids_) {
773 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
774 *cached_send_extension_ids_);
775 }
776 if (cached_recv_extension_ids_) {
777 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
778 *cached_recv_extension_ids_);
779 }
780 // Set the DtlsTransport and the |dtls_srtp_transport_| will handle the DTLS
781 // relate signal internally.
782 RTC_DCHECK(rtp_dtls_transport_);
783 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport_,
784 rtcp_dtls_transport_);
785
786 RTC_LOG(LS_INFO) << "Wrapping SrtpTransport in DtlsSrtpTransport.";
Zhi Huangcf990f52017-09-22 12:12:30 -0700787}
788
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200789bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
Steve Anton3828c062017-12-06 10:34:51 -0800790 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000791 ContentSource src,
jbauch5869f502017-06-29 12:31:36 -0700792 const std::vector<int>& encrypted_extension_ids,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000793 std::string* error_desc) {
Peter Boströmca8b4042016-03-08 14:24:13 -0800794 TRACE_EVENT0("webrtc", "BaseChannel::SetSrtp_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795 bool ret = false;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000796 bool dtls = false;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200797 ret = CheckSrtpConfig_n(cryptos, &dtls, error_desc);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000798 if (!ret) {
799 return false;
800 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700801
802 // If SRTP was not required, but we're setting a description that uses SDES,
803 // we need to upgrade to an SrtpTransport.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800804 if (!sdes_transport_ && !dtls && !cryptos.empty()) {
805 EnableSdes_n();
Zhi Huangcf990f52017-09-22 12:12:30 -0700806 }
Zhi Huangc99b6c72017-11-10 16:44:46 -0800807
Steve Anton3828c062017-12-06 10:34:51 -0800808 if ((type == SdpType::kAnswer || type == SdpType::kPrAnswer) && dtls) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800809 EnableDtlsSrtp_n();
810 }
Zhi Huangc99b6c72017-11-10 16:44:46 -0800811
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800812 UpdateEncryptedHeaderExtensionIds(src, encrypted_extension_ids);
813
814 if (!dtls) {
Steve Anton3828c062017-12-06 10:34:51 -0800815 switch (type) {
816 case SdpType::kOffer:
Zhi Huangcf990f52017-09-22 12:12:30 -0700817 ret = sdes_negotiator_.SetOffer(cryptos, src);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800818 break;
Steve Anton3828c062017-12-06 10:34:51 -0800819 case SdpType::kPrAnswer:
Zhi Huangcf990f52017-09-22 12:12:30 -0700820 ret = sdes_negotiator_.SetProvisionalAnswer(cryptos, src);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800821 break;
Steve Anton3828c062017-12-06 10:34:51 -0800822 case SdpType::kAnswer:
Zhi Huangcf990f52017-09-22 12:12:30 -0700823 ret = sdes_negotiator_.SetAnswer(cryptos, src);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800824 break;
825 default:
826 break;
827 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700828
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800829 // If setting an SDES answer succeeded, apply the negotiated parameters
830 // to the SRTP transport.
Steve Anton3828c062017-12-06 10:34:51 -0800831 if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800832 if (sdes_negotiator_.send_cipher_suite() &&
833 sdes_negotiator_.recv_cipher_suite()) {
834 RTC_DCHECK(cached_send_extension_ids_);
835 RTC_DCHECK(cached_recv_extension_ids_);
836 ret = sdes_transport_->SetRtpParams(
837 *(sdes_negotiator_.send_cipher_suite()),
838 sdes_negotiator_.send_key().data(),
839 static_cast<int>(sdes_negotiator_.send_key().size()),
840 *(cached_send_extension_ids_),
841 *(sdes_negotiator_.recv_cipher_suite()),
842 sdes_negotiator_.recv_key().data(),
843 static_cast<int>(sdes_negotiator_.recv_key().size()),
844 *(cached_recv_extension_ids_));
845 } else {
846 RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES.";
Steve Anton3828c062017-12-06 10:34:51 -0800847 if (type == SdpType::kAnswer && sdes_transport_) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800848 // Explicitly reset the |sdes_transport_| if no crypto param is
849 // provided in the answer. No need to call |ResetParams()| for
850 // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
851 sdes_transport_->ResetParams();
852 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700853 }
854 }
855 }
856
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000857 if (!ret) {
Zhi Huangc99b6c72017-11-10 16:44:46 -0800858 SafeSetError("Failed to setup SRTP.", error_desc);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000859 return false;
860 }
861 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000862}
863
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200864bool BaseChannel::SetRtcpMux_n(bool enable,
Steve Anton3828c062017-12-06 10:34:51 -0800865 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000866 ContentSource src,
867 std::string* error_desc) {
deadbeef8e814d72017-01-13 11:34:39 -0800868 // Provide a more specific error message for the RTCP mux "require" policy
869 // case.
zstein56162b92017-04-24 16:54:35 -0700870 if (rtcp_mux_required_ && !enable) {
deadbeef8e814d72017-01-13 11:34:39 -0800871 SafeSetError(
872 "rtcpMuxPolicy is 'require', but media description does not "
873 "contain 'a=rtcp-mux'.",
874 error_desc);
875 return false;
876 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877 bool ret = false;
Steve Anton3828c062017-12-06 10:34:51 -0800878 switch (type) {
879 case SdpType::kOffer:
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880 ret = rtcp_mux_filter_.SetOffer(enable, src);
881 break;
Steve Anton3828c062017-12-06 10:34:51 -0800882 case SdpType::kPrAnswer:
zhihuangb2cdd932017-01-19 16:54:25 -0800883 // This may activate RTCP muxing, but we don't yet destroy the transport
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700884 // because the final answer may deactivate it.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src);
886 break;
Steve Anton3828c062017-12-06 10:34:51 -0800887 case SdpType::kAnswer:
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000888 ret = rtcp_mux_filter_.SetAnswer(enable, src);
889 if (ret && rtcp_mux_filter_.IsActive()) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800890 ActivateRtcpMux();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891 }
892 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000893 default:
894 break;
895 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000896 if (!ret) {
897 SafeSetError("Failed to setup RTCP mux filter.", error_desc);
898 return false;
899 }
zsteine8ab5432017-07-12 11:48:11 -0700900 rtp_transport_->SetRtcpMuxEnabled(rtcp_mux_filter_.IsActive());
Steve Anton3828c062017-12-06 10:34:51 -0800901 // |rtcp_mux_filter_| can be active if |action| is SdpType::kPrAnswer or
902 // SdpType::kAnswer, but we only want to tear down the RTCP transport if we
903 // received a final answer.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000904 if (rtcp_mux_filter_.IsActive()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 // If the RTP transport is already writable, then so are we.
zsteine8ab5432017-07-12 11:48:11 -0700906 if (rtp_transport_->rtp_packet_transport()->writable()) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200907 ChannelWritable_n();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908 }
909 }
910
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000911 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000912}
913
914bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700915 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800916 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917}
918
Peter Boström0c4e06b2015-10-07 12:23:21 +0200919bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700920 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921 return media_channel()->RemoveRecvStream(ssrc);
922}
923
924bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800925 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000926 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927 // Check for streams that have been removed.
928 bool ret = true;
929 for (StreamParamsVec::const_iterator it = local_streams_.begin();
930 it != local_streams_.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000931 if (!GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000933 std::ostringstream desc;
934 desc << "Failed to remove send stream with ssrc "
935 << it->first_ssrc() << ".";
936 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937 ret = false;
938 }
939 }
940 }
941 // Check for new streams.
942 for (StreamParamsVec::const_iterator it = streams.begin();
943 it != streams.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000944 if (!GetStreamBySsrc(local_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 if (media_channel()->AddSendStream(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100946 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000948 std::ostringstream desc;
949 desc << "Failed to add send stream ssrc: " << it->first_ssrc();
950 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951 ret = false;
952 }
953 }
954 }
955 local_streams_ = streams;
956 return ret;
957}
958
959bool BaseChannel::UpdateRemoteStreams_w(
960 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800961 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000962 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963 // Check for streams that have been removed.
964 bool ret = true;
965 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
966 it != remote_streams_.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000967 if (!GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968 if (!RemoveRecvStream_w(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000969 std::ostringstream desc;
970 desc << "Failed to remove remote stream with ssrc "
971 << it->first_ssrc() << ".";
972 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000973 ret = false;
974 }
975 }
976 }
977 // Check for new streams.
978 for (StreamParamsVec::const_iterator it = streams.begin();
979 it != streams.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000980 if (!GetStreamBySsrc(remote_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000981 if (AddRecvStream_w(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100982 RTC_LOG(LS_INFO) << "Add remote ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000984 std::ostringstream desc;
985 desc << "Failed to add remote stream ssrc: " << it->first_ssrc();
986 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000987 ret = false;
988 }
989 }
990 }
991 remote_streams_ = streams;
992 return ret;
993}
994
jbauch5869f502017-06-29 12:31:36 -0700995RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
996 const RtpHeaderExtensions& extensions) {
997 if (!rtp_dtls_transport_ ||
998 !rtp_dtls_transport_->crypto_options()
999 .enable_encrypted_rtp_header_extensions) {
1000 RtpHeaderExtensions filtered;
1001 auto pred = [](const webrtc::RtpExtension& extension) {
1002 return !extension.encrypt;
1003 };
1004 std::copy_if(extensions.begin(), extensions.end(),
1005 std::back_inserter(filtered), pred);
1006 return filtered;
1007 }
1008
1009 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
1010}
1011
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001012void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension_w(
isheriff6f8d6862016-05-26 11:24:55 -07001013 const std::vector<webrtc::RtpExtension>& extensions) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001014// Absolute Send Time extension id is used only with external auth,
1015// so do not bother searching for it and making asyncronious call to set
1016// something that is not used.
1017#if defined(ENABLE_EXTERNAL_AUTH)
isheriff6f8d6862016-05-26 11:24:55 -07001018 const webrtc::RtpExtension* send_time_extension =
jbauch5869f502017-06-29 12:31:36 -07001019 webrtc::RtpExtension::FindHeaderExtensionByUri(
1020 extensions, webrtc::RtpExtension::kAbsSendTimeUri);
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001021 int rtp_abs_sendtime_extn_id =
henrike@webrtc.orgd43aa9d2014-02-21 23:43:24 +00001022 send_time_extension ? send_time_extension->id : -1;
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001023 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001024 RTC_FROM_HERE, network_thread_,
1025 Bind(&BaseChannel::CacheRtpAbsSendTimeHeaderExtension_n, this,
1026 rtp_abs_sendtime_extn_id));
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001027#endif
1028}
1029
1030void BaseChannel::CacheRtpAbsSendTimeHeaderExtension_n(
1031 int rtp_abs_sendtime_extn_id) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001032 if (sdes_transport_) {
1033 sdes_transport_->CacheRtpAbsSendTimeHeaderExtension(
Zhi Huangcf990f52017-09-22 12:12:30 -07001034 rtp_abs_sendtime_extn_id);
Zhi Huang2a4d70c2017-11-29 15:41:59 -08001035 } else if (dtls_srtp_transport_) {
1036 dtls_srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
1037 rtp_abs_sendtime_extn_id);
Zhi Huangcf990f52017-09-22 12:12:30 -07001038 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001039 RTC_LOG(LS_WARNING)
1040 << "Trying to cache the Absolute Send Time extension id "
1041 "but the SRTP is not active.";
Zhi Huangcf990f52017-09-22 12:12:30 -07001042 }
henrike@webrtc.orgd43aa9d2014-02-21 23:43:24 +00001043}
1044
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001045void BaseChannel::OnMessage(rtc::Message *pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +01001046 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001047 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001048 case MSG_SEND_RTP_PACKET:
1049 case MSG_SEND_RTCP_PACKET: {
1050 RTC_DCHECK(network_thread_->IsCurrent());
1051 SendPacketMessageData* data =
1052 static_cast<SendPacketMessageData*>(pmsg->pdata);
1053 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
1054 SendPacket(rtcp, &data->packet, data->options);
1055 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001056 break;
1057 }
1058 case MSG_FIRSTPACKETRECEIVED: {
1059 SignalFirstPacketReceived(this);
1060 break;
1061 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001062 }
1063}
1064
zstein3dcf0e92017-06-01 13:22:42 -07001065void BaseChannel::AddHandledPayloadType(int payload_type) {
zsteine8ab5432017-07-12 11:48:11 -07001066 rtp_transport_->AddHandledPayloadType(payload_type);
zstein3dcf0e92017-06-01 13:22:42 -07001067}
1068
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001069void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001070 // Flush all remaining RTCP messages. This should only be called in
1071 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001072 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001073 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001074 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
1075 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001076 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
1077 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001078 }
1079}
1080
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001081void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001082 RTC_DCHECK(network_thread_->IsCurrent());
1083 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001084 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001085 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
1086}
1087
1088void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
1089 RTC_DCHECK(worker_thread_->IsCurrent());
1090 SignalSentPacket(sent_packet);
1091}
1092
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001093void BaseChannel::UpdateEncryptedHeaderExtensionIds(
Zhi Huangc99b6c72017-11-10 16:44:46 -08001094 cricket::ContentSource source,
1095 const std::vector<int>& extension_ids) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001096 if (source == ContentSource::CS_LOCAL) {
1097 cached_recv_extension_ids_ = std::move(extension_ids);
1098 if (dtls_srtp_transport_) {
1099 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
1100 extension_ids);
1101 }
1102 } else {
1103 cached_send_extension_ids_ = std::move(extension_ids);
1104 if (dtls_srtp_transport_) {
1105 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
1106 extension_ids);
1107 }
1108 }
Zhi Huangc99b6c72017-11-10 16:44:46 -08001109}
1110
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001111void BaseChannel::ActivateRtcpMux() {
1112 // We permanently activated RTCP muxing; signal that we no longer need
1113 // the RTCP transport.
1114 std::string debug_name =
1115 transport_name_.empty()
1116 ? rtp_transport_->rtp_packet_transport()->transport_name()
1117 : transport_name_;
1118 RTC_LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name()
1119 << "; no longer need RTCP transport for " << debug_name;
1120 if (rtp_transport_->rtcp_packet_transport()) {
1121 SetTransport_n(/*rtcp=*/true, nullptr, nullptr);
1122 if (dtls_srtp_transport_) {
1123 RTC_DCHECK(rtp_dtls_transport_);
1124 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport_,
1125 /*rtcp_dtls_transport_=*/nullptr);
1126 } else {
1127 rtp_transport_->SetRtcpPacketTransport(nullptr);
1128 }
1129 SignalRtcpMuxFullyActive(transport_name_);
Zhi Huangc99b6c72017-11-10 16:44:46 -08001130 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001131 UpdateWritableState_n();
Zhi Huangc99b6c72017-11-10 16:44:46 -08001132}
1133
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001134VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
1135 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001136 rtc::Thread* signaling_thread,
Niels Möllerf120cba2018-01-30 09:33:03 +01001137 // TODO(nisse): Delete unused argument.
1138 MediaEngineInterface* /* media_engine */,
Steve Anton8699a322017-11-06 15:53:33 -08001139 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001140 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -08001141 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001142 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001143 : BaseChannel(worker_thread,
1144 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001145 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001146 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001147 content_name,
deadbeefac22f702017-01-12 21:59:29 -08001148 rtcp_mux_required,
Niels Möllerf120cba2018-01-30 09:33:03 +01001149 srtp_required) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001150
1151VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -08001152 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001153 // this can't be done in the base class, since it calls a virtual
1154 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001155 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001156}
1157
Peter Boström0c4e06b2015-10-07 12:23:21 +02001158bool VoiceChannel::SetAudioSend(uint32_t ssrc,
solenbergdfc8f4f2015-10-01 02:31:10 -07001159 bool enable,
solenberg1dd98f32015-09-10 01:57:14 -07001160 const AudioOptions* options,
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001161 AudioSource* source) {
stefanf79ade12017-06-02 06:44:03 -07001162 return InvokeOnWorker<bool>(
1163 RTC_FROM_HERE, Bind(&VoiceMediaChannel::SetAudioSend, media_channel(),
1164 ssrc, enable, options, source));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001165}
1166
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001167// TODO(juberti): Handle early media the right way. We should get an explicit
1168// ringing message telling us to start playing local ringback, which we cancel
1169// if any early media actually arrives. For now, we do the opposite, which is
1170// to wait 1 second for early media, and start playing local ringback if none
1171// arrives.
1172void VoiceChannel::SetEarlyMedia(bool enable) {
1173 if (enable) {
1174 // Start the early media timeout
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001175 worker_thread()->PostDelayed(RTC_FROM_HERE, kEarlyMediaTimeout, this,
1176 MSG_EARLYMEDIATIMEOUT);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001177 } else {
1178 // Stop the timeout if currently going.
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001179 worker_thread()->Clear(this, MSG_EARLYMEDIATIMEOUT);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001180 }
1181}
1182
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001183bool VoiceChannel::GetStats(VoiceMediaInfo* stats) {
stefanf79ade12017-06-02 06:44:03 -07001184 return InvokeOnWorker<bool>(RTC_FROM_HERE, Bind(&VoiceMediaChannel::GetStats,
1185 media_channel(), stats));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001186}
1187
zstein3dcf0e92017-06-01 13:22:42 -07001188void VoiceChannel::OnPacketReceived(bool rtcp,
zstein634977b2017-07-14 12:30:04 -07001189 rtc::CopyOnWriteBuffer* packet,
zstein3dcf0e92017-06-01 13:22:42 -07001190 const rtc::PacketTime& packet_time) {
1191 BaseChannel::OnPacketReceived(rtcp, packet, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001192 // Set a flag when we've received an RTP packet. If we're waiting for early
1193 // media, this will disable the timeout.
zstein3dcf0e92017-06-01 13:22:42 -07001194 if (!received_media_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001195 received_media_ = true;
1196 }
1197}
1198
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001199void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001200 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001201 invoker_.AsyncInvoke<void>(
1202 RTC_FROM_HERE, worker_thread_,
1203 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001204}
1205
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001206void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001207 // Render incoming data if we're the active call, and we have the local
1208 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001209 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -07001210 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001211
1212 // Send outgoing data if we're the active call, we have the remote content,
1213 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001214 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001215 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001216
Mirko Bonadei675513b2017-11-09 11:09:25 +01001217 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001218}
1219
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001220bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001221 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001222 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001223 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001224 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001225 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001226
Steve Antonb1c1de12017-12-21 15:14:30 -08001227 RTC_DCHECK(content);
1228 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001229 SafeSetError("Can't find audio content in local description.", error_desc);
1230 return false;
1231 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001232
Steve Antonb1c1de12017-12-21 15:14:30 -08001233 const AudioContentDescription* audio = content->as_audio();
1234
jbauch5869f502017-06-29 12:31:36 -07001235 RtpHeaderExtensions rtp_header_extensions =
1236 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
1237
Steve Anton3828c062017-12-06 10:34:51 -08001238 if (!SetRtpTransportParameters(content, type, CS_LOCAL, rtp_header_extensions,
1239 error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001240 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001241 }
1242
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001243 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001244 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001245 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -07001246 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001247 error_desc);
1248 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001249 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001250 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001251 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001252 }
1253 last_recv_params_ = recv_params;
1254
1255 // TODO(pthatcher): Move local streams into AudioSendParameters, and
1256 // only give it to the media channel once we have a remote
1257 // description too (without a remote description, we won't be able
1258 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001259 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001260 SafeSetError("Failed to set local audio description streams.", error_desc);
1261 return false;
1262 }
1263
1264 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001265 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001266 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001267}
1268
1269bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001270 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001271 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001272 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001273 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001274 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001275
Steve Antonb1c1de12017-12-21 15:14:30 -08001276 RTC_DCHECK(content);
1277 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001278 SafeSetError("Can't find audio content in remote description.", error_desc);
1279 return false;
1280 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001281
Steve Antonb1c1de12017-12-21 15:14:30 -08001282 const AudioContentDescription* audio = content->as_audio();
1283
jbauch5869f502017-06-29 12:31:36 -07001284 RtpHeaderExtensions rtp_header_extensions =
1285 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
1286
Steve Anton3828c062017-12-06 10:34:51 -08001287 if (!SetRtpTransportParameters(content, type, CS_REMOTE,
1288 rtp_header_extensions, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001289 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001290 }
1291
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001292 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001293 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
1294 &send_params);
skvladdc1c62c2016-03-16 19:07:43 -07001295
1296 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1297 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001298 SafeSetError("Failed to set remote audio description send parameters.",
1299 error_desc);
1300 return false;
1301 }
1302 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001303
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001304 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
1305 // and only give it to the media channel once we have a local
1306 // description too (without a local description, we won't be able to
1307 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001308 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001309 SafeSetError("Failed to set remote audio description streams.", error_desc);
1310 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001311 }
1312
Peter Thatcherbfab5cb2015-08-20 17:40:24 -07001313 if (audio->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -07001314 MaybeCacheRtpAbsSendTimeHeaderExtension_w(rtp_header_extensions);
Peter Thatcherbfab5cb2015-08-20 17:40:24 -07001315 }
1316
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001317 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001318 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001319 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001320}
1321
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001322void VoiceChannel::HandleEarlyMediaTimeout() {
1323 // This occurs on the main thread, not the worker thread.
1324 if (!received_media_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001325 RTC_LOG(LS_INFO) << "No early media received before timeout";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001326 SignalEarlyMediaTimeout(this);
1327 }
1328}
1329
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001330void VoiceChannel::OnMessage(rtc::Message *pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001331 switch (pmsg->message_id) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001332 case MSG_EARLYMEDIATIMEOUT:
1333 HandleEarlyMediaTimeout();
1334 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001335 default:
1336 BaseChannel::OnMessage(pmsg);
1337 break;
1338 }
1339}
1340
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001341VideoChannel::VideoChannel(rtc::Thread* worker_thread,
1342 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001343 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001344 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001345 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -08001346 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001347 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001348 : BaseChannel(worker_thread,
1349 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001350 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001351 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001352 content_name,
deadbeefac22f702017-01-12 21:59:29 -08001353 rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001354 srtp_required) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001355
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -08001357 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358 // this can't be done in the base class, since it calls a virtual
1359 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001360
1361 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001362}
1363
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001364void VideoChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001365 // Send outgoing data if we're the active call, we have the remote content,
1366 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001367 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001368 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001369 RTC_LOG(LS_ERROR) << "Failed to SetSend on video channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001370 // TODO(gangji): Report error back to server.
1371 }
1372
Mirko Bonadei675513b2017-11-09 11:09:25 +01001373 RTC_LOG(LS_INFO) << "Changing video state, send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001374}
1375
stefanf79ade12017-06-02 06:44:03 -07001376void VideoChannel::FillBitrateInfo(BandwidthEstimationInfo* bwe_info) {
1377 InvokeOnWorker<void>(RTC_FROM_HERE, Bind(&VideoMediaChannel::FillBitrateInfo,
1378 media_channel(), bwe_info));
1379}
1380
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001381bool VideoChannel::GetStats(VideoMediaInfo* stats) {
stefanf79ade12017-06-02 06:44:03 -07001382 return InvokeOnWorker<bool>(RTC_FROM_HERE, Bind(&VideoMediaChannel::GetStats,
1383 media_channel(), stats));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001384}
1385
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001387 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001388 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001389 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001390 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001391 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001392
Steve Antonb1c1de12017-12-21 15:14:30 -08001393 RTC_DCHECK(content);
1394 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001395 SafeSetError("Can't find video content in local description.", error_desc);
1396 return false;
1397 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398
Steve Antonb1c1de12017-12-21 15:14:30 -08001399 const VideoContentDescription* video = content->as_video();
1400
jbauch5869f502017-06-29 12:31:36 -07001401 RtpHeaderExtensions rtp_header_extensions =
1402 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1403
Steve Anton3828c062017-12-06 10:34:51 -08001404 if (!SetRtpTransportParameters(content, type, CS_LOCAL, rtp_header_extensions,
1405 error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001406 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407 }
1408
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001409 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001410 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001411 if (!media_channel()->SetRecvParameters(recv_params)) {
1412 SafeSetError("Failed to set local video description recv parameters.",
1413 error_desc);
1414 return false;
1415 }
1416 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001417 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001418 }
1419 last_recv_params_ = recv_params;
1420
1421 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1422 // only give it to the media channel once we have a remote
1423 // description too (without a remote description, we won't be able
1424 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001425 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001426 SafeSetError("Failed to set local video description streams.", error_desc);
1427 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001428 }
1429
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001430 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001431 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001432 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001433}
1434
1435bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001436 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001437 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001438 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001439 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001440 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001441
Steve Antonb1c1de12017-12-21 15:14:30 -08001442 RTC_DCHECK(content);
1443 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001444 SafeSetError("Can't find video content in remote description.", error_desc);
1445 return false;
1446 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001447
Steve Antonb1c1de12017-12-21 15:14:30 -08001448 const VideoContentDescription* video = content->as_video();
1449
jbauch5869f502017-06-29 12:31:36 -07001450 RtpHeaderExtensions rtp_header_extensions =
1451 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1452
Steve Anton3828c062017-12-06 10:34:51 -08001453 if (!SetRtpTransportParameters(content, type, CS_REMOTE,
1454 rtp_header_extensions, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001455 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456 }
1457
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001458 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001459 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
1460 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001461 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001462 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001463 }
skvladdc1c62c2016-03-16 19:07:43 -07001464
1465 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1466
1467 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001468 SafeSetError("Failed to set remote video description send parameters.",
1469 error_desc);
1470 return false;
1471 }
1472 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001474 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1475 // and only give it to the media channel once we have a local
1476 // description too (without a local description, we won't be able to
1477 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001478 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001479 SafeSetError("Failed to set remote video description streams.", error_desc);
1480 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001481 }
1482
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001483 if (video->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -07001484 MaybeCacheRtpAbsSendTimeHeaderExtension_w(rtp_header_extensions);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001485 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001486
1487 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001488 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001489 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001490}
1491
deadbeef953c2ce2017-01-09 14:53:41 -08001492RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1493 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001494 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001495 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001496 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -08001497 bool rtcp_mux_required,
deadbeef953c2ce2017-01-09 14:53:41 -08001498 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001499 : BaseChannel(worker_thread,
1500 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001501 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001502 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001503 content_name,
deadbeefac22f702017-01-12 21:59:29 -08001504 rtcp_mux_required,
deadbeef953c2ce2017-01-09 14:53:41 -08001505 srtp_required) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001506
deadbeef953c2ce2017-01-09 14:53:41 -08001507RtpDataChannel::~RtpDataChannel() {
1508 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001509 // this can't be done in the base class, since it calls a virtual
1510 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001511
1512 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001513}
1514
Steve Anton8699a322017-11-06 15:53:33 -08001515void RtpDataChannel::Init_w(
deadbeeff5346592017-01-24 21:51:21 -08001516 DtlsTransportInternal* rtp_dtls_transport,
1517 DtlsTransportInternal* rtcp_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -08001518 rtc::PacketTransportInternal* rtp_packet_transport,
1519 rtc::PacketTransportInternal* rtcp_packet_transport) {
Steve Anton8699a322017-11-06 15:53:33 -08001520 BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport,
1521 rtp_packet_transport, rtcp_packet_transport);
1522
deadbeef953c2ce2017-01-09 14:53:41 -08001523 media_channel()->SignalDataReceived.connect(this,
1524 &RtpDataChannel::OnDataReceived);
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001525 media_channel()->SignalReadyToSend.connect(
deadbeef953c2ce2017-01-09 14:53:41 -08001526 this, &RtpDataChannel::OnDataChannelReadyToSend);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001527}
1528
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001529void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
1530 BaseChannel::Init_w(rtp_transport);
1531 media_channel()->SignalDataReceived.connect(this,
1532 &RtpDataChannel::OnDataReceived);
1533 media_channel()->SignalReadyToSend.connect(
1534 this, &RtpDataChannel::OnDataChannelReadyToSend);
1535}
1536
deadbeef953c2ce2017-01-09 14:53:41 -08001537bool RtpDataChannel::SendData(const SendDataParams& params,
1538 const rtc::CopyOnWriteBuffer& payload,
1539 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001540 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001541 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1542 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001543}
1544
deadbeef953c2ce2017-01-09 14:53:41 -08001545bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001546 const DataContentDescription* content,
1547 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001548 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1549 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001550 // It's been set before, but doesn't match. That's bad.
1551 if (is_sctp) {
1552 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1553 error_desc);
1554 return false;
1555 }
1556 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001557}
1558
deadbeef953c2ce2017-01-09 14:53:41 -08001559bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001560 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001561 std::string* error_desc) {
1562 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001563 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001564 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001565
Steve Antonb1c1de12017-12-21 15:14:30 -08001566 RTC_DCHECK(content);
1567 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001568 SafeSetError("Can't find data content in local description.", error_desc);
1569 return false;
1570 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001571
Steve Antonb1c1de12017-12-21 15:14:30 -08001572 const DataContentDescription* data = content->as_data();
1573
deadbeef953c2ce2017-01-09 14:53:41 -08001574 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575 return false;
1576 }
1577
jbauch5869f502017-06-29 12:31:36 -07001578 RtpHeaderExtensions rtp_header_extensions =
1579 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1580
Steve Anton3828c062017-12-06 10:34:51 -08001581 if (!SetRtpTransportParameters(content, type, CS_LOCAL, rtp_header_extensions,
1582 error_desc)) {
deadbeef953c2ce2017-01-09 14:53:41 -08001583 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001584 }
1585
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001586 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001587 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001588 if (!media_channel()->SetRecvParameters(recv_params)) {
1589 SafeSetError("Failed to set remote data description recv parameters.",
1590 error_desc);
1591 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592 }
deadbeef953c2ce2017-01-09 14:53:41 -08001593 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001594 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001595 }
1596 last_recv_params_ = recv_params;
1597
1598 // TODO(pthatcher): Move local streams into DataSendParameters, and
1599 // only give it to the media channel once we have a remote
1600 // description too (without a remote description, we won't be able
1601 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001602 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001603 SafeSetError("Failed to set local data description streams.", error_desc);
1604 return false;
1605 }
1606
1607 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001608 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001609 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001610}
1611
deadbeef953c2ce2017-01-09 14:53:41 -08001612bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001613 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001614 std::string* error_desc) {
1615 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001616 RTC_DCHECK_RUN_ON(worker_thread());
1617 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001618
Steve Antonb1c1de12017-12-21 15:14:30 -08001619 RTC_DCHECK(content);
1620 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001621 SafeSetError("Can't find data content in remote description.", error_desc);
1622 return false;
1623 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001624
Steve Antonb1c1de12017-12-21 15:14:30 -08001625 const DataContentDescription* data = content->as_data();
1626
Zhi Huang801b8682017-11-15 11:36:43 -08001627 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1628 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001629 return true;
1630 }
1631
deadbeef953c2ce2017-01-09 14:53:41 -08001632 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001633 return false;
1634 }
1635
jbauch5869f502017-06-29 12:31:36 -07001636 RtpHeaderExtensions rtp_header_extensions =
1637 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1638
Mirko Bonadei675513b2017-11-09 11:09:25 +01001639 RTC_LOG(LS_INFO) << "Setting remote data description";
Steve Anton3828c062017-12-06 10:34:51 -08001640 if (!SetRtpTransportParameters(content, type, CS_REMOTE,
1641 rtp_header_extensions, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001642 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001643 }
1644
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001645 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001646 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
1647 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001648 if (!media_channel()->SetSendParameters(send_params)) {
1649 SafeSetError("Failed to set remote data description send parameters.",
1650 error_desc);
1651 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001652 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001653 last_send_params_ = send_params;
1654
1655 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1656 // and only give it to the media channel once we have a local
1657 // description too (without a local description, we won't be able to
1658 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001659 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001660 SafeSetError("Failed to set remote data description streams.",
1661 error_desc);
1662 return false;
1663 }
1664
1665 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001666 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001667 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001668}
1669
deadbeef953c2ce2017-01-09 14:53:41 -08001670void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001671 // Render incoming data if we're the active call, and we have the local
1672 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001673 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001674 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001675 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001676 }
1677
1678 // Send outgoing data if we're the active call, we have the remote content,
1679 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001680 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001681 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001682 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001683 }
1684
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001685 // Trigger SignalReadyToSendData asynchronously.
1686 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001687
Mirko Bonadei675513b2017-11-09 11:09:25 +01001688 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001689}
1690
deadbeef953c2ce2017-01-09 14:53:41 -08001691void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001692 switch (pmsg->message_id) {
1693 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001694 DataChannelReadyToSendMessageData* data =
1695 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001696 ready_to_send_data_ = data->data();
1697 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001698 delete data;
1699 break;
1700 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001701 case MSG_DATARECEIVED: {
1702 DataReceivedMessageData* data =
1703 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001704 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001705 delete data;
1706 break;
1707 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001708 default:
1709 BaseChannel::OnMessage(pmsg);
1710 break;
1711 }
1712}
1713
deadbeef953c2ce2017-01-09 14:53:41 -08001714void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1715 const char* data,
1716 size_t len) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001717 DataReceivedMessageData* msg = new DataReceivedMessageData(
1718 params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001719 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001720}
1721
deadbeef953c2ce2017-01-09 14:53:41 -08001722void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001723 // This is usded for congestion control to indicate that the stream is ready
1724 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1725 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001726 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001727 new DataChannelReadyToSendMessageData(writable));
1728}
1729
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001730} // namespace cricket