blob: e08e2b502de57ffd3e53e9baf5d605880e2dfc42 [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
Zhi Huang27f3bf52018-03-26 21:37:23 -070032#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "p2p/base/packettransportinternal.h"
34#include "pc/channelmanager.h"
Steve Anton4e70a722017-11-28 14:57:10 -080035#include "pc/rtpmediautils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
37namespace cricket {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000038using rtc::Bind;
Steve Anton3828c062017-12-06 10:34:51 -080039using webrtc::SdpType;
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +000040
deadbeef2d110be2016-01-13 12:00:26 -080041namespace {
Danil Chapovalov33b01f22016-05-11 19:55:27 +020042
43struct SendPacketMessageData : public rtc::MessageData {
44 rtc::CopyOnWriteBuffer packet;
45 rtc::PacketOptions options;
46};
47
deadbeef2d110be2016-01-13 12:00:26 -080048} // namespace
49
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050enum {
Steve Anton0807d152018-03-05 11:23:09 -080051 MSG_SEND_RTP_PACKET = 1,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020052 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 Huang27f3bf52018-03-26 21:37:23 -0700114 demuxer_criteria_.mid = content_name;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800115 rtp_transport_ = unencrypted_rtp_transport_.get();
116 ConnectToRtpTransport();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100117 RTC_LOG(LS_INFO) << "Created channel for " << content_name;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000118}
119
120BaseChannel::~BaseChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -0800121 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel");
Steve Anton8699a322017-11-06 15:53:33 -0800122 RTC_DCHECK_RUN_ON(worker_thread_);
wu@webrtc.org78187522013-10-07 23:32:02 +0000123 Deinit();
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200124 // Eats any outstanding messages or packets.
125 worker_thread_->Clear(&invoker_);
126 worker_thread_->Clear(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000127 // We must destroy the media channel before the transport channel, otherwise
128 // the media channel may try to send on the dead transport channel. NULLing
129 // is not an effective strategy since the sends will come on another thread.
Steve Anton8699a322017-11-06 15:53:33 -0800130 media_channel_.reset();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100131 RTC_LOG(LS_INFO) << "Destroyed channel: " << content_name_;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200132}
133
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800134void BaseChannel::ConnectToRtpTransport() {
135 RTC_DCHECK(rtp_transport_);
Zhi Huang27f3bf52018-03-26 21:37:23 -0700136 bool success = RegisterRtpDemuxerSink();
137 RTC_DCHECK(success);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800138 rtp_transport_->SignalReadyToSend.connect(
139 this, &BaseChannel::OnTransportReadyToSend);
Zhi Huang27f3bf52018-03-26 21:37:23 -0700140 rtp_transport_->SignalRtcpPacketReceived.connect(
141 this, &BaseChannel::OnRtcpPacketReceived);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800142 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);
Steve Antondb67ba12018-03-19 17:41:42 -0700148 // TODO(bugs.webrtc.org/8587): Set the metrics observer through
149 // JsepTransportController once it takes responsibility for creating
150 // RtpTransports.
151 if (metrics_observer_) {
152 rtp_transport_->SetMetricsObserver(metrics_observer_);
153 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800154}
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200155
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800156void BaseChannel::DisconnectFromRtpTransport() {
157 RTC_DCHECK(rtp_transport_);
Zhi Huang27f3bf52018-03-26 21:37:23 -0700158 rtp_transport_->UnregisterRtpDemuxerSink(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800159 rtp_transport_->SignalReadyToSend.disconnect(this);
Zhi Huang27f3bf52018-03-26 21:37:23 -0700160 rtp_transport_->SignalRtcpPacketReceived.disconnect(this);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800161 rtp_transport_->SignalNetworkRouteChanged.disconnect(this);
162 rtp_transport_->SignalWritableState.disconnect(this);
163 rtp_transport_->SignalSentPacket.disconnect(this);
Steve Antondb67ba12018-03-19 17:41:42 -0700164 rtp_transport_->SetMetricsObserver(nullptr);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200165}
166
Steve Anton8699a322017-11-06 15:53:33 -0800167void BaseChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
deadbeeff5346592017-01-24 21:51:21 -0800168 DtlsTransportInternal* rtcp_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -0800169 rtc::PacketTransportInternal* rtp_packet_transport,
170 rtc::PacketTransportInternal* rtcp_packet_transport) {
Steve Anton8699a322017-11-06 15:53:33 -0800171 RTC_DCHECK_RUN_ON(worker_thread_);
172 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800173 SetTransports_n(rtp_dtls_transport, rtcp_dtls_transport,
174 rtp_packet_transport, rtcp_packet_transport);
175
176 if (rtcp_mux_required_) {
177 rtcp_mux_filter_.SetActive();
178 }
Steve Anton8699a322017-11-06 15:53:33 -0800179 });
180
deadbeeff5346592017-01-24 21:51:21 -0800181 // Both RTP and RTCP channels should be set, we can call SetInterface on
182 // the media channel and it can set network options.
wu@webrtc.orgde305012013-10-31 15:40:38 +0000183 media_channel_->SetInterface(this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000184}
185
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800186void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
187 RTC_DCHECK_RUN_ON(worker_thread_);
188 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
189 SetRtpTransport(rtp_transport);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200190
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800191 if (rtcp_mux_required_) {
192 rtcp_mux_filter_.SetActive();
193 }
194 });
195
196 // Both RTP and RTCP channels should be set, we can call SetInterface on
197 // the media channel and it can set network options.
198 media_channel_->SetInterface(this);
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200199}
200
wu@webrtc.org78187522013-10-07 23:32:02 +0000201void BaseChannel::Deinit() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200202 RTC_DCHECK(worker_thread_->IsCurrent());
wu@webrtc.org78187522013-10-07 23:32:02 +0000203 media_channel_->SetInterface(NULL);
Danil Chapovalovdae07ba2016-05-14 01:43:50 +0200204 // Packets arrive on the network thread, processing packets calls virtual
205 // functions, so need to stop this process in Deinit that is called in
206 // derived classes destructor.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800207 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
Zhi Huang27f3bf52018-03-26 21:37:23 -0700208 if (rtp_transport_) {
209 FlushRtcpMessages_n();
210 if (dtls_srtp_transport_) {
211 dtls_srtp_transport_->SetDtlsTransports(nullptr, nullptr);
212 } else {
213 rtp_transport_->SetRtpPacketTransport(nullptr);
214 rtp_transport_->SetRtcpPacketTransport(nullptr);
215 }
216 DisconnectFromRtpTransport();
Zhi Huang97d5e5b2018-03-27 00:09:01 +0000217 }
Zhi Huang27f3bf52018-03-26 21:37:23 -0700218
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800219 // Clear pending read packets/messages.
220 network_thread_->Clear(&invoker_);
221 network_thread_->Clear(this);
Zhi Huang27f3bf52018-03-26 21:37:23 -0700222 // Because RTP level transports are accessed from the |network_thread_|,
223 // it's safer to release them from the |network_thread_| as well.
224 unencrypted_rtp_transport_.reset();
225 sdes_transport_.reset();
226 dtls_srtp_transport_.reset();
227 rtp_transport_ = nullptr;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800228 });
wu@webrtc.org78187522013-10-07 23:32:02 +0000229}
230
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800231void BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) {
232 if (!network_thread_->IsCurrent()) {
233 network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
234 SetRtpTransport(rtp_transport);
235 return;
236 });
237 }
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800238 RTC_DCHECK(rtp_transport);
Zhi Huang27f3bf52018-03-26 21:37:23 -0700239 if (rtp_transport == rtp_transport_) {
240 return;
241 }
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800242
243 if (rtp_transport_) {
244 DisconnectFromRtpTransport();
245 }
246 rtp_transport_ = rtp_transport;
247 RTC_LOG(LS_INFO) << "Setting the RtpTransport for " << content_name();
248 ConnectToRtpTransport();
249
250 UpdateWritableState_n();
251}
252
zhihuangb2cdd932017-01-19 16:54:25 -0800253void BaseChannel::SetTransports(DtlsTransportInternal* rtp_dtls_transport,
254 DtlsTransportInternal* rtcp_dtls_transport) {
deadbeeff5346592017-01-24 21:51:21 -0800255 network_thread_->Invoke<void>(
256 RTC_FROM_HERE,
257 Bind(&BaseChannel::SetTransports_n, this, rtp_dtls_transport,
258 rtcp_dtls_transport, rtp_dtls_transport, rtcp_dtls_transport));
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000259}
260
deadbeeff5346592017-01-24 21:51:21 -0800261void BaseChannel::SetTransports(
deadbeef5bd5ca32017-02-10 11:31:50 -0800262 rtc::PacketTransportInternal* rtp_packet_transport,
263 rtc::PacketTransportInternal* rtcp_packet_transport) {
deadbeeff5346592017-01-24 21:51:21 -0800264 network_thread_->Invoke<void>(
265 RTC_FROM_HERE, Bind(&BaseChannel::SetTransports_n, this, nullptr, nullptr,
266 rtp_packet_transport, rtcp_packet_transport));
267}
zhihuangf5b251b2017-01-12 19:37:48 -0800268
deadbeeff5346592017-01-24 21:51:21 -0800269void BaseChannel::SetTransports_n(
270 DtlsTransportInternal* rtp_dtls_transport,
271 DtlsTransportInternal* rtcp_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -0800272 rtc::PacketTransportInternal* rtp_packet_transport,
273 rtc::PacketTransportInternal* rtcp_packet_transport) {
deadbeeff5346592017-01-24 21:51:21 -0800274 RTC_DCHECK(network_thread_->IsCurrent());
275 // Validate some assertions about the input.
276 RTC_DCHECK(rtp_packet_transport);
277 RTC_DCHECK_EQ(NeedsRtcpTransport(), rtcp_packet_transport != nullptr);
278 if (rtp_dtls_transport || rtcp_dtls_transport) {
279 // DTLS/non-DTLS pointers should be to the same object.
280 RTC_DCHECK(rtp_dtls_transport == rtp_packet_transport);
281 RTC_DCHECK(rtcp_dtls_transport == rtcp_packet_transport);
282 // Can't go from non-DTLS to DTLS.
zsteine8ab5432017-07-12 11:48:11 -0700283 RTC_DCHECK(!rtp_transport_->rtp_packet_transport() || rtp_dtls_transport_);
deadbeeff5346592017-01-24 21:51:21 -0800284 } else {
285 // Can't go from DTLS to non-DTLS.
286 RTC_DCHECK(!rtp_dtls_transport_);
287 }
288 // Transport names should be the same.
zhihuangb2cdd932017-01-19 16:54:25 -0800289 if (rtp_dtls_transport && rtcp_dtls_transport) {
290 RTC_DCHECK(rtp_dtls_transport->transport_name() ==
291 rtcp_dtls_transport->transport_name());
zhihuangb2cdd932017-01-19 16:54:25 -0800292 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800293
294 if (rtp_packet_transport == rtp_transport_->rtp_packet_transport()) {
295 // Nothing to do if transport isn't changing.
296 return;
297 }
298
deadbeeff5346592017-01-24 21:51:21 -0800299 std::string debug_name;
300 if (rtp_dtls_transport) {
301 transport_name_ = rtp_dtls_transport->transport_name();
302 debug_name = transport_name_;
303 } else {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800304 debug_name = rtp_packet_transport->transport_name();
deadbeeff5346592017-01-24 21:51:21 -0800305 }
deadbeefac22f702017-01-12 21:59:29 -0800306 // If this BaseChannel doesn't require RTCP mux and we haven't fully
307 // negotiated RTCP mux, we need an RTCP transport.
deadbeeff5346592017-01-24 21:51:21 -0800308 if (rtcp_packet_transport) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100309 RTC_LOG(LS_INFO) << "Setting RTCP Transport for " << content_name()
310 << " on " << debug_name << " transport "
311 << rtcp_packet_transport;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800312 SetTransport_n(/*rtcp=*/true, rtcp_dtls_transport, rtcp_packet_transport);
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000313 }
314
Mirko Bonadei675513b2017-11-09 11:09:25 +0100315 RTC_LOG(LS_INFO) << "Setting RTP Transport for " << content_name() << " on "
316 << debug_name << " transport " << rtp_packet_transport;
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800317 SetTransport_n(/*rtcp=*/false, rtp_dtls_transport, rtp_packet_transport);
318
319 // Set DtlsTransport/PacketTransport for RTP-level transport.
320 if ((rtp_dtls_transport_ || rtcp_dtls_transport_) && dtls_srtp_transport_) {
321 // When setting the transport with non-null |dtls_srtp_transport_|, we are
322 // using DTLS-SRTP. This could happen for bundling. If the
323 // |dtls_srtp_transport| is null, we cannot tell if it doing DTLS-SRTP or
324 // SDES until the description is set. So don't call |EnableDtlsSrtp_n| here.
325 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport,
326 rtcp_dtls_transport);
327 } else {
328 rtp_transport_->SetRtpPacketTransport(rtp_packet_transport);
329 rtp_transport_->SetRtcpPacketTransport(rtcp_packet_transport);
330 }
guoweis46383312015-12-17 16:45:59 -0800331
deadbeefcbecd352015-09-23 11:50:27 -0700332 // Update aggregate writable/ready-to-send state between RTP and RTCP upon
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700333 // setting new transport channels.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200334 UpdateWritableState_n();
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000335}
336
deadbeeff5346592017-01-24 21:51:21 -0800337void BaseChannel::SetTransport_n(
338 bool rtcp,
339 DtlsTransportInternal* new_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -0800340 rtc::PacketTransportInternal* new_packet_transport) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200341 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800342 if (new_dtls_transport) {
343 RTC_DCHECK(new_dtls_transport == new_packet_transport);
344 }
deadbeeff5346592017-01-24 21:51:21 -0800345 DtlsTransportInternal*& old_dtls_transport =
zhihuangb2cdd932017-01-19 16:54:25 -0800346 rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_;
zsteind48dbda2017-04-04 19:45:57 -0700347 rtc::PacketTransportInternal* old_packet_transport =
zsteine8ab5432017-07-12 11:48:11 -0700348 rtcp ? rtp_transport_->rtcp_packet_transport()
349 : rtp_transport_->rtp_packet_transport();
zhihuangb2cdd932017-01-19 16:54:25 -0800350
deadbeeff5346592017-01-24 21:51:21 -0800351 if (!old_packet_transport && !new_packet_transport) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700352 // Nothing to do.
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000353 return;
354 }
zhihuangb2cdd932017-01-19 16:54:25 -0800355
deadbeeff5346592017-01-24 21:51:21 -0800356 RTC_DCHECK(old_packet_transport != new_packet_transport);
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000357
deadbeeff5346592017-01-24 21:51:21 -0800358 old_dtls_transport = new_dtls_transport;
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000359
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800360 // If there's no new transport, we're done.
deadbeeff5346592017-01-24 21:51:21 -0800361 if (!new_packet_transport) {
362 return;
363 }
364
365 if (rtcp && new_dtls_transport) {
Zhi Huangcf990f52017-09-22 12:12:30 -0700366 RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_active()))
367 << "Setting RTCP for DTLS/SRTP after the DTLS is active "
deadbeeff5346592017-01-24 21:51:21 -0800368 << "should never happen.";
369 }
zstein56162b92017-04-24 16:54:35 -0700370
deadbeeff5346592017-01-24 21:51:21 -0800371 auto& socket_options = rtcp ? rtcp_socket_options_ : socket_options_;
372 for (const auto& pair : socket_options) {
373 new_packet_transport->SetOption(pair.first, pair.second);
guoweis46383312015-12-17 16:45:59 -0800374 }
pthatcher@webrtc.org6ad507a2015-03-16 20:19:12 +0000375}
376
Steve Antondb67ba12018-03-19 17:41:42 -0700377void BaseChannel::SetMetricsObserver(
378 rtc::scoped_refptr<webrtc::MetricsObserverInterface> metrics_observer) {
379 metrics_observer_ = metrics_observer;
380 if (rtp_transport_) {
381 rtp_transport_->SetMetricsObserver(metrics_observer);
382 }
383}
384
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000385bool BaseChannel::Enable(bool enable) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700386 worker_thread_->Invoke<void>(
387 RTC_FROM_HERE,
388 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w,
389 this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000390 return true;
391}
392
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000393bool BaseChannel::AddRecvStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700394 return InvokeOnWorker<bool>(RTC_FROM_HERE,
395 Bind(&BaseChannel::AddRecvStream_w, this, sp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000396}
397
Peter Boström0c4e06b2015-10-07 12:23:21 +0200398bool BaseChannel::RemoveRecvStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700399 return InvokeOnWorker<bool>(
400 RTC_FROM_HERE, Bind(&BaseChannel::RemoveRecvStream_w, this, ssrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000401}
402
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000403bool BaseChannel::AddSendStream(const StreamParams& sp) {
stefanf79ade12017-06-02 06:44:03 -0700404 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700405 RTC_FROM_HERE, Bind(&MediaChannel::AddSendStream, media_channel(), sp));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000406}
407
Peter Boström0c4e06b2015-10-07 12:23:21 +0200408bool BaseChannel::RemoveSendStream(uint32_t ssrc) {
stefanf79ade12017-06-02 06:44:03 -0700409 return InvokeOnWorker<bool>(
410 RTC_FROM_HERE,
411 Bind(&MediaChannel::RemoveSendStream, media_channel(), ssrc));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000412}
413
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000414bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800415 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000416 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100417 TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
stefanf79ade12017-06-02 06:44:03 -0700418 return InvokeOnWorker<bool>(
419 RTC_FROM_HERE,
Steve Anton3828c062017-12-06 10:34:51 -0800420 Bind(&BaseChannel::SetLocalContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000421}
422
423bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800424 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000425 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +0100426 TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
stefanf79ade12017-06-02 06:44:03 -0700427 return InvokeOnWorker<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800428 RTC_FROM_HERE,
429 Bind(&BaseChannel::SetRemoteContent_w, this, content, type, error_desc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000430}
431
zhihuangf5b251b2017-01-12 19:37:48 -0800432bool BaseChannel::NeedsRtcpTransport() {
deadbeefac22f702017-01-12 21:59:29 -0800433 // If this BaseChannel doesn't require RTCP mux and we haven't fully
434 // negotiated RTCP mux, we need an RTCP transport.
zstein56162b92017-04-24 16:54:35 -0700435 return !rtcp_mux_required_ && !rtcp_mux_filter_.IsFullyActive();
pthatcher@webrtc.orgb4aac132015-03-13 18:25:21 +0000436}
437
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700438bool BaseChannel::IsReadyToReceiveMedia_w() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000439 // Receive data if we are enabled and have local content,
Steve Anton4e70a722017-11-28 14:57:10 -0800440 return enabled() &&
441 webrtc::RtpTransceiverDirectionHasRecv(local_content_direction_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000442}
443
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700444bool BaseChannel::IsReadyToSendMedia_w() const {
445 // Need to access some state updated on the network thread.
446 return network_thread_->Invoke<bool>(
447 RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this));
448}
449
450bool BaseChannel::IsReadyToSendMedia_n() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000451 // Send outgoing data if we are enabled, have local and remote content,
452 // and we have had some form of connectivity.
Steve Anton4e70a722017-11-28 14:57:10 -0800453 return enabled() &&
454 webrtc::RtpTransceiverDirectionHasRecv(remote_content_direction_) &&
455 webrtc::RtpTransceiverDirectionHasSend(local_content_direction_) &&
Zhi Huangcf990f52017-09-22 12:12:30 -0700456 was_ever_writable() && (srtp_active() || !ShouldSetupDtlsSrtp_n());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000457}
458
jbaucheec21bd2016-03-20 06:15:43 -0700459bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700460 const rtc::PacketOptions& options) {
461 return SendPacket(false, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000462}
463
jbaucheec21bd2016-03-20 06:15:43 -0700464bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700465 const rtc::PacketOptions& options) {
466 return SendPacket(true, packet, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000467}
468
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000469int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000470 int value) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200471 return network_thread_->Invoke<int>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700472 RTC_FROM_HERE, Bind(&BaseChannel::SetOption_n, this, type, opt, value));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200473}
474
475int BaseChannel::SetOption_n(SocketType type,
476 rtc::Socket::Option opt,
477 int value) {
478 RTC_DCHECK(network_thread_->IsCurrent());
deadbeef5bd5ca32017-02-10 11:31:50 -0800479 rtc::PacketTransportInternal* transport = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000480 switch (type) {
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000481 case ST_RTP:
zsteine8ab5432017-07-12 11:48:11 -0700482 transport = rtp_transport_->rtp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700483 socket_options_.push_back(
484 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000485 break;
486 case ST_RTCP:
zsteine8ab5432017-07-12 11:48:11 -0700487 transport = rtp_transport_->rtcp_packet_transport();
deadbeefcbecd352015-09-23 11:50:27 -0700488 rtcp_socket_options_.push_back(
489 std::pair<rtc::Socket::Option, int>(opt, value));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000490 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000491 }
deadbeeff5346592017-01-24 21:51:21 -0800492 return transport ? transport->SetOption(opt, value) : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000493}
494
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800495void BaseChannel::OnWritableState(bool writable) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200496 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800497 if (writable) {
498 // This is used to cover the scenario when the DTLS handshake is completed
499 // and DtlsTransport becomes writable before the remote description is set.
500 if (ShouldSetupDtlsSrtp_n()) {
501 EnableDtlsSrtp_n();
Zhi Huangcf990f52017-09-22 12:12:30 -0700502 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800503 ChannelWritable_n();
504 } else {
505 ChannelNotWritable_n();
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800506 }
507}
508
Zhi Huang942bc2e2017-11-13 13:26:07 -0800509void BaseChannel::OnNetworkRouteChanged(
510 rtc::Optional<rtc::NetworkRoute> network_route) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200511 RTC_DCHECK(network_thread_->IsCurrent());
Zhi Huang942bc2e2017-11-13 13:26:07 -0800512 rtc::NetworkRoute new_route;
513 if (network_route) {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800514 new_route = *(network_route);
Zhi Huang8c316c12017-11-13 21:13:45 +0000515 }
Zhi Huang942bc2e2017-11-13 13:26:07 -0800516 // Note: When the RTCP-muxing is not enabled, RTCP transport and RTP transport
517 // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot
518 // work correctly. Intentionally leave it broken to simplify the code and
519 // encourage the users to stop using non-muxing RTCP.
Steve Anton8699a322017-11-06 15:53:33 -0800520 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [=] {
Zhi Huang942bc2e2017-11-13 13:26:07 -0800521 media_channel_->OnNetworkRouteChanged(transport_name_, new_route);
Steve Anton8699a322017-11-06 15:53:33 -0800522 });
Honghai Zhangcc411c02016-03-29 17:27:21 -0700523}
524
zstein56162b92017-04-24 16:54:35 -0700525void BaseChannel::OnTransportReadyToSend(bool ready) {
Steve Anton8699a322017-11-06 15:53:33 -0800526 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
527 [=] { media_channel_->OnReadyToSend(ready); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000528}
529
stefanc1aeaf02015-10-15 07:26:07 -0700530bool BaseChannel::SendPacket(bool rtcp,
jbaucheec21bd2016-03-20 06:15:43 -0700531 rtc::CopyOnWriteBuffer* packet,
stefanc1aeaf02015-10-15 07:26:07 -0700532 const rtc::PacketOptions& options) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200533 // SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
534 // If the thread is not our network thread, we will post to our network
535 // so that the real work happens on our network. This avoids us having to
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000536 // synchronize access to all the pieces of the send path, including
537 // SRTP and the inner workings of the transport channels.
538 // The only downside is that we can't return a proper failure code if
539 // needed. Since UDP is unreliable anyway, this should be a non-issue.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200540 if (!network_thread_->IsCurrent()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000541 // Avoid a copy by transferring the ownership of the packet data.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200542 int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
543 SendPacketMessageData* data = new SendPacketMessageData;
kwiberg0eb15ed2015-12-17 03:04:15 -0800544 data->packet = std::move(*packet);
stefanc1aeaf02015-10-15 07:26:07 -0700545 data->options = options;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700546 network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000547 return true;
548 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200549 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000550
551 // Now that we are on the correct thread, ensure we have a place to send this
552 // packet before doing anything. (We might get RTCP packets that we don't
553 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
554 // transport.
zsteine8ab5432017-07-12 11:48:11 -0700555 if (!rtp_transport_->IsWritable(rtcp)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000556 return false;
557 }
558
559 // Protect ourselves against crazy data.
560 if (!ValidPacket(rtcp, packet)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100561 RTC_LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
562 << RtpRtcpStringLiteral(rtcp)
563 << " packet: wrong size=" << packet->size();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000564 return false;
565 }
566
Zhi Huangcf990f52017-09-22 12:12:30 -0700567 if (!srtp_active()) {
568 if (srtp_required_) {
569 // The audio/video engines may attempt to send RTCP packets as soon as the
570 // streams are created, so don't treat this as an error for RTCP.
571 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
572 if (rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000573 return false;
574 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700575 // However, there shouldn't be any RTP packets sent before SRTP is set up
576 // (and SetSend(true) is called).
Mirko Bonadei675513b2017-11-09 11:09:25 +0100577 RTC_LOG(LS_ERROR)
578 << "Can't send outgoing RTP packet when SRTP is inactive"
579 << " and crypto is required";
Zhi Huangcf990f52017-09-22 12:12:30 -0700580 RTC_NOTREACHED();
deadbeef8f425f92016-12-01 12:26:27 -0800581 return false;
582 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800583
584 std::string packet_type = rtcp ? "RTCP" : "RTP";
585 RTC_LOG(LS_WARNING) << "Sending an " << packet_type
586 << " packet without encryption.";
587 } else {
588 // Make sure we didn't accidentally send any packets without encryption.
589 RTC_DCHECK(rtp_transport_ == sdes_transport_.get() ||
590 rtp_transport_ == dtls_srtp_transport_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000591 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000592 // Bon voyage.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800593 return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
594 : rtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000595}
596
Zhi Huang27f3bf52018-03-26 21:37:23 -0700597void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) {
598 // Reconstruct the PacketTime from the |parsed_packet|.
599 // RtpPacketReceived.arrival_time_ms = (PacketTime + 500) / 1000;
600 // Note: The |not_before| field is always 0 here. This field is not currently
601 // used, so it should be fine.
602 int64_t timestamp = -1;
603 if (parsed_packet.arrival_time_ms() > 0) {
604 timestamp = parsed_packet.arrival_time_ms() * 1000;
605 }
606 rtc::PacketTime packet_time(timestamp, /*not_before=*/0);
607 OnPacketReceived(/*rtcp=*/false, parsed_packet.Buffer(), packet_time);
608}
609
610void BaseChannel::UpdateRtpHeaderExtensionMap(
611 const RtpHeaderExtensions& header_extensions) {
612 RTC_DCHECK(rtp_transport_);
613 rtp_transport_->UpdateRtpHeaderExtensionMap(header_extensions);
614}
615
616bool BaseChannel::RegisterRtpDemuxerSink() {
617 RTC_DCHECK(rtp_transport_);
618 return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria_, this);
619}
620
621void BaseChannel::OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
622 const rtc::PacketTime& packet_time) {
623 OnPacketReceived(/*rtcp=*/true, *packet, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000624}
625
zstein3dcf0e92017-06-01 13:22:42 -0700626void BaseChannel::OnPacketReceived(bool rtcp,
Zhi Huang27f3bf52018-03-26 21:37:23 -0700627 const rtc::CopyOnWriteBuffer& packet,
zstein3dcf0e92017-06-01 13:22:42 -0700628 const rtc::PacketTime& packet_time) {
honghaiz@google.coma67ca1a2015-01-28 19:48:33 +0000629 if (!has_received_packet_ && !rtcp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000630 has_received_packet_ = true;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700631 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632 }
633
Zhi Huangcf990f52017-09-22 12:12:30 -0700634 if (!srtp_active() && srtp_required_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000635 // Our session description indicates that SRTP is required, but we got a
636 // packet before our SRTP filter is active. This means either that
637 // a) we got SRTP packets before we received the SDES keys, in which case
638 // we can't decrypt it anyway, or
639 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
zhihuangb2cdd932017-01-19 16:54:25 -0800640 // transports, so we haven't yet extracted keys, even if DTLS did
641 // complete on the transport that the packets are being sent on. It's
642 // really good practice to wait for both RTP and RTCP to be good to go
643 // before sending media, to prevent weird failure modes, so it's fine
644 // for us to just eat packets here. This is all sidestepped if RTCP mux
645 // is used anyway.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100646 RTC_LOG(LS_WARNING)
647 << "Can't process incoming " << RtpRtcpStringLiteral(rtcp)
648 << " packet when SRTP is inactive and crypto is required";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649 return;
650 }
651
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200652 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700653 RTC_FROM_HERE, worker_thread_,
Zhi Huang27f3bf52018-03-26 21:37:23 -0700654 Bind(&BaseChannel::ProcessPacket, this, rtcp, packet, packet_time));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200655}
656
zstein3dcf0e92017-06-01 13:22:42 -0700657void BaseChannel::ProcessPacket(bool rtcp,
658 const rtc::CopyOnWriteBuffer& packet,
659 const rtc::PacketTime& packet_time) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200660 RTC_DCHECK(worker_thread_->IsCurrent());
zstein3dcf0e92017-06-01 13:22:42 -0700661
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200662 // Need to copy variable because OnRtcpReceived/OnPacketReceived
663 // requires non-const pointer to buffer. This doesn't memcpy the actual data.
664 rtc::CopyOnWriteBuffer data(packet);
665 if (rtcp) {
666 media_channel_->OnRtcpReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000667 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200668 media_channel_->OnPacketReceived(&data, packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669 }
670}
671
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000672void BaseChannel::EnableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700673 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000674 if (enabled_)
675 return;
676
Mirko Bonadei675513b2017-11-09 11:09:25 +0100677 RTC_LOG(LS_INFO) << "Channel enabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000678 enabled_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700679 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000680}
681
682void BaseChannel::DisableMedia_w() {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700683 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000684 if (!enabled_)
685 return;
686
Mirko Bonadei675513b2017-11-09 11:09:25 +0100687 RTC_LOG(LS_INFO) << "Channel disabled";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000688 enabled_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700689 UpdateMediaSendRecvState_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000690}
691
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200692void BaseChannel::UpdateWritableState_n() {
zsteind48dbda2017-04-04 19:45:57 -0700693 rtc::PacketTransportInternal* rtp_packet_transport =
zsteine8ab5432017-07-12 11:48:11 -0700694 rtp_transport_->rtp_packet_transport();
zsteind48dbda2017-04-04 19:45:57 -0700695 rtc::PacketTransportInternal* rtcp_packet_transport =
zsteine8ab5432017-07-12 11:48:11 -0700696 rtp_transport_->rtcp_packet_transport();
zsteind48dbda2017-04-04 19:45:57 -0700697 if (rtp_packet_transport && rtp_packet_transport->writable() &&
698 (!rtcp_packet_transport || rtcp_packet_transport->writable())) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200699 ChannelWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700700 } else {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200701 ChannelNotWritable_n();
deadbeefcbecd352015-09-23 11:50:27 -0700702 }
703}
704
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200705void BaseChannel::ChannelWritable_n() {
706 RTC_DCHECK(network_thread_->IsCurrent());
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800707 if (writable_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000708 return;
Guo-wei Shieh1218d7a2015-12-05 09:59:56 -0800709 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000710
Mirko Bonadei675513b2017-11-09 11:09:25 +0100711 RTC_LOG(LS_INFO) << "Channel writable (" << content_name_ << ")"
712 << (was_ever_writable_ ? "" : " for the first time");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000713
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714 was_ever_writable_ = true;
715 writable_ = true;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700716 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717}
718
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200719bool BaseChannel::ShouldSetupDtlsSrtp_n() const {
zhihuangb2cdd932017-01-19 16:54:25 -0800720 // Since DTLS is applied to all transports, checking RTP should be enough.
721 return rtp_dtls_transport_ && rtp_dtls_transport_->IsDtlsActive();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722}
723
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200724void BaseChannel::ChannelNotWritable_n() {
725 RTC_DCHECK(network_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726 if (!writable_)
727 return;
728
Mirko Bonadei675513b2017-11-09 11:09:25 +0100729 RTC_LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730 writable_ = false;
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700731 UpdateMediaSendRecvState();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000732}
733
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200734bool BaseChannel::SetRtpTransportParameters(
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700735 const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800736 SdpType type,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700737 ContentSource src,
jbauch5869f502017-06-29 12:31:36 -0700738 const RtpHeaderExtensions& extensions,
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700739 std::string* error_desc) {
jbauch5869f502017-06-29 12:31:36 -0700740 std::vector<int> encrypted_extension_ids;
741 for (const webrtc::RtpExtension& extension : extensions) {
742 if (extension.encrypt) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100743 RTC_LOG(LS_INFO) << "Using " << (src == CS_LOCAL ? "local" : "remote")
744 << " encrypted extension: " << extension.ToString();
jbauch5869f502017-06-29 12:31:36 -0700745 encrypted_extension_ids.push_back(extension.id);
746 }
747 }
748
deadbeef7af91dd2016-12-13 11:29:11 -0800749 // Cache srtp_required_ for belt and suspenders check on SendPacket
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200750 return network_thread_->Invoke<bool>(
Steve Anton3828c062017-12-06 10:34:51 -0800751 RTC_FROM_HERE,
752 Bind(&BaseChannel::SetRtpTransportParameters_n, this, content, type, src,
753 encrypted_extension_ids, error_desc));
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200754}
755
756bool BaseChannel::SetRtpTransportParameters_n(
757 const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -0800758 SdpType type,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200759 ContentSource src,
jbauch5869f502017-06-29 12:31:36 -0700760 const std::vector<int>& encrypted_extension_ids,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200761 std::string* error_desc) {
762 RTC_DCHECK(network_thread_->IsCurrent());
763
Steve Anton3828c062017-12-06 10:34:51 -0800764 if (!SetSrtp_n(content->cryptos(), type, src, encrypted_extension_ids,
765 error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700766 return false;
767 }
768
Steve Anton3828c062017-12-06 10:34:51 -0800769 if (!SetRtcpMux_n(content->rtcp_mux(), type, src, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -0700770 return false;
771 }
772
773 return true;
774}
775
zhihuangb2cdd932017-01-19 16:54:25 -0800776// |dtls| will be set to true if DTLS is active for transport and crypto is
777// empty.
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200778bool BaseChannel::CheckSrtpConfig_n(const std::vector<CryptoParams>& cryptos,
779 bool* dtls,
780 std::string* error_desc) {
deadbeeff5346592017-01-24 21:51:21 -0800781 *dtls = rtp_dtls_transport_ && rtp_dtls_transport_->IsDtlsActive();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000782 if (*dtls && !cryptos.empty()) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200783 SafeSetError("Cryptos must be empty when DTLS is active.", error_desc);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000784 return false;
785 }
786 return true;
787}
788
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800789void BaseChannel::EnableSdes_n() {
790 if (sdes_transport_) {
791 return;
Zhi Huangcf990f52017-09-22 12:12:30 -0700792 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800793 // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
794 // time.
795 RTC_DCHECK(!dtls_srtp_transport_);
Zhi Huang27f3bf52018-03-26 21:37:23 -0700796
797 sdes_transport_ = rtc::MakeUnique<webrtc::SrtpTransport>(rtcp_mux_required_);
Zhi Huangd7455782017-11-30 14:50:52 -0800798#if defined(ENABLE_EXTERNAL_AUTH)
799 sdes_transport_->EnableExternalAuth();
800#endif
Zhi Huang27f3bf52018-03-26 21:37:23 -0700801 sdes_transport_->SetRtpPacketTransport(
802 rtp_transport_->rtp_packet_transport());
803 sdes_transport_->SetRtcpPacketTransport(
804 rtp_transport_->rtcp_packet_transport());
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800805 SetRtpTransport(sdes_transport_.get());
Zhi Huang27f3bf52018-03-26 21:37:23 -0700806 RTC_LOG(LS_INFO) << "SrtpTransport is created for SDES.";
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800807}
808
809void BaseChannel::EnableDtlsSrtp_n() {
810 if (dtls_srtp_transport_) {
811 return;
812 }
813 // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
814 // time.
815 RTC_DCHECK(!sdes_transport_);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800816
Zhi Huang97d5e5b2018-03-27 00:09:01 +0000817 dtls_srtp_transport_ =
Zhi Huang27f3bf52018-03-26 21:37:23 -0700818 rtc::MakeUnique<webrtc::DtlsSrtpTransport>(rtcp_mux_required_);
819#if defined(ENABLE_EXTERNAL_AUTH)
820 dtls_srtp_transport_->EnableExternalAuth();
821#endif
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800822
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800823 SetRtpTransport(dtls_srtp_transport_.get());
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800824 if (cached_send_extension_ids_) {
825 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
826 *cached_send_extension_ids_);
827 }
828 if (cached_recv_extension_ids_) {
829 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
830 *cached_recv_extension_ids_);
831 }
832 // Set the DtlsTransport and the |dtls_srtp_transport_| will handle the DTLS
833 // relate signal internally.
834 RTC_DCHECK(rtp_dtls_transport_);
835 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport_,
836 rtcp_dtls_transport_);
Zhi Huang27f3bf52018-03-26 21:37:23 -0700837 RTC_LOG(LS_INFO) << "DtlsSrtpTransport is created for DTLS-SRTP.";
Zhi Huangcf990f52017-09-22 12:12:30 -0700838}
839
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200840bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
Steve Anton3828c062017-12-06 10:34:51 -0800841 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000842 ContentSource src,
jbauch5869f502017-06-29 12:31:36 -0700843 const std::vector<int>& encrypted_extension_ids,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000844 std::string* error_desc) {
Peter Boströmca8b4042016-03-08 14:24:13 -0800845 TRACE_EVENT0("webrtc", "BaseChannel::SetSrtp_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846 bool ret = false;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000847 bool dtls = false;
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200848 ret = CheckSrtpConfig_n(cryptos, &dtls, error_desc);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000849 if (!ret) {
850 return false;
851 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700852
853 // If SRTP was not required, but we're setting a description that uses SDES,
854 // we need to upgrade to an SrtpTransport.
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800855 if (!sdes_transport_ && !dtls && !cryptos.empty()) {
856 EnableSdes_n();
Zhi Huangcf990f52017-09-22 12:12:30 -0700857 }
Zhi Huangc99b6c72017-11-10 16:44:46 -0800858
Steve Anton3828c062017-12-06 10:34:51 -0800859 if ((type == SdpType::kAnswer || type == SdpType::kPrAnswer) && dtls) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800860 EnableDtlsSrtp_n();
861 }
Zhi Huangc99b6c72017-11-10 16:44:46 -0800862
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800863 UpdateEncryptedHeaderExtensionIds(src, encrypted_extension_ids);
864
865 if (!dtls) {
Steve Anton3828c062017-12-06 10:34:51 -0800866 switch (type) {
867 case SdpType::kOffer:
Zhi Huangcf990f52017-09-22 12:12:30 -0700868 ret = sdes_negotiator_.SetOffer(cryptos, src);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800869 break;
Steve Anton3828c062017-12-06 10:34:51 -0800870 case SdpType::kPrAnswer:
Zhi Huangcf990f52017-09-22 12:12:30 -0700871 ret = sdes_negotiator_.SetProvisionalAnswer(cryptos, src);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800872 break;
Steve Anton3828c062017-12-06 10:34:51 -0800873 case SdpType::kAnswer:
Zhi Huangcf990f52017-09-22 12:12:30 -0700874 ret = sdes_negotiator_.SetAnswer(cryptos, src);
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800875 break;
876 default:
877 break;
878 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700879
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800880 // If setting an SDES answer succeeded, apply the negotiated parameters
881 // to the SRTP transport.
Steve Anton3828c062017-12-06 10:34:51 -0800882 if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800883 if (sdes_negotiator_.send_cipher_suite() &&
884 sdes_negotiator_.recv_cipher_suite()) {
885 RTC_DCHECK(cached_send_extension_ids_);
886 RTC_DCHECK(cached_recv_extension_ids_);
887 ret = sdes_transport_->SetRtpParams(
888 *(sdes_negotiator_.send_cipher_suite()),
889 sdes_negotiator_.send_key().data(),
890 static_cast<int>(sdes_negotiator_.send_key().size()),
891 *(cached_send_extension_ids_),
892 *(sdes_negotiator_.recv_cipher_suite()),
893 sdes_negotiator_.recv_key().data(),
894 static_cast<int>(sdes_negotiator_.recv_key().size()),
895 *(cached_recv_extension_ids_));
896 } else {
897 RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES.";
Steve Anton3828c062017-12-06 10:34:51 -0800898 if (type == SdpType::kAnswer && sdes_transport_) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800899 // Explicitly reset the |sdes_transport_| if no crypto param is
900 // provided in the answer. No need to call |ResetParams()| for
901 // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
902 sdes_transport_->ResetParams();
903 }
Zhi Huangcf990f52017-09-22 12:12:30 -0700904 }
905 }
906 }
907
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000908 if (!ret) {
Zhi Huangc99b6c72017-11-10 16:44:46 -0800909 SafeSetError("Failed to setup SRTP.", error_desc);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000910 return false;
911 }
912 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000913}
914
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200915bool BaseChannel::SetRtcpMux_n(bool enable,
Steve Anton3828c062017-12-06 10:34:51 -0800916 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000917 ContentSource src,
918 std::string* error_desc) {
deadbeef8e814d72017-01-13 11:34:39 -0800919 // Provide a more specific error message for the RTCP mux "require" policy
920 // case.
zstein56162b92017-04-24 16:54:35 -0700921 if (rtcp_mux_required_ && !enable) {
deadbeef8e814d72017-01-13 11:34:39 -0800922 SafeSetError(
923 "rtcpMuxPolicy is 'require', but media description does not "
924 "contain 'a=rtcp-mux'.",
925 error_desc);
926 return false;
927 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000928 bool ret = false;
Steve Anton3828c062017-12-06 10:34:51 -0800929 switch (type) {
930 case SdpType::kOffer:
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931 ret = rtcp_mux_filter_.SetOffer(enable, src);
932 break;
Steve Anton3828c062017-12-06 10:34:51 -0800933 case SdpType::kPrAnswer:
zhihuangb2cdd932017-01-19 16:54:25 -0800934 // This may activate RTCP muxing, but we don't yet destroy the transport
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700935 // because the final answer may deactivate it.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src);
937 break;
Steve Anton3828c062017-12-06 10:34:51 -0800938 case SdpType::kAnswer:
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939 ret = rtcp_mux_filter_.SetAnswer(enable, src);
940 if (ret && rtcp_mux_filter_.IsActive()) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -0800941 ActivateRtcpMux();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000942 }
943 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944 default:
945 break;
946 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000947 if (!ret) {
948 SafeSetError("Failed to setup RTCP mux filter.", error_desc);
949 return false;
950 }
zsteine8ab5432017-07-12 11:48:11 -0700951 rtp_transport_->SetRtcpMuxEnabled(rtcp_mux_filter_.IsActive());
Steve Anton3828c062017-12-06 10:34:51 -0800952 // |rtcp_mux_filter_| can be active if |action| is SdpType::kPrAnswer or
953 // SdpType::kAnswer, but we only want to tear down the RTCP transport if we
954 // received a final answer.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000955 if (rtcp_mux_filter_.IsActive()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000956 // If the RTP transport is already writable, then so are we.
zsteine8ab5432017-07-12 11:48:11 -0700957 if (rtp_transport_->rtp_packet_transport()->writable()) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200958 ChannelWritable_n();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000959 }
960 }
961
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000962 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000963}
964
965bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700966 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
pbos482b12e2015-11-16 10:19:58 -0800967 return media_channel()->AddRecvStream(sp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968}
969
Peter Boström0c4e06b2015-10-07 12:23:21 +0200970bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) {
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -0700971 RTC_DCHECK(worker_thread() == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000972 return media_channel()->RemoveRecvStream(ssrc);
973}
974
975bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -0800976 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000977 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000978 // Check for streams that have been removed.
979 bool ret = true;
980 for (StreamParamsVec::const_iterator it = local_streams_.begin();
981 it != local_streams_.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000982 if (!GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000983 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000984 std::ostringstream desc;
985 desc << "Failed to remove send stream with ssrc "
986 << it->first_ssrc() << ".";
987 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988 ret = false;
989 }
990 }
991 }
992 // Check for new streams.
993 for (StreamParamsVec::const_iterator it = streams.begin();
994 it != streams.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000995 if (!GetStreamBySsrc(local_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000996 if (media_channel()->AddSendStream(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100997 RTC_LOG(LS_INFO) << "Add send stream ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000999 std::ostringstream desc;
1000 desc << "Failed to add send stream ssrc: " << it->first_ssrc();
1001 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001002 ret = false;
1003 }
1004 }
1005 }
1006 local_streams_ = streams;
1007 return ret;
1008}
1009
1010bool BaseChannel::UpdateRemoteStreams_w(
1011 const std::vector<StreamParams>& streams,
Steve Anton3828c062017-12-06 10:34:51 -08001012 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001013 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001014 // Check for streams that have been removed.
1015 bool ret = true;
1016 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
1017 it != remote_streams_.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +00001018 if (!GetStreamBySsrc(streams, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001019 if (!RemoveRecvStream_w(it->first_ssrc())) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001020 std::ostringstream desc;
1021 desc << "Failed to remove remote stream with ssrc "
1022 << it->first_ssrc() << ".";
1023 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024 ret = false;
1025 }
1026 }
1027 }
1028 // Check for new streams.
1029 for (StreamParamsVec::const_iterator it = streams.begin();
1030 it != streams.end(); ++it) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +00001031 if (!GetStreamBySsrc(remote_streams_, it->first_ssrc())) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001032 if (AddRecvStream_w(*it)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001033 RTC_LOG(LS_INFO) << "Add remote ssrc: " << it->ssrcs[0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001034 } else {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001035 std::ostringstream desc;
1036 desc << "Failed to add remote stream ssrc: " << it->first_ssrc();
1037 SafeSetError(desc.str(), error_desc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001038 ret = false;
1039 }
1040 }
1041 }
1042 remote_streams_ = streams;
1043 return ret;
1044}
1045
jbauch5869f502017-06-29 12:31:36 -07001046RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
1047 const RtpHeaderExtensions& extensions) {
1048 if (!rtp_dtls_transport_ ||
1049 !rtp_dtls_transport_->crypto_options()
1050 .enable_encrypted_rtp_header_extensions) {
1051 RtpHeaderExtensions filtered;
1052 auto pred = [](const webrtc::RtpExtension& extension) {
1053 return !extension.encrypt;
1054 };
1055 std::copy_if(extensions.begin(), extensions.end(),
1056 std::back_inserter(filtered), pred);
1057 return filtered;
1058 }
1059
1060 return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
1061}
1062
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001063void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension_w(
isheriff6f8d6862016-05-26 11:24:55 -07001064 const std::vector<webrtc::RtpExtension>& extensions) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001065// Absolute Send Time extension id is used only with external auth,
1066// so do not bother searching for it and making asyncronious call to set
1067// something that is not used.
1068#if defined(ENABLE_EXTERNAL_AUTH)
isheriff6f8d6862016-05-26 11:24:55 -07001069 const webrtc::RtpExtension* send_time_extension =
jbauch5869f502017-06-29 12:31:36 -07001070 webrtc::RtpExtension::FindHeaderExtensionByUri(
1071 extensions, webrtc::RtpExtension::kAbsSendTimeUri);
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001072 int rtp_abs_sendtime_extn_id =
henrike@webrtc.orgd43aa9d2014-02-21 23:43:24 +00001073 send_time_extension ? send_time_extension->id : -1;
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001074 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001075 RTC_FROM_HERE, network_thread_,
1076 Bind(&BaseChannel::CacheRtpAbsSendTimeHeaderExtension_n, this,
1077 rtp_abs_sendtime_extn_id));
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001078#endif
1079}
1080
1081void BaseChannel::CacheRtpAbsSendTimeHeaderExtension_n(
1082 int rtp_abs_sendtime_extn_id) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001083 if (sdes_transport_) {
1084 sdes_transport_->CacheRtpAbsSendTimeHeaderExtension(
Zhi Huangcf990f52017-09-22 12:12:30 -07001085 rtp_abs_sendtime_extn_id);
Zhi Huang2a4d70c2017-11-29 15:41:59 -08001086 } else if (dtls_srtp_transport_) {
1087 dtls_srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
1088 rtp_abs_sendtime_extn_id);
Zhi Huangcf990f52017-09-22 12:12:30 -07001089 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001090 RTC_LOG(LS_WARNING)
1091 << "Trying to cache the Absolute Send Time extension id "
1092 "but the SRTP is not active.";
Zhi Huangcf990f52017-09-22 12:12:30 -07001093 }
henrike@webrtc.orgd43aa9d2014-02-21 23:43:24 +00001094}
1095
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001096void BaseChannel::OnMessage(rtc::Message *pmsg) {
Peter Boström6f28cf02015-12-07 23:17:15 +01001097 TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001098 switch (pmsg->message_id) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001099 case MSG_SEND_RTP_PACKET:
1100 case MSG_SEND_RTCP_PACKET: {
1101 RTC_DCHECK(network_thread_->IsCurrent());
1102 SendPacketMessageData* data =
1103 static_cast<SendPacketMessageData*>(pmsg->pdata);
1104 bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
1105 SendPacket(rtcp, &data->packet, data->options);
1106 delete data;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001107 break;
1108 }
1109 case MSG_FIRSTPACKETRECEIVED: {
1110 SignalFirstPacketReceived(this);
1111 break;
1112 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001113 }
1114}
1115
zstein3dcf0e92017-06-01 13:22:42 -07001116void BaseChannel::AddHandledPayloadType(int payload_type) {
Zhi Huang27f3bf52018-03-26 21:37:23 -07001117 demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
zstein3dcf0e92017-06-01 13:22:42 -07001118}
1119
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001120void BaseChannel::FlushRtcpMessages_n() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001121 // Flush all remaining RTCP messages. This should only be called in
1122 // destructor.
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001123 RTC_DCHECK(network_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001124 rtc::MessageList rtcp_messages;
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001125 network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
1126 for (const auto& message : rtcp_messages) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001127 network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
1128 message.pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001129 }
1130}
1131
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001132void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001133 RTC_DCHECK(network_thread_->IsCurrent());
1134 invoker_.AsyncInvoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001135 RTC_FROM_HERE, worker_thread_,
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001136 rtc::Bind(&BaseChannel::SignalSentPacket_w, this, sent_packet));
1137}
1138
1139void BaseChannel::SignalSentPacket_w(const rtc::SentPacket& sent_packet) {
1140 RTC_DCHECK(worker_thread_->IsCurrent());
1141 SignalSentPacket(sent_packet);
1142}
1143
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001144void BaseChannel::UpdateEncryptedHeaderExtensionIds(
Zhi Huangc99b6c72017-11-10 16:44:46 -08001145 cricket::ContentSource source,
1146 const std::vector<int>& extension_ids) {
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001147 if (source == ContentSource::CS_LOCAL) {
1148 cached_recv_extension_ids_ = std::move(extension_ids);
1149 if (dtls_srtp_transport_) {
1150 dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
1151 extension_ids);
1152 }
1153 } else {
1154 cached_send_extension_ids_ = std::move(extension_ids);
1155 if (dtls_srtp_transport_) {
1156 dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
1157 extension_ids);
1158 }
1159 }
Zhi Huangc99b6c72017-11-10 16:44:46 -08001160}
1161
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001162void BaseChannel::ActivateRtcpMux() {
1163 // We permanently activated RTCP muxing; signal that we no longer need
1164 // the RTCP transport.
1165 std::string debug_name =
1166 transport_name_.empty()
1167 ? rtp_transport_->rtp_packet_transport()->transport_name()
1168 : transport_name_;
1169 RTC_LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name()
1170 << "; no longer need RTCP transport for " << debug_name;
1171 if (rtp_transport_->rtcp_packet_transport()) {
1172 SetTransport_n(/*rtcp=*/true, nullptr, nullptr);
1173 if (dtls_srtp_transport_) {
1174 RTC_DCHECK(rtp_dtls_transport_);
1175 dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport_,
1176 /*rtcp_dtls_transport_=*/nullptr);
1177 } else {
1178 rtp_transport_->SetRtcpPacketTransport(nullptr);
1179 }
1180 SignalRtcpMuxFullyActive(transport_name_);
Zhi Huangc99b6c72017-11-10 16:44:46 -08001181 }
Zhi Huangcd3fc5d2017-11-29 10:41:57 -08001182 UpdateWritableState_n();
Zhi Huangc99b6c72017-11-10 16:44:46 -08001183}
1184
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001185VoiceChannel::VoiceChannel(rtc::Thread* worker_thread,
1186 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001187 rtc::Thread* signaling_thread,
Niels Möllerf120cba2018-01-30 09:33:03 +01001188 // TODO(nisse): Delete unused argument.
1189 MediaEngineInterface* /* media_engine */,
Steve Anton8699a322017-11-06 15:53:33 -08001190 std::unique_ptr<VoiceMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001191 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -08001192 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001193 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001194 : BaseChannel(worker_thread,
1195 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001196 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001197 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001198 content_name,
deadbeefac22f702017-01-12 21:59:29 -08001199 rtcp_mux_required,
Niels Möllerf120cba2018-01-30 09:33:03 +01001200 srtp_required) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001201
1202VoiceChannel::~VoiceChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -08001203 TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001204 // this can't be done in the base class, since it calls a virtual
1205 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001206 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001207}
1208
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001209void BaseChannel::UpdateMediaSendRecvState() {
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001210 RTC_DCHECK(network_thread_->IsCurrent());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001211 invoker_.AsyncInvoke<void>(
1212 RTC_FROM_HERE, worker_thread_,
1213 Bind(&BaseChannel::UpdateMediaSendRecvState_w, this));
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001214}
1215
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001216void VoiceChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001217 // Render incoming data if we're the active call, and we have the local
1218 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001219 bool recv = IsReadyToReceiveMedia_w();
solenberg5b14b422015-10-01 04:10:31 -07001220 media_channel()->SetPlayout(recv);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001221
1222 // Send outgoing data if we're the active call, we have the remote content,
1223 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001224 bool send = IsReadyToSendMedia_w();
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -08001225 media_channel()->SetSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001226
Mirko Bonadei675513b2017-11-09 11:09:25 +01001227 RTC_LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001228}
1229
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001230bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001231 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001232 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001233 TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001234 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001235 RTC_LOG(LS_INFO) << "Setting local voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001236
Steve Antonb1c1de12017-12-21 15:14:30 -08001237 RTC_DCHECK(content);
1238 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001239 SafeSetError("Can't find audio content in local description.", error_desc);
1240 return false;
1241 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001242
Steve Antonb1c1de12017-12-21 15:14:30 -08001243 const AudioContentDescription* audio = content->as_audio();
1244
jbauch5869f502017-06-29 12:31:36 -07001245 RtpHeaderExtensions rtp_header_extensions =
1246 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
Zhi Huang27f3bf52018-03-26 21:37:23 -07001247 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
jbauch5869f502017-06-29 12:31:36 -07001248
Steve Anton3828c062017-12-06 10:34:51 -08001249 if (!SetRtpTransportParameters(content, type, CS_LOCAL, rtp_header_extensions,
1250 error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001251 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001252 }
1253
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001254 AudioRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001255 RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001256 if (!media_channel()->SetRecvParameters(recv_params)) {
Peter Thatcherbfab5cb2015-08-20 17:40:24 -07001257 SafeSetError("Failed to set local audio description recv parameters.",
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001258 error_desc);
1259 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001260 }
Zhi Huang27f3bf52018-03-26 21:37:23 -07001261
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001262 for (const AudioCodec& codec : audio->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001263 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001264 }
Zhi Huang27f3bf52018-03-26 21:37:23 -07001265 // Need to re-register the sink to update the handled payload.
1266 if (!RegisterRtpDemuxerSink()) {
1267 RTC_LOG(LS_ERROR) << "Failed to set up audio demuxing.";
1268 return false;
1269 }
1270
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001271 last_recv_params_ = recv_params;
1272
1273 // TODO(pthatcher): Move local streams into AudioSendParameters, and
1274 // only give it to the media channel once we have a remote
1275 // description too (without a remote description, we won't be able
1276 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001277 if (!UpdateLocalStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001278 SafeSetError("Failed to set local audio description streams.", error_desc);
1279 return false;
1280 }
1281
1282 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001283 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001284 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001285}
1286
1287bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001288 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001289 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001290 TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001291 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001292 RTC_LOG(LS_INFO) << "Setting remote voice description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001293
Steve Antonb1c1de12017-12-21 15:14:30 -08001294 RTC_DCHECK(content);
1295 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001296 SafeSetError("Can't find audio content in remote description.", error_desc);
1297 return false;
1298 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001299
Steve Antonb1c1de12017-12-21 15:14:30 -08001300 const AudioContentDescription* audio = content->as_audio();
1301
jbauch5869f502017-06-29 12:31:36 -07001302 RtpHeaderExtensions rtp_header_extensions =
1303 GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
1304
Zhi Huang27f3bf52018-03-26 21:37:23 -07001305 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Steve Anton3828c062017-12-06 10:34:51 -08001306 if (!SetRtpTransportParameters(content, type, CS_REMOTE,
1307 rtp_header_extensions, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001308 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001309 }
1310
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001311 AudioSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001312 RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
1313 &send_params);
Steve Antonbb50ce52018-03-26 10:24:32 -07001314 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001315
1316 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1317 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001318 SafeSetError("Failed to set remote audio description send parameters.",
1319 error_desc);
1320 return false;
1321 }
1322 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001323
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001324 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
1325 // and only give it to the media channel once we have a local
1326 // description too (without a local description, we won't be able to
1327 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001328 if (!UpdateRemoteStreams_w(audio->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001329 SafeSetError("Failed to set remote audio description streams.", error_desc);
1330 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001331 }
1332
Peter Thatcherbfab5cb2015-08-20 17:40:24 -07001333 if (audio->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -07001334 MaybeCacheRtpAbsSendTimeHeaderExtension_w(rtp_header_extensions);
Peter Thatcherbfab5cb2015-08-20 17:40:24 -07001335 }
1336
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001337 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001338 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001339 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001340}
1341
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001342VideoChannel::VideoChannel(rtc::Thread* worker_thread,
1343 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001344 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001345 std::unique_ptr<VideoMediaChannel> media_channel,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -08001347 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001348 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001349 : BaseChannel(worker_thread,
1350 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001351 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001352 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001353 content_name,
deadbeefac22f702017-01-12 21:59:29 -08001354 rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -08001355 srtp_required) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001357VideoChannel::~VideoChannel() {
Peter Boströmca8b4042016-03-08 14:24:13 -08001358 TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001359 // this can't be done in the base class, since it calls a virtual
1360 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001361 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
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001381bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001382 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001383 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001384 TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001385 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001386 RTC_LOG(LS_INFO) << "Setting local video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001387
Steve Antonb1c1de12017-12-21 15:14:30 -08001388 RTC_DCHECK(content);
1389 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001390 SafeSetError("Can't find video content in local description.", error_desc);
1391 return false;
1392 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001393
Steve Antonb1c1de12017-12-21 15:14:30 -08001394 const VideoContentDescription* video = content->as_video();
1395
jbauch5869f502017-06-29 12:31:36 -07001396 RtpHeaderExtensions rtp_header_extensions =
1397 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
Zhi Huang27f3bf52018-03-26 21:37:23 -07001398 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
jbauch5869f502017-06-29 12:31:36 -07001399
Steve Anton3828c062017-12-06 10:34:51 -08001400 if (!SetRtpTransportParameters(content, type, CS_LOCAL, rtp_header_extensions,
1401 error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001402 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001403 }
1404
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001405 VideoRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001406 RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001407 if (!media_channel()->SetRecvParameters(recv_params)) {
1408 SafeSetError("Failed to set local video description recv parameters.",
1409 error_desc);
1410 return false;
1411 }
Zhi Huang27f3bf52018-03-26 21:37:23 -07001412
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001413 for (const VideoCodec& codec : video->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001414 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001415 }
Zhi Huang27f3bf52018-03-26 21:37:23 -07001416 // Need to re-register the sink to update the handled payload.
1417 if (!RegisterRtpDemuxerSink()) {
1418 RTC_LOG(LS_ERROR) << "Failed to set up video demuxing.";
1419 return false;
1420 }
1421
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001422 last_recv_params_ = recv_params;
1423
1424 // TODO(pthatcher): Move local streams into VideoSendParameters, and
1425 // only give it to the media channel once we have a remote
1426 // description too (without a remote description, we won't be able
1427 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001428 if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001429 SafeSetError("Failed to set local video description streams.", error_desc);
1430 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001431 }
1432
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001433 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001434 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001435 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001436}
1437
1438bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001439 SdpType type,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001440 std::string* error_desc) {
Peter Boström9f45a452015-12-08 13:25:57 +01001441 TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001442 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001443 RTC_LOG(LS_INFO) << "Setting remote video description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001444
Steve Antonb1c1de12017-12-21 15:14:30 -08001445 RTC_DCHECK(content);
1446 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001447 SafeSetError("Can't find video content in remote description.", error_desc);
1448 return false;
1449 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001450
Steve Antonb1c1de12017-12-21 15:14:30 -08001451 const VideoContentDescription* video = content->as_video();
1452
jbauch5869f502017-06-29 12:31:36 -07001453 RtpHeaderExtensions rtp_header_extensions =
1454 GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
1455
Zhi Huang27f3bf52018-03-26 21:37:23 -07001456 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Steve Anton3828c062017-12-06 10:34:51 -08001457 if (!SetRtpTransportParameters(content, type, CS_REMOTE,
1458 rtp_header_extensions, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001459 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001460 }
1461
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001462 VideoSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001463 RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
1464 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001465 if (video->conference_mode()) {
nisse4b4dc862016-02-17 05:25:36 -08001466 send_params.conference_mode = true;
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001467 }
Steve Antonbb50ce52018-03-26 10:24:32 -07001468 send_params.mid = content_name();
skvladdc1c62c2016-03-16 19:07:43 -07001469
1470 bool parameters_applied = media_channel()->SetSendParameters(send_params);
1471
1472 if (!parameters_applied) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001473 SafeSetError("Failed to set remote video description send parameters.",
1474 error_desc);
1475 return false;
1476 }
1477 last_send_params_ = send_params;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001478
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001479 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1480 // and only give it to the media channel once we have a local
1481 // description too (without a local description, we won't be able to
1482 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001483 if (!UpdateRemoteStreams_w(video->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001484 SafeSetError("Failed to set remote video description streams.", error_desc);
1485 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001486 }
1487
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001488 if (video->rtp_header_extensions_set()) {
jbauch5869f502017-06-29 12:31:36 -07001489 MaybeCacheRtpAbsSendTimeHeaderExtension_w(rtp_header_extensions);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001490 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001491
1492 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001493 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001494 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001495}
1496
deadbeef953c2ce2017-01-09 14:53:41 -08001497RtpDataChannel::RtpDataChannel(rtc::Thread* worker_thread,
1498 rtc::Thread* network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001499 rtc::Thread* signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001500 std::unique_ptr<DataMediaChannel> media_channel,
deadbeef953c2ce2017-01-09 14:53:41 -08001501 const std::string& content_name,
deadbeefac22f702017-01-12 21:59:29 -08001502 bool rtcp_mux_required,
deadbeef953c2ce2017-01-09 14:53:41 -08001503 bool srtp_required)
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001504 : BaseChannel(worker_thread,
1505 network_thread,
zhihuangf5b251b2017-01-12 19:37:48 -08001506 signaling_thread,
Steve Anton8699a322017-11-06 15:53:33 -08001507 std::move(media_channel),
deadbeefcbecd352015-09-23 11:50:27 -07001508 content_name,
deadbeefac22f702017-01-12 21:59:29 -08001509 rtcp_mux_required,
deadbeef953c2ce2017-01-09 14:53:41 -08001510 srtp_required) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001511
deadbeef953c2ce2017-01-09 14:53:41 -08001512RtpDataChannel::~RtpDataChannel() {
1513 TRACE_EVENT0("webrtc", "RtpDataChannel::~RtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001514 // this can't be done in the base class, since it calls a virtual
1515 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001516 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517}
1518
Steve Anton8699a322017-11-06 15:53:33 -08001519void RtpDataChannel::Init_w(
deadbeeff5346592017-01-24 21:51:21 -08001520 DtlsTransportInternal* rtp_dtls_transport,
1521 DtlsTransportInternal* rtcp_dtls_transport,
deadbeef5bd5ca32017-02-10 11:31:50 -08001522 rtc::PacketTransportInternal* rtp_packet_transport,
1523 rtc::PacketTransportInternal* rtcp_packet_transport) {
Steve Anton8699a322017-11-06 15:53:33 -08001524 BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport,
1525 rtp_packet_transport, rtcp_packet_transport);
1526
deadbeef953c2ce2017-01-09 14:53:41 -08001527 media_channel()->SignalDataReceived.connect(this,
1528 &RtpDataChannel::OnDataReceived);
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001529 media_channel()->SignalReadyToSend.connect(
deadbeef953c2ce2017-01-09 14:53:41 -08001530 this, &RtpDataChannel::OnDataChannelReadyToSend);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001531}
1532
Zhi Huang2dfc42d2017-12-04 13:38:48 -08001533void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
1534 BaseChannel::Init_w(rtp_transport);
1535 media_channel()->SignalDataReceived.connect(this,
1536 &RtpDataChannel::OnDataReceived);
1537 media_channel()->SignalReadyToSend.connect(
1538 this, &RtpDataChannel::OnDataChannelReadyToSend);
1539}
1540
deadbeef953c2ce2017-01-09 14:53:41 -08001541bool RtpDataChannel::SendData(const SendDataParams& params,
1542 const rtc::CopyOnWriteBuffer& payload,
1543 SendDataResult* result) {
stefanf79ade12017-06-02 06:44:03 -07001544 return InvokeOnWorker<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001545 RTC_FROM_HERE, Bind(&DataMediaChannel::SendData, media_channel(), params,
1546 payload, result));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001547}
1548
deadbeef953c2ce2017-01-09 14:53:41 -08001549bool RtpDataChannel::CheckDataChannelTypeFromContent(
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001550 const DataContentDescription* content,
1551 std::string* error_desc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001552 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
1553 (content->protocol() == kMediaProtocolDtlsSctp));
deadbeef953c2ce2017-01-09 14:53:41 -08001554 // It's been set before, but doesn't match. That's bad.
1555 if (is_sctp) {
1556 SafeSetError("Data channel type mismatch. Expected RTP, got SCTP.",
1557 error_desc);
1558 return false;
1559 }
1560 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561}
1562
deadbeef953c2ce2017-01-09 14:53:41 -08001563bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001564 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001565 std::string* error_desc) {
1566 TRACE_EVENT0("webrtc", "RtpDataChannel::SetLocalContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001567 RTC_DCHECK_RUN_ON(worker_thread());
Mirko Bonadei675513b2017-11-09 11:09:25 +01001568 RTC_LOG(LS_INFO) << "Setting local data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001569
Steve Antonb1c1de12017-12-21 15:14:30 -08001570 RTC_DCHECK(content);
1571 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001572 SafeSetError("Can't find data content in local description.", error_desc);
1573 return false;
1574 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001575
Steve Antonb1c1de12017-12-21 15:14:30 -08001576 const DataContentDescription* data = content->as_data();
1577
deadbeef953c2ce2017-01-09 14:53:41 -08001578 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001579 return false;
1580 }
1581
jbauch5869f502017-06-29 12:31:36 -07001582 RtpHeaderExtensions rtp_header_extensions =
1583 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
Zhi Huang27f3bf52018-03-26 21:37:23 -07001584 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
jbauch5869f502017-06-29 12:31:36 -07001585
Steve Anton3828c062017-12-06 10:34:51 -08001586 if (!SetRtpTransportParameters(content, type, CS_LOCAL, rtp_header_extensions,
1587 error_desc)) {
deadbeef953c2ce2017-01-09 14:53:41 -08001588 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001589 }
1590
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001591 DataRecvParameters recv_params = last_recv_params_;
jbauch5869f502017-06-29 12:31:36 -07001592 RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001593 if (!media_channel()->SetRecvParameters(recv_params)) {
1594 SafeSetError("Failed to set remote data description recv parameters.",
1595 error_desc);
1596 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597 }
Zhi Huang27f3bf52018-03-26 21:37:23 -07001598
deadbeef953c2ce2017-01-09 14:53:41 -08001599 for (const DataCodec& codec : data->codecs()) {
zstein3dcf0e92017-06-01 13:22:42 -07001600 AddHandledPayloadType(codec.id);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001601 }
Zhi Huang27f3bf52018-03-26 21:37:23 -07001602 // Need to re-register the sink to update the handled payload.
1603 if (!RegisterRtpDemuxerSink()) {
1604 RTC_LOG(LS_ERROR) << "Failed to set up data demuxing.";
1605 return false;
1606 }
1607
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001608 last_recv_params_ = recv_params;
1609
1610 // TODO(pthatcher): Move local streams into DataSendParameters, and
1611 // only give it to the media channel once we have a remote
1612 // description too (without a remote description, we won't be able
1613 // to send them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001614 if (!UpdateLocalStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001615 SafeSetError("Failed to set local data description streams.", error_desc);
1616 return false;
1617 }
1618
1619 set_local_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001620 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001621 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001622}
1623
deadbeef953c2ce2017-01-09 14:53:41 -08001624bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
Steve Anton3828c062017-12-06 10:34:51 -08001625 SdpType type,
deadbeef953c2ce2017-01-09 14:53:41 -08001626 std::string* error_desc) {
1627 TRACE_EVENT0("webrtc", "RtpDataChannel::SetRemoteContent_w");
Steve Antonb1c1de12017-12-21 15:14:30 -08001628 RTC_DCHECK_RUN_ON(worker_thread());
1629 RTC_LOG(LS_INFO) << "Setting remote data description";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001630
Steve Antonb1c1de12017-12-21 15:14:30 -08001631 RTC_DCHECK(content);
1632 if (!content) {
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001633 SafeSetError("Can't find data content in remote description.", error_desc);
1634 return false;
1635 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001636
Steve Antonb1c1de12017-12-21 15:14:30 -08001637 const DataContentDescription* data = content->as_data();
1638
Zhi Huang801b8682017-11-15 11:36:43 -08001639 // If the remote data doesn't have codecs, it must be empty, so ignore it.
1640 if (!data->has_codecs()) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001641 return true;
1642 }
1643
deadbeef953c2ce2017-01-09 14:53:41 -08001644 if (!CheckDataChannelTypeFromContent(data, error_desc)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001645 return false;
1646 }
1647
jbauch5869f502017-06-29 12:31:36 -07001648 RtpHeaderExtensions rtp_header_extensions =
1649 GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
1650
Zhi Huang27f3bf52018-03-26 21:37:23 -07001651 UpdateRtpHeaderExtensionMap(rtp_header_extensions);
Mirko Bonadei675513b2017-11-09 11:09:25 +01001652 RTC_LOG(LS_INFO) << "Setting remote data description";
Steve Anton3828c062017-12-06 10:34:51 -08001653 if (!SetRtpTransportParameters(content, type, CS_REMOTE,
1654 rtp_header_extensions, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001655 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001656 }
1657
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001658 DataSendParameters send_params = last_send_params_;
jbauch5869f502017-06-29 12:31:36 -07001659 RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
1660 &send_params);
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001661 if (!media_channel()->SetSendParameters(send_params)) {
1662 SafeSetError("Failed to set remote data description send parameters.",
1663 error_desc);
1664 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001665 }
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001666 last_send_params_ = send_params;
1667
1668 // TODO(pthatcher): Move remote streams into DataRecvParameters,
1669 // and only give it to the media channel once we have a local
1670 // description too (without a local description, we won't be able to
1671 // recv them anyway).
Steve Anton3828c062017-12-06 10:34:51 -08001672 if (!UpdateRemoteStreams_w(data->streams(), type, error_desc)) {
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001673 SafeSetError("Failed to set remote data description streams.",
1674 error_desc);
1675 return false;
1676 }
1677
1678 set_remote_content_direction(content->direction());
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001679 UpdateMediaSendRecvState_w();
Peter Thatcherc2ee2c82015-08-07 16:05:34 -07001680 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001681}
1682
deadbeef953c2ce2017-01-09 14:53:41 -08001683void RtpDataChannel::UpdateMediaSendRecvState_w() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001684 // Render incoming data if we're the active call, and we have the local
1685 // content. We receive data on the default channel and multiplexed streams.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001686 bool recv = IsReadyToReceiveMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001687 if (!media_channel()->SetReceive(recv)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001688 RTC_LOG(LS_ERROR) << "Failed to SetReceive on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001689 }
1690
1691 // Send outgoing data if we're the active call, we have the remote content,
1692 // and we have had some form of connectivity.
Taylor Brandstetterbad33bf2016-08-25 13:31:14 -07001693 bool send = IsReadyToSendMedia_w();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001694 if (!media_channel()->SetSend(send)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001695 RTC_LOG(LS_ERROR) << "Failed to SetSend on data channel";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001696 }
1697
sergeyu@chromium.org9cf037b2014-02-07 19:03:26 +00001698 // Trigger SignalReadyToSendData asynchronously.
1699 OnDataChannelReadyToSend(send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700
Mirko Bonadei675513b2017-11-09 11:09:25 +01001701 RTC_LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001702}
1703
deadbeef953c2ce2017-01-09 14:53:41 -08001704void RtpDataChannel::OnMessage(rtc::Message* pmsg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001705 switch (pmsg->message_id) {
1706 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001707 DataChannelReadyToSendMessageData* data =
1708 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +00001709 ready_to_send_data_ = data->data();
1710 SignalReadyToSendData(ready_to_send_data_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001711 delete data;
1712 break;
1713 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001714 case MSG_DATARECEIVED: {
1715 DataReceivedMessageData* data =
1716 static_cast<DataReceivedMessageData*>(pmsg->pdata);
deadbeef953c2ce2017-01-09 14:53:41 -08001717 SignalDataReceived(data->params, data->payload);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001718 delete data;
1719 break;
1720 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001721 default:
1722 BaseChannel::OnMessage(pmsg);
1723 break;
1724 }
1725}
1726
deadbeef953c2ce2017-01-09 14:53:41 -08001727void RtpDataChannel::OnDataReceived(const ReceiveDataParams& params,
1728 const char* data,
1729 size_t len) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001730 DataReceivedMessageData* msg = new DataReceivedMessageData(
1731 params, data, len);
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001732 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_DATARECEIVED, msg);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001733}
1734
deadbeef953c2ce2017-01-09 14:53:41 -08001735void RtpDataChannel::OnDataChannelReadyToSend(bool writable) {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001736 // This is usded for congestion control to indicate that the stream is ready
1737 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
1738 // that the transport channel is ready.
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -07001739 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001740 new DataChannelReadyToSendMessageData(writable));
1741}
1742
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001743} // namespace cricket